Mercurial > hg > Game > Cerium
annotate SceneGraph/BlenderScript/export_xml.py @ 987:6c3dffa8996f draft akira
merge
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Sat, 02 Oct 2010 03:19:33 +0900 |
parents | 2eeb5f267264 |
children | ffe6ad89840e |
rev | line source |
---|---|
107 | 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 | |
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() |
147 | |
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 | |
109 | 169 file.write("\t\t\t%f %f %f\n" %(tri_first[0][0] + matrix[3][0], tri_first[0][1] + matrix[3][1], tri_first[0][2] + matrix[3][2]) ) |
170 file.write("\t\t\t%f %f %f\n" %(tri_second[0][0] + matrix[3][0], tri_second[0][1] + matrix[3][1], tri_second[0][2] + matrix[3][2]) ) | |
171 file.write("\t\t\t%f %f %f\n" %(tri_third[0][0] + matrix[3][0], tri_third[0][1] + matrix[3][1], tri_third[0][2] + matrix[3][2]) ) | |
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 | |
109 | 180 file.write("\t\t\t%f %f %f\n" %(tri_first[1][0], tri_first[1][1], tri_first[1][2]) ) |
181 file.write("\t\t\t%f %f %f\n" %(tri_second[1][0], tri_second[1][1], tri_second[1][2]) ) | |
182 file.write("\t\t\t%f %f %f\n" %(tri_third[1][0], tri_third[1][1], tri_third[1][2]) ) | |
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]] | |
196 | |
109 | 197 file.write("\t\t\t%f %f\n" %(tri_first[2][0], tri_first[2][1]) ) |
198 file.write("\t\t\t%f %f\n" %(tri_second[2][0], tri_second[2][1]) ) | |
199 file.write("\t\t\t%f %f\n" %(tri_third[2][0], tri_third[2][1]) ) | |
200 file.write("\t\t</texture>\n") | |
107 | 201 else: |
109 | 202 file.write("\t\t<texture/>\n") |
107 | 203 |
204 | |
205 ### get texture_image and change base64 data | |
206 texture = mesh.faces[0].image | |
207 if texture: | |
345 | 208 file.write(loadTexture(texture)) |
209 | |
210 else: | |
211 file.write("\t\t<image name=\"%s\">\n" %("sample_white.png") ) | |
212 | |
213 file.write("\t\t\tiVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAAAAADhZOFXAAAAEElEQVQImWP8zwABTAwUMQBJQQEP\n"); | |
214 file.write("\t\t\tlYH+agAAAABJRU5ErkJggg==\n"); | |
215 | |
109 | 216 file.write("\t\t</image>\n") |
107 | 217 |
109 | 218 #return str |
107 | 219 |
220 vdata = [] | |
221 vlist = [] | |
222 flist = [] | |
223 for face in mesh.faces: | |
224 iis = [-1, -1, -1, -1] | |
225 for vi in range(len(face.v)): | |
226 vert = face.v[vi] | |
227 if face.smooth: | |
228 normal = vert.no | |
229 else: | |
230 normal = face.no | |
231 if len(face.uv) == len(face.v): | |
232 uv = face.uv[vi] | |
233 else: | |
234 uv = [] | |
235 iis[vi] = addVertex(vert.index, vert.co, normal, uv) | |
236 addFace(face.materialIndex, iis[0], iis[1], iis[2]) | |
237 if len(face.v)==4: | |
238 addFace(face.materialIndex, iis[2], iis[3], iis[0]) | |
239 | |
109 | 240 #str = "" |
241 #str += getFaces() | |
242 getFaces(); | |
107 | 243 |
109 | 244 #return str |
107 | 245 |
246 | |
247 ###################################################### | |
248 # EXPORT | |
249 ###################################################### | |
250 def save_xml(filename, unindexedname, anim): | |
251 print("XML EXPORT\n") | |
252 time1 = Blender.sys.time() | |
253 print("Saving to '" + filename + "'...\n") | |
254 file = open(filename, 'w') | |
255 | |
256 count_h = 0 | |
257 n = 0 | |
258 filename_h = filename[:-4] + ".h" #header file for cpp | |
259 file_h = open(filename_h, 'w') | |
260 | |
261 ##### XML header ###### | |
262 file.write("<?xml version=\"1.0\"?>\n") | |
263 | |
264 #get all the objects in this scene | |
265 activelayers = Window.ViewLayer() | |
266 for i in range(len(activelayers)): | |
267 activelayers[i] = 2**(activelayers[i]-1) | |
268 object_list1 = Blender.Scene.GetCurrent().getChildren() | |
269 object_list = [] | |
270 matnames= [] | |
271 for obj in object_list1: | |
272 if obj.Layer in activelayers: | |
273 object_list.append(obj) | |
274 | |
275 if obj.getType() == "Mesh": | |
276 materials_obj_list = [] | |
277 materials_obj_list = obj.getData().materials | |
278 for mat in materials_obj_list: | |
279 if mat.name not in matnames: | |
280 matnames.append(mat.name) | |
281 | |
282 ##### Process Meshes ###### | |
283 meshlist = [] | |
284 file.write("<OBJECT-3D>\n") | |
285 for obj in object_list: | |
286 if obj.getType() == "Mesh": | |
287 objectname = obj.getName() | |
288 mesh = Blender.NMesh.GetRawFromObject(objectname) | |
289 meshname = mesh.name | |
290 meshlight = 0 | |
291 if len(mesh.materials) > 0: | |
292 mat0 = mesh.materials[0] | |
293 if mat0.emit > 0: | |
294 meshlight = 1 | |
295 if meshlight: | |
296 print "processing Object \"%s\" as Meshlight (Mesh \"%s\")..." %(objectname, meshname) | |
297 else: | |
298 print "processing Object \"%s\" (Mesh \"%s\")..." %(objectname, meshname) | |
299 try: | |
300 meshlist.index(meshname) | |
301 except ValueError: | |
109 | 302 ###change |
303 #file.write(exportMesh(mesh,obj)) | |
304 exportMesh(mesh,obj,file) | |
107 | 305 meshlist.append(meshname) |
306 if anim == 1: | |
307 #file.write("\t\t<anim>\n") | |
109 | 308 ###change |
309 #file.write(export_anime(obj)) | |
310 export_anime(obj,file) | |
107 | 311 #file.write("\t\t</anim>\n") |
312 file.write("\t</surface>\n") | |
313 file_h.write("#define %s scene_graph" %(obj.name)) | |
314 while n != count_h: | |
315 file_h.write("->next") | |
316 n = n + 1 | |
317 file_h.write("\n") | |
318 count_h = count_h + 1 | |
319 n = 0 | |
320 | |
321 | |
322 ##### XML FOOTER ###### | |
323 file.write("</OBJECT-3D>") | |
324 file.close() | |
325 file_h.close() | |
326 print("Finished.\n") | |
327 | |
328 time2 = Blender.sys.time() | |
329 print("Processing time: %f\n" %(time2-time1)) | |
330 Draw.Exit() | |
331 | |
332 | |
333 ### SAVE ANIMATION ### | |
334 def save_anim(filename): | |
335 global MatSaved | |
336 | |
337 MatSaved = 0 | |
338 unindexedname = filename | |
339 save_xml(filename, unindexedname, 1) | |
340 | |
341 | |
342 #### SAVE STILL (hackish...) #### | |
343 def save_still(filename): | |
344 global MatSaved | |
345 | |
346 MatSaved = 0 | |
347 unindexedname = filename | |
348 save_xml(filename, unindexedname, 0) | |
349 | |
350 ###################################################### | |
351 # Settings GUI | |
352 ###################################################### | |
353 | |
354 # Assign event numbers to buttons | |
355 evtNoEvt = 0 | |
356 evtExport = 1 | |
357 evtExportAnim = 2 | |
358 | |
359 # Set initial values of buttons | |
360 | |
361 ## <size>800 600</size> | |
362 | |
363 sceneSizeX = Scene.GetCurrent().getRenderingContext().imageSizeX() | |
364 sceneSizeY = Scene.GetCurrent().getRenderingContext().imageSizeY() | |
365 | |
366 SizeX = Draw.Create(sceneSizeX) | |
367 SizeY = Draw.Create(sceneSizeY) | |
368 TexExponent = Draw.Create(2.3) | |
369 | |
370 ## <metropolis>1</metropolis> | |
371 MLT = Draw.Create(1) | |
372 | |
373 ## <large_mutation_prob>0.1</large_mutation_prob> | |
374 LMP = Draw.Create(0.1) | |
375 | |
376 ## <max_change>0.02</max_change> | |
377 MaxChange = Draw.Create(0.02) | |
378 | |
379 ## <russian_roulette_live_prob>0.7</russian_roulette_live_prob> | |
380 RRLP = Draw.Create(0.7) | |
381 | |
382 ## <max_depth>100</max_depth> | |
383 MaxDepth = Draw.Create(100) | |
384 | |
385 ## <bidirectional>false</bidirectional> | |
386 Bidirectional = Draw.Create(0) | |
387 | |
388 ## <strata_width>14</strata_width> | |
389 StrataWidth = Draw.Create(14) | |
390 | |
391 ## <logging>0</logging> | |
392 Logging = Draw.Create(0) | |
393 | |
394 ## <save_untonemapped_exr>false</save_untonemapped_exr> | |
395 SaveUTMExr = Draw.Create(0) | |
396 | |
397 ## <save_tonemapped_exr>false</save_tonemapped_exr> | |
398 SaveTMExr = Draw.Create(0) | |
399 | |
400 ## <lens_radius>0.0</lens_radius> | |
401 LensRadius = Draw.Create(0.0) | |
402 | |
403 ## <focus_distance>2.0</focus_distance> | |
404 FocusDistance = Draw.Create(2.0) | |
405 | |
406 ## <turbidity>2.0</turbidity> | |
407 Turbidity = Draw.Create(2.0) | |
408 | |
409 GroundPlane = Draw.Create(1) | |
410 | |
411 ## Separate materials | |
412 MatFile = Draw.Create(1) | |
413 | |
414 # text color fix | |
415 textcol = [0, 0, 0] | |
416 | |
417 | |
418 def gui(): | |
419 global evtNoEvt, evtExport, evtExportAnim | |
420 global SizeX, SizeY, TexExponent, MLT, LMP, MaxChange, RRLP, MaxDepth, Bidirectional, StrataWidth, Logging, SaveUTMExr, SaveTMExr, LensRadius, FocusDistance,Turbidity, GroundPlane, MatFile | |
421 global textcol | |
422 | |
423 Draw.Button("Export", evtExport, 10, 25, 100, 18, "Open file dialog and export") | |
424 Draw.Button("Export Animation", evtExportAnim, 130, 25, 150, 18, "Open filedialog and export animation (careful: takes a lot of diskspace!!!)") | |
425 BGL.glColor3f(textcol[0], textcol[1], textcol[2]) ; BGL.glRasterPos2i(10,10) ; Draw.Text("Press Q or ESC to quit.", "tiny") | |
426 | |
427 BGL.glRasterPos2i(10,60) ; Draw.Text("xml exporter for libps3") | |
428 | |
429 | |
430 def event(evt, val): # function that handles keyboard and mouse events | |
431 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
|
432 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
|
433 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
|
434 Draw.Exit() |
2eeb5f267264
export_xml3 for Blender 2.5 ( not yet worked )
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
345
diff
changeset
|
435 return |
107 | 436 |
437 def buttonEvt(evt): # function that handles button events | |
438 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
|
439 Blender.Window.FileSelector(save_still, "Export", newFName('xml')) |
107 | 440 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
|
441 Blender.Window.FileSelector(save_anim, "Export Animation", newFName('xml')) |
107 | 442 #if there was an event, redraw the window |
443 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
|
444 Draw.Redraw() |
107 | 445 |
345 | 446 |
447 def loadTexture(texture): | |
448 global images, imageCount | |
449 name = texture.getName() | |
450 if name in images: | |
451 return "\t\t<image name=\"" + name + "\"/>\n" | |
452 out = "\t\t<image name=\"" + name + "\">\n" | |
453 imageCount += 1 | |
454 images[name] = imageCount | |
455 image_path = texture.getFilename() | |
456 input = open(expandpath(image_path), 'r') | |
457 output = open('output.txt', 'w') | |
458 base64.encode(input,output) | |
459 input.close() | |
460 output.close() | |
461 input = open('output.txt', 'r') | |
462 for b64 in input.readlines(): | |
463 out += "\t\t\t%s" %b64 | |
464 input.close() | |
465 os.remove('output.txt') | |
466 out += "\t\t</image>\n" | |
467 return out | |
468 | |
107 | 469 Draw.Register(gui, event, buttonEvt) |
470 | |
471 |