Open3D使用read_triangle_mesh读obj报ASSIMP加载失败问题咨询
异常表现
- 执行代码
mesh = o3d.io.read_triangle_mesh("data/1.obj")读取目标obj网格时,控制台抛出告警:[Open3D WARNING] Unable to load file data/1.obj with ASSIMP,最终返回的网格对象为空,无法开展后续三维处理 - 同一份obj文件使用numpy做解析加载时无异常,可正常提取顶点、面索引等核心网格数据
异常成因
Open3D的triangle_mesh读取接口默认依赖ASSIMP第三方库完成三维文件格式解析,该解析逻辑和numpy的逐行匹配式解析存在本质规则差异,是本次加载失败的核心原因:
- ASSIMP的obj格式校验逻辑极度严格:只要文件内存在不符合其内置规范的内容(包括非标准自定义注释、跨行列顶点数据缺省、负索引写法、材质关联段语法偏差、新版本建模软件导出的自定义扩展属性段),ASSIMP会直接终止整个文件的加载流程,抛出失败告警。而numpy的加载逻辑是逐行匹配
v、f等关键字行,碰到不规范内容只会跳过,不会中断整体解析流程,因此可以正常提取数据 - 前置校验逻辑差异:ASSIMP在加载文件前会做路径合法性、文件编码、文件权限的前置校验,碰到带BOM的UTF编码文件、软链接路径、无读权限的文件时会直接判定加载失败;numpy的文件读取不会做这类前置校验,只要路径可被操作系统识别就会尝试读取
- 版本兼容性问题:低版本Open3D绑定的ASSIMP库版本较旧,对部分新版Blender、ZBrush等软件导出的扩展格式obj支持不全,会出现解析失败的情况
对应解决方法
- 绕开ASSIMP解析通道,手动构造Open3D网格对象
借助numpy的解析能力提取网格的顶点坐标、三角面索引、顶点法线、纹理坐标等核心数据,再手动填充到Open3D的TriangleMesh对象中,完全规避ASSIMP的校验流程,核心实现参考:mesh = o3d.geometry.TriangleMesh() mesh.vertices = o3d.utility.Vector3dVector(vertices) mesh.triangles = o3d.utility.Vector3iVector(triangles) # 如有法线、纹理坐标数据,可对应补充Vector3dVector、Vector2dVector的赋值 - 预处理obj文件适配ASSIMP规则
逐行排查obj文件内容:删除所有自定义非标准注释、将负索引转换为正整数索引、修正材质关联段的语法偏差、移除文件开头的BOM编码标记,调整完成后重新执行原加载代码即可 - 升级依赖版本提升兼容性
将Open3D升级到最新稳定版本,新版本内置的ASSIMP库已经修复了大量旧版本的格式兼容问题,可直接重新尝试原read_triangle_mesh的加载逻辑
内容的提问来源于stack exchange,提问作者Jane
相关产品推荐
相关产品推荐

