add split iso_cuboid

This commit is contained in:
Maxime Gimeno 2020-03-23 16:14:33 +01:00
parent c3bcf9cbfe
commit 5762211d39
3 changed files with 136 additions and 33 deletions

View File

@ -547,6 +547,65 @@ bool clip(TriangleMesh& tm,
return clip(tm, clipper, np, parameters::all_default());
}
/**
* \ingroup PMP_corefinement_grp
* clips `tm` by keeping the part that is inside `iso_cuboid`.
* If `tm` is closed, the clipped part can be closed too if the named parameter `clip_volume` is set to `true`.
* See Subsection \ref coref_clip for more details.
*
* \note In the current implementation it is not possible to set the vertex point map and the default will be used. `Iso_cuboid_3` must be
* from the same %Kernel as the point of the vertex point map.
* \pre \link CGAL::Polygon_mesh_processing::does_self_intersect() `!CGAL::Polygon_mesh_processing::does_self_intersect(tm)` \endlink
*
* @tparam TriangleMesh a model of `MutableFaceGraph`, `HalfedgeListGraph` and `FaceListGraph`.
* An internal property map for `CGAL::vertex_point_t` must be available.
*
* @tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters"
*
* @param tm input triangulated surface mesh
* @param iso_cuboid iso-cuboid used to clip `tm`.
* @param np optional sequence of \ref pmp_namedparameters "Named Parameters" among the ones listed below
*
* \cgalNamedParamsBegin
* \cgalParamBegin{visitor} a class model of `PMPCorefinementVisitor`
* that is used to track the creation of new faces.
* \cgalParamEnd
* \cgalParamBegin{throw_on_self_intersection} if `true`,
* the set of triangles closed to the intersection of `tm` and `iso_cuboid` will be
* checked for self-intersections and `CGAL::Polygon_mesh_processing::Corefinement::Self_intersection_exception`
* will be thrown if at least one is found.
* \cgalParamEnd
* \cgalParamBegin{clip_volume} if `true` and `tm` is closed, the clipping will be done on
* the volume \link coref_def_subsec bounded \endlink by `tm` rather than on its surface
* (i.e., `tm` will be kept closed).
* \cgalParamEnd
* \cgalParamBegin{use_compact_clipper} if `false` and `clip_volume` is `false` and `tm` is open, the parts of `tm` coplanar with `is_cuboid`
* will not be part of the output.
* \cgalNamedParamsEnd
*
* @return `true` if the output surface mesh is manifold.
* If `false` is returned `tm` is only refined by the intersection with `iso_cuboid`.
*/
template <class TriangleMesh,
class NamedParameters>
bool clip(TriangleMesh& tm,
#ifdef DOXYGEN_RUNNING
const Iso_cuboid_3& iso_cuboid,
#else
const typename GetGeomTraits<TriangleMesh, NamedParameters>::type::Iso_cuboid_3& iso_cuboid,
#endif
const NamedParameters& np)
{
if(boost::begin(faces(tm))==boost::end(faces(tm))) return true;
TriangleMesh clipper;
make_hexahedron(iso_cuboid[0], iso_cuboid[1], iso_cuboid[2], iso_cuboid[3],
iso_cuboid[4], iso_cuboid[5], iso_cuboid[6], iso_cuboid[7],
clipper);
triangulate_faces(clipper);
return clip(tm, clipper, np, parameters::all_default());
}
/*!
* \ingroup PMP_corefinement_grp
@ -635,9 +694,6 @@ void split(TriangleMesh& tm,
* @param np optional sequence of \ref pmp_namedparameters "Named Parameters" among the ones listed below
*
* \cgalNamedParamsBegin
* \cgalParamBegin{vertex_point_map}
* the property map with the points associated to the vertices of `tm`.
* \cgalParamEnd
* \cgalParamBegin{visitor} a class model of `PMPCorefinementVisitor`
* that is used to track the creation of new faces.
* \cgalParamEnd
@ -680,23 +736,22 @@ void split(TriangleMesh& tm,
//else nothing to do, no intersection.
}
/**
* \ingroup PMP_corefinement_grp
* clips `tm` by keeping the part that is inside `iso_cuboid`.
* If `tm` is closed, the clipped part can be closed too if the named parameter `clip_volume` is set to `true`.
* See Subsection \ref coref_clip for more details.
* adds intersection edges of `iso_cuboid` and `tm` in `tm` and duplicates those edges.
*
* \note In the current implementation it is not possible to set the vertex point map and the default will be used. `Iso_cuboid_3` must be
* from the same %Kernel as the point of the vertex point map.
* \note In the current implementation it is not possible to set the vertex point map and the default will be used.
* \note `Iso_cuboid_3` must be from the same %Kernel as the point of the vertex point map.
* \pre \link CGAL::Polygon_mesh_processing::does_self_intersect() `!CGAL::Polygon_mesh_processing::does_self_intersect(tm)` \endlink
*
* @tparam TriangleMesh a model of `MutableFaceGraph`, `HalfedgeListGraph` and `FaceListGraph`.
* @tparam TriangleMesh a model of `MutableFaceGraph`, `HalfedgeListGraph` and `FaceListGraph`
* An internal property map for `CGAL::vertex_point_t` must be available.
*
* @tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters"
*
* @param tm input triangulated surface mesh
* @param iso_cuboid iso-cuboid used to clip `tm`.
* @param iso_cuboid iso-cuboid used to split `tm`.
* @param np optional sequence of \ref pmp_namedparameters "Named Parameters" among the ones listed below
*
* \cgalNamedParamsBegin
@ -708,36 +763,26 @@ void split(TriangleMesh& tm,
* checked for self-intersections and `CGAL::Polygon_mesh_processing::Corefinement::Self_intersection_exception`
* will be thrown if at least one is found.
* \cgalParamEnd
* \cgalParamBegin{clip_volume} if `true` and `tm` is closed, the clipping will be done on
* the volume \link coref_def_subsec bounded \endlink by `tm` rather than on its surface
* (i.e., `tm` will be kept closed).
* \cgalParamEnd
* \cgalParamBegin{use_compact_clipper} if `false` and `clip_volume` is `false` and `tm` is open, the parts of `tm` coplanar with `is_cuboid`
* will not be part of the output.
* \cgalNamedParamsEnd
*
* @return `true` if the output surface mesh is manifold.
* If `false` is returned `tm` is only refined by the intersection with `iso_cuboid`.
*/
template <class TriangleMesh,
class NamedParameters>
bool clip(TriangleMesh& tm,
#ifdef DOXYGEN_RUNNING
const Iso_cuboid_3& iso_cuboid,
#else
const typename GetGeomTraits<TriangleMesh, NamedParameters>::type::Iso_cuboid_3& iso_cuboid,
#endif
const NamedParameters& np)
void split(TriangleMesh& tm,
#ifdef DOXYGEN_RUNNING
const Iso_cuboid_3& iso_cuboid,
#else
const typename GetGeomTraits<TriangleMesh, NamedParameters>::type::Iso_cuboid_3& iso_cuboid,
#endif
const NamedParameters& np)
{
if(boost::begin(faces(tm))==boost::end(faces(tm))) return true;
TriangleMesh clipper;
TriangleMesh splitter;
make_hexahedron(iso_cuboid[0], iso_cuboid[1], iso_cuboid[2], iso_cuboid[3],
iso_cuboid[4], iso_cuboid[5], iso_cuboid[6], iso_cuboid[7],
clipper);
triangulate_faces(clipper);
iso_cuboid[4], iso_cuboid[5], iso_cuboid[6], iso_cuboid[7],
splitter);
triangulate_faces(splitter);
return clip(tm, clipper, np, parameters::all_default());
split(tm, splitter, np, parameters::all_default());
}
/// \cond SKIP_IN_MANUAL
@ -806,6 +851,13 @@ void split(TriangleMesh& tm,
split(tm, plane, parameters::all_default());
}
template <class TriangleMesh>
void split(TriangleMesh& tm,
const typename GetGeomTraits<TriangleMesh>::type::Iso_cuboid_3& iso_cuboid)
{
split(tm, iso_cuboid, parameters::all_default());
}
/// \endcond
} } //end of namespace CGAL::Polygon_mesh_processing

