CGAL如何将Point_set属性复制到Surface_mesh及顶点数量差异疑问
解决方案
一、classification属性复制错误修正
你代码的核心问题是覆盖了顶点存储的原始点集索引:你定义的三角网顶点基类Vbi的info字段本来是用来存Point_set::Index的,但你后面的循环把它改成了z坐标值,自然没法通过它索引到原始点云的classification属性。
修改步骤如下:
- 删除覆盖
vh->info()的循环代码,保留info中存储的原始点集索引 - 补充
class_lambda的实现,通过三角网顶点的info索引到原始点云属性,赋值给网格顶点属性 - 把属性类型从
double改成你需要的unsigned char
修改后的核心代码片段:
// 保留你之前获取original_class_map的代码不变 Point_set::Property_map<unsigned char> original_class_map = point_set.property_map<unsigned char>("classification").first; // 三角网创建部分不变,直接删除之前修改vh->info()的循环代码 TIN_with_info tin_with_info( boost::make_transform_iterator(point_set.begin(), idx_to_point_with_info), boost::make_transform_iterator(point_set.end(), idx_to_point_with_info)); using Mesh = CGAL::Surface_mesh<Point>; Mesh tin_class_mesh; // 把属性类型从double修改为unsigned char Mesh::Property_map<Mesh::Vertex_index, unsigned char> class_map = tin_class_mesh.add_property_map<Mesh::Vertex_index, unsigned char>("v:class").first; // 实现class_lambda逻辑完成属性赋值 auto class_lambda = [&](const TIN_with_info::Vertex_handle& tin_vh, const Mesh::Vertex_index& mesh_vh) { // 直接用三角网顶点存储的Point_set索引读取对应的classification属性 class_map[mesh_vh] = original_class_map[tin_vh->info()]; }; // copy_face_graph调用逻辑保持不变 CGAL::copy_face_graph(tin_with_info, tin_class_mesh, CGAL::parameters::vertex_to_vertex_output_iterator( boost::make_function_output_iterator(class_lambda)));
二、网格顶点数与点云数量不一致的原因
这是CGAL 2D Delaunay三角剖分的正常行为,主要原因有两个:
- 点云中存在坐标完全重合的点,或者投影到2D平面后坐标完全重合的点,三角剖分会自动合并重复点,仅保留一个顶点
- 三角剖分内部的无穷远顶点不会被复制到Surface_mesh中,该场景通常只会差1个顶点,若差异较大基本都是重复点合并导致的
内容的提问来源于stack exchange,提问作者dodol
相关产品推荐
相关产品推荐

