]> git.tdb.fi Git - libs/gl.git/commitdiff
Blender exporter:
authorMikko Rasa <tdb@tdb.fi>
Tue, 21 Oct 2008 20:08:53 +0000 (20:08 +0000)
committerMikko Rasa <tdb@tdb.fi>
Tue, 21 Oct 2008 20:08:53 +0000 (20:08 +0000)
Remove unused code
Support exporting faceless edges as lines
Determine default filename from object name
Store configuration between runs

mesh_export.py

index eecd5a69835595faaa99c876c88be666c0a18cbf..fbb282281e3dce09e3ef3af62d14ec264a69f65b 100644 (file)
@@ -77,7 +77,6 @@ class Vertex:
 class Face:
        def __init__(self, mf):
                self._mface=mf
-               #self.smooth_group=None
                self.edges=[]
                self.verts=[v for v in mf.verts]
                self.flag=False
@@ -111,78 +110,16 @@ class Face:
                                return e
 
 
-class SmoothGroup:
-       def __init__(self, index):
-               self.index=index
-               self.faces=[]
-               self.verts=[]
-
-       def find_vertices(self):
-               vert_map={}
-               for f in self.faces:
-                       for i in range(len(f.verts)):
-                               v=f.verts[i]
-                               if v.index not in vert_map:
-                                       vt=Vertex(v)
-                                       vt.index=len(self.verts)
-                                       self.verts.append(vt)
-
-                                       vert_map[v.index]=vt
-                                       vt.no=Blender.Mathutils.Vector(f.no)
-                               else:
-                                       vt=vert_map[v.index]
-                                       vt.no+=f.no
-                               f.verts[i]=vt
-
-               for v in self.verts:
-                       v.no.normalize()
-
-       def separate_uv(self):
-               copies={}
-               for f in self.faces:
-                       for i in range(len(f.verts)):
-                               v=f.verts[i]
-                               if not v.uv:
-                                       v.uv=f.uv[i]
-                               elif f.uv[i]!=v.uv:
-                                       if v.index not in copies:
-                                               copies[v.index]=[]
-
-                                       vt=None
-                                       for w in copies[v.index]:
-                                               if w.uv==f.uv[i]:
-                                                       vt=w
-                                                       break
-
-                                       if not vt:
-                                               vt=Vertex(v)
-                                               vt.index=len(self.verts)
-                                               vt.uv=f.uv[i]
-                                               self.verts.append(vt)
-                                               copies[v.index].append(vt)
-
-                                       f.verts[i]=vt
+class Line:
+       def __init__(self, e):
+               self.edge=e
+               self.verts=[e.v1, e.v2]
+               self.flag=False
 
-       def create_edges(self):
-               edge_map={}
-               for f in self.faces:
-                       vert_map=dict([(v.orig_index, v) for v in f.verts])
-                       for i in range(len(f.edges)):
-                               v1=vert_map[f.edges[i].v1.index]
-                               v2=vert_map[f.edges[i].v2.index]
-                               key=tuple(sorted((v1.index, v2.index)))
-
-                               if key in edge_map:
-                                       e=edge_map[key]
-                               else:
-                                       e=Edge(f.edges[i])
-                                       edge_map[key]=e
-                                       e.v1=v1
-                                       e.v2=v2
-                                       e.key=key
+       def __str__(self):
+               return "<Line (%d %d)>"%(self.verts[0].index, self.verts[1].index)
 
-                               f.edges[i]=e
-                               e.faces.append(f)
+       __repr__=__str__
 
 
 class Mesh:
@@ -203,6 +140,8 @@ class Mesh:
                                e.faces.append(self.faces[f.index])
                                f.edges.append(e)
 
+               self.lines=[Line(e) for e in self.edges.itervalues() if not e.faces]
+
                smooth_limit=math.cos(m.degr*math.pi/180)
                for e in self.edges.itervalues():
                        e.v1=self.verts[e.v1.index]
