Skip to content

Commit 324bdf4

Browse files
committed
improve doc + doc parameter for clip
add tests
1 parent 240e463 commit 324bdf4

3 files changed

Lines changed: 142 additions & 17 deletions

File tree

PMP_Boolean_operations/include/CGAL/Polygon_mesh_processing/clip.h

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -713,7 +713,7 @@ generic_clip_impl(
713713
typedef Corefinement::No_mark<TriangleMesh> NoMap;
714714
typedef Corefinement::Edge_properties_for_input<TriangleMesh, User_cst_map, NoMap, Edge_mark_map, NoMap> Edge_properties_in;
715715

716-
Edge_mark_map edge_mark_map = get(CGAL::dynamic_edge_property_t<bool>(), tm1);
716+
Edge_mark_map edge_mark_map = get(CGAL::dynamic_edge_property_t<bool>(), tm1, false);
717717

718718
// Face index point maps
719719
typedef typename CGAL::GetInitializedFaceIndexMap<TriangleMesh, NamedParameters1>::type FaceIndexMap1;
@@ -838,6 +838,13 @@ struct Visitor_wrapper_for_triangulate_face
838838
* will be set after refining `tm` with the intersection with `clipper`}
839839
* \cgalParamNEnd
840840
*
841+
* \cgalParamNBegin{edge_is_constrained_map}
842+
* \cgalParamDescription{a property map containing the constrained-or-not status of each edge of `tm`}
843+
* \cgalParamType{a class model of `ReadWritePropertyMap` with `boost::graph_traits<TriangleMesh>::%edge_descriptor` as key type and `bool` as value type.
844+
* If an edge marked as constrained in `tm` is split during clipping, the remaining part after the clip will be marked as constrained.}
845+
* \cgalParamDefault{a constant property map returning `false` for any edge}
846+
* \cgalParamNEnd
847+
*
841848
* \cgalParamNBegin{visitor}
842849
* \cgalParamDescription{a visitor used to track the creation of new faces}
843850
* \cgalParamType{a class model of `PMPCorefinementVisitor`}
@@ -943,6 +950,13 @@ clip(TriangleMesh& tm,
943950
* \cgalParamDefault{`boost::get(CGAL::vertex_point, pm)`}
944951
* \cgalParamNEnd
945952
*
953+
* \cgalParamNBegin{edge_is_constrained_map}
954+
* \cgalParamDescription{a property map containing the constrained-or-not status of each edge of `tm`}
955+
* \cgalParamType{a class model of `ReadWritePropertyMap` with `boost::graph_traits<TriangleMesh>::%edge_descriptor` as key type and `bool` as value type.
956+
* If an edge marked as constrained in `tm` is split during clipping, the remaining part after the clip will be marked as constrained.}
957+
* \cgalParamDefault{a constant property map returning `false` for any edge}
958+
* \cgalParamNEnd
959+
*
946960
* \cgalParamNBegin{visitor}
947961
* \cgalParamDescription{a visitor used to track the creation of new faces, edges, and faces.
948962
* Note that as there are no mesh associated with `plane`,
@@ -1032,6 +1046,7 @@ bool clip(PolygonMesh& pm,
10321046
return true;
10331047
}
10341048

1049+
using edge_descriptor = typename boost::graph_traits<PolygonMesh>::edge_descriptor;
10351050
using halfedge_descriptor = typename boost::graph_traits<PolygonMesh>::halfedge_descriptor;
10361051

10371052
using GT = typename GetGeomTraits<PolygonMesh, NamedParameters>::type;
@@ -1064,14 +1079,19 @@ bool clip(PolygonMesh& pm,
10641079
bool triangulate = !choose_parameter(get_parameter(np, internal_np::do_not_triangulate_faces), false);
10651080
constexpr bool traits_supports_cdt2 = !internal::Has_member_Does_not_support_CDT2<GT>::value;
10661081
auto vos = get(dynamic_vertex_property_t<Oriented_side>(), pm);
1067-
auto ecm = get(dynamic_edge_property_t<bool>(), pm, false);
1082+
1083+
using Default_ecm = Static_boolean_property_map<edge_descriptor, false>;
1084+
auto ecm = choose_parameter<Default_ecm>(get_parameter(np, internal_np::edge_is_constrained));
1085+
auto edge_is_marked_map = get(dynamic_edge_property_t<bool>(), pm, false);
1086+
10681087
auto construct_orthogonal_vector = traits.construct_orthogonal_vector_3_object();
10691088

10701089
if (traits_supports_cdt2 && triangulate && !is_triangle_mesh(pm))
10711090
triangulate = false;
10721091

10731092
refine_with_plane(pm, plane, parameters::vertex_oriented_side_map(vos)
1074-
.edge_is_marked_map(ecm)
1093+
.edge_is_marked_map(edge_is_marked_map)
1094+
.edge_is_constrained_map(ecm)
10751095
.vertex_point_map(vpm)
10761096
.geom_traits(traits)
10771097
.do_not_triangulate_faces(!triangulate)
@@ -1092,7 +1112,7 @@ bool clip(PolygonMesh& pm,
10921112

10931113
auto fcc = get(dynamic_face_property_t<std::size_t>(), pm);
10941114

1095-
std::size_t nbcc = connected_components(pm, fcc, CGAL::parameters::edge_is_constrained_map(ecm));
1115+
std::size_t nbcc = connected_components(pm, fcc, CGAL::parameters::edge_is_constrained_map(edge_is_marked_map));
10961116

10971117
std::vector<bool> classified(nbcc, false);
10981118
std::vector<std::size_t> ccs_to_remove;
@@ -1166,6 +1186,13 @@ bool clip(PolygonMesh& pm,
11661186
* \cgalParamDefault{`boost::get(CGAL::vertex_point, tm)`}
11671187
* \cgalParamNEnd
11681188
*
1189+
* \cgalParamNBegin{edge_is_constrained_map}
1190+
* \cgalParamDescription{a property map containing the constrained-or-not status of each edge of `tm`}
1191+
* \cgalParamType{a class model of `ReadWritePropertyMap` with `boost::graph_traits<TriangleMesh>::%edge_descriptor` as key type and `bool` as value type.
1192+
* If an edge marked as constrained in `tm` is split during clipping, the remaining part after the clip will be marked as constrained.}
1193+
* \cgalParamDefault{a constant property map returning `false` for any edge}
1194+
* \cgalParamNEnd
1195+
*
11691196
* \cgalParamNBegin{visitor}
11701197
* \cgalParamDescription{a visitor used to track the creation of new faces}
11711198
* \cgalParamType{a class model of `PMPCorefinementVisitor`}
@@ -1239,8 +1266,7 @@ bool clip(TriangleMesh& tm,
12391266

12401267
make_hexahedron(iso_cuboid[0], iso_cuboid[1], iso_cuboid[2], iso_cuboid[3],
12411268
iso_cuboid[4], iso_cuboid[5], iso_cuboid[6], iso_cuboid[7],
1242-
clipper);
1243-
triangulate_faces(clipper);
1269+
clipper, parameters::do_not_triangulate_faces(false));
12441270

12451271
const bool do_not_modify = choose_parameter(get_parameter(np, internal_np::allow_self_intersections), false);
12461272
return clip(tm, clipper, np, params::do_not_modify(do_not_modify));

PMP_Boolean_operations/include/CGAL/Polygon_mesh_processing/corefinement.h

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -191,8 +191,8 @@ enum Boolean_operation_type {UNION = 0, INTERSECTION=1,
191191
*
192192
* \cgalParamNBegin{edge_is_constrained_map}
193193
* \cgalParamDescription{a property map containing the constrained-or-not status of each edge of `tm1` (`tm2`)}
194-
* \cgalParamType{a class model of `ReadWritePropertyMap` with `boost::graph_traits<TriangleMesh>::%edge_descriptor`
195-
* as key type and `bool` as value type}
194+
* \cgalParamType{a class model of `ReadWritePropertyMap` with `boost::graph_traits<TriangleMesh>::%edge_descriptor`as key type and `bool` as value type.
195+
* If an edge marked as constrained in `tm1` (tm2`) is split during corefinement, the resulting sub-edges will be marked as constrained.}
196196
* \cgalParamDefault{a constant property map returning `false` for any edge}
197197
* \cgalParamNEnd
198198
*
@@ -246,8 +246,8 @@ enum Boolean_operation_type {UNION = 0, INTERSECTION=1,
246246
*
247247
* \cgalParamNBegin{edge_is_constrained_map}
248248
* \cgalParamDescription{a property map containing the constrained-or-not status of each edge of `tm_out`.
249-
* An edge of `tm_out` is constrained if it is on the intersection of `tm1` and `tm2`,
250-
* or if the edge corresponds to a constrained edge in `tm1` or `tm2`.}
249+
* An edge of `tm_out` is constrained if the edge corresponds to a constrained edge in `tm1` or `tm2`.
250+
* If an edge marked as constrained in `tm1` (tm2`) is split during corefinement, the resulting sub-edges will be marked as constrained.}
251251
* \cgalParamType{a class model of `WritablePropertyMap` with `boost::graph_traits<TriangleMesh>::%edge_descriptor`
252252
* as key type and `bool` as value type}
253253
* \cgalParamNEnd
@@ -529,8 +529,8 @@ corefine_and_compute_boolean_operations(
529529
*
530530
* \cgalParamNBegin{edge_is_constrained_map}
531531
* \cgalParamDescription{a property map containing the constrained-or-not status of each edge of `tm1` (`tm2`)}
532-
* \cgalParamType{a class model of `ReadWritePropertyMap` with `boost::graph_traits<TriangleMesh>::%edge_descriptor`
533-
* as key type and `bool` as value type}
532+
* \cgalParamType{a class model of `ReadWritePropertyMap` with `boost::graph_traits<TriangleMesh>::%edge_descriptor`as key type and `bool` as value type
533+
* If an edge marked as constrained in `tm1` (tm2`) is split during corefinement, the resulting sub-edges will be marked as constrained.
534534
* \cgalParamDefault{a constant property map returning `false` for any edge}
535535
* \cgalParamNEnd
536536
*
@@ -583,8 +583,7 @@ corefine_and_compute_boolean_operations(
583583
*
584584
* \cgalParamNBegin{edge_is_constrained_map}
585585
* \cgalParamDescription{a property map containing the constrained-or-not status of each edge of `tm_out`.
586-
* An edge of `tm_out` is constrained if it is on the intersection of `tm1` and `tm2`,
587-
* or if the edge corresponds to a constrained edge in `tm1` or `tm2`.}
586+
* An edge of `tm_out` is constrained if the edge corresponds to a (part of a) constrained edge in `tm1` or `tm2`.}
588587
* \cgalParamType{a class model of `WritablePropertyMap` with `boost::graph_traits<TriangleMesh>::%edge_descriptor`
589588
* as key type and `bool` as value type}
590589
* \cgalParamNEnd
@@ -724,9 +723,8 @@ corefine_and_compute_difference( TriangleMesh& tm1,
724723
*
725724
* \cgalParamNBegin{edge_is_constrained_map}
726725
* \cgalParamDescription{a property map containing the constrained-or-not status of each edge of `tm1` (`tm2`)}
727-
* \cgalParamType{a class model of `ReadWritePropertyMap` with `boost::graph_traits<TriangleMesh>::%edge_descriptor`
728-
* as key type and `bool` as value type. If an edge marked as constrained is split by this function,
729-
* the resulting edges will also be marked as constrained.}
726+
* \cgalParamType{a class model of `ReadWritePropertyMap` with `boost::graph_traits<TriangleMesh>::%edge_descriptor` as key type and `bool` as value type.
727+
* If an edge marked as constrained in is split during corefinement, the resulting sub-edges will be marked as constrained.}
730728
* \cgalParamDefault{a constant property map returning `false` for any edge}
731729
* \cgalParamNEnd
732730
*

PMP_Boolean_operations/test/PMP_Boolean_operations/test_pmp_clip.cpp

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#include <CGAL/Polygon_mesh_processing/clip.h>
22
#include <CGAL/Polygon_mesh_processing/transform.h>
3+
#include <CGAL/Polygon_mesh_processing/detect_features.h>
4+
#include <CGAL/boost/graph/generators.h>
35

46
#include <CGAL/Surface_mesh.h>
57
#include <CGAL/Polyhedron_3.h>
@@ -1294,6 +1296,102 @@ void test_clip_and_split_with_plane_visitor()
12941296

12951297
}
12961298

1299+
1300+
1301+
1302+
template <class ECM>
1303+
std::size_t
1304+
count_constrained_edges(const Surface_mesh& tm, ECM ecm)
1305+
{
1306+
std::size_t n=0;
1307+
for(auto e : tm.edges())
1308+
{
1309+
if ( ecm[e] ) ++n;
1310+
}
1311+
return n;
1312+
}
1313+
1314+
/*
1315+
template <class ECM>
1316+
void dump_constrained_edges(const Surface_mesh& tm, ECM ecm, std::string fname)
1317+
{
1318+
std::ofstream output(fname);
1319+
for(auto e : tm.edges())
1320+
{
1321+
if ( get(ecm, e) )
1322+
output << "2 " << tm.point( tm.vertex(e, 0) )
1323+
<< " " << tm.point( tm.vertex(e, 1) ) << "\n";
1324+
}
1325+
}
1326+
*/
1327+
1328+
void test_edge_is_contrained()
1329+
{
1330+
{
1331+
Surface_mesh tm;
1332+
std::ifstream(CGAL::data_file_path("meshes/joint_refined.off")) >> tm;
1333+
1334+
auto ecm = tm.add_property_map<Surface_mesh::Edge_index, bool>("ecm", false).first;
1335+
PMP::detect_sharp_edges(tm, 60, ecm);
1336+
1337+
CGAL::Bbox_3 bb(-0.61222702264785767, -0.31298750638961792, -0.16560758650302887,
1338+
0.54861283302307129, 0.62676382064819336, 0.68821543455123901);
1339+
1340+
Surface_mesh clipper;
1341+
CGAL::make_hexahedron(K::Iso_cuboid_3(bb), clipper, params::do_not_triangulate_faces(false));
1342+
1343+
PMP::clip(tm, clipper, params::edge_is_constrained_map(ecm));
1344+
1345+
assert( count_constrained_edges(tm, ecm)==132 );
1346+
}
1347+
1348+
{
1349+
Surface_mesh tm;
1350+
std::ifstream(CGAL::data_file_path("meshes/joint_refined.off")) >> tm;
1351+
1352+
auto ecm = tm.add_property_map<Surface_mesh::Edge_index, bool>("ecm", false).first;
1353+
PMP::detect_sharp_edges(tm, 60, ecm);
1354+
1355+
CGAL::Bbox_3 bb(-0.61222702264785767, -0.31298750638961792, -0.16560758650302887,
1356+
0.54861283302307129, 0.62676382064819336, 0.68821543455123901);
1357+
1358+
Surface_mesh clipper;
1359+
CGAL::make_hexahedron(K::Iso_cuboid_3(bb), clipper, params::do_not_triangulate_faces(false));
1360+
1361+
PMP::clip(tm, clipper, params::edge_is_constrained_map(ecm).clip_volume(true));
1362+
1363+
assert( count_constrained_edges(tm, ecm)==132 );
1364+
}
1365+
1366+
{
1367+
Surface_mesh tm;
1368+
std::ifstream(CGAL::data_file_path("meshes/joint_refined.off")) >> tm;
1369+
1370+
auto ecm = tm.add_property_map<Surface_mesh::Edge_index, bool>("ecm", false).first;
1371+
PMP::detect_sharp_edges(tm, 60, ecm);
1372+
1373+
K::Plane_3 plane(-1.63242e-16, -1, -2.22045e-16, -0.242727);
1374+
1375+
PMP::clip(tm, plane, params::edge_is_constrained_map(ecm));
1376+
1377+
assert( count_constrained_edges(tm, ecm)==146 );
1378+
}
1379+
1380+
{
1381+
Surface_mesh tm;
1382+
std::ifstream(CGAL::data_file_path("meshes/joint_refined.off")) >> tm;
1383+
1384+
auto ecm = tm.add_property_map<Surface_mesh::Edge_index, bool>("ecm", false).first;
1385+
PMP::detect_sharp_edges(tm, 60, ecm);
1386+
1387+
K::Plane_3 plane(-1.63242e-16, -1, -2.22045e-16, -0.242727);
1388+
1389+
PMP::clip(tm, plane, params::edge_is_constrained_map(ecm).clip_volume(true));
1390+
1391+
assert( count_constrained_edges(tm, ecm)==146 );
1392+
}
1393+
}
1394+
12971395
int main()
12981396
{
12991397
std::cout << "Surface Mesh" << std::endl;
@@ -1324,6 +1422,9 @@ int main()
13241422
std::cout << "Done!" << std::endl;
13251423
std::cout << "running test_clip_and_split_with_plane_visitor\n";
13261424
test_clip_and_split_with_plane_visitor();
1425+
std::cout << "running test_edge_is_contrained\n";
1426+
test_edge_is_contrained();
13271427
std::cout << "Done!" << std::endl;
1428+
13281429
return EXIT_SUCCESS;
13291430
}

0 commit comments

Comments
 (0)