Integrated Freestyle to rendering pipeline
[blender.git] / release / scripts / flt_lodedit.py
1 #!BPY
2
3 """
4 Name: 'FLT LOD Editor'
5 Blender: 240
6 Group: 'Misc'
7 Tooltip: 'Level of Detail Edtior for FLT nodes'
8 """
9
10 __author__ = "Geoffrey Bantle"
11 __version__ = "1.0 11/21/07"
12 __email__ = ('scripts', 'Author, ')
13 __url__ = ('blender', 'blenderartists.org')
14
15 __bpydoc__ ="""\
16 This script provides tools for working with OpenFlight databases in Blender. OpenFlight is a
17 registered trademark of MultiGen-Paradigm, Inc.
18
19 Feature overview and more availible at:
20 http://wiki.blender.org/index.php/Scripts/Manual/FLTools
21 """
22
23 # --------------------------------------------------------------------------
24 # flt_palettemanager.py version 0.1 2005/04/08
25 # --------------------------------------------------------------------------
26 # ***** BEGIN GPL LICENSE BLOCK *****
27 #
28 # Copyright (C) 2007: Blender Foundation
29 #
30 # This program is free software; you can redistribute it and/or
31 # modify it under the terms of the GNU General Public License
32 # as published by the Free Software Foundation; either version 2
33 # of the License, or (at your option) any later version.
34 #
35 # This program is distributed in the hope that it will be useful,
36 # but WITHOUT ANY WARRANTY; without even the implied warranty of
37 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
38 # GNU General Public License for more details.
39 #
40 # You should have received a copy of the GNU General Public License
41 # along with this program; if not, write to the Free Software Foundation,
42 # Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
43 #
44 # ***** END GPL LICENCE BLOCK *****
45 # --------------------------------------------------------------------------
46
47 import Blender.Draw as Draw
48 from Blender.BGL import *
49 import Blender
50 import flt_properties
51 reload(flt_properties)
52 from flt_properties import *
53
54 #event codes
55 evcode = {
56         "LOD_MAKE" : 100,
57         "LOD_DELETE" : 101,
58         "LOD_CALC_CENTER" : 102,
59         "LOD_GRAB_CENTER" : 103,
60         "LOD_X" : 104,
61         "LOD_Y" : 105,
62         "LOD_Z" : 106,
63         "LOD_FREEZE" : 107,
64         "LOD_SIG" : 108,
65         "LOD_IN" : 109,
66         "LOD_OUT" : 110,
67         "LOD_TRANS" : 111,              
68         "LOD_PREVIOUS" : 112
69 }
70
71
72 #system
73 LOD_MAKE = None                 #PushButton
74 LOD_DELETE = None               #PushButton
75 LOD_CALC_CENTER = None  #PushButton
76 LOD_GRAB_CENTER = None  #Pushbutton
77 LOD_FREEZE = None               #Toggle
78 LOD_PREVIOUS = None             #Toggle
79
80 LOD_X = None                    #Input
81 LOD_Y = None                    #Input
82 LOD_Z = None                    #Input
83
84 LOD_SIG = None                  #Input
85 LOD_IN = None                   #Input
86 LOD_OUT = None                  #Input
87 LOD_TRANS = None                #Input
88
89 #labels
90 LOD_EDITLABEL = None
91 LOD_SWITCHLABEL = None
92 LOD_CENTERLABEL = None
93
94 LOD_XLABEL = None
95 LOD_YLABEL = None
96 LOD_ZLABEL = None
97 LOD_SIGLABEL = None
98 LOD_INLABEL = None
99 LOD_OUTLABEL = None
100 LOD_TRANSLABEL = None
101
102
103 #ID Props
104 switch_in = '5d!switch in'
105 switch_out = '6d!switch out'
106 xco = '10d!X co'
107 yco = '11d!Y co'
108 zco = '12d!Z co'
109 trans = '13d!Transition'
110 sig_size = '14d!Sig Size'
111
112 #Flags
113 lodflag = '9I!flags'
114 previous_mask = (1 << 31)
115 freeze_mask = (1 << 29)
116
117 def update_state():
118         state = dict()
119         state["activeScene"] = Blender.Scene.GetCurrent()
120         state["activeObject"] = state["activeScene"].objects.active
121         if state["activeObject"] and not state["activeObject"].sel:
122                 state["activeObject"] = None
123         state["activeMesh"] = None
124         if state["activeObject"] and state["activeObject"].type == 'Mesh':
125                 state["activeMesh"] = state["activeObject"].getData(mesh=True)
126         
127         state["activeFace"] = None
128         if state["activeMesh"]:
129                 if state["activeMesh"].faceUV and state["activeMesh"].activeFace != None:
130                         state["activeFace"] = state["activeMesh"].faces[state["activeMesh"].activeFace]
131                 
132                 
133         #update editmode
134         state["editmode"]       = Blender.Window.EditMode()
135
136         return state
137         
138 def idprops_append(object, typecode, props):
139         object.properties["FLT"] = dict()
140         object.properties["FLT"]['type'] = typecode 
141         for prop in props:
142                 object.properties["FLT"][prop] = props[prop]
143         object.properties["FLT"]['3t8!id'] = object.name
144
145 def idprops_kill():
146         state = update_state()
147         if state["activeObject"] and state["activeObject"].properties.has_key('FLT'):
148                 state["activeObject"].properties.pop('FLT')
149
150 def idprops_copy(source):
151         state = update_state()
152         if source.properties.has_key('FLT'):
153                 for object in state["activeScene"].objects:
154                         if object.sel and object != source and (state["activeScene"].Layers & object.Layers):
155                                 idprops_kill(object)
156                                 object.properties['FLT'] = dict()
157                                 for key in source.properties['FLT']:
158                                         object.properties['FLT'][key] = source.properties['FLT'][key]
159
160 def select_by_typecode(typecode):
161         state = update_state()
162         
163         for object in state["activeScene"].objects:
164                 if object.properties.has_key('FLT') and object.properties['FLT']['type'] == typecode and state["activeScene"].Layers & object.Layers:
165                                 object.select(1)
166
167 def idprops_type(object, typecode):
168         if object.properties.has_key('FLT') and object.properties['FLT'].has_key('type') and object.properties['FLT']['type'] == typecode:
169                 return True
170         return False
171
172 #ui type code
173 def get_prop(typecode, prop):
174         
175         state = update_state()
176         if state["activeObject"] and idprops_type(state["activeObject"], typecode):
177                 props = state["activeObject"].properties['FLT']
178         else:
179                 props =  flt_properties.FLTLOD
180                 
181         return props[prop]      
182
183 def set_prop(typecode, prop, value):
184         state = update_state()
185         if state["activeObject"] and idprops_type(state["activeObject"],typecode):
186                 state["activeObject"].properties['FLT'][prop] = value           
187
188
189
190 def get_lockmask(mask):
191         global lodflag
192         state = update_state()
193         if state["activeObject"]:
194                 flag = get_prop(73,lodflag)
195                 if flag & mask:
196                         return True
197         return False    
198
199 def set_lockmask(mask):
200         state = update_state()
201         if state["activeObject"] and idprops_type(state["activeObject"], 73):
202                 oldvalue = state["activeObject"].properties['FLT'][lodflag]
203                 oldvalue = struct.unpack('>I', struct.pack('>i', oldvalue))[0]
204                 oldvalue |= mask
205                 state["activeObject"].properties['FLT'][lodflag] = struct.unpack('>i', struct.pack(">I", oldvalue))[0]
206
207 def clear_lockmask(mask):
208         state = update_state()
209         if state["activeObject"] and idprops_type(state["activeObject"], 73):
210                 oldvalue = state["activeObject"].properties['FLT'][lodflag]
211                 oldvalue = struct.unpack('>I', struct.pack('>i', oldvalue))[0]
212                 oldvalue &= ~mask
213                 state["activeObject"].properties['FLT'][lodflag] = struct.unpack('>i',struct.pack('>I',oldvalue))[0]    
214
215 def findchildren(object):
216         state = update_state()
217         children = list()
218         for candidate in state["activeScene"].objects:
219                 if candidate.parent == object:
220                         children.append(candidate)
221         retlist = list(children)
222         for child in children:
223                 retlist = retlist + findchildren(child)
224         return retlist
225
226 def get_object_center(object):
227         bbox = object.getBoundBox(1)
228         average = Blender.Mathutils.Vector(0.0, 0.0, 0.0)
229         
230         for point in bbox:
231                 average[0] += point[0]
232                 average[1] += point[1]
233                 average[2] += point[2]
234         
235         average[0] = average[0] / 8.0
236         average[1] = average[1] / 8.0
237         average[2] = average[2] / 8.0
238         
239         return average
240         
241
242 def calc_center():
243         
244         global xco
245         global yco
246         global zco
247         
248         state = update_state()
249         if state["activeObject"] and idprops_type(state["activeObject"], 73):
250                 average = Blender.Mathutils.Vector(0.0, 0.0, 0.0)
251                 children = findchildren(state["activeObject"]) #get children objects    
252                 if children:
253                         for child in children:
254                                 center = get_object_center(child)
255                                 average[0] += center[0]
256                                 average[1] += center[1]
257                                 average[2] += center[2]
258                         
259                         average[0] = average[0] / len(children)
260                         average[1] = average[1] / len(children)
261                         average[2] = average[2] / len(children)
262                         
263                 set_prop(73, xco, average[0])
264                 set_prop(73, yco, average[1])
265                 set_prop(73, zco, average[2])
266                 
267
268 def grab_center():
269         
270         global xco
271         global yco
272         global zco
273         
274         state = update_state()
275         if state["activeObject"] and idprops_type(state["activeObject"], 73):
276                 center = Blender.Window.GetCursorPos()
277                 
278                 set_prop(73, xco, center[0])
279                 set_prop(73, yco, center[1])
280                 set_prop(73, zco, center[2])    
281
282
283 def create_lod():
284         state = update_state()
285         actobj = state["activeObject"]
286         if actobj and not idprops_type(actobj, 73):
287                 idprops_kill()
288                 idprops_append(actobj,73, flt_properties.FLTLOD)
289                 calc_center()
290
291         
292                 
293 def event(evt,val):
294         if evt == Draw.ESCKEY:
295                 Draw.Exit()
296                 
297 def but_event(evt):
298
299         global LOD_MAKE
300         global LOD_DELETE
301         global LOD_CALC_CENTER
302         global LOD_GRAB_CENTER
303         global LOD_FREEZE
304         global LOD_PREVIOUS
305         global LOD_X
306         global LOD_Y
307         global LOD_Z
308         global LOD_SIG
309         global LOD_IN
310         global LOD_OUT
311         global LOD_TRANS
312         
313         global switch_in
314         global switch_out
315         global xco
316         global yco
317         global zco
318         global trans
319         global sig_size
320         
321         global lodflag
322         global previous_mask
323         global freeze_mask
324         
325         global evcode
326         
327         #do "system" events
328         if evt == evcode["LOD_MAKE"]:
329                 create_lod()
330
331         if evt == evcode["LOD_CALC_CENTER"]:
332                 calc_center()
333         
334         if evt == evcode["LOD_DELETE"]:
335                 idprops_kill()
336         
337         if evt == evcode["LOD_GRAB_CENTER"]:
338                 grab_center()
339
340         #do mask events
341         if evt == evcode["LOD_FREEZE"]:
342                 if LOD_FREEZE.val == True:
343                         set_lockmask(freeze_mask)
344                 else:
345                         clear_lockmask(freeze_mask)
346                         
347         if evt == evcode["LOD_PREVIOUS"]:
348                 if LOD_PREVIOUS.val == True:
349                         set_lockmask(previous_mask)
350                 else:
351                         clear_lockmask(previous_mask)
352                         
353         #do input events
354         if evt == evcode["LOD_X"]:
355                 set_prop(73, xco, LOD_X.val)
356         if evt == evcode["LOD_Y"]:
357                 set_prop(73, yco, LOD_Y.val)
358         if evt == evcode["LOD_Z"]:
359                 set_prop(73, zco, LOD_Z.val)
360         if evt == evcode["LOD_SIG"]:
361                 set_prop(73, sig_size, LOD_SIG.val)
362         if evt == evcode["LOD_IN"]:
363                 set_prop(73, switch_in, LOD_IN.val)
364         if evt == evcode["LOD_OUT"]:
365                 set_prop(73, switch_out, LOD_OUT.val)
366         if evt == evcode["LOD_TRANS"]:
367                 set_prop(73, trans, LOD_TRANS.val)      
368                                 
369
370         Draw.Redraw(1)
371         Blender.Window.RedrawAll()
372
373 def draw_propsheet(x,y):
374
375         global LOD_MAKE
376         global LOD_DELETE
377         global LOD_CALC_CENTER
378         global LOD_GRAB_CENTER
379         global LOD_FREEZE
380         global LOD_PREVIOUS
381         global LOD_X
382         global LOD_Y
383         global LOD_Z
384         global LOD_SIG
385         global LOD_IN
386         global LOD_OUT
387         global LOD_TRANS
388
389         #labels
390         global LOD_EDITLABEL
391         global LOD_SWITCHLABEL
392         global LOD_CENTERLABEL
393         global LOD_XLABEL
394         global LOD_YLABEL
395         global LOD_ZLABEL
396         global LOD_SIGLABEL
397         global LOD_INLABEL
398         global LOD_OUTLABEL
399         global LOD_TRANSLABEL
400         
401         
402         global switch_in
403         global switch_out
404         global xco
405         global yco
406         global zco
407         global trans
408         global sig_size
409         
410         global lodflag
411         global previous_mask
412         global freeze_mask
413         
414         global evcode
415
416
417         global evcode
418         
419         state = update_state()
420
421         label_width = 100       
422         row_height = 20
423         toggle_width = 50
424         input_width = 100
425         pad = 10
426         origx = x
427         origy = (row_height * 16) + (pad * 16)
428
429
430         #editor label
431         x = origx
432         y = origy
433         LOD_EDITLABEL = Blender.Draw.Label("FLT Level of Detail Editor", x, y, 250, row_height)
434
435
436         #Center inputs
437         x = origx
438         y = y- (row_height + pad)
439         LOD_CENTERLABEL = Blender.Draw.Label("LOD center", x, y, label_width, row_height)
440         y = y- (row_height + pad)
441         LOD_XLABEL = Blender.Draw.Label("X Coordinate", x, y, label_width, row_height)
442         x = origx + (label_width + pad)
443         LOD_X = Blender.Draw.Number("", evcode["LOD_X"], x, y, input_width, row_height,get_prop(73,xco),  -1000000.0, 1000000.0, "")
444         x = origx
445         y = y- (row_height + pad)
446         LOD_YLABEL = Blender.Draw.Label("Y Coordinate", x, y, label_width, row_height)  
447         x = origx + (label_width + pad)
448         LOD_Y = Blender.Draw.Number("", evcode["LOD_Y"], x, y, input_width, row_height,get_prop(73,yco), -1000000.0,  1000000.0, "")
449         x = origx
450         y = y- (row_height + pad)
451         LOD_ZLABEL = Blender.Draw.Label("Z Coordinate", x, y, label_width, row_height)
452         x = origx + (label_width + pad)         
453         LOD_Z = Blender.Draw.Number("", evcode["LOD_Z"], x, y, input_width, row_height,get_prop(73,zco), -1000000.0, 1000000.0, "")
454
455
456         #Switch inputs
457         x = origx
458         y = y- (row_height + pad)
459         LOD_SWITCHLABEL = Blender.Draw.Label("Switch Settings", x, y, input_width, row_height)
460         y = y- (row_height + pad)
461         LOD_SIGLABEL = Blender.Draw.Label("Significant Size", x, y, label_width, row_height)
462         x = origx + (label_width + pad)
463         LOD_SIG = Blender.Draw.Number("", evcode["LOD_SIG"], x, y, input_width, row_height, get_prop(73,sig_size),  -1000000.0, 1000000.0, "")
464         x = origx
465         y = y- (row_height + pad)
466         LOD_INLABEL = Blender.Draw.Label("Switch In", x, y, label_width, row_height)
467         x = origx + (label_width + pad)
468         LOD_IN = Blender.Draw.Number("", evcode["LOD_IN"], x, y, input_width, row_height, get_prop(73,switch_in), -1000000.0, 1000000.0, "")
469         x = origx
470         y = y- (row_height + pad)
471         LOD_OUTLABEL = Blender.Draw.Label("Switch Out", x, y, label_width, row_height)  
472         x = origx + (label_width + pad)
473         LOD_OUT = Blender.Draw.Number("", evcode["LOD_OUT"], x, y, input_width, row_height, get_prop(73,switch_out), -1000000.0, 1000000.0, "")
474         x = origx
475         y = y- (row_height + pad)
476         LOD_TRANSLABEL = Blender.Draw.Label("Transition", x, y, label_width, row_height)                
477         x = origx + (label_width + pad)
478         LOD_TRANS = Blender.Draw.Number("", evcode["LOD_TRANS"], x, y, input_width, row_height, get_prop(73,trans), -1000000.0, 1000000.0, "")  
479
480
481         x = origx
482         y = y - (row_height + pad)      
483         LOD_MAKE = Blender.Draw.PushButton("Make LOD", evcode["LOD_MAKE"], x, y, input_width + label_width + pad, row_height, "Make a LOD Node out of Active Object")
484         y = y - (row_height + pad)      
485         LOD_DELETE = Blender.Draw.PushButton("Delete LOD", evcode["LOD_DELETE"], x, y, input_width + label_width + pad, row_height, "Delete the LOD Node properties")
486         y = y - (row_height + pad)
487         LOD_CALC_CENTER = Blender.Draw.PushButton("Calculate Center", evcode["LOD_CALC_CENTER"], x, y, input_width + label_width + pad, row_height, "Calculate the center of this LOD")
488         y = y - (row_height + pad)
489         LOD_GRAB_CENTER = Blender.Draw.PushButton("Grab Center", evcode["LOD_GRAB_CENTER"], x, y, input_width + label_width + pad, row_height, "Grab center from 3d cursor")
490         y = y - (row_height + pad)
491         LOD_FREEZE = Blender.Draw.Toggle("Freeze Center", evcode["LOD_FREEZE"], x, y, input_width + label_width + pad, row_height, get_lockmask(freeze_mask), "")
492         y = y - (row_height + pad)
493         LOD_PREVIOUS = Blender.Draw.Toggle("Previous Range", evcode["LOD_PREVIOUS"], x, y, input_width + label_width + pad, row_height, get_lockmask(previous_mask), "")
494
495 def gui():
496         #draw the propsheet/toolbox.
497         psheety = 800
498         #psheetx = psheety + 10
499         draw_propsheet(20,psheety)
500
501 Draw.Register(gui,event,but_event)
502