You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CGAL如何将Point_set属性复制到Surface_mesh及顶点数量差异疑问

解决方案

一、classification属性复制错误修正

你代码的核心问题是覆盖了顶点存储的原始点集索引:你定义的三角网顶点基类Vbi的info字段本来是用来存Point_set::Index的,但你后面的循环把它改成了z坐标值,自然没法通过它索引到原始点云的classification属性。
修改步骤如下:

  1. 删除覆盖vh->info()的循环代码,保留info中存储的原始点集索引
  2. 补充class_lambda的实现,通过三角网顶点的info索引到原始点云属性,赋值给网格顶点属性
  3. 把属性类型从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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 14:18:04