class Batch:
def __init__(self, pt):
self.primitive_type = pt
+ self.patch_size = 0
self.vertices = []
self.use_uv = mesh.use_uv
self.tangent_uvtex = mesh.tangent_uvtex
self.use_strips = mesh.use_strips
+ self.use_patches = mesh.use_patches
self.use_lines = mesh.use_lines
self.vertex_groups = mesh.vertex_groups
# where they don't exist
edge_map = {e.key: e for e in self.edges}
for f in self.faces:
- if len(f.vertices)>4:
+ if len(f.vertices)>4 and not mesh.use.patches:
raise ValueError("Unsupported face on mesh {}: N-gon".format(self.name))
f.vertices = [self.vertices[i] for i in f.vertices]
v.edges.append(e)
# Store loose edges as lines
- if mesh.use_lines:
+ if mesh.use_lines and not mesh.use_patches:
self.lines = [Line(e) for e in self.edges if not e.faces]
else:
self.lines = []
self.lines += other.lines
def prepare_triangles(self, task):
+ if self.use_patches:
+ return
+
face_count = len(self.faces)
for i in range(face_count):
f = self.faces[i]
task.set_progress(i/len(self.vertices))
def prepare_sequence(self, task):
- subtask = task.task("Reordering faces", 0.5)
- self.reorder_faces(subtask)
+ if self.use_patches:
+ subtask = task.task("Reordering patches", 0.5)
+ self.reorder_patches(subtask)
- subtask = task.task("Building sequence", 1.0)
- if self.use_strips:
- self.build_tristrip_sequence(subtask)
+ subtask = task.task("Building sequence", 1.0)
+ self.build_patch_sequence(subtask)
else:
- self.build_triangle_sequence(subtask)
+ subtask = task.task("Reordering faces", 0.5)
+ self.reorder_faces(subtask)
+
+ subtask = task.task("Building sequence", 1.0)
+ if self.use_strips:
+ self.build_tristrip_sequence(subtask)
+ else:
+ self.build_triangle_sequence(subtask)
- if self.use_lines:
- self.build_line_sequence()
+ if self.use_lines:
+ self.build_line_sequence()
self.reorder_vertices()
batch.vertices += l.vertices
self.batches.append(batch)
- self.reorder_vertices()
+ def build_patch_sequence(self, task):
+ current_size = 0
+ sequence = None
+ for f in self.faces:
+ if len(f.vertices)!=current_size:
+ current_size = len(f.vertices)
+ self.batches.append(Batch("PATCHES"))
+ self.batches[-1].patch_size = current_size
+ sequence = self.batches[-1].vertices
+
+ sequence += f.vertices
def reorder_faces(self, task):
# Tom Forsyth's vertex cache optimization algorithm
for i, f in enumerate(self.faces):
f.index = i
+ def reorder_patches(self, task):
+ for f in self.faces:
+ f.flag = False
+
+ reordered_faces = []
+ n_processed = 0
+
+ while 1:
+ current_size = 0
+
+ for f in self.faces:
+ if f.flag:
+ continue
+
+ if not current_size:
+ current_size = len(f.vertices)
+ elif len(f.vertices)!=current_size:
+ continue
+
+ reordered_faces.append(f)
+ f.flag = True
+
+ n_processed += 1
+ task.set_progress(n_processed/len(self.faces))
+
+ if not current_size:
+ break
+
def reorder_vertices(self):
for v in self.vertices:
v.index = -1
mesh = context.active_object.data
self.layout.prop(mesh, "smoothing")
- self.layout.prop(mesh, "use_strips")
+ self.layout.prop(mesh, "use_patches")
+ if not mesh.use_patches:
+ self.layout.prop(mesh, "use_strips")
self.layout.separator()
col = self.layout.column()
col.label(text="Data selection")
- col.prop(mesh, "use_lines")
+ if not mesh.use_patches:
+ col.prop(mesh, "use_lines")
col.prop(mesh, "vertex_groups")
col.prop(mesh, "max_groups_per_vertex")
("MSPGL", "MspGL", "Compute vertex normals internally")))
bpy.types.Mesh.use_lines = bpy.props.BoolProperty(name="Include lines", description="Include edges without faces as lines", default=False)
bpy.types.Mesh.use_strips = bpy.props.BoolProperty(name="Use strips", description="Combine the mesh's triangles into triangle strips", default=True)
+ bpy.types.Mesh.use_patches = bpy.props.BoolProperty(name="Export as patches", description="Export faces as patches, suitable for tessellation", default=False)
bpy.types.Mesh.vertex_groups = bpy.props.BoolProperty(name="Vertex groups", description="Include vertex groups and weights", default=False)
bpy.types.Mesh.max_groups_per_vertex = bpy.props.IntProperty(name="Max groups", description="Maximum amount of groups per vertex", min=1, max=4, default=2)
bpy.types.Mesh.use_uv = bpy.props.EnumProperty(name="Use UV", description="Use UV coordinates", default="UNIT0",