4 def __init__(self, size):
6 self.slots = [-1]*self.size
9 hit = v.index in self.slots
11 self.slots.remove(v.index)
12 self.slots.append(v.index)
17 def fetch_strip(self, strip):
24 def test_strip(self, strip):
26 for i in range(len(strip)):
29 if strip[i].index in self.slots[i:]:
35 def __init__(self, fn):
37 self.file = sys.stdout
39 self.file = open(fn, "w")
42 def make(self, kwd, *params):
49 return "%s%s"%(kwd, pstr)
51 def write(self, kwd, *params):
52 self.file.write("%s%s;\n"%('\t'*self.indent, self.make(kwd, *params)))
54 def begin(self, kwd, *params):
56 self.file.write("%s%s\n%s{\n"%(i, self.make(kwd, *params), i))
61 self.file.write("%s};\n"%('\t'*self.indent))
66 self.use_strips = True
67 self.use_degen_tris = True
68 self.max_strip_len = 1024
69 self.optimize_cache = False
71 self.export_lines = True
72 self.export_uv = "UNIT0"
77 self.material_tex = False
79 self.smoothing = "MSPGL"
81 def stripify(self, mesh, progress = None):
90 if self.optimize_cache:
91 cache = VertexCache(self.cache_size)
113 other = e.other_face(f)
114 if other and not other.flag:
128 other = e.other_face(f)
129 if other and not other.flag:
131 if score>0 and score<best:
140 for i in range(len(island_strips)):
141 hits = cache.test_strip(island_strips[i])
146 s = island_strips[best]
147 del island_strips[best]
153 faces_done += len(island)
155 progress.set_progress(float(faces_done)/len(mesh.faces))
157 loose += [f for f in island if not f.flag]
165 strip = mesh.create_strip(face, self.max_strip_len)
167 island_strips.append(strip)
170 cache = VertexCache(self.cache_size)
173 if self.use_degen_tris and strips:
178 glue = [big_strip[-1], s[0]]
184 total_hits += cache.fetch_strip(glue)
188 total_hits += cache.fetch_strip(s)
192 order = (-1, -2, 0, 1)
194 order = (0, 1, -1, -2)
195 vertices = [f.vertices[i] for i in order[:len(f.vertices)]]
198 glue = [big_strip[-1], vertices[0]]
201 total_hits += cache.fetch_strip(glue)
203 big_strip += vertices
205 total_hits += cache.fetch_strip(vertices)
212 def export(self, context, fn):
214 objs = context.selected_objects
216 objs = [context.active_object]
219 raise Exception("Nothing to export")
222 raise Exception("Can only export Mesh data")
224 from .mesh import Mesh
225 from .util import Progress
227 progress = Progress()
228 progress.set_task("Preparing", 0.0, 0.0)
233 bmesh = o.to_mesh(context.scene, True, "PREVIEW")
234 bmeshes.append(bmesh)
238 mesh.splice(Mesh(bmesh))
240 progress.set_task("Smoothing", 0.05, 0.35)
241 if self.smoothing=="NONE":
243 mesh.split_smooth(progress)
245 if self.smoothing!="BLENDER":
246 mesh.compute_normals()
248 if self.material_tex and mesh.materials:
249 mesh.generate_material_uv()
252 if mesh.uv_layers and self.export_uv!="NONE":
253 # Figure out which UV layers to export
254 if self.export_uv=="UNIT0":
255 if mesh.uv_layers[0].unit==0:
258 texunits = range(len(mesh.uv_layers))
259 texunits = [(i, mesh.uv_layers[i]) for i in texunits]
260 texunits = [u for u in texunits if not u[1].hidden]
263 # TBN coordinates must be generated before vertices are split by any other layer
264 uv_names = [u.name for i, u in texunits]
265 if self.tbn_uvtex in uv_names:
266 tbn_index = uv_names.index(self.tbn_uvtex)
267 unit = texunits[tbn_index]
268 del texunits[tbn_index]
269 texunits.insert(0, unit)
271 for i, u in texunits:
272 progress.set_task("Splitting UVs", 0.35+0.3*i/len(texunits), 0.35+0.3*(i+1)/len(texunits))
273 mesh.split_uv(i, progress)
274 if self.tbn_vecs and u.name==self.tbn_uvtex:
283 progress.set_task("Creating strips", 0.65, 0.95)
284 strips, loose = self.stripify(mesh, progress)
286 progress.set_task("Writing file", 0.95, 1.0)
288 out_file = OutFile(fn)
290 out_file.begin("mesh")
294 for i, u in texunits:
298 fmt += "_TEXCOORD2%d"%u.unit
300 fmt += "_ATTRIB33_ATTRIB34"
302 out_file.begin("vertices", fmt)
304 uvs = [None]*len(texunits)
307 for v in mesh.vertices:
309 out_file.write("normal3", *v.normal)
311 for i, u in texunits:
314 out_file.write("texcoord2", *v.uvs[i])
316 out_file.write("multitexcoord2", u.unit, *v.uvs[i])
319 out_file.write("attrib3", 3, *v.tan)
322 out_file.write("attrib3", 4, *v.bino)
324 out_file.write("vertex3", *v.co)
327 out_file.begin("batch", "TRIANGLE_STRIP")
331 indices.append(v.index)
333 out_file.write("indices", *indices)
336 out_file.write("indices", *indices)
340 out_file.begin("batch", "TRIANGLES")
342 for i in range(2, len(f.vertices)):
343 out_file.write("indices", f.vertices[0].index, f.vertices[i-1].index, f.vertices[i].index)
346 if self.export_lines and mesh.lines:
347 out_file.write("batch", "LINES")
349 out_file.write("indices", l.vertices[0].index, l.vertices[1].index)
354 out_file.begin("technique")
355 out_file.begin("pass", '""')
357 if self.material_tex:
358 out_file.begin("material")
359 out_file.write("diffuse", 1.0, 1.0, 1.0, 1.0)
362 for u in mesh.uv_layers:
363 if u.name=="material_tex":
365 out_file.begin("texunit", index)
366 out_file.begin("texture2d")
367 out_file.write("min_filter", "NEAREST")
368 out_file.write("mag_filter", "NEAREST")
369 out_file.write("storage", "RGB", len(mesh.materials), 1)
371 for m in mesh.materials:
372 color = [int(c*255) for c in m.diffuse_color]
373 texdata += "\\x%02X\\x%02X\\x%02X"%tuple(color)
375 out_file.write("raw_data", texdata)
379 mat = mesh.materials[0]
380 out_file.begin("material")
381 diff = mat.diffuse_color
382 out_file.write("diffuse", diff.r, diff.g, diff.b, 1.0)
383 amb = diff*mat.ambient
384 out_file.write("ambient", amb.r, amb.g, amb.b, 1.0)
385 spec = mat.specular_color*mat.specular_intensity
386 out_file.write("specular", spec.r, spec.g, spec.b, 1.0)
387 out_file.write("shininess", mat.specular_hardness);
390 if self.textures!="NONE":
391 for slot in mesh.materials[0].texture_slots:
396 if tex.type!="IMAGE":
400 for u in mesh.uv_layers:
401 if u.name==slot.uv_layer:
404 index = mesh.uv_layers[0].unit
406 out_file.begin("texunit", index)
407 if self.textures=="INLINE":
408 out_file.begin("texture2d")
409 out_file.write("min_filter", "LINEAR")
410 out_file.write("storage", "RGBA", tex.image.size[0], tex.image.size[1])
412 for p in tex.image.pixels:
413 texdata += "\\x%02X"%int(p*255)
415 out_file.write("raw_data", texdata)
418 out_file.write("texture", '"%s"'%tex.image.name)
424 progress.set_task("Done", 1.0, 1.0)
427 bpy.data.meshes.remove(m)