self._mvert=mv
self.uv=None
self.orig_index=self._mvert.index
+ self.flag=False
def __getattr__(self, attr):
return getattr(self._mvert, attr)
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
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
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)
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]
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
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)
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]
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:
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()