trimesh合并网格按原始组件面着色的技术实现问询
Trimesh网格合并后的面颜色设置问题
颜色设置逻辑澄清
两种方式都可用于设置面颜色,适用场景不同:
- 直接修改
mesh.visual.face_colors:仅当当前网格的visual属性是ColorVisuals类型时生效,需传入形状为(面数, 4)的uint8数组(RGBA格式)。如果原visual是其他类型(如TextureVisuals),需先转换为ColorVisuals。 - 创建
ColorVisuals对象赋值:通用方案,不受原visual类型限制,直接替换为颜色视觉系统,示例:mesh.visual = trimesh.visual.ColorVisuals(face_colors=colors)
核心需求解决方案:基于面近似重叠关系上色
你之前用顶点集合判断的思路不可行,因为布尔合并后网格的顶点会重新计算(存在浮点偏移或拓扑重构)。可通过面中心的邻近匹配实现近似判断:
修正后的代码
from shapely import Polygon import trimesh import numpy as np # 生成原始组件网格 pts = ((100, 100), (400, 100), (400, 400), (100, 400)) hole = ((150, 150), (350, 150), (350, 350), (150, 350)) p = Polygon(pts, [hole]) mesh1 = trimesh.creation.extrude_polygon(p, 100) mesh2 = mesh1.copy() mesh2.apply_translation((150, 50, 50)) # 执行合并操作,保留原始网格引用 combined_mesh = mesh1.union(mesh2) # 初始化颜色数组:新生成的边界面设为灰色 colors = np.full((len(combined_mesh.faces), 4), [128, 128, 128, 255], dtype=np.uint8) # 获取所有面的中心坐标 combined_centers = combined_mesh.triangles_center # 匹配来自mesh1的面,设为绿色 dist_to_mesh1 = trimesh.proximity.closest_point(mesh1, combined_centers)[1] mesh1_mask = dist_to_mesh1 < 1e-3 # 阈值根据网格尺度调整 colors[mesh1_mask] = [0, 255, 0, 255] # 匹配来自mesh2的面,设为红色 dist_to_mesh2 = trimesh.proximity.closest_point(mesh2, combined_centers)[1] mesh2_mask = dist_to_mesh2 < 1e-3 colors[mesh2_mask] = [255, 0, 0, 255] # 应用颜色设置 combined_mesh.visual = trimesh.visual.ColorVisuals(face_colors=colors) combined_mesh.show()
关键细节
- 面中心邻近匹配:利用
trimesh.proximity.closest_point计算合并后面中心到原始网格的最小距离,通过阈值判断归属,规避浮点误差问题。 - 阈值调整:
1e-3是通用小阈值,若网格尺度很大,需按比例放大阈值。 - 边界面处理:合并时新生成的边界面会被设为灰色,可根据需求修改默认颜色。
复杂边界场景优化
如果遇到极端裁剪导致面中心匹配失效的情况,可改用面顶点集合的近似重合度判断:遍历合并后的每个面,检查其顶点是否与原始网格的某个面的顶点近似重合(计算顶点间距离的均值是否小于阈值)。
内容的提问来源于stack exchange,提问作者villares
相关产品推荐
相关产品推荐

