]> git.tdb.fi Git - libs/gl.git/blob - mesh_export.py
Blender export: Create triangle strips (incomplete)
[libs/gl.git] / mesh_export.py
1 #!BPY
2 # $Id$
3
4 """
5 Name: 'MSP GL Mesh (.mesh)...'
6 Blender: 244
7 Group: 'Export'
8 """
9
10 import sys
11 import math
12 import Blender
13
14 class Edge:
15         def __init__(self, me):
16                 self._medge=me
17                 self.faces=[]
18                 self.smooth=False
19
20         def __getattr__(self, attr):
21                 return getattr(self._medge, attr)
22
23         def check_smooth(self, limit):
24                 if len(self.faces)!=2:
25                         return
26
27                 d=Blender.Mathutils.DotVecs(self.faces[0].no, self.faces[1].no)
28                 if (d>limit and self.faces[0].smooth and self.faces[1].smooth) or d>0.999:
29                         self.smooth=1
30
31         def other_face(self, f):
32                 if f.index==self.faces[0].index:
33                         if len(self.faces)>=2:
34                                 return self.faces[1]
35                         else:
36                                 return None
37                 else:
38                         return self.faces[0]
39
40
41 class Vertex:
42         def __init__(self, mv):
43                 if mv.__class__==Vertex:
44                         self._mvert=mv._mvert
45                 else:
46                         self._mvert=mv
47
48         def __getattr__(self, attr):
49                 return getattr(self._mvert, attr)
50
51
52 class Face:
53         def __init__(self, mf):
54                 self._mface=mf
55                 self.smooth_group=None
56                 self.edges=[]
57                 self.verts=[v for v in mf.verts]
58                 self.flag=False
59         
60         def __getattr__(self, attr):
61                 return getattr(self._mface, attr)
62
63         def get_following_vertex(self, *vt):
64                 seen=False
65                 indices=[v.index for v in vt]
66                 for v in self.verts:
67                         if v.index in indices:
68                                 seen=True
69                         elif seen:
70                                 return v
71
72                 if seen:
73                         return self.verts[0]
74
75                 return None
76
77
78 class SmoothGroup:
79         def __init__(self, index):
80                 self.index=index
81                 self.faces=[]
82                 self.verts=[]
83
84         def find_vertices(self):
85                 vert_map={}
86                 for f in self.faces:
87                         for i in range(len(f.verts)):
88                                 v=f.verts[i]
89                                 if v.index not in vert_map:
90                                         vt=Vertex(v)
91                                         if not f.smooth:
92                                                 vt.no=f.no
93                                         self.verts.append(vt)
94                                         vert_map[v.index]=vt
95                                         f.verts[i]=vt
96                                 else:
97                                         f.verts[i]=vert_map[v.index]
98
99
100 class Exporter:
101         def __init__(self, fn):
102                 self.filename=fn
103                 if fn==None:
104                         self.out_file=sys.stdout
105                 else:
106                         self.out_file=file(fn, "w")
107
108         def find_smooth_group(self, face, sg):
109                 face.smooth_group=sg
110                 sg.faces.append(face)
111                 queue=[face]
112                 while queue:
113                         cur=queue.pop(0)
114                         for e in cur.edges:
115                                 if e.smooth:
116                                         other=e.other_face(cur)
117                                         if other and not other.smooth_group:
118                                                 other.smooth_group=sg
119                                                 sg.faces.append(other)
120                                                 queue.append(other)
121
122         def create_strip(self, face):
123                 edge=None
124                 for e in face.edges:
125                         other=e.other_face(face)
126                         if other and other.smooth_group.index==face.smooth_group.index and not other.flag:
127                                 edge=e
128                                 break
129
130                 if not edge:
131                         return None
132
133                 v1=face.get_following_vertex(edge.v1, edge.v2)
134                 v2=face.get_following_vertex(v1)
135                 if len(face.verts)==4:
136                         result=[v2, v1]
137                 else:
138                         result=[v1, v2]
139                         
140                 print edge.key
141                 print [v.index for v in result]
142
143                 while 1:
144                         face.flag=True
145                         print "face =",[v.index for v in face.verts]
146                         print [e.key for e in face.edges]
147                         for i in range(2, len(face.verts)):
148                                 v=face.get_following_vertex(result[-2], result[-1])
149                                 print v.index
150                                 result.append(v)
151                         print [v.index for v in result]
152
153                         i1=result[-2].index
154                         i2=result[-1].index
155                         ekey=(min(i1, i2), max(i1, i2))
156                         for e in face.edges:
157                                 if e.key==ekey:
158                                         edge=e
159                                         break
160
161                         next=edge.other_face(face)
162                         if next.smooth_group.index!=face.smooth_group.index or next.flag:
163                                 break
164                         face=next
165
166                 return result
167
168         def export(self):
169                 scene=Blender.Scene.GetCurrent()
170
171                 obj=scene.getActiveObject()
172                 if obj.getType()!="Mesh":
173                         raise Exception, "Can only export Mesh data"
174
175                 mesh=obj.getData(mesh=True)
176
177                 faces=[Face(f) for f in mesh.faces]
178
179                 edges=dict([(e.key, Edge(e)) for e in mesh.edges])
180                 for f in faces:
181                         for e in f.edge_keys:
182                                 edges[e].faces.append(f)
183                                 f.edges.append(edges[e])
184
185                 smooth_limit=math.cos(mesh.degr*math.pi/180)
186                 for e in edges.itervalues():
187                         e.check_smooth(smooth_limit)
188
189                 smooth_groups=[]
190                 for f in faces:
191                         if not f.smooth_group:
192                                 sg=SmoothGroup(len(smooth_groups))
193                                 smooth_groups.append(sg)
194                                 self.find_smooth_group(f, sg)
195
196                 strips=[]
197                 """XXX Stripping and smoothing are currently imcompatible
198                 for sg in smooth_groups:
199                         for f in sg.faces:
200                                 if not f.flag:
201                                         strip=self.create_strip(f)
202                                         if strip:
203                                                 strips.append(strip)"""
204
205                 for i in mesh.verts:
206                         print i.co
207
208                 #print [v.index for v in strips[0]]
209
210                 verts=[]
211                 for sg in smooth_groups:
212                         sg.find_vertices()
213                         for v in sg.verts:
214                                 v.index=len(verts)
215                                 verts.append(v)
216
217                 #print [v.index for v in strips[0]]
218
219                 self.out_file.write("vertices NORMAL3_VERTEX3\n{\n")
220                 for v in verts:
221                         self.out_file.write("\tnormal3 %f %f %f;\n"%tuple(v.no))
222                         self.out_file.write("\tvertex3 %f %f %f;\n"%tuple(v.co))
223                 self.out_file.write("};\n")
224                 for s in strips:
225                         self.out_file.write("batch TRIANGLE_STRIP\n{\n\tindices")
226                         for v in s:
227                                 self.out_file.write(" %u"%v.index)
228                         self.out_file.write(";\n};\n")
229
230                 first=True
231                 for f in faces:
232                         if not f.flag:
233                                 if first:
234                                         self.out_file.write("batch TRIANGLES\n{\n")
235                                         first=False
236                                 for i in range(2, len(f.verts)):
237                                         self.out_file.write("\tindices %u %u %u;\n"%(f.verts[0].index, f.verts[i-1].index, f.verts[i].index))
238                 if not first:
239                         self.out_file.write("};\n")
240
241
242 class FrontEnd:
243         def run(self):
244                 #self.export(None)
245                 Blender.Window.FileSelector(self.export, "Export MSP GL mesh", Blender.sys.makename(ext='.mesh'))
246
247         def export(self, fn):
248                 exp=Exporter(fn)
249                 exp.export()
250
251
252 if __name__=="__main__":
253         fe=FrontEnd()
254         fe.run()