1 # $Id: mesh_export.py 137 2010-12-05 19:22:35Z tdb $
6 def __init__(self, size):
8 self.slots = [-1]*self.size
11 hit = v.index in self.slots
13 self.slots.remove(v.index)
14 self.slots.append(v.index)
19 def fetch_strip(self, strip):
26 def test_strip(self, strip):
28 for i in range(len(strip)):
31 if strip[i].index in self.slots[i:]:
37 def __init__(self, fn):
39 self.file = sys.stdout
41 self.file = open(fn, "w")
44 def make(self, kwd, *params):
51 return "%s%s"%(kwd, pstr)
53 def write(self, kwd, *params):
54 self.file.write("%s%s;\n"%('\t'*self.indent, self.make(kwd, *params)))
56 def begin(self, kwd, *params):
58 self.file.write("%s%s\n%s{\n"%(i, self.make(kwd, *params), i))
63 self.file.write("%s};\n"%('\t'*self.indent))
68 self.use_strips = True
69 self.use_degen_tris = True
70 self.max_strip_len = 1024
71 self.optimize_cache = False
73 self.export_lines = True
74 self.export_uv = "UNIT0"
79 self.material_tex = False
80 self.smoothing = "MSPGL"
82 def stripify(self, mesh, progress = None):
91 if self.optimize_cache:
92 cache = VertexCache(self.cache_size)
114 other = e.other_face(f)
115 if other and not other.flag:
129 other = e.other_face(f)
130 if other and not other.flag:
132 if score>0 and score<best:
141 for i in range(len(island_strips)):
142 hits = cache.test_strip(island_strips[i])
147 s = island_strips[best]
148 del island_strips[best]
154 faces_done += len(island)
156 progress.set_progress(float(faces_done)/len(mesh.faces))
158 loose += [f for f in island if not f.flag]
166 strip = mesh.create_strip(face, self.max_strip_len)
168 island_strips.append(strip)
171 cache = VertexCache(self.cache_size)
174 if self.use_degen_tris and strips:
179 glue = [big_strip[-1], s[0]]
185 total_hits += cache.fetch_strip(glue)
189 total_hits += cache.fetch_strip(s)
193 order = (-1, -2, 0, 1)
195 order = (0, 1, -1, -2)
196 vertices = [f.vertices[i] for i in order[:len(f.vertices)]]
199 glue = [big_strip[-1], vertices[0]]
202 total_hits += cache.fetch_strip(glue)
204 big_strip += vertices
206 total_hits += cache.fetch_strip(vertices)
213 def export(self, context, fn):
215 objs = context.selected_objects
217 objs = [context.active_object]
220 raise Exception("Nothing to export")
223 raise Exception("Can only export Mesh data")
225 from .mesh import Mesh
226 from .util import Progress
228 progress = Progress()
229 progress.set_task("Preparing", 0.0, 0.0)
234 bmesh = o.create_mesh(context.scene, True, "PREVIEW")
235 bmeshes.append(bmesh)
239 mesh.splice(Mesh(bmesh))
241 progress.set_task("Smoothing", 0.05, 0.35)
242 if self.smoothing=="NONE":
244 mesh.split_smooth(progress)
246 if self.smoothing!="BLENDER":
247 mesh.compute_normals()
249 if self.material_tex:
250 mesh.generate_material_uv()
253 if mesh.uv_textures and self.export_uv!="NONE":
254 if self.export_uv=="UNIT0":
257 texunits = list(range(len(mesh.uv_textures)))
260 progress.set_task("Splitting UVs", 0.35+0.3*i/len(texunits), 0.35+0.3*(i+1)/len(texunits))
261 mesh.split_uv(i, progress)
265 mesh.compute_tbn(self.tbn_uvtex)
270 progress.set_task("Creating strips", 0.65, 0.95)
271 strips, loose = self.stripify(mesh, progress)
273 progress.set_task("Writing file", 0.95, 1.0)
275 out_file = OutFile(fn)
277 out_file.begin("mesh")
282 for i in texunits[1:]:
283 fmt += "_TEXCOORD2%d"%i
285 fmt += "_ATTRIB33_ATTRIB34"
287 out_file.begin("vertices", fmt)
289 uvs = [None]*len(mesh.uv_textures)
292 for v in mesh.vertices:
294 out_file.write("normal3", *v.normal)
299 out_file.write("texcoord2", *v.uvs[i])
301 out_file.write("multitexcoord2", i, *v.uvs[i])
304 out_file.write("attrib3", 3, *v.tan)
307 out_file.write("attrib3", 4, *v.bino)
309 out_file.write("vertex3", *v.co)
312 out_file.begin("batch", "TRIANGLE_STRIP")
316 indices.append(v.index)
318 out_file.write("indices", *indices)
321 out_file.write("indices", *indices)
325 out_file.begin("batch", "TRIANGLES")
327 for i in range(2, len(f.vertices)):
328 out_file.write("indices", f.vertices[0].index, f.vertices[i-1].index, f.vertices[i].index)
331 if self.export_lines and mesh.lines:
332 out_file.write("batch", "LINES")
334 out_file.write("indices", l.vertices[0].index, l.vertices[1].index)
339 out_file.begin("technique")
340 out_file.begin("pass", '""')
341 if self.material_tex:
342 out_file.begin("material")
343 out_file.write("diffuse", 1.0, 1.0, 1.0, 1.0)
345 out_file.begin("texunit", 0)
346 out_file.begin("texture2d")
347 out_file.write("min_filter", "NEAREST")
348 out_file.write("mag_filter", "NEAREST")
349 out_file.write("storage", "RGB", len(mesh.materials), 1)
351 for m in mesh.materials:
352 color = [int(c*255) for c in m.diffuse_color]
353 texdata += "\\x%02X\\x%02X\\x%02X"%tuple(color)
355 out_file.write("raw_data", texdata)
359 m = mesh.materials[0]
360 out_file.begin("material")
361 out_file.write("diffuse", m.R, m.G, m.B, 1.0)
362 out_file.write("ambient", m.R*m.amb, m.G*m.amb, m.B*m.amb, 1.0)
363 out_file.write("specular", m.specR*m.spec, m.specG*m.spec, m.specB*m.spec, 1.0)
364 out_file.write("shininess", m.hard);
369 progress.set_task("Done", 1.0, 1.0)
372 bpy.data.meshes.remove(m)