comparison SceneGraph/BlenderScript/export_xml3.py @ 658:30a72124c7fd

export_xml3 for Blender 2.5 ( not yet worked )
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Fri, 27 Nov 2009 18:22:20 +0900
parents
children e1856ef4fc74
comparison
equal deleted inserted replaced
655:0eed1fa290c1 658:30a72124c7fd
1 #!BPY
2 """Registration info for Blender menus:
3 Name: 'Libps3 (.xml)'
4 Blender: 240
5 Group: 'Export'
6 Tooltip: 'Export to (.xml) for libps3'
7 """
8
9
10 ######################################################
11 # Importing modules
12 ######################################################
13
14 import math
15 #import subprocess
16 import os
17 #import Blender
18 import struct
19 import base64
20 #from Blender import NMesh, Scene, Object, Material, Texture, Window
21 #from Blender import sys as bsys, Mathutils, Draw, BGL
22 #from Blender.sys import *
23
24 global images, imageCount
25 images = {}
26 imageCount = 0
27
28 def info(object, spacing=10, collapse=1):
29 """Print methods and doc strings.
30
31 Takes module, class, list, dictionary, or string."""
32 methodList = [e for e in dir(object) if callable(getattr(object, e))]
33 processFunc = collapse and (lambda s: " ".join(s.split())) or (lambda s: s)
34 print("\n".join(["{0:s} {1:s}".format((method.ljust(spacing),
35 processFunc(str(getattr(object, method).__doc__))))
36 for method in methodList]))
37
38
39 ######################################################
40 # Data Structures
41 ######################################################
42
43
44
45
46 ######################################################
47 # Functions
48 ######################################################
49
50 # Image Get ?
51 # New name based on old with a different extension
52 def newFName(ext):
53 return Blender.Get('filename')[: -len(Blender.Get('filename').split('.', -1)[-1]) ] + ext
54
55
56 #exporting an anime
57 ###change
58 #def export_anime(object_name):
59 def export_anime(object_name,file):
60 startF = Blender.Get('staframe')
61 endF = Blender.Get('endframe')
62 #str = ""
63 file.write("")
64 file.write("\t\t<anim frame=\"{0:d}\">\n".format((endF) ))
65 for i in range (startF, endF+1):
66 Blender.Set('curframe', i)
67 Blender.Redraw()
68 time1 = Blender.sys.time()
69
70 ##### XML header ######
71 #get all the objects in this scene
72 activelayers = Window.ViewLayer()
73 for i in range(len(activelayers)):
74 activelayers[i] = 2**(activelayers[i]-1)
75 object_list1 = Blender.Scene.GetCurrent().getChildren()
76 object_list = []
77 matnames= []
78 for obj in object_list1:
79 if obj.Layer in activelayers:
80 object_list.append(obj)
81
82 if obj.getType() == "Mesh":
83 materials_obj_list = []
84 materials_obj_list = obj.getData().materials
85 for mat in materials_obj_list:
86 if mat.name not in matnames:
87 matnames.append(mat.name)
88
89 ##### Process Meshes ######
90 for obj in object_list:
91 matrix = obj.getMatrix()
92 if obj == object_name:
93 file.write("\t\t\t{0:f} {1:f} {2:f}\n".format((matrix[3][0], matrix[3][1], matrix[3][2]) ))
94
95 file.write("\t\t</anim>\n")
96 #return str
97
98
99
100 # exporting a mesh
101 ##change
102 #def exportMesh(mesh, obj):
103 def exportMesh(mesh, obj, file):
104
105 vdata = [] # list of [ii0, ii1, ii2, ...] lists indexed by Blender-Vertex-index
106 vlist = []
107 flist = []
108 tri_first = []
109 tri_second = []
110 tri_third = []
111
112 def addVertex(bvindex, coord, normal, uv):
113 index = -1
114 if bvindex < len(vdata):
115 for ivindex in vdata[bvindex]:
116 v = vlist[ivindex]
117 if (abs(v[0][0]-coord[0])<0.0001) and \
118 (abs(v[0][1]-coord[1])<0.0001) and \
119 (abs(v[0][2]-coord[2])<0.0001) and \
120 (abs(v[1][0]-normal[0])<0.0001) and \
121 (abs(v[1][1]-normal[1])<0.0001) and \
122 (abs(v[1][2]-normal[2])<0.0001):
123 if ((v[2]==[]) and (uv==[])) or \
124 ((abs(v[2][0]-uv[0])<0.0001) and \
125 (abs(v[2][1]-uv[1])<0.0001)):
126 index = ivindex
127 if index < 0:
128 index = len(vlist)
129 vlist.append([coord, normal, uv])
130 while bvindex >= len(vdata):
131 vdata.append([])
132 vdata[bvindex].append(index)
133 return index
134
135 def addFace(mindex, index0, index1, index2):
136 while mindex >= len(flist):
137 flist.append([])
138 flist[mindex].append([index0, index1, index2])
139
140 ###change
141 def getFaces():
142 ##change
143 #str = ""
144 file.write("")
145 matrix = obj.getMatrix()
146
147 for mindex in range(len(flist)):
148 fl = flist[mindex]
149 if fl != []:
150 parent_name = obj.getParent()
151 if parent_name:
152 parent_name = "{0:s}".format(parent_name)
153 ###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])
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]) ))
156 else:
157 ###change
158 #str += "\t<surface name=\"{0:s}\" size=\"{0:d}\" prim=\"Triangle\" parent=\"NULL\">\n".format((obj.name, len(fl)*3)
159 file.write("\t<surface name=\"{0:s}\" size=\"{1:d}\" prim=\"Triangle\" parent=\"NULL\">\n".format((obj.name, len(fl)*3) ))
160 ###change
161 #str += "\t\t<coordinate>\n"
162 file.write("\t\t<coordinate>\n")
163 for f in fl:
164 tri_first = vlist[f[0]]
165 tri_second = vlist[f[1]]
166 tri_third = vlist[f[2]]
167
168 file.write("\t\t\t{0:f} {1:f} {2:f}\n".format((tri_first[0][0] + matrix[3][0], tri_first[0][1] + matrix[3][1], tri_first[0][2] + matrix[3][2]) ))
169 file.write("\t\t\t{0:f} {1:f} {2:f}\n".format((tri_second[0][0] + matrix[3][0], tri_second[0][1] + matrix[3][1], tri_second[0][2] + matrix[3][2]) ))
170 file.write("\t\t\t{0:f} {1:f} {2:f}\n".format((tri_third[0][0] + matrix[3][0], tri_third[0][1] + matrix[3][1], tri_third[0][2] + matrix[3][2]) ))
171 file.write("\t\t</coordinate>\n")
172
173 file.write("\t\t<normal>\n")
174 for f in fl:
175 tri_first = vlist[f[0]]
176 tri_second = vlist[f[1]]
177 tri_third = vlist[f[2]]
178
179 file.write("\t\t\t{0:f} {1:f} {2:f}\n".format((tri_first[1][0], tri_first[1][1], tri_first[1][2]) ))
180 file.write("\t\t\t{0:f} {1:f} {2:f}\n".format((tri_second[1][0], tri_second[1][1], tri_second[1][2]) ))
181 file.write("\t\t\t{0:f} {1:f} {2:f}\n".format((tri_third[1][0], tri_third[1][1], tri_third[1][2]) ))
182 file.write("\t\t</normal>\n" )
183
184 file.write("\t\t<model>\n" )
185 ###parameter of translate
186 file.write("\t\t\t{0:f} {1:f} {2:f}\n".format( (matrix[3][0], matrix[3][1], matrix[3][2]) ))
187 file.write("\t\t</model>\n")
188
189 if tri_first[2] != []:
190 file.write("\t\t<texture>\n")
191 for f in fl:
192 tri_first = vlist[f[0]]
193 tri_second = vlist[f[1]]
194 tri_third = vlist[f[2]]
195
196 file.write("\t\t\t{0:f} {1:f}\n".format((tri_first[2][0], tri_first[2][1]) ))
197 file.write("\t\t\t{0:f} {1:f}\n".format((tri_second[2][0], tri_second[2][1]) ))
198 file.write("\t\t\t{0:f} {0:f}\n".format((tri_third[2][0], tri_third[2][1]) ))
199 file.write("\t\t</texture>\n")
200 else:
201 file.write("\t\t<texture/>\n")
202
203
204 ### get texture_image and change base64 data
205 texture = mesh.faces[0].image
206 if texture:
207 file.write(loadTexture(texture))
208
209 else:
210 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")
216
217 #return str
218
219 vdata = []
220 vlist = []
221 flist = []
222 for face in mesh.faces:
223 iis = [-1, -1, -1, -1]
224 for vi in range(len(face.v)):
225 vert = face.v[vi]
226 if face.smooth:
227 normal = vert.no
228 else:
229 normal = face.no
230 if len(face.uv) == len(face.v):
231 uv = face.uv[vi]
232 else:
233 uv = []
234 iis[vi] = addVertex(vert.index, vert.co, normal, uv)
235 addFace(face.materialIndex, iis[0], iis[1], iis[2])
236 if len(face.v)==4:
237 addFace(face.materialIndex, iis[2], iis[3], iis[0])
238
239 #str = ""
240 #str += getFaces()
241 getFaces();
242
243 #return str
244
245
246 ######################################################
247 # EXPORT
248 ######################################################
249 def save_xml(filename, unindexedname, anim):
250 print("XML EXPORT\n")
251 time1 = Blender.sys.time()
252 print("Saving to '" + filename + "'...\n")
253 file = open(filename, 'w')
254
255 count_h = 0
256 n = 0
257 filename_h = filename[:-4] + ".h" #header file for cpp
258 file_h = open(filename_h, 'w')
259
260 ##### XML header ######
261 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")
284 for obj in object_list:
285 if obj.getType() == "Mesh":
286 objectname = obj.getName()
287 mesh = Blender.NMesh.GetRawFromObject(objectname)
288 meshname = mesh.name
289 meshlight = 0
290 if len(mesh.materials) > 0:
291 mat0 = mesh.materials[0]
292 if mat0.emit > 0:
293 meshlight = 1
294 if meshlight:
295 print("processing Object \"{0:s}\" as Meshlight (Mesh \"{1:s}\")...".format((objectname, meshname)))
296 else:
297 print("processing Object \"{0:s}\" (Mesh \"{1:s}\")...".format((objectname, meshname)))
298 try:
299 meshlist.index(meshname)
300 except ValueError:
301 ###change
302 #file.write(exportMesh(mesh,obj))
303 exportMesh(mesh,obj,file)
304 meshlist.append(meshname)
305 if anim == 1:
306 #file.write("\t\t<anim>\n")
307 ###change
308 #file.write(export_anime(obj))
309 export_anime(obj,file)
310 #file.write("\t\t</anim>\n")
311 file.write("\t</surface>\n")
312 file_h.write("#define {0:s} scene_graph".format((obj.name)))
313 while n != count_h:
314 file_h.write("->next")
315 n = n + 1
316 file_h.write("\n")
317 count_h = count_h + 1
318 n = 0
319
320
321 ##### XML FOOTER ######
322 file.write("</OBJECT-3D>")
323 file.close()
324 file_h.close()
325 print("Finished.\n")
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
445
446 def loadTexture(texture):
447 global images, imageCount
448 name = texture.getName()
449 if name in images:
450 return "\t\t<image name=\"" + name + "\"/>\n"
451 out = "\t\t<image name=\"" + name + "\">\n"
452 imageCount += 1
453 images[name] = imageCount
454 image_path = texture.getFilename()
455 input = open(expandpath(image_path), 'r')
456 output = open('output.txt', 'w')
457 base64.encode(input,output)
458 input.close()
459 output.close()
460 input = open('output.txt', 'r')
461 for b64 in input.readlines():
462 out += "\t\t\t{0:s}".format(b64)
463 input.close()
464 os.remove('output.txt')
465 out += "\t\t</image>\n"
466 return out
467
468 Draw.Register(gui, event, buttonEvt)
469
470