From 74fdcb92f1a94d5c024e8dfcc38f390b66405c24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 5 Oct 2018 08:54:11 +0200 Subject: [PATCH 001/141] move does_bound_a_volume() to orientation --- .../PackageDescription.txt | 2 +- .../Polygon_mesh_processing/corefinement.h | 185 ------------------ .../Polygon_mesh_processing/orientation.h | 181 +++++++++++++++++ 3 files changed, 182 insertions(+), 186 deletions(-) diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt index 3baa705dad3..42bb1ef82cf 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt @@ -119,6 +119,7 @@ and provides a list of the parameters that are used in this package. - `CGAL::Polygon_mesh_processing::reverse_face_orientations()` - `CGAL::Polygon_mesh_processing::orient_polygon_soup()` - `CGAL::Polygon_mesh_processing::orient()` +- `CGAL::Polygon_mesh_processing::does_bound_a_volume()` - `CGAL::Polygon_mesh_processing::orient_to_bound_a_volume()` ## Combinatorial Repairing Functions ## @@ -150,7 +151,6 @@ and provides a list of the parameters that are used in this package. - `CGAL::Polygon_mesh_processing::corefine()` - `CGAL::Polygon_mesh_processing::surface_intersection()` - `CGAL::Polygon_mesh_processing::clip()` -- `CGAL::Polygon_mesh_processing::does_bound_a_volume()` ## Geometric Measure Functions ## - \link measure_grp `CGAL::Polygon_mesh_processing::face_area()` \endlink diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/corefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/corefinement.h index 1f7383346ed..f52a7fdbaed 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/corefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/corefinement.h @@ -43,95 +43,6 @@ using Polygon_mesh_processing::Corefinement::Self_intersection_exception; namespace Polygon_mesh_processing { -namespace internal { - -template -bool recursive_does_bound_a_volume(const TriangleMesh& tm, - Vpm& vpm, - Fid_map& fid_map, - const std::vector& xtrm_vertices, - boost::dynamic_bitset<>& cc_handled, - const std::vector& face_cc, - std::size_t xtrm_cc_id, - bool is_parent_outward_oriented) -{ - typedef boost::graph_traits GT; - typedef typename GT::face_descriptor face_descriptor; - typedef Side_of_triangle_mesh Side_of_tm; -// first check that the orientation of the current cc is consistant with its -// parent cc containing it - bool new_is_parent_outward_oriented = internal::is_outward_oriented( - xtrm_vertices[xtrm_cc_id], tm, parameters::vertex_point_map(vpm)); - if (new_is_parent_outward_oriented==is_parent_outward_oriented) - return false; - cc_handled.set(xtrm_cc_id); - - std::size_t nb_cc = cc_handled.size(); - -// get all cc that are inside xtrm_cc_id - std::vector cc_faces; - BOOST_FOREACH(face_descriptor fd, faces(tm)) - { - if(face_cc[get(fid_map, fd)]==xtrm_cc_id) - cc_faces.push_back(fd); - } - - typename Side_of_tm::AABB_tree aabb_tree(cc_faces.begin(), cc_faces.end(), - tm, vpm); - Side_of_tm side_of_cc(aabb_tree); - - std::vector cc_inside; - for(std::size_t id=0; id new_cc_handled(nb_cc,0); - new_cc_handled.set(); - new_cc_handled.reset(new_xtrm_cc_id); - cc_handled.set(new_xtrm_cc_id); - - std::size_t nb_candidates = cc_inside.size(); - for (std::size_t i=1;i - get(vpm,xtrm_vertices[new_xtrm_cc_id]).z()) new_xtrm_cc_id=candidate; - new_cc_handled.reset(candidate); - cc_handled.set(candidate); - } - - if ( !internal::recursive_does_bound_a_volume( - tm, vpm, fid_map, xtrm_vertices, new_cc_handled, face_cc, - new_xtrm_cc_id, new_is_parent_outward_oriented) ) return false; - } - -// now explore remaining cc included in the same cc as xtrm_cc_id - boost::dynamic_bitset<> cc_not_handled = ~cc_handled; - std::size_t new_xtrm_cc_id = cc_not_handled.find_first(); - if (new_xtrm_cc_id == cc_not_handled.npos) return true; - - for (std::size_t candidate = cc_not_handled.find_next(new_xtrm_cc_id); - candidate < cc_not_handled.npos; - candidate = cc_not_handled.find_next(candidate)) - { - if(get(vpm,xtrm_vertices[candidate]).z() > get(vpm,xtrm_vertices[new_xtrm_cc_id]).z()) - new_xtrm_cc_id = candidate; - } - - return internal::recursive_does_bound_a_volume( - tm, vpm, fid_map, xtrm_vertices, cc_handled, face_cc, - new_xtrm_cc_id, is_parent_outward_oriented); -} - -} //end of namespace internal - namespace Corefinement { /** \ingroup PMP_corefinement_grp @@ -152,102 +63,6 @@ enum Boolean_operation_type {UNION = 0, INTERSECTION=1, #endif } -/** \ingroup PMP_corefinement_grp - * - * indicates if `tm` bounds a volume. - * See \ref coref_def_subsec for details. - * - * @tparam TriangleMesh a model of `MutableFaceGraph`, `HalfedgeListGraph` and `FaceListGraph`. - * @tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" - * - * @param tm a closed triangulated surface mesh - * @param np optional sequence of \ref pmp_namedparameters "Named Parameters" among the ones listed below - * - * @pre `CGAL::is_closed(tm)` - * - * \cgalNamedParamsBegin - * \cgalParamBegin{vertex_point_map} - * the property map with the points associated to the vertices of `tm`. - * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` must be available in `TriangleMesh` - * \cgalParamEnd - * \cgalParamBegin{face_index_map} - * a property map containing the index of each face of `tm`. - * \cgalParamEnd - * \cgalNamedParamsEnd - * - * \see `CGAL::Polygon_mesh_processing::orient_to_bound_a_volume()` - */ -template -bool does_bound_a_volume(const TriangleMesh& tm, const NamedParameters& np) -{ - typedef boost::graph_traits GT; - typedef typename GT::vertex_descriptor vertex_descriptor; - typedef typename GetVertexPointMap::const_type Vpm; - typedef typename GetFaceIndexMap::const_type Fid_map; - typedef typename Kernel_traits< - typename boost::property_traits::value_type >::Kernel Kernel; - - if (!is_closed(tm)) return false; - if (!is_triangle_mesh(tm)) return false; - - Vpm vpm = boost::choose_param(boost::get_param(np, internal_np::vertex_point), - get_const_property_map(boost::vertex_point, tm)); - - Fid_map fid_map = boost::choose_param(boost::get_param(np, internal_np::face_index), - get_const_property_map(boost::face_index, tm)); - - std::vector face_cc(num_faces(tm), std::size_t(-1)); - - // set the connected component id of each face - std::size_t nb_cc = connected_components(tm, - bind_property_maps(fid_map,make_property_map(face_cc)), - parameters::face_index_map(fid_map)); - - if (nb_cc == 1) - return true; - - boost::dynamic_bitset<> cc_handled(nb_cc, 0); - - // extract a vertex with max z coordinate for each connected component - std::vector xtrm_vertices(nb_cc, GT::null_vertex()); - BOOST_FOREACH(vertex_descriptor vd, vertices(tm)) - { - std::size_t cc_id = face_cc[get(fid_map, face(halfedge(vd, tm), tm))]; - if (xtrm_vertices[cc_id]==GT::null_vertex()) - xtrm_vertices[cc_id]=vd; - else - if (get(vpm, vd).z()>get(vpm,xtrm_vertices[cc_id]).z()) - xtrm_vertices[cc_id]=vd; - } - - //extract a vertex with max z amongst all components - std::size_t xtrm_cc_id=0; - for(std::size_t id=1; idget(vpm,xtrm_vertices[xtrm_cc_id]).z()) - xtrm_cc_id=id; - - bool is_parent_outward_oriented = - !internal::is_outward_oriented(xtrm_vertices[xtrm_cc_id], tm, np); - - return internal::recursive_does_bound_a_volume(tm, vpm, fid_map, - xtrm_vertices, - cc_handled, - face_cc, - xtrm_cc_id, - is_parent_outward_oriented); -} - -/// \cond SKIP_IN_MANUAL -template -bool does_bound_a_volume(const TriangleMesh& tm) -{ - return does_bound_a_volume(tm, parameters::all_default()); -} -/// \endcond - #define CGAL_COREF_SET_OUTPUT_EDGE_MARK_MAP(I) \ typedef typename boost::lookup_named_param_def < \ internal_np::edge_is_constrained_t, \ diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index 7434a130cec..9e65881f184 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -349,6 +349,91 @@ void reverse_face_orientations(const FaceRange& face_range, PolygonMesh& pmesh) } namespace internal { +template +bool recursive_does_bound_a_volume(const TriangleMesh& tm, + Vpm& vpm, + Fid_map& fid_map, + const std::vector& xtrm_vertices, + boost::dynamic_bitset<>& cc_handled, + const std::vector& face_cc, + std::size_t xtrm_cc_id, + bool is_parent_outward_oriented) +{ + typedef boost::graph_traits GT; + typedef typename GT::face_descriptor face_descriptor; + typedef Side_of_triangle_mesh Side_of_tm; +// first check that the orientation of the current cc is consistant with its +// parent cc containing it + bool new_is_parent_outward_oriented = internal::is_outward_oriented( + xtrm_vertices[xtrm_cc_id], tm, parameters::vertex_point_map(vpm)); + if (new_is_parent_outward_oriented==is_parent_outward_oriented) + return false; + cc_handled.set(xtrm_cc_id); + + std::size_t nb_cc = cc_handled.size(); + +// get all cc that are inside xtrm_cc_id + std::vector cc_faces; + BOOST_FOREACH(face_descriptor fd, faces(tm)) + { + if(face_cc[get(fid_map, fd)]==xtrm_cc_id) + cc_faces.push_back(fd); + } + + typename Side_of_tm::AABB_tree aabb_tree(cc_faces.begin(), cc_faces.end(), + tm, vpm); + Side_of_tm side_of_cc(aabb_tree); + + std::vector cc_inside; + for(std::size_t id=0; id new_cc_handled(nb_cc,0); + new_cc_handled.set(); + new_cc_handled.reset(new_xtrm_cc_id); + cc_handled.set(new_xtrm_cc_id); + + std::size_t nb_candidates = cc_inside.size(); + for (std::size_t i=1;i + get(vpm,xtrm_vertices[new_xtrm_cc_id]).z()) new_xtrm_cc_id=candidate; + new_cc_handled.reset(candidate); + cc_handled.set(candidate); + } + + if ( !internal::recursive_does_bound_a_volume( + tm, vpm, fid_map, xtrm_vertices, new_cc_handled, face_cc, + new_xtrm_cc_id, new_is_parent_outward_oriented) ) return false; + } + +// now explore remaining cc included in the same cc as xtrm_cc_id + boost::dynamic_bitset<> cc_not_handled = ~cc_handled; + std::size_t new_xtrm_cc_id = cc_not_handled.find_first(); + if (new_xtrm_cc_id == cc_not_handled.npos) return true; + + for (std::size_t candidate = cc_not_handled.find_next(new_xtrm_cc_id); + candidate < cc_not_handled.npos; + candidate = cc_not_handled.find_next(candidate)) + { + if(get(vpm,xtrm_vertices[candidate]).z() > get(vpm,xtrm_vertices[new_xtrm_cc_id]).z()) + new_xtrm_cc_id = candidate; + } + + return internal::recursive_does_bound_a_volume( + tm, vpm, fid_map, xtrm_vertices, cc_handled, face_cc, + new_xtrm_cc_id, is_parent_outward_oriented); +} + template void recursive_orient_volume_ccs( TriangleMesh& tm, Vpm& vpm, @@ -543,6 +628,102 @@ void orient(TriangleMesh& tm) orient(tm, parameters::all_default()); } +/** \ingroup PMP_orientation_grp + * + * indicates if `tm` bounds a volume. + * See \ref coref_def_subsec for details. + * + * @tparam TriangleMesh a model of `MutableFaceGraph`, `HalfedgeListGraph` and `FaceListGraph`. + * @tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" + * + * @param tm a closed triangulated surface mesh + * @param np optional sequence of \ref pmp_namedparameters "Named Parameters" among the ones listed below + * + * @pre `CGAL::is_closed(tm)` + * + * \cgalNamedParamsBegin + * \cgalParamBegin{vertex_point_map} + * the property map with the points associated to the vertices of `tm`. + * If this parameter is omitted, an internal property map for + * `CGAL::vertex_point_t` must be available in `TriangleMesh` + * \cgalParamEnd + * \cgalParamBegin{face_index_map} + * a property map containing the index of each face of `tm`. + * \cgalParamEnd + * \cgalNamedParamsEnd + * + * \see `CGAL::Polygon_mesh_processing::orient_to_bound_a_volume()` + */ +template +bool does_bound_a_volume(const TriangleMesh& tm, const NamedParameters& np) +{ + typedef boost::graph_traits GT; + typedef typename GT::vertex_descriptor vertex_descriptor; + typedef typename GetVertexPointMap::const_type Vpm; + typedef typename GetFaceIndexMap::const_type Fid_map; + typedef typename Kernel_traits< + typename boost::property_traits::value_type >::Kernel Kernel; + + if (!is_closed(tm)) return false; + if (!is_triangle_mesh(tm)) return false; + + Vpm vpm = boost::choose_param(boost::get_param(np, internal_np::vertex_point), + get_const_property_map(boost::vertex_point, tm)); + + Fid_map fid_map = boost::choose_param(boost::get_param(np, internal_np::face_index), + get_const_property_map(boost::face_index, tm)); + + std::vector face_cc(num_faces(tm), std::size_t(-1)); + + // set the connected component id of each face + std::size_t nb_cc = connected_components(tm, + bind_property_maps(fid_map,make_property_map(face_cc)), + parameters::face_index_map(fid_map)); + + if (nb_cc == 1) + return true; + + boost::dynamic_bitset<> cc_handled(nb_cc, 0); + + // extract a vertex with max z coordinate for each connected component + std::vector xtrm_vertices(nb_cc, GT::null_vertex()); + BOOST_FOREACH(vertex_descriptor vd, vertices(tm)) + { + std::size_t cc_id = face_cc[get(fid_map, face(halfedge(vd, tm), tm))]; + if (xtrm_vertices[cc_id]==GT::null_vertex()) + xtrm_vertices[cc_id]=vd; + else + if (get(vpm, vd).z()>get(vpm,xtrm_vertices[cc_id]).z()) + xtrm_vertices[cc_id]=vd; + } + + //extract a vertex with max z amongst all components + std::size_t xtrm_cc_id=0; + for(std::size_t id=1; idget(vpm,xtrm_vertices[xtrm_cc_id]).z()) + xtrm_cc_id=id; + + bool is_parent_outward_oriented = + !internal::is_outward_oriented(xtrm_vertices[xtrm_cc_id], tm, np); + + return internal::recursive_does_bound_a_volume(tm, vpm, fid_map, + xtrm_vertices, + cc_handled, + face_cc, + xtrm_cc_id, + is_parent_outward_oriented); +} + +/// \cond SKIP_IN_MANUAL +template +bool does_bound_a_volume(const TriangleMesh& tm) +{ + return does_bound_a_volume(tm, parameters::all_default()); +} +/// \endcond + /** \ingroup PMP_orientation_grp * From 5db832d0021ad3ed1003819b3e5d5bfdb58d60ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 5 Oct 2018 15:20:33 +0200 Subject: [PATCH 002/141] first version of the code to split into volume --- .../Polygon_mesh_processing/orientation.h | 244 ++++++++++++++++++ .../Polygon_mesh_processing/CMakeLists.txt | 1 + .../test_split_volume.cpp | 49 ++++ 3 files changed, 294 insertions(+) create mode 100644 Polygon_mesh_processing/test/Polygon_mesh_processing/test_split_volume.cpp diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index 9e65881f184..644df45a3dc 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -31,10 +31,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include @@ -716,12 +718,254 @@ bool does_bound_a_volume(const TriangleMesh& tm, const NamedParameters& np) is_parent_outward_oriented); } +// doc: non-closed connected components are reported as isolated volumes +// doc: connected components with at least one non-triangle face are reported as isolated volumes +// doc: self-intersecting connect components are reported as isolated volumes. +// TODO return a vector with info on the volume? non-triangle/open/SI/regular/... +template +std::size_t +volume_connected_components(const TriangleMesh& tm, + FaceIndexMap volume_id_map, + const NamedParameters& np) +{ + typedef boost::graph_traits GT; + typedef typename GT::vertex_descriptor vertex_descriptor; + typedef typename GT::face_descriptor face_descriptor; + typedef typename GT::halfedge_descriptor halfedge_descriptor; + typedef typename GetVertexPointMap::const_type Vpm; + typedef typename GetFaceIndexMap::const_type Fid_map; + typedef typename Kernel_traits< + typename boost::property_traits::value_type >::Kernel Kernel; + + Vpm vpm = boost::choose_param(boost::get_param(np, internal_np::vertex_point), + get_const_property_map(boost::vertex_point, tm)); + + // TODO handle user provided CC map ? + Fid_map fid_map = boost::choose_param(boost::get_param(np, internal_np::face_index), + get_const_property_map(boost::face_index, tm)); + + std::vector face_cc(num_faces(tm), std::size_t(-1)); + + // set the connected component id of each face + std::size_t nb_cc = connected_components(tm, + bind_property_maps(fid_map,make_property_map(face_cc)), + parameters::face_index_map(fid_map)); + + if (nb_cc == 1) + { + BOOST_FOREACH(face_descriptor fd, faces(tm)) + put(volume_id_map, fd, 0); + return 1; + } + + boost::dynamic_bitset<> cc_handled(nb_cc, 0); + std::vector cc_volume_ids(nb_cc, -1); + + std::size_t next_volume_id = 0; + // First handle non-pure triangle meshes + BOOST_FOREACH(face_descriptor fd, faces(tm)) + { + if (!is_triangle(halfedge(fd, tm), tm)) + { + std::size_t cc_id = face_cc[ get(fid_map, fd) ]; + if ( !cc_handled.test(cc_id) ) + { + cc_handled.set(cc_id); + cc_volume_ids[cc_id]=next_volume_id++; + } + } + } + + // Handle open connected components + BOOST_FOREACH(halfedge_descriptor h, halfedges(tm)) + { + if (is_border(h, tm)) + { + face_descriptor fd = face( opposite(h, tm), tm ); + std::size_t cc_id = face_cc[ get(fid_map, fd) ]; + if ( !cc_handled.test(cc_id) ) + { + cc_handled.set(cc_id); + cc_volume_ids[cc_id]=next_volume_id++; + } + } + } + + // Handle self-intersecting connected components + // TODO add an option for self-intersection handling (optional if known to be free from self-intersections + typedef std::pair Face_pair; + std::vector si_faces; + std::set< std::pair > inclusion_test_to_skip; // due to self-intersections TODO USE ME + self_intersections(tm, std::back_inserter(si_faces)); + BOOST_FOREACH(const Face_pair& fp, si_faces) + { + std::size_t first_cc_id = face_cc[ get(fid_map, fp.first) ]; + std::size_t second_cc_id = face_cc[ get(fid_map, fp.second) ]; + + if (first_cc_id==second_cc_id) + { + if ( !cc_handled.test(first_cc_id) ) + { + cc_handled.set(first_cc_id); + cc_volume_ids[first_cc_id]=next_volume_id++; + } + } + else + inclusion_test_to_skip.insert( make_sorted_pair(first_cc_id, second_cc_id) ); + } + + if (!cc_handled.all()) + { + // extract a vertex with max z coordinate for each connected component + std::vector xtrm_vertices(nb_cc, GT::null_vertex()); + BOOST_FOREACH(vertex_descriptor vd, vertices(tm)) + { + std::size_t cc_id = face_cc[get(fid_map, face(halfedge(vd, tm), tm))]; + if (cc_handled.test(cc_id)) continue; + if (xtrm_vertices[cc_id]==GT::null_vertex()) + xtrm_vertices[cc_id]=vd; + else + if (get(vpm, vd).z()>get(vpm,xtrm_vertices[cc_id]).z()) + xtrm_vertices[cc_id]=vd; + } + + const bool ignore_orientation_of_cc = false; // TODO add an option + + boost::dynamic_bitset<> is_cc_outward_oriented; + if (!ignore_orientation_of_cc) + { + is_cc_outward_oriented.resize(nb_cc); + for(std::size_t cc_id=0; cc_id > faces_per_cc(nb_cc); + std::vector< std::size_t > nb_faces_per_cc(nb_cc, 0); + BOOST_FOREACH(face_descriptor fd, faces(tm)) + { + std::size_t cc_id = face_cc[ get(fid_map, fd) ]; + ++nb_faces_per_cc[ cc_id ]; + } + for (std::size_t i=0; i > nested_cc_per_cc(nb_cc); // contains for each CC the CC that are in its bounded side + std::vector < std::size_t > nesting_levels(nb_cc, 0); // indicates for each CC its nesting level + std::vector < boost::dynamic_bitset<> > level_k_nestings; // container containing CCs in the same volume (one bitset per volume) at level k + level_k_nestings.push_back( ~cc_handled ); + + // the following loop is exploring the nesting level by level (0 -> max_level) + while (!level_k_nestings.empty()) + { + std::vector < boost::dynamic_bitset<> > level_k_plus_1_nestings; + BOOST_FOREACH(boost::dynamic_bitset<> cc_to_handle, level_k_nestings) + { + CGAL_assertion( cc_to_handle.any() ); + while(cc_to_handle.any()) + { + //extract a vertex with max z amongst all components + std::size_t xtrm_cc_id=cc_to_handle.find_first(); + for(std::size_t id = cc_to_handle.find_next(xtrm_cc_id); + id != cc_to_handle.npos; + id = cc_to_handle.find_next(id)) + { + if (get(vpm, xtrm_vertices[id]).z()>get(vpm,xtrm_vertices[xtrm_cc_id]).z()) + xtrm_cc_id=id; + } + cc_to_handle.reset(xtrm_cc_id); + nesting_levels[xtrm_cc_id] = k; + + // collect id inside xtrm_cc_id CC + typedef Side_of_triangle_mesh Side_of_tm; + typename Side_of_tm::AABB_tree aabb_tree(faces_per_cc[xtrm_cc_id].begin(), + faces_per_cc[xtrm_cc_id].end(), + tm, vpm); + Side_of_tm side_of_cc(aabb_tree); + + boost::dynamic_bitset<> nested_cc_to_handle(nb_cc, 0); + for(std::size_t id = cc_to_handle.find_first(); + id != cc_to_handle.npos; + id = cc_to_handle.find_next(id)) + { + if (side_of_cc(get(vpm,xtrm_vertices[id]))==ON_BOUNDED_SIDE) + { + nested_cc_per_cc[xtrm_cc_id].push_back(id); + // mark nested CC as handle and collect them for the handling of the next level + nested_cc_to_handle.set(id); + cc_to_handle.reset(id); + } + } + + if ( nested_cc_per_cc[xtrm_cc_id].empty() ) continue; + level_k_plus_1_nestings.push_back(nested_cc_to_handle); + } + } + ++k; + level_k_nestings.swap(level_k_plus_1_nestings); + } + + if (!ignore_orientation_of_cc) + { + //TODO correct inclusion and nesting levels + } + + // apply volume classification using level 0 nesting + for(std::size_t cc_id=0; cc_id bool does_bound_a_volume(const TriangleMesh& tm) { return does_bound_a_volume(tm, parameters::all_default()); } + +template +std::size_t volume_connected_components(const TriangleMesh& tm, FaceIndexMap volume_id_map) +{ + return volume_connected_components(tm, volume_id_map, parameters::all_default()); +} /// \endcond diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt b/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt index 6ffde721a7d..7aa02b98849 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt @@ -101,6 +101,7 @@ endif() create_single_source_cgal_program("test_orient_cc.cpp") create_single_source_cgal_program("test_pmp_transform.cpp") create_single_source_cgal_program("extrude_test.cpp") + create_single_source_cgal_program("test_split_volume.cpp") if( TBB_FOUND ) CGAL_target_use_TBB(test_pmp_distance) diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_split_volume.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_split_volume.cpp new file mode 100644 index 00000000000..5290c7f9c75 --- /dev/null +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_split_volume.cpp @@ -0,0 +1,49 @@ +#include +#include +#include +#include + +#include +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; +typedef CGAL::Surface_mesh Surface_mesh; + +int main(int argc, char** argv) +{ + if (argc==1) + { + std::cerr << "Nothing tested\n"; + return 1; + } + + for(int i=1;i> sm; + + Surface_mesh::Property_map vol_id_map = + sm.add_property_map().first; + std::size_t nb_vol = + CGAL::Polygon_mesh_processing::volume_connected_components(sm, vol_id_map); + std::cout << " found " << nb_vol << " volumes\n"; + typedef CGAL::Face_filtered_graph Filtered_graph; + Filtered_graph vol_mesh(sm, 0, vol_id_map); + for(std::size_t id = 0; id < nb_vol; ++id) + { + if(id > 0) + vol_mesh.set_selected_faces(id, vol_id_map); + Surface_mesh out; + CGAL::copy_face_graph(vol_mesh, out); + std::ostringstream oss; + oss << "vol_" << id <<".off"; + std::ofstream os(oss.str().data()); + os << out; + } + } +} From b3a9d5fb96fee805bc24fb4977893e211d984bb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 11 Oct 2018 18:10:28 +0200 Subject: [PATCH 003/141] use connected volume for the segmentation --- .../include/CGAL/Polygon_mesh_processing/orientation.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index 644df45a3dc..6b080ea16ae 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -926,11 +926,14 @@ volume_connected_components(const TriangleMesh& tm, for(std::size_t cc_id=0; cc_id Date: Fri, 12 Oct 2018 08:17:59 +0200 Subject: [PATCH 004/141] handle inconsistant orientation of cc --- .../Polygon_mesh_processing/orientation.h | 37 +++++++++++++------ 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index 6b080ea16ae..87c979b358d 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -721,6 +721,10 @@ bool does_bound_a_volume(const TriangleMesh& tm, const NamedParameters& np) // doc: non-closed connected components are reported as isolated volumes // doc: connected components with at least one non-triangle face are reported as isolated volumes // doc: self-intersecting connect components are reported as isolated volumes. +// doc: add option ignore_orientation_of_cc to control whether the inward/outward orientation of +// component must be taken into account rather than only the nesting. In case of incompatible +// orientation of a cc X with its parent, all other CC included in X (as well as X) are reported +// as independant volumes // TODO return a vector with info on the volume? non-triangle/open/SI/regular/... template std::size_t @@ -917,24 +921,35 @@ volume_connected_components(const TriangleMesh& tm, level_k_nestings.swap(level_k_plus_1_nestings); } - if (!ignore_orientation_of_cc) - { - //TODO correct inclusion and nesting levels - } - // apply volume classification using level 0 nesting for(std::size_t cc_id=0; cc_id Date: Fri, 12 Oct 2018 08:27:08 +0200 Subject: [PATCH 005/141] compute the direct parent of each surface cc in the nesting hierarchy --- .../Polygon_mesh_processing/orientation.h | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index 87c979b358d..eda28f3c702 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -753,9 +753,9 @@ volume_connected_components(const TriangleMesh& tm, std::vector face_cc(num_faces(tm), std::size_t(-1)); // set the connected component id of each face - std::size_t nb_cc = connected_components(tm, - bind_property_maps(fid_map,make_property_map(face_cc)), - parameters::face_index_map(fid_map)); + const std::size_t nb_cc = connected_components(tm, + bind_property_maps(fid_map,make_property_map(face_cc)), + parameters::face_index_map(fid_map)); if (nb_cc == 1) { @@ -953,6 +953,19 @@ volume_connected_components(const TriangleMesh& tm, } } + // TODO: add nesting_parent as an optional output parameter + // note that this will require to also output the cc_id map + // extract direct nested parent (more than one in case of self-intersection) + std::vector< std::vector > nesting_parent(nb_cc, nb_cc+1); + for(std::size_t cc_id=0; cc_id Date: Fri, 12 Oct 2018 18:32:57 +0200 Subject: [PATCH 006/141] Handle intersections between CCs --- .../Polygon_mesh_processing/orientation.h | 100 ++++++++++++++---- 1 file changed, 82 insertions(+), 18 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index eda28f3c702..163e20c2a64 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -721,6 +721,7 @@ bool does_bound_a_volume(const TriangleMesh& tm, const NamedParameters& np) // doc: non-closed connected components are reported as isolated volumes // doc: connected components with at least one non-triangle face are reported as isolated volumes // doc: self-intersecting connect components are reported as isolated volumes. +// doc: CC intersecting another CC is reported as a seperate volume and so are its nested CCs // doc: add option ignore_orientation_of_cc to control whether the inward/outward orientation of // component must be taken into account rather than only the nesting. In case of incompatible // orientation of a cc X with its parent, all other CC included in X (as well as X) are reported @@ -752,7 +753,7 @@ volume_connected_components(const TriangleMesh& tm, std::vector face_cc(num_faces(tm), std::size_t(-1)); - // set the connected component id of each face +// set the connected component id of each face const std::size_t nb_cc = connected_components(tm, bind_property_maps(fid_map,make_property_map(face_cc)), parameters::face_index_map(fid_map)); @@ -768,7 +769,7 @@ volume_connected_components(const TriangleMesh& tm, std::vector cc_volume_ids(nb_cc, -1); std::size_t next_volume_id = 0; - // First handle non-pure triangle meshes +// First handle non-pure triangle meshes BOOST_FOREACH(face_descriptor fd, faces(tm)) { if (!is_triangle(halfedge(fd, tm), tm)) @@ -782,7 +783,7 @@ volume_connected_components(const TriangleMesh& tm, } } - // Handle open connected components +// Handle open connected components BOOST_FOREACH(halfedge_descriptor h, halfedges(tm)) { if (is_border(h, tm)) @@ -797,12 +798,13 @@ volume_connected_components(const TriangleMesh& tm, } } - // Handle self-intersecting connected components +// Handle self-intersecting connected components // TODO add an option for self-intersection handling (optional if known to be free from self-intersections typedef std::pair Face_pair; std::vector si_faces; - std::set< std::pair > inclusion_test_to_skip; // due to self-intersections TODO USE ME + std::set< std::pair > self_intersecting_cc; // due to self-intersections self_intersections(tm, std::back_inserter(si_faces)); + std::vector is_involved_in_self_intersection(nb_cc, false); BOOST_FOREACH(const Face_pair& fp, si_faces) { std::size_t first_cc_id = face_cc[ get(fid_map, fp.first) ]; @@ -817,12 +819,16 @@ volume_connected_components(const TriangleMesh& tm, } } else - inclusion_test_to_skip.insert( make_sorted_pair(first_cc_id, second_cc_id) ); + { + is_involved_in_self_intersection[first_cc_id] = true; + is_involved_in_self_intersection[second_cc_id] = true; + self_intersecting_cc.insert( make_sorted_pair(first_cc_id, second_cc_id) ); + } } if (!cc_handled.all()) { - // extract a vertex with max z coordinate for each connected component + // extract a vertex with max z coordinate for each connected component std::vector xtrm_vertices(nb_cc, GT::null_vertex()); BOOST_FOREACH(vertex_descriptor vd, vertices(tm)) { @@ -837,6 +843,7 @@ volume_connected_components(const TriangleMesh& tm, const bool ignore_orientation_of_cc = false; // TODO add an option + // fill orientation vector for each surface CC boost::dynamic_bitset<> is_cc_outward_oriented; if (!ignore_orientation_of_cc) { @@ -848,7 +855,7 @@ volume_connected_components(const TriangleMesh& tm, } } - //collect faces per CC + //collect faces per CC std::vector< std::vector > faces_per_cc(nb_cc); std::vector< std::size_t > nb_faces_per_cc(nb_cc, 0); BOOST_FOREACH(face_descriptor fd, faces(tm)) @@ -864,14 +871,20 @@ volume_connected_components(const TriangleMesh& tm, faces_per_cc[ cc_id ].push_back(fd); } - // init the main loop + // init the main loop std::size_t k = 0; - std::vector > nested_cc_per_cc(nb_cc); // contains for each CC the CC that are in its bounded side + // contains for each CC the CC that are in its bounded side + std::vector > nested_cc_per_cc(nb_cc); + // similar as above but exclusively contains cc ids included by more that one CC. + // The result will be then merged with nested_cc_per_cc but temporarilly we need + // another container to not more than once the inclusion testing (in case a CC is + // included by more than 2 CC) + associate such CC to only one volume + std::vector > nested_cc_per_cc_shared(nb_cc); std::vector < std::size_t > nesting_levels(nb_cc, 0); // indicates for each CC its nesting level std::vector < boost::dynamic_bitset<> > level_k_nestings; // container containing CCs in the same volume (one bitset per volume) at level k level_k_nestings.push_back( ~cc_handled ); - // the following loop is exploring the nesting level by level (0 -> max_level) + // the following loop is exploring the nesting level by level (0 -> max_level) while (!level_k_nestings.empty()) { std::vector < boost::dynamic_bitset<> > level_k_plus_1_nestings; @@ -880,7 +893,7 @@ volume_connected_components(const TriangleMesh& tm, CGAL_assertion( cc_to_handle.any() ); while(cc_to_handle.any()) { - //extract a vertex with max z amongst all components + //extract a vertex with max z amongst all components std::size_t xtrm_cc_id=cc_to_handle.find_first(); for(std::size_t id = cc_to_handle.find_next(xtrm_cc_id); id != cc_to_handle.npos; @@ -892,18 +905,27 @@ volume_connected_components(const TriangleMesh& tm, cc_to_handle.reset(xtrm_cc_id); nesting_levels[xtrm_cc_id] = k; - // collect id inside xtrm_cc_id CC + // collect id inside xtrm_cc_id CC typedef Side_of_triangle_mesh Side_of_tm; typename Side_of_tm::AABB_tree aabb_tree(faces_per_cc[xtrm_cc_id].begin(), faces_per_cc[xtrm_cc_id].end(), tm, vpm); Side_of_tm side_of_cc(aabb_tree); + std::vector cc_intersecting; // contains id of CC intersecting xtrm_cc_id + boost::dynamic_bitset<> nested_cc_to_handle(nb_cc, 0); for(std::size_t id = cc_to_handle.find_first(); id != cc_to_handle.npos; id = cc_to_handle.find_next(id)) { + if (self_intersecting_cc.count( make_sorted_pair(xtrm_cc_id, id) )!= 0) + { + cc_intersecting.push_back(id); + nesting_levels[id] = k; // same level as xtrm_cc_id + continue; // to not dot inclusion test for intersecting CCs + } + if (side_of_cc(get(vpm,xtrm_vertices[id]))==ON_BOUNDED_SIDE) { nested_cc_per_cc[xtrm_cc_id].push_back(id); @@ -913,6 +935,22 @@ volume_connected_components(const TriangleMesh& tm, } } + //for each CC intersecting xtrm_cc_id, find the CCs included in both + BOOST_FOREACH(std::size_t id, cc_intersecting) + { + typename Side_of_tm::AABB_tree aabb_tree(faces_per_cc[id].begin(), + faces_per_cc[id].end(), + tm, vpm); + Side_of_tm side_of_cc(aabb_tree); + BOOST_FOREACH(std::size_t ncc_id, nested_cc_per_cc[xtrm_cc_id]) + { + if (self_intersecting_cc.count( make_sorted_pair(ncc_id, id) )!= 0) + continue; + if (side_of_cc(get(vpm,xtrm_vertices[ncc_id]))==ON_BOUNDED_SIDE) + nested_cc_per_cc_shared[id].push_back(ncc_id); + } + } + if ( nested_cc_per_cc[xtrm_cc_id].empty() ) continue; level_k_plus_1_nestings.push_back(nested_cc_to_handle); } @@ -921,13 +959,29 @@ volume_connected_components(const TriangleMesh& tm, level_k_nestings.swap(level_k_plus_1_nestings); } - // apply volume classification using level 0 nesting + // apply volume classification using level 0 nesting for(std::size_t cc_id=0; cc_id > nesting_parent(nb_cc, nb_cc+1); + // extract direct nested parent (more than one in case of self-intersection) + std::vector< std::vector > nesting_parent(nb_cc); for(std::size_t cc_id=0; cc_id Date: Fri, 12 Oct 2018 19:00:53 +0200 Subject: [PATCH 007/141] handle outward orientation at level 0 and inconsitent orientation --- .../Polygon_mesh_processing/orientation.h | 49 +++++++++++++++++-- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index 163e20c2a64..edea22ed893 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -958,16 +958,59 @@ volume_connected_components(const TriangleMesh& tm, ++k; level_k_nestings.swap(level_k_plus_1_nestings); } + // detect inconsistencies of the orientation at the level 0 + // and check if all CC at level 0 are in the same volume + std::size_t ref_cc_id = nb_cc; + std::size_t FIRST_LEVEL = 0; // used to know if even or odd nesting is the top level + if(!ignore_orientation_of_cc) + { + for(std::size_t cc_id=0; cc_id Date: Fri, 12 Oct 2018 19:17:54 +0200 Subject: [PATCH 008/141] add named parameters for orientation and SI tests --- .../CGAL/boost/graph/parameters_interface.h | 3 +++ BGL/test/BGL/test_cgal_bgl_named_params.cpp | 4 ++++ .../CGAL/Polygon_mesh_processing/orientation.h | 15 ++++++++++----- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/BGL/include/CGAL/boost/graph/parameters_interface.h b/BGL/include/CGAL/boost/graph/parameters_interface.h index 1ec0f1504de..16e1810ea62 100644 --- a/BGL/include/CGAL/boost/graph/parameters_interface.h +++ b/BGL/include/CGAL/boost/graph/parameters_interface.h @@ -78,6 +78,9 @@ CGAL_add_named_parameter(projection_functor_t, projection_functor, projection_fu CGAL_add_named_parameter(throw_on_self_intersection_t, throw_on_self_intersection, throw_on_self_intersection) CGAL_add_named_parameter(clip_volume_t, clip_volume, clip_volume) CGAL_add_named_parameter(use_compact_clipper_t, use_compact_clipper, use_compact_clipper) +CGAL_add_named_parameter(do_orientation_tests_t, do_orientation_tests, do_orientation_tests) +CGAL_add_named_parameter(do_self_intersection_tests_t, do_self_intersection_tests, do_self_intersection_tests) + // List of named parameters that we use in the package 'Surface Mesh Simplification' CGAL_add_named_parameter(get_cost_policy_t, get_cost_policy, get_cost) diff --git a/BGL/test/BGL/test_cgal_bgl_named_params.cpp b/BGL/test/BGL/test_cgal_bgl_named_params.cpp index 019ad98dedf..ca1fda75b5f 100644 --- a/BGL/test/BGL/test_cgal_bgl_named_params.cpp +++ b/BGL/test/BGL/test_cgal_bgl_named_params.cpp @@ -161,6 +161,8 @@ void test(const NamedParameters& np) check_same_type<43>(get_param(np, CGAL::internal_np::throw_on_self_intersection)); check_same_type<44>(get_param(np, CGAL::internal_np::clip_volume)); check_same_type<45>(get_param(np, CGAL::internal_np::use_compact_clipper)); + check_same_type<47>(get_param(np, CGAL::internal_np::do_self_intersection_tests)); + check_same_type<48>(get_param(np, CGAL::internal_np::do_orientation_tests)); // Named parameters that we use in the package 'Surface Mesh Simplification' check_same_type<34>(get_param(np, CGAL::internal_np::get_cost_policy)); @@ -238,6 +240,8 @@ int main() .clip_volume(A<44>(44)) .use_compact_clipper(A<45>(45)) .apply_per_connected_component(A<46>(46)) + .do_self_intersection_tests(A<47>(47)) + .do_orientation_tests(A<48>(48)) ); return EXIT_SUCCESS; diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index edea22ed893..e6f7bb3486e 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -726,6 +726,8 @@ bool does_bound_a_volume(const TriangleMesh& tm, const NamedParameters& np) // component must be taken into account rather than only the nesting. In case of incompatible // orientation of a cc X with its parent, all other CC included in X (as well as X) are reported // as independant volumes +// NP do_orientation_tests +// NP do_self_intersection_tests // TODO return a vector with info on the volume? non-triangle/open/SI/regular/... template std::size_t @@ -799,11 +801,14 @@ volume_connected_components(const TriangleMesh& tm, } // Handle self-intersecting connected components - // TODO add an option for self-intersection handling (optional if known to be free from self-intersections + const bool do_self_intersection_tests = + boost::choose_param(boost::get_param(np, internal_np::do_self_intersection_tests), + false); typedef std::pair Face_pair; std::vector si_faces; std::set< std::pair > self_intersecting_cc; // due to self-intersections - self_intersections(tm, std::back_inserter(si_faces)); + if (do_self_intersection_tests) + self_intersections(tm, std::back_inserter(si_faces)); std::vector is_involved_in_self_intersection(nb_cc, false); BOOST_FOREACH(const Face_pair& fp, si_faces) { @@ -841,7 +846,9 @@ volume_connected_components(const TriangleMesh& tm, xtrm_vertices[cc_id]=vd; } - const bool ignore_orientation_of_cc = false; // TODO add an option + const bool ignore_orientation_of_cc = + !boost::choose_param(boost::get_param(np, internal_np::do_orientation_tests), + true); // fill orientation vector for each surface CC boost::dynamic_bitset<> is_cc_outward_oriented; @@ -1007,8 +1014,6 @@ volume_connected_components(const TriangleMesh& tm, for(std::size_t cc_id=0; (!cc_handled.all()) && cc_id Date: Fri, 12 Oct 2018 19:33:29 +0200 Subject: [PATCH 009/141] add a vector with error codes --- .../Polygon_mesh_processing/orientation.h | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index e6f7bb3486e..666ad4f089e 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -718,6 +718,14 @@ bool does_bound_a_volume(const TriangleMesh& tm, const NamedParameters& np) is_parent_outward_oriented); } +//TODO Add documentation +enum Volume_error_code { VALID_VOLUME, + SURFACE_SELF_INTERSECTION, + VOLUME_INTERSECTION, + NON_TRIANGULATED_SURFACE, + INCONSISTENT_ORIENTATION }; + +//TODO Add documentation // doc: non-closed connected components are reported as isolated volumes // doc: connected components with at least one non-triangle face are reported as isolated volumes // doc: self-intersecting connect components are reported as isolated volumes. @@ -760,8 +768,19 @@ volume_connected_components(const TriangleMesh& tm, bind_property_maps(fid_map,make_property_map(face_cc)), parameters::face_index_map(fid_map)); + const bool do_self_intersection_tests = + boost::choose_param(boost::get_param(np, internal_np::do_self_intersection_tests), + false); + + std::vector error_codes; + if (nb_cc == 1) { + if (do_self_intersection_tests && does_self_intersect(tm, np)) + error_codes.push_back(SURFACE_SELF_INTERSECTION); + else + error_codes.push_back(VALID_VOLUME); + BOOST_FOREACH(face_descriptor fd, faces(tm)) put(volume_id_map, fd, 0); return 1; @@ -781,6 +800,7 @@ volume_connected_components(const TriangleMesh& tm, { cc_handled.set(cc_id); cc_volume_ids[cc_id]=next_volume_id++; + error_codes.push_back(NON_TRIANGULATED_SURFACE); } } } @@ -801,9 +821,6 @@ volume_connected_components(const TriangleMesh& tm, } // Handle self-intersecting connected components - const bool do_self_intersection_tests = - boost::choose_param(boost::get_param(np, internal_np::do_self_intersection_tests), - false); typedef std::pair Face_pair; std::vector si_faces; std::set< std::pair > self_intersecting_cc; // due to self-intersections @@ -821,6 +838,7 @@ volume_connected_components(const TriangleMesh& tm, { cc_handled.set(first_cc_id); cc_volume_ids[first_cc_id]=next_volume_id++; + error_codes.push_back(SURFACE_SELF_INTERSECTION); } } else @@ -986,6 +1004,7 @@ volume_connected_components(const TriangleMesh& tm, { if (cc_handled.test(cc_id)) continue; cc_volume_ids[id] = next_volume_id++; + error_codes.push_back(INCONSISTENT_ORIENTATION); } cc_handled.set(); break; @@ -1006,6 +1025,7 @@ volume_connected_components(const TriangleMesh& tm, } } ++next_volume_id; + error_codes.push_back(VALID_VOLUME); FIRST_LEVEL = 1; } } @@ -1018,6 +1038,7 @@ volume_connected_components(const TriangleMesh& tm, if( nesting_levels[cc_id]%2 != FIRST_LEVEL ) continue; cc_handled.set(cc_id); cc_volume_ids[cc_id] = next_volume_id++; + error_codes.push_back(VALID_VOLUME); //if the CC is involved in a self-intersection all nested CC are put in a seperate volumes if (is_involved_in_self_intersection[cc_id]) @@ -1026,6 +1047,7 @@ volume_connected_components(const TriangleMesh& tm, { cc_handled.set(ncc_id); cc_volume_ids[ncc_id] = next_volume_id++; + error_codes.push_back(VOLUME_INTERSECTION); } continue; } @@ -1042,10 +1064,12 @@ volume_connected_components(const TriangleMesh& tm, // the surface component has an incorrect orientation wrt to its parent: // we dump it and all included surface components as independant volumes. cc_volume_ids[ncc_id] = next_volume_id++; + error_codes.push_back(INCONSISTENT_ORIENTATION); BOOST_FOREACH(std::size_t nncc_id, nested_cc_per_cc[ncc_id]) { cc_handled.set(nncc_id); cc_volume_ids[nncc_id] = next_volume_id++; + error_codes.push_back(INCONSISTENT_ORIENTATION); } continue; } @@ -1094,6 +1118,7 @@ volume_connected_components(const TriangleMesh& tm, } } + CGAL_assertion(next_volume_id == error_codes.size()); return next_volume_id; } From e9ad187120e802144ece4f9df77401e4f8fe5722 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 12 Oct 2018 19:34:48 +0200 Subject: [PATCH 010/141] update TODOs --- .../include/CGAL/Polygon_mesh_processing/orientation.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index 666ad4f089e..791f7b218ed 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -1091,6 +1091,8 @@ volume_connected_components(const TriangleMesh& tm, // TODO: add nesting_parent as an optional output parameter // note that this will require to also output the cc_id map + // except if we restrict it to invalid volume and index the + // nesting using volume ids // extract direct nested parent (more than one in case of self-intersection) std::vector< std::vector > nesting_parent(nb_cc); for(std::size_t cc_id=0; cc_id Date: Fri, 19 Oct 2018 22:50:06 +0200 Subject: [PATCH 011/141] add named parameters to export error codes and nesting info --- .../CGAL/boost/graph/parameters_interface.h | 4 +- BGL/test/BGL/test_cgal_bgl_named_params.cpp | 6 ++ .../Polygon_mesh_processing/orientation.h | 74 ++++++++++++++++--- .../test_split_volume.cpp | 19 ++++- 4 files changed, 90 insertions(+), 13 deletions(-) diff --git a/BGL/include/CGAL/boost/graph/parameters_interface.h b/BGL/include/CGAL/boost/graph/parameters_interface.h index 16e1810ea62..193a496e26a 100644 --- a/BGL/include/CGAL/boost/graph/parameters_interface.h +++ b/BGL/include/CGAL/boost/graph/parameters_interface.h @@ -80,7 +80,9 @@ CGAL_add_named_parameter(clip_volume_t, clip_volume, clip_volume) CGAL_add_named_parameter(use_compact_clipper_t, use_compact_clipper, use_compact_clipper) CGAL_add_named_parameter(do_orientation_tests_t, do_orientation_tests, do_orientation_tests) CGAL_add_named_parameter(do_self_intersection_tests_t, do_self_intersection_tests, do_self_intersection_tests) - +CGAL_add_named_parameter(error_codes_t, error_codes, error_codes) +CGAL_add_named_parameter(volume_inclusions_t, volume_inclusions, volume_inclusions) +CGAL_add_named_parameter(face_cc_map_t, face_connected_component_map, face_connected_component_map) // List of named parameters that we use in the package 'Surface Mesh Simplification' CGAL_add_named_parameter(get_cost_policy_t, get_cost_policy, get_cost) diff --git a/BGL/test/BGL/test_cgal_bgl_named_params.cpp b/BGL/test/BGL/test_cgal_bgl_named_params.cpp index ca1fda75b5f..59120379db6 100644 --- a/BGL/test/BGL/test_cgal_bgl_named_params.cpp +++ b/BGL/test/BGL/test_cgal_bgl_named_params.cpp @@ -163,6 +163,9 @@ void test(const NamedParameters& np) check_same_type<45>(get_param(np, CGAL::internal_np::use_compact_clipper)); check_same_type<47>(get_param(np, CGAL::internal_np::do_self_intersection_tests)); check_same_type<48>(get_param(np, CGAL::internal_np::do_orientation_tests)); + check_same_type<49>(get_param(np, CGAL::internal_np::error_codes)); + check_same_type<50>(get_param(np, CGAL::internal_np::volume_inclusions)); + check_same_type<51>(get_param(np, CGAL::internal_np::face_connected_component_map)); // Named parameters that we use in the package 'Surface Mesh Simplification' check_same_type<34>(get_param(np, CGAL::internal_np::get_cost_policy)); @@ -242,6 +245,9 @@ int main() .apply_per_connected_component(A<46>(46)) .do_self_intersection_tests(A<47>(47)) .do_orientation_tests(A<48>(48)) + .error_codes(A<49>(49)) + .volume_inclusions(A<50>(50)) + .face_connected_component_map(A<51>(51)) ); return EXIT_SUCCESS; diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index 791f7b218ed..6d2256b6934 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -723,7 +723,53 @@ enum Volume_error_code { VALID_VOLUME, SURFACE_SELF_INTERSECTION, VOLUME_INTERSECTION, NON_TRIANGULATED_SURFACE, - INCONSISTENT_ORIENTATION }; + INCONSISTENT_ORIENTATION, + SINGLE_CONNECTED_COMPONENT}; +namespace internal { +template +void copy_error_codes(std::vector& error_codes_in, + RefToVector ref_wrapper) +{ + error_codes_in.swap(ref_wrapper.get()); +} + +inline void copy_error_codes(std::vector&, + boost::param_not_found) +{} + +template +void copy_nested_cc_per_cc( + std::vector< std::vector >& nested_cc_per_cc, + RefToVector ref_to_vector) +{ + ref_to_vector.get().swap( nested_cc_per_cc); +} + +inline void copy_nested_cc_per_cc( + std::vector< std::vector >&, + boost::param_not_found) +{} + +template +void set_f_cc_id(const std::vector& f_cc, + FaceIndexMap face_index_map, + FaceCCIdMap face_cc_map, + const TriangleMesh& tm) +{ + BOOST_FOREACH(typename boost::graph_traits::face_descriptor fd, faces(tm)) + { + put(face_cc_map, fd, f_cc[ get(face_index_map, fd) ]); + } +} + +template +void set_f_cc_id(const std::vector&, + FaceIndexMap, + boost::param_not_found, + const TriangleMesh&) +{} + +} // internal //TODO Add documentation // doc: non-closed connected components are reported as isolated volumes @@ -734,9 +780,14 @@ enum Volume_error_code { VALID_VOLUME, // component must be taken into account rather than only the nesting. In case of incompatible // orientation of a cc X with its parent, all other CC included in X (as well as X) are reported // as independant volumes +// doc: in case there is only one CC, no extra test is performed // NP do_orientation_tests // NP do_self_intersection_tests -// TODO return a vector with info on the volume? non-triangle/open/SI/regular/... +// NP error_codes +// NP face_index +// NP vertex_point_map +// NP volume_inclusions (must be a reference_wrapper) +// NP face_connected_component_map template std::size_t volume_connected_components(const TriangleMesh& tm, @@ -768,6 +819,12 @@ volume_connected_components(const TriangleMesh& tm, bind_property_maps(fid_map,make_property_map(face_cc)), parameters::face_index_map(fid_map)); + // contains for each CC the CC that are in its bounded side + std::vector > nested_cc_per_cc(nb_cc); + + // copy cc-id info + internal::set_f_cc_id(face_cc, fid_map, boost::get_param(np, internal_np::face_connected_component_map), tm); + const bool do_self_intersection_tests = boost::choose_param(boost::get_param(np, internal_np::do_self_intersection_tests), false); @@ -776,13 +833,13 @@ volume_connected_components(const TriangleMesh& tm, if (nb_cc == 1) { - if (do_self_intersection_tests && does_self_intersect(tm, np)) - error_codes.push_back(SURFACE_SELF_INTERSECTION); - else - error_codes.push_back(VALID_VOLUME); + error_codes.push_back(SINGLE_CONNECTED_COMPONENT); BOOST_FOREACH(face_descriptor fd, faces(tm)) put(volume_id_map, fd, 0); + + internal::copy_error_codes(error_codes, boost::get_param(np, internal_np::error_codes)); + internal::copy_nested_cc_per_cc(nested_cc_per_cc, boost::get_param(np, internal_np::volume_inclusions)); return 1; } @@ -898,8 +955,6 @@ volume_connected_components(const TriangleMesh& tm, // init the main loop std::size_t k = 0; - // contains for each CC the CC that are in its bounded side - std::vector > nested_cc_per_cc(nb_cc); // similar as above but exclusively contains cc ids included by more that one CC. // The result will be then merged with nested_cc_per_cc but temporarilly we need // another container to not more than once the inclusion testing (in case a CC is @@ -1120,8 +1175,9 @@ volume_connected_components(const TriangleMesh& tm, } } - //TODO add a NP to output it CGAL_assertion(next_volume_id == error_codes.size()); + internal::copy_error_codes(error_codes, boost::get_param(np, internal_np::error_codes)); + internal::copy_nested_cc_per_cc(nested_cc_per_cc, boost::get_param(np, internal_np::volume_inclusions)); return next_volume_id; } diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_split_volume.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_split_volume.cpp index 5290c7f9c75..663598342df 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_split_volume.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_split_volume.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -10,6 +11,8 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; typedef CGAL::Surface_mesh Surface_mesh; +namespace PMP = CGAL::Polygon_mesh_processing; + int main(int argc, char** argv) { if (argc==1) @@ -17,7 +20,7 @@ int main(int argc, char** argv) std::cerr << "Nothing tested\n"; return 1; } - + for(int i=1;i> sm; + std::vector error_codes; + std::vector< std::vector > nested_cc_per_cc; + + Surface_mesh::Property_map fccmap = + sm.add_property_map("f:CC").first; + Surface_mesh::Property_map vol_id_map = sm.add_property_map().first; - std::size_t nb_vol = - CGAL::Polygon_mesh_processing::volume_connected_components(sm, vol_id_map); + std::size_t nb_vol = PMP::volume_connected_components( + sm, vol_id_map, + CGAL::parameters::error_codes(boost::ref(error_codes)). + face_connected_component_map(fccmap). + volume_inclusions(boost::ref(nested_cc_per_cc))); + std::cout << " found " << nb_vol << " volumes\n"; typedef CGAL::Face_filtered_graph Filtered_graph; Filtered_graph vol_mesh(sm, 0, vol_id_map); From e777cd7c40e85a618a8a38a4ac89ca2c54024f29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 22 Oct 2018 10:02:22 +0200 Subject: [PATCH 012/141] Add documentation and missing error code --- .../NamedParameters.txt | 51 ++++++- .../PackageDescription.txt | 1 + .../Polygon_mesh_processing/orientation.h | 136 ++++++++++++++---- 3 files changed, 162 insertions(+), 26 deletions(-) diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt index 839bd7b52ff..b267893e53d 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt @@ -327,7 +327,7 @@ Parameter used in `isotropic_remeshing()` to specify an alternative vertex proje \cgalNPEnd \cgalNPBegin{apply_per_connected_component} \anchor PMP_apply_per_connected_component -Parameter used to indicate whether an algorithm should consider each connected component +Parameter used to indicate whether an algorithm should consider each connected component of a mesh independently.\n \b Type : `bool` \n \b Default value is `false` @@ -364,6 +364,55 @@ should be considered as part of the clipping volume or not. \b Default value is `true` \cgalNPEnd +\cgalNPBegin{do_orientation_tests} \anchor PMP_do_orientation_tests +Parameter used in `volume_connected_components()` to indicate if surface orientation test +must be done to decide of the belonging of a surface connected component to a volume. +\n +\b Type : `bool` \n +\b Default value is `true` +\cgalNPEnd + +\cgalNPBegin{do_self_intersection_tests} \anchor PMP_do_self_intersection_tests +Parameter used in `volume_connected_components()` to indicate if the input triangle mesh +might contains self-intersections that must be taken into account while detecting volume +connected components. +\n +\b Type : `bool` \n +\b Default value is `false` +\cgalNPEnd + +\cgalNPBegin{error_codes} \anchor PMP_error_codes +a reference to a vector holding the classification of a volume connected component identified by its id. +The size of the vector is exactly the number of volume connected components and the +object at position `k` in the vector correspond to the classification of the volume connected component +assigned the id `k`. +\n +\b Type: a `reference_wrapper` (either from `boost` or the standard library) + over an object of type `std::vector` \n +\b Default: None +\cgalNPEnd + +\cgalNPBegin{face_connected_component_map} \anchor PMP_face_connected_component_map +a property map that will contain for each face the id +of its surface connected component in the range +`[0, number of connected components - 1[`. +\n +Type: a class model of `WritablePropertyMap` with +`boost::graph_traits::%face_descriptor` as key type and `std::size_t` as value type\n +\b Default: None +\cgalNPEnd + +\cgalNPBegin{volume_inclusions} \anchor PMP_volume_inclusions +a reference to a vector holding vector of id of surface connected components. +The size of the vector is exactly the number of surface connected components of the triangle mesh considered +The vector at position `k` contains the id of each surface connected components +that is the first intersected by a ray with source on the surface connected component `k` +and directed outside the finite volume enclosed by the surface connected component `k`. +\n +\b Type: a `reference_wrapper` (either from `boost` or the standard library) + over an object of type `std::vector< std::vector >` \n +\b Default: None +\cgalNPEnd \cgalNPTableEnd diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt index 42bb1ef82cf..4882ba97582 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt @@ -121,6 +121,7 @@ and provides a list of the parameters that are used in this package. - `CGAL::Polygon_mesh_processing::orient()` - `CGAL::Polygon_mesh_processing::does_bound_a_volume()` - `CGAL::Polygon_mesh_processing::orient_to_bound_a_volume()` +- `CGAL::Polygon_mesh_processing::volume_connected_components()` ## Combinatorial Repairing Functions ## - \link PMP_repairing_grp `CGAL::Polygon_mesh_processing::stitch_borders()` \endlink diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index 6d2256b6934..ff63d3c61f4 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -718,13 +718,21 @@ bool does_bound_a_volume(const TriangleMesh& tm, const NamedParameters& np) is_parent_outward_oriented); } -//TODO Add documentation -enum Volume_error_code { VALID_VOLUME, - SURFACE_SELF_INTERSECTION, - VOLUME_INTERSECTION, - NON_TRIANGULATED_SURFACE, - INCONSISTENT_ORIENTATION, - SINGLE_CONNECTED_COMPONENT}; +/*! + * \ingroup PMP_orientation_grp + * Enumeration type used to indicate the status of a set of faces + * classified by the function `volume_connected_components()`. + * The set of faces defines either a volumic connected connected component + * in the case of `VALID_VOLUME` or a surfacic connected component otherwise. + */ +enum Volume_error_code { VALID_VOLUME, ///< The set of faces bounds a volume + SURFACE_SELF_INTERSECTION, ///< The set of faces are self-intersecting + VOLUME_INTERSECTION, ///< The set of faces intersect another surface connected component + OPEN_SURFACE, ///< The set of faces does not defined a close surface + NON_TRIANGULATED_SURFACE, ///< The set of faces contains at least a non-triangular face + INCONSISTENT_ORIENTATION, ///< The set of faces is included in a volume but has an incompatible orientation + SINGLE_CONNECTED_COMPONENT ///< The set of faces consists of all the faces of the mesh and no further test were done. + }; namespace internal { template void copy_error_codes(std::vector& error_codes_in, @@ -771,23 +779,101 @@ void set_f_cc_id(const std::vector&, } // internal -//TODO Add documentation -// doc: non-closed connected components are reported as isolated volumes -// doc: connected components with at least one non-triangle face are reported as isolated volumes -// doc: self-intersecting connect components are reported as isolated volumes. -// doc: CC intersecting another CC is reported as a seperate volume and so are its nested CCs -// doc: add option ignore_orientation_of_cc to control whether the inward/outward orientation of -// component must be taken into account rather than only the nesting. In case of incompatible -// orientation of a cc X with its parent, all other CC included in X (as well as X) are reported -// as independant volumes -// doc: in case there is only one CC, no extra test is performed -// NP do_orientation_tests -// NP do_self_intersection_tests -// NP error_codes -// NP face_index -// NP vertex_point_map -// NP volume_inclusions (must be a reference_wrapper) -// NP face_connected_component_map + +/*! + * \ingroup PMP_orientation_grp + * assigns to each face of `tm` an id corresponding to the volume connected component + * it contributes to define. + * + * Using the adjacency relation of two faces along an edge, a triangle mesh can be split + * into connected components (*surface components* in the following). + * A surface component without boundary separates the 3D space into an infinite and + * a finite volume. We say that the finite volume is enclosed by this surface + * component. + * + * The volume connected components (*volume components* in the following) are defines as follow: + * Each surface component `S` that is outside any volume enclosed by + * another surface component defines the *outer boundary* of a volume component. + * Each surface component that is inside the volume enclosed by `S` + * defines a *hole* if it is included in no other volume enclosed by a surface components + * but `S`. Ignoring the identified volume component, the same procedure is recursively + * repeated for all surface components in each hole. + * + * There are some special cases: + * - a non-closed surface component is reported as an isolated volume + * - a surface component with at least one non-triangle face is reported as an isolated volume + * - a self-intersecting surface component is reported as an isolated volume + * - a surface component intersecting another surface component + * is reported as an isolated volume, and so are all the surface components inside its + * enclosed volume. + * - if `do_orientation_tests` is `true`, if the holes are not all equally oriented + * (all inward or all outward) or if the holes and the outer boundary are equally + * oriented, each surface component is reported as an isolated volume, + * and so are all the surface components inside the corresponding enclosed volumes. + * - If all the faces of `tm` are part of the same surface component, then + * no further test (open/closed, self-intersecting) is done and all faces + * are assigned to the same volume components. + * - If `do_orientation_tests` is set to `true` and the surface components that are + * outside all enclosed volumes are inward oriented, they are then considered as holes + * of the unbounded volume (that has no outer boundary) + * + * A property map for each of `CGAL::face_index_t` and `CGAL::vertex_point_t` + * must be either available as an internal property map + * of `tm` or provided as one of the \ref pmp_namedparameters "Named Parameters". + * + * @tparam TriangleMesh a model of `FaceListGraph` + * @tparam FaceIndexMap a model of `WritablePropertyMap` with + * `boost::graph_traits::%face_descriptor` as key type and + * `boost::graph_traits::%faces_size_type` as value type. + * @tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" + * + * @param tm the input triangle mesh + * @param volume_id_map the property map filled by this function with indices of volume components associated to the faces of `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{face_index_map} + * a property map containing a unique id per face of `tm`, in the range `[0, num_faces(tm)[`. + * \cgalParamEnd + * \cgalParamBegin{face_connected_component_map} + * a property map filled by this function and that will contain for each face the id + * of its surface component in the range `[0, number of surface components - 1[`. + * \cgalParamEnd + * \cgalParamBegin{volume_inclusions} + * a `reference_wrapper` (either from `boost` or the standard library) containing + * a reference to an object of type `std::vector< std::vector >` + * The size of the vector is exactly the number of surface components of `tm`. + * The vector at position `k` contains the ids of all the + * surface components that are the first intersected by any ray with source on + * the surface component `k` and directed outside the volume enclosed by the + * surface component `k`. There is only one such id but when some surface components intersect. + * \cgalParamEnd + * \cgalParamBegin{do_orientation_tests} + * if `true` (the default value), the orientation of the faces of + * each surface components will be taken into account for the definition of the volume. + * If `false`, the face orientation is ignored and the volumes are defined only by the + * nesting of surface components. + * \cgalParamEnd + * \cgalParamBegin{error_codes} + * a `reference_wrapper` (either from `boost` or the standard library) containing + * a reference to an object of type `std::vector< Volume_error_code >`. + * The size of the vector is exactly the number of volume components. + * The vector indicates the status of a volume assigned to a set of faces. + * The description of the value type is given in the documentation of the enumeration type. + * \cgalParamEnd + * \cgalParamBegin{do_self_intersection_tests} + * If `false` (the default value), it is assumed that `tm` does not contains any self-intersections. + * if `true`, the input might contain some self-intersections and a test is done + * prior to the volume decomposition. + * \cgalParamEnd + * \cgalNamedParamsEnd + * + * \return the number of volume components defined by `tm` + * + */ template std::size_t volume_connected_components(const TriangleMesh& tm, @@ -808,7 +894,6 @@ volume_connected_components(const TriangleMesh& tm, Vpm vpm = boost::choose_param(boost::get_param(np, internal_np::vertex_point), get_const_property_map(boost::vertex_point, tm)); - // TODO handle user provided CC map ? Fid_map fid_map = boost::choose_param(boost::get_param(np, internal_np::face_index), get_const_property_map(boost::face_index, tm)); @@ -873,6 +958,7 @@ volume_connected_components(const TriangleMesh& tm, { cc_handled.set(cc_id); cc_volume_ids[cc_id]=next_volume_id++; + error_codes.push_back(OPEN_SURFACE); } } } From 91330c8c8b52ae5700e6dbacd555577e1558055c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 23 Oct 2018 11:39:46 +0200 Subject: [PATCH 013/141] add an example for volume decomposition --- .../Polygon_mesh_processing/CMakeLists.txt | 1 + .../volume_connected_components.cpp | 47 +++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 Polygon_mesh_processing/examples/Polygon_mesh_processing/volume_connected_components.cpp diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt b/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt index ed6a9a6e8f9..a04835a1a4c 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt @@ -104,6 +104,7 @@ create_single_source_cgal_program( "random_perturbation_SM_example.cpp" ) create_single_source_cgal_program( "corefinement_LCC.cpp") create_single_source_cgal_program( "hole_filling_example_LCC.cpp" ) create_single_source_cgal_program( "detect_features_example.cpp" ) +create_single_source_cgal_program( "volume_connected_components.cpp" ) if(OpenMesh_FOUND) create_single_source_cgal_program( "compute_normals_example_OM.cpp" ) diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/volume_connected_components.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/volume_connected_components.cpp new file mode 100644 index 00000000000..b7773d1ddb1 --- /dev/null +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/volume_connected_components.cpp @@ -0,0 +1,47 @@ +#include +#include +#include +#include +#include + +#include +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; +typedef CGAL::Surface_mesh Surface_mesh; + +namespace PMP = CGAL::Polygon_mesh_processing; + +int main(int argc, char** argv) +{ + const char* filename = (argc > 1) ? argv[1] : "data/blobby.off"; + std::ifstream input(filename); + assert(input); + Surface_mesh sm; + input >> sm; + + // property map to assign a volume id for each face + Surface_mesh::Property_map vol_id_map = + sm.add_property_map().first; + + // fill the volume id map + std::size_t nb_vol = PMP::volume_connected_components(sm, vol_id_map); + + std::cout << "Found " << nb_vol << " volumes\n"; + + // write each volume in an OFF file + typedef CGAL::Face_filtered_graph Filtered_graph; + Filtered_graph vol_mesh(sm, 0, vol_id_map); + for(std::size_t id = 0; id < nb_vol; ++id) + { + if(id > 0) + vol_mesh.set_selected_faces(id, vol_id_map); + Surface_mesh out; + CGAL::copy_face_graph(vol_mesh, out); + std::ostringstream oss; + oss << "vol_" << id <<".off"; + std::ofstream os(oss.str().data()); + os << out; + } +} From 138cd72d6a94121a71264c0aed49bfe9c7e44a77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 24 Oct 2018 09:18:33 +0200 Subject: [PATCH 014/141] add a more complete test --- .../Polygon_mesh_processing/orientation.h | 73 +++---- .../test_split_volume.cpp | 202 ++++++++++++++++-- 2 files changed, 216 insertions(+), 59 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index ff63d3c61f4..a9ead936dd2 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -729,7 +729,6 @@ enum Volume_error_code { VALID_VOLUME, ///< The set of faces bounds a volume SURFACE_SELF_INTERSECTION, ///< The set of faces are self-intersecting VOLUME_INTERSECTION, ///< The set of faces intersect another surface connected component OPEN_SURFACE, ///< The set of faces does not defined a close surface - NON_TRIANGULATED_SURFACE, ///< The set of faces contains at least a non-triangular face INCONSISTENT_ORIENTATION, ///< The set of faces is included in a volume but has an incompatible orientation SINGLE_CONNECTED_COMPONENT ///< The set of faces consists of all the faces of the mesh and no further test were done. }; @@ -746,14 +745,14 @@ inline void copy_error_codes(std::vector&, {} template -void copy_nested_cc_per_cc( - std::vector< std::vector >& nested_cc_per_cc, +void copy_nested_parents( + std::vector< std::vector >& nested_parents, RefToVector ref_to_vector) { - ref_to_vector.get().swap( nested_cc_per_cc); + ref_to_vector.get().swap( nested_parents ); } -inline void copy_nested_cc_per_cc( +inline void copy_nested_parents( std::vector< std::vector >&, boost::param_not_found) {} @@ -800,9 +799,8 @@ void set_f_cc_id(const std::vector&, * repeated for all surface components in each hole. * * There are some special cases: - * - a non-closed surface component is reported as an isolated volume - * - a surface component with at least one non-triangle face is reported as an isolated volume - * - a self-intersecting surface component is reported as an isolated volume + * - a non-closed surface component is reported as an isolated volume ignoring any inclusion test + * - a self-intersecting surface component is reported as an isolated volume ignoring any inclusion test * - a surface component intersecting another surface component * is reported as an isolated volume, and so are all the surface components inside its * enclosed volume. @@ -880,6 +878,8 @@ volume_connected_components(const TriangleMesh& tm, FaceIndexMap volume_id_map, const NamedParameters& np) { + CGAL_precondition( is_triangle_mesh(tm) ); + typedef boost::graph_traits GT; typedef typename GT::vertex_descriptor vertex_descriptor; typedef typename GT::face_descriptor face_descriptor; @@ -924,7 +924,8 @@ volume_connected_components(const TriangleMesh& tm, put(volume_id_map, fd, 0); internal::copy_error_codes(error_codes, boost::get_param(np, internal_np::error_codes)); - internal::copy_nested_cc_per_cc(nested_cc_per_cc, boost::get_param(np, internal_np::volume_inclusions)); + // nested_cc_per_cc is empty and used to clear the vector passed in case it was not empty + internal::copy_nested_parents(nested_cc_per_cc, boost::get_param(np, internal_np::volume_inclusions)); return 1; } @@ -932,21 +933,6 @@ volume_connected_components(const TriangleMesh& tm, std::vector cc_volume_ids(nb_cc, -1); std::size_t next_volume_id = 0; -// First handle non-pure triangle meshes - BOOST_FOREACH(face_descriptor fd, faces(tm)) - { - if (!is_triangle(halfedge(fd, tm), tm)) - { - std::size_t cc_id = face_cc[ get(fid_map, fd) ]; - if ( !cc_handled.test(cc_id) ) - { - cc_handled.set(cc_id); - cc_volume_ids[cc_id]=next_volume_id++; - error_codes.push_back(NON_TRIANGULATED_SURFACE); - } - } - } - // Handle open connected components BOOST_FOREACH(halfedge_descriptor h, halfedges(tm)) { @@ -992,6 +978,7 @@ volume_connected_components(const TriangleMesh& tm, } } + std::vector< std::vector > nesting_parents(nb_cc); if (!cc_handled.all()) { // extract a vertex with max z coordinate for each connected component @@ -1040,7 +1027,6 @@ volume_connected_components(const TriangleMesh& tm, } // init the main loop - std::size_t k = 0; // similar as above but exclusively contains cc ids included by more that one CC. // The result will be then merged with nested_cc_per_cc but temporarilly we need // another container to not more than once the inclusion testing (in case a CC is @@ -1051,6 +1037,7 @@ volume_connected_components(const TriangleMesh& tm, level_k_nestings.push_back( ~cc_handled ); // the following loop is exploring the nesting level by level (0 -> max_level) + std::size_t k = 0; while (!level_k_nestings.empty()) { std::vector < boost::dynamic_bitset<> > level_k_plus_1_nestings; @@ -1088,7 +1075,6 @@ volume_connected_components(const TriangleMesh& tm, if (self_intersecting_cc.count( make_sorted_pair(xtrm_cc_id, id) )!= 0) { cc_intersecting.push_back(id); - nesting_levels[id] = k; // same level as xtrm_cc_id continue; // to not dot inclusion test for intersecting CCs } @@ -1175,15 +1161,15 @@ volume_connected_components(const TriangleMesh& tm, for(std::size_t cc_id=0; (!cc_handled.all()) && cc_id > nesting_parent(nb_cc); for(std::size_t cc_id=0; cc_id #include #include +#include #include #include @@ -10,40 +11,195 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; typedef CGAL::Surface_mesh Surface_mesh; +typedef Kernel::Aff_transformation_3 Trsfrm; namespace PMP = CGAL::Polygon_mesh_processing; - -int main(int argc, char** argv) +namespace params = PMP::parameters; +int main() { - if (argc==1) + Surface_mesh base_cube; + std::ifstream input("data-coref/cube.off"); + input >> base_cube; + + Surface_mesh input_mesh; + Surface_mesh::Property_map vol_id_map = + input_mesh.add_property_map().first; + + // add large cube + input_mesh.join(base_cube); + + // add middle cube + Surface_mesh middle_cube = base_cube; + PMP::transform(Trsfrm(CGAL::SCALING, 0.5), middle_cube); + PMP::transform(Trsfrm(CGAL::TRANSLATION, Kernel::Vector_3(0.25,0.25,0.25)), middle_cube); + input_mesh.join(middle_cube); + + // add central cube + Surface_mesh small_cube = base_cube; + PMP::transform(Trsfrm(CGAL::SCALING, 0.1), small_cube); + PMP::transform(Trsfrm(CGAL::TRANSLATION, Kernel::Vector_3(0.5,0.5,0.5)), small_cube); + input_mesh.join(small_cube); + + // test using orientation + std::vector expected_result; + expected_result.push_back(PMP::VALID_VOLUME); + expected_result.push_back(PMP::INCONSISTENT_ORIENTATION); + expected_result.push_back(PMP::INCONSISTENT_ORIENTATION); + std::vector error_codes; + std::size_t nb_vol = PMP::volume_connected_components(input_mesh, vol_id_map, + params::error_codes(boost::ref(error_codes))); + assert(nb_vol==3); + std::sort(error_codes.begin(), error_codes.end()); + assert( error_codes==expected_result ); + + // test ignoring orientation + nb_vol = PMP::volume_connected_components(input_mesh, vol_id_map, + params::do_orientation_tests(false) + .error_codes(boost::ref(error_codes))); + assert(nb_vol==2); + expected_result.clear(); + expected_result.resize(2, PMP::VALID_VOLUME); + assert( error_codes==expected_result ); + + + // test surface component self-intersection { - std::cerr << "Nothing tested\n"; - return 1; + Surface_mesh tmp = input_mesh; + Surface_mesh::Property_map tmp_vol_id_map = + tmp.add_property_map().first; + // create a self-intersection + Surface_mesh::Halfedge_index h = *tmp.halfedges().begin(); + h = CGAL::Euler::split_edge(h, tmp); + CGAL::Euler::split_face(h, next( next(h, tmp), tmp), tmp); + h = opposite(h, tmp); + CGAL::Euler::split_face(h, next( next(h, tmp), tmp), tmp); + + nb_vol = PMP::volume_connected_components(tmp, tmp_vol_id_map, + params::do_orientation_tests(false) + .error_codes(boost::ref(error_codes)) + .do_self_intersection_tests(true)); + + assert(nb_vol==2); + expected_result.clear(); + expected_result.push_back(PMP::VALID_VOLUME); + expected_result.push_back(PMP::SURFACE_SELF_INTERSECTION); + std::sort(error_codes.begin(), error_codes.end()); + assert( error_codes==expected_result ); } - for(int i=1;i tmp_vol_id_map = + tmp.add_property_map().first; - std::ifstream input(argv[i]); - assert(input); - Surface_mesh sm; - input >> sm; + nb_vol = PMP::volume_connected_components(tmp, tmp_vol_id_map, + params::do_orientation_tests(false) + .error_codes(boost::ref(error_codes)) + .do_self_intersection_tests(true)); - std::vector error_codes; - std::vector< std::vector > nested_cc_per_cc; + assert(nb_vol==1); + expected_result.clear(); + expected_result.push_back(PMP::SINGLE_CONNECTED_COMPONENT); + assert( error_codes==expected_result ); + } - Surface_mesh::Property_map fccmap = - sm.add_property_map("f:CC").first; + // test open cc + { + Surface_mesh tmp = input_mesh; + Surface_mesh::Property_map tmp_vol_id_map = + tmp.add_property_map().first; + // create a self-intersection + Surface_mesh::Halfedge_index h = *tmp.halfedges().begin(); + CGAL::Euler::remove_face(h, tmp); - Surface_mesh::Property_map vol_id_map = - sm.add_property_map().first; - std::size_t nb_vol = PMP::volume_connected_components( - sm, vol_id_map, - CGAL::parameters::error_codes(boost::ref(error_codes)). - face_connected_component_map(fccmap). - volume_inclusions(boost::ref(nested_cc_per_cc))); + nb_vol = PMP::volume_connected_components(tmp, tmp_vol_id_map, + params::do_orientation_tests(false) + .error_codes(boost::ref(error_codes)) + .do_self_intersection_tests(true)); + assert(nb_vol==2); + expected_result.clear(); + expected_result.push_back(PMP::VALID_VOLUME); + expected_result.push_back(PMP::OPEN_SURFACE); + std::sort(error_codes.begin(), error_codes.end()); + assert( error_codes==expected_result ); + } + + // test intersection between cc + { + Surface_mesh tmp = input_mesh; + // create surface intersection + tmp.join(base_cube); + Surface_mesh::Property_map tmp_vol_id_map = + tmp.add_property_map().first; + + nb_vol = PMP::volume_connected_components(tmp, tmp_vol_id_map, + params::do_orientation_tests(false) + .error_codes(boost::ref(error_codes)) + .do_self_intersection_tests(true)); + + assert(nb_vol==4); + expected_result.clear(); + expected_result.resize(4, PMP::VOLUME_INTERSECTION); + assert( error_codes==expected_result ); + } + { + Surface_mesh tmp = input_mesh; + // create surface intersection + tmp.join(middle_cube); + tmp.join(middle_cube); + Surface_mesh::Property_map fccmap = + tmp.add_property_map("f:CC").first; + + Surface_mesh::Property_map tmp_vol_id_map = + tmp.add_property_map().first; + std::vector< std::vector > nested_cc_per_cc; + + nb_vol = PMP::volume_connected_components(tmp, tmp_vol_id_map, + params::do_orientation_tests(false) + .error_codes(boost::ref(error_codes)) + .face_connected_component_map(fccmap) + .do_self_intersection_tests(true) + .volume_inclusions(boost::ref(nested_cc_per_cc))); + + assert(nb_vol==5); + expected_result.clear(); + expected_result.push_back(PMP::VALID_VOLUME); + expected_result.resize(5, PMP::VOLUME_INTERSECTION); + std::sort(error_codes.begin(), error_codes.end()); + assert( error_codes==expected_result ); + std::size_t sum=0; + for (int i=0; i<5; ++i) + { + sum+=nested_cc_per_cc[i].size(); + assert(nested_cc_per_cc[i].size()==1 || + nested_cc_per_cc[i].size()==3 || + nested_cc_per_cc[i].size()==0); + } + assert(sum = 0+3*1+3); + } + + // test level 0 orientation + { + Surface_mesh tmp = base_cube; + PMP::transform(Trsfrm(CGAL::TRANSLATION, Kernel::Vector_3(2,0,0)), tmp); + tmp.join(base_cube); + PMP::reverse_face_orientations(tmp); + Surface_mesh::Property_map tmp_vol_id_map = + tmp.add_property_map().first; + // create a self-intersection + nb_vol = PMP::volume_connected_components(tmp, tmp_vol_id_map, + params::do_orientation_tests(false)); + + assert(nb_vol==2); + nb_vol = PMP::volume_connected_components(tmp, tmp_vol_id_map, + params::do_orientation_tests(true)); + + assert(nb_vol==1); + } + // debug code + /* std::cout << " found " << nb_vol << " volumes\n"; typedef CGAL::Face_filtered_graph Filtered_graph; Filtered_graph vol_mesh(sm, 0, vol_id_map); @@ -58,5 +214,5 @@ int main(int argc, char** argv) std::ofstream os(oss.str().data()); os << out; } - } + */ } From f05706798d396a94b573de2b5b62b0e9a9a52e2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 24 Oct 2018 09:30:12 +0200 Subject: [PATCH 015/141] update user manual --- .../doc/Polygon_mesh_processing/Polygon_mesh_processing.txt | 6 ++++-- .../doc/Polygon_mesh_processing/examples.txt | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt index 985deadf51f..f50dde6b03d 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt @@ -651,11 +651,14 @@ enable the user to keep and remove only a selection of connected components, provided either as a range of faces that belong to the desired connected components or as a range of connected component ids (one or more per connected component). -Finally, `CGAL::Polygon_mesh_processing::keep_largest_connected_components()` +`CGAL::Polygon_mesh_processing::keep_largest_connected_components()` enables the user to keep only the largest connected components. This feature can for example be useful for noisy data were small connected components should be discarded in favour of major connected components. +When a triangle mesh has no boundary a notion the 3D space is partition is different volumes. +The function `CGAL::Polygon_mesh_processing::volume_connected_components()` can be used to assign to +each face an id per volume defined by the surface connected components. \subsection CCExample Connected Components Example @@ -673,7 +676,6 @@ which enables to treat one or several connected components as a face graph. \cgalExample{Polygon_mesh_processing/face_filtered_graph_example.cpp} - \section PMPDistance Approximate Hausdorff Distance This package provides methods to compute (approximate) distances between meshes and point sets. diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt index 2811a37ecef..8e26399eae6 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt @@ -21,4 +21,5 @@ \example Polygon_mesh_processing/corefinement_mesh_union_and_intersection.cpp \example Polygon_mesh_processing/corefinement_consecutive_bool_op.cpp \example Polygon_mesh_processing/detect_features_example.cpp +\example Polygon_mesh_processing/volume_connected_components.cpp */ From b6beabc4707ea38fb5b8b0eaa7a35bddb5971425 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 24 Oct 2018 09:54:56 +0200 Subject: [PATCH 016/141] doc clean up --- .../Polygon_mesh_processing/orientation.h | 20 +++++++++---------- .../test_split_volume.cpp | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index a9ead936dd2..ee5b662ba0c 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -722,15 +722,15 @@ bool does_bound_a_volume(const TriangleMesh& tm, const NamedParameters& np) * \ingroup PMP_orientation_grp * Enumeration type used to indicate the status of a set of faces * classified by the function `volume_connected_components()`. - * The set of faces defines either a volumic connected connected component - * in the case of `VALID_VOLUME` or a surfacic connected component otherwise. + * The set of faces defines either a volume connected connected component + * in the case of `VALID_VOLUME` or a surface connected component otherwise. */ enum Volume_error_code { VALID_VOLUME, ///< The set of faces bounds a volume - SURFACE_SELF_INTERSECTION, ///< The set of faces are self-intersecting - VOLUME_INTERSECTION, ///< The set of faces intersect another surface connected component - OPEN_SURFACE, ///< The set of faces does not defined a close surface - INCONSISTENT_ORIENTATION, ///< The set of faces is included in a volume but has an incompatible orientation - SINGLE_CONNECTED_COMPONENT ///< The set of faces consists of all the faces of the mesh and no further test were done. + SURFACE_SELF_INTERSECTION, ///< The set of faces is self-intersecting + VOLUME_INTERSECTION, ///< The set of faces intersects another surface connected component + OPEN_SURFACE, ///< The set of faces does not define a close surface + INCOMPATIBLE_ORIENTATION, ///< The set of faces is included in a volume but has an incompatible orientation + SINGLE_CONNECTED_COMPONENT ///< The set of faces consists of all the faces of the mesh and no further test was done. }; namespace internal { template @@ -1131,7 +1131,7 @@ volume_connected_components(const TriangleMesh& tm, { if (cc_handled.test(cc_id)) continue; cc_volume_ids[id] = next_volume_id++; - error_codes.push_back(INCONSISTENT_ORIENTATION); + error_codes.push_back(INCOMPATIBLE_ORIENTATION); } cc_handled.set(); break; @@ -1193,12 +1193,12 @@ volume_connected_components(const TriangleMesh& tm, // the surface component has an incorrect orientation wrt to its parent: // we dump it and all included surface components as independant volumes. cc_volume_ids[ncc_id] = next_volume_id++; - error_codes.push_back(INCONSISTENT_ORIENTATION); + error_codes.push_back(INCOMPATIBLE_ORIENTATION); BOOST_FOREACH(std::size_t nncc_id, nested_cc_per_cc[ncc_id]) { cc_handled.set(nncc_id); cc_volume_ids[nncc_id] = next_volume_id++; - error_codes.push_back(INCONSISTENT_ORIENTATION); + error_codes.push_back(INCOMPATIBLE_ORIENTATION); } continue; } diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_split_volume.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_split_volume.cpp index 0581a11a2bb..4f197b5f5f9 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_split_volume.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_split_volume.cpp @@ -43,8 +43,8 @@ int main() // test using orientation std::vector expected_result; expected_result.push_back(PMP::VALID_VOLUME); - expected_result.push_back(PMP::INCONSISTENT_ORIENTATION); - expected_result.push_back(PMP::INCONSISTENT_ORIENTATION); + expected_result.push_back(PMP::INCOMPATIBLE_ORIENTATION); + expected_result.push_back(PMP::INCOMPATIBLE_ORIENTATION); std::vector error_codes; std::size_t nb_vol = PMP::volume_connected_components(input_mesh, vol_id_map, params::error_codes(boost::ref(error_codes))); From 119ca0dff8ca876e955c0d4ac978244cee553123 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 3 Jun 2019 16:26:37 +0200 Subject: [PATCH 017/141] Add Intersection between Bbox_3 and Bbox_3 --- .../Intersections_2/test_intersections_2.cpp | 90 ++++++++++++++++++- .../include/CGAL/Intersection_traits_3.h | 8 ++ .../CGAL/Intersections_3/Bbox_3_Bbox_3.h | 28 +++++- .../internal/intersection_3_1_impl.h | 11 ++- .../test/Intersections_3/call_test.cpp | 10 ++- 5 files changed, 140 insertions(+), 7 deletions(-) diff --git a/Intersections_2/test/Intersections_2/test_intersections_2.cpp b/Intersections_2/test/Intersections_2/test_intersections_2.cpp index 963beac1f15..83928d529d1 100644 --- a/Intersections_2/test/Intersections_2/test_intersections_2.cpp +++ b/Intersections_2/test/Intersections_2/test_intersections_2.cpp @@ -67,7 +67,6 @@ struct Test { typedef typename K::Circle_2 C; typedef std::vector

Pol; - template < typename Type > bool approx_equal_nt(const Type &t1, const Type &t2) { @@ -370,9 +369,98 @@ check_no_intersection (L(p(0, 0), p(10,10)), L(p(8,7), p(1, 0))); }; +template +void call_intersection(const A& a, const B& b) { + typename CGAL::cpp11::result_of::Intersect_2(A, B)>::type x = CGAL::intersection(a, b); + typename CGAL::cpp11::result_of::Intersect_2(A, B)>::type y = CGAL::intersection(b, a); + typename CGAL::cpp11::result_of::Intersect_2(B, A)>::type z = CGAL::intersection(b, a); + CGAL_USE(x); + CGAL_USE(y); + CGAL_USE(z); +} + +template +void call_do_intersect(const A& a, const B& b) { + CGAL::do_intersect(a, b); + CGAL::do_intersect(b, a); +} + int main() { Test< CGAL::Simple_cartesian >().run(); Test< CGAL::Homogeneous >().run(); + typedef typename CGAL::Simple_cartesian K; + typedef typename K::Point_2 P; + typedef typename K::Line_2 L; + typedef typename K::Segment_2 S; + typedef typename K::Ray_2 R; + typedef typename K::Triangle_2 T; + typedef typename K::Iso_rectangle_2 Rec; + typedef typename K::Circle_2 C; + + try{ + call_intersection(P(), P()); + call_intersection(P(), L()); + call_intersection(P(), S()); + call_intersection(P(), R()); + call_intersection(P(), T()); + call_intersection(P(), Rec()); + + call_intersection(L(), L()); + call_intersection(L(), S()); + call_intersection(L(), R()); + call_intersection(L(), T()); + call_intersection(L(), Rec()); + + call_intersection(S(), S()); + call_intersection(S(), R()); + call_intersection(S(), T()); + call_intersection(S(), Rec()); + + call_intersection(R(), R()); + call_intersection(R(), T()); + call_intersection(R(), Rec()); + + call_intersection(T(), T()); + call_intersection(T(), Rec()); + + call_intersection(Rec(), Rec()); + + call_do_intersect(P(), P()); + call_do_intersect(P(), L()); + call_do_intersect(P(), S()); + call_do_intersect(P(), R()); + call_do_intersect(P(), T()); + call_do_intersect(P(), Rec()); + call_do_intersect(P(), C()); + + call_do_intersect(L(), L()); + call_do_intersect(L(), S()); + call_do_intersect(L(), R()); + call_do_intersect(L(), T()); + call_do_intersect(L(), Rec()); + call_do_intersect(L(), C()); + + call_do_intersect(S(), S()); + call_do_intersect(S(), R()); + call_do_intersect(S(), T()); + call_do_intersect(S(), Rec()); +// call_do_intersect(S(), C()); + + call_do_intersect(R(), R()); + call_do_intersect(R(), T()); + call_do_intersect(R(), Rec()); +// call_do_intersect(R(), C()); + + call_do_intersect(T(), T()); + call_do_intersect(T(), Rec()); +// call_do_intersect(T(), C()); + + call_do_intersect(Rec(), Rec()); + call_do_intersect(Rec(), C()); + + call_do_intersect(C(), C()); + } + catch(...){} // TODO : test more kernels. } diff --git a/Intersections_3/include/CGAL/Intersection_traits_3.h b/Intersections_3/include/CGAL/Intersection_traits_3.h index 88864987cb3..d2744422637 100644 --- a/Intersections_3/include/CGAL/Intersection_traits_3.h +++ b/Intersections_3/include/CGAL/Intersection_traits_3.h @@ -280,6 +280,14 @@ struct Intersection_traits { boost::variant< typename K::Point_3 > variant_type; typedef typename boost::optional< variant_type > result_type; }; + +//// Bbox_3 Bbox_3, variant of 2 +//template +//struct Intersection_traits { +// typedef typename +// boost::variant< typename K::Point_3 , Bbox_3> variant_type; +// typedef typename boost::optional< variant_type > result_type; +//}; } // namespace #endif /* CGAL_INTERSECTION_TRAITS_3_H */ diff --git a/Intersections_3/include/CGAL/Intersections_3/Bbox_3_Bbox_3.h b/Intersections_3/include/CGAL/Intersections_3/Bbox_3_Bbox_3.h index d742cb8ff43..051b86ac9ad 100644 --- a/Intersections_3/include/CGAL/Intersections_3/Bbox_3_Bbox_3.h +++ b/Intersections_3/include/CGAL/Intersections_3/Bbox_3_Bbox_3.h @@ -25,7 +25,7 @@ #include - +#include namespace CGAL { bool inline @@ -35,6 +35,32 @@ do_intersect(const CGAL::Bbox_3& c, return CGAL::do_overlap(c, bbox); } +typename boost::optional< typename +boost::variant< Bbox_3> > +inline +intersection(const CGAL::Bbox_3& a, + const CGAL::Bbox_3& b) { + + typedef typename + boost::variant< Bbox_3> variant_type; + typedef typename boost::optional< variant_type > Result_type; + if(!do_intersect(a,b)) + { + return Result_type(); + } + + double xmin, xmax, ymin, ymax, zmin, zmax; + xmin = (std::max)(a.xmin(), b.xmin()); + xmax = (std::min)(a.xmax(), b.xmax()); + + ymin = (std::max)(a.ymin(), b.ymin()); + ymax = (std::min)(a.ymax(), b.ymax()); + + zmin = (std::max)(a.zmin(), b.zmin()); + zmax = (std::min)(a.zmax(), b.zmax()); + return Result_type(std::forward(Bbox_3(xmin, ymin, zmin, xmax, ymax, zmax))); +} + } //namespace CGAL diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/intersection_3_1_impl.h b/Intersections_3/include/CGAL/Intersections_3/internal/intersection_3_1_impl.h index 2112802e019..3ef9ceee933 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/intersection_3_1_impl.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/intersection_3_1_impl.h @@ -1252,6 +1252,16 @@ intersection(const Bbox_3 &box, return intersection(seg, box, k); } +template +inline +typename Intersection_traits::result_type +intersection(const Bbox_3 &a, + const Bbox_3 &b, + const K& k) +{ + return CGAL::intersection(a, b); +} + template typename Intersection_traits::result_type @@ -1576,7 +1586,6 @@ do_intersect(const Iso_cuboid_3 &j, const Line_3 &l, const R&) { return bool(CGAL::intersection(l, j)); } - } // namespace internal } // namespace Intersections } // namespace CGAL diff --git a/Intersections_3/test/Intersections_3/call_test.cpp b/Intersections_3/test/Intersections_3/call_test.cpp index 768c7d4ac6e..b6fb2684f5b 100644 --- a/Intersections_3/test/Intersections_3/call_test.cpp +++ b/Intersections_3/test/Intersections_3/call_test.cpp @@ -105,9 +105,11 @@ int main() call_intersection_global(Bbox_3(), L()); call_intersection_global(Bbox_3(), S()); call_intersection_global(Bbox_3(), R()); + CGAL::intersection(Bbox_3(), Bbox_3()); + // with kernel - + call_intersection_with_kernel(S(), S(), K()); call_intersection_with_kernel(S(), L(), K()); call_intersection_with_kernel(S(), Pl(), K()); @@ -157,14 +159,14 @@ int main() call_intersection_with_kernel(Bbox_3(), S(), K()); call_intersection_with_kernel(Bbox_3(), R(), K()); - // The doc defines calls to do_intersect for these objects + // The doc defines calls to do_intersect for these objects // Plane_3 // Line_3 // Ray_3 // Segment_3 // Triangle_3. - // Bbox_3. + // Bbox_3. call_do_intersect_global(Pl(), Pl()); call_do_intersect_global(Pl(), L()); call_do_intersect_global(Pl(), R()); @@ -214,7 +216,7 @@ int main() call_do_intersect_global(Bbox_3(), Tr()); call_do_intersect_global(Bbox_3(), Sph()); call_do_intersect_global(Bbox_3(), Bbox_3()); - + // with_kernel call_do_intersect_with_kernel(Pl(), Pl(), K()); call_do_intersect_with_kernel(Pl(), L(), K()); From 469ed5396bf719d5e3fa1a64d6bacc474f599171 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Tue, 4 Jun 2019 15:40:57 +0200 Subject: [PATCH 018/141] Add Tet / line intersections --- .../include/CGAL/Intersection_traits_3.h | 25 +++- .../Intersections_3/Bbox_3_Iso_cuboid_3.h | 14 ++ .../Intersections_3/Line_3_Tetrahedron_3.h | 16 ++- .../Tetrahedron_3_Line_3_intersection.h | 132 ++++++++++++++++++ .../internal/intersection_3_1_impl.h | 26 ++++ Intersections_3/include/CGAL/intersection_3.h | 1 + .../test/Intersections_3/call_test.cpp | 6 + .../Intersections_3/test_intersections_3.cpp | 25 +++- 8 files changed, 234 insertions(+), 11 deletions(-) create mode 100644 Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Line_3_intersection.h diff --git a/Intersections_3/include/CGAL/Intersection_traits_3.h b/Intersections_3/include/CGAL/Intersection_traits_3.h index d2744422637..31ab37bfeb4 100644 --- a/Intersections_3/include/CGAL/Intersection_traits_3.h +++ b/Intersections_3/include/CGAL/Intersection_traits_3.h @@ -39,6 +39,8 @@ CGAL_INTERSECTION_TRAITS_2(Line_3, Segment_3, Point_3, Segment_3) CGAL_INTERSECTION_TRAITS_2(Segment_3, Line_3, Point_3, Segment_3) CGAL_INTERSECTION_TRAITS_2(Line_3, Triangle_3, Point_3, Segment_3) +CGAL_INTERSECTION_TRAITS_2(Line_3, Tetrahedron_3, Point_3, Segment_3) +CGAL_INTERSECTION_TRAITS_2(Tetrahedron_3, Line_3, Point_3, Segment_3) CGAL_INTERSECTION_TRAITS_2(Triangle_3, Line_3, Point_3, Segment_3) CGAL_INTERSECTION_TRAITS_2(Plane_3, Plane_3, Line_3, Plane_3) @@ -156,6 +158,21 @@ struct Intersection_traits { typedef typename boost::optional< variant_type > result_type; }; + +// Bbox_3 Iso_cuboid_3, variant of 1 +template +struct Intersection_traits { + typedef typename + boost::variant< typename K::Iso_cuboid_3 > variant_type; + typedef typename boost::optional< variant_type > result_type; +}; + +template +struct Intersection_traits + : public Intersection_traits {}; + + + // Iso_cuboid_3 Point_3, variant of one template struct Intersection_traits { @@ -281,13 +298,7 @@ struct Intersection_traits { typedef typename boost::optional< variant_type > result_type; }; -//// Bbox_3 Bbox_3, variant of 2 -//template -//struct Intersection_traits { -// typedef typename -// boost::variant< typename K::Point_3 , Bbox_3> variant_type; -// typedef typename boost::optional< variant_type > result_type; -//}; + } // namespace #endif /* CGAL_INTERSECTION_TRAITS_3_H */ diff --git a/Intersections_3/include/CGAL/Intersections_3/Bbox_3_Iso_cuboid_3.h b/Intersections_3/include/CGAL/Intersections_3/Bbox_3_Iso_cuboid_3.h index 37f439444b5..ebdd1ae27fd 100644 --- a/Intersections_3/include/CGAL/Intersections_3/Bbox_3_Iso_cuboid_3.h +++ b/Intersections_3/include/CGAL/Intersections_3/Bbox_3_Iso_cuboid_3.h @@ -27,6 +27,7 @@ #include #include +#include namespace CGAL { @@ -42,6 +43,19 @@ bool do_intersect(const Iso_cuboid_3& a, return K().do_intersect_3_object()(b, a); } +template +typename Intersection_traits::result_type +intersection(const CGAL::Bbox_3& a, + const Iso_cuboid_3& b) { + return K().intersect_3_object()(a, b); +} + +template +typename Intersection_traits::result_type +intersection(const Iso_cuboid_3& a, + const CGAL::Bbox_3& b) { + return K().intersect_3_object()(a, b); +} } // namespace CGAL #endif // CGAL_INTERSECTIONS_3_BBOX_3_ISO_CUBOID_3_H diff --git a/Intersections_3/include/CGAL/Intersections_3/Line_3_Tetrahedron_3.h b/Intersections_3/include/CGAL/Intersections_3/Line_3_Tetrahedron_3.h index 0566ccb561b..b24b65a8894 100644 --- a/Intersections_3/include/CGAL/Intersections_3/Line_3_Tetrahedron_3.h +++ b/Intersections_3/include/CGAL/Intersections_3/Line_3_Tetrahedron_3.h @@ -26,10 +26,24 @@ #include #include -#include +#include namespace CGAL { CGAL_DO_INTERSECT_FUNCTION(Line_3, Tetrahedron_3, 3) + + template + typename Intersection_traits::result_type + intersection(const Line_3& line, + const Tetrahedron_3& tet) { + return K().intersect_3_object()(line, tet); + } + + template + typename Intersection_traits::result_type + intersection(const Tetrahedron_3& tet, + const Line_3& line) { + return K().intersect_3_object()(tet, line); + } } #endif // CGAL_INTERSECTIONS_3_LINE_3_TETRAHEDRON_3_H diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Line_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Line_3_intersection.h new file mode 100644 index 00000000000..b742557a62b --- /dev/null +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Line_3_intersection.h @@ -0,0 +1,132 @@ +// Copyright (c) 2019 GeometryFactory(France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// +// +// Author(s) : Maxime Gimeno +// + +#ifndef CGAL_INTERNAL_INTERSECTIONS_3_TETRAHEDRON_3_LINE_3_INTERSECTION_H +#define CGAL_INTERNAL_INTERSECTIONS_3_TETRAHEDRON_3_LINE_3_INTERSECTION_H + +#include +#include + +namespace CGAL { + +namespace Intersections { + +namespace internal { +//Tetrahedron_3 Line_3 +template +typename Intersection_traits::result_type +intersection( + const typename K::Tetrahedron_3 &tet, + const typename K::Line_3 &line, + const K&) +{ + typedef typename Intersection_traits::result_type Result_type; + + typedef typename Intersection_traits::result_type Inter_type; + + int res_id = -1; + + Inter_type tr_line[4]; + for(std::size_t i = 0; i < 4; ++i) + { + const typename K::Triangle_3 triangle(tet.vertex((i+1)%4), + tet.vertex((i+2)%4), + tet.vertex((i+3)%4)); + tr_line[i] = CGAL::intersection(line, triangle); + if(tr_line[i]) + if( boost::get(&*tr_line[i]) != nullptr) + res_id = i; + } + //if there is a segment in the intersections, then we return it + if(res_id !=-1) + return tr_line[res_id]; + //else, if all intersections are the same or none, we return this single point. + std::vector res_points; + res_points.reserve(4); + res_id = -1; + for(std::size_t i = 0; i< 4; ++i) + { + if(tr_line[i]) + { + if (const typename K::Point_3* p = boost::get(&*tr_line[i])) + { + if(res_points.empty()) + { + res_id = i; + } + else { + if(*p != res_points.front()) + { + res_id = -1; + } + } + res_points.push_back(*p); + } + } + } + if(res_id != -1) + { + return tr_line[res_id]; + } + //else, we return a segment of the 2 intersection points (the most far away, in case of inexact) + typename K::FT max_dist = 0; + std::size_t res_id_2 = -1; + std::vector > sq_distances(res_points.size()); + for(std::size_t i = 0; i< res_points.size(); ++i) + { + auto p1 = res_points[i]; + for(auto p2 : res_points) + { + sq_distances[i].push_back(CGAL::squared_distance(p1, p2)); + if(sq_distances[i].back() > max_dist) + { + res_id = i; + res_id_2 = sq_distances[i].size()-1; + max_dist = sq_distances[i].back(); + } + } + } + CGAL_assertion(res_id != -1); + CGAL_assertion(res_id_2 != -1); + CGAL_assertion(max_dist >0 ); + + typename K::Segment_3 res_seg(res_points[res_id], res_points[res_id_2]); + + return Result_type(std::forward(res_seg)); +} + +template +typename Intersection_traits::result_type +intersection( + const typename K::Line_3 &line, + const typename K::Tetrahedron_3 &tet, + const K& k) +{ + return intersection(tet, line, k); +} + +}}} +#endif // CGAL_INTERNAL_INTERSECTIONS_3_TETRAHEDRON_3_LINE_3_INTERSECTION_H diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/intersection_3_1_impl.h b/Intersections_3/include/CGAL/Intersections_3/internal/intersection_3_1_impl.h index 3ef9ceee933..c3e43e611a9 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/intersection_3_1_impl.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/intersection_3_1_impl.h @@ -34,6 +34,7 @@ #include #include #include +#include #include namespace CGAL { @@ -1263,6 +1264,31 @@ intersection(const Bbox_3 &a, } + + + +template +typename Intersection_traits::result_type +intersection(const CGAL::Bbox_3 &box, + const typename K::Iso_cuboid_3 &cub, + const K&) +{ + typename K::Iso_cuboid_3 iso_cub(box); + return intersection(iso_cub, cub); +} + + +template +inline +typename Intersection_traits::result_type +intersection(const typename K::Iso_cuboid_3 &cub, + const CGAL::Bbox_3 &box, + const K& k) +{ + return intersection(box,cub, k); +} + + template typename Intersection_traits::result_type intersection(const typename K::Line_3 &line, diff --git a/Intersections_3/include/CGAL/intersection_3.h b/Intersections_3/include/CGAL/intersection_3.h index cc50d65cf87..e14efb55b94 100644 --- a/Intersections_3/include/CGAL/intersection_3.h +++ b/Intersections_3/include/CGAL/intersection_3.h @@ -92,6 +92,7 @@ #include #include +#include #include diff --git a/Intersections_3/test/Intersections_3/call_test.cpp b/Intersections_3/test/Intersections_3/call_test.cpp index b6fb2684f5b..fa9f2bdda62 100644 --- a/Intersections_3/test/Intersections_3/call_test.cpp +++ b/Intersections_3/test/Intersections_3/call_test.cpp @@ -19,6 +19,8 @@ typedef CGAL::Iso_cuboid_3< K > Cub; typedef CGAL::Sphere_3< K > Sph; typedef CGAL::Circle_3< K > C; +typedef CGAL::Tetrahedron_3< K > T; + typedef CGAL::Bbox_3 Bbox_3; template @@ -101,12 +103,16 @@ int main() // call_intersection_global(Cub(), Tr()); call_intersection_global(Cub(), R()); call_intersection_global(Cub(), Cub()); +// call_intersection_global(Cub(), Bbox_3()); call_intersection_global(Bbox_3(), L()); call_intersection_global(Bbox_3(), S()); call_intersection_global(Bbox_3(), R()); + call_intersection_global(Bbox_3(), Cub()); CGAL::intersection(Bbox_3(), Bbox_3()); + call_intersection_global(T(), L()); + // with kernel diff --git a/Intersections_3/test/Intersections_3/test_intersections_3.cpp b/Intersections_3/test/Intersections_3/test_intersections_3.cpp index b8c20156922..db1bcd88a30 100644 --- a/Intersections_3/test/Intersections_3/test_intersections_3.cpp +++ b/Intersections_3/test/Intersections_3/test_intersections_3.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -60,6 +61,7 @@ struct Test { typedef CGAL::Ray_3< K > R; typedef CGAL::Iso_cuboid_3< K > Cub; typedef CGAL::Sphere_3< K > Sph; + typedef CGAL::Tetrahedron_3< K > Tet; typedef CGAL::Bbox_3 Bbox; @@ -563,7 +565,21 @@ struct Test { << do_intersect_counter << "\n"; } // end function Bbox_Tr - void run() + void Tet_L() + { + std::cout << "Tetrahedron_3 - Line_3\n"; + + //check_intersection (S(P(-3,0,0),P(3,0,0)),R(P(3,-2,0),P(3,0,0)),P(3,0,0)); + //check_no_intersection (S(P(-3,0,0),P(3,0,0)),R(P(0,-1,0),P(0,-2,0))); + Tet tet(P(0,0,0), P(0,1,0), P(1,0,0), P(0,0,1)); + check_no_intersection (tet, L(P(5,0,0), P(5,1,0))); + check_intersection (tet, L(P(0,2,0), P(0,3,0)), S(P(0,0,0), P(0,1,0))); + check_intersection (tet, L(P(0,1,0), P(0.25,0,0.25)), S(P(0,1,0), P(0.25,0,0.25))); + check_intersection (tet, L(P(1,1,0), P(-1,1,0)), P(0,1,0)); + + } + + void run(bool is_exact = false) { std::cout << "3D Intersection tests\n"; P_do_intersect(); @@ -581,6 +597,8 @@ struct Test { R_L(); R_S(); R_R(); + if(is_exact) + Tet_L(); Bbox_L(); Bbox_R(); Bbox_Tr(); @@ -590,8 +608,9 @@ struct Test { int main() { - Test< CGAL::Simple_cartesian >().run(); - Test< CGAL::Homogeneous >().run(); + Test< CGAL::Simple_cartesian >().run(); + Test< CGAL::Homogeneous >().run(); + Test< CGAL::Epeck >().run(true); // TODO : test more kernels. } From 9cb1173a414213c770127a51f69ebc300b411ad2 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Tue, 4 Jun 2019 16:17:17 +0200 Subject: [PATCH 019/141] Add intersection Tetrahedron_3 / Segment_3 --- .../include/CGAL/Intersection_traits_3.h | 6 +- .../Intersections_3/Segment_3_Tetrahedron_3.h | 2 + .../Tetrahedron_3_Segment_3_intersections.h | 150 ++++++++++++++++++ .../Intersections_3/test_intersections_3.cpp | 29 +++- 4 files changed, 181 insertions(+), 6 deletions(-) create mode 100644 Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Segment_3_intersections.h diff --git a/Intersections_3/include/CGAL/Intersection_traits_3.h b/Intersections_3/include/CGAL/Intersection_traits_3.h index 31ab37bfeb4..45c20a56559 100644 --- a/Intersections_3/include/CGAL/Intersection_traits_3.h +++ b/Intersections_3/include/CGAL/Intersection_traits_3.h @@ -40,7 +40,6 @@ CGAL_INTERSECTION_TRAITS_2(Segment_3, Line_3, Point_3, Segment_3) CGAL_INTERSECTION_TRAITS_2(Line_3, Triangle_3, Point_3, Segment_3) CGAL_INTERSECTION_TRAITS_2(Line_3, Tetrahedron_3, Point_3, Segment_3) -CGAL_INTERSECTION_TRAITS_2(Tetrahedron_3, Line_3, Point_3, Segment_3) CGAL_INTERSECTION_TRAITS_2(Triangle_3, Line_3, Point_3, Segment_3) CGAL_INTERSECTION_TRAITS_2(Plane_3, Plane_3, Line_3, Plane_3) @@ -68,10 +67,15 @@ CGAL_INTERSECTION_TRAITS_2(Triangle_3, Ray_3, Point_3, Segment_3) CGAL_INTERSECTION_TRAITS_2(Segment_3, Segment_3, Point_3, Segment_3) CGAL_INTERSECTION_TRAITS_2(Segment_3, Triangle_3, Point_3, Segment_3) +CGAL_INTERSECTION_TRAITS_2(Segment_3, Tetrahedron_3, Point_3, Segment_3) + CGAL_INTERSECTION_TRAITS_2(Triangle_3, Segment_3, Point_3, Segment_3) CGAL_INTERSECTION_TRAITS_3(Sphere_3, Sphere_3, Point_3, Circle_3, Sphere_3) +CGAL_INTERSECTION_TRAITS_2(Tetrahedron_3, Line_3, Point_3, Segment_3) +CGAL_INTERSECTION_TRAITS_2(Tetrahedron_3, Segment_3, Point_3, Segment_3) + template struct Intersection_traits { typedef typename diff --git a/Intersections_3/include/CGAL/Intersections_3/Segment_3_Tetrahedron_3.h b/Intersections_3/include/CGAL/Intersections_3/Segment_3_Tetrahedron_3.h index 3f5dc525a4c..7184ab76cb7 100644 --- a/Intersections_3/include/CGAL/Intersections_3/Segment_3_Tetrahedron_3.h +++ b/Intersections_3/include/CGAL/Intersections_3/Segment_3_Tetrahedron_3.h @@ -27,9 +27,11 @@ #include #include +#include namespace CGAL { CGAL_DO_INTERSECT_FUNCTION(Segment_3, Tetrahedron_3, 3) + CGAL_INTERSECTION_FUNCTION(Segment_3, Tetrahedron_3, 3) } #endif // CGAL_INTERSECTIONS_3_SEGMENT_3_TETRAHEDRON_3_H diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Segment_3_intersections.h b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Segment_3_intersections.h new file mode 100644 index 00000000000..ca7d6a94a45 --- /dev/null +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Segment_3_intersections.h @@ -0,0 +1,150 @@ +// Copyright (c) 2019 GeometryFactory(France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// +// +// Author(s) : Maxime Gimeno +// + +#ifndef CGAL_INTERNAL_INTERSECTIONS_3_TETRAHEDRON_3_Segment_3_INTERSECTION_H +#define CGAL_INTERNAL_INTERSECTIONS_3_TETRAHEDRON_3_Segment_3_INTERSECTION_H + +#include +#include + +namespace CGAL { + +namespace Intersections { + +namespace internal { +//Tetrahedron_3 Segment_3 +template +typename Intersection_traits::result_type +intersection( + const typename K::Tetrahedron_3 &tet, + const typename K::Segment_3 &seg, + const K&) +{ + typedef typename Intersection_traits::result_type Result_type; + + typedef typename Intersection_traits::result_type Inter_type; + + //if both segment extremities are inside tet, return the input segment. + if(tet.has_on_bounded_side(seg.source()) + && tet.has_on_bounded_side(seg.target())){ + typename K::Segment_3 result = seg; + return Result_type(std::forward(result)); + } + int res_id = -1; + + Inter_type tr_seg[4]; + for(std::size_t i = 0; i < 4; ++i) + { + const typename K::Triangle_3 triangle(tet.vertex((i+1)%4), + tet.vertex((i+2)%4), + tet.vertex((i+3)%4)); + tr_seg[i] = CGAL::intersection(seg, triangle); + if(tr_seg[i]) + if( boost::get(&*tr_seg[i]) != nullptr) + res_id = i; + } + //if there is a segment in the intersections, then we return it + if(res_id !=-1) + return tr_seg[res_id]; + + //else if there is only 1 intersection + std::vector res_points; + res_points.reserve(4); + res_id = -1; + for(std::size_t i = 0; i< 4; ++i) + { + if(tr_seg[i]) + { + if (const typename K::Point_3* p = boost::get(&*tr_seg[i])) + { + if(res_points.empty()) + { + res_id = i; + } + else { + if(*p != res_points.front()) + { + res_id = -1; + } + } + res_points.push_back(*p); + } + } + } + if(res_id != -1) + { + //If one extremity is inside tet : return a segment + if(tet.has_on_bounded_side(seg.source())) + { + typename K::Segment_3 result(seg.source(), res_points.front()); + return Result_type(std::forward(result)); + } + else if(tet.has_on_bounded_side(seg.target())){ + typename K::Segment_3 result(res_points.front(), seg.target()); + return Result_type(std::forward(result)); + } + //else point and segment entirely not inside: + return tr_seg[res_id]; + } + //else, we return a segment of the 2 intersection points (the most far away, in case of inexact) + typename K::FT max_dist = 0; + std::size_t res_id_2 = -1; + std::vector > sq_distances(res_points.size()); + for(std::size_t i = 0; i< res_points.size(); ++i) + { + auto p1 = res_points[i]; + for(auto p2 : res_points) + { + sq_distances[i].push_back(CGAL::squared_distance(p1, p2)); + if(sq_distances[i].back() > max_dist) + { + res_id = i; + res_id_2 = sq_distances[i].size()-1; + max_dist = sq_distances[i].back(); + } + } + } + CGAL_assertion(res_id != -1); + CGAL_assertion(res_id_2 != -1); + CGAL_assertion(max_dist >0 ); + + typename K::Segment_3 res_seg(res_points[res_id], res_points[res_id_2]); + + return Result_type(std::forward(res_seg)); +} + +template +typename Intersection_traits::result_type +intersection( + const typename K::Segment_3 &seg, + const typename K::Tetrahedron_3 &tet, + const K& k) +{ + return intersection(tet, seg, k); +} + +}}} +#endif // CGAL_INTERNAL_INTERSECTIONS_3_TETRAHEDRON_3_Segment_3_INTERSECTION_H diff --git a/Intersections_3/test/Intersections_3/test_intersections_3.cpp b/Intersections_3/test/Intersections_3/test_intersections_3.cpp index db1bcd88a30..11f0ed9e7b2 100644 --- a/Intersections_3/test/Intersections_3/test_intersections_3.cpp +++ b/Intersections_3/test/Intersections_3/test_intersections_3.cpp @@ -134,6 +134,7 @@ struct Test { Res tmp; assert(CGAL::do_intersect(o1, o2)); assert(CGAL::assign(tmp, CGAL::intersection(o1, o2))); + std::cout< Date: Wed, 5 Jun 2019 10:11:34 +0200 Subject: [PATCH 020/141] Add intersection Ray_3 / Tetrahedron_3 --- .../include/CGAL/Intersection_traits_3.h | 2 + .../Intersections_3/Ray_3_Tetrahedron_3.h | 2 + .../Tetrahedron_3_Ray_3_intersections.h | 140 ++++++++++++++++++ .../Intersections_3/test_intersections_3.cpp | 18 +++ 4 files changed, 162 insertions(+) create mode 100644 Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Ray_3_intersections.h diff --git a/Intersections_3/include/CGAL/Intersection_traits_3.h b/Intersections_3/include/CGAL/Intersection_traits_3.h index 45c20a56559..1ac0751be92 100644 --- a/Intersections_3/include/CGAL/Intersection_traits_3.h +++ b/Intersections_3/include/CGAL/Intersection_traits_3.h @@ -62,6 +62,7 @@ CGAL_INTERSECTION_TRAITS_2(Ray_3, Segment_3, Point_3, Segment_3) CGAL_INTERSECTION_TRAITS_2(Segment_3, Ray_3, Point_3, Segment_3) CGAL_INTERSECTION_TRAITS_2(Ray_3, Triangle_3, Point_3, Segment_3) +CGAL_INTERSECTION_TRAITS_2(Ray_3, Tetrahedron_3, Point_3, Segment_3) CGAL_INTERSECTION_TRAITS_2(Triangle_3, Ray_3, Point_3, Segment_3) CGAL_INTERSECTION_TRAITS_2(Segment_3, Segment_3, Point_3, Segment_3) @@ -75,6 +76,7 @@ CGAL_INTERSECTION_TRAITS_3(Sphere_3, Sphere_3, Point_3, Circle_3, Sphere_3) CGAL_INTERSECTION_TRAITS_2(Tetrahedron_3, Line_3, Point_3, Segment_3) CGAL_INTERSECTION_TRAITS_2(Tetrahedron_3, Segment_3, Point_3, Segment_3) +CGAL_INTERSECTION_TRAITS_2(Tetrahedron_3, Ray_3, Point_3, Segment_3) template struct Intersection_traits { diff --git a/Intersections_3/include/CGAL/Intersections_3/Ray_3_Tetrahedron_3.h b/Intersections_3/include/CGAL/Intersections_3/Ray_3_Tetrahedron_3.h index b9b4b10c93b..6d8fbe3ef4c 100644 --- a/Intersections_3/include/CGAL/Intersections_3/Ray_3_Tetrahedron_3.h +++ b/Intersections_3/include/CGAL/Intersections_3/Ray_3_Tetrahedron_3.h @@ -27,9 +27,11 @@ #include #include +#include namespace CGAL { CGAL_DO_INTERSECT_FUNCTION(Ray_3, Tetrahedron_3, 3) + CGAL_INTERSECTION_FUNCTION(Ray_3, Tetrahedron_3, 3) } #endif // CGAL_INTERSECTIONS_3_RAY_3_TETRAHEDRON_3_H diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Ray_3_intersections.h b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Ray_3_intersections.h new file mode 100644 index 00000000000..4e42156abd5 --- /dev/null +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Ray_3_intersections.h @@ -0,0 +1,140 @@ +// Copyright (c) 2019 GeometryFactory(France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// +// +// Author(s) : Maxime Gimeno +// + +#ifndef CGAL_INTERNAL_INTERSECTIONS_3_TETRAHEDRON_3_RAY_3_INTERSECTION_H +#define CGAL_INTERNAL_INTERSECTIONS_3_TETRAHEDRON_3_RAY_3_INTERSECTION_H + +#include +#include + +namespace CGAL { + +namespace Intersections { + +namespace internal { +//Tetrahedron_3 Ray_3 +template +typename Intersection_traits::result_type +intersection( + const typename K::Tetrahedron_3 &tet, + const typename K::Ray_3 &ray, + const K&) +{ + typedef typename Intersection_traits::result_type Result_type; + + typedef typename Intersection_traits::result_type Inter_type; + + int res_id = -1; + + Inter_type tr_seg[4]; + for(std::size_t i = 0; i < 4; ++i) + { + const typename K::Triangle_3 triangle(tet.vertex((i+1)%4), + tet.vertex((i+2)%4), + tet.vertex((i+3)%4)); + tr_seg[i] = CGAL::intersection(ray, triangle); + if(tr_seg[i]) + if( boost::get(&*tr_seg[i]) != nullptr) + res_id = i; + } + //if there is a segment in the intersections, then we return it + if(res_id !=-1) + return tr_seg[res_id]; + + //else if there is only 1 intersection + std::vector res_points; + res_points.reserve(4); + res_id = -1; + for(std::size_t i = 0; i< 4; ++i) + { + if(tr_seg[i]) + { + if (const typename K::Point_3* p = boost::get(&*tr_seg[i])) + { + if(res_points.empty()) + { + res_id = i; + } + else { + if(*p != res_points.front()) + { + res_id = -1; + } + } + res_points.push_back(*p); + } + } + } + if(res_id != -1) + { + //If source is inside tet : return a segment + if(tet.has_on_bounded_side(ray.source())) + { + typename K::Ray_3 result(ray.source(), res_points.front()); + return Result_type(std::forward(result)); + } + //else segment of intersections: + return tr_seg[res_id]; + } + //else, we return a segment of the 2 intersection points (the most far away, in case of inexact) + typename K::FT max_dist = 0; + std::size_t res_id_2 = -1; + std::vector > sq_distances(res_points.size()); + for(std::size_t i = 0; i< res_points.size(); ++i) + { + auto p1 = res_points[i]; + for(auto p2 : res_points) + { + sq_distances[i].push_back(CGAL::squared_distance(p1, p2)); + if(sq_distances[i].back() > max_dist) + { + res_id = i; + res_id_2 = sq_distances[i].size()-1; + max_dist = sq_distances[i].back(); + } + } + } + CGAL_assertion(res_id != -1); + CGAL_assertion(res_id_2 != -1); + CGAL_assertion(max_dist >0 ); + + typename K::Ray_3 res_seg(res_points[res_id], res_points[res_id_2]); + + return Result_type(std::forward(res_seg)); +} + +template +typename Intersection_traits::result_type +intersection( + const typename K::Ray_3 &seg, + const typename K::Tetrahedron_3 &tet, + const K& k) +{ + return intersection(tet, seg, k); +} + +}}} +#endif // CGAL_INTERNAL_INTERSECTIONS_3_TETRAHEDRON_3_RAY_3_INTERSECTION_H diff --git a/Intersections_3/test/Intersections_3/test_intersections_3.cpp b/Intersections_3/test/Intersections_3/test_intersections_3.cpp index 11f0ed9e7b2..f8c61da7dee 100644 --- a/Intersections_3/test/Intersections_3/test_intersections_3.cpp +++ b/Intersections_3/test/Intersections_3/test_intersections_3.cpp @@ -594,6 +594,23 @@ struct Test { } + void Tet_R() + { + std::cout << "Tetrahedron_3 - Ray_3\n"; + + Tet tet(P(0,0,0), P(0,1,0), P(1,0,0), P(0,0,1)); + check_no_intersection (tet, L(P(5,0,0), P(5,1,0))); + check_intersection (tet, R(P(0,2,0), P(0,-2,0)), S(P(0,1,0), P(0,0,0))); + check_intersection (tet, R(P(0,1,0), P(0.25,0,0.25)), S(P(0,1,0), P(0.25,0,0.25))); + check_intersection (tet, R(P(2,1,0), P(-2,1,0)), P(0,1,0)); + + check_intersection (tet, R(P(0.1,0.1,0.1), P(0.2,0.2,0.2)), S(P(0.1,0.1,0.1), P(0.2,0.2,0.2))); + typename K::FT coord = 1.0/3.0; + check_intersection (tet, R(P(0.25,0.25,0.25), P(2,2,2)), S(P(0.25,0.25,0.25), P(coord, coord, coord))); + + } + + void run(bool is_exact = false) { std::cout << "3D Intersection tests\n"; @@ -615,6 +632,7 @@ struct Test { if(is_exact){ Tet_L(); Tet_S(); + Tet_R(); } /* Bbox_L(); From abeb0cf52da63c438b8831aa0cd308412cf2b92e Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 13 Jun 2019 10:27:00 +0200 Subject: [PATCH 021/141] Add intersection Ray_3 / Tetrahedron_3 --- .../Tetrahedron_3_Line_3_intersection.h | 84 +--------- .../Tetrahedron_3_Ray_3_intersections.h | 116 ++++---------- .../Tetrahedron_3_Segment_3_intersections.h | 146 ++++++------------ .../tetrahedron_lines_intersections_3.h | 134 ++++++++++++++++ .../Intersections_3/test_intersections_3.cpp | 3 +- 5 files changed, 224 insertions(+), 259 deletions(-) create mode 100644 Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Line_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Line_3_intersection.h index b742557a62b..5217bd5db90 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Line_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Line_3_intersection.h @@ -25,12 +25,16 @@ #include #include +#include namespace CGAL { namespace Intersections { namespace internal { + + + //Tetrahedron_3 Line_3 template typename Intersection_traits::result_type @@ -39,83 +43,9 @@ intersection( const typename K::Line_3 &line, const K&) { - typedef typename Intersection_traits::result_type Result_type; - - typedef typename Intersection_traits::result_type Inter_type; - - int res_id = -1; - - Inter_type tr_line[4]; - for(std::size_t i = 0; i < 4; ++i) - { - const typename K::Triangle_3 triangle(tet.vertex((i+1)%4), - tet.vertex((i+2)%4), - tet.vertex((i+3)%4)); - tr_line[i] = CGAL::intersection(line, triangle); - if(tr_line[i]) - if( boost::get(&*tr_line[i]) != nullptr) - res_id = i; - } - //if there is a segment in the intersections, then we return it - if(res_id !=-1) - return tr_line[res_id]; - //else, if all intersections are the same or none, we return this single point. - std::vector res_points; - res_points.reserve(4); - res_id = -1; - for(std::size_t i = 0; i< 4; ++i) - { - if(tr_line[i]) - { - if (const typename K::Point_3* p = boost::get(&*tr_line[i])) - { - if(res_points.empty()) - { - res_id = i; - } - else { - if(*p != res_points.front()) - { - res_id = -1; - } - } - res_points.push_back(*p); - } - } - } - if(res_id != -1) - { - return tr_line[res_id]; - } - //else, we return a segment of the 2 intersection points (the most far away, in case of inexact) - typename K::FT max_dist = 0; - std::size_t res_id_2 = -1; - std::vector > sq_distances(res_points.size()); - for(std::size_t i = 0; i< res_points.size(); ++i) - { - auto p1 = res_points[i]; - for(auto p2 : res_points) - { - sq_distances[i].push_back(CGAL::squared_distance(p1, p2)); - if(sq_distances[i].back() > max_dist) - { - res_id = i; - res_id_2 = sq_distances[i].size()-1; - max_dist = sq_distances[i].back(); - } - } - } - CGAL_assertion(res_id != -1); - CGAL_assertion(res_id_2 != -1); - CGAL_assertion(max_dist >0 ); - - typename K::Segment_3 res_seg(res_points[res_id], res_points[res_id_2]); - - return Result_type(std::forward(res_seg)); + Tetrahedron_lines_intersection_3_base solver(tet, line); + solver.do_procede(); + return solver.output; } template diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Ray_3_intersections.h b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Ray_3_intersections.h index 4e42156abd5..fb81b941435 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Ray_3_intersections.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Ray_3_intersections.h @@ -25,12 +25,40 @@ #include #include +#include namespace CGAL { namespace Intersections { namespace internal { + +template +struct Tetrahedron_ray_intersection_3 + :public Tetrahedron_lines_intersection_3_base +{ + typedef typename K::Ray_3 O; + typedef Tetrahedron_lines_intersection_3_base Base; + typedef typename Base::Result_type Result_type; + + Tetrahedron_ray_intersection_3(const typename K::Tetrahedron_3& tet, + const O& o):Base(tet,o) {} + + bool are_extremities_inside_test() override + { + //If one extremity is inside tet : return a segment + if(this->tet.has_on_bounded_side(this->o.source())) + { + typename K::Segment_3 result(this->o.source(), this->res_points.front()); + this->output = Result_type(std::forward(result)); + return true; + } + return false; + } +}; + + //Tetrahedron_3 Ray_3 template typename Intersection_traits::result_type @@ -39,91 +67,9 @@ intersection( const typename K::Ray_3 &ray, const K&) { - typedef typename Intersection_traits::result_type Result_type; - - typedef typename Intersection_traits::result_type Inter_type; - - int res_id = -1; - - Inter_type tr_seg[4]; - for(std::size_t i = 0; i < 4; ++i) - { - const typename K::Triangle_3 triangle(tet.vertex((i+1)%4), - tet.vertex((i+2)%4), - tet.vertex((i+3)%4)); - tr_seg[i] = CGAL::intersection(ray, triangle); - if(tr_seg[i]) - if( boost::get(&*tr_seg[i]) != nullptr) - res_id = i; - } - //if there is a segment in the intersections, then we return it - if(res_id !=-1) - return tr_seg[res_id]; - - //else if there is only 1 intersection - std::vector res_points; - res_points.reserve(4); - res_id = -1; - for(std::size_t i = 0; i< 4; ++i) - { - if(tr_seg[i]) - { - if (const typename K::Point_3* p = boost::get(&*tr_seg[i])) - { - if(res_points.empty()) - { - res_id = i; - } - else { - if(*p != res_points.front()) - { - res_id = -1; - } - } - res_points.push_back(*p); - } - } - } - if(res_id != -1) - { - //If source is inside tet : return a segment - if(tet.has_on_bounded_side(ray.source())) - { - typename K::Ray_3 result(ray.source(), res_points.front()); - return Result_type(std::forward(result)); - } - //else segment of intersections: - return tr_seg[res_id]; - } - //else, we return a segment of the 2 intersection points (the most far away, in case of inexact) - typename K::FT max_dist = 0; - std::size_t res_id_2 = -1; - std::vector > sq_distances(res_points.size()); - for(std::size_t i = 0; i< res_points.size(); ++i) - { - auto p1 = res_points[i]; - for(auto p2 : res_points) - { - sq_distances[i].push_back(CGAL::squared_distance(p1, p2)); - if(sq_distances[i].back() > max_dist) - { - res_id = i; - res_id_2 = sq_distances[i].size()-1; - max_dist = sq_distances[i].back(); - } - } - } - CGAL_assertion(res_id != -1); - CGAL_assertion(res_id_2 != -1); - CGAL_assertion(max_dist >0 ); - - typename K::Ray_3 res_seg(res_points[res_id], res_points[res_id_2]); - - return Result_type(std::forward(res_seg)); + Tetrahedron_ray_intersection_3 solver(tet, ray); + solver.do_procede(); + return solver.output; } template diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Segment_3_intersections.h b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Segment_3_intersections.h index ca7d6a94a45..9191404469a 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Segment_3_intersections.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Segment_3_intersections.h @@ -20,17 +20,62 @@ // Author(s) : Maxime Gimeno // -#ifndef CGAL_INTERNAL_INTERSECTIONS_3_TETRAHEDRON_3_Segment_3_INTERSECTION_H -#define CGAL_INTERNAL_INTERSECTIONS_3_TETRAHEDRON_3_Segment_3_INTERSECTION_H +#ifndef CGAL_INTERNAL_INTERSECTIONS_3_TETRAHEDRON_3_SEGMENT_3_INTERSECTION_H +#define CGAL_INTERNAL_INTERSECTIONS_3_TETRAHEDRON_3_SEGMENT_3_INTERSECTION_H #include #include +#include namespace CGAL { namespace Intersections { namespace internal { + +template +struct Tetrahedron_segment_intersection_3 + :public Tetrahedron_lines_intersection_3_base +{ + typedef typename K::Segment_3 O; + typedef Tetrahedron_lines_intersection_3_base Base; + typedef typename Base::Result_type Result_type; + + Tetrahedron_segment_intersection_3(const typename K::Tetrahedron_3& tet, + const O& o):Base(tet,o) {} + + bool all_inside_test() override + { + //if both segment extremities are inside tet, return the input segment. + if(this->tet.has_on_bounded_side(this->o.source()) + && this->tet.has_on_bounded_side(this->o.target())){ + typename K::Segment_3 result = this->o; + this->output = Result_type(std::forward(result)); + return true; + } + return false; + } + + bool are_extremities_inside_test() override + { + //If one extremity is inside tet : return a segment + if(this->tet.has_on_bounded_side(this->o.source())) + { + typename K::Segment_3 result(this->o.source(), this->res_points.front()); + this->output = Result_type(std::forward(result)); + return true; + } + else if(this->tet.has_on_bounded_side(this->o.target())){ + typename K::Segment_3 result(this->res_points.front(), this->o.target()); + this->output = Result_type(std::forward(result)); + return true; + } + return false; + } +}; + + //Tetrahedron_3 Segment_3 template typename Intersection_traits::result_type @@ -39,101 +84,10 @@ intersection( const typename K::Segment_3 &seg, const K&) { - typedef typename Intersection_traits::result_type Result_type; + Tetrahedron_segment_intersection_3 solver(tet, seg); + solver.do_procede(); + return solver.output; - typedef typename Intersection_traits::result_type Inter_type; - - //if both segment extremities are inside tet, return the input segment. - if(tet.has_on_bounded_side(seg.source()) - && tet.has_on_bounded_side(seg.target())){ - typename K::Segment_3 result = seg; - return Result_type(std::forward(result)); - } - int res_id = -1; - - Inter_type tr_seg[4]; - for(std::size_t i = 0; i < 4; ++i) - { - const typename K::Triangle_3 triangle(tet.vertex((i+1)%4), - tet.vertex((i+2)%4), - tet.vertex((i+3)%4)); - tr_seg[i] = CGAL::intersection(seg, triangle); - if(tr_seg[i]) - if( boost::get(&*tr_seg[i]) != nullptr) - res_id = i; - } - //if there is a segment in the intersections, then we return it - if(res_id !=-1) - return tr_seg[res_id]; - - //else if there is only 1 intersection - std::vector res_points; - res_points.reserve(4); - res_id = -1; - for(std::size_t i = 0; i< 4; ++i) - { - if(tr_seg[i]) - { - if (const typename K::Point_3* p = boost::get(&*tr_seg[i])) - { - if(res_points.empty()) - { - res_id = i; - } - else { - if(*p != res_points.front()) - { - res_id = -1; - } - } - res_points.push_back(*p); - } - } - } - if(res_id != -1) - { - //If one extremity is inside tet : return a segment - if(tet.has_on_bounded_side(seg.source())) - { - typename K::Segment_3 result(seg.source(), res_points.front()); - return Result_type(std::forward(result)); - } - else if(tet.has_on_bounded_side(seg.target())){ - typename K::Segment_3 result(res_points.front(), seg.target()); - return Result_type(std::forward(result)); - } - //else point and segment entirely not inside: - return tr_seg[res_id]; - } - //else, we return a segment of the 2 intersection points (the most far away, in case of inexact) - typename K::FT max_dist = 0; - std::size_t res_id_2 = -1; - std::vector > sq_distances(res_points.size()); - for(std::size_t i = 0; i< res_points.size(); ++i) - { - auto p1 = res_points[i]; - for(auto p2 : res_points) - { - sq_distances[i].push_back(CGAL::squared_distance(p1, p2)); - if(sq_distances[i].back() > max_dist) - { - res_id = i; - res_id_2 = sq_distances[i].size()-1; - max_dist = sq_distances[i].back(); - } - } - } - CGAL_assertion(res_id != -1); - CGAL_assertion(res_id_2 != -1); - CGAL_assertion(max_dist >0 ); - - typename K::Segment_3 res_seg(res_points[res_id], res_points[res_id_2]); - - return Result_type(std::forward(res_seg)); } template diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h new file mode 100644 index 00000000000..ef2449873f1 --- /dev/null +++ b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h @@ -0,0 +1,134 @@ +#ifndef TETRAHEDRON_LINES_INTERSECTIONS_3_H +#define TETRAHEDRON_LINES_INTERSECTIONS_3_H + +#include +#include +#include + +namespace CGAL { + +namespace Intersections { + +namespace internal { +template +struct Tetrahedron_lines_intersection_3_base +{ + typedef typename Intersection_traits, + O>::result_type Result_type; + + typedef typename Intersection_traits, + O>::result_type Inter_type; + + Tetrahedron_lines_intersection_3_base(const typename K::Tetrahedron_3& tet, + const O& o):tet(tet), o(o) + {} + const typename K::Tetrahedron_3& tet; + const O& o; + std::vector res_points; + Result_type output; + virtual bool all_inside_test() + { + return false; + } + + virtual bool are_extremities_inside_test() + { + return false; + } + virtual ~Tetrahedron_lines_intersection_3_base() + {} + + void do_procede() + { + if(all_inside_test()) + return; + + int res_id = -1; + + Inter_type tr_seg[4]; + for(std::size_t i = 0; i < 4; ++i) + { + const typename K::Triangle_3 triangle(tet.vertex((i+1)%4), + tet.vertex((i+2)%4), + tet.vertex((i+3)%4)); + tr_seg[i] = typename K::Intersect_3()(o, triangle); + if(tr_seg[i]) + if( boost::get(&*tr_seg[i]) != nullptr) + res_id = i; + } + + //if there is a segment in the intersections, then we return it + if(res_id !=-1) + { + output = tr_seg[res_id]; + return; + } + + //else if there is only 1 intersection + res_points.reserve(4); + res_id = -1; + for(std::size_t i = 0; i< 4; ++i) + { + if(tr_seg[i]) + { + if (const typename K::Point_3* p = boost::get(&*tr_seg[i])) + { + if(res_points.empty()) + { + res_id = i; + } + else { + if(*p != res_points.front()) + { + res_id = -1; + } + } + res_points.push_back(*p); + } + } + } + if(res_points.empty()) + return; + if(res_id != -1) + { + if(are_extremities_inside_test()) + return; + //else point and segment entirely not inside: + output = tr_seg[res_id]; + return; + } + //else, we return a segment of the 2 intersection points (the most far away, in case of inexact) + typename K::FT max_dist = 0; + std::size_t res_id_2 = -1; + std::vector > sq_distances(res_points.size()); + for(std::size_t i = 0; i< res_points.size(); ++i) + { + auto p1 = res_points[i]; + for(auto p2 : res_points) + { + sq_distances[i].push_back(CGAL::squared_distance(p1, p2)); + if(sq_distances[i].back() > max_dist) + { + res_id = i; + res_id_2 = sq_distances[i].size()-1; + max_dist = sq_distances[i].back(); + } + } + } + CGAL_assertion(res_id != -1); + CGAL_assertion(res_id_2 != -1); + CGAL_assertion(max_dist >0 ); + + typename K::Segment_3 res_seg(res_points[res_id], res_points[res_id_2]); + + output = Result_type(std::forward(res_seg)); + return; + } +}; + +} +} +} +#endif // TETRAHEDRON_LINES_INTERSECTIONS_3_H diff --git a/Intersections_3/test/Intersections_3/test_intersections_3.cpp b/Intersections_3/test/Intersections_3/test_intersections_3.cpp index f8c61da7dee..765a04ecb6f 100644 --- a/Intersections_3/test/Intersections_3/test_intersections_3.cpp +++ b/Intersections_3/test/Intersections_3/test_intersections_3.cpp @@ -600,12 +600,13 @@ struct Test { Tet tet(P(0,0,0), P(0,1,0), P(1,0,0), P(0,0,1)); check_no_intersection (tet, L(P(5,0,0), P(5,1,0))); + check_intersection (tet, R(P(0,2,0), P(0,-2,0)), S(P(0,1,0), P(0,0,0))); check_intersection (tet, R(P(0,1,0), P(0.25,0,0.25)), S(P(0,1,0), P(0.25,0,0.25))); check_intersection (tet, R(P(2,1,0), P(-2,1,0)), P(0,1,0)); - check_intersection (tet, R(P(0.1,0.1,0.1), P(0.2,0.2,0.2)), S(P(0.1,0.1,0.1), P(0.2,0.2,0.2))); typename K::FT coord = 1.0/3.0; + check_intersection (tet, R(P(0.1,0.1,0.1), P(0.2,0.2,0.2)), S(P(0.1,0.1,0.1), P(coord, coord, coord))); check_intersection (tet, R(P(0.25,0.25,0.25), P(2,2,2)), S(P(0.25,0.25,0.25), P(coord, coord, coord))); } From 38bf604b4a7a543953c7cd2161a27b59350c244f Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 5 Jun 2019 16:14:30 +0200 Subject: [PATCH 022/141] Add intersections for Tet/plane --- .../include/CGAL/Intersection_traits_3.h | 19 ++ .../Intersections_3/Plane_3_Tetrahedron_3.h | 2 + .../Tetrahedron_3_Plane_3_intersections.h | 194 ++++++++++++++++++ .../Intersections_3/test_intersections_3.cpp | 35 +++- 4 files changed, 247 insertions(+), 3 deletions(-) create mode 100644 Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersections.h diff --git a/Intersections_3/include/CGAL/Intersection_traits_3.h b/Intersections_3/include/CGAL/Intersection_traits_3.h index 1ac0751be92..b1f8c7eb761 100644 --- a/Intersections_3/include/CGAL/Intersection_traits_3.h +++ b/Intersections_3/include/CGAL/Intersection_traits_3.h @@ -304,6 +304,25 @@ struct Intersection_traits { typedef typename boost::optional< variant_type > result_type; }; +//Tetrahedron_3 Plane_3, variant of 4 +template +struct Intersection_traits +{ + typedef typename + boost::variant< typename K::Point_3 , typename K::Segment_3, + typename K::Triangle_3, std::vector > variant_type; + typedef typename boost::optional< variant_type > result_type; +}; +//Plane_3 Tetrahedron_3, variant of 4 +template +struct Intersection_traits +{ + typedef typename + boost::variant< typename K::Point_3 , typename K::Segment_3, + typename K::Triangle_3, std::vector > variant_type; + typedef typename boost::optional< variant_type > result_type; +}; + } // namespace diff --git a/Intersections_3/include/CGAL/Intersections_3/Plane_3_Tetrahedron_3.h b/Intersections_3/include/CGAL/Intersections_3/Plane_3_Tetrahedron_3.h index ef92801ef67..5eb429d8917 100644 --- a/Intersections_3/include/CGAL/Intersections_3/Plane_3_Tetrahedron_3.h +++ b/Intersections_3/include/CGAL/Intersections_3/Plane_3_Tetrahedron_3.h @@ -27,9 +27,11 @@ #include #include +#include namespace CGAL { CGAL_DO_INTERSECT_FUNCTION(Tetrahedron_3, Plane_3, 3) + CGAL_INTERSECTION_FUNCTION(Tetrahedron_3, Plane_3, 3) } #endif // CGAL_INTERSECTIONS_3_PLANE_3_TETRAHEDRON_3_H diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersections.h b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersections.h new file mode 100644 index 00000000000..141c4701311 --- /dev/null +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersections.h @@ -0,0 +1,194 @@ +// Copyright (c) 2019 GeometryFactory(France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// +// +// Author(s) : Maxime Gimeno +// + + +#ifndef CGAL_INTERNAL_INTERSECTIONS_3_TETRAHEDRON_3_PLANE_3_INTERSECTIONS_H +#define CGAL_INTERNAL_INTERSECTIONS_3_TETRAHEDRON_3_PLANE_3_INTERSECTIONS_H + +#include +#include +#include +#include +namespace CGAL { + +namespace Intersections { + +namespace internal { + +//Tetrahedron_3 Segment_3 +template +typename Intersection_traits::result_type +intersection( + const typename K::Tetrahedron_3 &tet, + const typename K::Plane_3 &pl, + const K&) +{ + typedef typename Intersection_traits::result_type Result_type; + + typedef typename Intersection_traits::result_type Inter_type; + + typedef typename K::Segment_3 Segment_3; + Inter_type intersections[4]; + std::size_t seg_id = -1, + p_id = -1; + std::vector points; + std::vector segments; + for(std::size_t i = 0; i < 4; ++i) + { + const typename K::Triangle_3 triangle(tet.vertex((i+1)%4), + tet.vertex((i+2)%4), + tet.vertex((i+3)%4)); + intersections[i] = typename K::Intersect_3()(pl, triangle); + if(intersections[i]){ + if(const typename K::Triangle_3* tr = boost::get(&*intersections[i])) + { + typename K::Triangle_3 res = *tr; + return Result_type(std::forward(res)); + } + else if( const Segment_3* s + = boost::get(&*intersections[i])) + { + segments.push_back(*s); + seg_id = i; + } + else if( const typename K::Point_3* p + = boost::get(&*intersections[i])) + { + points.push_back(*p); + p_id = i; + } + } + } + CGAL_assertion(segments.size() != 1); + + switch(segments.size()) + { + case 0: + { + if(p_id == -1) + return Result_type(); + else + { + typename K::Point_3 p + = *boost::get(&*intersections[p_id]); + + return Result_type(std::forward(p)); + } + } + break; + case 2: + { + return Result_type(std::forward(segments.back())); + } + break; + default: + { + std::set all_points; + for (auto s : segments) + { + all_points.insert(s.source()); + all_points.insert(s.target()); + } + if(all_points.size() == 3) + { + auto p_it = all_points.begin(); + ++p_it; + typename K::Point_3 mid_point = *p_it; + ++p_it; + typename K::Triangle_3 result(*all_points.begin(), mid_point, *p_it ); + return Result_type(std::forward(result)); + } + else //size = 4 + { + Segment_3 edge = segments.back(); + segments.pop_back(); + std::vector result; + auto s_it = segments.begin(); + + result.push_back(edge.source()); + result.push_back(edge.target()); + + int counter = 0; + for(; counter <2; ++counter )//1 or 2 rounds + { + if(edge.target() == s_it->source()) + { + result.push_back(s_it->target()); + break; + } + else if (edge.target() == s_it->target()) + { + result.push_back(s_it->source()); + break; + } + else + ++s_it; + } + if(counter > 1) //not exact, won't find the right inter anyway. + return Result_type(); + + segments.erase(s_it); + + s_it = segments.begin(); + if(edge.source() == s_it->target()) + { + result.push_back(s_it->source()); + } + else if(edge.source() == s_it->source()) + { + result.push_back(s_it->target()); + } + else + { + if(result.back() == s_it->target()) + { + result.push_back(s_it->source()); + } + else if(result.back() == s_it->source()) + { + result.push_back(s_it->target()); + } + } + return Result_type(std::forward >(result)); + } + } + break; + } + return Result_type(); +} + +template +typename Intersection_traits::result_type +intersection( + const typename K::Plane_3 &pl, + const typename K::Tetrahedron_3 &tet, + const K& k) +{ + return intersection(tet, pl, k); +} + +}}} +#endif // CGAL_INTERNAL_INTERSECTIONS_3_TETRAHEDRON_3_PLANE_3_INTERSECTIONS_H diff --git a/Intersections_3/test/Intersections_3/test_intersections_3.cpp b/Intersections_3/test/Intersections_3/test_intersections_3.cpp index 765a04ecb6f..dc5281e90c6 100644 --- a/Intersections_3/test/Intersections_3/test_intersections_3.cpp +++ b/Intersections_3/test/Intersections_3/test_intersections_3.cpp @@ -583,7 +583,7 @@ struct Test { std::cout << "Tetrahedron_3 - Segment_3\n"; Tet tet(P(0,0,0), P(0,1,0), P(1,0,0), P(0,0,1)); - check_no_intersection (tet, L(P(5,0,0), P(5,1,0))); + check_no_intersection (tet, S(P(5,0,0), P(5,1,0))); check_intersection (tet, S(P(0,2,0), P(0,-2,0)), S(P(0,1,0), P(0,0,0))); check_intersection (tet, S(P(0,1,0), P(0.25,0,0.25)), S(P(0,1,0), P(0.25,0,0.25))); check_intersection (tet, S(P(2,1,0), P(-2,1,0)), P(0,1,0)); @@ -599,7 +599,7 @@ struct Test { std::cout << "Tetrahedron_3 - Ray_3\n"; Tet tet(P(0,0,0), P(0,1,0), P(1,0,0), P(0,0,1)); - check_no_intersection (tet, L(P(5,0,0), P(5,1,0))); + check_no_intersection (tet, R(P(5,0,0), P(5,1,0))); check_intersection (tet, R(P(0,2,0), P(0,-2,0)), S(P(0,1,0), P(0,0,0))); check_intersection (tet, R(P(0,1,0), P(0.25,0,0.25)), S(P(0,1,0), P(0.25,0,0.25))); @@ -608,9 +608,37 @@ struct Test { typename K::FT coord = 1.0/3.0; check_intersection (tet, R(P(0.1,0.1,0.1), P(0.2,0.2,0.2)), S(P(0.1,0.1,0.1), P(coord, coord, coord))); check_intersection (tet, R(P(0.25,0.25,0.25), P(2,2,2)), S(P(0.25,0.25,0.25), P(coord, coord, coord))); - } + void Tet_Pl() + { + std::cout << "Tetrahedron_3 - Plane_3\n"; + + Tet tet(P(0,0,0), P(0,1,0), P(1,0,0), P(0,0,1)); + check_no_intersection (tet, Pl(P(2,0,0), + P(2,1,0), + P(2,0,1))); + + check_intersection (tet, Pl(P(0,2,0), P(0,0,0), P(0,0,1)), + Tr(P(0,0,0), P(0,1,0), P(0,0,1))); + + check_intersection (tet, Pl(P(0,1,0), P(1,0,0), P(0.5,0,-0.5)), + S(P(0,1,0), P(1,0,0))); + + check_intersection (tet, Pl(P(-1,1,12), P(0,1,-50), P(0.5,1,-0.5)), + P(0,1,0)); + + check_intersection (tet, Pl(P(0,0.5,0), P(1,0.5,-5), P(0.5,0.5,0.5)), + Tr(P(0.5,0.5,0), P(0,0.5,0), P(0,0.5,0.5))); + Pl pl(P(0,0.9,0), P(0.9,0,0), P(0.9,0.01,0.06)); + + typedef typename CGAL::Intersection_traits::result_type Res; + assert(CGAL::do_intersect(tet, pl)); + //Don't have the right values to test further. + + } void run(bool is_exact = false) { @@ -634,6 +662,7 @@ struct Test { Tet_L(); Tet_S(); Tet_R(); + Tet_Pl(); } /* Bbox_L(); From 5e9891ea75bc3121baad5a97ef74fcb64ef9f2bd Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 6 Jun 2019 10:46:02 +0200 Subject: [PATCH 023/141] Tet / tr --- .../include/CGAL/Intersection_traits_3.h | 43 ++ .../Intersections_3/Iso_cuboid_3_Plane_3.h | 2 + .../Intersections_3/Plane_3_Tetrahedron_3.h | 2 +- .../Intersections_3/Ray_3_Tetrahedron_3.h | 2 +- .../Intersections_3/Segment_3_Tetrahedron_3.h | 2 +- .../Tetrahedron_3_Triangle_3.h | 2 + .../Iso_cuboid_3_Plane_3_intersection.h | 262 ++++++++ ...h => Tetrahedron_3_Plane_3_intersection.h} | 61 +- ...s.h => Tetrahedron_3_Ray_3_intersection.h} | 0 ...=> Tetrahedron_3_Segment_3_intersection.h} | 0 .../Tetrahedron_3_Triangle_3_intersection.h | 299 ++++++++++ .../tetrahedron_intersection_helpers.h | 246 ++++++++ .../Intersections_3/test_intersections_3.cpp | 563 ++++++++++++++---- 13 files changed, 1308 insertions(+), 176 deletions(-) create mode 100644 Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h rename Intersections_3/include/CGAL/Intersections_3/internal/{Tetrahedron_3_Plane_3_intersections.h => Tetrahedron_3_Plane_3_intersection.h} (74%) rename Intersections_3/include/CGAL/Intersections_3/internal/{Tetrahedron_3_Ray_3_intersections.h => Tetrahedron_3_Ray_3_intersection.h} (100%) rename Intersections_3/include/CGAL/Intersections_3/internal/{Tetrahedron_3_Segment_3_intersections.h => Tetrahedron_3_Segment_3_intersection.h} (100%) create mode 100644 Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Triangle_3_intersection.h create mode 100644 Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h diff --git a/Intersections_3/include/CGAL/Intersection_traits_3.h b/Intersections_3/include/CGAL/Intersection_traits_3.h index b1f8c7eb761..ac9513417f8 100644 --- a/Intersections_3/include/CGAL/Intersection_traits_3.h +++ b/Intersections_3/include/CGAL/Intersection_traits_3.h @@ -187,6 +187,28 @@ struct Intersection_traits { typedef typename boost::optional< variant_type > result_type; }; + +// Iso_cuboid_3 Plane_3, variant of 4 +template +struct Intersection_traits { + typedef typename + boost::variant< typename K::Point_3, typename K::Segment_3, + typename K::Triangle_3, std::vector > variant_type; + + typedef typename boost::optional< variant_type > result_type; +}; + +template +struct Intersection_traits { + typedef typename + boost::variant< typename K::Point_3, typename K::Segment_3, + typename K::Triangle_3, std::vector > variant_type; + + typedef typename boost::optional< variant_type > result_type; +}; + + + // Point_3 Line_3, variant of one template struct Intersection_traits { @@ -324,6 +346,27 @@ struct Intersection_traits }; +//Triangle_3 Tetrahedron_3, variant of 4 +template +struct Intersection_traits +{ + typedef typename + boost::variant< typename K::Point_3 , typename K::Segment_3, + typename K::Triangle_3, std::vector > variant_type; + typedef typename boost::optional< variant_type > result_type; +}; + +// Tetrahedron_3 Triangle_3, variant of 4 +template +struct Intersection_traits +{ + typedef typename + boost::variant< typename K::Point_3 , typename K::Segment_3, + typename K::Triangle_3, std::vector > variant_type; + typedef typename boost::optional< variant_type > result_type; +}; + + } // namespace #endif /* CGAL_INTERSECTION_TRAITS_3_H */ diff --git a/Intersections_3/include/CGAL/Intersections_3/Iso_cuboid_3_Plane_3.h b/Intersections_3/include/CGAL/Intersections_3/Iso_cuboid_3_Plane_3.h index 11c5eff3120..c503bbba418 100644 --- a/Intersections_3/include/CGAL/Intersections_3/Iso_cuboid_3_Plane_3.h +++ b/Intersections_3/include/CGAL/Intersections_3/Iso_cuboid_3_Plane_3.h @@ -26,10 +26,12 @@ #include #include #include +#include namespace CGAL { CGAL_DO_INTERSECT_FUNCTION(Iso_cuboid_3, Plane_3, 3) + CGAL_INTERSECTION_FUNCTION(Iso_cuboid_3, Plane_3, 3) } #endif // CGAL_INTERSECTIONS_3_ISO_CUBOID_3_PLANE_3_H diff --git a/Intersections_3/include/CGAL/Intersections_3/Plane_3_Tetrahedron_3.h b/Intersections_3/include/CGAL/Intersections_3/Plane_3_Tetrahedron_3.h index 5eb429d8917..55c171a63d2 100644 --- a/Intersections_3/include/CGAL/Intersections_3/Plane_3_Tetrahedron_3.h +++ b/Intersections_3/include/CGAL/Intersections_3/Plane_3_Tetrahedron_3.h @@ -27,7 +27,7 @@ #include #include -#include +#include namespace CGAL { CGAL_DO_INTERSECT_FUNCTION(Tetrahedron_3, Plane_3, 3) diff --git a/Intersections_3/include/CGAL/Intersections_3/Ray_3_Tetrahedron_3.h b/Intersections_3/include/CGAL/Intersections_3/Ray_3_Tetrahedron_3.h index 6d8fbe3ef4c..40429f99666 100644 --- a/Intersections_3/include/CGAL/Intersections_3/Ray_3_Tetrahedron_3.h +++ b/Intersections_3/include/CGAL/Intersections_3/Ray_3_Tetrahedron_3.h @@ -27,7 +27,7 @@ #include #include -#include +#include namespace CGAL { CGAL_DO_INTERSECT_FUNCTION(Ray_3, Tetrahedron_3, 3) diff --git a/Intersections_3/include/CGAL/Intersections_3/Segment_3_Tetrahedron_3.h b/Intersections_3/include/CGAL/Intersections_3/Segment_3_Tetrahedron_3.h index 7184ab76cb7..f58529d8db9 100644 --- a/Intersections_3/include/CGAL/Intersections_3/Segment_3_Tetrahedron_3.h +++ b/Intersections_3/include/CGAL/Intersections_3/Segment_3_Tetrahedron_3.h @@ -27,7 +27,7 @@ #include #include -#include +#include namespace CGAL { CGAL_DO_INTERSECT_FUNCTION(Segment_3, Tetrahedron_3, 3) diff --git a/Intersections_3/include/CGAL/Intersections_3/Tetrahedron_3_Triangle_3.h b/Intersections_3/include/CGAL/Intersections_3/Tetrahedron_3_Triangle_3.h index da0193e3291..671498a6246 100644 --- a/Intersections_3/include/CGAL/Intersections_3/Tetrahedron_3_Triangle_3.h +++ b/Intersections_3/include/CGAL/Intersections_3/Tetrahedron_3_Triangle_3.h @@ -27,9 +27,11 @@ #include #include +#include namespace CGAL { CGAL_DO_INTERSECT_FUNCTION(Tetrahedron_3, Triangle_3, 3) + CGAL_INTERSECTION_FUNCTION(Tetrahedron_3, Triangle_3, 3) } #endif // CGAL_INTERSECTIONS_3_TETRAHEDRON_3_TRIANGLE_3_H diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h new file mode 100644 index 00000000000..2715b9e40ae --- /dev/null +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h @@ -0,0 +1,262 @@ +// Copyright (c) 2019 GeometryFactory(France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// +// +// Author(s) : Maxime Gimeno +// + +#ifndef CGAL_INTERNAL_INTERSECTIONS_3_ISO_CUBOID_3_PLANE_3_INTERSECTION_H +#define CGAL_INTERNAL_INTERSECTIONS_3_ISO_CUBOID_3_PLANE_3_INTERSECTION_H +#include +#include +#include +#include +#include + +#include +namespace CGAL { + +namespace Intersections { + +namespace internal { + +template +void filter_points(const std::vector& input, + std::vector& output) +{ + std::set tmp; + for( auto p : input) + tmp.insert(p); + for(auto p: tmp) + output.push_back(p); +} + +//Tetrahedron_3 Line_3 +template +typename Intersection_traits::result_type +intersection( + const typename K::Iso_cuboid_3 &cub, + const typename K::Plane_3 &pl, + const K&) +{ + typedef typename K::Point_3 Point_3; + typedef typename K::Segment_3 Segment_3; + typedef typename K::Line_3 Line_3; + typedef typename K::Plane_3 Plane_3; + typedef std::vector Poly; + + typedef typename Intersection_traits, + CGAL::Plane_3 >::result_type Result_type; + + typedef typename Intersection_traits, + CGAL::Plane_3 >::result_type Inter_type; + + std::vector edges; + edges.reserve(12); + + //get all edges of cub + for(int i=0; i< 4; ++i) + { + edges.push_back(Segment_3(cub.vertex(i), cub.vertex((i+1)%4))); + } + + for(int i=0; i < 4; ++i) + { + edges.push_back(Segment_3(cub.vertex(i+4), cub.vertex((i+1)%4+4))); + } + + for(int i=0; i < 4; ++i) + { + edges.push_back(Segment_3(cub.vertex(i), cub.vertex((i+1)%4+4))); + } + //get all intersections between pl and cub edges + std::vector segments; + std::vector points; + + for(int i=0; i < 12; ++i) + { + Inter_type inter = typename K::Intersect_3()(pl, edges[i]); + if(inter){ + if(const Segment_3* seg = boost::get(&*inter)) + { + segments.push_back(*seg); + } + else if(const Point_3* p = boost::get(&*inter)) + { + points.push_back(*p); + } + } + } + + switch(segments.size()) + { + case 1: //adj to an edge + { + return Result_type(std::forward(segments.front())); + } + break; + + case 2: //intersects diagonally + { + Poly res(4); + Segment_3 front(segments.front()), + back(segments.back()); + res[0] = front.target(); + if((front.target() - front.source()) + * (back.target() - back.source()) > 0) + { + res[1] = back.target(); + res[2] = back.source(); + } + else + { + res[1] = back.source(); + res[2] = back.target(); + } + res[3] = front.source(); + + return Result_type(std::forward(res)); + } + break; + case 4: // intersects a face + { + Poly res; + res.reserve(4); + std::list tmp; + std::list seg_list; + for(auto s : segments) + seg_list.push_back(s); + fill_points_list(seg_list, tmp); + for(auto p : tmp) + res.push_back(p); + return Result_type(std::forward(res)); + } + break; + default: + break; + } + + Poly filtered_points; + filter_points(points, filtered_points); + if(filtered_points.empty()) + return Result_type(); + //adjacent to a vertex + if(filtered_points.size() == 1) + { + return Result_type(std::forward(filtered_points.front())); + } + else + { + //get intersections between pl and each face -> line. Foreach line, creates segment with points. Then use helper_function to recover polygon. + typedef typename Intersection_traits, + CGAL::Plane_3 >::result_type Pl_pl_type; + + std::vector plane_intersections; + Pl_pl_type pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(0), + cub.vertex(1), + cub.vertex(5))); + if(const Line_3* line = boost::get(&*pl_inter)){ + plane_intersections.push_back(*line); + } + pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(0), + cub.vertex(3), + cub.vertex(4))); + if(const Line_3* line = boost::get(&*pl_inter)){ + plane_intersections.push_back(*line); + } + pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(0), + cub.vertex(1), + cub.vertex(3))); + if(const Line_3* line = boost::get(&*pl_inter)){ + plane_intersections.push_back(*line); + } + pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(7), + cub.vertex(6), + cub.vertex(1))); + if(const Line_3* line = boost::get(&*pl_inter)){ + plane_intersections.push_back(*line); + } + pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(7), + cub.vertex(4), + cub.vertex(3))); + if(const Line_3* line = boost::get(&*pl_inter)){ + plane_intersections.push_back(*line); + } + pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(7), + cub.vertex(6), + cub.vertex(4))); + if(const Line_3* line = boost::get(&*pl_inter)){ + plane_intersections.push_back(*line); + } + + std::list tmp_segs; + for(auto line : plane_intersections) + { + bool first_found = false; + Point_3 first_p; + for(auto p : filtered_points) + { + if(line.has_on(p)) + { + if(!first_found) + { + first_found = true; + first_p = p; + } + else + { + tmp_segs.push_back(Segment_3(first_p, p)); + break; + } + } + } + } + if(tmp_segs.size() < 3) + return Result_type(); + std::list tmp_pts; + fill_points_list(tmp_segs,tmp_pts); + Poly res; + for(auto p : tmp_pts) + res.push_back(p); + if(res.size() == 3){ + typename K::Triangle_3 tr(res[0], res[1], res[2]); + return Result_type(std::forward(tr)); + } + else + { + return Result_type(std::forward(res)); + } + } +} + +template +typename Intersection_traits::result_type +intersection( + const typename K::Plane_3 &pl, + const typename K::Iso_cuboid_3 &cub, + const K& k) +{ + return intersection(cub, pl, k); +} + +}}} + +#endif // CGAL_INTERNAL_INTERSECTIONS_3_ISO_CUBOID_3_PLANE_3_INTERSECTION_H diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersections.h b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersection.h similarity index 74% rename from Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersections.h rename to Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersection.h index 141c4701311..3a6353c9809 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersections.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersection.h @@ -27,6 +27,7 @@ #include #include #include +#include #include namespace CGAL { @@ -34,6 +35,7 @@ namespace Intersections { namespace internal { + //Tetrahedron_3 Segment_3 template typename Intersection_traits::result_type @@ -123,56 +125,15 @@ intersection( } else //size = 4 { - Segment_3 edge = segments.back(); - segments.pop_back(); - std::vector result; - auto s_it = segments.begin(); - - result.push_back(edge.source()); - result.push_back(edge.target()); - - int counter = 0; - for(; counter <2; ++counter )//1 or 2 rounds - { - if(edge.target() == s_it->source()) - { - result.push_back(s_it->target()); - break; - } - else if (edge.target() == s_it->target()) - { - result.push_back(s_it->source()); - break; - } - else - ++s_it; - } - if(counter > 1) //not exact, won't find the right inter anyway. - return Result_type(); - - segments.erase(s_it); - - s_it = segments.begin(); - if(edge.source() == s_it->target()) - { - result.push_back(s_it->source()); - } - else if(edge.source() == s_it->source()) - { - result.push_back(s_it->target()); - } - else - { - if(result.back() == s_it->target()) - { - result.push_back(s_it->source()); - } - else if(result.back() == s_it->source()) - { - result.push_back(s_it->target()); - } - } - return Result_type(std::forward >(result)); + std::list segs; + for(auto s : segments) + segs.push_back(s); + std::list tmp; + fill_points_list(segs, tmp); + std::vector res; + for( auto p : tmp) + res.push_back(p); + return Result_type(std::forward >(res)); } } break; diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Ray_3_intersections.h b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Ray_3_intersection.h similarity index 100% rename from Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Ray_3_intersections.h rename to Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Ray_3_intersection.h diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Segment_3_intersections.h b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Segment_3_intersection.h similarity index 100% rename from Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Segment_3_intersections.h rename to Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Segment_3_intersection.h diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Triangle_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Triangle_3_intersection.h new file mode 100644 index 00000000000..14e28980475 --- /dev/null +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Triangle_3_intersection.h @@ -0,0 +1,299 @@ +// Copyright (c) 2019 GeometryFactory(France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// +// +// Author(s) : Maxime Gimeno +// + + +#ifndef CGAL_INTERNAL_INTERSECTIONS_3_TETRAHEDRON_3_TRIANGLE_3_INTERSECTIONS_H +#define CGAL_INTERNAL_INTERSECTIONS_3_TETRAHEDRON_3_TRIANGLE_3_INTERSECTIONS_H + +#include +#include +#include +#include +#include +namespace CGAL { + +namespace Intersections { + +namespace internal { + +//Tetrahedron_3 Segment_3 +template +typename Intersection_traits::result_type +intersection( + const typename K::Tetrahedron_3 &tet, + const typename K::Triangle_3 &tr, + const K&) +{ + typedef typename Intersection_traits::result_type Result_type; + + typedef typename Intersection_traits::result_type Inter_type; + + typedef typename K::Segment_3 Segment_3; + typedef typename K::Point_3 Point_3; + typedef typename K::Triangle_3 Triangle_3; + typedef std::vector Poly; + + std::vector inside_points; + for(int i = 0; i< 3; ++i) + { + if(tet.has_on_bounded_side(tr.vertex(i)) + || tet.has_on_boundary(tr.vertex(i))) + inside_points.push_back(tr.vertex(i)); + } + switch(inside_points.size()) + { + case 0: + { + Inter_type intersections[4]; + std::vector segments; + std::vector seg_ids; + std::vector points; + for(std::size_t i = 0; i < 4; ++i) + { + const typename K::Triangle_3 triangle(tet.vertex((i+1)%4), + tet.vertex((i+2)%4), + tet.vertex((i+3)%4)); + intersections[i] = typename K::Intersect_3()(tr, triangle); + if(intersections[i]){ + //a face is inside the input tr + if(const Triangle_3* t = boost::get(&*intersections[i])) + { + Triangle_3 res = *t; + return Result_type(std::forward(res)); + } + //get segs and pts to construct poly + else if( const Segment_3* s + = boost::get(&*intersections[i])) + { + segments.push_back(*s); + seg_ids.push_back(i); + } + else if( const typename K::Point_3* p + = boost::get(&*intersections[i])) + { + points.push_back(*p); + } + //if poly : then the input is in a supporting plane of a face, return the poly. + else if( const Poly* p + = boost::get(&*intersections[i])) + { + Poly res = *p; + return Result_type(std::forward(res)); + } + } + } + if(segments.size() > 1) + { + std::vector filtered; + filter_segments(segments, filtered); + segments = filtered; + } + //if there are several segments, then we need to compute the polygone. + if(segments.size() > 1) + { + std::list tmp; + fill_segments_infos(segments,tmp, tr); + Poly res; + res.reserve(4); + for( auto p : tmp) + res.push_back(p); + return Result_type(std::forward(res)); + } + //else it must be adjacent to an vertex, so we return the point + else if(segments.size() == 1) + { + //adjacency to an edge, return resulting segment. + return Result_type(std::forward(segments.front())); + } + else + { + //no segment = adjacency to an vertex or an edge : return result point + return Result_type(std::forward(points.front())); + + } + } + break; + case 1: + case 2: + { + //tricky cases + Inter_type intersections[4]; + std::vector points; + std::vector segments; + for(std::size_t i = 0; i < 4; ++i) + { + const typename K::Triangle_3 triangle(tet.vertex((i+1)%4), + tet.vertex((i+2)%4), + tet.vertex((i+3)%4)); + intersections[i] = typename K::Intersect_3()(tr, triangle); + if(intersections[i]){ + if(const Triangle_3* t = boost::get(&*intersections[i])) + { + Triangle_3 res = *t; + return Result_type(std::forward(res)); + } + //get segs and pts to construct poly + else if( const Segment_3* s + = boost::get(&*intersections[i])) + { + segments.push_back(*s); + } + else if( const typename K::Point_3* p + = boost::get(&*intersections[i])) + { + points.push_back(*p); + } + //if poly : then the input is in a supporting plane of a face, return the poly. + else if( const Poly* p + = boost::get(&*intersections[i])) + { + Poly res = *p; + return Result_type(std::forward(res)); + } + } + } + if(segments.empty()) + { + //then there is only one point of contact. Return it: + return Result_type(std::forward(points.front())); + } + + if(segments.size() > 1) + { + std::vector filtered; + filter_segments(segments, filtered); + segments = filtered; + } + + switch(segments.size()) + { + case 1: + { + bool return_solo_seg = true; + //only one intersection, a triangle edge is one of the tet edges, and + //the 3rd point is outside. This is the only intersection. + for(auto p : inside_points) + { + if(!tet.has_on_boundary(p)) + { + return_solo_seg = false; + break; + } + } + if(return_solo_seg) + { + return Result_type(std::forward(segments.front())); + } + + if(inside_points.size() == 1) + { + Triangle_3 res(inside_points.front(), segments.front().source(), + segments.front().target()); + return Result_type(std::forward(res)); + } + else //size 2 + { + Poly res(4); + res[0] = inside_points.front(); + res[1] = inside_points.back(); + if((inside_points.front() - inside_points.back()) * + (segments.front().source() - segments.front().target()) > 0) + { + res[2] = segments.front().target(); + res[3] = segments.front().source(); + } + else + { + res[3] = segments.front().target(); + res[2] = segments.front().source(); + } + return Result_type(std::forward(res)); + } + } + break; + case 2: + case 3: + { + std::list segs; + for(auto s : segments) + segs.push_back(s); + std::list tmp; + fill_points_list(segs, tmp); + if(inside_points.size() == 1) + { + Poly res; + res.reserve(4); + res.push_back(inside_points.front()); + for( auto p : tmp) + res.push_back(p); + return Result_type(std::forward(res)); + } + else //size 2 + { + Poly res; + res.reserve(5); + if((inside_points.front() - inside_points.back()) * + (tmp.front() - tmp.back()) > 0) + res.push_back(inside_points.front()); + res.push_back(inside_points.back()); + for( auto p : tmp) + res.push_back(p); + return Result_type(std::forward(res)); + } + } + break; + default: + //3 faces max if a point or more are inside tetrahedron + break; + } + } + break; + + case 3: + { + //triangle entirely inside tetra : return input triangle + typename K::Triangle_3 res = tr; + return Result_type(std::forward(res)); + } + break; + default: + //never happens (only 3 pts in a tr) + break; + } +} + +template +typename Intersection_traits::result_type +intersection( + const typename K::Triangle_3 &pl, + const typename K::Tetrahedron_3 &tet, + const K& k) +{ + return intersection(tet, pl, k); +} + +}}} +#endif // CGAL_INTERNAL_INTERSECTIONS_3_TETRAHEDRON_3_TRIANGLE_3_INTERSECTIONS_H diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h new file mode 100644 index 00000000000..ced97166b57 --- /dev/null +++ b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h @@ -0,0 +1,246 @@ +#ifndef CGAL_INTERNAL_TETRAHEDRON_INTERSECTION_HELPERS_H +#define CGAL_INTERNAL_TETRAHEDRON_INTERSECTION_HELPERS_H + +#include +#include +#include + +namespace CGAL { + +namespace Intersections { + +namespace internal { + +template +void filter_segments(const std::vector& input, + std::vector& output) +{ + std::list tmp(input.begin(), input.end()); + + do + { + Segment s = tmp.back(); + tmp.pop_back(); + auto s_it = tmp.begin(); + for(; s_it != tmp.end();) + { + if(s == *s_it || s == s_it->opposite()) + { + s_it = tmp.erase(s_it); + } + else { + ++s_it; + } + } + output.push_back(s); + }while (!tmp.empty()); +} + +template +void fill_segments_infos(std::vector& segments, + std::list& points, const Triangle& input_tr) +{ + struct Wrapped_segment + { + Segment segment; + bool s_dangling; + bool t_dangling; + std::size_t s_neighbor; + std::size_t t_neighbor; + Wrapped_segment(const Segment& s) + :segment(s), s_dangling(true), + t_dangling(true){} + }; + + std::vector wrapped_segments; + + for(auto s:segments) + wrapped_segments.push_back(Wrapped_segment(s)); + + std::vector bis = segments; + for(int plouf = 0; plouf < bis.size()-1; ++plouf) + { + Segment s = bis.back(); + bis.pop_back(); + Wrapped_segment& super_s = wrapped_segments.back(); + if(!super_s.s_dangling && ! super_s.t_dangling) + continue; + for(std::size_t i = 0; i< bis.size(); ++i) + { + const Segment& s2 = bis[i]; + if(s2.target() == s.source()) + { + super_s.s_dangling = false; + super_s.s_neighbor = i; + //same i because we empty from the bottom + wrapped_segments[i].t_dangling = false; + wrapped_segments[i].t_neighbor = bis.size(); + } + else if(s2.target() == s.target()) + { + super_s.t_dangling = false; + super_s.t_neighbor = i; + wrapped_segments[i].s_dangling = false; + wrapped_segments[i].s_neighbor = bis.size(); + wrapped_segments[i].segment = wrapped_segments[i].segment.opposite(); //also orient the structure + + } + else if(s2.source() == s.source()) + { + super_s.s_dangling = false; + super_s.s_neighbor = i; + wrapped_segments[i].t_dangling = false; + wrapped_segments[i].t_neighbor = bis.size(); + wrapped_segments[i].segment = wrapped_segments[i].segment.opposite(); + } + else if(s2.source() == s.target()) + { + super_s.t_dangling = false; + super_s.t_neighbor = i; + wrapped_segments[i].s_dangling = false; + wrapped_segments[i].s_neighbor = bis.size(); + } + } + + //fill dangling extremities using triangle edges + if(super_s.s_dangling) + { + for(std::size_t e_id = 0; e_id < 3; ++e_id) + { + Segment edge(input_tr.vertex(e_id), input_tr.vertex(e_id+1)); + if(!edge.has_on(s.source())) + { + continue; + } + for(std::size_t i = 0; i< bis.size(); ++i) + { + if(edge.has_on(bis[i].source())) + { + super_s.s_dangling = false; + super_s.s_neighbor = i; + //same i because we empty from the bottom + wrapped_segments[i].t_dangling = false; + wrapped_segments[i].t_neighbor = bis.size(); + wrapped_segments[i].segment = wrapped_segments[i].segment.opposite(); + } + else if(edge.has_on(bis[i].target())) + { + super_s.s_dangling = false; + super_s.s_neighbor = i; + //same i because we empty from the bottom + wrapped_segments[i].t_dangling = false; + wrapped_segments[i].t_neighbor = bis.size(); + } + } + } + } + if(super_s.t_dangling) + { + for(std::size_t e_id = 0; e_id < 3; ++e_id) + { + Segment edge(input_tr.vertex(e_id), input_tr.vertex(e_id+1)); + if(!edge.has_on(s.target())) + { + continue; + } + for(std::size_t i = 0; i< bis.size(); ++i) + { + if(edge.has_on(bis[i].source())) + { + super_s.t_dangling = false; + super_s.t_neighbor = i; + //same i because we empty from the bottom + wrapped_segments[i].s_dangling = false; + wrapped_segments[i].s_neighbor = bis.size(); + } + else if(edge.has_on(bis[i].target())) + { + super_s.t_dangling = false; + super_s.t_neighbor = i; + //same i because we empty from the bottom + wrapped_segments[i].s_dangling = false; + wrapped_segments[i].s_neighbor = bis.size(); + wrapped_segments[i].segment = wrapped_segments[i].segment.opposite(); + } + } + } + } + + if(super_s.s_dangling || super_s.t_dangling) + { + std::cerr<<"Error. Kernel must have exact constructions to compute this intersection."< +void fill_points_list(std::list& segments, std::list& points) +{ + assert(segments.size() > 1); + //init : take seg.front = seg. + Segment seg = segments.front(); + segments.pop_front(); + //put source and target in points. + points.push_back(seg.source()); + points.push_back(seg.target()); + //find first seg with a point in common with seg.front = s2. + do{ + auto seg_it = segments.begin(); + bool found = false; + for(;seg_it != segments.end(); ++seg_it) + { + if(seg_it->source() == points.front()) + { + points.push_front(seg_it->target()); + found = true; + } + else if(seg_it->source() == points.back()) + { + points.push_back(seg_it->target()); + found = true; + } + else if(seg_it->target() == points.front()) + { + points.push_front(seg_it->source()); + found = true; + } + else if(seg_it->target() == points.back()) + { + points.push_back(seg_it->source()); + found = true; + } + if(found) + { + break; + } + } + if(!found) + { + std::cerr<<"Error. Kernel must have exact constructions to compute this intersection."< @@ -68,79 +68,78 @@ struct Test { template < typename Type > bool approx_equal_nt(const Type &t1, const Type &t2) { - if (t1 == t2) - return true; - if (CGAL::abs(t1 - t2) / (CGAL::max)(CGAL::abs(t1), CGAL::abs(t2)) < epsilon) - return true; - std::cout << " Approximate comparison failed between : " << t1 << " and " << t2 << "\n"; - return false; + if (t1 == t2) + return true; + if (CGAL::abs(t1 - t2) / (CGAL::max)(CGAL::abs(t1), CGAL::abs(t2)) < epsilon) + return true; + std::cout << " Approximate comparison failed between : " << t1 << " and " << t2 << "\n"; + return false; } template < typename Type > bool approx_equal(const Type&t1, const Type&t2) { - return t1 == t2; - // we need approx equal to check approx kernels, but maybe we should only test with exact kernels - // (approx kernels were useful before, when the text output was checked by diff ?) - // idea : test containment with intervals ? or use some "epsilon double"? - // I need to convert the text output to exact rationals in the source... - // Well, for now the current scheme works. + return t1 == t2; + // we need approx equal to check approx kernels, but maybe we should only test with exact kernels + // (approx kernels were useful before, when the text output was checked by diff ?) + // idea : test containment with intervals ? or use some "epsilon double"? + // I need to convert the text output to exact rationals in the source... + // Well, for now the current scheme works. } bool approx_equal(const P & p, const P & q) { - return approx_equal_nt(p.x(), q.x()) && - approx_equal_nt(p.y(), q.y()) && - approx_equal_nt(p.z(), q.z()); + return approx_equal_nt(p.x(), q.x()) && + approx_equal_nt(p.y(), q.y()) && + approx_equal_nt(p.z(), q.z()); } bool approx_equal(const S & p, const S & q) { - return approx_equal(p.source(), q.source()) && approx_equal(p.target(), q.target()); + return approx_equal(p.source(), q.source()) && approx_equal(p.target(), q.target()); } /* bool approx_equal(const Pol & p, const Pol & q) { - if (p.size() != q.size()) - return false; - for(typename Pol::const_iterator itp = p.begin(), itq = q.begin(); itp != p.end(); ++itp, ++itq) - if (!approx_equal(*itp, *itq)) - return false; - return true; + if (p.size() != q.size()) + return false; + for(typename Pol::const_iterator itp = p.begin(), itq = q.begin(); itp != p.end(); ++itp, ++itq) + if (!approx_equal(*itp, *itq)) + return false; + return true; } */ template < typename O1, typename O2> void check_no_intersection(const O1& o1, const O2& o2) { - assert(!CGAL::do_intersect(o1, o2)); - assert(!CGAL::do_intersect(o2, o1)); + assert(!CGAL::do_intersect(o1, o2)); + assert(!CGAL::do_intersect(o2, o1)); } template < typename Res, typename O1, typename O2 > void check_intersection(const O1& o1, const O2& o2) { - Res tmp; - assert(CGAL::do_intersect(o1, o2)); - assert(CGAL::assign(tmp, CGAL::intersection(o1, o2))); - assert(CGAL::do_intersect(o2, o1)); - assert(CGAL::assign(tmp, CGAL::intersection(o2, o1))); + Res tmp; + assert(CGAL::do_intersect(o1, o2)); + assert(CGAL::assign(tmp, CGAL::intersection(o1, o2))); + assert(CGAL::do_intersect(o2, o1)); + assert(CGAL::assign(tmp, CGAL::intersection(o2, o1))); } template < typename Res, typename O1, typename O2 > void check_intersection(const O1& o1, const O2& o2, const Res& result, bool do_opposite = true) { - Res tmp; - assert(CGAL::do_intersect(o1, o2)); - assert(CGAL::assign(tmp, CGAL::intersection(o1, o2))); - std::cout< (pl(0, 0, 1,-1), L(p( 1, 1, 1), p( 2, 3, 1))); check_no_intersection (pl(0, 0, 1,-2), L(p( 1, 1, 1), p( 2, 3, 1))); check_intersection (pl(1, 0, 1, 3), L(p( 1, 1, 1), p( 2, 3, -1)), - P( 6, 11, -9)); + P( 6, 11, -9)); check_intersection (pl(1, 2, 4, 7), L(p( 1, 1, 1), p( 2, 3, 4)), - P( 0.176471, -0.647059, -1.47059)); + P( 0.176471, -0.647059, -1.47059)); } void Pl_Pl() @@ -292,35 +291,35 @@ struct Test { { std::cout << "Ray - Iso_cuboid\n"; check_intersection (R(p( -3, 1, -5), p( -2, -5, -7)), Cub(p( -7, -8, -9), p( -1, 2, -4)), - S(P(-3, 1, -5), P(-1.5, -8, -8))); + S(P(-3, 1, -5), P(-1.5, -8, -8))); check_intersection (R(p( 0, 0, 3), p( 1, 2, 3)), Cub(p( 1, 1, 1), p( 3, 5, 8)), - S(P( 1, 2, 3), P( 2.5, 5, 3))); + S(P( 1, 2, 3), P( 2.5, 5, 3))); check_intersection (R(p( 1, 0, 0), p( 1, 2, 3)), Cub(p( 1, 1, 1), p( 3, 5, 8)), - S(P( 1, 1,1.5), P( 1, 5,7.5))); + S(P( 1, 1,1.5), P( 1, 5,7.5))); check_intersection (R(p( 0, 2, 0), p( 1, 2, 3)), Cub(p( 2, 1, 1), p( 3, 5, 8)), - S(P( 2, 2, 6), P(2.66667,2, 8))); + S(P( 2, 2, 6), P(2.66667,2, 8))); check_no_intersection (R(p( 0, 0, 0), p( 1, 0, 3)), Cub(p( 2, 1, 1), p( 3, 5, 8))); check_no_intersection (R(p( 4, 0, 0), p( 4, 1, 3)), Cub(p( 2, 1, 1), p( 3, 5, 8))); check_intersection (R(p( 0, 0, 0), p( 1, 2, 3)), Cub(p( 1, 1, 1), p( 3, 5, 8)), - S(P( 1, 2, 3), P(2.5, 5, 7.5))); + S(P( 1, 2, 3), P(2.5, 5, 7.5))); } void S_Cub() { std::cout << "Segment - Iso_cuboid\n"; check_intersection (S(p( -3, 1, -5), p( -2, -5, -7)), Cub(p( -7, -8, -9), p( -1, 2, -4)), - S(P(-3, 1, -5), P( -2, -5, -7))); + S(P(-3, 1, -5), P( -2, -5, -7))); check_intersection (S(p( 0, 0, 3), p( 1, 2, 3)), Cub(p( 1, 1, 1), p( 3, 5, 8)), - P( 1, 2, 3)); + P( 1, 2, 3)); check_intersection (S(p( 1, 0, 0), p( 1, 2, 3)), Cub(p( 1, 1, 1), p( 3, 5, 8)), - S(P( 1, 1, 1.5), P( 1, 2, 3))); + S(P( 1, 1, 1.5), P( 1, 2, 3))); check_no_intersection (S(p( 0, 2, 0), p( 1, 2, 3)), Cub(p( 2, 1, 1), p( 3, 5, 8))); check_no_intersection (S(p( 0, 0, 0), p( 1, 0, 3)), Cub(p( 2, 1, 1), p( 3, 5, 8))); check_no_intersection (S(p( 4, 0, 0), p( 4, 1, 3)), Cub(p( 2, 1, 1), p( 3, 5, 8))); check_intersection (S(p( 0, 0, 0), p( 1, 2, 3)), Cub(p( 1, 1, 1), p( 3, 5, 8)), - P( 1, 2, 3)); + P( 1, 2, 3)); } - + void Pl_Tr() { std::cout << "Plane - Triangle\n"; @@ -329,7 +328,7 @@ struct Test { check_intersection ( Pl(P(0,0,0),P(12,0,0),P(0,11,0)),Tr(P(0,0,0),P(1,0,0),P(0,1,1)),S(P(0,0,0),P(1,0,0)),true); check_intersection ( Pl(P(0,0,0),P(12,0,0),P(0,11,0)),Tr(P(1,0,-1),P(-1,0,-1),P(0,0,1)),S(P(0.5,0,0),P(-0.5,0,0)),true); } - + void S_L() { std::cout << "Segment - Line\n"; @@ -337,7 +336,7 @@ struct Test { check_intersection ( S(P(0,0,0),P(12,0,0)),L(P(0,1,0),P(0,-1,0)),P(0,0,0),true); check_intersection ( S(P(-12,0,0),P(12,0,0)),L(P(0,1,0),P(0,-1,0)),P(0,0,0),true); } - + void R_L() { std::cout << "Ray - Line\n"; @@ -395,11 +394,11 @@ struct Test { check_no_intersection (R(P(0,0,0),P(1,0,0)),R(P(0,-1,0),P(0,-2,0))); check_no_intersection (R(P(0,0,0),P(1,0,0)),R(P(0,1,0),P(0,2,0))); } - + void Bbox_L(){ std::cout << "Bbox - Line\n"; Bbox box(-1,-1,-1,1,1,1); - + //not in x,y,z slab check_no_intersection (box,L(P(2,0,0),P(2,0,0.5))); check_no_intersection (box,L(P(0,2,0),P(0,2,0.5))); @@ -411,41 +410,41 @@ struct Test { //in each slab, time not matching //xz check_no_intersection (box,L(P(-8,0,0),P(0,0, 8))); - check_no_intersection (box,L(P( 8,0,0),P(0,0, 8))); + check_no_intersection (box,L(P( 8,0,0),P(0,0, 8))); check_no_intersection (box,L(P(-8,0,0),P(0,0,-8))); check_no_intersection (box,L(P( 8,0,0),P(0,0,-8))); //yz check_no_intersection (box,L(P(0,-8,0),P(0,0, 8))); - check_no_intersection (box,L(P(0, 8,0),P(0,0, 8))); + check_no_intersection (box,L(P(0, 8,0),P(0,0, 8))); check_no_intersection (box,L(P(0,-8,0),P(0,0,-8))); check_no_intersection (box,L(P(0, 8,0),P(0,0,-8))); //xy check_no_intersection (box,L(P(0,-8,0),P(8,0,0))); - check_no_intersection (box,L(P(0, 8,0),P(8,0,0))); + check_no_intersection (box,L(P(0, 8,0),P(8,0,0))); check_no_intersection (box,L(P(0,-8,0),P(-8,0,0))); check_no_intersection (box,L(P(0, 8,0),P(-8,0,0))); //Intersecting //xz check_intersection (box,L(P(-0.5,0,0),P(0,0, 0.5))); - check_intersection (box,L(P( 0.5,0,0),P(0,0, 0.5))); + check_intersection (box,L(P( 0.5,0,0),P(0,0, 0.5))); check_intersection (box,L(P(-0.5,0,0),P(0,0,-0.5))); check_intersection (box,L(P( 0.5,0,0),P(0,0,-0.5))); //yz check_intersection (box,L(P(0,-0.5,0),P(0,0, 0.5))); - check_intersection (box,L(P(0, 0.5,0),P(0,0, 0.5))); + check_intersection (box,L(P(0, 0.5,0),P(0,0, 0.5))); check_intersection (box,L(P(0,-0.5,0),P(0,0,-0.5))); check_intersection (box,L(P(0, 0.5,0),P(0,0,-0.5))); //xy check_intersection (box,L(P(0,-0.5,0),P(0.5,0,0))); - check_intersection (box,L(P(0, 0.5,0),P(0.5,0,0))); + check_intersection (box,L(P(0, 0.5,0),P(0.5,0,0))); check_intersection (box,L(P(0,-0.5,0),P(-0.5,0,0))); check_intersection (box,L(P(0, 0.5,0),P(-0.5,0,0))); } - + void Bbox_R(){ std::cout << "Bbox - Ray\n"; Bbox box(-1,-1,-1,1,1,1); - + //not in x,y,z slab check_no_intersection (box,R(P(2,0,0),P(2,0,0.5))); check_no_intersection (box,R(P(0,2,0),P(0,2,0.5))); @@ -457,33 +456,33 @@ struct Test { //in each slab, time not matching //xz check_no_intersection (box,R(P(-8,0,0),P(0,0, 8))); - check_no_intersection (box,R(P( 8,0,0),P(0,0, 8))); + check_no_intersection (box,R(P( 8,0,0),P(0,0, 8))); check_no_intersection (box,R(P(-8,0,0),P(0,0,-8))); check_no_intersection (box,R(P( 8,0,0),P(0,0,-8))); //yz check_no_intersection (box,R(P(0,-8,0),P(0,0, 8))); - check_no_intersection (box,R(P(0, 8,0),P(0,0, 8))); + check_no_intersection (box,R(P(0, 8,0),P(0,0, 8))); check_no_intersection (box,R(P(0,-8,0),P(0,0,-8))); check_no_intersection (box,R(P(0, 8,0),P(0,0,-8))); //xy check_no_intersection (box,R(P(0,-8,0),P(8,0,0))); - check_no_intersection (box,R(P(0, 8,0),P(8,0,0))); + check_no_intersection (box,R(P(0, 8,0),P(8,0,0))); check_no_intersection (box,R(P(0,-8,0),P(-8,0,0))); check_no_intersection (box,R(P(0, 8,0),P(-8,0,0))); //Intersecting //xz check_intersection (box,R(P(-0.5,0,0),P(0,0, 0.5))); - check_intersection (box,R(P( 0.5,0,0),P(0,0, 0.5))); + check_intersection (box,R(P( 0.5,0,0),P(0,0, 0.5))); check_intersection (box,R(P(-0.5,0,0),P(0,0,-0.5))); check_intersection (box,R(P( 0.5,0,0),P(0,0,-0.5))); //yz check_intersection (box,R(P(0,-0.5,0),P(0,0, 0.5))); - check_intersection (box,R(P(0, 0.5,0),P(0,0, 0.5))); + check_intersection (box,R(P(0, 0.5,0),P(0,0, 0.5))); check_intersection (box,R(P(0,-0.5,0),P(0,0,-0.5))); check_intersection (box,R(P(0, 0.5,0),P(0,0,-0.5))); //xy check_intersection (box,R(P(0,-0.5,0),P(0.5,0,0))); - check_intersection (box,R(P(0, 0.5,0),P(0.5,0,0))); + check_intersection (box,R(P(0, 0.5,0),P(0.5,0,0))); check_intersection (box,R(P(0,-0.5,0),P(-0.5,0,0))); check_intersection (box,R(P(0, 0.5,0),P(-0.5,0,0))); } @@ -566,85 +565,400 @@ struct Test { << do_intersect_counter << "\n"; } // end function Bbox_Tr - void Tet_L() + void Tet_L(bool is_exact) { std::cout << "Tetrahedron_3 - Line_3\n"; Tet tet(P(0,0,0), P(0,1,0), P(1,0,0), P(0,0,1)); - check_no_intersection (tet, L(P(5,0,0), P(5,1,0))); - check_intersection (tet, L(P(0,2,0), P(0,3,0)), S(P(0,0,0), P(0,1,0))); - check_intersection (tet, L(P(0,1,0), P(0.25,0,0.25)), S(P(0,1,0), P(0.25,0,0.25))); - check_intersection (tet, L(P(1,1,0), P(-1,1,0)), P(0,1,0)); + if(is_exact) + { + check_no_intersection (tet, L(P(5,0,0), P(5,1,0))); + check_intersection (tet, L(P(0,2,0), P(0,3,0)), S(P(0,0,0), P(0,1,0))); + check_intersection (tet, L(P(0,1,0), P(0.25,0,0.25)), S(P(0,1,0), P(0.25,0,0.25))); + check_intersection (tet, L(P(1,1,0), P(-1,1,0)), P(0,1,0)); + } } - void Tet_S() + void Tet_S(bool is_exact) { std::cout << "Tetrahedron_3 - Segment_3\n"; Tet tet(P(0,0,0), P(0,1,0), P(1,0,0), P(0,0,1)); - check_no_intersection (tet, S(P(5,0,0), P(5,1,0))); - check_intersection (tet, S(P(0,2,0), P(0,-2,0)), S(P(0,1,0), P(0,0,0))); - check_intersection (tet, S(P(0,1,0), P(0.25,0,0.25)), S(P(0,1,0), P(0.25,0,0.25))); - check_intersection (tet, S(P(2,1,0), P(-2,1,0)), P(0,1,0)); + if(is_exact) + { + check_no_intersection (tet, S(P(5,0,0), P(5,1,0))); + check_intersection (tet, S(P(0,2,0), P(0,-2,0)), S(P(0,1,0), P(0,0,0))); + check_intersection (tet, S(P(0,1,0), P(0.25,0,0.25)), S(P(0,1,0), P(0.25,0,0.25))); + check_intersection (tet, S(P(2,1,0), P(-2,1,0)), P(0,1,0)); - check_intersection (tet, S(P(0.1,0.1,0.1), P(0.2,0.2,0.2)), S(P(0.1,0.1,0.1), P(0.2,0.2,0.2))); - typename K::FT coord = 1.0/3.0; - check_intersection (tet, S(P(0.25,0.25,0.25), P(2,2,2)), S(P(0.25,0.25,0.25), P(coord, coord, coord))); + check_intersection (tet, S(P(0.1,0.1,0.1), P(0.2,0.2,0.2)), S(P(0.1,0.1,0.1), P(0.2,0.2,0.2))); + typename K::FT coord = 1.0/3.0; + check_intersection (tet, S(P(0.25,0.25,0.25), P(2,2,2)), S(P(0.25,0.25,0.25), P(coord, coord, coord))); + } + else + { + CGAL::intersection (tet, S(P(0,2,0), P(0,-2,0))); + CGAL::intersection (tet, S(P(0,1,0), P(0.25,0,0.25))); + CGAL::intersection (tet, S(P(2,1,0), P(-2,1,0))); + CGAL::intersection (tet, S(P(0.1,0.1,0.1), P(0.2,0.2,0.2))); + CGAL::intersection (tet, S(P(0.25,0.25,0.25), P(2,2,2))); + } } - void Tet_R() + void Tet_R(bool is_exact) { std::cout << "Tetrahedron_3 - Ray_3\n"; Tet tet(P(0,0,0), P(0,1,0), P(1,0,0), P(0,0,1)); - check_no_intersection (tet, R(P(5,0,0), P(5,1,0))); + if(is_exact) + { + check_no_intersection (tet, R(P(5,0,0), P(5,1,0))); - check_intersection (tet, R(P(0,2,0), P(0,-2,0)), S(P(0,1,0), P(0,0,0))); - check_intersection (tet, R(P(0,1,0), P(0.25,0,0.25)), S(P(0,1,0), P(0.25,0,0.25))); - check_intersection (tet, R(P(2,1,0), P(-2,1,0)), P(0,1,0)); + check_intersection (tet, R(P(0,2,0), P(0,-2,0)), S(P(0,1,0), P(0,0,0))); + check_intersection (tet, R(P(0,1,0), P(0.25,0,0.25)), S(P(0,1,0), P(0.25,0,0.25))); + check_intersection (tet, R(P(2,1,0), P(-2,1,0)), P(0,1,0)); - typename K::FT coord = 1.0/3.0; - check_intersection (tet, R(P(0.1,0.1,0.1), P(0.2,0.2,0.2)), S(P(0.1,0.1,0.1), P(coord, coord, coord))); - check_intersection (tet, R(P(0.25,0.25,0.25), P(2,2,2)), S(P(0.25,0.25,0.25), P(coord, coord, coord))); + typename K::FT coord = 1.0/3.0; + check_intersection (tet, R(P(0.1,0.1,0.1), P(0.2,0.2,0.2)), S(P(0.1,0.1,0.1), P(coord, coord, coord))); + check_intersection (tet, R(P(0.25,0.25,0.25), P(2,2,2)), S(P(0.25,0.25,0.25), P(coord, coord, coord))); + } + else + { + CGAL::intersection (tet, R(P(0,2,0), P(0,-2,0))); + CGAL::intersection (tet, R(P(0,1,0), P(0.25,0,0.25))); + CGAL::intersection (tet, R(P(2,1,0), P(-2,1,0))); + CGAL::intersection (tet, R(P(0.1,0.1,0.1), P(0.2,0.2,0.2))); + CGAL::intersection (tet, R(P(0.25,0.25,0.25), P(2,2,2))); + } } - void Tet_Pl() + void Tet_Pl(bool is_exact) { std::cout << "Tetrahedron_3 - Plane_3\n"; Tet tet(P(0,0,0), P(0,1,0), P(1,0,0), P(0,0,1)); - check_no_intersection (tet, Pl(P(2,0,0), - P(2,1,0), - P(2,0,1))); + if(is_exact) + { + check_no_intersection (tet, Pl(P(2,0,0), + P(2,1,0), + P(2,0,1))); - check_intersection (tet, Pl(P(0,2,0), P(0,0,0), P(0,0,1)), - Tr(P(0,0,0), P(0,1,0), P(0,0,1))); + check_intersection (tet, Pl(P(0,2,0), P(0,0,0), P(0,0,1)), + Tr(P(0,0,0), P(0,1,0), P(0,0,1))); - check_intersection (tet, Pl(P(0,1,0), P(1,0,0), P(0.5,0,-0.5)), - S(P(0,1,0), P(1,0,0))); + check_intersection (tet, Pl(P(0,1,0), P(1,0,0), P(0.5,0,-0.5)), + S(P(0,1,0), P(1,0,0))); - check_intersection (tet, Pl(P(-1,1,12), P(0,1,-50), P(0.5,1,-0.5)), - P(0,1,0)); + check_intersection (tet, Pl(P(-1,1,12), P(0,1,-50), P(0.5,1,-0.5)), + P(0,1,0)); - check_intersection (tet, Pl(P(0,0.5,0), P(1,0.5,-5), P(0.5,0.5,0.5)), - Tr(P(0.5,0.5,0), P(0,0.5,0), P(0,0.5,0.5))); - Pl pl(P(0,0.9,0), P(0.9,0,0), P(0.9,0.01,0.06)); + check_intersection (tet, Pl(P(0,0.5,0), P(1,0.5,-5), P(0.5,0.5,0.5)), + Tr(P(0.5,0.5,0), P(0,0.5,0), P(0,0.5,0.5))); + Pl pl(P(0,0.9,0), P(0.9,0,0), P(0.9,0.01,0.06)); + + typedef typename CGAL::Intersection_traits::result_type Res; + + + //Don't have the right values to test further. + Res res = CGAL::intersection (tet, pl); + + const std::vector

* poly = boost::get >(&*res); + CGAL_assertion(poly != nullptr); + CGAL_assertion(poly->size() == 4); + } + else + { + CGAL::intersection (tet, Pl(P(0,2,0), P(0,0,0), P(0,0,1))); + CGAL::intersection (tet, Pl(P(0,1,0), P(1,0,0), P(0.5,0,-0.5))); + CGAL::intersection (tet, Pl(P(-1,1,12), P(0,1,-50), P(0.5,1,-0.5))); + CGAL::intersection (tet, Pl(P(0,0.5,0), P(1,0.5,-5), P(0.5,0.5,0.5))); + } + + } + + void Tet_Tr(bool is_exact) + { + std::cout << "Tetrahedron_3 - Triangle_3\n"; typedef typename CGAL::Intersection_traits::result_type Res; - assert(CGAL::do_intersect(tet, pl)); - //Don't have the right values to test further. + typename K::Triangle_3>::result_type Res; + + Tet tet(P(0,0,0), P(0,1,0), P(1,0,0), P(0,0,1)); + if(is_exact) + { + check_no_intersection (tet, Tr(P(2,0,0), + P(2,1,0), + P(2,0,1))); + + //tr inside a face + check_intersection (tet, Tr(P(0,0.9,0), P(0,0.1,0), P(0,0,0.9)), + Tr(P(0,0.9,0), P(0,0.1,0), P(0,0,0.9))); + //face inside tr + check_intersection (tet, Tr(P(0,2,0), P(0,-2,0), P(0,0,2)), + Tr(P(0,0,1), P(0,0,0), P(0,1,0))); + + Tr tr(P(-2,2,0), P(2,2,0), P(0.25,0.25,0)); + + Res res = CGAL::intersection(tet, tr); + const std::vector

* poly = boost::get >(&*res); + CGAL_assertion(poly != nullptr); + CGAL_assertion(poly->size() == 4); + for(auto p : *poly) + { + CGAL_assertion(tet.has_on_boundary(p) && tr.has_on(p)); + } + + //only one edge intersecting + check_intersection (tet, Tr(P(-2, 0.5, 0.5), P(-2,0.75,1), P(1.5, 0.5, 0.5)), + P(0,0.5,0.5)); + + + //edge shared, 3rd point outside + check_intersection (tet, Tr(P(0,1,0), P(1,0,0), P(0.5,0,-100)), + S(P(0,1,0), P(1,0,0))); + + //shared edge, 3rd point inside + check_intersection (tet, Tr(P(0,1,0), P(1,0,0), P(0.25,0.25,0.25)), + Tr(P(0,1,0), P(1,0,0), P(0.25,0.25,0.25))); + + //tr adjacent to a vertex, outside + check_intersection (tet, Tr(P(-1,1,12), P(0,1,-50), P(0.5,1,-0.5)), + P(0,1,0)); + + //tr adjacent to an edge, outside + check_intersection (tet, Tr(P(-0.6, 1, 0.6), + P(0.5, 1.20, -0.5), + P(0, -0.5, 0)), + S(P(0,0,0), P(0,1,0))); + + + //tr share a vertex, inside + check_intersection (tet, Tr(P(0,1,0), P(0.1,0.1,0), P(0.5,0.1,0)), + Tr(P(0,1,0), P(0.1,0.1,0), P(0.5,0.1,0))); + + //tr edge adjacent to a vertex + check_intersection (tet, Tr(P(-1,1,0), P(3,1,0), P(0,3,0)), + P(0,1,0)); + + //tr vertex adjacent to a vertex + check_intersection (tet, Tr(P(0,1,0), P(3,1,0), P(0,3,0)), + P(0,1,0)); + + + //traversing triangles + tr = Tr(P(-2, 0.5, 0.25), + P(-2, 0.75, 0.6), + P(1.5, 0.5, 0.25)); + + res = CGAL::intersection(tet, tr); + + + std::vector

* inter = boost::get >(&*res); + CGAL_assertion(inter != nullptr); + CGAL_assertion(inter->size() == 4); + for(auto p : *inter) + { + CGAL_assertion(tet.has_on_boundary(p) && tr.has_on(p)); + } + + tr = Tr(P(-2, 0.25, 0), + P(-2, 0.75, 0), + P(1.5, 0.5, 0)); + + res = CGAL::intersection(tet, tr); + + + inter = boost::get >(&*res); + CGAL_assertion(inter != nullptr); + CGAL_assertion(inter->size() == 4); + for(auto p : *inter) + { + CGAL_assertion(tet.has_on_boundary(p) && tr.has_on(p)); + } + + tr = Tr(P(0.2, 0.15, 0.3), + P(-2, 0.6, 0.15), + P(-2, 0.12, 0.15)); + + res = CGAL::intersection(tet, tr); + Tr* res_tr = boost::get(&*res); + CGAL_assertion(res_tr != nullptr); + + tr = Tr(P(0.2, 0.15, 0.3), + P(-1, 0.15, -2), + P(-1, 0.15, 2)); + + res = CGAL::intersection(tet, tr); + + + inter = boost::get >(&*res); + CGAL_assertion(inter != nullptr); + CGAL_assertion(inter->size() == 4); + + tr = Tr(P(0.45, 0.20, 0.1), + P(0.1, 0.20, 0.5), + P(-0.5, 0.25, -0.5)); + + res = CGAL::intersection(tet, tr); + + + inter = boost::get >(&*res); + CGAL_assertion(inter != nullptr); + CGAL_assertion(inter->size() == 4); + + for(auto p : *inter) + { + CGAL_assertion( + (tet.has_on_bounded_side(p) || tet.has_on_boundary(p)) + && tr.has_on(p)); + } + + //tr share a vertex, through + tr = Tr(P(0,1,0), P(0.1,0.1,0), P(0.9,0.1,0)); + res = CGAL::intersection(tet, tr); + res_tr = boost::get(&*res); + CGAL_assertion(res_tr != nullptr); + + + tr = Tr(P(0.1, 0.5, 0.1), P(0.3,0.1,0.1), P(4,0.3,0.9)); + res = CGAL::intersection(tet, tr); + inter = boost::get >(&*res); + CGAL_assertion(inter != nullptr); + CGAL_assertion(inter->size() == 4); + } + else + { + //tr inside a face + CGAL::intersection(tet, Tr(P(0,0.9,0), P(0,0.1,0), P(0,0,0.9))); + //face inside tr + CGAL::intersection(tet, Tr(P(0,2,0), P(0,-2,0), P(0,0,2))); + + //only one edge intersecting + CGAL::intersection(tet, Tr(P(-2, 0.5, 0.5), P(-2,0.75,1), P(1.5, 0.5, 0.5))); + + //edge shared, 3rd point outside + CGAL::intersection(tet, Tr(P(0,1,0), P(1,0,0), P(0.5,0,-100))); + + //shared edge, 3rd point inside + CGAL::intersection(tet, Tr(P(0,1,0), P(1,0,0), P(0.25,0.25,0.25))); + + //tr adjacent to a vertex, outside + CGAL::intersection(tet, Tr(P(-1,1,12), P(0,1,-50), P(0.5,1,-0.5))); + + //tr share a vertex, inside + CGAL::intersection(tet, Tr(P(0,1,0), P(0.1,0.1,0), P(0.5,0.1,0))); + + //tr edge adjacent to a vertex + CGAL::intersection(tet, Tr(P(-1,1,0), P(3,1,0), P(0,3,0))); + + //tr vertex adjacent to a vertex + CGAL::intersection(tet, Tr(P(0,1,0), P(3,1,0), P(0,3,0))); + + typedef typename CGAL::Intersection_traits::result_type Res; + //traversing triangles + Tr tr(P(-2, 0.5, 0.25), + P(-2, 0.75, 0.6), + P(1.5, 0.5, 0.25)); + + Res res = CGAL::intersection(tet, tr); + + //tr share a vertex, through + tr = Tr(P(0,1,0), P(0.1,0.1,0), P(0.9,0.1,0)); + res = CGAL::intersection(tet, tr); + } } + void Pl_Cub(bool is_exact) + { + std::cout << "Plane_3 - Cuboid_3\n"; + + Cub cub(P(1,1,1), P(2,2,2)); + + if(is_exact) + { + check_no_intersection (cub, Pl(P(3,0,0), + P(3,1,0), + P(3,0,1))); + + //edge + check_intersection (cub, Pl(P(1,1,1), P(1,2,1), P(1.5,0,0)), + S(P(1,2,1), P(1,1,1))); + //face + typedef typename CGAL::Intersection_traits::result_type Res; + Res res = CGAL::intersection(cub, Pl(P(1,1,1), P(1,2,1), P(1,2,2))); + + const std::vector

* poly = boost::get >(&*res); + CGAL_assertion(poly != nullptr); + CGAL_assertion(poly->size() == 4); + for(auto p : *poly) + { + CGAL_assertion(p.x() == 1); + } + res = CGAL::intersection(cub, Pl(P(1,1,1), P(1,2,1), P(2,2,2))); + poly = boost::get >(&*res); + CGAL_assertion(poly != nullptr); + CGAL_assertion(poly->size() == 4); + for(auto p : *poly) + { + CGAL_assertion(cub.has_on_boundary(p)); + } + //vertex + check_intersection (cub, Pl(0.5, -0.5, -0.5, 0), + P(2,1,1)); + //triangle + + check_intersection (cub, Pl(P(2, 1.66, 2), + P(1.66,2,2), + P(2,2,1.66)), + Tr(P(2, 1.66, 2), + P(1.66,2,2), + P(2,2,1.66))); + //random + Pl pl(0.265189, 0.902464, 0.33946, -2.47551); + res = CGAL::intersection(cub, pl); + poly = boost::get >(&*res); + CGAL_assertion(poly != nullptr); + CGAL_assertion(poly->size() == 5); + for(auto p : *poly) + { + CGAL_assertion(pl.has_on(p) && cub.has_on_boundary(p)); + } + } + else + { + CGAL::intersection(cub, Pl(P(1,1,1), P(1,2,1), P(1.5,0,0))); + //face + typedef typename CGAL::Intersection_traits::result_type Res; + Res res = CGAL::intersection(cub, Pl(P(1,1,1), P(1,2,1), P(1,2,2))); + res = CGAL::intersection(cub, Pl(P(1,1,1), P(1,2,1), P(2,2,2))); + CGAL::intersection (cub, Pl(0.5, -0.5, -0.5, 0)); + CGAL::intersection (cub, Pl(P(2, 1.66, 2), + P(1.66,2,2), + P(2,2,1.66))); + Pl pl(0.265189, 0.902464, 0.33946, -2.47551); + res = CGAL::intersection(cub, pl); + } + } + + void run(bool is_exact = false) { std::cout << "3D Intersection tests\n"; + /* P_do_intersect(); - /* Cub_Cub(); + Cub_Cub(); L_Cub(); Pl_L(); Pl_Pl(); @@ -658,12 +972,15 @@ struct Test { R_L(); R_S(); R_R();*/ - if(is_exact){ - Tet_L(); - Tet_S(); - Tet_R(); - Tet_Pl(); - } + + //If not exact, only check that it doesn't crash{ + //Tet_L(is_exact); + //Tet_S(is_exact); + //Tet_R(is_exact); + //Tet_Pl(is_exact); + Tet_Tr(is_exact); + // Pl_Cub(is_exact); + //} /* Bbox_L(); Bbox_R(); @@ -678,6 +995,6 @@ int main() Test< CGAL::Simple_cartesian >().run(); Test< CGAL::Homogeneous >().run(); Test< CGAL::Epeck >().run(true); - // TODO : test more kernels. + // TODO : test more kernels. } From c391e0e87632aa68f44173ac41b82bf12e55a6dc Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 12 Jun 2019 15:42:42 +0200 Subject: [PATCH 024/141] add Cub_tr as a Lazy implementation. Remains only Bbo intersections for the 3D --- .../include/CGAL/Intersection_traits_3.h | 18 ++ .../Intersections_3/Iso_cuboid_3_Triangle_3.h | 4 +- .../Iso_cuboid_3_Triangle_3_intersection.h | 212 ++++++++++++++++++ .../Intersections_3/test_intersections_3.cpp | 101 +++++++-- 4 files changed, 317 insertions(+), 18 deletions(-) create mode 100644 Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Triangle_3_intersection.h diff --git a/Intersections_3/include/CGAL/Intersection_traits_3.h b/Intersections_3/include/CGAL/Intersection_traits_3.h index ac9513417f8..bb843288f1d 100644 --- a/Intersections_3/include/CGAL/Intersection_traits_3.h +++ b/Intersections_3/include/CGAL/Intersection_traits_3.h @@ -207,6 +207,24 @@ struct Intersection_traits { typedef typename boost::optional< variant_type > result_type; }; +// Iso_cuboid_3 Triangle_3, variant of 4 +template +struct Intersection_traits { + typedef typename + boost::variant< typename K::Point_3, typename K::Segment_3, + typename K::Triangle_3, std::vector > variant_type; + + typedef typename boost::optional< variant_type > result_type; +}; + +template +struct Intersection_traits { + typedef typename + boost::variant< typename K::Point_3, typename K::Segment_3, + typename K::Triangle_3, std::vector > variant_type; + + typedef typename boost::optional< variant_type > result_type; +}; // Point_3 Line_3, variant of one diff --git a/Intersections_3/include/CGAL/Intersections_3/Iso_cuboid_3_Triangle_3.h b/Intersections_3/include/CGAL/Intersections_3/Iso_cuboid_3_Triangle_3.h index 9c0e6ac71e2..9f56eece4bf 100644 --- a/Intersections_3/include/CGAL/Intersections_3/Iso_cuboid_3_Triangle_3.h +++ b/Intersections_3/include/CGAL/Intersections_3/Iso_cuboid_3_Triangle_3.h @@ -27,9 +27,11 @@ #include #include +#include namespace CGAL { - CGAL_DO_INTERSECT_FUNCTION(Iso_cuboid_3,Triangle_3, 3) + CGAL_DO_INTERSECT_FUNCTION(Iso_cuboid_3, Triangle_3, 3) + CGAL_INTERSECTION_FUNCTION(Iso_cuboid_3, Triangle_3, 3) } #endif // CGAL_INTERSECTIONS_3_BBOX_3_TRIANGLE_3_H diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Triangle_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Triangle_3_intersection.h new file mode 100644 index 00000000000..a04a1978908 --- /dev/null +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Triangle_3_intersection.h @@ -0,0 +1,212 @@ +// Copyright (c) 2019 GeometryFactory(France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// +// +// Author(s) : Maxime Gimeno +// + +#ifndef CGAL_INTERSECTIONS_3_INTERNAL_ISO_CUBOID_3_TRIANGLE_3_INTERSECTION_H +#define CGAL_INTERSECTIONS_3_INTERNAL_ISO_CUBOID_3_TRIANGLE_3_INTERSECTION_H + +#include +#include + +#include +#include + +namespace CGAL { + +namespace Intersections { + +namespace internal { + +//only work for convex polygons, but in here that's always the case +template +void clip_poly_halfspace( + const std::vector& input, + const typename K::Plane_3& pl, + std::vector& output) +{ + if(input.empty()) + return; + + typedef typename K::Point_3 Point; + typedef typename K::Plane_3 Plane; + typedef typename K::Segment_3 S; + + typedef typename Intersection_traits, + CGAL::Segment_3 >::result_type SP_type; + + std::list p_list(input.begin(), input.end()); + auto it = p_list.begin(); + //corefine with plane. + while(it != p_list.end()) + { + Point p = *it; + ++it; + if(it == p_list.end()) + break; + if(do_intersect(S(p, *it), pl)) + { + SP_type inter = typename K::Intersect_3()(S(p, *it), pl); + if(inter) + { + Point* p_inter = boost::get(&*inter); + if(p_inter + && *p_inter != p + && *p_inter != *it) + p_list.insert(it, *p_inter); + } + } + } + + if(input.size() >2) + { + Point p2(p_list.front()), + p1(p_list.back()); + S seg(p1, p2); + if(do_intersect(seg, pl)) + { + SP_type inter = typename K::Intersect_3()(seg, pl); + if(inter) + { + Point* p_inter = boost::get(&*inter); + if(p_inter + && *p_inter != p1 + && *p_inter != p2) + p_list.push_back(*p_inter); + } + } + } + //remove all points on positive side + + for(auto p_it = p_list.begin(); + p_it != p_list.end();) + { + if(pl.has_on_positive_side(*p_it)) + p_it = p_list.erase(p_it); + else + ++p_it; + } + for(auto p : p_list) + output.push_back(p); + +} + +template +typename Intersection_traits::result_type +intersection( + const typename K::Iso_cuboid_3 &cub, + const typename K::Triangle_3 &tr, + const K&) +{ + typedef typename K::Point_3 Point; + typedef typename K::Segment_3 Segment; + typedef typename K::Triangle_3 Triangle; + typedef typename K::Plane_3 Plane_3; + typedef std::vector Poly; + + typedef typename Intersection_traits, + CGAL::Triangle_3 >::result_type Res_type; + + //Lazy implem: clip 6 times the input triangle. + Plane_3 planes[6]; + planes[0] = Plane_3(cub.vertex(0), + cub.vertex(1), + cub.vertex(5)); + + planes[1] = Plane_3(cub.vertex(0), + cub.vertex(4), + cub.vertex(3)); + + planes[2]=Plane_3(cub.vertex(0), + cub.vertex(3), + cub.vertex(1)); + + planes[3] = Plane_3(cub.vertex(7), + cub.vertex(6), + cub.vertex(1)); + + planes[4] = Plane_3(cub.vertex(7), + cub.vertex(3), + cub.vertex(4)); + + planes[5] = Plane_3(cub.vertex(7), + cub.vertex(4), + cub.vertex(6)); + + std::vector poly; + poly.push_back(tr.vertex(0)); + poly.push_back(tr.vertex(1)); + poly.push_back(tr.vertex(2)); + + for (int i = 0; i < 6; ++i) + { + Poly clipped; + clip_poly_halfspace(poly, planes[i], clipped); + poly = clipped; + for(auto p : poly) + std::cout<(res)); + } + break; + case 2: + { + Segment res = Segment(poly.front(), poly.back()); + return Res_type(std::forward(res)); + } + break; + case 3: + { + + Triangle res = Triangle (poly[0], poly[1], poly[2]); + return Res_type(std::forward(res)); + } + break; + default: + { + return Res_type(std::forward(poly)); + } + break; + } +} + +template +typename Intersection_traits::result_type +intersection( + const typename K::Triangle_3 &tr, + const typename K::Iso_cuboid_3 &cub, + const K& k) +{ + return intersection(cub, tr, k); +} +}}} + +#endif // CGAL_INTERSECTIONS_3_INTERNAL_ISO_CUBOID_3_TRIANGLE_3_INTERSECTION_H diff --git a/Intersections_3/test/Intersections_3/test_intersections_3.cpp b/Intersections_3/test/Intersections_3/test_intersections_3.cpp index 0bb7232530d..cace6db9c1b 100644 --- a/Intersections_3/test/Intersections_3/test_intersections_3.cpp +++ b/Intersections_3/test/Intersections_3/test_intersections_3.cpp @@ -920,9 +920,10 @@ struct Test { check_intersection (cub, Pl(P(2, 1.66, 2), P(1.66,2,2), P(2,2,1.66)), - Tr(P(2, 1.66, 2), + Tr(P(2, 2, 1.66), P(1.66,2,2), - P(2,2,1.66))); + P(2,1.66,2))); + //random Pl pl(0.265189, 0.902464, 0.33946, -2.47551); res = CGAL::intersection(cub, pl); @@ -952,11 +953,77 @@ struct Test { } } + void Cub_Tr(bool is_exact) + { + std::cout << "Triangle_3 - Cuboid_3\n"; + + Cub cub(P(1,1,1), P(2,2,2)); + + check_no_intersection(cub, Tr(P(1.1, 2,0), + P(2, 3, 1), + P(4, 5, 6))); + + //tr in a face + check_intersection(cub, Tr(P(1,1.1,1), + P(1,1.5,1), + P(1,1,1.1)), + Tr(P(1,1.1,1), + P(1,1.5,1), + P(1,1,1.1)) + ); + //face in a tr + + typedef typename CGAL::Intersection_traits::result_type Res; + Tr tr(P(-3, -3, 1), P(3,-3,1), P(1.5,6,1)); + Res res = CGAL::intersection(cub, tr); + if(is_exact) + { + std::vector

* poly = boost::get >(&*res); + CGAL_assertion(poly != nullptr); + CGAL_assertion(poly->size() == 4); + for(auto p : *poly) + { + CGAL_assertion(tr.has_on(p) && cub.has_on_boundary(p)); + } + } + + //tr adj to a point + + check_intersection (cub, Tr(P(1, 0.5, 0.5), + P(3, 2, 1), + P(3, 1, 2)), + P(2,1,1)); + //tr adj to an edge + check_intersection (cub, Tr(P(1,0,4), P(2,1,0), P(4,3,0)), + S(P(2,1,2), P(2,1,1))); + //tr inside + check_intersection (cub, Tr(P(1.1,1.1,1.1), P(1.8,1.8,1.8), P(1.5,1.8,1.1)), + Tr(P(1.1,1.1,1.1), P(1.8,1.8,1.8), P(1.5,1.8,1.1))); + //tr through + tr = Tr(P(2, 4, 2), + P(1, 3.5, -0.5), + P(1, -1, 1)); + res = CGAL::intersection(cub, tr); + if(is_exact) + { + std::vector

* poly = boost::get >(&*res); + CGAL_assertion(poly != nullptr); + CGAL_assertion(poly->size() == 4); + for(auto p : *poly) + { + std::cout< Date: Thu, 13 Jun 2019 10:24:38 +0200 Subject: [PATCH 025/141] Add misisng intersections for bbox_3 --- .../include/CGAL/Intersection_traits_3.h | 39 +++++ .../CGAL/Intersections_3/Bbox_3_Plane_3.h | 18 +++ .../CGAL/Intersections_3/Bbox_3_Triangle_3.h | 16 ++ .../Iso_cuboid_3_Triangle_3_intersection.h | 2 - .../Intersections_3/test_intersections_3.cpp | 140 +++++++++++++++++- 5 files changed, 212 insertions(+), 3 deletions(-) diff --git a/Intersections_3/include/CGAL/Intersection_traits_3.h b/Intersections_3/include/CGAL/Intersection_traits_3.h index bb843288f1d..c49fc277357 100644 --- a/Intersections_3/include/CGAL/Intersection_traits_3.h +++ b/Intersections_3/include/CGAL/Intersection_traits_3.h @@ -179,6 +179,7 @@ struct Intersection_traits + // Iso_cuboid_3 Point_3, variant of one template struct Intersection_traits { @@ -226,6 +227,44 @@ struct Intersection_traits typedef typename boost::optional< variant_type > result_type; }; +// Bbox_3 Plane_3, variant of 4 +template +struct Intersection_traits { + typedef typename + boost::variant< typename K::Point_3, typename K::Segment_3, + typename K::Triangle_3, std::vector > variant_type; + + typedef typename boost::optional< variant_type > result_type; +}; + +template +struct Intersection_traits { + typedef typename + boost::variant< typename K::Point_3, typename K::Segment_3, + typename K::Triangle_3, std::vector > variant_type; + + typedef typename boost::optional< variant_type > result_type; +}; + +// Bbox_3 Triangle_3, variant of 4 +template +struct Intersection_traits { + typedef typename + boost::variant< typename K::Point_3, typename K::Segment_3, + typename K::Triangle_3, std::vector > variant_type; + + typedef typename boost::optional< variant_type > result_type; +}; + +template +struct Intersection_traits { + typedef typename + boost::variant< typename K::Point_3, typename K::Segment_3, + typename K::Triangle_3, std::vector > variant_type; + + typedef typename boost::optional< variant_type > result_type; +}; + // Point_3 Line_3, variant of one template diff --git a/Intersections_3/include/CGAL/Intersections_3/Bbox_3_Plane_3.h b/Intersections_3/include/CGAL/Intersections_3/Bbox_3_Plane_3.h index 639a7986aee..c6fd821083e 100644 --- a/Intersections_3/include/CGAL/Intersections_3/Bbox_3_Plane_3.h +++ b/Intersections_3/include/CGAL/Intersections_3/Bbox_3_Plane_3.h @@ -27,6 +27,7 @@ #include #include +#include namespace CGAL { @@ -43,6 +44,23 @@ bool do_intersect(const Plane_3& a, return K().do_intersect_3_object()(a, b); } +template +typename Intersection_traits::result_type +intersection(const CGAL::Bbox_3& box, + const Plane_3& pl) { + typename K::Iso_cuboid_3 cub(box.xmin(), box.ymin(), box.zmin(), + box.xmax(), box.ymax(), box.zmax()); + return typename K::Intersect_3()(cub, pl); +} + +template +typename Intersection_traits::result_type +intersection(const Plane_3& a, + const CGAL::Bbox_3& b) { + return intersection(b,a); +} + + } #endif // CGAL_INTERSECTIONS_3_BBOX_3_PLANE_3_H diff --git a/Intersections_3/include/CGAL/Intersections_3/Bbox_3_Triangle_3.h b/Intersections_3/include/CGAL/Intersections_3/Bbox_3_Triangle_3.h index c7d5a122a9e..33fb3bc1717 100644 --- a/Intersections_3/include/CGAL/Intersections_3/Bbox_3_Triangle_3.h +++ b/Intersections_3/include/CGAL/Intersections_3/Bbox_3_Triangle_3.h @@ -27,6 +27,7 @@ #include #include +#include namespace CGAL { @@ -42,6 +43,21 @@ bool do_intersect(const Triangle_3& a, return K().do_intersect_3_object()(a, b); } +template +typename Intersection_traits::result_type +intersection(const CGAL::Bbox_3& box, + const Triangle_3& tr) { + typename K::Iso_cuboid_3 cub(box.xmin(), box.ymin(), box.zmin(), + box.xmax(), box.ymax(), box.zmax()); + return typename K::Intersect_3()(cub, tr); +} + +template +typename Intersection_traits::result_type +intersection(const Triangle_3& a, + const CGAL::Bbox_3& b) { + return intersection(b,a); +} } // namespace CGAL diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Triangle_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Triangle_3_intersection.h index a04a1978908..0e8f1ebc186 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Triangle_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Triangle_3_intersection.h @@ -162,8 +162,6 @@ intersection( Poly clipped; clip_poly_halfspace(poly, planes[i], clipped); poly = clipped; - for(auto p : poly) - std::cout<size() == 4); for(auto p : *poly) { - std::cout<::result_type Res; + Res res = CGAL::intersection(cub, Pl(P(1,1,1), P(1,2,1), P(1,2,2))); + + const std::vector

* poly = boost::get >(&*res); + CGAL_assertion(poly != nullptr); + CGAL_assertion(poly->size() == 4); + for(auto p : *poly) + { + CGAL_assertion(p.x() == 1); + } + res = CGAL::intersection(cub, Pl(P(1,1,1), P(1,2,1), P(2,2,2))); + poly = boost::get >(&*res); + CGAL_assertion(poly != nullptr); + CGAL_assertion(poly->size() == 4); + //vertex + check_intersection (cub, Pl(0.5, -0.5, -0.5, 0), + P(2,1,1)); + //triangle + + check_intersection (cub, Pl(P(2, 1.66, 2), + P(1.66,2,2), + P(2,2,1.66)), + Tr(P(2, 2, 1.66), + P(1.66,2,2), + P(2,1.66,2))); + + //random + Pl pl(0.265189, 0.902464, 0.33946, -2.47551); + res = CGAL::intersection(cub, pl); + poly = boost::get >(&*res); + CGAL_assertion(poly != nullptr); + CGAL_assertion(poly->size() == 5); + for(auto p : *poly) + { + CGAL_assertion(pl.has_on(p)); + } + } + else + { + CGAL::intersection(cub, Pl(P(1,1,1), P(1,2,1), P(1.5,0,0))); + //face + typedef typename CGAL::Intersection_traits::result_type Res; + Res res = CGAL::intersection(cub, Pl(P(1,1,1), P(1,2,1), P(1,2,2))); + res = CGAL::intersection(cub, Pl(P(1,1,1), P(1,2,1), P(2,2,2))); + CGAL::intersection (cub, Pl(0.5, -0.5, -0.5, 0)); + CGAL::intersection (cub, Pl(P(2, 1.66, 2), + P(1.66,2,2), + P(2,2,1.66))); + Pl pl(0.265189, 0.902464, 0.33946, -2.47551); + res = CGAL::intersection(cub, pl); + } + } + + void Box_Tr(bool is_exact) + { + std::cout << "Triangle_3 - Cuboid_3\n"; + + Cub cub(P(1,1,1), P(2,2,2)); + + check_no_intersection(cub, Tr(P(1.1, 2,0), + P(2, 3, 1), + P(4, 5, 6))); + + //tr in a face + check_intersection(cub, Tr(P(1,1.1,1), + P(1,1.5,1), + P(1,1,1.1)), + Tr(P(1,1.1,1), + P(1,1.5,1), + P(1,1,1.1)) + ); + //face in a tr + + typedef typename CGAL::Intersection_traits::result_type Res; + Tr tr(P(-3, -3, 1), P(3,-3,1), P(1.5,6,1)); + Res res = CGAL::intersection(cub, tr); + if(is_exact) + { + std::vector

* poly = boost::get >(&*res); + CGAL_assertion(poly != nullptr); + CGAL_assertion(poly->size() == 4); + for(auto p : *poly) + { + CGAL_assertion(tr.has_on(p) && cub.has_on_boundary(p)); + } + } + + //tr adj to a point + + check_intersection (cub, Tr(P(1, 0.5, 0.5), + P(3, 2, 1), + P(3, 1, 2)), + P(2,1,1)); + //tr adj to an edge + check_intersection (cub, Tr(P(1,0,4), P(2,1,0), P(4,3,0)), + S(P(2,1,2), P(2,1,1))); + //tr inside + check_intersection (cub, Tr(P(1.1,1.1,1.1), P(1.8,1.8,1.8), P(1.5,1.8,1.1)), + Tr(P(1.1,1.1,1.1), P(1.8,1.8,1.8), P(1.5,1.8,1.1))); + //tr through + tr = Tr(P(2, 4, 2), + P(1, 3.5, -0.5), + P(1, -1, 1)); + res = CGAL::intersection(cub, tr); + if(is_exact) + { + std::vector

* poly = boost::get >(&*res); + CGAL_assertion(poly != nullptr); + CGAL_assertion(poly->size() == 4); + for(auto p : *poly) + { + CGAL_assertion(tr.has_on(p) && cub.has_on_boundary(p)); + } + } + } void run(bool is_exact = false) @@ -1049,6 +1185,8 @@ struct Test { Tet_Tr(is_exact); Pl_Cub(is_exact); Cub_Tr(is_exact); + Pl_Box(is_exact); + Box_Tr(is_exact); //@} Bbox_L(); From f969555a3c7cda10780ca25a10cbb151f472c482 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 13 Jun 2019 11:04:50 +0200 Subject: [PATCH 026/141] Update doc and add test for homogeneous exact --- .../Intersections_3/test_intersections_3.cpp | 1 + Kernel_23/doc/Kernel_23/CGAL/intersections.h | 69 +++++++++++++++---- 2 files changed, 57 insertions(+), 13 deletions(-) diff --git a/Intersections_3/test/Intersections_3/test_intersections_3.cpp b/Intersections_3/test/Intersections_3/test_intersections_3.cpp index bd045f7b2aa..ed5ad9d428c 100644 --- a/Intersections_3/test/Intersections_3/test_intersections_3.cpp +++ b/Intersections_3/test/Intersections_3/test_intersections_3.cpp @@ -1200,6 +1200,7 @@ int main() Test< CGAL::Simple_cartesian >().run(); Test< CGAL::Homogeneous >().run(); Test< CGAL::Epeck >().run(true); + Test< CGAL::Homogeneous >().run(true); // TODO : test more kernels. } diff --git a/Kernel_23/doc/Kernel_23/CGAL/intersections.h b/Kernel_23/doc/Kernel_23/CGAL/intersections.h index 9c3814aaa8d..4363e7a32b0 100644 --- a/Kernel_23/doc/Kernel_23/CGAL/intersections.h +++ b/Kernel_23/doc/Kernel_23/CGAL/intersections.h @@ -47,23 +47,15 @@ Also, `Type1` and `Type2` can be both of type In three-dimensional space, the types `Type1` and `Type2` can be any of the following: +- `Bbox_3`. - `Point_3` - `Plane_3` - `Line_3` - `Ray_3` - `Segment_3` +- `Sphere_3` - `Triangle_3`. -- `Bbox_3`. - -Also, `Type1` and `Type2` can be respectively of types - -- `Triangle_3` and `Tetrahedron_3` -- `Plane_3` and `Sphere_3` (or the contrary) -- `Sphere_3` and `Sphere_3` -- `Line_3` and `Iso_cuboid_3` -- `Ray_3` and `Iso_cuboid_3` -- `Segment_3` and `Iso_cuboid_3` -- `Iso_cuboid_3` and `Iso_cuboid_3`. +- `Tetrahedron_3`. */ bool do_intersect(Type1 obj1, Type2 obj2); /// @} @@ -230,6 +222,16 @@ It is equivalent to `boost::optional< boost::variant< T... > >`, the last column Triangle_3 Point_3, or Segment_3 + + Line_3 + Tetrahedron_3 + Point_3, or Segment_3 + + + Line_3 + Iso_cuboid_3 + Point_3, or Segment_3 + Plane_3 Plane_3 @@ -255,6 +257,16 @@ It is equivalent to `boost::optional< boost::variant< T... > >`, the last column Triangle_3 Point_3, or Segment_3, or Triangle_3 + + Plane_3 + Tetrahedron_3 + Point_3, or Segment_3, or Triangle_3, or std::vector + + + Plane_3 + Iso_cuboid_3 + Point_3, or Segment_3, or Triangle_3, or std::vector + Ray_3 Ray_3 @@ -268,7 +280,17 @@ It is equivalent to `boost::optional< boost::variant< T... > >`, the last column Ray_3 Triangle_3 -p Point_3, or Segment_3 + Point_3, or Segment_3 + + + Ray_3 + Tetrahedron_3 + Point_3, or Segment_3 + + + Ray_3 + Iso_cuboid_3 + Point_3, or Segment_3 Segment_3 @@ -280,6 +302,16 @@ p Point_3, or Segment_3 Triangle_3 Point_3, or Segment_3 + + Segment_3 + Tetrahedron_3 + Point_3, or Segment_3 + + + Segment_3 + Iso_cuboid_3 + Point_3, or Segment_3 + Sphere_3 Sphere_3 @@ -290,11 +322,22 @@ p Point_3, or Segment_3 Triangle_3 Point_3, or Segment_3, or Triangle_3, or std::vector < Point_3 > + + Triangle_3 + Tetrahedron_3 + Point_3, or Segment_3, or Triangle_3, or std::vector < Point_3 > + + + Triangle_3 + Iso_cuboid_3 + Point_3, or Segment_3, or Triangle_3, or std::vector < Point_3 > + Additional overloads are provided for the type `Point_3` combined with any other type with the result type being -`boost::optional< boost::variant< Point_3 > >`. +`boost::optional< boost::variant< Point_3 > >`. Overloads are also provided for the type `Bbox_3`, for all +intersections existing with the type `Iso_cuboid_3`. \cgalHeading{Examples} From 443f3f636fe9510cbc7a27115895aba9498e9139 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 13 Jun 2019 15:49:21 +0200 Subject: [PATCH 027/141] Add missing intersection_2 and update doc. --- .../include/CGAL/Intersection_traits_2.h | 22 ++++++ .../CGAL/Intersections_2/Bbox_2_Bbox_2.h | 67 ++++++++++++++++ .../CGAL/Intersections_2/Bbox_2_Circle_2.h | 1 + .../Intersections_2/Bbox_2_Iso_rectangle_2.h | 68 +++++++++++++++++ .../CGAL/Intersections_2/Bbox_2_Line_2.h | 33 +++++++- .../CGAL/Intersections_2/Bbox_2_Point_2.h | 1 + .../CGAL/Intersections_2/Bbox_2_Ray_2.h | 36 +++++++++ .../CGAL/Intersections_2/Bbox_2_Segment_2.h | 68 +++++++++++++++++ .../CGAL/Intersections_2/Bbox_2_Triangle_2.h | 68 +++++++++++++++++ .../Intersections_2/test_intersections_2.cpp | 76 +++++++++++++++---- Kernel_23/doc/Kernel_23/CGAL/intersections.h | 6 +- 11 files changed, 426 insertions(+), 20 deletions(-) create mode 100644 Intersections_2/include/CGAL/Intersections_2/Bbox_2_Bbox_2.h create mode 100644 Intersections_2/include/CGAL/Intersections_2/Bbox_2_Iso_rectangle_2.h create mode 100644 Intersections_2/include/CGAL/Intersections_2/Bbox_2_Segment_2.h create mode 100644 Intersections_2/include/CGAL/Intersections_2/Bbox_2_Triangle_2.h diff --git a/Intersections_2/include/CGAL/Intersection_traits_2.h b/Intersections_2/include/CGAL/Intersection_traits_2.h index 90a50a7f7e6..ab102d906ea 100644 --- a/Intersections_2/include/CGAL/Intersection_traits_2.h +++ b/Intersections_2/include/CGAL/Intersection_traits_2.h @@ -114,6 +114,28 @@ template struct Intersection_traits : public Intersection_traits {}; +template +struct Intersection_traits { + typedef typename Intersection_traits::result_type result_type; +}; + +template +struct Intersection_traits { + typedef typename Intersection_traits::result_type result_type; +}; + +template +struct Intersection_traits { + typedef typename boost::variant variant_type; + typedef boost::optional result_type; +}; + +template +struct Intersection_traits { + typedef typename boost::variant variant_type; + typedef boost::optional result_type; +}; + } // namespace CGAL #endif /* CGAL_INTERSECTION_TRAITS_2_H */ diff --git a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Bbox_2.h b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Bbox_2.h new file mode 100644 index 00000000000..90fdc2495e4 --- /dev/null +++ b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Bbox_2.h @@ -0,0 +1,67 @@ +// Copyright (c) 2019 +// GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// +// +// Author(s) : Maxime Gimeno + + +#ifndef CGAL_INTERSECTIONS_BBOX_2_BBOX_2_H +#define CGAL_INTERSECTIONS_BBOX_2_BBOX_2_H + +#include +#include +#include +#include +#include + +namespace CGAL { + +bool +inline +do_intersect(const CGAL::Bbox_2& c, + const CGAL::Bbox_2& bbox) +{ + return CGAL::do_overlap(c, bbox); +} + +typename boost::optional< typename +boost::variant< Bbox_2> > +inline +intersection(const CGAL::Bbox_2& a, + const CGAL::Bbox_2& b) { + + typedef typename + boost::variant< Bbox_2> variant_type; + typedef typename boost::optional< variant_type > Result_type; + if(!do_intersect(a,b)) + { + return Result_type(); + } + + double xmin, xmax, ymin, ymax; + xmin = (std::max)(a.xmin(), b.xmin()); + xmax = (std::min)(a.xmax(), b.xmax()); + + ymin = (std::max)(a.ymin(), b.ymin()); + ymax = (std::min)(a.ymax(), b.ymax()); + + return Result_type(std::forward(Bbox_2(xmin, ymin, xmax, ymax))); +} + +} +#endif // BBOX_2_BBOX_2_H diff --git a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Circle_2.h b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Circle_2.h index aaa9f323f1c..44a329db872 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Circle_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Circle_2.h @@ -42,5 +42,6 @@ bool do_intersect(const Circle_2& a, return K().do_intersect_2_object()(a, b); } + } #endif // CGAL_INTERSECTIONS_2_BBOX_2_CIRCLE_2_H diff --git a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Iso_rectangle_2.h b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Iso_rectangle_2.h new file mode 100644 index 00000000000..907ae0bc05b --- /dev/null +++ b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Iso_rectangle_2.h @@ -0,0 +1,68 @@ +// Copyright (c) 2019 +// GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// +// +// Author(s) : Maxime Gimeno + + +#ifndef CGAL_INTERSECTIONS_BBOX_2_ISO_RECTANGLE_2_H +#define CGAL_INTERSECTIONS_BBOX_2_ISO_RECTANGLE_2_H + +#include +#include +#include +#include +#include + +namespace CGAL { + + +template +inline bool do_intersect( + const Iso_rectangle_2 &line, + const Bbox_2 &box) +{ + typename K::Iso_rectangle_2 rec(box.xmin(), box.ymin(), box.xmax(), box.ymax()); + return do_intersect(rec, line); +} + +template +inline bool do_intersect( + const Bbox_2 &box, +const Iso_rectangle_2 &line) +{ + return do_intersect(line, box); +} + +template +typename Intersection_traits::result_type +intersection(const CGAL::Bbox_2& box, + const Iso_rectangle_2& line) { + typename K::Iso_rectangle_2 rec(box.xmin(), box.ymin(), box.xmax(), box.ymax()); + return intersection(rec, line); +} + +template +typename Intersection_traits::result_type +intersection(const Iso_rectangle_2& line, + const CGAL::Bbox_2& box) { + return intersection(box, line); +} + +} +#endif // BBOX_2_ISO_RECTANGLE_2_H diff --git a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Line_2.h b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Line_2.h index c5804de228c..86102016563 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Line_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Line_2.h @@ -32,6 +32,8 @@ #include #include +#include + namespace CGAL { class Bbox_2_Line_2_pair_impl; @@ -85,14 +87,39 @@ bool do_intersect_line_2( to_double(line->b()), to_double(line->c())); } -template + + +template inline bool do_intersect( - const Line_2 &line, + const Line_2 &line, const Bbox_2 &box) { - return do_intersect(box, line); + typename K::Iso_rectangle_2 rec(box.xmin(), box.ymin(), box.xmax(), box.ymax()); + return do_intersect(rec, line); } +template +inline bool do_intersect( + const Bbox_2 &box, +const Line_2 &line) +{ + return do_intersect(line, box); +} + +template +typename Intersection_traits::result_type +intersection(const CGAL::Bbox_2& box, + const Line_2& line) { + typename K::Iso_rectangle_2 rec(box.xmin(), box.ymin(), box.xmax(), box.ymax()); + return intersection(rec, line); +} + +template +typename Intersection_traits::result_type +intersection(const Line_2& line, + const CGAL::Bbox_2& box) { + return intersection(box, line); +} } //namespace CGAL #ifdef CGAL_HEADER_ONLY diff --git a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Point_2.h b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Point_2.h index 5df79996e48..875508bac57 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Point_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Point_2.h @@ -28,6 +28,7 @@ #include + namespace CGAL { template diff --git a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Ray_2.h b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Ray_2.h index 512f4779b2f..eb6b6410d15 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Ray_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Ray_2.h @@ -31,6 +31,7 @@ #include #include #include +#include namespace CGAL { @@ -74,6 +75,41 @@ inline bool do_intersect_ray_2( { return do_intersect_ray_2(box, ray); } + + + + +template +inline bool do_intersect( + const Ray_2 &line, + const Bbox_2 &box) +{ + typename K::Iso_rectangle_2 rec(box.xmin(), box.ymin(), box.xmax(), box.ymax()); + return do_intersect(rec, line); +} + +template +inline bool do_intersect( + const Bbox_2 &box, +const Ray_2 &line) +{ + return do_intersect(line, box); +} + +template +typename Intersection_traits::result_type +intersection(const CGAL::Bbox_2& box, + const Ray_2& line) { + typename K::Iso_rectangle_2 rec(box.xmin(), box.ymin(), box.xmax(), box.ymax()); + return intersection(rec, line); +} + +template +typename Intersection_traits::result_type +intersection(const Ray_2& line, + const CGAL::Bbox_2& box) { + return intersection(box, line); +} } //namespace CGAL #ifdef CGAL_HEADER_ONLY diff --git a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Segment_2.h b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Segment_2.h new file mode 100644 index 00000000000..92f9881e87c --- /dev/null +++ b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Segment_2.h @@ -0,0 +1,68 @@ +// Copyright (c) 2019 +// GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// +// +// Author(s) : Maxime Gimeno + + +#ifndef CGAL_INTERSECTIONS_BBOX_2_SEGMENT_2_H +#define CGAL_INTERSECTIONS_BBOX_2_SEGMENT_2_H + +#include +#include +#include +#include +#include + +namespace CGAL { + + +template +inline bool do_intersect( + const Segment_2 &line, + const Bbox_2 &box) +{ + typename K::Iso_rectangle_2 rec(box.xmin(), box.ymin(), box.xmax(), box.ymax()); + return do_intersect(rec, line); +} + +template +inline bool do_intersect( + const Bbox_2 &box, +const Segment_2 &line) +{ + return do_intersect(line, box); +} + +template +typename Intersection_traits::result_type +intersection(const CGAL::Bbox_2& box, + const Segment_2& line) { + typename K::Iso_rectangle_2 rec(box.xmin(), box.ymin(), box.xmax(), box.ymax()); + return intersection(rec, line); +} + +template +typename Intersection_traits::result_type +intersection(const Segment_2& line, + const CGAL::Bbox_2& box) { + return intersection(box, line); +} + +} +#endif // BBOX_2_SEGMENT_2_H diff --git a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Triangle_2.h b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Triangle_2.h new file mode 100644 index 00000000000..a21a55908b1 --- /dev/null +++ b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Triangle_2.h @@ -0,0 +1,68 @@ +// Copyright (c) 2019 +// GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// +// +// Author(s) : Maxime Gimeno + + +#ifndef CGAL_INTERSECTIONS_BBOX_2_TRIANGLE_2_H +#define CGAL_INTERSECTIONS_BBOX_2_TRIANGLE_2_H + +#include +#include +#include +#include +#include + +namespace CGAL { + + +template +inline bool do_intersect( + const Triangle_2 &line, + const Bbox_2 &box) +{ + typename K::Iso_rectangle_2 rec(box.xmin(), box.ymin(), box.xmax(), box.ymax()); + return do_intersect(rec, line); +} + +template +inline bool do_intersect( + const Bbox_2 &box, +const Triangle_2 &line) +{ + return do_intersect(line, box); +} + +template +typename Intersection_traits::result_type +intersection(const CGAL::Bbox_2& box, + const Triangle_2& line) { + typename K::Iso_rectangle_2 rec(box.xmin(), box.ymin(), box.xmax(), box.ymax()); + return intersection(rec, line); +} + +template +typename Intersection_traits::result_type +intersection(const Triangle_2& line, + const CGAL::Bbox_2& box) { + return intersection(box, line); +} + +} +#endif // BBOX_2_TRIANGLE_2_H diff --git a/Intersections_2/test/Intersections_2/test_intersections_2.cpp b/Intersections_2/test/Intersections_2/test_intersections_2.cpp index 83928d529d1..05a03613246 100644 --- a/Intersections_2/test/Intersections_2/test_intersections_2.cpp +++ b/Intersections_2/test/Intersections_2/test_intersections_2.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -16,6 +17,12 @@ #include #include #include +#include +#include +#include +#include +#include +#include #include #include @@ -308,26 +315,43 @@ check_no_intersection (L(p(0, 0), p(10,10)), L(p(8,7), p(1, 0))); void L_Rec() { + Rec rec(p( 2, 0), p( 6, 3)); std::cout << "Line - Iso_rectangle\n"; - check_intersection (L(p( 18, 6), p(0, 0)), Rec(p( 2, 0), p( 6, 3))); + check_intersection (L(p( 18, 6), p(0, 0)), rec); + std::cout << "Line - Bbox\n"; + check_intersection (L(p( 18, 6), p(0, 0)), rec.bbox()); } void R_Rec() { + Rec rec(p( 2, 0), p( 6, 3)); std::cout << "Ray - Iso_rectangle\n"; - check_intersection (R(p( 18, 6), p(0, 0)), Rec(p( 2, 0), p( 6, 3))); + check_intersection (R(p( 18, 6), p(0, 0)), rec); + + std::cout << "Ray - Bbox\n"; + check_intersection (R(p( 18, 6), p(0, 0)), rec.bbox()); } void S_Rec() { + Rec rec(p( 2, 0), p( 6, 3)); std::cout << "Segment - Iso_rectangle\n"; - check_intersection (S(p( 18, 6), p(0, 0)), Rec(p( 2, 0), p( 6, 3))); + check_intersection (S(p( 18, 6), p(0, 0)), rec); + + std::cout << "Segment - Bbox\n"; + check_intersection (S(p( 18, 6), p(0, 0)), rec.bbox()); } void Rec_Rec() { std::cout << "Iso_rectangle - Iso_rectangle\n"; check_intersection (Rec(p( 10, 12), p(30, 40)), Rec(p( 25, 40), p( 26, 103)), Rec(P(25, 40), P(26, 40))); + + std::cout << "Iso_rectangle - Bbox\n"; + check_intersection (Rec(p( 10, 12), p(30, 40)), Rec(p( 25, 40), p( 26, 103)).bbox(), Rec(P(25, 40), P(26, 40))); + + std::cout << "Bbox - Bbox\n"; + check_intersection (Rec(p( 10, 12), p(30, 40)).bbox(), Rec(p( 25, 40), p( 26, 103)).bbox(), Rec(P(25, 40), P(26, 40)).bbox()); } void T_Rec() @@ -342,29 +366,46 @@ check_no_intersection (L(p(0, 0), p(10,10)), L(p(8,7), p(1, 0))); check_intersection

(Rec(p( 0, 0), p(1, 1)), T(p( -1, 0), p( 0, 0), p(0, -1))); check_intersection

(Rec(p( 0, 0), p(1, 1)), T(p( 0, 0), p( -1, 0), p(0, -1))); check_intersection(Rec(p( 100, 100), p(200, 200)), T(p(150, 50), p(250, 170), p(50, 170))); + + std::cout << "Triangle Bbox\n"; + check_intersection(Rec(p( 0, 0), p(1, 1)).bbox(), T(p( -1, 0), p( -1, 2), p(2, 2))); + check_intersection(Rec(p( 0, 0), p(1, 1)).bbox(), T(p( -1, 0), p(2, 2), p( -1, 2))); + check_intersection(Rec(p( 0, 0), p(1, 1)).bbox(), T(p( -1, -2), p( -1, 2), p(5, 2))); + check_intersection(Rec(p( 0, 0), p(2, 2)).bbox(), T(p( 0, 0), p( 1, 0), p(0, 1))); + check_intersection(Rec(p( 0, 0), p(3, 3)).bbox(), T(p( 1, 1), p( 2, 1), p(1, 2))); + check_intersection

(Rec(p( 0, 0), p(1, 1)).bbox(), T(p( -1, 0), p( 0, 0), p(0, -1))); + check_intersection

(Rec(p( 0, 0), p(1, 1)).bbox(), T(p( 0, 0), p( -1, 0), p(0, -1))); + check_intersection(Rec(p( 100, 100), p(200, 200)).bbox(), T(p(150, 50), p(250, 170), p(50, 170))); + + } void run() { std::cout << "2D Intersection tests\n"; B_P(); - L_L(); - S_S(); - R_R(); - S_R(); - L_R(); - S_L(); - T_T(); - L_T(); - R_T(); - S_T(); - P_T(); P_P(); + P_T(); + + L_L(); + L_T(); + L_R(); L_Rec(); - R_Rec(); + + S_S(); + S_L(); + S_R(); + S_T(); S_Rec(); - Rec_Rec(); + + R_R(); + R_T(); + R_Rec(); + + T_T(); T_Rec(); + + Rec_Rec(); } }; @@ -389,6 +430,9 @@ int main() { Test< CGAL::Simple_cartesian >().run(); Test< CGAL::Homogeneous >().run(); + Test< CGAL::Simple_cartesian >().run(); + Test< CGAL::Homogeneous >().run(); + typedef typename CGAL::Simple_cartesian K; typedef typename K::Point_2 P; typedef typename K::Line_2 L; diff --git a/Kernel_23/doc/Kernel_23/CGAL/intersections.h b/Kernel_23/doc/Kernel_23/CGAL/intersections.h index 4363e7a32b0..0244487cee6 100644 --- a/Kernel_23/doc/Kernel_23/CGAL/intersections.h +++ b/Kernel_23/doc/Kernel_23/CGAL/intersections.h @@ -185,6 +185,9 @@ It is equivalent to `boost::optional< boost::variant< T... > >`, the last column Additional overloads are provided for the type `Point_2` combined with any other type with the result type being `boost::optional< boost::variant< Point_2 > >`. +Overloads are also provided for the type `Bbox_2`, for all +intersections existing with the type `Iso_rectangle_2`. Note that the return type for `Bbox_2` - `Bbox_2` + is `Bbox_2` and not `Iso_rectangle_2`. \cgalHeading{3D Intersections} @@ -337,7 +340,8 @@ It is equivalent to `boost::optional< boost::variant< T... > >`, the last column Additional overloads are provided for the type `Point_3` combined with any other type with the result type being `boost::optional< boost::variant< Point_3 > >`. Overloads are also provided for the type `Bbox_3`, for all -intersections existing with the type `Iso_cuboid_3`. +intersections existing with the type `Iso_cuboid_3`. Note that the return type for `Bbox_3` - `Bbox_3` + is `Bbox_3` and not `Iso_cuboid_3`. \cgalHeading{Examples} From 6f2930acac8fd3b99b10bafa7517d79863f7e2d9 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 14 Jun 2019 13:19:06 +0200 Subject: [PATCH 028/141] Add missing license headers --- .../tetrahedron_intersection_helpers.h | 22 +++++++++++++++++++ .../tetrahedron_lines_intersections_3.h | 22 +++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h index ced97166b57..b6c4f44be0b 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h @@ -1,3 +1,25 @@ +// Copyright (c) 2019 GeometryFactory(France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// +// +// Author(s) : Maxime Gimeno +// + #ifndef CGAL_INTERNAL_TETRAHEDRON_INTERSECTION_HELPERS_H #define CGAL_INTERNAL_TETRAHEDRON_INTERSECTION_HELPERS_H diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h index ef2449873f1..3d0bc69bc10 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h @@ -1,3 +1,25 @@ +// Copyright (c) 2019 GeometryFactory(France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// +// +// Author(s) : Maxime Gimeno +// + #ifndef TETRAHEDRON_LINES_INTERSECTIONS_3_H #define TETRAHEDRON_LINES_INTERSECTIONS_3_H From 3e5d3acb2fae0eea56e8296e963e5436a4efbfd4 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 17 Jun 2019 15:17:58 +0200 Subject: [PATCH 029/141] Replace the virtual helper class with a CRTP pattern to avoid the virtual methods. --- .../Tetrahedron_3_Line_3_intersection.h | 23 +++++++- .../Tetrahedron_3_Ray_3_intersection.h | 11 ++-- .../Tetrahedron_3_Segment_3_intersection.h | 11 ++-- .../Tetrahedron_3_Triangle_3_intersection.h | 19 +++---- .../tetrahedron_intersection_helpers.h | 52 +++++++++---------- .../tetrahedron_lines_intersections_3.h | 12 ++--- 6 files changed, 75 insertions(+), 53 deletions(-) diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Line_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Line_3_intersection.h index 5217bd5db90..51fc6c4a46e 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Line_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Line_3_intersection.h @@ -33,7 +33,28 @@ namespace Intersections { namespace internal { +template +struct Tetrahedron_Line_intersection_3 + :public Tetrahedron_lines_intersection_3_base > +{ + typedef typename K::Line_3 O; + typedef Tetrahedron_lines_intersection_3_base > Base; + typedef typename Base::Result_type Result_type; + Tetrahedron_Line_intersection_3(const typename K::Tetrahedron_3& tet, + const O& o):Base(tet,o) {} + bool all_inside_test() + { + return false; + } + + bool are_extremities_inside_test() + { + return false; + } + +}; //Tetrahedron_3 Line_3 template @@ -43,7 +64,7 @@ intersection( const typename K::Line_3 &line, const K&) { - Tetrahedron_lines_intersection_3_base solver(tet, line); + Tetrahedron_lines_intersection_3_base > solver(tet, line); solver.do_procede(); return solver.output; } diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Ray_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Ray_3_intersection.h index fb81b941435..a97f4d4302f 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Ray_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Ray_3_intersection.h @@ -35,17 +35,18 @@ namespace internal { template struct Tetrahedron_ray_intersection_3 - :public Tetrahedron_lines_intersection_3_base + :public Tetrahedron_lines_intersection_3_base > { typedef typename K::Ray_3 O; - typedef Tetrahedron_lines_intersection_3_base Base; + typedef Tetrahedron_lines_intersection_3_base > Base; typedef typename Base::Result_type Result_type; Tetrahedron_ray_intersection_3(const typename K::Tetrahedron_3& tet, - const O& o):Base(tet,o) {} + const O& o):Base(tet,o) {} - bool are_extremities_inside_test() override + bool are_extremities_inside_test() { //If one extremity is inside tet : return a segment if(this->tet.has_on_bounded_side(this->o.source())) diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Segment_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Segment_3_intersection.h index 9191404469a..46e1d63e88e 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Segment_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Segment_3_intersection.h @@ -35,17 +35,18 @@ namespace internal { template struct Tetrahedron_segment_intersection_3 - :public Tetrahedron_lines_intersection_3_base + :public Tetrahedron_lines_intersection_3_base > { typedef typename K::Segment_3 O; - typedef Tetrahedron_lines_intersection_3_base Base; + typedef Tetrahedron_lines_intersection_3_base > Base; typedef typename Base::Result_type Result_type; Tetrahedron_segment_intersection_3(const typename K::Tetrahedron_3& tet, const O& o):Base(tet,o) {} - bool all_inside_test() override + bool all_inside_test() { //if both segment extremities are inside tet, return the input segment. if(this->tet.has_on_bounded_side(this->o.source()) @@ -57,7 +58,7 @@ struct Tetrahedron_segment_intersection_3 return false; } - bool are_extremities_inside_test() override + bool are_extremities_inside_test() { //If one extremity is inside tet : return a segment if(this->tet.has_on_bounded_side(this->o.source())) diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Triangle_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Triangle_3_intersection.h index 14e28980475..9e41b0a9841 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Triangle_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Triangle_3_intersection.h @@ -60,8 +60,9 @@ intersection( for(int i = 0; i< 3; ++i) { if(tet.has_on_bounded_side(tr.vertex(i)) - || tet.has_on_boundary(tr.vertex(i))) + || tet.has_on_boundary(tr.vertex(i))){ inside_points.push_back(tr.vertex(i)); + } } switch(inside_points.size()) { @@ -118,8 +119,9 @@ intersection( fill_segments_infos(segments,tmp, tr); Poly res; res.reserve(4); - for( auto p : tmp) + for( auto p : tmp){ res.push_back(p); + } return Result_type(std::forward(res)); } //else it must be adjacent to an vertex, so we return the point @@ -238,8 +240,7 @@ intersection( case 3: { std::list segs; - for(auto s : segments) - segs.push_back(s); + for(auto s : segments){segs.push_back(s);} std::list tmp; fill_points_list(segs, tmp); if(inside_points.size() == 1) @@ -247,8 +248,7 @@ intersection( Poly res; res.reserve(4); res.push_back(inside_points.front()); - for( auto p : tmp) - res.push_back(p); + for( auto p : tmp){res.push_back(p);} return Result_type(std::forward(res)); } else //size 2 @@ -257,10 +257,11 @@ intersection( res.reserve(5); if((inside_points.front() - inside_points.back()) * (tmp.front() - tmp.back()) > 0) - res.push_back(inside_points.front()); + { + res.push_back(inside_points.front()); + } res.push_back(inside_points.back()); - for( auto p : tmp) - res.push_back(p); + for( auto p : tmp){res.push_back(p);} return Result_type(std::forward(res)); } } diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h index b6c4f44be0b..36785471ca3 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h @@ -82,28 +82,28 @@ void fill_segments_infos(std::vector& segments, wrapped_segments.push_back(Wrapped_segment(s)); std::vector bis = segments; - for(int plouf = 0; plouf < bis.size()-1; ++plouf) + for(int dummy = 0; dummy < bis.size()-1; ++dummy) { Segment s = bis.back(); bis.pop_back(); - Wrapped_segment& super_s = wrapped_segments.back(); - if(!super_s.s_dangling && ! super_s.t_dangling) + Wrapped_segment& w_s = wrapped_segments.back(); + if(!w_s.s_dangling && ! w_s.t_dangling) continue; for(std::size_t i = 0; i< bis.size(); ++i) { const Segment& s2 = bis[i]; if(s2.target() == s.source()) { - super_s.s_dangling = false; - super_s.s_neighbor = i; + w_s.s_dangling = false; + w_s.s_neighbor = i; //same i because we empty from the bottom wrapped_segments[i].t_dangling = false; wrapped_segments[i].t_neighbor = bis.size(); } else if(s2.target() == s.target()) { - super_s.t_dangling = false; - super_s.t_neighbor = i; + w_s.t_dangling = false; + w_s.t_neighbor = i; wrapped_segments[i].s_dangling = false; wrapped_segments[i].s_neighbor = bis.size(); wrapped_segments[i].segment = wrapped_segments[i].segment.opposite(); //also orient the structure @@ -111,23 +111,23 @@ void fill_segments_infos(std::vector& segments, } else if(s2.source() == s.source()) { - super_s.s_dangling = false; - super_s.s_neighbor = i; + w_s.s_dangling = false; + w_s.s_neighbor = i; wrapped_segments[i].t_dangling = false; wrapped_segments[i].t_neighbor = bis.size(); wrapped_segments[i].segment = wrapped_segments[i].segment.opposite(); } else if(s2.source() == s.target()) { - super_s.t_dangling = false; - super_s.t_neighbor = i; + w_s.t_dangling = false; + w_s.t_neighbor = i; wrapped_segments[i].s_dangling = false; wrapped_segments[i].s_neighbor = bis.size(); } } //fill dangling extremities using triangle edges - if(super_s.s_dangling) + if(w_s.s_dangling) { for(std::size_t e_id = 0; e_id < 3; ++e_id) { @@ -140,8 +140,8 @@ void fill_segments_infos(std::vector& segments, { if(edge.has_on(bis[i].source())) { - super_s.s_dangling = false; - super_s.s_neighbor = i; + w_s.s_dangling = false; + w_s.s_neighbor = i; //same i because we empty from the bottom wrapped_segments[i].t_dangling = false; wrapped_segments[i].t_neighbor = bis.size(); @@ -149,8 +149,8 @@ void fill_segments_infos(std::vector& segments, } else if(edge.has_on(bis[i].target())) { - super_s.s_dangling = false; - super_s.s_neighbor = i; + w_s.s_dangling = false; + w_s.s_neighbor = i; //same i because we empty from the bottom wrapped_segments[i].t_dangling = false; wrapped_segments[i].t_neighbor = bis.size(); @@ -158,7 +158,7 @@ void fill_segments_infos(std::vector& segments, } } } - if(super_s.t_dangling) + if(w_s.t_dangling) { for(std::size_t e_id = 0; e_id < 3; ++e_id) { @@ -171,16 +171,16 @@ void fill_segments_infos(std::vector& segments, { if(edge.has_on(bis[i].source())) { - super_s.t_dangling = false; - super_s.t_neighbor = i; + w_s.t_dangling = false; + w_s.t_neighbor = i; //same i because we empty from the bottom wrapped_segments[i].s_dangling = false; wrapped_segments[i].s_neighbor = bis.size(); } else if(edge.has_on(bis[i].target())) { - super_s.t_dangling = false; - super_s.t_neighbor = i; + w_s.t_dangling = false; + w_s.t_neighbor = i; //same i because we empty from the bottom wrapped_segments[i].s_dangling = false; wrapped_segments[i].s_neighbor = bis.size(); @@ -190,7 +190,7 @@ void fill_segments_infos(std::vector& segments, } } - if(super_s.s_dangling || super_s.t_dangling) + if(w_s.s_dangling || w_s.t_dangling) { std::cerr<<"Error. Kernel must have exact constructions to compute this intersection."<& segments, } //finally fill points - std::size_t voyager = 0; + std::size_t n = 0; do { - Wrapped_segment& ws = wrapped_segments[voyager]; + Wrapped_segment& ws = wrapped_segments[n]; points.push_back(ws.segment.source()); if(wrapped_segments[ws.t_neighbor].segment.source() != ws.segment.target()) points.push_back(ws.segment.target()); - voyager = ws.t_neighbor; - }while(voyager!=0); + n = ws.t_neighbor; + }while(n!=0); } diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h index 3d0bc69bc10..60c42c88fb6 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h @@ -32,7 +32,7 @@ namespace CGAL { namespace Intersections { namespace internal { -template +template struct Tetrahedron_lines_intersection_3_base { typedef typename Intersection_traits res_points; Result_type output; - virtual bool all_inside_test() + bool all_inside_test() { return false; } - virtual bool are_extremities_inside_test() + bool are_extremities_inside_test() { return false; } - virtual ~Tetrahedron_lines_intersection_3_base() - {} void do_procede() { - if(all_inside_test()) + if(static_cast(this)->all_inside_test()) return; int res_id = -1; @@ -115,7 +113,7 @@ struct Tetrahedron_lines_intersection_3_base return; if(res_id != -1) { - if(are_extremities_inside_test()) + if(static_cast(this)->are_extremities_inside_test()) return; //else point and segment entirely not inside: output = tr_seg[res_id]; From e58b4475e7fbd6cbe09435c1fa2bebebbbcc63fd Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 17 Jun 2019 15:24:43 +0200 Subject: [PATCH 030/141] clean-up --- .../internal/Iso_cuboid_3_Plane_3_intersection.h | 8 +++----- .../internal/Tetrahedron_3_Plane_3_intersection.h | 12 +++++------- .../internal/tetrahedron_intersection_helpers.h | 3 +-- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h index 2715b9e40ae..9e292eaf6ee 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h @@ -37,7 +37,7 @@ namespace internal { template void filter_points(const std::vector& input, - std::vector& output) + std::vector& output) { std::set tmp; for( auto p : input) @@ -60,12 +60,10 @@ intersection( typedef typename K::Plane_3 Plane_3; typedef std::vector Poly; - typedef typename Intersection_traits, + typedef typename Intersection_traits, CGAL::Plane_3 >::result_type Result_type; - typedef typename Intersection_traits, + typedef typename Intersection_traits, CGAL::Plane_3 >::result_type Inter_type; std::vector edges; diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersection.h index 3a6353c9809..8dcb4cd085d 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersection.h @@ -60,9 +60,9 @@ intersection( std::vector segments; for(std::size_t i = 0; i < 4; ++i) { - const typename K::Triangle_3 triangle(tet.vertex((i+1)%4), - tet.vertex((i+2)%4), - tet.vertex((i+3)%4)); + const typename K::Triangle_3 triangle(tet.vertex((i+1)%4), + tet.vertex((i+2)%4), + tet.vertex((i+3)%4)); intersections[i] = typename K::Intersect_3()(pl, triangle); if(intersections[i]){ if(const typename K::Triangle_3* tr = boost::get(&*intersections[i])) @@ -95,7 +95,7 @@ intersection( else { typename K::Point_3 p - = *boost::get(&*intersections[p_id]); + = *boost::get(&*intersections[p_id]); return Result_type(std::forward(p)); } @@ -125,9 +125,7 @@ intersection( } else //size = 4 { - std::list segs; - for(auto s : segments) - segs.push_back(s); + std::list segs(segments.begin(), segments.end()); std::list tmp; fill_points_list(segs, tmp); std::vector res; diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h index 36785471ca3..4525a9ea032 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h @@ -43,8 +43,7 @@ void filter_segments(const std::vector& input, { Segment s = tmp.back(); tmp.pop_back(); - auto s_it = tmp.begin(); - for(; s_it != tmp.end();) + for(auto s_it = tmp.begin(); s_it != tmp.end();) { if(s == *s_it || s == s_it->opposite()) { From d9b09ef001032ef9e463c195593bf2907a8b0134 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 17 Jun 2019 15:54:25 +0200 Subject: [PATCH 031/141] Clean-up loop --- .../Intersections_3/internal/tetrahedron_intersection_helpers.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h index 4525a9ea032..c355a851fe9 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h @@ -81,7 +81,7 @@ void fill_segments_infos(std::vector& segments, wrapped_segments.push_back(Wrapped_segment(s)); std::vector bis = segments; - for(int dummy = 0; dummy < bis.size()-1; ++dummy) + while(!bis.empty()) { Segment s = bis.back(); bis.pop_back(); From 89b35a5b173b5f689e74cba65ed27841a74f227d Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Tue, 25 Jun 2019 13:15:51 +0200 Subject: [PATCH 032/141] Add missing case for Pl / Cub --- .../Iso_cuboid_3_Plane_3_intersection.h | 49 ++++++++++++++++++- .../Intersections_3/test_intersections_3.cpp | 22 +++++++-- 2 files changed, 65 insertions(+), 6 deletions(-) diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h index 9e292eaf6ee..c24ed9f552f 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h @@ -105,9 +105,54 @@ intersection( switch(segments.size()) { - case 1: //adj to an edge + case 1: { - return Result_type(std::forward(segments.front())); + //adj to an edge + if(points.size() == 4) + { + return Result_type(std::forward(segments.front())); + } + //through an edge not on diagonal + else{ + Poly res(4); + Segment_3 front(segments.front()); + Point_3 p1,p2; + bool has_p1(false), + has_p2(false); + for(auto p : points) + { + if(!front.has_on(p)) + { + if(!has_p1) + { + p1 = p; + has_p1 = true; + } + else { + p2 = p; + has_p2 = true; + break; + } + } + } + CGAL_assertion(has_p1 && has_p2); + Segment_3 back(p1,p2); + res[0] = front.target(); + if((front.target() - front.source()) + * (back.target() - back.source()) > 0) + { + res[1] = back.target(); + res[2] = back.source(); + } + else + { + res[1] = back.source(); + res[2] = back.target(); + } + res[3] = front.source(); + + return Result_type(std::forward(res)); + } } break; diff --git a/Intersections_3/test/Intersections_3/test_intersections_3.cpp b/Intersections_3/test/Intersections_3/test_intersections_3.cpp index ed5ad9d428c..e326680f295 100644 --- a/Intersections_3/test/Intersections_3/test_intersections_3.cpp +++ b/Intersections_3/test/Intersections_3/test_intersections_3.cpp @@ -891,6 +891,8 @@ struct Test { //edge check_intersection (cub, Pl(P(1,1,1), P(1,2,1), P(1.5,0,0)), S(P(1,2,1), P(1,1,1))); + + //face typedef typename CGAL::Intersection_traits >(&*res); + CGAL_assertion(poly != nullptr); + CGAL_assertion(poly->size() == 4); + for(auto p : *poly) + { + CGAL_assertion(pl.has_on(p) && cub.has_on_boundary(p)); + } + //random - Pl pl(0.265189, 0.902464, 0.33946, -2.47551); + pl = Pl(0.265189, 0.902464, 0.33946, -2.47551); res = CGAL::intersection(cub, pl); poly = boost::get >(&*res); CGAL_assertion(poly != nullptr); @@ -1197,10 +1211,10 @@ struct Test { int main() { - Test< CGAL::Simple_cartesian >().run(); - Test< CGAL::Homogeneous >().run(); +// Test< CGAL::Simple_cartesian >().run(); +// Test< CGAL::Homogeneous >().run(); Test< CGAL::Epeck >().run(true); - Test< CGAL::Homogeneous >().run(true); +// Test< CGAL::Homogeneous >().run(true); // TODO : test more kernels. } From 4f796c9ab5c10745ba4141215577dd142523cc0c Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Tue, 9 Jul 2019 11:47:01 +0200 Subject: [PATCH 033/141] Add missing do_intersect() and associated tests --- .../CGAL/Intersections_2/Circle_2_Line_2.h | 4 +- .../CGAL/Intersections_2/Circle_2_Ray_2.h | 57 +++++++++++++++++++ .../CGAL/Intersections_2/Circle_2_Segment_2.h | 57 +++++++++++++++++++ .../Intersections_2/Circle_2_Triangle_2.h | 57 +++++++++++++++++++ Intersections_2/include/CGAL/intersection_2.h | 4 ++ .../Intersections_2/test_intersections_2.cpp | 40 +++++++++++++ 6 files changed, 217 insertions(+), 2 deletions(-) create mode 100644 Intersections_2/include/CGAL/Intersections_2/Circle_2_Ray_2.h create mode 100644 Intersections_2/include/CGAL/Intersections_2/Circle_2_Segment_2.h create mode 100644 Intersections_2/include/CGAL/Intersections_2/Circle_2_Triangle_2.h diff --git a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Line_2.h b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Line_2.h index 49e7e90183b..472ba0ce4c4 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Line_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Line_2.h @@ -1,9 +1,9 @@ -// Copyright (c) 2000 +// Copyright (c) 2000 // Utrecht University (The Netherlands), // ETH Zurich (Switzerland), // INRIA Sophia-Antipolis (France), // Max-Planck-Institute Saarbruecken (Germany), -// and Tel-Aviv University (Israel). All rights reserved. +// and Tel-Aviv University (Israel). All rights reserved. // // This file is part of CGAL (www.cgal.org); you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public License as diff --git a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Ray_2.h b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Ray_2.h new file mode 100644 index 00000000000..63f7ace0629 --- /dev/null +++ b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Ray_2.h @@ -0,0 +1,57 @@ +// Copyright (c) 2019 +// GeometryFactory. All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// +// +// Author(s) : Maxime Gimeno + +#ifndef CGAL_INTERSECTIONS_2_CIRCLE_2_RAY_2_H +#define CGAL_INTERSECTIONS_2_CIRCLE_2_RAY_2_H + +#include +#include +#include +#include + +namespace CGAL { +namespace Intersections { +namespace internal { +template +bool +do_intersect(const typename K::Circle_2 & c, + const typename K::Ray_2& r, + const K&) +{ + return squared_distance(c.center(), r) <= c.squared_radius(); +} + +template +bool +do_intersect(const typename K::Ray_2& r, + const typename K::Circle_2 & c, + const K&) +{ + return squared_distance(c.center(), r) <= c.squared_radius(); +} + +} // namespace internal +} // namespace Intersections + +CGAL_DO_INTERSECT_FUNCTION(Circle_2, Ray_2, 2) + +} // namespace CGAL +#endif // CGAL_INTERSECTIONS_2_CIRCLE_2_RAY_2_H diff --git a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Segment_2.h b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Segment_2.h new file mode 100644 index 00000000000..de9128f56e2 --- /dev/null +++ b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Segment_2.h @@ -0,0 +1,57 @@ +// Copyright (c) 2019 +// GeometryFactory. All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// +// +// Author(s) : Maxime Gimeno + +#ifndef CGAL_INTERSECTIONS_2_CIRCLE_2_SEGMENT_2_H +#define CGAL_INTERSECTIONS_2_CIRCLE_2_SEGMENT_2_H + +#include +#include +#include +#include + +namespace CGAL { +namespace Intersections { +namespace internal { +template +bool +do_intersect(const typename K::Circle_2 & c, + const typename K::Segment_2& s, + const K&) +{ + return squared_distance(c.center(), s) <= c.squared_radius(); +} + +template +bool +do_intersect(const typename K::Segment_2& s, + const typename K::Circle_2 & c, + const K&) +{ + return squared_distance(c.center(), s) <= c.squared_radius(); +} + +} // namespace internal +} // namespace Intersections + +CGAL_DO_INTERSECT_FUNCTION(Circle_2, Segment_2, 2) + +} // namespace CGAL +#endif // CGAL_INTERSECTIONS_2_CIRCLE_2_SEGMENT_2_H diff --git a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Triangle_2.h b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Triangle_2.h new file mode 100644 index 00000000000..354b2253fcf --- /dev/null +++ b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Triangle_2.h @@ -0,0 +1,57 @@ +// Copyright (c) 2019 +// GeometryFactory. All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// +// +// Author(s) : Maxime Gimeno + +#ifndef CGAL_INTERSECTIONS_2_CIRCLE_2_TRIANGLE_2_H +#define CGAL_INTERSECTIONS_2_CIRCLE_2_TRIANGLE_2_H + +#include +#include +#include +#include + +namespace CGAL { +namespace Intersections { +namespace internal { +template +bool +do_intersect(const typename K::Circle_2 & c, + const typename K::Triangle_2& t, + const K&) +{ + return squared_distance(c.center(), t) <= c.squared_radius(); +} + +template +bool +do_intersect(const typename K::Triangle_2& t, + const typename K::Circle_2 & c, + const K&) +{ + return squared_distance(c.center(), t) <= c.squared_radius(); +} + +} // namespace internal +} // namespace Intersections + +CGAL_DO_INTERSECT_FUNCTION(Circle_2, Triangle_2, 2) + +} // namespace CGAL +#endif // CGAL_INTERSECTIONS_2_CIRCLE_2_TRIANGLE_2_H diff --git a/Intersections_2/include/CGAL/intersection_2.h b/Intersections_2/include/CGAL/intersection_2.h index 188bdd4e553..a3184c5f4df 100644 --- a/Intersections_2/include/CGAL/intersection_2.h +++ b/Intersections_2/include/CGAL/intersection_2.h @@ -37,6 +37,10 @@ #include #include #include +#include +#include +#include + #include #include diff --git a/Intersections_2/test/Intersections_2/test_intersections_2.cpp b/Intersections_2/test/Intersections_2/test_intersections_2.cpp index f501bf75211..635b3b1e71f 100644 --- a/Intersections_2/test/Intersections_2/test_intersections_2.cpp +++ b/Intersections_2/test/Intersections_2/test_intersections_2.cpp @@ -318,6 +318,43 @@ struct Test check_intersection

(C(p( 0, 0), 25) , p( 5, 0)); } + void C_S() + { + std::cout << "Circle - Segment" << std::endl; + + check_no_do_intersect (C(p( 2, 8), 6), S(p(-3, -2), p( 2, -4))); + check_no_do_intersect (C(p( 2, 8), 6), S(p(-3, 22), p( 2, 34))); + + check_do_intersect (C(p( 3, 4), 0), S(p(-3, 8), p( 6, 2))); + check_do_intersect (C(p( 4, 3), 4), S(p( 6, -7), p( 5, 2))); + + check_do_intersect (C(p(-3, 1), 7), S(p(-1, -3), p(-6, 7))); + } + + void C_R() + { + std::cout << "Circle - Ray" << std::endl; + + check_no_do_intersect (C(p( 2, 8), 6), R(p(-3, -2), p( 2, -4))); + check_no_do_intersect (C(p( 2, 8), 6), R(p(-3, 22), p( 2, 34))); + + check_do_intersect (C(p( 3, 4), 0), R(p(-3, 8), p( 6, 2))); + check_do_intersect (C(p( 4, 3), 4), R(p( 6, -7), p( 5, 2))); + + check_do_intersect (C(p(-3, 1), 7), R(p(-1, -3), p(-6, 7))); + } + + void C_T() + { + std::cout << "Circle - Triangle" << std::endl; + check_no_do_intersect (C(p( 2, 8), 6), T(p(6,0), p( 8, 0), p(8,2))); + + check_do_intersect (C(p( 3, 4), 0), T(p(-3, 8), p( 6, 2), p(4,6))); + check_do_intersect (C(p( 4, 3), 4), T(p( 6, -7), p( 5, 2), p(2,-3))); + + check_do_intersect (C(p( 4, 3), 4), T(p( 6, -7), p( 4, 6), p(2,-3))); + } + void L_L() { std::cout << "Line - Line" << std::endl; @@ -761,6 +798,9 @@ struct Test C_Rec(); C_L(); C_P(); + C_S(); + C_R(); + C_T(); Rec_Rec(); Rec_L(); From 2424caf12643ff5a49741965b690d1eb8b87bdc4 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Tue, 9 Jul 2019 14:11:28 +0200 Subject: [PATCH 034/141] Remove that assertion In a multi-threaded application, the double map can be modified while the `size()` function is queried. That is a race-condition. We usually do not care, because the query is here only to display messages, but we do not want the assertion to trigger because the two sides of the double map were being modified while another thread calls `is_valid()`. --- Mesher_level/include/CGAL/Double_map.h | 1 - 1 file changed, 1 deletion(-) diff --git a/Mesher_level/include/CGAL/Double_map.h b/Mesher_level/include/CGAL/Double_map.h index 7de1f9d66e6..dbeba570b90 100644 --- a/Mesher_level/include/CGAL/Double_map.h +++ b/Mesher_level/include/CGAL/Double_map.h @@ -138,7 +138,6 @@ public : size_type size() const { - CGAL_assertion(is_valid()); return direct_func().size(); } From e068363fbfac2f142e6ef05e2efd128253ea6aad Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Tue, 9 Jul 2019 14:14:09 +0200 Subject: [PATCH 035/141] Add an API to replace QMessageBox static functions .. and possibly compatible with scripts (not yet implemented). --- Polyhedron/demo/Polyhedron/Three.cpp | 13 +++++++++++++ Three/include/CGAL/Three/Three.h | 20 ++++++++++++++++++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Three.cpp b/Polyhedron/demo/Polyhedron/Three.cpp index 6c7641af2b2..7c4489854e5 100644 --- a/Polyhedron/demo/Polyhedron/Three.cpp +++ b/Polyhedron/demo/Polyhedron/Three.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "Messages_interface.h" using namespace CGAL::Three; @@ -175,6 +176,18 @@ void Three::error(QString s) { qobject_cast(mainWindow())->message_error(s); } +void Three::information(QString title, QString s) +{ + QMessageBox::information(mainWindow(), title, s); +} +void Three::warning(QString title, QString s) +{ + QMessageBox::warning(mainWindow(), title, s); +} +void Three::error(QString title, QString s) +{ + QMessageBox::critical(mainWindow(), title, s); +} RenderingMode Three::defaultSurfaceMeshRenderingMode() { return s_defaultSMRM; diff --git a/Three/include/CGAL/Three/Three.h b/Three/include/CGAL/Three/Three.h index 71cd9847f1e..e2c0f41dd57 100644 --- a/Three/include/CGAL/Three/Three.h +++ b/Three/include/CGAL/Three/Three.h @@ -82,15 +82,31 @@ public: * in the plugin. */ static void autoConnectActions(CGAL::Three::Polyhedron_demo_plugin_interface* plugin); + /*! + * Displays in the console a blue text preceded by the mention + * "INFO: ". + */ static void information(QString); /*! - * Displays a blue text preceded by the mention "WARNING :". + * Displays in the console an orange text preceded by the mention "WARNING: ". */ static void warning(QString); /*! - * Displays a red text preceded by the mention "ERROR :". + * Displays in the console a red text preceded by the mention "ERROR: ". */ static void error(QString); + /*! + * Displays an information popup. + */ + static void information(QString title, QString message); + /*! + * Displays a warning popup. + */ + static void warning(QString title, QString message); + /*! + * Displays an error popup. + */ + static void error(QString title, QString message); protected: static QMainWindow* s_mainwindow; static Viewer_interface* s_mainviewer; From 15dca64f4f8dd94dbb1801a1e3eccb28ac56cd95 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Wed, 10 Jul 2019 10:12:46 +0200 Subject: [PATCH 036/141] Initialize that value even when it is not used --- .../demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.cpp index 3425d41f357..5761dc4dab9 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.cpp @@ -161,6 +161,9 @@ Meshing_thread* cgal_code_mesh_3(const Implicit_function_interface* pfunction, param.tet_shape = tet_shape; param.edge_sizing = edge_size; param.manifold = manifold; + param.detect_connected_components = false; // to avoid random values + // in the debug displays + typedef ::Mesh_function Mesh_function; From 03a591099de7a5c22b60d6d28c0e73bd9996d3f7 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Fri, 12 Jul 2019 13:33:03 +0200 Subject: [PATCH 037/141] Make mesh_3_plugin scriptable --- .../Plugins/Mesh_3/Mesh_3_plugin.cpp | 261 ++++++++++++------ 1 file changed, 171 insertions(+), 90 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp index 804beed5389..267f5ccd58c 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp @@ -39,6 +39,7 @@ const QColor default_mesh_color(45,169,70); #include "Mesh_3_plugin_cgal_code.h" // declare functions `cgal_code_mesh_3` #include "split_polylines.h" +#include class Mesh_3_plugin : public QObject, @@ -48,6 +49,25 @@ class Mesh_3_plugin : Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "mesh_3_plugin.json") + Q_PROPERTY(double angle READ get_angle WRITE set_angle); + Q_PROPERTY(double sharp_edges_angle_bound + READ get_sharp_edges_angle_bound + WRITE set_sharp_edges_angle_bound); + Q_PROPERTY(double edges_sizing READ get_edges_sizing WRITE set_edges_sizing); + Q_PROPERTY(double facets_sizing READ get_facets_sizing WRITE set_facets_sizing); + Q_PROPERTY(double approx READ get_approx WRITE set_approx); + Q_PROPERTY(double tets_sizing READ get_tets_sizing WRITE set_tets_sizing); + Q_PROPERTY(double tets_shape READ get_tets_shape WRITE set_tets_shape); + Q_PROPERTY(bool protect_features READ get_protect_features WRITE set_protect_features); + Q_PROPERTY(bool protect_borders READ get_protect_borders WRITE set_protect_borders); + Q_PROPERTY(bool manifold_criterion READ get_manifold_criterion WRITE set_manifold_criterion); + + typedef CGAL::Mesh_facet_topology Mesh_facet_topology; + Q_ENUMS(Mesh_facet_topology) + Q_PROPERTY(Mesh_facet_topology facet_topology + READ get_facet_topology + WRITE set_facet_topology) + public: void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, @@ -113,15 +133,47 @@ public: } public Q_SLOTS: + boost::optional get_items_or_return_error_string(); + void set_defaults(); void mesh_3_volume(); void mesh_3_surface(); - void mesh_3_surface_with_defaults() { mesh_3(true, true); } + void mesh_3_surface_with_defaults() { mesh_3(Mesh_type::SURFACE_ONLY, Dialog_choice::NO_DIALOG); } void splitPolylines(); void meshing_done(Meshing_thread* t); void status_report(QString str); +public Q_SLOTS: + void set_angle(const double v) { angle = v; }; + void set_sharp_edges_angle_bound(const double v) { + sharp_edges_angle_bound = v; + } + void set_edges_sizing(const double v) { edges_sizing = v; }; + void set_facets_sizing(const double v) { facets_sizing = v; }; + void set_approx(const double v) { approx = v; }; + void set_tets_sizing(const double v) { tets_sizing = v; }; + void set_tets_shape(const double v) { tets_shape = v; }; + void set_manifold_criterion(const bool v) { manifold_criterion = v; } + void set_facet_topology(const CGAL::Mesh_facet_topology v) { facet_topology = v; } + void set_protect_features(const bool v) { protect_features = v; }; + void set_protect_borders(const bool v) { protect_borders = v; }; + + double get_angle() { return angle; }; + double get_sharp_edges_angle_bound() { return sharp_edges_angle_bound; } + double get_edges_sizing() { return edges_sizing; }; + double get_facets_sizing() { return facets_sizing; }; + double get_approx() { return approx; }; + double get_tets_sizing() { return tets_sizing; }; + double get_tets_shape() { return tets_shape; }; + bool get_manifold_criterion() { return manifold_criterion; }; + CGAL::Mesh_facet_topology get_facet_topology() { return facet_topology; }; + bool get_protect_features() { return protect_features; }; + bool get_protect_borders() { return protect_borders; }; + + private: - void mesh_3(const bool surface_only, const bool use_defaults = false); + enum class Mesh_type : bool { VOLUME, SURFACE_ONLY }; + enum class Dialog_choice : bool { NO_DIALOG, DIALOG }; + void mesh_3(const Mesh_type mesh_type, const Dialog_choice dialog = Dialog_choice::DIALOG); void launch_thread(Meshing_thread* mesh_thread); void treat_result(Scene_item& source_item, Scene_c3t3_item* result_item) const; @@ -136,6 +188,30 @@ private: CGAL::Three::Scene_interface* scene; QMainWindow* mw; bool as_facegraph; + + double angle; + double sharp_edges_angle_bound; + int sizing_decimals; + int decimals = 0; + double approx; + int approx_decimals; + double edges_sizing; + double facets_sizing; + double tets_sizing; + double tets_shape; + bool manifold_criterion; + CGAL::Mesh_facet_topology facet_topology; + bool protect_features; + bool protect_borders; + + QList sm_items = {}; + Scene_surface_mesh_item* bounding_sm_item = nullptr; + Scene_implicit_function_item* function_item = nullptr; + Scene_image_item* image_item = nullptr; + Scene_polylines_item* polylines_item = nullptr; + bool features_protection_available = false; + Scene_item* item = nullptr; + CGAL::Three::Scene_interface::Bbox bbox = {}; }; // end class Mesh_3_plugin double @@ -168,21 +244,22 @@ void Mesh_3_plugin::splitPolylines() { void Mesh_3_plugin::mesh_3_surface() { - mesh_3(true); + mesh_3(Mesh_type::SURFACE_ONLY); } void Mesh_3_plugin::mesh_3_volume() { - mesh_3(false); + mesh_3(Mesh_type::VOLUME); } -void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults) -{ - QList sm_items; - Scene_surface_mesh_item* bounding_sm_item = nullptr; - Scene_implicit_function_item* function_item = nullptr; - Scene_image_item* image_item = nullptr; - Scene_polylines_item* polylines_item = nullptr; - +boost::optional Mesh_3_plugin::get_items_or_return_error_string() { + sm_items.clear(); + bounding_sm_item = nullptr; + function_item = nullptr; + image_item = nullptr; + polylines_item = nullptr; + features_protection_available = false; + item = nullptr; + function_item = nullptr; for(int ind: scene->selectionIndices()) { Scene_surface_mesh_item* sm_item = qobject_cast(scene->item(ind)); @@ -207,36 +284,24 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults) nullptr != (polylines_item = qobject_cast(scene->item(ind)))) {} else { - QMessageBox::warning(mw, tr("Mesh_3 plugin"), - tr("Wrong selection of items")); - return; + return tr("Wrong selection of items"); } } - Scene_item* item = nullptr; - const bool more_than_one_item = sm_items.size() > 1; - bool features_protection_available = false; + item = nullptr; + features_protection_available = false; if(!sm_items.empty()) { for(auto sm_item : sm_items) { if(nullptr == sm_item->polyhedron()) { - QApplication::restoreOverrideCursor(); - QMessageBox::critical(mw, tr("Mesh_3 plugin"), - tr("ERROR: no data in selected item %1").arg(sm_item->name())); - return; + return tr("ERROR: no data in selected item %1").arg(sm_item->name()); } - if (!is_triangle_mesh(*sm_item->polyhedron())) - { - QApplication::restoreOverrideCursor(); - QMessageBox::warning(mw, tr("Mesh_3 plugin"), - tr("Selected Scene_surface_mesh_item %1 is not triangulated.") - .arg(sm_item->name())); - return; + if (!is_triangle_mesh(*sm_item->polyhedron())) { + return tr("Selected Scene_surface_mesh_item %1 is not triangulated.") + .arg(sm_item->name()); } if(sm_item->getNbIsolatedvertices() != 0) { - QApplication::restoreOverrideCursor(); - QMessageBox::critical(mw, tr(""), tr("ERROR: there are isolated vertices in this mesh.")); - return; + return tr("ERROR: there are isolated vertices in this mesh."); } } item = sm_items.front(); @@ -273,19 +338,43 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults) } if(!fit_wrdtp) { - QMessageBox::warning(mw, tr(""), - tr("Selected object can't be meshed because the image's word type is not supported by this plugin.")); - return; + return tr("Selected object can't be meshed because the image's word type is not supported by this plugin."); } } #endif if (nullptr == item) { - QMessageBox::warning(mw, tr(""), - tr("Selected object can't be meshed")); + return tr("Selected object can't be meshed"); + } + bbox = item->bbox(); + for(auto it: sm_items) { + bbox = bbox + it->bbox(); + } + return {}; +} + +void Mesh_3_plugin::set_defaults() { + auto error = get_items_or_return_error_string(); + if(error) return; + double diag = CGAL::sqrt((bbox.xmax()-bbox.xmin())*(bbox.xmax()-bbox.xmin()) + (bbox.ymax()-bbox.ymin())*(bbox.ymax()-bbox.ymin()) + (bbox.zmax()-bbox.zmin())*(bbox.zmax()-bbox.zmin())); + facets_sizing = get_approximate(diag * 0.05, 2, sizing_decimals); + edges_sizing = facets_sizing; + tets_sizing = facets_sizing; + angle = 25.; + sharp_edges_angle_bound = 60.; + approx = get_approximate(diag * 0.005, 2, approx_decimals); +} + +void Mesh_3_plugin::mesh_3(const Mesh_type mesh_type, const Dialog_choice dialog_choice) +{ + auto error_string = get_items_or_return_error_string(); + if(error_string) { + QApplication::restoreOverrideCursor(); + QMessageBox::warning(mw, tr("Mesh_3 plugin"), *error_string); return; } + const bool more_than_one_item = sm_items.size() > 1; // ----------------------------------- // Create Mesh dialog // ----------------------------------- @@ -345,54 +434,45 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults) QString("%1...").arg(item->name()) : item->name(); - // Set default parameters - CGAL::Three::Scene_interface::Bbox bbox = item->bbox(); - if(more_than_one_item) { - for(auto it: sm_items) { - bbox = bbox + it->bbox(); - } - } ui.objectName->setText(item_name); ui.objectNameSize->setText(tr("Object bbox size (w,h,d): %1, %2, %3") .arg(bbox.xmax() - bbox.xmin(),0,'g',3) .arg(bbox.ymax() - bbox.ymin(),0,'g',3) .arg(bbox.zmax() - bbox.zmin(),0,'g',3) ); - + set_defaults(); double diag = CGAL::sqrt((bbox.xmax()-bbox.xmin())*(bbox.xmax()-bbox.xmin()) + (bbox.ymax()-bbox.ymin())*(bbox.ymax()-bbox.ymin()) + (bbox.zmax()-bbox.zmin())*(bbox.zmax()-bbox.zmin())); - int decimals = 0; - double sizing_default = get_approximate(diag * 0.05, 2, decimals); - ui.facetSizing->setDecimals(-decimals+2); - ui.facetSizing->setSingleStep(std::pow(10.,decimals)); + ui.facetSizing->setDecimals(-sizing_decimals+2); + ui.facetSizing->setSingleStep(std::pow(10.,sizing_decimals)); ui.facetSizing->setRange(diag * 10e-6, // min diag); // max - ui.facetSizing->setValue(sizing_default); // default value - ui.edgeSizing->setValue(sizing_default); + ui.facetSizing->setValue(facets_sizing); // default value + ui.edgeSizing->setValue(edges_sizing); - ui.tetSizing->setDecimals(-decimals+2); - ui.tetSizing->setSingleStep(std::pow(10.,decimals)); + ui.tetSizing->setDecimals(-sizing_decimals+2); + ui.tetSizing->setSingleStep(std::pow(10.,sizing_decimals)); ui.tetSizing->setRange(diag * 10e-6, // min diag); // max - ui.tetSizing->setValue(sizing_default); // default value + ui.tetSizing->setValue(tets_sizing); // default value - double approx_default = get_approximate(diag * 0.005, 2, decimals); - ui.approx->setDecimals(-decimals+2); - ui.approx->setSingleStep(std::pow(10.,decimals)); + ui.approx->setDecimals(-approx_decimals+2); + ui.approx->setSingleStep(std::pow(10.,approx_decimals)); ui.approx->setRange(diag * 10e-7, // min diag); // max - ui.approx->setValue(approx_default); + ui.approx->setValue(approx); ui.protect->setEnabled(features_protection_available); ui.protect->setChecked(features_protection_available); ui.protectEdges->setEnabled(features_protection_available); - ui.facegraphCheckBox->setVisible(surface_only); + ui.facegraphCheckBox->setVisible(mesh_type == Mesh_type::SURFACE_ONLY); ui.initializationGroup->setVisible(image_item != nullptr && !image_item->isGray()); ui.grayImgGroup->setVisible(image_item != nullptr && image_item->isGray()); if (!sm_items.empty()) - ui.volumeGroup->setVisible(!surface_only && nullptr != bounding_sm_item); + ui.volumeGroup->setVisible(mesh_type == Mesh_type::VOLUME && nullptr != bounding_sm_item); else - ui.volumeGroup->setVisible(!surface_only); - if ((!sm_items.empty())|| polylines_item != nullptr) { + ui.volumeGroup->setVisible(mesh_type == Mesh_type::VOLUME); + ui.sharpEdgesAngle->setValue(sharp_edges_angle_bound); + if (sm_items.empty()|| polylines_item != nullptr) { ui.sharpEdgesAngleLabel->setVisible(false); ui.sharpEdgesAngle->setVisible(false); @@ -410,7 +490,7 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults) { if (!sm_items.empty()) { - if (surface_only) + if (mesh_type == Mesh_type::SURFACE_ONLY) { ui.protectEdges->addItem(QString("Sharp and Boundary edges")); ui.protectEdges->addItem(QString("Boundary edges only")); @@ -434,21 +514,22 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults) //reset cursor from the code for the scripts QApplication::restoreOverrideCursor(); - if(!use_defaults) { + if(dialog_choice == Dialog_choice::DIALOG) { int i = dialog.exec(); if( i == QDialog::Rejected ) { return; } } // 0 means parameter is not considered - const double angle = !ui.noAngle->isChecked() ? 0 : ui.facetAngle->value(); - const double approx = !ui.noApprox->isChecked() ? 0 : ui.approx->value(); - const double facet_sizing = !ui.noFacetSizing->isChecked() ? 0 : ui.facetSizing->value(); - const double radius_edge = !ui.noTetShape->isChecked() ? 0 : ui.tetShape->value(); - const double tet_sizing = !ui.noTetSizing->isChecked() ? 0 : ui.tetSizing->value(); - const double edge_size = !ui.noEdgeSizing->isChecked() ? DBL_MAX : ui.edgeSizing->value(); - const bool protect_features = ui.protect->isChecked() && (ui.protectEdges->currentIndex() == 0); - const bool protect_borders = ui.protect->isChecked() && (ui.protectEdges->currentIndex() == 1); - const double sharp_edges_angle = ui.sharpEdgesAngle->value(); + angle = !ui.noAngle->isChecked() ? 0 : ui.facetAngle->value(); + sharp_edges_angle_bound = ui.sharpEdgesAngle->value(); + std::cerr << "sharp_edges_angle_bound: " << sharp_edges_angle_bound << '\n'; + edges_sizing = !ui.noEdgeSizing->isChecked() ? DBL_MAX : ui.edgeSizing->value(); + facets_sizing = !ui.noFacetSizing->isChecked() ? 0 : ui.facetSizing->value(); + approx = !ui.noApprox->isChecked() ? 0 : ui.approx->value(); + tets_shape = !ui.noTetShape->isChecked() ? 0 : ui.tetShape->value(); + tets_sizing = !ui.noTetSizing->isChecked() ? 0 : ui.tetSizing->value(); + protect_features = ui.protect->isChecked() && (ui.protectEdges->currentIndex() == 0); + protect_borders = ui.protect->isChecked() && (ui.protectEdges->currentIndex() == 1); const bool detect_connected_components = ui.detectComponents->isChecked(); const int manifold = (ui.manifoldCheckBox->isChecked() ? 1 : 0) @@ -456,7 +537,7 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults) const float iso_value = float(ui.iso_value_spinBox->value()); const float value_outside = float(ui.value_outside_spinBox->value()); const float inside_is_less = float(ui.inside_is_less_checkBox->isChecked()); - as_facegraph = surface_only ? ui.facegraphCheckBox->isChecked() : false; + as_facegraph = (mesh_type == Mesh_type::SURFACE_ONLY) ? ui.facegraphCheckBox->isChecked() : false; Meshing_thread* thread = nullptr; if (!sm_items.empty()) @@ -477,16 +558,16 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults) bounding_polyhedron, item_name, angle, - facet_sizing, + facets_sizing, approx, - tet_sizing, - edge_size, - radius_edge, + tets_sizing, + edges_sizing, + tets_shape, protect_features, protect_borders, - sharp_edges_angle, + sharp_edges_angle_bound, manifold, - surface_only); + mesh_type == Mesh_type::SURFACE_ONLY); } // Image #ifdef CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS @@ -501,13 +582,13 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults) thread = cgal_code_mesh_3(pFunction, angle, - facet_sizing, + facets_sizing, approx, - tet_sizing, - edge_size, - radius_edge, + tets_sizing, + edges_sizing, + tets_shape, manifold, - surface_only); + mesh_type == Mesh_type::SURFACE_ONLY); } #endif #ifdef CGAL_MESH_3_DEMO_ACTIVATE_SEGMENTED_IMAGES @@ -525,14 +606,14 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults) thread = cgal_code_mesh_3(pImage, (polylines_item == nullptr)?plc:polylines_item->polylines, angle, - facet_sizing, + facets_sizing, approx, - tet_sizing, - edge_size, - radius_edge, + tets_sizing, + edges_sizing, + tets_shape, protect_features, manifold, - surface_only, + mesh_type == Mesh_type::SURFACE_ONLY, detect_connected_components, image_item->isGray(), iso_value, From 876505bdec0a22e7f11428568ba9dbdcfe829d79 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Fri, 12 Jul 2019 13:28:18 +0200 Subject: [PATCH 038/141] Fix a bug in applicable() by rearranging completly the private data In passing, I have used - the Guidelines Support Library (actually `gsl::not_null`), - `boost::optional` and `boost::variant` to better deal with the state of private data. --- .../CGAL_setup_GuidelinesSupportLibrary.cmake | 16 + Polyhedron/demo/Polyhedron/CMakeLists.txt | 3 +- .../Polyhedron/Plugins/Mesh_3/CMakeLists.txt | 2 +- .../Plugins/Mesh_3/Mesh_3_plugin.cpp | 565 ++++++++++-------- 4 files changed, 334 insertions(+), 252 deletions(-) create mode 100644 Installation/cmake/modules/CGAL_setup_GuidelinesSupportLibrary.cmake diff --git a/Installation/cmake/modules/CGAL_setup_GuidelinesSupportLibrary.cmake b/Installation/cmake/modules/CGAL_setup_GuidelinesSupportLibrary.cmake new file mode 100644 index 00000000000..b77f5edd010 --- /dev/null +++ b/Installation/cmake/modules/CGAL_setup_GuidelinesSupportLibrary.cmake @@ -0,0 +1,16 @@ +if(NOT TARGET cxx::gsl) + include(ExternalProject) + ExternalProject_Add(gsl-download + URL https://github.com/microsoft/GSL/archive/v2.0.0.tar.gz + DOWNLOAD_NAME GSL-2.0.0.tar.gz + URL_HASH SHA512=7339527222c8a97a94c0bb4038b3d142045ec5d80995e628574ac96f4d9d13c41ad70fbe0d8390586dc0db8d9ea55107dbc95de80f7335eb78ef9d2e7047d726 + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + ) + ExternalProject_Get_Property(gsl-download source_dir) + add_library(CGAL-Microsoft-gsl INTERFACE) + target_include_directories(CGAL-Microsoft-gsl SYSTEM INTERFACE ${source_dir}/include) + add_dependencies(CGAL-Microsoft-gsl gsl-download) + add_library(cxx::gsl ALIAS CGAL-Microsoft-gsl) +endif() diff --git a/Polyhedron/demo/Polyhedron/CMakeLists.txt b/Polyhedron/demo/Polyhedron/CMakeLists.txt index d1c810bba9c..2917c88831f 100644 --- a/Polyhedron/demo/Polyhedron/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/CMakeLists.txt @@ -122,8 +122,7 @@ else( CGAL_ACTIVATE_CONCURRENT_MESH_3 OR ENV{CGAL_ACTIVATE_CONCURRENT_MESH_3} ) endif( LINK_WITH_TBB ) endif() - - +include(CGAL_setup_GuidelinesSupportLibrary) if(CGAL_Qt5_FOUND AND Qt5_FOUND) include(${CGAL_USE_FILE}) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/CMakeLists.txt index 9db4d61b2e1..9939bf1dc8d 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/CMakeLists.txt @@ -8,7 +8,7 @@ qt5_wrap_ui( meshingUI_FILES Meshing_dialog.ui Smoother_dialog.ui Local_optimiz polyhedron_demo_plugin(mesh_3_plugin Mesh_3_plugin Mesh_3_plugin_cgal_code.cpp Meshing_thread.cpp split_polylines.cpp ${meshingUI_FILES} KEYWORDS Mesh_3) -target_link_libraries(mesh_3_plugin PUBLIC scene_polygon_soup_item scene_polylines_item scene_implicit_function_item scene_image_item +target_link_libraries(mesh_3_plugin PUBLIC cxx::gsl scene_polygon_soup_item scene_polylines_item scene_implicit_function_item scene_image_item scene_surface_mesh_item scene_c3t3_item ${OPENGL_gl_LIBRARY} ) find_package(VTK QUIET COMPONENTS diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp index 267f5ccd58c..d7fe399d902 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp @@ -19,6 +19,9 @@ #include #include +#include +#include +#include #include "Scene_polylines_item.h" #ifdef CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS @@ -111,29 +114,11 @@ public: return qobject_cast (scene->item(scene->mainSelectionIndex())) != nullptr; } -#ifdef CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS - if(qobject_cast - (scene->item(scene->mainSelectionIndex())) != nullptr) { - return true; - } -#endif -#ifdef CGAL_MESH_3_DEMO_ACTIVATE_SEGMENTED_IMAGES - if( qobject_cast - (scene->item(scene->mainSelectionIndex())) != nullptr ) { - return true; - } -#endif - for(int ind: scene->selectionIndices()){ - Scene_surface_mesh_item* sm_item - = qobject_cast(scene->item(ind)); - if(nullptr == sm_item) - return false; - } - return true; + return !get_items_or_return_error_string(); } public Q_SLOTS: - boost::optional get_items_or_return_error_string(); + boost::optional get_items_or_return_error_string() const; void set_defaults(); void mesh_3_volume(); void mesh_3_surface(); @@ -204,14 +189,31 @@ private: bool protect_features; bool protect_borders; - QList sm_items = {}; - Scene_surface_mesh_item* bounding_sm_item = nullptr; - Scene_implicit_function_item* function_item = nullptr; - Scene_image_item* image_item = nullptr; - Scene_polylines_item* polylines_item = nullptr; - bool features_protection_available = false; - Scene_item* item = nullptr; - CGAL::Three::Scene_interface::Bbox bbox = {}; + struct Polyhedral_mesh_items { + Polyhedral_mesh_items() noexcept + : sm_items{}, bounding_sm_item(nullptr), polylines_item(nullptr) {} + QList> sm_items; + Scene_surface_mesh_item* bounding_sm_item; + Scene_polylines_item* polylines_item; + }; + struct Image_mesh_items { + gsl::not_null image_item; + }; + struct Implicit_mesh_items { + gsl::not_null function_item; + }; + enum Item_types { + POLYHEDRAL_MESH_ITEMS, + IMAGE_MESH_ITEMS, + IMPLICIT_MESH_ITEMS + }; + mutable boost::optional> + items; + mutable bool features_protection_available = false; + mutable Scene_item* item = nullptr; + mutable CGAL::Three::Scene_interface::Bbox bbox = {}; }; // end class Mesh_3_plugin double @@ -251,105 +253,117 @@ void Mesh_3_plugin::mesh_3_volume() mesh_3(Mesh_type::VOLUME); } -boost::optional Mesh_3_plugin::get_items_or_return_error_string() { - sm_items.clear(); - bounding_sm_item = nullptr; - function_item = nullptr; - image_item = nullptr; - polylines_item = nullptr; +boost::optional Mesh_3_plugin::get_items_or_return_error_string() const { + using boost::get; + items = {}; features_protection_available = false; item = nullptr; - function_item = nullptr; - for(int ind: scene->selectionIndices()) { - Scene_surface_mesh_item* sm_item = - qobject_cast(scene->item(ind)); - if(sm_item) { - sm_items.push_back(sm_item); - if(is_closed(*sm_item->polyhedron())) { - bounding_sm_item = sm_item; + for (int ind : scene->selectionIndices()) { + try { + if (auto sm_item = + qobject_cast(scene->item(ind))) { + if (!items) items = Polyhedral_mesh_items{}; + auto& poly_items = get(*items); + auto& sm_items = poly_items.sm_items; + sm_items.push_back(gsl::make_not_null(sm_item)); + if (is_closed(*sm_item->polyhedron())) { + poly_items.bounding_sm_item = sm_item; + } } - } -#ifdef CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS - else if(function_item == nullptr && - nullptr != - (function_item = qobject_cast(scene->item(ind)))) - {} -#endif -#ifdef CGAL_MESH_3_DEMO_ACTIVATE_SEGMENTED_IMAGES - else if(image_item == nullptr && - nullptr != (image_item = qobject_cast(scene->item(ind)))) - {} -#endif - else if(polylines_item == nullptr && - nullptr != (polylines_item = qobject_cast(scene->item(ind)))) - {} - else { - return tr("Wrong selection of items"); - } - } +# ifdef CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS + else if (auto function_item = qobject_cast( + scene->item(ind))) { + if (!items) + items = Implicit_mesh_items{gsl::make_not_null(function_item)}; + else + return tr( + "An implicit function cannot be mixed with other items type"); + } +# endif +# ifdef CGAL_MESH_3_DEMO_ACTIVATE_SEGMENTED_IMAGES + else if (auto image_item = + qobject_cast(scene->item(ind))) { + if (!items) + items = Image_mesh_items{gsl::make_not_null(image_item)}; + else + return tr("An image items cannot be mixed with other items type"); + } +# endif + else if (auto polylines_item = + qobject_cast(scene->item(ind))) { + if (!items) items = Polyhedral_mesh_items{}; + auto& poly_items = get(*items); + if (poly_items.polylines_item) { + return tr("Only one polyline item is accepted"); + } else { + poly_items.polylines_item = polylines_item; + } + } else { + return tr("Wrong selection of items"); + } + } catch (const boost::bad_get&) { return tr("Wrong selection of items"); } + } // end for loop on selected items + if (!items) { return tr("Selected objects can't be meshed"); } item = nullptr; features_protection_available = false; - if(!sm_items.empty()) - { - for(auto sm_item : sm_items) { - if(nullptr == sm_item->polyhedron()) { + if (auto poly_items = get(&*items)) { + auto& sm_items = poly_items->sm_items; + for (auto sm_item : sm_items) { + if (nullptr == sm_item->polyhedron()) { return tr("ERROR: no data in selected item %1").arg(sm_item->name()); } if (!is_triangle_mesh(*sm_item->polyhedron())) { return tr("Selected Scene_surface_mesh_item %1 is not triangulated.") - .arg(sm_item->name()); + .arg(sm_item->name()); } - if(sm_item->getNbIsolatedvertices() != 0) - { + if (sm_item->getNbIsolatedvertices() != 0) { return tr("ERROR: there are isolated vertices in this mesh."); } } - item = sm_items.front(); + if (!sm_items.empty()) item = sm_items.front(); features_protection_available = true; } -#ifdef CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS - else if (nullptr != function_item) { item = function_item; } -#endif -#ifdef CGAL_MESH_3_DEMO_ACTIVATE_SEGMENTED_IMAGES - else if (nullptr != image_item) - { +# ifdef CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS + else if (auto implicit_mesh_items = get(&*items)) { + item = implicit_mesh_items->function_item; + } +# endif +# ifdef CGAL_MESH_3_DEMO_ACTIVATE_SEGMENTED_IMAGES + else if (auto image_mesh_items = get(&*items)) { + auto& image_item = image_mesh_items->image_item; item = image_item; features_protection_available = true; bool fit_wrdtp = true; std::size_t img_wdim = image_item->image()->image()->wdim; WORD_KIND img_wordKind = image_item->image()->image()->wordKind; - //check if the word type fits the hardcoded values in the plugin - if(image_item->isGray()) - { - if(img_wordKind != WK_FLOAT) + // check if the word type fits the hardcoded values in the plugin + if (image_item->isGray()) { + if (img_wordKind != WK_FLOAT) fit_wrdtp = false; - else - if(img_wdim != 4) - fit_wrdtp = false; - } - else - { - if(img_wordKind != WK_FIXED) + else if (img_wdim != 4) + fit_wrdtp = false; + } else { + if (img_wordKind != WK_FIXED) + fit_wrdtp = false; + else if (img_wdim != 1) fit_wrdtp = false; - else - if(img_wdim != 1) - fit_wrdtp = false; } - if(!fit_wrdtp) - { - return tr("Selected object can't be meshed because the image's word type is not supported by this plugin."); + if (!fit_wrdtp) { + return tr( + "Selected object can't be meshed because the image's word type is " + "not supported by this plugin."); } } -#endif +# endif - if (nullptr == item) - { - return tr("Selected object can't be meshed"); - } bbox = item->bbox(); - for(auto it: sm_items) { - bbox = bbox + it->bbox(); + if (auto poly_items = get(&*items)) { + for (auto it : poly_items->sm_items) { + bbox = bbox + it->bbox(); + } + if (poly_items->polylines_item) + bbox = bbox + poly_items->polylines_item->bbox(); } return {}; } @@ -366,15 +380,36 @@ void Mesh_3_plugin::set_defaults() { approx = get_approximate(diag * 0.005, 2, approx_decimals); } -void Mesh_3_plugin::mesh_3(const Mesh_type mesh_type, const Dialog_choice dialog_choice) -{ +void Mesh_3_plugin::mesh_3(const Mesh_type mesh_type, + const Dialog_choice dialog_choice) { + CGAL_assertion(static_cast(items)); auto error_string = get_items_or_return_error_string(); - if(error_string) { + if (error_string) { QApplication::restoreOverrideCursor(); QMessageBox::warning(mw, tr("Mesh_3 plugin"), *error_string); return; } - const bool more_than_one_item = sm_items.size() > 1; + using boost::get; + const bool more_than_one_item = + get(&*items) && + (get(&*items)->sm_items.size() > 1); + + Scene_image_item* image_item = + get(&*items) + ? get(&*items)->image_item.get() + : nullptr; + Scene_surface_mesh_item* bounding_sm_item = + get(&*items) + ? get(&*items)->bounding_sm_item + : nullptr; + Scene_polylines_item* polylines_item = + get(&*items) + ? get(&*items)->polylines_item + : nullptr; + Scene_implicit_function_item* function_item = + get(&*items) + ? get(&*items)->function_item.get() + : nullptr; // ----------------------------------- // Create Mesh dialog // ----------------------------------- @@ -387,77 +422,99 @@ void Mesh_3_plugin::mesh_3(const Mesh_type mesh_type, const Dialog_choice dialog &QLabel::linkActivated, &QDesktopServices::openUrl); - dialog.setWindowFlags(Qt::Dialog|Qt::CustomizeWindowHint|Qt::WindowCloseButtonHint); - connect(ui.buttonBox, SIGNAL(accepted()), - &dialog, SLOT(accept())); - connect(ui.buttonBox, SIGNAL(rejected()), - &dialog, SLOT(reject())); + dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | + Qt::WindowCloseButtonHint); + connect(ui.buttonBox, SIGNAL(accepted()), &dialog, SLOT(accept())); + connect(ui.buttonBox, SIGNAL(rejected()), &dialog, SLOT(reject())); // Connect checkboxes to spinboxes - connect(ui.noApprox, SIGNAL(toggled(bool)), - ui.approx, SLOT(setEnabled(bool))); + connect( + ui.noApprox, SIGNAL(toggled(bool)), ui.approx, SLOT(setEnabled(bool))); - connect(ui.noFacetSizing, SIGNAL(toggled(bool)), - ui.facetSizing, SLOT(setEnabled(bool))); + connect(ui.noFacetSizing, + SIGNAL(toggled(bool)), + ui.facetSizing, + SLOT(setEnabled(bool))); - connect(ui.noAngle, SIGNAL(toggled(bool)), - ui.facetAngle, SLOT(setEnabled(bool))); + connect( + ui.noAngle, SIGNAL(toggled(bool)), ui.facetAngle, SLOT(setEnabled(bool))); - connect(ui.noTetSizing, SIGNAL(toggled(bool)), - ui.tetSizing, SLOT(setEnabled(bool))); + connect(ui.noTetSizing, + SIGNAL(toggled(bool)), + ui.tetSizing, + SLOT(setEnabled(bool))); - connect(ui.noTetShape, SIGNAL(toggled(bool)), - ui.tetShape, SLOT(setEnabled(bool))); + connect(ui.noTetShape, + SIGNAL(toggled(bool)), + ui.tetShape, + SLOT(setEnabled(bool))); - connect(ui.protect, SIGNAL(toggled(bool)), - ui.noEdgeSizing, SLOT(setEnabled(bool))); + connect(ui.protect, + SIGNAL(toggled(bool)), + ui.noEdgeSizing, + SLOT(setEnabled(bool))); - connect(ui.protect, SIGNAL(toggled(bool)), - ui.noEdgeSizing, SLOT(setChecked(bool))); + connect(ui.protect, + SIGNAL(toggled(bool)), + ui.noEdgeSizing, + SLOT(setChecked(bool))); - connect(ui.noEdgeSizing, SIGNAL(toggled(bool)), - ui.edgeLabel, SLOT(setEnabled(bool))); + connect(ui.noEdgeSizing, + SIGNAL(toggled(bool)), + ui.edgeLabel, + SLOT(setEnabled(bool))); - connect(ui.noEdgeSizing, SIGNAL(toggled(bool)), - ui.edgeSizing, SLOT(setEnabled(bool))); + connect(ui.noEdgeSizing, + SIGNAL(toggled(bool)), + ui.edgeSizing, + SLOT(setEnabled(bool))); - connect(ui.protect, SIGNAL(toggled(bool)), - ui.sharpEdgesAngle, SLOT(setEnabled(bool))); + connect(ui.protect, + SIGNAL(toggled(bool)), + ui.sharpEdgesAngle, + SLOT(setEnabled(bool))); - connect(ui.protect, SIGNAL(toggled(bool)), - ui.sharpEdgesAngleLabel, SLOT(setEnabled(bool))); + connect(ui.protect, + SIGNAL(toggled(bool)), + ui.sharpEdgesAngleLabel, + SLOT(setEnabled(bool))); - connect(ui.protect, SIGNAL(toggled(bool)), - ui.protectEdges, SLOT(setEnabled(bool))); + connect(ui.protect, + SIGNAL(toggled(bool)), + ui.protectEdges, + SLOT(setEnabled(bool))); - QString item_name = more_than_one_item ? - QString("%1...").arg(item->name()) : - item->name(); + QString item_name = + more_than_one_item ? QString("%1...").arg(item->name()) : item->name(); ui.objectName->setText(item_name); - ui.objectNameSize->setText(tr("Object bbox size (w,h,d): %1, %2, %3") - .arg(bbox.xmax() - bbox.xmin(),0,'g',3) - .arg(bbox.ymax() - bbox.ymin(),0,'g',3) - .arg(bbox.zmax() - bbox.zmin(),0,'g',3) ); + ui.objectNameSize->setText( + tr("Object bbox size (w,h,d): %1, %2, %3") + .arg(bbox.xmax() - bbox.xmin(), 0, 'g', 3) + .arg(bbox.ymax() - bbox.ymin(), 0, 'g', 3) + .arg(bbox.zmax() - bbox.zmin(), 0, 'g', 3)); set_defaults(); - double diag = CGAL::sqrt((bbox.xmax()-bbox.xmin())*(bbox.xmax()-bbox.xmin()) + (bbox.ymax()-bbox.ymin())*(bbox.ymax()-bbox.ymin()) + (bbox.zmax()-bbox.zmin())*(bbox.zmax()-bbox.zmin())); - ui.facetSizing->setDecimals(-sizing_decimals+2); - ui.facetSizing->setSingleStep(std::pow(10.,sizing_decimals)); - ui.facetSizing->setRange(diag * 10e-6, // min - diag); // max + double diag = + CGAL::sqrt((bbox.xmax() - bbox.xmin()) * (bbox.xmax() - bbox.xmin()) + + (bbox.ymax() - bbox.ymin()) * (bbox.ymax() - bbox.ymin()) + + (bbox.zmax() - bbox.zmin()) * (bbox.zmax() - bbox.zmin())); + ui.facetSizing->setDecimals(-sizing_decimals + 2); + ui.facetSizing->setSingleStep(std::pow(10., sizing_decimals)); + ui.facetSizing->setRange(diag * 10e-6, // min + diag); // max ui.facetSizing->setValue(facets_sizing); // default value ui.edgeSizing->setValue(edges_sizing); - ui.tetSizing->setDecimals(-sizing_decimals+2); - ui.tetSizing->setSingleStep(std::pow(10.,sizing_decimals)); + ui.tetSizing->setDecimals(-sizing_decimals + 2); + ui.tetSizing->setSingleStep(std::pow(10., sizing_decimals)); ui.tetSizing->setRange(diag * 10e-6, // min - diag); // max + diag); // max ui.tetSizing->setValue(tets_sizing); // default value - ui.approx->setDecimals(-approx_decimals+2); - ui.approx->setSingleStep(std::pow(10.,approx_decimals)); + ui.approx->setDecimals(-approx_decimals + 2); + ui.approx->setSingleStep(std::pow(10., approx_decimals)); ui.approx->setRange(diag * 10e-7, // min - diag); // max + diag); // max ui.approx->setValue(approx); ui.protect->setEnabled(features_protection_available); @@ -465,45 +522,41 @@ void Mesh_3_plugin::mesh_3(const Mesh_type mesh_type, const Dialog_choice dialog ui.protectEdges->setEnabled(features_protection_available); ui.facegraphCheckBox->setVisible(mesh_type == Mesh_type::SURFACE_ONLY); - ui.initializationGroup->setVisible(image_item != nullptr && !image_item->isGray()); + ui.initializationGroup->setVisible(image_item != nullptr && + !image_item->isGray()); ui.grayImgGroup->setVisible(image_item != nullptr && image_item->isGray()); - if (!sm_items.empty()) - ui.volumeGroup->setVisible(mesh_type == Mesh_type::VOLUME && nullptr != bounding_sm_item); + if (items->which() == POLYHEDRAL_MESH_ITEMS) + ui.volumeGroup->setVisible(mesh_type == Mesh_type::VOLUME && + nullptr != bounding_sm_item); else ui.volumeGroup->setVisible(mesh_type == Mesh_type::VOLUME); ui.sharpEdgesAngle->setValue(sharp_edges_angle_bound); - if (sm_items.empty()|| polylines_item != nullptr) { + if (items->which() != POLYHEDRAL_MESH_ITEMS || polylines_item != nullptr) { ui.sharpEdgesAngleLabel->setVisible(false); ui.sharpEdgesAngle->setVisible(false); ui.facetTopology->setEnabled(false); - ui.facetTopology->setToolTip(tr("Notice: " - "This option is only available with a" - " polyhedron or a surface mesh, when features are detected" - " automatically")); + ui.facetTopology->setToolTip( + tr("Notice: " + "This option is only available with a" + " polyhedron or a surface mesh, when features are detected" + " automatically")); } ui.noEdgeSizing->setChecked(ui.protect->isChecked()); ui.edgeLabel->setEnabled(ui.noEdgeSizing->isChecked()); ui.edgeSizing->setEnabled(ui.noEdgeSizing->isChecked()); - if (features_protection_available) - { - if (!sm_items.empty()) - { - if (mesh_type == Mesh_type::SURFACE_ONLY) - { + if (features_protection_available) { + if (items->which() == POLYHEDRAL_MESH_ITEMS) { + if (mesh_type == Mesh_type::SURFACE_ONLY) { ui.protectEdges->addItem(QString("Sharp and Boundary edges")); ui.protectEdges->addItem(QString("Boundary edges only")); - } - else + } else ui.protectEdges->addItem(QString("Sharp edges")); - } - else if(nullptr != image_item) - { - if(polylines_item != nullptr) + } else if (items->which() == IMAGE_MESH_ITEMS) { + if (polylines_item != nullptr) ui.protectEdges->addItem(QString("Input polylines")); - else - { + else { ui.protectEdges->addItem(QString("Polylines on cube")); } } @@ -512,119 +565,133 @@ void Mesh_3_plugin::mesh_3(const Mesh_type mesh_type, const Dialog_choice dialog // Get values // ----------------------------------- - //reset cursor from the code for the scripts + // reset cursor from the code for the scripts QApplication::restoreOverrideCursor(); - if(dialog_choice == Dialog_choice::DIALOG) { + if (dialog_choice == Dialog_choice::DIALOG) { int i = dialog.exec(); - if( i == QDialog::Rejected ) { return; } + if (i == QDialog::Rejected) { return; } } // 0 means parameter is not considered angle = !ui.noAngle->isChecked() ? 0 : ui.facetAngle->value(); sharp_edges_angle_bound = ui.sharpEdgesAngle->value(); std::cerr << "sharp_edges_angle_bound: " << sharp_edges_angle_bound << '\n'; - edges_sizing = !ui.noEdgeSizing->isChecked() ? DBL_MAX : ui.edgeSizing->value(); + edges_sizing = + !ui.noEdgeSizing->isChecked() ? DBL_MAX : ui.edgeSizing->value(); facets_sizing = !ui.noFacetSizing->isChecked() ? 0 : ui.facetSizing->value(); approx = !ui.noApprox->isChecked() ? 0 : ui.approx->value(); tets_shape = !ui.noTetShape->isChecked() ? 0 : ui.tetShape->value(); - tets_sizing = !ui.noTetSizing->isChecked() ? 0 : ui.tetSizing->value(); - protect_features = ui.protect->isChecked() && (ui.protectEdges->currentIndex() == 0); - protect_borders = ui.protect->isChecked() && (ui.protectEdges->currentIndex() == 1); + tets_sizing = !ui.noTetSizing->isChecked() ? 0 : ui.tetSizing->value(); + protect_features = + ui.protect->isChecked() && (ui.protectEdges->currentIndex() == 0); + protect_borders = + ui.protect->isChecked() && (ui.protectEdges->currentIndex() == 1); const bool detect_connected_components = ui.detectComponents->isChecked(); - const int manifold = - (ui.manifoldCheckBox->isChecked() ? 1 : 0) - + (ui.facetTopology->isChecked() ? 2 : 0); + const int manifold = (ui.manifoldCheckBox->isChecked() ? 1 : 0) + + (ui.facetTopology->isChecked() ? 2 : 0); const float iso_value = float(ui.iso_value_spinBox->value()); const float value_outside = float(ui.value_outside_spinBox->value()); - const float inside_is_less = float(ui.inside_is_less_checkBox->isChecked()); - as_facegraph = (mesh_type == Mesh_type::SURFACE_ONLY) ? ui.facegraphCheckBox->isChecked() : false; + const float inside_is_less = float(ui.inside_is_less_checkBox->isChecked()); + as_facegraph = (mesh_type == Mesh_type::SURFACE_ONLY) + ? ui.facegraphCheckBox->isChecked() + : false; Meshing_thread* thread = nullptr; - if (!sm_items.empty()) - { + switch (items->which()) { + case POLYHEDRAL_MESH_ITEMS: { + auto& poly_items = get(*items); + auto& sm_items = poly_items.sm_items; + const auto bounding_sm_item = poly_items.bounding_sm_item; + const auto polylines_item = poly_items.polylines_item; QList polyhedrons; - sm_items.removeAll(bounding_sm_item); - std::transform(sm_items.begin(), sm_items.end(), - std::back_inserter(polyhedrons), - [](Scene_surface_mesh_item* item) { - return item->polyhedron(); - }); + sm_items.removeAll(gsl::make_not_null(bounding_sm_item)); + std::transform( + sm_items.begin(), + sm_items.end(), + std::back_inserter(polyhedrons), + [](Scene_surface_mesh_item* item) { return item->polyhedron(); }); Scene_polylines_item::Polylines_container plc; - SMesh *bounding_polyhedron = - (bounding_sm_item == nullptr) ? nullptr : bounding_sm_item->polyhedron(); + SMesh* bounding_polyhedron = (bounding_sm_item == nullptr) + ? nullptr + : bounding_sm_item->polyhedron(); - thread = cgal_code_mesh_3(polyhedrons, - (polylines_item == nullptr)?plc:polylines_item->polylines, - bounding_polyhedron, - item_name, - angle, - facets_sizing, - approx, - tets_sizing, - edges_sizing, - tets_shape, - protect_features, - protect_borders, - sharp_edges_angle_bound, - manifold, - mesh_type == Mesh_type::SURFACE_ONLY); + thread = cgal_code_mesh_3( + polyhedrons, + (polylines_item == nullptr) ? plc : polylines_item->polylines, + bounding_polyhedron, + item_name, + angle, + facets_sizing, + approx, + tets_sizing, + edges_sizing, + tets_shape, + protect_features, + protect_borders, + sharp_edges_angle_bound, + manifold, + mesh_type == Mesh_type::SURFACE_ONLY); + break; } // Image -#ifdef CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS - else if (nullptr != function_item) - { +# ifdef CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS + case IMPLICIT_MESH_ITEMS: { const Implicit_function_interface* pFunction = function_item->function(); - if (nullptr == pFunction) - { + if (nullptr == pFunction) { QMessageBox::critical(mw, tr(""), tr("ERROR: no data in selected item")); return; } - thread = cgal_code_mesh_3(pFunction, - angle, - facets_sizing, - approx, - tets_sizing, - edges_sizing, - tets_shape, - manifold, - mesh_type == Mesh_type::SURFACE_ONLY); + thread = cgal_code_mesh_3(pFunction, + angle, + facets_sizing, + approx, + tets_sizing, + edges_sizing, + tets_shape, + manifold, + mesh_type == Mesh_type::SURFACE_ONLY); + break; } -#endif -#ifdef CGAL_MESH_3_DEMO_ACTIVATE_SEGMENTED_IMAGES - else if (nullptr != image_item) - { +# endif +# ifdef CGAL_MESH_3_DEMO_ACTIVATE_SEGMENTED_IMAGES + case IMAGE_MESH_ITEMS: { const Image* pImage = image_item->image(); - if (nullptr == pImage) - { + if (nullptr == pImage) { QMessageBox::critical(mw, tr(""), tr("ERROR: no data in selected item")); return; } Scene_polylines_item::Polylines_container plc; - thread = cgal_code_mesh_3(pImage, - (polylines_item == nullptr)?plc:polylines_item->polylines, - angle, - facets_sizing, - approx, - tets_sizing, - edges_sizing, - tets_shape, - protect_features, - manifold, - mesh_type == Mesh_type::SURFACE_ONLY, - detect_connected_components, - image_item->isGray(), - iso_value, - value_outside, - inside_is_less); + thread = cgal_code_mesh_3( + pImage, + (polylines_item == nullptr) ? plc : polylines_item->polylines, + angle, + facets_sizing, + approx, + tets_sizing, + edges_sizing, + tets_shape, + protect_features, + manifold, + mesh_type == Mesh_type::SURFACE_ONLY, + detect_connected_components, + image_item->isGray(), + iso_value, + value_outside, + inside_is_less); + break; } -#endif + default: + CGAL::Three::Three::error(tr("Mesh_3 plugin"), + tr("This type of item is not handled!")); + return; + } // end switch +# endif - if ( nullptr == thread ) - { - QMessageBox::critical(mw,tr(""),tr("ERROR: no thread created")); + if (nullptr == thread) { + QMessageBox::critical(mw, tr(""), tr("ERROR: no thread created")); return; } From 4313a8ee66c343cfdda91908ec8f1cb56690f770 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Fri, 12 Jul 2019 13:29:49 +0200 Subject: [PATCH 039/141] Add compatibility with old Qt Scripts --- .../demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp index d7fe399d902..71e6ca79180 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp @@ -122,7 +122,17 @@ public Q_SLOTS: void set_defaults(); void mesh_3_volume(); void mesh_3_surface(); - void mesh_3_surface_with_defaults() { mesh_3(Mesh_type::SURFACE_ONLY, Dialog_choice::NO_DIALOG); } + void mesh_3_surface_with_defaults() { + mesh_3(Mesh_type::SURFACE_ONLY, Dialog_choice::NO_DIALOG); + } + void mesh_3_volume_with_defaults() { + mesh_3(Mesh_type::VOLUME, Dialog_choice::NO_DIALOG); + } + void mesh_3(bool with_dialog) { // compatibility with old Qt Scripts + return mesh_3( + Mesh_type::VOLUME, + with_dialog ? Dialog_choice::DIALOG : Dialog_choice::NO_DIALOG); + } void splitPolylines(); void meshing_done(Meshing_thread* t); void status_report(QString str); From 245b2211e654300f189f3f69387277e1442b1c19 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Tue, 30 Jul 2019 11:33:10 +0200 Subject: [PATCH 040/141] Add a cw test before returning the triangle or polygon result of a triangle/XXX intersection. --- .../Triangle_2_Triangle_2_intersection_impl.h | 42 ++++++++++++++++--- .../Intersections_2/test_intersections_2.cpp | 26 +++++++----- 2 files changed, 51 insertions(+), 17 deletions(-) diff --git a/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h b/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h index ab5d9386874..a9e9778b795 100644 --- a/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h +++ b/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h @@ -281,17 +281,38 @@ Triangle_2_Triangle_2_pair::vertex(int n) const return cur->point; } +//algorithm taken from here : https://stackoverflow.com/questions/1165647/how-to-determine-if-a-list-of-polygon-points-are-in-clockwise-order +template +bool is_cw(std::vector ps) +{ + typename K::FT res(0); + std::size_t length = ps.size(); + for(std::size_t i = 0; i 0; +} + template typename K::Triangle_2 Triangle_2_Triangle_2_pair::intersection_triangle() const { typedef typename K::Triangle_2 Triangle_2; - if (!_known) - intersection_type(); - CGAL_kernel_assertion(_result == TRIANGLE); - return Triangle_2(_pointlist.first->point, - _pointlist.first->next->point, - _pointlist.first->next->next->point); + if (!_known) + intersection_type(); + CGAL_kernel_assertion(_result == TRIANGLE); + std::vector res; + res.push_back(_pointlist.first->point); + res.push_back(_pointlist.first->next->point); + res.push_back(_pointlist.first->next->next->point); + if(!is_cw(res)) + { + return Triangle_2(res[0], res[1], res[2]); + } + else { + return Triangle_2(res[0], res[2], res[1]); + } } template @@ -343,6 +364,15 @@ intersection(const typename K::Triangle_2 &tr1, for (int i =0; i < ispair.vertex_count(); i++) { points[i] = ispair.vertex(i); } + if(is_cw(points)) + { + std::size_t length = points.size(); + + for(std::size_t i = 0; i< length/2; ++i) + { + std::swap(points[i], points[length-i-1]); + } + } return intersection_return(points); } } diff --git a/Intersections_2/test/Intersections_2/test_intersections_2.cpp b/Intersections_2/test/Intersections_2/test_intersections_2.cpp index 0057287d69f..aced87d8315 100644 --- a/Intersections_2/test/Intersections_2/test_intersections_2.cpp +++ b/Intersections_2/test/Intersections_2/test_intersections_2.cpp @@ -98,7 +98,8 @@ struct Test { if (p.size() != q.size()) return false; - + if (CGAL::Intersections::internal::is_cw(p)) + return false; for(typename Pol::const_iterator itp = p.begin(), itq = q.begin(); itp != p.end(); ++itp, ++itq) if (!approx_equal(*itp, *itq)) return false; @@ -106,6 +107,15 @@ struct Test return true; } + bool approx_equal(const T & p, const T & q) + { + std::vector

vec(3); + for(int i=0; i<3; ++i){vec[i]=p[i];} + if (CGAL::Intersections::internal::is_cw(vec)) + return false; + return p == q; + } + template void check_no_do_intersect(const O1& o1, const O2& o2) { @@ -515,18 +525,12 @@ struct Test // polygon intersection Pol pol0; - pol0.push_back(P(-6, -4)); - pol0.push_back(P( -5.11111, -0.222222 )); - pol0.push_back(P( 0, 10 )); pol0.push_back(P( 8, 4 )); + pol0.push_back(P( 0, 10 )); + pol0.push_back(P( -5.11111, -0.222222 )); + pol0.push_back(P(-6, -4)); check_intersection (T(p( 0, 10), p(-10, -10), p( 20, -5)), T(p( 2, 30), p( -6, -4), p(15, 8)), pol0, false); - - Pol pol1; - pol1.push_back(P( 8, 4)); - pol1.push_back(P( 0, 10 )); - pol1.push_back(P( -5.11111, -0.222222 )); - pol1.push_back(P(-6, -4)); - check_intersection (T(p( -10,-10), p( 0, 10), p( 20, -5)), T(p( 2, 30), p( -6, -4), p(15, 8)), pol1, false); + check_intersection (T(p( -10,-10), p( 0, 10), p( 20, -5)), T(p( 2, 30), p( -6, -4), p(15, 8)), pol0, false); Pol pol2; pol2.push_back(P( 10.2222, 2.33333 )); From e4474d8c3b6756d4e02fcd62c7347586595ed270 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 23 Aug 2019 11:57:49 +0200 Subject: [PATCH 041/141] set point to make sure there is a self-intersection --- .../test/Polygon_mesh_processing/test_split_volume.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_split_volume.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_split_volume.cpp index 4f197b5f5f9..2637ae47c46 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_split_volume.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_split_volume.cpp @@ -70,6 +70,7 @@ int main() // create a self-intersection Surface_mesh::Halfedge_index h = *tmp.halfedges().begin(); h = CGAL::Euler::split_edge(h, tmp); + tmp.point( target(h, tmp) ) = tmp.point( target( tmp.next(h), tmp) ); CGAL::Euler::split_face(h, next( next(h, tmp), tmp), tmp); h = opposite(h, tmp); CGAL::Euler::split_face(h, next( next(h, tmp), tmp), tmp); From baea5490a4f73cbe7237523aafb21d22be07600d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 23 Aug 2019 12:00:17 +0200 Subject: [PATCH 042/141] collect only faces for cc to be handled --- .../include/CGAL/Polygon_mesh_processing/orientation.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index ee5b662ba0c..7a743e06b40 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -17,7 +17,7 @@ // SPDX-License-Identifier: GPL-3.0+ // // -// Author(s) : Ilker O. Yaz +// Author(s) : Sebastien Loriot and Ilker O. Yaz #ifndef CGAL_ORIENT_POLYGON_MESH_H @@ -1019,11 +1019,13 @@ volume_connected_components(const TriangleMesh& tm, ++nb_faces_per_cc[ cc_id ]; } for (std::size_t i=0; i Date: Fri, 23 Aug 2019 14:59:59 +0200 Subject: [PATCH 043/141] move self-intersection computation in an internal function --- .../Polygon_mesh_processing/orientation.h | 66 ++++++++++++------- 1 file changed, 43 insertions(+), 23 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index 7a743e06b40..c27c2ffcdfe 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -778,13 +778,36 @@ void set_f_cc_id(const std::vector&, } // internal +namespace Volume_cc +{ + +template +void self_intersections_amongst_cc(const TriangleMesh& tm, FaceCCIdMap f_scc_id, const Vpm& vpm, + std::set< std::pair >& self_intersecting_ccs) +{ + typedef boost::graph_traits GT; + typedef typename GT::face_descriptor face_descriptor; + + typedef std::pair Face_pair; + std::vector si_faces; + + self_intersections(tm, std::back_inserter(si_faces), parameters::vertex_point_map(vpm)); + for(const Face_pair& fp : si_faces) + { + std::size_t first_cc_id = get(f_scc_id, fp.first); + std::size_t second_cc_id = get(f_scc_id, fp.second); + self_intersecting_ccs.insert( make_sorted_pair(first_cc_id, second_cc_id) ); + } +} + +} // end of Volume_cc namespace /*! * \ingroup PMP_orientation_grp * assigns to each face of `tm` an id corresponding to the volume connected component * it contributes to define. * - * Using the adjacency relation of two faces along an edge, a triangle mesh can be split + * Using the adjacency relation of two faces along an edge, a triangle mesh can be decomposed * into connected components (*surface components* in the following). * A surface component without boundary separates the 3D space into an infinite and * a finite volume. We say that the finite volume is enclosed by this surface @@ -950,31 +973,28 @@ volume_connected_components(const TriangleMesh& tm, } // Handle self-intersecting connected components - typedef std::pair Face_pair; - std::vector si_faces; - std::set< std::pair > self_intersecting_cc; // due to self-intersections - if (do_self_intersection_tests) - self_intersections(tm, std::back_inserter(si_faces)); std::vector is_involved_in_self_intersection(nb_cc, false); - BOOST_FOREACH(const Face_pair& fp, si_faces) + std::set< std::pair > self_intersecting_ccs; // due to self-intersections + if (do_self_intersection_tests) { - std::size_t first_cc_id = face_cc[ get(fid_map, fp.first) ]; - std::size_t second_cc_id = face_cc[ get(fid_map, fp.second) ]; - - if (first_cc_id==second_cc_id) + Volume_cc::self_intersections_amongst_cc( + tm, bind_property_maps(fid_map,make_property_map(face_cc)), vpm, self_intersecting_ccs); + for(const std::pair& p : self_intersecting_ccs) { - if ( !cc_handled.test(first_cc_id) ) + if (p.first==p.second) { - cc_handled.set(first_cc_id); - cc_volume_ids[first_cc_id]=next_volume_id++; - error_codes.push_back(SURFACE_SELF_INTERSECTION); + if ( !cc_handled.test(p.first) ) + { + cc_handled.set(p.first); + cc_volume_ids[p.first]=next_volume_id++; + error_codes.push_back(SURFACE_SELF_INTERSECTION); + } + } + else + { + is_involved_in_self_intersection[p.first] = true; + is_involved_in_self_intersection[p.second] = true; } - } - else - { - is_involved_in_self_intersection[first_cc_id] = true; - is_involved_in_self_intersection[second_cc_id] = true; - self_intersecting_cc.insert( make_sorted_pair(first_cc_id, second_cc_id) ); } } @@ -1074,7 +1094,7 @@ volume_connected_components(const TriangleMesh& tm, id != cc_to_handle.npos; id = cc_to_handle.find_next(id)) { - if (self_intersecting_cc.count( make_sorted_pair(xtrm_cc_id, id) )!= 0) + if (self_intersecting_ccs.count( make_sorted_pair(xtrm_cc_id, id) )!= 0) { cc_intersecting.push_back(id); continue; // to not dot inclusion test for intersecting CCs @@ -1098,7 +1118,7 @@ volume_connected_components(const TriangleMesh& tm, Side_of_tm side_of_cc(aabb_tree); BOOST_FOREACH(std::size_t ncc_id, nested_cc_per_cc[xtrm_cc_id]) { - if (self_intersecting_cc.count( make_sorted_pair(ncc_id, id) )!= 0) + if (self_intersecting_ccs.count( make_sorted_pair(ncc_id, id) )!= 0) continue; if (side_of_cc(get(vpm,xtrm_vertices[ncc_id]))==ON_BOUNDED_SIDE) nested_cc_per_cc_shared[id].push_back(ncc_id); From 48b72b3fab44a0385757faac228de4e15202b9ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 23 Aug 2019 15:22:01 +0200 Subject: [PATCH 044/141] use c++11 for-range loop --- .../Polygon_mesh_processing/orientation.h | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index c27c2ffcdfe..af08d3a08b9 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -943,7 +943,7 @@ volume_connected_components(const TriangleMesh& tm, { error_codes.push_back(SINGLE_CONNECTED_COMPONENT); - BOOST_FOREACH(face_descriptor fd, faces(tm)) + for(face_descriptor fd : faces(tm)) put(volume_id_map, fd, 0); internal::copy_error_codes(error_codes, boost::get_param(np, internal_np::error_codes)); @@ -1003,7 +1003,7 @@ volume_connected_components(const TriangleMesh& tm, { // extract a vertex with max z coordinate for each connected component std::vector xtrm_vertices(nb_cc, GT::null_vertex()); - BOOST_FOREACH(vertex_descriptor vd, vertices(tm)) + for(vertex_descriptor vd : vertices(tm)) { std::size_t cc_id = face_cc[get(fid_map, face(halfedge(vd, tm), tm))]; if (cc_handled.test(cc_id)) continue; @@ -1033,7 +1033,7 @@ volume_connected_components(const TriangleMesh& tm, //collect faces per CC std::vector< std::vector > faces_per_cc(nb_cc); std::vector< std::size_t > nb_faces_per_cc(nb_cc, 0); - BOOST_FOREACH(face_descriptor fd, faces(tm)) + for(face_descriptor fd : faces(tm)) { std::size_t cc_id = face_cc[ get(fid_map, fd) ]; ++nb_faces_per_cc[ cc_id ]; @@ -1041,7 +1041,7 @@ volume_connected_components(const TriangleMesh& tm, for (std::size_t i=0; i > level_k_plus_1_nestings; - BOOST_FOREACH(boost::dynamic_bitset<> cc_to_handle, level_k_nestings) + for(boost::dynamic_bitset<> cc_to_handle : level_k_nestings) { CGAL_assertion( cc_to_handle.any() ); while(cc_to_handle.any()) @@ -1110,13 +1110,13 @@ volume_connected_components(const TriangleMesh& tm, } //for each CC intersecting xtrm_cc_id, find the CCs included in both - BOOST_FOREACH(std::size_t id, cc_intersecting) + for(std::size_t id : cc_intersecting) { typename Side_of_tm::AABB_tree aabb_tree(faces_per_cc[id].begin(), faces_per_cc[id].end(), tm, vpm); Side_of_tm side_of_cc(aabb_tree); - BOOST_FOREACH(std::size_t ncc_id, nested_cc_per_cc[xtrm_cc_id]) + for(std::size_t ncc_id : nested_cc_per_cc[xtrm_cc_id]) { if (self_intersecting_ccs.count( make_sorted_pair(ncc_id, id) )!= 0) continue; @@ -1192,7 +1192,7 @@ volume_connected_components(const TriangleMesh& tm, if (is_involved_in_self_intersection[cc_id]) { error_codes.push_back(VOLUME_INTERSECTION); - BOOST_FOREACH(std::size_t ncc_id, nested_cc_per_cc[cc_id]) + for(std::size_t ncc_id : nested_cc_per_cc[cc_id]) { cc_handled.set(ncc_id); cc_volume_ids[ncc_id] = next_volume_id++; @@ -1203,7 +1203,7 @@ volume_connected_components(const TriangleMesh& tm, else error_codes.push_back(VALID_VOLUME); - BOOST_FOREACH(std::size_t ncc_id, nested_cc_per_cc[cc_id]) + for(std::size_t ncc_id : nested_cc_per_cc[cc_id]) { if ( nesting_levels[ncc_id]==nesting_levels[cc_id]+1 ) { @@ -1216,7 +1216,7 @@ volume_connected_components(const TriangleMesh& tm, // we dump it and all included surface components as independant volumes. cc_volume_ids[ncc_id] = next_volume_id++; error_codes.push_back(INCOMPATIBLE_ORIENTATION); - BOOST_FOREACH(std::size_t nncc_id, nested_cc_per_cc[ncc_id]) + for(std::size_t nncc_id : nested_cc_per_cc[ncc_id]) { cc_handled.set(nncc_id); cc_volume_ids[nncc_id] = next_volume_id++; @@ -1229,7 +1229,7 @@ volume_connected_components(const TriangleMesh& tm, { cc_volume_ids[ncc_id] = next_volume_id++; error_codes.push_back(VOLUME_INTERSECTION); - BOOST_FOREACH(std::size_t nncc_id, nested_cc_per_cc[ncc_id]) + for(std::size_t nncc_id : nested_cc_per_cc[ncc_id]) { if (cc_handled.test(nncc_id)) { @@ -1261,7 +1261,7 @@ volume_connected_components(const TriangleMesh& tm, // extract direct nested parent (more than one in case of self-intersection) for(std::size_t cc_id=0; cc_id Date: Fri, 23 Aug 2019 15:31:07 +0200 Subject: [PATCH 045/141] Revert "move self-intersection computation in an internal function" This reverts commit 3ae8e0f06ff0a0ae4f6b2d8efe82aae569c5b7c9. --- .../Polygon_mesh_processing/orientation.h | 66 +++++++------------ 1 file changed, 23 insertions(+), 43 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index af08d3a08b9..77afe890828 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -778,36 +778,13 @@ void set_f_cc_id(const std::vector&, } // internal -namespace Volume_cc -{ - -template -void self_intersections_amongst_cc(const TriangleMesh& tm, FaceCCIdMap f_scc_id, const Vpm& vpm, - std::set< std::pair >& self_intersecting_ccs) -{ - typedef boost::graph_traits GT; - typedef typename GT::face_descriptor face_descriptor; - - typedef std::pair Face_pair; - std::vector si_faces; - - self_intersections(tm, std::back_inserter(si_faces), parameters::vertex_point_map(vpm)); - for(const Face_pair& fp : si_faces) - { - std::size_t first_cc_id = get(f_scc_id, fp.first); - std::size_t second_cc_id = get(f_scc_id, fp.second); - self_intersecting_ccs.insert( make_sorted_pair(first_cc_id, second_cc_id) ); - } -} - -} // end of Volume_cc namespace /*! * \ingroup PMP_orientation_grp * assigns to each face of `tm` an id corresponding to the volume connected component * it contributes to define. * - * Using the adjacency relation of two faces along an edge, a triangle mesh can be decomposed + * Using the adjacency relation of two faces along an edge, a triangle mesh can be split * into connected components (*surface components* in the following). * A surface component without boundary separates the 3D space into an infinite and * a finite volume. We say that the finite volume is enclosed by this surface @@ -973,29 +950,32 @@ volume_connected_components(const TriangleMesh& tm, } // Handle self-intersecting connected components - std::vector is_involved_in_self_intersection(nb_cc, false); - std::set< std::pair > self_intersecting_ccs; // due to self-intersections + typedef std::pair Face_pair; + std::vector si_faces; + std::set< std::pair > self_intersecting_cc; // due to self-intersections if (do_self_intersection_tests) + self_intersections(tm, std::back_inserter(si_faces)); + std::vector is_involved_in_self_intersection(nb_cc, false); + for(const Face_pair& fp : si_faces) { - Volume_cc::self_intersections_amongst_cc( - tm, bind_property_maps(fid_map,make_property_map(face_cc)), vpm, self_intersecting_ccs); - for(const std::pair& p : self_intersecting_ccs) + std::size_t first_cc_id = face_cc[ get(fid_map, fp.first) ]; + std::size_t second_cc_id = face_cc[ get(fid_map, fp.second) ]; + + if (first_cc_id==second_cc_id) { - if (p.first==p.second) + if ( !cc_handled.test(first_cc_id) ) { - if ( !cc_handled.test(p.first) ) - { - cc_handled.set(p.first); - cc_volume_ids[p.first]=next_volume_id++; - error_codes.push_back(SURFACE_SELF_INTERSECTION); - } - } - else - { - is_involved_in_self_intersection[p.first] = true; - is_involved_in_self_intersection[p.second] = true; + cc_handled.set(first_cc_id); + cc_volume_ids[first_cc_id]=next_volume_id++; + error_codes.push_back(SURFACE_SELF_INTERSECTION); } } + else + { + is_involved_in_self_intersection[first_cc_id] = true; + is_involved_in_self_intersection[second_cc_id] = true; + self_intersecting_cc.insert( make_sorted_pair(first_cc_id, second_cc_id) ); + } } std::vector< std::vector > nesting_parents(nb_cc); @@ -1094,7 +1074,7 @@ volume_connected_components(const TriangleMesh& tm, id != cc_to_handle.npos; id = cc_to_handle.find_next(id)) { - if (self_intersecting_ccs.count( make_sorted_pair(xtrm_cc_id, id) )!= 0) + if (self_intersecting_cc.count( make_sorted_pair(xtrm_cc_id, id) )!= 0) { cc_intersecting.push_back(id); continue; // to not dot inclusion test for intersecting CCs @@ -1118,7 +1098,7 @@ volume_connected_components(const TriangleMesh& tm, Side_of_tm side_of_cc(aabb_tree); for(std::size_t ncc_id : nested_cc_per_cc[xtrm_cc_id]) { - if (self_intersecting_ccs.count( make_sorted_pair(ncc_id, id) )!= 0) + if (self_intersecting_cc.count( make_sorted_pair(ncc_id, id) )!= 0) continue; if (side_of_cc(get(vpm,xtrm_vertices[ncc_id]))==ON_BOUNDED_SIDE) nested_cc_per_cc_shared[id].push_back(ncc_id); From 83fcb5d24e10c8e74b0c6292f3ea4f190816201f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Sun, 25 Aug 2019 09:46:56 +0200 Subject: [PATCH 046/141] add new named parmeters to extract more info from the function --- .../CGAL/boost/graph/parameters_interface.h | 3 + BGL/test/BGL/test_cgal_bgl_named_params.cpp | 4 + .../Polygon_mesh_processing/orientation.h | 77 +++++++++++++++++-- 3 files changed, 78 insertions(+), 6 deletions(-) diff --git a/BGL/include/CGAL/boost/graph/parameters_interface.h b/BGL/include/CGAL/boost/graph/parameters_interface.h index 193a496e26a..37fdf34a95e 100644 --- a/BGL/include/CGAL/boost/graph/parameters_interface.h +++ b/BGL/include/CGAL/boost/graph/parameters_interface.h @@ -84,6 +84,9 @@ CGAL_add_named_parameter(error_codes_t, error_codes, error_codes) CGAL_add_named_parameter(volume_inclusions_t, volume_inclusions, volume_inclusions) CGAL_add_named_parameter(face_cc_map_t, face_connected_component_map, face_connected_component_map) +CGAL_add_named_parameter(ccid_to_vid_vector_t, connected_component_id_to_volume_id, connected_component_id_to_volume_id) +CGAL_add_named_parameter(is_cc_outward_oriented_bs_t, is_cc_outward_oriented, is_cc_outward_oriented); + // List of named parameters that we use in the package 'Surface Mesh Simplification' CGAL_add_named_parameter(get_cost_policy_t, get_cost_policy, get_cost) CGAL_add_named_parameter(get_placement_policy_t, get_placement_policy, get_placement) diff --git a/BGL/test/BGL/test_cgal_bgl_named_params.cpp b/BGL/test/BGL/test_cgal_bgl_named_params.cpp index 59120379db6..ed60b02f4f5 100644 --- a/BGL/test/BGL/test_cgal_bgl_named_params.cpp +++ b/BGL/test/BGL/test_cgal_bgl_named_params.cpp @@ -166,6 +166,8 @@ void test(const NamedParameters& np) check_same_type<49>(get_param(np, CGAL::internal_np::error_codes)); check_same_type<50>(get_param(np, CGAL::internal_np::volume_inclusions)); check_same_type<51>(get_param(np, CGAL::internal_np::face_connected_component_map)); + check_same_type<52>(get_param(np, CGAL::internal_np::connected_component_id_to_volume_id)); + check_same_type<53>(get_param(np, CGAL::internal_np::is_cc_outward_oriented)); // Named parameters that we use in the package 'Surface Mesh Simplification' check_same_type<34>(get_param(np, CGAL::internal_np::get_cost_policy)); @@ -248,6 +250,8 @@ int main() .error_codes(A<49>(49)) .volume_inclusions(A<50>(50)) .face_connected_component_map(A<51>(51)) + .connected_component_id_to_volume_id(A<52>(52)) + .is_cc_outward_oriented(A<53>(53)) ); return EXIT_SUCCESS; diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index 77afe890828..6e122e5c92a 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -776,6 +776,46 @@ void set_f_cc_id(const std::vector&, const TriangleMesh&) {} +template +void copy_cc_to_volume_id( + std::vector& cc_volume_ids, + RefToVector ref_to_vector) +{ + ref_to_vector.get().swap( cc_volume_ids ); +} + +inline void copy_cc_to_volume_id( + const std::vector&, + boost::param_not_found) +{} + +template +void copy_orientation_bitset( + const std::vector& is_cc_outward_oriented, + RefToBitset ref_to_bs) +{ + ref_to_bs.get() = is_cc_outward_oriented; +} + +inline void copy_orientation_bitset( + const boost::dynamic_bitset<>&, + boost::param_not_found) +{} + +template +void set_cc_intersecting_pairs(const std::set< std::pair >& self_intersecting_cc, + OutputIterator out) +{ + for (const std::pair& p : self_intersecting_cc) + { + *out++=p; + } +} + +inline void set_cc_intersecting_pairs(const std::set< std::pair >&, + boost::param_not_found) +{} + } // internal @@ -867,6 +907,21 @@ void set_f_cc_id(const std::vector&, * if `true`, the input might contain some self-intersections and a test is done * prior to the volume decomposition. * \cgalParamEnd + * \cgalParamBegin{connected_component_id_to_volume_id} + * a `reference_wrapper` (either from `boost` or the standard library) containing + * a reference to an object of type `std::vector< std::size_t >`. + * The size of the vector is exactly the number of connected components. + * For each connected component identified using its id `ccid`, the id of the volume it contributes + * to describe is the value at the position `ccid` in the parameter vector. + * \cgalParamEnd + * \cgalParamBegin{is_cc_outward_oriented} + * a `reference_wrapper` (either from `boost` or the standard library) containing + * a reference to an object of type `std::vector`. + * The size of the vector is exactly the number of connected components. + * For each connected component identified using its id `ccid`, the output of `is_outward_oriented` + * called on the submesh corresponding to this connected component + * is the value at the position `ccid` in the parameter vector. + * \cgalParamEnd * \cgalNamedParamsEnd * * \return the number of volume components defined by `tm` @@ -913,8 +968,13 @@ volume_connected_components(const TriangleMesh& tm, const bool do_self_intersection_tests = boost::choose_param(boost::get_param(np, internal_np::do_self_intersection_tests), false); + const bool ignore_orientation_of_cc = + !boost::choose_param(boost::get_param(np, internal_np::do_orientation_tests), + true); std::vector error_codes; + std::vector is_cc_outward_oriented; + std::vector cc_volume_ids(nb_cc, -1); if (nb_cc == 1) { @@ -926,11 +986,17 @@ volume_connected_components(const TriangleMesh& tm, internal::copy_error_codes(error_codes, boost::get_param(np, internal_np::error_codes)); // nested_cc_per_cc is empty and used to clear the vector passed in case it was not empty internal::copy_nested_parents(nested_cc_per_cc, boost::get_param(np, internal_np::volume_inclusions)); + if (!ignore_orientation_of_cc && + !boost::is_default_param(get_param(np, internal_np::connected_component_id_to_volume_id))) + { + is_cc_outward_oriented.push_back(is_outward_oriented(tm, np)); + internal::copy_orientation_bitset(is_cc_outward_oriented, boost::get_param(np, internal_np::is_cc_outward_oriented)); + } + internal::copy_cc_to_volume_id(cc_volume_ids, boost::get_param(np, internal_np::connected_component_id_to_volume_id)); return 1; } boost::dynamic_bitset<> cc_handled(nb_cc, 0); - std::vector cc_volume_ids(nb_cc, -1); std::size_t next_volume_id = 0; // Handle open connected components @@ -994,12 +1060,7 @@ volume_connected_components(const TriangleMesh& tm, xtrm_vertices[cc_id]=vd; } - const bool ignore_orientation_of_cc = - !boost::choose_param(boost::get_param(np, internal_np::do_orientation_tests), - true); - // fill orientation vector for each surface CC - boost::dynamic_bitset<> is_cc_outward_oriented; if (!ignore_orientation_of_cc) { is_cc_outward_oriented.resize(nb_cc); @@ -1267,6 +1328,10 @@ volume_connected_components(const TriangleMesh& tm, CGAL_assertion(next_volume_id == error_codes.size()); internal::copy_error_codes(error_codes, boost::get_param(np, internal_np::error_codes)); internal::copy_nested_parents(nesting_parents, boost::get_param(np, internal_np::volume_inclusions)); + internal::copy_cc_to_volume_id(cc_volume_ids, boost::get_param(np, internal_np::connected_component_id_to_volume_id)); + internal::copy_orientation_bitset(is_cc_outward_oriented, boost::get_param(np, internal_np::is_cc_outward_oriented)); + //internal::set_cc_intersecting_pairs + return next_volume_id; } From 242cce424b0bc1fb5b989ea8c019bbc0d2c3b3f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Sun, 25 Aug 2019 13:53:32 +0200 Subject: [PATCH 047/141] add parameters to collect pair of cc intersecting --- BGL/include/CGAL/boost/graph/parameters_interface.h | 2 +- BGL/test/BGL/test_cgal_bgl_named_params.cpp | 2 ++ .../CGAL/Polygon_mesh_processing/orientation.h | 11 ++++++++--- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/BGL/include/CGAL/boost/graph/parameters_interface.h b/BGL/include/CGAL/boost/graph/parameters_interface.h index 37fdf34a95e..a764e6b1890 100644 --- a/BGL/include/CGAL/boost/graph/parameters_interface.h +++ b/BGL/include/CGAL/boost/graph/parameters_interface.h @@ -83,9 +83,9 @@ CGAL_add_named_parameter(do_self_intersection_tests_t, do_self_intersection_test CGAL_add_named_parameter(error_codes_t, error_codes, error_codes) CGAL_add_named_parameter(volume_inclusions_t, volume_inclusions, volume_inclusions) CGAL_add_named_parameter(face_cc_map_t, face_connected_component_map, face_connected_component_map) - CGAL_add_named_parameter(ccid_to_vid_vector_t, connected_component_id_to_volume_id, connected_component_id_to_volume_id) CGAL_add_named_parameter(is_cc_outward_oriented_bs_t, is_cc_outward_oriented, is_cc_outward_oriented); +CGAL_add_named_parameter(intersecting_volume_pairs_t, intersecting_volume_pairs_output_iterator, intersecting_volume_pairs_output_iterator); // List of named parameters that we use in the package 'Surface Mesh Simplification' CGAL_add_named_parameter(get_cost_policy_t, get_cost_policy, get_cost) diff --git a/BGL/test/BGL/test_cgal_bgl_named_params.cpp b/BGL/test/BGL/test_cgal_bgl_named_params.cpp index ed60b02f4f5..4c8da57538e 100644 --- a/BGL/test/BGL/test_cgal_bgl_named_params.cpp +++ b/BGL/test/BGL/test_cgal_bgl_named_params.cpp @@ -168,6 +168,7 @@ void test(const NamedParameters& np) check_same_type<51>(get_param(np, CGAL::internal_np::face_connected_component_map)); check_same_type<52>(get_param(np, CGAL::internal_np::connected_component_id_to_volume_id)); check_same_type<53>(get_param(np, CGAL::internal_np::is_cc_outward_oriented)); + check_same_type<54>(get_param(np, CGAL::internal_np::intersecting_volume_pairs_output_iterator)); // Named parameters that we use in the package 'Surface Mesh Simplification' check_same_type<34>(get_param(np, CGAL::internal_np::get_cost_policy)); @@ -252,6 +253,7 @@ int main() .face_connected_component_map(A<51>(51)) .connected_component_id_to_volume_id(A<52>(52)) .is_cc_outward_oriented(A<53>(53)) + .intersecting_volume_pairs_output_iterator(A<54>(54)) ); return EXIT_SUCCESS; diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index 6e122e5c92a..b47f98b9f12 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -785,7 +785,7 @@ void copy_cc_to_volume_id( } inline void copy_cc_to_volume_id( - const std::vector&, + std::vector&, boost::param_not_found) {} @@ -798,7 +798,7 @@ void copy_orientation_bitset( } inline void copy_orientation_bitset( - const boost::dynamic_bitset<>&, + const std::vector&, boost::param_not_found) {} @@ -922,6 +922,11 @@ inline void set_cc_intersecting_pairs(const std::set< std::pair Date: Tue, 27 Aug 2019 08:10:12 +0200 Subject: [PATCH 048/141] use the new function to implement does_bound_a_volume this makes the implementation non-recursive --- .../CGAL/boost/graph/parameters_interface.h | 1 + BGL/test/BGL/test_cgal_bgl_named_params.cpp | 2 + .../Polygon_mesh_processing/orientation.h | 224 +++++++++++------- 3 files changed, 137 insertions(+), 90 deletions(-) diff --git a/BGL/include/CGAL/boost/graph/parameters_interface.h b/BGL/include/CGAL/boost/graph/parameters_interface.h index a764e6b1890..f9eef60109b 100644 --- a/BGL/include/CGAL/boost/graph/parameters_interface.h +++ b/BGL/include/CGAL/boost/graph/parameters_interface.h @@ -86,6 +86,7 @@ CGAL_add_named_parameter(face_cc_map_t, face_connected_component_map, face_conne CGAL_add_named_parameter(ccid_to_vid_vector_t, connected_component_id_to_volume_id, connected_component_id_to_volume_id) CGAL_add_named_parameter(is_cc_outward_oriented_bs_t, is_cc_outward_oriented, is_cc_outward_oriented); CGAL_add_named_parameter(intersecting_volume_pairs_t, intersecting_volume_pairs_output_iterator, intersecting_volume_pairs_output_iterator); +CGAL_add_named_parameter(i_used_as_a_predicate_t, i_used_as_a_predicate, i_used_as_a_predicate); // List of named parameters that we use in the package 'Surface Mesh Simplification' CGAL_add_named_parameter(get_cost_policy_t, get_cost_policy, get_cost) diff --git a/BGL/test/BGL/test_cgal_bgl_named_params.cpp b/BGL/test/BGL/test_cgal_bgl_named_params.cpp index 4c8da57538e..d5ada86ebe9 100644 --- a/BGL/test/BGL/test_cgal_bgl_named_params.cpp +++ b/BGL/test/BGL/test_cgal_bgl_named_params.cpp @@ -169,6 +169,7 @@ void test(const NamedParameters& np) check_same_type<52>(get_param(np, CGAL::internal_np::connected_component_id_to_volume_id)); check_same_type<53>(get_param(np, CGAL::internal_np::is_cc_outward_oriented)); check_same_type<54>(get_param(np, CGAL::internal_np::intersecting_volume_pairs_output_iterator)); + check_same_type<55>(get_param(np, CGAL::internal_np::i_used_as_a_predicate)); // Named parameters that we use in the package 'Surface Mesh Simplification' check_same_type<34>(get_param(np, CGAL::internal_np::get_cost_policy)); @@ -254,6 +255,7 @@ int main() .connected_component_id_to_volume_id(A<52>(52)) .is_cc_outward_oriented(A<53>(53)) .intersecting_volume_pairs_output_iterator(A<54>(54)) + .i_used_as_a_predicate(A<55>(55)) ); return EXIT_SUCCESS; diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index b47f98b9f12..b0c8ffb8787 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -630,94 +630,6 @@ void orient(TriangleMesh& tm) orient(tm, parameters::all_default()); } -/** \ingroup PMP_orientation_grp - * - * indicates if `tm` bounds a volume. - * See \ref coref_def_subsec for details. - * - * @tparam TriangleMesh a model of `MutableFaceGraph`, `HalfedgeListGraph` and `FaceListGraph`. - * @tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" - * - * @param tm a closed triangulated surface mesh - * @param np optional sequence of \ref pmp_namedparameters "Named Parameters" among the ones listed below - * - * @pre `CGAL::is_closed(tm)` - * - * \cgalNamedParamsBegin - * \cgalParamBegin{vertex_point_map} - * the property map with the points associated to the vertices of `tm`. - * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` must be available in `TriangleMesh` - * \cgalParamEnd - * \cgalParamBegin{face_index_map} - * a property map containing the index of each face of `tm`. - * \cgalParamEnd - * \cgalNamedParamsEnd - * - * \see `CGAL::Polygon_mesh_processing::orient_to_bound_a_volume()` - */ -template -bool does_bound_a_volume(const TriangleMesh& tm, const NamedParameters& np) -{ - typedef boost::graph_traits GT; - typedef typename GT::vertex_descriptor vertex_descriptor; - typedef typename GetVertexPointMap::const_type Vpm; - typedef typename GetFaceIndexMap::const_type Fid_map; - typedef typename Kernel_traits< - typename boost::property_traits::value_type >::Kernel Kernel; - - if (!is_closed(tm)) return false; - if (!is_triangle_mesh(tm)) return false; - - Vpm vpm = boost::choose_param(boost::get_param(np, internal_np::vertex_point), - get_const_property_map(boost::vertex_point, tm)); - - Fid_map fid_map = boost::choose_param(boost::get_param(np, internal_np::face_index), - get_const_property_map(boost::face_index, tm)); - - std::vector face_cc(num_faces(tm), std::size_t(-1)); - - // set the connected component id of each face - std::size_t nb_cc = connected_components(tm, - bind_property_maps(fid_map,make_property_map(face_cc)), - parameters::face_index_map(fid_map)); - - if (nb_cc == 1) - return true; - - boost::dynamic_bitset<> cc_handled(nb_cc, 0); - - // extract a vertex with max z coordinate for each connected component - std::vector xtrm_vertices(nb_cc, GT::null_vertex()); - BOOST_FOREACH(vertex_descriptor vd, vertices(tm)) - { - std::size_t cc_id = face_cc[get(fid_map, face(halfedge(vd, tm), tm))]; - if (xtrm_vertices[cc_id]==GT::null_vertex()) - xtrm_vertices[cc_id]=vd; - else - if (get(vpm, vd).z()>get(vpm,xtrm_vertices[cc_id]).z()) - xtrm_vertices[cc_id]=vd; - } - - //extract a vertex with max z amongst all components - std::size_t xtrm_cc_id=0; - for(std::size_t id=1; idget(vpm,xtrm_vertices[xtrm_cc_id]).z()) - xtrm_cc_id=id; - - bool is_parent_outward_oriented = - !internal::is_outward_oriented(xtrm_vertices[xtrm_cc_id], tm, np); - - return internal::recursive_does_bound_a_volume(tm, vpm, fid_map, - xtrm_vertices, - cc_handled, - face_cc, - xtrm_cc_id, - is_parent_outward_oriented); -} - /*! * \ingroup PMP_orientation_grp * Enumeration type used to indicate the status of a set of faces @@ -977,6 +889,12 @@ volume_connected_components(const TriangleMesh& tm, !boost::choose_param(boost::get_param(np, internal_np::do_orientation_tests), true); + const bool used_as_a_predicate = + boost::choose_param(boost::get_param(np, internal_np::i_used_as_a_predicate), + false); // indicate if the function is called by does_bound_a_volume + + CGAL_assertion(!used_as_a_predicate || !ignore_orientation_of_cc); + std::vector error_codes; std::vector is_cc_outward_oriented; std::vector cc_volume_ids(nb_cc, -1); @@ -1016,6 +934,7 @@ volume_connected_components(const TriangleMesh& tm, cc_handled.set(cc_id); cc_volume_ids[cc_id]=next_volume_id++; error_codes.push_back(OPEN_SURFACE); + if (used_as_a_predicate) return 0; } } } @@ -1027,6 +946,10 @@ volume_connected_components(const TriangleMesh& tm, if (do_self_intersection_tests) self_intersections(tm, std::back_inserter(si_faces)); std::vector is_involved_in_self_intersection(nb_cc, false); + + if (!si_faces.empty() && used_as_a_predicate) + return 0; + for(const Face_pair& fp : si_faces) { std::size_t first_cc_id = face_cc[ get(fid_map, fp.first) ]; @@ -1194,6 +1117,7 @@ volume_connected_components(const TriangleMesh& tm, else if( is_cc_outward_oriented[cc_id] != is_cc_outward_oriented[ref_cc_id] ) { + if (used_as_a_predicate) return 0; // all is indefinite for(std::size_t id=0; id +bool does_bound_a_volume(const TriangleMesh& tm, const NamedParameters& np) +{ + typedef boost::graph_traits GT; + typedef typename GT::face_descriptor face_descriptor; + + if (!is_closed(tm)) return false; + if (!is_triangle_mesh(tm)) return false; + + Static_property_map vidmap(0); + std::size_t res = + volume_connected_components(tm, vidmap, np.do_orientation_tests(true) + .i_used_as_a_predicate(true)); + CGAL_assertion(res==0 || res==1); + + return res!=0; + +#if 0 // recursive implementation + typedef typename GetVertexPointMap::const_type Vpm; + Vpm vpm = boost::choose_param(boost::get_param(np, internal_np::vertex_point), + get_const_property_map(boost::vertex_point, tm)); + + typedef typename GetFaceIndexMap::const_type Fid_map; + typedef typename Kernel_traits< + typename boost::property_traits::value_type >::Kernel Kernel; + + Fid_map fid_map = boost::choose_param(boost::get_param(np, internal_np::face_index), + get_const_property_map(boost::face_index, tm)); + + std::vector face_cc(num_faces(tm), std::size_t(-1)); + + // set the connected component id of each face + std::size_t nb_cc = connected_components(tm, + bind_property_maps(fid_map,make_property_map(face_cc)), + parameters::face_index_map(fid_map)); + + if (nb_cc == 1) + return true; + + boost::dynamic_bitset<> cc_handled(nb_cc, 0); + + // extract a vertex with max z coordinate for each connected component + typedef typename GT::vertex_descriptor vertex_descriptor; + std::vector xtrm_vertices(nb_cc, GT::null_vertex()); + BOOST_FOREACH(vertex_descriptor vd, vertices(tm)) + { + std::size_t cc_id = face_cc[get(fid_map, face(halfedge(vd, tm), tm))]; + if (xtrm_vertices[cc_id]==GT::null_vertex()) + xtrm_vertices[cc_id]=vd; + else + if (get(vpm, vd).z()>get(vpm,xtrm_vertices[cc_id]).z()) + xtrm_vertices[cc_id]=vd; + } + + //extract a vertex with max z amongst all components + std::size_t xtrm_cc_id=0; + for(std::size_t id=1; idget(vpm,xtrm_vertices[xtrm_cc_id]).z()) + xtrm_cc_id=id; + + bool is_parent_outward_oriented = + !internal::is_outward_oriented(xtrm_vertices[xtrm_cc_id], tm, np); + + return internal::recursive_does_bound_a_volume(tm, vpm, fid_map, + xtrm_vertices, + cc_handled, + face_cc, + xtrm_cc_id, + is_parent_outward_oriented); +#endif +} + /// \cond SKIP_IN_MANUAL template bool does_bound_a_volume(const TriangleMesh& tm) From 09de5587a6d72d4ac2f2e4538f4459f8ab378753 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 27 Aug 2019 08:13:24 +0200 Subject: [PATCH 049/141] remove no longer used function --- .../Polygon_mesh_processing/orientation.h | 141 ------------------ 1 file changed, 141 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index b0c8ffb8787..5bbc1e7c3ae 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -351,91 +351,6 @@ void reverse_face_orientations(const FaceRange& face_range, PolygonMesh& pmesh) } namespace internal { -template -bool recursive_does_bound_a_volume(const TriangleMesh& tm, - Vpm& vpm, - Fid_map& fid_map, - const std::vector& xtrm_vertices, - boost::dynamic_bitset<>& cc_handled, - const std::vector& face_cc, - std::size_t xtrm_cc_id, - bool is_parent_outward_oriented) -{ - typedef boost::graph_traits GT; - typedef typename GT::face_descriptor face_descriptor; - typedef Side_of_triangle_mesh Side_of_tm; -// first check that the orientation of the current cc is consistant with its -// parent cc containing it - bool new_is_parent_outward_oriented = internal::is_outward_oriented( - xtrm_vertices[xtrm_cc_id], tm, parameters::vertex_point_map(vpm)); - if (new_is_parent_outward_oriented==is_parent_outward_oriented) - return false; - cc_handled.set(xtrm_cc_id); - - std::size_t nb_cc = cc_handled.size(); - -// get all cc that are inside xtrm_cc_id - std::vector cc_faces; - BOOST_FOREACH(face_descriptor fd, faces(tm)) - { - if(face_cc[get(fid_map, fd)]==xtrm_cc_id) - cc_faces.push_back(fd); - } - - typename Side_of_tm::AABB_tree aabb_tree(cc_faces.begin(), cc_faces.end(), - tm, vpm); - Side_of_tm side_of_cc(aabb_tree); - - std::vector cc_inside; - for(std::size_t id=0; id new_cc_handled(nb_cc,0); - new_cc_handled.set(); - new_cc_handled.reset(new_xtrm_cc_id); - cc_handled.set(new_xtrm_cc_id); - - std::size_t nb_candidates = cc_inside.size(); - for (std::size_t i=1;i - get(vpm,xtrm_vertices[new_xtrm_cc_id]).z()) new_xtrm_cc_id=candidate; - new_cc_handled.reset(candidate); - cc_handled.set(candidate); - } - - if ( !internal::recursive_does_bound_a_volume( - tm, vpm, fid_map, xtrm_vertices, new_cc_handled, face_cc, - new_xtrm_cc_id, new_is_parent_outward_oriented) ) return false; - } - -// now explore remaining cc included in the same cc as xtrm_cc_id - boost::dynamic_bitset<> cc_not_handled = ~cc_handled; - std::size_t new_xtrm_cc_id = cc_not_handled.find_first(); - if (new_xtrm_cc_id == cc_not_handled.npos) return true; - - for (std::size_t candidate = cc_not_handled.find_next(new_xtrm_cc_id); - candidate < cc_not_handled.npos; - candidate = cc_not_handled.find_next(candidate)) - { - if(get(vpm,xtrm_vertices[candidate]).z() > get(vpm,xtrm_vertices[new_xtrm_cc_id]).z()) - new_xtrm_cc_id = candidate; - } - - return internal::recursive_does_bound_a_volume( - tm, vpm, fid_map, xtrm_vertices, cc_handled, face_cc, - new_xtrm_cc_id, is_parent_outward_oriented); -} - template void recursive_orient_volume_ccs( TriangleMesh& tm, Vpm& vpm, @@ -1326,62 +1241,6 @@ bool does_bound_a_volume(const TriangleMesh& tm, const NamedParameters& np) CGAL_assertion(res==0 || res==1); return res!=0; - -#if 0 // recursive implementation - typedef typename GetVertexPointMap::const_type Vpm; - Vpm vpm = boost::choose_param(boost::get_param(np, internal_np::vertex_point), - get_const_property_map(boost::vertex_point, tm)); - - typedef typename GetFaceIndexMap::const_type Fid_map; - typedef typename Kernel_traits< - typename boost::property_traits::value_type >::Kernel Kernel; - - Fid_map fid_map = boost::choose_param(boost::get_param(np, internal_np::face_index), - get_const_property_map(boost::face_index, tm)); - - std::vector face_cc(num_faces(tm), std::size_t(-1)); - - // set the connected component id of each face - std::size_t nb_cc = connected_components(tm, - bind_property_maps(fid_map,make_property_map(face_cc)), - parameters::face_index_map(fid_map)); - - if (nb_cc == 1) - return true; - - boost::dynamic_bitset<> cc_handled(nb_cc, 0); - - // extract a vertex with max z coordinate for each connected component - typedef typename GT::vertex_descriptor vertex_descriptor; - std::vector xtrm_vertices(nb_cc, GT::null_vertex()); - BOOST_FOREACH(vertex_descriptor vd, vertices(tm)) - { - std::size_t cc_id = face_cc[get(fid_map, face(halfedge(vd, tm), tm))]; - if (xtrm_vertices[cc_id]==GT::null_vertex()) - xtrm_vertices[cc_id]=vd; - else - if (get(vpm, vd).z()>get(vpm,xtrm_vertices[cc_id]).z()) - xtrm_vertices[cc_id]=vd; - } - - //extract a vertex with max z amongst all components - std::size_t xtrm_cc_id=0; - for(std::size_t id=1; idget(vpm,xtrm_vertices[xtrm_cc_id]).z()) - xtrm_cc_id=id; - - bool is_parent_outward_oriented = - !internal::is_outward_oriented(xtrm_vertices[xtrm_cc_id], tm, np); - - return internal::recursive_does_bound_a_volume(tm, vpm, fid_map, - xtrm_vertices, - cc_handled, - face_cc, - xtrm_cc_id, - is_parent_outward_oriented); -#endif } /// \cond SKIP_IN_MANUAL From 0e7d85ca07451a6d262a275ac685539873169fe5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 27 Aug 2019 08:29:44 +0200 Subject: [PATCH 050/141] add TODO --- .../include/CGAL/Polygon_mesh_processing/orientation.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index 5bbc1e7c3ae..3cd07a1f78c 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -758,6 +758,7 @@ inline void set_cc_intersecting_pairs(const std::set< std::pair std::size_t From 7fd73c3919fbdaac16bda30216ff717f6a897aca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 30 Aug 2019 17:25:21 +0200 Subject: [PATCH 051/141] use the new function to implement orient_to_bound_a_volume the former implementation was recursive this makes the implementation non-recursive --- .../CGAL/boost/graph/parameters_interface.h | 2 + BGL/test/BGL/test_cgal_bgl_named_params.cpp | 4 + .../Polygon_mesh_processing/orientation.h | 209 +++++++----------- .../test_orient_cc.cpp | 15 ++ 4 files changed, 102 insertions(+), 128 deletions(-) diff --git a/BGL/include/CGAL/boost/graph/parameters_interface.h b/BGL/include/CGAL/boost/graph/parameters_interface.h index f9eef60109b..43710fa8253 100644 --- a/BGL/include/CGAL/boost/graph/parameters_interface.h +++ b/BGL/include/CGAL/boost/graph/parameters_interface.h @@ -87,6 +87,8 @@ CGAL_add_named_parameter(ccid_to_vid_vector_t, connected_component_id_to_volume_ CGAL_add_named_parameter(is_cc_outward_oriented_bs_t, is_cc_outward_oriented, is_cc_outward_oriented); CGAL_add_named_parameter(intersecting_volume_pairs_t, intersecting_volume_pairs_output_iterator, intersecting_volume_pairs_output_iterator); CGAL_add_named_parameter(i_used_as_a_predicate_t, i_used_as_a_predicate, i_used_as_a_predicate); +CGAL_add_named_parameter(nesting_levels_t, nesting_levels, nesting_levels); +CGAL_add_named_parameter(i_used_for_volume_orientation_t, i_used_for_volume_orientation, i_used_for_volume_orientation); // List of named parameters that we use in the package 'Surface Mesh Simplification' CGAL_add_named_parameter(get_cost_policy_t, get_cost_policy, get_cost) diff --git a/BGL/test/BGL/test_cgal_bgl_named_params.cpp b/BGL/test/BGL/test_cgal_bgl_named_params.cpp index d5ada86ebe9..ddab4a8a481 100644 --- a/BGL/test/BGL/test_cgal_bgl_named_params.cpp +++ b/BGL/test/BGL/test_cgal_bgl_named_params.cpp @@ -170,6 +170,8 @@ void test(const NamedParameters& np) check_same_type<53>(get_param(np, CGAL::internal_np::is_cc_outward_oriented)); check_same_type<54>(get_param(np, CGAL::internal_np::intersecting_volume_pairs_output_iterator)); check_same_type<55>(get_param(np, CGAL::internal_np::i_used_as_a_predicate)); + check_same_type<56>(get_param(np, CGAL::internal_np::nesting_levels)); + check_same_type<57>(get_param(np, CGAL::internal_np::i_used_for_volume_orientation)); // Named parameters that we use in the package 'Surface Mesh Simplification' check_same_type<34>(get_param(np, CGAL::internal_np::get_cost_policy)); @@ -256,6 +258,8 @@ int main() .is_cc_outward_oriented(A<53>(53)) .intersecting_volume_pairs_output_iterator(A<54>(54)) .i_used_as_a_predicate(A<55>(55)) + .nesting_levels(A<56>(56)) + .i_used_for_volume_orientation(A<57>(57)) ); return EXIT_SUCCESS; diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index 3cd07a1f78c..2a720f13e67 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -349,97 +349,6 @@ void reverse_face_orientations(const FaceRange& face_range, PolygonMesh& pmesh) } } } -namespace internal { - -template -void recursive_orient_volume_ccs( TriangleMesh& tm, - Vpm& vpm, - Fid_map& fid_map, - const std::vector& xtrm_vertices, - boost::dynamic_bitset<>& cc_handled, - const std::vector& face_cc, - std::size_t xtrm_cc_id, - bool is_parent_outward_oriented) -{ - typedef boost::graph_traits Graph_traits; - typedef typename Graph_traits::face_descriptor face_descriptor; - typedef Side_of_triangle_mesh Side_of_tm; - std::vector cc_faces; - BOOST_FOREACH(face_descriptor fd, faces(tm)) - { - if(face_cc[get(fid_map, fd)]==xtrm_cc_id) - cc_faces.push_back(fd); - } -// first check that the orientation of the current cc is consistant with its -// parent cc containing it - bool new_is_parent_outward_oriented = internal::is_outward_oriented( - xtrm_vertices[xtrm_cc_id], tm, parameters::vertex_point_map(vpm)); - if (new_is_parent_outward_oriented==is_parent_outward_oriented) - { - Polygon_mesh_processing::reverse_face_orientations(cc_faces, tm); - new_is_parent_outward_oriented = !new_is_parent_outward_oriented; - } - cc_handled.set(xtrm_cc_id); - - std::size_t nb_cc = cc_handled.size(); - -// get all cc that are inside xtrm_cc_id - - typename Side_of_tm::AABB_tree aabb_tree(cc_faces.begin(), cc_faces.end(), - tm, vpm); - Side_of_tm side_of_cc(aabb_tree); - - std::vector cc_inside; - for(std::size_t id=0; id new_cc_handled(nb_cc,0); - new_cc_handled.set(); - new_cc_handled.reset(new_xtrm_cc_id); - cc_handled.set(new_xtrm_cc_id); - - std::size_t nb_candidates = cc_inside.size(); - for (std::size_t i=1;i - get(vpm,xtrm_vertices[new_xtrm_cc_id]).z()) new_xtrm_cc_id=candidate; - new_cc_handled.reset(candidate); - cc_handled.set(candidate); - } - - internal::recursive_orient_volume_ccs( - tm, vpm, fid_map, xtrm_vertices, new_cc_handled, face_cc, - new_xtrm_cc_id, new_is_parent_outward_oriented); - } - -// now explore remaining cc included in the same cc as xtrm_cc_id - boost::dynamic_bitset<> cc_not_handled = ~cc_handled; - std::size_t new_xtrm_cc_id = cc_not_handled.find_first(); - if (new_xtrm_cc_id == cc_not_handled.npos) return ; - - for (std::size_t candidate = cc_not_handled.find_next(new_xtrm_cc_id); - candidate < cc_not_handled.npos; - candidate = cc_not_handled.find_next(candidate)) - { - if(get(vpm,xtrm_vertices[candidate]).z() > get(vpm,xtrm_vertices[new_xtrm_cc_id]).z()) - new_xtrm_cc_id = candidate; - } - - internal::recursive_orient_volume_ccs( - tm, vpm, fid_map, xtrm_vertices, cc_handled, face_cc, - new_xtrm_cc_id, is_parent_outward_oriented); -} - -}//end internal /** * \ingroup PMP_orientation_grp @@ -616,6 +525,19 @@ inline void copy_cc_to_volume_id( boost::param_not_found) {} +template +void copy_nesting_levels( + std::vector& nesting_levels, + RefToVector ref_to_vector) +{ + ref_to_vector.get().swap( nesting_levels ); +} + +inline void copy_nesting_levels( + std::vector&, + boost::param_not_found) +{} + template void copy_orientation_bitset( const std::vector& is_cc_outward_oriented, @@ -741,6 +663,13 @@ inline void set_cc_intersecting_pairs(const std::set< std::pair`. + * The size of the vector is exactly the number of connected components. + * For each connected component identified using its id `ccid`, the vector contains the number of + * connected components containing on its bounded side this component. + * \cgalParamEnd * \cgalParamBegin{is_cc_outward_oriented} * a `reference_wrapper` (either from `boost` or the standard library) containing * a reference to an object of type `std::vector`. @@ -757,8 +686,6 @@ inline void set_cc_intersecting_pairs(const std::set< std::pair std::size_t @@ -814,6 +741,7 @@ volume_connected_components(const TriangleMesh& tm, std::vector error_codes; std::vector is_cc_outward_oriented; std::vector cc_volume_ids(nb_cc, -1); + std::vector < std::size_t > nesting_levels(nb_cc, 0); // indicates for each CC its nesting level if (nb_cc == 1) { @@ -939,7 +867,6 @@ volume_connected_components(const TriangleMesh& tm, // another container to not more than once the inclusion testing (in case a CC is // included by more than 2 CC) + associate such CC to only one volume std::vector > nested_cc_per_cc_shared(nb_cc); - std::vector < std::size_t > nesting_levels(nb_cc, 0); // indicates for each CC its nesting level std::vector < boost::dynamic_bitset<> > level_k_nestings; // container containing CCs in the same volume (one bitset per volume) at level k level_k_nestings.push_back( ~cc_handled ); @@ -1017,6 +944,15 @@ volume_connected_components(const TriangleMesh& tm, ++k; level_k_nestings.swap(level_k_plus_1_nestings); } + + // early return for orient_to_bound_a_volume + if (boost::choose_param(boost::get_param(np, internal_np::i_used_for_volume_orientation),false)) + { + internal::copy_nesting_levels(nesting_levels, boost::get_param(np, internal_np::nesting_levels)); + internal::copy_orientation_bitset(is_cc_outward_oriented, boost::get_param(np, internal_np::is_cc_outward_oriented)); + return 0; + } + // detect inconsistencies of the orientation at the level 0 // and check if all CC at level 0 are in the same volume std::size_t ref_cc_id = nb_cc; @@ -1193,6 +1129,7 @@ volume_connected_components(const TriangleMesh& tm, CGAL_assertion(next_volume_id == error_codes.size()); internal::copy_error_codes(error_codes, boost::get_param(np, internal_np::error_codes)); internal::copy_nested_parents(nesting_parents, boost::get_param(np, internal_np::volume_inclusions)); + internal::copy_nesting_levels(nesting_levels, boost::get_param(np, internal_np::nesting_levels)); internal::copy_cc_to_volume_id(cc_volume_ids, boost::get_param(np, internal_np::connected_component_id_to_volume_id)); internal::copy_orientation_bitset(is_cc_outward_oriented, boost::get_param(np, internal_np::is_cc_outward_oriented)); internal::set_cc_intersecting_pairs(self_intersecting_cc, boost::get_param(np, internal_np::intersecting_volume_pairs_output_iterator)); @@ -1235,10 +1172,10 @@ bool does_bound_a_volume(const TriangleMesh& tm, const NamedParameters& np) if (!is_closed(tm)) return false; if (!is_triangle_mesh(tm)) return false; - Static_property_map vidmap(0); + Static_property_map vidmap(0); // dummy map not used std::size_t res = volume_connected_components(tm, vidmap, np.do_orientation_tests(true) - .i_used_as_a_predicate(true)); + .i_used_as_a_predicate(true)); CGAL_assertion(res==0 || res==1); return res!=0; @@ -1295,13 +1232,11 @@ void orient_to_bound_a_volume(TriangleMesh& tm, const NamedParameters& np) { typedef boost::graph_traits Graph_traits; - typedef typename Graph_traits::vertex_descriptor vertex_descriptor; + typedef typename Graph_traits::face_descriptor face_descriptor; typedef typename GetVertexPointMap::const_type Vpm; typedef typename GetFaceIndexMap::const_type Fid_map; - typedef typename Kernel_traits< - typename boost::property_traits::value_type >::Kernel Kernel; if (!is_closed(tm)) return; if (!is_triangle_mesh(tm)) return; @@ -1320,48 +1255,66 @@ void orient_to_bound_a_volume(TriangleMesh& tm, std::vector face_cc(num_faces(tm), std::size_t(-1)); + std::vector nesting_levels; + std::vector is_cc_outward_oriented; + Static_property_map vidmap(0); // dummy map not used + + volume_connected_components(tm, vidmap, + parameters::vertex_point_map(vpm) + .nesting_levels(boost::ref(nesting_levels)) + .face_connected_component_map(bind_property_maps(fid_map,make_property_map(face_cc))) + .i_used_for_volume_orientation(true) + .do_orientation_tests(true) + .is_cc_outward_oriented(boost::ref(is_cc_outward_oriented)) + ); + // set the connected component id of each face - std::size_t nb_cc = connected_components(tm, - bind_property_maps(fid_map,make_property_map(face_cc)), - parameters::face_index_map(fid_map)); + std::size_t nb_cc = nesting_levels.size(); if (nb_cc == 1) { - if( orient_outward != is_outward_oriented(tm)) + if( orient_outward != is_cc_outward_oriented[0]) reverse_face_orientations(faces(tm), tm); return ; } - - boost::dynamic_bitset<> cc_handled(nb_cc, 0); - - // extract a vertex with max z coordinate for each connected component - std::vector xtrm_vertices(nb_cc, Graph_traits::null_vertex()); - BOOST_FOREACH(vertex_descriptor vd, vertices(tm)) + boost::dynamic_bitset<> cc_to_reverse(nb_cc, 0); + for(std::size_t i=0; iget(vpm,xtrm_vertices[cc_id]).z()) - xtrm_vertices[cc_id]=vd; + { + if (nesting_levels[i]%2==0) + { + if (is_cc_outward_oriented[i]) + cc_to_reverse.set(i); + } + else + { + if (!is_cc_outward_oriented[i]) + cc_to_reverse.set(i); + } + } } - //extract a vertex with max z amongst all components - std::size_t xtrm_cc_id=0; - for(std::size_t id=1; idget(vpm,xtrm_vertices[xtrm_cc_id]).z()) - xtrm_cc_id=id; + std::vector faces_to_reverse; + for (face_descriptor f : faces(tm)) + if ( cc_to_reverse.test( face_cc[get(fid_map, f)] ) ) + faces_to_reverse.push_back(f); - bool is_parent_outward_oriented = - ! orient_outward; - - internal::recursive_orient_volume_ccs(tm, vpm, fid_map, - xtrm_vertices, - cc_handled, - face_cc, - xtrm_cc_id, - is_parent_outward_oriented); + reverse_face_orientations(faces_to_reverse, tm); } template diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_orient_cc.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_orient_cc.cpp index 78e66369cbb..85e5f3cf830 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_orient_cc.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_orient_cc.cpp @@ -119,6 +119,7 @@ int main() return 1; } + assert(!PMP::does_bound_a_volume(volume)); PMP::orient_to_bound_a_volume(volume); if( !PMP::does_bound_a_volume(volume)) { @@ -126,5 +127,19 @@ int main() return 1; } + PMP::orient_to_bound_a_volume(volume); + if( !PMP::does_bound_a_volume(volume)) + { + std::cerr << "ERROR for test5\n"; + return 1; + } + + PMP::orient_to_bound_a_volume(volume); + if( !PMP::does_bound_a_volume(volume, CGAL::parameters::outward_orientation(false)) ) + { + std::cerr << "ERROR for test6\n"; + return 1; + } + return 0; } From a5e3841a14becd657298edef44e7c5dd78d40253 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 30 Aug 2019 17:43:21 +0200 Subject: [PATCH 052/141] reduce expression + improve test --- .../Polygon_mesh_processing/orientation.h | 26 ++----------------- .../test_orient_cc.cpp | 7 ++--- 2 files changed, 6 insertions(+), 27 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index 2a720f13e67..83364704ebf 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -1281,31 +1281,9 @@ void orient_to_bound_a_volume(TriangleMesh& tm, boost::dynamic_bitset<> cc_to_reverse(nb_cc, 0); for(std::size_t i=0; i> sm1; sm2 = sm1; sm3 = sm1; sm4 = sm1; volume = sm1; + volume_copy = volume; PMP::orient(sm1); if(!test_orientation(sm1, true, PMP::parameters::all_default())) return 1; @@ -134,8 +135,8 @@ int main() return 1; } - PMP::orient_to_bound_a_volume(volume); - if( !PMP::does_bound_a_volume(volume, CGAL::parameters::outward_orientation(false)) ) + PMP::orient_to_bound_a_volume(volume_copy, CGAL::parameters::outward_orientation(false)); + if( !PMP::does_bound_a_volume(volume_copy) ) { std::cerr << "ERROR for test6\n"; return 1; From 54895543b3dfd54aee731fc7b96012d417111aab Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 4 Sep 2019 17:04:20 +0200 Subject: [PATCH 053/141] Fix boost::get_param and bad if() --- BGL/test/BGL/test_cgal_bgl_named_params.cpp | 22 +++--- .../Polygon_mesh_processing/orientation.h | 69 ++++++++----------- 2 files changed, 41 insertions(+), 50 deletions(-) diff --git a/BGL/test/BGL/test_cgal_bgl_named_params.cpp b/BGL/test/BGL/test_cgal_bgl_named_params.cpp index 4f3c6915307..d5e9d68ec0d 100644 --- a/BGL/test/BGL/test_cgal_bgl_named_params.cpp +++ b/BGL/test/BGL/test_cgal_bgl_named_params.cpp @@ -175,17 +175,17 @@ void test(const NamedParameters& np) check_same_type<54>(get_parameter(np, CGAL::internal_np::use_area_smoothing)); check_same_type<55>(get_parameter(np, CGAL::internal_np::use_Delaunay_flips)); check_same_type<56>(get_parameter(np, CGAL::internal_np::use_safety_constraints)); - check_same_type<58>(get_param(np, CGAL::internal_np::do_self_intersection_tests)); - check_same_type<59>(get_param(np, CGAL::internal_np::do_orientation_tests)); - check_same_type<60>(get_param(np, CGAL::internal_np::error_codes)); - check_same_type<61>(get_param(np, CGAL::internal_np::volume_inclusions)); - check_same_type<62>(get_param(np, CGAL::internal_np::face_connected_component_map)); - check_same_type<63>(get_param(np, CGAL::internal_np::connected_component_id_to_volume_id)); - check_same_type<64>(get_param(np, CGAL::internal_np::is_cc_outward_oriented)); - check_same_type<65>(get_param(np, CGAL::internal_np::intersecting_volume_pairs_output_iterator)); - check_same_type<66>(get_param(np, CGAL::internal_np::i_used_as_a_predicate)); - check_same_type<67>(get_param(np, CGAL::internal_np::nesting_levels)); - check_same_type<68>(get_param(np, CGAL::internal_np::i_used_for_volume_orientation)); + check_same_type<58>(get_parameter(np, CGAL::internal_np::do_self_intersection_tests)); + check_same_type<59>(get_parameter(np, CGAL::internal_np::do_orientation_tests)); + check_same_type<60>(get_parameter(np, CGAL::internal_np::error_codes)); + check_same_type<61>(get_parameter(np, CGAL::internal_np::volume_inclusions)); + check_same_type<62>(get_parameter(np, CGAL::internal_np::face_connected_component_map)); + check_same_type<63>(get_parameter(np, CGAL::internal_np::connected_component_id_to_volume_id)); + check_same_type<64>(get_parameter(np, CGAL::internal_np::is_cc_outward_oriented)); + check_same_type<65>(get_parameter(np, CGAL::internal_np::intersecting_volume_pairs_output_iterator)); + check_same_type<66>(get_parameter(np, CGAL::internal_np::i_used_as_a_predicate)); + check_same_type<67>(get_parameter(np, CGAL::internal_np::nesting_levels)); + check_same_type<68>(get_parameter(np, CGAL::internal_np::i_used_for_volume_orientation)); // Named parameters that we use in the package 'Surface Mesh Simplification' diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index cd4fce9805b..c8aa831db92 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -476,7 +476,7 @@ void copy_error_codes(std::vector& error_codes_in, } inline void copy_error_codes(std::vector&, - boost::param_not_found) + internal_np::Param_not_found) {} template @@ -489,7 +489,7 @@ void copy_nested_parents( inline void copy_nested_parents( std::vector< std::vector >&, - boost::param_not_found) + internal_np::Param_not_found) {} template @@ -507,7 +507,7 @@ void set_f_cc_id(const std::vector& f_cc, template void set_f_cc_id(const std::vector&, FaceIndexMap, - boost::param_not_found, + internal_np::Param_not_found, const TriangleMesh&) {} @@ -521,7 +521,7 @@ void copy_cc_to_volume_id( inline void copy_cc_to_volume_id( std::vector&, - boost::param_not_found) + internal_np::Param_not_found) {} template @@ -534,7 +534,7 @@ void copy_nesting_levels( inline void copy_nesting_levels( std::vector&, - boost::param_not_found) + internal_np::Param_not_found) {} template @@ -547,7 +547,7 @@ void copy_orientation_bitset( inline void copy_orientation_bitset( const std::vector&, - boost::param_not_found) + internal_np::Param_not_found) {} template @@ -561,7 +561,7 @@ void set_cc_intersecting_pairs(const std::set< std::pair >&, - boost::param_not_found) + internal_np::Param_not_found) {} } // internal @@ -705,10 +705,10 @@ volume_connected_components(const TriangleMesh& tm, typedef typename Kernel_traits< typename boost::property_traits::value_type >::Kernel Kernel; - Vpm vpm = boost::choose_param(boost::get_param(np, internal_np::vertex_point), + Vpm vpm = parameters::choose_parameter(parameters::get_parameter(np, internal_np::vertex_point), get_const_property_map(boost::vertex_point, tm)); - Fid_map fid_map = boost::choose_param(boost::get_param(np, internal_np::face_index), + Fid_map fid_map = parameters::choose_parameter(parameters::get_parameter(np, internal_np::face_index), get_const_property_map(boost::face_index, tm)); std::vector face_cc(num_faces(tm), std::size_t(-1)); @@ -722,17 +722,17 @@ volume_connected_components(const TriangleMesh& tm, std::vector > nested_cc_per_cc(nb_cc); // copy cc-id info - internal::set_f_cc_id(face_cc, fid_map, boost::get_param(np, internal_np::face_connected_component_map), tm); + internal::set_f_cc_id(face_cc, fid_map, parameters::get_parameter(np, internal_np::face_connected_component_map), tm); const bool do_self_intersection_tests = - boost::choose_param(boost::get_param(np, internal_np::do_self_intersection_tests), + parameters::choose_parameter(parameters::get_parameter(np, internal_np::do_self_intersection_tests), false); const bool ignore_orientation_of_cc = - !boost::choose_param(boost::get_param(np, internal_np::do_orientation_tests), + !parameters::choose_parameter(parameters::get_parameter(np, internal_np::do_orientation_tests), true); const bool used_as_a_predicate = - boost::choose_param(boost::get_param(np, internal_np::i_used_as_a_predicate), + parameters::choose_parameter(parameters::get_parameter(np, internal_np::i_used_as_a_predicate), false); // indicate if the function is called by does_bound_a_volume CGAL_assertion(!used_as_a_predicate || !ignore_orientation_of_cc); @@ -749,16 +749,16 @@ volume_connected_components(const TriangleMesh& tm, for(face_descriptor fd : faces(tm)) put(volume_id_map, fd, 0); - internal::copy_error_codes(error_codes, boost::get_param(np, internal_np::error_codes)); + internal::copy_error_codes(error_codes, parameters::get_parameter(np, internal_np::error_codes)); // nested_cc_per_cc is empty and used to clear the vector passed in case it was not empty - internal::copy_nested_parents(nested_cc_per_cc, boost::get_param(np, internal_np::volume_inclusions)); + internal::copy_nested_parents(nested_cc_per_cc, parameters::get_parameter(np, internal_np::volume_inclusions)); if (!ignore_orientation_of_cc && - !boost::is_default_param(get_param(np, internal_np::connected_component_id_to_volume_id))) + !parameters::is_default_parameter(parameters::get_parameter(np, internal_np::is_cc_outward_oriented))) { is_cc_outward_oriented.push_back(is_outward_oriented(tm, np)); - internal::copy_orientation_bitset(is_cc_outward_oriented, boost::get_param(np, internal_np::is_cc_outward_oriented)); + internal::copy_orientation_bitset(is_cc_outward_oriented, parameters::get_parameter(np, internal_np::is_cc_outward_oriented)); } - internal::copy_cc_to_volume_id(cc_volume_ids, boost::get_param(np, internal_np::connected_component_id_to_volume_id)); + internal::copy_cc_to_volume_id(cc_volume_ids, parameters::get_parameter(np, internal_np::connected_component_id_to_volume_id)); return 1; } @@ -945,10 +945,10 @@ volume_connected_components(const TriangleMesh& tm, } // early return for orient_to_bound_a_volume - if (boost::choose_param(boost::get_param(np, internal_np::i_used_for_volume_orientation),false)) + if (parameters::choose_parameter(parameters::get_parameter(np, internal_np::i_used_for_volume_orientation),false)) { - internal::copy_nesting_levels(nesting_levels, boost::get_param(np, internal_np::nesting_levels)); - internal::copy_orientation_bitset(is_cc_outward_oriented, boost::get_param(np, internal_np::is_cc_outward_oriented)); + internal::copy_nesting_levels(nesting_levels, parameters::get_parameter(np, internal_np::nesting_levels)); + internal::copy_orientation_bitset(is_cc_outward_oriented, parameters::get_parameter(np, internal_np::is_cc_outward_oriented)); return 0; } @@ -1126,12 +1126,12 @@ volume_connected_components(const TriangleMesh& tm, } CGAL_assertion(next_volume_id == error_codes.size()); - internal::copy_error_codes(error_codes, boost::get_param(np, internal_np::error_codes)); - internal::copy_nested_parents(nesting_parents, boost::get_param(np, internal_np::volume_inclusions)); - internal::copy_nesting_levels(nesting_levels, boost::get_param(np, internal_np::nesting_levels)); - internal::copy_cc_to_volume_id(cc_volume_ids, boost::get_param(np, internal_np::connected_component_id_to_volume_id)); - internal::copy_orientation_bitset(is_cc_outward_oriented, boost::get_param(np, internal_np::is_cc_outward_oriented)); - internal::set_cc_intersecting_pairs(self_intersecting_cc, boost::get_param(np, internal_np::intersecting_volume_pairs_output_iterator)); + internal::copy_error_codes(error_codes, parameters::get_parameter(np, internal_np::error_codes)); + internal::copy_nested_parents(nesting_parents, parameters::get_parameter(np, internal_np::volume_inclusions)); + internal::copy_nesting_levels(nesting_levels, parameters::get_parameter(np, internal_np::nesting_levels)); + internal::copy_cc_to_volume_id(cc_volume_ids, parameters::get_parameter(np, internal_np::connected_component_id_to_volume_id)); + internal::copy_orientation_bitset(is_cc_outward_oriented, parameters::get_parameter(np, internal_np::is_cc_outward_oriented)); + internal::set_cc_intersecting_pairs(self_intersecting_cc, parameters::get_parameter(np, internal_np::intersecting_volume_pairs_output_iterator)); return next_volume_id; } @@ -1268,26 +1268,17 @@ void orient_to_bound_a_volume(TriangleMesh& tm, ); // set the connected component id of each face - std::size_t nb_cc = nesting_levels.size(); - if (nb_cc == 1) + + if (nesting_levels.empty()) //case 1 cc { if( orient_outward != is_cc_outward_oriented[0]) reverse_face_orientations(faces(tm), tm); return ; } - -<<<<<<< HEAD + std::size_t nb_cc = nesting_levels.size(); boost::dynamic_bitset<> cc_to_reverse(nb_cc, 0); for(std::size_t i=0; i cc_handled(nb_cc, 0); - - // extract a vertex with max z coordinate for each connected component - std::vector xtrm_vertices(nb_cc, Graph_traits::null_vertex()); - for(vertex_descriptor vd : vertices(tm)) ->>>>>>> cgal/master { if ( ((nesting_levels[i]%2==0) == orient_outward) != is_cc_outward_oriented[i] ) { From 2e8b3ec7a5d660f4d2754bae7f212423f2517d42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 5 Sep 2019 08:10:11 +0200 Subject: [PATCH 054/141] remove BOOST_FOREACH --- .../include/CGAL/Polygon_mesh_processing/orientation.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index c8aa831db92..36e76aad9b0 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -498,7 +498,7 @@ void set_f_cc_id(const std::vector& f_cc, FaceCCIdMap face_cc_map, const TriangleMesh& tm) { - BOOST_FOREACH(typename boost::graph_traits::face_descriptor fd, faces(tm)) + for(typename boost::graph_traits::face_descriptor fd : faces(tm)) { put(face_cc_map, fd, f_cc[ get(face_index_map, fd) ]); } @@ -766,7 +766,7 @@ volume_connected_components(const TriangleMesh& tm, std::size_t next_volume_id = 0; // Handle open connected components - BOOST_FOREACH(halfedge_descriptor h, halfedges(tm)) + for(halfedge_descriptor h : halfedges(tm)) { if (is_border(h, tm)) { From e5a8da9c918a7787075be6f7845f9d1ac60b6496 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 5 Sep 2019 08:12:03 +0200 Subject: [PATCH 055/141] rephrase --- .../doc/Polygon_mesh_processing/Polygon_mesh_processing.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt index 7ffef533320..72b72a5ef79 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt @@ -781,7 +781,7 @@ enable the user to keep and remove only a selection of connected components, provided either as a range of faces that belong to the desired connected components or as a range of connected component ids (one or more per connected component). -When a triangle mesh has no boundary a notion the 3D space is partition is different volumes. +When a triangle mesh has no boundary, it partitions the 3D space in different volumes. The function `CGAL::Polygon_mesh_processing::volume_connected_components()` can be used to assign to each face an id per volume defined by the surface connected components. From 44efc0730bc83e05a434c6b093b18db3ca48486c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 5 Sep 2019 08:19:21 +0200 Subject: [PATCH 056/141] add missing doc --- .../NamedParameters.txt | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt index 970d2f85d7e..d80f0b42afc 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt @@ -474,6 +474,51 @@ and directed outside the finite volume enclosed by the surface connected compone \b Default: None \cgalNPEnd +\cgalParamBegin{connected_component_id_to_volume_id} +a `reference_wrapper` (either from `boost` or the standard library) containing +a reference to an object of type `std::vector< std::size_t >`. +The size of the vector is exactly the number of connected components. +For each connected component identified using its id `ccid`, the id of the volume it contributes +to describe is the value at the position `ccid` in the parameter vector. +\n +\b Type: a `reference_wrapper` (either from `boost` or the standard library) + over an object of type `std::vector` \n +\b Default: None +\cgalParamEnd + +\cgalParamBegin{nesting_levels} +a `reference_wrapper` (either from `boost` or the standard library) containing +a reference to an object of type `std::vector< std::size_t >`. +The size of the vector is exactly the number of connected components. +For each connected component identified using its id `ccid`, the vector contains the number of +connected components containing on its bounded side this component. +\n +\b Type: a `reference_wrapper` (either from `boost` or the standard library) + over an object of type `std::vector` \n +\b Default: None +\cgalParamEnd + +\cgalParamBegin{is_cc_outward_oriented} +a `reference_wrapper` (either from `boost` or the standard library) containing +a reference to an object of type `std::vector`. +The size of the vector is exactly the number of connected components. +For each connected component identified using its id `ccid`, the output of `is_outward_oriented` +called on the submesh corresponding to this connected component +is the value at the position `ccid` in the parameter vector. +\n +\b Type: a `reference_wrapper` (either from `boost` or the standard library) + over an object of type `std::vector` \n +\b Default: None +\cgalParamEnd + +\cgalParamBegin{intersecting_volume_pairs_output_iterator} +Output iterator into which pairs of ids (id must be convertible to `std::size_t`) can be put. +Each pair of connected components intersecting will be reported using their ids. +If `do_self_intersection_tests` named parameter is not set to `true`, nothing will be reported. +\b Type : a model of `OutputIterator` \n +\b Default : `#CGAL::Emptyset_iterator` +\cgalParamEnd + \cgalNPBegin{use_Delaunay_flips_t} \anchor PMP_use_Delaunay_flips Parameter used in the function `smooth_mesh()` to indicate if Delaunay-based flips should be used after area-based smoothing has been performed. A user wishing to preserve combinatorial information From 0b71f00eb5b23a850e9fabe0226a8bbd3dcaae80 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 5 Sep 2019 14:27:36 +0200 Subject: [PATCH 057/141] Add a bitset to foes_bound_a_volume and add a hidden test for all possible orientations of nested_cubes. --- .../Polygon_mesh_processing/orientation.h | 14 +++- .../test_orient_cc.cpp | 68 ++++++++++++++++++- 2 files changed, 79 insertions(+), 3 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index 36e76aad9b0..e0457c0f3eb 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -1086,7 +1086,11 @@ volume_connected_components(const TriangleMesh& tm, } } } - if (used_as_a_predicate) return 1; + if (used_as_a_predicate) + { + internal::copy_orientation_bitset(is_cc_outward_oriented, parameters::get_parameter(np, internal_np::is_cc_outward_oriented)); + return 1; + } // merge nested_cc_per_cc and nested_cc_per_cc_shared // (done after the volume creation to assign a CC to a unique volume) @@ -1158,6 +1162,14 @@ volume_connected_components(const TriangleMesh& tm, * \cgalParamBegin{face_index_map} * a property map containing the index of each face of `tm`. * \cgalParamEnd + * \cgalParamBegin{is_cc_outward_oriented} + * a `reference_wrapper` (either from `boost` or the standard library) containing + * a reference to an object of type `std::vector`. + * The size of the vector is exactly the number of connected components. + * For each connected component identified using its id `ccid`, the output of `is_outward_oriented` + * called on the submesh corresponding to this connected component + * is the value at the position `ccid` in the parameter vector. + * \cgalParamEnd * \cgalNamedParamsEnd * * \see `CGAL::Polygon_mesh_processing::orient_to_bound_a_volume()` diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_orient_cc.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_orient_cc.cpp index 4e62117e324..d85fd9122d9 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_orient_cc.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_orient_cc.cpp @@ -2,15 +2,17 @@ #include #include #include - +#include #include #include +//#define TEST_ALL_ORIENTATIONS 1 namespace PMP = CGAL::Polygon_mesh_processing; typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; typedef CGAL::Surface_mesh SMesh; + template bool test_orientation(TriangleMesh& tm, bool is_positive, const NamedParameters& np) { @@ -24,7 +26,7 @@ bool test_orientation(TriangleMesh& tm, bool is_positive, const NamedParameters& using CGAL::parameters::choose_parameter; using CGAL::parameters::get_parameter; - + Vpm vpm = choose_parameter(get_parameter(np, CGAL::internal_np::vertex_point), CGAL::get_const_property_map(boost::vertex_point, tm)); @@ -145,5 +147,67 @@ int main() return 1; } +#ifdef TEST_ALL_ORIENTATIONS //takes around 2 hours + std::cout<<"testing ALL orientations..."< fccmap = + sm1.add_property_map("f:CC").first; + std::vector is_cc_o_or; + PMP::orient_to_bound_a_volume(sm1); + PMP::does_bound_a_volume(sm1, + CGAL::parameters::is_cc_outward_oriented(std::ref(is_cc_o_or))); + + std::size_t nb_ccs = PMP::connected_components(sm1, fccmap); + + std::vector< std::vector > faces_per_cc(nb_ccs); + for(SMesh::Face_index fd : faces(sm1)) + { + std::size_t cc_id = get(fccmap, fd); + faces_per_cc[cc_id].push_back(fd); + } + double total_length = 1<<20; + CGAL::Timer timer; + timer.start(); + for(std::size_t i=1; i>=1; + ++cc; + } + std::vector is_loop_o_o; + PMP::orient_to_bound_a_volume(loop_m); + + if( !PMP::does_bound_a_volume(loop_m, + CGAL::parameters::is_cc_outward_oriented(std::ref(is_loop_o_o))) ) + { + std::cerr << "ERROR for test7\n"; + return 1; + } + if(is_loop_o_o.empty()) + return 1; + if(is_loop_o_o!= is_cc_o_or) + { + std::cerr << "ERROR for test7\n"; + return 1; + } + if(i%1000 == 0){ + timer.stop(); + double remaining = ((1<<20) -i)* timer.time()/1000.0 ; + std::cout< Date: Fri, 6 Sep 2019 11:45:42 +0200 Subject: [PATCH 058/141] Replace the hardcoded std::vector<> of the NPs by a more flexible concept, and add functions for copy. --- .../NamedParameters.txt | 47 ++++--- .../Polygon_mesh_processing/orientation.h | 117 +++++++++++++----- .../test_orient_cc.cpp | 28 +++-- 3 files changed, 132 insertions(+), 60 deletions(-) diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt index d80f0b42afc..50714ee9c95 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt @@ -442,13 +442,14 @@ connected components. \cgalNPEnd \cgalNPBegin{error_codes} \anchor PMP_error_codes -a reference to a vector holding the classification of a volume connected component identified by its id. -The size of the vector is exactly the number of volume connected components and the -object at position `k` in the vector correspond to the classification of the volume connected component +a reference to an object that must be a model of the `BackInsertionSequence` Concept, +holding the classification of a volume connected component identified by its id. +The size of the container is exactly the number of volume connected components and the +object at position `k` in the container correspond to the classification of the volume connected component assigned the id `k`. \n \b Type: a `reference_wrapper` (either from `boost` or the standard library) - over an object of type `std::vector` \n + over an object of type `container` \n \b Default: None \cgalNPEnd @@ -463,51 +464,57 @@ of its surface connected component in the range \cgalNPEnd \cgalNPBegin{volume_inclusions} \anchor PMP_volume_inclusions -a reference to a vector holding vector of id of surface connected components. -The size of the vector is exactly the number of surface connected components of the triangle mesh considered -The vector at position `k` contains the id of each surface connected components +a reference to a container holding a container of id of surface connected components. +The container must be a model of the `BackInsertionSequence` Concept, +with a value type being a model of `BackInsertionSequence` of ids, +both types having the functions `reserve()` and `push_back()`. +The size of the container is exactly the number of surface connected components of the triangle mesh considered +The container at position `k` contains the id of each surface connected components that is the first intersected by a ray with source on the surface connected component `k` and directed outside the finite volume enclosed by the surface connected component `k`. \n \b Type: a `reference_wrapper` (either from `boost` or the standard library) - over an object of type `std::vector< std::vector >` \n + over an object of type `container< container >` \n \b Default: None \cgalNPEnd \cgalParamBegin{connected_component_id_to_volume_id} a `reference_wrapper` (either from `boost` or the standard library) containing -a reference to an object of type `std::vector< std::size_t >`. -The size of the vector is exactly the number of connected components. +a reference to an object that must be a model of the `BackInsertionSequence` Concept, +with a value_type being `std::size_t`. +The size of the container is exactly the number of connected components. For each connected component identified using its id `ccid`, the id of the volume it contributes -to describe is the value at the position `ccid` in the parameter vector. +to describe is the value at the position `ccid` in the parameter container. \n \b Type: a `reference_wrapper` (either from `boost` or the standard library) - over an object of type `std::vector` \n + over an object of type `container` \n \b Default: None \cgalParamEnd \cgalParamBegin{nesting_levels} a `reference_wrapper` (either from `boost` or the standard library) containing -a reference to an object of type `std::vector< std::size_t >`. -The size of the vector is exactly the number of connected components. -For each connected component identified using its id `ccid`, the vector contains the number of +a reference to an object that must be a model of the `BackInsertionSequence` Concept, +with a value_type being `std::size_t`. +The size of the container is exactly the number of connected components. +For each connected component identified using its id `ccid`, the container contains the number of connected components containing on its bounded side this component. \n \b Type: a `reference_wrapper` (either from `boost` or the standard library) - over an object of type `std::vector` \n + over an object of type `container` \n \b Default: None \cgalParamEnd \cgalParamBegin{is_cc_outward_oriented} a `reference_wrapper` (either from `boost` or the standard library) containing -a reference to an object of type `std::vector`. -The size of the vector is exactly the number of connected components. +a reference to an object that must be a model of the `BackInsertionSequence` Concept, +with a value_type being `bool`. +The size of the container is exactly the number of connected components. For each connected component identified using its id `ccid`, the output of `is_outward_oriented` called on the submesh corresponding to this connected component -is the value at the position `ccid` in the parameter vector. +is the value at the position `ccid` in the parameter container. \n \b Type: a `reference_wrapper` (either from `boost` or the standard library) - over an object of type `std::vector` \n + over an object of type `container` \n \b Default: None \cgalParamEnd diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index e0457c0f3eb..4109b8a30ab 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -40,6 +40,9 @@ #include #include +#include + +#include namespace CGAL { namespace Polygon_mesh_processing { @@ -468,23 +471,68 @@ enum Volume_error_code { VALID_VOLUME, ///< The set of faces bounds a volume SINGLE_CONNECTED_COMPONENT ///< The set of faces consists of all the faces of the mesh and no further test was done. }; namespace internal { -template -void copy_error_codes(std::vector& error_codes_in, - RefToVector ref_wrapper) + +template +void copy_container_content(std::vector& vec, RefToContainer ref_wrapper) { - error_codes_in.swap(ref_wrapper.get()); + ref_wrapper.get().reserve(vec.size()); + for(const T& t : vec) + { + ref_wrapper.get().push_back(t); + } } -inline void copy_error_codes(std::vector&, +template +void copy_container_content(std::vector& vec, std::reference_wrapper > ref_wrapper) +{ + vec.swap(ref_wrapper.get()); +} + +template +void copy_container_content(std::vector& vec, boost::reference_wrapper > ref_wrapper) +{ + vec.swap(ref_wrapper.get()); +} +template +inline void copy_container_content(std::vector&, internal_np::Param_not_found) {} -template + +template void copy_nested_parents( std::vector< std::vector >& nested_parents, - RefToVector ref_to_vector) + RefToContainer ref_to_vector) { - ref_to_vector.get().swap( nested_parents ); + typedef typename RefToContainer::type Container; + typedef typename Container::value_type Container_value; + + ref_to_vector.get().reserve(nested_parents.size()); + for(const auto& t : nested_parents) + { + Container_value c; + c.reserve(t.size()); + for(const std::size_t& val : t){ + c.push_back(val); + } + ref_to_vector.get().push_back(c); + } +} + +template <> +void copy_nested_parents( + std::vector< std::vector >& nested_parents, + std::reference_wrapper > > ref_to_vector) +{ + nested_parents.swap(ref_to_vector.get()); +} + +template <> +void copy_nested_parents( + std::vector< std::vector >& nested_parents, + boost::reference_wrapper > > ref_to_vector) +{ + nested_parents.swap(ref_to_vector.get()); } inline void copy_nested_parents( @@ -630,9 +678,11 @@ inline void set_cc_intersecting_pairs(const std::set< std::pair >` - * The size of the vector is exactly the number of surface components of `tm`. - * The vector at position `k` contains the ids of all the + * a reference to an object that must be a model of the `BackInsertionSequence` Concept, + * with a value type being a model of `BackInsertionSequence` of `std::size_t`, + * both types having the functions `reserve()` and `push_back()`. + * The size of the container is exactly the number of surface components of `tm`. + * The container at position `k` contains the ids of all the * surface components that are the first intersected by any ray with source on * the surface component `k` and directed outside the volume enclosed by the * surface component `k`. There is only one such id but when some surface components intersect. @@ -645,9 +695,10 @@ inline void set_cc_intersecting_pairs(const std::set< std::pair`. - * The size of the vector is exactly the number of volume components. - * The vector indicates the status of a volume assigned to a set of faces. + * a reference to an object that must be a model of the `BackInsertionSequence` Concept, + * with a value_type being `Volume_error_code`. + * The size of the container is exactly the number of volume components. + * The container indicates the status of a volume assigned to a set of faces. * The description of the value type is given in the documentation of the enumeration type. * \cgalParamEnd * \cgalParamBegin{do_self_intersection_tests} @@ -657,22 +708,25 @@ inline void set_cc_intersecting_pairs(const std::set< std::pair`. - * The size of the vector is exactly the number of connected components. + * a reference to an object that must be a model of the `BackInsertionSequence` Concept, + * with a value_type being `std::size_t`. + * The size of the container is exactly the number of connected components. * For each connected component identified using its id `ccid`, the id of the volume it contributes - * to describe is the value at the position `ccid` in the parameter vector. + * to describe is the value at the position `ccid` in the parameter container. * \cgalParamEnd * \cgalParamBegin{nesting_levels} * a `reference_wrapper` (either from `boost` or the standard library) containing - * a reference to an object of type `std::vector< std::size_t >`. - * The size of the vector is exactly the number of connected components. + * a reference to an object that must be a model of the `BackInsertionSequence` Concept, + * with a value_type being `std::size_t`. + * The size of the container is exactly the number of connected components. * For each connected component identified using its id `ccid`, the vector contains the number of * connected components containing on its bounded side this component. * \cgalParamEnd * \cgalParamBegin{is_cc_outward_oriented} * a `reference_wrapper` (either from `boost` or the standard library) containing - * a reference to an object of type `std::vector`. - * The size of the vector is exactly the number of connected components. + * a reference to an object that must be a model of the `BackInsertionSequence` Concept, + * with a value_type being `bool`. + * The size of the container is exactly the number of connected components. * For each connected component identified using its id `ccid`, the output of `is_outward_oriented` * called on the submesh corresponding to this connected component * is the value at the position `ccid` in the parameter vector. @@ -682,6 +736,7 @@ inline void set_cc_intersecting_pairs(const std::set< std::pair #include #include -//#define TEST_ALL_ORIENTATIONS 1 + +#define TEST_ALL_ORIENTATIONS 1 namespace PMP = CGAL::Polygon_mesh_processing; typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; typedef CGAL::Surface_mesh SMesh; +template +struct deque_wrapper : public std::deque +{ + template + void reserve(const U&){} +}; template bool test_orientation(TriangleMesh& tm, bool is_positive, const NamedParameters& np) @@ -162,12 +169,13 @@ int main() for(SMesh::Face_index fd : faces(sm1)) { std::size_t cc_id = get(fccmap, fd); - faces_per_cc[cc_id].push_back(fd); + faces_per_cc[cc_id].push_back(fd); } double total_length = 1<<20; CGAL::Timer timer; timer.start(); - for(std::size_t i=1; i>=1; ++cc; } - std::vector is_loop_o_o; + deque_wrapper is_loop_o_o; PMP::orient_to_bound_a_volume(loop_m); if( !PMP::does_bound_a_volume(loop_m, @@ -194,10 +202,12 @@ int main() } if(is_loop_o_o.empty()) return 1; - if(is_loop_o_o!= is_cc_o_or) - { - std::cerr << "ERROR for test7\n"; - return 1; + for(std::size_t k = 0; k< is_loop_o_o.size(); ++k){ + if(is_loop_o_o[k]!= is_cc_o_or[k]) + { + std::cerr << "ERROR for test7\n"; + return 1; + } } if(i%1000 == 0){ timer.stop(); @@ -207,7 +217,7 @@ int main() timer.start(); } } -std::cout<<"finished ! "< Date: Fri, 6 Sep 2019 15:50:28 +0200 Subject: [PATCH 059/141] remove capital and make vec const --- .../Polygon_mesh_processing/NamedParameters.txt | 10 +++++----- .../CGAL/Polygon_mesh_processing/orientation.h | 14 +++++++------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt index 50714ee9c95..f377665bfbe 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt @@ -442,7 +442,7 @@ connected components. \cgalNPEnd \cgalNPBegin{error_codes} \anchor PMP_error_codes -a reference to an object that must be a model of the `BackInsertionSequence` Concept, +a reference to an object that must be a model of the `BackInsertionSequence` concept, holding the classification of a volume connected component identified by its id. The size of the container is exactly the number of volume connected components and the object at position `k` in the container correspond to the classification of the volume connected component @@ -465,7 +465,7 @@ of its surface connected component in the range \cgalNPBegin{volume_inclusions} \anchor PMP_volume_inclusions a reference to a container holding a container of id of surface connected components. -The container must be a model of the `BackInsertionSequence` Concept, +The container must be a model of the `BackInsertionSequence` concept, with a value type being a model of `BackInsertionSequence` of ids, both types having the functions `reserve()` and `push_back()`. The size of the container is exactly the number of surface connected components of the triangle mesh considered @@ -480,7 +480,7 @@ and directed outside the finite volume enclosed by the surface connected compone \cgalParamBegin{connected_component_id_to_volume_id} a `reference_wrapper` (either from `boost` or the standard library) containing -a reference to an object that must be a model of the `BackInsertionSequence` Concept, +a reference to an object that must be a model of the `BackInsertionSequence` concept, with a value_type being `std::size_t`. The size of the container is exactly the number of connected components. For each connected component identified using its id `ccid`, the id of the volume it contributes @@ -493,7 +493,7 @@ to describe is the value at the position `ccid` in the parameter container. \cgalParamBegin{nesting_levels} a `reference_wrapper` (either from `boost` or the standard library) containing -a reference to an object that must be a model of the `BackInsertionSequence` Concept, +a reference to an object that must be a model of the `BackInsertionSequence` concept, with a value_type being `std::size_t`. The size of the container is exactly the number of connected components. For each connected component identified using its id `ccid`, the container contains the number of @@ -506,7 +506,7 @@ connected components containing on its bounded side this component. \cgalParamBegin{is_cc_outward_oriented} a `reference_wrapper` (either from `boost` or the standard library) containing -a reference to an object that must be a model of the `BackInsertionSequence` Concept, +a reference to an object that must be a model of the `BackInsertionSequence` concept, with a value_type being `bool`. The size of the container is exactly the number of connected components. For each connected component identified using its id `ccid`, the output of `is_outward_oriented` diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index 4109b8a30ab..1b6a400a56f 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -473,7 +473,7 @@ enum Volume_error_code { VALID_VOLUME, ///< The set of faces bounds a volume namespace internal { template -void copy_container_content(std::vector& vec, RefToContainer ref_wrapper) +void copy_container_content(const std::vector& vec, RefToContainer ref_wrapper) { ref_wrapper.get().reserve(vec.size()); for(const T& t : vec) @@ -501,7 +501,7 @@ inline void copy_container_content(std::vector&, template void copy_nested_parents( - std::vector< std::vector >& nested_parents, + const std::vector< std::vector >& nested_parents, RefToContainer ref_to_vector) { typedef typename RefToContainer::type Container; @@ -678,7 +678,7 @@ inline void set_cc_intersecting_pairs(const std::set< std::pair Date: Fri, 27 Sep 2019 13:23:56 +0200 Subject: [PATCH 060/141] Fix copy_nested_parents --- .../include/CGAL/Polygon_mesh_processing/orientation.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index 1b6a400a56f..135d44b41a4 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -519,7 +519,6 @@ void copy_nested_parents( } } -template <> void copy_nested_parents( std::vector< std::vector >& nested_parents, std::reference_wrapper > > ref_to_vector) @@ -527,7 +526,7 @@ void copy_nested_parents( nested_parents.swap(ref_to_vector.get()); } -template <> + void copy_nested_parents( std::vector< std::vector >& nested_parents, boost::reference_wrapper > > ref_to_vector) From 7de9465bbb4f115b47fde8e6c27ea860ba6c0790 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 2 Oct 2019 14:39:23 +0200 Subject: [PATCH 061/141] Optimize for triangle intersections --- .../Triangle_2_Triangle_2_intersection_impl.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h b/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h index a9e9778b795..ee3e9951d09 100644 --- a/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h +++ b/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h @@ -282,8 +282,8 @@ Triangle_2_Triangle_2_pair::vertex(int n) const } //algorithm taken from here : https://stackoverflow.com/questions/1165647/how-to-determine-if-a-list-of-polygon-points-are-in-clockwise-order -template -bool is_cw(std::vector ps) +template +bool is_cw(const ArrayOfPoints& ps) { typename K::FT res(0); std::size_t length = ps.size(); @@ -302,10 +302,10 @@ Triangle_2_Triangle_2_pair::intersection_triangle() const if (!_known) intersection_type(); CGAL_kernel_assertion(_result == TRIANGLE); - std::vector res; - res.push_back(_pointlist.first->point); - res.push_back(_pointlist.first->next->point); - res.push_back(_pointlist.first->next->next->point); + std::array res; + res[0]=_pointlist.first->point; + res[1]=_pointlist.first->next->point; + res[2]=_pointlist.first->next->next->point; if(!is_cw(res)) { return Triangle_2(res[0], res[1], res[2]); From ad3c3d16b7b05cac23b042c70e212894688bf571 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 2 Oct 2019 15:24:18 +0200 Subject: [PATCH 062/141] Use left_turn() instead of custom inefficient function. --- .../internal/Triangle_2_Triangle_2_intersection_impl.h | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h b/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h index ee3e9951d09..1cf2b107762 100644 --- a/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h +++ b/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h @@ -285,13 +285,7 @@ Triangle_2_Triangle_2_pair::vertex(int n) const template bool is_cw(const ArrayOfPoints& ps) { - typename K::FT res(0); - std::size_t length = ps.size(); - for(std::size_t i = 0; i 0; + return !CGAL::left_turn(ps[0], ps[1], ps[2]); } template From 9ede1f3ee7967652296787ee46fbc507eaf61d90 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 3 Oct 2019 10:48:52 +0200 Subject: [PATCH 063/141] Specialize the cw test to be more robust if the kernel is not exact --- .../Triangle_2_Triangle_2_intersection_impl.h | 50 +++++++++++++------ .../Intersections_2/test_intersections_2.cpp | 6 ++- 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h b/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h index 1cf2b107762..7d6b32f3239 100644 --- a/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h +++ b/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h @@ -30,6 +30,7 @@ #include #include +#include namespace CGAL { @@ -281,13 +282,6 @@ Triangle_2_Triangle_2_pair::vertex(int n) const return cur->point; } -//algorithm taken from here : https://stackoverflow.com/questions/1165647/how-to-determine-if-a-list-of-polygon-points-are-in-clockwise-order -template -bool is_cw(const ArrayOfPoints& ps) -{ - return !CGAL::left_turn(ps[0], ps[1], ps[2]); -} - template typename K::Triangle_2 Triangle_2_Triangle_2_pair::intersection_triangle() const @@ -296,16 +290,18 @@ Triangle_2_Triangle_2_pair::intersection_triangle() const if (!_known) intersection_type(); CGAL_kernel_assertion(_result == TRIANGLE); - std::array res; - res[0]=_pointlist.first->point; - res[1]=_pointlist.first->next->point; - res[2]=_pointlist.first->next->next->point; - if(!is_cw(res)) + if(CGAL::left_turn(_pointlist.first->point, + _pointlist.first->next->point, + _pointlist.first->next->next->point)) { - return Triangle_2(res[0], res[1], res[2]); + return Triangle_2(_pointlist.first->point, + _pointlist.first->next->point, + _pointlist.first->next->next->point); } else { - return Triangle_2(res[0], res[2], res[1]); + return Triangle_2(_pointlist.first->point, + _pointlist.first->next->next->point, + _pointlist.first->next->point); } } @@ -332,6 +328,30 @@ Triangle_2_Triangle_2_pair::intersection_point() const } +//algorithm taken from here : https://stackoverflow.com/questions/1165647/how-to-determine-if-a-list-of-polygon-points-are-in-clockwise-order +template +struct Is_cw{ +bool operator()(const ArrayOfPoints& ps) +{ + typename K::FT res(0); + std::size_t length = ps.size(); + for(std::size_t i = 0; i 0; +} +}; + +template +struct Is_cw{ +bool operator()(const ArrayOfPoints& ps) +{ + return !CGAL::left_turn(ps[0], ps[1], ps[2]); +} +}; + + template typename CGAL::Intersection_traits @@ -358,7 +378,7 @@ intersection(const typename K::Triangle_2 &tr1, for (int i =0; i < ispair.vertex_count(); i++) { points[i] = ispair.vertex(i); } - if(is_cw(points)) + if(Is_cw::Is_exact>()(points)) { std::size_t length = points.size(); diff --git a/Intersections_2/test/Intersections_2/test_intersections_2.cpp b/Intersections_2/test/Intersections_2/test_intersections_2.cpp index aced87d8315..bc1ea6bd322 100644 --- a/Intersections_2/test/Intersections_2/test_intersections_2.cpp +++ b/Intersections_2/test/Intersections_2/test_intersections_2.cpp @@ -98,7 +98,8 @@ struct Test { if (p.size() != q.size()) return false; - if (CGAL::Intersections::internal::is_cw(p)) + if (CGAL::Intersections::internal::Is_cw::Is_exact>()(p)) return false; for(typename Pol::const_iterator itp = p.begin(), itq = q.begin(); itp != p.end(); ++itp, ++itq) if (!approx_equal(*itp, *itq)) @@ -111,7 +112,8 @@ struct Test { std::vector

vec(3); for(int i=0; i<3; ++i){vec[i]=p[i];} - if (CGAL::Intersections::internal::is_cw(vec)) + if (CGAL::Intersections::internal::Is_cw, + typename CGAL::Algebraic_structure_traits::Is_exact>(vec)) return false; return p == q; } From 3c875e8a188c00d6142aae7ae3977e58cecfbe0f Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 4 Oct 2019 15:30:52 +0200 Subject: [PATCH 064/141] WIP review --- .../CGAL/Intersections_2/Bbox_2_Bbox_2.h | 9 +++---- .../Intersections_2/Bbox_2_Iso_rectangle_2.h | 25 ++++++++----------- .../CGAL/Intersections_2/Bbox_2_Point_2.h | 1 - .../CGAL/Intersections_2/Bbox_2_Segment_2.h | 20 +++++++-------- .../CGAL/Intersections_2/Bbox_2_Triangle_2.h | 24 ++++++++---------- .../CGAL/Intersections_2/Circle_2_Ray_2.h | 1 + .../CGAL/Intersections_2/Circle_2_Segment_2.h | 1 + .../Intersections_2/Circle_2_Triangle_2.h | 1 + .../Triangle_2_Triangle_2_intersection_impl.h | 12 ++++----- .../Intersections_2/test_intersections_2.cpp | 16 +++++++++--- .../include/CGAL/Intersection_traits_3.h | 3 ++- 11 files changed, 58 insertions(+), 55 deletions(-) diff --git a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Bbox_2.h b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Bbox_2.h index 90fdc2495e4..3ccbcad3c61 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Bbox_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Bbox_2.h @@ -39,18 +39,17 @@ do_intersect(const CGAL::Bbox_2& c, return CGAL::do_overlap(c, bbox); } -typename boost::optional< typename -boost::variant< Bbox_2> > +typename boost::optional< typename boost::variant< Bbox_2> > inline intersection(const CGAL::Bbox_2& a, const CGAL::Bbox_2& b) { typedef typename boost::variant< Bbox_2> variant_type; - typedef typename boost::optional< variant_type > Result_type; + typedef typename boost::optional< variant_type > result_type; if(!do_intersect(a,b)) { - return Result_type(); + return result_type(); } double xmin, xmax, ymin, ymax; @@ -60,7 +59,7 @@ intersection(const CGAL::Bbox_2& a, ymin = (std::max)(a.ymin(), b.ymin()); ymax = (std::min)(a.ymax(), b.ymax()); - return Result_type(std::forward(Bbox_2(xmin, ymin, xmax, ymax))); + return result_type(std::forward(Bbox_2(xmin, ymin, xmax, ymax))); } } diff --git a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Iso_rectangle_2.h b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Iso_rectangle_2.h index 907ae0bc05b..decd0a11a61 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Iso_rectangle_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Iso_rectangle_2.h @@ -25,8 +25,6 @@ #include #include -#include -#include #include namespace CGAL { @@ -34,35 +32,34 @@ namespace CGAL { template inline bool do_intersect( - const Iso_rectangle_2 &line, + const Iso_rectangle_2 &rect, const Bbox_2 &box) { - typename K::Iso_rectangle_2 rec(box.xmin(), box.ymin(), box.xmax(), box.ymax()); - return do_intersect(rec, line); + return do_intersect(K::Iso_rectangle_2(box), rect); } template inline bool do_intersect( const Bbox_2 &box, -const Iso_rectangle_2 &line) +const Iso_rectangle_2 &rect) { - return do_intersect(line, box); + return do_intersect(rect, box); } template typename Intersection_traits::result_type -intersection(const CGAL::Bbox_2& box, - const Iso_rectangle_2& line) { +intersection(const Bbox_2& box, + const Iso_rectangle_2& rect) { typename K::Iso_rectangle_2 rec(box.xmin(), box.ymin(), box.xmax(), box.ymax()); - return intersection(rec, line); + return intersection(rec, rect); } template typename Intersection_traits::result_type -intersection(const Iso_rectangle_2& line, - const CGAL::Bbox_2& box) { - return intersection(box, line); +intersection(const Iso_rectangle_2& rect, + const Bbox_2& box) { + return intersection(box, rect); } } -#endif // BBOX_2_ISO_RECTANGLE_2_H +#endif // CGAL_INTERSECTIONS_BBOX_2_ISO_RECTANGLE_2_H diff --git a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Point_2.h b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Point_2.h index 196c756fe5b..c047a36474c 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Point_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Point_2.h @@ -28,7 +28,6 @@ #include - namespace CGAL { namespace Intersections { namespace internal { diff --git a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Segment_2.h b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Segment_2.h index 92f9881e87c..67b4aa7cc0c 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Segment_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Segment_2.h @@ -25,8 +25,6 @@ #include #include -#include -#include #include namespace CGAL { @@ -34,35 +32,35 @@ namespace CGAL { template inline bool do_intersect( - const Segment_2 &line, + const Segment_2 &seg, const Bbox_2 &box) { typename K::Iso_rectangle_2 rec(box.xmin(), box.ymin(), box.xmax(), box.ymax()); - return do_intersect(rec, line); + return do_intersect(rec, seg); } template inline bool do_intersect( const Bbox_2 &box, -const Segment_2 &line) +const Segment_2 &seg) { - return do_intersect(line, box); + return do_intersect(seg, box); } template typename Intersection_traits::result_type intersection(const CGAL::Bbox_2& box, - const Segment_2& line) { + const Segment_2& seg) { typename K::Iso_rectangle_2 rec(box.xmin(), box.ymin(), box.xmax(), box.ymax()); - return intersection(rec, line); + return intersection(rec, seg); } template typename Intersection_traits::result_type -intersection(const Segment_2& line, +intersection(const Segment_2& seg, const CGAL::Bbox_2& box) { - return intersection(box, line); + return intersection(box, seg); } } -#endif // BBOX_2_SEGMENT_2_H +#endif // CGAL_INTERSECTIONS_BBOX_2_SEGMENT_2_H diff --git a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Triangle_2.h b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Triangle_2.h index a21a55908b1..6a712e160b6 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Triangle_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Triangle_2.h @@ -25,8 +25,6 @@ #include #include -#include -#include #include namespace CGAL { @@ -34,35 +32,35 @@ namespace CGAL { template inline bool do_intersect( - const Triangle_2 &line, + const Triangle_2 &tr, const Bbox_2 &box) { typename K::Iso_rectangle_2 rec(box.xmin(), box.ymin(), box.xmax(), box.ymax()); - return do_intersect(rec, line); + return do_intersect(rec, tr); } template inline bool do_intersect( const Bbox_2 &box, -const Triangle_2 &line) +const Triangle_2 &tr) { - return do_intersect(line, box); + return do_intersect(tr, box); } template typename Intersection_traits::result_type -intersection(const CGAL::Bbox_2& box, - const Triangle_2& line) { +intersection(const Bbox_2& box, + const Triangle_2& tr) { typename K::Iso_rectangle_2 rec(box.xmin(), box.ymin(), box.xmax(), box.ymax()); - return intersection(rec, line); + return intersection(rec, tr); } template typename Intersection_traits::result_type -intersection(const Triangle_2& line, - const CGAL::Bbox_2& box) { - return intersection(box, line); +intersection(const Triangle_2& tr, + const Bbox_2& box) { + return intersection(box, tr); } } -#endif // BBOX_2_TRIANGLE_2_H +#endif // CGAL_INTERSECTIONS_BBOX_2_TRIANGLE_2_H diff --git a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Ray_2.h b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Ray_2.h index 63f7ace0629..1882357d31b 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Ray_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Ray_2.h @@ -30,6 +30,7 @@ namespace CGAL { namespace Intersections { namespace internal { + template bool do_intersect(const typename K::Circle_2 & c, diff --git a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Segment_2.h b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Segment_2.h index de9128f56e2..2188499ee83 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Segment_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Segment_2.h @@ -30,6 +30,7 @@ namespace CGAL { namespace Intersections { namespace internal { + template bool do_intersect(const typename K::Circle_2 & c, diff --git a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Triangle_2.h b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Triangle_2.h index 354b2253fcf..c9151401e3f 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Triangle_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Triangle_2.h @@ -30,6 +30,7 @@ namespace CGAL { namespace Intersections { namespace internal { + template bool do_intersect(const typename K::Circle_2 & c, diff --git a/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h b/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h index 7d6b32f3239..f326ac10779 100644 --- a/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h +++ b/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h @@ -329,9 +329,9 @@ Triangle_2_Triangle_2_pair::intersection_point() const //algorithm taken from here : https://stackoverflow.com/questions/1165647/how-to-determine-if-a-list-of-polygon-points-are-in-clockwise-order -template +template struct Is_cw{ -bool operator()(const ArrayOfPoints& ps) +bool operator()(const std::vector& ps) { typename K::FT res(0); std::size_t length = ps.size(); @@ -343,9 +343,9 @@ bool operator()(const ArrayOfPoints& ps) } }; -template -struct Is_cw{ -bool operator()(const ArrayOfPoints& ps) +template +struct Is_cw{ +bool operator()(const std::vector& ps) { return !CGAL::left_turn(ps[0], ps[1], ps[2]); } @@ -378,7 +378,7 @@ intersection(const typename K::Triangle_2 &tr1, for (int i =0; i < ispair.vertex_count(); i++) { points[i] = ispair.vertex(i); } - if(Is_cw::Is_exact>()(points)) + if(Is_cw::Is_exact>()(points)) { std::size_t length = points.size(); diff --git a/Intersections_2/test/Intersections_2/test_intersections_2.cpp b/Intersections_2/test/Intersections_2/test_intersections_2.cpp index bc1ea6bd322..53004b4cf62 100644 --- a/Intersections_2/test/Intersections_2/test_intersections_2.cpp +++ b/Intersections_2/test/Intersections_2/test_intersections_2.cpp @@ -98,7 +98,7 @@ struct Test { if (p.size() != q.size()) return false; - if (CGAL::Intersections::internal::Is_cw::Is_exact>()(p)) return false; for(typename Pol::const_iterator itp = p.begin(), itq = q.begin(); itp != p.end(); ++itp, ++itq) @@ -110,9 +110,12 @@ struct Test bool approx_equal(const T & p, const T & q) { - std::vector

vec(3); - for(int i=0; i<3; ++i){vec[i]=p[i];} - if (CGAL::Intersections::internal::Is_cw, + if(p.size() != q.size()) + return false; + + std::vector

vec { p[0], p[1], p[2] }; + + if (CGAL::Intersections::internal::Is_cw::Is_exact>(vec)) return false; return p == q; @@ -336,11 +339,15 @@ struct Test check_no_do_intersect (C(p( 2, 8), 6), S(p(-3, -2), p( 2, -4))); check_no_do_intersect (C(p( 2, 8), 6), S(p(-3, 22), p( 2, 34))); + check_no_do_intersect (C(p( 2, 8), 9), S(p(2.5, 3.5), p(3, 4))); check_do_intersect (C(p( 3, 4), 0), S(p(-3, 8), p( 6, 2))); check_do_intersect (C(p( 4, 3), 4), S(p( 6, -7), p( 5, 2))); check_do_intersect (C(p(-3, 1), 7), S(p(-1, -3), p(-6, 7))); + + check_do_intersect (C(p(1, 1), 4), S(p(-1, 1), p(-6, -8))); + check_do_intersect (C(p(1, 1), 4), S(p(-1, 4), p(-1, -4))); } void C_R() @@ -360,6 +367,7 @@ struct Test { std::cout << "Circle - Triangle" << std::endl; check_no_do_intersect (C(p( 2, 8), 6), T(p(6,0), p( 8, 0), p(8,2))); + check_no_do_intersect (C(p( 0, 0), 9), T(p(1,1), p( 1, -1), p(0.1,0.1))); check_do_intersect (C(p( 3, 4), 0), T(p(-3, 8), p( 6, 2), p(4,6))); check_do_intersect (C(p( 4, 3), 4), T(p( 6, -7), p( 5, 2), p(2,-3))); diff --git a/Intersections_3/include/CGAL/Intersection_traits_3.h b/Intersections_3/include/CGAL/Intersection_traits_3.h index c49fc277357..decc1b24475 100644 --- a/Intersections_3/include/CGAL/Intersection_traits_3.h +++ b/Intersections_3/include/CGAL/Intersection_traits_3.h @@ -39,9 +39,10 @@ CGAL_INTERSECTION_TRAITS_2(Line_3, Segment_3, Point_3, Segment_3) CGAL_INTERSECTION_TRAITS_2(Segment_3, Line_3, Point_3, Segment_3) CGAL_INTERSECTION_TRAITS_2(Line_3, Triangle_3, Point_3, Segment_3) -CGAL_INTERSECTION_TRAITS_2(Line_3, Tetrahedron_3, Point_3, Segment_3) CGAL_INTERSECTION_TRAITS_2(Triangle_3, Line_3, Point_3, Segment_3) +CGAL_INTERSECTION_TRAITS_2(Line_3, Tetrahedron_3, Point_3, Segment_3) + CGAL_INTERSECTION_TRAITS_2(Plane_3, Plane_3, Line_3, Plane_3) CGAL_INTERSECTION_TRAITS_2(Plane_3, Ray_3, Point_3, Ray_3) From 63a6dc2a4b3eb06bbd8f8b57d46ad3e0ba3f11d5 Mon Sep 17 00:00:00 2001 From: Maxime GIMENO Date: Fri, 18 Oct 2019 16:01:43 +0200 Subject: [PATCH 065/141] Fix typo Co-Authored-By: Mael --- .../include/CGAL/Polygon_mesh_processing/orientation.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index 135d44b41a4..d07026711c8 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -625,7 +625,7 @@ inline void set_cc_intersecting_pairs(const std::set< std::pairenclosed by this surface * component. * - * The volume connected components (*volume components* in the following) are defines as follow: + * The volume connected components (*volume components* in the following) are defined as follows: * Each surface component `S` that is outside any volume enclosed by * another surface component defines the *outer boundary* of a volume component. * Each surface component that is inside the volume enclosed by `S` From e9a0b2d6956158128851b0bbae78b5f5c5b40f2d Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 4 Oct 2019 15:30:52 +0200 Subject: [PATCH 066/141] Fixes after review --- .../Intersections_2/Circle_2_Triangle_2.h | 18 +++++++++++++-- .../Intersections_2/test_intersections_2.cpp | 2 +- .../tetrahedron_lines_intersections_3.h | 23 ++++++++++++------- 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Triangle_2.h b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Triangle_2.h index c9151401e3f..6bd6f4334a4 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Triangle_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Triangle_2.h @@ -37,7 +37,21 @@ do_intersect(const typename K::Circle_2 & c, const typename K::Triangle_2& t, const K&) { - return squared_distance(c.center(), t) <= c.squared_radius(); + char nb_close(0); +//if all three points are inside the circle, there is no intersection. + if(squared_distance(c.center(), t) < c.squared_radius()) + { + for(int i = 0; i< 3; ++i) + { + if(squared_distance(c.center(), t[i]) == c.squared_radius()) + return true; + if(squared_distance(c.center(), t[i]) < c.squared_radius()) + ++nb_close; + } + return (nb_close < 3); + } + else + return squared_distance(c.center(), t) == c.squared_radius(); } template @@ -46,7 +60,7 @@ do_intersect(const typename K::Triangle_2& t, const typename K::Circle_2 & c, const K&) { - return squared_distance(c.center(), t) <= c.squared_radius(); + return do_intersect(c,t); } } // namespace internal diff --git a/Intersections_2/test/Intersections_2/test_intersections_2.cpp b/Intersections_2/test/Intersections_2/test_intersections_2.cpp index 53004b4cf62..9f5c607ac41 100644 --- a/Intersections_2/test/Intersections_2/test_intersections_2.cpp +++ b/Intersections_2/test/Intersections_2/test_intersections_2.cpp @@ -367,7 +367,7 @@ struct Test { std::cout << "Circle - Triangle" << std::endl; check_no_do_intersect (C(p( 2, 8), 6), T(p(6,0), p( 8, 0), p(8,2))); - check_no_do_intersect (C(p( 0, 0), 9), T(p(1,1), p( 1, -1), p(0.1,0.1))); + check_no_do_intersect (C(p( 0, 0), 9), T(p(1,1), p( 1, -1), p(0,0))); check_do_intersect (C(p( 3, 4), 0), T(p(-3, 8), p( 6, 2), p(4,6))); check_do_intersect (C(p( 4, 3), 4), T(p( 6, -7), p( 5, 2), p(2,-3))); diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h index 60c42c88fb6..ea8cb0b0f69 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h @@ -20,8 +20,8 @@ // Author(s) : Maxime Gimeno // -#ifndef TETRAHEDRON_LINES_INTERSECTIONS_3_H -#define TETRAHEDRON_LINES_INTERSECTIONS_3_H +#ifndef CGAL_INTERNAL_INTERSECTIONS_3_TETRAHEDRON_LINES_INTERSECTIONS_3_H +#define CGAL_INTERNAL_INTERSECTIONS_3_TETRAHEDRON_LINES_INTERSECTIONS_3_H #include #include @@ -73,10 +73,15 @@ struct Tetrahedron_lines_intersection_3_base const typename K::Triangle_3 triangle(tet.vertex((i+1)%4), tet.vertex((i+2)%4), tet.vertex((i+3)%4)); - tr_seg[i] = typename K::Intersect_3()(o, triangle); - if(tr_seg[i]) - if( boost::get(&*tr_seg[i]) != nullptr) - res_id = i; + if(do_intersect(o, triangle)) + { + tr_seg[i] = typename K::Intersect_3()(o, triangle); + if( boost::get(&*tr_seg[i]) != nullptr) + { + res_id = i; + break; + } + } } //if there is a segment in the intersections, then we return it @@ -110,12 +115,14 @@ struct Tetrahedron_lines_intersection_3_base } } if(res_points.empty()) + { return; + } if(res_id != -1) { if(static_cast(this)->are_extremities_inside_test()) return; - //else point and segment entirely not inside: + //else point and segment entirely not inside or one intersection on boundary: output = tr_seg[res_id]; return; } @@ -151,4 +158,4 @@ struct Tetrahedron_lines_intersection_3_base } } } -#endif // TETRAHEDRON_LINES_INTERSECTIONS_3_H +#endif // CGAL_INTERNAL_INTERSECTIONS_3_TETRAHEDRON_LINES_INTERSECTIONS_3_H From 16ee956bae97054d676142aad493ceb7edc4e9e5 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 21 Oct 2019 15:49:16 +0200 Subject: [PATCH 067/141] restore tests --- .../test/Intersections_3/test_intersections_3.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Intersections_3/test/Intersections_3/test_intersections_3.cpp b/Intersections_3/test/Intersections_3/test_intersections_3.cpp index e326680f295..0eca13bfb97 100644 --- a/Intersections_3/test/Intersections_3/test_intersections_3.cpp +++ b/Intersections_3/test/Intersections_3/test_intersections_3.cpp @@ -1211,10 +1211,10 @@ struct Test { int main() { -// Test< CGAL::Simple_cartesian >().run(); -// Test< CGAL::Homogeneous >().run(); + Test< CGAL::Simple_cartesian >().run(); + Test< CGAL::Homogeneous >().run(); Test< CGAL::Epeck >().run(true); -// Test< CGAL::Homogeneous >().run(true); + Test< CGAL::Homogeneous >().run(true); // TODO : test more kernels. } From b4fb7cb779dfc958cd650acdee1115f77f1c3b54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 22 Oct 2019 11:19:45 +0200 Subject: [PATCH 068/141] Minor improvements to Cuboid/Tr computations - Slight robustness improvements by storing in memory that the intersection points are by construction on the plane. - const& and such Pair programming w/ mgimeno! --- .../Iso_cuboid_3_Triangle_3_intersection.h | 126 ++++++++++-------- 1 file changed, 71 insertions(+), 55 deletions(-) diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Triangle_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Triangle_3_intersection.h index 0e8f1ebc186..e94f309dc9f 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Triangle_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Triangle_3_intersection.h @@ -26,8 +26,9 @@ #include #include -#include +#include #include +#include namespace CGAL { @@ -38,49 +39,61 @@ namespace internal { //only work for convex polygons, but in here that's always the case template void clip_poly_halfspace( - const std::vector& input, + std::vector& polygon, const typename K::Plane_3& pl, - std::vector& output) + const K& k) { - if(input.empty()) + if(polygon.empty()) return; typedef typename K::Point_3 Point; typedef typename K::Plane_3 Plane; - typedef typename K::Segment_3 S; + typedef typename K::Segment_3 Segment; typedef typename Intersection_traits, CGAL::Segment_3 >::result_type SP_type; - std::list p_list(input.begin(), input.end()); - auto it = p_list.begin(); + // Keep in memory which points we are going to delete later (newer intersection points + // by construction will not be deleted) + std::list > p_list; + for(const Point& p : polygon) + p_list.emplace_back(p, pl.has_on_positive_side(p)); + //corefine with plane. + auto it = p_list.begin(); while(it != p_list.end()) { - Point p = *it; - ++it; + const Point& p1 = (it++)->first; if(it == p_list.end()) break; - if(do_intersect(S(p, *it), pl)) + + const Point& p2 = it->first; + const Segment seg = k.construct_segment_3_object()(p1, p2); + + if(do_intersect(seg, pl)) { - SP_type inter = typename K::Intersect_3()(S(p, *it), pl); + SP_type inter = k.intersect_3_object()(seg, pl); if(inter) { Point* p_inter = boost::get(&*inter); if(p_inter - && *p_inter != p - && *p_inter != *it) - p_list.insert(it, *p_inter); + && !(k.equal_3_object()(*p_inter, p1)) + && !(k.equal_3_object()(*p_inter, p2))) + { + // 'false' because we know the intersection is by construction not on the positive side of the plane + p_list.insert(it, std::make_pair(*p_inter, false)); + } } } } - if(input.size() >2) + if(polygon.size() > 2) { - Point p2(p_list.front()), - p1(p_list.back()); - S seg(p1, p2); + const Point& p2 = p_list.front().first; + const Point& p1 = p_list.back().first; + const Segment seg(p1, p2); + if(do_intersect(seg, pl)) { SP_type inter = typename K::Intersect_3()(seg, pl); @@ -88,25 +101,29 @@ void clip_poly_halfspace( { Point* p_inter = boost::get(&*inter); if(p_inter - && *p_inter != p1 - && *p_inter != p2) - p_list.push_back(*p_inter); + && !(k.equal_3_object()(*p_inter, p1)) + && !(k.equal_3_object()(*p_inter, p2))) + { + // 'false' because we know the intersection is by construction not on the positive side of the plane + p_list.emplace_back(*p_inter, false); + } } } } + //remove all points on positive side - - for(auto p_it = p_list.begin(); - p_it != p_list.end();) + for(auto it = p_list.begin(); it != p_list.end();) { - if(pl.has_on_positive_side(*p_it)) - p_it = p_list.erase(p_it); + if(it->second) + it = p_list.erase(it); else - ++p_it; + ++it; } - for(auto p : p_list) - output.push_back(p); + // Update the polygon + polygon.clear(); + for(const auto& pr : p_list) + polygon.push_back(pr.first); } template @@ -114,12 +131,12 @@ typename Intersection_traits Poly; typedef typename Intersection_traits >::result_type Res_type; //Lazy implem: clip 6 times the input triangle. - Plane_3 planes[6]; - planes[0] = Plane_3(cub.vertex(0), - cub.vertex(1), - cub.vertex(5)); + Plane planes[6]; + planes[0] = Plane(cub.vertex(0), + cub.vertex(1), + cub.vertex(5)); - planes[1] = Plane_3(cub.vertex(0), - cub.vertex(4), - cub.vertex(3)); + planes[1] = Plane(cub.vertex(0), + cub.vertex(4), + cub.vertex(3)); - planes[2]=Plane_3(cub.vertex(0), + planes[2] = Plane(cub.vertex(0), cub.vertex(3), cub.vertex(1)); - planes[3] = Plane_3(cub.vertex(7), - cub.vertex(6), - cub.vertex(1)); + planes[3] = Plane(cub.vertex(7), + cub.vertex(6), + cub.vertex(1)); - planes[4] = Plane_3(cub.vertex(7), - cub.vertex(3), - cub.vertex(4)); + planes[4] = Plane(cub.vertex(7), + cub.vertex(3), + cub.vertex(4)); - planes[5] = Plane_3(cub.vertex(7), - cub.vertex(4), - cub.vertex(6)); + planes[5] = Plane(cub.vertex(7), + cub.vertex(4), + cub.vertex(6)); std::vector poly; poly.push_back(tr.vertex(0)); @@ -158,11 +175,7 @@ intersection( poly.push_back(tr.vertex(2)); for (int i = 0; i < 6; ++i) - { - Poly clipped; - clip_poly_halfspace(poly, planes[i], clipped); - poly = clipped; - } + clip_poly_halfspace(poly, planes[i], k); switch(poly.size()) { @@ -184,7 +197,7 @@ intersection( case 3: { - Triangle res = Triangle (poly[0], poly[1], poly[2]); + Triangle res = Triangle(poly[0], poly[1], poly[2]); return Res_type(std::forward(res)); } break; @@ -205,6 +218,9 @@ intersection( { return intersection(cub, tr, k); } -}}} + +} // namespace internal +} // namespace Intersections +} // namespace CGAL #endif // CGAL_INTERSECTIONS_3_INTERNAL_ISO_CUBOID_3_TRIANGLE_3_INTERSECTION_H From a5f09f89a6d1b537b1dd2aed8752030a4526b1e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 22 Oct 2019 12:36:46 +0200 Subject: [PATCH 069/141] Partial code cleaning (and fix some typedefs) --- .../CGAL/Intersections_2/Bbox_2_Bbox_2.h | 33 ++-- .../Intersections_2/Bbox_2_Iso_rectangle_2.h | 24 +-- .../Triangle_2_Triangle_2_intersection_impl.h | 82 ++++----- .../Intersections_2/test_intersections_2.cpp | 11 +- .../include/CGAL/Intersection_traits_3.h | 26 +-- .../CGAL/Intersections_3/Bbox_3_Bbox_3.h | 17 +- .../Iso_cuboid_3_Plane_3_intersection.h | 169 +++++++++--------- .../tetrahedron_intersection_helpers.h | 5 +- 8 files changed, 184 insertions(+), 183 deletions(-) diff --git a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Bbox_2.h b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Bbox_2.h index 3ccbcad3c61..3fae935f659 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Bbox_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Bbox_2.h @@ -19,15 +19,10 @@ // // Author(s) : Maxime Gimeno - #ifndef CGAL_INTERSECTIONS_BBOX_2_BBOX_2_H #define CGAL_INTERSECTIONS_BBOX_2_BBOX_2_H #include -#include -#include -#include -#include namespace CGAL { @@ -39,28 +34,26 @@ do_intersect(const CGAL::Bbox_2& c, return CGAL::do_overlap(c, bbox); } -typename boost::optional< typename boost::variant< Bbox_2> > +typename boost::optional< typename boost::variant > inline intersection(const CGAL::Bbox_2& a, - const CGAL::Bbox_2& b) { + const CGAL::Bbox_2& b) +{ + typedef typename boost::variant variant_type; + typedef typename boost::optional result_type; - typedef typename - boost::variant< Bbox_2> variant_type; - typedef typename boost::optional< variant_type > result_type; - if(!do_intersect(a,b)) - { + if(!do_intersect(a, b)) return result_type(); - } - double xmin, xmax, ymin, ymax; - xmin = (std::max)(a.xmin(), b.xmin()); - xmax = (std::min)(a.xmax(), b.xmax()); + double xmin = (std::max)(a.xmin(), b.xmin()); + double xmax = (std::min)(a.xmax(), b.xmax()); - ymin = (std::max)(a.ymin(), b.ymin()); - ymax = (std::min)(a.ymax(), b.ymax()); + double ymin = (std::max)(a.ymin(), b.ymin()); + double ymax = (std::min)(a.ymax(), b.ymax()); return result_type(std::forward(Bbox_2(xmin, ymin, xmax, ymax))); } -} -#endif // BBOX_2_BBOX_2_H +} // namespace CGAL + +#endif // CGAL_INTERSECTIONS_BBOX_2_BBOX_2_H diff --git a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Iso_rectangle_2.h b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Iso_rectangle_2.h index decd0a11a61..a4fadb75961 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Iso_rectangle_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Iso_rectangle_2.h @@ -29,19 +29,16 @@ namespace CGAL { - -template -inline bool do_intersect( - const Iso_rectangle_2 &rect, - const Bbox_2 &box) +template +inline bool do_intersect(const Iso_rectangle_2 &rect, + const Bbox_2 &box) { return do_intersect(K::Iso_rectangle_2(box), rect); } -template -inline bool do_intersect( - const Bbox_2 &box, -const Iso_rectangle_2 &rect) +template +inline bool do_intersect(const Bbox_2 &box, + const Iso_rectangle_2 &rect) { return do_intersect(rect, box); } @@ -49,7 +46,8 @@ const Iso_rectangle_2 &rect) template typename Intersection_traits::result_type intersection(const Bbox_2& box, - const Iso_rectangle_2& rect) { + const Iso_rectangle_2& rect) +{ typename K::Iso_rectangle_2 rec(box.xmin(), box.ymin(), box.xmax(), box.ymax()); return intersection(rec, rect); } @@ -57,9 +55,11 @@ intersection(const Bbox_2& box, template typename Intersection_traits::result_type intersection(const Iso_rectangle_2& rect, - const Bbox_2& box) { + const Bbox_2& box) +{ return intersection(box, rect); } -} +} // namespace CGAL + #endif // CGAL_INTERSECTIONS_BBOX_2_ISO_RECTANGLE_2_H diff --git a/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h b/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h index f326ac10779..eb38bc0527c 100644 --- a/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h +++ b/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h @@ -330,66 +330,66 @@ Triangle_2_Triangle_2_pair::intersection_point() const //algorithm taken from here : https://stackoverflow.com/questions/1165647/how-to-determine-if-a-list-of-polygon-points-are-in-clockwise-order template -struct Is_cw{ -bool operator()(const std::vector& ps) +struct Is_cw { - typename K::FT res(0); - std::size_t length = ps.size(); - for(std::size_t i = 0; i 0; -} + bool operator()(const std::vector& ps) + { + typename K::FT res(0); + std::size_t length = ps.size(); + for(std::size_t i = 0; i 0; + } }; template -struct Is_cw{ -bool operator()(const std::vector& ps) +struct Is_cw { - return !CGAL::left_turn(ps[0], ps[1], ps[2]); -} + bool operator()(const std::vector& ps) + { + return !CGAL::left_turn(ps[0], ps[1], ps[2]); + } }; - - template typename CGAL::Intersection_traits ::result_type intersection(const typename K::Triangle_2 &tr1, - const typename K::Triangle_2 &tr2, - const K&) + const typename K::Triangle_2 &tr2, + const K&) { - typedef Triangle_2_Triangle_2_pair is_t; - is_t ispair(&tr1, &tr2); - switch (ispair.intersection_type()) { + typedef Triangle_2_Triangle_2_pair is_t; + is_t ispair(&tr1, &tr2); + switch (ispair.intersection_type()) + { case is_t::NO_INTERSECTION: default: - return intersection_return(); + return intersection_return(); case is_t::POINT: - return intersection_return(ispair.intersection_point()); + return intersection_return(ispair.intersection_point()); case is_t::SEGMENT: - return intersection_return(ispair.intersection_segment()); + return intersection_return(ispair.intersection_segment()); case is_t::TRIANGLE: - return intersection_return(ispair.intersection_triangle()); - case is_t::POLYGON: { - typedef std::vector Container; - Container points(ispair.vertex_count()); - for (int i =0; i < ispair.vertex_count(); i++) { - points[i] = ispair.vertex(i); - } - if(Is_cw::Is_exact>()(points)) - { - std::size_t length = points.size(); + return intersection_return(ispair.intersection_triangle()); + case is_t::POLYGON: + { + typedef std::vector Container; + Container points(ispair.vertex_count()); + for (int i =0; i < ispair.vertex_count(); i++) + points[i] = ispair.vertex(i); - for(std::size_t i = 0; i< length/2; ++i) - { - std::swap(points[i], points[length-i-1]); - } - } - return intersection_return(points); - } + if(Is_cw::Is_exact>()(points)) + { + std::size_t length = points.size(); + + for(std::size_t i = 0; i< length/2; ++i) + std::swap(points[i], points[length-i-1]); + + } + return intersection_return(points); } + } } } // namespace internal diff --git a/Intersections_2/test/Intersections_2/test_intersections_2.cpp b/Intersections_2/test/Intersections_2/test_intersections_2.cpp index 9f5c607ac41..c7b0bb9c4ad 100644 --- a/Intersections_2/test/Intersections_2/test_intersections_2.cpp +++ b/Intersections_2/test/Intersections_2/test_intersections_2.cpp @@ -108,7 +108,7 @@ struct Test return true; } - bool approx_equal(const T & p, const T & q) + bool approx_equal(const T& p, const T& q) { if(p.size() != q.size()) return false; @@ -118,7 +118,8 @@ struct Test if (CGAL::Intersections::internal::Is_cw::Is_exact>(vec)) return false; - return p == q; + + return approx_equal(p[0], q[0]) && approx_equal(p[1], q[1]) && approx_equal(p[2], q[2]); } template @@ -366,10 +367,10 @@ struct Test void C_T() { std::cout << "Circle - Triangle" << std::endl; - check_no_do_intersect (C(p( 2, 8), 6), T(p(6,0), p( 8, 0), p(8,2))); - check_no_do_intersect (C(p( 0, 0), 9), T(p(1,1), p( 1, -1), p(0,0))); + check_no_do_intersect (C(p( 2, 8), 6), T(p( 6, 0), p( 8, 0), p(8, 2))); + check_no_do_intersect (C(p( 0, 0), 9), T(p( 1, 1), p( 1, -1), p(0, 0))); - check_do_intersect (C(p( 3, 4), 0), T(p(-3, 8), p( 6, 2), p(4,6))); + check_do_intersect (C(p( 3, 4), 0), T(p(-3, 8), p( 6, 2), p(4,6))); check_do_intersect (C(p( 4, 3), 4), T(p( 6, -7), p( 5, 2), p(2,-3))); check_do_intersect (C(p( 4, 3), 4), T(p( 6, -7), p( 4, 6), p(2,-3))); diff --git a/Intersections_3/include/CGAL/Intersection_traits_3.h b/Intersections_3/include/CGAL/Intersection_traits_3.h index decc1b24475..7b60f993292 100644 --- a/Intersections_3/include/CGAL/Intersection_traits_3.h +++ b/Intersections_3/include/CGAL/Intersection_traits_3.h @@ -42,6 +42,7 @@ CGAL_INTERSECTION_TRAITS_2(Line_3, Triangle_3, Point_3, Segment_3) CGAL_INTERSECTION_TRAITS_2(Triangle_3, Line_3, Point_3, Segment_3) CGAL_INTERSECTION_TRAITS_2(Line_3, Tetrahedron_3, Point_3, Segment_3) +CGAL_INTERSECTION_TRAITS_2(Tetrahedron_3, Line_3, Point_3, Segment_3) CGAL_INTERSECTION_TRAITS_2(Plane_3, Plane_3, Line_3, Plane_3) @@ -63,21 +64,20 @@ CGAL_INTERSECTION_TRAITS_2(Ray_3, Segment_3, Point_3, Segment_3) CGAL_INTERSECTION_TRAITS_2(Segment_3, Ray_3, Point_3, Segment_3) CGAL_INTERSECTION_TRAITS_2(Ray_3, Triangle_3, Point_3, Segment_3) -CGAL_INTERSECTION_TRAITS_2(Ray_3, Tetrahedron_3, Point_3, Segment_3) CGAL_INTERSECTION_TRAITS_2(Triangle_3, Ray_3, Point_3, Segment_3) +CGAL_INTERSECTION_TRAITS_2(Ray_3, Tetrahedron_3, Point_3, Segment_3) +CGAL_INTERSECTION_TRAITS_2(Tetrahedron_3, Ray_3, Point_3, Segment_3) + CGAL_INTERSECTION_TRAITS_2(Segment_3, Segment_3, Point_3, Segment_3) CGAL_INTERSECTION_TRAITS_2(Segment_3, Triangle_3, Point_3, Segment_3) -CGAL_INTERSECTION_TRAITS_2(Segment_3, Tetrahedron_3, Point_3, Segment_3) - CGAL_INTERSECTION_TRAITS_2(Triangle_3, Segment_3, Point_3, Segment_3) -CGAL_INTERSECTION_TRAITS_3(Sphere_3, Sphere_3, Point_3, Circle_3, Sphere_3) - -CGAL_INTERSECTION_TRAITS_2(Tetrahedron_3, Line_3, Point_3, Segment_3) +CGAL_INTERSECTION_TRAITS_2(Segment_3, Tetrahedron_3, Point_3, Segment_3) CGAL_INTERSECTION_TRAITS_2(Tetrahedron_3, Segment_3, Point_3, Segment_3) -CGAL_INTERSECTION_TRAITS_2(Tetrahedron_3, Ray_3, Point_3, Segment_3) + +CGAL_INTERSECTION_TRAITS_3(Sphere_3, Sphere_3, Point_3, Circle_3, Sphere_3) template struct Intersection_traits { @@ -330,7 +330,7 @@ struct Intersection_traits { boost::variant< typename K::Point_3 > variant_type; typedef typename boost::optional< variant_type > result_type; }; - + // Plane_3 Point_3, variant of one template struct Intersection_traits { @@ -338,7 +338,7 @@ struct Intersection_traits { boost::variant< typename K::Point_3 > variant_type; typedef typename boost::optional< variant_type > result_type; }; - + // Point_3 Triangle_3, variant of one template struct Intersection_traits { @@ -346,6 +346,7 @@ struct Intersection_traits { boost::variant< typename K::Point_3 > variant_type; typedef typename boost::optional< variant_type > result_type; }; + // Triangle_3 Point_3, variant of one template struct Intersection_traits { @@ -353,7 +354,7 @@ struct Intersection_traits { boost::variant< typename K::Point_3 > variant_type; typedef typename boost::optional< variant_type > result_type; }; - + // Point_3 Tetrahedron_3, variant of one template struct Intersection_traits { @@ -361,6 +362,7 @@ struct Intersection_traits { boost::variant< typename K::Point_3 > variant_type; typedef typename boost::optional< variant_type > result_type; }; + // Tetrahedron_3 Point_3, variant of one template struct Intersection_traits { @@ -368,7 +370,7 @@ struct Intersection_traits { boost::variant< typename K::Point_3 > variant_type; typedef typename boost::optional< variant_type > result_type; }; - + // Point_3 Sphere_3, variant of one template struct Intersection_traits { @@ -376,6 +378,7 @@ struct Intersection_traits { boost::variant< typename K::Point_3 > variant_type; typedef typename boost::optional< variant_type > result_type; }; + // Sphere_3 Point_3, variant of one template struct Intersection_traits { @@ -393,6 +396,7 @@ struct Intersection_traits typename K::Triangle_3, std::vector > variant_type; typedef typename boost::optional< variant_type > result_type; }; + //Plane_3 Tetrahedron_3, variant of 4 template struct Intersection_traits diff --git a/Intersections_3/include/CGAL/Intersections_3/Bbox_3_Bbox_3.h b/Intersections_3/include/CGAL/Intersections_3/Bbox_3_Bbox_3.h index 051b86ac9ad..fae33a52e50 100644 --- a/Intersections_3/include/CGAL/Intersections_3/Bbox_3_Bbox_3.h +++ b/Intersections_3/include/CGAL/Intersections_3/Bbox_3_Bbox_3.h @@ -23,10 +23,11 @@ #ifndef CGAL_INTERSECTIONS_3_BBOX_3_BBOX_3_H #define CGAL_INTERSECTIONS_3_BBOX_3_BBOX_3_H - #include #include + namespace CGAL { + bool inline do_intersect(const CGAL::Bbox_3& c, @@ -35,19 +36,16 @@ do_intersect(const CGAL::Bbox_3& c, return CGAL::do_overlap(c, bbox); } -typename boost::optional< typename -boost::variant< Bbox_3> > +typename boost::optional< typename boost::variant< Bbox_3> > inline intersection(const CGAL::Bbox_3& a, - const CGAL::Bbox_3& b) { + const CGAL::Bbox_3& b) +{ + typedef typename boost::variant variant_type; + typedef typename boost::optional Result_type; - typedef typename - boost::variant< Bbox_3> variant_type; - typedef typename boost::optional< variant_type > Result_type; if(!do_intersect(a,b)) - { return Result_type(); - } double xmin, xmax, ymin, ymax, zmin, zmax; xmin = (std::max)(a.xmin(), b.xmin()); @@ -58,6 +56,7 @@ intersection(const CGAL::Bbox_3& a, zmin = (std::max)(a.zmin(), b.zmin()); zmax = (std::min)(a.zmax(), b.zmax()); + return Result_type(std::forward(Bbox_3(xmin, ymin, zmin, xmax, ymax, zmax))); } diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h index c24ed9f552f..c684578035f 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h @@ -22,13 +22,16 @@ #ifndef CGAL_INTERNAL_INTERSECTIONS_3_ISO_CUBOID_3_PLANE_3_INTERSECTION_H #define CGAL_INTERNAL_INTERSECTIONS_3_ISO_CUBOID_3_PLANE_3_INTERSECTION_H + #include #include + #include #include #include #include + namespace CGAL { namespace Intersections { @@ -61,7 +64,7 @@ intersection( typedef std::vector Poly; typedef typename Intersection_traits, - CGAL::Plane_3 >::result_type Result_type; + CGAL::Plane_3 >::result_type result_type; typedef typename Intersection_traits, CGAL::Plane_3 >::result_type Inter_type; @@ -71,72 +74,92 @@ intersection( //get all edges of cub for(int i=0; i< 4; ++i) - { edges.push_back(Segment_3(cub.vertex(i), cub.vertex((i+1)%4))); - } - for(int i=0; i < 4; ++i) - { edges.push_back(Segment_3(cub.vertex(i+4), cub.vertex((i+1)%4+4))); - } - for(int i=0; i < 4; ++i) - { edges.push_back(Segment_3(cub.vertex(i), cub.vertex((i+1)%4+4))); - } + //get all intersections between pl and cub edges std::vector segments; std::vector points; for(int i=0; i < 12; ++i) { + // Intersect_3 checks the orientation of the segment's extremities to avoid actually computing + // the intersection if possible Inter_type inter = typename K::Intersect_3()(pl, edges[i]); - if(inter){ + if(inter) + { if(const Segment_3* seg = boost::get(&*inter)) - { segments.push_back(*seg); - } else if(const Point_3* p = boost::get(&*inter)) - { points.push_back(*p); - } } } switch(segments.size()) { - case 1: - { - //adj to an edge - if(points.size() == 4) + case 1: { - return Result_type(std::forward(segments.front())); - } - //through an edge not on diagonal - else{ - Poly res(4); - Segment_3 front(segments.front()); - Point_3 p1,p2; - bool has_p1(false), - has_p2(false); - for(auto p : points) + //adj to an edge + if(points.size() == 4) { - if(!front.has_on(p)) + return result_type(std::forward(segments.front())); + } + //through an edge not on diagonal + else + { + Poly res(4); + Segment_3 front(segments.front()); + Point_3 p1, p2; + bool has_p1(false), + has_p2(false); + + for(auto p : points) { - if(!has_p1) + if(!front.has_on(p)) { - p1 = p; - has_p1 = true; - } - else { - p2 = p; - has_p2 = true; - break; + if(!has_p1) + { + p1 = p; + has_p1 = true; + } + else { + p2 = p; + has_p2 = true; + break; + } } } + + CGAL_assertion(has_p1 && has_p2); + Segment_3 back(p1,p2); + res[0] = front.target(); + + if((front.target() - front.source()) + * (back.target() - back.source()) > 0) + { + res[1] = back.target(); + res[2] = back.source(); + } + else + { + res[1] = back.source(); + res[2] = back.target(); + } + res[3] = front.source(); + + return result_type(std::forward(res)); } - CGAL_assertion(has_p1 && has_p2); - Segment_3 back(p1,p2); + } + break; + + case 2: //intersects diagonally + { + Poly res(4); + Segment_3 front(segments.front()), + back(segments.back()); res[0] = front.target(); if((front.target() - front.source()) * (back.target() - back.source()) > 0) @@ -151,59 +174,37 @@ intersection( } res[3] = front.source(); - return Result_type(std::forward(res)); + return result_type(std::forward(res)); } - } - break; - - case 2: //intersects diagonally - { - Poly res(4); - Segment_3 front(segments.front()), - back(segments.back()); - res[0] = front.target(); - if((front.target() - front.source()) - * (back.target() - back.source()) > 0) + break; + case 4: // intersects a face { - res[1] = back.target(); - res[2] = back.source(); - } - else - { - res[1] = back.source(); - res[2] = back.target(); - } - res[3] = front.source(); + Poly res; + res.reserve(4); + std::list tmp; + std::list seg_list; + for(const Segment_3& s : segments) + seg_list.push_back(s); + fill_points_list(seg_list, tmp); + for(const Point_3& p : tmp) + res.push_back(p); - return Result_type(std::forward(res)); - } - break; - case 4: // intersects a face - { - Poly res; - res.reserve(4); - std::list tmp; - std::list seg_list; - for(auto s : segments) - seg_list.push_back(s); - fill_points_list(seg_list, tmp); - for(auto p : tmp) - res.push_back(p); - return Result_type(std::forward(res)); - } - break; - default: - break; + return result_type(std::forward(res)); + } + break; + default: + break; } Poly filtered_points; filter_points(points, filtered_points); if(filtered_points.empty()) - return Result_type(); + return result_type(); + //adjacent to a vertex if(filtered_points.size() == 1) { - return Result_type(std::forward(filtered_points.front())); + return result_type(std::forward(filtered_points.front())); } else { @@ -273,7 +274,7 @@ intersection( } } if(tmp_segs.size() < 3) - return Result_type(); + return result_type(); std::list tmp_pts; fill_points_list(tmp_segs,tmp_pts); Poly res; @@ -281,11 +282,11 @@ intersection( res.push_back(p); if(res.size() == 3){ typename K::Triangle_3 tr(res[0], res[1], res[2]); - return Result_type(std::forward(tr)); + return result_type(std::forward(tr)); } else { - return Result_type(std::forward(res)); + return result_type(std::forward(res)); } } } diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h index c355a851fe9..193d28dc3d8 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h @@ -213,13 +213,16 @@ template void fill_points_list(std::list& segments, std::list& points) { - assert(segments.size() > 1); + CGAL_assertion(segments.size() > 1); + //init : take seg.front = seg. Segment seg = segments.front(); segments.pop_front(); + //put source and target in points. points.push_back(seg.source()); points.push_back(seg.target()); + //find first seg with a point in common with seg.front = s2. do{ auto seg_it = segments.begin(); From 9a8f26ced7cf757e85fad70fbb1b40ca9313fc41 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Tue, 22 Oct 2019 14:00:46 +0200 Subject: [PATCH 070/141] More changes after review --- .../CGAL/Intersections_3/Bbox_3_Bbox_3.h | 15 +- .../Iso_cuboid_3_Plane_3_intersection.h | 215 +++++++++--------- .../Tetrahedron_3_Line_3_intersection.h | 9 +- .../Tetrahedron_3_Plane_3_intersection.h | 2 +- .../Intersections_3/test_intersections_3.cpp | 1 - 5 files changed, 119 insertions(+), 123 deletions(-) diff --git a/Intersections_3/include/CGAL/Intersections_3/Bbox_3_Bbox_3.h b/Intersections_3/include/CGAL/Intersections_3/Bbox_3_Bbox_3.h index fae33a52e50..8ff63ab2883 100644 --- a/Intersections_3/include/CGAL/Intersections_3/Bbox_3_Bbox_3.h +++ b/Intersections_3/include/CGAL/Intersections_3/Bbox_3_Bbox_3.h @@ -47,15 +47,12 @@ intersection(const CGAL::Bbox_3& a, if(!do_intersect(a,b)) return Result_type(); - double xmin, xmax, ymin, ymax, zmin, zmax; - xmin = (std::max)(a.xmin(), b.xmin()); - xmax = (std::min)(a.xmax(), b.xmax()); - - ymin = (std::max)(a.ymin(), b.ymin()); - ymax = (std::min)(a.ymax(), b.ymax()); - - zmin = (std::max)(a.zmin(), b.zmin()); - zmax = (std::min)(a.zmax(), b.zmax()); + double xmin = (std::max)(a.xmin(), b.xmin()); + double xmax = (std::min)(a.xmax(), b.xmax()); + double ymin = (std::max)(a.ymin(), b.ymin()); + double ymax = (std::min)(a.ymax(), b.ymax()); + double zmin = (std::max)(a.zmin(), b.zmin()); + double zmax = (std::min)(a.zmax(), b.zmax()); return Result_type(std::forward(Bbox_3(xmin, ymin, zmin, xmax, ymax, zmax))); } diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h index c684578035f..d4d11fd50cd 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h @@ -33,20 +33,17 @@ #include namespace CGAL { - namespace Intersections { - namespace internal { template -void filter_points(const std::vector& input, +void filter_points(std::vector& input, std::vector& output) { - std::set tmp; - for( auto p : input) - tmp.insert(p); - for(auto p: tmp) - output.push_back(p); + std::sort(input.begin(), input.end()); + auto last = std::unique(input.begin(), input.end()); + input.erase(last, input.end()); + output = std::move(input); } //Tetrahedron_3 Line_3 @@ -55,7 +52,7 @@ typename Intersection_traits:: intersection( const typename K::Iso_cuboid_3 &cub, const typename K::Plane_3 &pl, - const K&) + const K& k) { typedef typename K::Point_3 Point_3; typedef typename K::Segment_3 Segment_3; @@ -74,11 +71,11 @@ intersection( //get all edges of cub for(int i=0; i< 4; ++i) - edges.push_back(Segment_3(cub.vertex(i), cub.vertex((i+1)%4))); + edges.emplace_back(cub.vertex(i), cub.vertex((i+1)%4)); for(int i=0; i < 4; ++i) - edges.push_back(Segment_3(cub.vertex(i+4), cub.vertex((i+1)%4+4))); + edges.emplace_back(cub.vertex(i+4), cub.vertex((i+1)%4+4)); for(int i=0; i < 4; ++i) - edges.push_back(Segment_3(cub.vertex(i), cub.vertex((i+1)%4+4))); + edges.emplace_back(cub.vertex(i), cub.vertex((i+1)%4+4)); //get all intersections between pl and cub edges std::vector segments; @@ -98,8 +95,14 @@ intersection( } } + if(segments.empty() && points.empty()) + return result_type(); + switch(segments.size()) { + case 0: + //points dealt with later + break; case 1: { //adj to an edge @@ -107,48 +110,48 @@ intersection( { return result_type(std::forward(segments.front())); } - //through an edge not on diagonal + //plane intersecting through an edge (not 2) else { Poly res(4); - Segment_3 front(segments.front()); + const Segment_3& entry_seg(segments.front()); Point_3 p1, p2; - bool has_p1(false), - has_p2(false); + bool p1_found(false), + p2_found(false); - for(auto p : points) + for(const Point_3& p : points) { - if(!front.has_on(p)) + if(!k.equal_3_object()(entry_seg.source(), p) + && ! k.equal_3_object()(entry_seg.target(), p)) { - if(!has_p1) + if(!p1_found) { p1 = p; - has_p1 = true; + p1_found = true; } else { p2 = p; - has_p2 = true; + p2_found = true; break; } } } - CGAL_assertion(has_p1 && has_p2); - Segment_3 back(p1,p2); - res[0] = front.target(); + CGAL_assertion(p1_found && p2_found); + res[0] = entry_seg.target(); - if((front.target() - front.source()) - * (back.target() - back.source()) > 0) + if((entry_seg.target() - p1) + * (p2 - p1) > 0) { - res[1] = back.target(); - res[2] = back.source(); + res[1] = p2; + res[2] = p1; } else { - res[1] = back.source(); - res[2] = back.target(); + res[1] = p1; + res[2] = p2; } - res[3] = front.source(); + res[3] = entry_seg.source(); return result_type(std::forward(res)); } @@ -198,96 +201,92 @@ intersection( Poly filtered_points; filter_points(points, filtered_points); - if(filtered_points.empty()) - return result_type(); //adjacent to a vertex if(filtered_points.size() == 1) { return result_type(std::forward(filtered_points.front())); } - else + + //get intersections between pl and each face -> line. Foreach line, creates segment with points. Then use helper_function to recover polygon. + typedef typename Intersection_traits, + CGAL::Plane_3 >::result_type Pl_pl_type; + + std::vector plane_intersections; + Pl_pl_type pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(0), + cub.vertex(1), + cub.vertex(5))); + if(const Line_3* line = boost::get(&*pl_inter)){ + plane_intersections.push_back(*line); + } + pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(0), + cub.vertex(3), + cub.vertex(4))); + if(const Line_3* line = boost::get(&*pl_inter)){ + plane_intersections.push_back(*line); + } + pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(0), + cub.vertex(1), + cub.vertex(3))); + if(const Line_3* line = boost::get(&*pl_inter)){ + plane_intersections.push_back(*line); + } + pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(7), + cub.vertex(6), + cub.vertex(1))); + if(const Line_3* line = boost::get(&*pl_inter)){ + plane_intersections.push_back(*line); + } + pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(7), + cub.vertex(4), + cub.vertex(3))); + if(const Line_3* line = boost::get(&*pl_inter)){ + plane_intersections.push_back(*line); + } + pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(7), + cub.vertex(6), + cub.vertex(4))); + if(const Line_3* line = boost::get(&*pl_inter)){ + plane_intersections.push_back(*line); + } + + std::list tmp_segs; + for(auto line : plane_intersections) { - //get intersections between pl and each face -> line. Foreach line, creates segment with points. Then use helper_function to recover polygon. - typedef typename Intersection_traits, - CGAL::Plane_3 >::result_type Pl_pl_type; - - std::vector plane_intersections; - Pl_pl_type pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(0), - cub.vertex(1), - cub.vertex(5))); - if(const Line_3* line = boost::get(&*pl_inter)){ - plane_intersections.push_back(*line); - } - pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(0), - cub.vertex(3), - cub.vertex(4))); - if(const Line_3* line = boost::get(&*pl_inter)){ - plane_intersections.push_back(*line); - } - pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(0), - cub.vertex(1), - cub.vertex(3))); - if(const Line_3* line = boost::get(&*pl_inter)){ - plane_intersections.push_back(*line); - } - pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(7), - cub.vertex(6), - cub.vertex(1))); - if(const Line_3* line = boost::get(&*pl_inter)){ - plane_intersections.push_back(*line); - } - pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(7), - cub.vertex(4), - cub.vertex(3))); - if(const Line_3* line = boost::get(&*pl_inter)){ - plane_intersections.push_back(*line); - } - pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(7), - cub.vertex(6), - cub.vertex(4))); - if(const Line_3* line = boost::get(&*pl_inter)){ - plane_intersections.push_back(*line); - } - - std::list tmp_segs; - for(auto line : plane_intersections) + bool first_found = false; + Point_3 first_p; + for(auto p : filtered_points) { - bool first_found = false; - Point_3 first_p; - for(auto p : filtered_points) + if(line.has_on(p)) { - if(line.has_on(p)) + if(!first_found) { - if(!first_found) - { - first_found = true; - first_p = p; - } - else - { - tmp_segs.push_back(Segment_3(first_p, p)); - break; - } + first_found = true; + first_p = p; + } + else + { + tmp_segs.push_back(Segment_3(first_p, p)); + break; } } } - if(tmp_segs.size() < 3) - return result_type(); - std::list tmp_pts; - fill_points_list(tmp_segs,tmp_pts); - Poly res; - for(auto p : tmp_pts) - res.push_back(p); - if(res.size() == 3){ - typename K::Triangle_3 tr(res[0], res[1], res[2]); - return result_type(std::forward(tr)); - } - else - { - return result_type(std::forward(res)); - } + } + if(tmp_segs.size() < 3) + return result_type(); + std::list tmp_pts; + fill_points_list(tmp_segs,tmp_pts); + Poly res; + for(auto p : tmp_pts) + res.push_back(p); + if(res.size() == 3){ + typename K::Triangle_3 tr(res[0], res[1], res[2]); + return result_type(std::forward(tr)); + } + else + { + return result_type(std::forward(res)); } } diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Line_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Line_3_intersection.h index 51fc6c4a46e..f9a8e8f7895 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Line_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Line_3_intersection.h @@ -37,12 +37,13 @@ template struct Tetrahedron_Line_intersection_3 :public Tetrahedron_lines_intersection_3_base > { - typedef typename K::Line_3 O; typedef Tetrahedron_lines_intersection_3_base > Base; typedef typename Base::Result_type Result_type; - Tetrahedron_Line_intersection_3(const typename K::Tetrahedron_3& tet, - const O& o):Base(tet,o) {} + Tetrahedron_Line_intersection_3( + const typename K::Tetrahedron_3& tet, + const typename K::Line_3& o):Base(tet,o) + {} bool all_inside_test() { @@ -64,7 +65,7 @@ intersection( const typename K::Line_3 &line, const K&) { - Tetrahedron_lines_intersection_3_base > solver(tet, line); + Tetrahedron_Line_intersection_3 solver(tet, line); solver.do_procede(); return solver.output; } diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersection.h index 8dcb4cd085d..9206ddcd4e5 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersection.h @@ -36,7 +36,7 @@ namespace Intersections { namespace internal { -//Tetrahedron_3 Segment_3 +//Tetrahedron_3 Plane_3 template typename Intersection_traits::result_type intersection( diff --git a/Intersections_3/test/Intersections_3/test_intersections_3.cpp b/Intersections_3/test/Intersections_3/test_intersections_3.cpp index 0eca13bfb97..7292f661203 100644 --- a/Intersections_3/test/Intersections_3/test_intersections_3.cpp +++ b/Intersections_3/test/Intersections_3/test_intersections_3.cpp @@ -1215,6 +1215,5 @@ int main() Test< CGAL::Homogeneous >().run(); Test< CGAL::Epeck >().run(true); Test< CGAL::Homogeneous >().run(true); - // TODO : test more kernels. } From 2bfa95a2edf6fe30e374e9a99d2450e58e3c243d Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 23 Oct 2019 09:56:56 +0200 Subject: [PATCH 071/141] more indentation fixes --- .../tetrahedron_intersection_helpers.h | 33 +++++------ .../tetrahedron_lines_intersections_3.h | 58 ++++++++++--------- 2 files changed, 48 insertions(+), 43 deletions(-) diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h index 193d28dc3d8..39a387ddca4 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h @@ -28,9 +28,7 @@ #include namespace CGAL { - namespace Intersections { - namespace internal { template @@ -41,19 +39,19 @@ void filter_segments(const std::vector& input, do { - Segment s = tmp.back(); - tmp.pop_back(); - for(auto s_it = tmp.begin(); s_it != tmp.end();) - { - if(s == *s_it || s == s_it->opposite()) + Segment s = tmp.back(); + tmp.pop_back(); + for(auto s_it = tmp.begin(); s_it != tmp.end();) { - s_it = tmp.erase(s_it); + if(s == *s_it || s == s_it->opposite()) + { + s_it = tmp.erase(s_it); + } + else { + ++s_it; + } } - else { - ++s_it; - } - } - output.push_back(s); + output.push_back(s); }while (!tmp.empty()); } @@ -215,16 +213,15 @@ void fill_points_list(std::list& segments, std::list& points) { CGAL_assertion(segments.size() > 1); - //init : take seg.front = seg. Segment seg = segments.front(); segments.pop_front(); - //put source and target in points. points.push_back(seg.source()); points.push_back(seg.target()); //find first seg with a point in common with seg.front = s2. - do{ + do + { auto seg_it = segments.begin(); bool found = false; for(;seg_it != segments.end(); ++seg_it) @@ -266,5 +263,7 @@ void fill_points_list(std::list& segments, std::list& points) }while(!segments.empty()); } -}}}//end namespaces +} +} +}//end namespaces #endif // CGAL_INTERNAL_TETRAHEDRON_INTERSECTION_HELPERS_H diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h index ea8cb0b0f69..f7eb10e0338 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h @@ -28,28 +28,29 @@ #include namespace CGAL { - namespace Intersections { - namespace internal { -template + +template struct Tetrahedron_lines_intersection_3_base { typedef typename Intersection_traits, - O>::result_type Result_type; + CGAL::Tetrahedron_3, + O>::result_type Result_type; typedef typename Intersection_traits, - O>::result_type Inter_type; + CGAL::Triangle_3, + O>::result_type Inter_type; - Tetrahedron_lines_intersection_3_base(const typename K::Tetrahedron_3& tet, - const O& o):tet(tet), o(o) - {} const typename K::Tetrahedron_3& tet; const O& o; std::vector res_points; Result_type output; + + Tetrahedron_lines_intersection_3_base(const typename K::Tetrahedron_3& tet, + const O& o):tet(tet), o(o) + {} + bool all_inside_test() { return false; @@ -62,7 +63,7 @@ struct Tetrahedron_lines_intersection_3_base void do_procede() { - if(static_cast(this)->all_inside_test()) + if(static_cast(this)->all_inside_test()) return; int res_id = -1; @@ -70,18 +71,18 @@ struct Tetrahedron_lines_intersection_3_base Inter_type tr_seg[4]; for(std::size_t i = 0; i < 4; ++i) { - const typename K::Triangle_3 triangle(tet.vertex((i+1)%4), - tet.vertex((i+2)%4), - tet.vertex((i+3)%4)); - if(do_intersect(o, triangle)) - { - tr_seg[i] = typename K::Intersect_3()(o, triangle); - if( boost::get(&*tr_seg[i]) != nullptr) - { - res_id = i; - break; - } - } + const typename K::Triangle_3 triangle(tet.vertex((i+1)%4), + tet.vertex((i+2)%4), + tet.vertex((i+3)%4)); + if(do_intersect(o, triangle)) + { + tr_seg[i] = typename K::Intersect_3()(o, triangle); + if( boost::get(&*tr_seg[i]) != nullptr) + { + res_id = i; + break; + } + } } //if there is a segment in the intersections, then we return it @@ -94,6 +95,7 @@ struct Tetrahedron_lines_intersection_3_base //else if there is only 1 intersection res_points.reserve(4); res_id = -1; + for(std::size_t i = 0; i< 4; ++i) { if(tr_seg[i]) @@ -114,22 +116,26 @@ struct Tetrahedron_lines_intersection_3_base } } } + if(res_points.empty()) { return; } + if(res_id != -1) { - if(static_cast(this)->are_extremities_inside_test()) + if(static_cast(this)->are_extremities_inside_test()) return; //else point and segment entirely not inside or one intersection on boundary: output = tr_seg[res_id]; return; } + //else, we return a segment of the 2 intersection points (the most far away, in case of inexact) typename K::FT max_dist = 0; std::size_t res_id_2 = -1; std::vector > sq_distances(res_points.size()); + for(std::size_t i = 0; i< res_points.size(); ++i) { auto p1 = res_points[i]; @@ -144,12 +150,12 @@ struct Tetrahedron_lines_intersection_3_base } } } + CGAL_assertion(res_id != -1); CGAL_assertion(res_id_2 != -1); CGAL_assertion(max_dist >0 ); typename K::Segment_3 res_seg(res_points[res_id], res_points[res_id_2]); - output = Result_type(std::forward(res_seg)); return; } @@ -157,5 +163,5 @@ struct Tetrahedron_lines_intersection_3_base } } -} +} //end namespaces #endif // CGAL_INTERNAL_INTERSECTIONS_3_TETRAHEDRON_LINES_INTERSECTIONS_3_H From 23d41c50a6e35d9d3f03c54fe555ca6e78ed81f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 22 Nov 2019 11:24:47 +0100 Subject: [PATCH 072/141] handle case of a halfedge on the boundary (ignore in the if after) --- .../include/CGAL/Polygon_mesh_processing/orientation.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index d07026711c8..e78085048a1 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -876,7 +876,9 @@ volume_connected_components(const TriangleMesh& tm, std::vector xtrm_vertices(nb_cc, GT::null_vertex()); for(vertex_descriptor vd : vertices(tm)) { - std::size_t cc_id = face_cc[get(fid_map, face(halfedge(vd, tm), tm))]; + halfedge_descriptor h = halfedge(vd, tm); + if (is_border(h, tm)) h = opposite(h, tm); + std::size_t cc_id = face_cc[get(fid_map, face(h, tm))]; if (cc_handled.test(cc_id)) continue; if (xtrm_vertices[cc_id]==GT::null_vertex()) xtrm_vertices[cc_id]=vd; From 7c042a3fb36288e2e1468ed9ecd7bffeab6b0264 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Fri, 3 Jan 2020 16:40:48 +0100 Subject: [PATCH 073/141] Fix a bug in applicable --- .../Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp index 4d238894cc4..c635867deda 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp @@ -366,13 +366,15 @@ boost::optional Mesh_3_plugin::get_items_or_return_error_string() const } # endif - bbox = item->bbox(); - if (auto poly_items = get(&*items)) { - for (auto it : poly_items->sm_items) { - bbox = bbox + it->bbox(); + if(item) { + bbox = item->bbox(); + if (auto poly_items = get(&*items)) { + for (auto it : poly_items->sm_items) { + bbox = bbox + it->bbox(); + } + if (poly_items->polylines_item) + bbox = bbox + poly_items->polylines_item->bbox(); } - if (poly_items->polylines_item) - bbox = bbox + poly_items->polylines_item->bbox(); } return {}; } From cc200d210df4ca03da6ff14dd207cf271261e121 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Fri, 3 Jan 2020 16:41:11 +0100 Subject: [PATCH 074/141] Support for CGAL_NO_EXTERNAL_PROJECTS --- .../CGAL_setup_GuidelinesSupportLibrary.cmake | 43 +++++++++++++------ 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/Installation/cmake/modules/CGAL_setup_GuidelinesSupportLibrary.cmake b/Installation/cmake/modules/CGAL_setup_GuidelinesSupportLibrary.cmake index b77f5edd010..a3214a237b4 100644 --- a/Installation/cmake/modules/CGAL_setup_GuidelinesSupportLibrary.cmake +++ b/Installation/cmake/modules/CGAL_setup_GuidelinesSupportLibrary.cmake @@ -1,16 +1,33 @@ if(NOT TARGET cxx::gsl) include(ExternalProject) - ExternalProject_Add(gsl-download - URL https://github.com/microsoft/GSL/archive/v2.0.0.tar.gz - DOWNLOAD_NAME GSL-2.0.0.tar.gz - URL_HASH SHA512=7339527222c8a97a94c0bb4038b3d142045ec5d80995e628574ac96f4d9d13c41ad70fbe0d8390586dc0db8d9ea55107dbc95de80f7335eb78ef9d2e7047d726 - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - INSTALL_COMMAND "" - ) - ExternalProject_Get_Property(gsl-download source_dir) - add_library(CGAL-Microsoft-gsl INTERFACE) - target_include_directories(CGAL-Microsoft-gsl SYSTEM INTERFACE ${source_dir}/include) - add_dependencies(CGAL-Microsoft-gsl gsl-download) - add_library(cxx::gsl ALIAS CGAL-Microsoft-gsl) + + if(NOT CGAL_NO_EXTERNAL_PROJECTS) + ExternalProject_Add(gsl-download + URL https://github.com/microsoft/GSL/archive/v2.0.0.tar.gz + DOWNLOAD_NAME GSL-2.0.0.tar.gz + URL_HASH SHA512=7339527222c8a97a94c0bb4038b3d142045ec5d80995e628574ac96f4d9d13c41ad70fbe0d8390586dc0db8d9ea55107dbc95de80f7335eb78ef9d2e7047d726 + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + ) + ExternalProject_Get_Property(gsl-download source_dir) + find_path(gsl_include_dir + NAMES gsl/gsl + PATHS ${source_dir}/include + DOC "Include directory of the C++ Guideline Support Library") + endif() + if(NOT gsl_include_dir) + find_path(gsl_include_dir + NAMES gsl/gsl + PATH_SUFFIXES guidelines-support-library + DOC "Include directory of the C++ Guideline Support Library (version 2.0 or later)") + endif() + if(gsl_include_dir) + add_library(CGAL-gsl INTERFACE) + target_include_directories(CGAL-gsl SYSTEM INTERFACE ${gsl_include_dir}) + if(TARGET gsl-download) + add_dependencies(CGAL-gsl gsl-download) + endif() + add_library(cxx::gsl ALIAS CGAL-gsl) + endif() endif() From 9de3913dbffc5d9706323b2bf5b91a47ba8207fa Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Mon, 6 Jan 2020 09:50:41 +0100 Subject: [PATCH 075/141] Fix warnings --- Mesh_3/include/CGAL/Mesh_3/Refine_cells_3.h | 1 + Mesh_3/include/CGAL/Mesh_3/Refine_facets_3.h | 1 + Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp | 3 +-- .../demo/Polyhedron/Plugins/Mesh_3/Optimization_plugin.cpp | 6 +++--- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Mesh_3/include/CGAL/Mesh_3/Refine_cells_3.h b/Mesh_3/include/CGAL/Mesh_3/Refine_cells_3.h index 5d5d582ab02..0b7ca09469a 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Refine_cells_3.h +++ b/Mesh_3/include/CGAL/Mesh_3/Refine_cells_3.h @@ -434,6 +434,7 @@ public: && !defined(CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE) this->remove_element(c); #endif + CGAL_USE(c); } // Parallel: it's always lazy, so do nothing void remove_element_from_refinement_queue(Cell_handle, Parallel_tag) {} diff --git a/Mesh_3/include/CGAL/Mesh_3/Refine_facets_3.h b/Mesh_3/include/CGAL/Mesh_3/Refine_facets_3.h index 38f066ef049..bba248c5538 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Refine_facets_3.h +++ b/Mesh_3/include/CGAL/Mesh_3/Refine_facets_3.h @@ -570,6 +570,7 @@ protected: Facet canonical_facet = this->canonical_facet(facet); this->remove_element(canonical_facet); #endif + CGAL_USE(facet); } #ifdef CGAL_LINKED_WITH_TBB /// Removes facet from refinement queue diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp index c635867deda..59d52031fa4 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp @@ -513,7 +513,6 @@ void Mesh_3_plugin::mesh_3(const Mesh_type mesh_type, set_defaults(); double diag = CGAL::sqrt((bbox.xmax()-bbox.xmin())*(bbox.xmax()-bbox.xmin()) + (bbox.ymax()-bbox.ymin())*(bbox.ymax()-bbox.ymin()) + (bbox.zmax()-bbox.zmin())*(bbox.zmax()-bbox.zmin())); - int decimals = 0; ui.facetSizing->setRange(diag * 10e-6, // min diag); // max ui.facetSizing->setValue(facets_sizing); @@ -601,7 +600,7 @@ void Mesh_3_plugin::mesh_3(const Mesh_type mesh_type, (ui.facetTopology->isChecked() ? 2 : 0); const float iso_value = float(ui.iso_value_spinBox->value()); const float value_outside = float(ui.value_outside_spinBox->value()); - const float inside_is_less = float(ui.inside_is_less_checkBox->isChecked()); + const bool inside_is_less = ui.inside_is_less_checkBox->isChecked(); as_facegraph = (mesh_type == Mesh_type::SURFACE_ONLY) ? ui.facegraphCheckBox->isChecked() : false; diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Optimization_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Optimization_plugin.cpp index d069d109672..7395203a2ec 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Optimization_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Optimization_plugin.cpp @@ -521,9 +521,9 @@ treat_result(Scene_c3t3_item& source_item, if ( &source_item != &result_item) { const Scene_item::Bbox& bbox = result_item.bbox(); - result_item.setPosition((bbox.xmin() + bbox.xmax())/2.f, - (bbox.ymin() + bbox.ymax())/2.f, - (bbox.zmin() + bbox.zmax())/2.f); + result_item.setPosition(static_cast(bbox.xmin() + bbox.xmax())/2.f, + static_cast(bbox.ymin() + bbox.ymax())/2.f, + static_cast(bbox.zmin() + bbox.zmax())/2.f); result_item.setColor(QColor(59,74,226)); result_item.setRenderingMode(source_item.renderingMode()); From e051d446916214f62b2fa16bfe7f234b89cc2191 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Wed, 8 Jan 2020 15:51:43 +0100 Subject: [PATCH 076/141] Support precompiled headers for Mesh_3 plugins --- Polyhedron/demo/Polyhedron/C3t3_type.h | 3 +++ Polyhedron/demo/Polyhedron/CMakeLists.txt | 4 ++++ Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp | 1 + Polyhedron/demo/Polyhedron/Plugins/Mesh_3/config_mesh_3.h | 2 +- Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp | 4 ++-- 5 files changed, 11 insertions(+), 3 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/C3t3_type.h b/Polyhedron/demo/Polyhedron/C3t3_type.h index db47e612a0f..c7d63fd9ef5 100644 --- a/Polyhedron/demo/Polyhedron/C3t3_type.h +++ b/Polyhedron/demo/Polyhedron/C3t3_type.h @@ -1,6 +1,9 @@ #ifndef CGAL_DEMO_MESH_3_C3T3_TYPE_H #define CGAL_DEMO_MESH_3_C3T3_TYPE_H +#include "config.h" +#include "Plugins/Mesh_3/config_mesh_3.h" + // include this to get #define BOOST_PARAMETER_MAX_ARITY 12 // as otherwise it gets set via inclusion of Polyhedron_3.h #include diff --git a/Polyhedron/demo/Polyhedron/CMakeLists.txt b/Polyhedron/demo/Polyhedron/CMakeLists.txt index 005af31df2a..45469400764 100644 --- a/Polyhedron/demo/Polyhedron/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/CMakeLists.txt @@ -246,6 +246,10 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND) if(TBB_FOUND) CGAL_target_use_TBB(scene_c3t3_item) endif() + if(COMMAND target_precompile_headers) + # Support for precompiled headers, for Mesh_3 (since CMake 3.16) + target_precompile_headers(scene_c3t3_item PUBLIC [["C3t3_type.h"]]) + endif() add_item(scene_transform_item Plugins/PCA/Scene_facegraph_transform_item.cpp ) add_item(scene_edit_box_item Plugins/PCA/Scene_edit_box_item.cpp ) add_item(scene_image_item Scene_image_item.cpp) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp index 59d52031fa4..f4fbc454d88 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp @@ -29,6 +29,7 @@ #endif #ifdef CGAL_MESH_3_DEMO_ACTIVATE_SEGMENTED_IMAGES #include "Scene_image_item.h" +#include "Image_type.h" #endif #include "Meshing_thread.h" diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/config_mesh_3.h b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/config_mesh_3.h index fb142e294ac..67397810033 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/config_mesh_3.h +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/config_mesh_3.h @@ -31,7 +31,7 @@ # define CGAL_POLYHEDRON_DEMO_USE_SURFACE_MESHER #endif -#define CGAL_MESH_3_DEMO_BIGGER_HISTOGRAM_WITH_WHITE_BACKGROUNG +//#define CGAL_MESH_3_DEMO_BIGGER_HISTOGRAM_WITH_WHITE_BACKGROUNG // If you define this, implicit function and segmented images won't be available //#define CGAL_MESH_3_DEMO_ACTIVATE_SHARP_FEATURES_IN_POLYHEDRAL_DOMAIN diff --git a/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp b/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp index 9ad4cfa9dc2..0933b5328e4 100644 --- a/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp @@ -747,8 +747,8 @@ Scene_c3t3_item::build_histogram() const int text_margin = 3; const int text_height = 34; - histogram_ = QPixmap(width, height + text_height); - histogram_.fill(QColor(255, 255, 255)); + d->histogram_ = QPixmap(width, height + text_height); + d->histogram_.fill(QColor(255, 255, 255)); #else // Create an histogram_ and display it const int height = 140; From a8cb280133e82b6ca486014a7bed686b546efe85 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Wed, 8 Jan 2020 15:52:12 +0100 Subject: [PATCH 077/141] Fix a compilation error with CGAL_MESH_3_PROTECTION_DEBUG --- Mesh_3/include/CGAL/Polyhedral_mesh_domain_with_features_3.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mesh_3/include/CGAL/Polyhedral_mesh_domain_with_features_3.h b/Mesh_3/include/CGAL/Polyhedral_mesh_domain_with_features_3.h index d5f9979bc9b..1e7b4622d3c 100644 --- a/Mesh_3/include/CGAL/Polyhedral_mesh_domain_with_features_3.h +++ b/Mesh_3/include/CGAL/Polyhedral_mesh_domain_with_features_3.h @@ -306,7 +306,7 @@ void dump_graph_edges(std::ostream& out, const Graph& g) typedef typename boost::graph_traits::edge_descriptor edge_descriptor; out.precision(17); - for(edge_descriptor e : edges(g)) + for(edge_descriptor e : make_range(edges(g))) { vertex_descriptor s = source(e, g); vertex_descriptor t = target(e, g); From b8aee673f06288fdf310a43c5417fb81492d46df Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Wed, 8 Jan 2020 15:53:21 +0100 Subject: [PATCH 078/141] Optimization_plugin.cpp does not need to know the C3t3 type --- .../demo/Polyhedron/Plugins/Mesh_3/Optimization_plugin.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Optimization_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Optimization_plugin.cpp index 7395203a2ec..e25c5619df5 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Optimization_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Optimization_plugin.cpp @@ -16,7 +16,6 @@ #include "ui_Local_optimizers_dialog.h" #include "Scene_c3t3_item.h" -#include "C3t3_type.h" #include "Optimizer_thread.h" From daf2e6839f591171d1f76f004d4e0627891b4d7c Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Thu, 9 Jan 2020 16:52:05 +0100 Subject: [PATCH 079/141] Improve the code that deals with CGAL_MESH_3_PROTECTION_DEBUG --- .../CGAL/Mesh_3/Protect_edges_sizing_field.h | 25 ++++++++++++++----- .../CGAL/Mesh_3/polylines_to_protect.h | 4 +-- .../Mesh_domain_with_polyline_features_3.h | 2 +- .../CGAL/Polyhedral_complex_mesh_domain_3.h | 2 +- .../Polyhedral_mesh_domain_with_features_3.h | 6 ++--- .../Polyhedron/Plugins/Mesh_3/config_mesh_3.h | 9 +++++++ 6 files changed, 35 insertions(+), 13 deletions(-) diff --git a/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h b/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h index 3fdc4cf0b0b..e1afa5fbe6e 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h +++ b/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h @@ -444,7 +444,13 @@ private: if(dim == 0) msg << "corner ("; else msg << "point ("; msg << p << ")"; - CGAL_error_msg(msg.str().c_str()); + CGAL_error_msg(([this, str = msg.str()](){ + CGAL_USE(this); +#if CGAL_MESH_3_PROTECTION_DEBUG & 4 + dump_c3t3(this->c3t3_, "dump-bug"); +#endif + return str.c_str(); + }())); } return s; } @@ -730,7 +736,7 @@ smart_insert_point(const Bare_point& p, Weight w, int dim, const Index& index, Vertex_handle nearest_vh = tr.nearest_power_vertex(p, ch); FT sq_d = sq_distance(p, cp(tr.point(nearest_vh))); -#if CGAL_MESH_3_PROTECTION_DEBUG & 2 +#if CGAL_MESH_3_PROTECTION_DEBUG & 16 std::cerr << "Nearest power vertex of (" << p << ") is " << &*nearest_vh << " (" << c3t3_.triangulation().point(nearest_vh) << ") " << "at distance: " << sq_d << std::endl; @@ -1247,8 +1253,15 @@ insert_balls(const Vertex_handle& vp, norm_step_size = step_size; } else { CGAL_assertion_code(using boost::math::float_prior); - CGAL_assertion(n==0 || - dleft_frac >= float_prior(float_prior(1.))); + CGAL_assertion_msg(n==0 || + dleft_frac >= float_prior(float_prior(1.)), + ([this](){ + CGAL_USE(this); +#if CGAL_MESH_3_PROTECTION_DEBUG & 4 + dump_c3t3(this->c3t3_, "dump-bug"); +#endif + return "the sampling of protecting balls is not possible"; + }())); } // Launch balls @@ -1304,7 +1317,7 @@ void Protect_edges_sizing_field:: refine_balls() { -#if CGAL_MESH_3_PROTECTION_DEBUG & 4 +#if CGAL_MESH_3_PROTECTION_DEBUG & 8 dump_c3t3(c3t3_, "dump-before-refine_balls"); dump_c3t3_edges(c3t3_, "dump-before-refine_balls"); #endif @@ -1418,7 +1431,7 @@ refine_balls() } } -#if CGAL_MESH_3_PROTECTION_DEBUG & 4 +#if CGAL_MESH_3_PROTECTION_DEBUG & 8 dump_c3t3(c3t3_, "dump-before-check_and_repopulate_edges"); dump_c3t3_edges(c3t3_, "dump-before-check_and_repopulate_edges"); #endif diff --git a/Mesh_3/include/CGAL/Mesh_3/polylines_to_protect.h b/Mesh_3/include/CGAL/Mesh_3/polylines_to_protect.h index 96c049491b1..1b1285a577a 100644 --- a/Mesh_3/include/CGAL/Mesh_3/polylines_to_protect.h +++ b/Mesh_3/include/CGAL/Mesh_3/polylines_to_protect.h @@ -264,7 +264,7 @@ struct Polyline_visitor ~Polyline_visitor() {//DEBUG -#if CGAL_MESH_3_PROTECTION_DEBUG > 1 +#if CGAL_MESH_3_PROTECTION_DEBUG & 2 std::ofstream og("polylines_graph.polylines.txt"); og.precision(17); for(const std::vector

& poly : polylines) @@ -274,7 +274,7 @@ struct Polyline_visitor og << p << " "; og << std::endl; } -#endif // CGAL_MESH_3_PROTECTION_DEBUG > 1 +#endif // CGAL_MESH_3_PROTECTION_DEBUG & 2 } void start_new_polyline() diff --git a/Mesh_3/include/CGAL/Mesh_domain_with_polyline_features_3.h b/Mesh_3/include/CGAL/Mesh_domain_with_polyline_features_3.h index e452e53c47c..255f650ff6b 100644 --- a/Mesh_3/include/CGAL/Mesh_domain_with_polyline_features_3.h +++ b/Mesh_3/include/CGAL/Mesh_domain_with_polyline_features_3.h @@ -1410,7 +1410,7 @@ compute_corners_incidences() std::inserter(incidences, incidences.begin())); } -#ifdef CGAL_MESH_3_PROTECTION_DEBUG +#if CGAL_MESH_3_PROTECTION_DEBUG & 1 display_corner_incidences(std::cerr, cit->first, id); #endif // CGAL_MESH_3_PROTECTION_DEBUG diff --git a/Mesh_3/include/CGAL/Polyhedral_complex_mesh_domain_3.h b/Mesh_3/include/CGAL/Polyhedral_complex_mesh_domain_3.h index ae6413ca009..e7d86ca4c6c 100644 --- a/Mesh_3/include/CGAL/Polyhedral_complex_mesh_domain_3.h +++ b/Mesh_3/include/CGAL/Polyhedral_complex_mesh_domain_3.h @@ -990,7 +990,7 @@ add_featured_edges_to_graph(const Polyhedron_type& p, } } -#if CGAL_MESH_3_PROTECTION_DEBUG > 1 +#if CGAL_MESH_3_PROTECTION_DEBUG & 2 {// DEBUG Mesh_3::internal::dump_graph_edges("edges-graph.polylines.txt", g_copy); } diff --git a/Mesh_3/include/CGAL/Polyhedral_mesh_domain_with_features_3.h b/Mesh_3/include/CGAL/Polyhedral_mesh_domain_with_features_3.h index 1e7b4622d3c..25b60c2b02e 100644 --- a/Mesh_3/include/CGAL/Polyhedral_mesh_domain_with_features_3.h +++ b/Mesh_3/include/CGAL/Polyhedral_mesh_domain_with_features_3.h @@ -403,7 +403,7 @@ add_features_from_split_graph_into_polylines(Featured_edges_copy_graph& g_copy) this->add_features_with_context(polylines.begin(), polylines.end()); -#if CGAL_MESH_3_PROTECTION_DEBUG > 1 +#if CGAL_MESH_3_PROTECTION_DEBUG & 2 {//DEBUG std::ofstream og("polylines_graph.polylines.txt"); og.precision(17); @@ -416,7 +416,7 @@ add_features_from_split_graph_into_polylines(Featured_edges_copy_graph& g_copy) } og.close(); } -#endif // CGAL_MESH_3_PROTECTION_DEBUG > 1 +#endif // CGAL_MESH_3_PROTECTION_DEBUG & 2 } @@ -475,7 +475,7 @@ add_featured_edges_to_graph(const Polyhedron& p, } } -#if CGAL_MESH_3_PROTECTION_DEBUG > 1 +#if CGAL_MESH_3_PROTECTION_DEBUG & 2 {// DEBUG dump_graph_edges("edges-graph.polylines.txt", g_copy); } diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/config_mesh_3.h b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/config_mesh_3.h index 67397810033..9b1329b6cd7 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/config_mesh_3.h +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/config_mesh_3.h @@ -3,6 +3,15 @@ #define BOOST_PARAMETER_MAX_ARITY 12 +// CGAL_MESH_3_PROTECTION_DEBUG: +// - 1 : display debug messages +// - 2 : dump file `polylines_graph.polylines.txt` and +// `edges-graph.polylines.txt` from polyhedral and image domains +// - 4 : dump c3t3 in case of a bug +// - 8 : dump c3t3 at various stages of the protection +// - 16 : more precise debug messages +//#define CGAL_MESH_3_PROTECTION_DEBUG 255 + //#define CGAL_PROFILE From f136b25b2daaca67ee34b2a0df4f3b3767c59e36 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Thu, 9 Jan 2020 16:52:35 +0100 Subject: [PATCH 080/141] Fix warnings --- .../demo/Polyhedron/Scene_c3t3_item.cpp | 284 ++++++++---------- 1 file changed, 122 insertions(+), 162 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp b/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp index 0933b5328e4..fdace3d1452 100644 --- a/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp @@ -50,6 +50,14 @@ typedef Edge_container Ec; typedef Point_container Pc; typedef Viewer_interface Vi; +QVector4D cgal_plane_to_vector4d(EPICK::Plane_3 plane) { + return { + static_cast(-plane.a()), + static_cast(-plane.b()), + static_cast(-plane.c()), + static_cast(-plane.d()) }; +} + // The special Scene_item only for triangles class Scene_intersection_item : public CGAL::Three::Scene_item_rendering_helper { @@ -148,7 +156,7 @@ public : viewer->makeCurrent(); const EPICK::Plane_3& plane = qobject_cast(this->parent())->plane(); float shrink_factor = qobject_cast(this->parent())->getShrinkFactor(); - QVector4D cp(-plane.a(), -plane.b(), -plane.c(), -plane.d()); + QVector4D cp = cgal_plane_to_vector4d(plane); getTriangleContainer(0)->setPlane(cp); getTriangleContainer(0)->setShrinkFactor(shrink_factor); // positions_poly is also used for the faces in the cut plane @@ -161,7 +169,7 @@ public : if(is_fast) return; const EPICK::Plane_3& plane = qobject_cast(this->parent())->plane(); - QVector4D cp(-plane.a(), -plane.b(), -plane.c(), -plane.d()); + QVector4D cp = cgal_plane_to_vector4d(plane); getEdgeContainer(0)->setPlane(cp); getEdgeContainer(0)->setColor(QColor(Qt::black)); getEdgeContainer(0)->draw(viewer, true); @@ -180,48 +188,38 @@ public : Geom_traits::Vector_3 n = cross_product(pb - pa, pc - pa); n = n / CGAL::sqrt(n*n); + auto push_normal = [this](auto n) { + normals->push_back(static_cast(n.x())); + normals->push_back(static_cast(n.y())); + normals->push_back(static_cast(n.z())); + }; + + auto push_vertex = [this, &offset](const auto& p) { + this->vertices->push_back(static_cast(p.x()+offset.x)); + this->vertices->push_back(static_cast(p.y()+offset.y)); + this->vertices->push_back(static_cast(p.z()+offset.z)); + }; + + auto push_edge = [this, &offset](const auto& pa, const auto& pb) { + this->edges->push_back(static_cast(pa.x()+offset.x)); + this->edges->push_back(static_cast(pa.y()+offset.y)); + this->edges->push_back(static_cast(pa.z()+offset.z)); + this->edges->push_back(static_cast(pb.x()+offset.x)); + this->edges->push_back(static_cast(pb.y()+offset.y)); + this->edges->push_back(static_cast(pb.z()+offset.z)); + }; + for (int i = 0; i<3; i++) { - normals->push_back(n.x()); - normals->push_back(n.y()); - normals->push_back(n.z()); + push_normal(n); } + push_vertex(pa); + push_vertex(pb); + push_vertex(pc); - vertices->push_back(pa.x()+offset.x); - vertices->push_back(pa.y()+offset.y); - vertices->push_back(pa.z()+offset.z); - - vertices->push_back(pb.x()+offset.x); - vertices->push_back(pb.y()+offset.y); - vertices->push_back(pb.z()+offset.z); - - vertices->push_back(pc.x()+offset.x); - vertices->push_back(pc.y()+offset.y); - vertices->push_back(pc.z()+offset.z); - - edges->push_back(pa.x()+offset.x); - edges->push_back(pa.y()+offset.y); - edges->push_back(pa.z()+offset.z); - - edges->push_back(pb.x()+offset.x); - edges->push_back(pb.y()+offset.y); - edges->push_back(pb.z()+offset.z); - - edges->push_back(pb.x()+offset.x); - edges->push_back(pb.y()+offset.y); - edges->push_back(pb.z()+offset.z); - - edges->push_back(pc.x()+offset.x); - edges->push_back(pc.y()+offset.y); - edges->push_back(pc.z()+offset.z); - - edges->push_back(pc.x()+offset.x); - edges->push_back(pc.y()+offset.y); - edges->push_back(pc.z()+offset.z); - - edges->push_back(pa.x()+offset.x); - edges->push_back(pa.y()+offset.y); - edges->push_back(pa.z()+offset.z); + push_edge(pa, pb); + push_edge(pb, pc); + push_edge(pc, pa); for(int i=0; i<3; i++) { @@ -229,9 +227,9 @@ public : colors->push_back((float)color.green()/255); colors->push_back((float)color.blue()/255); - barycenters->push_back((pa[0]+pb[0]+pc[0])/3.0 + offset.x); - barycenters->push_back((pa[1]+pb[1]+pc[1])/3.0 + offset.y); - barycenters->push_back((pa[2]+pb[2]+pc[2])/3.0 + offset.z); + barycenters->push_back(static_cast((pa[0]+pb[0]+pc[0])/3.0 + offset.x)); + barycenters->push_back(static_cast((pa[1]+pb[1]+pc[1])/3.0 + offset.y)); + barycenters->push_back(static_cast((pa[2]+pb[2]+pc[2])/3.0 + offset.z)); } } @@ -502,6 +500,28 @@ struct Scene_c3t3_item_priv { bool is_valid; bool is_surface; bool last_intersection; + + void push_normal(std::vector& normals, const EPICK::Vector_3& n) const + { + normals.push_back(static_cast(n.x())); + normals.push_back(static_cast(n.y())); + normals.push_back(static_cast(n.z())); + } + void push_point(std::vector& points, const EPICK::Point_3& p, + const CGAL::qglviewer::Vec& offset) const + { + points.push_back(static_cast(p.x()+offset.x)); + points.push_back(static_cast(p.y()+offset.y)); + points.push_back(static_cast(p.z()+offset.z)); + } + void push_edge(std::vector& edges, + const EPICK::Point_3& pa, + const EPICK::Point_3& pb, + const CGAL::qglviewer::Vec& offset) const + { + push_point(edges, pa, offset); + push_point(edges, pb, offset); + } }; struct Set_show_tetrahedra { @@ -932,7 +952,7 @@ void Scene_c3t3_item::draw(CGAL::Three::Viewer_interface* viewer) const { if(renderingMode() == Flat || renderingMode() == FlatPlusEdges) { - QVector4D cp(this->plane().a(),this->plane().b(),this->plane().c(),this->plane().d()); + QVector4D cp = cgal_plane_to_vector4d(this->plane()); getTriangleContainer(C3t3_faces)->setPlane(cp); float shrink_factor = getShrinkFactor(); getTriangleContainer(C3t3_faces)->setShrinkFactor(shrink_factor); @@ -967,7 +987,7 @@ void Scene_c3t3_item::draw(CGAL::Three::Viewer_interface* viewer) const { getEdgeContainer(Grid_edges)->setColor(QColor(Qt::black)); QMatrix4x4 f_mat; for (int i = 0; i<16; i++) - f_mat.data()[i] = d->frame->matrix()[i]; + f_mat.data()[i] = static_cast(d->frame->matrix()[i]); getEdgeContainer(Grid_edges)->setFrameMatrix(f_mat); getEdgeContainer(Grid_edges)->draw(viewer, true); } @@ -1004,12 +1024,12 @@ void Scene_c3t3_item::drawEdges(CGAL::Three::Viewer_interface* viewer) const { getEdgeContainer(Grid_edges)->setColor(QColor(Qt::black)); QMatrix4x4 f_mat; for (int i = 0; i<16; i++) - f_mat.data()[i] = d->frame->matrix()[i]; + f_mat.data()[i] = static_cast(d->frame->matrix()[i]); getEdgeContainer(Grid_edges)->setFrameMatrix(f_mat); getEdgeContainer(Grid_edges)->draw(viewer, true); } - QVector4D cp(this->plane().a(),this->plane().b(),this->plane().c(),this->plane().d()); + QVector4D cp = cgal_plane_to_vector4d(this->plane()); getEdgeContainer(C3t3_edges)->setPlane(cp); getEdgeContainer(C3t3_edges)->setIsSurface(d->is_surface); getEdgeContainer(C3t3_edges)->setColor(QColor(Qt::black)); @@ -1059,7 +1079,7 @@ void Scene_c3t3_item::drawPoints(CGAL::Three::Viewer_interface * viewer) const } - QVector4D cp(this->plane().a(),this->plane().b(),this->plane().c(),this->plane().d()); + QVector4D cp = cgal_plane_to_vector4d(this->plane()); getPointContainer(C3t3_points)->setPlane(cp); getPointContainer(C3t3_points)->setIsSurface(d->is_surface); getPointContainer(C3t3_points)->setColor(this->color()); @@ -1070,7 +1090,7 @@ void Scene_c3t3_item::drawPoints(CGAL::Three::Viewer_interface * viewer) const getEdgeContainer(Grid_edges)->setColor(QColor(Qt::black)); QMatrix4x4 f_mat; for (int i = 0; i<16; i++) - f_mat.data()[i] = d->frame->matrix()[i]; + f_mat.data()[i] = static_cast(d->frame->matrix()[i]); getEdgeContainer(Grid_edges)->setFrameMatrix(f_mat); getEdgeContainer(Grid_edges)->draw(viewer, true); } @@ -1085,100 +1105,41 @@ void Scene_c3t3_item_priv::draw_triangle(const Tr::Bare_point& pa, const Tr::Bare_point& pb, const Tr::Bare_point& pc) const { -#undef darker Geom_traits::Vector_3 n = cross_product(pb - pa, pc - pa); n = n / CGAL::sqrt(n*n); const CGAL::qglviewer::Vec offset = Three::mainViewer()->offset(); for (int i = 0; i<3; i++) { - normals.push_back(n.x()); - normals.push_back(n.y()); - normals.push_back(n.z()); + push_normal(normals, n); } - positions_poly.push_back(pa.x()+offset.x); - positions_poly.push_back(pa.y()+offset.y); - positions_poly.push_back(pa.z()+offset.z); - - positions_poly.push_back(pb.x()+offset.x); - positions_poly.push_back(pb.y()+offset.y); - positions_poly.push_back(pb.z()+offset.z); - - positions_poly.push_back(pc.x()+offset.x); - positions_poly.push_back(pc.y()+offset.y); - positions_poly.push_back(pc.z()+offset.z); + push_point(positions_poly, pa, offset); + push_point(positions_poly, pb, offset); + push_point(positions_poly, pc, offset); for(int i=0; i<3; ++i) { - positions_barycenter.push_back((pa[0]+pb[0]+pc[0])/3.0 + offset.x); - positions_barycenter.push_back((pa[1]+pb[1]+pc[1])/3.0 + offset.y); - positions_barycenter.push_back((pa[2]+pb[2]+pc[2])/3.0 + offset.z); + push_point(positions_barycenter, CGAL::centroid(pa, pb, pc), offset); } - - } void Scene_c3t3_item_priv::draw_triangle_edges(const Tr::Bare_point& pa, const Tr::Bare_point& pb, const Tr::Bare_point& pc) const { -#undef darker const CGAL::qglviewer::Vec offset = Three::mainViewer()->offset(); - positions_lines.push_back(pa.x()+offset.x); - positions_lines.push_back(pa.y()+offset.y); - positions_lines.push_back(pa.z()+offset.z); - - positions_lines.push_back(pb.x()+offset.x); - positions_lines.push_back(pb.y()+offset.y); - positions_lines.push_back(pb.z()+offset.z); - - positions_lines.push_back(pb.x()+offset.x); - positions_lines.push_back(pb.y()+offset.y); - positions_lines.push_back(pb.z()+offset.z); - - positions_lines.push_back(pc.x()+offset.x); - positions_lines.push_back(pc.y()+offset.y); - positions_lines.push_back(pc.z()+offset.z); - - positions_lines.push_back(pc.x()+offset.x); - positions_lines.push_back(pc.y()+offset.y); - positions_lines.push_back(pc.z()+offset.z); - - positions_lines.push_back(pa.x()+offset.x); - positions_lines.push_back(pa.y()+offset.y); - positions_lines.push_back(pa.z()+offset.z); - + push_edge(positions_lines, pa, pb, offset); + push_edge(positions_lines, pb, pc, offset); + push_edge(positions_lines, pc, pa, offset); } void Scene_c3t3_item_priv::draw_triangle_edges_cnc(const Tr::Bare_point& pa, const Tr::Bare_point& pb, const Tr::Bare_point& pc) const { -#undef darker const CGAL::qglviewer::Vec offset = Three::mainViewer()->offset(); - positions_lines_not_in_complex.push_back(pa.x()+offset.x); - positions_lines_not_in_complex.push_back(pa.y()+offset.y); - positions_lines_not_in_complex.push_back(pa.z()+offset.z); - - positions_lines_not_in_complex.push_back(pb.x()+offset.x); - positions_lines_not_in_complex.push_back(pb.y()+offset.y); - positions_lines_not_in_complex.push_back(pb.z()+offset.z); - - positions_lines_not_in_complex.push_back(pb.x()+offset.x); - positions_lines_not_in_complex.push_back(pb.y()+offset.y); - positions_lines_not_in_complex.push_back(pb.z()+offset.z); - - positions_lines_not_in_complex.push_back(pc.x()+offset.x); - positions_lines_not_in_complex.push_back(pc.y()+offset.y); - positions_lines_not_in_complex.push_back(pc.z()+offset.z); - - positions_lines_not_in_complex.push_back(pc.x()+offset.x); - positions_lines_not_in_complex.push_back(pc.y()+offset.y); - positions_lines_not_in_complex.push_back(pc.z()+offset.z); - - positions_lines_not_in_complex.push_back(pa.x()+offset.x); - positions_lines_not_in_complex.push_back(pa.y()+offset.y); - positions_lines_not_in_complex.push_back(pa.z()+offset.z); - + push_edge(positions_lines_not_in_complex, pa, pb, offset); + push_edge(positions_lines_not_in_complex, pb, pc, offset); + push_edge(positions_lines_not_in_complex, pc, pa, offset); } double Scene_c3t3_item_priv::complex_diag() const { @@ -1434,7 +1395,7 @@ void Scene_c3t3_item_priv::computeSpheres() Tr::Bare_point center(wp2p(vit->point()).x() + offset.x, wp2p(vit->point()).y() + offset.y, wp2p(vit->point()).z() + offset.z); - float radius = vit->point().weight() ; + double radius = vit->point().weight() ; typedef unsigned char UC; spheres->add_sphere(Geom_traits::Sphere_3(center, radius), CGAL::Color(UC(c.red()), UC(c.green()), UC(c.blue()))); @@ -1464,29 +1425,29 @@ void Scene_c3t3_item_priv::computeElements() //The grid { - float x = (2 * (float)complex_diag()) / 10.0; - float y = (2 * (float)complex_diag()) / 10.0; + float x = (2 * (float)complex_diag()) / 10.0f; + float y = (2 * (float)complex_diag()) / 10.0f; for (float u = 0; u < 11; u += 1.f) { positions_grid.push_back(-(float)complex_diag() + x* u); positions_grid.push_back(-(float)complex_diag()); - positions_grid.push_back(0.0); + positions_grid.push_back(0.0f); positions_grid.push_back(-(float)complex_diag() + x* u); positions_grid.push_back((float)complex_diag()); - positions_grid.push_back(0.0); + positions_grid.push_back(0.0f); } for (float v = 0; v<11; v += 1.f) { positions_grid.push_back(-(float)complex_diag()); positions_grid.push_back(-(float)complex_diag() + v * y); - positions_grid.push_back(0.0); + positions_grid.push_back(0.0f); positions_grid.push_back((float)complex_diag()); positions_grid.push_back(-(float)complex_diag() + v * y); - positions_grid.push_back(0.0); + positions_grid.push_back(0.0f); } } @@ -1507,9 +1468,9 @@ void Scene_c3t3_item_priv::computeElements() const Tr::Bare_point& pc = wp2p(cell->vertex((index + 3) & 3)->point()); QColor color = colors[cell->surface_patch_index(index)]; - f_colors.push_back(color.redF());f_colors.push_back(color.greenF());f_colors.push_back(color.blueF()); - f_colors.push_back(color.redF());f_colors.push_back(color.greenF());f_colors.push_back(color.blueF()); - f_colors.push_back(color.redF());f_colors.push_back(color.greenF());f_colors.push_back(color.blueF()); + f_colors.push_back((float)color.redF());f_colors.push_back((float)color.greenF());f_colors.push_back((float)color.blueF()); + f_colors.push_back((float)color.redF());f_colors.push_back((float)color.greenF());f_colors.push_back((float)color.blueF()); + f_colors.push_back((float)color.redF());f_colors.push_back((float)color.greenF());f_colors.push_back((float)color.blueF()); if ((index % 2 == 1) == c3t3.is_in_complex(cell)) draw_triangle(pb, pa, pc); else draw_triangle(pa, pb, pc); @@ -1771,10 +1732,10 @@ QString Scene_c3t3_item::computeStats(int type) if(!d->computed_stats) { - float nb_edges = 0; - float total_edges = 0; - float nb_angle = 0; - float total_angle = 0; + double nb_edges = 0; + double total_edges = 0; + double nb_angle = 0; + double total_angle = 0; for (C3t3::Facet_iterator fit = d->c3t3.facets_begin(), @@ -1786,19 +1747,19 @@ QString Scene_c3t3_item::computeStats(int type) const Tr::Bare_point& pa = wp2p(cell->vertex((index + 1) & 3)->point()); const Tr::Bare_point& pb = wp2p(cell->vertex((index + 2) & 3)->point()); const Tr::Bare_point& pc = wp2p(cell->vertex((index + 3) & 3)->point()); - float edges[3]; + double edges[3]; edges[0]=(std::sqrt(CGAL::squared_distance(pa, pb))); edges[1]=(std::sqrt(CGAL::squared_distance(pa, pc))); edges[2]=(std::sqrt(CGAL::squared_distance(pb, pc))); for(int i=0; i<3; ++i) { - if(edges[i] < d->min_edges_length){ d->min_edges_length = edges[i]; } - if(edges[i] > d->max_edges_length){ d->max_edges_length = edges[i]; } + if(edges[i] < d->min_edges_length){ d->min_edges_length = static_cast(edges[i]); } + if(edges[i] > d->max_edges_length){ d->max_edges_length = static_cast(edges[i]); } total_edges+=edges[i]; ++nb_edges; } } - d->mean_edges_length = total_edges/(float)nb_edges; + d->mean_edges_length = static_cast(total_edges/nb_edges); for(Tr::Finite_vertices_iterator vit = d->c3t3.triangulation().finite_vertices_begin(), end = d->c3t3.triangulation().finite_vertices_end(); @@ -1846,10 +1807,10 @@ QString Scene_c3t3_item::computeStats(int type) const Tr::Bare_point& p1 = wp2p(cit->vertex(1)->point()); const Tr::Bare_point& p2 = wp2p(cit->vertex(2)->point()); const Tr::Bare_point& p3 = wp2p(cit->vertex(3)->point()); - float v = std::abs(CGAL::volume(p0, p1, p2, p3)); - float circumradius = std::sqrt(CGAL::squared_radius(p0, p1, p2, p3)); + double v = std::abs(CGAL::volume(p0, p1, p2, p3)); + double circumradius = std::sqrt(CGAL::squared_radius(p0, p1, p2, p3)); //find smallest edge - float edges[6]; + double edges[6]; edges[0] = std::sqrt(CGAL::squared_distance(p0, p1)); edges[1] = std::sqrt(CGAL::squared_distance(p0, p2)); edges[2] = std::sqrt(CGAL::squared_distance(p0, p3)); @@ -1857,60 +1818,59 @@ QString Scene_c3t3_item::computeStats(int type) edges[4] = std::sqrt(CGAL::squared_distance(p2, p3)); edges[5] = std::sqrt(CGAL::squared_distance(p1, p3)); - float min_edge = edges[0]; + double min_edge = edges[0]; for(int i=1; i<6; ++i) { if(edges[i]smallest_edge_radius) - d->smallest_edge_radius = smallest_edge_radius; + d->smallest_edge_radius = static_cast(smallest_edge_radius); if(smallest_radius_radius < d->smallest_radius_radius) - d->smallest_radius_radius = smallest_radius_radius; + d->smallest_radius_radius = static_cast(smallest_radius_radius); if(biggest_v_sma_cube > d->biggest_v_sma_cube) - d->biggest_v_sma_cube = biggest_v_sma_cube; + d->biggest_v_sma_cube = static_cast(biggest_v_sma_cube); + + auto update_min_max_dihedral_angle = [this](double a) { + if(a < this->d->min_dihedral_angle) { this->d->min_dihedral_angle = static_cast(a); } + if(a > this->d->max_dihedral_angle) { this->d->max_dihedral_angle = static_cast(a); } + }; double a = CGAL::to_double(CGAL::abs(approx_dihedral_angle(p0, p1, p2, p3))); - if(a < d->min_dihedral_angle) { d->min_dihedral_angle = a; } - if(a > d->max_dihedral_angle) { d->max_dihedral_angle = a; } + update_min_max_dihedral_angle(a); total_angle+=a; ++nb_angle; a = CGAL::to_double(CGAL::abs(approx_dihedral_angle(p0, p2, p1, p3))); - if(a < d->min_dihedral_angle) { d->min_dihedral_angle = a; } - if(a > d->max_dihedral_angle) { d->max_dihedral_angle = a; } + update_min_max_dihedral_angle(a); total_angle+=a; ++nb_angle; a = CGAL::to_double(CGAL::abs(approx_dihedral_angle(p0, p3, p1, p2))); - if(a < d->min_dihedral_angle) { d->min_dihedral_angle = a; } - if(a > d->max_dihedral_angle) { d->max_dihedral_angle = a; } + update_min_max_dihedral_angle(a); total_angle+=a; ++nb_angle; a = CGAL::to_double(CGAL::abs(approx_dihedral_angle(p1, p2, p0, p3))); - if(a < d->min_dihedral_angle) { d->min_dihedral_angle = a; } - if(a > d->max_dihedral_angle) { d->max_dihedral_angle = a; } + update_min_max_dihedral_angle(a); total_angle+=a; ++nb_angle; a = CGAL::to_double(CGAL::abs(approx_dihedral_angle(p1, p3, p0, p2))); - if(a < d->min_dihedral_angle) { d->min_dihedral_angle = a; } - if(a > d->max_dihedral_angle) { d->max_dihedral_angle = a; } + update_min_max_dihedral_angle(a); total_angle+=a; ++nb_angle; a = CGAL::to_double(CGAL::abs(approx_dihedral_angle(p2, p3, p0, p1))); - if(a < d->min_dihedral_angle) { d->min_dihedral_angle = a; } - if(a > d->max_dihedral_angle) { d->max_dihedral_angle = a; } + update_min_max_dihedral_angle(a); total_angle+=a; ++nb_angle; } - d->mean_dihedral_angle = total_angle/(float)nb_angle; + d->mean_dihedral_angle = static_cast(total_angle/nb_angle); d->nb_subdomains = sub_ids.size(); d->nb_vertices = d->c3t3.number_of_vertices_in_complex(); d->nb_tets = d->c3t3.number_of_cells(); From 0b0154cac2c7b065f76fa81a3267cfe57b45b931 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Thu, 9 Jan 2020 15:59:41 +0100 Subject: [PATCH 081/141] Bug in the demo --- Mesh_3/include/CGAL/Mesh_3/Mesher_3.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Mesh_3/include/CGAL/Mesh_3/Mesher_3.h b/Mesh_3/include/CGAL/Mesh_3/Mesher_3.h index e58a21ff397..15e213613a1 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Mesher_3.h +++ b/Mesh_3/include/CGAL/Mesh_3/Mesher_3.h @@ -817,7 +817,13 @@ status() const if(boost::is_convertible::value) { const WorksharingDataStructureType* ws_ds = this->get_worksharing_data_structure(); - return Mesher_status(approximate_number_of_vertices(Concurrency_tag()), + return Mesher_status( +# if CGAL_CONCURRENT_COMPACT_CONTAINER_APPROXIMATE_SIZE + approximate_number_of_vertices(Concurrency_tag()), +#else + // not thread-safe, but that is not important + approximate_number_of_vertices(CGAL::Sequential_tag()), +#endif 0, ws_ds->approximate_number_of_enqueued_element()); } From 4fe7be4855579786c89d3bc4e3f81509d7c4da3b Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Fri, 10 Jan 2020 09:33:48 +0100 Subject: [PATCH 082/141] Fix [-Wconversion] warnings --- Polyhedron/demo/Polyhedron/MainWindow.cpp | 4 +- Polyhedron/demo/Polyhedron/Scene.cpp | 6 +- .../Scene_implicit_function_item.cpp | 6 +- Polyhedron/demo/Polyhedron/Viewer.cpp | 58 +++++++++---------- 4 files changed, 37 insertions(+), 37 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/MainWindow.cpp b/Polyhedron/demo/Polyhedron/MainWindow.cpp index 04e48f8668e..1fef4191c6c 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.cpp +++ b/Polyhedron/demo/Polyhedron/MainWindow.cpp @@ -2416,8 +2416,8 @@ void MainWindow::viewerShowObject() CGAL::qglviewer::Vec min((float)bbox.xmin()+viewer->offset().x, (float)bbox.ymin()+viewer->offset().y, (float)bbox.zmin()+viewer->offset().z), max((float)bbox.xmax()+viewer->offset().x, (float)bbox.ymax()+viewer->offset().y, (float)bbox.zmax()+viewer->offset().z); viewer->setSceneBoundingBox(min, max); - viewerShow(min.x, min.y, min.z, - max.x, max.y, max.z); + viewerShow((float)min.x, (float)min.y, (float)min.z, + (float)max.x, (float)max.y, (float)max.z); } } /* to check diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index 05998239946..dbef3cd7402 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -822,9 +822,9 @@ Scene::draw_aux(bool with_names, CGAL::Three::Viewer_interface* viewer) //blending program.bind(); vaos[viewer]->bind(); - viewer->glClearColor(background.redF(), - background.greenF(), - background.blueF(), + viewer->glClearColor((GLclampf)background.redF(), + (GLclampf)background.greenF(), + (GLclampf)background.blueF(), 0.0f); viewer->glDisable(GL_DEPTH_TEST); viewer->glClear(GL_COLOR_BUFFER_BIT); diff --git a/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.cpp b/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.cpp index 4e42ecc3b89..270ce9f839e 100644 --- a/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.cpp @@ -102,9 +102,9 @@ void Scene_implicit_function_item_priv::compute_vertices_and_texmap(void) const CGAL::Three::Scene_item::Bbox& b = item->bbox(); float x,y,z; - z = (b.zmax()+b.zmin())/2.0; - x = (b.xmax()+b.xmin())/2.0; - y = (b.ymax()+b.ymin())/2.0; + z = static_cast(b.zmax()+b.zmin())/2.0f; + x = static_cast(b.xmax()+b.xmin())/2.0f; + y = static_cast(b.ymax()+b.ymin())/2.0f; // The Quad { diff --git a/Polyhedron/demo/Polyhedron/Viewer.cpp b/Polyhedron/demo/Polyhedron/Viewer.cpp index bfb1a2331ad..83cf0afcf48 100644 --- a/Polyhedron/demo/Polyhedron/Viewer.cpp +++ b/Polyhedron/demo/Polyhedron/Viewer.cpp @@ -128,23 +128,23 @@ public: .arg(d->position.y()) .arg(d->position.z())); QPalette palette; - ambient=QColor(255*d->ambient.x(), - 255*d->ambient.y(), - 255*d->ambient.z()); + ambient=QColor::fromRgbF(d->ambient.x(), + d->ambient.y(), + d->ambient.z()); palette.setColor(QPalette::Button,ambient); ambientButton->setPalette(palette); ambientButton->setStyle(QStyleFactory::create("Fusion")); - diffuse=QColor(255*d->diffuse.x(), - 255*d->diffuse.y(), - 255*d->diffuse.z()); + diffuse=QColor::fromRgbF(d->diffuse.x(), + d->diffuse.y(), + d->diffuse.z()); palette.setColor(QPalette::Button,diffuse); diffuseButton->setPalette(palette); diffuseButton->setStyle(QStyleFactory::create("Fusion")); - specular=QColor(255*d->specular.x(), - 255*d->specular.y(), - 255*d->specular.z()); + specular=QColor::fromRgbF(d->specular.x(), + d->specular.y(), + d->specular.z()); palette.setColor(QPalette::Button,specular); specularButton->setPalette(palette); specularButton->setStyle(QStyleFactory::create("Fusion")); @@ -256,15 +256,15 @@ void Viewer::doBindings() 1.0f); QString front_color = viewer_settings.value("front_color", QString("1.0,0.0,0.0")).toString(); - d->front_color= QColor(255*front_color.split(",").at(0).toFloat(), - 255*front_color.split(",").at(1).toFloat(), - 255*front_color.split(",").at(2).toFloat(), - 1.0f); + d->front_color= QColor::fromRgbF(front_color.split(",").at(0).toFloat(), + front_color.split(",").at(1).toFloat(), + front_color.split(",").at(2).toFloat(), + 1.0f); QString back_color = viewer_settings.value("back_color", QString("0.0,0.0,1.0")).toString(); - d->back_color= QColor( 255*back_color.split(",").at(0).toFloat(), - 255*back_color.split(",").at(1).toFloat(), - 255*back_color.split(",").at(2).toFloat(), - 1.0f); + d->back_color= QColor::fromRgbF( back_color.split(",").at(0).toFloat(), + back_color.split(",").at(1).toFloat(), + back_color.split(",").at(2).toFloat(), + 1.0f); d->spec_power = viewer_settings.value("spec_power", 51.8).toFloat(); d->scene = 0; d->projection_is_ortho = false; @@ -1770,7 +1770,7 @@ void Viewer::setLighting() msgBox->exec(); return; } - double coords[3]; + float coords[3]; for(int j=0; j<3; ++j) { bool ok; @@ -1792,9 +1792,9 @@ void Viewer::setLighting() //set ambient connect(dialog, &LightingDialog::s_ambient_changed, [this, dialog](){ - d->ambient=QVector4D(dialog->ambient.redF(), - dialog->ambient.greenF(), - dialog->ambient.blueF(), + d->ambient=QVector4D((float)dialog->ambient.redF(), + (float)dialog->ambient.greenF(), + (float)dialog->ambient.blueF(), 1.0f); update(); }); @@ -1802,18 +1802,18 @@ void Viewer::setLighting() //set diffuse connect(dialog, &LightingDialog::s_diffuse_changed, [this, dialog](){ - d->diffuse=QVector4D(dialog->diffuse.redF(), - dialog->diffuse.greenF(), - dialog->diffuse.blueF(), + d->diffuse=QVector4D((float)dialog->diffuse.redF(), + (float)dialog->diffuse.greenF(), + (float)dialog->diffuse.blueF(), 1.0f); update(); }); //set specular connect(dialog, &LightingDialog::s_specular_changed, [this, dialog](){ - d->specular=QVector4D(dialog->specular.redF() , - dialog->specular.greenF(), - dialog->specular.blueF() , + d->specular=QVector4D((float)dialog->specular.redF(), + (float)dialog->specular.greenF(), + (float)dialog->specular.blueF(), 1.0f); update(); @@ -1823,8 +1823,8 @@ void Viewer::setLighting() connect(dialog->buttonBox->button(QDialogButtonBox::StandardButton::RestoreDefaults), &QPushButton::clicked, [this](){ d->position = QVector4D(0,0,1,1); - d->ambient=QVector4D(77.0/255,77.0/255,77.0/255, 1.0); - d->diffuse=QVector4D(204.0/255,204.0/255,204.0/255,1.0); + d->ambient=QVector4D(77.0f/255,77.0f/255,77.0f/255, 1.0); + d->diffuse=QVector4D(204.0f/255,204.0f/255,204.0f/255,1.0); d->specular=QVector4D(0,0,0,1.0); d->spec_power = 51; update(); From c368b349d516e5e4649febd931658f0350344c66 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 15 Jan 2020 15:26:02 +0100 Subject: [PATCH 083/141] clean-up --- .../include/CGAL/Intersection_traits_3.h | 4 - .../Iso_cuboid_3_Plane_3_intersection.h | 81 +++++++++---------- .../Intersections_3/test_intersections_3.cpp | 3 +- 3 files changed, 41 insertions(+), 47 deletions(-) diff --git a/Intersections_3/include/CGAL/Intersection_traits_3.h b/Intersections_3/include/CGAL/Intersection_traits_3.h index dbc539598ba..6a626f21e23 100644 --- a/Intersections_3/include/CGAL/Intersection_traits_3.h +++ b/Intersections_3/include/CGAL/Intersection_traits_3.h @@ -169,9 +169,6 @@ template struct Intersection_traits : public Intersection_traits {}; - - - // Iso_cuboid_3 Point_3, variant of one template struct Intersection_traits { @@ -396,7 +393,6 @@ struct Intersection_traits typedef typename boost::optional< variant_type > result_type; }; - //Triangle_3 Tetrahedron_3, variant of 4 template struct Intersection_traits diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h index d4d11fd50cd..ff2411c8058 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h @@ -139,19 +139,18 @@ intersection( CGAL_assertion(p1_found && p2_found); res[0] = entry_seg.target(); - - if((entry_seg.target() - p1) - * (p2 - p1) > 0) - { - res[1] = p2; - res[2] = p1; - } - else - { - res[1] = p1; - res[2] = p2; - } + res[1] = p2; + res[2] = p1; res[3] = entry_seg.source(); + + typename K::Coplanar_orientation_3 coplanar_orientation = + k.coplanar_orientation_3_object(); + + if( coplanar_orientation(res[0], res[1], res[2]) + != coplanar_orientation(res[0], res[1], res[3])) + { + std::swap(res[1], res[2]); + } return result_type(std::forward(res)); } @@ -164,41 +163,39 @@ intersection( Segment_3 front(segments.front()), back(segments.back()); res[0] = front.target(); - if((front.target() - front.source()) - * (back.target() - back.source()) > 0) - { - res[1] = back.target(); - res[2] = back.source(); - } - else - { - res[1] = back.source(); - res[2] = back.target(); - } + res[1] = back.target(); + res[2] = back.source(); res[3] = front.source(); + typename K::Coplanar_orientation_3 coplanar_orientation = + k.coplanar_orientation_3_object(); + + if( coplanar_orientation(res[0], res[1], res[2]) + != coplanar_orientation(res[0], res[1], res[3])) + { + std::swap(res[1], res[2]); + } return result_type(std::forward(res)); } - break; - case 4: // intersects a face - { - Poly res; - res.reserve(4); - std::list tmp; - std::list seg_list; - for(const Segment_3& s : segments) - seg_list.push_back(s); - fill_points_list(seg_list, tmp); - for(const Point_3& p : tmp) - res.push_back(p); - - return result_type(std::forward(res)); - } - break; - default: - break; + break; + case 4: // intersects a face + { + Poly res; + res.reserve(4); + std::list tmp; + std::list seg_list; + for(auto s : segments) + seg_list.push_back(s); + fill_points_list(seg_list, tmp); + for(auto p : tmp) + res.push_back(p); + return result_type(std::forward(res)); } - + break; + default: + break; + } + Poly filtered_points; filter_points(points, filtered_points); diff --git a/Intersections_3/test/Intersections_3/test_intersections_3.cpp b/Intersections_3/test/Intersections_3/test_intersections_3.cpp index 21b6807b0b4..83dbc610f9c 100644 --- a/Intersections_3/test/Intersections_3/test_intersections_3.cpp +++ b/Intersections_3/test/Intersections_3/test_intersections_3.cpp @@ -1251,7 +1251,7 @@ int main() { std::cout << " |||||||| Test Simple_cartesian ||||||||" << std::endl; Test< CGAL::Simple_cartesian >().run(); - +/* std::cout << " |||||||| Test CGAL::Homogeneous ||||||||" << std::endl; Test< CGAL::Homogeneous >().run(); @@ -1260,4 +1260,5 @@ int main() std::cout << " |||||||| Test CGAL::Homogeneous ||||||||" << std::endl; Test< CGAL::Homogeneous >().run(true); + */ } From 0f3305f98314f58e0e30965ebb54174bd0466a16 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 16 Jan 2020 17:20:13 +0100 Subject: [PATCH 084/141] Enhancements after review --- .../CGAL/Intersections_2/Bbox_2_Segment_2.h | 2 +- .../CGAL/Intersections_2/Bbox_2_Triangle_2.h | 2 +- .../CGAL/Intersections_3/Bbox_3_Bbox_3.h | 6 +- .../CGAL/Intersections_3/Line_3_Point_3.h | 8 +-- .../CGAL/Intersections_3/Plane_3_Point_3.h | 8 +-- .../CGAL/Intersections_3/Point_3_Ray_3.h | 8 +-- .../CGAL/Intersections_3/Point_3_Segment_3.h | 8 +-- .../Iso_cuboid_3_Plane_3_intersection.h | 71 ++++++++++++++++--- .../Tetrahedron_3_Line_3_intersection.h | 8 +-- .../Tetrahedron_3_Plane_3_intersection.h | 20 +++--- .../Tetrahedron_3_Triangle_3_intersection.h | 53 +++++++------- .../Triangle_3_Triangle_3_intersection.h | 2 +- .../internal/intersection_3_1_impl.h | 6 +- .../tetrahedron_intersection_helpers.h | 2 +- .../tetrahedron_lines_intersections_3.h | 4 +- .../Intersections_3/test_intersections_3.cpp | 10 ++- 16 files changed, 136 insertions(+), 82 deletions(-) diff --git a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Segment_2.h b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Segment_2.h index 67b4aa7cc0c..511691b0ac2 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Segment_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Segment_2.h @@ -42,7 +42,7 @@ inline bool do_intersect( template inline bool do_intersect( const Bbox_2 &box, -const Segment_2 &seg) + const Segment_2 &seg) { return do_intersect(seg, box); } diff --git a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Triangle_2.h b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Triangle_2.h index 6a712e160b6..dc345b986d7 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Triangle_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Triangle_2.h @@ -42,7 +42,7 @@ inline bool do_intersect( template inline bool do_intersect( const Bbox_2 &box, -const Triangle_2 &tr) + const Triangle_2 &tr) { return do_intersect(tr, box); } diff --git a/Intersections_3/include/CGAL/Intersections_3/Bbox_3_Bbox_3.h b/Intersections_3/include/CGAL/Intersections_3/Bbox_3_Bbox_3.h index d2f4eab8172..b0220d8ad8f 100644 --- a/Intersections_3/include/CGAL/Intersections_3/Bbox_3_Bbox_3.h +++ b/Intersections_3/include/CGAL/Intersections_3/Bbox_3_Bbox_3.h @@ -33,10 +33,10 @@ intersection(const CGAL::Bbox_3& a, const CGAL::Bbox_3& b) { typedef typename boost::variant variant_type; - typedef typename boost::optional Result_type; + typedef typename boost::optional result_type; if(!do_intersect(a,b)) - return Result_type(); + return result_type(); double xmin = (std::max)(a.xmin(), b.xmin()); double xmax = (std::min)(a.xmax(), b.xmax()); @@ -45,7 +45,7 @@ intersection(const CGAL::Bbox_3& a, double zmin = (std::max)(a.zmin(), b.zmin()); double zmax = (std::min)(a.zmax(), b.zmax()); - return Result_type(std::forward(Bbox_3(xmin, ymin, zmin, xmax, ymax, zmax))); + return result_type(std::forward(Bbox_3(xmin, ymin, zmin, xmax, ymax, zmax))); } } //namespace CGAL diff --git a/Intersections_3/include/CGAL/Intersections_3/Line_3_Point_3.h b/Intersections_3/include/CGAL/Intersections_3/Line_3_Point_3.h index 6f0df12e9ef..abbfd75146f 100644 --- a/Intersections_3/include/CGAL/Intersections_3/Line_3_Point_3.h +++ b/Intersections_3/include/CGAL/Intersections_3/Line_3_Point_3.h @@ -27,18 +27,18 @@ template inline bool do_intersect(const typename K::Point_3 &pt, const typename K::Line_3 &line, - const K&) + const K& k) { - return line.has_on(pt); + return k.has_on_3_object()(line,pt); } template inline bool do_intersect(const typename K::Line_3 &line, const typename K::Point_3 &pt, - const K&) + const K& k) { - return line.has_on(pt); + return k.has_on_3_object()(line, pt); } template diff --git a/Intersections_3/include/CGAL/Intersections_3/Plane_3_Point_3.h b/Intersections_3/include/CGAL/Intersections_3/Plane_3_Point_3.h index 5ad93c3e9c4..3f862cba645 100644 --- a/Intersections_3/include/CGAL/Intersections_3/Plane_3_Point_3.h +++ b/Intersections_3/include/CGAL/Intersections_3/Plane_3_Point_3.h @@ -27,18 +27,18 @@ template inline bool do_intersect(const typename K::Point_3 &pt, const typename K::Plane_3 &plane, - const K&) + const K& k) { - return plane.has_on(pt); + return k.has_on_3_object()(plane,pt); } template inline bool do_intersect(const typename K::Plane_3 &plane, const typename K::Point_3 &pt, - const K&) + const K& k) { - return plane.has_on(pt); + return k.has_on_3_object()(plane,pt); } template diff --git a/Intersections_3/include/CGAL/Intersections_3/Point_3_Ray_3.h b/Intersections_3/include/CGAL/Intersections_3/Point_3_Ray_3.h index a7162964189..7d41e283a89 100644 --- a/Intersections_3/include/CGAL/Intersections_3/Point_3_Ray_3.h +++ b/Intersections_3/include/CGAL/Intersections_3/Point_3_Ray_3.h @@ -28,9 +28,9 @@ inline bool do_intersect(const typename K::Point_3 &pt, const typename K::Ray_3 &ray, - const K&) + const K& k) { - return ray.has_on(pt); + return k.has_on_3_object()(ray,pt); } @@ -39,9 +39,9 @@ inline bool do_intersect(const typename K::Ray_3 &ray, const typename K::Point_3 &pt, - const K&) + const K& k) { - return ray.has_on(pt); + return k.has_on_3_object()(ray,pt); } diff --git a/Intersections_3/include/CGAL/Intersections_3/Point_3_Segment_3.h b/Intersections_3/include/CGAL/Intersections_3/Point_3_Segment_3.h index 74fb8ac0d26..b1860dbbb95 100644 --- a/Intersections_3/include/CGAL/Intersections_3/Point_3_Segment_3.h +++ b/Intersections_3/include/CGAL/Intersections_3/Point_3_Segment_3.h @@ -28,9 +28,9 @@ inline bool do_intersect(const typename K::Point_3 &pt, const typename K::Segment_3 &seg, - const K&) + const K& k) { - return seg.has_on(pt); + return k.has_on_3_object()(seg, pt); } template @@ -38,9 +38,9 @@ inline bool do_intersect(const typename K::Segment_3 &seg, const typename K::Point_3 &pt, - const K&) + const K& k) { - return seg.has_on(pt); + return k.has_on_3_object()(seg, pt); } diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h index ff2411c8058..831d162553d 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h @@ -182,13 +182,62 @@ intersection( { Poly res; res.reserve(4); - std::list tmp; - std::list seg_list; - for(auto s : segments) - seg_list.push_back(s); - fill_points_list(seg_list, tmp); - for(auto p : tmp) - res.push_back(p); + typename K::Has_on_3 has_on; + if(has_on(pl, cub.vertex(0)) + && has_on(pl, cub.vertex(5)) + && has_on(pl, cub.vertex(4))) + { + res.push_back(cub.vertex(0)); + res.push_back(cub.vertex(5)); + res.push_back(cub.vertex(4)); + res.push_back(cub.vertex(3)); + } + else if(has_on(pl, cub.vertex(0)) + && has_on(pl, cub.vertex(1)) + && has_on(pl, cub.vertex(6))) + { + res.push_back(cub.vertex(0)); + res.push_back(cub.vertex(1)); + res.push_back(cub.vertex(6)); + res.push_back(cub.vertex(5)); + + } + else if(has_on(pl, cub.vertex(1)) + && has_on(pl, cub.vertex(2)) + && has_on(pl, cub.vertex(7))) + { + res.push_back(cub.vertex(1)); + res.push_back(cub.vertex(2)); + res.push_back(cub.vertex(7)); + res.push_back(cub.vertex(6)); + } + else if(has_on(pl, cub.vertex(2)) + && has_on(pl, cub.vertex(3)) + && has_on(pl, cub.vertex(4))) + { + res.push_back(cub.vertex(2)); + res.push_back(cub.vertex(3)); + res.push_back(cub.vertex(4)); + res.push_back(cub.vertex(7)); + } + else if(has_on(pl, cub.vertex(6)) + && has_on(pl, cub.vertex(7)) + && has_on(pl, cub.vertex(4))) + { + res.push_back(cub.vertex(6)); + res.push_back(cub.vertex(7)); + res.push_back(cub.vertex(4)); + res.push_back(cub.vertex(5)); + } + else if(has_on(pl, cub.vertex(2)) + && has_on(pl, cub.vertex(1)) + && has_on(pl, cub.vertex(0))) + { + res.push_back(cub.vertex(2)); + res.push_back(cub.vertex(1)); + res.push_back(cub.vertex(0)); + res.push_back(cub.vertex(3)); + } return result_type(std::forward(res)); } break; @@ -249,11 +298,11 @@ intersection( } std::list tmp_segs; - for(auto line : plane_intersections) + for(const auto& line : plane_intersections) { bool first_found = false; Point_3 first_p; - for(auto p : filtered_points) + for(const auto &p : filtered_points) { if(line.has_on(p)) { @@ -264,7 +313,7 @@ intersection( } else { - tmp_segs.push_back(Segment_3(first_p, p)); + tmp_segs.emplace_back(first_p, p); break; } } @@ -275,7 +324,7 @@ intersection( std::list tmp_pts; fill_points_list(tmp_segs,tmp_pts); Poly res; - for(auto p : tmp_pts) + for(const auto& p : tmp_pts) res.push_back(p); if(res.size() == 3){ typename K::Triangle_3 tr(res[0], res[1], res[2]); diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Line_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Line_3_intersection.h index f9a8e8f7895..835df62193e 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Line_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Line_3_intersection.h @@ -38,23 +38,23 @@ struct Tetrahedron_Line_intersection_3 :public Tetrahedron_lines_intersection_3_base > { typedef Tetrahedron_lines_intersection_3_base > Base; + Tetrahedron_Line_intersection_3 > Base; typedef typename Base::Result_type Result_type; Tetrahedron_Line_intersection_3( const typename K::Tetrahedron_3& tet, const typename K::Line_3& o):Base(tet,o) {} - + bool all_inside_test() { return false; } - + bool are_extremities_inside_test() { return false; } - + }; //Tetrahedron_3 Line_3 diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersection.h index 9206ddcd4e5..6b3ff24e209 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersection.h @@ -46,7 +46,7 @@ intersection( { typedef typename Intersection_traits::result_type Result_type; + typename K::Plane_3>::result_type result_type; typedef typename Intersection_traits(&*intersections[i])) { typename K::Triangle_3 res = *tr; - return Result_type(std::forward(res)); + return result_type(std::forward(res)); } else if( const Segment_3* s = boost::get(&*intersections[i])) @@ -91,25 +91,25 @@ intersection( case 0: { if(p_id == -1) - return Result_type(); + return result_type(); else { typename K::Point_3 p = *boost::get(&*intersections[p_id]); - return Result_type(std::forward(p)); + return result_type(std::forward(p)); } } break; case 2: { - return Result_type(std::forward(segments.back())); + return result_type(std::forward(segments.back())); } break; default: { std::set all_points; - for (auto s : segments) + for (const auto& s : segments) { all_points.insert(s.source()); all_points.insert(s.target()); @@ -121,7 +121,7 @@ intersection( typename K::Point_3 mid_point = *p_it; ++p_it; typename K::Triangle_3 result(*all_points.begin(), mid_point, *p_it ); - return Result_type(std::forward(result)); + return result_type(std::forward(result)); } else //size = 4 { @@ -129,14 +129,14 @@ intersection( std::list tmp; fill_points_list(segs, tmp); std::vector res; - for( auto p : tmp) + for( const auto& p : tmp) res.push_back(p); - return Result_type(std::forward >(res)); + return result_type(std::forward >(res)); } } break; } - return Result_type(); + return result_type(); } template diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Triangle_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Triangle_3_intersection.h index 9e41b0a9841..9ad385a2cd0 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Triangle_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Triangle_3_intersection.h @@ -41,11 +41,11 @@ typename Intersection_traits::result_type Result_type; + typename K::Triangle_3>::result_type result_type; typedef typename Intersection_traits(&*intersections[i])) { Triangle_3 res = *t; - return Result_type(std::forward(res)); + return result_type(std::forward(res)); } //get segs and pts to construct poly else if( const Segment_3* s @@ -102,7 +102,7 @@ intersection( = boost::get(&*intersections[i])) { Poly res = *p; - return Result_type(std::forward(res)); + return result_type(std::forward(res)); } } } @@ -119,21 +119,21 @@ intersection( fill_segments_infos(segments,tmp, tr); Poly res; res.reserve(4); - for( auto p : tmp){ + for( const auto& p : tmp){ res.push_back(p); } - return Result_type(std::forward(res)); + return result_type(std::forward(res)); } //else it must be adjacent to an vertex, so we return the point else if(segments.size() == 1) { //adjacency to an edge, return resulting segment. - return Result_type(std::forward(segments.front())); + return result_type(std::forward(segments.front())); } else { //no segment = adjacency to an vertex or an edge : return result point - return Result_type(std::forward(points.front())); + return result_type(std::forward(points.front())); } } @@ -155,7 +155,7 @@ intersection( if(const Triangle_3* t = boost::get(&*intersections[i])) { Triangle_3 res = *t; - return Result_type(std::forward(res)); + return result_type(std::forward(res)); } //get segs and pts to construct poly else if( const Segment_3* s @@ -173,14 +173,14 @@ intersection( = boost::get(&*intersections[i])) { Poly res = *p; - return Result_type(std::forward(res)); + return result_type(std::forward(res)); } } } if(segments.empty()) { //then there is only one point of contact. Return it: - return Result_type(std::forward(points.front())); + return result_type(std::forward(points.front())); } if(segments.size() > 1) @@ -197,7 +197,7 @@ intersection( bool return_solo_seg = true; //only one intersection, a triangle edge is one of the tet edges, and //the 3rd point is outside. This is the only intersection. - for(auto p : inside_points) + for(const auto& p : inside_points) { if(!tet.has_on_boundary(p)) { @@ -207,14 +207,14 @@ intersection( } if(return_solo_seg) { - return Result_type(std::forward(segments.front())); + return result_type(std::forward(segments.front())); } if(inside_points.size() == 1) { Triangle_3 res(inside_points.front(), segments.front().source(), segments.front().target()); - return Result_type(std::forward(res)); + return result_type(std::forward(res)); } else //size 2 { @@ -232,15 +232,14 @@ intersection( res[3] = segments.front().target(); res[2] = segments.front().source(); } - return Result_type(std::forward(res)); + return result_type(std::forward(res)); } } break; case 2: case 3: { - std::list segs; - for(auto s : segments){segs.push_back(s);} + std::list segs(segments.begin(), segments.end()); std::list tmp; fill_points_list(segs, tmp); if(inside_points.size() == 1) @@ -248,21 +247,26 @@ intersection( Poly res; res.reserve(4); res.push_back(inside_points.front()); - for( auto p : tmp){res.push_back(p);} - return Result_type(std::forward(res)); + for( const auto& p : tmp){res.push_back(p);} + return result_type(std::forward(res)); } else //size 2 { Poly res; res.reserve(5); - if((inside_points.front() - inside_points.back()) * - (tmp.front() - tmp.back()) > 0) + typename K::Compute_scalar_product_3 scalar = + k.compute_scalar_product_3_object(); + typename K::Construct_vector_3 construct_vector = + k.construct_vector_3_object(); + + if(scalar(construct_vector(inside_points.front(), inside_points.back()), + construct_vector(tmp.front(), tmp.back())) > 0) { res.push_back(inside_points.front()); } res.push_back(inside_points.back()); - for( auto p : tmp){res.push_back(p);} - return Result_type(std::forward(res)); + for( const auto& p : tmp){res.push_back(p);} + return result_type(std::forward(res)); } } break; @@ -276,8 +280,7 @@ intersection( case 3: { //triangle entirely inside tetra : return input triangle - typename K::Triangle_3 res = tr; - return Result_type(std::forward(res)); + return result_type(tr); } break; default: diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Triangle_3_Triangle_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Triangle_3_Triangle_3_intersection.h index 424bb84c69f..58751dfb6e7 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Triangle_3_Triangle_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Triangle_3_Triangle_3_intersection.h @@ -128,7 +128,7 @@ struct Triangle_Line_visitor { result_type operator()(const typename K::Point_3& p, const typename K::Segment_3& s) const { - if ( s.has_on(p) ) + if ( typename K::Has_on_3()(s,p) ) return intersection_return(p); else return result_type(); diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/intersection_3_1_impl.h b/Intersections_3/include/CGAL/Intersections_3/internal/intersection_3_1_impl.h index 96e00b8782f..4a3a52a2d93 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/intersection_3_1_impl.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/intersection_3_1_impl.h @@ -1249,15 +1249,11 @@ inline typename Intersection_traits::result_type intersection(const Bbox_3 &a, const Bbox_3 &b, - const K& k) + const K&) { return CGAL::intersection(a, b); } - - - - template typename Intersection_traits::result_type intersection(const CGAL::Bbox_3 &box, diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h index 39a387ddca4..97c63a26724 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h @@ -75,7 +75,7 @@ void fill_segments_infos(std::vector& segments, std::vector wrapped_segments; - for(auto s:segments) + for(const auto& s:segments) wrapped_segments.push_back(Wrapped_segment(s)); std::vector bis = segments; diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h index f7eb10e0338..d71154e04c6 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h @@ -138,8 +138,8 @@ struct Tetrahedron_lines_intersection_3_base for(std::size_t i = 0; i< res_points.size(); ++i) { - auto p1 = res_points[i]; - for(auto p2 : res_points) + const auto& p1 = res_points[i]; + for(const auto& p2 : res_points) { sq_distances[i].push_back(CGAL::squared_distance(p1, p2)); if(sq_distances[i].back() > max_dist) diff --git a/Intersections_3/test/Intersections_3/test_intersections_3.cpp b/Intersections_3/test/Intersections_3/test_intersections_3.cpp index 83dbc610f9c..02dd5145459 100644 --- a/Intersections_3/test/Intersections_3/test_intersections_3.cpp +++ b/Intersections_3/test/Intersections_3/test_intersections_3.cpp @@ -574,9 +574,16 @@ struct Test { if(is_exact) { check_no_intersection (tet, L(P(5,0,0), P(5,1,0))); + //on edge check_intersection (tet, L(P(0,2,0), P(0,3,0)), S(P(0,0,0), P(0,1,0))); + //through vertex and out from face check_intersection (tet, L(P(0,1,0), P(0.25,0,0.25)), S(P(0,1,0), P(0.25,0,0.25))); + //through a vertex only check_intersection (tet, L(P(1,1,0), P(-1,1,0)), P(0,1,0)); + //through 2 faces + check_intersection (tet, L(P(0.25,0.25,0), P(0.25,0,0.25)), S(P(0.25,0,0.25), P(0.25,0.25,0))); + //through one edge + check_intersection (tet, L(P(0.5,-0.5,0.5), P(0.5,0.5,0.5)), P(0.5,0,0.5)); } } @@ -1251,7 +1258,7 @@ int main() { std::cout << " |||||||| Test Simple_cartesian ||||||||" << std::endl; Test< CGAL::Simple_cartesian >().run(); -/* + std::cout << " |||||||| Test CGAL::Homogeneous ||||||||" << std::endl; Test< CGAL::Homogeneous >().run(); @@ -1260,5 +1267,4 @@ int main() std::cout << " |||||||| Test CGAL::Homogeneous ||||||||" << std::endl; Test< CGAL::Homogeneous >().run(true); - */ } From bf8205642e56c1db24a9e783e6f58928d86e440e Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Mon, 20 Jan 2020 18:16:47 +0100 Subject: [PATCH 085/141] Fix conversion warnings --- GraphicsView/include/CGAL/Buffer_for_vao.h | 12 ++++++------ GraphicsView/include/CGAL/Qt/manipulatedFrame_impl.h | 2 +- GraphicsView/include/CGAL/Qt/qglviewer_impl.h | 4 ++-- Polyhedron/demo/Polyhedron/Color_map.h | 2 +- .../Plugins/Mesh_3/C3t3_rib_exporter_plugin.cpp | 6 +++--- .../Plugins/PCA/Basic_generator_plugin.cpp | 7 ++++--- 6 files changed, 17 insertions(+), 16 deletions(-) diff --git a/GraphicsView/include/CGAL/Buffer_for_vao.h b/GraphicsView/include/CGAL/Buffer_for_vao.h index c70d4a920a2..366ab655767 100644 --- a/GraphicsView/include/CGAL/Buffer_for_vao.h +++ b/GraphicsView/include/CGAL/Buffer_for_vao.h @@ -460,9 +460,9 @@ public: static void add_point_in_buffer(const KPoint& kp, std::vector& buffer) { Local_point p=get_local_point(kp); - buffer.push_back(p.x()); - buffer.push_back(p.y()); - buffer.push_back(p.z()); + buffer.push_back(static_cast(p.x())); + buffer.push_back(static_cast(p.y())); + buffer.push_back(static_cast(p.z())); } /// adds `kv` coordinates to `buffer` @@ -471,9 +471,9 @@ public: bool inverse_normal=false) { Local_vector n=(inverse_normal?-get_local_vector(kv):get_local_vector(kv)); - buffer.push_back(n.x()); - buffer.push_back(n.y()); - buffer.push_back(n.z()); + buffer.push_back(static_cast(n.x())); + buffer.push_back(static_cast(n.y())); + buffer.push_back(static_cast(n.z())); } ///adds `acolor` RGB components to `buffer` diff --git a/GraphicsView/include/CGAL/Qt/manipulatedFrame_impl.h b/GraphicsView/include/CGAL/Qt/manipulatedFrame_impl.h index 617f1df0f7d..96d03db9adc 100644 --- a/GraphicsView/include/CGAL/Qt/manipulatedFrame_impl.h +++ b/GraphicsView/include/CGAL/Qt/manipulatedFrame_impl.h @@ -251,7 +251,7 @@ CGAL_INLINE_FUNCTION void ManipulatedFrame::computeMouseSpeed(const QMouseEvent *const e) { const QPoint delta = (e->pos() - prevPos_); const qreal dist = sqrt(qreal(delta.x() * delta.x() + delta.y() * delta.y())); - delay_ = last_move_time.restart(); + delay_ = static_cast(last_move_time.restart()); if (delay_ == 0) // Less than a millisecond: assume delay = 1ms mouseSpeed_ = dist; diff --git a/GraphicsView/include/CGAL/Qt/qglviewer_impl.h b/GraphicsView/include/CGAL/Qt/qglviewer_impl.h index 8b2cad8f9a1..0dc7256cb38 100644 --- a/GraphicsView/include/CGAL/Qt/qglviewer_impl.h +++ b/GraphicsView/include/CGAL/Qt/qglviewer_impl.h @@ -2248,7 +2248,7 @@ void CGAL::QGLViewer::keyPressEvent(QKeyEvent *e) { static QElapsedTimer doublePress; if (modifiers == playPathKeyboardModifiers()) { - int elapsed = doublePress.restart(); + qint64 elapsed = doublePress.restart(); if ((elapsed < 250) && (index == previousPathId_)) camera()->resetPath(index); else { @@ -2263,7 +2263,7 @@ void CGAL::QGLViewer::keyPressEvent(QKeyEvent *e) { } previousPathId_ = index; } else if (modifiers == addKeyFrameKeyboardModifiers()) { - int elapsed = doublePress.restart(); + qint64 elapsed = doublePress.restart(); if ((elapsed < 250) && (index == previousPathId_)) { if (camera()->keyFrameInterpolator(index)) { disconnect(camera()->keyFrameInterpolator(index), diff --git a/Polyhedron/demo/Polyhedron/Color_map.h b/Polyhedron/demo/Polyhedron/Color_map.h index 46164c649cb..2e04a3ee5bd 100644 --- a/Polyhedron/demo/Polyhedron/Color_map.h +++ b/Polyhedron/demo/Polyhedron/Color_map.h @@ -8,7 +8,7 @@ inline QColor generate_color(double h, double s_min = 0.35) std::size_t s_max=255; if(h >0.8 && h < 0.95) //span of ugly pink, desaturates make it less garish IMO s_max = 160; - std::size_t s = std::rand() % (s_max-static_cast(s_min*255)) +s_min*255; + std::size_t s = std::rand() % (s_max-static_cast(s_min*255)) + static_cast(s_min*255); return QColor::fromHsvF(h,s/255.0,1.0); } diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/C3t3_rib_exporter_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/C3t3_rib_exporter_plugin.cpp index 89b8a92ecc3..edf8e6b13f7 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/C3t3_rib_exporter_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/C3t3_rib_exporter_plugin.cpp @@ -755,8 +755,8 @@ write_surface_cells(const C3t3& c3t3, const Plane& /* plane */, std::ofstream& o //const int TRANSPARENCY_ALPHA_VALUE = 100; CGAL::Bbox_3 bbox = c3t3.bbox(); - float relPos = (c->weighted_circumcenter().x() - bbox.xmin()) - / (bbox.xmax() - bbox.xmin()); + float relPos = static_cast((c->weighted_circumcenter().x() - bbox.xmin()) + / (bbox.xmax() - bbox.xmin())); float TRANSPARENCY_ALPHA_VALUE = 1.f - (relPos < 0.25f ? @@ -842,7 +842,7 @@ write_surface_cells(const C3t3& c3t3, const Plane& /* plane */, std::ofstream& o { if (i == last_2D_vertex_index) { - edgecolor.setAlpha(TRANSPARENCY_ALPHA_VALUE); + edgecolor.setAlphaF(TRANSPARENCY_ALPHA_VALUE); } else { diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Basic_generator_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PCA/Basic_generator_plugin.cpp index 269eb121ae4..abc04bc2849 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Basic_generator_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Basic_generator_plugin.cpp @@ -777,7 +777,8 @@ void Basic_generator_plugin::generateGrid() QString points_text; Point extrema[2]; - typename boost::graph_traits::vertices_size_type nb_cells[2]; + using size_type = typename boost::graph_traits::vertices_size_type; + size_type nb_cells[2]; bool triangulated = dock_widget->grid_checkBox->isChecked(); points_text= dock_widget->grid_lineEdit->text(); @@ -806,8 +807,8 @@ void Basic_generator_plugin::generateGrid() } extrema[0] = Point(coords[0], coords[1], coords[2]); extrema[1] = Point(coords[3], coords[4], coords[5]); - nb_cells[0] = static_cast(dock_widget->gridX_spinBox->value()); - nb_cells[1] = static_cast(dock_widget->gridY_spinBox->value()); + nb_cells[0] = static_cast(dock_widget->gridX_spinBox->value()); + nb_cells[1] = static_cast(dock_widget->gridY_spinBox->value()); //nb_points = nb_cells+1 Point_generator point_gen(nb_cells[0]+1, nb_cells[1]+1, extrema[0], extrema[1]); From a4991fd6daf32ccb55e6f6f710951921c659e056 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Mon, 20 Jan 2020 18:17:14 +0100 Subject: [PATCH 086/141] More dump of the c3t3 in case of crash --- Mesh_3/include/CGAL/Mesh_3/Refine_facets_3.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Mesh_3/include/CGAL/Mesh_3/Refine_facets_3.h b/Mesh_3/include/CGAL/Mesh_3/Refine_facets_3.h index bba248c5538..b7b90c2e4ed 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Refine_facets_3.h +++ b/Mesh_3/include/CGAL/Mesh_3/Refine_facets_3.h @@ -38,6 +38,7 @@ #ifdef CGAL_MESH_3_PROFILING #include #endif +#include #include #include @@ -847,8 +848,12 @@ public: if( zone.locate_type == Tr::VERTEX ) { std::stringstream sstr; + sstr.precision(17); sstr << "(" << p << ") is already inserted on surface.\n"; - CGAL_error_msg(sstr.str().c_str()); + CGAL_error_msg(([this,str=sstr.str()] { + dump_c3t3(this->r_c3t3_, "dump-bug"); + return str.c_str(); + }())); return CONFLICT_AND_ELEMENT_SHOULD_BE_DROPPED; } else From 4532ae48b70926795707332c8133d6534d481aa4 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Mon, 20 Jan 2020 18:18:27 +0100 Subject: [PATCH 087/141] Improve the code that deals with CGAL_MESH_3_DEBUG_FACET_CRITERIA --- ...cet_topological_criterion_with_adjacency.h | 33 +++++++++++++++++-- .../Mesh_3/mesh_standard_facet_criteria.h | 8 +++++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/Mesh_3/include/CGAL/Mesh_3/experimental/Facet_topological_criterion_with_adjacency.h b/Mesh_3/include/CGAL/Mesh_3/experimental/Facet_topological_criterion_with_adjacency.h index 690c8afe091..d80d3986685 100644 --- a/Mesh_3/include/CGAL/Mesh_3/experimental/Facet_topological_criterion_with_adjacency.h +++ b/Mesh_3/include/CGAL/Mesh_3/experimental/Facet_topological_criterion_with_adjacency.h @@ -87,8 +87,16 @@ protected: Index_set set; domain->get_corner_incidences(corner_id, std::back_inserter(set)); - if(std::find(set.begin(), set.end(), patch_index) == set.end()) + if(std::find(set.begin(), set.end(), patch_index) == set.end()) { +#ifdef CGAL_MESH_3_DEBUG_FACET_CRITERIA + std::cerr << "Bad facet " + "(Facet_topological_criterion_with_adjacency: corner #" + << corner_id << ", point " << v->point() + << ", is not incident to patch #" << patch_index << ")" + << std::endl; +#endif return Is_bad(Quality(1)); // bad! + } } break; case 1: @@ -98,13 +106,28 @@ protected: domain->curve_index(v->index()); Index_set set; domain->get_incidences(curve_id, std::back_inserter(set)); - if(std::find(set.begin(), set.end(), patch_index) == set.end()) + if(std::find(set.begin(), set.end(), patch_index) == set.end()) { +#ifdef CGAL_MESH_3_DEBUG_FACET_CRITERIA + std::cerr << "Bad facet " + "(Facet_topological_criterion_with_adjacency: curve #" + << curve_id << ", at point " << v->point() + << ", is not incident to patch #" << patch_index << ")" + << std::endl; +#endif return Is_bad(Quality(1)); // bad! + } } break; case 2: - if(domain->surface_patch_index(v->index()) != patch_index) + if(domain->surface_patch_index(v->index()) != patch_index) { +#ifdef CGAL_MESH_3_DEBUG_FACET_CRITERIA + std::cerr << "Bad facet (Facet_topological_criterion_with_adjacency: " + "vertex at point " + << v->point() << " is not on patch #" << patch_index << ")" + << std::endl; +#endif return Is_bad(Quality(1)); // bad! + } break; default: return Is_bad(Quality(1)); @@ -112,6 +135,10 @@ protected: } } if(nb_vertices_on_curves == 3) { +#ifdef CGAL_MESH_3_DEBUG_FACET_CRITERIA + std::cerr << "Bad facet (Facet_topological_criterion_with_adjacency: " + "three points on a curve)\n"; +#endif return Is_bad(Quality(1)); // bad! // All vertices are on curves. That means that the facet could be on // several different patches. Let's disallow that. diff --git a/Mesh_3/include/CGAL/Mesh_3/mesh_standard_facet_criteria.h b/Mesh_3/include/CGAL/Mesh_3/mesh_standard_facet_criteria.h index 27684186651..cdfb7458400 100644 --- a/Mesh_3/include/CGAL/Mesh_3/mesh_standard_facet_criteria.h +++ b/Mesh_3/include/CGAL/Mesh_3/mesh_standard_facet_criteria.h @@ -565,6 +565,10 @@ protected: { if ( !(v2->index() == index) ) { +#ifdef CGAL_MESH_3_DEBUG_FACET_CRITERIA + std::cerr << "Bad facet (on same surface criterion: " + << v2->index() << " != " << index << ")" << std::endl; +#endif return Is_bad(Quality(1)); } } @@ -579,6 +583,10 @@ protected: { if ( is_index_initialized && !(v3->index() == index) ) { +#ifdef CGAL_MESH_3_DEBUG_FACET_CRITERIA + std::cerr << "Bad facet (on same surface criterion: " + << v3->index() << " != " << index << ")" << std::endl; +#endif return Is_bad(Quality(1)); } } From c8fe41922d47a2b2dd5c4956dcae6947c9602eeb Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Mon, 20 Jan 2020 18:19:52 +0100 Subject: [PATCH 088/141] Add a debug display with CGAL_MESH_3_PROTECTION_DEBUG & 1 --- Mesh_3/include/CGAL/Mesh_domain_with_polyline_features_3.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Mesh_3/include/CGAL/Mesh_domain_with_polyline_features_3.h b/Mesh_3/include/CGAL/Mesh_domain_with_polyline_features_3.h index 255f650ff6b..731e441c70a 100644 --- a/Mesh_3/include/CGAL/Mesh_domain_with_polyline_features_3.h +++ b/Mesh_3/include/CGAL/Mesh_domain_with_polyline_features_3.h @@ -1165,6 +1165,13 @@ add_features_and_incidences(InputIterator first, InputIterator end, Curve_index curve_id = insert_edge(polyline.begin(), polyline.end()); edges_incidences_[curve_id].insert(patches_ids.begin(), patches_ids.end()); +#if CGAL_MESH_3_PROTECTION_DEBUG & 1 + std::cerr << "Curve #" << curve_id << " is incident to the following patches: {"; + for(auto id: patches_ids) { + std::cerr << " " << id; + } + std::cerr << "}\n"; +#endif // CGAL_MESH_3_PROTECTION_DEBUG & 1 *indices_out++ = curve_id; } From 77ad2b42d2ee300969c164272577722f91239952 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Tue, 28 Jan 2020 15:56:00 +0100 Subject: [PATCH 089/141] Copy two files from Microsoft GSL instead of have CMake download it --- .../CGAL_setup_GuidelinesSupportLibrary.cmake | 33 --- Polyhedron/demo/Polyhedron/CMakeLists.txt | 2 - .../Polyhedron/Plugins/Mesh_3/CMakeLists.txt | 3 +- .../Plugins/Mesh_3/Mesh_3_plugin.cpp | 35 +++- .../Plugins/Mesh_3/include/gsl/gsl_assert | 167 +++++++++++++++ .../Plugins/Mesh_3/include/gsl/pointers | 198 ++++++++++++++++++ 6 files changed, 393 insertions(+), 45 deletions(-) delete mode 100644 Installation/cmake/modules/CGAL_setup_GuidelinesSupportLibrary.cmake create mode 100644 Polyhedron/demo/Polyhedron/Plugins/Mesh_3/include/gsl/gsl_assert create mode 100644 Polyhedron/demo/Polyhedron/Plugins/Mesh_3/include/gsl/pointers diff --git a/Installation/cmake/modules/CGAL_setup_GuidelinesSupportLibrary.cmake b/Installation/cmake/modules/CGAL_setup_GuidelinesSupportLibrary.cmake deleted file mode 100644 index a3214a237b4..00000000000 --- a/Installation/cmake/modules/CGAL_setup_GuidelinesSupportLibrary.cmake +++ /dev/null @@ -1,33 +0,0 @@ -if(NOT TARGET cxx::gsl) - include(ExternalProject) - - if(NOT CGAL_NO_EXTERNAL_PROJECTS) - ExternalProject_Add(gsl-download - URL https://github.com/microsoft/GSL/archive/v2.0.0.tar.gz - DOWNLOAD_NAME GSL-2.0.0.tar.gz - URL_HASH SHA512=7339527222c8a97a94c0bb4038b3d142045ec5d80995e628574ac96f4d9d13c41ad70fbe0d8390586dc0db8d9ea55107dbc95de80f7335eb78ef9d2e7047d726 - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - INSTALL_COMMAND "" - ) - ExternalProject_Get_Property(gsl-download source_dir) - find_path(gsl_include_dir - NAMES gsl/gsl - PATHS ${source_dir}/include - DOC "Include directory of the C++ Guideline Support Library") - endif() - if(NOT gsl_include_dir) - find_path(gsl_include_dir - NAMES gsl/gsl - PATH_SUFFIXES guidelines-support-library - DOC "Include directory of the C++ Guideline Support Library (version 2.0 or later)") - endif() - if(gsl_include_dir) - add_library(CGAL-gsl INTERFACE) - target_include_directories(CGAL-gsl SYSTEM INTERFACE ${gsl_include_dir}) - if(TARGET gsl-download) - add_dependencies(CGAL-gsl gsl-download) - endif() - add_library(cxx::gsl ALIAS CGAL-gsl) - endif() -endif() diff --git a/Polyhedron/demo/Polyhedron/CMakeLists.txt b/Polyhedron/demo/Polyhedron/CMakeLists.txt index 45469400764..d99d23ac187 100644 --- a/Polyhedron/demo/Polyhedron/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/CMakeLists.txt @@ -120,8 +120,6 @@ else( CGAL_ACTIVATE_CONCURRENT_MESH_3 OR ENV{CGAL_ACTIVATE_CONCURRENT_MESH_3} ) endif( LINK_WITH_TBB ) endif() -include(CGAL_setup_GuidelinesSupportLibrary) - if(CGAL_Qt5_FOUND AND Qt5_FOUND) include(${CGAL_USE_FILE}) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/CMakeLists.txt index 9939bf1dc8d..2ad0874130c 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/CMakeLists.txt @@ -8,8 +8,9 @@ qt5_wrap_ui( meshingUI_FILES Meshing_dialog.ui Smoother_dialog.ui Local_optimiz polyhedron_demo_plugin(mesh_3_plugin Mesh_3_plugin Mesh_3_plugin_cgal_code.cpp Meshing_thread.cpp split_polylines.cpp ${meshingUI_FILES} KEYWORDS Mesh_3) -target_link_libraries(mesh_3_plugin PUBLIC cxx::gsl scene_polygon_soup_item scene_polylines_item scene_implicit_function_item scene_image_item +target_link_libraries(mesh_3_plugin PUBLIC scene_polygon_soup_item scene_polylines_item scene_implicit_function_item scene_image_item scene_surface_mesh_item scene_c3t3_item ${OPENGL_gl_LIBRARY} ) +target_include_directories(mesh_3_plugin PRIVATE include) find_package(VTK QUIET COMPONENTS vtkImagingGeneral vtkIOImage NO_MODULE) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp index f4fbc454d88..2eb04fb34d3 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp @@ -19,7 +19,14 @@ #include #include -#include +#include + +// Small addition from GSL v2.0.0: +template +auto make_not_null(T&& t) { + return gsl::not_null>>{std::forward(t)}; +} + #include #include #include "Scene_polylines_item.h" @@ -208,6 +215,7 @@ private: }; struct Image_mesh_items { gsl::not_null image_item; + Scene_polylines_item* polylines_item = nullptr; }; struct Implicit_mesh_items { gsl::not_null function_item; @@ -275,7 +283,7 @@ boost::optional Mesh_3_plugin::get_items_or_return_error_string() const if (!items) items = Polyhedral_mesh_items{}; auto& poly_items = get(*items); auto& sm_items = poly_items.sm_items; - sm_items.push_back(gsl::make_not_null(sm_item)); + sm_items.push_back(make_not_null(sm_item)); if (is_closed(*sm_item->polyhedron())) { poly_items.bounding_sm_item = sm_item; } @@ -284,7 +292,7 @@ boost::optional Mesh_3_plugin::get_items_or_return_error_string() const else if (auto function_item = qobject_cast( scene->item(ind))) { if (!items) - items = Implicit_mesh_items{gsl::make_not_null(function_item)}; + items = Implicit_mesh_items{make_not_null(function_item)}; else return tr( "An implicit function cannot be mixed with other items type"); @@ -294,7 +302,7 @@ boost::optional Mesh_3_plugin::get_items_or_return_error_string() const else if (auto image_item = qobject_cast(scene->item(ind))) { if (!items) - items = Image_mesh_items{gsl::make_not_null(image_item)}; + items = Image_mesh_items{make_not_null(image_item)}; else return tr("An image items cannot be mixed with other items type"); } @@ -302,11 +310,20 @@ boost::optional Mesh_3_plugin::get_items_or_return_error_string() const else if (auto polylines_item = qobject_cast(scene->item(ind))) { if (!items) items = Polyhedral_mesh_items{}; - auto& poly_items = get(*items); - if (poly_items.polylines_item) { - return tr("Only one polyline item is accepted"); + auto poly_items_ptr = get(&*items); + if(poly_items_ptr) { + if (poly_items_ptr->polylines_item) { + return tr("Only one polyline item is accepted"); + } else { + poly_items_ptr->polylines_item = polylines_item; + } } else { - poly_items.polylines_item = polylines_item; + auto image_items = get(*items); + if (image_items.polylines_item) { + return tr("Only one polyline item is accepted"); + } else { + image_items.polylines_item = polylines_item; + } } } else { return tr("Wrong selection of items"); @@ -615,7 +632,7 @@ void Mesh_3_plugin::mesh_3(const Mesh_type mesh_type, const auto polylines_item = poly_items.polylines_item; QList polyhedrons; if(mesh_type != Mesh_type::SURFACE_ONLY) { - sm_items.removeAll(gsl::make_not_null(bounding_sm_item)); + sm_items.removeAll(make_not_null(bounding_sm_item)); } std::transform(sm_items.begin(), sm_items.end(), std::back_inserter(polyhedrons), diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/include/gsl/gsl_assert b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/include/gsl/gsl_assert new file mode 100644 index 00000000000..3c952e6e01a --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/include/gsl/gsl_assert @@ -0,0 +1,167 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2015 Microsoft Corporation. All rights reserved. +// +// This code is licensed under the MIT License (MIT). +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef GSL_CONTRACTS_H +#define GSL_CONTRACTS_H + +#include +#include // for logic_error + +// +// make suppress attributes parse for some compilers +// Hopefully temporary until suppresion standardization occurs +// +#if defined (_MSC_VER) +#define GSL_SUPPRESS(x) [[gsl::suppress(x)]] +#else +#if defined(__clang__) +#define GSL_SUPPRESS(x) [[gsl::suppress("x")]] +#else +#define GSL_SUPPRESS(x) +#endif // __clang__ +#endif // _MSC_VER + +// +// Temporary until MSVC STL supports no-exceptions mode. +// Currently terminate is a no-op in this mode, so we add termination behavior back +// +#if defined(_MSC_VER) && defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS +#define GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND +#include +#define RANGE_CHECKS_FAILURE 0 +#endif + +// +// There are three configuration options for this GSL implementation's behavior +// when pre/post conditions on the GSL types are violated: +// +// 1. GSL_TERMINATE_ON_CONTRACT_VIOLATION: std::terminate will be called (default) +// 2. GSL_THROW_ON_CONTRACT_VIOLATION: a gsl::fail_fast exception will be thrown +// 3. GSL_UNENFORCED_ON_CONTRACT_VIOLATION: nothing happens +// +#if !(defined(GSL_THROW_ON_CONTRACT_VIOLATION) || defined(GSL_TERMINATE_ON_CONTRACT_VIOLATION) || \ + defined(GSL_UNENFORCED_ON_CONTRACT_VIOLATION)) +#define GSL_TERMINATE_ON_CONTRACT_VIOLATION +#endif + +#define GSL_STRINGIFY_DETAIL(x) #x +#define GSL_STRINGIFY(x) GSL_STRINGIFY_DETAIL(x) + +#if defined(__clang__) || defined(__GNUC__) +#define GSL_LIKELY(x) __builtin_expect(!!(x), 1) +#define GSL_UNLIKELY(x) __builtin_expect(!!(x), 0) +#else +#define GSL_LIKELY(x) (!!(x)) +#define GSL_UNLIKELY(x) (!!(x)) +#endif + +// +// GSL_ASSUME(cond) +// +// Tell the optimizer that the predicate cond must hold. It is unspecified +// whether or not cond is actually evaluated. +// +#ifdef _MSC_VER +#define GSL_ASSUME(cond) __assume(cond) +#elif defined(__GNUC__) +#define GSL_ASSUME(cond) ((cond) ? static_cast(0) : __builtin_unreachable()) +#else +#define GSL_ASSUME(cond) static_cast((cond) ? 0 : 0) +#endif + +// +// GSL.assert: assertions +// + +namespace gsl +{ +struct fail_fast : public std::logic_error +{ + explicit fail_fast(char const* const message) : std::logic_error(message) {} +}; + +namespace details +{ +#if defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND) + + typedef void (__cdecl *terminate_handler)(); + + GSL_SUPPRESS(f.6) // NO-FORMAT: attribute + [[noreturn]] inline void __cdecl default_terminate_handler() + { + __fastfail(RANGE_CHECKS_FAILURE); + } + + inline gsl::details::terminate_handler& get_terminate_handler() noexcept + { + static terminate_handler handler = &default_terminate_handler; + return handler; + } + +#endif + + [[noreturn]] inline void terminate() noexcept + { +#if defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND) + (*gsl::details::get_terminate_handler())(); +#else + std::terminate(); +#endif + } + +#if defined(GSL_TERMINATE_ON_CONTRACT_VIOLATION) + + template + [[noreturn]] void throw_exception(Exception&&) noexcept + { + gsl::details::terminate(); + } + +#else + + template + [[noreturn]] void throw_exception(Exception&& exception) + { + throw std::forward(exception); + } + +#endif + +} // namespace details +} // namespace gsl + +#if defined(GSL_THROW_ON_CONTRACT_VIOLATION) + +#define GSL_CONTRACT_CHECK(type, cond) \ + (GSL_LIKELY(cond) ? static_cast(0) \ + : gsl::details::throw_exception(gsl::fail_fast( \ + "GSL: " type " failure at " __FILE__ ": " GSL_STRINGIFY(__LINE__)))) + +#elif defined(GSL_TERMINATE_ON_CONTRACT_VIOLATION) + +#define GSL_CONTRACT_CHECK(type, cond) \ + (GSL_LIKELY(cond) ? static_cast(0) : gsl::details::terminate()) + +#elif defined(GSL_UNENFORCED_ON_CONTRACT_VIOLATION) + +#define GSL_CONTRACT_CHECK(type, cond) GSL_ASSUME(cond) + +#endif + +#define Expects(cond) GSL_CONTRACT_CHECK("Precondition", cond) +#define Ensures(cond) GSL_CONTRACT_CHECK("Postcondition", cond) + +#endif // GSL_CONTRACTS_H diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/include/gsl/pointers b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/include/gsl/pointers new file mode 100644 index 00000000000..a3388561184 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/include/gsl/pointers @@ -0,0 +1,198 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2015 Microsoft Corporation. All rights reserved. +// +// This code is licensed under the MIT License (MIT). +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef GSL_POINTERS_H +#define GSL_POINTERS_H + +#include // for Ensures, Expects + +#include // for forward +#include // for ptrdiff_t, nullptr_t, ostream, size_t +#include // for shared_ptr, unique_ptr +#include // for hash +#include // for enable_if_t, is_convertible, is_assignable + +#if defined(_MSC_VER) && _MSC_VER < 1910 +#pragma push_macro("constexpr") +#define constexpr /*constexpr*/ + +#endif // defined(_MSC_VER) && _MSC_VER < 1910 + +namespace gsl +{ + +// +// GSL.owner: ownership pointers +// +using std::unique_ptr; +using std::shared_ptr; + +// +// owner +// +// owner is designed as a bridge for code that must deal directly with owning pointers for some reason +// +// T must be a pointer type +// - disallow construction from any type other than pointer type +// +template ::value>> +using owner = T; + +// +// not_null +// +// Restricts a pointer or smart pointer to only hold non-null values. +// +// Has zero size overhead over T. +// +// If T is a pointer (i.e. T == U*) then +// - allow construction from U* +// - disallow construction from nullptr_t +// - disallow default construction +// - ensure construction from null U* fails +// - allow implicit conversion to U* +// +template +class not_null +{ +public: + static_assert(std::is_assignable::value, "T cannot be assigned nullptr."); + + template ::value>> + constexpr explicit not_null(U&& u) : ptr_(std::forward(u)) + { + Expects(ptr_ != nullptr); + } + + template ::value>> + constexpr explicit not_null(T u) : ptr_(u) + { + Expects(ptr_ != nullptr); + } + + template ::value>> + constexpr not_null(const not_null& other) : not_null(other.get()) + { + } + + not_null(not_null&& other) = default; + not_null(const not_null& other) = default; + not_null& operator=(const not_null& other) = default; + + constexpr T get() const + { + Ensures(ptr_ != nullptr); + return ptr_; + } + + constexpr operator T() const { return get(); } + constexpr T operator->() const { return get(); } + constexpr decltype(auto) operator*() const { return *get(); } + + // prevents compilation when someone attempts to assign a null pointer constant + not_null(std::nullptr_t) = delete; + not_null& operator=(std::nullptr_t) = delete; + + // unwanted operators...pointers only point to single objects! + not_null& operator++() = delete; + not_null& operator--() = delete; + not_null operator++(int) = delete; + not_null operator--(int) = delete; + not_null& operator+=(std::ptrdiff_t) = delete; + not_null& operator-=(std::ptrdiff_t) = delete; + void operator[](std::ptrdiff_t) const = delete; + +private: + T ptr_; +}; + +template +auto make_not_null(T&& t) { + return gsl::not_null>>{std::forward(t)}; +} + +template +std::ostream& operator<<(std::ostream& os, const not_null& val) +{ + os << val.get(); + return os; +} + +template +auto operator==(const not_null& lhs, const not_null& rhs) -> decltype(lhs.get() == rhs.get()) +{ + return lhs.get() == rhs.get(); +} + +template +auto operator!=(const not_null& lhs, const not_null& rhs) -> decltype(lhs.get() != rhs.get()) +{ + return lhs.get() != rhs.get(); +} + +template +auto operator<(const not_null& lhs, const not_null& rhs) -> decltype(lhs.get() < rhs.get()) +{ + return lhs.get() < rhs.get(); +} + +template +auto operator<=(const not_null& lhs, const not_null& rhs) -> decltype(lhs.get() <= rhs.get()) +{ + return lhs.get() <= rhs.get(); +} + +template +auto operator>(const not_null& lhs, const not_null& rhs) -> decltype(lhs.get() > rhs.get()) +{ + return lhs.get() > rhs.get(); +} + +template +auto operator>=(const not_null& lhs, const not_null& rhs) -> decltype(lhs.get() >= rhs.get()) +{ + return lhs.get() >= rhs.get(); +} + +// more unwanted operators +template +std::ptrdiff_t operator-(const not_null&, const not_null&) = delete; +template +not_null operator-(const not_null&, std::ptrdiff_t) = delete; +template +not_null operator+(const not_null&, std::ptrdiff_t) = delete; +template +not_null operator+(std::ptrdiff_t, const not_null&) = delete; + +} // namespace gsl + +namespace std +{ +template +struct hash> +{ + std::size_t operator()(const gsl::not_null& value) const { return hash{}(value); } +}; + +} // namespace std + +#if defined(_MSC_VER) && _MSC_VER < 1910 +#undef constexpr +#pragma pop_macro("constexpr") + +#endif // defined(_MSC_VER) && _MSC_VER < 1910 + +#endif // GSL_POINTERS_H From 5b8d92e08f59d1893a440563f9207c8afbe0b430 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Mon, 17 Feb 2020 10:28:02 +0100 Subject: [PATCH 090/141] First version of split_subconstraint_graph_into_constraints() --- .../CGAL/Constrained_triangulation_plus_2.h | 7 + .../CGAL/Constrained_triangulation_plus_2.h | 17 +++ .../internal/CTP2_subconstraint_graph.h | 124 ++++++++++++++++++ 3 files changed, 148 insertions(+) create mode 100644 Triangulation_2/include/CGAL/Triangulation_2/internal/CTP2_subconstraint_graph.h diff --git a/Triangulation_2/doc/Triangulation_2/CGAL/Constrained_triangulation_plus_2.h b/Triangulation_2/doc/Triangulation_2/CGAL/Constrained_triangulation_plus_2.h index 4fb60c08fbc..cef1af9c55f 100644 --- a/Triangulation_2/doc/Triangulation_2/CGAL/Constrained_triangulation_plus_2.h +++ b/Triangulation_2/doc/Triangulation_2/CGAL/Constrained_triangulation_plus_2.h @@ -293,6 +293,13 @@ std::size_t insert_constraints(PointIterator points_first, PointIterator points_ IndicesIterator indices_first, IndicesIterator indices_last); +/*! +splits into constraints the subconstraint graph g at vertices of degree greater than 2. + +\warning all existing constraints will be discarded. +*/ +void split_subconstraint_graph_into_constraints(); + /*! removes the constraint `cid`, without removing the points from the triangulation. */ diff --git a/Triangulation_2/include/CGAL/Constrained_triangulation_plus_2.h b/Triangulation_2/include/CGAL/Constrained_triangulation_plus_2.h index dad024bd902..676952750b9 100644 --- a/Triangulation_2/include/CGAL/Constrained_triangulation_plus_2.h +++ b/Triangulation_2/include/CGAL/Constrained_triangulation_plus_2.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -315,6 +316,22 @@ public: return n; } */ + + void split_subconstraint_graph_into_constraints(const std::function& is_terminal + = std::function()) + { + internal::CTP2_graph_visitor visitor(*this); + if (is_terminal) + CGAL::split_graph_into_polylines (internal::CTP2_subconstraint_graph(*this), visitor, + [&is_terminal](Vertex_handle vh, + const internal::CTP2_subconstraint_graph&) -> bool + { + return is_terminal(vh); + }); + else + CGAL::split_graph_into_polylines (internal::CTP2_subconstraint_graph(*this), visitor); + } + Vertex_handle push_back(const Point& p) { return insert(p); diff --git a/Triangulation_2/include/CGAL/Triangulation_2/internal/CTP2_subconstraint_graph.h b/Triangulation_2/include/CGAL/Triangulation_2/internal/CTP2_subconstraint_graph.h new file mode 100644 index 00000000000..9e1346d3d2c --- /dev/null +++ b/Triangulation_2/include/CGAL/Triangulation_2/internal/CTP2_subconstraint_graph.h @@ -0,0 +1,124 @@ +// Copyright (c) 2020 GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Simon Giraudot + +#ifndef CGAL_CTP2_SUBCONSTRAINT_GRAPH_H +#define CGAL_CTP2_SUBCONSTRAINT_GRAPH_H + +#include + +#include +#include + +namespace CGAL +{ + +namespace internal +{ + +template +class CTP2_subconstraint_graph +{ + CTP2& ctp2; +public: + + typedef typename CTP2::Vertex_handle vertex_descriptor; + typedef typename CTP2::Subconstraint edge_descriptor; + typedef boost::undirected_tag directed_category; + typedef boost::disallow_parallel_edge_tag edge_parallel_category; + struct CTP2_graph_traversal_category : + public virtual boost::bidirectional_graph_tag, + public virtual boost::adjacency_graph_tag, + public virtual boost::edge_list_graph_tag, + public virtual boost::vertex_list_graph_tag + { }; + typedef CTP2_graph_traversal_category traversal_category; + typedef internal::Dereference_to_handle_enforcer< + CTP2, + typename CTP2::Finite_vertices_iterator, + vertex_descriptor> vertex_iterator; + + typedef typename CTP2::Subconstraint_iterator::value_type Subconstr_it_v_t; + typedef First_of_pair_property_map Subconstr_map; + typedef Property_map_to_unary_function Subconstr_uf; + typedef boost::transform_iterator edge_iterator; + + CTP2_subconstraint_graph (CTP2& ctp2) : ctp2(ctp2) { } + + friend Iterator_range vertices (const CTP2_subconstraint_graph& g) + { + return make_range (vertex_iterator(g.ctp2.finite_vertices_begin()), + vertex_iterator(g.ctp2.finite_vertices_end())); + } + + friend Iterator_range edges (const CTP2_subconstraint_graph& g) + { + return make_range (boost::make_transform_iterator(g.ctp2.subconstraints_begin(), Subconstr_uf(Subconstr_map())), + boost::make_transform_iterator(g.ctp2.subconstraints_end(), Subconstr_uf(Subconstr_map()))); + } + + friend vertex_descriptor source (edge_descriptor ed, const CTP2_subconstraint_graph& g) + { + return ed.first; + } + + friend vertex_descriptor target (edge_descriptor ed, const CTP2_subconstraint_graph& g) + { + return ed.second; + } +}; + + +template +class CTP2_graph_visitor +{ +private: + CTP2& ctp2; + std::vector to_remove; + typename CTP2::Constraint_id current; + typename CTP2::Vertex_handle latest_vertex; + +public: + + CTP2_graph_visitor (CTP2& ctp2) : ctp2 (ctp2) { } + + void start_new_polyline() + { + latest_vertex = typename CTP2::Vertex_handle(); + current = typename CTP2::Constraint_id(); + } + + void add_node (typename CTP2::Vertex_handle vh) + { + if (latest_vertex != typename CTP2::Vertex_handle()) + { + to_remove.push_back (ctp2.context(latest_vertex, vh).id()); + typename CTP2::Constraint_id cid = ctp2.insert_constraint(latest_vertex, vh); + if (current == typename CTP2::Constraint_id()) + current = cid; + else + current = ctp2.concatenate (current, cid); + } + latest_vertex = vh; + } + + void end_polyline() + { + for (typename CTP2::Constraint_id id : to_remove) + ctp2.remove_constraint(id); + to_remove.clear(); + } +}; + +} // namespace internal + +} // namespace CGAL + +#endif // CGAL_CTP2_SUBCONSTRAINT_GRAPH_H From 68ddb1f4e593747200c6fa760a0af7100da0a212 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Mon, 17 Feb 2020 13:22:27 +0100 Subject: [PATCH 091/141] Add example --- .../doc/Triangulation_2/examples.txt | 1 + .../segment_soup_to_polylines.cpp | 50 +++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 Triangulation_2/examples/Triangulation_2/segment_soup_to_polylines.cpp diff --git a/Triangulation_2/doc/Triangulation_2/examples.txt b/Triangulation_2/doc/Triangulation_2/examples.txt index 45128d71309..7061593de13 100644 --- a/Triangulation_2/doc/Triangulation_2/examples.txt +++ b/Triangulation_2/doc/Triangulation_2/examples.txt @@ -19,5 +19,6 @@ \example Triangulation_2/voronoi.cpp \example Triangulation_2/copy_triangulation_2.cpp \example Triangulation_2/polylines_triangulation.cpp +\example Triangulation_2/segment_soup_to_polylines.cpp \example Triangulation_2/draw_triangulation_2.cpp */ diff --git a/Triangulation_2/examples/Triangulation_2/segment_soup_to_polylines.cpp b/Triangulation_2/examples/Triangulation_2/segment_soup_to_polylines.cpp new file mode 100644 index 00000000000..3db888d35ec --- /dev/null +++ b/Triangulation_2/examples/Triangulation_2/segment_soup_to_polylines.cpp @@ -0,0 +1,50 @@ +#include +#include +#include + +#include + +typedef CGAL::Exact_predicates_exact_constructions_kernel K; +typedef CGAL::Polygon_2 Polygon_2; +typedef CGAL::Constrained_Delaunay_triangulation_2 CDT; +typedef CGAL::Constrained_triangulation_plus_2 CDTP; + +typedef CDTP::Point Point; +typedef CDTP::Constraint_id Cid; +typedef CDTP::Vertex_handle Vertex_handle; + +int main() +{ + CDTP cdtp; + + // First polyline + cdtp.insert_constraint(Point(0,0), Point(1,1)); + cdtp.insert_constraint(Point(1,1), Point(2,2)); + cdtp.insert_constraint(Point(2,2), Point(3,3)); + + // Second polyline that cuts the first one in 2 + cdtp.insert_constraint(Point(1,1), Point(1,2)); + cdtp.insert_constraint(Point(1,2), Point(1,3)); + + // Third polyline + cdtp.insert_constraint(Point(10,10), Point(20,20)); + cdtp.insert_constraint(Point(20,20), Point(30,30)); + + // Fourth polyline + cdtp.insert_constraint(Point(100,100), Point(200,200)); + + // Segment soup of 8 segments as input + std::cout << "Input CDT+ has " + << std::distance (cdtp.constraints_begin(), cdtp.constraints_end()) + << " constraints/subconstraints" << std::endl; + + std::cout << "Splitting subconstraints graph into constraints" << std::endl; + cdtp.split_subconstraint_graph_into_constraints(); + + // 5 polylines as output + std::cout << "Output CDT+ has " + << std::distance (cdtp.constraints_begin(), cdtp.constraints_end()) + << " constraints" << std::endl; + + return EXIT_SUCCESS; +} From 5c95ec2681bb9ccfcb2a19a66e28282943575ff9 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Mon, 17 Feb 2020 13:22:40 +0100 Subject: [PATCH 092/141] User manual + some fixe --- .../CGAL/Constrained_triangulation_plus_2.h | 12 ++++++++++-- .../doc/Triangulation_2/Triangulation_2.txt | 15 +++++++++++++++ Triangulation_2/doc/Triangulation_2/dependencies | 1 + 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/Triangulation_2/doc/Triangulation_2/CGAL/Constrained_triangulation_plus_2.h b/Triangulation_2/doc/Triangulation_2/CGAL/Constrained_triangulation_plus_2.h index cef1af9c55f..da7bf476941 100644 --- a/Triangulation_2/doc/Triangulation_2/CGAL/Constrained_triangulation_plus_2.h +++ b/Triangulation_2/doc/Triangulation_2/CGAL/Constrained_triangulation_plus_2.h @@ -294,11 +294,19 @@ std::size_t insert_constraints(PointIterator points_first, PointIterator points_ /*! -splits into constraints the subconstraint graph g at vertices of degree greater than 2. +splits into polylines the graph `g` at vertices of degree greater than 2 +and at vertices for which `is_terminal(v)==true`. \warning all existing constraints will be discarded. + +\param is_terminal An optional function returning true if the vertex +`v` of degree 2 is a polyline endpoint and false otherwise. If no +function is provided, a default function is provided that returns true +for vertices whose degree is different from 2. + +\sa `split_graph_into_polylines()` */ -void split_subconstraint_graph_into_constraints(); +void split_subconstraint_graph_into_constraints(const std::function& is_terminal); /*! removes the constraint `cid`, without removing the points from the triangulation. diff --git a/Triangulation_2/doc/Triangulation_2/Triangulation_2.txt b/Triangulation_2/doc/Triangulation_2/Triangulation_2.txt index 9451f88be77..fc94bccbf5e 100644 --- a/Triangulation_2/doc/Triangulation_2/Triangulation_2.txt +++ b/Triangulation_2/doc/Triangulation_2/Triangulation_2.txt @@ -1124,6 +1124,21 @@ through the edge. \cgalExample{Triangulation_2/polylines_triangulation.cpp} +\subsection Triangulation_2ExampleBuildingFromSoup Example: Building a Triangulated Arrangement of Polylines from a Segment Soup + +The `Constrained_triangulation_plus_2` structure is initialized by a +set of polylines. As users may only be able to provide a disconnected +segment soup as input, a member function +[split_subconstraint_graph_into_constraints()](@ref Constrained_triangulation_plus_2::split_subconstraint_graph_into_constraints()) +is provided: this function identifies the polylines by connecting +segments until a vertex whose degree is different than 2 is reached. + +The following code shows how a "blind" insertion of disconnected +polylines can be processed into a set of well-defined polyline +constraints in a `Constrained_triangulation_plus_2`: + +\cgalExample{Triangulation_2/segment_soup_to_polylines.cpp} + \section Section_2D_Triangulations_Hierarchy The Triangulation Hierarchy The class `Triangulation_hierarchy_2` diff --git a/Triangulation_2/doc/Triangulation_2/dependencies b/Triangulation_2/doc/Triangulation_2/dependencies index 84dba85f07d..22ae69dcfef 100644 --- a/Triangulation_2/doc/Triangulation_2/dependencies +++ b/Triangulation_2/doc/Triangulation_2/dependencies @@ -4,6 +4,7 @@ STL_Extension Algebraic_foundations Circulator Stream_support +BGL TDS_2 Triangulation_3 Spatial_sorting From b546a7078fd04de9ef3e0a9c6d0e467584b4196e Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Mon, 17 Feb 2020 13:59:26 +0100 Subject: [PATCH 093/141] Improve example --- .../segment_soup_to_polylines.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/Triangulation_2/examples/Triangulation_2/segment_soup_to_polylines.cpp b/Triangulation_2/examples/Triangulation_2/segment_soup_to_polylines.cpp index 3db888d35ec..9ba5f5d88d7 100644 --- a/Triangulation_2/examples/Triangulation_2/segment_soup_to_polylines.cpp +++ b/Triangulation_2/examples/Triangulation_2/segment_soup_to_polylines.cpp @@ -34,17 +34,21 @@ int main() cdtp.insert_constraint(Point(100,100), Point(200,200)); // Segment soup of 8 segments as input - std::cout << "Input CDT+ has " - << std::distance (cdtp.constraints_begin(), cdtp.constraints_end()) - << " constraints/subconstraints" << std::endl; + std::cout << "Input CDT+ has " << cdtp.number_of_constraints() << " constraints/subconstraints" << std::endl; std::cout << "Splitting subconstraints graph into constraints" << std::endl; cdtp.split_subconstraint_graph_into_constraints(); // 5 polylines as output - std::cout << "Output CDT+ has " - << std::distance (cdtp.constraints_begin(), cdtp.constraints_end()) - << " constraints" << std::endl; + std::cout << "Output CDT+ has " << cdtp.number_of_constraints() << " constraints:" << std::endl; + + for (CDTP::Constraint_id cid : cdtp.constraints()) + { + std::cout << " *"; + for (CDTP::Vertex_handle vh : cdtp.vertices_in_constraint(cid)) + std::cout << " (" << vh->point() << ")"; + std::cout << std::endl; + } return EXIT_SUCCESS; } From 5c889ef61cdf27d13ae15ee3257c1c228ef35e46 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Mon, 17 Feb 2020 14:47:20 +0100 Subject: [PATCH 094/141] Improve example and doc --- .../CGAL/Constrained_triangulation_plus_2.h | 13 +++++++++++-- .../Triangulation_2/segment_soup_to_polylines.cpp | 3 --- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Triangulation_2/doc/Triangulation_2/CGAL/Constrained_triangulation_plus_2.h b/Triangulation_2/doc/Triangulation_2/CGAL/Constrained_triangulation_plus_2.h index da7bf476941..2494659dcca 100644 --- a/Triangulation_2/doc/Triangulation_2/CGAL/Constrained_triangulation_plus_2.h +++ b/Triangulation_2/doc/Triangulation_2/CGAL/Constrained_triangulation_plus_2.h @@ -294,8 +294,17 @@ std::size_t insert_constraints(PointIterator points_first, PointIterator points_ /*! -splits into polylines the graph `g` at vertices of degree greater than 2 -and at vertices for which `is_terminal(v)==true`. +splits into constraints the graph of subconstraints. + +Consider the graph `g={V,E}` where `V` is the set of vertices of the +triangulation and `E` is the set of all subconstraints of all +constraints of the triangulation. + +This function splits into polylines the graph `g` at vertices of +degree greater than 2 and at vertices for which +`is_terminal(v)==true`. + +Each computed polyline is stored as a constraint of the triangulation. \warning all existing constraints will be discarded. diff --git a/Triangulation_2/examples/Triangulation_2/segment_soup_to_polylines.cpp b/Triangulation_2/examples/Triangulation_2/segment_soup_to_polylines.cpp index 9ba5f5d88d7..5eadd29090f 100644 --- a/Triangulation_2/examples/Triangulation_2/segment_soup_to_polylines.cpp +++ b/Triangulation_2/examples/Triangulation_2/segment_soup_to_polylines.cpp @@ -2,10 +2,7 @@ #include #include -#include - typedef CGAL::Exact_predicates_exact_constructions_kernel K; -typedef CGAL::Polygon_2 Polygon_2; typedef CGAL::Constrained_Delaunay_triangulation_2 CDT; typedef CGAL::Constrained_triangulation_plus_2 CDTP; From e4714165f0649c1941186d36ee6b165761cc90cc Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Wed, 19 Feb 2020 12:40:05 +0100 Subject: [PATCH 095/141] Add missing include --- .../CGAL/Triangulation_2/internal/CTP2_subconstraint_graph.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Triangulation_2/include/CGAL/Triangulation_2/internal/CTP2_subconstraint_graph.h b/Triangulation_2/include/CGAL/Triangulation_2/internal/CTP2_subconstraint_graph.h index 9e1346d3d2c..cd4dff681b4 100644 --- a/Triangulation_2/include/CGAL/Triangulation_2/internal/CTP2_subconstraint_graph.h +++ b/Triangulation_2/include/CGAL/Triangulation_2/internal/CTP2_subconstraint_graph.h @@ -17,6 +17,8 @@ #include #include +#include + namespace CGAL { From 916573af3dfeccc419360d09d91b2ca7455ab34d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 25 Feb 2020 15:21:19 +0100 Subject: [PATCH 096/141] Fix and enhance merge_duplicate_vertices_in_boundary_cycles Bug fix: improper check of overlapping intervals Enhancement: don't throw everything as soon as there is a pair of intervals that are incompatible, only remove one of the intervals (taken arbitrarily as the widest) --- .../merge_border_vertices.h | 127 +++++++++++++----- 1 file changed, 96 insertions(+), 31 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/merge_border_vertices.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/merge_border_vertices.h index 891882f13d0..0d600739bfd 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/merge_border_vertices.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/merge_border_vertices.h @@ -58,6 +58,80 @@ struct Less_on_point_of_target const VertexPointMap& vpm; }; +template +void sanitize_candidates(const std::vector::halfedge_descriptor, std::size_t> >& cycle_hedges, + std::vector >& candidate_hedges_with_id, + const VPM vpm, + const PolygonMesh& pm) +{ + if(candidate_hedges_with_id.empty()) + return; + + std::size_t nm_vertices_n = candidate_hedges_with_id.size(); + for(std::size_t fr_id=0, fr_end=nm_vertices_n-1; fr_id& first_candidates = candidate_hedges_with_id[fr_id]; + CGAL_assertion(first_candidates.size() >= 2); + + for(std::size_t i=0, ie=first_candidates.size()-1; i& second_candidates = candidate_hedges_with_id[sr_id]; + CGAL_assertion(second_candidates.size() >= 2); + + for(std::size_t j=0, je=second_candidates.size()-1; j >::iterator to_remove_iter = candidate_hedges_with_id.begin(); + if(first_candidates_range > second_candidates_range) + std::advance(to_remove_iter, fr_id); + else + std::advance(to_remove_iter, sr_id); + + candidate_hedges_with_id.erase(to_remove_iter); + + // restart the whole thing + return sanitize_candidates(cycle_hedges, candidate_hedges_with_id, vpm, pm); + } + } // entries of the second range + } // second range + } // entries of the first range + } // first range +} // warning: cycle_hedges will be altered (sorted) template @@ -75,26 +149,23 @@ void detect_identical_mergeable_vertices( std::size_t nbv=cycle_hedges.size(); std::size_t i=1; - std::set< std::pair > intervals; + // IDs of cycle_hedges + std::vector > candidate_hedges_with_id; - while(i!=nbv) + while(i != nbv) { - if ( get(vpm, target(cycle_hedges[i].first, pm)) == - get(vpm, target(cycle_hedges[i-1].first, pm)) ) + if(get(vpm, target(cycle_hedges[i].first, pm)) == + get(vpm, target(cycle_hedges[i-1].first, pm)) ) { - hedges_with_identical_point_target.push_back( std::vector() ); - hedges_with_identical_point_target.back().push_back(cycle_hedges[i-1].first); - hedges_with_identical_point_target.back().push_back(cycle_hedges[i].first); - intervals.insert( std::make_pair(cycle_hedges[i-1].second, cycle_hedges[i].second) ); - std::size_t previous = cycle_hedges[i].second; - while(++i!=nbv) + candidate_hedges_with_id.resize(candidate_hedges_with_id.size() + 1); + candidate_hedges_with_id.back().push_back(i-1); + candidate_hedges_with_id.back().push_back(i); + while(++i != nbv) { - if ( get(vpm, target(cycle_hedges[i].first, pm)) == - get(vpm, target(cycle_hedges[i-1].first, pm)) ) + if(get(vpm, target(cycle_hedges[i].first, pm)) == + get(vpm, target(cycle_hedges[i-1].first, pm))) { - hedges_with_identical_point_target.back().push_back(cycle_hedges[i].first); - intervals.insert( std::make_pair(previous, cycle_hedges[i].second) ); - previous = cycle_hedges[i].second; + candidate_hedges_with_id.back().push_back(i); } else { @@ -104,29 +175,23 @@ void detect_identical_mergeable_vertices( } } else + { ++i; + } } // check that intervals are disjoint or strictly nested // if there is only one issue we drop the whole cycle. - /// \todo shall we try to be more conservative? - if (hedges_with_identical_point_target.empty()) return; - std::set< std::pair >::iterator it1 = intervals.begin(), - end2 = intervals.end(), - end1 = std::prev(end2), - it2; - for (; it1!=end1; ++it1) - for(it2=std::next(it1); it2!= end2; ++it2 ) + sanitize_candidates(cycle_hedges, candidate_hedges_with_id, vpm, pm); + + for(const std::vector& candidates : candidate_hedges_with_id) + { + hedges_with_identical_point_target.resize(hedges_with_identical_point_target.size() + 1); + for(const std::size_t hid : candidates) { - CGAL_assertion(it1->firstfirst); - CGAL_assertion(it1->first < it1->second && it2->first < it2->second); - if (it1->second > it2->first && it2->second > it1->second) - { - std::cerr << "Merging is skipt to avoid bad cycle connections\n"; - hedges_with_identical_point_target.clear(); - return; - } + hedges_with_identical_point_target.back().push_back(cycle_hedges[hid].first); } + } } // \ingroup PMP_repairing_grp From fc9597ac1cd128eef295f8c6fafa50aaaef4c5c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 25 Feb 2020 15:23:32 +0100 Subject: [PATCH 097/141] Add another test for merge_duplicate_vertices_on_boundary_cycles --- .../data/merge_points_2.off | 148 ++++++++++++++++++ .../test_merging_border_vertices.cpp | 1 + 2 files changed, 149 insertions(+) create mode 100644 Polygon_mesh_processing/test/Polygon_mesh_processing/data/merge_points_2.off diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/data/merge_points_2.off b/Polygon_mesh_processing/test/Polygon_mesh_processing/data/merge_points_2.off new file mode 100644 index 00000000000..899498241eb --- /dev/null +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/data/merge_points_2.off @@ -0,0 +1,148 @@ +OFF +69 77 0 +2734.3676346525872 3434.3504459479127 1442.9335140122612 +2719.3403506595987 3453.4161721323617 1460.6868219157659 +2709.1200036965829 3441.0937601908799 1443.3605847576555 +2707.2898207580311 3427.6843473822037 1462.6824351011669 +2722.1846572494605 3416.4192046623757 1441.5944682235963 +2742.8716613249344 3402.490623086861 1440.3198836496226 +2753.3364495634642 3427.6689952491442 1442.5723811823786 +2677.1902323292707 3388.8980441619497 1468.2608674769649 +2682.9890456558351 3394.0201967527873 1469.405566697666 +2675.442865180702 3393.1462806017598 1467.5442633199923 +2686.8980753431397 3380.7421806328939 1443.2374713937929 +2716.5786976037834 3400.3200157594829 1451.4765490779578 +2685.7236893195068 3384.3586152364051 1464.1503953788588 +2684.8536689831963 3407.8756005874329 1468.3014418028488 +2697.5519534461582 3412.3935343507283 1472.1757125168774 +2671.8706491766616 3440.1432641534166 1468.4737378177533 +2690.720700628156 3395.1959881699113 1469.5153182281392 +2629.6983323962659 3429.4843967878969 1472.5423339454806 +2594.4066161078717 3450.0106258471924 1477.7666258487839 +2611.1701258541689 3412.7742988800183 1469.5336661012821 +2578.8472625124887 3405.1212073127308 1451.316062559159 +2597.9102056517986 3407.5801335061378 1455.8513406758216 +2595.5942479980158 3336.8714115436887 1450.4555995156179 +2651.1411353571648 3268.7347854042091 1448.2437478852689 +2642.0007558087773 3340.8524168296035 1471.6775773740933 +2684.6578030762194 3284.3494943162532 1444.8361338629848 +2746.6435546875 3281.73828125 1464.1597900390625 +2740.7837371075884 3314.211365505269 1439.3263783429693 +2733.017717935536 3268.5602714994648 1441.9623977045908 +2809.9441752754037 3300.5772357138785 1435.0251730088157 +2773.6435271344671 3279.0727549248313 1437.6208090620771 +2800.655517578125 3280.3955078125 1435.466064453125 +2614.6291234451946 3386.7314361481222 1449.0219180273643 +2588.0364408767973 3377.0482872259145 1462.3690172263191 +2827.7365690371798 3283.0041660240058 1433.753734396882 +2825.802734375 3295.31640625 1451.844482421875 +2635.3136822443203 3449.3019266923911 1473.2683784698279 +2648.414115329484 3487.3622759119589 1479.7258550820666 +2823.434618860947 3319.5472154122308 1435.5915969990174 +2853.7975913909549 3332.2754306138595 1438.0417630460538 +2807.2569703176523 3348.2627066182322 1437.2224669894972 +2694.882230800019 3316.5825583479455 1442.8415459717917 +2685.0408118635805 3352.1126936768487 1444.1628949826604 +2669.277004428076 3401.8710698669383 1463.7753003388066 +2628.353515625 3411.537841796875 1453.240966796875 +2647.3840165088322 3387.4930258137474 1446.4389282539896 +2832.307535839569 3381.235958495593 1441.9428539616388 +2786.0634765625 3373.05712890625 1453.71337890625 +2838.2438104016237 3417.000586555514 1465.3140587573271 +2718.1522711267571 3264.9136200035673 1457.5973059275025 +2704.2383913459889 3256.7073475650695 1444.8385837253218 +2720.8878481688253 3350.5889280456677 1459.9354608396256 +2730.6231271484994 3356.6350443986285 1440.5864729182235 +2724.5318986025195 3383.7888818757892 1445.0939258740668 +2668.8563414775472 3369.7017848427331 1445.3383453307138 +2723.925537109375 3293.966796875 1470.58935546875 +2755.482421875 3367.92919921875 1455.7613525390625 +2781.495849609375 3361.289306640625 1454.6324462890625 +2773.2406815180684 3369.0781148672268 1438.1137239370505 +2762.7962173755814 3381.5269947752195 1439.1176815674298 +2777.5338287310433 3450.4593918498058 1445.8167897288913 +2746.2389104526192 3344.8938903067665 1439.2729644592046 +2716.5786976037834 3400.3200157594829 1451.4765490779578 +2686.8980753431397 3380.7421806328939 1443.2374713937929 +2740.7837371075884 3314.211365505269 1439.3263783429693 +2733.017717935536 3268.5602714994648 1441.9623977045908 +2669.277004428076 3401.8710698669383 1463.7753003388066 +2730.6231271484994 3356.6350443986285 1440.5864729182235 +2762.7962173755814 3381.5269947752195 1439.1176815674298 +3 0 1 2 +3 3 4 2 +3 2 4 0 +3 5 6 0 +3 7 8 9 +3 63 11 12 +3 13 14 15 +3 16 8 12 +3 17 18 19 +3 18 20 21 +3 22 23 24 +3 24 23 25 +3 26 27 28 +3 29 30 31 +3 22 32 33 +3 34 29 31 +3 29 34 35 +3 36 15 37 +3 29 35 38 +3 62 4 3 +3 35 39 38 +3 17 36 18 +3 5 0 4 +3 17 15 36 +3 29 38 40 +3 24 41 42 +3 38 39 40 +3 2 1 15 +3 66 44 45 +3 39 46 40 +3 15 43 13 +3 47 40 46 +3 48 47 46 +3 15 1 37 +3 49 25 50 +3 9 8 13 +3 41 51 42 +3 10 52 53 +3 41 64 51 +3 13 8 16 +3 57 47 58 +3 25 41 24 +3 33 21 20 +3 59 47 6 +3 17 43 15 +3 60 6 47 +3 42 51 52 +3 58 61 57 +3 56 58 59 +3 42 52 10 +3 67 27 61 +3 21 33 32 +3 44 21 32 +3 14 13 16 +3 56 61 58 +3 67 61 56 +3 27 40 61 +3 27 26 30 +3 40 57 61 +3 32 45 44 +3 29 27 30 +3 28 30 26 +3 47 48 60 +3 27 29 40 +3 65 25 49 +3 6 5 59 +3 13 43 9 +3 47 59 58 +3 25 65 55 +3 25 55 41 +3 22 24 32 +3 12 8 7 +3 41 55 64 +3 16 12 11 +3 42 10 54 +3 53 52 68 +3 19 18 21 diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_merging_border_vertices.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_merging_border_vertices.cpp index 4ae670175e3..08e76756edf 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_merging_border_vertices.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_merging_border_vertices.cpp @@ -43,6 +43,7 @@ int main(int argc, char** argv) if (argc==1) { test_merge_duplicated_vertices_in_boundary_cycles("data/merge_points.off", 43); + test_merge_duplicated_vertices_in_boundary_cycles("data/merge_points_2.off", 62); } else { From 0c77ffe593574839ab26d190911ee6c6f96dce37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 25 Feb 2020 15:29:56 +0100 Subject: [PATCH 098/141] Fix includes --- .../CGAL/Polygon_mesh_processing/merge_border_vertices.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/merge_border_vertices.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/merge_border_vertices.h index 0d600739bfd..2efb62ed5f4 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/merge_border_vertices.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/merge_border_vertices.h @@ -22,8 +22,11 @@ #include #include -#include -#include +#include +#include +#include +#include +#include namespace CGAL { From f9c6cea0fdc650561d6860565d1899d0fa4cd6b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 25 Feb 2020 15:30:11 +0100 Subject: [PATCH 099/141] Hide debug code behind macros --- .../merge_border_vertices.h | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/merge_border_vertices.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/merge_border_vertices.h index 2efb62ed5f4..2fd05b5273c 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/merge_border_vertices.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/merge_border_vertices.h @@ -108,16 +108,18 @@ void sanitize_candidates(const std::vector >::iterator to_remove_iter = candidate_hedges_with_id.begin(); if(first_candidates_range > second_candidates_range) From 45e8903640a3602711095a6a48bd853d2a9a8776 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 25 Feb 2020 17:34:59 +0100 Subject: [PATCH 100/141] Add merge_duplicate_vertices_on_boundary_cycles to the CGAL demo --- .../Plugins/PMP/Repair_polyhedron_plugin.cpp | 41 ++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Repair_polyhedron_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Repair_polyhedron_plugin.cpp index a02cae1f847..a4cf1f1d134 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Repair_polyhedron_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Repair_polyhedron_plugin.cpp @@ -11,11 +11,15 @@ #include #include #include -#include #include #include #include +#include + +#include +#include +#include using namespace CGAL::Three; class Polyhedron_demo_repair_polyhedron_plugin : @@ -41,6 +45,7 @@ public: actionRemoveSelfIntersections = new QAction(tr("Remove Self-Intersections"), mw); actionStitchCloseBorderHalfedges = new QAction(tr("Stitch Close Border Halfedges"), mw); actionDuplicateNMVertices = new QAction(tr("Duplicate Non-Manifold Vertices"), mw); + actionMergeDuplicatedVerticesOnBoundaryCycles = new QAction(tr("Merge Duplicated Vertices on Boundary Cycles"), mw); actionAutorefine = new QAction(tr("Autorefine Mesh"), mw); actionAutorefineAndRMSelfIntersections = new QAction(tr("Autorefine and Remove Self-Intersections"), mw); @@ -49,6 +54,7 @@ public: actionRemoveSelfIntersections->setObjectName("actionRemoveSelfIntersections"); actionStitchCloseBorderHalfedges->setObjectName("actionStitchCloseBorderHalfedges"); actionDuplicateNMVertices->setObjectName("actionDuplicateNMVertices"); + actionMergeDuplicatedVerticesOnBoundaryCycles->setObjectName("actionMergeDuplicatedVerticesOnBoundaryCycles"); actionAutorefine->setObjectName("actionAutorefine"); actionAutorefineAndRMSelfIntersections->setObjectName("actionAutorefineAndRMSelfIntersections"); @@ -57,6 +63,7 @@ public: actionRemoveSelfIntersections->setProperty("subMenuName", "Polygon Mesh Processing/Repair/Experimental"); actionRemoveIsolatedVertices->setProperty("subMenuName", "Polygon Mesh Processing/Repair"); actionDuplicateNMVertices->setProperty("subMenuName", "Polygon Mesh Processing/Repair"); + actionMergeDuplicatedVerticesOnBoundaryCycles->setProperty("subMenuName", "Polygon Mesh Processing/Repair"); actionAutorefine->setProperty("subMenuName", "Polygon Mesh Processing/Repair/Experimental"); actionAutorefineAndRMSelfIntersections->setProperty("subMenuName", "Polygon Mesh Processing/Repair/Experimental"); @@ -70,6 +77,7 @@ public: << actionRemoveSelfIntersections << actionStitchCloseBorderHalfedges << actionDuplicateNMVertices + << actionMergeDuplicatedVerticesOnBoundaryCycles << actionAutorefine << actionAutorefineAndRMSelfIntersections; } @@ -90,6 +98,8 @@ public: template void on_actionDuplicateNMVertices_triggered(Scene_interface::Item_id index); template + void on_actionMergeDuplicatedVerticesOnBoundaryCycles_triggered(Scene_interface::Item_id index); + template void on_actionAutorefine_triggered(Scene_interface::Item_id index); template void on_actionAutorefineAndRMSelfIntersections_triggered(Scene_interface::Item_id index); @@ -100,6 +110,7 @@ public Q_SLOTS: void on_actionRemoveSelfIntersections_triggered(); void on_actionStitchCloseBorderHalfedges_triggered(); void on_actionDuplicateNMVertices_triggered(); + void on_actionMergeDuplicatedVerticesOnBoundaryCycles_triggered(); void on_actionAutorefine_triggered(); void on_actionAutorefineAndRMSelfIntersections_triggered(); @@ -109,6 +120,7 @@ private: QAction* actionRemoveSelfIntersections; QAction* actionStitchCloseBorderHalfedges; QAction* actionDuplicateNMVertices; + QAction* actionMergeDuplicatedVerticesOnBoundaryCycles; QAction* actionAutorefine; QAction* actionAutorefineAndRMSelfIntersections; @@ -308,4 +320,31 @@ void Polyhedron_demo_repair_polyhedron_plugin::on_actionDuplicateNMVertices_trig QApplication::restoreOverrideCursor(); } +template +void Polyhedron_demo_repair_polyhedron_plugin::on_actionMergeDuplicatedVerticesOnBoundaryCycles_triggered(Scene_interface::Item_id index) +{ + namespace PMP = CGAL::Polygon_mesh_processing; + + if(Item* poly_item = qobject_cast(scene->item(index))) + { + const SMesh::size_type old_nv = vertices(*poly_item->polyhedron()).size(); + PMP::merge_duplicated_vertices_in_boundary_cycles(*poly_item->polyhedron()); + const SMesh::size_type new_nv = vertices(*poly_item->polyhedron()).size(); + CGAL::Three::Three::information(tr(" %1 vertices merged").arg(old_nv - new_nv)); + if(old_nv != new_nv) + { + poly_item->invalidateOpenGLBuffers(); + Q_EMIT poly_item->itemChanged(); + } + } +} + +void Polyhedron_demo_repair_polyhedron_plugin::on_actionMergeDuplicatedVerticesOnBoundaryCycles_triggered() +{ + QApplication::setOverrideCursor(Qt::WaitCursor); + const Scene_interface::Item_id index = scene->mainSelectionIndex(); + on_actionMergeDuplicatedVerticesOnBoundaryCycles_triggered(index); + QApplication::restoreOverrideCursor(); +} + #include "Repair_polyhedron_plugin.moc" From 2280bea679d8c58ff834896dbe1b9bd0d1c3f8ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 10 Mar 2020 10:57:52 +0100 Subject: [PATCH 101/141] add missing inline --- .../Polygon_mesh_processing/orientation.h | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index 8d0ec55f9b2..bd0cffb9bbb 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -487,8 +487,9 @@ void copy_container_content(std::vector& vec, boost::reference_wrapper -inline void copy_container_content(std::vector&, - internal_np::Param_not_found) +inline +void copy_container_content(std::vector&, + internal_np::Param_not_found) {} @@ -512,6 +513,7 @@ void copy_nested_parents( } } +inline void copy_nested_parents( std::vector< std::vector >& nested_parents, std::reference_wrapper > > ref_to_vector) @@ -519,7 +521,7 @@ void copy_nested_parents( nested_parents.swap(ref_to_vector.get()); } - +inline void copy_nested_parents( std::vector< std::vector >& nested_parents, boost::reference_wrapper > > ref_to_vector) @@ -527,7 +529,8 @@ void copy_nested_parents( nested_parents.swap(ref_to_vector.get()); } -inline void copy_nested_parents( +inline +void copy_nested_parents( std::vector< std::vector >&, internal_np::Param_not_found) {} @@ -559,7 +562,8 @@ void copy_cc_to_volume_id( ref_to_vector.get().swap( cc_volume_ids ); } -inline void copy_cc_to_volume_id( +inline +void copy_cc_to_volume_id( std::vector&, internal_np::Param_not_found) {} @@ -572,7 +576,8 @@ void copy_nesting_levels( ref_to_vector.get().swap( nesting_levels ); } -inline void copy_nesting_levels( +inline +void copy_nesting_levels( std::vector&, internal_np::Param_not_found) {} @@ -585,7 +590,8 @@ void copy_orientation_bitset( ref_to_bs.get() = is_cc_outward_oriented; } -inline void copy_orientation_bitset( +inline +void copy_orientation_bitset( const std::vector&, internal_np::Param_not_found) {} @@ -600,7 +606,8 @@ void set_cc_intersecting_pairs(const std::set< std::pair >&, +inline +void set_cc_intersecting_pairs(const std::set< std::pair >&, internal_np::Param_not_found) {} From f05ec48bda7f46c1e73a3e36e51a746e5cbf218c Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Thu, 12 Mar 2020 10:05:52 +0100 Subject: [PATCH 102/141] Add missing BGL dependencies --- .../package_info/Polyline_simplification_2/dependencies | 1 + 1 file changed, 1 insertion(+) diff --git a/Polyline_simplification_2/package_info/Polyline_simplification_2/dependencies b/Polyline_simplification_2/package_info/Polyline_simplification_2/dependencies index ba5bb8645f3..46b60927a44 100644 --- a/Polyline_simplification_2/package_info/Polyline_simplification_2/dependencies +++ b/Polyline_simplification_2/package_info/Polyline_simplification_2/dependencies @@ -1,5 +1,6 @@ Algebraic_foundations Arithmetic_kernel +BGL Cartesian_kernel Circulator Distance_2 From 4c0a3788c3f91a8654916c283b56f83cc536f0c3 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Thu, 12 Mar 2020 11:26:10 +0100 Subject: [PATCH 103/141] Update from review --- .../CGAL/Constrained_triangulation_plus_2.h | 8 ++++---- .../doc/Triangulation_2/Triangulation_2.txt | 11 ++++++----- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Triangulation_2/doc/Triangulation_2/CGAL/Constrained_triangulation_plus_2.h b/Triangulation_2/doc/Triangulation_2/CGAL/Constrained_triangulation_plus_2.h index 2494659dcca..4347b5c7aff 100644 --- a/Triangulation_2/doc/Triangulation_2/CGAL/Constrained_triangulation_plus_2.h +++ b/Triangulation_2/doc/Triangulation_2/CGAL/Constrained_triangulation_plus_2.h @@ -308,10 +308,10 @@ Each computed polyline is stored as a constraint of the triangulation. \warning all existing constraints will be discarded. -\param is_terminal An optional function returning true if the vertex -`v` of degree 2 is a polyline endpoint and false otherwise. If no -function is provided, a default function is provided that returns true -for vertices whose degree is different from 2. +\param is_terminal An optional function returning `true` if the vertex +`v` of degree 2 is a polyline endpoint and `false` otherwise. If +omitted, a function always returning `false` will be used, that is no +degree 2 vertex will be considered as a polyline endpoint. \sa `split_graph_into_polylines()` */ diff --git a/Triangulation_2/doc/Triangulation_2/Triangulation_2.txt b/Triangulation_2/doc/Triangulation_2/Triangulation_2.txt index fc94bccbf5e..312b62eb8fb 100644 --- a/Triangulation_2/doc/Triangulation_2/Triangulation_2.txt +++ b/Triangulation_2/doc/Triangulation_2/Triangulation_2.txt @@ -1128,13 +1128,14 @@ through the edge. The `Constrained_triangulation_plus_2` structure is initialized by a set of polylines. As users may only be able to provide a disconnected -segment soup as input, a member function -[split_subconstraint_graph_into_constraints()](@ref Constrained_triangulation_plus_2::split_subconstraint_graph_into_constraints()) -is provided: this function identifies the polylines by connecting -segments until a vertex whose degree is different than 2 is reached. +segment soup as input, a member function \link +Constrained_triangulation_plus_2::split_subconstraint_graph_into_constraints() +`split_subconstraint_graph_into_constraints()` \endlink is provided: +this function identifies the polylines by connecting segments until a +vertex whose degree is different from 2 is reached. The following code shows how a "blind" insertion of disconnected -polylines can be processed into a set of well-defined polyline +segments can be processed into a set of well-defined polyline constraints in a `Constrained_triangulation_plus_2`: \cgalExample{Triangulation_2/segment_soup_to_polylines.cpp} From 9e72d43784e3cede6cce8232da25012bbca25fb0 Mon Sep 17 00:00:00 2001 From: Sebastien Loriot Date: Tue, 17 Mar 2020 08:21:50 +0100 Subject: [PATCH 104/141] Apply suggestions from code review Co-Authored-By: Mael --- .../doc/Polygon_mesh_processing/NamedParameters.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt index 50b793b45ec..78c38a43a91 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt @@ -423,8 +423,8 @@ flips to recover good shapes, unless specified otherwise (see below). \cgalNPEnd \cgalNPBegin{do_orientation_tests} \anchor PMP_do_orientation_tests -Parameter used in `volume_connected_components()` to indicate if surface orientation test -must be done to decide of the belonging of a surface connected component to a volume. +Parameter used in `volume_connected_components()` to indicate if a surface orientation test +must be performed to decide whether a surface connected component belong to a volume or not. \n \b Type : `bool` \n \b Default value is `true` @@ -443,7 +443,7 @@ connected components. a reference to an object that must be a model of the `BackInsertionSequence` concept, holding the classification of a volume connected component identified by its id. The size of the container is exactly the number of volume connected components and the -object at position `k` in the container correspond to the classification of the volume connected component +object at position `k` in the container corresponds to the classification of the volume connected component assigned the id `k`. \n \b Type: a `reference_wrapper` (either from `boost` or the standard library) @@ -482,7 +482,7 @@ a reference to an object that must be a model of the `BackInsertionSequence` con with a value_type being `std::size_t`. The size of the container is exactly the number of connected components. For each connected component identified using its id `ccid`, the id of the volume it contributes -to describe is the value at the position `ccid` in the parameter container. +to is the value at the position `ccid` in the parameter container. \n \b Type: a `reference_wrapper` (either from `boost` or the standard library) over an object of type `container` \n @@ -495,7 +495,7 @@ a reference to an object that must be a model of the `BackInsertionSequence` con with a value_type being `std::size_t`. The size of the container is exactly the number of connected components. For each connected component identified using its id `ccid`, the container contains the number of -connected components containing on its bounded side this component. +connected components containing on their bounded side this component. \n \b Type: a `reference_wrapper` (either from `boost` or the standard library) over an object of type `container` \n @@ -519,7 +519,7 @@ is the value at the position `ccid` in the parameter container. \cgalParamBegin{intersecting_volume_pairs_output_iterator} Output iterator into which pairs of ids (id must be convertible to `std::size_t`) can be put. Each pair of connected components intersecting will be reported using their ids. -If `do_self_intersection_tests` named parameter is not set to `true`, nothing will be reported. +If `do_self_intersection_tests` named parameter is set to `false`, nothing will be reported. \b Type : a model of `OutputIterator` \n \b Default : `#CGAL::Emptyset_iterator` \cgalParamEnd From d44dad60c224a2d106df40d71d9d65b6d2f108d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 17 Mar 2020 09:50:52 +0100 Subject: [PATCH 105/141] still collect faces if cc_handled as it is used to set the volume id --- .../include/CGAL/Polygon_mesh_processing/orientation.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index bd0cffb9bbb..5db75baa18b 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -912,8 +912,7 @@ volume_connected_components(const TriangleMesh& tm, for(face_descriptor fd : faces(tm)) { std::size_t cc_id = face_cc[ get(fid_map, fd) ]; - if (!cc_handled.test(cc_id)) - faces_per_cc[ cc_id ].push_back(fd); + faces_per_cc[ cc_id ].push_back(fd); } // init the main loop @@ -1173,7 +1172,7 @@ volume_connected_components(const TriangleMesh& tm, for(std::size_t cc_id=0; cc_id Date: Tue, 17 Mar 2020 10:19:34 +0100 Subject: [PATCH 106/141] fix indentation --- .../Polygon_mesh_processing/orientation.h | 59 +++++++++++-------- 1 file changed, 34 insertions(+), 25 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index 5db75baa18b..83e3e871279 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -465,8 +465,11 @@ enum Volume_error_code { VALID_VOLUME, ///< The set of faces bounds a volume }; namespace internal { +// helper function to copy data template -void copy_container_content(const std::vector& vec, RefToContainer ref_wrapper) +void copy_container_content( + const std::vector& vec, + RefToContainer ref_wrapper) { ref_wrapper.get().reserve(vec.size()); for(const T& t : vec) @@ -476,23 +479,28 @@ void copy_container_content(const std::vector& vec, RefToContainer ref_wrappe } template -void copy_container_content(std::vector& vec, std::reference_wrapper > ref_wrapper) +void copy_container_content( + std::vector& vec, + std::reference_wrapper > ref_wrapper) { vec.swap(ref_wrapper.get()); } template -void copy_container_content(std::vector& vec, boost::reference_wrapper > ref_wrapper) +void copy_container_content( + std::vector& vec, + boost::reference_wrapper > ref_wrapper) { vec.swap(ref_wrapper.get()); } + template inline -void copy_container_content(std::vector&, - internal_np::Param_not_found) +void copy_container_content( + std::vector&, + internal_np::Param_not_found) {} - template void copy_nested_parents( const std::vector< std::vector >& nested_parents, @@ -506,10 +514,9 @@ void copy_nested_parents( { Container_value c; c.reserve(t.size()); - for(const std::size_t& val : t){ + for(const std::size_t& val : t) c.push_back(val); - } - ref_to_vector.get().push_back(c); + ref_to_vector.get().push_back(c); } } @@ -535,23 +542,25 @@ void copy_nested_parents( internal_np::Param_not_found) {} + +// helper function for setting id maps template -void set_f_cc_id(const std::vector& f_cc, - FaceIndexMap face_index_map, - FaceCCIdMap face_cc_map, - const TriangleMesh& tm) +void set_f_cc_id( + const std::vector& f_cc, + FaceIndexMap face_index_map, + FaceCCIdMap face_cc_map, + const TriangleMesh& tm) { for(typename boost::graph_traits::face_descriptor fd : faces(tm)) - { put(face_cc_map, fd, f_cc[ get(face_index_map, fd) ]); - } } template -void set_f_cc_id(const std::vector&, - FaceIndexMap, - internal_np::Param_not_found, - const TriangleMesh&) +void set_f_cc_id( + const std::vector&, + FaceIndexMap, + internal_np::Param_not_found, + const TriangleMesh&) {} template @@ -597,18 +606,18 @@ void copy_orientation_bitset( {} template -void set_cc_intersecting_pairs(const std::set< std::pair >& self_intersecting_cc, - OutputIterator out) +void set_cc_intersecting_pairs( + const std::set< std::pair >& self_intersecting_cc, + OutputIterator out) { for (const std::pair& p : self_intersecting_cc) - { *out++=p; - } } inline -void set_cc_intersecting_pairs(const std::set< std::pair >&, - internal_np::Param_not_found) +void set_cc_intersecting_pairs( + const std::set< std::pair >&, + internal_np::Param_not_found) {} } // internal From 8d00b92bbac36e635127a0e88f16e19277800c8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 17 Mar 2020 10:20:04 +0100 Subject: [PATCH 107/141] add precondition --- .../include/CGAL/Polygon_mesh_processing/orientation.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index 83e3e871279..175f2d931c6 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -1245,7 +1245,7 @@ bool does_bound_a_volume(const TriangleMesh& tm, const NamedParameters& np) typedef typename GT::face_descriptor face_descriptor; if (!is_closed(tm)) return false; - if (!is_triangle_mesh(tm)) return false; + CGAL_precondition(is_triangle_mesh(tm)); Static_property_map vidmap(0); // dummy map not used std::size_t res = From 6b8f85495f53d80eb5ae3713d7f1bf52ebb8601e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 17 Mar 2020 10:24:57 +0100 Subject: [PATCH 108/141] remove extra spaces --- .../Polygon_mesh_processing/orientation.h | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index 175f2d931c6..b623a03fb70 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -1108,7 +1108,7 @@ volume_connected_components(const TriangleMesh& tm, for(std::size_t ncc_id : nested_cc_per_cc[cc_id]) { - if ( nesting_levels[ncc_id]==nesting_levels[cc_id]+1 ) + if (nesting_levels[ncc_id]==nesting_levels[cc_id]+1) { cc_handled.set(ncc_id); if (!ignore_orientation_of_cc) @@ -1131,20 +1131,20 @@ volume_connected_components(const TriangleMesh& tm, } if (is_involved_in_self_intersection[ncc_id]) { - cc_volume_ids[ncc_id] = next_volume_id++; - error_codes.push_back(VOLUME_INTERSECTION); - for(std::size_t nncc_id : nested_cc_per_cc[ncc_id]) + cc_volume_ids[ncc_id] = next_volume_id++; + error_codes.push_back(VOLUME_INTERSECTION); + for(std::size_t nncc_id : nested_cc_per_cc[ncc_id]) + { + if (cc_handled.test(nncc_id)) { - if (cc_handled.test(nncc_id)) - { - error_codes[ cc_volume_ids[nncc_id] ] = VOLUME_INTERSECTION; - continue; - } - cc_handled.set(nncc_id); - cc_volume_ids[nncc_id] = next_volume_id++; - error_codes.push_back(VOLUME_INTERSECTION); + error_codes[ cc_volume_ids[nncc_id] ] = VOLUME_INTERSECTION; + continue; } - continue; + cc_handled.set(nncc_id); + cc_volume_ids[nncc_id] = next_volume_id++; + error_codes.push_back(VOLUME_INTERSECTION); + } + continue; } cc_volume_ids[ncc_id] = cc_volume_ids[cc_id]; } From b26905f2e6dd1cd9afd45b79f03d6b78dda9f5cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 17 Mar 2020 10:31:51 +0100 Subject: [PATCH 109/141] doc requirement on vpm --- .../include/CGAL/Polygon_mesh_processing/orientation.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index b623a03fb70..00e9c3ac04b 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -157,7 +157,10 @@ namespace internal{ * @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 `pmesh` \cgalParamEnd + * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh` + * If this parameter is omitted, an internal property map for + * `CGAL::vertex_point_t` must be available in `TriangleMesh` + * \cgalParamEnd * \cgalParamBegin{geom_traits} a geometric traits class instance \cgalParamEnd * \cgalNamedParamsEnd * @@ -181,7 +184,6 @@ bool is_outward_oriented(const PolygonMesh& pmesh, if (faces(pmesh).first == faces(pmesh).second) return true; - using parameters::get_parameter; //VertexPointMap @@ -676,6 +678,8 @@ void set_cc_intersecting_pairs( * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} * the property map with the points associated to the vertices of `tm`. + * If this parameter is omitted, an internal property map for + * `CGAL::vertex_point_t` must be available in `TriangleMesh` * \cgalParamEnd * \cgalParamBegin{face_index_map} * a property map containing a unique id per face of `tm`, in the range `[0, num_faces(tm)[`. From 440f9f1e77dd834e35ad5da7f1e606167c4bef60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 17 Mar 2020 10:49:33 +0100 Subject: [PATCH 110/141] remove todo that it does not worth implement --- .../include/CGAL/Polygon_mesh_processing/orientation.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index 00e9c3ac04b..887dfcdbbc6 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -164,8 +164,9 @@ namespace internal{ * \cgalParamBegin{geom_traits} a geometric traits class instance \cgalParamEnd * \cgalNamedParamsEnd * - * \todo code : The following only handles polyhedron with one connected component - * the code, the sample example and the plugin must be updated. + * \note This function is only doing an orientation test for one connected component of `pmesh`. + * For performance reason, it is left to the user to call the function `does_bound_a_volume()` + * on a triangulated version of `pmesh` to ensure the result returned is relevant. * * \sa `CGAL::Polygon_mesh_processing::reverse_face_orientations()` */ @@ -173,7 +174,7 @@ template bool is_outward_oriented(const PolygonMesh& pmesh, const NamedParameters& np) { - CGAL_warning(CGAL::is_closed(pmesh)); + CGAL_warning(CGAL::does_bound_a_volume(pmesh)); CGAL_precondition(CGAL::is_valid_polygon_mesh(pmesh)); #ifdef CGAL_PMP_DEBUG_CODE From b032917945e97c046af3f24441c7ad796ed20117 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 17 Mar 2020 11:09:08 +0100 Subject: [PATCH 111/141] more doc --- .../include/CGAL/Polygon_mesh_processing/orientation.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index 887dfcdbbc6..3d0d5c289a4 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -167,6 +167,7 @@ namespace internal{ * \note This function is only doing an orientation test for one connected component of `pmesh`. * For performance reason, it is left to the user to call the function `does_bound_a_volume()` * on a triangulated version of `pmesh` to ensure the result returned is relevant. + * For advanced usages, the function `volume_connected_components()` should be used instead. * * \sa `CGAL::Polygon_mesh_processing::reverse_face_orientations()` */ @@ -174,7 +175,7 @@ template bool is_outward_oriented(const PolygonMesh& pmesh, const NamedParameters& np) { - CGAL_warning(CGAL::does_bound_a_volume(pmesh)); + CGAL_warning(CGAL::is_closed(pmesh)); CGAL_precondition(CGAL::is_valid_polygon_mesh(pmesh)); #ifdef CGAL_PMP_DEBUG_CODE From d8e2691bfa4a6dbacc18e980bc1a1a7693d2ef83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 17 Mar 2020 11:10:21 +0100 Subject: [PATCH 112/141] typo --- .../include/CGAL/Polygon_mesh_processing/orientation.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index 3d0d5c289a4..213b677dfcb 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -165,7 +165,7 @@ namespace internal{ * \cgalNamedParamsEnd * * \note This function is only doing an orientation test for one connected component of `pmesh`. - * For performance reason, it is left to the user to call the function `does_bound_a_volume()` + * For performance reasons, it is left to the user to call the function `does_bound_a_volume()` * on a triangulated version of `pmesh` to ensure the result returned is relevant. * For advanced usages, the function `volume_connected_components()` should be used instead. * From 60a846a04b5f024715db04d8fb4420eb890391b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 17 Mar 2020 11:19:35 +0100 Subject: [PATCH 113/141] update changes --- Installation/CHANGES.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Installation/CHANGES.md b/Installation/CHANGES.md index 736a64839c6..cc15c174af2 100644 --- a/Installation/CHANGES.md +++ b/Installation/CHANGES.md @@ -28,7 +28,9 @@ Release date: June 2020 components that would be removed with the specified threshold, but without actually removing them. - The function `CGAL::Polygon_mesh_processing::stitch_borders()` now returns the number of halfedge pairs that were stitched. - +- Added the function `CGAL::Polygon_mesh_processing::volume_connected_component()` that can be used to + get information about the nesting of the connected components of a given triangle mesh and about + the volumes defined. ### 2D Triangulations - To fix an inconsistency between code and documentation and to clarify which types of intersections are truly allowed in constrained Delaunay triangulations, the tag `CGAL::No_intersection_tag` From f4b5f4f7a03c3025a0d45d6abde6ee8ff340a888 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 17 Mar 2020 11:31:04 +0100 Subject: [PATCH 114/141] add sentense in the user manual --- .../doc/Polygon_mesh_processing/Polygon_mesh_processing.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt index 78477966ade..20ef2f48645 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt @@ -589,6 +589,9 @@ an oriented polygon mesh is oriented such that the normals to all faces are orie outside of the domain bounded by the input polygon mesh. - The function `CGAL::Polygon_mesh_processing::reverse_face_orientations()` reverses the orientation of halfedges around faces. +- The function `CGAL::Polygon_mesh_processing::volume_connected_component()` provides information about +the 3D arrangement of the surface connected components in a given triangle mesh. It comes with many +named parameter options making it also a more general version of `is_outward_oriented()`. As a consequence, the normal computed for each face (see Section \ref PMPNormalComp) is also reversed. From 2378b0199d9f27f04e04841b57cc45759aae528c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 17 Mar 2020 11:38:27 +0100 Subject: [PATCH 115/141] "fix position" --- .../doc/Polygon_mesh_processing/Polygon_mesh_processing.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt index 20ef2f48645..fc6cdb63d86 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt @@ -589,11 +589,12 @@ an oriented polygon mesh is oriented such that the normals to all faces are orie outside of the domain bounded by the input polygon mesh. - The function `CGAL::Polygon_mesh_processing::reverse_face_orientations()` reverses the orientation of halfedges around faces. +As a consequence, the normal computed for each face (see Section +\ref PMPNormalComp) is also reversed. - The function `CGAL::Polygon_mesh_processing::volume_connected_component()` provides information about the 3D arrangement of the surface connected components in a given triangle mesh. It comes with many named parameter options making it also a more general version of `is_outward_oriented()`. -As a consequence, the normal computed for each face (see Section -\ref PMPNormalComp) is also reversed. + \subsection PolygonSoupExample Orientation Example From dc85217d5a0ea610b786c003a9f0feeb22eb303c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 17 Mar 2020 15:49:46 +0100 Subject: [PATCH 116/141] fixes after @afabri's review --- .../NamedParameters.txt | 8 +- .../Polygon_mesh_processing.txt | 2 +- .../volume_connected_components.cpp | 10 ++- .../Polygon_mesh_processing/orientation.h | 82 +++++++------------ .../test_split_volume.cpp | 6 +- 5 files changed, 45 insertions(+), 63 deletions(-) diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt index 78c38a43a91..ad45fc0e9cc 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt @@ -476,7 +476,7 @@ and directed outside the finite volume enclosed by the surface connected compone \b Default: None \cgalNPEnd -\cgalParamBegin{connected_component_id_to_volume_id} +\cgalParamBegin{connected_component_id_to_volume_id} \anchor PMP_connected_component_id_to_volume_id a `reference_wrapper` (either from `boost` or the standard library) containing a reference to an object that must be a model of the `BackInsertionSequence` concept, with a value_type being `std::size_t`. @@ -489,7 +489,7 @@ to is the value at the position `ccid` in the parameter container. \b Default: None \cgalParamEnd -\cgalParamBegin{nesting_levels} +\cgalParamBegin{nesting_levels} \anchor PMP_nesting_levels a `reference_wrapper` (either from `boost` or the standard library) containing a reference to an object that must be a model of the `BackInsertionSequence` concept, with a value_type being `std::size_t`. @@ -502,7 +502,7 @@ connected components containing on their bounded side this component. \b Default: None \cgalParamEnd -\cgalParamBegin{is_cc_outward_oriented} +\cgalParamBegin{is_cc_outward_oriented} \anchor PMP_is_cc_outward_oriented a `reference_wrapper` (either from `boost` or the standard library) containing a reference to an object that must be a model of the `BackInsertionSequence` concept, with a value_type being `bool`. @@ -516,7 +516,7 @@ is the value at the position `ccid` in the parameter container. \b Default: None \cgalParamEnd -\cgalParamBegin{intersecting_volume_pairs_output_iterator} +\cgalParamBegin{intersecting_volume_pairs_output_iterator} \anchor PMP_intersecting_volume_pairs_output_iterator Output iterator into which pairs of ids (id must be convertible to `std::size_t`) can be put. Each pair of connected components intersecting will be reported using their ids. If `do_self_intersection_tests` named parameter is set to `false`, nothing will be reported. diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt index fc6cdb63d86..330a419e1e0 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt @@ -591,7 +591,7 @@ outside of the domain bounded by the input polygon mesh. of halfedges around faces. As a consequence, the normal computed for each face (see Section \ref PMPNormalComp) is also reversed. -- The function `CGAL::Polygon_mesh_processing::volume_connected_component()` provides information about +- The function `CGAL::Polygon_mesh_processing::volume_connected_components()` provides information about the 3D arrangement of the surface connected components in a given triangle mesh. It comes with many named parameter options making it also a more general version of `is_outward_oriented()`. diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/volume_connected_components.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/volume_connected_components.cpp index b7773d1ddb1..948706a87df 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/volume_connected_components.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/volume_connected_components.cpp @@ -2,7 +2,6 @@ #include #include #include -#include #include #include @@ -12,6 +11,7 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; typedef CGAL::Surface_mesh Surface_mesh; namespace PMP = CGAL::Polygon_mesh_processing; +namespace params = CGAL::parameters; int main(int argc, char** argv) { @@ -25,8 +25,12 @@ int main(int argc, char** argv) Surface_mesh::Property_map vol_id_map = sm.add_property_map().first; + std::vector err_codes; // fill the volume id map - std::size_t nb_vol = PMP::volume_connected_components(sm, vol_id_map); + std::size_t nb_vol = + PMP::volume_connected_components(sm, + vol_id_map, + params::error_codes(std::ref(err_codes))); std::cout << "Found " << nb_vol << " volumes\n"; @@ -35,6 +39,8 @@ int main(int argc, char** argv) Filtered_graph vol_mesh(sm, 0, vol_id_map); for(std::size_t id = 0; id < nb_vol; ++id) { + if (err_codes[id] != PMP::VALID_VOLUME) + std::cerr << "There is an issue with volume #" << id << "\n"; if(id > 0) vol_mesh.set_selected_faces(id, vol_id_map); Surface_mesh out; diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index 213b677dfcb..aeb21c78429 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -461,11 +461,10 @@ void orient(TriangleMesh& tm) * in the case of `VALID_VOLUME` or a surface connected component otherwise. */ enum Volume_error_code { VALID_VOLUME, ///< The set of faces bounds a volume - SURFACE_SELF_INTERSECTION, ///< The set of faces is self-intersecting + SURFACE_WITH_SELF_INTERSECTIONS, ///< The set of faces is self-intersecting VOLUME_INTERSECTION, ///< The set of faces intersects another surface connected component - OPEN_SURFACE, ///< The set of faces does not define a close surface - INCOMPATIBLE_ORIENTATION, ///< The set of faces is included in a volume but has an incompatible orientation - SINGLE_CONNECTED_COMPONENT ///< The set of faces consists of all the faces of the mesh and no further test was done. + SURFACE_WITH_BOUNDARIES, ///< The set of faces does not define a closed surface + INCOMPATIBLE_ORIENTATION ///< The set of faces is included in a volume but has an incompatible orientation }; namespace internal { @@ -630,7 +629,7 @@ void set_cc_intersecting_pairs( /*! * \ingroup PMP_orientation_grp * assigns to each face of `tm` an id corresponding to the volume connected component - * it contributes to define. + * it contributes to. * * Using the adjacency relation of two faces along an edge, a triangle mesh can be split * into connected components (*surface components* in the following). @@ -642,23 +641,20 @@ void set_cc_intersecting_pairs( * Each surface component `S` that is outside any volume enclosed by * another surface component defines the *outer boundary* of a volume component. * Each surface component that is inside the volume enclosed by `S` - * defines a *hole* if it is included in no other volume enclosed by a surface components + * defines a *hole* if it is included in no other volume enclosed by a surface component * but `S`. Ignoring the identified volume component, the same procedure is recursively * repeated for all surface components in each hole. * * There are some special cases: - * - a non-closed surface component is reported as an isolated volume ignoring any inclusion test - * - a self-intersecting surface component is reported as an isolated volume ignoring any inclusion test + * - a non-closed surface component is reported as a volume component ignoring any inclusion test + * - a self-intersecting surface component is reported as a volume component ignoring any inclusion test * - a surface component intersecting another surface component - * is reported as an isolated volume, and so are all the surface components inside its - * enclosed volume. - * - if `do_orientation_tests` is `true`, if the holes are not all equally oriented + * is reported as a volume component, and so are all the surface components inside its + * enclosed volume + * - if `do_orientation_tests` is set to `true`, if the holes are not all equally oriented * (all inward or all outward) or if the holes and the outer boundary are equally - * oriented, each surface component is reported as an isolated volume, - * and so are all the surface components inside the corresponding enclosed volumes. - * - If all the faces of `tm` are part of the same surface component, then - * no further test (open/closed, self-intersecting) is done and all faces - * are assigned to the same volume components. + * oriented, each surface component is reported as a volume component, + * and so are all the surface components inside the corresponding enclosed volumes * - If `do_orientation_tests` is set to `true` and the surface components that are * outside all enclosed volumes are inward oriented, they are then considered as holes * of the unbounded volume (that has no outer boundary) @@ -684,11 +680,11 @@ void set_cc_intersecting_pairs( * `CGAL::vertex_point_t` must be available in `TriangleMesh` * \cgalParamEnd * \cgalParamBegin{face_index_map} - * a property map containing a unique id per face of `tm`, in the range `[0, num_faces(tm)[`. + * a property map containing a unique id per face of `tm`, in the range `[0, num_faces(tm)[` * \cgalParamEnd * \cgalParamBegin{face_connected_component_map} * a property map filled by this function and that will contain for each face the id - * of its surface component in the range `[0, number of surface components - 1[`. + * of its surface component in the range `[0, number of surface components - 1[` * \cgalParamEnd * \cgalParamBegin{volume_inclusions} * a `reference_wrapper` (either from `boost` or the standard library) containing @@ -709,8 +705,8 @@ void set_cc_intersecting_pairs( * \cgalParamEnd * \cgalParamBegin{error_codes} * a `reference_wrapper` (either from `boost` or the standard library) containing - * a reference to an object that must be a model of the `BackInsertionSequence` concept, - * with a value_type being `Volume_error_code`. + * a reference to a container that must be a model of the `BackInsertionSequence` concept, + * with a `value_type` being \link CGAL::Polygon_mesh_processing::Volume_error_code `Volume_error_code` \endlink. * The size of the container is exactly the number of volume components. * The container indicates the status of a volume assigned to a set of faces. * The description of the value type is given in the documentation of the enumeration type. @@ -722,33 +718,33 @@ void set_cc_intersecting_pairs( * \cgalParamEnd * \cgalParamBegin{connected_component_id_to_volume_id} * a `reference_wrapper` (either from `boost` or the standard library) containing - * a reference to an object that must be a model of the `BackInsertionSequence` concept, + * a reference to a container that must be a model of the `BackInsertionSequence` concept, * with a value_type being `std::size_t`. * The size of the container is exactly the number of connected components. * For each connected component identified using its id `ccid`, the id of the volume it contributes - * to describe is the value at the position `ccid` in the parameter container. + * to describe is the value at the position `ccid` in the container. * \cgalParamEnd * \cgalParamBegin{nesting_levels} * a `reference_wrapper` (either from `boost` or the standard library) containing - * a reference to an object that must be a model of the `BackInsertionSequence` concept, - * with a value_type being `std::size_t`. + * a reference to a container that must be a model of the `BackInsertionSequence` concept, + * with a `value_type` being `std::size_t`. * The size of the container is exactly the number of connected components. - * For each connected component identified using its id `ccid`, the vector contains the number of + * For each connected component identified using its id `ccid`, the container contains the number of * connected components containing on its bounded side this component. * \cgalParamEnd * \cgalParamBegin{is_cc_outward_oriented} * a `reference_wrapper` (either from `boost` or the standard library) containing - * a reference to an object that must be a model of the `BackInsertionSequence` concept, - * with a value_type being `bool`. + * a reference to a container that must be a model of the `BackInsertionSequence` concept, + * with a `value_type` being `bool`. * The size of the container is exactly the number of connected components. - * For each connected component identified using its id `ccid`, the output of `is_outward_oriented` - * called on the submesh corresponding to this connected component - * is the value at the position `ccid` in the parameter vector. + * For each connected component identified using its id `ccid`, the output of `is_outward_oriented()` + * called on the triangle mesh corresponding to this connected component + * is the value at the position `ccid` in the container. * \cgalParamEnd * \cgalParamBegin{intersecting_volume_pairs_output_iterator} * Output iterator into which pairs of ids (id must be convertible to `std::size_t`) can be put. * Each pair of connected components intersecting will be reported using their ids. - * If `do_self_intersection_tests` named parameter is not set to `true`, nothing will be reported. + * If `do_self_intersection_tests` named parameter is set to `false`, nothing will be reported. * \cgalParamEnd * * \cgalNamedParamsEnd @@ -811,26 +807,6 @@ volume_connected_components(const TriangleMesh& tm, std::vector cc_volume_ids(nb_cc, -1); std::vector < std::size_t > nesting_levels(nb_cc, 0); // indicates for each CC its nesting level - if (nb_cc == 1) - { - error_codes.push_back(SINGLE_CONNECTED_COMPONENT); - - for(face_descriptor fd : faces(tm)) - put(volume_id_map, fd, 0); - - internal::copy_container_content(error_codes, parameters::get_parameter(np, internal_np::error_codes)); - // nested_cc_per_cc is empty and used to clear the vector passed in case it was not empty - internal::copy_nested_parents(nested_cc_per_cc, parameters::get_parameter(np, internal_np::volume_inclusions)); - if (!ignore_orientation_of_cc && - !parameters::is_default_parameter(parameters::get_parameter(np, internal_np::is_cc_outward_oriented))) - { - is_cc_outward_oriented.push_back(is_outward_oriented(tm, np)); - internal::copy_container_content(is_cc_outward_oriented, parameters::get_parameter(np, internal_np::is_cc_outward_oriented)); - } - internal::copy_container_content(cc_volume_ids, parameters::get_parameter(np, internal_np::connected_component_id_to_volume_id)); - return 1; - } - boost::dynamic_bitset<> cc_handled(nb_cc, 0); std::size_t next_volume_id = 0; @@ -845,7 +821,7 @@ volume_connected_components(const TriangleMesh& tm, { cc_handled.set(cc_id); cc_volume_ids[cc_id]=next_volume_id++; - error_codes.push_back(OPEN_SURFACE); + error_codes.push_back(SURFACE_WITH_BOUNDARIES); if (used_as_a_predicate) return 0; } } @@ -873,7 +849,7 @@ volume_connected_components(const TriangleMesh& tm, { cc_handled.set(first_cc_id); cc_volume_ids[first_cc_id]=next_volume_id++; - error_codes.push_back(SURFACE_SELF_INTERSECTION); + error_codes.push_back(SURFACE_WITH_SELF_INTERSECTIONS); } } else diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_split_volume.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_split_volume.cpp index 2637ae47c46..611e23e5477 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_split_volume.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_split_volume.cpp @@ -83,7 +83,7 @@ int main() assert(nb_vol==2); expected_result.clear(); expected_result.push_back(PMP::VALID_VOLUME); - expected_result.push_back(PMP::SURFACE_SELF_INTERSECTION); + expected_result.push_back(PMP::SURFACE_WITH_SELF_INTERSECTIONS); std::sort(error_codes.begin(), error_codes.end()); assert( error_codes==expected_result ); } @@ -101,7 +101,7 @@ int main() assert(nb_vol==1); expected_result.clear(); - expected_result.push_back(PMP::SINGLE_CONNECTED_COMPONENT); + expected_result.push_back(PMP::VALID_VOLUME); assert( error_codes==expected_result ); } @@ -122,7 +122,7 @@ int main() assert(nb_vol==2); expected_result.clear(); expected_result.push_back(PMP::VALID_VOLUME); - expected_result.push_back(PMP::OPEN_SURFACE); + expected_result.push_back(PMP::SURFACE_WITH_BOUNDARIES); std::sort(error_codes.begin(), error_codes.end()); assert( error_codes==expected_result ); } From e437fe049ae473b67d6668702fb0cd134d55c530 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 17 Mar 2020 16:04:38 +0100 Subject: [PATCH 117/141] fix link --- .../include/CGAL/Polygon_mesh_processing/orientation.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index aeb21c78429..1a70add698f 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -706,7 +706,7 @@ void set_cc_intersecting_pairs( * \cgalParamBegin{error_codes} * a `reference_wrapper` (either from `boost` or the standard library) containing * a reference to a container that must be a model of the `BackInsertionSequence` concept, - * with a `value_type` being \link CGAL::Polygon_mesh_processing::Volume_error_code `Volume_error_code` \endlink. + * with a `value_type` being \link PMP_orientation_grp `Volume_error_code` \endlink * The size of the container is exactly the number of volume components. * The container indicates the status of a volume assigned to a set of faces. * The description of the value type is given in the documentation of the enumeration type. From 08872b80d0d0c4de6b38ee7429b1abd276619234 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 17 Mar 2020 16:07:49 +0100 Subject: [PATCH 118/141] try to fix conflict with master --- Installation/CHANGES.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Installation/CHANGES.md b/Installation/CHANGES.md index cc15c174af2..35b6df4eca2 100644 --- a/Installation/CHANGES.md +++ b/Installation/CHANGES.md @@ -23,14 +23,17 @@ Release date: June 2020 - Introduced a new function, `CGAL::Polygon_mesh_processing::remove_connected_components_of_negligible_size()`, which can be used to remove connected components whose area or volume is under a certain threshold. Area and volume thresholds are either specified by the user or deduced from the bounding box of the mesh. +- Added the function `CGAL::Polygon_mesh_processing::volume_connected_component()` that can be used to + get information about the nesting of the connected components of a given triangle mesh and about + the volumes defined. - Added a new named parameter for `keep_large_connected_components()` and `remove_connected_components_of_negligible_size` that can be used to perform a dry run of the operation, meaning that the function will return the number of connected components that would be removed with the specified threshold, but without actually removing them. - The function `CGAL::Polygon_mesh_processing::stitch_borders()` now returns the number of halfedge pairs that were stitched. -- Added the function `CGAL::Polygon_mesh_processing::volume_connected_component()` that can be used to - get information about the nesting of the connected components of a given triangle mesh and about - the volumes defined. + - Added parallel versions of the functions `CGAL::Polygon_mesh_processing::does_self_intersect()` + and `CGAL::Polygon_mesh_processing::self_intersections()`. + ### 2D Triangulations - To fix an inconsistency between code and documentation and to clarify which types of intersections are truly allowed in constrained Delaunay triangulations, the tag `CGAL::No_intersection_tag` From 5bf302092d39b57a00cee1edccec310eb3061edc Mon Sep 17 00:00:00 2001 From: Mael Date: Wed, 18 Mar 2020 08:49:05 +0100 Subject: [PATCH 119/141] Update comments --- .../CGAL/Polygon_mesh_processing/merge_border_vertices.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/merge_border_vertices.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/merge_border_vertices.h index 2fd05b5273c..36b80b9cc23 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/merge_border_vertices.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/merge_border_vertices.h @@ -61,6 +61,11 @@ struct Less_on_point_of_target const VertexPointMap& vpm; }; +// Given a vector of pairs of halfedges whose target are geometrically indentical, +// check that the intervals described by these pairs are either disjoint or nested. +// This is done to ensure valid combinatorics when we merge the vertices. +// If incompatible (overlapping) intervals are found, the pair representating the longest +// interval (arbitrary choice) is removed from the candidate list. template void sanitize_candidates(const std::vector::halfedge_descriptor, std::size_t> >& cycle_hedges, std::vector >& candidate_hedges_with_id, @@ -185,8 +190,7 @@ void detect_identical_mergeable_vertices( } } - // check that intervals are disjoint or strictly nested - // if there is only one issue we drop the whole cycle. + // Check that intervals are disjoint or strictly nested sanitize_candidates(cycle_hedges, candidate_hedges_with_id, vpm, pm); for(const std::vector& candidates : candidate_hedges_with_id) From 38abfdfa1f1c56c364b138a9458236369d3d4ed3 Mon Sep 17 00:00:00 2001 From: Mael Date: Wed, 18 Mar 2020 08:51:09 +0100 Subject: [PATCH 120/141] Tiny clarification --- .../CGAL/Polygon_mesh_processing/merge_border_vertices.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/merge_border_vertices.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/merge_border_vertices.h index 36b80b9cc23..8fa56070cb1 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/merge_border_vertices.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/merge_border_vertices.h @@ -61,7 +61,7 @@ struct Less_on_point_of_target const VertexPointMap& vpm; }; -// Given a vector of pairs of halfedges whose target are geometrically indentical, +// Given a container of vectors of halfedges whose target are geometrically indentical, // check that the intervals described by these pairs are either disjoint or nested. // This is done to ensure valid combinatorics when we merge the vertices. // If incompatible (overlapping) intervals are found, the pair representating the longest From 8a6bdd90b34a79e4a753cfa7740df5043bd87b8a Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 19 Mar 2020 11:31:35 +0100 Subject: [PATCH 121/141] Fix after review --- Intersections_2/include/CGAL/Intersection_traits_2.h | 6 +++--- .../internal/Triangle_2_Triangle_2_intersection_impl.h | 2 +- .../internal/Iso_cuboid_3_Plane_3_intersection.h | 3 ++- .../test/Intersections_3/test_intersections_3.cpp | 4 ++++ 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/Intersections_2/include/CGAL/Intersection_traits_2.h b/Intersections_2/include/CGAL/Intersection_traits_2.h index 3d1bd3c77f9..b449bfc2341 100644 --- a/Intersections_2/include/CGAL/Intersection_traits_2.h +++ b/Intersections_2/include/CGAL/Intersection_traits_2.h @@ -110,9 +110,9 @@ struct Intersection_traits { typedef typename Intersection_traits::result_type result_type; }; -template -struct Intersection_traits { - typedef typename Intersection_traits::result_type result_type; +template +struct Intersection_traits { + typedef typename Intersection_traits::result_type result_type; }; template diff --git a/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h b/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h index 0d1cc8c9462..8cd451c6d9e 100644 --- a/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h +++ b/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h @@ -339,7 +339,7 @@ struct Is_cw { bool operator()(const std::vector& ps) { - return !CGAL::left_turn(ps[0], ps[1], ps[2]); + return CGAL::right_turn(ps[0], ps[1], ps[2]); } }; diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h index 831d162553d..1545070f5d8 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h @@ -302,9 +302,10 @@ intersection( { bool first_found = false; Point_3 first_p; + typename K::Has_on_3 has_on; for(const auto &p : filtered_points) { - if(line.has_on(p)) + if(has_on(line, p)) { if(!first_found) { diff --git a/Intersections_3/test/Intersections_3/test_intersections_3.cpp b/Intersections_3/test/Intersections_3/test_intersections_3.cpp index 02dd5145459..73d72640c32 100644 --- a/Intersections_3/test/Intersections_3/test_intersections_3.cpp +++ b/Intersections_3/test/Intersections_3/test_intersections_3.cpp @@ -584,6 +584,10 @@ struct Test { check_intersection (tet, L(P(0.25,0.25,0), P(0.25,0,0.25)), S(P(0.25,0,0.25), P(0.25,0.25,0))); //through one edge check_intersection (tet, L(P(0.5,-0.5,0.5), P(0.5,0.5,0.5)), P(0.5,0,0.5)); + //in a single face through 2 edges + check_intersection (tet, L(P(0.0,0.5,0.0), P(0.5,0.5,0.0)), S(P(0.0,0.5,0.0), P(0.5, 0.5, 0.0) )); + //in a single face through 1 vertex and 1 edge + check_intersection (tet, L(P(0.0,0.5,0.0), P(1.0,0.0,0.0)), S(P(0.0,0.5,0.0), P(1.0, 0.0, 0.0) )); } } From ce4cbe6d0662445dce4c7338323ee1add2b27d5d Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 19 Mar 2020 11:41:57 +0100 Subject: [PATCH 122/141] Fix licenses --- .../CGAL/Intersections_2/Bbox_2_Bbox_2.h | 17 ++++------------- .../Intersections_2/Bbox_2_Iso_rectangle_2.h | 13 ++----------- .../CGAL/Intersections_2/Bbox_2_Segment_2.h | 13 ++----------- .../CGAL/Intersections_2/Bbox_2_Triangle_2.h | 13 ++----------- .../CGAL/Intersections_2/Circle_2_Ray_2.h | 13 ++----------- .../CGAL/Intersections_2/Circle_2_Segment_2.h | 13 ++----------- .../CGAL/Intersections_2/Circle_2_Triangle_2.h | 13 ++----------- .../Iso_cuboid_3_Plane_3_intersection.h | 13 ++----------- .../Tetrahedron_3_Line_3_intersection.h | 13 ++----------- .../Tetrahedron_3_Plane_3_intersection.h | 13 ++----------- .../internal/Tetrahedron_3_Ray_3_intersection.h | 13 ++----------- .../Tetrahedron_3_Segment_3_intersection.h | 13 ++----------- .../Tetrahedron_3_Triangle_3_intersection.h | 13 ++----------- .../internal/tetrahedron_intersection_helpers.h | 13 ++----------- .../tetrahedron_lines_intersections_3.h | 13 ++----------- 15 files changed, 32 insertions(+), 167 deletions(-) diff --git a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Bbox_2.h b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Bbox_2.h index 3fae935f659..9b75f968c2e 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Bbox_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Bbox_2.h @@ -1,20 +1,11 @@ -// Copyright (c) 2019 -// GeometryFactory (France). All rights reserved. +// Copyright (c) 2019 GeometryFactory (France). +// All rights reserved. // -// This file is part of CGAL (www.cgal.org); you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public License as -// published by the Free Software Foundation; either version 3 of the License, -// or (at your option) any later version. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// This file is part of CGAL (www.cgal.org) // // $URL$ // $Id$ -// SPDX-License-Identifier: LGPL-3.0+ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // // Author(s) : Maxime Gimeno diff --git a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Iso_rectangle_2.h b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Iso_rectangle_2.h index a4fadb75961..1ada75030d3 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Iso_rectangle_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Iso_rectangle_2.h @@ -1,20 +1,11 @@ // Copyright (c) 2019 // GeometryFactory (France). All rights reserved. // -// This file is part of CGAL (www.cgal.org); you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public License as -// published by the Free Software Foundation; either version 3 of the License, -// or (at your option) any later version. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// This file is part of CGAL (www.cgal.org) // // $URL$ // $Id$ -// SPDX-License-Identifier: LGPL-3.0+ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // // Author(s) : Maxime Gimeno diff --git a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Segment_2.h b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Segment_2.h index 511691b0ac2..1bb05d61c91 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Segment_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Segment_2.h @@ -1,20 +1,11 @@ // Copyright (c) 2019 // GeometryFactory (France). All rights reserved. // -// This file is part of CGAL (www.cgal.org); you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public License as -// published by the Free Software Foundation; either version 3 of the License, -// or (at your option) any later version. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// This file is part of CGAL (www.cgal.org) // // $URL$ // $Id$ -// SPDX-License-Identifier: LGPL-3.0+ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // // Author(s) : Maxime Gimeno diff --git a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Triangle_2.h b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Triangle_2.h index dc345b986d7..854499c7151 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Triangle_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Bbox_2_Triangle_2.h @@ -1,20 +1,11 @@ // Copyright (c) 2019 // GeometryFactory (France). All rights reserved. // -// This file is part of CGAL (www.cgal.org); you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public License as -// published by the Free Software Foundation; either version 3 of the License, -// or (at your option) any later version. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// This file is part of CGAL (www.cgal.org) // // $URL$ // $Id$ -// SPDX-License-Identifier: LGPL-3.0+ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // // Author(s) : Maxime Gimeno diff --git a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Ray_2.h b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Ray_2.h index 1882357d31b..6a4c9d8b25d 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Ray_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Ray_2.h @@ -1,20 +1,11 @@ // Copyright (c) 2019 // GeometryFactory. All rights reserved. // -// This file is part of CGAL (www.cgal.org); you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public License as -// published by the Free Software Foundation; either version 3 of the License, -// or (at your option) any later version. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// This file is part of CGAL (www.cgal.org) // // $URL$ // $Id$ -// SPDX-License-Identifier: LGPL-3.0+ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // // Author(s) : Maxime Gimeno diff --git a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Segment_2.h b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Segment_2.h index 2188499ee83..efed12af6e3 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Segment_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Segment_2.h @@ -1,20 +1,11 @@ // Copyright (c) 2019 // GeometryFactory. All rights reserved. // -// This file is part of CGAL (www.cgal.org); you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public License as -// published by the Free Software Foundation; either version 3 of the License, -// or (at your option) any later version. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// This file is part of CGAL (www.cgal.org) // // $URL$ // $Id$ -// SPDX-License-Identifier: LGPL-3.0+ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // // Author(s) : Maxime Gimeno diff --git a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Triangle_2.h b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Triangle_2.h index 6bd6f4334a4..35cfdd3ac01 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Triangle_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Triangle_2.h @@ -1,20 +1,11 @@ // Copyright (c) 2019 // GeometryFactory. All rights reserved. // -// This file is part of CGAL (www.cgal.org); you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public License as -// published by the Free Software Foundation; either version 3 of the License, -// or (at your option) any later version. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// This file is part of CGAL (www.cgal.org) // // $URL$ // $Id$ -// SPDX-License-Identifier: LGPL-3.0+ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // // Author(s) : Maxime Gimeno diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h index 1545070f5d8..76f9f725014 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h @@ -1,20 +1,11 @@ // Copyright (c) 2019 GeometryFactory(France). // All rights reserved. // -// This file is part of CGAL (www.cgal.org); you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public License as -// published by the Free Software Foundation; either version 3 of the License, -// or (at your option) any later version. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// This file is part of CGAL (www.cgal.org) // // $URL$ // $Id$ -// SPDX-License-Identifier: LGPL-3.0+ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // // Author(s) : Maxime Gimeno diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Line_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Line_3_intersection.h index 835df62193e..27b1e33919d 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Line_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Line_3_intersection.h @@ -1,20 +1,11 @@ // Copyright (c) 2019 GeometryFactory(France). // All rights reserved. // -// This file is part of CGAL (www.cgal.org); you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public License as -// published by the Free Software Foundation; either version 3 of the License, -// or (at your option) any later version. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// This file is part of CGAL (www.cgal.org) // // $URL$ // $Id$ -// SPDX-License-Identifier: LGPL-3.0+ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // // Author(s) : Maxime Gimeno diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersection.h index 6b3ff24e209..736522636a1 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersection.h @@ -1,20 +1,11 @@ // Copyright (c) 2019 GeometryFactory(France). // All rights reserved. // -// This file is part of CGAL (www.cgal.org); you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public License as -// published by the Free Software Foundation; either version 3 of the License, -// or (at your option) any later version. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// This file is part of CGAL (www.cgal.org) // // $URL$ // $Id$ -// SPDX-License-Identifier: LGPL-3.0+ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // // Author(s) : Maxime Gimeno diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Ray_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Ray_3_intersection.h index a97f4d4302f..4738c5e3a71 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Ray_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Ray_3_intersection.h @@ -1,20 +1,11 @@ // Copyright (c) 2019 GeometryFactory(France). // All rights reserved. // -// This file is part of CGAL (www.cgal.org); you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public License as -// published by the Free Software Foundation; either version 3 of the License, -// or (at your option) any later version. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// This file is part of CGAL (www.cgal.org) // // $URL$ // $Id$ -// SPDX-License-Identifier: LGPL-3.0+ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // // Author(s) : Maxime Gimeno diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Segment_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Segment_3_intersection.h index 46e1d63e88e..bcf694cdc3c 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Segment_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Segment_3_intersection.h @@ -1,20 +1,11 @@ // Copyright (c) 2019 GeometryFactory(France). // All rights reserved. // -// This file is part of CGAL (www.cgal.org); you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public License as -// published by the Free Software Foundation; either version 3 of the License, -// or (at your option) any later version. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// This file is part of CGAL (www.cgal.org) // // $URL$ // $Id$ -// SPDX-License-Identifier: LGPL-3.0+ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // // Author(s) : Maxime Gimeno diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Triangle_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Triangle_3_intersection.h index 9ad385a2cd0..e981d7298e0 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Triangle_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Triangle_3_intersection.h @@ -1,20 +1,11 @@ // Copyright (c) 2019 GeometryFactory(France). // All rights reserved. // -// This file is part of CGAL (www.cgal.org); you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public License as -// published by the Free Software Foundation; either version 3 of the License, -// or (at your option) any later version. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// This file is part of CGAL (www.cgal.org) // // $URL$ // $Id$ -// SPDX-License-Identifier: LGPL-3.0+ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // // Author(s) : Maxime Gimeno diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h index 97c63a26724..025acd70885 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h @@ -1,20 +1,11 @@ // Copyright (c) 2019 GeometryFactory(France). // All rights reserved. // -// This file is part of CGAL (www.cgal.org); you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public License as -// published by the Free Software Foundation; either version 3 of the License, -// or (at your option) any later version. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// This file is part of CGAL (www.cgal.org) // // $URL$ // $Id$ -// SPDX-License-Identifier: LGPL-3.0+ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // // Author(s) : Maxime Gimeno diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h index d71154e04c6..d74d6392e57 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h @@ -1,20 +1,11 @@ // Copyright (c) 2019 GeometryFactory(France). // All rights reserved. // -// This file is part of CGAL (www.cgal.org); you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public License as -// published by the Free Software Foundation; either version 3 of the License, -// or (at your option) any later version. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// This file is part of CGAL (www.cgal.org) // // $URL$ // $Id$ -// SPDX-License-Identifier: LGPL-3.0+ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // // Author(s) : Maxime Gimeno From 6d215c776bde45f59f3afb386aea4372a0777a2f Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Thu, 19 Mar 2020 13:28:23 +0100 Subject: [PATCH 123/141] Fix compilation error on Windows --- Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h b/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h index e1afa5fbe6e..625920ff9cc 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h +++ b/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h @@ -444,13 +444,14 @@ private: if(dim == 0) msg << "corner ("; else msg << "point ("; msg << p << ")"; - CGAL_error_msg(([this, str = msg.str()](){ - CGAL_USE(this); #if CGAL_MESH_3_PROTECTION_DEBUG & 4 + CGAL_error_msg(([this, str = msg.str()](){ dump_c3t3(this->c3t3_, "dump-bug"); -#endif return str.c_str(); }())); +#else // not CGAL_MESH_3_PROTECTION_DEBUG & 4 + CGAL_error_msg(msg.str().c_str()); +#endif } return s; } From fe0d4d0a6e2162305443477e3914adb5112f3890 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 19 Mar 2020 16:41:59 +0100 Subject: [PATCH 124/141] more clean-up --- .../Triangle_2_Triangle_2_intersection_impl.h | 19 +- .../include/CGAL/Intersection_traits_3.h | 28 +-- .../Iso_cuboid_3_Plane_3_intersection.h | 8 +- .../Tetrahedron_3_Segment_3_intersection.h | 8 +- .../Tetrahedron_3_Triangle_3_intersection.h | 9 +- .../internal/intersection_3_1_impl.h | 170 +++++++++--------- .../tetrahedron_intersection_helpers.h | 2 +- .../Intersections_3/test_intersections_3.cpp | 24 +-- 8 files changed, 135 insertions(+), 133 deletions(-) diff --git a/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h b/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h index 8cd451c6d9e..bfde9e77409 100644 --- a/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h +++ b/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h @@ -350,20 +350,20 @@ intersection(const typename K::Triangle_2 &tr1, const typename K::Triangle_2 &tr2, const K&) { - typedef Triangle_2_Triangle_2_pair is_t; - is_t ispair(&tr1, &tr2); + typedef Triangle_2_Triangle_2_pair Intersection_type; + Intersection_type ispair(&tr1, &tr2); switch (ispair.intersection_type()) { - case is_t::NO_INTERSECTION: + case Intersection_type::NO_INTERSECTION: default: return intersection_return(); - case is_t::POINT: + case Intersection_type::POINT: return intersection_return(ispair.intersection_point()); - case is_t::SEGMENT: + case Intersection_type::SEGMENT: return intersection_return(ispair.intersection_segment()); - case is_t::TRIANGLE: + case Intersection_type::TRIANGLE: return intersection_return(ispair.intersection_triangle()); - case is_t::POLYGON: + case Intersection_type::POLYGON: { typedef std::vector Container; Container points(ispair.vertex_count()); @@ -372,10 +372,7 @@ intersection(const typename K::Triangle_2 &tr1, if(Is_cw::Is_exact>()(points)) { - std::size_t length = points.size(); - - for(std::size_t i = 0; i< length/2; ++i) - std::swap(points[i], points[length-i-1]); + std::reverse(points.begin(), points.end()); } return intersection_return(points); diff --git a/Intersections_3/include/CGAL/Intersection_traits_3.h b/Intersections_3/include/CGAL/Intersection_traits_3.h index 6a626f21e23..7b82fda3e5b 100644 --- a/Intersections_3/include/CGAL/Intersection_traits_3.h +++ b/Intersections_3/include/CGAL/Intersection_traits_3.h @@ -173,8 +173,8 @@ struct Intersection_traits template struct Intersection_traits { typedef typename - boost::variant< typename K::Point_3 > variant_type; - typedef typename boost::optional< variant_type > result_type; + boost::variant< typename K::Point_3 > variant_type; + typedef typename boost::optional< variant_type > result_type; }; // Iso_cuboid_3 Plane_3, variant of 4 @@ -182,7 +182,7 @@ template struct Intersection_traits { typedef typename boost::variant< typename K::Point_3, typename K::Segment_3, - typename K::Triangle_3, std::vector > variant_type; + typename K::Triangle_3, std::vector > variant_type; typedef typename boost::optional< variant_type > result_type; }; @@ -191,7 +191,7 @@ template struct Intersection_traits { typedef typename boost::variant< typename K::Point_3, typename K::Segment_3, - typename K::Triangle_3, std::vector > variant_type; + typename K::Triangle_3, std::vector > variant_type; typedef typename boost::optional< variant_type > result_type; }; @@ -201,7 +201,7 @@ template struct Intersection_traits { typedef typename boost::variant< typename K::Point_3, typename K::Segment_3, - typename K::Triangle_3, std::vector > variant_type; + typename K::Triangle_3, std::vector > variant_type; typedef typename boost::optional< variant_type > result_type; }; @@ -210,7 +210,7 @@ template struct Intersection_traits { typedef typename boost::variant< typename K::Point_3, typename K::Segment_3, - typename K::Triangle_3, std::vector > variant_type; + typename K::Triangle_3, std::vector > variant_type; typedef typename boost::optional< variant_type > result_type; }; @@ -220,7 +220,7 @@ template struct Intersection_traits { typedef typename boost::variant< typename K::Point_3, typename K::Segment_3, - typename K::Triangle_3, std::vector > variant_type; + typename K::Triangle_3, std::vector > variant_type; typedef typename boost::optional< variant_type > result_type; }; @@ -229,7 +229,7 @@ template struct Intersection_traits { typedef typename boost::variant< typename K::Point_3, typename K::Segment_3, - typename K::Triangle_3, std::vector > variant_type; + typename K::Triangle_3, std::vector > variant_type; typedef typename boost::optional< variant_type > result_type; }; @@ -239,7 +239,7 @@ template struct Intersection_traits { typedef typename boost::variant< typename K::Point_3, typename K::Segment_3, - typename K::Triangle_3, std::vector > variant_type; + typename K::Triangle_3, std::vector > variant_type; typedef typename boost::optional< variant_type > result_type; }; @@ -248,7 +248,7 @@ template struct Intersection_traits { typedef typename boost::variant< typename K::Point_3, typename K::Segment_3, - typename K::Triangle_3, std::vector > variant_type; + typename K::Triangle_3, std::vector > variant_type; typedef typename boost::optional< variant_type > result_type; }; @@ -379,7 +379,7 @@ struct Intersection_traits { typedef typename boost::variant< typename K::Point_3 , typename K::Segment_3, - typename K::Triangle_3, std::vector > variant_type; + typename K::Triangle_3, std::vector > variant_type; typedef typename boost::optional< variant_type > result_type; }; @@ -389,7 +389,7 @@ struct Intersection_traits { typedef typename boost::variant< typename K::Point_3 , typename K::Segment_3, - typename K::Triangle_3, std::vector > variant_type; + typename K::Triangle_3, std::vector > variant_type; typedef typename boost::optional< variant_type > result_type; }; @@ -399,7 +399,7 @@ struct Intersection_traits { typedef typename boost::variant< typename K::Point_3 , typename K::Segment_3, - typename K::Triangle_3, std::vector > variant_type; + typename K::Triangle_3, std::vector > variant_type; typedef typename boost::optional< variant_type > result_type; }; @@ -409,7 +409,7 @@ struct Intersection_traits { typedef typename boost::variant< typename K::Point_3 , typename K::Segment_3, - typename K::Triangle_3, std::vector > variant_type; + typename K::Triangle_3, std::vector > variant_type; typedef typename boost::optional< variant_type > result_type; }; diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h index 76f9f725014..56ec7b5f9f5 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h @@ -151,8 +151,8 @@ intersection( case 2: //intersects diagonally { Poly res(4); - Segment_3 front(segments.front()), - back(segments.back()); + Segment_3 &front(segments.front()), + &back(segments.back()); res[0] = front.target(); res[1] = back.target(); res[2] = back.source(); @@ -311,13 +311,17 @@ intersection( } } } + if(tmp_segs.size() < 3) return result_type(); + std::list tmp_pts; fill_points_list(tmp_segs,tmp_pts); + Poly res; for(const auto& p : tmp_pts) res.push_back(p); + if(res.size() == 3){ typename K::Triangle_3 tr(res[0], res[1], res[2]); return result_type(std::forward(tr)); diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Segment_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Segment_3_intersection.h index bcf694cdc3c..a79424649f6 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Segment_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Segment_3_intersection.h @@ -32,7 +32,7 @@ struct Tetrahedron_segment_intersection_3 typedef typename K::Segment_3 O; typedef Tetrahedron_lines_intersection_3_base > Base; - typedef typename Base::Result_type Result_type; + typedef typename Base::Result_type result_type; Tetrahedron_segment_intersection_3(const typename K::Tetrahedron_3& tet, const O& o):Base(tet,o) {} @@ -43,7 +43,7 @@ struct Tetrahedron_segment_intersection_3 if(this->tet.has_on_bounded_side(this->o.source()) && this->tet.has_on_bounded_side(this->o.target())){ typename K::Segment_3 result = this->o; - this->output = Result_type(std::forward(result)); + this->output = result_type(std::forward(result)); return true; } return false; @@ -55,12 +55,12 @@ struct Tetrahedron_segment_intersection_3 if(this->tet.has_on_bounded_side(this->o.source())) { typename K::Segment_3 result(this->o.source(), this->res_points.front()); - this->output = Result_type(std::forward(result)); + this->output = result_type(std::forward(result)); return true; } else if(this->tet.has_on_bounded_side(this->o.target())){ typename K::Segment_3 result(this->res_points.front(), this->o.target()); - this->output = Result_type(std::forward(result)); + this->output = result_type(std::forward(result)); return true; } return false; diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Triangle_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Triangle_3_intersection.h index e981d7298e0..243fa7185b4 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Triangle_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Triangle_3_intersection.h @@ -110,9 +110,8 @@ intersection( fill_segments_infos(segments,tmp, tr); Poly res; res.reserve(4); - for( const auto& p : tmp){ + for(const auto& p : tmp) res.push_back(p); - } return result_type(std::forward(res)); } //else it must be adjacent to an vertex, so we return the point @@ -238,7 +237,8 @@ intersection( Poly res; res.reserve(4); res.push_back(inside_points.front()); - for( const auto& p : tmp){res.push_back(p);} + for(const auto& p : tmp) + res.push_back(p); return result_type(std::forward(res)); } else //size 2 @@ -256,7 +256,8 @@ intersection( res.push_back(inside_points.front()); } res.push_back(inside_points.back()); - for( const auto& p : tmp){res.push_back(p);} + for(const auto& p : tmp) + res.push_back(p); return result_type(std::forward(res)); } } diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/intersection_3_1_impl.h b/Intersections_3/include/CGAL/Intersections_3/internal/intersection_3_1_impl.h index 4a3a52a2d93..a6eac72e415 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/intersection_3_1_impl.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/intersection_3_1_impl.h @@ -82,8 +82,8 @@ namespace internal { template typename Intersection_traits::result_type intersection(const typename K::Plane_3 &plane, - const typename K::Line_3 &line, - const K& /*k*/) + const typename K::Line_3 &line, + const K& /*k*/) { typedef typename K::Point_3 Point_3; typedef typename K::Direction_3 Direction_3; @@ -116,8 +116,8 @@ template inline typename Intersection_traits::result_type intersection(const typename K::Line_3 &line, - const typename K::Plane_3 &plane, - const K& k) + const typename K::Plane_3 &plane, + const K& k) { return intersection(plane, line, k); } @@ -125,8 +125,8 @@ intersection(const typename K::Line_3 &line, template typename Intersection_traits::result_type intersection(const typename K::Plane_3 &plane1, - const typename K::Plane_3 &plane2, - const K&) + const typename K::Plane_3 &plane2, + const K&) { typedef typename K::Point_3 Point_3; typedef typename K::Direction_3 Direction_3; @@ -187,9 +187,9 @@ boost::optional< boost::variant > intersection(const typename K::Plane_3 &plane1, - const typename K::Plane_3 &plane2, - const typename K::Plane_3 &plane3, - const K& k) + const typename K::Plane_3 &plane2, + const typename K::Plane_3 &plane3, + const K& k) { typedef typename boost::optional< @@ -238,8 +238,8 @@ intersection(const typename K::Plane_3 &plane1, template bool do_intersect(const typename K::Plane_3 &plane, - const typename K::Line_3 &line, - const K&) + const typename K::Line_3 &line, + const K&) { typedef typename K::Point_3 Point_3; typedef typename K::Direction_3 Direction_3; @@ -266,8 +266,8 @@ template inline bool do_intersect(const typename K::Line_3 &line, - const typename K::Plane_3 &plane, - const K& k) + const typename K::Plane_3 &plane, + const K& k) { return do_intersect(plane, line, k); } @@ -275,8 +275,8 @@ do_intersect(const typename K::Line_3 &line, template typename Intersection_traits::result_type intersection(const typename K::Line_3 &l1, - const typename K::Line_3 &l2, - const K&) + const typename K::Line_3 &l2, + const K&) { typedef typename K::FT FT; typedef typename K::Point_3 Point_3; @@ -313,8 +313,8 @@ intersection(const typename K::Line_3 &l1, template bool do_intersect(const typename K::Line_3 &l1, - const typename K::Line_3 &l2, - const K&) + const typename K::Line_3 &l2, + const K&) { typedef typename K::Point_3 Point_3; typedef typename K::Vector_3 Vector_3; @@ -400,8 +400,8 @@ struct L_p_visitor : public boost::static_visitor< template typename Intersection_traits::result_type intersection(const typename K::Segment_3 &s1, - const typename K::Segment_3 &s2, - const K&) + const typename K::Segment_3 &s2, + const K&) { CGAL_precondition(! s1.is_degenerate () && ! s2.is_degenerate () ); @@ -450,8 +450,8 @@ do_intersect(const typename K::Segment_3 &s1, template typename Intersection_traits::result_type intersection(const typename K::Line_3 &l, - const typename K::Segment_3 &s, - const K& k) + const typename K::Segment_3 &s, + const K& k) { CGAL_precondition(! l.is_degenerate () && ! s.is_degenerate () ); @@ -474,8 +474,8 @@ intersection(const typename K::Line_3 &l, template typename Intersection_traits::result_type intersection(const typename K::Segment_3 &s, - const typename K::Line_3 &l, - const K& k) + const typename K::Line_3 &l, + const K& k) { return intersection(l,s,k); } @@ -519,8 +519,8 @@ template bool Ray_3_has_on_collinear_Point_3( const typename K::Ray_3 &r, - const typename K::Point_3 &p, - const K& k) + const typename K::Point_3 &p, + const K& k) { return k.equal_3_object()(r.source(),p) @@ -534,8 +534,8 @@ Ray_3_has_on_collinear_Point_3( template typename Intersection_traits::result_type intersection(const typename K::Line_3 &l, - const typename K::Ray_3 &r, - const K& k) + const typename K::Ray_3 &r, + const K& k) { CGAL_precondition(! l.is_degenerate () && ! r.is_degenerate () ); @@ -556,8 +556,8 @@ intersection(const typename K::Line_3 &l, template typename Intersection_traits::result_type intersection(const typename K::Ray_3 &r, - const typename K::Line_3 &l, - const K& k) + const typename K::Line_3 &l, + const K& k) { return intersection(l,r,k); } @@ -593,8 +593,8 @@ do_intersect(const typename K::Ray_3 &r, template typename Intersection_traits::result_type intersection(const typename K::Segment_3 &s, - const typename K::Ray_3 &r, - const K& k) + const typename K::Ray_3 &r, + const K& k) { CGAL_precondition(! s.is_degenerate () && ! r.is_degenerate () ); @@ -638,8 +638,8 @@ intersection(const typename K::Segment_3 &s, template typename Intersection_traits::result_type intersection(const typename K::Ray_3 &r, - const typename K::Segment_3 &s, - const K& k) + const typename K::Segment_3 &s, + const K& k) { return intersection(s,r,k); } @@ -681,8 +681,8 @@ do_intersect(const typename K::Ray_3 &r, template typename Intersection_traits::result_type intersection(const typename K::Ray_3 &r1, - const typename K::Ray_3 &r2, - const K& k) + const typename K::Ray_3 &r2, + const K& k) { CGAL_precondition(! r1.is_degenerate () && ! r2.is_degenerate () ); @@ -852,8 +852,8 @@ do_intersect(const typename K::Sphere_3 &s1, template typename Intersection_traits::result_type intersection(const typename K::Plane_3 &plane, - const typename K::Ray_3 &ray, - const K& k) + const typename K::Ray_3 &ray, + const K& k) { typedef typename K::Point_3 Point_3; @@ -879,8 +879,8 @@ template inline typename Intersection_traits::result_type intersection(const typename K::Ray_3 &ray, - const typename K::Plane_3 &plane, - const K& k) + const typename K::Plane_3 &plane, + const K& k) { return intersection(plane, ray, k); } @@ -890,8 +890,8 @@ intersection(const typename K::Ray_3 &ray, template bool do_intersect(const typename K::Plane_3 &plane, - const typename K::Ray_3 &ray, - const K& k) + const typename K::Ray_3 &ray, + const K& k) { typedef typename K::Point_3 Point_3; @@ -912,8 +912,8 @@ template inline bool do_intersect(const typename K::Ray_3 &ray, - const typename K::Plane_3 &plane, - const K& k) + const typename K::Plane_3 &plane, + const K& k) { return do_intersect(plane, ray, k); } @@ -922,8 +922,8 @@ do_intersect(const typename K::Ray_3 &ray, template typename Intersection_traits::result_type intersection(const typename K::Plane_3 &plane, - const typename K::Segment_3 &seg, - const K& k) + const typename K::Segment_3 &seg, + const K& k) { typedef typename K::Point_3 Point_3; const Point_3 &source = seg.source(); @@ -996,8 +996,8 @@ template inline typename Intersection_traits::result_type intersection(const typename K::Segment_3 &seg, - const typename K::Plane_3 &plane, - const K& k) + const typename K::Plane_3 &plane, + const K& k) { return intersection(plane, seg, k); } @@ -1006,8 +1006,8 @@ intersection(const typename K::Segment_3 &seg, template bool do_intersect(const typename K::Plane_3 &plane, - const typename K::Segment_3 &seg, - const K&) + const typename K::Segment_3 &seg, + const K&) { typedef typename K::Point_3 Point_3; const Point_3 &source = seg.source(); @@ -1028,8 +1028,8 @@ template inline bool do_intersect(const typename K::Segment_3 &seg, - const typename K::Plane_3 &plane, - const K& k) + const typename K::Plane_3 &plane, + const K& k) { return do_intersect(plane, seg, k); } @@ -1038,8 +1038,8 @@ template inline typename Intersection_traits::result_type intersection(const typename K::Plane_3 &plane, - const typename K::Triangle_3 &tri, - const K& k) + const typename K::Triangle_3 &tri, + const K& k) { typedef typename Intersection_traits::result_type @@ -1139,8 +1139,8 @@ template inline typename Intersection_traits::result_type intersection(const typename K::Triangle_3 &triangle, - const typename K::Plane_3 &plane, - const K& k) + const typename K::Plane_3 &plane, + const K& k) { return intersection(plane, triangle, k); } @@ -1148,8 +1148,8 @@ intersection(const typename K::Triangle_3 &triangle, template typename Intersection_traits::result_type intersection(const typename K::Line_3 &line, - const Bbox_3 &box, - const K&) + const Bbox_3 &box, + const K&) { typedef typename K::Point_3 Point_3; typedef typename K::Direction_3 Direction_3; @@ -1171,8 +1171,8 @@ template inline typename Intersection_traits::result_type intersection(const Bbox_3 &box, - const typename K::Line_3 &line, - const K& k) + const typename K::Line_3 &line, + const K& k) { return intersection(line, box, k); } @@ -1181,8 +1181,8 @@ intersection(const Bbox_3 &box, template typename Intersection_traits::result_type intersection(const typename K::Ray_3 &ray, - const Bbox_3 &box, - const K&) + const Bbox_3 &box, + const K&) { typedef typename K::Point_3 Point_3; typedef typename K::Direction_3 Direction_3; @@ -1204,8 +1204,8 @@ template inline typename Intersection_traits::result_type intersection(const Bbox_3 &box, - const typename K::Ray_3 &ray, - const K& k) + const typename K::Ray_3 &ray, + const K& k) { return intersection(ray, box, k); } @@ -1215,8 +1215,8 @@ intersection(const Bbox_3 &box, template typename Intersection_traits::result_type intersection(const typename K::Segment_3 &seg, - const Bbox_3 &box, - const K&) + const Bbox_3 &box, + const K&) { typedef typename K::Point_3 Point_3; typedef typename K::Vector_3 Vector_3; @@ -1238,8 +1238,8 @@ template inline typename Intersection_traits::result_type intersection(const Bbox_3 &box, - const typename K::Segment_3 &seg, - const K& k) + const typename K::Segment_3 &seg, + const K& k) { return intersection(seg, box, k); } @@ -1248,8 +1248,8 @@ template inline typename Intersection_traits::result_type intersection(const Bbox_3 &a, - const Bbox_3 &b, - const K&) + const Bbox_3 &b, + const K&) { return CGAL::intersection(a, b); } @@ -1257,8 +1257,8 @@ intersection(const Bbox_3 &a, template typename Intersection_traits::result_type intersection(const CGAL::Bbox_3 &box, - const typename K::Iso_cuboid_3 &cub, - const K&) + const typename K::Iso_cuboid_3 &cub, + const K&) { typename K::Iso_cuboid_3 iso_cub(box); return intersection(iso_cub, cub); @@ -1269,8 +1269,8 @@ template inline typename Intersection_traits::result_type intersection(const typename K::Iso_cuboid_3 &cub, - const CGAL::Bbox_3 &box, - const K& k) + const CGAL::Bbox_3 &box, + const K& k) { return intersection(box,cub, k); } @@ -1279,8 +1279,8 @@ intersection(const typename K::Iso_cuboid_3 &cub, template typename Intersection_traits::result_type intersection(const typename K::Line_3 &line, - const typename K::Iso_cuboid_3 &box, - const K&) + const typename K::Iso_cuboid_3 &box, + const K&) { typedef typename K::Point_3 Point_3; typedef typename K::Vector_3 Vector_3; @@ -1341,8 +1341,8 @@ template inline typename Intersection_traits::result_type intersection(const typename K::Iso_cuboid_3 &box, - const typename K::Line_3 &line, - const K& k) + const typename K::Line_3 &line, + const K& k) { return intersection(line, box, k); } @@ -1352,8 +1352,8 @@ intersection(const typename K::Iso_cuboid_3 &box, template typename Intersection_traits::result_type intersection(const typename K::Ray_3 &ray, - const typename K::Iso_cuboid_3 &box, - const K&) + const typename K::Iso_cuboid_3 &box, + const K&) { typedef typename K::Point_3 Point_3; typedef typename K::Vector_3 Vector_3; @@ -1413,8 +1413,8 @@ template inline typename Intersection_traits::result_type intersection(const typename K::Iso_cuboid_3 &box, - const typename K::Ray_3 &ray, - const K& k) + const typename K::Ray_3 &ray, + const K& k) { return intersection(ray, box, k); } @@ -1423,8 +1423,8 @@ intersection(const typename K::Iso_cuboid_3 &box, template typename Intersection_traits::result_type intersection(const typename K::Segment_3 &seg, - const typename K::Iso_cuboid_3 &box, - const K&) + const typename K::Iso_cuboid_3 &box, + const K&) { typedef typename K::Point_3 Point_3; typedef typename K::Vector_3 Vector_3; @@ -1485,8 +1485,8 @@ template inline typename Intersection_traits::result_type intersection(const typename K::Iso_cuboid_3 &box, - const typename K::Segment_3 &seg, - const K& k) + const typename K::Segment_3 &seg, + const K& k) { return intersection(seg, box, k); } diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h index 025acd70885..03a8db1348d 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h @@ -66,7 +66,7 @@ void fill_segments_infos(std::vector& segments, std::vector wrapped_segments; - for(const auto& s:segments) + for(const Segment& s:segments) wrapped_segments.push_back(Wrapped_segment(s)); std::vector bis = segments; diff --git a/Intersections_3/test/Intersections_3/test_intersections_3.cpp b/Intersections_3/test/Intersections_3/test_intersections_3.cpp index 73d72640c32..b83f4d23276 100644 --- a/Intersections_3/test/Intersections_3/test_intersections_3.cpp +++ b/Intersections_3/test/Intersections_3/test_intersections_3.cpp @@ -720,7 +720,7 @@ struct Test { const std::vector

* poly = boost::get >(&*res); CGAL_assertion(poly != nullptr); CGAL_assertion(poly->size() == 4); - for(auto p : *poly) + for(auto& p : *poly) { CGAL_assertion(tet.has_on_boundary(p) && tr.has_on(p)); } @@ -773,7 +773,7 @@ struct Test { std::vector

* inter = boost::get >(&*res); CGAL_assertion(inter != nullptr); CGAL_assertion(inter->size() == 4); - for(auto p : *inter) + for(auto& p : *inter) { CGAL_assertion(tet.has_on_boundary(p) && tr.has_on(p)); } @@ -788,7 +788,7 @@ struct Test { inter = boost::get >(&*res); CGAL_assertion(inter != nullptr); CGAL_assertion(inter->size() == 4); - for(auto p : *inter) + for(auto& p : *inter) { CGAL_assertion(tet.has_on_boundary(p) && tr.has_on(p)); } @@ -823,7 +823,7 @@ struct Test { CGAL_assertion(inter != nullptr); CGAL_assertion(inter->size() == 4); - for(auto p : *inter) + for(auto& p : *inter) { CGAL_assertion( (tet.has_on_bounded_side(p) || tet.has_on_boundary(p)) @@ -914,7 +914,7 @@ struct Test { const std::vector

* poly = boost::get >(&*res); CGAL_assertion(poly != nullptr); CGAL_assertion(poly->size() == 4); - for(auto p : *poly) + for(auto& p : *poly) { CGAL_assertion(p.x() == 1); } @@ -922,7 +922,7 @@ struct Test { poly = boost::get >(&*res); CGAL_assertion(poly != nullptr); CGAL_assertion(poly->size() == 4); - for(auto p : *poly) + for(auto& p : *poly) { CGAL_assertion(cub.has_on_boundary(p)); } @@ -945,7 +945,7 @@ struct Test { poly = boost::get >(&*res); CGAL_assertion(poly != nullptr); CGAL_assertion(poly->size() == 4); - for(auto p : *poly) + for(auto& p : *poly) { CGAL_assertion(pl.has_on(p) && cub.has_on_boundary(p)); } @@ -956,7 +956,7 @@ struct Test { poly = boost::get >(&*res); CGAL_assertion(poly != nullptr); CGAL_assertion(poly->size() == 5); - for(auto p : *poly) + for(auto& p : *poly) { CGAL_assertion(pl.has_on(p) && cub.has_on_boundary(p)); } @@ -1105,7 +1105,7 @@ struct Test { const std::vector

* poly = boost::get >(&*res); CGAL_assertion(poly != nullptr); CGAL_assertion(poly->size() == 4); - for(auto p : *poly) + for(auto& p : *poly) { CGAL_assertion(p.x() == 1); } @@ -1131,7 +1131,7 @@ struct Test { poly = boost::get >(&*res); CGAL_assertion(poly != nullptr); CGAL_assertion(poly->size() == 5); - for(auto p : *poly) + for(auto& p : *poly) { CGAL_assertion(pl.has_on(p)); } @@ -1184,7 +1184,7 @@ struct Test { std::vector

* poly = boost::get >(&*res); CGAL_assertion(poly != nullptr); CGAL_assertion(poly->size() == 4); - for(auto p : *poly) + for(auto& p : *poly) { CGAL_assertion(tr.has_on(p) && cub.has_on_boundary(p)); } @@ -1212,7 +1212,7 @@ struct Test { std::vector

* poly = boost::get >(&*res); CGAL_assertion(poly != nullptr); CGAL_assertion(poly->size() == 4); - for(auto p : *poly) + for(auto& p : *poly) { CGAL_assertion(tr.has_on(p) && cub.has_on_boundary(p)); } From d395e096f2487c70639c3cbb787b81d2d5211190 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 20 Mar 2020 10:35:16 +0100 Subject: [PATCH 125/141] fix warnings --- .../Intersections_2/test_intersections_2.cpp | 2 +- .../Tetrahedron_3_Plane_3_intersection.h | 7 +- .../Tetrahedron_3_Triangle_3_intersection.h | 1 + .../tetrahedron_lines_intersections_3.h | 2 +- .../Intersections_3/test_intersections_3.cpp | 92 +++++++++---------- 5 files changed, 52 insertions(+), 52 deletions(-) diff --git a/Intersections_2/test/Intersections_2/test_intersections_2.cpp b/Intersections_2/test/Intersections_2/test_intersections_2.cpp index c7b0bb9c4ad..23a01a4fc2b 100644 --- a/Intersections_2/test/Intersections_2/test_intersections_2.cpp +++ b/Intersections_2/test/Intersections_2/test_intersections_2.cpp @@ -340,7 +340,7 @@ struct Test check_no_do_intersect (C(p( 2, 8), 6), S(p(-3, -2), p( 2, -4))); check_no_do_intersect (C(p( 2, 8), 6), S(p(-3, 22), p( 2, 34))); - check_no_do_intersect (C(p( 2, 8), 9), S(p(2.5, 3.5), p(3, 4))); + check_no_do_intersect (C(p( 4, 16), 18), S(p(5, 7), p(6, 8))); check_do_intersect (C(p( 3, 4), 0), S(p(-3, 8), p( 6, 2))); check_do_intersect (C(p( 4, 3), 4), S(p( 6, -7), p( 5, 2))); diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersection.h index 736522636a1..fa55cb268f2 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersection.h @@ -45,11 +45,10 @@ intersection( typedef typename K::Segment_3 Segment_3; Inter_type intersections[4]; - std::size_t seg_id = -1, - p_id = -1; + int p_id = -1; std::vector points; std::vector segments; - for(std::size_t i = 0; i < 4; ++i) + for(int i = 0; i < 4; ++i) { const typename K::Triangle_3 triangle(tet.vertex((i+1)%4), tet.vertex((i+2)%4), @@ -65,7 +64,6 @@ intersection( = boost::get(&*intersections[i])) { segments.push_back(*s); - seg_id = i; } else if( const typename K::Point_3* p = boost::get(&*intersections[i])) @@ -127,6 +125,7 @@ intersection( } break; } + CGAL_assertion(false); return result_type(); } diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Triangle_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Triangle_3_intersection.h index 243fa7185b4..80fdbb55520 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Triangle_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Triangle_3_intersection.h @@ -279,6 +279,7 @@ intersection( //never happens (only 3 pts in a tr) break; } + return result_type(); } template diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h index d74d6392e57..0c1037834af 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h @@ -143,7 +143,7 @@ struct Tetrahedron_lines_intersection_3_base } CGAL_assertion(res_id != -1); - CGAL_assertion(res_id_2 != -1); + CGAL_assertion(res_id_2 != static_cast(-1)); CGAL_assertion(max_dist >0 ); typename K::Segment_3 res_seg(res_points[res_id], res_points[res_id_2]); diff --git a/Intersections_3/test/Intersections_3/test_intersections_3.cpp b/Intersections_3/test/Intersections_3/test_intersections_3.cpp index b83f4d23276..99390106d79 100644 --- a/Intersections_3/test/Intersections_3/test_intersections_3.cpp +++ b/Intersections_3/test/Intersections_3/test_intersections_3.cpp @@ -679,8 +679,8 @@ struct Test { Res res = CGAL::intersection (tet, pl); const std::vector

* poly = boost::get >(&*res); - CGAL_assertion(poly != nullptr); - CGAL_assertion(poly->size() == 4); + assert(poly != nullptr); + assert(poly->size() == 4); } else { @@ -718,11 +718,11 @@ struct Test { Res res = CGAL::intersection(tet, tr); const std::vector

* poly = boost::get >(&*res); - CGAL_assertion(poly != nullptr); - CGAL_assertion(poly->size() == 4); + assert(poly != nullptr); + assert(poly->size() == 4); for(auto& p : *poly) { - CGAL_assertion(tet.has_on_boundary(p) && tr.has_on(p)); + assert(tet.has_on_boundary(p) && tr.has_on(p)); } //only one edge intersecting @@ -771,11 +771,11 @@ struct Test { std::vector

* inter = boost::get >(&*res); - CGAL_assertion(inter != nullptr); - CGAL_assertion(inter->size() == 4); + assert(inter != nullptr); + assert(inter->size() == 4); for(auto& p : *inter) { - CGAL_assertion(tet.has_on_boundary(p) && tr.has_on(p)); + assert(tet.has_on_boundary(p) && tr.has_on(p)); } tr = Tr(P(-2, 0.25, 0), @@ -786,11 +786,11 @@ struct Test { inter = boost::get >(&*res); - CGAL_assertion(inter != nullptr); - CGAL_assertion(inter->size() == 4); + assert(inter != nullptr); + assert(inter->size() == 4); for(auto& p : *inter) { - CGAL_assertion(tet.has_on_boundary(p) && tr.has_on(p)); + assert(tet.has_on_boundary(p) && tr.has_on(p)); } tr = Tr(P(0.2, 0.15, 0.3), @@ -799,7 +799,7 @@ struct Test { res = CGAL::intersection(tet, tr); Tr* res_tr = boost::get(&*res); - CGAL_assertion(res_tr != nullptr); + assert(res_tr != nullptr); tr = Tr(P(0.2, 0.15, 0.3), P(-1, 0.15, -2), @@ -809,8 +809,8 @@ struct Test { inter = boost::get >(&*res); - CGAL_assertion(inter != nullptr); - CGAL_assertion(inter->size() == 4); + assert(inter != nullptr); + assert(inter->size() == 4); tr = Tr(P(0.45, 0.20, 0.1), P(0.1, 0.20, 0.5), @@ -820,12 +820,12 @@ struct Test { inter = boost::get >(&*res); - CGAL_assertion(inter != nullptr); - CGAL_assertion(inter->size() == 4); + assert(inter != nullptr); + assert(inter->size() == 4); for(auto& p : *inter) { - CGAL_assertion( + assert( (tet.has_on_bounded_side(p) || tet.has_on_boundary(p)) && tr.has_on(p)); } @@ -834,14 +834,14 @@ struct Test { tr = Tr(P(0,1,0), P(0.1,0.1,0), P(0.9,0.1,0)); res = CGAL::intersection(tet, tr); res_tr = boost::get(&*res); - CGAL_assertion(res_tr != nullptr); + assert(res_tr != nullptr); tr = Tr(P(0.1, 0.5, 0.1), P(0.3,0.1,0.1), P(4,0.3,0.9)); res = CGAL::intersection(tet, tr); inter = boost::get >(&*res); - CGAL_assertion(inter != nullptr); - CGAL_assertion(inter->size() == 4); + assert(inter != nullptr); + assert(inter->size() == 4); } else { @@ -912,19 +912,19 @@ struct Test { Res res = CGAL::intersection(cub, Pl(P(1,1,1), P(1,2,1), P(1,2,2))); const std::vector

* poly = boost::get >(&*res); - CGAL_assertion(poly != nullptr); - CGAL_assertion(poly->size() == 4); + assert(poly != nullptr); + assert(poly->size() == 4); for(auto& p : *poly) { - CGAL_assertion(p.x() == 1); + assert(p.x() == 1); } res = CGAL::intersection(cub, Pl(P(1,1,1), P(1,2,1), P(2,2,2))); poly = boost::get >(&*res); - CGAL_assertion(poly != nullptr); - CGAL_assertion(poly->size() == 4); + assert(poly != nullptr); + assert(poly->size() == 4); for(auto& p : *poly) { - CGAL_assertion(cub.has_on_boundary(p)); + assert(cub.has_on_boundary(p)); } //vertex @@ -943,22 +943,22 @@ struct Test { Pl pl(P(1,1,1), P(1,2,1), P(1.5, 1, 2)); res = CGAL::intersection(cub, pl); poly = boost::get >(&*res); - CGAL_assertion(poly != nullptr); - CGAL_assertion(poly->size() == 4); + assert(poly != nullptr); + assert(poly->size() == 4); for(auto& p : *poly) { - CGAL_assertion(pl.has_on(p) && cub.has_on_boundary(p)); + assert(pl.has_on(p) && cub.has_on_boundary(p)); } //random pl = Pl(0.265189, 0.902464, 0.33946, -2.47551); res = CGAL::intersection(cub, pl); poly = boost::get >(&*res); - CGAL_assertion(poly != nullptr); - CGAL_assertion(poly->size() == 5); + assert(poly != nullptr); + assert(poly->size() == 5); for(auto& p : *poly) { - CGAL_assertion(pl.has_on(p) && cub.has_on_boundary(p)); + assert(pl.has_on(p) && cub.has_on_boundary(p)); } } else @@ -1103,16 +1103,16 @@ struct Test { Res res = CGAL::intersection(cub, Pl(P(1,1,1), P(1,2,1), P(1,2,2))); const std::vector

* poly = boost::get >(&*res); - CGAL_assertion(poly != nullptr); - CGAL_assertion(poly->size() == 4); + assert(poly != nullptr); + assert(poly->size() == 4); for(auto& p : *poly) { - CGAL_assertion(p.x() == 1); + assert(p.x() == 1); } res = CGAL::intersection(cub, Pl(P(1,1,1), P(1,2,1), P(2,2,2))); poly = boost::get >(&*res); - CGAL_assertion(poly != nullptr); - CGAL_assertion(poly->size() == 4); + assert(poly != nullptr); + assert(poly->size() == 4); //vertex check_intersection (cub, Pl(0.5, -0.5, -0.5, 0), P(2,1,1)); @@ -1129,11 +1129,11 @@ struct Test { Pl pl(0.265189, 0.902464, 0.33946, -2.47551); res = CGAL::intersection(cub, pl); poly = boost::get >(&*res); - CGAL_assertion(poly != nullptr); - CGAL_assertion(poly->size() == 5); + assert(poly != nullptr); + assert(poly->size() == 5); for(auto& p : *poly) { - CGAL_assertion(pl.has_on(p)); + assert(pl.has_on(p)); } } else @@ -1182,11 +1182,11 @@ struct Test { if(is_exact) { std::vector

* poly = boost::get >(&*res); - CGAL_assertion(poly != nullptr); - CGAL_assertion(poly->size() == 4); + assert(poly != nullptr); + assert(poly->size() == 4); for(auto& p : *poly) { - CGAL_assertion(tr.has_on(p) && cub.has_on_boundary(p)); + assert(tr.has_on(p) && cub.has_on_boundary(p)); } } @@ -1210,11 +1210,11 @@ struct Test { if(is_exact) { std::vector

* poly = boost::get >(&*res); - CGAL_assertion(poly != nullptr); - CGAL_assertion(poly->size() == 4); + assert(poly != nullptr); + assert(poly->size() == 4); for(auto& p : *poly) { - CGAL_assertion(tr.has_on(p) && cub.has_on_boundary(p)); + assert(tr.has_on(p) && cub.has_on_boundary(p)); } } } From a91a225bd8bfb86b1fefb6b32a3631409acfcec6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 20 Mar 2020 15:32:56 +0100 Subject: [PATCH 126/141] Fix conversion warning https://cgal.geometryfactory.com/CGAL/testsuite/CGAL-5.1-Ic-103/Polyhedron_Demo/TestReport_Blake_Windows_MSVC-2019-Community-Release-64bits.gz --- .../demo/Polyhedron/Plugins/PMP/Repair_polyhedron_plugin.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Repair_polyhedron_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Repair_polyhedron_plugin.cpp index a4cf1f1d134..28048122fa7 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Repair_polyhedron_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Repair_polyhedron_plugin.cpp @@ -327,9 +327,9 @@ void Polyhedron_demo_repair_polyhedron_plugin::on_actionMergeDuplicatedVerticesO if(Item* poly_item = qobject_cast(scene->item(index))) { - const SMesh::size_type old_nv = vertices(*poly_item->polyhedron()).size(); + const boost::graph_traits::vertices_size_type old_nv = vertices(*poly_item->polyhedron()).size(); PMP::merge_duplicated_vertices_in_boundary_cycles(*poly_item->polyhedron()); - const SMesh::size_type new_nv = vertices(*poly_item->polyhedron()).size(); + const boost::graph_traits::vertices_size_type new_nv = vertices(*poly_item->polyhedron()).size(); CGAL::Three::Three::information(tr(" %1 vertices merged").arg(old_nv - new_nv)); if(old_nv != new_nv) { From 586987e377818cd6cbd1672a12ef27544363707e Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 23 Mar 2020 11:34:37 +0100 Subject: [PATCH 127/141] fix warning. --- .../internal/Iso_cuboid_3_Plane_3_intersection.h | 2 +- .../internal/tetrahedron_lines_intersections_3.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h index 56ec7b5f9f5..456f2219cf1 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h @@ -127,7 +127,7 @@ intersection( } } } - + CGAL_USE(p2_found); CGAL_assertion(p1_found && p2_found); res[0] = entry_seg.target(); res[1] = p2; diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h index 0c1037834af..3afe0fbdd0b 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h @@ -60,7 +60,7 @@ struct Tetrahedron_lines_intersection_3_base int res_id = -1; Inter_type tr_seg[4]; - for(std::size_t i = 0; i < 4; ++i) + for(int i = 0; i < 4; ++i) { const typename K::Triangle_3 triangle(tet.vertex((i+1)%4), tet.vertex((i+2)%4), @@ -87,7 +87,7 @@ struct Tetrahedron_lines_intersection_3_base res_points.reserve(4); res_id = -1; - for(std::size_t i = 0; i< 4; ++i) + for(int i = 0; i< 4; ++i) { if(tr_seg[i]) { @@ -135,7 +135,7 @@ struct Tetrahedron_lines_intersection_3_base sq_distances[i].push_back(CGAL::squared_distance(p1, p2)); if(sq_distances[i].back() > max_dist) { - res_id = i; + res_id = static_cast(i); res_id_2 = sq_distances[i].size()-1; max_dist = sq_distances[i].back(); } From 0d98265009419327e70a62d4e029c7d63280a4bd Mon Sep 17 00:00:00 2001 From: Mael Date: Mon, 23 Mar 2020 12:11:21 +0100 Subject: [PATCH 128/141] Fix conversion warning --- .../demo/Polyhedron/Plugins/PMP/Repair_polyhedron_plugin.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Repair_polyhedron_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Repair_polyhedron_plugin.cpp index 28048122fa7..fe3759c6f79 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Repair_polyhedron_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Repair_polyhedron_plugin.cpp @@ -327,9 +327,9 @@ void Polyhedron_demo_repair_polyhedron_plugin::on_actionMergeDuplicatedVerticesO if(Item* poly_item = qobject_cast(scene->item(index))) { - const boost::graph_traits::vertices_size_type old_nv = vertices(*poly_item->polyhedron()).size(); + const std::size_t old_nv = vertices(*poly_item->polyhedron()).size(); PMP::merge_duplicated_vertices_in_boundary_cycles(*poly_item->polyhedron()); - const boost::graph_traits::vertices_size_type new_nv = vertices(*poly_item->polyhedron()).size(); + const std::size_t new_nv = vertices(*poly_item->polyhedron()).size(); CGAL::Three::Three::information(tr(" %1 vertices merged").arg(old_nv - new_nv)); if(old_nv != new_nv) { From 8b29d69755b19df6694a63648449e9a0b33800fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 23 Mar 2020 19:36:32 +0100 Subject: [PATCH 129/141] fix warning --- .../CGAL/Triangulation_2/internal/CTP2_subconstraint_graph.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Triangulation_2/include/CGAL/Triangulation_2/internal/CTP2_subconstraint_graph.h b/Triangulation_2/include/CGAL/Triangulation_2/internal/CTP2_subconstraint_graph.h index cd4dff681b4..66557dda87a 100644 --- a/Triangulation_2/include/CGAL/Triangulation_2/internal/CTP2_subconstraint_graph.h +++ b/Triangulation_2/include/CGAL/Triangulation_2/internal/CTP2_subconstraint_graph.h @@ -66,12 +66,12 @@ public: boost::make_transform_iterator(g.ctp2.subconstraints_end(), Subconstr_uf(Subconstr_map()))); } - friend vertex_descriptor source (edge_descriptor ed, const CTP2_subconstraint_graph& g) + friend vertex_descriptor source (edge_descriptor ed, const CTP2_subconstraint_graph&) { return ed.first; } - friend vertex_descriptor target (edge_descriptor ed, const CTP2_subconstraint_graph& g) + friend vertex_descriptor target (edge_descriptor ed, const CTP2_subconstraint_graph&) { return ed.second; } From 24611ab4ed974078c4c1bc8e7e6d7421ebb8c07c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 24 Mar 2020 08:53:00 +0100 Subject: [PATCH 130/141] fix assertion --- .../test/Polygon_mesh_processing/test_split_volume.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_split_volume.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_split_volume.cpp index 611e23e5477..91a62a01c22 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_split_volume.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_split_volume.cpp @@ -178,7 +178,7 @@ int main() nested_cc_per_cc[i].size()==3 || nested_cc_per_cc[i].size()==0); } - assert(sum = 0+3*1+3); + assert(sum == 0+3*1+3); } // test level 0 orientation From ed5c6f1a1bb7c6b6f9b2aabc34e3eae67a8de730 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 24 Mar 2020 09:41:00 +0100 Subject: [PATCH 131/141] change a test into a precondition --- .../Polygon_mesh_processing/orientation.h | 33 +++++++------------ 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index 5214bcaac0c..6e9dae3cf7e 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -361,6 +361,8 @@ void reverse_face_orientations(const FaceRange& face_range, PolygonMesh& pmesh) * @param tm a closed triangulated surface mesh * @param np optional sequence of \ref pmp_namedparameters among the ones listed below * +* \pre `CGAL::is_closed(tm)` +* * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} * the property map with the points associated to the vertices of `tm`. @@ -459,7 +461,6 @@ void orient(TriangleMesh& tm) enum Volume_error_code { VALID_VOLUME, ///< The set of faces bounds a volume SURFACE_WITH_SELF_INTERSECTIONS, ///< The set of faces is self-intersecting VOLUME_INTERSECTION, ///< The set of faces intersects another surface connected component - SURFACE_WITH_BOUNDARIES, ///< The set of faces does not define a closed surface INCOMPATIBLE_ORIENTATION ///< The set of faces is included in a volume but has an incompatible orientation }; namespace internal { @@ -668,6 +669,8 @@ void set_cc_intersecting_pairs( * @param volume_id_map the property map filled by this function with indices of volume components associated to the faces of `tm` * @param np optional sequence of \ref pmp_namedparameters "Named Parameters" among the ones listed below * + * @pre `CGAL::is_closed(tm)` + * * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} * the property map with the points associated to the vertices of `tm`. @@ -752,7 +755,8 @@ volume_connected_components(const TriangleMesh& tm, VolumeFaceIndexMap volume_id_map, const NamedParameters& np) { - CGAL_precondition( is_triangle_mesh(tm) ); + CGAL_precondition(is_triangle_mesh(tm)); + CGAL_precondition(is_closed(tm)); typedef boost::graph_traits GT; typedef typename GT::vertex_descriptor vertex_descriptor; @@ -803,24 +807,7 @@ volume_connected_components(const TriangleMesh& tm, std::vector < std::size_t > nesting_levels(nb_cc, 0); // indicates for each CC its nesting level boost::dynamic_bitset<> cc_handled(nb_cc, 0); - std::size_t next_volume_id = 0; -// Handle open connected components - for(halfedge_descriptor h : halfedges(tm)) - { - if (is_border(h, tm)) - { - face_descriptor fd = face( opposite(h, tm), tm ); - std::size_t cc_id = face_cc[ get(fid_map, fd) ]; - if ( !cc_handled.test(cc_id) ) - { - cc_handled.set(cc_id); - cc_volume_ids[cc_id]=next_volume_id++; - error_codes.push_back(SURFACE_WITH_BOUNDARIES); - if (used_as_a_predicate) return 0; - } - } - } // Handle self-intersecting connected components typedef std::pair Face_pair; @@ -1221,7 +1208,7 @@ bool does_bound_a_volume(const TriangleMesh& tm, const NamedParameters& np) typedef boost::graph_traits GT; typedef typename GT::face_descriptor face_descriptor; - if (!is_closed(tm)) return false; + CGAL_precondition(is_closed(tm)); CGAL_precondition(is_triangle_mesh(tm)); Static_property_map vidmap(0); // dummy map not used @@ -1259,6 +1246,8 @@ std::size_t volume_connected_components(const TriangleMesh& tm, VolumeFaceIndexM * @param tm a closed triangulated surface mesh * @param np optional sequence of \ref pmp_namedparameters among the ones listed below * + * @pre `CGAL::is_closed(tm)` + * * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} * the property map with the points associated to the vertices of `tm`. @@ -1287,8 +1276,8 @@ void orient_to_bound_a_volume(TriangleMesh& tm, typedef typename GetVertexPointMap::const_type Vpm; typedef typename GetInitializedFaceIndexMap::type FaceIndexMap; - if (!is_closed(tm)) return; - if (!is_triangle_mesh(tm)) return; + CGAL_assertion(is_closed(tm)); + CGAL_assertion(is_triangle_mesh(tm)); using parameters::get_parameter; From 7a002c15ccd24e2a3ca6759167c7b03e788c5c4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 24 Mar 2020 14:29:22 +0100 Subject: [PATCH 132/141] remove open from test --- .../test_split_volume.cpp | 22 ------------------- 1 file changed, 22 deletions(-) diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_split_volume.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_split_volume.cpp index 91a62a01c22..2270a34c4cb 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_split_volume.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_split_volume.cpp @@ -105,28 +105,6 @@ int main() assert( error_codes==expected_result ); } - // test open cc - { - Surface_mesh tmp = input_mesh; - Surface_mesh::Property_map tmp_vol_id_map = - tmp.add_property_map().first; - // create a self-intersection - Surface_mesh::Halfedge_index h = *tmp.halfedges().begin(); - CGAL::Euler::remove_face(h, tmp); - - nb_vol = PMP::volume_connected_components(tmp, tmp_vol_id_map, - params::do_orientation_tests(false) - .error_codes(boost::ref(error_codes)) - .do_self_intersection_tests(true)); - - assert(nb_vol==2); - expected_result.clear(); - expected_result.push_back(PMP::VALID_VOLUME); - expected_result.push_back(PMP::SURFACE_WITH_BOUNDARIES); - std::sort(error_codes.begin(), error_codes.end()); - assert( error_codes==expected_result ); - } - // test intersection between cc { Surface_mesh tmp = input_mesh; From 9c0e99ab515851990972884edea0a3530f374632 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 24 Mar 2020 14:29:45 +0100 Subject: [PATCH 133/141] input must be triangulated --- .../internal/Corefinement/intersection_impl.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/intersection_impl.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/intersection_impl.h index ab52338fcab..72c94c605d7 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/intersection_impl.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/intersection_impl.h @@ -1268,6 +1268,8 @@ public: : nodes(tm1, tm2, vpm1, vpm2) , visitor(v) { + CGAL_precondition(is_triangle_mesh(tm1)); + CGAL_precondition(is_triangle_mesh(tm2)); CGAL_assertion_code( doing_autorefinement=false; ) } @@ -1278,6 +1280,7 @@ public: : nodes(tm, tm, vpm, vpm) , visitor(v) { + CGAL_precondition(is_triangle_mesh(tm)); CGAL_assertion_code( doing_autorefinement=true; ) } From ea80a641ece0ebe5033effee766258af383f38fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 24 Mar 2020 14:30:45 +0100 Subject: [PATCH 134/141] check init only if writable --- .../Corefinement/Face_graph_output_builder.h | 12 ++++++++++-- .../Corefinement/Output_builder_for_autorefinement.h | 6 +++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h index 602ae2a2fde..325a3693d5b 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h @@ -463,11 +463,19 @@ public: Intersection_edge_map& intersection_edges2 = mesh_to_intersection_edges[&tm2]; // The property map must be either writable or well-initialized - if(!BGL::internal::is_index_map_valid(fids1, num_faces(tm1), faces(tm1))) + if( CGAL::internal::Is_writable_property_map::value && + !BGL::internal::is_index_map_valid(fids1, num_faces(tm1), faces(tm1)) ) + { BGL::internal::initialize_face_index_map(fids1, tm1); + } + CGAL_assertion(BGL::internal::is_index_map_valid(fids1, num_faces(tm1), faces(tm1))); - if(!BGL::internal::is_index_map_valid(fids2, num_faces(tm2), faces(tm2))) + if( CGAL::internal::Is_writable_property_map::value && + !BGL::internal::is_index_map_valid(fids2, num_faces(tm2), faces(tm2)) ) + { BGL::internal::initialize_face_index_map(fids2, tm2); + } + CGAL_assertion(BGL::internal::is_index_map_valid(fids2, num_faces(tm2), faces(tm2))); // bitset to identify coplanar faces boost::dynamic_bitset<> tm1_coplanar_faces(num_faces(tm1), 0); diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Output_builder_for_autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Output_builder_for_autorefinement.h index 031d23a1c36..db57fbee53a 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Output_builder_for_autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Output_builder_for_autorefinement.h @@ -237,8 +237,12 @@ public: } // The property map must be either writable or well-initialized - if(!BGL::internal::is_index_map_valid(fids, num_faces(tm), faces(tm))) + if( CGAL::internal::Is_writable_property_map::value && + !BGL::internal::is_index_map_valid(fids, num_faces(tm), faces(tm)) ) + { BGL::internal::initialize_face_index_map(fids, tm); + } + CGAL_assertion(BGL::internal::is_index_map_valid(fids, num_faces(tm), faces(tm))); // bitset to identify coplanar faces boost::dynamic_bitset<> tm_coplanar_faces(num_faces(tm), 0); From e6a42bb597488cb3fe45616ebb4fa0ef47696da4 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Tue, 24 Mar 2020 21:20:44 +0100 Subject: [PATCH 135/141] Fix again a compilation error on Windows It was: ``` ..\include\CGAL/Mesh_3/Protect_edges_sizing_field.h(1265): error C2121: '#': invalid character: possibly the result of a macro expansion ..\include\CGAL/Mesh_3/Protect_edges_sizing_field.h(1257): error C2760: syntax error: unexpected token 'identifier', expected '(' ``` --- Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h b/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h index 625920ff9cc..df7a76cb2c2 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h +++ b/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h @@ -1254,15 +1254,17 @@ insert_balls(const Vertex_handle& vp, norm_step_size = step_size; } else { CGAL_assertion_code(using boost::math::float_prior); +#if CGAL_MESH_3_PROTECTION_DEBUG & 4 CGAL_assertion_msg(n==0 || dleft_frac >= float_prior(float_prior(1.)), ([this](){ CGAL_USE(this); -#if CGAL_MESH_3_PROTECTION_DEBUG & 4 dump_c3t3(this->c3t3_, "dump-bug"); -#endif return "the sampling of protecting balls is not possible"; }())); +#else + CGAL_assertion(n==0 || dleft_frac >= float_prior(float_prior(1.))); +#endif } // Launch balls From 401e06c64cbf8e51b6dfe6411ee26255c21f4e5d Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Tue, 24 Mar 2020 16:33:54 +0100 Subject: [PATCH 136/141] fix warning --- .../internal/tetrahedron_intersection_helpers.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h index 03a8db1348d..b227f9e3918 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_intersection_helpers.h @@ -61,7 +61,8 @@ void fill_segments_infos(std::vector& segments, std::size_t t_neighbor; Wrapped_segment(const Segment& s) :segment(s), s_dangling(true), - t_dangling(true){} + t_dangling(true), s_neighbor(0), + t_neighbor(0){} }; std::vector wrapped_segments; @@ -117,7 +118,7 @@ void fill_segments_infos(std::vector& segments, //fill dangling extremities using triangle edges if(w_s.s_dangling) { - for(std::size_t e_id = 0; e_id < 3; ++e_id) + for(int e_id = 0; e_id < 3; ++e_id) { Segment edge(input_tr.vertex(e_id), input_tr.vertex(e_id+1)); if(!edge.has_on(s.source())) @@ -148,7 +149,7 @@ void fill_segments_infos(std::vector& segments, } if(w_s.t_dangling) { - for(std::size_t e_id = 0; e_id < 3; ++e_id) + for(int e_id = 0; e_id < 3; ++e_id) { Segment edge(input_tr.vertex(e_id), input_tr.vertex(e_id+1)); if(!edge.has_on(s.target())) From 8b4118912d126c8939b1cc068d4f8d45458b65b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 26 Mar 2020 18:58:21 +0100 Subject: [PATCH 137/141] extra run of the script to remove tabs and trailing whitespaces --- .../include/CGAL/Intersection_traits_2.h | 10 +- .../CGAL/Intersections_2/Circle_2_Line_2.h | 6 +- .../Triangle_2_Triangle_2_intersection_impl.h | 14 +- Intersections_2/include/CGAL/intersection_2.h | 6 +- .../Intersections_2/test_intersections_2.cpp | 2 +- .../include/CGAL/Intersection_traits_3.h | 24 +-- .../Iso_cuboid_3_Plane_3_intersection.h | 14 +- .../Tetrahedron_3_Line_3_intersection.h | 6 +- .../Tetrahedron_3_Triangle_3_intersection.h | 6 +- .../Triangle_3_Triangle_3_intersection.h | 24 +-- .../internal/intersection_3_1_impl.h | 192 +++++++++--------- .../Intersections_3/test_intersections_3.cpp | 4 +- Kernel_23/doc/Kernel_23/CGAL/intersections.h | 4 +- 13 files changed, 156 insertions(+), 156 deletions(-) diff --git a/Intersections_2/include/CGAL/Intersection_traits_2.h b/Intersections_2/include/CGAL/Intersection_traits_2.h index b449bfc2341..d87c599548c 100644 --- a/Intersections_2/include/CGAL/Intersection_traits_2.h +++ b/Intersections_2/include/CGAL/Intersection_traits_2.h @@ -6,7 +6,7 @@ // $URL$ // $Id$ // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial -// +// // // Author(s) : Philipp Möller @@ -47,7 +47,7 @@ CGAL_INTERSECTION_TRAITS_2(Ray_2, Triangle_2, Point_2, Segment_2) template struct Intersection_traits { - typedef typename + typedef typename boost::variant< typename K::Point_2, typename K::Segment_2, typename K::Triangle_2, typename std::vector< typename K::Point_2 > > variant_type; typedef typename boost::optional< variant_type > result_type; @@ -95,11 +95,11 @@ struct Intersection_traits { template struct Intersection_traits { - typedef typename boost::variant > variant_type; typedef typename boost::optional < variant_type > result_type; -}; +}; template struct Intersection_traits diff --git a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Line_2.h b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Line_2.h index f2b5f0df088..2ff82e64475 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Line_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Line_2.h @@ -10,7 +10,7 @@ // $URL$ // $Id$ // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial -// +// // // Author(s) : Geert-Jan Giezeman @@ -29,7 +29,7 @@ namespace internal { template bool -do_intersect(const typename K::Circle_2 & c, +do_intersect(const typename K::Circle_2 & c, const typename K::Line_2& l, const K&) { @@ -38,7 +38,7 @@ do_intersect(const typename K::Circle_2 & c, template bool -do_intersect(const typename K::Line_2& l, +do_intersect(const typename K::Line_2& l, const typename K::Circle_2 & c, const K&) { diff --git a/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h b/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h index bfde9e77409..896c6bf5748 100644 --- a/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h +++ b/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h @@ -1,16 +1,16 @@ -// Copyright (c) 2000 +// Copyright (c) 2000 // Utrecht University (The Netherlands), // ETH Zurich (Switzerland), // INRIA Sophia-Antipolis (France), // Max-Planck-Institute Saarbruecken (Germany), -// and Tel-Aviv University (Israel). All rights reserved. +// and Tel-Aviv University (Israel). All rights reserved. // // This file is part of CGAL (www.cgal.org) // // $URL$ // $Id$ // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial -// +// // // Author(s) : Geert-Jan Giezeman @@ -24,7 +24,7 @@ #include namespace CGAL { - + namespace Intersections { namespace internal { @@ -156,7 +156,7 @@ public: enum Intersection_results {NO_INTERSECTION, POINT, SEGMENT, TRIANGLE, POLYGON}; Triangle_2_Triangle_2_pair(typename K::Triangle_2 const *trian1, typename K::Triangle_2 const *trian2) - : _trian1(trian1), _trian2(trian2), _known(false) {} + : _trian1(trian1), _trian2(trian2), _known(false) {} Intersection_results intersection_type() const; @@ -305,7 +305,7 @@ Triangle_2_Triangle_2_pair::intersection_segment() const intersection_type(); CGAL_kernel_assertion(_result == SEGMENT); return Segment_2(_pointlist.first->point, - _pointlist.first->next->point); + _pointlist.first->next->point); } template @@ -346,7 +346,7 @@ struct Is_cw template typename CGAL::Intersection_traits ::result_type -intersection(const typename K::Triangle_2 &tr1, +intersection(const typename K::Triangle_2 &tr1, const typename K::Triangle_2 &tr2, const K&) { diff --git a/Intersections_2/include/CGAL/intersection_2.h b/Intersections_2/include/CGAL/intersection_2.h index cfc71672e5c..4b22e327369 100644 --- a/Intersections_2/include/CGAL/intersection_2.h +++ b/Intersections_2/include/CGAL/intersection_2.h @@ -1,16 +1,16 @@ -// Copyright (c) 2000 +// Copyright (c) 2000 // Utrecht University (The Netherlands), // ETH Zurich (Switzerland), // INRIA Sophia-Antipolis (France), // Max-Planck-Institute Saarbruecken (Germany), -// and Tel-Aviv University (Israel). All rights reserved. +// and Tel-Aviv University (Israel). All rights reserved. // // This file is part of CGAL (www.cgal.org) // // $URL$ // $Id$ // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial -// +// // // Author(s) : Geert-Jan Giezeman diff --git a/Intersections_2/test/Intersections_2/test_intersections_2.cpp b/Intersections_2/test/Intersections_2/test_intersections_2.cpp index 23a01a4fc2b..7e0ff4ca84c 100644 --- a/Intersections_2/test/Intersections_2/test_intersections_2.cpp +++ b/Intersections_2/test/Intersections_2/test_intersections_2.cpp @@ -19,7 +19,7 @@ const double epsilon = 0.001; struct randomint { randomint() ; - int get() const { return sequence[cur]; } + int get() const { return sequence[cur]; } int next() { cur = (cur+1)%11; return get();} private: int sequence[11]; diff --git a/Intersections_3/include/CGAL/Intersection_traits_3.h b/Intersections_3/include/CGAL/Intersection_traits_3.h index 7b82fda3e5b..dee4d2e3e8b 100644 --- a/Intersections_3/include/CGAL/Intersection_traits_3.h +++ b/Intersections_3/include/CGAL/Intersection_traits_3.h @@ -6,7 +6,7 @@ // $URL$ // $Id$ // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial -// +// // // Author(s) : Philipp Möller @@ -72,7 +72,7 @@ CGAL_INTERSECTION_TRAITS_3(Sphere_3, Sphere_3, Point_3, Circle_3, Sphere_3) template struct Intersection_traits { - typedef typename + typedef typename boost::variant< typename K::Point_3, typename K::Segment_3, typename K::Triangle_3, typename std::vector< typename K::Point_3 > > variant_type; typedef typename boost::optional< variant_type > result_type; @@ -96,7 +96,7 @@ CGAL_INTERSECTION_TRAITS_2(Iso_cuboid_3, Ray_3, Point_3, Segment_3) // Iso_cuboid_3 Iso_cuboid_3, variant of one template struct Intersection_traits { - typedef typename + typedef typename boost::variant< typename K::Iso_cuboid_3 > variant_type; typedef typename boost::optional< variant_type > result_type; }; @@ -106,31 +106,31 @@ struct Intersection_traits struct Intersection_traits { - typedef typename + typedef typename boost::variant< typename K::Segment_3, typename K::Point_3 > variant_type; typedef typename boost::optional< variant_type > result_type; }; template -struct Intersection_traits : +struct Intersection_traits : public Intersection_traits {}; // Bbox_3 Segment_3 template -struct Intersection_traits : +struct Intersection_traits : public Intersection_traits {}; template -struct Intersection_traits : +struct Intersection_traits : public Intersection_traits {}; // Bbox_3 Ray_3 template -struct Intersection_traits : +struct Intersection_traits : public Intersection_traits {}; template -struct Intersection_traits : +struct Intersection_traits : public Intersection_traits {}; // Point_3 Iso_cuboid_3, variant of one @@ -140,7 +140,7 @@ struct Intersection_traits { boost::variant< typename K::Point_3 > variant_type; typedef typename boost::optional< variant_type > result_type; }; - + // Bbox_3 Point_3, variant of one template struct Intersection_traits { @@ -155,7 +155,7 @@ struct Intersection_traits { boost::variant< typename K::Point_3 > variant_type; typedef typename boost::optional< variant_type > result_type; }; - + // Bbox_3 Iso_cuboid_3, variant of 1 template @@ -176,7 +176,7 @@ struct Intersection_traits { boost::variant< typename K::Point_3 > variant_type; typedef typename boost::optional< variant_type > result_type; }; - + // Iso_cuboid_3 Plane_3, variant of 4 template struct Intersection_traits { diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h index 456f2219cf1..977c7dcc584 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h @@ -133,10 +133,10 @@ intersection( res[1] = p2; res[2] = p1; res[3] = entry_seg.source(); - - typename K::Coplanar_orientation_3 coplanar_orientation = + + typename K::Coplanar_orientation_3 coplanar_orientation = k.coplanar_orientation_3_object(); - + if( coplanar_orientation(res[0], res[1], res[2]) != coplanar_orientation(res[0], res[1], res[3])) { @@ -157,9 +157,9 @@ intersection( res[1] = back.target(); res[2] = back.source(); res[3] = front.source(); - typename K::Coplanar_orientation_3 coplanar_orientation = + typename K::Coplanar_orientation_3 coplanar_orientation = k.coplanar_orientation_3_object(); - + if( coplanar_orientation(res[0], res[1], res[2]) != coplanar_orientation(res[0], res[1], res[3])) { @@ -191,7 +191,7 @@ intersection( res.push_back(cub.vertex(1)); res.push_back(cub.vertex(6)); res.push_back(cub.vertex(5)); - + } else if(has_on(pl, cub.vertex(1)) && has_on(pl, cub.vertex(2)) @@ -235,7 +235,7 @@ intersection( default: break; } - + Poly filtered_points; filter_points(points, filtered_points); diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Line_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Line_3_intersection.h index 27b1e33919d..a36871403a7 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Line_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Line_3_intersection.h @@ -35,17 +35,17 @@ struct Tetrahedron_Line_intersection_3 const typename K::Tetrahedron_3& tet, const typename K::Line_3& o):Base(tet,o) {} - + bool all_inside_test() { return false; } - + bool are_extremities_inside_test() { return false; } - + }; //Tetrahedron_3 Line_3 diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Triangle_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Triangle_3_intersection.h index 80fdbb55520..0a3839ec258 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Triangle_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Triangle_3_intersection.h @@ -245,11 +245,11 @@ intersection( { Poly res; res.reserve(5); - typename K::Compute_scalar_product_3 scalar = + typename K::Compute_scalar_product_3 scalar = k.compute_scalar_product_3_object(); - typename K::Construct_vector_3 construct_vector = + typename K::Construct_vector_3 construct_vector = k.construct_vector_3_object(); - + if(scalar(construct_vector(inside_points.front(), inside_points.back()), construct_vector(tmp.front(), tmp.back())) > 0) { diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Triangle_3_Triangle_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Triangle_3_Triangle_3_intersection.h index 58751dfb6e7..17358b81ea5 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Triangle_3_Triangle_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Triangle_3_Triangle_3_intersection.h @@ -26,7 +26,7 @@ namespace CGAL { template class Triangle_3; - + namespace Intersections { namespace internal{ @@ -50,7 +50,7 @@ void intersection_coplanar_triangles_cutoff( orientations[ &(*it) ]=orient(p,q,r,*it); int pt_added=0; - + const typename Kernel::Point_3* prev = &(*boost::prior(inter_pts.end())); Iterator stop = inter_pts.size() > 2 ? inter_pts.end() : boost::prior(inter_pts.end()); for (Iterator it=inter_pts.begin();it!=stop;++it) @@ -61,7 +61,7 @@ void intersection_coplanar_triangles_cutoff( { typename Intersection_traits - ::result_type + ::result_type obj = intersection(Line_3(p,q),Line_3(*prev,curr),k); // assert "not empty" CGAL_kernel_assertion(bool(obj)); @@ -71,9 +71,9 @@ void intersection_coplanar_triangles_cutoff( orientations[prev]=COLLINEAR; ++pt_added; } - prev=&(*it); + prev=&(*it); } - + CGAL_kernel_assertion(pt_added<3); Iterator it=inter_pts.begin(); while(it!=inter_pts.end()) @@ -84,7 +84,7 @@ void intersection_coplanar_triangles_cutoff( ++it; } } - + template typename Intersection_traits::result_type intersection_coplanar_triangles( @@ -93,7 +93,7 @@ intersection_coplanar_triangles( const K& k) { const typename K::Point_3& p=t1.vertex(0),q=t1.vertex(1),r=t1.vertex(2); - + std::list inter_pts; inter_pts.push_back(t2.vertex(0)); inter_pts.push_back(t2.vertex(1)); @@ -103,7 +103,7 @@ intersection_coplanar_triangles( intersection_coplanar_triangles_cutoff(p,q,r,k,inter_pts); //line pq intersection_coplanar_triangles_cutoff(q,r,p,k,inter_pts); //line qr intersection_coplanar_triangles_cutoff(r,p,q,k,inter_pts); //line rp - + switch ( inter_pts.size() ) { case 0: return intersection_return(); @@ -149,7 +149,7 @@ struct Triangle_Line_visitor { result_type operator()(const typename K::Segment_3& s1, const typename K::Segment_3& s2) const { - typename Intersection_traits::result_type + typename Intersection_traits::result_type v = intersection_collinear_segments(s1,s2,K()); if(v) { @@ -162,7 +162,7 @@ struct Triangle_Line_visitor { return result_type(); } }; - + template typename Intersection_traits::result_type intersection( @@ -172,7 +172,7 @@ intersection( { CGAL_precondition(!t1.is_degenerate() && !t2.is_degenerate()); - typename Intersection_traits::result_type + typename Intersection_traits::result_type v = internal::intersection(t1.supporting_plane(), t2.supporting_plane(), k); if(!v) { @@ -190,7 +190,7 @@ intersection( typedef typename Intersection_traits::result_type Triangle_Line_Inter; - + Triangle_Line_Inter inter1 = intersection_coplanar(t1,*line,k); Triangle_Line_Inter inter2 = intersection_coplanar(t2,*line,k); if(!inter1 || !inter2) { diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/intersection_3_1_impl.h b/Intersections_3/include/CGAL/Intersections_3/internal/intersection_3_1_impl.h index a6eac72e415..f836dbd6aea 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/intersection_3_1_impl.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/intersection_3_1_impl.h @@ -10,7 +10,7 @@ // $URL$ // $Id$ // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial -// +// // // Author(s) : Geert-Jan Giezeman // Sebastien Loriot @@ -56,7 +56,7 @@ namespace CGAL { // the special plane_3 function template -inline +inline typename cpp11::result_of::type intersection(const Plane_3 &plane1, const Plane_3 &plane2, const Plane_3 &plane3) @@ -81,7 +81,7 @@ namespace internal { template typename Intersection_traits::result_type -intersection(const typename K::Plane_3 &plane, +intersection(const typename K::Plane_3 &plane, const typename K::Line_3 &line, const K& /*k*/) { @@ -115,7 +115,7 @@ intersection(const typename K::Plane_3 &plane, template inline typename Intersection_traits::result_type -intersection(const typename K::Line_3 &line, +intersection(const typename K::Line_3 &line, const typename K::Plane_3 &plane, const K& k) { @@ -124,7 +124,7 @@ intersection(const typename K::Line_3 &line, template typename Intersection_traits::result_type -intersection(const typename K::Plane_3 &plane1, +intersection(const typename K::Plane_3 &plane1, const typename K::Plane_3 &plane2, const K&) { @@ -191,11 +191,11 @@ intersection(const typename K::Plane_3 &plane1, const typename K::Plane_3 &plane3, const K& k) { - typedef - typename boost::optional< + typedef + typename boost::optional< boost::variant > + typename K::Plane_3> > result_type; typedef typename K::Point_3 Point_3; @@ -206,11 +206,11 @@ intersection(const typename K::Plane_3 &plane1, // a line, a plane, or empty. typename Intersection_traits::result_type o12 = internal::intersection(plane1, plane2, k); - + if(o12) { if(const Line_3* l = intersect_get(o12)) { // either point or line - typename Intersection_traits::result_type + typename Intersection_traits::result_type v = internal::intersection(plane3, *l, k); if(v) { if(const Point_3* p = intersect_get(v)) @@ -220,7 +220,7 @@ intersection(const typename K::Plane_3 &plane1, } } else if(const Plane_3 *pl = intersect_get(o12)) { // either line or plane - typename Intersection_traits::result_type + typename Intersection_traits::result_type v = internal::intersection(plane3, *pl, k); if(v) { if(const Plane_3* p = intersect_get(v)) @@ -230,14 +230,14 @@ intersection(const typename K::Plane_3 &plane1, } } } - + return result_type(); } template bool -do_intersect(const typename K::Plane_3 &plane, +do_intersect(const typename K::Plane_3 &plane, const typename K::Line_3 &line, const K&) { @@ -265,7 +265,7 @@ do_intersect(const typename K::Plane_3 &plane, template inline bool -do_intersect(const typename K::Line_3 &line, +do_intersect(const typename K::Line_3 &line, const typename K::Plane_3 &plane, const K& k) { @@ -290,7 +290,7 @@ intersection(const typename K::Line_3 &l1, (v1.y() * v2.z() == v1.z() * v2.y())) return intersection_return(l1); } - + if(K().are_parallel_3_object()(l1,l2)) return intersection_return(); const Point_3 &p1 = l1.point(); const Point_3 &p3 = l2.point(); @@ -340,7 +340,7 @@ intersection_collinear_segments(const typename K::Segment_3 &s1, const typename K::Point_3& p=s1[0],q=s1[1],r=s2[0],s=s2[1]; typename K::Collinear_are_ordered_along_line_3 cln_order=k.collinear_are_ordered_along_line_3_object(); - + if ( cln_order(p,r,q) ){ if ( cln_order(p,s,q) ) return intersection_return(s2); @@ -349,33 +349,33 @@ intersection_collinear_segments(const typename K::Segment_3 &s1, if ( cln_order(r,q,s) ) return intersection_return(s1); return intersection_return(p); } - return r!=q ? intersection_return( typename K::Segment_3(r,q) ) + return r!=q ? intersection_return( typename K::Segment_3(r,q) ) : intersection_return(q); } if ( cln_order(p,s,q) ){ if ( cln_order(r,p,s) ){ if (s!=p) return intersection_return( typename K::Segment_3(s,p) ); - if (cln_order(r,q,s)) return intersection_return(s1); + if (cln_order(r,q,s)) return intersection_return(s1); return intersection_return(p); } - return s!=q ? intersection_return( typename K::Segment_3(s,q) ) + return s!=q ? intersection_return( typename K::Segment_3(s,q) ) : intersection_return(q); } - + if ( cln_order(r,p,s) ) - return intersection_return(s1); + return intersection_return(s1); return intersection_return(); } template -struct L_p_visitor : public boost::static_visitor< - typename Intersection_traits::result_type - > + > { - typedef typename Intersection_traits::result_type result_type; L_p_visitor(const typename K::Segment_3& s1, const typename K::Segment_3& s2) : s1(s1), s2(s2) { } @@ -405,7 +405,7 @@ intersection(const typename K::Segment_3 &s1, { CGAL_precondition(! s1.is_degenerate () && ! s2.is_degenerate () ); - typename Intersection_traits::result_type + typename Intersection_traits::result_type v = internal::intersection(s1.supporting_line(),s2.supporting_line(), K()); if(v) { @@ -429,16 +429,16 @@ do_intersect(const typename K::Segment_3 &s1, typename K::Coplanar_orientation_3 cpl_orient=k.coplanar_orientation_3_object(); ::CGAL::Orientation or1 = cpl_orient(s1[0],s1[1],s2[0]); ::CGAL::Orientation or2 = cpl_orient(s1[0],s1[1],s2[1]); - + if ( or1 == COLLINEAR && or2 ==COLLINEAR ) { //segments are collinear typename K::Collinear_are_ordered_along_line_3 cln_order=k.collinear_are_ordered_along_line_3_object(); - return cln_order(s1[0],s2[0],s1[1]) || + return cln_order(s1[0],s2[0],s1[1]) || cln_order(s1[0],s2[1],s1[1]) || cln_order(s2[0],s1[0],s2[1]) ; } - + if ( or1 != or2 ){ or1=cpl_orient(s2[0],s2[1],s1[0]); return (or1 == COLLINEAR || or1 != cpl_orient(s2[0],s2[1],s1[1])); @@ -454,20 +454,20 @@ intersection(const typename K::Line_3 &l, const K& k) { CGAL_precondition(! l.is_degenerate () && ! s.is_degenerate () ); - - typename Intersection_traits::result_type + + typename Intersection_traits::result_type v = internal::intersection(l,s.supporting_line(), K()); if(v) { if(const typename K::Point_3* p = intersect_get (v)) { typename K::Collinear_are_ordered_along_line_3 cln_order=k.collinear_are_ordered_along_line_3_object(); - if(cln_order(s[0],*p,s[1])) + if(cln_order(s[0],*p,s[1])) return intersection_return(*p); } else { return intersection_return(s); } } - + return intersection_return(); } @@ -496,9 +496,9 @@ do_intersect(const typename K::Line_3 &l, typename K::Point_3 p1=l.point(0); typename K::Point_3 p2=l.point(1); ::CGAL::Orientation or1 = cpl_orient(p1,p2,s[0]); - + if ( or1 == COLLINEAR ) return true; - + ::CGAL::Orientation or2 = cpl_orient(p1,p2,s[1]); return or1!=or2; } @@ -539,12 +539,12 @@ intersection(const typename K::Line_3 &l, { CGAL_precondition(! l.is_degenerate () && ! r.is_degenerate () ); - typename Intersection_traits::result_type + typename Intersection_traits::result_type v = internal::intersection(l,r.supporting_line(), k); - + if(v) { if(const typename K::Point_3* p = intersect_get(v)) { - if( Ray_3_has_on_collinear_Point_3(r,*p,k) ) + if( Ray_3_has_on_collinear_Point_3(r,*p,k) ) return intersection_return(*p); } else if(intersect_get(v)) { return intersection_return(r); @@ -598,12 +598,12 @@ intersection(const typename K::Segment_3 &s, { CGAL_precondition(! s.is_degenerate () && ! r.is_degenerate () ); - typename Intersection_traits::result_type + typename Intersection_traits::result_type v = internal::intersection(r.supporting_line(),s, K()); if(v) { if(const typename K::Point_3* p = intersect_get(v)) { - if( Ray_3_has_on_collinear_Point_3(r,*p,k) ) + if( Ray_3_has_on_collinear_Point_3(r,*p,k) ) return intersection_return(*p); } else if(const typename K::Segment_3* s2 = intersect_get(v)) { bool has_source=Ray_3_has_on_collinear_Point_3(r,s.source(),k); @@ -623,7 +623,7 @@ intersection(const typename K::Segment_3 &s, else{ if (has_target){ if (k.equal_3_object() (r.source(),s.target())) - return intersection_return(r.source()); + return intersection_return(r.source()); else return intersection_return( k.construct_segment_3_object()(r.source(),s.target())); @@ -686,12 +686,12 @@ intersection(const typename K::Ray_3 &r1, { CGAL_precondition(! r1.is_degenerate () && ! r2.is_degenerate () ); - typename Intersection_traits::result_type + typename Intersection_traits::result_type v = internal::intersection(r1.supporting_line(),r2, k); if(v) { if(const typename K::Point_3* p = intersect_get(v)) { - if(Ray_3_has_on_collinear_Point_3(r1,*p,k)) + if(Ray_3_has_on_collinear_Point_3(r1,*p,k)) return intersection_return(*p); } else if(const typename K::Ray_3* r = intersect_get(v)) { bool r1_has_s2=Ray_3_has_on_collinear_Point_3(r1,r2.source(),k); @@ -703,7 +703,7 @@ intersection(const typename K::Ray_3 &r1, return intersection_return(r1.source()); else { return intersection_return( - k.construct_segment_3_object()(r1.source(),r2.source())); + k.construct_segment_3_object()(r1.source(),r2.source())); } } else @@ -731,9 +731,9 @@ do_intersect(const typename K::Ray_3 &r1, typename K::Coplanar_orientation_3 pred=k.coplanar_orientation_3_object(); Orientation p0p1s=pred(r1.point(0),r1.point(1),r2.source()); Orientation stp0 =pred(r2.source(),r2.second_point(),r1.point(0)); - + if ( p0p1s == COLLINEAR){ - if(stp0 == COLLINEAR ) + if(stp0 == COLLINEAR ) return Ray_3_has_on_collinear_Point_3(r2,r1.source(),k) || Ray_3_has_on_collinear_Point_3(r1,r2.source(),k); else @@ -753,8 +753,8 @@ intersection(const typename K::Plane_3 &p, typedef typename K::Circle_3 Circle_3; typedef typename K::Point_3 Point_3; typedef typename K::FT FT; - const FT d2 = CGAL::square(p.a()*s.center().x() + - p.b()*s.center().y() + + const FT d2 = CGAL::square(p.a()*s.center().x() + + p.b()*s.center().y() + p.c()*s.center().z() + p.d()) / (square(p.a()) + square(p.b()) + square(p.c())); const FT cmp = d2 - s.squared_radius(); @@ -775,8 +775,8 @@ do_intersect(const typename K::Plane_3 &p, const K&) { typedef typename K::FT FT; - const FT d2 = CGAL::square(p.a()*s.center().x() + - p.b()*s.center().y() + + const FT d2 = CGAL::square(p.a()*s.center().x() + + p.b()*s.center().y() + p.c()*s.center().z() + p.d()) / (square(p.a()) + square(p.b()) + square(p.c())); return d2 <= s.squared_radius(); @@ -818,9 +818,9 @@ intersection(const typename K::Sphere_3 &s1, } else return intersection_return(); // cocentrics } Plane_3 p = K().construct_radical_plane_3_object()(s1,s2); - - - typename Intersection_traits::result_type + + + typename Intersection_traits::result_type v = intersection(p, s1, k); @@ -851,13 +851,13 @@ do_intersect(const typename K::Sphere_3 &s1, template typename Intersection_traits::result_type -intersection(const typename K::Plane_3 &plane, +intersection(const typename K::Plane_3 &plane, const typename K::Ray_3 &ray, const K& k) { typedef typename K::Point_3 Point_3; - typename Intersection_traits::result_type + typename Intersection_traits::result_type v = internal::intersection(plane, ray.supporting_line(), k); if(v) { @@ -878,7 +878,7 @@ intersection(const typename K::Plane_3 &plane, template inline typename Intersection_traits::result_type -intersection(const typename K::Ray_3 &ray, +intersection(const typename K::Ray_3 &ray, const typename K::Plane_3 &plane, const K& k) { @@ -889,21 +889,21 @@ intersection(const typename K::Ray_3 &ray, template bool -do_intersect(const typename K::Plane_3 &plane, +do_intersect(const typename K::Plane_3 &plane, const typename K::Ray_3 &ray, const K& k) { typedef typename K::Point_3 Point_3; - + typename Intersection_traits - ::result_type + ::result_type line_intersection = internal::intersection(plane, ray.supporting_line(), k); if(!line_intersection) return false; if(const Point_3 *isp = intersect_get(line_intersection)) return ray.collinear_has_on(*isp); - + return true; } @@ -911,7 +911,7 @@ do_intersect(const typename K::Plane_3 &plane, template inline bool -do_intersect(const typename K::Ray_3 &ray, +do_intersect(const typename K::Ray_3 &ray, const typename K::Plane_3 &plane, const K& k) { @@ -921,7 +921,7 @@ do_intersect(const typename K::Ray_3 &ray, template typename Intersection_traits::result_type -intersection(const typename K::Plane_3 &plane, +intersection(const typename K::Plane_3 &plane, const typename K::Segment_3 &seg, const K& k) { @@ -945,8 +945,8 @@ intersection(const typename K::Plane_3 &plane, case ON_POSITIVE_SIDE: return intersection_return(); default: // ON_NEGATIVE_SIDE: - { - // intersection object should be a point, but rounding errors + { + // intersection object should be a point, but rounding errors // could lead to: // - a line: in such case, return seg, // - the empty set: return the empty set. @@ -967,8 +967,8 @@ intersection(const typename K::Plane_3 &plane, case ON_ORIENTED_BOUNDARY: return intersection_return(target); case ON_POSITIVE_SIDE: - { - // intersection object should be a point, but rounding errors + { + // intersection object should be a point, but rounding errors // could lead to: // - a line: in such case, return seg, // - the empty set: return the empty set. @@ -995,7 +995,7 @@ intersection(const typename K::Plane_3 &plane, template inline typename Intersection_traits::result_type -intersection(const typename K::Segment_3 &seg, +intersection(const typename K::Segment_3 &seg, const typename K::Plane_3 &plane, const K& k) { @@ -1005,7 +1005,7 @@ intersection(const typename K::Segment_3 &seg, template bool -do_intersect(const typename K::Plane_3 &plane, +do_intersect(const typename K::Plane_3 &plane, const typename K::Segment_3 &seg, const K&) { @@ -1027,7 +1027,7 @@ do_intersect(const typename K::Plane_3 &plane, template inline bool -do_intersect(const typename K::Segment_3 &seg, +do_intersect(const typename K::Segment_3 &seg, const typename K::Plane_3 &plane, const K& k) { @@ -1037,26 +1037,26 @@ do_intersect(const typename K::Segment_3 &seg, template inline typename Intersection_traits::result_type -intersection(const typename K::Plane_3 &plane, +intersection(const typename K::Plane_3 &plane, const typename K::Triangle_3 &tri, const K& k) { - typedef - typename Intersection_traits::result_type + typedef + typename Intersection_traits::result_type pl_res; typename K::Construct_vertex_3 vertex_on = k.construct_vertex_3_object(); - + Oriented_side or0=plane.oriented_side(vertex_on(tri,0)); Oriented_side or1=plane.oriented_side(vertex_on(tri,1)); Oriented_side or2=plane.oriented_side(vertex_on(tri,2)); - + if (or0==ON_ORIENTED_BOUNDARY){ if (or1==ON_ORIENTED_BOUNDARY){ - if (or2==ON_ORIENTED_BOUNDARY) + if (or2==ON_ORIENTED_BOUNDARY) return intersection_return(tri); - else + else return intersection_return(k.construct_segment_3_object() (tri.vertex(0),tri.vertex(1))); } @@ -1089,10 +1089,10 @@ intersection(const typename K::Plane_3 &plane, const typename K::Point_3* p = intersect_get(v); CGAL_kernel_assertion(p!=nullptr); return intersection_return(k.construct_segment_3_object() - (*p,tri.vertex(1))); + (*p,tri.vertex(1))); } } - + if (or2==ON_ORIENTED_BOUNDARY){ if (or1==or0) return intersection_return(tri.vertex(2)); @@ -1101,36 +1101,36 @@ intersection(const typename K::Plane_3 &plane, const typename K::Point_3* p = intersect_get(v); CGAL_kernel_assertion(p!=nullptr); return intersection_return(k.construct_segment_3_object() - (*p,tri.vertex(2))); + (*p,tri.vertex(2))); } } - + //triangle vertices are not in the plane std::vector pts; pts.reserve(2); if (or0!=or1){ pl_res v = intersection(plane, k.construct_line_3_object()(tri.vertex(0),tri.vertex(1)), k); const typename K::Point_3* pt_ptr = intersect_get(v); - CGAL_kernel_assertion( pt_ptr!=nullptr ); + CGAL_kernel_assertion( pt_ptr!=nullptr ); pts.push_back( *pt_ptr ); } if (or0!=or2){ pl_res v = intersection(plane, k.construct_line_3_object()(tri.vertex(0),tri.vertex(2)), k); const typename K::Point_3* pt_ptr = intersect_get(v); - CGAL_kernel_assertion( pt_ptr!=nullptr ); - pts.push_back( *pt_ptr ); + CGAL_kernel_assertion( pt_ptr!=nullptr ); + pts.push_back( *pt_ptr ); } if (or1!=or2){ pl_res v = intersection(plane, k.construct_line_3_object()(tri.vertex(1),tri.vertex(2)), k); const typename K::Point_3* pt_ptr = intersect_get(v); - CGAL_kernel_assertion( pt_ptr!=nullptr ); + CGAL_kernel_assertion( pt_ptr!=nullptr ); pts.push_back( *pt_ptr ); } - + if (pts.empty()) return intersection_return(); - + CGAL_kernel_assertion(pts.size()==2); - + return intersection_return( k.construct_segment_3_object() (*pts.begin(),*boost::prior(pts.end())) ); } @@ -1170,7 +1170,7 @@ intersection(const typename K::Line_3 &line, template inline typename Intersection_traits::result_type -intersection(const Bbox_3 &box, +intersection(const Bbox_3 &box, const typename K::Line_3 &line, const K& k) { @@ -1203,7 +1203,7 @@ intersection(const typename K::Ray_3 &ray, template inline typename Intersection_traits::result_type -intersection(const Bbox_3 &box, +intersection(const Bbox_3 &box, const typename K::Ray_3 &ray, const K& k) { @@ -1214,7 +1214,7 @@ intersection(const Bbox_3 &box, template typename Intersection_traits::result_type -intersection(const typename K::Segment_3 &seg, +intersection(const typename K::Segment_3 &seg, const Bbox_3 &box, const K&) { @@ -1237,7 +1237,7 @@ intersection(const typename K::Segment_3 &seg, template inline typename Intersection_traits::result_type -intersection(const Bbox_3 &box, +intersection(const Bbox_3 &box, const typename K::Segment_3 &seg, const K& k) { @@ -1340,7 +1340,7 @@ intersection(const typename K::Line_3 &line, template inline typename Intersection_traits::result_type -intersection(const typename K::Iso_cuboid_3 &box, +intersection(const typename K::Iso_cuboid_3 &box, const typename K::Line_3 &line, const K& k) { @@ -1412,7 +1412,7 @@ intersection(const typename K::Ray_3 &ray, template inline typename Intersection_traits::result_type -intersection(const typename K::Iso_cuboid_3 &box, +intersection(const typename K::Iso_cuboid_3 &box, const typename K::Ray_3 &ray, const K& k) { @@ -1475,7 +1475,7 @@ intersection(const typename K::Segment_3 &seg, if (_max == _min) { return intersection_return(Point_3(_ref_point + _dir * _min )); } - + return intersection_return( Segment_3(_ref_point + _dir*_min, _ref_point + _dir*_max)); } @@ -1484,7 +1484,7 @@ intersection(const typename K::Segment_3 &seg, template inline typename Intersection_traits::result_type -intersection(const typename K::Iso_cuboid_3 &box, +intersection(const typename K::Iso_cuboid_3 &box, const typename K::Segment_3 &seg, const K& k) { @@ -1496,7 +1496,7 @@ template typename Intersection_traits::result_type intersection( const typename K::Iso_cuboid_3 &icub1, - const typename K::Iso_cuboid_3 &icub2, + const typename K::Iso_cuboid_3 &icub2, const K&) { typedef typename K::Point_3 Point_3; diff --git a/Intersections_3/test/Intersections_3/test_intersections_3.cpp b/Intersections_3/test/Intersections_3/test_intersections_3.cpp index 99390106d79..80913337543 100644 --- a/Intersections_3/test/Intersections_3/test_intersections_3.cpp +++ b/Intersections_3/test/Intersections_3/test_intersections_3.cpp @@ -20,7 +20,7 @@ const double epsilon = 0.001; struct randomint { randomint() ; - int get() const { return sequence[cur]; } + int get() const { return sequence[cur]; } int next() { cur = (cur+1)%11; return get();} private: int sequence[11]; @@ -1262,7 +1262,7 @@ int main() { std::cout << " |||||||| Test Simple_cartesian ||||||||" << std::endl; Test< CGAL::Simple_cartesian >().run(); - + std::cout << " |||||||| Test CGAL::Homogeneous ||||||||" << std::endl; Test< CGAL::Homogeneous >().run(); diff --git a/Kernel_23/doc/Kernel_23/CGAL/intersections.h b/Kernel_23/doc/Kernel_23/CGAL/intersections.h index 0244487cee6..47155df7898 100644 --- a/Kernel_23/doc/Kernel_23/CGAL/intersections.h +++ b/Kernel_23/doc/Kernel_23/CGAL/intersections.h @@ -183,7 +183,7 @@ It is equivalent to `boost::optional< boost::variant< T... > >`, the last column -Additional overloads are provided for the type `Point_2` combined with any other type with the result type being +Additional overloads are provided for the type `Point_2` combined with any other type with the result type being `boost::optional< boost::variant< Point_2 > >`. Overloads are also provided for the type `Bbox_2`, for all intersections existing with the type `Iso_rectangle_2`. Note that the return type for `Bbox_2` - `Bbox_2` @@ -338,7 +338,7 @@ It is equivalent to `boost::optional< boost::variant< T... > >`, the last column -Additional overloads are provided for the type `Point_3` combined with any other type with the result type being +Additional overloads are provided for the type `Point_3` combined with any other type with the result type being `boost::optional< boost::variant< Point_3 > >`. Overloads are also provided for the type `Bbox_3`, for all intersections existing with the type `Iso_cuboid_3`. Note that the return type for `Bbox_3` - `Bbox_3` is `Bbox_3` and not `Iso_cuboid_3`. From 58b10a3605cab96bc2a342c3610779da5c4c4952 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 26 Mar 2020 18:58:50 +0100 Subject: [PATCH 138/141] extra run of the script to remove tabs and trailing whitespaces --- GraphicsView/include/CGAL/Buffer_for_vao.h | 90 ++--- GraphicsView/include/CGAL/Qt/qglviewer_impl.h | 108 +++--- Mesh_3/include/CGAL/Mesh_3/Refine_cells_3.h | 8 +- ...cet_topological_criterion_with_adjacency.h | 16 +- .../Mesh_3/mesh_standard_facet_criteria.h | 108 +++--- .../Mesh_domain_with_polyline_features_3.h | 12 +- Mesher_level/include/CGAL/Double_map.h | 58 +-- Polyhedron/demo/Polyhedron/C3t3_type.h | 6 +- .../Mesh_3/C3t3_rib_exporter_plugin.cpp | 340 +++++++++--------- .../Plugins/Mesh_3/Optimization_plugin.cpp | 140 ++++---- .../Polyhedron/Plugins/Mesh_3/config_mesh_3.h | 4 +- .../Plugins/PCA/Basic_generator_plugin.cpp | 2 +- Polyhedron/demo/Polyhedron/Scene.cpp | 76 ++-- .../demo/Polyhedron/Scene_c3t3_item.cpp | 88 ++--- .../Scene_implicit_function_item.cpp | 18 +- Three/include/CGAL/Three/Three.h | 4 +- 16 files changed, 539 insertions(+), 539 deletions(-) diff --git a/GraphicsView/include/CGAL/Buffer_for_vao.h b/GraphicsView/include/CGAL/Buffer_for_vao.h index 0c5d062fe54..41e92e460df 100644 --- a/GraphicsView/include/CGAL/Buffer_for_vao.h +++ b/GraphicsView/include/CGAL/Buffer_for_vao.h @@ -6,7 +6,7 @@ // $URL$ // $Id$ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial -// +// // // Author(s) : Guillaume Damiand @@ -57,7 +57,7 @@ namespace internal normal); ++nb; } - + assert(nb>0); return (typename Kernel_traits::Kernel::Construct_scaled_vector_3() (normal, 1.0/nb)); @@ -189,18 +189,18 @@ public: bool has_flat_normal() const { return m_flat_normal_buffer!=nullptr; } - + bool has_gouraud_normal() const { return m_gouraud_normal_buffer!=nullptr; } bool has_zero_x() const - { return m_zero_x; } + { return m_zero_x; } bool has_zero_y() const - { return m_zero_y; } + { return m_zero_y; } bool has_zero_z() const - { return m_zero_z; } + { return m_zero_z; } void negate_normals() { @@ -212,19 +212,19 @@ public: { (*array)[i]=-(*array)[i]; } } } - + // 1.1) Add a point, without color. Return the index of the added point. template std::size_t add_point(const KPoint& kp) { if (!has_position()) return (std::size_t)-1; - + Local_point p=get_local_point(kp); add_point_in_buffer(p, *m_pos_buffer); if (m_bb!=nullptr) { (*m_bb)=(*m_bb)+p.bbox(); } - + if (m_zero_x && p.x()!=0) { m_zero_x=false; } if (m_zero_y && p.y()!=0) { m_zero_y=false; } if (m_zero_z && p.z()!=0) { m_zero_z=false; } @@ -265,7 +265,7 @@ public: add_point(kp1); add_point(kp2); } - + // 2.2) Add a segment, with color. template void add_segment(const KPoint& kp1, const KPoint& kp2, const CGAL::Color& c) @@ -273,7 +273,7 @@ public: add_segment(kp1, kp2); add_color(c); add_color(c); - } + } // 2.3) Add an indexed segment, without color. template @@ -324,7 +324,7 @@ public: /// @return true iff a face has begun. bool is_a_face_started() const { return m_face_started; } - + // 3.1) Add a face, without color, without normal. void face_begin() { face_begin_internal(false, false); } @@ -369,7 +369,7 @@ public: } return false; } - + /// Add a point at the end of the current face /// @param p the point to add /// @p_normal the vertex normal at this point (for Gouraud shading) @@ -385,7 +385,7 @@ public: } /// Add an indexed point at the end of the current face, without giving the vertex normal. - /// When Indexation is used, it is not possible to use flat shading or multiple colors + /// When Indexation is used, it is not possible to use flat shading or multiple colors /// for face sor edges. /// Note that we still need the point itself, in order to triangulate the face when necessary. template @@ -398,7 +398,7 @@ public: } return false; } - + /// End the face: compute the triangulation. void face_end() { @@ -408,7 +408,7 @@ public: { /* std::cerr<<"PB: you try to triangulate a face with "<(m_points_of_face)); @@ -444,7 +444,7 @@ public: { if (m_points_of_face.size()==4) { convex_quadrangular_face_end_internal(normal); } // Convex quad - else + else { convex_face_end_internal(normal); } // Convex face with > 4 vertices } else @@ -515,10 +515,10 @@ public: const Local_point& S=facet[id]; const Local_point& T=facet[(id+1==facet.size())?0:id+1]; Local_vector V1=Local_vector((T-S).x(), (T-S).y(), (T-S).z()); - + const Local_point& U=facet[(id+2>=facet.size())?id+2-facet.size():id+2]; Local_vector V2=Local_vector((U-T).x(), (U-T).y(), (U-T).z()); - + local_orientation=Local_kernel::Orientation_3()(V1, V2, normal) ; if(local_orientation!=CGAL::ZERO && local_orientation!=orientation) @@ -537,7 +537,7 @@ protected: std::cerr<<"You cannot start a new face before to finish the previous one."<0) - { - add_indexed_point(m_indices_of_points_of_face[i]); + { + add_indexed_point(m_indices_of_points_of_face[i]); } else { add_point(m_points_of_face[i]); // Add the position of the point if (m_started_face_is_colored) - { add_color(m_color_of_face); } // Add the color + { add_color(m_color_of_face); } // Add the color add_flat_normal(normal); // Add the flat normal // Its smooth normal (if given by the user) if (m_vertex_normals_for_face.size()>0) @@ -575,7 +575,7 @@ protected: } } } - + void convex_quadrangular_face_end_internal(const Local_vector& normal) { // Add indices when they exist @@ -584,7 +584,7 @@ protected: add_indexed_point(m_indices_of_points_of_face[0]); add_indexed_point(m_indices_of_points_of_face[1]); add_indexed_point(m_indices_of_points_of_face[2]); - + add_indexed_point(m_indices_of_points_of_face[0]); add_indexed_point(m_indices_of_points_of_face[2]); add_indexed_point(m_indices_of_points_of_face[3]); @@ -609,7 +609,7 @@ protected: add_flat_normal(normal); if (m_vertex_normals_for_face.size()==0) - { add_gouraud_normal(normal); } + { add_gouraud_normal(normal); } } if (m_vertex_normals_for_face.size()>0) @@ -617,14 +617,14 @@ protected: add_gouraud_normal(m_vertex_normals_for_face[0]); add_gouraud_normal(m_vertex_normals_for_face[1]); add_gouraud_normal(m_vertex_normals_for_face[2]); - + add_gouraud_normal(m_vertex_normals_for_face[0]); add_gouraud_normal(m_vertex_normals_for_face[2]); add_gouraud_normal(m_vertex_normals_for_face[3]); } } } - + void convex_face_end_internal(const Local_vector& normal) { for(std::size_t i=1; imax(p1,p2) std::map > edges; @@ -687,13 +687,13 @@ protected: p1=m_points_of_face[i]; p2=m_points_of_face[i==0?m_points_of_face.size()-1:i-1]; if (p2 m; m[p2]=1; edges[p1]=m; } else if (edges[p1].count(p2)==0) { edges[p1][p2]=1; } else { ++(edges[p1][p2]); } } - + // (1) We insert all the edges as contraint in the CDT. typename CDT::Vertex_handle previous=nullptr, first=nullptr; for (unsigned int i=0; iinfo().v=m_vertex_normals_for_face[i]; } else @@ -709,7 +709,7 @@ protected: if (m_indices_of_points_of_face.size()>0) { vh->info().index=m_indices_of_points_of_face[i]; } - + if(previous!=nullptr && previous!=vh) { p1=m_points_of_face[i]; p2=m_points_of_face[i-1]; @@ -719,7 +719,7 @@ protected: } previous=vh; } - + if (previous!=nullptr && previous!=first) { p1=m_points_of_face[m_points_of_face.size()-1]; p2=m_points_of_face[0]; @@ -727,9 +727,9 @@ protected: if ((edges[p1][p2])%2==1) // odd number of time => constraint { cdt.insert_constraint(previous, first); } } - + // (2) We mark all external triangles - // (2.1) We initialize is_external and is_process values + // (2.1) We initialize is_external and is_process values for(typename CDT::All_faces_iterator fit = cdt.all_faces_begin(), fitend = cdt.all_faces_end(); fit!=fitend; ++fit) { @@ -762,10 +762,10 @@ protected: } } } - + if ( face_internal!=nullptr ) { face_queue.push(face_internal); } - + while(!face_queue.empty()) { typename CDT::Face_handle fh = face_queue.front(); @@ -784,8 +784,8 @@ protected: } } } - - // (3) Now we iterates on the internal faces to add the vertices + + // (3) Now we iterates on the internal faces to add the vertices // and the normals to the appropriate vectors for(typename CDT::Finite_faces_iterator ffit=cdt.finite_faces_begin(), ffitend = cdt.finite_faces_end(); ffit!=ffitend; ++ffit) @@ -793,7 +793,7 @@ protected: if(!ffit->info().is_external) { for(unsigned int i=0; i<3; ++i) - { + { // Add indices when they exist if (m_indices_of_points_of_face.size()>0) { add_indexed_point(ffit->vertex(i)->info().index); } @@ -832,7 +832,7 @@ protected: if (m_color_buffer!=nullptr) { add_color_in_buffer(acolor, *m_color_buffer); } } - + template void add_flat_normal(const KVector& kv) { @@ -899,7 +899,7 @@ protected: bool m_zero_z; /// True iff all points have z==0 bool m_inverse_normal;; - + // Local variables, used when we started a new face.g bool m_face_started; bool m_started_face_is_colored; diff --git a/GraphicsView/include/CGAL/Qt/qglviewer_impl.h b/GraphicsView/include/CGAL/Qt/qglviewer_impl.h index 0dc7256cb38..b097030d1ea 100644 --- a/GraphicsView/include/CGAL/Qt/qglviewer_impl.h +++ b/GraphicsView/include/CGAL/Qt/qglviewer_impl.h @@ -202,7 +202,7 @@ This method is automatically called once, before the first call to paintGL(). Overload init() instead of this method to modify viewer specific OpenGL state. -If a 4.3 context could not be set, a ES 2.0 context will be used instead. +If a 4.3 context could not be set, a ES 2.0 context will be used instead. \see `isOpenGL_4_3()` */ CGAL_INLINE_FUNCTION @@ -214,7 +214,7 @@ void CGAL::QGLViewer::initializeGL() { if ( !context()->isValid() || format.majorVersion() != 4 || QCoreApplication::arguments().contains(QStringLiteral("--old"))) - + { format.setDepthBufferSize(24); format.setStencilBufferSize(8); @@ -223,7 +223,7 @@ void CGAL::QGLViewer::initializeGL() { format.setSamples(0); format.setOption(QSurfaceFormat::DebugContext); QSurfaceFormat::setDefaultFormat(format); - + needNewContext(); qDebug()<<"GL 4.3 context initialization failed. "; is_ogl_4_3 = false; @@ -232,7 +232,7 @@ void CGAL::QGLViewer::initializeGL() { { is_ogl_4_3 = true; } - + QSurfaceFormat cur_f = QOpenGLContext::currentContext()->format(); const char* rt =(cur_f.renderableType() == QSurfaceFormat::OpenGLES) ? "GLES" : "GL"; qDebug()<<"Using context " @@ -258,7 +258,7 @@ void CGAL::QGLViewer::initializeGL() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Calls user defined method. Default emits a signal. init(); - + //OpenGL buffers and programs initialization for(int i=0; i(grid_size)); vaos[GRID].release(); rendering_program.release(); - + rendering_program_light.bind(); vaos[GRID_AXIS].bind(); - + rendering_program_light.setUniformValue("mvp_matrix", mvpMatrix); rendering_program_light.setUniformValue("mv_matrix", mvMatrix); glDrawArrays(GL_TRIANGLES, 0, static_cast(g_axis_size/9)); @@ -3159,12 +3159,12 @@ void CGAL::QGLViewer::drawVisualHints() { vaos[AXIS].bind(); int viewport[4]; int scissor[4]; - + // The viewport and the scissor are changed to fit the upper right // corner. Original values are saved. glGetIntegerv(GL_VIEWPORT, viewport); glGetIntegerv(GL_SCISSOR_BOX, scissor); - + // Axis viewport size, in pixels int size = 100; glViewport(width()*devicePixelRatio()-size, height()*devicePixelRatio()-size, size, size); @@ -3175,8 +3175,8 @@ void CGAL::QGLViewer::drawVisualHints() { glViewport(viewport[0],viewport[1],viewport[2],viewport[3]); vaos[AXIS].release(); rendering_program_light.release(); - - //P i v o t - P o i n t + + //P i v o t - P o i n t if (visualHint_ & 1) { std::vector vertices; @@ -3215,7 +3215,7 @@ void CGAL::QGLViewer::drawVisualHints() { vaos[PIVOT_POINT].release(); rendering_program.release(); } - + } /*! Defines the mask that will be used to drawVisualHints(). The only available @@ -3238,13 +3238,13 @@ void CGAL::QGLViewer::resetVisualHints() { visualHint_ = 0; } // A x i s a n d G r i d d i s p l a y l i s t s // //////////////////////////////////////////////////////////////////////////////// -/*! Draws a 3D arrow between the 3D point \p from and the 3D point \p to. +/*! Draws a 3D arrow between the 3D point \p from and the 3D point \p to. \p data is filled with the three components of a point, then its normal, and then its color, which makes it filled like this: [P1.x-P1.y-P1.z-N1.x-N1.y-N1.z-C1.r-C1.g-C1.b|P2.x-P2.y-P2.z-N2.x-N2.y-N2.z-C2.r-C2.g-C2.b|...] */ CGAL_INLINE_FUNCTION void CGAL::QGLViewer::drawArrow(double r,double R, int prec, CGAL::qglviewer::Vec from, - CGAL::qglviewer::Vec to, CGAL::qglviewer::Vec color, + CGAL::qglviewer::Vec to, CGAL::qglviewer::Vec color, std::vector &data) { using std::cos; using std::sin; @@ -3426,7 +3426,7 @@ void CGAL::QGLViewer::drawArrow(double r,double R, int prec, CGAL::qglviewer::Ve The axis orientation matches the current modelView matrix state: three arrows (red, green and blue) of length \p length are drawn along the -positive X, Y and Z directions in the top right corner of the screen. +positive X, Y and Z directions in the top right corner of the screen. X arrow is red, Y arrow is green and Z arrow is blue.*/ CGAL_INLINE_FUNCTION void CGAL::QGLViewer::drawAxis(qreal length) { @@ -3442,11 +3442,11 @@ void CGAL::QGLViewer::drawAxis(qreal length) { rendering_program_light.enableAttributeArray("vertex"); rendering_program_light.setAttributeBuffer("vertex",GL_FLOAT,0,3, static_cast(9*sizeof(float))); - + rendering_program_light.enableAttributeArray("normal"); rendering_program_light.setAttributeBuffer("normal",GL_FLOAT,3*sizeof(float),3, static_cast(9*sizeof(float))); - + rendering_program_light.enableAttributeArray("colors"); rendering_program_light.setAttributeBuffer("colors",GL_FLOAT,6*sizeof(float),3, static_cast(9*sizeof(float))); @@ -3462,7 +3462,7 @@ coordinate system). \p size (OpenGL units) and \p nbSubdivisions define its geometry.*/ CGAL_INLINE_FUNCTION void CGAL::QGLViewer::drawGrid(qreal size, int nbSubdivisions) { - + //The Grid std::vector v_Grid; for (int i=0; i<=nbSubdivisions; ++i) @@ -3494,7 +3494,7 @@ void CGAL::QGLViewer::drawGrid(qreal size, int nbSubdivisions) { vaos[GRID].release(); rendering_program.release(); grid_size = v_Grid.size(); - + //The Axis std::vector d_axis; d_axis.resize(0); @@ -3510,11 +3510,11 @@ void CGAL::QGLViewer::drawGrid(qreal size, int nbSubdivisions) { rendering_program_light.enableAttributeArray("vertex"); rendering_program_light.setAttributeBuffer("vertex",GL_FLOAT,0,3, static_cast(9*sizeof(float))); - + rendering_program_light.enableAttributeArray("normal"); rendering_program_light.setAttributeBuffer("normal",GL_FLOAT,3*sizeof(float),3, static_cast(9*sizeof(float))); - + rendering_program_light.enableAttributeArray("colors"); rendering_program_light.setAttributeBuffer("colors",GL_FLOAT,6*sizeof(float),3, static_cast(9*sizeof(float))); @@ -3823,7 +3823,7 @@ void CGAL::QGLViewer::initFromDOMElement(const QDomElement &element) { // #CONNECTION# default values from defaultConstructor() // setMouseTracking(DomUtils::boolFromDom(child, "mouseTracking", false)); // if ((child.attribute("cameraMode", "revolve") == "fly") && - // (cameraIsInRevolveMode())) toggleCameraMode(); + // (cameraIsInRevolveMode())) toggleCameraMode(); QDomElement ch = child.firstChild().toElement(); while (!ch.isNull()) { @@ -3909,14 +3909,14 @@ GLuint CGAL::QGLViewer::bufferTextureId() const { CGAL_INLINE_FUNCTION void CGAL::QGLViewer::setOffset(CGAL::qglviewer::Vec offset) -{ - this->_offset = offset; +{ + this->_offset = offset; } CGAL_INLINE_FUNCTION -CGAL::qglviewer::Vec CGAL::QGLViewer::offset()const -{ - return _offset; +CGAL::qglviewer::Vec CGAL::QGLViewer::offset()const +{ + return _offset; } CGAL_INLINE_FUNCTION @@ -4039,7 +4039,7 @@ QImage* CGAL::QGLViewer::takeSnapshot( CGAL::qglviewer::SnapShotBackground back nbX++; if (nbY * subSize.height() < finalSize.height()) nbY++; - GLdouble frustum[6]; + GLdouble frustum[6]; camera()->getFrustum(frustum); QOpenGLFramebufferObject fbo(size,QOpenGLFramebufferObject::CombinedDepthStencil, GL_TEXTURE_2D, GL_RGBA32F); stored_fbo = &fbo; diff --git a/Mesh_3/include/CGAL/Mesh_3/Refine_cells_3.h b/Mesh_3/include/CGAL/Mesh_3/Refine_cells_3.h index 0b7ca09469a..b7d7e050735 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Refine_cells_3.h +++ b/Mesh_3/include/CGAL/Mesh_3/Refine_cells_3.h @@ -479,7 +479,7 @@ public: return sstr.str(); } - + /// Adds \c cell to the refinement queue if needed void treat_new_cell(const Cell_handle& cell); @@ -521,7 +521,7 @@ private: } }; #endif // CGAL_LINKED_WITH_TBB - + // ----------------------------------- // ----------------------------------- // ----------------------------------- @@ -669,7 +669,7 @@ scan_triangulation_impl() std::cerr << "Scanning triangulation for bad cells (in parallel)"; # endif add_to_TLS_lists(true); - + typedef typename Tr::All_cells_iterator All_cells_iterator; // WITH PARALLEL_FOR @@ -795,7 +795,7 @@ conflicts_zone_impl(const Weighted_point& point facet_is_in_its_cz = true; // Always true - CGAL_HISTOGRAM_PROFILER("Mesh_3::Refine_cells::conflict zone", + CGAL_HISTOGRAM_PROFILER("Mesh_3::Refine_cells::conflict zone", static_cast(zone.cells.size())); return zone; } diff --git a/Mesh_3/include/CGAL/Mesh_3/experimental/Facet_topological_criterion_with_adjacency.h b/Mesh_3/include/CGAL/Mesh_3/experimental/Facet_topological_criterion_with_adjacency.h index d80d3986685..2e3f3e313bb 100644 --- a/Mesh_3/include/CGAL/Mesh_3/experimental/Facet_topological_criterion_with_adjacency.h +++ b/Mesh_3/include/CGAL/Mesh_3/experimental/Facet_topological_criterion_with_adjacency.h @@ -28,17 +28,17 @@ public Mesh_3::Abstract_criterion { private: typedef typename Tr::Facet Facet; - + typedef Mesh_3::Abstract_criterion Base; typedef typename Base::Quality Quality; typedef typename Base::Is_bad Is_bad; - + typedef Facet_topological_criterion_with_adjacency Self; typedef typename Tr::Geom_traits::FT FT; const MeshDomain* domain; - + public: /// Constructor Facet_topological_criterion_with_adjacency(const MeshDomain* domain) @@ -47,24 +47,24 @@ public: /// Destructor virtual ~Facet_topological_criterion_with_adjacency() {} - + protected: virtual void do_accept(Visitor_& v) const { v.visit(*this); } - + virtual Self* do_clone() const { // Call copy ctor on this return new Self(*this); } - + virtual Is_bad do_is_bad (const Tr& /*tr*/, const Facet& f) const { typedef typename Tr::Vertex_handle Vertex_handle; typedef typename Tr::Cell_handle Cell_handle; - + const Cell_handle& ch = f.first; const int& i = f.second; @@ -99,7 +99,7 @@ protected: } } break; - case 1: + case 1: { ++nb_vertices_on_curves; const typename MeshDomain::Curve_index curve_id = diff --git a/Mesh_3/include/CGAL/Mesh_3/mesh_standard_facet_criteria.h b/Mesh_3/include/CGAL/Mesh_3/mesh_standard_facet_criteria.h index cdfb7458400..71498b35bfc 100644 --- a/Mesh_3/include/CGAL/Mesh_3/mesh_standard_facet_criteria.h +++ b/Mesh_3/include/CGAL/Mesh_3/mesh_standard_facet_criteria.h @@ -307,7 +307,7 @@ class Facet_size_criterion : public Mesh_3::Abstract_criterion { }; - + // Variable size Criterion class template class Variable_size_criterion : @@ -317,25 +317,25 @@ private: typedef typename Tr::Facet Facet; typedef typename Tr::Geom_traits::FT FT; typedef typename Tr::Vertex::Index Index; - + typedef Mesh_3::Abstract_criterion Base; typedef typename Base::Quality Quality; typedef typename Base::Is_bad Is_bad; - + typedef Variable_size_criterion Self; typedef SizingField Sizing_field; - + public: // Nb: the default bound of the criterion is such that the criterion // is always fulfilled Variable_size_criterion(const Sizing_field& s) : size_(s) {} - + protected: virtual void do_accept(Visitor_& v) const { v.visit(*this); } - + virtual Self* do_clone() const { // Call copy ctor on this @@ -345,7 +345,7 @@ protected: virtual Is_bad do_is_bad(const Tr& tr, const Facet& f) const { CGAL_assertion (f.first->is_facet_on_surface(f.second)); - + typedef typename Tr::Geom_traits Gt; typedef typename Tr::Bare_point Bare_point; typedef typename Tr::Weighted_point Weighted_point; @@ -360,7 +360,7 @@ protected: const FT sq_radius = tr.min_squared_distance(p1, ball_center); const FT sq_bound = CGAL::square(size_(ball_center, 2, index)); CGAL_assertion(sq_bound > FT(0)); - + if ( sq_radius > sq_bound ) { #ifdef CGAL_MESH_3_DEBUG_FACET_CRITERIA @@ -372,14 +372,14 @@ protected: else return Is_bad(); } - + private: Sizing_field size_; - + }; // end Variable_size_criterion - - - + + + // Uniform size Criterion class template class Uniform_size_criterion : @@ -394,7 +394,7 @@ private: typedef typename Base::Is_bad Is_bad; typedef Uniform_size_criterion Self; - + public: // Nb: the default bound of the criterion is such that the criterion // is always fulfilled @@ -505,20 +505,20 @@ protected: } }; // end class Facet_on_surface_criterion - + template class Facet_on_same_surface_criterion : public Mesh_3::Abstract_criterion { private: typedef typename Tr::Facet Facet; - + typedef Mesh_3::Abstract_criterion Base; typedef typename Base::Quality Quality; typedef typename Base::Is_bad Is_bad; - + typedef Facet_on_same_surface_criterion Self; - + public: /// Constructor Facet_on_same_surface_criterion() {} @@ -530,7 +530,7 @@ protected: { v.visit(*this); } - + virtual Self* do_clone() const { // Call copy ctor on this @@ -542,23 +542,23 @@ protected: typedef typename Tr::Vertex_handle Vertex_handle; typedef typename Tr::Cell_handle Cell_handle; typedef typename Tr::Vertex::Index Index; - + const Cell_handle& ch = f.first; const int& i = f.second; - + const Vertex_handle& v1 = ch->vertex((i+1)&3); const Vertex_handle& v2 = ch->vertex((i+2)&3); const Vertex_handle& v3 = ch->vertex((i+3)&3); - + Index index = Index(); bool is_index_initialized = false; - + if ( v1->in_dimension() == 2 ) - { + { index = v1->index(); is_index_initialized = true; } - + if ( v2->in_dimension() == 2 ) { if ( is_index_initialized ) @@ -575,10 +575,10 @@ protected: else { index = v2->index(); - is_index_initialized = true; + is_index_initialized = true; } } - + if ( v3->in_dimension() == 2 ) { if ( is_index_initialized && !(v3->index() == index) ) @@ -588,12 +588,12 @@ protected: << v3->index() << " != " << index << ")" << std::endl; #endif return Is_bad(Quality(1)); - } + } } - + return Is_bad(); } - + }; // end class Facet_on_same_surface_criterion @@ -625,16 +625,16 @@ public: } }; // end class Facet_criterion_visitor - - - + + + template class Facet_criterion_visitor_with_features : public Mesh_3::Criterion_visitor { typedef Mesh_3::Criterion_visitor Base; typedef Facet_criterion_visitor_with_features Self; - + typedef Mesh_3::Abstract_criterion Criterion; typedef Mesh_3::Curvature_size_criterion Curvature_size_criterion; typedef Mesh_3::Aspect_ratio_criterion Aspect_ratio_criterion; @@ -645,12 +645,12 @@ class Facet_criterion_visitor_with_features typedef typename Tr::Geom_traits Gt; typedef typename Gt::FT FT; -public: +public: typedef typename Base::Quality Facet_quality; typedef typename Base::Is_bad Is_facet_bad; typedef typename Base::Handle Handle; typedef Handle Facet; - + // Constructor Facet_criterion_visitor_with_features(const Tr& tr, const Facet& fh) : Base(tr, fh) @@ -674,11 +674,11 @@ public: const Cell_handle& c = fh.first; const int& k = fh.second; - + int k1 = (k+1)&3; int k2 = (k+2)&3; int k3 = (k+3)&3; - + // Get number of weighted points, and ensure that they will be accessible // using k1...ki, if i is the number of weighted points. const Weighted_point& wpk1 = tr.point(c, k1); @@ -715,13 +715,13 @@ public: ratio_ = r / cw(p1); break; } - + case 2: { FT r13 = sq_radius(p1,p3) / cw(p1); FT r23 = sq_radius(p2,p3) / cw(p2); ratio_ = (std::max)(r13, r23); - + do_spheres_intersect_ = (compare(p1,p2,FT(0)) != CGAL::LARGER); break; } @@ -730,12 +730,12 @@ public: { do_spheres_intersect_ = (compare(p1,p2,p3,FT(0)) != CGAL::LARGER); break; - } - + } + default: break; } } - + // Destructor ~Facet_criterion_visitor_with_features() {} @@ -743,14 +743,14 @@ public: void visit(const Criterion& criterion) { if ( 3 == wp_nb_ && do_spheres_intersect_ ) - { + { Base::increment_counter(); return; } - + Base::do_visit(criterion); } - + void visit(const Curvature_size_criterion& criterion) { if ( ratio_ < approx_ratio_ @@ -759,10 +759,10 @@ public: Base::increment_counter(); return; } - + Base::do_visit(criterion); } - + void visit(const Aspect_ratio_criterion& criterion) { if ( ratio_ < angle_ratio_ @@ -771,10 +771,10 @@ public: Base::increment_counter(); return; } - + Base::do_visit(criterion); } - + void visit(const Facet_size_criterion& criterion) { if ( ratio_ < size_ratio_ @@ -783,10 +783,10 @@ public: Base::increment_counter(); return; } - + Base::do_visit(criterion); } - + private: int wp_nb_; bool do_spheres_intersect_; @@ -794,9 +794,9 @@ private: FT approx_ratio_; FT angle_ratio_; FT size_ratio_; - + }; // end class Facet_criterion_visitor - + } // end namespace Mesh_3 diff --git a/Mesh_3/include/CGAL/Mesh_domain_with_polyline_features_3.h b/Mesh_3/include/CGAL/Mesh_domain_with_polyline_features_3.h index 731e441c70a..9a35bf41a70 100644 --- a/Mesh_3/include/CGAL/Mesh_domain_with_polyline_features_3.h +++ b/Mesh_3/include/CGAL/Mesh_domain_with_polyline_features_3.h @@ -635,7 +635,7 @@ public: PolylinePMap polyline_pmap, IncidentPatchesIndicesPMap incident_paches_indices_pmap, IndicesOutputIterator out /* = CGAL::Emptyset_iterator() */); - + template IndicesOutputIterator add_features_with_context(InputIterator first, InputIterator end, @@ -644,7 +644,7 @@ public: /// @} /// \endcond /*! - Add 1-dimensional features in the domain. `InputIterator` value type must + Add 1-dimensional features in the domain. `InputIterator` value type must be a model of the concept `MeshPolyline_3`. */ template @@ -664,9 +664,9 @@ public: /*! Add 1-dimensional features (curves) from the range `[first, end)` in the domain with their incidences with 2-dimensional features (patches) of the domain. - + \tparam InputIterator input iterator over curves - \tparam PolylinePMap is a model of `ReadablePropertyMap` with key type + \tparam PolylinePMap is a model of `ReadablePropertyMap` with key type `std::iterator_traits::%reference` and a value type that is a model of `MeshPolyline_3`. \tparam IncidentPatchesIndicesPMap is a model of `ReadablePropertyMap` @@ -681,7 +681,7 @@ public: \param incident_patches_indices_pmap the property map that provides access to the set of indices of the surface patches that are incident to a given 1D-feature (curve) - */ + */ template @@ -696,7 +696,7 @@ public: CGAL::Emptyset_iterator()); } /// @} - + /// \name Implementation of the concept MeshDomainWithFeatures_3 /// The following methods implement the requirement of the concept /// `MeshDomainWithFeatures_3`. diff --git a/Mesher_level/include/CGAL/Double_map.h b/Mesher_level/include/CGAL/Double_map.h index d7a7182dbe5..927324a69a1 100644 --- a/Mesher_level/include/CGAL/Double_map.h +++ b/Mesher_level/include/CGAL/Double_map.h @@ -6,7 +6,7 @@ // $URL$ // $Id$ // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial -// +// // // Author(s) : Laurent RINEAU @@ -44,7 +44,7 @@ namespace CGAL { -template , +template , class _Reverse_compare = std::less<_Data> > class Double_map { @@ -55,10 +55,10 @@ public: typedef _Reverse_compare Reverse_compare; typedef Double_map Self; - + #ifdef CGAL_USE_BOOST_BIMAP typedef ::boost::bimap< ::boost::bimaps::set_of, - ::boost::bimaps::multiset_of > Boost_bimap; + ::boost::bimaps::multiset_of > Boost_bimap; typedef typename Boost_bimap::left_map Direct_func; typedef typename Boost_bimap::right_map Reverse_func; @@ -78,7 +78,7 @@ public: typedef typename Self::Reverse_func::value_type right_value_type; #endif typedef typename Direct_func::value_type Direct_entry; - // std::pair + // std::pair typedef typename Reverse_func::value_type Reverse_entry; // std::pair ; @@ -136,7 +136,7 @@ public : { return(direct_func().size()==reverse_func().size()); } - + void clear() { #ifdef CGAL_USE_BOOST_BIMAP @@ -145,7 +145,7 @@ public : direct_func().clear(); reverse_func().clear(); #endif - + } Self& operator=(const Self& dm) @@ -161,14 +161,14 @@ public : #ifdef CGAL_USE_BOOST_BIMAP for(direct_const_iterator rit = dm.direct_func().begin(); - rit != dm.direct_func().end(); + rit != dm.direct_func().end(); ++rit) { direct_func().insert(*rit); } #else reverse_func() = dm.reverse_func(); - + for(reverse_iterator rit = reverse_func().begin(); rit != reverse_func().end(); ++rit) @@ -190,7 +190,7 @@ public : direct_iterator hint = boost_bimap.left.lower_bound(k); if(hint != boost_bimap.left.end() && hint->first == k) - return false; + return false; boost_bimap.left.insert(hint, Direct_entry(k, d)); return true; @@ -198,11 +198,11 @@ public : direct_iterator direct_hint = direct_func().lower_bound(k); if(direct_hint != direct_func().end() && - direct_hint->first == k) + direct_hint->first == k) return false; - + reverse_iterator reverse_it = reverse_func().insert(Reverse_entry(d, k)); - + direct_func().insert(direct_hint, Direct_entry(k, reverse_it)); CGAL_assertion(is_valid()); @@ -229,7 +229,7 @@ public : direct_iterator pos = direct_func().find(rit->second); CGAL_assertion(pos != direct_func().end()); CGAL_assertion(pos->second == rit); - + direct_func().erase(pos); reverse_func().erase(rit); CGAL_assertion(is_valid()); @@ -240,7 +240,7 @@ public : { return direct_func().begin(); } - + const_iterator end() const { return direct_func().end(); @@ -248,20 +248,20 @@ public : template void dump_direct_func(std::ostream& out, - Func_key func_key, - Func_data func_data) + Func_key func_key, + Func_data func_data) { for(typename Direct_func::iterator it = direct_func().begin(); - it != direct_func().end(); - ++it) + it != direct_func().end(); + ++it) { out << func_key(it->first) << " -> " #ifdef CGAL_USE_BOOST_BIMAP - << func_data(it->second) + << func_data(it->second) #else - << func_data(it->second->first) + << func_data(it->second->first) #endif - << std::endl; + << std::endl; } } @@ -272,25 +272,25 @@ public : template void dump_reverse_func(std::ostream& out, - Func_key func_key, - Func_data func_data) + Func_key func_key, + Func_data func_data) { for(typename Reverse_func::iterator it = reverse_func().begin(); - it != reverse_func().end(); - ++it) + it != reverse_func().end(); + ++it) { out << func_data(it->first) << " " - << func_key(it->second) << std::endl; + << func_key(it->second) << std::endl; } } - void dump_reverse_func(std::ostream& out) + void dump_reverse_func(std::ostream& out) { dump_reverse_func(out, CGAL::Identity(), CGAL::Identity()); } }; -template bool Double_map<_Key, _Data, _Direct_compare, _Reverse_compare>:: diff --git a/Polyhedron/demo/Polyhedron/C3t3_type.h b/Polyhedron/demo/Polyhedron/C3t3_type.h index c7d63fd9ef5..d37bf5306f7 100644 --- a/Polyhedron/demo/Polyhedron/C3t3_type.h +++ b/Polyhedron/demo/Polyhedron/C3t3_type.h @@ -36,13 +36,13 @@ struct Wrapper { typedef int return_type; typedef typename K::Point_3 Point_3; - + Wrapper(const Implicit_function_interface& f) : f_(f) {} return_type operator()(const Point_3& p, const bool=true) const { return (f_(p.x(),p.y(),p.z()) < 0) ? 1 : 0; } - + private: const Implicit_function_interface& f_; }; @@ -72,7 +72,7 @@ typedef CGAL::Compact_mesh_cell_base_3 Cell typedef CGAL::Triangulation_cell_base_with_info_3 Cell_base_with_info; #ifdef CGAL_CONCURRENT_MESH_3 - typedef CGAL::Mesh_triangulation_3 actions() const { @@ -51,12 +51,12 @@ public: bool applicable(QAction*)const{ Scene_c3t3_item* item = qobject_cast(scene->item(scene->mainSelectionIndex())); return item && item->is_valid();} - + public Q_SLOTS: void create_rib(); void height_changed(int i); void width_changed(int i); - + private: typedef Tr::Bare_point Bare_point; typedef Tr::Weighted_point Weighted_point; @@ -65,12 +65,12 @@ private: typedef Geom_traits::Plane_3 Plane; typedef Geom_traits::FT FT; typedef Geom_traits::Aff_transformation_3 Aff_transformation_3; - + typedef CGAL::qglviewer::Vec qglVec; - + enum Rib_exporter_mode { CUT=0, MESH, TRIANGULATION }; - - struct Rib_exporter_parameters + + struct Rib_exporter_parameters { // Materials double sphere_radius; @@ -81,88 +81,88 @@ private: double ambientIntensity; bool shadowOn; double shadowIntensity; - + // Picture int width; int height; Rib_exporter_mode mode; bool is_preview; }; - + private: void update_mask(); - + bool get_parameters_from_dialog(); - + QStringList nameFilters() const; - bool save(const Scene_c3t3_item&, const QFileInfo& fileinfo); + bool save(const Scene_c3t3_item&, const QFileInfo& fileinfo); void init_maps(const C3t3& c3t3, const QColor& color); void init_point_radius(const C3t3& c3t3); void init_parameters(); - + Bare_point camera_coordinates(const Bare_point& p); void fill_points_and_edges_map(const C3t3& c3t3); - + void add_edge(const Bare_point& p, const Bare_point& q, const QColor& color); void add_vertex(const Bare_point& p, const QColor& color); - + void write_header(const std::string& filename, std::ofstream& out); - + void write_lights(std::ofstream& out); void write_turn_background_light(bool turn_on, std::ofstream& out); - + void write_facets(const C3t3& c3t3, std::ofstream& out); void write_facets(const C3t3& c3t3, const Plane& plane, std::ofstream& out); void write_surface_cells(const C3t3& c3t3, const Plane& plane, std::ofstream& out); void write_cells_intersecting_a_plane(const C3t3& c3t3, const Plane& plane, std::ofstream& out); void write_cells_on_the_positive_side_of_a_plane(const C3t3& c3t3, const Plane& plane, std::ofstream& out); - + void write_triangle(const Bare_point& p, const Bare_point& q, const Bare_point& r, const QColor& color, const QColor& edge_color, std::ofstream& out); void write_tetrahedron (const Bare_point& p, const Bare_point& q, const Bare_point& r, const Bare_point& s, const QColor& color, const QColor& edge_color, std::ofstream& out); - + void write_point(const Bare_point& p, std::ofstream& out); void write_point_sphere(const Bare_point& p, std::ofstream& out); - + void write_edge_cylinder(const Bare_point& p, const Bare_point& q, std::ofstream& out); - + // Writes data which has been stored during triangle drawing void write_edges_flat(std::ofstream& out); void write_edges_volumic(std::ofstream& out); void write_vertices_volumic(std::ofstream& out); - + void write_color(const QColor& color, bool use_transparency, std::ofstream& out); void write_opacity(const double alpha, std::ofstream& out); - + // Background void write_background(const QColor& color, std::ofstream& out); - + private: QAction* actionCreateRib; - + // Viewer - + typedef std::map Surface_map; typedef std::map Subdomain_map; - + Surface_map surface_map_; Subdomain_map subdomain_map_; - + typedef std::map,QColor> Edge_map; typedef std::map Vertex_map; - + Edge_map edges_; Vertex_map vertices_; - + double zmax_; double diag_; - + // Cache data to avoid writing too much lines in rib file QColor prev_color_; double prev_alpha_; const Scene_c3t3_item* prev_c3t3_; - + Rib_exporter_parameters parameters_; }; @@ -176,7 +176,7 @@ C3t3_rib_exporter_plugin() , prev_alpha_(1) , prev_c3t3_(NULL) { - + } @@ -186,7 +186,7 @@ init(QMainWindow* mainWindow, Scene_interface* scene_interface, Messages_interfa { this->scene = scene_interface; this->mw = mainWindow; - + actionCreateRib = new QAction("Export C3t3 to RIB", mw); if( NULL != actionCreateRib ) { @@ -205,18 +205,18 @@ C3t3_rib_exporter_plugin::create_rib() std::cerr << "Can't find viewer" << std::endl; return; } - + // Get Scene_c3t3_item Scene_interface::Item_id index = scene->mainSelectionIndex(); - + Scene_c3t3_item* c3t3_item = qobject_cast(scene->item(index)); - + if ( NULL == c3t3_item ) { return; } - + // Init data //if ( c3t3_item != prev_c3t3_ ) // Commented because it was causing problems // when changing the color of the c3t3 @@ -224,40 +224,40 @@ C3t3_rib_exporter_plugin::create_rib() init_maps(c3t3_item->c3t3(), c3t3_item->color()); init_point_radius(c3t3_item->c3t3()); init_parameters(); - + prev_c3t3_ = c3t3_item; } - + // Get parameters from user dialog if ( !get_parameters_from_dialog() ) - { + { QBitmap bitmap; bitmap.clear(); Three::activeViewer()->setMask(bitmap); return; } - + // Disable Mask QBitmap bitmap; bitmap.clear(); Three::activeViewer()->setMask(bitmap); - + // Save dialog QStringList filters; filters << nameFilters(); filters << tr("All files (*)"); - + QString filename = QFileDialog::getSaveFileName(mw, tr("Save to File..."), QString(), filters.join(";;")); - + QFileInfo fileinfo(filename); - + // Save rib file save(*c3t3_item,fileinfo); - + std::cout << "Rib file created successfully" << std::endl; } @@ -284,7 +284,7 @@ C3t3_rib_exporter_plugin:: update_mask() { double ratio = double(parameters_.width) / double(parameters_.height); - + if ( NULL == Three::activeViewer() ) { std::cerr << "Can't find viewer..." << std::endl; @@ -312,11 +312,11 @@ get_parameters_from_dialog() connect(ui.buttonBox, SIGNAL(rejected()), &dialog, SLOT(reject())); connect(ui.resWidth, SIGNAL(valueChanged(int)), this, SLOT(width_changed(int))); connect(ui.resHeight, SIGNAL(valueChanged(int)), this, SLOT(height_changed(int))); - + // ----------------------------------- // Set data // ----------------------------------- - + // Materials ui.sphereRadius->setValue(parameters_.sphere_radius); ui.cylinderRadius->setValue(parameters_.cylinder_radius); @@ -326,54 +326,54 @@ get_parameters_from_dialog() ui.ambientIntensity->setValue(parameters_.ambientIntensity); ui.isShadowOn->setChecked(parameters_.shadowOn); ui.shadowIntensity->setValue(parameters_.shadowIntensity); - + // Picture QStringList mode_list; mode_list << "Export Cut (draws current cut view)" << "Export Mesh (draws all surface facets)" << "Export Triangulation (draws all points and edges)"; - + ui.exportMode->insertItems(0,mode_list); - + ui.resWidth->setValue(parameters_.width); ui.resHeight->setValue(parameters_.height); ui.exportMode->setCurrentIndex(static_cast(parameters_.mode)); ui.isPreview->setChecked(parameters_.is_preview); - + // Update mask update_mask(); - + // ----------------------------------- // Get data // ----------------------------------- int i = dialog.exec(); if(i == QDialog::Rejected) return false; - + // Materials parameters_.sphere_radius = ui.sphereRadius->value(); parameters_.cylinder_radius = ui.cylinderRadius->value(); - + // Lights parameters_.ambientOn = ui.isAmbientOn->isChecked(); parameters_.ambientIntensity = ui.ambientIntensity->value(); parameters_.shadowOn = ui.isShadowOn->isChecked(); parameters_.shadowIntensity = ui.shadowIntensity->value(); - + // Picture parameters_.width = ui.resWidth->value(); parameters_.height = ui.resHeight->value(); parameters_.mode = static_cast(ui.exportMode->currentIndex()); parameters_.is_preview = ui.isPreview->isChecked(); - + return true; } - + QStringList C3t3_rib_exporter_plugin::nameFilters() const -{ +{ return QStringList() << "RenderMan file (*.rib)"; } @@ -385,52 +385,52 @@ save(const Scene_c3t3_item& c3t3_item, const QFileInfo& fileInfo) QString path = fileInfo.absoluteFilePath(); std::ofstream rib_file (qPrintable(path)); rib_file.precision(8); - + // Header QString basename = fileInfo.baseName(); write_header(qPrintable(basename), rib_file); - + // Lights write_lights(rib_file); - + // Triangles switch ( parameters_.mode ) { case CUT: rib_file << "Surface \"plastic\" \"Ka\" 0.65 \"Kd\" 0.85 \"Ks\" 0.25 \"roughness\" 0.1" << std::endl; write_facets(c3t3_item.c3t3(), c3t3_item.plane(), rib_file); - + rib_file << "Surface \"plastic\" \"Ka\" 0.65 \"Kd\" 0.65 \"Ks\" 0.35 \"roughness\" 0.2" << std::endl; //write_cells_intersecting_a_plane(c3t3_item.c3t3(), c3t3_item.plane(), rib_file); write_cells_on_the_positive_side_of_a_plane(c3t3_item.c3t3(), c3t3_item.plane(), rib_file); break; - + case MESH: rib_file << "Surface \"plastic\" \"Ka\" 0.65 \"Kd\" 0.85 \"Ks\" 0.25 \"roughness\" 0.1" << std::endl; //write_facets(c3t3_item.c3t3(), rib_file); write_surface_cells(c3t3_item.c3t3(), c3t3_item.plane(), rib_file); break; - + case TRIANGULATION: fill_points_and_edges_map(c3t3_item.c3t3()); break; - + default: std::cerr << "Unexpected mode found" << std::endl; return false; break; } - + // Edges and vertices rib_file << "Surface \"plastic\" \"Ka\" 0.65 \"Kd\" 0.85 \"Ks\" 0.25 \"roughness\" 0.1" << std::endl; write_edges_volumic(rib_file); write_vertices_volumic(rib_file); - + // Background write_background(QColor(255,255,255), rib_file); - + rib_file << "WorldEnd" << std::endl; - + return true; } @@ -441,23 +441,23 @@ C3t3_rib_exporter_plugin::init_maps(const C3t3& c3t3, const QColor& color) subdomain_map_.clear(); edges_.clear(); vertices_.clear(); - + // Fill maps with 0 as value for ( C3t3::Facets_in_complex_iterator fit = c3t3.facets_in_complex_begin(), fend = c3t3.facets_in_complex_end() ; fit != fend ; ++fit ) { surface_map_.insert(std::make_pair(c3t3.surface_patch_index(*fit),QColor(0,0,0))); } - + for ( C3t3::Cells_in_complex_iterator cit = c3t3.cells_in_complex_begin(), cend = c3t3.cells_in_complex_end() ; cit != cend ; ++cit ) { subdomain_map_.insert(std::make_pair(c3t3.subdomain_index(cit),QColor(0,0,0))); } - + // Fill value of maps size_t nb_colors = subdomain_map_.size(); // + surface_map_.size(); - + // Starting hue double c = color.hueF(); int i = 0; @@ -476,13 +476,13 @@ C3t3_rib_exporter_plugin:: init_point_radius(const C3t3& c3t3) { const CGAL::Bbox_3 bbox = c3t3.bbox(); - + const double xdelta = bbox.xmax() - bbox.xmin(); const double ydelta = bbox.ymax() - bbox.ymin(); const double zdelta = bbox.zmax() - bbox.zmin(); - + diag_ = std::sqrt(xdelta*xdelta + ydelta*ydelta + zdelta*zdelta); - + parameters_.sphere_radius = diag_ * 0.0015; parameters_.cylinder_radius = diag_ * 0.00065; } @@ -497,7 +497,7 @@ init_parameters() parameters_.ambientIntensity = 0.20; parameters_.shadowOn = true; parameters_.shadowIntensity = 0.85; - + // Picture parameters_.width = 800; parameters_.height = 800; @@ -512,10 +512,10 @@ camera_coordinates(const Bare_point& p) { qglVec p_vec ( p.x(), p.y(), p.z() ); qglVec p_cam = Three::activeViewer()->camera()->cameraCoordinatesOf(p_vec); - + // Store maximal depth zmax_ = (std::max)(zmax_, double(-p_cam[2])); - + return Bare_point(p_cam[0],p_cam[1],p_cam[2]); } @@ -534,16 +534,16 @@ fill_points_and_edges_map(const C3t3& c3t3) const Bare_point& p2 = wp2p(it->vertex(1)->point()); const Bare_point& p3 = wp2p(it->vertex(2)->point()); const Bare_point& p4 = wp2p(it->vertex(3)->point()); - + const QColor& edge_color = subdomain_map_[c3t3.subdomain_index(it)]; - + add_edge(p1,p2,edge_color); add_edge(p1,p3,edge_color); add_edge(p1,p4,edge_color); add_edge(p2,p3,edge_color); add_edge(p2,p4,edge_color); add_edge(p3,p4,edge_color); - + add_vertex(p1,edge_color); add_vertex(p2,edge_color); add_vertex(p3,edge_color); @@ -558,11 +558,11 @@ add_edge(const Bare_point& p, const Bare_point& q, const QColor& color) { if ( p < q ) { - edges_.insert(std::make_pair(std::make_pair(p,q),color)); + edges_.insert(std::make_pair(std::make_pair(p,q),color)); } else { - edges_.insert(std::make_pair(std::make_pair(q,p),color)); + edges_.insert(std::make_pair(std::make_pair(q,p),color)); } } @@ -571,7 +571,7 @@ void C3t3_rib_exporter_plugin:: add_vertex(const Bare_point& p, const QColor& color) { - vertices_.insert(std::make_pair(p,color)); + vertices_.insert(std::make_pair(p,color)); } @@ -581,15 +581,15 @@ write_header(const std::string& filename, std::ofstream& out) { out << "Option \"limits\" \"numthreads\" [16]" << std::endl << "Option \"searchpath\" \"shader\" \".:./shaders:%PIXIE_SHADERS%:%PIXIEHOME%/shaders\"" << std::endl; - + if ( ! parameters_.is_preview ) { out << "Attribute \"visibility\" \"specular\" 1" << std::endl << "Attribute \"visibility\" \"transmission\" 1" << std::endl << std::endl; } - + out << "Display \""<< filename << ".tif\" \"file\" \"rgb\"" << std::endl; - + if ( ! parameters_.is_preview ) { out << "Format " << parameters_.width << " " << parameters_.height << " 1" << std::endl; @@ -597,25 +597,25 @@ write_header(const std::string& filename, std::ofstream& out) else { double ratio = double(parameters_.height) / double(parameters_.width); - + int width = (ratio < 1.) ? 300 : int(300. / ratio); int height = (ratio < 1.) ? int(ratio * 300.) : 300; - + out << "Format " << width << " " << height << " 1" << std::endl; } - - + + if ( parameters_.width > parameters_.height ) { double ratio = double(parameters_.height) / double(parameters_.width); - out << "ScreenWindow -1 1 " << -ratio << " " << ratio << std::endl; + out << "ScreenWindow -1 1 " << -ratio << " " << ratio << std::endl; } else if ( parameters_.height > parameters_.width ) { double ratio = double(parameters_.width) / double(parameters_.height); - out << "ScreenWindow " << -ratio << " " << ratio << " -1 1" << std::endl; + out << "ScreenWindow " << -ratio << " " << ratio << " -1 1" << std::endl; } - + out << "Projection \"perspective\" \"fov\" 45" << std::endl << "PixelSamples 4 4" << std::endl << "PixelFilter \"catmull-rom\" 3 3" << std::endl @@ -634,7 +634,7 @@ write_lights(std::ofstream& out) // ShadowLight out << "LightSource \"shadowdistant\" 1 \"from\" [0 0 0] \"to\" [0 0 1]" << " \"shadowname\" \"raytrace\" \"intensity\" " << parameters_.shadowIntensity << std::endl; - + // Ambient light out << "LightSource \"ambientlight\" 2 \"intensity\" " << parameters_.ambientIntensity << std::endl; } @@ -643,7 +643,7 @@ write_lights(std::ofstream& out) out << "LightSource \"distantLight\" 1 \"from\" [0 0 0] \"to\" [0 0 1]" << " \"intensity\" 0.85" << std::endl; } - + // Background light out << "LightSource \"ambientlight\" 99 \"intensity\" 1" << std::endl; write_turn_background_light(false,out); @@ -681,14 +681,14 @@ write_facets(const C3t3& c3t3, std::ofstream& out) { const C3t3::Cell_handle& c = it->first; const int& k = it->second; - + const Bare_point& p1 = wp2p(c->vertex((k+1)&3)->point()); const Bare_point& p2 = wp2p(c->vertex((k+2)&3)->point()); const Bare_point& p3 = wp2p(c->vertex((k+3)&3)->point()); - + QColor color = c3t3.is_in_complex(c) ? subdomain_map_[c3t3.subdomain_index(c)] : subdomain_map_[c3t3.subdomain_index(c->neighbor(k))]; - + write_triangle(p1, p2, p3, color, color.darker(125), out ); } } @@ -708,7 +708,7 @@ write_facets(const C3t3& c3t3, const Plane& plane, std::ofstream& out) { const C3t3::Cell_handle& c = it->first; const int& k = it->second; - + const Bare_point& p1 = wp2p(c->vertex((k+1)&3)->point()); const Bare_point& p2 = wp2p(c->vertex((k+2)&3)->point()); const Bare_point& p3 = wp2p(c->vertex((k+3)&3)->point()); @@ -716,13 +716,13 @@ write_facets(const C3t3& c3t3, const Plane& plane, std::ofstream& out) const Side s1 = plane.oriented_side(p1); const Side s2 = plane.oriented_side(p2); const Side s3 = plane.oriented_side(p3); - - if( s1 == CGAL::ON_NEGATIVE_SIDE && s2 == CGAL::ON_NEGATIVE_SIDE + + if( s1 == CGAL::ON_NEGATIVE_SIDE && s2 == CGAL::ON_NEGATIVE_SIDE && s3 == CGAL::ON_NEGATIVE_SIDE ) { QColor color = c3t3.is_in_complex(c) ? subdomain_map_[c3t3.subdomain_index(c)] : subdomain_map_[c3t3.subdomain_index(c->neighbor(k))]; - + write_triangle(p1, p2, p3, color, color.darker(125), out ); } } @@ -752,16 +752,16 @@ write_surface_cells(const C3t3& c3t3, const Plane& /* plane */, std::ofstream& o last_2D_vertex_index = i; } } - + //const int TRANSPARENCY_ALPHA_VALUE = 100; CGAL::Bbox_3 bbox = c3t3.bbox(); - float relPos = static_cast((c->weighted_circumcenter().x() - bbox.xmin()) + float relPos = static_cast((c->weighted_circumcenter().x() - bbox.xmin()) / (bbox.xmax() - bbox.xmin())); - float TRANSPARENCY_ALPHA_VALUE = - 1.f - - (relPos < 0.25f ? - 0.0f : - (relPos > 0.75f ? + float TRANSPARENCY_ALPHA_VALUE = + 1.f - + (relPos < 0.25f ? + 0.0f : + (relPos > 0.75f ? 1.0f : (relPos - 0.25f)*1.0f/0.5f ) @@ -775,7 +775,7 @@ write_surface_cells(const C3t3& c3t3, const Plane& /* plane */, std::ofstream& o QColor basecolor = subdomain_map_[c3t3.subdomain_index(c)]; QColor facecolor = basecolor.darker(150); QColor edgecolor = facecolor.darker(150); - + for (int i = 0 ; i < 4 ; ++i) { if (c3t3.in_dimension(c->vertex((i+1)%4)) == 2 @@ -796,14 +796,14 @@ write_surface_cells(const C3t3& c3t3, const Plane& /* plane */, std::ofstream& o } }*/ - + // SURFACE CELLS ARE TRANSPARENT if (num_2D_vertices >= 2) { QColor basecolor = subdomain_map_[c3t3.subdomain_index(c)]; QColor facecolor = basecolor.darker(150); QColor edgecolor = facecolor.darker(150); - + /* typedef Kernel::Oriented_side Side; @@ -812,7 +812,7 @@ write_surface_cells(const C3t3& c3t3, const Plane& /* plane */, std::ofstream& o const Side s1 = plane.oriented_side(wp2p(c->vertex(1)->point())); const Side s2 = plane.oriented_side(wp2p(c->vertex(2)->point())); const Side s3 = plane.oriented_side(wp2p(c->vertex(3)->point())); - if( s0 == CGAL::ON_NEGATIVE_SIDE && s1 == CGAL::ON_NEGATIVE_SIDE + if( s0 == CGAL::ON_NEGATIVE_SIDE && s1 == CGAL::ON_NEGATIVE_SIDE && s2 == CGAL::ON_NEGATIVE_SIDE && s3 == CGAL::ON_NEGATIVE_SIDE ) { edgecolor.setAlpha(TRANSPARENCY_ALPHA_VALUE); @@ -821,9 +821,9 @@ write_surface_cells(const C3t3& c3t3, const Plane& /* plane */, std::ofstream& o { edgecolor.setAlpha(255); }*/ - + edgecolor.setAlphaF(TRANSPARENCY_ALPHA_VALUE); - + for (int i = 0 ; i < 4 ; ++i) { write_triangle(wp2p(c->vertex((i+1)%4)->point()), @@ -837,7 +837,7 @@ write_surface_cells(const C3t3& c3t3, const Plane& /* plane */, std::ofstream& o QColor basecolor = subdomain_map_[c3t3.subdomain_index(c)]; QColor facecolor = basecolor.darker(150); QColor edgecolor = facecolor.darker(150); - + for (int i = 0 ; i < 4 ; ++i) { if (i == last_2D_vertex_index) @@ -875,12 +875,12 @@ write_cells_intersecting_a_plane(const C3t3& c3t3, const Plane& plane, std::ofst const Bare_point& p2 = wp2p(it->vertex(1)->point()); const Bare_point& p3 = wp2p(it->vertex(2)->point()); const Bare_point& p4 = wp2p(it->vertex(3)->point()); - + const Side s1 = plane.oriented_side(p1); const Side s2 = plane.oriented_side(p2); const Side s3 = plane.oriented_side(p3); const Side s4 = plane.oriented_side(p4); - + if( s1 == CGAL::ON_ORIENTED_BOUNDARY || s2 == CGAL::ON_ORIENTED_BOUNDARY || s3 == CGAL::ON_ORIENTED_BOUNDARY || s4 == CGAL::ON_ORIENTED_BOUNDARY || s2 != s1 || s3 != s1 || s4 != s1 ) @@ -890,17 +890,17 @@ write_cells_intersecting_a_plane(const C3t3& c3t3, const Plane& plane, std::ofst QColor edgecolor = facecolor.darker(150); edgecolor.setAlpha(20); - + // Don't write facet twice if ( s1 != CGAL::ON_NEGATIVE_SIDE || s2 != CGAL::ON_NEGATIVE_SIDE || s3 != CGAL::ON_NEGATIVE_SIDE ) write_triangle(p1, p2, p3, facecolor, edgecolor, out ); - + if ( s1 != CGAL::ON_NEGATIVE_SIDE || s2 != CGAL::ON_NEGATIVE_SIDE || s4 != CGAL::ON_NEGATIVE_SIDE ) write_triangle(p1, p2, p4, facecolor, edgecolor, out ); - + if ( s1 != CGAL::ON_NEGATIVE_SIDE || s3 != CGAL::ON_NEGATIVE_SIDE || s4 != CGAL::ON_NEGATIVE_SIDE ) write_triangle(p1, p3, p4, facecolor, edgecolor, out ); - + if ( s2 != CGAL::ON_NEGATIVE_SIDE || s3 != CGAL::ON_NEGATIVE_SIDE || s4 != CGAL::ON_NEGATIVE_SIDE ) write_triangle(p2, p3, p4, facecolor, edgecolor, out ); } @@ -923,12 +923,12 @@ write_cells_on_the_positive_side_of_a_plane(const C3t3& c3t3, const Plane& plane const Bare_point& p2 = wp2p(it->vertex(1)->point()); const Bare_point& p3 = wp2p(it->vertex(2)->point()); const Bare_point& p4 = wp2p(it->vertex(3)->point()); - + const Side s1 = plane.oriented_side(p1); const Side s2 = plane.oriented_side(p2); const Side s3 = plane.oriented_side(p3); const Side s4 = plane.oriented_side(p4); - + if( ( s1 == CGAL::ON_POSITIVE_SIDE || s2 == CGAL::ON_POSITIVE_SIDE || s3 == CGAL::ON_POSITIVE_SIDE || s4 == CGAL::ON_POSITIVE_SIDE ) /*&& @@ -943,17 +943,17 @@ write_cells_on_the_positive_side_of_a_plane(const C3t3& c3t3, const Plane& plane QColor edgecolor = facecolor.darker(150); edgecolor.setAlpha(10); - + // Don't write facet twice if ( s1 != CGAL::ON_NEGATIVE_SIDE || s2 != CGAL::ON_NEGATIVE_SIDE || s3 != CGAL::ON_NEGATIVE_SIDE ) write_triangle(p1, p2, p3, facecolor, edgecolor, out ); - + if ( s1 != CGAL::ON_NEGATIVE_SIDE || s2 != CGAL::ON_NEGATIVE_SIDE || s4 != CGAL::ON_NEGATIVE_SIDE ) write_triangle(p1, p2, p4, facecolor, edgecolor, out ); - + if ( s1 != CGAL::ON_NEGATIVE_SIDE || s3 != CGAL::ON_NEGATIVE_SIDE || s4 != CGAL::ON_NEGATIVE_SIDE ) write_triangle(p1, p3, p4, facecolor, edgecolor, out ); - + if ( s2 != CGAL::ON_NEGATIVE_SIDE || s3 != CGAL::ON_NEGATIVE_SIDE || s4 != CGAL::ON_NEGATIVE_SIDE ) write_triangle(p2, p3, p4, facecolor, edgecolor, out ); } @@ -968,14 +968,14 @@ write_triangle (const Bare_point& p, const Bare_point& q, const Bare_point& r, { // Color write_color(color, true, out); - + // Triangle out << "Polygon \"P\" ["; write_point(p,out); write_point(q,out); write_point(r,out); out << "]" << std::endl; - + // Edges (will be drawn later on) add_edge(p,q,edge_color); add_edge(p,r,edge_color); @@ -994,7 +994,7 @@ write_tetrahedron (const Bare_point& p, const Bare_point& q, const Bare_point& r { // Color write_color(color, true, out); - + // Triangle out << "Polygon \"P\" ["; write_point(p,out); @@ -1002,7 +1002,7 @@ write_tetrahedron (const Bare_point& p, const Bare_point& q, const Bare_point& r write_point(r,out); write_point(s,out); out << "]" << std::endl; - + // Edges (will be drawn later on) add_edge(p,q,edge_color); add_edge(p,r,edge_color); @@ -1024,7 +1024,7 @@ write_point (const Bare_point& p, std::ofstream& out) { // Transform point in camera coordinates const Bare_point& p_cam = camera_coordinates(p); - + // Write it out << " " << -p_cam.x() << " " << -p_cam.y() << " " << -p_cam.z() << " "; } @@ -1036,12 +1036,12 @@ write_point_sphere(const Bare_point& p, std::ofstream& out) { // Transform point in camera coordinates const Bare_point& p_cam = camera_coordinates(p); - + // radius const double& r = parameters_.sphere_radius; - + out << "Translate " << -p_cam.x() << " " << -p_cam.y() << " " << -p_cam.z() << std::endl; - + // Sphere radius zmin zmax thetamax out << "Sphere " << r << " " << -r << " " << r << " 360" << std::endl; out << "Identity" << std::endl; @@ -1055,50 +1055,50 @@ write_edge_cylinder(const Bare_point& p, const Bare_point& q, std::ofstream& out // Transform point in camera coordinates const Bare_point& p_cam = camera_coordinates(p); const Bare_point& q_cam = camera_coordinates(q); - + double pq = CGAL::to_double(CGAL::sqrt(CGAL::squared_distance(p_cam,q_cam))); - + Aff_transformation_3 t (CGAL::Translation(), Vector_3(p_cam,CGAL::ORIGIN)); const Bare_point& q_cam_t = q_cam.transform(t); - + Vector_3 Oq (CGAL::ORIGIN,q_cam_t); Vector_3 Oz (FT(0),FT(0),FT(1)); - + Vector_3 r_axis = CGAL::cross_product(Oq,Oz); double cos_angle = CGAL::to_double((Oq*Oz)/CGAL::sqrt(Oq.squared_length())); double angle = std::acos(cos_angle) * 180. / CGAL_PI; - + // radius const double& r = parameters_.cylinder_radius; - + out << "Translate " << -p_cam.x() << " " << -p_cam.y() << " " << -p_cam.z() << std::endl; - out << "Rotate " << (angle+180.) << " " << -r_axis.x() << " " << -r_axis.y() << " " << -r_axis.z() << std::endl; - + out << "Rotate " << (angle+180.) << " " << -r_axis.x() << " " << -r_axis.y() << " " << -r_axis.z() << std::endl; + // Cylinder radius zmin zmax thetamax out << "Cylinder " << r << " 0 " << pq << " 360" << std::endl; out << "Identity" << std::endl; } -void +void C3t3_rib_exporter_plugin:: write_edges_flat(std::ofstream& out) { // Lights write_turn_background_light(true,out); - + out << "Surface \"constant\"" << std::endl; write_opacity(CGAL_RIB_NON_TRANSPARENT_MATERIAL_ALPHA, out); - + // Translation out << "Translate 0 0 -0.1" << std::endl; - + for ( Edge_map::iterator it = edges_.begin(), end = edges_.end() ; it != end ; ++it ) { // Color write_color(it->second, true, out); - + // Edge out << "Curves \"linear\" [2] \"nonperiodic\" \"P\" ["; write_point(it->first.first,out); @@ -1108,13 +1108,13 @@ write_edges_flat(std::ofstream& out) } -void +void C3t3_rib_exporter_plugin:: write_edges_volumic(std::ofstream& out) { // Material write_opacity(CGAL_RIB_NON_TRANSPARENT_MATERIAL_ALPHA, out); - + for ( Edge_map::iterator it = edges_.begin(), end = edges_.end() ; it != end ; ++it ) { @@ -1125,13 +1125,13 @@ write_edges_volumic(std::ofstream& out) } } -void +void C3t3_rib_exporter_plugin:: write_vertices_volumic(std::ofstream& out) { // Material write_opacity(CGAL_RIB_NON_TRANSPARENT_MATERIAL_ALPHA, out); - + for ( Vertex_map::iterator it = vertices_.begin(), end = vertices_.end() ; it != end ; ++it ) { @@ -1143,26 +1143,26 @@ write_vertices_volumic(std::ofstream& out) } -void +void C3t3_rib_exporter_plugin:: write_color(const QColor& color, bool use_transparency, std::ofstream& out) { if ( prev_color_ == color ) - { + { return; } - + // Cache data prev_color_ = color; - + // Write opacity data if (use_transparency) { write_opacity(color.alphaF(),out); } - + // Write color data - out << "Color [ " << color.redF() << " " << color.greenF() << " " + out << "Color [ " << color.redF() << " " << color.greenF() << " " << color.blueF() << " ]" << std::endl; } @@ -1175,27 +1175,27 @@ write_opacity(const double alpha, std::ofstream& out) { return; } - + // Cache data prev_alpha_ = alpha; - + // Write opacity data out << "Opacity " << alpha << " " << alpha << " " << alpha << std::endl; } -void +void C3t3_rib_exporter_plugin:: write_background(const QColor& color, std::ofstream& out) { write_turn_background_light(false,out); - + out << "Surface \"constant\"" << std::endl; write_color(color,false,out); - + double corner = zmax_ * 2.; double depth_pos = zmax_ * 1.6; - + out << "Polygon \"P\" ["; out << " " << -corner << " " << -corner << " " << depth_pos << " "; out << " " << corner << " " << -corner << " " << depth_pos << " "; diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Optimization_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Optimization_plugin.cpp index e25c5619df5..85cb6ccd1a1 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Optimization_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Optimization_plugin.cpp @@ -86,7 +86,7 @@ public: Mesh_3_optimization_plugin(); virtual void init(QMainWindow*, Scene_interface*, Messages_interface*); inline virtual QList actions() const; - + bool applicable(QAction* a) const { Scene_c3t3_item* item = qobject_cast(scene->item(scene->mainSelectionIndex())); @@ -112,16 +112,16 @@ public Q_SLOTS: #ifndef CGAL_MESH_3_DEMO_DISABLE_EXUDER void exude(); #endif - + void optimization_done(Optimizer_thread* t); void status_report(QString s); - + private: Scene_c3t3_item* get_c3t3_item() const; - + void treat_result(Scene_c3t3_item& source_item, Scene_c3t3_item& result_item, const QString& name) const; - + void launch_thread(Optimizer_thread* thread, const QString& msg); private: @@ -131,7 +131,7 @@ private: QAction* actionExude; Messages_interface* msg; QMessageBox* message_box_; - + Scene_c3t3_item* source_item_; Scene_interface *scene; QMainWindow* mw; @@ -151,7 +151,7 @@ Mesh_3_optimization_plugin() { } -void +void Mesh_3_optimization_plugin:: init(QMainWindow* mainWindow, Scene_interface* scene_interface, @@ -159,7 +159,7 @@ init(QMainWindow* mainWindow, { this->scene = scene_interface; this->mw = mainWindow; - + // Create menu items #ifndef CGAL_MESH_3_DEMO_DISABLE_ODT actionOdt = new QAction(tr("odt_optimize_mesh_3"), mw); @@ -169,7 +169,7 @@ init(QMainWindow* mainWindow, connect(actionOdt, SIGNAL(triggered()), this, SLOT(odt())); } #endif - + #ifndef CGAL_MESH_3_DEMO_DISABLE_LLOYD actionLloyd = new QAction(tr("lloyd_optimize_mesh_3"), mw); if( NULL != actionLloyd ) @@ -178,7 +178,7 @@ init(QMainWindow* mainWindow, connect(actionLloyd, SIGNAL(triggered()), this, SLOT(lloyd())); } #endif - + #ifndef CGAL_MESH_3_DEMO_DISABLE_PERTURBER actionPerturb = new QAction(tr("perturb_mesh_3"), mw); if( NULL != actionPerturb ) @@ -187,7 +187,7 @@ init(QMainWindow* mainWindow, connect(actionPerturb, SIGNAL(triggered()), this, SLOT(perturb())); } #endif - + #ifndef CGAL_MESH_3_DEMO_DISABLE_EXUDER actionExude =new QAction(tr("exude_mesh_3"), mw); if( NULL != actionExude ) @@ -196,16 +196,16 @@ init(QMainWindow* mainWindow, connect(actionExude, SIGNAL(triggered()), this, SLOT(exude())); } #endif - + msg = msg_interface; } inline -QList +QList Mesh_3_optimization_plugin::actions() const { - return QList() << actionOdt << actionLloyd + return QList() << actionOdt << actionLloyd << actionPerturb << actionExude; } @@ -236,45 +236,45 @@ Mesh_3_optimization_plugin::odt() &dialog, SLOT(accept())); connect(ui.buttonBox, SIGNAL(rejected()), &dialog, SLOT(reject())); - + connect(ui.noTimeLimit, SIGNAL(toggled(bool)), ui.maxTime, SLOT(setDisabled(bool))); - + ui.objectName->setText(item->name()); namespace cgpd = CGAL::parameters::default_values; ui.convergenceRatio->setValue(cgpd::odt_convergence_ratio); ui.freezeRatio->setValue(cgpd::odt_freeze_ratio); - + int i = dialog.exec(); if(i == QDialog::Rejected) return; - + // 0 means parameter is not considered const double max_time = ui.noTimeLimit->isChecked() ? 0 : ui.maxTime->value(); const int max_iteration_nb = static_cast(ui.maxIterationNb->value()); const double convergence = ui.convergenceRatio->value(); const double freeze = ui.freezeRatio->value(); const bool create_new_item = ui.createNewItem->isChecked(); - + // ----------------------------------- // Launch optimization // ----------------------------------- QApplication::setOverrideCursor(Qt::WaitCursor); - + Optimizer_thread* opt_thread = cgal_code_odt_mesh_3(*item, max_time, convergence, freeze, max_iteration_nb, create_new_item); - + if ( NULL == opt_thread ) { QApplication::restoreOverrideCursor(); return; } - + source_item_ = item; launch_thread(opt_thread, "Odt iterations are running..."); QApplication::restoreOverrideCursor(); @@ -299,25 +299,25 @@ Mesh_3_optimization_plugin::lloyd() ui.setupUi(&dialog); dialog.setWindowFlags(Qt::Dialog|Qt::CustomizeWindowHint|Qt::WindowCloseButtonHint); dialog.setWindowTitle(tr("Lloyd-smoothing parameters")); - + connect(ui.buttonBox, SIGNAL(accepted()), &dialog, SLOT(accept())); connect(ui.buttonBox, SIGNAL(rejected()), &dialog, SLOT(reject())); - + connect(ui.noTimeLimit, SIGNAL(toggled(bool)), ui.maxTime, SLOT(setDisabled(bool))); - + ui.objectName->setText(item->name()); - + namespace cgpd = CGAL::parameters::default_values; ui.convergenceRatio->setValue(cgpd::lloyd_convergence_ratio); ui.freezeRatio->setValue(cgpd::lloyd_freeze_ratio); - + int i = dialog.exec(); if(i == QDialog::Rejected) return; - + // 0 means parameter is not considered const double max_time = ui.noTimeLimit->isChecked() ? 0 : ui.maxTime->value(); const int max_iteration_nb = static_cast(ui.maxIterationNb->value()); @@ -329,7 +329,7 @@ Mesh_3_optimization_plugin::lloyd() // Launch optimization // ----------------------------------- QApplication::setOverrideCursor(Qt::WaitCursor); - + Optimizer_thread* opt_thread = cgal_code_lloyd_mesh_3(*item, max_time, convergence, @@ -357,7 +357,7 @@ Mesh_3_optimization_plugin::perturb() // ----------------------------------- Scene_c3t3_item* item = get_c3t3_item(); if ( NULL == item ) { return; } - + // ----------------------------------- // Dialog box // ----------------------------------- @@ -367,46 +367,46 @@ Mesh_3_optimization_plugin::perturb() ui.sliverBound->setRange(0,180); dialog.setWindowFlags(Qt::Dialog|Qt::CustomizeWindowHint|Qt::WindowCloseButtonHint); dialog.setWindowTitle(tr("Sliver perturbation parameters")); - + connect(ui.buttonBox, SIGNAL(accepted()), &dialog, SLOT(accept())); connect(ui.buttonBox, SIGNAL(rejected()), &dialog, SLOT(reject())); - + connect(ui.noTimeLimit, SIGNAL(toggled(bool)), ui.maxTime, SLOT(setDisabled(bool))); - + connect(ui.noBound, SIGNAL(toggled(bool)), ui.sliverBound, SLOT(setDisabled(bool))); - + ui.objectName->setText(item->name()); - + int i = dialog.exec(); if(i == QDialog::Rejected) return; - + // 0 means parameter is not considered const double max_time = ui.noTimeLimit->isChecked() ? 0 : ui.maxTime->value(); const double sliver_bound = ui.noBound->isChecked() ? 0 : ui.sliverBound->value(); const bool create_new_item = ui.createNewItem->isChecked(); - + // ----------------------------------- // Launch optimization // ----------------------------------- QApplication::setOverrideCursor(Qt::WaitCursor); - + Optimizer_thread* opt_thread = cgal_code_perturb_mesh_3(*item, max_time, sliver_bound, create_new_item); - + if ( NULL == opt_thread ) { QApplication::restoreOverrideCursor(); return; } - + source_item_ = item; launch_thread(opt_thread, "Sliver perturbation is running..."); QApplication::restoreOverrideCursor(); @@ -423,7 +423,7 @@ Mesh_3_optimization_plugin::exude() // ----------------------------------- Scene_c3t3_item* item = get_c3t3_item(); if ( NULL == item ) { return; } - + // ----------------------------------- // Dialog box // ----------------------------------- @@ -432,35 +432,35 @@ Mesh_3_optimization_plugin::exude() ui.setupUi(&dialog); dialog.setWindowFlags(Qt::Dialog|Qt::CustomizeWindowHint|Qt::WindowCloseButtonHint); dialog.setWindowTitle(tr("Sliver exudation parameters")); - + connect(ui.buttonBox, SIGNAL(accepted()), &dialog, SLOT(accept())); connect(ui.buttonBox, SIGNAL(rejected()), &dialog, SLOT(reject())); - + connect(ui.noTimeLimit, SIGNAL(toggled(bool)), ui.maxTime, SLOT(setDisabled(bool))); - + connect(ui.noBound, SIGNAL(toggled(bool)), ui.sliverBound, SLOT(setDisabled(bool))); - + ui.objectName->setText(item->name()); ui.sliverBound->setValue(25.); - + int i = dialog.exec(); if(i == QDialog::Rejected) return; - + // 0 means parameter is not considered const double max_time = ui.noTimeLimit->isChecked() ? 0 : ui.maxTime->value(); const double sliver_bound = ui.noBound->isChecked() ? 0 : ui.sliverBound->value(); const bool create_new_item = ui.createNewItem->isChecked(); - + // ----------------------------------- // Launch optimization // ----------------------------------- QApplication::setOverrideCursor(Qt::WaitCursor); - + Optimizer_thread* opt_thread = cgal_code_exude_mesh_3(*item, max_time, sliver_bound, @@ -471,7 +471,7 @@ Mesh_3_optimization_plugin::exude() QApplication::restoreOverrideCursor(); return; } - + source_item_ = item; launch_thread(opt_thread, "Sliver exudation is running..."); QApplication::restoreOverrideCursor(); @@ -492,14 +492,14 @@ get_c3t3_item() const tr("Selected object is not a mesh... optimization can't be performed")); return NULL; } - + if ( NULL == item->data_item() ) { QMessageBox::critical(mw,tr(""), tr("Can't perturb: data object has been destroyed !")); return NULL; } - + return item; } @@ -513,9 +513,9 @@ treat_result(Scene_c3t3_item& source_item, { result_item.setName(tr("%1 [%2]").arg(source_item.name()) .arg(name)); - + result_item.c3t3_changed(); - + // If a new item has been created if ( &source_item != &result_item) { @@ -523,23 +523,23 @@ treat_result(Scene_c3t3_item& source_item, result_item.setPosition(static_cast(bbox.xmin() + bbox.xmax())/2.f, static_cast(bbox.ymin() + bbox.ymax())/2.f, static_cast(bbox.zmin() + bbox.zmax())/2.f); - + result_item.setColor(QColor(59,74,226)); result_item.setRenderingMode(source_item.renderingMode()); result_item.set_data_item(source_item.data_item()); source_item.setVisible(false); - + const Scene_interface::Item_id index = scene->mainSelectionIndex(); scene->itemChanged(index); - + Scene_interface::Item_id new_item_id = scene->addItem(&result_item); scene->setSelectedItem(new_item_id); } else { result_item.update_histogram(); - + const Scene_interface::Item_id index = scene->mainSelectionIndex(); scene->itemChanged(index); } @@ -552,7 +552,7 @@ optimization_done(Optimizer_thread* thread) { CGAL::Mesh_optimization_return_code return_code = thread->return_code(); QString name = thread->optimizer_name(); - + // Print message in console QString str = QString("%1 of \"%2\" done in %3s
" "End reason: '%4'
") @@ -560,14 +560,14 @@ optimization_done(Optimizer_thread* thread) .arg(source_item_->name()) .arg(thread->time()) .arg(translate(return_code)); - + Q_FOREACH( QString param, thread->parameters_log() ) { str.append(QString("( %1 )
").arg(param)); } - + CGAL::Three::Three::information(qPrintable(str)); - + // Treat new c3t3 item Scene_c3t3_item* result_item = thread->item(); treat_result( *source_item_, *result_item, name); @@ -591,25 +591,25 @@ launch_thread(Optimizer_thread* opt_thread, const QString& window_text) window_text, QMessageBox::Cancel, mw); - + message_box_->setDefaultButton(QMessageBox::Cancel); QAbstractButton* cancelButton = message_box_->button(QMessageBox::Cancel); cancelButton->setText(tr("Stop")); - + QObject::connect(cancelButton, SIGNAL(clicked()), opt_thread, SLOT(stop())); - + message_box_->show(); - + // ----------------------------------- // Connect main thread to optimization thread and launch optimizer // ----------------------------------- QObject::connect(opt_thread, SIGNAL(done(Optimizer_thread*)), this, SLOT(optimization_done(Optimizer_thread*))); - + QObject::connect(opt_thread, SIGNAL(status_report(QString)), this, SLOT(status_report(QString))); - + opt_thread->start(); } @@ -620,7 +620,7 @@ Mesh_3_optimization_plugin:: status_report(QString str) { if ( NULL == message_box_ ) { return; } - + message_box_->setInformativeText(str); } @@ -638,7 +638,7 @@ translate(CGAL::Mesh_optimization_return_code rc) case CGAL::MAX_ITERATION_NUMBER_REACHED: return QString("Max iteration number reached"); case CGAL::ALL_VERTICES_FROZEN: return QString("All vertices have been frozen"); } - + return QString("ERROR"); } diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/config_mesh_3.h b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/config_mesh_3.h index 9b1329b6cd7..50aa90773b8 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/config_mesh_3.h +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/config_mesh_3.h @@ -99,7 +99,7 @@ // ===================== // Worksharing strategy // ===================== - + //# define CGAL_MESH_3_LOAD_BASED_WORKSHARING // Not recommended // ========================================================================== @@ -125,7 +125,7 @@ # define CGAL_MESH_3_IF_UNSORTED_QUEUE_JUST_SORT_AFTER_SCAN #endif // CGAL_CONCURRENT_MESH_3 - + //#define CGAL_MESH_3_PROFILING #endif // CGAL_DEMO_MESH_3_CONFIG_H diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Basic_generator_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PCA/Basic_generator_plugin.cpp index 259db52f02a..184770f685b 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Basic_generator_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Basic_generator_plugin.cpp @@ -55,7 +55,7 @@ public : QMenu* menuFile = mw->findChild("menuFile"); - + QMenu* menu = menuFile->findChild("menuGenerateObject"); if(!menu){ QAction* actionLoad = mw->findChild("actionLoadPlugin"); diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index c60deb3c54e..d664cb9d707 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -82,7 +82,7 @@ Scene::addItem(CGAL::Three::Scene_item* item) qobject_cast(item); if(group) addGroup(group); - //init the item for the mainViewer to avoid using unexisting + //init the item for the mainViewer to avoid using unexisting //VAOs if the mainViewer is not the first to be drawn. QOpenGLFramebufferObject* fbo = CGAL::Three::Three::mainViewer()->depthPeelingFbo(); CGAL::Three::Three::mainViewer()->setDepthPeelingFbo(nullptr);//to prevent crashing as the fbo is not initialized in this call. @@ -249,7 +249,7 @@ Scene::erase(QList indices) children.removeAll(removed_item); indexErased(removed_item); m_entries.removeAll(item); - + Q_EMIT itemAboutToBeDestroyed(item); item->aboutToBeDestroyed(); item->deleteLater(); @@ -312,7 +312,7 @@ Scene::item(Item_id index) const return m_entries.value(index); // QList::value checks bounds } -Scene::Item_id +Scene::Item_id Scene::item_id(CGAL::Three::Scene_item* scene_item) const { return m_entries.indexOf(scene_item); @@ -347,7 +347,7 @@ Scene::duplicate(Item_id index) void Scene::initializeGL(CGAL::Three::Viewer_interface* viewer) { - + //Vertex source code const char vertex_source[] = { @@ -361,9 +361,9 @@ void Scene::initializeGL(CGAL::Three::Viewer_interface* viewer) " f_texCoord = v_texCoord; \n" " gl_Position = projection_matrix * vertex; \n" "} \n" - + }; - + const char vertex_source_comp[] = { "attribute highp vec4 vertex; \n" @@ -375,7 +375,7 @@ void Scene::initializeGL(CGAL::Three::Viewer_interface* viewer) " f_texCoord = v_texCoord; \n" " gl_Position = projection_matrix * vertex; \n" "} \n" - + }; //Fragment source code const char fragment_source[] = @@ -398,8 +398,8 @@ void Scene::initializeGL(CGAL::Three::Viewer_interface* viewer) " gl_FragColor = texture2D(texture, f_texCoord); \n" "} \n" }; - - + + QOpenGLShader vertex_shader(QOpenGLShader::Vertex); QOpenGLShader fragment_shader(QOpenGLShader::Fragment); if(viewer->isOpenGL_4_3()) @@ -408,7 +408,7 @@ void Scene::initializeGL(CGAL::Three::Viewer_interface* viewer) { std::cerr<<"Compiling vertex source FAILED"<makeCurrent(); vaos[viewer] = new QOpenGLVertexArrayObject(); vaos[viewer]->create(); @@ -467,7 +467,7 @@ void Scene::initializeGL(CGAL::Three::Viewer_interface* viewer) program.enableAttributeArray("vertex"); program.setAttributeArray("vertex", GL_FLOAT, 0, 3); vbo[0].release(); - + vbo[1].bind(); vbo[1].allocate(uvs, 12 * sizeof(float)); program.enableAttributeArray("v_texCoord"); @@ -519,7 +519,7 @@ bool item_should_be_skipped_in_draw(Scene_item* item) { } return true; } - + void Scene::renderScene(const QList &items, Viewer_interface *viewer, @@ -555,7 +555,7 @@ void Scene::renderScene(const QList &items, } item.draw(viewer); if(with_names) { - + // read depth buffer at pick location; float depth = 1.0; viewer->glReadPixels(picked_pixel.x(),viewer->camera()->screenHeight()-1-picked_pixel.y(),1,1,GL_DEPTH_COMPONENT, GL_FLOAT, &depth); @@ -681,7 +681,7 @@ void Scene::renderPointScene(const QList &items, return true; return false; } -void +void Scene::draw_aux(bool with_names, CGAL::Three::Viewer_interface* viewer) { QMap picked_item_IDs; @@ -704,9 +704,9 @@ Scene::draw_aux(bool with_names, CGAL::Three::Viewer_interface* viewer) renderScene(children, viewer, picked_item_IDs, with_names, -1, false, NULL); if(with_names) { - //here we get the selected point, before erasing the depth buffer. We store it - //in a dynamic property as a QList. If there is some alpha, the - //depth buffer is altered, and the picking will return true even when it is + //here we get the selected point, before erasing the depth buffer. We store it + //in a dynamic property as a QList. If there is some alpha, the + //depth buffer is altered, and the picking will return true even when it is // performed in the background, when it should return false. To avoid that, // we distinguish the case were there is no alpha, to let the viewer //perform it, and the case where the pixel is not found. In the first case, @@ -737,7 +737,7 @@ Scene::draw_aux(bool with_names, CGAL::Three::Viewer_interface* viewer) QColor background = viewer->backgroundColor(); fbos.resize((int)viewer->total_pass()); depth_test.resize((int)viewer->total_pass()-1); - + //first pass fbos[0] = new QOpenGLFramebufferObject(viewer->width(), viewer->height(),QOpenGLFramebufferObject::Depth, GL_TEXTURE_2D, GL_RGBA32F); fbos[0]->bind(); @@ -767,7 +767,7 @@ Scene::draw_aux(bool with_names, CGAL::Three::Viewer_interface* viewer) renderScene(opaque_items, viewer, picked_item_IDs, false, 0,true, NULL); renderScene(transparent_items, viewer, picked_item_IDs, false, 0,true, NULL); depth_test[0]->release(); - + //other passes for(int i=1; itotal_pass()-1; ++i) { @@ -787,7 +787,7 @@ Scene::draw_aux(bool with_names, CGAL::Three::Viewer_interface* viewer) renderScene(opaque_items , viewer, picked_item_IDs, false, i, false, depth_test[i-1]); renderScene(transparent_items, viewer, picked_item_IDs, false, i, false, depth_test[i-1]); fbos[i]->release(); - + depth_test[i] = new QOpenGLFramebufferObject(viewer->width(), viewer->height(),QOpenGLFramebufferObject::Depth, GL_TEXTURE_2D, GL_RGBA32F); depth_test[i]->bind(); viewer->glDisable(GL_BLEND); @@ -803,8 +803,8 @@ Scene::draw_aux(bool with_names, CGAL::Three::Viewer_interface* viewer) renderScene(transparent_items, viewer, picked_item_IDs, false, i, true, depth_test[i-1]); depth_test[i]->release(); } - - + + //last pass fbos[(int)viewer->total_pass()-1] = new QOpenGLFramebufferObject(viewer->width(), viewer->height(),QOpenGLFramebufferObject::Depth, GL_TEXTURE_2D, GL_RGBA32F); fbos[(int)viewer->total_pass()-1]->bind(); @@ -822,7 +822,7 @@ Scene::draw_aux(bool with_names, CGAL::Three::Viewer_interface* viewer) fbos[(int)viewer->total_pass()-1]->release(); if(viewer->getStoredFrameBuffer() != NULL) viewer->getStoredFrameBuffer()->bind(); - + //blending program.bind(); vaos[viewer]->bind(); @@ -834,7 +834,7 @@ Scene::draw_aux(bool with_names, CGAL::Three::Viewer_interface* viewer) viewer->glClear(GL_COLOR_BUFFER_BIT); viewer->glEnable(GL_BLEND); viewer->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - + QMatrix4x4 proj_mat; proj_mat.setToIdentity(); proj_mat.ortho(-1,1,-1,1,0,1); @@ -852,13 +852,13 @@ Scene::draw_aux(bool with_names, CGAL::Three::Viewer_interface* viewer) vaos[viewer]->release(); program.release(); } - + viewer->glDepthFunc(GL_LEQUAL); // Wireframe OpenGL drawing renderWireScene(children, viewer, picked_item_IDs, with_names); // Points OpenGL drawing renderPointScene(children, viewer, picked_item_IDs, with_names); - + if(with_names) { QList depths = picked_item_IDs.keys(); @@ -1126,7 +1126,7 @@ bool Scene::dropMimeData(const QMimeData * /*data*/, //todo : if a group is selected, don't treat it's children. bool Scene::sort_lists(QVector >&sorted_lists, bool up) -{ +{ QVector group_found; Q_FOREACH(int i, selectionIndices()) { @@ -1149,7 +1149,7 @@ bool Scene::sort_lists(QVector >&sorted_lists, bool up) } } } - //iterate the first list to find the groups that are selected and remove the corresponding + //iterate the first list to find the groups that are selected and remove the corresponding //sub lists. //todo: do that for each group. (treat subgroups) for(int i = 0; i< sorted_lists.first().size(); ++i) @@ -1198,7 +1198,7 @@ void Scene::moveRowUp() //if moving one up would put it out of range, then we stop and do nothing. if(!sort_lists(sorted_lists, true)) return; - + for(int i=0; i is) QItemSelection Scene::createSelectionAll() { - //it is not possible to directly create a selection with items that have different parents, so + //it is not possible to directly create a selection with items that have different parents, so //we do it iteratively. QItemSelection sel; for(int i=0; i< m_entries.size(); ++i) @@ -1382,7 +1382,7 @@ void Scene::itemVisibilityChanged(CGAL::Three::Scene_item* item) //does not recenter if(visibility_recentering_enabled){ Q_EMIT updated_bbox(true); - + } } } @@ -1917,7 +1917,7 @@ void Scene::initGL(Viewer_interface *viewer) program.release(); } -void Scene::callDraw(){ +void Scene::callDraw(){ Q_FOREACH(CGAL::QGLViewer* v, CGAL::QGLViewer::QGLViewerPool()) { qobject_cast(v)->update(); diff --git a/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp b/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp index 8a314482721..85d79582dd3 100644 --- a/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp @@ -79,7 +79,7 @@ public : delete alphaSlider; } void compute_bbox() const Q_DECL_OVERRIDE{} - + void gl_initialization(Vi* viewer) { if(!isInit(viewer)) @@ -113,7 +113,7 @@ public : { getTriangleContainer(0)->reset_vbos(ALL); getEdgeContainer(0)->reset_vbos(ALL); - + getTriangleContainer(0)->allocate(Tc::Flat_vertices, vertices->data(), static_cast(vertices->size()*sizeof(float))); getTriangleContainer(0)->allocate(Tc::Flat_normals, normals->data(), @@ -139,7 +139,7 @@ public : getEdgeContainer(0)->setFlatDataSize(edges->size()); } } - + //Displays the item void draw(CGAL::Three::Viewer_interface* viewer) const Q_DECL_OVERRIDE { @@ -173,7 +173,7 @@ public : getEdgeContainer(0)->setPlane(cp); getEdgeContainer(0)->setColor(QColor(Qt::black)); getEdgeContainer(0)->draw(viewer, true); - + } void setFast(bool b) @@ -238,10 +238,10 @@ public : QMenu* contextMenu() Q_DECL_OVERRIDE { QMenu* menu = Scene_item::contextMenu(); - + const char* prop_name = "Menu modified by Scene_surface_mesh_item."; bool menuChanged = menu->property(prop_name).toBool(); - + if(!menuChanged) { menu->addSeparator(); QMenu *container = new QMenu(tr("Alpha value")); @@ -253,7 +253,7 @@ public : setAlpha(alphaSlider->value()); redraw(); }); - + container->addAction(sliderAction); menu->addMenu(container); setProperty("menu_changed", true); @@ -265,10 +265,10 @@ public : { return m_alpha ; } - + void setAlpha(int a) Q_DECL_OVERRIDE { - m_alpha = a / 255.0f; + m_alpha = a / 255.0f; redraw(); } private: @@ -541,14 +541,14 @@ void Scene_c3t3_item::common_constructor(bool is_surface) c3t3_changed(); setRenderingMode(FlatPlusEdges); create_flat_and_wire_sphere(1.0f,d->s_vertex,d->s_normals, d->ws_vertex); - + d->is_surface = is_surface; d->is_grid_shown = !is_surface; d->show_tetrahedra = !is_surface; d->last_intersection = !d->show_tetrahedra; - + setTriangleContainer(C3t3_faces, new Tc(Vi::PROGRAM_C3T3, false)); - + setEdgeContainer(CNC, new Ec(Vi::PROGRAM_NO_SELECTION, false)); setEdgeContainer(Grid_edges, new Ec(Vi::PROGRAM_NO_SELECTION, false)); setEdgeContainer(C3t3_edges, new Ec(Vi::PROGRAM_C3T3_EDGES, false)); @@ -569,7 +569,7 @@ Scene_c3t3_item::Scene_c3t3_item(const C3t3& c3t3, bool is_surface) : Scene_group_item("unnamed") , d(new Scene_c3t3_item_priv(c3t3, this)) { - d->reset_cut_plane(); + d->reset_cut_plane(); common_constructor(is_surface); } @@ -968,7 +968,7 @@ void Scene_c3t3_item::draw(CGAL::Three::Viewer_interface* viewer) const { d->intersection->setFast(false); else d->intersection->setFast(true); - + if(!d->frame->isManipulated() && !d->areInterBufFilled(viewer)) { //initGL @@ -984,7 +984,7 @@ void Scene_c3t3_item::draw(CGAL::Three::Viewer_interface* viewer) const { } if(d->is_grid_shown) { - //viewer->makeCurrent(); //messes with the depthPeeling + //viewer->makeCurrent(); //messes with the depthPeeling getEdgeContainer(Grid_edges)->setColor(QColor(Qt::black)); QMatrix4x4 f_mat; for (int i = 0; i<16; i++) @@ -1029,13 +1029,13 @@ void Scene_c3t3_item::drawEdges(CGAL::Three::Viewer_interface* viewer) const { getEdgeContainer(Grid_edges)->setFrameMatrix(f_mat); getEdgeContainer(Grid_edges)->draw(viewer, true); } - + QVector4D cp = cgal_plane_to_vector4d(this->plane()); getEdgeContainer(C3t3_edges)->setPlane(cp); getEdgeContainer(C3t3_edges)->setIsSurface(d->is_surface); getEdgeContainer(C3t3_edges)->setColor(QColor(Qt::black)); getEdgeContainer(C3t3_edges)->draw(viewer, true); - + if(d->show_tetrahedra){ if(!d->frame->isManipulated()) d->intersection->setFast(false); @@ -1078,14 +1078,14 @@ void Scene_c3t3_item::drawPoints(CGAL::Three::Viewer_interface * viewer) const computeElements(); initializeBuffers(viewer); } - - + + QVector4D cp = cgal_plane_to_vector4d(this->plane()); getPointContainer(C3t3_points)->setPlane(cp); getPointContainer(C3t3_points)->setIsSurface(d->is_surface); getPointContainer(C3t3_points)->setColor(this->color()); getPointContainer(C3t3_points)->draw(viewer, true); - + if(d->is_grid_shown) { getEdgeContainer(Grid_edges)->setColor(QColor(Qt::black)); @@ -1175,7 +1175,7 @@ QMenu* Scene_c3t3_item::contextMenu() bool menuChanged = menu->property(prop_name).toBool(); if (!menuChanged) { - + QMenu *container = new QMenu(tr("Alpha value")); container->menuAction()->setProperty("is_groupable", true); QWidgetAction *sliderAction = new QWidgetAction(0); @@ -1190,7 +1190,7 @@ QMenu* Scene_c3t3_item::contextMenu() ); container->addAction(sliderAction); menu->addMenu(container); - + container = new QMenu(tr("Tetrahedra's Shrink Factor")); sliderAction = new QWidgetAction(0); connect(d->tet_Slider, &QSlider::valueChanged, this, &Scene_c3t3_item::itemChanged); @@ -1234,7 +1234,7 @@ QMenu* Scene_c3t3_item::contextMenu() connect(actionShowGrid, SIGNAL(toggled(bool)), this, SLOT(show_grid(bool))); - + menu->setProperty(prop_name, true); } return menu; @@ -1248,8 +1248,8 @@ void Scene_c3t3_item_priv::initializeBuffers(CGAL::Three::Viewer_interface *view item->getTriangleContainer(Scene_c3t3_item::C3t3_faces)->initializeBuffers(viewer); item->getTriangleContainer(Scene_c3t3_item::C3t3_faces)->setFlatDataSize( positions_poly_size); - - + + positions_poly.clear(); positions_poly.shrink_to_fit(); normals.clear(); @@ -1271,7 +1271,7 @@ void Scene_c3t3_item_priv::initializeBuffers(CGAL::Three::Viewer_interface *view item->getPointContainer(Scene_c3t3_item::C3t3_points)->initializeBuffers(viewer); item->getPointContainer(Scene_c3t3_item::C3t3_points)->setFlatDataSize( positions_lines_size); - + positions_lines.clear(); positions_lines.shrink_to_fit(); } @@ -1341,7 +1341,7 @@ void Scene_c3t3_item_priv::computeIntersections(CGAL::Three::Viewer_interface* v positions_barycenter.clear(); const Geom_traits::Plane_3& plane = item->plane(offset); tree.all_intersected_primitives(plane, - boost::make_function_output_iterator(ComputeIntersection(*this))); + boost::make_function_output_iterator(ComputeIntersection(*this))); intersection->gl_initialization(viewer); } @@ -1401,13 +1401,13 @@ void Scene_c3t3_item_priv::computeSpheres() tr_vertices.push_back(*vit); spheres->add_sphere(Geom_traits::Sphere_3(center, radius),s_id++, CGAL::Color(UC(c.red()), UC(c.green()), UC(c.blue()))); - + } spheres->invalidateOpenGLBuffers(); } void Scene_c3t3_item_priv::computeElements() -{ +{ if(!alphaSlider) { alphaSlider = new QSlider(::Qt::Horizontal); @@ -1415,7 +1415,7 @@ void Scene_c3t3_item_priv::computeElements() alphaSlider->setMaximum(255); alphaSlider->setValue(255); } - + positions_poly.clear(); positions_grid.clear(); normals.clear(); @@ -1576,7 +1576,7 @@ void Scene_c3t3_item::show_spheres(bool b) QString msg = QString("Vertex's index : %1; Vertex's in dimension: %2.").arg(d->tr_vertices[id].index()).arg(d->tr_vertices[id].in_dimension()); CGAL::Three::Three::information(msg); CGAL::Three::Three::mainViewer()->displayMessage(msg, 5000); - + }); d->spheres->setName("Protecting spheres"); d->spheres->setRenderingMode(Gouraud); @@ -1958,7 +1958,7 @@ void Scene_c3t3_item::invalidateOpenGLBuffers() getEdgeContainer(CNC)->reset_vbos(ALL); getEdgeContainer(Grid_edges)->reset_vbos(ALL); getPointContainer(C3t3_points)->reset_vbos(ALL); - + Q_FOREACH(CGAL::QGLViewer* v, CGAL::QGLViewer::QGLViewerPool()) { CGAL::Three::Viewer_interface* viewer = static_cast(v); @@ -2037,52 +2037,52 @@ void Scene_c3t3_item::computeElements()const { QApplication::setOverrideCursor(Qt::WaitCursor); const_cast(this)->d->computeElements(); - + getTriangleContainer(C3t3_faces)->allocate( Tc::Flat_vertices, d->positions_poly.data(), static_cast(d->positions_poly.size()*sizeof(float))); - + getTriangleContainer(C3t3_faces)->allocate( Tc::Flat_normals, d->normals.data(), static_cast(d->normals.size()*sizeof(float))); - - + + getTriangleContainer(C3t3_faces)->allocate( Tc::FColors, d->f_colors.data(), static_cast(d->f_colors.size()*sizeof(float))); - + getTriangleContainer(C3t3_faces)->allocate( Tc::Facet_centers, d->positions_barycenter.data(), static_cast(d->positions_barycenter.size()*sizeof(float))); - + d->positions_poly_size = d->positions_poly.size(); - + getEdgeContainer(C3t3_edges)->allocate( Ec::Vertices, d->positions_lines.data(), static_cast(d->positions_lines.size()*sizeof(float))); d->positions_lines_size = d->positions_lines.size(); - + getEdgeContainer(CNC)->allocate( Ec::Vertices, d->positions_lines_not_in_complex.data(), static_cast(d->positions_lines_not_in_complex.size()*sizeof(float))); - + d->positions_lines_not_in_complex_size = d->positions_lines_not_in_complex.size(); - + getEdgeContainer(Grid_edges)->allocate( Ec::Vertices, d->positions_grid.data(), static_cast(d->positions_grid.size()*sizeof(float))); - + getPointContainer(C3t3_points)->allocate( Pc::Vertices, d->positions_lines.data(), static_cast(d->positions_lines.size()*sizeof(float))); - + setBuffersFilled(true); QApplication::restoreOverrideCursor(); } diff --git a/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.cpp b/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.cpp index 270ce9f839e..0066720cd5e 100644 --- a/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.cpp @@ -76,13 +76,13 @@ void Scene_implicit_function_item_priv::initialize_buffers(CGAL::Three::Viewer_i { item->getTriangleContainer(0)->initializeBuffers(viewer); item->getTriangleContainer(0)->setFlatDataSize(nb_quad); - + item->getEdgeContainer(0)->initializeBuffers(viewer); item->getEdgeContainer(0)->setFlatDataSize(nb_cube); - + item->getEdgeContainer(1)->initializeBuffers(viewer); item->getEdgeContainer(1)->setFlatDataSize(nb_grid); - + positions_tex_quad.clear(); positions_tex_quad.shrink_to_fit(); texture_map.clear(); @@ -371,14 +371,14 @@ Scene_implicit_function_item::draw(CGAL::Three::Viewer_interface* viewer) const d->frame_->setOrientation(1., 0, 0, 0); d->init = true; } - + if(d->frame_->isManipulated()) { if(d->need_update_) { compute_function_grid(); d->need_update_ = false; } } - + if(!isInit(viewer)) initGL(viewer); if ( getBuffersFilled() && @@ -420,7 +420,7 @@ Scene_implicit_function_item::drawEdges(CGAL::Three::Viewer_interface* viewer) c computeElements(); initializeBuffers(viewer); } - + getEdgeContainer(0)->setColor(QColor(0,0,0)); getEdgeContainer(0)->draw(viewer, true); QMatrix4x4 f_mat; @@ -601,18 +601,18 @@ void Scene_implicit_function_item::computeElements() const d->positions_tex_quad.data(), static_cast(d->positions_tex_quad.size()*sizeof(float))); d->nb_quad = d->positions_tex_quad.size(); - + getTriangleContainer(0)->allocate( Tc::Texture_map, d->texture_map.data(), static_cast(d->texture_map.size()*sizeof(float))); - + getEdgeContainer(0)->allocate( Ec::Vertices, d->positions_cube.data(), static_cast(d->positions_cube.size()*sizeof(float))); d->nb_cube= d->positions_cube.size(); - + getEdgeContainer(1)->allocate( Ec::Vertices, d->positions_grid.data(), diff --git a/Three/include/CGAL/Three/Three.h b/Three/include/CGAL/Three/Three.h index d80d4fb1e8a..38b2ac8ea7d 100644 --- a/Three/include/CGAL/Three/Three.h +++ b/Three/include/CGAL/Three/Three.h @@ -53,13 +53,13 @@ public: static int getDefaultLinesWidth(); /*! \brief Adds a dock widget to the interface * - * Adds a dock widget in the left section of the MainWindow. If the slot is already + * Adds a dock widget in the left section of the MainWindow. If the slot is already * taken, the dock widgets will be tabified. */ void addDockWidget(QDockWidget* dock_widget); /*! \brief Gets an item of the templated type. - * \returns the first `SceneType` item found in the scene's list of currently selected + * \returns the first `SceneType` item found in the scene's list of currently selected * items; * \returns nullptr if there is no `SceneType` in the list. */ From 68728f4cd8578e0723d446bb7db28837f9cbf883 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 26 Mar 2020 19:05:04 +0100 Subject: [PATCH 139/141] extra run of the script to remove tabs and trailing whitespaces --- .../examples/Polygon_mesh_processing/CMakeLists.txt | 4 ++-- .../test/Polygon_mesh_processing/CMakeLists.txt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt b/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt index 57ee5939e64..26646ab4ad1 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt @@ -10,7 +10,7 @@ find_package( CGAL QUIET COMPONENTS ) if ( NOT CGAL_FOUND ) message(STATUS "This project requires the CGAL library, and will not be compiled.") - return() + return() endif() @@ -21,7 +21,7 @@ if ( NOT Boost_FOUND ) message(STATUS "This project requires the Boost library, and will not be compiled.") - return() + return() endif() diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt b/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt index 15b55bfa094..e4e2b21f80b 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt @@ -10,7 +10,7 @@ find_package( CGAL QUIET COMPONENTS Core) if ( NOT CGAL_FOUND ) message(STATUS "This project requires the CGAL library, and will not be compiled.") - return() + return() endif() @@ -23,7 +23,7 @@ if ( NOT Boost_FOUND ) message(STATUS "This project requires the Boost library, and will not be compiled.") - return() + return() endif() From f8414293d74db55904f3c3752be25e24dceae37f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 26 Mar 2020 19:27:08 +0100 Subject: [PATCH 140/141] extra run of the script to remove tabs and trailing whitespaces --- .../CGAL/Constrained_triangulation_plus_2.h | 424 +++++++++--------- .../doc/Triangulation_2/Triangulation_2.txt | 376 ++++++++-------- .../CGAL/Constrained_triangulation_plus_2.h | 300 ++++++------- .../internal/CTP2_subconstraint_graph.h | 16 +- 4 files changed, 558 insertions(+), 558 deletions(-) diff --git a/Triangulation_2/doc/Triangulation_2/CGAL/Constrained_triangulation_plus_2.h b/Triangulation_2/doc/Triangulation_2/CGAL/Constrained_triangulation_plus_2.h index 4347b5c7aff..7f8eeddc547 100644 --- a/Triangulation_2/doc/Triangulation_2/CGAL/Constrained_triangulation_plus_2.h +++ b/Triangulation_2/doc/Triangulation_2/CGAL/Constrained_triangulation_plus_2.h @@ -12,7 +12,7 @@ in the triangulation. The class `Constrained_triangulation_plus_2` inherits from its template parameter Tr, which has to be instantiated by a constrained or constrained Delaunay triangulation. -The intersection tag of the base class determines whether +The intersection tag of the base class determines whether intersecting input constraints are supported or not. When intersections of input constraints are supported, the base class constructs a triangulation of the arrangement @@ -28,7 +28,7 @@ either vertices of the input constraint or intersection points. \todo The following description does not match the code Two consecutive vertices of an input constraint form a *subconstraint*. A subconstraint is a pair of vertex handles and corresponds to a constrained edge of the -triangulation, which is a pair of a face handle and an index. +triangulation, which is a pair of a face handle and an index. The triangulation also enables the retrieval of the set of subconstraints of the triangulation (not ordered along constraints). @@ -38,82 +38,82 @@ one can obtain the input constraints which induce `e`. \tparam Tr must be either a CGAL::Constrained_triangulation_2 or a CGAL::Constrained_Delaunay_triangulation_2 -\sa `CGAL::Constrained_triangulation_2` -\sa `CGAL::Constrained_Delaunay_triangulation_2` -\sa `ConstrainedTriangulationTraits_2` -\sa `ConstrainedDelaunayTriangulationTraits_2` +\sa `CGAL::Constrained_triangulation_2` +\sa `CGAL::Constrained_Delaunay_triangulation_2` +\sa `ConstrainedTriangulationTraits_2` +\sa `ConstrainedDelaunayTriangulationTraits_2` */ template< typename Tr > class Constrained_triangulation_plus_2 : public Tr { public: -/// \name Types +/// \name Types /// @{ -/*! -The triangulation base class. -*/ -typedef Tr Triangulation; - -/*! -The intersection tag as defined in `Tr`. -*/ - typedef Tr::Intersection_tag Intersection_tag; - /*! -The identifier of a polyline constraint. -The class is model of `Assignable`, `CopyConstructible`, `DefaultConstructible`, `LessThanComparable` and `EqualityComparable`. +The triangulation base class. +*/ +typedef Tr Triangulation; + +/*! +The intersection tag as defined in `Tr`. +*/ + typedef Tr::Intersection_tag Intersection_tag; + +/*! +The identifier of a polyline constraint. +The class is model of `Assignable`, `CopyConstructible`, `DefaultConstructible`, `LessThanComparable` and `EqualityComparable`. A default constructed `Constraint_id` is a singular value that can not be the ID of a constraint. */ typedef unspecified_type Constraint_id; -/*! -An iterator to visit -all the input constraints. The order of visit is undefined. -The value type of this iterator is `Constraint_id`. -*/ -typedef unspecified_type Constraint_iterator; +/*! +An iterator to visit +all the input constraints. The order of visit is undefined. +The value type of this iterator is `Constraint_id`. +*/ +typedef unspecified_type Constraint_iterator; /*! A range type for iterating over all constraints. -*/ +*/ typedef Iterator_range Constraints; - + /*! A subconstraint is a pair of vertices that correspond to an `Edge`. */ typedef std::pair Subconstraint; -/*! -An iterator -to visit all the subconstraints of the triangulation. -The order of visit is undefined. -The value type of this iterator is `std::pair*>` -corresponding to the vertices of the -subconstraint. -*/ -typedef unspecified_type Subconstraint_iterator; +/*! +An iterator +to visit all the subconstraints of the triangulation. +The order of visit is undefined. +The value type of this iterator is `std::pair*>` +corresponding to the vertices of the +subconstraint. +*/ +typedef unspecified_type Subconstraint_iterator; /*! A range type for iterating over all subconstraints. -*/ +*/ typedef Iterator_range Subconstraints; - -/*! -An iterator on the -vertices of the chain of subconstraints representing a -constraint. The value type of this iterator is `Vertex_handle`. -*/ -typedef unspecified_type Vertices_in_constraint_iterator; -/*! -A context enables the access to the vertices of a constraint that pass +/*! +An iterator on the +vertices of the chain of subconstraints representing a +constraint. The value type of this iterator is `Vertex_handle`. +*/ +typedef unspecified_type Vertices_in_constraint_iterator; + +/*! +A context enables the access to the vertices of a constraint that pass through a subconstraint. -*/ +*/ class Context { public: /*! @@ -137,121 +137,121 @@ through a subconstraint. correspond to the two vertices of the subconstraint. */ Vertices_in_constraint_iterator current() const; - }; + }; -/*! -An iterator on -constraints enclosing a given subconstraint. The value type of this -iterator -is `Context`. -*/ -typedef unspecified_type Context_iterator; +/*! +An iterator on +constraints enclosing a given subconstraint. The value type of this +iterator +is `Context`. +*/ +typedef unspecified_type Context_iterator; /*! range type for iterating over contexts. */ -typedef Iterator_range Contexts; -/// @} +typedef Iterator_range Contexts; +/// @} -/// \name Creation +/// \name Creation /// @{ -/*! +/*! Introduces an empty triangulation. -*/ -Constrained_triangulation_plus_2(const Geom_traits& gt=Geom_traits()); +*/ +Constrained_triangulation_plus_2(const Geom_traits& gt=Geom_traits()); -/*! -Copy constructor. -*/ -Constrained_triangulation_plus_2(const -Constrained_triangulation_plus_2& ct); +/*! +Copy constructor. +*/ +Constrained_triangulation_plus_2(const +Constrained_triangulation_plus_2& ct); -/*! -Introduces a constrained triangulation +/*! +Introduces a constrained triangulation from the constraints in the range `[first,last)`. -\tparam ConstraintIterator must be an `InputIterator` with the value type `std::pair` or `Segment`. -*/ -template -Constrained_triangulation_plus_2( -ConstraintIterator first, +\tparam ConstraintIterator must be an `InputIterator` with the value type `std::pair` or `Segment`. +*/ +template +Constrained_triangulation_plus_2( +ConstraintIterator first, ConstraintIterator last, -const Geom_traits& gt= Geom_traits()); +const Geom_traits& gt= Geom_traits()); -/// @} +/// @} -/// \name Assignment +/// \name Assignment /// @{ -/*! -Assignment. All the vertices and faces are duplicated. +/*! +Assignment. All the vertices and faces are duplicated. The bidirectional mapping between constraints and subconstraints is also duplicated. -*/ -Constrained_triangulation_plus_2 operator=(const -Constrained_triangulation_plus_2& tr); +*/ +Constrained_triangulation_plus_2 operator=(const +Constrained_triangulation_plus_2& tr); -/*! -The triangulations `tr` and this triangulation are swapped. -This operation should be preferred to the assignment or to -the copy constructor if `tr` is deleted after that. -*/ -void swap(Constrained_triangulation_plus_2 tr); +/*! +The triangulations `tr` and this triangulation are swapped. +This operation should be preferred to the assignment or to +the copy constructor if `tr` is deleted after that. +*/ +void swap(Constrained_triangulation_plus_2 tr); -/// @} +/// @} -/// \name Insertion and Removal +/// \name Insertion and Removal /// The class `Constrained_triangulation_plus_2` overwrites the /// following insertion and removal member functions for points and /// constraints. /// @{ -/*! -inserts point `p` as a vertex of the triangulation. -*/ -Vertex_handle insert(const Point& p, -Face_handle start = Face_handle() ); +/*! +inserts point `p` as a vertex of the triangulation. +*/ +Vertex_handle insert(const Point& p, +Face_handle start = Face_handle() ); -/*! -inserts point `p` in the triangulation at the location given by `(lt,loc,i)`. +/*! +inserts point `p` in the triangulation at the location given by `(lt,loc,i)`. \sa `Triangulation_2::locate()` -*/ -Vertex_handle insert(const Point& p, -Locate_type lt, -Face_handle loc, int li ); +*/ +Vertex_handle insert(const Point& p, +Locate_type lt, +Face_handle loc, int li ); -/*! -Equivalent to `insert(p)`. -*/ -Vertex_handle push_back(const Point& p); +/*! +Equivalent to `insert(p)`. +*/ +Vertex_handle push_back(const Point& p); -/*! +/*! inserts the points in the range `[first,last)`. -Returns the number of inserted points. -\tparam PointIterator must be an `InputIterator` with the value type `Point`. -*/ -template < class PointIterator > -size_type -insert(PointIterator first, PointIterator last); +Returns the number of inserted points. +\tparam PointIterator must be an `InputIterator` with the value type `Point`. +*/ +template < class PointIterator > +size_type +insert(PointIterator first, PointIterator last); -/*! +/*! inserts the constraint segment `ab` in the triangulation. If the two points are equal the point is inserted but no constraint, and the default constructed `Constraint_id` is returned. -*/ +*/ Constraint_id insert_constraint(Point a, Point b); -/*! -inserts the constraint `c`. -*/ - void push_back(const std::pair& c); +/*! +inserts the constraint `c`. +*/ + void push_back(const std::pair& c); -/*! -inserts a constraint whose endpoints are the vertices +/*! +inserts a constraint whose endpoints are the vertices pointed by `va` and `vb` in the triangulation. If the two vertex handles are equal no constraint is inserted, and the default constructed `Constraint_id` is returned. -*/ +*/ Constraint_id insert_constraint(Vertex_handle va, Vertex_handle vb); /*! @@ -262,7 +262,7 @@ When traversing the vertices of a closed polyline constraint with a `Vertices_i In case the range is empty `Constraint_id()`is returned. In case all points are equal the point is inserted but no constraint, and `Constraint_id()`is returned. -\tparam PointIterator must be an `InputIterator` with the value type `Point`. +\tparam PointIterator must be an `InputIterator` with the value type `Point`. */ template < class PointIterator> Constraint_id insert_constraint(PointIterator first, PointIterator last, bool close=false); @@ -293,7 +293,7 @@ std::size_t insert_constraints(PointIterator points_first, PointIterator points_ IndicesIterator indices_first, IndicesIterator indices_last); -/*! +/*! splits into constraints the graph of subconstraints. Consider the graph `g={V,E}` where `V` is the set of vertices of the @@ -314,115 +314,115 @@ omitted, a function always returning `false` will be used, that is no degree 2 vertex will be considered as a polyline endpoint. \sa `split_graph_into_polylines()` -*/ +*/ void split_subconstraint_graph_into_constraints(const std::function& is_terminal); - -/*! + +/*! removes the constraint `cid`, without removing the points from the triangulation. -*/ -void remove_constraint(Constraint_id cid); +*/ +void remove_constraint(Constraint_id cid); -/// @} +/// @} -/// \name Access +/// \name Access /// @{ -/*! -returns a `Constraint_iterator` that points at the first -constraint of the triangulation. -*/ -Constraint_iterator constraints_begin() const; +/*! +returns a `Constraint_iterator` that points at the first +constraint of the triangulation. +*/ +Constraint_iterator constraints_begin() const; -/*! -returns the past-the-end iterator of the constraints of the triangulation. -*/ -Constraint_iterator constraints_end() const; +/*! +returns the past-the-end iterator of the constraints of the triangulation. +*/ +Constraint_iterator constraints_end() const; /*! returns a range of constraints. -*/ -Subconstraints constraints() const; - -/*! -returns a `Subconstraint_iterator` pointing at the first -subconstraint of the triangulation. -*/ -Subconstraint_iterator subconstraints_begin() const; +*/ +Subconstraints constraints() const; -/*! -returns the past-the-end iterator of the subconstraints of the triangulation. -*/ -Subconstraint_iterator subconstraints_end() const; +/*! +returns a `Subconstraint_iterator` pointing at the first +subconstraint of the triangulation. +*/ +Subconstraint_iterator subconstraints_begin() const; + +/*! +returns the past-the-end iterator of the subconstraints of the triangulation. +*/ +Subconstraint_iterator subconstraints_end() const; /*! returns a range of subconstraints. -*/ -Subconstraints subconstraints() const; - -/*! -returns the number of constraints enclosing the subconstraint -`(va,vb)`. -\pre `va` and `vb` refer to the vertices of a constrained edge of the triangulation. -*/ -int number_of_enclosing_constraints(Vertex_handle va, -Vertex_handle vb) const; - -/*! -returns the `Context` relative to one of the constraints -enclosing the subconstraint `(va,vb)`. -\pre `va` and `vb` refer to the vertices of a constrained edge of the triangulation. -*/ -Context context(Vertex_handle va, Vertex_handle vb) const; - -/*! -returns an iterator pointing at the first `Context` -of the sequence of contexts -corresponding to the constraints enclosing the subconstraint `(va,vb)`. -\pre `va` and `vb` refer to the vertices of a constrained edge of the triangulation. -*/ -Context_iterator contexts_begin(Vertex_handle va, - Vertex_handle vb) const; +*/ +Subconstraints subconstraints() const; /*! -returns an iterator past the end `Context` +returns the number of constraints enclosing the subconstraint +`(va,vb)`. +\pre `va` and `vb` refer to the vertices of a constrained edge of the triangulation. +*/ +int number_of_enclosing_constraints(Vertex_handle va, +Vertex_handle vb) const; + +/*! +returns the `Context` relative to one of the constraints +enclosing the subconstraint `(va,vb)`. +\pre `va` and `vb` refer to the vertices of a constrained edge of the triangulation. +*/ +Context context(Vertex_handle va, Vertex_handle vb) const; + +/*! +returns an iterator pointing at the first `Context` of the sequence of contexts -corresponding to the constraints enclosing the subconstraint `(va,vb)`. -\pre `va` and `vb` refer to the vertices of a constrained edge of the triangulation. -*/ -Context_iterator contexts_end(Vertex_handle va, - Vertex_handle vb) const; +corresponding to the constraints enclosing the subconstraint `(va,vb)`. +\pre `va` and `vb` refer to the vertices of a constrained edge of the triangulation. +*/ +Context_iterator contexts_begin(Vertex_handle va, + Vertex_handle vb) const; + +/*! +returns an iterator past the end `Context` +of the sequence of contexts +corresponding to the constraints enclosing the subconstraint `(va,vb)`. +\pre `va` and `vb` refer to the vertices of a constrained edge of the triangulation. +*/ +Context_iterator contexts_end(Vertex_handle va, + Vertex_handle vb) const; /*! returns a range of contexts. */ -Contexts contexts(Vertex_handle va, - Vertex_handle vb) const; - -/*! -returns an iterator on the first vertex on the constraint `cid`. -*/ -Vertices_in_constraint_iterator -vertices_in_constraint_begin(Constraint_id cid) const; +Contexts contexts(Vertex_handle va, + Vertex_handle vb) const; /*! -returns an iterator past the last vertex on the constraint `cid`. -*/ -Vertices_in_constraint_iterator -vertices_in_constraint_end(Constraint_id cid) const; +returns an iterator on the first vertex on the constraint `cid`. +*/ +Vertices_in_constraint_iterator +vertices_in_constraint_begin(Constraint_id cid) const; /*! -returns a range of the vertices on the constraint `cid`. -*/ +returns an iterator past the last vertex on the constraint `cid`. +*/ +Vertices_in_constraint_iterator +vertices_in_constraint_end(Constraint_id cid) const; + +/*! +returns a range of the vertices on the constraint `cid`. +*/ Vertices_in_constraint -vertices_in_constraint(Constraint_id cid) const; +vertices_in_constraint(Constraint_id cid) const; /// @} /*! \name Polyline Simplification -\cgalAdvancedBegin +\cgalAdvancedBegin The polyline simplification algorithm described in Chapter -\ref Chapter_2D_Polyline_simplification +\ref Chapter_2D_Polyline_simplification operates on polyline constraints. The algorithm removes in each simplification step a vertex of a constraint and at the same time from the triangulation. @@ -430,16 +430,16 @@ The class `Constrained_triangulation_plus_2` stores for each constraint not only the sequence of vertices but also the original sequence of points at those vertices. As the `Vertices_in_constraint_iterator` enables the traversal of -the current set of vertices, the `Points_in_constraint_iterator` -enables the traversal of the points that were in the constraint +the current set of vertices, the `Points_in_constraint_iterator` +enables the traversal of the points that were in the constraint before the simplification algorithm started. -It enables the simplification algorithm to compute the error introduced by +It enables the simplification algorithm to compute the error introduced by each simplification step: it is the distance of the current sequence (vertices) to the original sequence (points). -Those stored points which do not correspond to a vertex can be removed +Those stored points which do not correspond to a vertex can be removed afterward either for a single constraint or for all constraints. The simplification algorithm uses the following types and functions. @@ -467,7 +467,7 @@ Returns an iterator to the first point on the constraint before any simplificati \cgalAdvancedEnd */ Points_in_constraint_iterator points_in_constraint_begin(Constraint_id cid) const; - + /*! \cgalAdvancedFunction \cgalAdvancedBegin @@ -485,7 +485,7 @@ of the constraint until `remove_points_without_corresponding_vertex(Constraint_i or `remove_points_without_corresponding_vertex()` is called. The polyline simplification algorithm described in Chapter -\ref Chapter_2D_Polyline_simplification +\ref Chapter_2D_Polyline_simplification operates on polyline constraints and applies `simplify()` to vertices in constraints based on a cost and stop function. @@ -529,20 +529,20 @@ remove_points_without_corresponding_vertex(); Writes the triangulation as for `Tr`, then writes one constraint per line, starting with the number of vertices and the indices of the vertices of the constraint. -\relates Constrained_triangulation_plus_2 +\relates Constrained_triangulation_plus_2 */ - + template std::ostream & operator<<(std::ostream& os, const Constrained_triangulation_plus_2 &ctp); - -/*! -Reads a triangulation from stream `is` and assigns it to the triangulation. -\relates Constrained_triangulation_plus_2 +/*! +Reads a triangulation from stream `is` and assigns it to the triangulation. + +\relates Constrained_triangulation_plus_2 */ template std::istream & operator>>(std::istream& is, Constrained_triangulation_plus_2 &ctp); - + } /* end namespace CGAL */ diff --git a/Triangulation_2/doc/Triangulation_2/Triangulation_2.txt b/Triangulation_2/doc/Triangulation_2/Triangulation_2.txt index 312b62eb8fb..90446677a4c 100644 --- a/Triangulation_2/doc/Triangulation_2/Triangulation_2.txt +++ b/Triangulation_2/doc/Triangulation_2/Triangulation_2.txt @@ -1,7 +1,7 @@ namespace CGAL { /*! -\mainpage User Manual +\mainpage User Manual \anchor Chapter_2D_Triangulations \cgalAutoToc @@ -11,16 +11,16 @@ namespace CGAL { \image latex tr1dt1.png This chapter describes the two dimensional triangulations -of \cgal. +of \cgal. Section \ref Section_2D_Triangulations_Definitions recalls the main definitions about triangulations. Section \ref Section_2D_Triangulations_Representation discusses the way two-dimensional triangulations are represented in \cgal. Section \ref Section_2D_Triangulations_Software_Design presents the overall software -design of the 2D triangulations package. +design of the 2D triangulations package. The next sections present the different two dimensional triangulations classes -available in \cgal: +available in \cgal: basic triangulations (Section \ref Section_2D_Triangulations_Basic), Delaunay triangulations (Section \ref Section_2D_Triangulations_Delaunay), @@ -33,18 +33,18 @@ and constrained Delaunay triangulations Section \ref Section_2D_Triangulations_Constrained_Plus describes a class which implements a constrained or constrained Delaunay triangulation with -an additional data structure -to describe how the constraints are refined +an additional data structure +to describe how the constraints are refined by the edges of the triangulations. Section \ref Section_2D_Triangulations_Hierarchy describes a hierarchical data structure for fast point location queries. -At last, Section \ref Section_2D_Triangulations_Flexibility -explains how the user can benefit from the flexibility +At last, Section \ref Section_2D_Triangulations_Flexibility +explains how the user can benefit from the flexibility of \cgal triangulations using customized classes for faces and vertices. -\section Section_2D_Triangulations_Definitions Definitions +\section Section_2D_Triangulations_Definitions Definitions A two dimensional triangulation can be roughly described as a set \f$ T\f$ of triangular facets such that: @@ -52,40 +52,40 @@ of triangular facets such that: - two facets either are disjoint or share a lower dimensional face (edge or vertex). -- the set of facets in \f$ T\f$ is connected for the adjacency relation. +- the set of facets in \f$ T\f$ is connected for the adjacency relation. - the domain \f$ U_T\f$ which is the union of facets in \f$ T\f$ has no singularity. -More precisely, a triangulation can be described +More precisely, a triangulation can be described as a simplicial complex. Let us first record a few definitions. -A simplicial complex is a set \f$ T\f$ of simplices such that +A simplicial complex is a set \f$ T\f$ of simplices such that -- any face of a simplex in \f$ T\f$ is a simplex in \f$ T\f$ +- any face of a simplex in \f$ T\f$ is a simplex in \f$ T\f$ - two simplices in \f$ T\f$ either are disjoint or share a common sub-face. -The dimension \f$ d\f$ of a simplicial complex is the -maximal dimension of its simplices. +The dimension \f$ d\f$ of a simplicial complex is the +maximal dimension of its simplices. A simplicial complex \f$ T\f$ is pure if any simplex of \f$ T\f$ -is included in a simplex of \f$ T\f$ with maximal dimension. +is included in a simplex of \f$ T\f$ with maximal dimension. Two simplexes in \f$ T\f$ with maximal dimension \f$ d\f$ are said to be adjacent if they share a \f$ d-1\f$ dimensional sub-face. A simplicial complex is connected if the adjacency relation -defines a connected graph -over the set of simplices of \f$ T\f$ with maximal dimension. +defines a connected graph +over the set of simplices of \f$ T\f$ with maximal dimension. The union \f$ U_T\f$ of all simplices in \f$ T\f$ is called the domain of \f$ T\f$. -A point \f$ p\f$ in the domain of \f$ T\f$ is said to singular +A point \f$ p\f$ in the domain of \f$ T\f$ is said to singular if its surrounding in \f$ U_T\f$ is neither a topological ball nor a topological disc. -Then, a two dimensional triangulation can be described as a +Then, a two dimensional triangulation can be described as a two dimensional simplicial complex that is pure, connected and without singularity. @@ -94,14 +94,14 @@ which in turn induces an orientation on the edges incident to that facet. The orientation of two adjacent facets are said to be consistent if they induce opposite orientations on their common incident edge. -A triangulation is said to be orientable if +A triangulation is said to be orientable if the orientation of each facet can be chosen in such a way that all pairs of incident facets have consistent orientations. The data structure underlying \cgal triangulations -allows the user to represent the combinatorics of +allows the user to represent the combinatorics of any orientable two dimensional triangulations -without boundaries. +without boundaries. On top of this data structure, the 2D triangulations classes take care of the geometric embedding of the triangulation and are designed to handle planar triangulations. @@ -114,32 +114,32 @@ convex hull of their vertices. Because any planar triangulation can be completed, this is not a real restriction. For instance, a triangulation of a polygonal region can be -constructed and represented as a subset of a constrained triangulation -in which the region boundary edges have been input as +constructed and represented as a subset of a constrained triangulation +in which the region boundary edges have been input as constrained edges (see Section \ref Section_2D_Triangulations_Constrained, -\ref Section_2D_Triangulations_Constrained_Delaunay and +\ref Section_2D_Triangulations_Constrained_Delaunay and \ref Section_2D_Triangulations_Constrained_Plus). Strictly speaking, the term face should be used to design a face of any dimension, -and the two-dimensional faces of a triangulation +and the two-dimensional faces of a triangulation should be properly called facets. However, following a common usage, we hereafter often call faces, the facets of a two dimensional triangulation. -\section Section_2D_Triangulations_Representation Representation +\section Section_2D_Triangulations_Representation Representation \subsection Triangulation_2TheSetofFaces The Set of Faces -A 2D triangulation of \cgal can be viewed as a planar partition +A 2D triangulation of \cgal can be viewed as a planar partition whose bounded faces are triangular and cover -the convex hull of the set of vertices. +the convex hull of the set of vertices. The single unbounded face of this partition -is the complementary of the convex hull. +is the complementary of the convex hull. In many applications, such as Kirkpatrick's hierarchy or incremental Delaunay construction, it is convenient to -deal with only triangular faces. Therefore, +deal with only triangular faces. Therefore, a fictitious vertex, called the *infinite vertex* is added to the triangulation as well as *infinite edges* and *infinite faces* incident to it. @@ -155,7 +155,7 @@ equivalent to a two-dimensional sphere. This extends to lower dimensional triangulations arising in degenerate cases or when the triangulations as less than three vertices. -Including the infinite faces, +Including the infinite faces, a one dimensional triangulation is a ring of edges and vertices topologically equivalent to a \f$ 1\f$-sphere. @@ -185,16 +185,16 @@ saves storage space and results in faster algorithms \cgalCite{bdty-tcgal-00}. The basic elements of the representation are vertices and faces. -Each triangular face gives access to its three incident vertices -and to its three adjacent faces. +Each triangular face gives access to its three incident vertices +and to its three adjacent faces. Each vertex gives access to one of its incident faces and through that face to the circular list of its incident faces. The three vertices of a face are indexed with 0, 1 and 2 -in counterclockwise order. The neighbors of a face are also +in counterclockwise order. The neighbors of a face are also indexed with 0,1,2 in such a way that the neighbor indexed by `i` is opposite to the vertex with the same index. -See \cgalFigureRef{Triangulation_2D_Fig_neighbors1}, +See \cgalFigureRef{Triangulation_2D_Fig_neighbors1}, the functions `ccw(i)` and `cw(i)` shown on this figure compute respectively \f$ i+1\f$ and \f$ i-1\f$ modulo 3. @@ -203,21 +203,21 @@ The edges are not explicitly represented, they are only implicitly represented through the adjacency relations of two faces. Each edge has two implicit representations: the edge of a face `f` which is opposed to the vertex indexed `i`, -can be represented as well as an edge of the `neighbor(i)` of +can be represented as well as an edge of the `neighbor(i)` of `f`. \cgalFigureBegin{Triangulation_2D_Fig_neighbors1,rep_bis.png} Vertices and neighbors. \cgalFigureEnd -\section Section_2D_Triangulations_Software_Design Software Design +\section Section_2D_Triangulations_Software_Design Software Design -The triangulations classes of \cgal +The triangulations classes of \cgal provide high-level geometric functionalities such as location of a point in the triangulation, insertion, removal, or displacement of a point. They are build as a layer on top of a data structure called the triangulation data structure. -The triangulation data structure can be thought +The triangulation data structure can be thought of as a container for the faces and vertices of the triangulation. This data structure also takes care of all the combinatorial aspects of the triangulation. @@ -229,8 +229,8 @@ that the triangulation classes have two template parameters:

  • the first parameter stands for a -geometric traits class providing -the geometric primitives (points, segments and triangles) +geometric traits class providing +the geometric primitives (points, segments and triangles) of the triangulation and the elementary operations (predicate or constructions) on those objects. @@ -249,14 +249,14 @@ as a default model of triangulation data structure. The class `Triangulation_data_structure_2` has two template parameters standing for a vertex class and a face class. -\cgal defines concepts +\cgal defines concepts for these template parameters and provide default models for these concepts. The vertex and base classes are templated by the geometric traits class which enables them to obtain some knowledge of the geometric -primitives of the triangulation. +primitives of the triangulation. Those default vertex and face base classes -can be replaced by +can be replaced by user customized base classes in order, for example, to deal with additional properties attached to the vertices or faces of a triangulation. See Section \ref Section_2D_Triangulations_Flexibility @@ -272,58 +272,58 @@ forming this design. The triangulations software design. \cgalFigureEnd -The top triangulation level, responsible for the geometric -embedding of the triangulation comes in different flavors +The top triangulation level, responsible for the geometric +embedding of the triangulation comes in different flavors according to the different kind of triangulations: basic, Delaunay, regular, constrained or constrained Delaunay. Each kind of triangulations correspond to a different -class. +class. \cgalFigureRef{Triangulation_2D_Fig_derivation_tree} summarizes the derivation dependencies of \cgal 2D triangulations classes. Any 2D triangulation class is parametrized by a geometric traits class and a triangulation data structure. While a unique concept `TriangulationDataStructure_2` describes the triangulation data structure requirements -for any triangulation class, +for any triangulation class, the requirements on the geometric traits class actually depend on the triangulation class. -In general, the requirements for the vertex and face base classes +In general, the requirements for the vertex and face base classes are described by the basic concepts `TriangulationVertexBase_2` and `TriangulationFaceBase_2`. However, some triangulation classes require base classes implementing -refinements +refinements of the basic concepts. \cgalFigureBegin{Triangulation_2D_Fig_derivation_tree,derivation_tree.png} The derivation tree of 2D triangulations. \cgalFigureEnd -\section Section_2D_Triangulations_Basic Basic Triangulations +\section Section_2D_Triangulations_Basic Basic Triangulations -\subsection Subsection_2D_Triangulations_Basic_Description Description +\subsection Subsection_2D_Triangulations_Basic_Description Description The class `Triangulation_2` serves as a base class for the other 2D triangulations classes -and +and implements the user interface to a triangulation. -The vertices and faces of the triangulations are accessed through +The vertices and faces of the triangulations are accessed through `handles`, `iterators` and `circulators`. A handle is a model of the concept `Handle` which basically offers the two dereference operators `*` and `->`. A circulator is a type devoted to visit circular sequences. -Handles are used whenever the accessed element +Handles are used whenever the accessed element is not part of a sequence. Iterators and circulators are used to visit all or parts of the triangulation. The iterators and circulators are all bidirectional and non mutable. -The circulators and iterators are convertible to the -handles with the same value type, so that +The circulators and iterators are convertible to the +handles with the same value type, so that when calling a member function, any handle type argument can be replaced by an iterator or a circulator @@ -332,18 +332,18 @@ with the same value type. The triangulation class provides a function to visit the vertices and neighbors of a face in clockwise or counterclockwise order. -There are circulators -to visit the edges or faces -incident to a given vertex or the vertices +There are circulators +to visit the edges or faces +incident to a given vertex or the vertices adjacent to it. Another circulator type enables the visit of all the faces traversed by a given line. -Circulators step through infinite features as well as +Circulators step through infinite features as well as through finite ones. -The triangulation class offers -some iterators to visit all the -faces, edges or vertices and also iterators to visit +The triangulation class offers +some iterators to visit all the +faces, edges or vertices and also iterators to visit selectively the finite faces, edges or vertices. @@ -356,7 +356,7 @@ The triangulation class provides a method to locate a given point with respect to a triangulation. In particular, this method reports whether the point coincides with a vertex of the triangulation, lies on an edge, -in a face or outside of the convex hull. In case of a degenerate +in a face or outside of the convex hull. In case of a degenerate lower dimensional triangulation, the query point may also lie outside the triangulation affine hull. @@ -364,7 +364,7 @@ The triangulation class also provides methods to locate a point with respect to a given finite face of the triangulation or with respect to its circumcircle. -The faces of the triangulation and their circumcircles +The faces of the triangulation and their circumcircles have the counterclockwise orientation. The triangulation can be modified by several functions: @@ -405,7 +405,7 @@ if no optional argument is given. It takes time \f$ O(n)\f$ in the worst case for Delaunay Triangulations, but only \f$ O(\sqrt{n})\f$ on average if the vertices are distributed uniformly at random. The class `Triangulation_hierarchy_2`, -described in section \ref Section_2D_Triangulations_Hierarchy, +described in section \ref Section_2D_Triangulations_Hierarchy, implements a data structure designed to offer an alternate more efficient point location algorithm. @@ -423,7 +423,7 @@ re-triangulating the hole. Removal takes a time at most proportional to which is \f$ O(1)\f$ for a random vertex. Displacement of a vertex is done by: first, verifying if the triangulation embedding -remains planar after the displacement; if yes the vertex is directly placed at the new location; otherwise, a point is inserted at the new location +remains planar after the displacement; if yes the vertex is directly placed at the new location; otherwise, a point is inserted at the new location and the vertex at the obsolete location is removed. The face, edge, and vertex iterators on finite features @@ -431,36 +431,36 @@ are derived from their counterparts visiting all (finite and infinite) features which are themselves derived from the corresponding iterators of the triangulation data structure. -\subsection Subsubsection_2D_Triangulation_Basic_Geometric_Traits Geometric Traits +\subsection Subsubsection_2D_Triangulation_Basic_Geometric_Traits Geometric Traits -The geometric traits class of a triangulation +The geometric traits class of a triangulation is required to provide the geometric objects (points, segments and triangles) building up the triangulation together with the geometric predicates on those objects. -The required predicates are: +The required predicates are: - comparison of the `x` or `y` coordinates of two points. -- the orientation test which computes +- the orientation test which computes the order type of three given point. The concept -`TriangulationTraits_2` describes the requirements for the +`TriangulationTraits_2` describes the requirements for the geometric traits class of a triangulation. -The \cgal kernel classes +The \cgal kernel classes are models for this concept. The \cgal library also provides dedicated models -of `TriangulationTraits_2` +of `TriangulationTraits_2` using the kernel geometric objects and predicates. These classes are themselves templated with a \cgal kernel and extract the required types and predicates from the kernel. -The class `Projection_traits_xy_3` +The class `Projection_traits_xy_3` is a geometric traits class to build the triangulation of a terrain. Such a triangulation is a two-dimensional triangulation embedded in three dimensional space. The data points are three-dimensional points. -The triangulation is +The triangulation is build according to the projections of those points on the \f$ xy\f$ plane and then lifted up to the original three-dimensional data points. @@ -479,15 +479,15 @@ deal with projections on the `yz` plane and `xz`-plane, respectively. -\subsection Subsection_2D_Triangulations_Basic_Example Example of a Basic Triangulation +\subsection Subsection_2D_Triangulations_Basic_Example Example of a Basic Triangulation The following program creates a triangulation of 2D points -using the default kernel +using the default kernel `Exact_predicate_inexact_constructions_kernel` as geometric traits class and the default triangulation data structure. -The input points are read from a file +The input points are read from a file and inserted in the triangulation. -Finally points on the convex hull are written to cout. +Finally points on the convex hull are written to cout. \cgalExample{Triangulation_2/triangulation_prog1.cpp} \subsection Triangulation2Draw Draw a 2D Triangulation @@ -503,17 +503,17 @@ This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASI Result of the run of the draw_triangulation_2 program. A window shows the 2D triangulation and allows to navigate through the scene. \cgalFigureEnd -\section Section_2D_Triangulations_Delaunay Delaunay Triangulations +\section Section_2D_Triangulations_Delaunay Delaunay Triangulations -\subsection Subsection_2D_Triangulations_Delaunay_Description Description +\subsection Subsection_2D_Triangulations_Delaunay_Description Description The class `Delaunay_triangulation_2` is designed to represent the Delaunay triangulation of a set of data points in the plane. A Delaunay triangulation fulfills -the following empty circle property +the following empty circle property (also called Delaunay property): the circumscribing -circle of any facet of the triangulation +circle of any facet of the triangulation contains no data point in its interior. For a point set with no subset of four co-circular points the Delaunay triangulation is unique, it is dual @@ -523,7 +523,7 @@ The class `Delaunay_triangulation_2` derives from the class `Triangulation_2`. The class `Delaunay_triangulation_2` -inherits the types defined by the +inherits the types defined by the basic class `Triangulation_2`. Additional types, provided by the traits class, are defined to represent the dual Voronoi diagram. @@ -536,7 +536,7 @@ to answer nearest neighbor queries and member functions to construct the elements (vertices and edges) of the dual Voronoi diagram. -Geometric Traits +Geometric Traits -------------- The geometric traits class has to be a model of the concept @@ -546,43 +546,43 @@ In particular this concept provides the `side_of_oriented_circle` predicate which, given four points `p,q,r,s` decides the position of the point \f$ s\f$ with respect to the circle -passing through \f$ p\f$, \f$ q\f$ and \f$ r\f$. +passing through \f$ p\f$, \f$ q\f$ and \f$ r\f$. The `side_of_oriented_circle` predicate actually defines the Delaunay triangulation. -Changing this predicate +Changing this predicate allows the user to build variant of Delaunay triangulations for different metrics such that \f$ L_1\f$ or \f$ L_{\infty}\f$ metric or any metric defined by a convex object. However, the user of an exotic metric -must be careful that the constructed triangulation +must be careful that the constructed triangulation has to be a triangulation of the convex hull which means that convex hull edges have to be Delaunay edges. This is granted for any smooth convex metric (like \f$ L_2\f$) and can be ensured for other metrics (like \f$ L_{\infty}\f$) by the addition to the point set of well chosen sentinel points. -The \cgal kernel classes +The \cgal kernel classes are models of the concept `DelaunayTriangulationTraits_2` for the Euclidean metric. The traits class for terrains, `Projection_traits_xy_3`, `Projection_traits_yz_3`, and -`Projection_traits_xz_3` +`Projection_traits_xz_3` are also models of `DelaunayTriangulationTraits_2` except that they do not fulfill the requirements for the duality functions and nearest vertex queries. -Implementation +Implementation -------------- The insertion of a new point in the Delaunay triangulation is performed using first the insertion member function -of the basic triangulation and second -performing a sequence of flips to restore the Delaunay property. +of the basic triangulation and second +performing a sequence of flips to restore the Delaunay property. The number of flips that have to be performed is \f$ O(d)\f$ if the new vertex has degree \f$ d\f$ in the updated Delaunay triangulation. For -points distributed uniformly at random, +points distributed uniformly at random, each insertion takes time \f$ O(1)\f$ on average, once the point has been located in the triangulation. @@ -598,9 +598,9 @@ for random points \cgalCite{d-vrtdd-09}. The displacement of a vertex \f$ v\f$ at a point \f$ p\f$ to a new location \f$ p'\f$, first checks whether the triangulation embedding remains planar or not after moving \f$ v\f$ to \f$ p'\f$. If yes, it moves \f$ v\f$ to \f$ p'\f$ and simply performs a sequence of flips -to restore the Delaunay property, which is \f$ O(d)\f$ where \f$ d\f$ is the degree of the vertex after the displacement. +to restore the Delaunay property, which is \f$ O(d)\f$ where \f$ d\f$ is the degree of the vertex after the displacement. Otherwise, the displacement is done by inserting a vertex at the new location, -and removing the obsolete vertex. +and removing the obsolete vertex. The complexity is \f$ O(n)\f$ in the worst case, but only \f$ O(1 + \delta \sqrt{n})\f$ for evenly distributed vertices in the unit square, where \f$ \delta\f$ is the Euclidean distance between the new and old locations. After having performed a point location, the @@ -608,20 +608,20 @@ nearest neighbor of a point is found in time \f$ O(n)\f$ in the worst case, but in time \f$ O(1)\f$ for vertices distributed uniformly at random and any query point. -\subsection Subsection_2D_Triangulations_Delaunay_Terrain Example: a Delaunay Terrain +\subsection Subsection_2D_Triangulations_Delaunay_Terrain Example: a Delaunay Terrain -The following code creates a Delaunay triangulation with -the usual Euclidean metric for the vertical projection of a +The following code creates a Delaunay triangulation with +the usual Euclidean metric for the vertical projection of a terrain model. The points have elevation, that is they are 3D points, but the predicates used to build the Delaunay triangulation -are computed using only the \f$ x\f$ and \f$ y\f$ coordinates +are computed using only the \f$ x\f$ and \f$ y\f$ coordinates of these points. The class `Projection_traits_xy_3` is part of the 2D and 3D Linear Geometric Kernel. \cgalExample{Triangulation_2/terrain.cpp} -\subsection Subsection_2D_Triangulations_Voronoi Example: Voronoi Diagram +\subsection Subsection_2D_Triangulations_Voronoi Example: Voronoi Diagram The following code computes the edges of Voronoi diagram of a set of data points @@ -629,9 +629,9 @@ and counts the number of finite edges and the number of rays of this diagram \cgalExample{Triangulation_2/voronoi.cpp} -\subsection Subsection_2D_Triangulations_Cropped_Voronoi Example: Print Voronoi Diagram Edges Restricted to a Rectangle +\subsection Subsection_2D_Triangulations_Cropped_Voronoi Example: Print Voronoi Diagram Edges Restricted to a Rectangle -The following code computes the Delaunay triangulation of a set of points and prints the Voronoi edges +The following code computes the Delaunay triangulation of a set of points and prints the Voronoi edges restricted to a given rectangle. \cgalFigureBegin{figurecropped_voronoi,cropped_voronoi.png} @@ -640,11 +640,11 @@ Voronoi diagram (in red) of the black points restricted to the blue rectangle. \cgalExample{Triangulation_2/print_cropped_voronoi.cpp} -\section Section_2D_Triangulations_Regular Regular Triangulations +\section Section_2D_Triangulations_Regular Regular Triangulations -\subsection Subsection_2D_Triangulations_Regular_Description Description +\subsection Subsection_2D_Triangulations_Regular_Description Description -Let \f$ { PW} = \{(p_i, w_i) | i = 1, \ldots , n \}\f$ be a set of +Let \f$ { PW} = \{(p_i, w_i) | i = 1, \ldots , n \}\f$ be a set of weighted points where each \f$ p_i\f$ is a point and each \f$ w_i\f$ is a scalar called the weight of point \f$ p_i\f$. Alternatively, each weighted point \f$ (p_i, w_i)\f$ can be regarded @@ -654,18 +654,18 @@ of \f$ p_i\f$) with center \f$ p_i\f$ and radius \f$ r_i=\sqrt{w_i}\f$. The power diagram of the set \f$ { PW}\f$ is a space partition in which each cell corresponds to a sphere \f$ (p_i, w_i)\f$ of \f$ { PW}\f$ and is the locus of points \f$ p\f$ whose power with respect to \f$ (p_i, w_i)\f$ -is less than its power with respect to any other sphere +is less than its power with respect to any other sphere in \f$ { PW}\f$. In the two-dimensional space, -the dual of this diagram is a triangulation -whose domain covers the convex hull of the set +the dual of this diagram is a triangulation +whose domain covers the convex hull of the set \f$ { P}= \{ p_i | i = 1, \ldots , n \}\f$ of center points and whose vertices form a subset of \f$ { P}\f$. Such a triangulation is called a regular triangulation. Three points \f$ p_i, p_j\f$ and \f$ p_k\f$ of \f$ { P}\f$ form a triangle in the regular triangulation of \f$ { PW}\f$ -iff there is a point \f$ p\f$ of the plane with equal +iff there is a point \f$ p\f$ of the plane with equal powers with respect to \f$ (p_i, w_i)\f$, \f$ (p_j, w_j)\f$ -and \f$ (p_k, w_k)\f$ and such that this power +and \f$ (p_k, w_k)\f$ and such that this power is less than the power of \f$ p\f$ with respect to any other sphere in \f$ { PW}\f$. @@ -673,7 +673,7 @@ Let us defined the power product of two weighted points \f$ (p_i, w_i)\f$ and \f$ (p_j, w_j)\f$ as: \f[ \Pi(p_i, w_i, p_j, w_j) = p_ip_j ^2 - w_i - w_j . \f] \f$ \Pi(p_i, w_i, p_j, 0)\f$ is simply the power of point \f$ p_j\f$ -with respect to the sphere \f$ (p_i, w_i)\f$, and two weighted points +with respect to the sphere \f$ (p_i, w_i)\f$, and two weighted points are said to be orthogonal if their power product is null. The power circle of three weighted points \f$ (p_i, w_i)\f$, \f$ (p_j, w_j)\f$ @@ -683,7 +683,7 @@ and \f$ (p_k, w_k)\f$ is defined as the unique circle and \f$ (p_k, w_k)\f$. The regular triangulation of the sets \f$ { PW}\f$ -satisfies the following regular property (which just reduces to the +satisfies the following regular property (which just reduces to the Delaunay property when all the weights are null): a triangle \f$ p_ip_jp_k\f$ is a face of the regular triangulation of \f$ { PW}\f$ iff the power product of any weighted point @@ -691,7 +691,7 @@ of \f$ { PW}\f$ iff the power product of any weighted point \f$ (p_i, w_i)\f$, \f$ (p_j, w_j)\f$ and \f$ (p_k, w_k)\f$ is positive or null. We call power test of \f$ (p_i, w_i)\f$, \f$ (p_j, w_j)\f$, \f$ (p_k, w_k)\f$, and \f$ (p_l, w_l)\f$, the predicates which amount to compute -the sign of +the sign of the power product of \f$ (p_l, w_l)\f$ with respect to the power circle of \f$ (p_i, w_i)\f$, \f$ (p_j, w_j)\f$ and \f$ (p_k, w_k)\f$. @@ -722,18 +722,18 @@ Alternatively, the regular triangulation of the weighted points set \f$ { PW}\f$ can be obtained as the projection on the two dimensional plane of the convex hull of the set of three -dimensional points +dimensional points \f$ { P'}= \{ (p_i,p_i ^2 - w_i ) | i = 1, \ldots , n \}\f$. The class `Regular_triangulation_2` is designed to maintain the regular triangulation of a set of \f$ 2d\f$ weighted points. It derives from the class `Triangulation_2`. -The functions `insert` and +The functions `insert` and `remove` are overwritten to handle weighted points and maintain the regular property. -The function `move()` is not +The function `move()` is not overwritten and thus does not preserve the regular property. The vertices of the regular triangulation of a set of weighted points \f$ {PW}\f$ correspond only to a subset @@ -745,14 +745,14 @@ triangulation. Such a point is called a hidden point. Because hidden points can reappear later on as vertices when some other point is removed, -they have to be stored somewhere. +they have to be stored somewhere. The regular triangulation store those points in special vertices, called -hidden vertices. +hidden vertices. A hidden point can reappear as vertex of the triangulation only when the two dimensional face that hides it is removed from the triangulation. To deal with this feature, each face of a regular triangulation stores a list of hidden vertices. -The points in those vertices +The points in those vertices are reinserted in the triangulation when the face is removed. @@ -764,7 +764,7 @@ the vertices and edges of the dual power diagrams. The geometric traits class of a regular triangulation must provide a weighted point type and a power test on these weighted points. -The concept +The concept `RegularTriangulationTraits_2`, is a refinement of the concept `TriangulationTraits_2`. All \cgal kernels are a model for the traits concept @@ -778,31 +778,31 @@ includes a Boolean data member to mark the hidden state of the vertex. Therefore \cgal defines the concept `RegularTriangulationVertexBase_2` which refine the concept `TriangulationVertexBase_2` -and provides a default model +and provides a default model for this concept. The face base type of a regular triangulation is required to provide a list of hidden vertices, designed to store the points hidden by the face. It has to be a model of the concept `RegularTriangulationFaceBase_2`. -\cgal provides the templated class +\cgal provides the templated class `Regular_triangulation_face_base_2` as a default base class for faces of regular triangulations. -\subsection Subsection_2D_Triangulations_Regular_Example Example: a Regular Triangulation +\subsection Subsection_2D_Triangulations_Regular_Example Example: a Regular Triangulation -The following code creates a regular triangulation +The following code creates a regular triangulation of a set of weighted points and output the number of vertices and the number of hidden vertices. \cgalExample{Triangulation_2/regular.cpp} -\section Section_2D_Triangulations_Constrained Constrained Triangulations +\section Section_2D_Triangulations_Constrained Constrained Triangulations A constrained triangulation is a triangulation of a set of points -that has to include among its edges +that has to include among its edges a given set of polylines joining the points. The -polylines are called *constraints*. The corresponding +polylines are called *constraints*. The corresponding edges are called *constrained edges*. The endpoints of constrained edges are of course vertices of the @@ -810,8 +810,8 @@ triangulation. However, the triangulation may include other vertices as well. There are three versions of constrained triangulations.
      -
    • In the basic version, the constrained triangulation -does not handle intersecting constraints, and the set of input +
    • In the basic version, the constrained triangulation +does not handle intersecting constraints, and the set of input constraints is required to be a set of segments that do not intersect, except possibly at their endpoints. Any number of constrained edges may share the same endpoint. Constrained edges may be vertical or @@ -820,7 +820,7 @@ have zero length. In those versions, input constraints may consist of intersecting, overlapping or partially overlapping segments. The triangulation introduces additional vertices at each point that -is the proper intersection point of two +is the proper intersection point of two constraints. A single constraint intersecting other constraints will then appear as several constrained edges in the triangulation. There are two ways to deal with intersecting constraints. @@ -861,10 +861,10 @@ from a list of pairs of points which represent the constraints. The class `Constrained_triangulation_2` overrides the insertion and removal of a point to take care of the -information about constrained edges. The class also allows the user +information about constrained edges. The class also allows the user online insertion of a new constraint, given as sequence of points, or the removal of a constraint. -In the current version, the function `move()` is not +In the current version, the function `move()` is not overwritten and thus does not handle vertices of constraints. In order to retrieve the constrained edges of a constraint, or @@ -880,8 +880,8 @@ as it avoids the cascading of intersection computations. The geometric traits class of a constraint triangulation has to be a model of the concept `TriangulationTraits_2`. -When intersections of input constraints are supported, -the geometric traits class has to be a model +When intersections of input constraints are supported, +the geometric traits class has to be a model of the concept `ConstrainedTriangulationTraits_2`, which refines the concept `TriangulationTraits_2` providing additional function object types @@ -889,7 +889,7 @@ to compute the intersection of two segments. \subsection Triangulation_2TheFaceBaseClassofaConstrained The Face Base Class of a Constrained Triangulation -The information about constrained edges is stored in the +The information about constrained edges is stored in the faces of the triangulation. The face base of a Constrained Triangulation has to be a model for the concept `ConstrainedTriangulationFaceBase_2` which refines the concept `TriangulationFaceBase_2`. @@ -909,7 +909,7 @@ Constrained and Constrained Delaunay triangulation: the constraining edges are t \cgalFigureEnd -\section Section_2D_Triangulations_Constrained_Delaunay Constrained Delaunay Triangulations +\section Section_2D_Triangulations_Constrained_Delaunay Constrained Delaunay Triangulations A constrained Delaunay triangulation is a triangulation with constrained edges which try to be as much Delaunay as possible. @@ -919,16 +919,16 @@ necessarily fulfill the empty circle property but they fulfill a weaker *constrained empty circle property*. To state this property, it is convenient to think of constrained -edges as blocking the view. Then, a triangulation is +edges as blocking the view. Then, a triangulation is constrained Delaunay iff the circumscribing circle -of any facet encloses +of any facet encloses no vertex visible from the interior of the facet. As in the case of constrained triangulations, three different versions of Delaunay constrained triangulations are provided. The first version handles a set of constraints which do not intersect except possibly -at the endpoints. The two other versions +at the endpoints. The two other versions handle intersecting input constraints. One of them is designed to be robust when used in conjunction with a geometric traits class @@ -942,7 +942,7 @@ The \cgal class is designed to represent constrained Delaunay triangulations. -As in the case of constrained triangulations, the third parameter +As in the case of constrained triangulations, the third parameter `Itag` is the intersection tag and serves to choose how intersecting constraints are dealt with. It can be instantiated with one of the following @@ -958,7 +958,7 @@ derives from the class `Constrained_triangulation_2`. The constrained Delaunay triangulation -has member functions to override the +has member functions to override the insertion and removal of a point or of a constraint. Each of those member functions takes care to restore @@ -967,13 +967,13 @@ property. \subsection Triangulation_2TheGeometricTraits_2 The Geometric Traits -The geometric traits class +The geometric traits class of a constrained Delaunay triangulation is required to provide the `side_of_oriented_circle` predicate as the geometric traits class of a Delaunay triangulation, and has to be a model of the concept `DelaunayTriangulationTraits_2`. When intersecting input constraints -is supported, the geometric traits class is further required +is supported, the geometric traits class is further required to provide function objects to compute constraints intersections. Then, the geometric traits class has to be at the same time a model of the concept `ConstrainedTriangulationTraits_2`. @@ -987,19 +987,19 @@ and the face base class of a constrained Delaunay triangulation has to be a model of `ConstrainedTriangulationFaceBase_2`. -\subsection Subsection_2D_Triangulations_Constrained_Delaunay_Example Example: a Constrained Delaunay Triangulation +\subsection Subsection_2D_Triangulations_Constrained_Delaunay_Example Example: a Constrained Delaunay Triangulation The following code inserts a set of intersecting constraint segments -into a triangulation +into a triangulation and counts the number of constrained edges of the resulting triangulation. \cgalExample{Triangulation_2/constrained.cpp} -\subsection Subsection_2D_Triangulations_Polygon_triangulation Example: Triangulating a Polygonal Domain +\subsection Subsection_2D_Triangulations_Polygon_triangulation Example: Triangulating a Polygonal Domain The following code inserts two nested polygons into a constrained Delaunay triangulation and counts the number of facets that -are inside the domain delimited by these polygons. Note that the following code does not work if the +are inside the domain delimited by these polygons. Note that the following code does not work if the boundaries of the polygons intersect. \cgalFigureBegin{figuretri_domain,tri_domain.png} @@ -1012,7 +1012,7 @@ Triangulation (in blue) of the domain delimited by the red polygons. The class `Constrained_triangulation_plus_2` provides a constrained triangulation with an additional data -structure +structure that keeps track of the input constraints and of their refinement in the triangulation. The class `Constrained_triangulation_plus_2` @@ -1047,7 +1047,7 @@ For a pair `(fh,i)` it is the edge of the face `*fh`, which is opposite to the ` A constrained edge `e` is an edge of a constrained triangulation `ct`, for which `ct.is_constrained(e)` returns `true`. A constraint is a polyline which is given as input (in the simplest case just a segment), and -which is split into constrained edges in the triangulation. +which is split into constrained edges in the triangulation. The type `Subconstraint` is defined as `typedef std::pair Subconstraint`. The two vertex handles must be the vertices of a constrained edge. @@ -1061,7 +1061,7 @@ and offer a `Constrained_edges_iterator`. The class `Constrained_triangulation_plus_2` additionally provides the means to - traverse all the constraints of the triangulation using an iterator of type `Constraint_iterator` the value type of which is `Constraint_id`, - obtain all constraints that induce a constrained edge or a subconstraint, -- traverse the sequence of vertices of a constraint using an iterator of type `Vertices_in_constraint_iterator`, the value type of which is `Vertex_handle` +- traverse the sequence of vertices of a constraint using an iterator of type `Vertices_in_constraint_iterator`, the value type of which is `Vertex_handle` - traverse the subconstraints in the triangulation using an iterator of type `Subconstraint_iterator`, the value type of which is `Subconstraint`. Note that the `Constrained_edges_iterator` and the `Subconstraint_iterator` are quite similar. @@ -1108,8 +1108,8 @@ define an input segment that induce `e`. The following code inserts two polyline constraints into a triangulation. Note that if the triangulation supports intersections we can have arbitrary complicated overlapping polylines. They can share -any number of edges, and a polyline may pass several times through -the same edge. +any number of edges, and a polyline may pass several times through +the same edge. @@ -1117,7 +1117,7 @@ For an edge we can further find out how many and which polyline constraints pass through it. For an edge we can obtain an iterator range with value type `Constrained_triangulation_plus_2::Context`. From a context we can obtain the `Constrained_triangulation_plus_2::Constraint_id`, and an iterator -pointing at the vertex in the polyline constraint that passes +pointing at the vertex in the polyline constraint that passes through the edge. @@ -1140,14 +1140,14 @@ constraints in a `Constrained_triangulation_plus_2`: \cgalExample{Triangulation_2/segment_soup_to_polylines.cpp} -\section Section_2D_Triangulations_Hierarchy The Triangulation Hierarchy +\section Section_2D_Triangulations_Hierarchy The Triangulation Hierarchy The class `Triangulation_hierarchy_2` implements a triangulation augmented with a data structure to efficiently answer point location queries. -The data structure is a hierarchy +The data structure is a hierarchy of triangulations. The triangulation at the lowest level is -the original triangulation where operations and point location are to +the original triangulation where operations and point location are to be performed. Then at each succeeding level, the data structure stores a triangulation of a small random sample of the vertices @@ -1160,7 +1160,7 @@ is found through a linear walk performed from the nearest neighbor found at the preceding level. Because the number of vertices in each triangulation is only a small fraction of the number of vertices of the preceding triangulation, -the data structure remains small and achieves fast point location +the data structure remains small and achieves fast point location queries on real data. As proved in \cgalCite{d-iirdt-98}, this structure has an optimal behavior when it is built for Delaunay triangulations. @@ -1170,7 +1170,7 @@ which is to be instantiated by one of the \cgal triangulation classes. The class `Triangulation_hierarchy_2` inherits from the -triangulation type passed as template parameter `Tr`. +triangulation type passed as template parameter `Tr`. The `insert`, `move`, and `remove` member functions are overwritten to update the data structure at each operation. The locate queries are also overwritten to take advantage of the data @@ -1178,30 +1178,30 @@ structure for a fast processing. \subsection Triangulation_2TheVertexofaTriangulation The Vertex of a Triangulation Hierarchy -The base vertex class of a triangulation hierarchy +The base vertex class of a triangulation hierarchy has to be a model of the concept `TriangulationHierarchyVertexBase_2` which extends the concept `TriangulationVertexBase_2`. This extension adds -access and setting member functions -for two pointers to the corresponding vertices in the +access and setting member functions +for two pointers to the corresponding vertices in the triangulations of the next and preceding levels. \cgal provides the class `Triangulation_hierarchy_vertex_base_2` -which is a model for the concept +which is a model for the concept `TriangulationHierarchyVertexBase_2`. This class is templated by a parameter `Vb` which is to be instantiated by a model of the concept `TriangulationVertexBase_2`. The class `Triangulation_hierarchy_vertex_base_2` inherits from its template parameter `Vb`. -This design enables the usage of +This design enables the usage of either the default vertex class or a user customized vertex class with additional functionalities for `Vb`. -\subsection Subsection_2D_Triangulations_Hierarchy_Examples Examples For the Use of a Triangulation Hierarchy +\subsection Subsection_2D_Triangulations_Hierarchy_Examples Examples For the Use of a Triangulation Hierarchy The following program is an example for the standard use of a triangulation hierarchy @@ -1218,7 +1218,7 @@ a triangulation hierarchy in conjunction with a constrained triangulation with a -\section Section_2D_Triangulations_Flexibility Flexibility +\section Section_2D_Triangulations_Flexibility Flexibility \subsection Triangulation_2UsingCustomizedVerticesand Using Customized Vertices and Faces @@ -1232,7 +1232,7 @@ which the user can instantiate with his own customized classes. The most useful flexibility however comes from the fact that the triangulation data structure itself has two template -parameters to be instantiated by +parameters to be instantiated by classes for the vertices and faces of the triangulation. Using his own customized classes to instantiate these parameters, the user can easily build up a triangulation with additional @@ -1252,23 +1252,23 @@ structure, and there is a cyclic dependency on template parameter. The cyclic dependency in triangulations software design. \cgalFigureEnd -Previously, this cyclic dependency was avoided by +Previously, this cyclic dependency was avoided by using only `void*` pointers in the interface of base classes. These `void*` were converted to appropriate types at the triangulation data structure levels. This solution had some drawbacks -: mainly the user could not add in the vertices or faces of the -triangulation a functionality related to types defined by +: mainly the user could not add in the vertices or faces of the +triangulation a functionality related to types defined by the triangulation data structure, for instance a handle to a vertex, -and he was lead to use himself +and he was lead to use himself `void*` pointers). The new solution to resolve the template dependency -is based on a rebind mechanism similar to the mechanism used in the +is based on a rebind mechanism similar to the mechanism used in the standard allocator class std::allocator. The rebind mechanism -is described in Section \ref TDS_2D_default "The Default Triangulation Data Structure" +is described in Section \ref TDS_2D_default "The Default Triangulation Data Structure" of Chapter \ref Chapter_2D_Triangulation_Data_Structure "2D Triangulation Data Structure". For now, we will just notice that the design requires -the existence in the vertex and face base classes +the existence in the vertex and face base classes of a nested template class `Rebind_TDS` defining a type `Other` used by the rebinding mechanism. @@ -1279,17 +1279,17 @@ base classes parameters. \subsection Triangulation_2AddingColors Adding Colors -The first example corresponds to a case where the user wishes to add in +The first example corresponds to a case where the user wishes to add in the vertices or faces of the triangulation an additional information that does not depend on types provided -by the triangulation data structure. +by the triangulation data structure. In that case, predefined classes `Triangulation_vertex_base_with_info_2` or `Triangulation_face_base_with_info_2` can be used. Those classes have a template parameter `Info` devoted to handle additional information. -The following example shows how to add a +The following example shows how to add a `Color` in the triangulation faces. \cgalExample{Triangulation_2/colored_face.cpp} @@ -1303,8 +1303,8 @@ The second example adds a `std::string` in the vertices of a terrain. \subsection Triangulation_2AddingHandles Adding Handles This example shows how the user can still -derive and plug in his own vertex -or face class when he would like to have +derive and plug in his own vertex +or face class when he would like to have additional functionalities depending on types provided by the triangulation data structure. @@ -1316,10 +1316,10 @@ The most efficient method to insert (weighted) points in a Delaunay (or regular) triangulation is to provide an iterator range over (weighted) points to the insert function. However, an iterator range of (weighted) points does not allow the user to set different information to each vertex. -To solve this problem, in the case the vertex type of the triangulation +To solve this problem, in the case the vertex type of the triangulation is a model of the concept `TriangulationVertexBaseWithInfo_2` -(such as `Triangulation_vertex_base_with_info_2`), we provide three examples -doing the same operation: set an unsigned integer as the information +(such as `Triangulation_vertex_base_with_info_2`), we provide three examples +doing the same operation: set an unsigned integer as the information of each vertex. The value of this unsigned integer is the initial order of the corresponding point given in the range. @@ -1349,10 +1349,10 @@ is dereferenced only once per point during the insertion. The code of this package is the result of a long development process. Here follows a tentative list of people who added their stone to this package: -Jean-Daniel Boissonnat, Hervé Brönnimann, +Jean-Daniel Boissonnat, Hervé Brönnimann, Olivier Devillers, Andreas Fabri, Frédéric Fichel, Julia Flötotto, Monique Teillaud and Mariette Yvinec. -*/ +*/ } /* namespace CGAL */ diff --git a/Triangulation_2/include/CGAL/Constrained_triangulation_plus_2.h b/Triangulation_2/include/CGAL/Constrained_triangulation_plus_2.h index 676952750b9..0b19a9a5698 100644 --- a/Triangulation_2/include/CGAL/Constrained_triangulation_plus_2.h +++ b/Triangulation_2/include/CGAL/Constrained_triangulation_plus_2.h @@ -6,7 +6,7 @@ // $URL$ // $Id$ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial -// +// // // Author(s) : Andreas Fabri, Mariette Yvinec @@ -57,25 +57,25 @@ public: } }; // end class template Pct2_vertex_handle_less_xy -// Tr the base triangulation class +// Tr the base triangulation class // Tr has to be Constrained or Constrained_Delaunay with Constrained_triangulation_plus_vertex_base template < class Tr_ = Default > -class Constrained_triangulation_plus_2 - : public -Default::Get< Tr_, Constrained_Delaunay_triangulation_2< +class Constrained_triangulation_plus_2 + : public +Default::Get< Tr_, Constrained_Delaunay_triangulation_2< Exact_predicates_inexact_constructions_kernel - , Triangulation_data_structure_2< + , Triangulation_data_structure_2< Triangulation_vertex_base_2 , Constrained_triangulation_face_base_2 > , CGAL::Exact_predicates_tag > >::type { - typedef typename - Default::Get< Tr_, Constrained_Delaunay_triangulation_2< + typedef typename + Default::Get< Tr_, Constrained_Delaunay_triangulation_2< Exact_predicates_inexact_constructions_kernel - , Triangulation_data_structure_2< + , Triangulation_data_structure_2< Triangulation_vertex_base_2 , Constrained_triangulation_face_base_2 > @@ -89,7 +89,7 @@ Default::Get< Tr_, Constrained_Delaunay_triangulation_2< typedef typename CDT::Vertex_handle Vertex_handle; typedef typename CDT::Face_handle Face_handle; private: - typedef boost::tuple TFace; + typedef boost::tuple TFace; std::vector faces; CDT& cdt; @@ -111,8 +111,8 @@ Default::Get< Tr_, Constrained_Delaunay_triangulation_2< void write_faces(OutputIterator out) { - for(typename std::vector::reverse_iterator - it = faces.rbegin(); it != faces.rend(); ++it) { + for(typename std::vector::reverse_iterator + it = faces.rbegin(); it != faces.rend(); ++it) { Face_handle fh; if(cdt.is_face(boost::get<0>(*it), boost::get<1>(*it), boost::get<2>(*it), fh)){ *out++ = fh; @@ -127,7 +127,7 @@ public: typedef Constrained_triangulation_plus_2 Self; typedef Tr Base; - + #ifndef CGAL_CFG_USING_BASE_MEMBER_BUG_2 using Triangulation::vertices_begin; using Triangulation::vertices_end; @@ -170,29 +170,29 @@ public: typedef Tag_false Periodic_tag; // for user interface with the constraint hierarchy - typedef typename Constraint_hierarchy::Vertex_it + typedef typename Constraint_hierarchy::Vertex_it Vertices_in_constraint_iterator; typedef Iterator_range Vertices_in_constraint; - + typedef typename Constraint_hierarchy::Point_it Points_in_constraint_iterator; typedef Iterator_range Points_in_constraint; - + typedef typename Constraint_hierarchy::Context Context; typedef typename Constraint_hierarchy::Context_iterator Context_iterator; typedef Iterator_range Contexts; - + typedef typename Constraint_hierarchy::C_iterator Constraint_iterator; typedef Iterator_range Constraints; - + typedef typename Constraint_hierarchy::Subconstraint_iterator Subconstraint_iterator; typedef Iterator_range Subconstraints; - - typedef typename Constraint_hierarchy::Constraint_id Constraint_id; - + + typedef typename Constraint_hierarchy::Constraint_id Constraint_id; + typedef std::pair Subconstraint; - + using Triangulation::geom_traits; using Triangulation::cw; using Triangulation::ccw; @@ -200,14 +200,14 @@ public: protected: Constraint_hierarchy hierarchy; - + public: Constraint_hierarchy& hierarchy_ref() { return hierarchy; } - Constrained_triangulation_plus_2(const Geom_traits& gt=Geom_traits()) + Constrained_triangulation_plus_2(const Geom_traits& gt=Geom_traits()) : Triangulation(gt) , hierarchy(Vh_less_xy(this)) { } @@ -227,8 +227,8 @@ public: template Constrained_triangulation_plus_2(InputIterator first, - InputIterator last, - const Geom_traits& gt=Geom_traits() ) + InputIterator last, + const Geom_traits& gt=Geom_traits() ) : Triangulation(gt) , hierarchy(Vh_less_xy(this)) { @@ -238,7 +238,7 @@ public: Constrained_triangulation_plus_2(const std::list > &constraints, - const Geom_traits& gt=Geom_traits() ) + const Geom_traits& gt=Geom_traits() ) : Triangulation(gt) , hierarchy(Vh_less_xy(this)) { @@ -251,12 +251,12 @@ public: void swap(Constrained_triangulation_plus_2 &ctp); // INSERTION - Vertex_handle insert(const Point& a, - Face_handle start = Face_handle() ); + Vertex_handle insert(const Point& a, + Face_handle start = Face_handle() ); Vertex_handle insert(const Point& p, - Locate_type lt, - Face_handle loc, int li ); - + Locate_type lt, + Face_handle loc, int li ); + Constraint_id insert_constraint(const Point& a, const Point& b) { Vertex_handle va= insert(a); @@ -264,14 +264,14 @@ public: // close to point a // Otherwise, to start here is as good as elsewhere Vertex_handle vb = insert(b, va->face()); - return insert_constraint(va, vb); + return insert_constraint(va, vb); } - Constraint_id insert_constraint(const Constraint& c) + Constraint_id insert_constraint(const Constraint& c) { return insert_constraint(c.first, c.second); } - + Constraint_id insert_constraint(Vertex_handle va, Vertex_handle vb) { // protects against inserting a zero length constraint @@ -280,7 +280,7 @@ public: } // protects against inserting twice the same constraint Constraint_id cid = hierarchy.insert_constraint_old_API(va, vb); - if (va != vb && (cid != Constraint_id(nullptr)) ) insert_subconstraint(va,vb); + if (va != vb && (cid != Constraint_id(nullptr)) ) insert_subconstraint(va,vb); return cid; } @@ -343,7 +343,7 @@ public: } // for backward compatibility - // not const Point&, because otherwise VC6/7 messes it up with + // not const Point&, because otherwise VC6/7 messes it up with // the insert that takes an iterator range Constraint_id insert(Point a, Point b) { return insert_constraint(a, b); } Constraint_id insert(Vertex_handle va, Vertex_handle vb) { return insert_constraint(va,vb); } @@ -370,8 +370,8 @@ public: Vertices_in_constraint_iterator - insert_vertex_in_constraint(Constraint_id cid, Vertices_in_constraint_iterator pos, - Vertex_handle vh) + insert_vertex_in_constraint(Constraint_id cid, Vertices_in_constraint_iterator pos, + Vertex_handle vh) { return insert_vertex_in_constraint(cid, pos, vh, Emptyset_iterator()); } @@ -385,8 +385,8 @@ public: template Vertices_in_constraint_iterator - remove_vertex_from_constraint(Constraint_id cid, Vertices_in_constraint_iterator pos, - OutputIterator out) + remove_vertex_from_constraint(Constraint_id cid, Vertices_in_constraint_iterator pos, + OutputIterator out) { if(pos == vertices_in_constraint_begin(cid)){ ++pos; @@ -427,7 +427,7 @@ public: ++pos; tail = hierarchy.split(cid,pos); } - + Constraint_id aux = insert_constraint(a, b, std::back_inserter(fc)); pos = vertices_in_constraint_end(aux); --pos; @@ -452,8 +452,8 @@ public: // Writes the modified faces to out template Vertices_in_constraint_iterator - insert_vertex_in_constraint(Constraint_id cid, Vertices_in_constraint_iterator pos, - Vertex_handle vh, OutputIterator out) + insert_vertex_in_constraint(Constraint_id cid, Vertices_in_constraint_iterator pos, + Vertex_handle vh, OutputIterator out) { // Insertion before the first vertex if(pos == vertices_in_constraint_begin(cid)){ @@ -461,7 +461,7 @@ public: Constraint_id head = insert_constraint(vh, *pos, out); hierarchy.concatenate2(head, cid); return vertices_in_constraint_begin(cid); - } + } // Insertion after the last vertex if(pos == vertices_in_constraint_end(cid)){ @@ -474,7 +474,7 @@ public: return pos; } Vertex_handle b = *pos; - --pos; + --pos; Vertex_handle a = *pos; ++pos; Face_container fc(*this); @@ -483,7 +483,7 @@ public: vcit = beg; ++beg; // If the constraint consists only of a segment, and we want to insert - // in the middle + // in the middle if((pos == vcit) && (beg == vertices_in_constraint_end(cid))){ //std::cout << "insertion in constraint which is a segment" << std::endl; Constraint_id aux1 = insert_constraint(a, vh, std::back_inserter(fc)); @@ -494,7 +494,7 @@ public: remove_constraint(aux1, std::back_inserter(fc)); fc.write_faces(out); return pos; - + } Constraint_id head = 0, tail = 0; Vertices_in_constraint_iterator bit = vertices_in_constraint_begin(cid); @@ -513,9 +513,9 @@ public: --eit; if(pos != eit){ //std::cout << "split tail" << std::endl; - tail = split(cid, pos); + tail = split(cid, pos); } - + // make the new constraint Constraint_id aux1 = insert_constraint(a, vh, std::back_inserter(fc)); Constraint_id aux2 = insert_constraint(vh, b, std::back_inserter(fc)); @@ -551,7 +551,7 @@ public: hint = vh->face(); // no duplicates if(vertices.empty() || (vertices.back() != vh)){ - vertices.push_back(vh); + vertices.push_back(vh); } } int n = vertices.size(); @@ -559,24 +559,24 @@ public: return nullptr; } Constraint_id ca = hierarchy.insert_constraint(vertices[0],vertices[1]); - insert_subconstraint(vertices[0],vertices[1], std::back_inserter(fc)); + insert_subconstraint(vertices[0],vertices[1], std::back_inserter(fc)); if(n>2){ for(int j=1; jfixed() = true; // Vertices_in_constraint_iterator end = boost::prior(vertices_in_constraint_end(ca)); // end->fixed() = true; fc.write_faces(out); - + return ca; } @@ -592,7 +592,7 @@ private: hint = vh->face(); // no duplicates if(vertices.empty() || (vertices.back() != vh)){ - vertices.push_back(vh); + vertices.push_back(vh); } } if(is_polygon && (vertices.size()>1) && (vertices.front() != vertices.back())){ @@ -604,26 +604,26 @@ private: return nullptr; } CGAL_assertion(n >= 2); - + Constraint_id ca = hierarchy.insert_constraint(vertices[0],vertices[1]); - insert_subconstraint(vertices[0],vertices[1]); + insert_subconstraint(vertices[0],vertices[1]); if(n>2){ for(std::size_t j=1; jfixed() = true; // vertices.back()->fixed() = true; return ca; } - + public: - + void file_output(std::ostream& os) const { @@ -648,9 +648,9 @@ public: void file_input(std::istream& is) { - + is >> static_cast(*this); - + std::vector V; V.reserve(number_of_vertices()); for(Vertex_iterator vit = vertices_begin(); vit != vertices_end() ; ++vit){ @@ -663,7 +663,7 @@ public: while(is >> n){ is >> i0 >> i1; cid = insert_constraint(V[i0],V[i1]); - + for(int i = 2; i < n; i++){ i0 = i1; is >> i1; @@ -673,7 +673,7 @@ public: } } - + template typename Constrained_triangulation_plus_2::Constraint_id insert_constraint(Vertex_handle va, Vertex_handle vb, OutputIterator out) @@ -684,11 +684,11 @@ public: } // protects against inserting twice the same constraint Constraint_id cid = hierarchy.insert_constraint(va, vb); - if (va != vb && (cid != nullptr) ) insert_subconstraint(va,vb,out); - + if (va != vb && (cid != nullptr) ) insert_subconstraint(va,vb,out); + for(Vertices_in_constraint_iterator vcit = vertices_in_constraint_begin(cid); - vcit != vertices_in_constraint_end(cid); - vcit++){ + vcit != vertices_in_constraint_end(cid); + vcit++){ insert_incident_faces(vcit, out); } return cid; @@ -713,26 +713,26 @@ public: Vertex_handle vaa, Vertex_handle vbb, Exact_predicates_tag); - + // REMOVAL template void remove_constraint(Constraint_id cid, OutputIterator out) { std::list vertices(hierarchy.vertices_in_constraint_begin(cid), - hierarchy.vertices_in_constraint_end(cid)); + hierarchy.vertices_in_constraint_end(cid)); hierarchy.remove_constraint(cid); - for(typename std::list::iterator it = vertices.begin(), - succ = it; - ++succ != vertices.end(); - ++it){ + for(typename std::list::iterator it = vertices.begin(), + succ = it; + ++succ != vertices.end(); + ++it){ if(! is_subconstraint(*it, *succ)){ // this checks whether other constraints pass - Face_handle fh; - int i; - bool b = Triangulation::is_edge(*it, *succ, fh, i); - CGAL_assume(b); - Triangulation::remove_constrained_edge(fh,i, out); // this does also flipping if necessary. + Face_handle fh; + int i; + bool b = Triangulation::is_edge(*it, *succ, fh, i); + CGAL_assume(b); + Triangulation::remove_constrained_edge(fh,i, out); // this does also flipping if necessary. } } } @@ -741,18 +741,18 @@ public: remove_constraint(cid, Emptyset_iterator()); } - + void simplify(Vertices_in_constraint_iterator v) { Vertices_in_constraint_iterator u = boost::prior(v); Vertices_in_constraint_iterator w = boost::next(v); bool unew = (*u != *w); hierarchy.simplify(u,v,w); - + Triangulation::remove_incident_constraints(*v); - + Triangulation::remove(*v); - + if(unew){ Triangulation::insert_constraint(*u, *w); } @@ -776,10 +776,10 @@ public: // split a constraint in two constraints, so that vcit becomes the first // vertex of the new constraint - // returns the new constraint + // returns the new constraint Constraint_id split(Constraint_id first, Vertices_in_constraint_iterator vcit); - + // Query of the constraint hierarchy Constraint_iterator constraints_begin() const; Constraint_iterator constraints_end() const; @@ -787,7 +787,7 @@ public: { return Constraints(constraints_begin(),constraints_end()); } - + Subconstraint_iterator subconstraints_begin() const; Subconstraint_iterator subconstraints_end() const; @@ -795,31 +795,31 @@ public: { return Subconstraints(subconstraints_begin(),subconstraints_end()); } - - Context context(Vertex_handle va, Vertex_handle vb); //AF: const; - bool is_subconstraint(Vertex_handle va, - Vertex_handle vb); - size_type number_of_enclosing_constraints(Vertex_handle va, + Context context(Vertex_handle va, Vertex_handle vb); //AF: const; + + bool is_subconstraint(Vertex_handle va, + Vertex_handle vb); + size_type number_of_enclosing_constraints(Vertex_handle va, Vertex_handle vb) const; - Context_iterator contexts_begin(Vertex_handle va, - Vertex_handle vb) const; - Context_iterator contexts_end(Vertex_handle va, - Vertex_handle vb) const; + Context_iterator contexts_begin(Vertex_handle va, + Vertex_handle vb) const; + Context_iterator contexts_end(Vertex_handle va, + Vertex_handle vb) const; Contexts contexts(Vertex_handle va, Vertex_handle vb) const { return Contexts(contexts_begin(va,vb),contexts_end(va,vb)); } - + Vertices_in_constraint_iterator vertices_in_constraint_begin(Constraint_id cid) const; Vertices_in_constraint_iterator vertices_in_constraint_end(Constraint_id cid) const; - + Vertices_in_constraint vertices_in_constraint(Constraint_id cid) const { return Vertices_in_constraint(vertices_in_constraint_begin(cid), vertices_in_constraint_end(cid)); } - + Points_in_constraint_iterator points_in_constraint_begin(Constraint_id cid) const; Points_in_constraint_iterator points_in_constraint_end(Constraint_id cid) const ; @@ -855,12 +855,12 @@ protected: fc++; }while(fc != done); } - } + } void insert_subconstraint(Vertex_handle vaa, - Vertex_handle vbb) + Vertex_handle vbb) { insert_subconstraint(vaa,vbb,Emptyset_iterator()); } @@ -871,9 +871,9 @@ insert_subconstraint(Vertex_handle vaa, template void insert_subconstraint(Vertex_handle vaa, - Vertex_handle vbb, - OutputItertator out) - // insert the subconstraint [vaa vbb] + Vertex_handle vbb, + OutputItertator out) + // insert the subconstraint [vaa vbb] // it will eventually be split into several subconstraints { std::stack > stack; @@ -883,7 +883,7 @@ insert_subconstraint(Vertex_handle vaa, boost::tie(vaa,vbb) = stack.top(); stack.pop(); CGAL_triangulation_precondition( vaa != vbb); - + Vertex_handle vi; Face_handle fr; @@ -896,11 +896,11 @@ insert_subconstraint(Vertex_handle vaa, } continue; } - + List_faces intersected_faces; List_edges conflict_boundary_ab, conflict_boundary_ba; - - bool intersection = this->find_intersected_faces( + + bool intersection = this->find_intersected_faces( vaa, vbb, intersected_faces, conflict_boundary_ab, @@ -910,10 +910,10 @@ insert_subconstraint(Vertex_handle vaa, if ( intersection) { if (vi != vaa && vi != vbb) { hierarchy.split_constraint(vaa,vbb,vi); - stack.push(std::make_pair(vaa,vi)); - stack.push(std::make_pair(vi,vbb)); + stack.push(std::make_pair(vaa,vi)); + stack.push(std::make_pair(vi,vbb)); } - else stack.push(std::make_pair(vaa,vbb)); + else stack.push(std::make_pair(vaa,vbb)); continue; } @@ -954,7 +954,7 @@ insert_subconstraint(Vertex_handle vaa, if (vi != vbb) { hierarchy.split_constraint(vaa,vbb,vi); - stack.push(std::make_pair(vi,vbb)); + stack.push(std::make_pair(vi,vbb)); } } } @@ -971,7 +971,7 @@ public: #if defined(_MSC_VER) std::ptrdiff_t insert(InputIterator first, InputIterator last, int i = 0) #else - std::ptrdiff_t insert(InputIterator first, InputIterator last) + std::ptrdiff_t insert(InputIterator first, InputIterator last) #endif { #if defined(_MSC_VER) @@ -1000,7 +1000,7 @@ copy_triangulation(const Constrained_triangulation_plus_2 &ctp) { Base::copy_triangulation(ctp); //the following assumes that the triangulation and its copy - // iterate on their vertices in the same order + // iterate on their vertices in the same order std::map vmap; Vertex_iterator vit = ctp.vertices_begin(); Vertex_iterator vvit = this->vertices_begin(); @@ -1021,7 +1021,7 @@ swap(Constrained_triangulation_plus_2 &ctp) } template < class Tr > -inline +inline typename Constrained_triangulation_plus_2::Vertex_handle Constrained_triangulation_plus_2:: insert(const Point& a, Face_handle start) @@ -1059,17 +1059,17 @@ insert(const Point& a, Locate_type lt, Face_handle loc, int li) } template -typename Constrained_triangulation_plus_2:: Vertex_handle +typename Constrained_triangulation_plus_2:: Vertex_handle Constrained_triangulation_plus_2:: -intersect(Face_handle f, int i, - Vertex_handle vaa, - Vertex_handle vbb) +intersect(Face_handle f, int i, + Vertex_handle vaa, + Vertex_handle vbb) { return intersect(f, i, vaa, vbb, Intersection_tag()); } template -typename Constrained_triangulation_plus_2:: Vertex_handle +typename Constrained_triangulation_plus_2:: Vertex_handle Constrained_triangulation_plus_2:: intersect(Face_handle, int, Vertex_handle, @@ -1093,13 +1093,13 @@ intersect(Face_handle, int, } template -typename Constrained_triangulation_plus_2:: Vertex_handle +typename Constrained_triangulation_plus_2:: Vertex_handle Constrained_triangulation_plus_2:: -intersect(Face_handle f, int i, - Vertex_handle vaa, - Vertex_handle vbb, - Exact_intersections_tag) -// compute the intersection of the constraint edge (f,i) +intersect(Face_handle f, int i, + Vertex_handle vaa, + Vertex_handle vbb, + Exact_intersections_tag) +// compute the intersection of the constraint edge (f,i) // with the subconstraint (vaa,vbb) being inserted // insert the intersection point // (the constraint edge (f,i) will be split in hierarchy by insert) @@ -1127,16 +1127,16 @@ intersect(Face_handle f, int i, CGAL_triangulation_assertion(ok); Vertex_handle vi = insert(pi, Triangulation::EDGE, f, i); - return vi; + return vi; } template -typename Constrained_triangulation_plus_2::Vertex_handle +typename Constrained_triangulation_plus_2::Vertex_handle Constrained_triangulation_plus_2:: -intersect(Face_handle f, int i, - Vertex_handle vaa, - Vertex_handle vbb, - Exact_predicates_tag) +intersect(Face_handle f, int i, + Vertex_handle vaa, + Vertex_handle vbb, + Exact_predicates_tag) { Vertex_handle vcc, vdd; vcc = f->vertex(cw(i)); @@ -1158,7 +1158,7 @@ intersect(Face_handle f, int i, case 0 : vi = vaa; break; case 1 : vi = vbb; break; case 2 : vi = vcc; break; - case 3 : vi = vdd; break; + case 3 : vi = vdd; break; } if(vi == vaa || vi == vbb) { Triangulation::remove_constrained_edge(f, i); @@ -1171,15 +1171,15 @@ intersect(Face_handle f, int i, // vi == vc or vi == vd may happen even if intersection==true // due to approximate construction of the intersection - if (vi != vcc && vi != vdd) { + if (vi != vcc && vi != vdd) { hierarchy.split_constraint(vcc,vdd,vi); - insert_subconstraint(vcc,vi); + insert_subconstraint(vcc,vi); insert_subconstraint(vi, vdd); - } + } else { insert_subconstraint(vcc,vdd); } - return vi; + return vi; } // CONCATENATE AND SPLIT @@ -1194,7 +1194,7 @@ Constrained_triangulation_plus_2::concatenate(Constraint_id first, Constrain // split a constraint in two constraints, so that vcit becomes the first // vertex of the new constraint - // returns the new constraint + // returns the new constraint template typename Constrained_triangulation_plus_2::Constraint_id Constrained_triangulation_plus_2::split(Constraint_id first, Vertices_in_constraint_iterator vcit) @@ -1205,8 +1205,8 @@ Constrained_triangulation_plus_2::split(Constraint_id first, Vertices_in_con template std::ostream & -operator<<(std::ostream& os, - const Constrained_triangulation_plus_2 &ct) +operator<<(std::ostream& os, + const Constrained_triangulation_plus_2 &ct) { ct.file_output(os); return os ; @@ -1214,8 +1214,8 @@ operator<<(std::ostream& os, template std::istream & -operator>>(std::istream& is, - Constrained_triangulation_plus_2 &ct) +operator>>(std::istream& is, + Constrained_triangulation_plus_2 &ct) { ct.file_input(is); return is ; @@ -1275,13 +1275,13 @@ context(Vertex_handle va, Vertex_handle vb) // AF: const template -inline +inline typename Constrained_triangulation_plus_2::size_type Constrained_triangulation_plus_2:: number_of_enclosing_constraints(Vertex_handle va, Vertex_handle vb) const { - return static_cast - (hierarchy.number_of_enclosing_constraints(va,vb)); + return static_cast + (hierarchy.number_of_enclosing_constraints(va,vb)); } template @@ -1289,7 +1289,7 @@ inline bool Constrained_triangulation_plus_2:: is_subconstraint(Vertex_handle va, Vertex_handle vb) { - return hierarchy.is_subconstrained_edge(va,vb); + return hierarchy.is_subconstrained_edge(va,vb); } diff --git a/Triangulation_2/include/CGAL/Triangulation_2/internal/CTP2_subconstraint_graph.h b/Triangulation_2/include/CGAL/Triangulation_2/internal/CTP2_subconstraint_graph.h index 66557dda87a..77e212b9f04 100644 --- a/Triangulation_2/include/CGAL/Triangulation_2/internal/CTP2_subconstraint_graph.h +++ b/Triangulation_2/include/CGAL/Triangulation_2/internal/CTP2_subconstraint_graph.h @@ -5,7 +5,7 @@ // $URL$ // $Id$ // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial -// +// // // Author(s) : Simon Giraudot @@ -53,24 +53,24 @@ public: typedef boost::transform_iterator edge_iterator; CTP2_subconstraint_graph (CTP2& ctp2) : ctp2(ctp2) { } - + friend Iterator_range vertices (const CTP2_subconstraint_graph& g) { return make_range (vertex_iterator(g.ctp2.finite_vertices_begin()), vertex_iterator(g.ctp2.finite_vertices_end())); } - + friend Iterator_range edges (const CTP2_subconstraint_graph& g) { return make_range (boost::make_transform_iterator(g.ctp2.subconstraints_begin(), Subconstr_uf(Subconstr_map())), boost::make_transform_iterator(g.ctp2.subconstraints_end(), Subconstr_uf(Subconstr_map()))); } - + friend vertex_descriptor source (edge_descriptor ed, const CTP2_subconstraint_graph&) { return ed.first; } - + friend vertex_descriptor target (edge_descriptor ed, const CTP2_subconstraint_graph&) { return ed.second; @@ -90,13 +90,13 @@ private: public: CTP2_graph_visitor (CTP2& ctp2) : ctp2 (ctp2) { } - + void start_new_polyline() { latest_vertex = typename CTP2::Vertex_handle(); current = typename CTP2::Constraint_id(); } - + void add_node (typename CTP2::Vertex_handle vh) { if (latest_vertex != typename CTP2::Vertex_handle()) @@ -110,7 +110,7 @@ public: } latest_vertex = vh; } - + void end_polyline() { for (typename CTP2::Constraint_id id : to_remove) From a14e247bdf98334a23161d462bd05eacb6af999c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 27 Mar 2020 08:23:32 +0100 Subject: [PATCH 141/141] extra run of the script to remove tabs and trailing whitespaces --- .../demo/Polyhedron/Plugins/PMP/Repair_polyhedron_plugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Repair_polyhedron_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Repair_polyhedron_plugin.cpp index fe3759c6f79..1a5c52cd3ba 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Repair_polyhedron_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Repair_polyhedron_plugin.cpp @@ -238,7 +238,7 @@ void Polyhedron_demo_repair_polyhedron_plugin::on_actionAutorefineAndRMSelfInter if (poly_item) { try{ - bool solved = + bool solved = CGAL::Polygon_mesh_processing::experimental:: autorefine_and_remove_self_intersections(*poly_item->polyhedron()); if (!solved)