Catch segments with no valid geometry, read NDXL in try-except block

This commit is contained in:
William Herald Snyder 2022-01-20 23:40:19 -05:00
parent 7fe5b48d0b
commit 637c3c2afa
2 changed files with 45 additions and 25 deletions

View File

@ -323,18 +323,22 @@ def _read_segm(segm: Reader, materials_list: List[Material]) -> GeometrySegment:
for _ in range(num_texcoords): for _ in range(num_texcoords):
geometry_seg.texcoords.append(Vector(uv0l.read_f32(2))) geometry_seg.texcoords.append(Vector(uv0l.read_f32(2)))
# TODO: Can't remember exact issue here... # TODO: Can't remember exact issue here, but this chunk sometimes fails
elif next_header == "NDXL": elif next_header == "NDXL":
with segm.read_child() as ndxl: with segm.read_child() as ndxl:
pass
'''
num_polygons = ndxl.read_u32()
for _ in range(num_polygons): try:
polygon = ndxl.read_u16(ndxl.read_u16()) num_polygons = ndxl.read_u32()
geometry_seg.polygons.append(polygon)
''' for _ in range(num_polygons):
num_inds = ndxl.read_u16()
polygon = ndxl.read_u16(num_inds)
geometry_seg.polygons.append(polygon)
except:
print("Failed to read polygon list!")
geometry_seg.polygons = []
elif next_header == "NDXT": elif next_header == "NDXT":
with segm.read_child() as ndxt: with segm.read_child() as ndxt:

View File

@ -104,6 +104,8 @@ def extract_and_apply_anim(filename : str, scene : Scene):
# Create the msh hierachy. Armatures are not created here. Much of this could use some optimization... # Create the msh hierachy. Armatures are not created here. Much of this could use some optimization...
# TODO: Replace with an approach informed by existing Blender addons (io_scene_obj e.g.)
def extract_models(scene: Scene, materials_map : Dict[str, bpy.types.Material]) -> Dict[str, bpy.types.Object]: def extract_models(scene: Scene, materials_map : Dict[str, bpy.types.Material]) -> Dict[str, bpy.types.Object]:
# This will be filled with model names -> Blender objects and returned # This will be filled with model names -> Blender objects and returned
@ -128,22 +130,34 @@ def extract_models(scene: Scene, materials_map : Dict[str, bpy.types.Material])
face_range_to_material_index = [] face_range_to_material_index = []
materials_to_use = []
segment_index = 0
if model.geometry: if model.geometry:
#if model.collisionprimitive is None: def validate_segment(segment : GeometrySegment):
# print(f"On model: {model.name}") if not segment.positions:
return False
if not segment.triangles and not segment.triangle_strips and not segment.polygons:
return False
if not segment.material_name:
return False
return True
for i,seg in enumerate(model.geometry):
for seg in model.geometry:
if not validate_segment(seg):
continue
verts += [tuple(convert_vector_space(v)) for v in seg.positions] verts += [tuple(convert_vector_space(v)) for v in seg.positions]
#if model.collisionprimitive is None: materials_to_use.append(seg.material_name)
# print("Importing segment with material: {} with and {} verts".format(seg.material_name, len(seg.positions)))
if seg.weights: if seg.weights:
weights_offsets[offset] = seg.weights weights_offsets[offset] = seg.weights
if seg.texcoords is not None: if seg.texcoords:
full_texcoords += seg.texcoords full_texcoords += seg.texcoords
else: else:
full_texcoords += [(0.0,0.0) for _ in range(len(seg.positions))] full_texcoords += [(0.0,0.0) for _ in range(len(seg.positions))]
@ -152,17 +166,22 @@ def extract_models(scene: Scene, materials_map : Dict[str, bpy.types.Material])
if seg.triangles: if seg.triangles:
faces += [tuple([ind + offset for ind in tri]) for tri in seg.triangles] faces += [tuple([ind + offset for ind in tri]) for tri in seg.triangles]
else: elif seg.triangle_strips:
for strip in seg.triangle_strips: for strip in seg.triangle_strips:
for i in range(len(strip) - 2): for i in range(len(strip) - 2):
face = tuple([offset + strip[j] for j in range(i,i+3)]) face = tuple([offset + strip[j] for j in range(i,i+3)])
faces.append(face) faces.append(face)
elif seg.polygons:
faces += [tuple([ind + offset for ind in polygon]) for polygon in seg.polygons]
face_range_upper = len(faces) face_range_upper = len(faces)
face_range_to_material_index.append((face_range_lower, face_range_upper, i)) face_range_to_material_index.append((face_range_lower, face_range_upper, segment_index))
offset += len(seg.positions) offset += len(seg.positions)
segment_index += 1
new_mesh.from_pydata(verts, [], faces) new_mesh.from_pydata(verts, [], faces)
new_mesh.update() new_mesh.update()
new_mesh.validate() new_mesh.validate()
@ -185,9 +204,8 @@ def extract_models(scene: Scene, materials_map : Dict[str, bpy.types.Material])
edit_mesh_face.material_index = ind edit_mesh_face.material_index = ind
for i,loop in enumerate(edit_mesh_face.loops): for i,loop in enumerate(edit_mesh_face.loops):
texcoord = full_texcoords[mesh_face[i]] texcoord = full_texcoords[mesh_face[i]]
loop[uvlayer].uv = tuple([texcoord.x, texcoord.y]) loop[uvlayer].uv = tuple([texcoord[0], texcoord[1]])
edit_mesh.to_mesh(new_mesh) edit_mesh.to_mesh(new_mesh)
edit_mesh.free() edit_mesh.free()
@ -213,11 +231,9 @@ def extract_models(scene: Scene, materials_map : Dict[str, bpy.types.Material])
''' '''
Assign Material slots Assign Material slots
''' '''
if model.geometry: for material_name in materials_to_use:
for seg in model.geometry: material = materials_map[material_name]
if seg.material_name: new_obj.data.materials.append(material)
material = materials_map[seg.material_name]
new_obj.data.materials.append(material)
else: else: