修obj合并bug

This commit is contained in:
龙澳 2025-01-03 11:16:30 +08:00
parent 38db33b2c0
commit ffcd4ef8d5

View File

@ -111,40 +111,40 @@ class MergeObj:
self.logger.info(f"开始合并OBJ模型:\n输入1: {obj1_path}\n输入2: {obj2_path}") self.logger.info(f"开始合并OBJ模型:\n输入1: {obj1_path}\n输入2: {obj2_path}")
# 读取两个obj文件 # 读取两个obj文件
vertices1, tex_coords1, normals1, faces1, face_materials1, mtl1 = self.read_obj(obj1_path) vertices1, tex_coords1, normals1, faces1, face_materials1, mtl1 = self.read_obj(
vertices2, tex_coords2, normals2, faces2, face_materials2, mtl2 = self.read_obj(obj2_path) obj1_path)
vertices2, tex_coords2, normals2, faces2, face_materials2, mtl2 = self.read_obj(
obj2_path)
# 读取MTL文件内容以获取正确的材质名称 # 读取MTL文件内容以获取正确的材质名称
src_dir1 = os.path.dirname(obj1_path) src_dir1 = os.path.dirname(obj1_path)
src_dir2 = os.path.dirname(obj2_path) src_dir2 = os.path.dirname(obj2_path)
mtl1_path = os.path.join(src_dir1, mtl1) mtl1_path = os.path.join(src_dir1, mtl1)
mtl2_path = os.path.join(src_dir2, mtl2) mtl2_path = os.path.join(src_dir2, mtl2)
# 读取并更新材质内容 # 读取并更新材质内容
materials1 = self.read_mtl(mtl1_path) materials1 = self.read_mtl(mtl1_path)
materials2 = self.read_mtl(mtl2_path) materials2 = self.read_mtl(mtl2_path)
# 创建材质名称映射使用与MTL文件相同的命名格式 # 创建材质名称映射使用与MTL文件相同的命名格式
material_map1 = {} material_map1 = {}
material_map2 = {} material_map2 = {}
# 处理第一个模型的材质映射 # 处理第一个模型的材质映射
for old_name in materials1.keys(): for old_name in materials1.keys():
# 如果材质名称已经包含了网格ID前缀就不再添加 if "grid_0_0" in obj1_path:
if old_name.startswith(f"material_{grid_id1[0]}_{grid_id1[1]}_"):
material_map1[old_name] = old_name
else:
material_map1[old_name] = f"material_{grid_id1[0]}_{grid_id1[1]}_{old_name}" material_map1[old_name] = f"material_{grid_id1[0]}_{grid_id1[1]}_{old_name}"
else:
# 更新完一次后,之后就不用再更新了
material_map1[old_name] = old_name
# 处理第二个模型的材质映射 # 处理第二个模型的材质映射
for old_name in materials2.keys(): for old_name in materials2.keys():
if old_name.startswith(f"material_{grid_id2[0]}_{grid_id2[1]}_"): material_map2[old_name] = f"material_{grid_id2[0]}_{grid_id2[1]}_{old_name}"
material_map2[old_name] = old_name
else:
material_map2[old_name] = f"material_{grid_id2[0]}_{grid_id2[1]}_{old_name}"
# 平移第二个模型的顶点 # 平移第二个模型的顶点
vertices2_translated = self.translate_vertices(vertices2, translation) vertices2_translated = self.translate_vertices(
vertices2, translation)
# 计算偏移量 # 计算偏移量
v_offset = len(vertices1) v_offset = len(vertices1)
@ -159,23 +159,25 @@ class MergeObj:
# 调整第二个模型的面索引和材质名称 # 调整第二个模型的面索引和材质名称
all_faces = faces1.copy() all_faces = faces1.copy()
all_face_materials = [] all_face_materials = []
# 更新第一个模型的材质名称 # 更新第一个模型的材质名称
for material in face_materials1: for material in face_materials1:
all_face_materials.append(material_map1.get(material, material)) all_face_materials.append(material_map1.get(material))
# 更新第二个模型的面索引和材质名称 # 更新第二个模型的面索引和材质名称
for face, material in zip(faces2, face_materials2): for face, material in zip(faces2, face_materials2):
new_face_v = [f + v_offset for f in face[0]] new_face_v = [f + v_offset for f in face[0]]
new_face_vt = [f + vt_offset for f in face[1]] if face[1] else [] new_face_vt = [
new_face_vn = [f + vn_offset for f in face[2]] if face[2] else [] f + vt_offset for f in face[1]] if face[1] else []
new_face_vn = [
f + vn_offset for f in face[2]] if face[2] else []
all_faces.append((new_face_v, new_face_vt, new_face_vn)) all_faces.append((new_face_v, new_face_vt, new_face_vn))
all_face_materials.append(material_map2.get(material, material)) all_face_materials.append(material_map2.get(material))
# 写入合并后的obj文件使用与MTL文件相同的名称 # 写入合并后的obj文件使用与MTL文件相同的名称
mtl_filename = "merged_model.mtl" # 使用固定的MTL文件名 mtl_filename = "merged_model.mtl" # 使用固定的MTL文件名
self.write_obj(output_path, all_vertices, all_tex_coords, all_normals, self.write_obj(output_path, all_vertices, all_tex_coords, all_normals,
all_faces, all_face_materials, mtl_filename) all_faces, all_face_materials, mtl_filename)
self.logger.info(f"模型合并成功,已保存至: {output_path}") self.logger.info(f"模型合并成功,已保存至: {output_path}")
except Exception as e: except Exception as e:
@ -287,7 +289,8 @@ class MergeObj:
mtl_path = os.path.join(base_dir, "odm_textured_model_geo.mtl") mtl_path = os.path.join(base_dir, "odm_textured_model_geo.mtl")
if not os.path.exists(obj_path) or not os.path.exists(mtl_path): if not os.path.exists(obj_path) or not os.path.exists(mtl_path):
self.logger.warning(f"网格 ({grid_id[0]},{grid_id[1]}) 的文件不存在") self.logger.warning(
f"网格 ({grid_id[0]},{grid_id[1]}) 的文件不存在")
continue continue
grid_files[grid_id] = { grid_files[grid_id] = {
@ -309,7 +312,7 @@ class MergeObj:
output_model_dir, output_model_dir,
grid_id grid_id
) )
# 读取并更新MTL内容 # 读取并更新MTL内容
materials = self.read_mtl(files['mtl']) materials = self.read_mtl(files['mtl'])
updated_materials = self.update_mtl_content( updated_materials = self.update_mtl_content(
@ -344,15 +347,9 @@ class MergeObj:
) )
temp_files.append(temp_output) # 添加到临时文件列表 temp_files.append(temp_output) # 添加到临时文件列表
self.merge_two_objs(merged_obj, files['obj'], temp_output, translation, reference_id, grid_id) self.merge_two_objs(
merged_obj, files['obj'], temp_output, translation, reference_id, grid_id)
# 如果上一个merged_obj是临时文件则删除它
if merged_obj != grid_files[reference_id]['obj'] and os.path.exists(merged_obj):
try:
os.remove(merged_obj)
except Exception as e:
self.logger.warning(f"删除临时文件失败: {merged_obj}, 错误: {str(e)}")
merged_obj = temp_output merged_obj = temp_output
# 最终结果 # 最终结果
@ -375,7 +372,8 @@ class MergeObj:
try: try:
os.remove(temp_file) os.remove(temp_file)
except Exception as e: except Exception as e:
self.logger.warning(f"删除临时文件失败: {temp_file}, 错误: {str(e)}") self.logger.warning(
f"删除临时文件失败: {temp_file}, 错误: {str(e)}")
self.logger.info( self.logger.info(
f"模型合并完成,输出目录: {output_model_dir}\n" f"模型合并完成,输出目录: {output_model_dir}\n"