mirror of https://github.com/AxioDL/metaforce.git
Work on mesh generation
This commit is contained in:
parent
3a4647e4c3
commit
5900c39ea0
|
@ -11,6 +11,7 @@ class VertPool:
|
||||||
|
|
||||||
# Initialize hash-unique index for each available attribute
|
# Initialize hash-unique index for each available attribute
|
||||||
def __init__(self, bm, rna_loops):
|
def __init__(self, bm, rna_loops):
|
||||||
|
self.bm = bm
|
||||||
self.rna_loops = rna_loops
|
self.rna_loops = rna_loops
|
||||||
self.pos = {}
|
self.pos = {}
|
||||||
self.norm = {}
|
self.norm = {}
|
||||||
|
@ -123,6 +124,36 @@ class VertPool:
|
||||||
uf = loop[self.ulays[uidx]].uv.copy().freeze()
|
uf = loop[self.ulays[uidx]].uv.copy().freeze()
|
||||||
return self.uv[uf]
|
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):
|
def loop_out(self, writebuf, loop):
|
||||||
writebuf(struct.pack('B', 1))
|
writebuf(struct.pack('B', 1))
|
||||||
writebuf(struct.pack('II', self.get_pos_idx(loop.vert), self.get_norm_idx(loop)))
|
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)
|
edge = find_opposite_edge(face, boot_edge, boot_edge_2, last_edge, last_edge_2)
|
||||||
if not edge:
|
if not edge:
|
||||||
return None, None, None
|
return None, None, None
|
||||||
|
edge.select = True
|
||||||
for f in edge.link_faces:
|
for f in edge.link_faces:
|
||||||
if f == face:
|
if f == face:
|
||||||
continue
|
continue
|
||||||
|
@ -269,6 +301,11 @@ def stripify_primitive(writebuf, vert_pool, prim_faces, last_loop, next_idx):
|
||||||
loop = loop.link_loop_next
|
loop = loop.link_loop_next
|
||||||
|
|
||||||
for i in range(1, len(prim_faces)):
|
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])
|
loop = find_loop_opposite_from_other_face(prim_faces[i], prim_faces[i-1])
|
||||||
vert_pool.loop_out(writebuf, loop)
|
vert_pool.loop_out(writebuf, loop)
|
||||||
last_loop = loop
|
last_loop = loop
|
||||||
|
|
|
@ -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.object.mode_set(mode='EDIT')
|
||||||
bpy.ops.mesh.select_all(action='SELECT')
|
bpy.ops.mesh.select_all(action='SELECT')
|
||||||
bpy.ops.mesh.quads_convert_to_tris()
|
bpy.ops.mesh.quads_convert_to_tris()
|
||||||
|
bpy.ops.mesh.select_all(action='DESELECT')
|
||||||
bpy.context.scene.update()
|
bpy.context.scene.update()
|
||||||
bpy.ops.object.mode_set(mode='OBJECT')
|
bpy.ops.object.mode_set(mode='OBJECT')
|
||||||
rna_loops = None
|
rna_loops = None
|
||||||
|
@ -124,9 +125,29 @@ def cook(writebuf, mesh_obj, max_skin_banks, max_octant_length=None):
|
||||||
|
|
||||||
# Create master BMesh and VertPool
|
# Create master BMesh and VertPool
|
||||||
bm_master = bmesh.new()
|
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)
|
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
|
# Sort materials by pass index first
|
||||||
sorted_material_idxs = []
|
sorted_material_idxs = []
|
||||||
source_mat_set = set(range(len(mesh_obj.data.materials)))
|
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:
|
if mesh_obj.data.hecl_material_count > 0:
|
||||||
writebuf(struct.pack('I', mesh_obj.data.hecl_material_count))
|
writebuf(struct.pack('I', mesh_obj.data.hecl_material_count))
|
||||||
for grp_idx in range(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)))
|
writebuf(struct.pack('I', len(mesh_obj.data.materials)))
|
||||||
for mat_idx in sorted_material_idxs:
|
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
|
found = False
|
||||||
for mat in bpy.data.materials:
|
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)
|
write_out_material(writebuf, mat, mesh_obj)
|
||||||
found = True
|
found = True
|
||||||
break
|
break
|
||||||
if not found:
|
if not found:
|
||||||
raise RuntimeError('uneven material set %d in %s' % (grp_idx, mesh_obj.name))
|
raise RuntimeError('uneven material set %d in %s' % (grp_idx, mesh_obj.name))
|
||||||
else:
|
else:
|
||||||
writebuf(struct.pack('II', 1, len(sorted_material_idxs)))
|
writebuf(struct.pack('II', 1, len(mesh_obj.data.materials)))
|
||||||
for mat_idx in sorted_material_idxs:
|
for mat in mesh_obj.data.materials:
|
||||||
mat = mesh_obj.data.materials[mat_idx]
|
|
||||||
write_out_material(writebuf, mat, mesh_obj)
|
write_out_material(writebuf, mat, mesh_obj)
|
||||||
|
|
||||||
# Output vert pool
|
# Output vert pool
|
||||||
|
@ -238,10 +262,12 @@ def cook(writebuf, mesh_obj, max_skin_banks, max_octant_length=None):
|
||||||
writebuf(struct.pack('B', 0))
|
writebuf(struct.pack('B', 0))
|
||||||
|
|
||||||
# Delete copied mesh from scene
|
# Delete copied mesh from scene
|
||||||
bm_master.free()
|
#bm_master.free()
|
||||||
bpy.context.scene.objects.unlink(copy_obj)
|
#bpy.context.scene.objects.unlink(copy_obj)
|
||||||
bpy.data.objects.remove(copy_obj)
|
#bpy.data.objects.remove(copy_obj)
|
||||||
bpy.data.meshes.remove(copy_mesh)
|
#bpy.data.meshes.remove(copy_mesh)
|
||||||
|
|
||||||
|
bpy.context.scene.objects.active = copy_obj
|
||||||
|
|
||||||
|
|
||||||
def draw(layout, context):
|
def draw(layout, context):
|
||||||
|
@ -268,6 +294,25 @@ def material_update(self, context):
|
||||||
if mat.name.endswith('_%u_%u' % (target_idx, mat_idx)):
|
if mat.name.endswith('_%u_%u' % (target_idx, mat_idx)):
|
||||||
self.materials[mat_idx] = mat
|
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
|
import bpy
|
||||||
def register():
|
def register():
|
||||||
bpy.types.Scene.hecl_mesh_obj = bpy.props.StringProperty(
|
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_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.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(HMDLShader.hecl_shader_operator)
|
||||||
|
bpy.utils.register_class(hecl_mesh_operator)
|
||||||
pass
|
pass
|
||||||
def unregister():
|
def unregister():
|
||||||
bpy.utils.unregister_class(HMDLShader.hecl_shader_operator)
|
bpy.utils.unregister_class(HMDLShader.hecl_shader_operator)
|
||||||
|
bpy.utils.unregister_class(hecl_mesh_operator)
|
||||||
pass
|
pass
|
||||||
|
|
Loading…
Reference in New Issue