comparison SceneGraph/BlenderScript/export_xml.py @ 107:ce5755f544c1 cvs

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