@@ -250,7 +189,6 @@ class Mesh:
                                                if debug:
                                                        print "  Splitting edge %s with faces %s"%(e.key, e.faces)
 
-                                               old=e
                                                if not e.smooth:
                                                        if len(e.faces)>=2:
                                                                k=e.faces.index(f)
@@ -295,12 +233,14 @@ class Mesh:
 
        def compute_normals(self):
                for v in self.verts:
-                       if not v.faces:
-                               print "WTF?  Vertex %s without faces?"%v
-                       v.no=Blender.Mathutils.Vector()
-                       for f in v.faces:
-                               v.no+=f.no
-                       v.no.normalize()
+                       if v.faces:
+                               v.no=Blender.Mathutils.Vector()
+                               for f in v.faces:
+                                       v.no+=f.no
+                               v.no.normalize()
+                       else:
+                               # XXX Should use edges to compute normal
+                               v.no=Blender.Mathutils.Vector(0, 0, 1)
 
        def create_strip(self, face, reverse, debug):
                edge=None
@@ -361,72 +301,11 @@ class Exporter:
                self.use_strips=True
                self.use_degen_tris=True
                self.optimize_locality=True
+               self.export_lines=True
                self.debug=False
                self.strip_debug=False
                self.smooth_debug=False
 
-       """def find_smooth_group(self, face, sg):
-               face.smooth_group=sg
-               sg.faces.append(face)
-               queue=[face]
-               while queue:
-                       cur=queue.pop(0)
-                       for e in cur.edges:
-                               if e.smooth:
-                                       other=e.other_face(cur)
-                                       if other and not other.smooth_group:
-                                               other.smooth_group=sg
-                                               sg.faces.append(other)
-                                               queue.append(other)"""
-
-       """def create_strip(self, face, reverse):
-               edge=None
-               for e in face.edges:
-                       other=e.other_face(face)
-                       if other and "other.smooth_group.index==face.smooth_group.index" and not other.flag:
-                               edge=e
-                               break
-
-               if not edge:
-                       return None
-
-               if self.strip_debug:
-                       print "Starting strip from %s, edge %s, reverse=%s"%([v.index for v in face.verts], edge.key, reverse)
-
-               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(reverse, *result[-2:])
-                       k=len(result)%2
-                       if self.strip_debug:
-                               print "  Adding %s"%[v.index for v in verts]
-
-                       face.flag=True
-                       if len(verts)==4 and not k:
-                               result.append(verts[3])
-                       result.append(verts[2])
-                       if len(verts)==4 and k:
-                               result.append(verts[3])
-
-                       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.flag:
-                               break
-                       face=next
-
-               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)):
@@ -469,50 +348,6 @@ class Exporter:
 
                mesh.compute_normals()
 
-               #return
-
-               """faces=[Face(f) for f in mesh.faces]
-
-               edges=dict([(e.key, Edge(e)) for e in mesh.edges])
-               for f in faces:
-                       for e in f.edge_keys:
-                               edges[e].faces.append(f)
-                               f.edges.append(edges[e])
-
-               smooth_limit=math.cos(mesh.degr*math.pi/180)
-               for e in edges.itervalues():
-                       e.check_smooth(smooth_limit)
-
-               if self.debug:
-                       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:
-                       if not f.smooth_group:
-                               sg=SmoothGroup(len(smooth_groups))
-                               smooth_groups.append(sg)
-                               self.find_smooth_group(f, sg)
-
-               for sg in smooth_groups:
-                       sg.find_vertices()
-                       if mesh.faceUV:
-                               sg.separate_uv()
-                       sg.create_edges()
-
-               verts=[]
-               for sg in smooth_groups:
-                       for v in sg.verts:
-                               v.index=len(verts)
-                               verts.append(v)
-
-               if self.debug:
-                       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 f in mesh.faces:
@@ -548,7 +383,7 @@ class Exporter:
                                nind=sum([len(s) for s in strips])+sum([len(f.verts) for f in mesh.faces if not f.flag])
                                print "%d indices total"%nind
 
