X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=mesh_export.py;h=dd8e5414e95ab3dcb3531eb968aec7d96c5f215e;hb=5c59a04e253bf7868796fc0dc8e9768ad1988b33;hp=75db9d12dd1d1ab70faf9347c2b247f822155604;hpb=982005bfbccb429767d0676bd840caf1118c9e21;p=libs%2Fgl.git diff --git a/mesh_export.py b/mesh_export.py index 75db9d12..dd8e5414 100644 --- a/mesh_export.py +++ b/mesh_export.py @@ -52,6 +52,7 @@ class Vertex: self._mvert=mv self.uv=None self.orig_index=self._mvert.index + self.flag=False def __getattr__(self, attr): return getattr(self._mvert, attr) @@ -68,13 +69,23 @@ class Face: def __getattr__(self, attr): return getattr(self._mface, attr) - def get_vertices_from(self, *vt): + def get_vertices_from(self, reverse, *vt): + verts=self.verts[:] + if reverse: + verts.reverse() indices=[u.index for u in vt] - flags=[(v.index in indices) for v in self.verts] - l=len(self.verts) + flags=[(v.index in indices) for v in verts] + l=len(verts) for i in range(l): if flags[i] and not flags[(i+l-1)%l]: - return self.verts[i:]+self.verts[:i] + return verts[i:]+verts[:i] + + def get_edge(self, v1, v2): + i1=v1.index + i2=v2.index + for e in self.edges: + if (e.v1.index==i1 or e.v1.index==i2) and (e.v2.index==i1 or e.v2.index==i2): + return e class SmoothGroup: @@ -160,7 +171,9 @@ class Exporter: self.out_file=file(fn, "w") self.use_strips=True self.use_degen_tris=True + self.optimize_locality=True self.debug=False + self.strip_debug=False def find_smooth_group(self, face, sg): face.smooth_group=sg @@ -176,7 +189,7 @@ class Exporter: sg.faces.append(other) queue.append(other) - def create_strip(self, face): + def create_strip(self, face, reverse): edge=None for e in face.edges: other=e.other_face(face) @@ -187,17 +200,20 @@ class Exporter: if not edge: return None - if self.debug: - print "Starting strip from %s"%[v.index for v in face.verts] + if self.strip_debug: + print "Starting strip from %s, edge %s, reverse=%s"%([v.index for v in face.verts], (edge.v1.index, edge.v2.index), reverse) - verts=face.get_vertices_from(edge.v1, edge.v2) - result=[verts[-2], verts[-1]] + verts=face.get_vertices_from(reverse, edge.v1, edge.v2) + if len(verts)==3: + result=[verts[-1], verts[0]] + else: + result=[verts[-2], verts[-1]] while 1: - verts=face.get_vertices_from(*result[-2:]) + verts=face.get_vertices_from(reverse, *result[-2:]) k=len(result)%2 - if self.debug: - print " %d %s"%(len(result), [v.index for v in verts]) + if self.strip_debug: + print " Adding %s"%[v.index for v in verts] face.flag=True if len(verts)==4 and not k: @@ -206,24 +222,42 @@ class Exporter: if len(verts)==4 and k: result.append(verts[3]) - i1=result[-2].index - i2=result[-1].index - ekey=(min(i1, i2), max(i1, i2)) - for e in face.edges: - if e.key==ekey: - edge=e - break + edge=face.get_edge(*result[-2:]) + + if self.strip_debug: + print " Next edge is %s"%((edge.v1.index, edge.v2.index), ) next=edge.other_face(face) if not next or next.smooth_group.index!=face.smooth_group.index or next.flag: break face=next - if self.debug: + if self.strip_debug: print " %s"%[v.index for v in result] return result + def get_locality(self, strip): + total=0 + for i in range(1, len(strip)): + if strip[i].index!=strip[i-1].index: + total+=1.0/(abs(strip[i].index-strip[i-1].index)) + return total/len(strip) + + def get_followers(self, strip): + result={} + for i in range(len(strip)-1): + v=strip[i] + n=strip[i+1] + if v.index!=n.index: + if v.index not in result: + result[v.index]={} + if n.index not in result[v.index]: + result[v.index][n.index]=1 + else: + result[v.index][n.index]+=1 + return result + def export(self): scene=bpy.data.scenes.active @@ -246,7 +280,8 @@ class Exporter: e.check_smooth(smooth_limit) if self.debug: - print "%d faces, %d edges"%(len(faces), len(edges)) + ntris=sum([len(f.verts)-2 for f in faces]) + print "%d faces (%d triangles), %d edges"%(len(faces), ntris, len(edges)) smooth_groups=[] for f in faces: @@ -268,19 +303,41 @@ class Exporter: verts.append(v) if self.debug: - print "%d smooth groups:"%(len(smooth_groups)) + print "%d smooth groups:"%len(smooth_groups) for i in range(len(smooth_groups)): sg=smooth_groups[i] print " %d: %d faces, %d vertices"%(i, len(sg.faces), len(sg.verts)) + print "%d vertices total"%len(verts) strips=[] if self.use_strips: - for sg in smooth_groups: - for f in sg.faces: - if not f.flag: - strip=self.create_strip(f) - if strip: - strips.append(strip) + while 1: + best=5 + face=None + for f in faces: + if f.flag: + continue + score=0 + for e in f.edges: + other=e.other_face(f) + if other and other.smooth_group.index==f.smooth_group.index and not other.flag: + score+=1 + if score>0 and scorebest and not verts[n].flag: + next=verts[n] + best=flw[n]+0.9/abs(vert.index-n) + + if not next: + for v in verts: + if not v.flag: + next=v + break + if not next: + break + + vert=next + + verts=verts2 + + for i in range(len(verts)): + verts[i].index=i + + if self.debug: + print "Locality after optimization: "+" ".join(["%.3f"%self.get_locality(s) for s in strips]) self.out_file.write("vertices NORMAL3") if mesh.faceUV: @@ -339,13 +444,31 @@ class Exporter: class FrontEnd: def run(self): - #self.export(None) - Blender.Window.FileSelector(self.export, "Export MSP GL mesh", Blender.sys.makename(ext='.mesh')) + self.use_strips=Blender.Draw.Create(True) + self.use_degen_tris=Blender.Draw.Create(True) + self.optimize_locality=Blender.Draw.Create(True) + self.debug=Blender.Draw.Create(False) + self.strip_debug=Blender.Draw.Create(False) + ret=Blender.Draw.PupBlock("Export MSP GL mesh", + [("Use strips", self.use_strips, "Generage OpenGL triangle strips"), + ("Use degen tris", self.use_degen_tris, "Use degenerate triangles to combine triangle strips"), + ("Optimize locality", self.optimize_locality), + ("Debugging options"), + ("Debug", self.debug), + ("Debug strips", self.strip_debug)]) + if ret: + Blender.Window.FileSelector(self.export, "Export MSP GL mesh", Blender.sys.makename(ext='.mesh')) + + def draw(self): + pass def export(self, fn): exp=Exporter(fn) - #exp.use_degen_tris=False - #exp.debug=True + exp.use_strips=self.use_strips.val + exp.use_degen_tris=self.use_degen_tris.val + exp.optimize_locality=self.optimize_locality.val + exp.debug=self.debug.val + exp.strip_debug=self.strip_debug.val exp.export()