从表面减去闭合网格(CGAL?)

时间:2017-08-02 17:15:21

标签: c++ geometry computational-geometry cgal

我有以下问题,最好用下图说明。

我有一个3D表面,所以它可以有垂直重叠,是一个非闭合网格。我有一个对象,我想从中减去它。绿色+黄色区域是原始表面,红色线条勾勒出一个球体(如三角形网格,而不是原始)。黄色区域是与球体相交的表面的一部分,需要从原始表面移除。绿色区域是减法的结果:需要的表面。

我已经在使用CGAL库,但仍然是新手,所以使用CGAL的解决方案将是最受欢迎的。但是,如果某人有没有CGAL的解决方案也会受到欢迎。

我能看到的最好的方法是给表面一个轻微的厚度(保持当前表面为底部)。然后使用Nef_polyhedron_3减去另一个对象,然后转换为Polyhedron_3并仅保留底面。但这似乎有点像黑客。

Intersection

编辑: 使用提出的解决方案我非常接近,但是我无法使用以下代码使用所提出的反向法线剪切到正确的一侧。 我还试图看看面顶点顺序(顺时针/逆时针)是否有任何效果,但似乎没有任何效果。

typedef CGAL::Simple_cartesian<double>                  SC;
typedef CGAL::Surface_mesh<SC::Point_3>                 SurfaceMesh;
typedef SurfaceMesh::Property_map<SM_fid, SC::Vector_3> SM_fnormals;
typedef SurfaceMesh::Vertex_index                       SM_vid;
typedef SurfaceMesh::Face_index                         SM_fid;

namespace PMP = CGAL::Polygon_mesh_processing;
namespace params = PMP::parameters;

void clip(SurfaceMesh P&, SurfaceMesh& Q) {        
    SM_fnormals fnormals = CGALobstacle->add_property_map<SM_fid, SC::Vector_3>
        ("f:normals", CGAL::NULL_VECTOR).first;

    PMP::compute_face_normals(Q, fnormals);

    PMP::clip(P, Q, false, params::all_default(), params::face_normal_map(fnormals));
}

1 个答案:

答案 0 :(得分:2)

Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/clip.h中的CGAL 4.10开始,有一个未记录的函数。功能签名是:

/// requires face_index_map, vertex_index_map for np_tm
/// requires face_index_map for np_c
/// if edge_is_constrained_map is not provided in np_tm a default one is
/// provided using boost::unordered_set<edge_descriptor>
template <class TriangleMesh,
          class NamedParameters1,
          class NamedParameters2>
bool
clip(      TriangleMesh& tm,
 /*const*/ TriangleMesh& clipper,
           bool close,
     const NamedParameters1& np_tm,
     const NamedParameters2& np_c)

第二个参数是你的球体,第一个是你的表面。第三个表示您是否希望关闭输出表面(在您的情况下为假)。请注意,该函数是剪切,因此如果您想要球体的外部部分,则需要反转球体的方向(向内法线)。

有一个用法示例here

我建议使用Surface_mesh而不是Polyhedron_3

请注意,该函数未记录在案,并且标题可能会在即将发布的版本中消失(如果这样做意味着它已正式记录)。

编辑:自CGAL 4.13起正式记录的函数为here