View File

@ -952,7 +952,7 @@ void split_connected_components_impl(FIMap fim,
using parameters::is_default_parameter;
Fpm pidmap = choose_parameter(get_parameter(np, internal_np::face_patch),
get(CGAL::dynamic_face_property_t<std::size_t>(), tm));
get(CGAL::dynamic_face_property_t<int>(), tm));
std::size_t nb_patches = 0;
if(is_default_parameter(get_parameter(np, internal_np::face_patch)))

View File

@ -546,6 +546,7 @@ void test_split()
CGAL_assertion(num_vertices(meshes[2]) == 142);
CGAL_assertion(num_vertices(meshes[3]) == 83);
CGAL_assertion(num_vertices(meshes[4]) == 104);
CGAL_assertion(tm1.is_valid());
CGAL::clear(tm1);
CGAL::clear(tm2);
@ -586,14 +587,59 @@ void test_split()
//if the list does contain all those numbers.
CGAL_assertion(num_vertices(meshes[0]) == 588);
CGAL_assertion(num_vertices(meshes[1]) == 50);
CGAL_assertion(tm1.is_valid());
CGAL::clear(tm1);
CGAL::clear(tm2);
meshes.clear();
}
template <class TriangleMesh>
void test_isocuboid()
{
TriangleMesh tm;
//closed intersection curves
std::ifstream input("data-coref/elephant.off");
input >> tm;
if(!input)
{
std::cerr<<"File not found. Aborting."<<std::endl;
CGAL_assertion(false);
return ;
}
input.close();
std::vector<TriangleMesh> meshes;
K::Iso_cuboid_3 splitter(K::Point_3(-0.3, -0.45, -0.25),
K::Point_3( 0.3, 0.45, 0.25));
PMP::split(tm, splitter);
PMP::split_connected_components(tm,
meshes);
CGAL_assertion(meshes.size() == 10);
//if the order is not deterministc, put the num_vertices in a list and check
//if the list does contain all those numbers.
CGAL_assertion(num_vertices(meshes[0]) == 2657);
CGAL_assertion(num_vertices(meshes[1]) == 131 );
CGAL_assertion(num_vertices(meshes[2]) == 32 );
CGAL_assertion(num_vertices(meshes[3]) == 123 );
CGAL_assertion(num_vertices(meshes[4]) == 220 );
CGAL_assertion(num_vertices(meshes[5]) == 107 );
CGAL_assertion(num_vertices(meshes[6]) == 121 );
CGAL_assertion(num_vertices(meshes[7]) == 56 );
CGAL_assertion(num_vertices(meshes[8]) == 49 );
CGAL_assertion(num_vertices(meshes[9]) == 13 );
CGAL_assertion(tm.is_valid());
CGAL::clear(tm);
meshes.clear();
}
int main()
{
std::cout << "Surface Mesh" << std::endl;
test<Surface_mesh>();
@ -603,6 +649,9 @@ int main()
std::cout << "running test_split with Surface_mesh\n";
test_split<Surface_mesh>();
std::cout << "running test_iso_cuboid with Surface_mesh\n";
test_isocuboid<Surface_mesh>();
std::cout << "running test_split_plane with Surface_mesh\n";
test_split_plane<Surface_mesh>();
@ -612,6 +661,8 @@ int main()
std::cout << "running test_split_plane with Polyhedron\n";
test_split_plane<Polyhedron>();
std::cout << "running test_iso_cuboid with Polyhedron\n";
test_isocuboid<Polyhedron>();
std::cout << "Done!" << std::endl;
return EXIT_SUCCESS;