-                       if self.use_degen_tris:
+                       if self.use_degen_tris and strips:
                                big_strip=[]
                                for s in strips:
                                        if big_strip:
@@ -573,10 +408,10 @@ class Exporter:
                                        print "Big strip has %d indices"%len(big_strip)
 
                if self.debug:
-                       print "%.2f indices per triangle"%(float(nind)/ntris)
+                       print "%.2f indices per triangle"%(float(nind)/max(ntris, 1))
                        print "Locality before optimization: "+" ".join(["%.3f"%self.get_locality(s) for s in strips])
 
-               if self.optimize_locality and self.use_strips:
+               if self.optimize_locality and self.use_strips and strips:
                        followers={}
                        for s in strips:
                                followers.update(self.get_followers(s))
@@ -650,34 +485,62 @@ class Exporter:
                if not first:
                        self.out_file.write("};\n")
 
+               if self.export_lines and mesh.lines:
+                       self.out_file.write("batch LINES\n{\n")
+                       for l in mesh.lines:
+                               self.out_file.write("\tindices %u %u;\n"%(l.verts[0].index, l.verts[1].index))
+                       self.out_file.write("};\n")
+
 
 class FrontEnd:
+       def __init__(self):
+               self.config=Blender.Registry.GetKey('mspgl_export', True) or {}
+               self.temp_config=Blender.Registry.GetKey('mspgl_export_temp') or {}
+
        def run(self):
-               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)
-               self.smooth_debug=Blender.Draw.Create(False)
+               self.use_strips=Blender.Draw.Create(self.config.get('use_strips', True))
+               self.use_degen_tris=Blender.Draw.Create(self.config.get('use_degen_tris', True))
+               self.optimize_locality=Blender.Draw.Create(self.config.get('optimize_locality', True))
+               self.export_lines=Blender.Draw.Create(self.config.get('export_lines', False))
+               self.debug=Blender.Draw.Create(self.config.get('debug', False))
+               self.strip_debug=Blender.Draw.Create(self.config.get('strip_debug', False))
+               self.smooth_debug=Blender.Draw.Create(self.config.get('smooth_debug', 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),
+                               ("Export lines", self.export_lines),
                                ("Debugging options"),
                                ("Debug", self.debug),
                                ("Debug strips", self.strip_debug),
                                ("Debug smoothing", self.smooth_debug)])
                if ret:
-                       Blender.Window.FileSelector(self.export, "Export MSP GL mesh", Blender.sys.makename(ext='.mesh'))
+                       dirname=self.temp_config.get("dirname", Blender.sys.dirname(Blender.Get("filename")))
+                       obj=bpy.data.scenes.active.objects.active
+                       Blender.Window.FileSelector(self.export, "Export MSP GL mesh", "%s/%s.mesh"%(dirname, obj.name))
 
        def draw(self):
                pass
 
        def export(self, fn):
+               self.config['use_strips']=self.use_strips.val
+               self.config['use_degen_tris']=self.use_degen_tris.val
+               self.config['optimize_locality']=self.optimize_locality.val
+               self.config['export_lines']=self.export_lines.val
+               self.config['debug']=self.debug.val
+               self.config['strip_debug']=self.strip_debug.val
+               self.config['smooth_debug']=self.smooth_debug.val
+               Blender.Registry.SetKey('mspgl_export', self.config, True)
+
+               import os
+               self.temp_config["dirname"]=os.path.dirname(fn)
+               Blender.Registry.SetKey('mspgl_export_temp', self.temp_config)
+
                exp=Exporter(fn)
                exp.use_strips=self.use_strips.val
                exp.use_degen_tris=self.use_degen_tris.val
                exp.optimize_locality=self.optimize_locality.val
+               exp.export_lines=self.export_lines.val
                exp.debug=self.debug.val
                exp.strip_debug=self.strip_debug.val
                exp.smooth_debug=self.smooth_debug.val