从表面减去封闭网格(CGAL?)
Substract closed mesh from surface (CGAL?)
我有以下问题,最好用下图描述。
我有一个 3D 表面,因此它可以有垂直重叠并且是一个非闭合网格。我有一个要从中减去的对象。绿色+黄色区域是原始表面,红线勾勒出一个球体(作为三角网格,不是图元)。黄色区域是与需要从原始表面移除的球体相交的表面部分。绿色区域是减法的结果:需要的表面。
我已经在使用 CGAL 库,但仍然是新手,因此使用 CGAL 的解决方案将是首选。但是,如果有人有没有 CGAL 的解决方案,那也将受到欢迎。
我能看到的最好方法是给表面一个轻微的厚度(保持当前表面为底部)。然后用 Nef_polyhedron_3 减去另一个对象,然后转换为 Polyhedron_3 只保留底面。但这似乎有点 hack。
编辑:
使用建议的解决方案我非常接近,但我无法使用建议的反向法线裁剪到正确的一侧,使用以下代码。
我也试过看人脸顶点顺序(顺时针/逆时针)有没有效果,但是好像没有。
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));
}
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
。
请注意,该功能未记录在案,header 可能会在即将发布的版本中消失(如果确实存在,则意味着它已正式记录在案)。
EDIT:自 CGAL 4.13 以来官方记录的函数是 here。
我有以下问题,最好用下图描述。
我有一个 3D 表面,因此它可以有垂直重叠并且是一个非闭合网格。我有一个要从中减去的对象。绿色+黄色区域是原始表面,红线勾勒出一个球体(作为三角网格,不是图元)。黄色区域是与需要从原始表面移除的球体相交的表面部分。绿色区域是减法的结果:需要的表面。
我已经在使用 CGAL 库,但仍然是新手,因此使用 CGAL 的解决方案将是首选。但是,如果有人有没有 CGAL 的解决方案,那也将受到欢迎。
我能看到的最好方法是给表面一个轻微的厚度(保持当前表面为底部)。然后用 Nef_polyhedron_3 减去另一个对象,然后转换为 Polyhedron_3 只保留底面。但这似乎有点 hack。
编辑: 使用建议的解决方案我非常接近,但我无法使用建议的反向法线裁剪到正确的一侧,使用以下代码。 我也试过看人脸顶点顺序(顺时针/逆时针)有没有效果,但是好像没有。
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));
}
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
。
请注意,该功能未记录在案,header 可能会在即将发布的版本中消失(如果确实存在,则意味着它已正式记录在案)。
EDIT:自 CGAL 4.13 以来官方记录的函数是 here。