C++ 从曲面减去闭合网格(CGAL?)

C++ 从曲面减去闭合网格(CGAL?),c++,geometry,computational-geometry,cgal,C++,Geometry,Computational Geometry,Cgal,我有以下问题,最好用下面的图片来描述 我有一个3D曲面,所以它可以有垂直重叠,是一个非闭合网格。我有一个物体,我想从中减去它。绿色+黄色区域是原始曲面,红线勾勒出球体(作为三角网格,而不是基本体)。黄色区域是与球体相交的曲面部分,需要从原始曲面中删除。绿色区域是减法的结果:需要的曲面 我已经在使用CGAL库了,但对它还是陌生的,所以使用CGAL的解决方案将是最受欢迎的。然而,如果有人有一个没有CGAL的解决方案,那也会受到欢迎 我能看到的最好的方法是给表面一点厚度(保持当前表面为底部)。然后使用

我有以下问题,最好用下面的图片来描述

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

我已经在使用CGAL库了,但对它还是陌生的,所以使用CGAL的解决方案将是最受欢迎的。然而,如果有人有一个没有CGAL的解决方案,那也会受到欢迎

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


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

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));
}
typedef CGAL::Simple_cartesian SC;
typedef CGAL::表面\网格表面网格;
typedef SurfaceMesh::Property_map SM_fnormals;
typedef SurfaceMesh::顶点索引SM_vid;
typedef SurfaceMesh::Face_index SM_fid;
名称空间PMP=CGAL::多边形网格处理;
名称空间参数=PMP::parameters;
无效剪辑(表面网格P和,表面网格和Q){
SM\u fnormals fnormals=CGALobstacle->添加属性\u映射
(“f:法线”,CGAL::NULL_向量);
PMP::计算面法线(Q,fnormals);
剪辑(P,Q,false,params::all_default(),params::face_normal_map(fnormals));
}

多边形网格处理/include/CGAL/Polygon网格处理/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)
///np\u tm需要面索引图、顶点索引图
///需要np_c的面索引图
///如果边受约束,则np_tm中未提供默认的边映射
///使用boost::无序_集提供
模板
布尔
夹子(TriangleMesh&tm,
/*康斯特*/TriangleMesh&clipper,
布尔-克洛斯,
常数命名参数1和np_tm,
常数命名参数2和np_c)
第二个参数是球体,第一个参数是曲面。第三个指示是否要关闭输出曲面(在您的情况下为false)。请注意,该函数是剪切的,因此如果您想要球体的外部,则需要反转球体的方向(向内法线)

这里有一个用法示例

我建议使用
曲面网格
而不是
多面体网格

请注意,函数没有文档化,标题可能会在即将发布的版本中消失(如果它消失了,则意味着它得到了正式文档化)


编辑:自CGAL 4.13以来正式记录的函数是。

多边形网格处理/include/CGAL/Polygon网格处理/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)
///np\u tm需要面索引图、顶点索引图
///需要np_c的面索引图
///如果边受约束,则np_tm中未提供默认的边映射
///使用boost::无序_集提供
模板
布尔
夹子(TriangleMesh&tm,
/*康斯特*/TriangleMesh&clipper,
布尔-克洛斯,
常数命名参数1和np_tm,
常数命名参数2和np_c)
第二个参数是球体,第一个参数是曲面。第三个指示是否要关闭输出曲面(在您的情况下为false)。请注意,该函数是剪切的,因此如果您想要球体的外部,则需要反转球体的方向(向内法线)

这里有一个用法示例

我建议使用
曲面网格
而不是
多面体网格

请注意,函数没有文档化,标题可能会在即将发布的版本中消失(如果它消失了,则意味着它得到了正式文档化)


编辑:自CGAL 4.13以来正式记录的功能是。

谢谢您的回答。曲面网格确实比我使用的更好。但是,我无法剪裁到被剪裁障碍物的正确一侧。我已经编辑了我的问题,你是否看到了一个明显的错误?删除所有关于正常计算的内容,并调用裁剪网格上的函数。谢谢你的回答。曲面网格确实比我使用的更好。但是,我无法剪裁到被剪裁障碍物的正确一侧。我已经编辑了我的问题,是否有一个明显的错误,你可以看到吗?删除所有关于正常计算的内容,并调用裁剪网格上的函数。