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

CGAL::Polyhedron_3调用make_tetrahedron产生重复顶点如何解决?

CGAL Polyhedron_3调用make_tetrahedron重复存储顶点问题

我在使用CGAL::Polyhedron_3数据结构生成体网格的测试过程中,发现make_tetrahedron函数会重复存储多面体中已存在的顶点。

测试场景:两个共享公共面的四面体

测试代码

#include <CGAL/Simple_cartesian.h>
#include <CGAL/Polyhedron_3.h>
#include <iostream>

typedef CGAL::Simple_cartesian<double>     Kernel;
typedef Kernel::Point_3                    Point_3;
typedef CGAL::Polyhedron_3<Kernel>         Polyhedron;
typedef Polyhedron::Vertex_iterator        Vertex_iterator;

int main(void) {
    // 公共点
    Point_3 p( 1.0, 0.0, 0.0 );
    Point_3 q( 0.0, 1.0, 0.0 );
    Point_3 s( 0.0, 0.0, 0.0 );

    // 另外两个顶点
    Point_3 r( 0.0, 0.0, 1.0 );
    Point_3 d( 0.0, 0.0,-1.0 );

    Polyhedron P;
    P.make_tetrahedron( p, q, r, s );
    P.make_tetrahedron( p, q, s, d );

    CGAL::IO::set_ascii_mode( std::cout );
    
    // 打印所有顶点
    for ( Vertex_iterator v = P.vertices_begin(); v != P.vertices_end(); ++v )
        std::cout << v->point() << std::endl;

    return 0;
}

期望输出

我预期得到5个不重复的顶点:

1 0 0
0 1 0
0 0 1
0 0 0
0 0 -1

实际输出

运行后得到的结果存在重复顶点:

1 0 0
0 1 0
0 0 1
0 0 0
1 0 0
0 1 0
0 0 0
0 0 -1

问题

调用make_tetrahedron函数时,能否实现CGAL::Polyhedron_3中同一个坐标点仅作为一个顶点存储?


解答

make_tetrahedron默认没有自动去重逻辑,每次传入Point_3调用时都会独立插入4个全新顶点、构建对应的四面体拓扑,不会主动比对现有顶点的坐标来复用实例,因此会出现重复存储的问题。可以通过以下两种方案实现同坐标顶点仅存一份:

方案1:手动复用顶点句柄

make_tetrahedron支持传入Vertex_handle类型参数而非Point_3,你可以先把所有唯一顶点插入多面体拿到对应句柄,再用句柄构建四面体,不会生成新的重复顶点,修改后的示例代码如下:

int main(void) {
    Point_3 p( 1.0, 0.0, 0.0 );
    Point_3 q( 0.0, 1.0, 0.0 );
    Point_3 s( 0.0, 0.0, 0.0 );
    Point_3 r( 0.0, 0.0, 1.0 );
    Point_3 d( 0.0, 0.0,-1.0 );

    Polyhedron P;
    // 先插入所有唯一顶点,拿到对应句柄
    auto v_p = P.make_vertex(p);
    auto v_q = P.make_vertex(q);
    auto v_s = P.make_vertex(s);
    auto v_r = P.make_vertex(r);
    auto v_d = P.make_vertex(d);
    // 用顶点句柄构建四面体,不会生成新顶点
    P.make_tetrahedron(v_p, v_q, v_r, v_s);
    P.make_tetrahedron(v_p, v_q, v_s, v_d);

    CGAL::IO::set_ascii_mode( std::cout );
    for ( Vertex_iterator v = P.vertices_begin(); v != P.vertices_end(); ++v )
        std::cout << v->point() << std::endl;
    return 0;
}

方案2:全局批量去重

如果你已经用Point_3参数调用make_tetrahedron生成了带重复顶点的多面体,可以调用CGAL的拓扑处理工具做全局顶点合并:使用CGAL::Polygon_mesh_processing::merge_duplicate_vertices函数,指定坐标容差即可把坐标一致的顶点合并为同一个实例。


内容的提问来源于stack exchange,提问作者Davide

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 09:27:00