我有以下问题,最好用下图说明。
我有一个3D表面,所以它可以有垂直重叠,是一个非闭合网格。我有一个对象,我想从中减去它。绿色+黄色区域是原始表面,红色线条勾勒出一个球体(如三角形网格,而不是原始)。黄色区域是与球体相交的表面的一部分,需要从原始表面移除。绿色区域是减法的结果:需要的表面。
我已经在使用CGAL库,但仍然是新手,所以使用CGAL的解决方案将是最受欢迎的。但是,如果某人有没有CGAL的解决方案也会受到欢迎。
我能看到的最好的方法是给表面一个轻微的厚度(保持当前表面为底部)。然后使用Nef_polyhedron_3减去另一个对象,然后转换为Polyhedron_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));
}
答案 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。