Mercurial > hg > Members > kono > Cerium
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 |