]> git.tdb.fi Git - libs/gl.git/blob - mesh_export.py
Drop Id tags and copyright notices from files
[libs/gl.git] / mesh_export.py
1 #!BPY
2
3 """
4 Name: 'MSP GL Mesh (.mesh)...'
5 Blender: 244
6 Group: 'Export'
7 """
8
9 import sys
10 import math
11 import bpy
12 import Blender
13
14 def make_edge_key(i1, i2):
15         return (min(i1, i2), max(i1, i2))
16
17 progress_range = (0.0, 1.0, "")
18
19 def set_progress(value):
20         Blender.Window.DrawProgressBar(progress_range[0]+progress_range[1]*value, progress_range[2])
21
22 def set_progress_range(low, high, text):
23         global progress_range
24         progress_range = (low, high-low, text)
25         set_progress(0.0)
26
27
28 class Edge:
29         def __init__(self, me):
30                 if me.__class__==Edge:
31                         self._medge = me._medge
32                         self.v1 = me.v1
33                         self.v2 = me.v2
34                         self.smooth = me.smooth
35                 else:
36                         self._medge = me
37                         self.smooth = False
38                 self.faces = []
39
40         def __getattr__(self, attr):
41                 return getattr(self._medge, attr)
42
43         def check_smooth(self, limit):
44                 if len(self.faces)!=2:
45                         return
46
47                 d = Blender.Mathutils.DotVecs(self.faces[0].no, self.faces[1].no)
48                 if (d>limit and self.faces[0].smooth and self.faces[1].smooth) or d>0.999:
49                         self.smooth = True
50
51         def other_face(self, f):
52                 if f.index==self.faces[0].index:
53                         if len(self.faces)>=2:
54                                 return self.faces[1]
55                         else:
56                                 return None
57                 else:
58                         return self.faces[0]
59
60
61 class Vertex:
62         def __init__(self, mv):
63                 if mv.__class__==Vertex:
64                         self._mvert = mv._mvert
65                         self.no = mv.no
66                         self.uv = mv.uv
67                 else:
68                         self._mvert = mv
69                         self.uv = None
70                 self.flag = False
71                 self.faces = []
72                 self.tan = None
73                 self.bino = None
74
75         def __getattr__(self, attr):
76                 return getattr(self._mvert, attr)
77
78         def __cmp__(self, other):
79                 if other is None:
80                         return 1
81                 return cmp(self.index, other.index)
82
83         def __str__(self):
84                 return "<Vert %d (%.4f, %.4f, %.4f) (%.4f, %.4f, %.4f)>"%(self.index, self.co[0], self.co[1], self.co[2], self.no[0], self.no[1], self.no[2])
85         
86         __repr__ = __str__
87
88
89 class Face:
90         def __init__(self, mf):
91                 self._mface = mf
92                 self.edges = []
93                 self.verts = [v for v in mf.verts]
94                 self.flag = False
95
96         def __getattr__(self, attr):
97                 return getattr(self._mface, attr)
98
99         def __cmp__(self, other):
100                 if other is None:
101                         return 1
102                 return cmp(self.index, other.index)
103
104         def __str__(self):
105                 return "<Face %d (%s)>"%(self.index, " ".join([str(v.index) for v in self.verts]))
106         
107         __repr__ = __str__
108
109         def pivot_vertices(self, *vt):
110                 flags = [(v in vt) for v in self.verts]
111                 l = len(self.verts)
112                 for i in range(l):
113                         if flags[i] and not flags[(i+l-1)%l]:
114                                 return self.verts[i:]+self.verts[:i]
115
116         def get_edge(self, v1, v2):     
117                 key = make_edge_key(v1.index, v2.index)
118                 for e in self.edges:
119                         if e.key==key:
120                                 return e
121                 raise KeyError, "No edge %s"%(key,)
122
123
124 class Line:
125         def __init__(self, e):
126                 self.edge = e
127                 self.verts = [e.v1, e.v2]
128                 self.flag = False
129
130         def __str__(self):
131                 return "<Line (%d %d)>"%(self.verts[0].index, self.verts[1].index)
132
133         __repr__ = __str__
134
135
136 class Mesh:
137         def __init__(self, m):
138                 self._mesh = m
139                 self.verts = [Vertex(v) for v in m.verts]
140                 self.faces = [Face(f) for f in m.faces]
141                 self.materials = m.materials[:]
142
143                 for f in self.faces:
144                         for i in range(len(f.verts)):
145                                 f.verts[i] = self.verts[f.verts[i].index]
146                                 f.verts[i].faces.append(f)
147
148                 self.edges = dict([(e.key, Edge(e)) for e in m.edges])
149                 for f in self.faces:
150                         for k in f.edge_keys:
151                                 e = self.edges[k]
152                                 e.faces.append(self.faces[f.index])
153                                 f.edges.append(e)
154
155                 self.lines = [Line(e) for e in self.edges.itervalues() if not e.faces]
156
157                 if m.mode&Blender.Mesh.Modes.AUTOSMOOTH:
158                         smooth_limit = math.cos(m.degr*math.pi/180)
159                 else:
160                         smooth_limit = -1
161
162                 for e in self.edges.itervalues():
163                         e.v1 = self.verts[e.v1.index]
164                         e.v2 = self.verts[e.v2.index]
165                         e.check_smooth(smooth_limit)
166
167         def __getattr__(self, attr):
168                 return getattr(self._mesh, attr)
169
170         def splice(self, other):
171                 material_map = []
172                 for m in other.materials:
173                         if m in self.materials:
174                                 material_map.append(self.materials.index(m))
175                         else:
176                                 material_map.append(len(self.materials))
177                                 self.materials.append(m)
178
179                 offset = len(self.verts)
180                 for v in other.verts:
181                         v.index += offset
182                         self.verts.append(v)
183
184                 offset = len(self.faces)
185                 for f in other.faces:
186                         f.index += offset
187                         f.mat = material_map[f.mat]
188                         self.faces.append(f)
189
190                 for e in other.edges.itervalues():
191                         e.key = make_edge_key(e.v1.index, e.v2.index)
192                         self.edges[e.key] = e
193
194                 self.lines += other.lines
195         
196         def generate_material_uv(self):
197                 for f in self.faces:
198                         f.uv = ([(f.mat+0.5)/len(self.materials), 0.5],)*len(f.verts)
199                 self.faceUV = True
200
201         def split_vertices(self, find_group_func, debug):
202                 groups = []
203                 for i in range(len(self.verts)):
204                         v = self.verts[i]
205                         for f in v.faces:
206                                 f.flag = False
207
208                         vg = []
209                         for f in v.faces:
210                                 if not f.flag:
211                                         vg.append(find_group_func(v, f))
212
213                         groups.append(vg)
214
215                         set_progress(i*0.5/len(self.verts))
216
217                 for i in range(len(self.verts)):
218                         if len(groups[i])==1:
219                                 continue
220
221                         if debug:
222                                 print "Vertex %s has %d groups"%(self.verts[i], len(groups[i]))
223
224                         for g in groups[i][1:]:
225                                 v = Vertex(self.verts[i])
226                                 v.index = len(self.verts)
227                                 self.verts.append(v)
228
229                                 if debug:
230                                         print "  -> %d %s"%(v.index, [f.index for f in g])
231
232                                 for f in g:
233                                         for j in range(len(f.edges)):
234                                                 e = f.edges[j]
235
236                                                 if e.v1!=self.verts[i] and e.v2!=self.verts[i]:
237                                                         continue
238
239                                                 if debug:
240                                                         print "  Splitting edge %s with faces %s"%(e.key, e.faces)
241
242                                                 if e.other_face(f) not in g and len(e.faces)>=2:
243                                                         k = e.faces.index(f)
244                                                         e.faces.remove(f)
245                                                         e = Edge(e)
246                                                         f.edges[j] = e
247                                                         e.faces.append(f)
248                                                 else:
249                                                         del self.edges[e.key]
250
251                                                 if e.v1==self.verts[i]:
252                                                         e.v1 = v
253                                                 elif e.v2==self.verts[i]:
254                                                         e.v2 = v
255
256                                                 e.key = make_edge_key(e.v1.index, e.v2.index)
257                                                 self.edges[e.key] = e
258
259                                         self.verts[i].faces.remove(f)
260                                         f.verts[f.verts.index(self.verts[i])] = v
261                                         v.faces.append(f)
262
263                         set_progress(0.5+i*0.5/len(self.verts))
264
265         def split_smooth(self, debug = False):
266                 self.split_vertices(self.find_smooth_group, debug)
267
268         def split_uv(self, debug = False):
269                 self.split_vertices(self.find_uv_group, debug)
270
271         def find_smooth_group(self, vert, face):
272                 face.flag = True
273                 queue = [face]
274
275                 for f in queue:
276                         for e in f.edges:
277                                 other = e.other_face(f)
278                                 #if not other or other.index not in face_indices:
279                                 if other not in vert.faces:
280                                         continue
281
282                                 if e.smooth:
283                                         if not other.flag:
284                                                 other.flag = True
285                                                 queue.append(other)
286
287                 return queue
288
289         def find_uv_group(self, vert, face):
290                 uv = face.uv[face.verts.index(vert)]
291                 face.flag = True
292                 group = [face]
293                 for f in vert.faces:
294                         if not f.flag and f.uv[f.verts.index(vert)]==uv:
295                                 f.flag = True
296                                 group.append(f)
297                 return group
298
299         def compute_normals(self):
300                 for v in self.verts:
301                         if v.faces:
302                                 v.no = Blender.Mathutils.Vector()
303                                 for f in v.faces:
304                                         v.no += f.no
305                                 v.no.normalize()
306                         else:
307                                 # XXX Should use edges to compute normal
308                                 v.no = Blender.Mathutils.Vector(0, 0, 1)
309
310         def compute_uv(self):
311                 for v in self.verts:
312                         if v.faces:
313                                 v.uv = v.faces[0].uv[v.faces[0].verts.index(v)]
314
315         def compute_tbn(self):
316                 for v in self.verts:
317                         v.tan = Blender.Mathutils.Vector()
318                         v.bino = Blender.Mathutils.Vector()
319                         for f in v.faces:
320                                 fverts = f.pivot_vertices(False, v)
321                                 v1 = fverts[1]
322                                 v2 = fverts[-1]
323                                 du1 = v1.uv[0]-v.uv[0]
324                                 du2 = v2.uv[0]-v.uv[0]
325                                 dv1 = v1.uv[1]-v.uv[1]
326                                 dv2 = v2.uv[1]-v.uv[1]
327                                 div = du1*dv2-du2*dv1
328                                 edge1 = fverts[1].co-fverts[0].co
329                                 edge2 = fverts[-1].co-fverts[0].co
330                                 v.tan += (edge1*dv2-edge2*dv1)/div
331                                 v.bino += (edge2*du1-edge1*du2)/div
332                         v.tan.normalize()
333                         v.bino.normalize()
334
335         def create_strip(self, face, max_len, debug):
336                 edge = None
337                 for e in face.edges:
338                         other = e.other_face(face)
339                         if other and not other.flag:
340                                 edge = e
341                                 break
342
343                 if not edge:
344                         return None
345
346                 if debug:
347                         print "Starting strip from %s, edge %s"%([v.index for v in face.verts], (edge.v1.index, edge.v2.index))
348
349                 verts = face.pivot_vertices(edge.v1, edge.v2)
350                 if len(verts)==3:
351                         result = [verts[-1], verts[0]]
352                 else:
353                         result = [verts[-2], verts[-1]]
354
355                 while 1:
356                         if debug:
357                                 print "  Adding %s"%face
358
359                         verts = face.pivot_vertices(*result[-2:])
360                         k = len(result)%2
361
362                         face.flag = True
363                         if len(verts)==4 and not k:
364                                 result.append(verts[3])
365                         result.append(verts[2])
366                         if len(verts)==4 and k:
367                                 result.append(verts[3])
368
369                         if len(result)>=max_len:
370                                 if debug:
371                                         print "  Max length exceeded"
372                                 break
373
374                         edge = face.get_edge(*result[-2:])
375
376                         if debug:
377                                 print "  Next edge is %s"%(edge.key, )
378
379                         next = edge.other_face(face)
380                         if not next or next.flag:
381                                 break
382                         face = next
383
384                 if debug:
385                         print "  %s"%[v.index for v in result]
386
387                 return result
388
389
390 class VertexCache:
391         def __init__(self, size):
392                 self.size = size
393                 self.slots = [-1]*self.size
394
395         def fetch(self, v):
396                 hit = v.index in self.slots
397                 if hit:
398                         self.slots.remove(v.index)
399                 self.slots.append(v.index)
400                 if not hit:
401                         del self.slots[0]
402                 return hit
403
404         def fetch_strip(self, strip):
405                 hits = 0
406                 for v in strip:
407                         if self.fetch(v):
408                                 hits += 1
409                 return hits
410
411         def test_strip(self, strip):
412                 hits = 0
413                 for i in range(len(strip)):
414                         if i>=self.size:
415                                 break
416                         if strip[i].index in self.slots[i:]:
417                                 hits += 1
418                 return hits
419
420
421 class OutFile:
422         def __init__(self, fn):
423                 if fn==None:
424                         self.file = sys.stdout
425                 else:
426                         self.file = open(fn, "w")
427                 self.indent = 0
428
429         def make(self, kwd, *params):
430                 pstr = ""
431                 for p in params:
432                         if type(p)==float:
433                                 pstr += " %.6g"%p
434                         else:
435                                 pstr += " %s"%p
436                 return "%s%s"%(kwd, pstr)
437
438         def write(self, kwd, *params):
439                 self.file.write("%s%s;\n"%('\t'*self.indent, self.make(kwd, *params)))
440
441         def begin(self, kwd, *params):
442                 i = '\t'*self.indent
443                 self.file.write("%s%s\n%s{\n"%(i, self.make(kwd, *params), i))
444                 self.indent += 1
445
446         def end(self):
447                 self.indent -= 1
448                 self.file.write("%s};\n"%('\t'*self.indent))
449
450
451 class Exporter:
452         def __init__(self, fn):
453                 self.out_file = OutFile(fn)
454                 self.use_strips = True
455                 self.use_degen_tris = True
456                 self.max_strip_len = 1024
457                 self.optimize_cache = False
458                 self.cache_size = 64
459                 self.export_lines = True
460                 self.tbn_vecs = False
461                 self.compound = False
462                 self.object = False
463                 self.material_tex = False
464                 self.debug = False
465                 self.strip_debug = False
466                 self.split_debug = False
467
468         def stripify(self, mesh):
469                 for f in mesh.faces:
470                         f.flag = False
471
472                 faces_done = 0
473                 strips = []
474                 loose = []
475
476                 cache = None
477                 if self.optimize_cache:
478                         cache = VertexCache(self.cache_size)
479
480                 island = []
481                 island_strips = []
482                 while 1:
483                         if not island:
484                                 queue = []
485                                 for f in mesh.faces:
486                                         if not f.flag:
487                                                 f.flag = True
488                                                 queue.append(f)
489                                                 break
490
491                                 if not queue:
492                                         break
493
494                                 while queue:
495                                         f = queue[0]
496                                         del queue[0]
497                                         island.append(f)
498
499                                         for e in f.edges:
500                                                 other = e.other_face(f)
501                                                 if other and not other.flag:
502                                                         other.flag = True
503                                                         queue.append(other)
504
505                                 for f in island:
506                                         f.flag = False
507
508                         best = 5
509                         face = None
510                         for f in island:
511                                 if f.flag:
512                                         continue
513                                 score = 0
514                                 for e in f.edges:
515                                         other = e.other_face(f)
516                                         if other and not other.flag:
517                                                 score += 1
518                                 if score>0 and score<best:
519                                         face = f
520                                         best = score
521
522                         if not face:
523                                 while island_strips:
524                                         best = 0
525                                         if cache:
526                                                 best_hits = 0
527                                                 for i in range(len(island_strips)):
528                                                         hits = cache.test_strip(island_strips[i])
529                                                         if hits>best_hits:
530                                                                 best = i
531                                                                 best_hits = hits
532
533                                         s = island_strips[best]
534                                         del island_strips[best]
535                                         strips.append(s)
536
537                                         if cache:
538                                                 cache.fetch_strip(s)
539
540                                 faces_done += len(island)
541                                 set_progress(float(faces_done)/len(mesh.faces))
542
543                                 loose += [f for f in island if not f.flag]
544                                 for f in island:
545                                         f.flag = True
546
547                                 island = []
548                                 island_strips = []
549                                 continue
550
551                         strip = mesh.create_strip(face, self.max_strip_len, self.strip_debug)
552                         if strip:
553                                 island_strips.append(strip)
554
555                 if self.debug:
556                         print "%d strips:"%len(strips)
557                         for i in range(len(strips)):
558                                 print "  %d: %d indices"%(i, len(strips[i]))
559                         print "%d loose faces"%len(loose)
560                         nind = sum([len(s) for s in strips])+sum([len(f.verts) for f in loose])
561                         print "%d indices total"%nind
562
563                 if cache:
564                         cache = VertexCache(self.cache_size)
565                         total_hits = 0
566
567                 if self.use_degen_tris and strips:
568                         big_strip = []
569
570                         for s in strips:
571                                 if big_strip:
572                                         glue = [big_strip[-1], s[0]]
573                                         if len(big_strip)%2:
574                                                 glue += [s[0]]
575
576                                         big_strip += glue
577                                         if cache:
578                                                 total_hits += cache.fetch_strip(glue)
579
580                                 big_strip += s
581                                 if cache:
582                                         total_hits += cache.fetch_strip(s)
583
584                         for f in loose:
585                                 if len(big_strip)%2:
586                                         order = (-1, -2, 0, 1)
587                                 else:
588                                         order = (0, 1, -1, -2)
589                                 verts = [f.verts[i] for i in order[:len(f.verts)]]
590
591                                 if big_strip:
592                                         glue = [big_strip[-1], verts[0]]
593                                         big_strip += glue
594                                         if cache:
595                                                 total_hits += cache.fetch_strip(glue)
596
597                                 big_strip += verts
598                                 if cache:
599                                         total_hits += cache.fetch_strip(verts)
600
601                         strips = [big_strip]
602                         loose = []
603                         
604                         if self.debug:
605                                 nind = len(big_strip)
606                                 print "Big strip has %d indices"%nind
607                                 if self.optimize_cache:
608                                         print "%d cache hits"%total_hits
609
610                 if self.debug:
611                         ntris = sum([len(f.verts)-2 for f in mesh.faces])
612                         print "%.2f indices per triangle"%(float(nind)/max(ntris, 1))
613
614                 return strips, loose
615
616         def export(self):
617                 scene = bpy.data.scenes.active
618
619                 objs = Blender.Object.GetSelected()
620                 if not objs:
621                         raise Exception, "Nothing to export"
622                 for o in objs:
623                         if o.getType()!="Mesh":
624                                 raise Exception, "Can only export Mesh data"
625
626                 Blender.Window.DrawProgressBar(0.0, "Preparing");
627
628                 mesh = Blender.Mesh.New("export_tmp")
629                 mesh.getFromObject(objs[0])
630                 mesh = Mesh(mesh)
631                 if self.compound:
632                         # Must keep a ref to each Blender mesh
633                         bmeshes = []
634                         for o in objs[1:]:
635                                 bmesh = Blender.Mesh.New("export_tmp")
636                                 bmesh.getFromObject(o)
637                                 bmeshes.append(bmesh)
638                                 mesh.splice(Mesh(bmesh))
639
640                 if self.debug:
641                         ntris = sum([len(f.verts)-2 for f in mesh.faces])
642                         print "Starting with %d vertices, %d faces (%d triangles) and %d edges"%(len(mesh.verts), len(mesh.faces), ntris, len(mesh.edges))
643
644                 set_progress_range(0.05, 0.35, "Smoothing")
645                 mesh.split_smooth(self.split_debug)
646
647                 if self.debug:
648                         print "After smooth splitting %d vertices and %d edges"%(len(mesh.verts), len(mesh.edges))
649
650                 mesh.compute_normals()
651
652                 if self.material_tex:
653                         mesh.generate_material_uv()
654
655                 if mesh.faceUV:
656                         set_progress_range(0.35, 0.65, "Splitting UVs")
657                         mesh.split_uv(self.split_debug)
658                         if self.debug:
659                                 print "After UV splitting %d vertices and %d edges"%(len(mesh.verts), len(mesh.edges))
660
661                         mesh.compute_uv()
662                         if self.tbn_vecs:
663                                 mesh.compute_tbn()
664
665                 set_progress_range(0.65, 0.95, "Creating strips")
666                 strips = []
667                 loose = mesh.faces
668                 if self.use_strips:
669                         strips, loose = self.stripify(mesh)
670
671                 Blender.Window.DrawProgressBar(0.95, "Writing file");
672
673                 if self.object:
674                         self.out_file.begin("mesh")
675
676                 fmt = "NORMAL3"
677                 if mesh.faceUV:
678                         fmt += "_TEXCOORD2"
679                         if self.tbn_vecs:
680                                 fmt += "_ATTRIB33_ATTRIB34"
681                 fmt += "_VERTEX3"
682                 self.out_file.begin("vertices", fmt)
683                 norm = None
684                 uv = None
685                 tan = None
686                 bino = None
687                 for v in mesh.verts:
688                         if v.no!=norm:
689                                 self.out_file.write("normal3", *v.no)
690                                 norm = v.no
691                         if v.uv!=uv:
692                                 self.out_file.write("texcoord2", *v.uv)
693                                 uv = v.uv
694                         if v.tan!=tan:
695                                 self.out_file.write("attrib3", 3, *v.tan)
696                                 tan = v.tan
697                         if v.bino!=bino:
698                                 self.out_file.write("attrib3", 4, *v.bino)
699                                 bino = v.bino
700                         self.out_file.write("vertex3", *v.co)
701                 self.out_file.end()
702                 for s in strips:
703                         self.out_file.begin("batch", "TRIANGLE_STRIP")
704                         indices = []
705                         n = 0
706                         for v in s:
707                                 indices.append(v.index)
708                                 if len(indices)>=32:
709                                         self.out_file.write("indices", *indices)
710                                         indices = []
711                         if indices:
712                                 self.out_file.write("indices", *indices)
713                         self.out_file.end()
714
715                 if loose:
716                         self.out_file.begin("batch", "TRIANGLES")
717                         for f in loose:
718                                 for i in range(2, len(f.verts)):
719                                         self.out_file.write("indices", f.verts[0].index, f.verts[i-1].index, f.verts[i].index)
720                         self.out_file.end()
721
722                 if self.export_lines and mesh.lines:
723                         self.out_file.write("batch", "LINES")
724                         for l in mesh.lines:
725                                 self.out_file.write("indices", l.verts[0].index, l.verts[1].index)
726                         self.out_file.end()
727
728                 if self.object:
729                         self.out_file.end()
730                         self.out_file.begin("technique")
731                         self.out_file.begin("pass", '""')
732                         if self.material_tex:
733                                 self.out_file.begin("material")
734                                 self.out_file.write("diffuse", 1.0, 1.0, 1.0, 1.0)
735                                 self.out_file.end()
736                                 self.out_file.begin("texunit", 0)
737                                 self.out_file.begin("texture2d")
738                                 self.out_file.write("min_filter", "NEAREST")
739                                 self.out_file.write("mag_filter", "NEAREST")
740                                 self.out_file.write("storage", "RGB", len(mesh.materials), 1)
741                                 texdata = '"'
742                                 for m in mesh.materials:
743                                         texdata += "\\x%02X\\x%02X\\x%02X"%(int(m.R*255), int(m.G*255), int(m.B*255))
744                                 texdata += '"'
745                                 self.out_file.write("raw_data", texdata)
746                                 self.out_file.end()
747                                 self.out_file.end()
748                         elif mesh.materials:
749                                 m = mesh.materials[0]
750                                 self.out_file.begin("material")
751                                 self.out_file.write("diffuse", m.R, m.G, m.B, 1.0)
752                                 self.out_file.write("ambient", m.R*m.amb, m.G*m.amb, m.B*m.amb, 1.0)
753                                 self.out_file.write("specular", m.specR*m.spec, m.specG*m.spec, m.specB*m.spec, 1.0)
754                                 self.out_file.write("shininess", m.hard);
755                                 self.out_file.end()
756                         self.out_file.end()
757                         self.out_file.end()
758
759                 Blender.Window.DrawProgressBar(1.0, "Done")
760
761
762 class FrontEnd:
763         def __init__(self):
764                 self.config = Blender.Registry.GetKey('mspgl_export', True) or {}
765                 self.temp_config = Blender.Registry.GetKey('mspgl_export_temp') or {}
766
767         def run(self):
768                 self.use_strips = Blender.Draw.Create(self.config.get('use_strips', True))
769                 self.use_degen_tris = Blender.Draw.Create(self.config.get('use_degen_tris', True))
770                 self.max_strip_len = Blender.Draw.Create(self.config.get('max_strip_len', 1024))
771                 self.optimize_cache = Blender.Draw.Create(self.config.get('optimize_cache', False))
772                 self.cache_size = Blender.Draw.Create(self.config.get('cache_size', 64))
773                 self.export_lines = Blender.Draw.Create(self.config.get('export_lines', False))
774                 self.tbn_vecs = Blender.Draw.Create(self.config.get('tbn_vecs', False))
775                 self.compound = Blender.Draw.Create(self.config.get('compound', False))
776                 self.object = Blender.Draw.Create(self.config.get('object', False))
777                 self.material_tex = Blender.Draw.Create(self.config.get('material_tex', False))
778                 self.debug = Blender.Draw.Create(self.config.get('debug', False))
779                 self.strip_debug = Blender.Draw.Create(self.config.get('strip_debug', False))
780                 self.split_debug = Blender.Draw.Create(self.config.get('split_debug', False))
781                 ret = Blender.Draw.PupBlock("Export MSP GL mesh",
782                         [("Use strips", self.use_strips, "Generage OpenGL triangle strips"),
783                                 ("Use degen tris", self.use_degen_tris, "Use degenerate triangles to combine triangle strips"),
784                                 ("Max strip len", self.max_strip_len, 4, 16384, "Maximum length of a triangle strip"),
785                                 ("Optimize cache", self.optimize_cache, "Optimize for vertex cache"),
786                                 ("Cache size", self.cache_size, 8, 1024, "Cache size to optimize for"),
787                                 ("Export lines", self.export_lines, "Export lone edges as lines"),
788                                 ("Compute T/B vecs", self.tbn_vecs, "Compute tangent/binormal vectors for bumpmapping"),
789                                 ("Compound", self.compound, "Create a compound mesh of all selected objects"),
790                                 ("Object", self.object, "Export as an object"),
791                                 ("Material texture", self.material_tex, "Create a texture from material data"),
792                                 ("Debugging options"),
793                                 ("Debug", self.debug),
794                                 ("Debug strips", self.strip_debug),
795                                 ("Debug splitting", self.split_debug)])
796                 if ret:
797                         dirname = self.temp_config.get("dirname", Blender.sys.dirname(Blender.Get("filename")))
798                         obj = Blender.Object.GetSelected()[0]
799                         ext = "mesh"
800                         if self.object.val:
801                                 ext = "object"
802                         Blender.Window.FileSelector(self.export, "Export MSP GL mesh", "%s/%s.%s"%(dirname, obj.name, ext))
803
804         def draw(self):
805                 pass
806
807         def export(self, fn):
808                 self.config['use_strips'] = self.use_strips.val
809                 self.config['use_degen_tris'] = self.use_degen_tris.val
810                 self.config['max_strip_len'] = self.max_strip_len.val
811                 self.config['optimize_cache'] = self.optimize_cache.val
812                 self.config['cache_size'] = self.cache_size.val
813                 self.config['export_lines'] = self.export_lines.val
814                 self.config['tbn_vecs'] = self.tbn_vecs.val
815                 self.config['compound'] = self.compound.val
816                 self.config['object'] = self.object.val
817                 self.config['material_tex'] = self.material_tex.val
818                 self.config['debug'] = self.debug.val
819                 self.config['strip_debug'] = self.strip_debug.val
820                 self.config['split_debug'] = self.split_debug.val
821                 Blender.Registry.SetKey('mspgl_export', self.config, True)
822
823                 import os
824                 self.temp_config["dirname"] = os.path.dirname(fn)
825                 Blender.Registry.SetKey('mspgl_export_temp', self.temp_config)
826
827                 exp = Exporter(fn)
828                 exp.use_strips = self.use_strips.val
829                 exp.use_degen_tris = self.use_degen_tris.val
830                 exp.max_strip_len = self.max_strip_len.val
831                 exp.optimize_cache = self.optimize_cache.val
832                 exp.cache_size = self.cache_size.val
833                 exp.export_lines = self.export_lines.val
834                 exp.tbn_vecs = self.tbn_vecs.val
835                 exp.compound = self.compound.val
836                 exp.object = self.object.val
837                 exp.material_tex = self.material_tex.val
838                 exp.debug = self.debug.val
839                 exp.strip_debug = self.strip_debug.val
840                 exp.split_debug = self.split_debug.val
841                 exp.export()
842
843
844 if __name__=="__main__":
845         fe = FrontEnd()
846         fe.run()