Mercurial > hg > Game > Cerium
annotate SceneGraph/BlenderScript/export_xml.py @ 1888:5238ca826d6e draft
clean up DMA
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 03 Jan 2014 18:59:15 +0900 |
parents | 2403d545abd8 |
children |
rev | line source |
---|---|
107 | 1 #!BPY |
2 """Registration info for Blender menus: | |
1035 | 3 Name: 'Libps+x (.xml)' |
107 | 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 | |
345 | 24 global images, imageCount |
25 images = {} | |
26 imageCount = 0 | |
107 | 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) | |
655
2eeb5f267264
export_xml3 for Blender 2.5 ( not yet worked )
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
345
diff
changeset
|
34 # print "\n".join(["%s %s" % |
2eeb5f267264
export_xml3 for Blender 2.5 ( not yet worked )
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
345
diff
changeset
|
35 # (method.ljust(spacing), |
2eeb5f267264
export_xml3 for Blender 2.5 ( not yet worked )
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
345
diff
changeset
|
36 # processFunc(str(getattr(object, method).__doc__))) |
2eeb5f267264
export_xml3 for Blender 2.5 ( not yet worked )
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
345
diff
changeset
|
37 # for method in methodList]) |
107 | 38 |
39 | |
40 ###################################################### | |
41 # Data Structures | |
42 ###################################################### | |
43 | |
44 | |
45 | |
46 | |
47 ###################################################### | |
48 # Functions | |
49 ###################################################### | |
50 | |
345 | 51 # Image Get ? |
107 | 52 # New name based on old with a different extension |
53 def newFName(ext): | |
54 return Blender.Get('filename')[: -len(Blender.Get('filename').split('.', -1)[-1]) ] + ext | |
55 | |
56 | |
57 #exporting an anime | |
109 | 58 ###change |
59 #def export_anime(object_name): | |
60 def export_anime(object_name,file): | |
107 | 61 startF = Blender.Get('staframe') |
655
2eeb5f267264
export_xml3 for Blender 2.5 ( not yet worked )
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
345
diff
changeset
|
62 endF = Blender.Get('endframe') |
109 | 63 #str = "" |
64 file.write("") | |
65 file.write("\t\t<anim frame=\"%d\">\n" %(endF) ) | |
107 | 66 for i in range (startF, endF+1): |
67 Blender.Set('curframe', i) | |
68 Blender.Redraw() | |
69 time1 = Blender.sys.time() | |
70 | |
655
2eeb5f267264
export_xml3 for Blender 2.5 ( not yet worked )
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
345
diff
changeset
|
71 ##### XML header ###### |
2eeb5f267264
export_xml3 for Blender 2.5 ( not yet worked )
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
345
diff
changeset
|
72 #get all the objects in this scene |
107 | 73 activelayers = Window.ViewLayer() |
74 for i in range(len(activelayers)): | |
75 activelayers[i] = 2**(activelayers[i]-1) | |
76 object_list1 = Blender.Scene.GetCurrent().getChildren() | |
77 object_list = [] | |
78 matnames= [] | |
79 for obj in object_list1: | |
80 if obj.Layer in activelayers: | |
81 object_list.append(obj) | |
82 | |
83 if obj.getType() == "Mesh": | |
84 materials_obj_list = [] | |
85 materials_obj_list = obj.getData().materials | |
86 for mat in materials_obj_list: | |
87 if mat.name not in matnames: | |
88 matnames.append(mat.name) | |
89 | |
90 ##### Process Meshes ###### | |
91 for obj in object_list: | |
92 matrix = obj.getMatrix() | |
93 if obj == object_name: | |
109 | 94 file.write("\t\t\t%f %f %f\n" %(matrix[3][0], matrix[3][1], matrix[3][2]) ) |
107 | 95 |
109 | 96 file.write("\t\t</anim>\n") |
655
2eeb5f267264
export_xml3 for Blender 2.5 ( not yet worked )
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
345
diff
changeset
|
97 #return str |
107 | 98 |
99 | |
100 | |
101 # exporting a mesh | |
109 | 102 ##change |
103 #def exportMesh(mesh, obj): | |
104 def exportMesh(mesh, obj, file): | |
105 | |
107 | 106 vdata = [] # list of [ii0, ii1, ii2, ...] lists indexed by Blender-Vertex-index |
107 vlist = [] | |
108 flist = [] | |
109 tri_first = [] | |
110 tri_second = [] | |
111 tri_third = [] | |
112 | |
113 def addVertex(bvindex, coord, normal, uv): | |
114 index = -1 | |
115 if bvindex < len(vdata): | |
116 for ivindex in vdata[bvindex]: | |
117 v = vlist[ivindex] | |
118 if (abs(v[0][0]-coord[0])<0.0001) and \ | |
119 (abs(v[0][1]-coord[1])<0.0001) and \ | |
120 (abs(v[0][2]-coord[2])<0.0001) and \ | |
121 (abs(v[1][0]-normal[0])<0.0001) and \ | |
122 (abs(v[1][1]-normal[1])<0.0001) and \ | |
123 (abs(v[1][2]-normal[2])<0.0001): | |
124 if ((v[2]==[]) and (uv==[])) or \ | |
125 ((abs(v[2][0]-uv[0])<0.0001) and \ | |
126 (abs(v[2][1]-uv[1])<0.0001)): | |
127 index = ivindex | |
128 if index < 0: | |
129 index = len(vlist) | |
130 vlist.append([coord, normal, uv]) | |
131 while bvindex >= len(vdata): | |
132 vdata.append([]) | |
133 vdata[bvindex].append(index) | |
134 return index | |
135 | |
136 def addFace(mindex, index0, index1, index2): | |
137 while mindex >= len(flist): | |
138 flist.append([]) | |
139 flist[mindex].append([index0, index1, index2]) | |
140 | |
109 | 141 ###change |
107 | 142 def getFaces(): |
109 | 143 ##change |
144 #str = "" | |
145 file.write("") | |
107 | 146 matrix = obj.getMatrix() |
1035 | 147 big = 6 |
107 | 148 for mindex in range(len(flist)): |
149 fl = flist[mindex] | |
150 if fl != []: | |
151 parent_name = obj.getParent() | |
152 if parent_name: | |
153 parent_name = "%s" %parent_name | |
109 | 154 ###change |
155 #str += "\t<surface name=\"%s\" size=\"%d\" prim=\"Triangle\" parent=%s>\n" %(obj.name, len(fl)*3, parent_name[8:-1]) | |
156 file.write("\t<surface name=\"%s\" size=\"%d\" prim=\"Triangle\" parent=%s>\n" %(obj.name, len(fl)*3, parent_name[8:-1]) ) | |
107 | 157 else: |
109 | 158 ###change |
159 #str += "\t<surface name=\"%s\" size=\"%d\" prim=\"Triangle\" parent=\"NULL\">\n" %(obj.name, len(fl)*3) | |
160 file.write("\t<surface name=\"%s\" size=\"%d\" prim=\"Triangle\" parent=\"NULL\">\n" %(obj.name, len(fl)*3) ) | |
161 ###change | |
162 #str += "\t\t<coordinate>\n" | |
163 file.write("\t\t<coordinate>\n") | |
107 | 164 for f in fl: |
165 tri_first = vlist[f[0]] | |
166 tri_second = vlist[f[1]] | |
167 tri_third = vlist[f[2]] | |
168 | |
1035 | 169 file.write("\t\t\t%f %f %f\n" %(big*(tri_first[0][0] + matrix[3][0]), big*(tri_first[0][1] + matrix[3][1]), big*(tri_first[0][2] + matrix[3][2])) ) |
170 file.write("\t\t\t%f %f %f\n" %(big*(tri_second[0][0] + matrix[3][0]), big*(tri_second[0][1] + matrix[3][1]), big*(tri_second[0][2] + matrix[3][2])) ) | |
171 file.write("\t\t\t%f %f %f\n" %(big*(tri_third[0][0] + matrix[3][0]), big*(tri_third[0][1] + matrix[3][1]), big*(tri_third[0][2] + matrix[3][2])) ) | |
109 | 172 file.write("\t\t</coordinate>\n") |
107 | 173 |
109 | 174 file.write("\t\t<normal>\n") |
107 | 175 for f in fl: |
176 tri_first = vlist[f[0]] | |
177 tri_second = vlist[f[1]] | |
178 tri_third = vlist[f[2]] | |
179 | |
1035 | 180 file.write("\t\t\t%f %f %f\n" %(big*(tri_first[1][0]), big*(tri_first[1][1]), big*(tri_first[1][2])) ) |
181 file.write("\t\t\t%f %f %f\n" %(big*(tri_second[1][0]), big*(tri_second[1][1]), big*(tri_second[1][2])) ) | |
182 file.write("\t\t\t%f %f %f\n" %(big*(tri_third[1][0]), big*(tri_third[1][1]), big*(tri_third[1][2])) ) | |
109 | 183 file.write("\t\t</normal>\n" ) |
107 | 184 |
109 | 185 file.write("\t\t<model>\n" ) |
107 | 186 ###parameter of translate |
109 | 187 file.write("\t\t\t%f %f %f\n" % (matrix[3][0], matrix[3][1], matrix[3][2]) ) |
188 file.write("\t\t</model>\n") | |
107 | 189 |
190 if tri_first[2] != []: | |
109 | 191 file.write("\t\t<texture>\n") |
107 | 192 for f in fl: |
193 tri_first = vlist[f[0]] | |
194 tri_second = vlist[f[1]] | |
195 tri_third = vlist[f[2]] | |
1035 | 196 file.write("\t\t\t%f %f\n" %(tri_first[2][0], (-1*(tri_first[2][1])+1 ))) |
197 file.write("\t\t\t%f %f\n" %(tri_second[2][0], (-1*(tri_second[2][1])+1 ))) | |
198 file.write("\t\t\t%f %f\n" %(tri_third[2][0], (-1*(tri_third[2][1])+1 ))) | |
109 | 199 file.write("\t\t</texture>\n") |
107 | 200 else: |
1035 | 201 file.write("\t\t<texture>\n") |
202 for f in fl: | |
203 file.write("\t\t\t0.000000 0.000000\n") | |
204 file.write("\t\t\t0.000000 0.000000\n") | |
205 file.write("\t\t\t0.000000 0.000000\n") | |
206 file.write("\t\t</texture>\n") | |
107 | 207 ### get texture_image and change base64 data |
208 texture = mesh.faces[0].image | |
209 if texture: | |
1035 | 210 file.write(loadTexture(texture)) |
345 | 211 else: |
1035 | 212 file.write("\t\t<image name=\"%s\">\n" %("dummy.png") ) |
213 file.write("\t\t\tiVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAGUlEQVQokWP8/fs3AymAiSTVoxpG\n"); | |
214 file.write("\t\t\tNQwpDQAwxQMRlevqcQAAAABJRU5ErkJggg==\n"); | |
109 | 215 file.write("\t\t</image>\n") |
216 #return str | |
107 | 217 |
218 vdata = [] | |
219 vlist = [] | |
220 flist = [] | |
221 for face in mesh.faces: | |
222 iis = [-1, -1, -1, -1] | |
223 for vi in range(len(face.v)): | |
224 vert = face.v[vi] | |
225 if face.smooth: | |
226 normal = vert.no | |
227 else: | |
228 normal = face.no | |
229 if len(face.uv) == len(face.v): | |
230 uv = face.uv[vi] | |
231 else: | |
232 uv = [] | |
233 iis[vi] = addVertex(vert.index, vert.co, normal, uv) | |
234 addFace(face.materialIndex, iis[0], iis[1], iis[2]) | |
235 if len(face.v)==4: | |
236 addFace(face.materialIndex, iis[2], iis[3], iis[0]) | |
237 | |
109 | 238 #str = "" |
239 #str += getFaces() | |
240 getFaces(); | |
107 | 241 |
109 | 242 #return str |
107 | 243 |
244 | |
245 ###################################################### | |
246 # EXPORT | |
247 ###################################################### | |
248 def save_xml(filename, unindexedname, anim): | |
249 print("XML EXPORT\n") | |
250 time1 = Blender.sys.time() | |
251 print("Saving to '" + filename + "'...\n") | |
252 file = open(filename, 'w') | |
253 | |
254 count_h = 0 | |
255 n = 0 | |
256 filename_h = filename[:-4] + ".h" #header file for cpp | |
257 file_h = open(filename_h, 'w') | |
258 | |
259 ##### XML header ###### | |
260 file.write("<?xml version=\"1.0\"?>\n") | |
261 | |
262 #get all the objects in this scene | |
263 activelayers = Window.ViewLayer() | |
264 for i in range(len(activelayers)): | |
265 activelayers[i] = 2**(activelayers[i]-1) | |
266 object_list1 = Blender.Scene.GetCurrent().getChildren() | |
267 object_list = [] | |
268 matnames= [] | |
269 for obj in object_list1: | |
270 if obj.Layer in activelayers: | |
271 object_list.append(obj) | |
272 | |
273 if obj.getType() == "Mesh": | |
274 materials_obj_list = [] | |
275 materials_obj_list = obj.getData().materials | |
276 for mat in materials_obj_list: | |
277 if mat.name not in matnames: | |
278 matnames.append(mat.name) | |
279 | |
280 ##### Process Meshes ###### | |
281 meshlist = [] | |
282 file.write("<OBJECT-3D>\n") | |
283 for obj in object_list: | |
284 if obj.getType() == "Mesh": | |
285 objectname = obj.getName() | |
286 mesh = Blender.NMesh.GetRawFromObject(objectname) | |
287 meshname = mesh.name | |
288 meshlight = 0 | |
289 if len(mesh.materials) > 0: | |
290 mat0 = mesh.materials[0] | |
291 if mat0.emit > 0: | |
292 meshlight = 1 | |
293 if meshlight: | |
294 print "processing Object \"%s\" as Meshlight (Mesh \"%s\")..." %(objectname, meshname) | |
295 else: | |
296 print "processing Object \"%s\" (Mesh \"%s\")..." %(objectname, meshname) | |
297 try: | |
298 meshlist.index(meshname) | |
299 except ValueError: | |
109 | 300 ###change |
301 #file.write(exportMesh(mesh,obj)) | |
302 exportMesh(mesh,obj,file) | |
107 | 303 meshlist.append(meshname) |
304 if anim == 1: | |
305 #file.write("\t\t<anim>\n") | |
109 | 306 ###change |
307 #file.write(export_anime(obj)) | |
308 export_anime(obj,file) | |
107 | 309 #file.write("\t\t</anim>\n") |
310 file.write("\t</surface>\n") | |
311 file_h.write("#define %s scene_graph" %(obj.name)) | |
312 while n != count_h: | |
313 file_h.write("->next") | |
314 n = n + 1 | |
315 file_h.write("\n") | |
316 count_h = count_h + 1 | |
317 n = 0 | |
318 | |
319 | |
320 ##### XML FOOTER ###### | |
321 file.write("</OBJECT-3D>") | |
322 file.close() | |
323 file_h.close() | |
324 print("Finished.\n") | |
325 | |
326 time2 = Blender.sys.time() | |
327 print("Processing time: %f\n" %(time2-time1)) | |
328 Draw.Exit() | |
329 | |
330 | |
331 ### SAVE ANIMATION ### | |
332 def save_anim(filename): | |
333 global MatSaved | |
334 | |
335 MatSaved = 0 | |
336 unindexedname = filename | |
337 save_xml(filename, unindexedname, 1) | |
338 | |
339 | |
340 #### SAVE STILL (hackish...) #### | |
341 def save_still(filename): | |
342 global MatSaved | |
343 | |
344 MatSaved = 0 | |
345 unindexedname = filename | |
346 save_xml(filename, unindexedname, 0) | |
347 | |
348 ###################################################### | |
349 # Settings GUI | |
350 ###################################################### | |
351 | |
352 # Assign event numbers to buttons | |
353 evtNoEvt = 0 | |
354 evtExport = 1 | |
355 evtExportAnim = 2 | |
356 | |
357 # Set initial values of buttons | |
358 | |
359 ## <size>800 600</size> | |
360 | |
361 sceneSizeX = Scene.GetCurrent().getRenderingContext().imageSizeX() | |
362 sceneSizeY = Scene.GetCurrent().getRenderingContext().imageSizeY() | |
363 | |
364 SizeX = Draw.Create(sceneSizeX) | |
365 SizeY = Draw.Create(sceneSizeY) | |
366 TexExponent = Draw.Create(2.3) | |
367 | |
368 ## <metropolis>1</metropolis> | |
369 MLT = Draw.Create(1) | |
370 | |
371 ## <large_mutation_prob>0.1</large_mutation_prob> | |
372 LMP = Draw.Create(0.1) | |
373 | |
374 ## <max_change>0.02</max_change> | |
375 MaxChange = Draw.Create(0.02) | |
376 | |
377 ## <russian_roulette_live_prob>0.7</russian_roulette_live_prob> | |
378 RRLP = Draw.Create(0.7) | |
379 | |
380 ## <max_depth>100</max_depth> | |
381 MaxDepth = Draw.Create(100) | |
382 | |
383 ## <bidirectional>false</bidirectional> | |
384 Bidirectional = Draw.Create(0) | |
385 | |
386 ## <strata_width>14</strata_width> | |
387 StrataWidth = Draw.Create(14) | |
388 | |
389 ## <logging>0</logging> | |
390 Logging = Draw.Create(0) | |
391 | |
392 ## <save_untonemapped_exr>false</save_untonemapped_exr> | |
393 SaveUTMExr = Draw.Create(0) | |
394 | |
395 ## <save_tonemapped_exr>false</save_tonemapped_exr> | |
396 SaveTMExr = Draw.Create(0) | |
397 | |
398 ## <lens_radius>0.0</lens_radius> | |
399 LensRadius = Draw.Create(0.0) | |
400 | |
401 ## <focus_distance>2.0</focus_distance> | |
402 FocusDistance = Draw.Create(2.0) | |
403 | |
404 ## <turbidity>2.0</turbidity> | |
405 Turbidity = Draw.Create(2.0) | |
406 | |
407 GroundPlane = Draw.Create(1) | |
408 | |
409 ## Separate materials | |
410 MatFile = Draw.Create(1) | |
411 | |
412 # text color fix | |
413 textcol = [0, 0, 0] | |
414 | |
415 | |
416 def gui(): | |
417 global evtNoEvt, evtExport, evtExportAnim | |
418 global SizeX, SizeY, TexExponent, MLT, LMP, MaxChange, RRLP, MaxDepth, Bidirectional, StrataWidth, Logging, SaveUTMExr, SaveTMExr, LensRadius, FocusDistance,Turbidity, GroundPlane, MatFile | |
419 global textcol | |
420 | |
421 Draw.Button("Export", evtExport, 10, 25, 100, 18, "Open file dialog and export") | |
422 Draw.Button("Export Animation", evtExportAnim, 130, 25, 150, 18, "Open filedialog and export animation (careful: takes a lot of diskspace!!!)") | |
423 BGL.glColor3f(textcol[0], textcol[1], textcol[2]) ; BGL.glRasterPos2i(10,10) ; Draw.Text("Press Q or ESC to quit.", "tiny") | |
424 | |
425 BGL.glRasterPos2i(10,60) ; Draw.Text("xml exporter for libps3") | |
426 | |
427 | |
428 def event(evt, val): # function that handles keyboard and mouse events | |
429 if evt == Draw.ESCKEY or evt == Draw.QKEY: | |
655
2eeb5f267264
export_xml3 for Blender 2.5 ( not yet worked )
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
345
diff
changeset
|
430 stop = Draw.PupMenu("OK?%t|Cancel export %x1") |
2eeb5f267264
export_xml3 for Blender 2.5 ( not yet worked )
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
345
diff
changeset
|
431 if stop == 1: |
2eeb5f267264
export_xml3 for Blender 2.5 ( not yet worked )
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
345
diff
changeset
|
432 Draw.Exit() |
2eeb5f267264
export_xml3 for Blender 2.5 ( not yet worked )
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
345
diff
changeset
|
433 return |
107 | 434 |
435 def buttonEvt(evt): # function that handles button events | |
436 if evt == evtExport: | |
655
2eeb5f267264
export_xml3 for Blender 2.5 ( not yet worked )
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
345
diff
changeset
|
437 Blender.Window.FileSelector(save_still, "Export", newFName('xml')) |
107 | 438 if evt == evtExportAnim: |
655
2eeb5f267264
export_xml3 for Blender 2.5 ( not yet worked )
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
345
diff
changeset
|
439 Blender.Window.FileSelector(save_anim, "Export Animation", newFName('xml')) |
107 | 440 #if there was an event, redraw the window |
441 if evt: | |
655
2eeb5f267264
export_xml3 for Blender 2.5 ( not yet worked )
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
345
diff
changeset
|
442 Draw.Redraw() |
107 | 443 |
345 | 444 |
445 def loadTexture(texture): | |
446 global images, imageCount | |
447 name = texture.getName() | |
1029 | 448 #if name in images: |
449 # return "\t\t<image name=\"" + name + "\"/>\n" | |
345 | 450 out = "\t\t<image name=\"" + name + "\">\n" |
451 imageCount += 1 | |
452 images[name] = imageCount | |
453 image_path = texture.getFilename() | |
454 input = open(expandpath(image_path), 'r') | |
455 output = open('output.txt', 'w') | |
456 base64.encode(input,output) | |
457 input.close() | |
458 output.close() | |
459 input = open('output.txt', 'r') | |
460 for b64 in input.readlines(): | |
461 out += "\t\t\t%s" %b64 | |
462 input.close() | |
463 os.remove('output.txt') | |
464 out += "\t\t</image>\n" | |
465 return out | |
466 | |
107 | 467 Draw.Register(gui, event, buttonEvt) |
468 | |
469 |