使用trimesh合并网格并导出OBJ后纹理损坏问题求助
解决Trimesh合并网格后纹理损坏的问题
合并网格后纹理损坏,核心原因是UV坐标丢失、材质ID冲突、纹理路径未正确关联这几点,以下是针对性的解决步骤和修改后的代码:
关键修复点
保留原始网格的UV与材质信息
加载网格时禁用自动处理,避免trimesh默认的简化操作破坏UV坐标和材质数据。偏移材质ID避免冲突
不同网格的材质ID可能重复,合并后会导致纹理映射混乱,需要给每个网格的材质ID加上之前所有网格的材质总数作为偏移量。导出时关联材质文件
OBJ文件依赖.mtl文件存储纹理信息,导出时需确保生成对应的材质文件,并修正纹理路径为可访问的相对路径。
修改后的完整代码
import trimesh import glob import os import shutil # 初始化全局材质列表与偏移量 materials = [] material_offset = 0 meshs = [] # 遍历处理每个网格 for file_path, size, translation, rotation_angle in zip(file_paths, size_data, translation_data, rotation_angles): obj_path = '/home/om/Project/3D-FUTURE-model/*/raw_model.obj'.replace('*', file_path) obj_files = glob.glob(obj_path) if len(obj_files) == 1: # 禁用自动处理,保留原始UV、材质信息 mesh = trimesh.load_mesh(obj_files[0], process=False) # 应用旋转变换与平移 rotation_matrix = trimesh.transformations.rotation_matrix(rotation_angle, rotation_axis) mesh.apply_transform(rotation_matrix) mesh.apply_translation(translation) # 处理材质ID偏移与纹理路径 if isinstance(mesh.visual, trimesh.visual.TextureVisual): # 偏移当前网格的材质ID if hasattr(mesh.visual, 'face_materials'): mesh.visual.face_materials += material_offset # 复制纹理到目标目录并修正路径 for mat in mesh.visual.material: if hasattr(mat, 'texture') and mat.texture is not None: tex_path = mat.texture.image_path if tex_path and os.path.exists(tex_path): dest_tex = os.path.join(room_directory, os.path.basename(tex_path)) shutil.copy(tex_path, dest_tex) mat.texture.image_path = os.path.basename(tex_path) # 收集材质到全局列表 materials.extend(mesh.visual.material) material_offset += len(mesh.visual.material) meshs.append(mesh) # 合并所有网格 merged_mesh = trimesh.util.concatenate(meshs) # 更新合并后网格的材质 if materials: merged_mesh.visual.material = materials # 导出OBJ与关联的MTL文件 merged_mesh.export(os.path.join(room_directory, 'merged.obj'), include_materials=True)
额外注意事项
- 如果部分网格是纯色材质(非纹理),需确保
trimesh能正确识别并合并这类材质,避免视觉异常。 - 若合并后仍有纹理问题,可检查每个网格的
mesh.visual类型,确认是TextureVisual而非ColorVisual(后者无纹理信息)。
内容的提问来源于stack exchange,提问作者Omar Mobarak
相关产品推荐
相关产品推荐

