X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=mesh_export.py;h=dd8e5414e95ab3dcb3531eb968aec7d96c5f215e;hb=224c40efa231c85b61da772a6f58c067d7b579b3;hp=bafbf917e527eea2b7c7e230b2115dce987e4012;hpb=a3d391a32578483ede32fcd27266cd703f951e37;p=libs%2Fgl.git diff --git a/mesh_export.py b/mesh_export.py index bafbf917..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,16 @@ 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 @@ -167,6 +171,7 @@ 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 @@ -184,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) @@ -196,16 +201,16 @@ class Exporter: return None if self.strip_debug: - print "Starting strip from %s, edge %s"%([v.index for v in face.verts], (edge.v1.index, edge.v2.index)) + 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) + 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.strip_debug: print " Adding %s"%[v.index for v in verts] @@ -239,6 +244,20 @@ class Exporter: 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 @@ -308,7 +327,7 @@ class Exporter: best=score if not face: break - strip=self.create_strip(face) + strip=self.create_strip(face, self.use_degen_tris and sum([len(s) for s in strips])%2) if strip: strips.append(strip) @@ -322,28 +341,20 @@ class Exporter: if self.use_degen_tris: big_strip=[] - while strips: - strip=None + for s in strips: if big_strip: - for i in range(len(strips)): - if strips[i][0].index==big_strip[-1].index: - strip=strips.pop(i) - break - if not strip: - strip=strips.pop(0) - if big_strip: - if strip[0].index!=big_strip[-1].index: - big_strip+=[big_strip[-1]] - big_strip+=[strip[0]] - big_strip+=strip + big_strip+=[big_strip[-1], s[0]] + big_strip+=s for f in faces: if not f.flag: + if len(big_strip)%2: + order=(-1, -2, 0, 1) + else: + order=(0, 1, -1, -2) if big_strip: - big_strip+=[big_strip[-1], f.verts[0]] - big_strip+=[f.verts[i] for i in (0, 1, -1)] - if len(f.verts)==4: - big_strip.append(f.verts[-2]) + big_strip+=[big_strip[-1], f.verts[order[0]]] + big_strip+=[f.verts[i] for i in order[:len(f.verts)]] f.flag=True strips=[big_strip] @@ -353,22 +364,46 @@ class Exporter: print "Big strip has %d indices"%len(big_strip) if self.debug: - print "%.2f vertices per triangle"%(float(nind)/ntris) + print "%.2f indices per triangle"%(float(nind)/ntris) print "Locality before optimization: "+" ".join(["%.3f"%self.get_locality(s) for s in strips]) - used=[False]*len(verts) - i=0 - for s in strips: - for v in s: - if not used[v.index]: - used[v.index]=True - v.index=i - i+=1 + if self.optimize_locality and self.use_strips: + followers={} + for s in strips: + followers.update(self.get_followers(s)) - verts.sort(cmp=lambda x,y: cmp(x.index, y.index)) + verts2=[] + vert=strips[0][0] + while 1: + vert.flag=True + verts2.append(vert) + + next=None + if vert.index in followers: + flw=followers[vert.index] + best=0 + for n in flw: + if flw[n]>best 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 - if self.debug: - print "Locality after optimization: "+" ".join(["%.3f"%self.get_locality(s) for s in strips]) + 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: @@ -409,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()