
Trimesh 默认的 slice_mesh_plane 不会继承原始网格的顶点颜色;可通过构建 KD 树实现切片顶点到原网格顶点的最近邻映射,从而准确传递颜色属性。
trimesh 默认的 `slice_mesh_plane` 不会继承原始网格的顶点颜色;可通过构建 kd 树实现切片顶点到原网格顶点的最近邻映射,从而准确传递颜色属性。
在使用 trimesh.intersections.slice_mesh_plane 对带颜色的网格(如 .ply 或 .obj 加载后设置了 vertex_colors 的模型)执行切片时,返回的 cut_mesh 是一个新生成的几何体,其顶点是原始面片与切割平面交线插值得到的——这些新顶点并不自动关联原始网格的视觉属性(如顶点颜色、法向或 UV),导致可视化时颜色丢失。
解决该问题的核心思路是:将切片后新生成的顶点,映射回原始网格中最邻近的顶点,并复用其颜色。这可通过 scipy.spatial.cKDTree 高效实现:
from scipy.spatial import cKDTree
import trimesh
# 假设 mesh 是已加载且含 vertex_colors 的原始网格
box = trimesh.creation.box(bounds=[[min_x, min_y, 0], [max_x, max_y, max_z]])
cut_mesh = trimesh.intersections.slice_mesh_plane(
mesh, -box.facets_normal[0], box.facets_origin[0]
)
# ✅ 安全地继承顶点颜色(仅当原始网格支持时)
if hasattr(mesh.visual, 'vertex_colors') and mesh.visual.vertex_colors is not None:
# 构建原始顶点的 KD 树(支持快速最近邻查询)
tree = cKDTree(mesh.vertices)
# 查询每个切片顶点在原始网格中的最近邻索引
_, indices = tree.query(cut_mesh.vertices)
# 复制对应颜色(注意:vertex_colors 形状为 (n, 4),RGBA)
cut_mesh.visual.vertex_colors = mesh.visual.vertex_colors[indices]⚠️ 注意事项:
-
slice_mesh_plane返回的cut_mesh可能不含visual属性(尤其当原始mesh.visual为None时),建议在赋值前确保cut_mesh.visual已初始化:cut_mesh.visual = trimesh.visual.ColorVisuals(); - 若原始网格使用的是
face_colors而非vertex_colors,需改用面插值(如重心坐标映射),本方案不适用; -
cKDTree查询默认使用欧氏距离,适用于绝大多数场景;若网格尺度差异极大(如单位混杂),建议先对mesh.vertices归一化或标准化; - 性能方面,该方法时间复杂度为 O(m log n)(m 为切片顶点数,n 为原始顶点数),对百万级网格仍高效。
最终,cut_mesh 即可正确显示与原始网格一致的着色效果,适用于医学影像分割、CAD 截面分析、3D 打印预览等需保色切片的工业级流程。

















