- def __init__(self):
- 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 = []
- 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 f.get_neighbors():
- if not n.flag:
- n.flag = True
- queue.append(n)
-
- # 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 f in island:
- if f.flag:
- continue
-
- score = sum(not n.flag for n in f.get_neighbors())
- 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)
+ def export_mesh(self, ctx, mesh_or_obj):
+ from .mesh import Mesh, create_mesh_from_object
+
+ if type(mesh_or_obj)==Mesh:
+ mesh = mesh_or_obj
+ else:
+ task = ctx.task("Preparing mesh", 0.9)
+ mesh = create_mesh_from_object(task, mesh_or_obj)
+
+ from .datafile import Resource, Statement, Token
+ resource = Resource(mesh.name+".mesh", "mesh")
+ statements = resource.statements
+
+ task = ctx.task("Creating statements", 1.0)
+
+ statements.append(Statement("winding", Token('COUNTERCLOCKWISE')))
+
+ st = Statement("vertices", Token("VERTEX3_FLOAT"))
+ stride = 12
+ if mesh.vertices[0].color:
+ st.append(Token("COLOR4_UBYTE"))
+ stride += 4
+ if mesh.uv_layers:
+ for u in mesh.uv_layers:
+ size = len(u.uvs[0])
+ min_val = min(*u.uvs[0])
+ max_val = max(*u.uvs[1])
+ for c in u.uvs:
+ min_val = min(min_val, *c)
+ max_val = max(max_val, *c)
+ uv_type = "USHORT" if min_val>=0.0 and max_val<=1.0 else "FLOAT"
+ if uv_type=="FLOAT" and stride%4:
+ pad = 4-stride%4
+ st.append(Token("PADDING{}".format(pad)))
+ stride += pad
+ if u.unit==0:
+ st.append(Token("TEXCOORD{}_{}".format(size, uv_type)))