Work on mesh generation

This commit is contained in:
Jack Andersen 2015-10-19 19:02:30 -10:00
parent 3a4647e4c3
commit 5900c39ea0
2 changed files with 95 additions and 11 deletions

View File

@ -11,6 +11,7 @@ class VertPool:
# Initialize hash-unique index for each available attribute
def __init__(self, bm, rna_loops):
self.bm = bm
self.rna_loops = rna_loops
self.pos = {}
self.norm = {}
@ -123,6 +124,36 @@ class VertPool:
uf = loop[self.ulays[uidx]].uv.copy().freeze()
return self.uv[uf]
def loops_contiguous(self, la, lb):
if la.vert != lb.vert:
return False
if self.get_norm_idx(la) != self.get_norm_idx(lb):
return False
for cl in range(len(self.clays)):
if self.get_color_idx(la, cl) != self.get_color_idx(lb, cl):
return False
for ul in range(len(self.ulays)):
if self.get_uv_idx(la, ul) != self.get_uv_idx(lb, ul):
return False
return True
def splitable_edge(self, edge):
if len(edge.link_faces) < 2:
return False
for v in edge.verts:
found = None
for f in edge.link_faces:
for l in f.loops:
if l.vert == v:
if not found:
found = l
break
else:
if not self.loops_contiguous(found, l):
return True
break
return False
def loop_out(self, writebuf, loop):
writebuf(struct.pack('B', 1))
writebuf(struct.pack('II', self.get_pos_idx(loop.vert), self.get_norm_idx(loop)))
@ -204,6 +235,7 @@ def recursive_faces_strip(list_out, rem_list, face, boot_edge, boot_edge_2, last
edge = find_opposite_edge(face, boot_edge, boot_edge_2, last_edge, last_edge_2)
if not edge:
return None, None, None
edge.select = True
for f in edge.link_faces:
if f == face:
continue
@ -269,6 +301,11 @@ def stripify_primitive(writebuf, vert_pool, prim_faces, last_loop, next_idx):
loop = loop.link_loop_next
for i in range(1, len(prim_faces)):
if prim_faces[i].index == 688:
print(prim_faces[i], prim_faces[i-1], prim_faces[i-2])
#prim_faces[i].select = True
#prim_faces[i-1].select = True
#prim_faces[i-2].select = True
loop = find_loop_opposite_from_other_face(prim_faces[i], prim_faces[i-1])
vert_pool.loop_out(writebuf, loop)
last_loop = loop

View File

@ -109,6 +109,7 @@ def cook(writebuf, mesh_obj, max_skin_banks, max_octant_length=None):
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.quads_convert_to_tris()
bpy.ops.mesh.select_all(action='DESELECT')
bpy.context.scene.update()
bpy.ops.object.mode_set(mode='OBJECT')
rna_loops = None
@ -124,9 +125,29 @@ def cook(writebuf, mesh_obj, max_skin_banks, max_octant_length=None):
# Create master BMesh and VertPool
bm_master = bmesh.new()
bm_master.from_mesh(copy_obj.data)
bm_master.from_mesh(copy_mesh)
vert_pool = HMDLMesh.VertPool(bm_master, rna_loops)
# Split edges where there are distinctive loops
splittable_edges = []
for e in bm_master.edges:
if vert_pool.splitable_edge(e):
#splittable_edges.append(e)
e.seam = True
#bmesh.ops.split(bm_master, geom=splittable_edges)
bm_master.to_mesh(copy_mesh)
bpy.context.scene.objects.active = copy_obj
return
if copy_mesh.has_custom_normals:
copy_mesh.calc_normals_split()
rna_loops = copy_mesh.loops
bpy.ops.object.mode_set(mode='EDIT')
bm_master = bmesh.from_edit_mesh(copy_mesh)
vert_pool = HMDLMesh.VertPool(bm_master, rna_loops)
# Sort materials by pass index first
sorted_material_idxs = []
source_mat_set = set(range(len(mesh_obj.data.materials)))
@ -143,20 +164,23 @@ def cook(writebuf, mesh_obj, max_skin_banks, max_octant_length=None):
if mesh_obj.data.hecl_material_count > 0:
writebuf(struct.pack('I', mesh_obj.data.hecl_material_count))
for grp_idx in range(mesh_obj.data.hecl_material_count):
writebuf(struct.pack('I', len(sorted_material_idxs)))
for mat_idx in sorted_material_idxs:
writebuf(struct.pack('I', len(mesh_obj.data.materials)))
for ref_mat in mesh_obj.data.materials:
ref_mat_split = ref_mat.name.split('_')
if len(ref_mat_split) != 3:
raise RuntimeError('material names must follow MAT_%u_%u format')
ref_mat_idx = int(ref_mat_split[2])
found = False
for mat in bpy.data.materials:
if mat.name.endswith('_%u_%u' % (grp_idx, mat_idx)):
if mat.name.endswith('_%u_%u' % (grp_idx, ref_mat_idx)):
write_out_material(writebuf, mat, mesh_obj)
found = True
break
if not found:
raise RuntimeError('uneven material set %d in %s' % (grp_idx, mesh_obj.name))
else:
writebuf(struct.pack('II', 1, len(sorted_material_idxs)))
for mat_idx in sorted_material_idxs:
mat = mesh_obj.data.materials[mat_idx]
writebuf(struct.pack('II', 1, len(mesh_obj.data.materials)))
for mat in mesh_obj.data.materials:
write_out_material(writebuf, mat, mesh_obj)
# Output vert pool
@ -238,10 +262,12 @@ def cook(writebuf, mesh_obj, max_skin_banks, max_octant_length=None):
writebuf(struct.pack('B', 0))
# Delete copied mesh from scene
bm_master.free()
bpy.context.scene.objects.unlink(copy_obj)
bpy.data.objects.remove(copy_obj)
bpy.data.meshes.remove(copy_mesh)
#bm_master.free()
#bpy.context.scene.objects.unlink(copy_obj)
#bpy.data.objects.remove(copy_obj)
#bpy.data.meshes.remove(copy_mesh)
bpy.context.scene.objects.active = copy_obj
def draw(layout, context):
@ -268,6 +294,25 @@ def material_update(self, context):
if mat.name.endswith('_%u_%u' % (target_idx, mat_idx)):
self.materials[mat_idx] = mat
def fake_writebuf(by):
pass
# DEBUG operator
import bpy
class hecl_mesh_operator(bpy.types.Operator):
bl_idname = "scene.hecl_mesh"
bl_label = "DEBUG HECL mesh maker"
bl_description = "Test mesh generation utility"
@classmethod
def poll(cls, context):
return context.object and context.object.type == 'MESH'
def execute(self, context):
cook(fake_writebuf, context.object, -1)
return {'FINISHED'}
import bpy
def register():
bpy.types.Scene.hecl_mesh_obj = bpy.props.StringProperty(
@ -279,7 +324,9 @@ def register():
bpy.types.Mesh.hecl_material_count = bpy.props.IntProperty(name='HECL Material Count', default=0, min=0)
bpy.types.Mesh.hecl_active_material = bpy.props.IntProperty(name='HECL Active Material', default=0, min=0, update=material_update)
bpy.utils.register_class(HMDLShader.hecl_shader_operator)
bpy.utils.register_class(hecl_mesh_operator)
pass
def unregister():
bpy.utils.unregister_class(HMDLShader.hecl_shader_operator)
bpy.utils.unregister_class(hecl_mesh_operator)
pass