505 lines
14 KiB
Python
505 lines
14 KiB
Python
#!BPY
|
|
|
|
"""
|
|
Name: 'FLT Palette Manager'
|
|
Blender: 240
|
|
Group: 'Misc'
|
|
Tooltip: 'Manage FLT colors'
|
|
"""
|
|
|
|
__author__ = "Geoffrey Bantle"
|
|
__version__ = "1.0 11/21/2007"
|
|
__email__ = ('scripts', 'Author, ')
|
|
__url__ = ('blender', 'blenderartists.org')
|
|
|
|
__bpydoc__ ="""\
|
|
|
|
This script manages colors in OpenFlight databases. OpenFlight is a
|
|
registered trademark of MultiGen-Paradigm, Inc.
|
|
|
|
Todo:
|
|
-Figure out whats causing the PC speaker to beep when initializing...
|
|
|
|
Feature overview and more availible at:
|
|
http://wiki.blender.org/index.php/Scripts/Manual/FLTools
|
|
"""
|
|
|
|
# --------------------------------------------------------------------------
|
|
# flt_palettemanager.py version 1.0 2005/04/08
|
|
# --------------------------------------------------------------------------
|
|
# ***** BEGIN GPL LICENSE BLOCK *****
|
|
#
|
|
# Copyright (C) 2007: Blender Foundation
|
|
#
|
|
# This program is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU General Public License
|
|
# as published by the Free Software Foundation; either version 2
|
|
# of the License, or (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software Foundation,
|
|
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
#
|
|
# ***** END GPL LICENCE BLOCK *****
|
|
# --------------------------------------------------------------------------
|
|
|
|
import Blender.Draw as Draw
|
|
from Blender.BGL import *
|
|
import Blender
|
|
import flt_properties
|
|
import flt_defaultp as defaultp
|
|
from flt_properties import *
|
|
|
|
def RGBtoHSV( r, g, b):
|
|
minc = min( r, g, b )
|
|
maxc = max( r, g, b )
|
|
v = maxc
|
|
|
|
delta = maxc - minc
|
|
|
|
if( max != 0 ):
|
|
s = delta / maxc
|
|
else:
|
|
s = 0
|
|
h = -1
|
|
return (h,s,v)
|
|
|
|
if( r == maxc ):
|
|
h = ( g - b ) / delta
|
|
elif( g == maxc ):
|
|
h = 2 + ( b - r ) / delta
|
|
else:
|
|
h = 4 + ( r - g ) / delta
|
|
|
|
h *= 60
|
|
if( h < 0 ):
|
|
h += 360
|
|
|
|
return(h,s,v)
|
|
|
|
def HSVtoRGB(h,s,v):
|
|
|
|
if( s == 0 ):
|
|
return (v,v,v)
|
|
|
|
|
|
h /= 60
|
|
i = math.floor( h)
|
|
f = h - i
|
|
p = v * ( 1 - s )
|
|
q = v * ( 1 - s * f )
|
|
t = v * ( 1 - s * ( 1 - f ) )
|
|
|
|
if i == 0:
|
|
r = v
|
|
g = t
|
|
b = p
|
|
elif i == 1:
|
|
r = q
|
|
g = v
|
|
b = p
|
|
|
|
elif i== 2:
|
|
r = p
|
|
g = v
|
|
b = t
|
|
elif i==3:
|
|
r = p
|
|
g = q
|
|
b = v
|
|
elif i==4:
|
|
r = t
|
|
g = p
|
|
b = v
|
|
|
|
else:
|
|
r = v
|
|
g = p
|
|
b = q
|
|
|
|
return(r,g,b)
|
|
|
|
|
|
palette_size = 12
|
|
palette_x = 0
|
|
palette_y = 0
|
|
|
|
colors = list()
|
|
curint = 1.0
|
|
curswatch = 0
|
|
#make a default palette, not very useful.
|
|
cinc = 1.0 / 1024.0
|
|
cstep = 0.0
|
|
picker = None
|
|
ptt = ""
|
|
|
|
|
|
ts1=None
|
|
ts2=None
|
|
ts3=None
|
|
ts4=None
|
|
ts5=None
|
|
|
|
for i in xrange(1024):
|
|
colors.append([cstep,cstep,cstep])
|
|
cstep = cstep + cinc
|
|
def update_state():
|
|
state = dict()
|
|
state["activeScene"] = Blender.Scene.getCurrent()
|
|
state["activeObject"] = state["activeScene"].getActiveObject()
|
|
state["activeMesh"] = None
|
|
if state["activeObject"] and state["activeObject"].type == 'Mesh':
|
|
state["activeMesh"] = state["activeObject"].getData(mesh=True)
|
|
|
|
state["activeFace"] = None
|
|
if state["activeMesh"]:
|
|
if state["activeMesh"].faceUV and state["activeMesh"].activeFace != None:
|
|
state["activeFace"] = state["activeMesh"].faces[state["activeMesh"].activeFace]
|
|
|
|
return state
|
|
|
|
def pack_face_index(index, intensity):
|
|
return ((127*intensity)+(128*index))
|
|
def unpack_face_index(face_index):
|
|
index = face_index / 128
|
|
intensity = float(face_index - 128.0 * index) / 127.0
|
|
return(index,intensity)
|
|
|
|
def event(evt,val):
|
|
global palette_size
|
|
global palette_x
|
|
global palette_y
|
|
global colors
|
|
global curint
|
|
global curswatch
|
|
|
|
areas = Blender.Window.GetScreenInfo()
|
|
curarea = Blender.Window.GetAreaID()
|
|
curRect = None
|
|
editmode = 0
|
|
|
|
for area in areas:
|
|
if area['id'] == curarea:
|
|
curRect = area['vertices']
|
|
break
|
|
|
|
if evt == Draw.LEFTMOUSE:
|
|
mval = Blender.Window.GetMouseCoords()
|
|
rastx = mval[0] - curRect[0]
|
|
rasty = mval[1] - curRect[1]
|
|
|
|
swatchx = (rastx -palette_x) / palette_size #+state["palette_x"]
|
|
swatchy = (rasty -palette_y) / palette_size #+state["palette_y"]
|
|
if rastx > palette_x and rastx < (palette_x + palette_size * 32) and rasty > palette_y and rasty < (palette_y+ palette_size* 32):
|
|
if swatchx < 32 and swatchy < 32:
|
|
curswatch = (swatchx * 32) + swatchy
|
|
Draw.Redraw(1)
|
|
|
|
elif swatchy < 34 and swatchx < 32:
|
|
curint = 1.0 - (float(rastx-palette_x)/(palette_size*32.0))
|
|
Draw.Redraw(1)
|
|
|
|
#copy current color and intensity to selected faces.
|
|
elif evt == Draw.VKEY:
|
|
|
|
if Blender.Window.EditMode():
|
|
Blender.Window.EditMode(0)
|
|
editmode = 1
|
|
state = update_state()
|
|
|
|
#retrieve color from palette
|
|
color = struct.unpack('>BBBB',struct.pack('>i',colors[curswatch]))
|
|
actmesh = state["activeMesh"]
|
|
if actmesh:
|
|
if(Blender.Window.GetKeyQualifiers() != Blender.Window.Qual["CTRL"]):
|
|
selfaces = list()
|
|
for face in actmesh.faces:
|
|
if face.sel:
|
|
selfaces.append(face)
|
|
|
|
if not "FLT_COL" in actmesh.faces.properties:
|
|
actmesh.faces.addPropertyLayer("FLT_COL",Blender.Mesh.PropertyTypes["INT"])
|
|
for face in actmesh.faces:
|
|
face.setProperty("FLT_COL",127) #default
|
|
try:
|
|
actmesh.activeColorLayer = "FLT_Fcol"
|
|
except:
|
|
actmesh.addColorLayer("FLT_Fcol")
|
|
actmesh.activeColorLayer = "FLT_Fcol"
|
|
|
|
|
|
for face in selfaces:
|
|
#First append packed index + color and store in face property
|
|
face.setProperty("FLT_COL",int(pack_face_index(curswatch,curint)))
|
|
#Save baked color to face vertex colors
|
|
for col in face.col:
|
|
col.r = int(color[0] * curint)
|
|
col.g = int(color[1] * curint)
|
|
col.b = int(color[2] * curint)
|
|
col.a = int(color[3] * curint)
|
|
else:
|
|
if Blender.Mesh.Mode() == Blender.Mesh.SelectModes['VERTEX']:
|
|
if not 'FLT_VCOL' in actmesh.verts.properties:
|
|
actmesh.verts.addPropertyLayer("FLT_VCOL",Blender.Mesh.PropertyTypes["INT"])
|
|
for vert in actmesh.verts:
|
|
vert.setProperty("FLT_VCOL",127)
|
|
else:
|
|
for vert in actmesh.verts:
|
|
if vert.sel:
|
|
vert.setProperty("FLT_VCOL",int(pack_face_index(curswatch,curint)))
|
|
|
|
if editmode:
|
|
Blender.Window.EditMode(1)
|
|
|
|
Blender.Window.RedrawAll()
|
|
|
|
#grab color and intensity from active face
|
|
elif evt == Draw.CKEY:
|
|
if Blender.Window.EditMode():
|
|
Blender.Window.EditMode(0)
|
|
editmode = 1
|
|
state = update_state()
|
|
|
|
actmesh = state["activeMesh"]
|
|
activeFace = state["activeFace"]
|
|
|
|
|
|
if activeFace:
|
|
if not "FLT_COL" in actmesh.faces.properties:
|
|
actmesh.faces.addPropertyLayer("FLT_COL",Blender.Mesh.PropertyTypes["INT"])
|
|
for face in actmesh.faces:
|
|
face.setProperty("FLT_COL",127) #default
|
|
try:
|
|
actmesh.activeColorLayer = "FLT_Fcol"
|
|
except:
|
|
actmesh.addColorLayer("FLT_Fcol")
|
|
actmesh.activeColorLayer = "FLT_Fcol"
|
|
tcol = activeFace.getProperty("FLT_COL")
|
|
(index,intensity) = unpack_face_index(tcol)
|
|
curswatch = index
|
|
curint = intensity
|
|
|
|
if editmode:
|
|
Blender.Window.EditMode(1)
|
|
|
|
Blender.Window.RedrawAll()
|
|
|
|
elif evt == Draw.GKEY:
|
|
if Blender.Window.EditMode():
|
|
Blender.Window.EditMode(0)
|
|
editmode =1
|
|
state = update_state()
|
|
|
|
actmesh = state["activeMesh"]
|
|
activeFace = state["activeFace"]
|
|
|
|
if activeFace and "FLT_COL" in actmesh.faces.properties:
|
|
(index,intensity) = unpack_face_index(activeFace.getProperty("FLT_COL"))
|
|
for face in actmesh.faces:
|
|
(index2, intensity2) = unpack_face_index(face.getProperty("FLT_COL"))
|
|
if index == index2:
|
|
face.sel = 1
|
|
|
|
|
|
elif evt == Draw.ESCKEY:
|
|
Draw.Exit()
|
|
|
|
if editmode:
|
|
Blender.Window.EditMode(1)
|
|
|
|
def update_all():
|
|
global colors
|
|
state = update_state()
|
|
#update the baked FLT colors for all meshes.
|
|
for object in state["activeScene"].objects:
|
|
if object.type == "Mesh":
|
|
mesh = object.getData(mesh=True)
|
|
if 'FLT_COL' in mesh.faces.properties and "FLT_Fcol" in mesh.getColorLayerNames():
|
|
mesh.activeColorLayer = "FLT_Fcol"
|
|
for face in mesh.faces:
|
|
(index,intensity) = unpack_face_index(face.getProperty('FLT_COL'))
|
|
color = struct.unpack('>BBBB',struct.pack('>i',colors[index]))
|
|
#update the vertex colors for this face
|
|
for col in face.col:
|
|
col.r = int(color[0] * intensity)
|
|
col.g = int(color[1] * intensity)
|
|
col.b = int(color[2] * intensity)
|
|
col.a = 255
|
|
|
|
|
|
def but_event(evt):
|
|
global palette_size
|
|
global palette_x
|
|
global palette_y
|
|
global colors
|
|
global curint
|
|
global curswatch
|
|
global picker
|
|
state = update_state()
|
|
|
|
if evt == 1:
|
|
if picker.val:
|
|
rval = (int(picker.val[0]*255),int(picker.val[1]*255),int(picker.val[2]*255),255)
|
|
rval = struct.pack('>BBBB',rval[0],rval[1],rval[2],rval[3])
|
|
rval = struct.unpack('>i',rval)
|
|
colors[curswatch] = rval[0]
|
|
#go cd through all meshes and update their FLT colors
|
|
update_all()
|
|
|
|
Draw.Redraw(1)
|
|
def init_pal():
|
|
global palette_size
|
|
global palette_x
|
|
global palette_y
|
|
global colors
|
|
global curint
|
|
global curswatch
|
|
|
|
state = update_state()
|
|
|
|
if not state["activeScene"].properties.has_key('FLT'):
|
|
state["activeScene"].properties['FLT'] = dict()
|
|
|
|
try:
|
|
colors = state["activeScene"].properties['FLT']['Color Palette']
|
|
except:
|
|
state["activeScene"].properties['FLT']['Color Palette'] = defaultp.pal
|
|
colors = state["activeScene"].properties['FLT']['Color Palette']
|
|
|
|
def draw_palette():
|
|
global palette_size
|
|
global palette_x
|
|
global palette_y
|
|
global colors
|
|
global curint
|
|
global curswatch
|
|
global picker
|
|
global ts1
|
|
global ts2
|
|
global ts3
|
|
global ts4
|
|
global ts5
|
|
|
|
state = update_state()
|
|
init_pal()
|
|
|
|
ssize = palette_size
|
|
xpos = palette_x
|
|
cid = 0
|
|
|
|
highlight = [(palette_x,palette_y),(palette_x+palette_size,palette_y),(palette_x+palette_size,palette_y+palette_size),(palette_x,palette_y+palette_size)]
|
|
for x in xrange(32):
|
|
ypos = palette_y
|
|
for y in xrange(32):
|
|
color = struct.unpack('>BBBB',struct.pack('>i',colors[cid]))
|
|
glColor3f(color[0]/255.0,color[1]/255.0,color[2]/255.0)
|
|
glBegin(GL_POLYGON)
|
|
glVertex2i(xpos,ypos)
|
|
glVertex2i(xpos+ssize,ypos)
|
|
glVertex2i(xpos+ssize,ypos+ssize)
|
|
glVertex2i(xpos,ypos+ssize)
|
|
glEnd()
|
|
|
|
if curswatch == cid:
|
|
highlight[0] = (xpos,ypos)
|
|
highlight[1] = (xpos+ssize,ypos)
|
|
highlight[2] = (xpos+ssize,ypos+ssize)
|
|
highlight[3] = (xpos,ypos+ssize)
|
|
|
|
glColor3f(0.0,0.0,0.0)
|
|
glBegin(GL_LINE_LOOP)
|
|
glVertex2i(xpos,ypos)
|
|
glVertex2i(xpos+ssize,ypos)
|
|
glVertex2i(xpos+ssize,ypos+ssize)
|
|
glVertex2i(xpos,ypos+ssize)
|
|
glVertex2i(xpos,ypos)
|
|
glEnd()
|
|
|
|
|
|
cid = cid + 1
|
|
ypos = ypos + ssize
|
|
|
|
xpos = xpos + ssize
|
|
|
|
#draw intensity gradient
|
|
color = struct.unpack('>BBBB',struct.pack('>i',colors[curswatch]))
|
|
color = [color[0]/255.0,color[1]/255.0,color[2]/255.0]
|
|
colsteps = [color[0]/255.0,color[1]/255.0,color[2]/255.0]
|
|
stripwidth = (palette_size * 32.0) / 256
|
|
strippad = palette_size / 2.0
|
|
|
|
xpos = palette_x
|
|
grady = (palette_y + (palette_size * 32.0)) + strippad
|
|
for x in xrange(256):
|
|
color[0] = color[0] - colsteps[0]
|
|
color[1] = color[1] - colsteps[1]
|
|
color[2] = color[2] - colsteps[2]
|
|
|
|
glColor3f(color[0], color[1] ,color[2])
|
|
glBegin(GL_POLYGON)
|
|
glVertex2f(xpos,grady)
|
|
glVertex2f(xpos+stripwidth,grady)
|
|
glVertex2f(xpos+stripwidth,grady+palette_size)
|
|
glVertex2f(xpos,grady+palette_size)
|
|
glEnd()
|
|
xpos = xpos + stripwidth
|
|
|
|
#draw intensity slider bar
|
|
#xposition == 512 - ((curint) * 512)
|
|
xpos = ((palette_size*32) * (1.0 - curint)) + palette_x
|
|
glColor3f(1.0,1.0,1.0)
|
|
glBegin(GL_LINE_LOOP)
|
|
glVertex2i(int(xpos-6),int(grady-1))
|
|
glVertex2i(int(xpos+6),int(grady-1))
|
|
glVertex2i(int(xpos+6),int(grady+palette_size+1))
|
|
glVertex2i(int(xpos-6),int(grady+palette_size+1))
|
|
#glVertex2i(xpos-6,grady+7)
|
|
glEnd()
|
|
|
|
#draw color picker
|
|
color = struct.unpack('>BBBB',struct.pack('>i',colors[curswatch]))
|
|
pickcol = (color[0]/255.0,color[1]/255.0,color[2]/255.0)
|
|
picker = Blender.Draw.ColorPicker(1,highlight[0][0]+1,highlight[0][1]+1,ssize-2,ssize-2,pickcol,ptt)
|
|
|
|
#draw highlight swatch
|
|
glColor3f(1.0,1.0,1.0)
|
|
glBegin(GL_LINE_LOOP)
|
|
glVertex2i(highlight[0][0],highlight[0][1])
|
|
glVertex2i(highlight[1][0],highlight[1][1])
|
|
glVertex2i(highlight[2][0],highlight[2][1])
|
|
glVertex2i(highlight[3][0],highlight[3][1])
|
|
glVertex2i(highlight[0][0],highlight[0][1])
|
|
glEnd()
|
|
|
|
#draw text string explanations
|
|
xpos = palette_size*32+20
|
|
ypos = palette_size*32+10
|
|
glRasterPos2d(xpos,ypos)
|
|
ts1 = Blender.Draw.Text("FLT Palette Manager V 1.0")
|
|
ypos = ypos - 20
|
|
glRasterPos2d(xpos,ypos)
|
|
ts3 = Blender.Draw.Text("CKEY - Copy Active Face Color*")
|
|
ypos = ypos - 20
|
|
glRasterPos2d(xpos,ypos)
|
|
ts2 = Blender.Draw.Text("VKEY - Paste Color to Selected Faces")
|
|
ypos = ypos - 20
|
|
glRasterPos2d(xpos,ypos)
|
|
ts4 = Blender.Draw.Text("GKEY - Select Faces With Same Color")
|
|
ypos = ypos - 15
|
|
glRasterPos2d(xpos,ypos)
|
|
ts5 = Blender.Draw.Text("(*Requires mesh with UV coordinates)", 'small')
|
|
|
|
def gui():
|
|
glClearColor(0.5,0.5,0.5,1.0)
|
|
glClear(GL_COLOR_BUFFER_BIT)
|
|
draw_palette()
|
|
|
|
|
|
init_pal()
|
|
Draw.Register(gui,event,but_event)
|
|
|