comparison SceneGraph/BlenderScript/export_xml3.py @ 660:e1856ef4fc74

export xml3 not yet worked.
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Fri, 27 Nov 2009 20:16:51 +0900
parents 30a72124c7fd
children
comparison
equal deleted inserted replaced
659:00391feebc79 660:e1856ef4fc74
19 import base64 19 import base64
20 #from Blender import NMesh, Scene, Object, Material, Texture, Window 20 #from Blender import NMesh, Scene, Object, Material, Texture, Window
21 #from Blender import sys as bsys, Mathutils, Draw, BGL 21 #from Blender import sys as bsys, Mathutils, Draw, BGL
22 #from Blender.sys import * 22 #from Blender.sys import *
23 23
24 global anim
25 anim = 0
26
27
24 global images, imageCount 28 global images, imageCount
25 images = {} 29 images = {}
26 imageCount = 0 30 imageCount = 0
27 31
28 def info(object, spacing=10, collapse=1): 32
29 """Print methods and doc strings. 33 __author__ = ["Shinji KONO"]
30 34 __url__ = ("www.ie.u-ryukyu.ac.jp/~kono/")
31 Takes module, class, list, dictionary, or string.""" 35 __version__ = "0.01a"
32 methodList = [e for e in dir(object) if callable(getattr(object, e))] 36 __bpydoc__ = """\
33 processFunc = collapse and (lambda s: " ".join(s.split())) or (lambda s: s) 37
34 print("\n".join(["{0:s} {1:s}".format((method.ljust(spacing), 38 Cerium XML converter
35 processFunc(str(getattr(object, method).__doc__)))) 39
36 for method in methodList])) 40 """
37 41
38 42
39 ###################################################### 43 ######################################################
40 # Data Structures 44 # Data Structures
41 ###################################################### 45 ######################################################
45 49
46 ###################################################### 50 ######################################################
47 # Functions 51 # Functions
48 ###################################################### 52 ######################################################
49 53
50 # Image Get ? 54
51 # New name based on old with a different extension 55 def create_derived_objects(ob):
52 def newFName(ext): 56 if ob.parent and ob.parent.dupli_type != 'NONE':
53 return Blender.Get('filename')[: -len(Blender.Get('filename').split('.', -1)[-1]) ] + ext 57 return False, None
58
59 if ob.dupli_type != 'NONE':
60 ob.create_dupli_list()
61 return True, [(dob.object, dob.matrix) for dob in ob.dupli_list]
62 else:
63 return False, [(ob, ob.matrix)]
64
65 # also used by X3D exporter
66 def free_derived_objects(ob):
67 ob.free_dupli_list()
54 68
55 69
56 #exporting an anime 70 #exporting an anime
57 ###change 71 ###change
58 #def export_anime(object_name): 72 #def export_anime(object_name):
77 matnames= [] 91 matnames= []
78 for obj in object_list1: 92 for obj in object_list1:
79 if obj.Layer in activelayers: 93 if obj.Layer in activelayers:
80 object_list.append(obj) 94 object_list.append(obj)
81 95
82 if obj.getType() == "Mesh": 96 if obj.type == 'Mesh':
83 materials_obj_list = [] 97 materials_obj_list = []
84 materials_obj_list = obj.getData().materials 98 materials_obj_list = obj.getData().materials
85 for mat in materials_obj_list: 99 for mat in materials_obj_list:
86 if mat.name not in matnames: 100 if mat.name not in matnames:
87 matnames.append(mat.name) 101 matnames.append(mat.name)
140 ###change 154 ###change
141 def getFaces(): 155 def getFaces():
142 ##change 156 ##change
143 #str = "" 157 #str = ""
144 file.write("") 158 file.write("")
145 matrix = obj.getMatrix() 159 # matrix = obj.matrix
160 # already calcurated?
161 matrix = [[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]]
146 162
147 for mindex in range(len(flist)): 163 for mindex in range(len(flist)):
148 fl = flist[mindex] 164 fl = flist[mindex]
149 if fl != []: 165 if fl != []:
150 parent_name = obj.getParent() 166 parent_name = obj.parent
151 if parent_name: 167 if parent_name:
152 parent_name = "{0:s}".format(parent_name) 168 parent_name = "{0:s}".format(parent_name)
153 ###change 169 ###change
154 #str += "\t<surface name=\"{0:s}\" size=\"{0:d}\" prim=\"Triangle\" parent={0:s}>\n".format((obj.name, len(fl)*3, parent_name[8:-1]) 170 #str += "\t<surface name=\"{0:s}\" size=\"{0:d}\" prim=\"Triangle\" parent={0:s}>\n".format((obj.name, len(fl)*3, parent_name[8:-1])
155 file.write("\t<surface name=\"{0:s}\" size=\"{1:d}\" prim=\"Triangle\" parent={2:s}>\n".format((obj.name, len(fl)*3, parent_name[8:-1]) )) 171 file.write("\t<surface name=\"{0:s}\" size=\"{1:d}\" prim=\"Triangle\" parent={2:s}>\n".format((obj.name, len(fl)*3, parent_name[8:-1]) ))
202 218
203 219
204 ### get texture_image and change base64 data 220 ### get texture_image and change base64 data
205 texture = mesh.faces[0].image 221 texture = mesh.faces[0].image
206 if texture: 222 if texture:
207 file.write(loadTexture(texture)) 223 file.write(loadTexture(texture.name))
208
209 else: 224 else:
210 file.write("\t\t<image name=\"{0:s}\">\n".format(("sample_white.png") )) 225 file.write("\t\t<image name=\"{0:s}\">\n".format(("sample_white.png") ))
211
212 file.write("\t\t\tiVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAAAAADhZOFXAAAAEElEQVQImWP8zwABTAwUMQBJQQEP\n");
213 file.write("\t\t\tlYH+agAAAABJRU5ErkJggg==\n");
214
215 file.write("\t\t</image>\n") 226 file.write("\t\t</image>\n")
216 227
217 #return str 228 #return str
218 229
219 vdata = [] 230 vdata = []
240 #str += getFaces() 251 #str += getFaces()
241 getFaces(); 252 getFaces();
242 253
243 #return str 254 #return str
244 255
256 def make_material_chunk(material, image):
257 if image:
258 file.write(loadTexture(image))
259 else:
260 file.write("\t\t<image name=\"{0:s}\">\n".format(("sample_white.png") ))
261 global sample_whited
262 if (sample_whited == 0):
263
264 file.write("\t\t\tiVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAAAAADhZOFXAAAAEElEQVQImWP8zwABTAwUMQBJQQEP\n");
265 file.write("\t\t\tlYH+agAAAABJRU5ErkJggg==\n");
266 sample_whited=1
267
268 file.write("\t\t</image>\n")
245 269
246 ###################################################### 270 ######################################################
247 # EXPORT 271 # EXPORT
248 ###################################################### 272 ######################################################
249 def save_xml(filename, unindexedname, anim): 273
250 print("XML EXPORT\n") 274
251 time1 = Blender.sys.time() 275 def save_xml(filename, context):
276 '''Save the Blender scene to a Cerium xml file.'''
277 # Time the export
278 global MatSaved
279 global anim
280 MatSaved = 0
281
282 if not filename.lower().endswith('.xml'):
283 filename += '.xml'
252 print("Saving to '" + filename + "'...\n") 284 print("Saving to '" + filename + "'...\n")
253 file = open(filename, 'w') 285 file = open(filename, 'w')
254 286
255 count_h = 0 287 # XXX
256 n = 0 288 # if not BPyMessages.Warning_SaveOver(filename):
257 filename_h = filename[:-4] + ".h" #header file for cpp 289 # return
258 file_h = open(filename_h, 'w') 290
291 # XXX
292 time1 = time.clock()
293 # time1= Blender.sys.time()
294 # Blender.Window.WaitCursor(1)
259 295
260 ##### XML header ###### 296 ##### XML header ######
261 file.write("<?xml version=\"1.0\"?>\n") 297 file.write("<?xml version=\"1.0\"?>\n")
262
263 #get all the objects in this scene
264 activelayers = Window.ViewLayer()
265 for i in range(len(activelayers)):
266 activelayers[i] = 2**(activelayers[i]-1)
267 object_list1 = Blender.Scene.GetCurrent().getChildren()
268 object_list = []
269 matnames= []
270 for obj in object_list1:
271 if obj.Layer in activelayers:
272 object_list.append(obj)
273
274 if obj.getType() == "Mesh":
275 materials_obj_list = []
276 materials_obj_list = obj.getData().materials
277 for mat in materials_obj_list:
278 if mat.name not in matnames:
279 matnames.append(mat.name)
280
281 ##### Process Meshes ######
282 meshlist = []
283 file.write("<OBJECT-3D>\n") 298 file.write("<OBJECT-3D>\n")
284 for obj in object_list: 299
285 if obj.getType() == "Mesh": 300 sce = context.scene
286 objectname = obj.getName() 301
287 mesh = Blender.NMesh.GetRawFromObject(objectname) 302 # Get all the supported objects selected in this scene:
288 meshname = mesh.name 303 # ob_sel= list(sce.objects.context)
289 meshlight = 0 304 # mesh_objects = [ (ob, me) for ob in ob_sel for me in (BPyMesh.getMeshFromObject(ob, None, True, False, sce),) if me ]
290 if len(mesh.materials) > 0: 305 # empty_objects = [ ob for ob in ob_sel if ob.type == 'Empty' ]
291 mat0 = mesh.materials[0] 306
292 if mat0.emit > 0: 307 # Make a list of all materials used in the selected meshes (use a dictionary,
293 meshlight = 1 308 # each material is added once):
294 if meshlight: 309 materialDict = {}
295 print("processing Object \"{0:s}\" as Meshlight (Mesh \"{1:s}\")...".format((objectname, meshname))) 310 mesh_objects = []
296 else: 311 for ob in [ob for ob in context.scene.objects if ob.is_visible()]:
297 print("processing Object \"{0:s}\" (Mesh \"{1:s}\")...".format((objectname, meshname))) 312 # for ob in sce.objects.context:
298 try: 313
299 meshlist.index(meshname) 314 # get derived objects
300 except ValueError: 315 free, derived = create_derived_objects(ob)
301 ###change 316
302 #file.write(exportMesh(mesh,obj)) 317 if derived == None: continue
303 exportMesh(mesh,obj,file) 318
304 meshlist.append(meshname) 319 for ob_derived, mat in derived:
305 if anim == 1: 320 # for ob_derived, mat in getDerivedObjects(ob, False):
306 #file.write("\t\t<anim>\n") 321
307 ###change 322 if ob.type not in ('MESH', 'CURVE', 'SURFACE', 'TEXT', 'META'):
308 #file.write(export_anime(obj)) 323 continue
309 export_anime(obj,file) 324
310 #file.write("\t\t</anim>\n") 325 data = ob_derived.create_mesh(True, 'PREVIEW')
311 file.write("\t</surface>\n") 326 # data = getMeshFromObject(ob_derived, None, True, False, sce)
312 file_h.write("#define {0:s} scene_graph".format((obj.name))) 327 if data:
313 while n != count_h: 328 data.transform(mat)
314 file_h.write("->next") 329 # data.transform(mat, recalc_normals=False)
315 n = n + 1 330 mesh_objects.append((ob_derived, data))
316 file_h.write("\n") 331 mat_ls = data.materials
317 count_h = count_h + 1 332 mat_ls_len = len(mat_ls)
318 n = 0 333
319 334 # get material/image tuples.
320 335 if len(data.uv_textures):
321 ##### XML FOOTER ###### 336 # if data.faceUV:
322 file.write("</OBJECT-3D>") 337 if not mat_ls:
338 mat = mat_name = None
339
340 for f, uf in zip(data.faces, data.active_uv_texture.data):
341 if mat_ls:
342 mat_index = f.material_index
343 # mat_index = f.mat
344 if mat_index >= mat_ls_len:
345 mat_index = f.mat = 0
346 mat = mat_ls[mat_index]
347 if mat: mat_name = mat.name
348 else: mat_name = None
349 # else there alredy set to none
350
351 img = uf.image
352 # img = f.image
353 if img: img_name = img.name
354 else: img_name = None
355
356 materialDict.setdefault((mat_name, img_name), (mat, img) )
357
358
359 else:
360 for mat in mat_ls:
361 if mat: # material may be None so check its not.
362 materialDict.setdefault((mat.name, None), (mat, None) )
363
364 # Why 0 Why!
365 for f in data.faces:
366 if f.material_index >= mat_ls_len:
367 # if f.mat >= mat_ls_len:
368 f.material_index = 0
369 # f.mat = 0
370
371 if free:
372 free_derived_objects(ob)
373
374
375 # Make material chunks for all materials used in the meshes:
376 for mat_and_image in materialDict.values():
377 print("make material chunk {0:s}\n".format(mat_and_image[1]))
378 make_material_chunk(mat_and_image[0], mat_and_image[1])
379
380 # Give all objects a unique ID and build a dictionary from object name to object id:
381 """
382 name_to_id = {}
383 for ob, data in mesh_objects:
384 name_to_id[ob.name]= len(name_to_id)
385 #for ob in empty_objects:
386 # name_to_id[ob.name]= len(name_to_id)
387 """
388
389 # Create object chunks for all meshes:
390 for ob, blender_mesh in mesh_objects:
391 print("export mesh {0:s}\n".format(ob.name))
392 exportMesh(blender_mesh,ob,file)
393 if (anim):
394 export_anime(obj,file)
395 file.write("\t</surface>\n")
396 # if not blender_mesh.users:
397 bpy.data.remove_mesh(blender_mesh)
398 # blender_mesh.verts = None
399
400 # Close the file:
323 file.close() 401 file.close()
324 file_h.close() 402
325 print("Finished.\n") 403
326
327 time2 = Blender.sys.time()
328 print("Processing time: {0:f}\n".format((time2-time1)))
329 Draw.Exit()
330
331
332 ### SAVE ANIMATION ###
333 def save_anim(filename):
334 global MatSaved
335
336 MatSaved = 0
337 unindexedname = filename
338 save_xml(filename, unindexedname, 1)
339
340
341 #### SAVE STILL (hackish...) ####
342 def save_still(filename):
343 global MatSaved
344
345 MatSaved = 0
346 unindexedname = filename
347 save_xml(filename, unindexedname, 0)
348
349 ######################################################
350 # Settings GUI
351 ######################################################
352
353 # Assign event numbers to buttons
354 evtNoEvt = 0
355 evtExport = 1
356 evtExportAnim = 2
357
358 # Set initial values of buttons
359
360 ## <size>800 600</size>
361
362 sceneSizeX = Scene.GetCurrent().getRenderingContext().imageSizeX()
363 sceneSizeY = Scene.GetCurrent().getRenderingContext().imageSizeY()
364
365 SizeX = Draw.Create(sceneSizeX)
366 SizeY = Draw.Create(sceneSizeY)
367 TexExponent = Draw.Create(2.3)
368
369 ## <metropolis>1</metropolis>
370 MLT = Draw.Create(1)
371
372 ## <large_mutation_prob>0.1</large_mutation_prob>
373 LMP = Draw.Create(0.1)
374
375 ## <max_change>0.02</max_change>
376 MaxChange = Draw.Create(0.02)
377
378 ## <russian_roulette_live_prob>0.7</russian_roulette_live_prob>
379 RRLP = Draw.Create(0.7)
380
381 ## <max_depth>100</max_depth>
382 MaxDepth = Draw.Create(100)
383
384 ## <bidirectional>false</bidirectional>
385 Bidirectional = Draw.Create(0)
386
387 ## <strata_width>14</strata_width>
388 StrataWidth = Draw.Create(14)
389
390 ## <logging>0</logging>
391 Logging = Draw.Create(0)
392
393 ## <save_untonemapped_exr>false</save_untonemapped_exr>
394 SaveUTMExr = Draw.Create(0)
395
396 ## <save_tonemapped_exr>false</save_tonemapped_exr>
397 SaveTMExr = Draw.Create(0)
398
399 ## <lens_radius>0.0</lens_radius>
400 LensRadius = Draw.Create(0.0)
401
402 ## <focus_distance>2.0</focus_distance>
403 FocusDistance = Draw.Create(2.0)
404
405 ## <turbidity>2.0</turbidity>
406 Turbidity = Draw.Create(2.0)
407
408 GroundPlane = Draw.Create(1)
409
410 ## Separate materials
411 MatFile = Draw.Create(1)
412
413 # text color fix
414 textcol = [0, 0, 0]
415
416
417 def gui():
418 global evtNoEvt, evtExport, evtExportAnim
419 global SizeX, SizeY, TexExponent, MLT, LMP, MaxChange, RRLP, MaxDepth, Bidirectional, StrataWidth, Logging, SaveUTMExr, SaveTMExr, LensRadius, FocusDistance,Turbidity, GroundPlane, MatFile
420 global textcol
421
422 Draw.Button("Export", evtExport, 10, 25, 100, 18, "Open file dialog and export")
423 Draw.Button("Export Animation", evtExportAnim, 130, 25, 150, 18, "Open filedialog and export animation (careful: takes a lot of diskspace!!!)")
424 BGL.glColor3f(textcol[0], textcol[1], textcol[2]) ; BGL.glRasterPos2i(10,10) ; Draw.Text("Press Q or ESC to quit.", "tiny")
425
426 BGL.glRasterPos2i(10,60) ; Draw.Text("xml exporter for libps3")
427
428
429 def event(evt, val): # function that handles keyboard and mouse events
430 if evt == Draw.ESCKEY or evt == Draw.QKEY:
431 stop = Draw.PupMenu("OK?%t|Cancel export %x1")
432 if stop == 1:
433 Draw.Exit()
434 return
435
436 def buttonEvt(evt): # function that handles button events
437 if evt == evtExport:
438 Blender.Window.FileSelector(save_still, "Export", newFName('xml'))
439 if evt == evtExportAnim:
440 Blender.Window.FileSelector(save_anim, "Export Animation", newFName('xml'))
441 #if there was an event, redraw the window
442 if evt:
443 Draw.Redraw()
444 404
445 405
446 def loadTexture(texture): 406 def loadTexture(texture):
447 global images, imageCount 407 global images, imageCount
448 name = texture.getName() 408 name = texture.name
449 if name in images: 409 if name in images:
450 return "\t\t<image name=\"" + name + "\"/>\n" 410 return "\t\t<image name=\"" + name + "\"/>\n"
451 out = "\t\t<image name=\"" + name + "\">\n" 411 out = "\t\t<image name=\"" + name + "\">\n"
452 imageCount += 1 412 imageCount += 1
453 images[name] = imageCount 413 images[name] = imageCount
463 input.close() 423 input.close()
464 os.remove('output.txt') 424 os.remove('output.txt')
465 out += "\t\t</image>\n" 425 out += "\t\t</image>\n"
466 return out 426 return out
467 427
468 Draw.Register(gui, event, buttonEvt) 428
469 429 from bpy.props import *
470 430 class ExportPS3(bpy.types.Operator):
431 '''Export to Cerium XML file format.'''
432 bl_idname = "export.ps3cerium"
433 bl_label = 'Export PS3 Cerium'
434
435 # List of operator properties, the attributes will be assigned
436 # to the class instance from the operator settings before calling.
437
438
439 path = StringProperty(name="File Path", description="File path used for exporting the Cerium XML file", maxlen= 1024, default= "")
440
441
442 def execute(self, context):
443 save_xml(self.properties.path, context)
444 return ('FINISHED',)
445
446 def invoke(self, context, event):
447 wm = context.manager
448 wm.add_fileselect(self)
449 return ('RUNNING_MODAL',)
450
451 def poll(self, context): # Poll isnt working yet
452 return context.active_object != None
453
454 bpy.ops.add(ExportPS3)
455
456 # Add to a menu
457 import dynamic_menu
458
459 def menu_func(self, context):
460 default_path = bpy.data.filename.replace(".blend", ".xml")
461 self.layout.operator(ExportPS3.bl_idname, text="PS3 Cerium...").path = default_path
462
463 menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func)
464
465 # end