5 Name: 'MSP GL Mesh (.mesh)...'
16 def __init__(self, me):
17 if me.__class__==Edge:
25 def __getattr__(self, attr):
26 return getattr(self._medge, attr)
28 def check_smooth(self, limit):
29 if len(self.faces)!=2:
32 d=Blender.Mathutils.DotVecs(self.faces[0].no, self.faces[1].no)
33 if (d>limit and self.faces[0].smooth and self.faces[1].smooth) or d>0.999:
36 def other_face(self, f):
37 if f.index==self.faces[0].index:
38 if len(self.faces)>=2:
47 def __init__(self, mv):
48 if mv.__class__==Vertex:
54 self.orig_index=self._mvert.index
56 def __getattr__(self, attr):
57 return getattr(self._mvert, attr)
61 def __init__(self, mf):
63 self.smooth_group=None
65 self.verts=[v for v in mf.verts]
68 def __getattr__(self, attr):
69 return getattr(self._mface, attr)
71 def get_vertices_from(self, reverse, *vt):
75 indices=[u.index for u in vt]
76 flags=[(v.index in indices) for v in verts]
79 if flags[i] and not flags[(i+l-1)%l]:
80 return verts[i:]+verts[:i]
82 def get_edge(self, v1, v2):
86 if (e.v1.index==i1 or e.v1.index==i2) and (e.v2.index==i1 or e.v2.index==i2):
91 def __init__(self, index):
96 def find_vertices(self):
99 for i in range(len(f.verts)):
101 if v.index not in vert_map:
103 vt.index=len(self.verts)
104 self.verts.append(vt)
107 vt.no=Blender.Mathutils.Vector(f.no)
116 def separate_uv(self):
119 for i in range(len(f.verts)):
124 if v.index not in copies:
128 for w in copies[v.index]:
135 vt.index=len(self.verts)
137 self.verts.append(vt)
138 copies[v.index].append(vt)
142 def create_edges(self):
145 vert_map=dict([(v.orig_index, v) for v in f.verts])
146 for i in range(len(f.edges)):
147 v1=vert_map[f.edges[i].v1.index]
148 v2=vert_map[f.edges[i].v2.index]
149 key=tuple(sorted((v1.index, v2.index)))
165 def __init__(self, fn):
168 self.out_file=sys.stdout
170 self.out_file=file(fn, "w")
172 self.use_degen_tris=True
174 self.strip_debug=False
176 def find_smooth_group(self, face, sg):
178 sg.faces.append(face)
184 other=e.other_face(cur)
185 if other and not other.smooth_group:
186 other.smooth_group=sg
187 sg.faces.append(other)
190 def create_strip(self, face, reverse):
193 other=e.other_face(face)
194 if other and other.smooth_group.index==face.smooth_group.index and not other.flag:
202 print "Starting strip from %s, edge %s, reverse=%s"%([v.index for v in face.verts], (edge.v1.index, edge.v2.index), reverse)
204 verts=face.get_vertices_from(reverse, edge.v1, edge.v2)
206 result=[verts[-1], verts[0]]
208 result=[verts[-2], verts[-1]]
211 verts=face.get_vertices_from(reverse, *result[-2:])
214 print " Adding %s"%[v.index for v in verts]
217 if len(verts)==4 and not k:
218 result.append(verts[3])
219 result.append(verts[2])
220 if len(verts)==4 and k:
221 result.append(verts[3])
223 edge=face.get_edge(*result[-2:])
226 print " Next edge is %s"%((edge.v1.index, edge.v2.index), )
228 next=edge.other_face(face)
229 if not next or next.smooth_group.index!=face.smooth_group.index or next.flag:
234 print " %s"%[v.index for v in result]
238 def get_locality(self, strip):
240 for i in range(1, len(strip)):
241 if strip[i].index!=strip[i-1].index:
242 total+=1.0/(abs(strip[i].index-strip[i-1].index))
243 return total/len(strip)
246 scene=bpy.data.scenes.active
248 obj=scene.objects.active
249 if obj.getType()!="Mesh":
250 raise Exception, "Can only export Mesh data"
252 mesh=obj.getData(mesh=True)
254 faces=[Face(f) for f in mesh.faces]
256 edges=dict([(e.key, Edge(e)) for e in mesh.edges])
258 for e in f.edge_keys:
259 edges[e].faces.append(f)
260 f.edges.append(edges[e])
262 smooth_limit=math.cos(mesh.degr*math.pi/180)
263 for e in edges.itervalues():
264 e.check_smooth(smooth_limit)
267 ntris=sum([len(f.verts)-2 for f in faces])
268 print "%d faces (%d triangles), %d edges"%(len(faces), ntris, len(edges))
272 if not f.smooth_group:
273 sg=SmoothGroup(len(smooth_groups))
274 smooth_groups.append(sg)
275 self.find_smooth_group(f, sg)
277 for sg in smooth_groups:
284 for sg in smooth_groups:
290 print "%d smooth groups:"%len(smooth_groups)
291 for i in range(len(smooth_groups)):
293 print " %d: %d faces, %d vertices"%(i, len(sg.faces), len(sg.verts))
294 print "%d vertices total"%len(verts)
306 other=e.other_face(f)
307 if other and other.smooth_group.index==f.smooth_group.index and not other.flag:
309 if score>0 and score<best:
314 strip=self.create_strip(face, self.use_degen_tris and sum([len(s) for s in strips])%2)
319 print "%d strips:"%len(strips)
320 for i in range(len(strips)):
321 print " %d: %d indices"%(i, len(strips[i]))
322 print "%d loose faces"%len([f for f in faces if not f.flag])
323 nind=sum([len(s) for s in strips])+sum([len(f.verts) for f in faces if not f.flag])
324 print "%d indices total"%nind
326 if self.use_degen_tris:
330 big_strip+=[big_strip[-1], s[0]]
336 big_strip+=[big_strip[-1], f.verts[0]]
338 big_strip+=[f.verts[i] for i in (-1, -2, 0)]
340 big_strip.append(f.verts[1])
342 big_strip+=[f.verts[i] for i in (0, 1, -1)]
344 big_strip.append(f.verts[-2])
351 print "Big strip has %d indices"%len(big_strip)
354 print "%.2f vertices per triangle"%(float(nind)/ntris)
355 print "Locality before optimization: "+" ".join(["%.3f"%self.get_locality(s) for s in strips])
357 used=[False]*len(verts)
361 if not used[v.index]:
366 verts.sort(cmp=lambda x,y: cmp(x.index, y.index))
369 print "Locality after optimization: "+" ".join(["%.3f"%self.get_locality(s) for s in strips])
371 self.out_file.write("vertices NORMAL3")
373 self.out_file.write("_TEXCOORD2")
374 self.out_file.write("_VERTEX3\n{\n")
379 self.out_file.write("\tnormal3 %f %f %f;\n"%tuple(v.no))
382 self.out_file.write("\ttexcoord2 %f %f;\n"%tuple(v.uv))
384 self.out_file.write("\tvertex3 %f %f %f;\n"%tuple(v.co))
385 self.out_file.write("};\n")
387 self.out_file.write("batch TRIANGLE_STRIP\n{\n\tindices")
390 self.out_file.write(" %u"%v.index)
393 self.out_file.write(";\n\tindices")
394 self.out_file.write(";\n};\n")
400 self.out_file.write("batch TRIANGLES\n{\n")
402 for i in range(2, len(f.verts)):
403 self.out_file.write("\tindices %u %u %u;\n"%(f.verts[0].index, f.verts[i-1].index, f.verts[i].index))
405 self.out_file.write("};\n")
411 Blender.Window.FileSelector(self.export, "Export MSP GL mesh", Blender.sys.makename(ext='.mesh'))
413 def export(self, fn):
415 #exp.use_degen_tris=False
417 #exp.strip_debug=True
421 if __name__=="__main__":