- def __init__(self):
- self.show_progress = True
- self.use_strips = True
- self.use_degen_tris = False
- self.max_strip_len = 1024
- self.optimize_cache = True
- self.cache_size = 64
- self.export_lines = False
- self.export_uv = "UNIT0"
- self.tbn_vecs = False
- self.tbn_uvtex = ""
- self.compound = False
- self.material_tex = False
- self.smoothing = "MSPGL"
- self.export_groups = False
- self.max_groups = 2
-
- def stripify(self, mesh, progress=None):
- for f in mesh.faces:
- f.flag = False
-
- faces_done = 0
- strips = []
- loose = []
-
- cache = None
- if self.optimize_cache:
- cache = VertexCache(self.cache_size)
-
- island = []
- face_neighbors = []
- island_strips = []
- while 1:
- if not island:
- # No current island; find any unused face to start from
- queue = []
- for f in mesh.faces:
- if not f.flag:
- f.flag = True
- queue.append(f)
- break
-
- if not queue:
- break
-
- # Find all faces connected to the first one
- while queue:
- face = queue.pop(0)
- island.append(face)
-
- for n in face.get_neighbors():
- if not n.flag:
- n.flag = True
- queue.append(n)
-
- face_neighbors = [f.get_neighbors() for f in island]
-
- # Unflag the island for the next phase
- for f in island:
- f.flag = False
-
- # Find an unused face with as few unused neighbors as possible, but
- # at least one. This heuristic gives a preference to faces in corners
- # or along borders of a non-closed island.
- best = 5
- face = None
- for i, f in enumerate(island):
- if f.flag:
- continue
-
- score = sum(not n.flag for n in face_neighbors[i])
- if score>0 and score<best:
- face = f
- best = score
-
- if face:
- # Create a strip starting from the face. This will flag the faces.
- strip = mesh.create_strip(face, self.max_strip_len)
- if strip:
- island_strips.append(strip)
- else:
- face.flag = True
- else:
- # Couldn't find a candidate face for starting a strip, so we're
- # done with this island
- while island_strips:
- best = 0
- if cache:
- # Find the strip that benefits the most from the current
- # contents of the vertex cache
- best_hits = 0
- for i in range(len(island_strips)):
- hits = cache.test_strip(island_strips[i])
- if hits>best_hits:
- best = i
- best_hits = hits
-
- strip = island_strips.pop(best)
- strips.append(strip)
-
- if cache:
- cache.fetch_strip(strip)
-
- faces_done += len(island)
- if progress:
- progress.set_progress(float(faces_done)/len(mesh.faces))
-
- # Collect any faces that weren't used in strips
- loose += [f for f in island if not f.flag]
- for f in island:
- f.flag = True
-
- island = []
- island_strips = []
-
- if cache:
- cache = VertexCache(self.cache_size)
- total_hits = 0
-
- if self.use_degen_tris and strips:
- big_strip = []
-
- for s in strips:
- if big_strip:
- # Generate glue elements, ensuring that the next strip begins at
- # an even position
- glue = [big_strip[-1], s[0]]
- if len(big_strip)%2:
- glue += [s[0]]
-
- big_strip += glue
- if cache:
- total_hits += cache.fetch_strip(glue)
-
- big_strip += s
- if cache:
- total_hits += cache.fetch_strip(s)
-
- for f in loose:
- # Add loose faces to the end. This wastes space, using five
- # elements per triangle and six elements per quad.
- if len(big_strip)%2:
- order = (-1, -2, 0, 1)
- else:
- order = (0, 1, -1, -2)
- vertices = [f.vertices[i] for i in order[:len(f.vertices)]]
-
- if big_strip:
- glue = [big_strip[-1], vertices[0]]
- big_strip += glue
- if cache:
- total_hits += cache.fetch_strip(glue)
-
- big_strip += vertices
- if cache:
- total_hits += cache.fetch_strip(vertices)
-
- strips = [big_strip]
- loose = []
-
- return strips, loose
-
- def export(self, context, out_file, objs=None, progress=None):
- if objs:
- objs = [(o, mathutils.Matrix()) for o in objs]
-
- if self.compound:
- if objs is None:
- objs = [(o, mathutils.Matrix()) for o in context.selected_objects]
- check = objs
- while check:
- children = []
- for o, m in check:
- for c in o.children:
- if c.compound:
- children.append((c, m*c.matrix_local))
- objs += children
- check = children
- elif objs is None:
- objs = [(context.active_object, mathutils.Matrix())]
-
- if not objs:
- raise Exception("Nothing to export")
- for o, m in objs:
- if o.type!="MESH":
- raise Exception("Can only export Mesh data")