diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt index 5f25dbfb367..823650933c9 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt @@ -38,8 +38,8 @@ ## Predicate Functions and Classes ## - `CGAL::is_oriented()` -- `CGAL::do_self_intersect()` -- `CGAL::self_intersections()` +- `CGAL::Polygon_mesh_processing::is_self_intersecting()` +- `CGAL::Polygon_mesh_processing::self_intersections()` - `CGAL::Point_inside_polyhedron_3` ## Combinatorial Repairing Functions and Classes ## diff --git a/Polygon_mesh_processing/include/CGAL/Self_intersection_polyhedron_3.h b/Polygon_mesh_processing/include/CGAL/polygon_mesh_self_intersections.h similarity index 52% rename from Polygon_mesh_processing/include/CGAL/Self_intersection_polyhedron_3.h rename to Polygon_mesh_processing/include/CGAL/polygon_mesh_self_intersections.h index 7204fceb8ae..aadada98ad0 100644 --- a/Polygon_mesh_processing/include/CGAL/Self_intersection_polyhedron_3.h +++ b/Polygon_mesh_processing/include/CGAL/polygon_mesh_self_intersections.h @@ -22,8 +22,8 @@ // compute self-intersection of a CGAL triangle polyhedron mesh // original code from Lutz Kettner -#ifndef CGAL_SELF_INTERSECTION_POLYHEDRON_3 -#define CGAL_SELF_INTERSECTION_POLYHEDRON_3 +#ifndef CGAL_POLYGON_MESH_SELF_INTERSECTIONS +#define CGAL_POLYGON_MESH_SELF_INTERSECTIONS #include #include @@ -38,7 +38,7 @@ namespace CGAL { namespace internal { -template +template struct Intersect_facets { // wrapper to check whether anything is inserted to output iterator @@ -59,11 +59,11 @@ struct Intersect_facets // typedefs typedef typename Kernel::Segment_3 Segment; typedef typename Kernel::Triangle_3 Triangle; - typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - typedef typename boost::property_map::const_type Ppmap; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::property_map::const_type Ppmap; // members - const FaceGraph& m_polyhedron; + const PolygonMesh& m_pmesh; const Ppmap m_point; mutable OutputIterator m_iterator; mutable bool m_intersected; @@ -74,10 +74,10 @@ struct Intersect_facets typename Kernel::Do_intersect_3 do_intersect_3_functor; - Intersect_facets(const FaceGraph& polyhedron, OutputIterator it, const Kernel& kernel) + Intersect_facets(const PolygonMesh& pmesh, OutputIterator it, const Kernel& kernel) : - m_polyhedron(polyhedron), - m_point(get(vertex_point, m_polyhedron)), + m_pmesh(pmesh), + m_point(get(vertex_point, m_pmesh)), m_iterator(it), m_intersected(false), m_iterator_wrapper(Output_iterator_with_bool(&m_iterator, &m_intersected)), @@ -89,53 +89,53 @@ struct Intersect_facets void operator()(const Box* b, const Box* c) const { - halfedge_descriptor h = halfedge(b->info(),m_polyhedron); + halfedge_descriptor h = halfedge(b->info(),m_pmesh); // check for shared egde --> no intersection - if(face(opposite(h,m_polyhedron),m_polyhedron) == c->info() || - face(opposite(next(h,m_polyhedron),m_polyhedron),m_polyhedron) == c->info() || - face(opposite(next(next(h,m_polyhedron),m_polyhedron),m_polyhedron),m_polyhedron) == c->info()) + if(face(opposite(h,m_pmesh),m_pmesh) == c->info() || + face(opposite(next(h,m_pmesh),m_pmesh),m_pmesh) == c->info() || + face(opposite(next(next(h,m_pmesh),m_pmesh),m_pmesh),m_pmesh) == c->info()) return; // check for shared vertex --> maybe intersection, maybe not - halfedge_descriptor g = halfedge(c->info(),m_polyhedron); + halfedge_descriptor g = halfedge(c->info(),m_pmesh); halfedge_descriptor v; - if(target(h,m_polyhedron) == target(g,m_polyhedron)) + if(target(h,m_pmesh) == target(g,m_pmesh)) v = g; - if(target(h,m_polyhedron) == target(next(g,m_polyhedron),m_polyhedron)) - v = next(g,m_polyhedron); - if(target(h,m_polyhedron) == target(next(next(g,m_polyhedron),m_polyhedron),m_polyhedron)) - v = next(next(g,m_polyhedron),m_polyhedron); + if(target(h,m_pmesh) == target(next(g,m_pmesh),m_pmesh)) + v = next(g,m_pmesh); + if(target(h,m_pmesh) == target(next(next(g,m_pmesh),m_pmesh),m_pmesh)) + v = next(next(g,m_pmesh),m_pmesh); if(v == halfedge_descriptor()){ - h = next(h,m_polyhedron); - if(target(h,m_polyhedron) == target(g,m_polyhedron)) + h = next(h,m_pmesh); + if(target(h,m_pmesh) == target(g,m_pmesh)) v = g; - if(target(h,m_polyhedron) == target(next(g,m_polyhedron),m_polyhedron)) - v = next(g,m_polyhedron); - if(target(h,m_polyhedron) == target(next(next(g,m_polyhedron),m_polyhedron),m_polyhedron)) - v = next(next(g,m_polyhedron),m_polyhedron); + if(target(h,m_pmesh) == target(next(g,m_pmesh),m_pmesh)) + v = next(g,m_pmesh); + if(target(h,m_pmesh) == target(next(next(g,m_pmesh),m_pmesh),m_pmesh)) + v = next(next(g,m_pmesh),m_pmesh); if(v == halfedge_descriptor()){ - h = next(h,m_polyhedron); - if(target(h,m_polyhedron) == target(g,m_polyhedron)) + h = next(h,m_pmesh); + if(target(h,m_pmesh) == target(g,m_pmesh)) v = g; - if(target(h,m_polyhedron) == target(next(g,m_polyhedron),m_polyhedron)) - v = next(g,m_polyhedron); - if(target(h,m_polyhedron) == target(next(next(g,m_polyhedron),m_polyhedron),m_polyhedron)) - v = next(next(g,m_polyhedron),m_polyhedron); + if(target(h,m_pmesh) == target(next(g,m_pmesh),m_pmesh)) + v = next(g,m_pmesh); + if(target(h,m_pmesh) == target(next(next(g,m_pmesh),m_pmesh),m_pmesh)) + v = next(next(g,m_pmesh),m_pmesh); } } if(v != halfedge_descriptor()){ // found shared vertex: - CGAL_assertion(target(h,m_polyhedron) == target(v,m_polyhedron)); + CGAL_assertion(target(h,m_pmesh) == target(v,m_pmesh)); // geometric check if the opposite segments intersect the triangles - Triangle t1 = triangle_functor( m_point[target(h,m_polyhedron)], m_point[target(next(h,m_polyhedron),m_polyhedron)], m_point[target(next(next(h,m_polyhedron),m_polyhedron),m_polyhedron)]); - Triangle t2 = triangle_functor( m_point[target(v,m_polyhedron)], m_point[target(next(v,m_polyhedron),m_polyhedron)], m_point[target(next(next(v,m_polyhedron),m_polyhedron),m_polyhedron)]); + Triangle t1 = triangle_functor( m_point[target(h,m_pmesh)], m_point[target(next(h,m_pmesh),m_pmesh)], m_point[target(next(next(h,m_pmesh),m_pmesh),m_pmesh)]); + Triangle t2 = triangle_functor( m_point[target(v,m_pmesh)], m_point[target(next(v,m_pmesh),m_pmesh)], m_point[target(next(next(v,m_pmesh),m_pmesh),m_pmesh)]); - Segment s1 = segment_functor( m_point[target(next(h,m_polyhedron),m_polyhedron)], m_point[target(next(next(h,m_polyhedron),m_polyhedron),m_polyhedron)]); - Segment s2 = segment_functor( m_point[target(next(v,m_polyhedron),m_polyhedron)], m_point[target(next(next(v,m_polyhedron),m_polyhedron),m_polyhedron)]); + Segment s1 = segment_functor( m_point[target(next(h,m_pmesh),m_pmesh)], m_point[target(next(next(h,m_pmesh),m_pmesh),m_pmesh)]); + Segment s2 = segment_functor( m_point[target(next(v,m_pmesh),m_pmesh)], m_point[target(next(next(v,m_pmesh),m_pmesh),m_pmesh)]); if(do_intersect_3_functor(t1,s2)){ *m_iterator_wrapper++ = std::make_pair(b->info(), c->info()); @@ -146,8 +146,8 @@ struct Intersect_facets } // check for geometric intersection - Triangle t1 = triangle_functor( m_point[target(h,m_polyhedron)], m_point[target(next(h,m_polyhedron),m_polyhedron)], m_point[target(next(next(h,m_polyhedron),m_polyhedron),m_polyhedron)]); - Triangle t2 = triangle_functor( m_point[target(g,m_polyhedron)], m_point[target(next(g,m_polyhedron),m_polyhedron)], m_point[target(next(next(g,m_polyhedron),m_polyhedron),m_polyhedron)]); + Triangle t1 = triangle_functor( m_point[target(h,m_pmesh)], m_point[target(next(h,m_pmesh),m_pmesh)], m_point[target(next(next(h,m_pmesh),m_pmesh),m_pmesh)]); + Triangle t2 = triangle_functor( m_point[target(g,m_pmesh)], m_point[target(next(g,m_pmesh),m_pmesh)], m_point[target(next(next(g,m_pmesh),m_pmesh),m_pmesh)]); if(do_intersect_3_functor(t1, t2)){ *m_iterator_wrapper++ = std::make_pair(b->info(), c->info()); } @@ -166,6 +166,8 @@ struct Throw_at_output { }// namespace internal +namespace Polygon_mesh_processing { + /** * \ingroup PkgPolygonMeshProcessing * Detects and reports self-intersections of a triangulated polyhedral surface. @@ -173,55 +175,55 @@ struct Throw_at_output { * @pre @a p.is_pure_triangle() * * @tparam GeomTraits a model of `SelfIntersectionTraits` - * @tparam FaceGraph a \cgal polyhedron - * @tparam OutputIterator Output iterator accepting objects of type `std::pair` - * if @a polyhedron is passed by const reference. + * @tparam PolygonMesh a model of `FaceListGraph` (possibly a \cgal polyhedron) + * @tparam OutputIterator Output iterator accepting objects of type + * `std::pair` + * if @a polygon mesh is passed by const reference. * - * @param polyhedron polyhedron to be checked, might be passed by const reference or reference + * @param pmesh polygon mesh to be checked, might be passed by const reference or reference * @param out all pairs of non-adjacent facets intersecting are put in it * @param geom_traits traits class providing intersection test primitives * * @return `out`. Note the OutputIterator can be empty. * - * \todo Polyhedron should be a model of `FaceListGraph` - * \todo check whether polyhedron should be `p.is_pure_triangle()`. Inconsistency between code and doc + * \todo check whether polygon mesh should be `p.is_pure_triangle()`. Inconsistency between code and doc */ -template +template OutputIterator -self_intersections(const FaceGraph& polyhedron, +self_intersections(const PolygonMesh& pmesh, OutputIterator out, const GeomTraits& geom_traits = GeomTraits()) { - //CGAL_assertion(polyhedron.is_pure_triangle()); + //CGAL_assertion(pmesh.is_pure_triangle()); - typedef typename boost::graph_traits::face_iterator Facet_it; + typedef typename boost::graph_traits::face_iterator Facet_it; - typedef typename boost::graph_traits::face_descriptor Facet_hdl; + typedef typename boost::graph_traits::face_descriptor Facet_hdl; typedef typename CGAL::Box_intersection_d::Box_with_info_d Box; - typedef typename boost::property_map::const_type Ppmap; + typedef typename boost::property_map::const_type Ppmap; - Ppmap m_point = get(CGAL::vertex_point, polyhedron); + Ppmap m_point = get(CGAL::vertex_point, pmesh); // make one box per facet std::vector boxes; - boxes.reserve(num_faces(polyhedron)); + boxes.reserve(num_faces(pmesh)); Facet_it fi,e; - for(boost::tie(fi,e)= faces(polyhedron); + for(boost::tie(fi,e)= faces(pmesh); fi != e; ++fi){ Facet_hdl f = *fi; - boxes.push_back(Box( m_point[target(halfedge(f,polyhedron),polyhedron)].bbox() + - m_point[target(next(halfedge(f,polyhedron),polyhedron),polyhedron)].bbox() + - m_point[target(next(next(halfedge(f,polyhedron),polyhedron),polyhedron),polyhedron)].bbox(), + boxes.push_back(Box( m_point[target(halfedge(f,pmesh),pmesh)].bbox() + + m_point[target(next(halfedge(f,pmesh),pmesh),pmesh)].bbox() + + m_point[target(next(next(halfedge(f,pmesh),pmesh),pmesh),pmesh)].bbox(), f)); } // generate box pointers std::vector box_ptr; - box_ptr.reserve(num_faces(polyhedron)); + box_ptr.reserve(num_faces(pmesh)); typename std::vector::iterator b; for(b = boxes.begin(); b != boxes.end(); @@ -229,7 +231,7 @@ self_intersections(const FaceGraph& polyhedron, box_ptr.push_back(&*b); // compute self-intersections filtered out by boxes - internal::Intersect_facets intersect_facets(polyhedron, out, geom_traits); + internal::Intersect_facets intersect_facets(pmesh, out, geom_traits); std::ptrdiff_t cutoff = 2000; CGAL::box_self_intersection_d(box_ptr.begin(), box_ptr.end(),intersect_facets,cutoff); return intersect_facets.m_iterator; @@ -237,26 +239,27 @@ self_intersections(const FaceGraph& polyhedron, /** * \ingroup PkgPolygonMeshProcessing - * Checks if a polyhedron is self-intersecting. + * Checks if a polygon mesh is self-intersecting. * Depends on \ref PkgBoxIntersectionDSummary * @pre @a p.is_pure_triangle() * * @tparam GeomTraits a model of `SelfIntersectionTraits` - * @tparam FaceGraph a %CGAL polyhedron + * @tparam PolygonMesh a model of `FaceListGraph` (possibly a %CGAL polyhedron) * - * @param polyhedron polyhedron to be tested + * @param pmesh PolygonMesh to be tested * @param geom_traits traits class providing intersection test primitives * * \todo Polyhedron should be a model of `FaceListGraph` - * @return true if `polyhedron` is self-intersecting + * @return true if `mes` is self-intersecting */ -template -bool do_self_intersect(const FaceGraph& polyhedron, const GeomTraits& geom_traits = GeomTraits()) +template +bool is_self_intersecting(const PolygonMesh& pmesh, + const GeomTraits& geom_traits = GeomTraits()) { try { typedef boost::function_output_iterator OutputIterator; - self_intersections(polyhedron, OutputIterator(), geom_traits); + self_intersections(pmesh, OutputIterator(), geom_traits); } catch( internal::Throw_at_output::Throw_at_output_exception& ) { return true; } @@ -264,6 +267,8 @@ bool do_self_intersect(const FaceGraph& polyhedron, const GeomTraits& geom_trait return false; } +}// end namespace Polygon_mesh_processing + }// namespace CGAL #endif // CGAL_SELF_INTERSECTION_POLYHEDRON_3 diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/self_intersection_polyhedron_test.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/self_intersection_polyhedron_test.cpp index f7d67655b6c..2c42fe76f6f 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/self_intersection_polyhedron_test.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/self_intersection_polyhedron_test.cpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include @@ -27,7 +27,8 @@ int main(int, char** argv) { timer.start(); std::vector > intersected_tris; - CGAL::self_intersections(poly, back_inserter(intersected_tris)); + CGAL::Polygon_mesh_processing::self_intersections + (poly, back_inserter(intersected_tris)); bool intersecting_1 = !intersected_tris.empty(); CGAL_assertion(intersecting_1); @@ -35,10 +36,11 @@ int main(int, char** argv) { std::cerr << intersected_tris.size() << " pairs of triangles are intersecting." << std::endl; timer.reset(); - bool intersecting_2 = CGAL::do_self_intersect(poly); + bool intersecting_2 + = CGAL::Polygon_mesh_processing::is_self_intersecting(poly); CGAL_assertion(intersecting_1 == intersecting_2); - std::cerr << "Is self-intersection test took " << timer.time() << " sec." << std::endl; + std::cerr << "is_self_intersecting test took " << timer.time() << " sec." << std::endl; std::cerr << (intersecting_2 ? "There is a self-intersection." : "There is no self-intersection.") << std::endl; return 0; diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/self_intersection_surface_mesh_test.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/self_intersection_surface_mesh_test.cpp index 793be9131c4..e3e5abc5be3 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/self_intersection_surface_mesh_test.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/self_intersection_surface_mesh_test.cpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include typedef CGAL::Exact_predicates_inexact_constructions_kernel K; @@ -25,17 +25,19 @@ int main(int, char** argv) { timer.start(); std::vector > intersected_tris; - CGAL::self_intersections(m, back_inserter(intersected_tris)); + CGAL::Polygon_mesh_processing::self_intersections + (m, back_inserter(intersected_tris)); bool intersecting_1 = !intersected_tris.empty(); std::cerr << "self_intersections test took " << timer.time() << " sec." << std::endl; std::cerr << intersected_tris.size() << " pairs of triangles are intersecting." << std::endl; timer.reset(); - bool intersecting_2 = CGAL::do_self_intersect(m); + bool intersecting_2 + = CGAL::Polygon_mesh_processing::is_self_intersecting(m); CGAL_assertion(intersecting_1 == intersecting_2); - std::cerr << "do_self_intersect test took " << timer.time() << " sec." << std::endl; + std::cerr << "is_self_intersecting test took " << timer.time() << " sec." << std::endl; std::cerr << (intersecting_2 ? "There is a self-intersection." : "There is no self-intersection.") << std::endl; return 0; diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_self_intersection_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_self_intersection_plugin.cpp index 1c6c3670efc..0da0f14c80c 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_self_intersection_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_self_intersection_plugin.cpp @@ -14,7 +14,7 @@ #include #include -#include +#include #include typedef Kernel::Triangle_3 Triangle; @@ -56,7 +56,8 @@ void Polyhedron_demo_self_intersection_plugin::on_actionSelfIntersection_trigger typedef Polyhedron::Facet_handle Facet_handle; std::vector > facets; - CGAL::self_intersections(*pMesh, back_inserter(facets)); + CGAL::Polygon_mesh_processing::self_intersections + (*pMesh, back_inserter(facets)); std::cout << "ok (" << facets.size() << " triangle pair(s))" << std::endl;