mirror of https://github.com/AxioDL/metaforce.git
Much more optimal mesh optimizer
This commit is contained in:
parent
5d550cd21d
commit
87b86b7553
|
@ -216,103 +216,15 @@ def recursive_faces_islands(dlay, list_out, rem_list, skin_slot_set, skin_slot_c
|
||||||
next_faces.append(f)
|
next_faces.append(f)
|
||||||
return next_faces
|
return next_faces
|
||||||
|
|
||||||
def find_opposite_edge(face, boot_edge, boot_edge2, last_edge, last_edge_2):
|
def strip_next_loop(prev_loop, out_count):
|
||||||
if last_edge_2:
|
if out_count & 1:
|
||||||
for e in face.edges:
|
radial_loop = prev_loop.link_loop_radial_next
|
||||||
if e.verts[0] in last_edge_2.verts or e.verts[1] in last_edge_2.verts:
|
loop = radial_loop.link_loop_prev
|
||||||
continue
|
return loop, loop
|
||||||
return e
|
|
||||||
elif last_edge:
|
|
||||||
return boot_edge2
|
|
||||||
else:
|
else:
|
||||||
return boot_edge
|
radial_loop = prev_loop.link_loop_radial_prev
|
||||||
|
loop = radial_loop.link_loop_next
|
||||||
def recursive_faces_strip(list_out, rem_list, face, boot_edge, boot_edge_2, last_edge, last_edge_2):
|
return loop.link_loop_next, loop
|
||||||
if face not in rem_list:
|
|
||||||
return None, None, None
|
|
||||||
list_out.append(face)
|
|
||||||
rem_list.remove(face)
|
|
||||||
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
|
|
||||||
return f, edge, last_edge
|
|
||||||
return None, None, None
|
|
||||||
|
|
||||||
def count_contiguous_edges(face):
|
|
||||||
retval = 0
|
|
||||||
for e in face.edges:
|
|
||||||
if e.is_contiguous:
|
|
||||||
retval += 1
|
|
||||||
return retval
|
|
||||||
|
|
||||||
def find_loop_opposite_from_other_face(face, other_face):
|
|
||||||
for e in face.edges:
|
|
||||||
if e in other_face.edges:
|
|
||||||
edge = e
|
|
||||||
break
|
|
||||||
for l in face.loops:
|
|
||||||
if l.vert in edge.verts:
|
|
||||||
continue
|
|
||||||
return l
|
|
||||||
|
|
||||||
def stripify_primitive(writebuf, vert_pool, prim_faces, last_loop, next_idx):
|
|
||||||
if last_loop:
|
|
||||||
vert_pool.loop_out(writebuf, last_loop)
|
|
||||||
next_idx += 1
|
|
||||||
|
|
||||||
if len(prim_faces) == 1:
|
|
||||||
loop = prim_faces[0].loops[0]
|
|
||||||
if last_loop:
|
|
||||||
vert_pool.loop_out(writebuf, loop)
|
|
||||||
next_idx += 1
|
|
||||||
if next_idx & 1:
|
|
||||||
rev = True
|
|
||||||
else:
|
|
||||||
rev = False
|
|
||||||
for i in range(3):
|
|
||||||
vert_pool.loop_out(writebuf, loop)
|
|
||||||
last_loop = loop
|
|
||||||
next_idx += 1
|
|
||||||
if rev:
|
|
||||||
loop = loop.link_loop_prev
|
|
||||||
else:
|
|
||||||
loop = loop.link_loop_next
|
|
||||||
return last_loop, next_idx
|
|
||||||
|
|
||||||
loop = find_loop_opposite_from_other_face(prim_faces[0], prim_faces[1])
|
|
||||||
if last_loop:
|
|
||||||
vert_pool.loop_out(writebuf, loop)
|
|
||||||
next_idx += 1
|
|
||||||
if next_idx & 1:
|
|
||||||
rev = True
|
|
||||||
else:
|
|
||||||
rev = False
|
|
||||||
for i in range(3):
|
|
||||||
vert_pool.loop_out(writebuf, loop)
|
|
||||||
last_loop = loop
|
|
||||||
next_idx += 1
|
|
||||||
if rev:
|
|
||||||
loop = loop.link_loop_prev
|
|
||||||
else:
|
|
||||||
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
|
|
||||||
next_idx += 1
|
|
||||||
|
|
||||||
return last_loop, next_idx
|
|
||||||
|
|
||||||
|
|
||||||
def write_out_surface(writebuf, vert_pool, island_faces, mat_idx):
|
def write_out_surface(writebuf, vert_pool, island_faces, mat_idx):
|
||||||
|
|
||||||
|
@ -350,43 +262,53 @@ def write_out_surface(writebuf, vert_pool, island_faces, mat_idx):
|
||||||
writebuf(struct.pack('I', len(island_faces) * 3))
|
writebuf(struct.pack('I', len(island_faces) * 3))
|
||||||
|
|
||||||
# Verts themselves
|
# Verts themselves
|
||||||
last_loop = None
|
prev_loop_emit = None
|
||||||
next_idx = 0
|
out_count = 0
|
||||||
while len(island_faces):
|
while len(island_faces):
|
||||||
sel_lists_local = []
|
sel_lists_local = []
|
||||||
|
restore_out_count = out_count
|
||||||
for start_face in island_faces:
|
for start_face in island_faces:
|
||||||
for e in start_face.edges:
|
for l in start_face.loops:
|
||||||
next_edges = []
|
out_count = restore_out_count
|
||||||
for f in e.link_faces:
|
|
||||||
if f == start_face:
|
|
||||||
continue
|
|
||||||
for eg in f.edges:
|
|
||||||
if eg == e:
|
|
||||||
continue
|
|
||||||
next_edges.append(eg)
|
|
||||||
break
|
|
||||||
if len(next_edges) == 0:
|
|
||||||
next_edges.append(None)
|
|
||||||
for e2 in next_edges:
|
|
||||||
island_local = list(island_faces)
|
island_local = list(island_faces)
|
||||||
sel_list = []
|
if out_count & 1:
|
||||||
next_face = start_face
|
prev_loop = l.link_loop_prev
|
||||||
last_edge = None
|
loop = prev_loop.link_loop_prev
|
||||||
last_edge_2 = None
|
sel_list = [l, prev_loop, loop]
|
||||||
while next_face is not None:
|
prev_loop = loop
|
||||||
next_face, last_edge, last_edge_2 = recursive_faces_strip(sel_list, island_local, next_face,
|
else:
|
||||||
e, e2, last_edge, last_edge_2)
|
prev_loop = l.link_loop_next
|
||||||
if len(sel_list):
|
loop = prev_loop.link_loop_next
|
||||||
sel_lists_local.append(sel_list)
|
sel_list = [l, prev_loop, loop]
|
||||||
|
out_count += 3
|
||||||
|
island_local.remove(start_face)
|
||||||
|
while True:
|
||||||
|
if not prev_loop.edge.is_contiguous or prev_loop.edge.tag:
|
||||||
|
break
|
||||||
|
loop, prev_loop = strip_next_loop(prev_loop, out_count)
|
||||||
|
face = loop.face
|
||||||
|
if face not in island_local:
|
||||||
|
break
|
||||||
|
sel_list.append(loop)
|
||||||
|
island_local.remove(face)
|
||||||
|
out_count += 1
|
||||||
|
sel_lists_local.append((sel_list, island_local, out_count))
|
||||||
max_count = 0
|
max_count = 0
|
||||||
max_sl = None
|
max_sl = None
|
||||||
|
max_island_faces = None
|
||||||
for sl in sel_lists_local:
|
for sl in sel_lists_local:
|
||||||
if len(sl) > max_count:
|
if len(sl[0]) > max_count:
|
||||||
max_count = len(sl)
|
max_count = len(sl[0])
|
||||||
max_sl = sl
|
max_sl = sl[0]
|
||||||
for f in max_sl:
|
max_island_faces = sl[1]
|
||||||
island_faces.remove(f)
|
out_count = sl[2]
|
||||||
last_loop, next_idx = stripify_primitive(writebuf, vert_pool, max_sl, last_loop, next_idx)
|
island_faces = max_island_faces
|
||||||
|
if prev_loop_emit:
|
||||||
|
vert_pool.loop_out(writebuf, prev_loop_emit)
|
||||||
|
vert_pool.loop_out(writebuf, max_sl[0])
|
||||||
|
for loop in max_sl:
|
||||||
|
vert_pool.loop_out(writebuf, loop)
|
||||||
|
prev_loop_emit = loop
|
||||||
|
|
||||||
writebuf(struct.pack('B', 0))
|
writebuf(struct.pack('B', 0))
|
||||||
|
|
||||||
|
|
|
@ -128,25 +128,10 @@ def cook(writebuf, mesh_obj, max_skin_banks, max_octant_length=None):
|
||||||
bm_master.from_mesh(copy_mesh)
|
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
|
# Tag edges where there are distinctive loops
|
||||||
splittable_edges = []
|
splittable_edges = []
|
||||||
for e in bm_master.edges:
|
for e in bm_master.edges:
|
||||||
if vert_pool.splitable_edge(e):
|
e.tag = 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 = []
|
||||||
|
@ -262,12 +247,10 @@ 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):
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 1601abcc7a4261ca0d6822729aec683fb39f2c9e
|
Subproject commit e8616914801e274155bfe8d9fe3353448f0ec219
|
Loading…
Reference in New Issue