From 2260c4fab3756034d8fd80b1bbd7f079cae0b698 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 3 Feb 2023 10:39:58 +0100 Subject: [PATCH 001/329] more than one curve can be on the left of an event with overlapping curves on the right --- .../Surface_sweep_2/Surface_sweep_2_impl.h | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/Surface_sweep_2/include/CGAL/Surface_sweep_2/Surface_sweep_2_impl.h b/Surface_sweep_2/include/CGAL/Surface_sweep_2/Surface_sweep_2_impl.h index de98db8e9a03..41d961803103 100644 --- a/Surface_sweep_2/include/CGAL/Surface_sweep_2/Surface_sweep_2_impl.h +++ b/Surface_sweep_2/include/CGAL/Surface_sweep_2/Surface_sweep_2_impl.h @@ -110,19 +110,28 @@ void Surface_sweep_2::_handle_left_curves() this->m_currentEvent->push_back_curve_to_right(sc); } else { - this->m_currentEvent->push_back_curve_to_left(sc); this->m_currentEvent->set_weak_intersection(); - this->m_visitor->update_event(this->m_currentEvent, sc); - _add_curve_to_right(this->m_currentEvent, sc); + auto status_line_it = this->m_status_line_insert_hint; + do{ + this->m_currentEvent->push_back_curve_to_left(sc); + this->m_visitor->update_event(this->m_currentEvent, sc); + _add_curve_to_right(this->m_currentEvent, sc); + ++status_line_it; + if (status_line_it==this->m_statusLine.end()) break; + if (this->m_statusLineCurveLess(this->m_currentEvent->point(), *status_line_it)!=EQUAL) + break; + sc = *status_line_it; + } + while(true); // the loop is only needed in case there are overlapping curve in right curves } - // sc is now on the left + // some subcurves have been addded on the left CGAL_SS_PRINT_TEXT("Event after update:"); CGAL_SS_PRINT_EOL(); CGAL_SS_PRINT_EVENT_INFO(this->m_currentEvent); CGAL_SS_PRINT_EOL(); CGAL_assertion(std::distance(this->m_currentEvent->left_curves_begin(), - this->m_currentEvent->left_curves_end())==1); + this->m_currentEvent->left_curves_end())!=0); } else { // The event is not located on any subcurve. From a1ff847b6a4ec05ce40e3e24b7d38d8a87fd868e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 2 Jan 2023 08:17:16 +0100 Subject: [PATCH 002/329] add "brute-force" version of autorefine() --- .../Polygon_mesh_processing/CMakeLists.txt | 1 + .../triangle_mesh_autorefinement.cpp | 29 + .../Polygon_mesh_processing/autorefinement.h | 507 ++++++++++++++++++ .../internal/parameters_interface.h | 1 + 4 files changed, 538 insertions(+) create mode 100644 Polygon_mesh_processing/examples/Polygon_mesh_processing/triangle_mesh_autorefinement.cpp create mode 100644 Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt b/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt index 192e7d29b745..e188e01e3eb7 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt @@ -50,6 +50,7 @@ create_single_source_cgal_program("match_faces.cpp") create_single_source_cgal_program("cc_compatible_orientations.cpp") create_single_source_cgal_program("hausdorff_distance_remeshing_example.cpp") create_single_source_cgal_program("hausdorff_bounded_error_distance_example.cpp") +create_single_source_cgal_program("triangle_mesh_autorefinement.cpp") find_package(Eigen3 3.2.0 QUIET) #(requires 3.2.0 or greater) include(CGAL_Eigen3_support) diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/triangle_mesh_autorefinement.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/triangle_mesh_autorefinement.cpp new file mode 100644 index 000000000000..65db52fef2c9 --- /dev/null +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/triangle_mesh_autorefinement.cpp @@ -0,0 +1,29 @@ +#include +#include + +#include +#include + +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; +typedef Kernel::Point_3 Point; + +typedef CGAL::Surface_mesh Mesh; + +namespace PMP = CGAL::Polygon_mesh_processing; + +int main(int argc, char** argv) +{ + Mesh mesh; + + const std::string filename = argc == 1 ? CGAL::data_file_path("meshes/elephant.off") + : std::string(argv[1]); + CGAL::IO::read_polygon_mesh(filename, mesh); + + PMP::autorefine(mesh); + + CGAL::IO::write_polygon_mesh("autorefined.off", mesh, CGAL::parameters::stream_precision(17)); + + return 0; +} diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h new file mode 100644 index 000000000000..8c34b4041d86 --- /dev/null +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -0,0 +1,507 @@ +// Copyright (c) 2023 GeometryFactory (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Sebastien Loriot +// + +#ifndef CGAL_POLYGON_MESH_PROCESSING_AUTOREFINEMENT_H +#define CGAL_POLYGON_MESH_PROCESSING_AUTOREFINEMENT_H + +#include + +#include +#include +#include +#include + +// output +#include +#include + +#ifndef NDEBUG +// debug +#include +#endif + +#include + +namespace CGAL { +namespace Polygon_mesh_processing { + +#ifndef DOXYGEN_RUNNING +namespace autorefine_impl { + +template +void generate_subtriangles(const typename EK::Triangle_3& t, + const std::vector& segments, + const std::vector& points, + std::vector& new_triangles) +{ + typedef CGAL::Projection_traits_3 P_traits; + // typedef CGAL::Exact_intersections_tag Itag; + typedef CGAL::No_constraint_intersection_requiring_constructions_tag Itag; + typedef CGAL::Constrained_Delaunay_triangulation_2 CDT; + + + P_traits cdt_traits(normal(t[0], t[1], t[2])); + CDT cdt(cdt_traits); + + cdt.insert_outside_affine_hull(t[0]); + cdt.insert_outside_affine_hull(t[1]); + typename CDT::Vertex_handle v = cdt.tds().insert_dim_up(cdt.infinite_vertex(), false); + v->set_point(t[2]); + + for (const typename EK::Segment_3& s : segments) + cdt.insert_constraint(s[0], s[1]); + + for (const typename EK::Point_3& p : points) + cdt.insert(p); + + for (typename CDT::Face_handle fh : cdt.finite_face_handles()) + { + new_triangles.emplace_back(fh->vertex(0)->point(), + fh->vertex(cdt.ccw(0))->point(), + fh->vertex(cdt.cw(0))->point()); + } +} + +template +struct Intersection_visitor +{ + std::vector& all_segments_1; + std::vector& all_segments_2; + std::vector& all_points_1; + std::vector& all_points_2; + + Intersection_visitor(std::vector& all_segments_1, + std::vector& all_segments_2, + std::vector& all_points_1, + std::vector& all_points_2) + : all_segments_1(all_segments_1) + , all_segments_2(all_segments_2) + , all_points_1(all_points_1) + , all_points_2(all_points_2) + {} + + typedef void result_type; + void operator()(const typename EK::Point_3& p) + { + all_points_1.push_back(p); + all_points_2.push_back(p); + } + + void operator()(const typename EK::Segment_3& s) + { + all_segments_1.push_back(s); + all_segments_2.push_back(s); + } + + void operator()(const typename EK::Triangle_3& t) + { + for (std::size_t i=1; i<3; ++i) + { + typename EK::Segment_3 s(t[i-1], t[i]); + all_segments_1.push_back(s); + all_segments_2.push_back(s); + } + } + + void operator()(const std::vector& poly) + { + std::size_t nbp = poly.size(); + for (std::size_t i=1; i +bool is_output_valid(TriangleMesh& tm , VPM vpm, TID_Map tid_map, const std::vector< std::vector>>& triangles) +{ + typedef typename Kernel_traits::value_type>::type IK; + typedef boost::graph_traits Graph_traits; + typedef typename Graph_traits::face_descriptor face_descriptor; + typedef typename Graph_traits::halfedge_descriptor halfedge_descriptor; + + std::vector soup_points; + std::vector > soup_triangles; + Cartesian_converter to_exact; + std::map point_id_map; + + auto get_point_id = [&](const typename EK::Point_3& pt) + { + auto insert_res = point_id_map.insert(std::make_pair(pt, soup_points.size())); + if (insert_res.second) + soup_points.push_back(pt); + return insert_res.first->second; + }; + + for (face_descriptor f : faces(tm)) + { + int tid = get(tid_map, f); + if (tid == -1) + { + halfedge_descriptor h = halfedge(f, tm); + soup_triangles.emplace_back( + CGAL::make_array(get_point_id(to_exact(get(vpm,source(h, tm)))), + get_point_id(to_exact(get(vpm,target(h, tm)))), + get_point_id(to_exact(get(vpm,target(next(h, tm), tm))))) + ); + } + else + { + for (const typename EK::Triangle_3& t : triangles[tid]) + { + soup_triangles.emplace_back(CGAL::make_array(get_point_id(t[0]), get_point_id(t[1]), get_point_id(t[2]))); + } + } + } + + typedef Surface_mesh Exact_mesh; + Exact_mesh etm; + orient_polygon_soup(soup_points, soup_triangles); + polygon_soup_to_polygon_mesh(soup_points, soup_triangles, etm); + typename Exact_mesh::Property_map is_border_map = + etm.template add_property_map("v:is_border", false).first; + for(typename Exact_mesh::Halfedge_index h : etm.halfedges()) + { + if (CGAL::is_border(h, etm)) + is_border_map[target(h, etm)] = true; + } + + //TODO: double check me + auto skip_faces = [&](const std::pair& p) + { + typename Exact_mesh::Halfedge_index h1 = etm.halfedge(p.first), h2=etm.halfedge(p.second); + + boost::container::small_vector bv1; + if (is_border_map[source(h1, etm)]) bv1.push_back(prev(h1, etm)); + if (is_border_map[target(h1, etm)]) bv1.push_back(h1); + if (is_border_map[target(next(h1, etm), etm)]) bv1.push_back(next(h1, etm)); + if (bv1.empty()) return false; + + boost::container::small_vector bv2; + if (is_border_map[source(h2, etm)]) bv2.push_back(prev(h2, etm)); + if (is_border_map[target(h2, etm)]) bv2.push_back(h2); + if (is_border_map[target(next(h2, etm), etm)]) bv2.push_back(next(h2, etm)); + if (bv2.empty()) return false; + + //collect identical border vertices + boost::container::small_vector, 3> common; + for(typename Exact_mesh::Halfedge_index h1 : bv1) + for(typename Exact_mesh::Halfedge_index h2 : bv2) + if (etm.point(target(h1, etm))==etm.point(target(h2,etm))) + common.push_back(std::make_pair(h1,h2)); + + if (common.empty()) return false; + + switch (common.size()) + { + case 1: + { + // geometric check if the opposite segments intersect the triangles + const typename EK::Triangle_3 t1(etm.point(source(h1,etm)), + etm.point(target(h1,etm)), + etm.point(target(next(h1,etm),etm))); + const typename EK::Triangle_3 t2(etm.point(source(h2,etm)), + etm.point(target(h2,etm)), + etm.point(target(next(h2,etm),etm))); + + const typename EK::Segment_3 s1(etm.point(source(common[0].first,etm)), etm.point(target(next(common[0].first,etm),etm))); + const typename EK::Segment_3 s2(etm.point(source(common[0].second,etm)), etm.point(target(next(common[0].second,etm),etm))); + + if(do_intersect(t1, s2) || do_intersect(t2, s1)) + return false; + return true; + } + case 2: + { + // shared edge + h1 = next(common[0].first, etm) == common[1].first ? common[1].first : common[0].first; + h2 = next(common[0].second, etm) == common[1].second ? common[1].second : common[0].second; + + if ( is_border(etm.opposite(h1), etm) && + is_border(etm.opposite(h2), etm) ) + { + if( CGAL::coplanar(etm.point(source(h1,etm)), + etm.point(target(h1,etm)), + etm.point(target(etm.next(h1),etm)), + etm.point(source(h1,etm))) && + CGAL::coplanar_orientation(etm.point(source(h1,etm)), + etm.point(target(h1,etm)), + etm.point(target(etm.next(h1),etm)), + etm.point(source(h1,etm))) == CGAL::POSITIVE) + { + return false; + } + return true; + } + else + { + // TODO: 2 identical border vertices, no common edge on the boundary. Not sure what to do + return false; + } + } + default: // size == 3 + return true; + } + }; + + std::vector< std::pair > si_faces; + self_intersections(etm, + CGAL::filter_output_iterator(std::back_inserter(si_faces), + skip_faces)); + + return si_faces.empty(); +} + +} // end of autorefine_impl +#endif + +/** + * \ingroup PMP_corefinement_grp + * \link coref_def_subsec autorefines \endlink `tm`. Refines a triangle mesh + * so that no triangles intersects in their interior. + * Self-intersection edges will be marked as constrained. If an edge that was marked as + * constrained is split, its sub-edges will be marked as constrained as well. + * + * @tparam TriangleMesh a model of `HalfedgeListGraph`, `FaceListGraph`, and `MutableFaceGraph` + * @tparam NamedParameters a sequence of \ref namedparameters + * + * @param tm input triangulated surface mesh + * @param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below + * + * \cgalParamNBegin{geom_traits} + * \cgalParamDescription{an instance of a geometric traits class} + * \cgalParamType{a class model of `PMPSelfIntersectionTraits`} + * \cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`} + * \cgalParamExtra{The geometric traits class must be compatible with the vertex point type.} + * \cgalParamNEnd + * + * \cgalNamedParamsBegin + * \cgalParamNBegin{vertex_point_map} + * \cgalParamDescription{a property map associating points to the vertices of `tm`} + * \cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits::%vertex_descriptor` + * as key type and `%Point_3` as value type} + * \cgalParamDefault{`boost::get(CGAL::vertex_point, tm)`} + * \cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t` + * must be available in `TriangleMesh`.} + * \cgalParamNEnd + * + * \cgalParamNBegin{edge_is_constrained_map} + * \cgalParamDescription{a property map containing the constrained-or-not status of each edge of `tm`} + * \cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits::%edge_descriptor` + * as key type and `bool` as value type} + * \cgalParamDefault{a constant property map returning `false` for any edge} + * \cgalParamNEnd + * + * \cgalParamNBegin{face_index_map} + * \cgalParamDescription{a property map associating to each face of `tm` a unique index between `0` and `num_faces(tm) - 1`} + * \cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits::%face_descriptor` + * as key type and `std::size_t` as value type} + * \cgalParamDefault{an automatically indexed internal map} + * \cgalParamExtra{If the property map is writable, the indices of the faces of `tm1` and `tm2` + * will be set after the corefinement is done.} + * \cgalParamNEnd + * + * \cgalParamNBegin{visitor} + * \cgalParamDescription{a visitor used to track the creation of new faces} + * \cgalParamType{a class model of `PMPCorefinementVisitor`} + * \cgalParamDefault{`Corefinement::Default_visitor`} + * \cgalParamNEnd + * \cgalNamedParamsEnd + * + */ +template +void +autorefine( TriangleMesh& tm, + const NamedParameters& np = parameters::default_values()) +{ + //TODO: what about degenerate faces? + + using parameters::choose_parameter; + using parameters::get_parameter; + + typedef typename GetGeomTraits::type GT; + GT traits = choose_parameter(get_parameter(np, internal_np::geom_traits)); + + typedef typename GetVertexPointMap::type VPM; + VPM vpm = choose_parameter(get_parameter(np, internal_np::vertex_point), + get_property_map(vertex_point, tm)); + + typedef typename internal_np::Lookup_named_param_def < + internal_np::concurrency_tag_t, + NamedParameters, + Sequential_tag + > ::type Concurrency_tag; + + typedef boost::graph_traits Graph_traits; + typedef typename Graph_traits::face_descriptor face_descriptor; + typedef typename Graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename Graph_traits::vertex_descriptor vertex_descriptor; + typedef std::pair Pair_of_faces; + + std::vector si_pairs; + + // collect intersecting pairs of triangles + self_intersections(tm, std::back_inserter(si_pairs), np); + + if (si_pairs.empty()) return; + + // assign an id per triangle involved in an intersection + // + the faces involved in the intersection + typedef CGAL::dynamic_face_property_t Face_property_tag; + typedef typename boost::property_map::type Triangle_id_map; + + Triangle_id_map tid_map = get(Face_property_tag(), tm); + for (face_descriptor f : faces(tm)) + put(tid_map, f, -1); + + std::vector intersected_faces; + int tid=-1; + for (const Pair_of_faces& p : si_pairs) + { + if (get(tid_map, p.first)==-1) + { + put(tid_map, p.first, ++tid); + intersected_faces.push_back(p.first); + } + if (get(tid_map, p.second)==-1) + { + put(tid_map, p.second, ++tid); + intersected_faces.push_back(p.second); + } + } + + // init the vector of triangles used for the autorefinement of triangles + typedef CGAL::Exact_predicates_exact_constructions_kernel EK; + std::vector< std::vector > triangles(tid+1); + Cartesian_converter to_exact; + + for(face_descriptor f : intersected_faces) + { + halfedge_descriptor h = halfedge(f, tm); + triangles[get(tid_map, f)].emplace_back( + to_exact( get(vpm, source(h, tm)) ), + to_exact( get(vpm, target(h, tm)) ), + to_exact( get(vpm, target(next(h, tm), tm)) ) ); + } + + typename EK::Intersect_3 intersection = EK().intersect_3_object(); + for (const Pair_of_faces& p : si_pairs) + { + int i1 = get(tid_map, p.first), + i2 = get(tid_map, p.second); + + + std::size_t nbt_1 = triangles[i1].size(), + nbt_2 = triangles[i2].size(); + + std::vector< std::vector > all_segments_1(nbt_1); + std::vector< std::vector > all_segments_2(nbt_2); + std::vector< std::vector > all_points_1(nbt_1); + std::vector< std::vector > all_points_2(nbt_2); + + std::vector t1_subtriangles, t2_subtriangles; + for (std::size_t it1=0; it1 intersection_visitor(all_segments_1[it1], all_segments_2[it2], + all_points_1[it1], all_points_2[it2]); + + boost::apply_visitor(intersection_visitor, *inter); + } + } + } + + // now refine triangles + std::vector new_triangles; + for(std::size_t it1=0; it1(triangles[i1][it1], all_segments_1[it1], all_points_1[it1], new_triangles); + } + triangles[i1].swap(new_triangles); + new_triangles.clear(); + for(std::size_t it2=0; it2(triangles[i2][it2], all_segments_2[it2], all_points_2[it2], new_triangles); + } + triangles[i2].swap(new_triangles); + } + + CGAL_assertion( autorefine_impl::is_output_valid(tm, vpm, tid_map, triangles) ); + + // brute force output: create a soup, orient and to-mesh + // WARNING: there is no reason when using double that identical exact points are identical in double + std::vector soup_points; + std::vector > soup_triangles; + Cartesian_converter to_input; + std::map point_id_map; + + for (vertex_descriptor v : vertices(tm)) + { + if (point_id_map.insert(std::make_pair(to_exact(get(vpm,v)), soup_points.size())).second) + soup_points.push_back(get(vpm,v)); + } + + auto get_point_id = [&](const typename EK::Point_3& pt) + { + auto insert_res = point_id_map.insert(std::make_pair(pt, soup_points.size())); + if (insert_res.second) + soup_points.push_back(to_input(pt)); + return insert_res.first->second; + }; + + for (face_descriptor f : faces(tm)) + { + int tid = get(tid_map, f); + if (tid == -1) + { + halfedge_descriptor h = halfedge(f, tm); + soup_triangles.emplace_back( + CGAL::make_array(get_point_id(to_exact(get(vpm,source(h, tm)))), + get_point_id(to_exact(get(vpm,target(h, tm)))), + get_point_id(to_exact(get(vpm,target(next(h, tm), tm))))) + ); + } + else + { + for (const typename EK::Triangle_3& t : triangles[tid]) + { + soup_triangles.emplace_back(CGAL::make_array(get_point_id(t[0]), get_point_id(t[1]), get_point_id(t[2]))); + } + } + } + clear(tm); + orient_polygon_soup(soup_points, soup_triangles); + polygon_soup_to_polygon_mesh(soup_points, soup_triangles, tm); +} + +} } // end of CGAL::Polygon_mesh_processing + +#endif // CGAL_POLYGON_MESH_PROCESSING_AUTOREFINEMENT_H diff --git a/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h b/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h index 5c649faa56c7..7d758abc4ee6 100644 --- a/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h +++ b/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h @@ -45,6 +45,7 @@ CGAL_add_named_parameter(implementation_tag_t, implementation_tag, implementatio CGAL_add_named_parameter(prevent_unselection_t, prevent_unselection, prevent_unselection) CGAL_add_named_parameter(verbose_t, verbose, verbose) +CGAL_add_named_parameter(concurrency_tag_t, concurrency_tag, concurrency_tag) // List of named parameters used for IO CGAL_add_named_parameter(vertex_normal_output_iterator_t, vertex_normal_output_iterator, vertex_normal_output_iterator) From b0edd90580ea3044ca3fbfe11086d5413f9338cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 2 Jan 2023 17:21:01 +0100 Subject: [PATCH 003/329] add option to directly dump the soup --- .../Polygon_mesh_processing/autorefinement.h | 149 ++++++++++-------- 1 file changed, 84 insertions(+), 65 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 8c34b4041d86..fd124bce8579 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -266,67 +266,12 @@ bool is_output_valid(TriangleMesh& tm , VPM vpm, TID_Map tid_map, const std::vec } } // end of autorefine_impl -#endif -/** - * \ingroup PMP_corefinement_grp - * \link coref_def_subsec autorefines \endlink `tm`. Refines a triangle mesh - * so that no triangles intersects in their interior. - * Self-intersection edges will be marked as constrained. If an edge that was marked as - * constrained is split, its sub-edges will be marked as constrained as well. - * - * @tparam TriangleMesh a model of `HalfedgeListGraph`, `FaceListGraph`, and `MutableFaceGraph` - * @tparam NamedParameters a sequence of \ref namedparameters - * - * @param tm input triangulated surface mesh - * @param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below - * - * \cgalParamNBegin{geom_traits} - * \cgalParamDescription{an instance of a geometric traits class} - * \cgalParamType{a class model of `PMPSelfIntersectionTraits`} - * \cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`} - * \cgalParamExtra{The geometric traits class must be compatible with the vertex point type.} - * \cgalParamNEnd - * - * \cgalNamedParamsBegin - * \cgalParamNBegin{vertex_point_map} - * \cgalParamDescription{a property map associating points to the vertices of `tm`} - * \cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits::%vertex_descriptor` - * as key type and `%Point_3` as value type} - * \cgalParamDefault{`boost::get(CGAL::vertex_point, tm)`} - * \cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t` - * must be available in `TriangleMesh`.} - * \cgalParamNEnd - * - * \cgalParamNBegin{edge_is_constrained_map} - * \cgalParamDescription{a property map containing the constrained-or-not status of each edge of `tm`} - * \cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits::%edge_descriptor` - * as key type and `bool` as value type} - * \cgalParamDefault{a constant property map returning `false` for any edge} - * \cgalParamNEnd - * - * \cgalParamNBegin{face_index_map} - * \cgalParamDescription{a property map associating to each face of `tm` a unique index between `0` and `num_faces(tm) - 1`} - * \cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits::%face_descriptor` - * as key type and `std::size_t` as value type} - * \cgalParamDefault{an automatically indexed internal map} - * \cgalParamExtra{If the property map is writable, the indices of the faces of `tm1` and `tm2` - * will be set after the corefinement is done.} - * \cgalParamNEnd - * - * \cgalParamNBegin{visitor} - * \cgalParamDescription{a visitor used to track the creation of new faces} - * \cgalParamType{a class model of `PMPCorefinementVisitor`} - * \cgalParamDefault{`Corefinement::Default_visitor`} - * \cgalParamNEnd - * \cgalNamedParamsEnd - * - */ -template -void -autorefine( TriangleMesh& tm, - const NamedParameters& np = parameters::default_values()) +template +void autorefine_soup_output(const TriangleMesh& tm, + std::vector& soup_points, + std::vector >& soup_triangles, + const NamedParameters& np = parameters::default_values()) { //TODO: what about degenerate faces? @@ -336,9 +281,9 @@ autorefine( TriangleMesh& tm, typedef typename GetGeomTraits::type GT; GT traits = choose_parameter(get_parameter(np, internal_np::geom_traits)); - typedef typename GetVertexPointMap::type VPM; + typedef typename GetVertexPointMap::const_type VPM; VPM vpm = choose_parameter(get_parameter(np, internal_np::vertex_point), - get_property_map(vertex_point, tm)); + get_const_property_map(vertex_point, tm)); typedef typename internal_np::Lookup_named_param_def < internal_np::concurrency_tag_t, @@ -362,7 +307,7 @@ autorefine( TriangleMesh& tm, // assign an id per triangle involved in an intersection // + the faces involved in the intersection typedef CGAL::dynamic_face_property_t Face_property_tag; - typedef typename boost::property_map::type Triangle_id_map; + typedef typename boost::property_map::const_type Triangle_id_map; Triangle_id_map tid_map = get(Face_property_tag(), tm); for (face_descriptor f : faces(tm)) @@ -458,8 +403,6 @@ autorefine( TriangleMesh& tm, // brute force output: create a soup, orient and to-mesh // WARNING: there is no reason when using double that identical exact points are identical in double - std::vector soup_points; - std::vector > soup_triangles; Cartesian_converter to_input; std::map point_id_map; @@ -497,11 +440,87 @@ autorefine( TriangleMesh& tm, } } } + +} +#endif + +/** + * \ingroup PMP_corefinement_grp + * \link coref_def_subsec autorefines \endlink `tm`. Refines a triangle mesh + * so that no triangles intersects in their interior. + * Self-intersection edges will be marked as constrained. If an edge that was marked as + * constrained is split, its sub-edges will be marked as constrained as well. + * + * @tparam TriangleMesh a model of `HalfedgeListGraph`, `FaceListGraph`, and `MutableFaceGraph` + * @tparam NamedParameters a sequence of \ref namedparameters + * + * @param tm input triangulated surface mesh + * @param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below + * + * \cgalParamNBegin{geom_traits} + * \cgalParamDescription{an instance of a geometric traits class} + * \cgalParamType{a class model of `PMPSelfIntersectionTraits`} + * \cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`} + * \cgalParamExtra{The geometric traits class must be compatible with the vertex point type.} + * \cgalParamNEnd + * + * \cgalNamedParamsBegin + * \cgalParamNBegin{vertex_point_map} + * \cgalParamDescription{a property map associating points to the vertices of `tm`} + * \cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits::%vertex_descriptor` + * as key type and `%Point_3` as value type} + * \cgalParamDefault{`boost::get(CGAL::vertex_point, tm)`} + * \cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t` + * must be available in `TriangleMesh`.} + * \cgalParamNEnd + * + * \cgalParamNBegin{edge_is_constrained_map} + * \cgalParamDescription{a property map containing the constrained-or-not status of each edge of `tm`} + * \cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits::%edge_descriptor` + * as key type and `bool` as value type} + * \cgalParamDefault{a constant property map returning `false` for any edge} + * \cgalParamNEnd + * + * \cgalParamNBegin{face_index_map} + * \cgalParamDescription{a property map associating to each face of `tm` a unique index between `0` and `num_faces(tm) - 1`} + * \cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits::%face_descriptor` + * as key type and `std::size_t` as value type} + * \cgalParamDefault{an automatically indexed internal map} + * \cgalParamExtra{If the property map is writable, the indices of the faces of `tm1` and `tm2` + * will be set after the corefinement is done.} + * \cgalParamNEnd + * + * \cgalParamNBegin{visitor} + * \cgalParamDescription{a visitor used to track the creation of new faces} + * \cgalParamType{a class model of `PMPCorefinementVisitor`} + * \cgalParamDefault{`Corefinement::Default_visitor`} + * \cgalParamNEnd + * \cgalNamedParamsEnd + * + */ +template +void +autorefine( TriangleMesh& tm, + const NamedParameters& np = parameters::default_values()) +{ + using parameters::choose_parameter; + using parameters::get_parameter; + + typedef typename GetGeomTraits::type GT; + GT traits = choose_parameter(get_parameter(np, internal_np::geom_traits)); + + std::vector soup_points; + std::vector > soup_triangles; + + autorefine_soup_output(tm, soup_points, soup_triangles, np); + clear(tm); orient_polygon_soup(soup_points, soup_triangles); polygon_soup_to_polygon_mesh(soup_points, soup_triangles, tm); } + } } // end of CGAL::Polygon_mesh_processing #endif // CGAL_POLYGON_MESH_PROCESSING_AUTOREFINEMENT_H From 47ac016af779ab6a987ee16c62bbf723bd4c182f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 2 Jan 2023 17:32:35 +0100 Subject: [PATCH 004/329] skip degenerate faces --- .../Polygon_mesh_processing/autorefinement.h | 32 ++++++++++++------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index fd124bce8579..4b7020b5615b 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -125,8 +126,8 @@ struct Intersection_visitor } }; -template -bool is_output_valid(TriangleMesh& tm , VPM vpm, TID_Map tid_map, const std::vector< std::vector>>& triangles) +template +bool is_output_valid(TriangleMesh& tm , VPM vpm, TID_Map tid_map, Is_degen_map is_degen, const std::vector< std::vector>>& triangles) { typedef typename Kernel_traits::value_type>::type IK; typedef boost::graph_traits Graph_traits; @@ -148,6 +149,7 @@ bool is_output_valid(TriangleMesh& tm , VPM vpm, TID_Map tid_map, const std::vec for (face_descriptor f : faces(tm)) { + if (get(is_degen, f)) continue; // skip degenerate faces int tid = get(tid_map, f); if (tid == -1) { @@ -273,8 +275,6 @@ void autorefine_soup_output(const TriangleMesh& tm, std::vector >& soup_triangles, const NamedParameters& np = parameters::default_values()) { - //TODO: what about degenerate faces? - using parameters::choose_parameter; using parameters::get_parameter; @@ -304,12 +304,20 @@ void autorefine_soup_output(const TriangleMesh& tm, if (si_pairs.empty()) return; + // mark degenerate faces so that we can ignore them + typedef CGAL::dynamic_face_property_t Degen_property_tag; + typedef typename boost::property_map::const_type Is_degen_map; + Is_degen_map is_degen = get(Degen_property_tag(), tm); + + for(face_descriptor f : faces(tm)) + put(is_degen, f, is_degenerate_triangle_face(f, tm, np)); + // assign an id per triangle involved in an intersection // + the faces involved in the intersection - typedef CGAL::dynamic_face_property_t Face_property_tag; - typedef typename boost::property_map::const_type Triangle_id_map; + typedef CGAL::dynamic_face_property_t TID_property_tag; + typedef typename boost::property_map::const_type Triangle_id_map; - Triangle_id_map tid_map = get(Face_property_tag(), tm); + Triangle_id_map tid_map = get(TID_property_tag(), tm); for (face_descriptor f : faces(tm)) put(tid_map, f, -1); @@ -317,12 +325,12 @@ void autorefine_soup_output(const TriangleMesh& tm, int tid=-1; for (const Pair_of_faces& p : si_pairs) { - if (get(tid_map, p.first)==-1) + if (get(tid_map, p.first)==-1 && !get(is_degen, p.first)) { put(tid_map, p.first, ++tid); intersected_faces.push_back(p.first); } - if (get(tid_map, p.second)==-1) + if (get(tid_map, p.second)==-1 && !get(is_degen, p.second)) { put(tid_map, p.second, ++tid); intersected_faces.push_back(p.second); @@ -349,6 +357,7 @@ void autorefine_soup_output(const TriangleMesh& tm, int i1 = get(tid_map, p.first), i2 = get(tid_map, p.second); + if (i1==-1 || i2==-1) continue; //skip degenerate faces std::size_t nbt_1 = triangles[i1].size(), nbt_2 = triangles[i2].size(); @@ -399,7 +408,7 @@ void autorefine_soup_output(const TriangleMesh& tm, triangles[i2].swap(new_triangles); } - CGAL_assertion( autorefine_impl::is_output_valid(tm, vpm, tid_map, triangles) ); + CGAL_assertion( autorefine_impl::is_output_valid(tm, vpm, tid_map, is_degen, triangles) ); // brute force output: create a soup, orient and to-mesh // WARNING: there is no reason when using double that identical exact points are identical in double @@ -422,6 +431,8 @@ void autorefine_soup_output(const TriangleMesh& tm, for (face_descriptor f : faces(tm)) { + if (get(is_degen, f)) continue; //skip degenerate faces + int tid = get(tid_map, f); if (tid == -1) { @@ -440,7 +451,6 @@ void autorefine_soup_output(const TriangleMesh& tm, } } } - } #endif From 6df9926f9b6ea6553be1fbcfd1c0996e76b802f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 2 Jan 2023 17:47:04 +0100 Subject: [PATCH 005/329] add another example with soup as input --- .../Polygon_mesh_processing/CMakeLists.txt | 1 + .../soup_autorefinement.cpp | 39 +++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt b/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt index e188e01e3eb7..d2faeb70cb28 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt @@ -51,6 +51,7 @@ create_single_source_cgal_program("cc_compatible_orientations.cpp") create_single_source_cgal_program("hausdorff_distance_remeshing_example.cpp") create_single_source_cgal_program("hausdorff_bounded_error_distance_example.cpp") create_single_source_cgal_program("triangle_mesh_autorefinement.cpp") +create_single_source_cgal_program("soup_autorefinement.cpp") find_package(Eigen3 3.2.0 QUIET) #(requires 3.2.0 or greater) include(CGAL_Eigen3_support) diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp new file mode 100644 index 000000000000..fa1f5d686907 --- /dev/null +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp @@ -0,0 +1,39 @@ +#include +#include + +#include +#include +#include +#include +#include + +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; +typedef Kernel::Point_3 Point; + +typedef CGAL::Surface_mesh Mesh; + +namespace PMP = CGAL::Polygon_mesh_processing; + +int main(int argc, char** argv) +{ + const std::string filename = argc == 1 ? CGAL::data_file_path("meshes/elephant.off") + : std::string(argv[1]); + + std::vector input_points; + std::vector > input_triangles; + + CGAL::IO::read_polygon_soup(filename, input_points, input_triangles); + PMP::repair_polygon_soup(input_points, input_triangles); + + Mesh mesh; + PMP::orient_polygon_soup(input_points, input_triangles); + PMP::polygon_soup_to_polygon_mesh(input_points, input_triangles, mesh); + + PMP::autorefine(mesh); + + CGAL::IO::write_polygon_mesh("autorefined.off", mesh, CGAL::parameters::stream_precision(17)); + + return 0; +} From e1414de8d935cc5da43682c48b5419823b806c77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 2 Jan 2023 18:09:26 +0100 Subject: [PATCH 006/329] add debug --- .../Polygon_mesh_processing/autorefinement.h | 46 +++++++++++++++++-- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 4b7020b5615b..8dd8d28fcfcc 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -181,6 +181,17 @@ bool is_output_valid(TriangleMesh& tm , VPM vpm, TID_Map tid_map, Is_degen_map i is_border_map[target(h, etm)] = true; } +#ifdef CGAL_DEBUG_PMP_AUTOREFINE + std::cerr << std::setprecision(17); + auto verbose_fail_msg = [&](int i, const std::pair& p) + { + typename Exact_mesh::Halfedge_index h1 = halfedge(p.first, etm), h2 = halfedge(p.second, etm); + std::cerr << "DEBUG: failing at check #" << i << "\n"; + std::cerr << "DEBUG: " << etm.point(source(h1, etm)) << " " << etm.point(target(h1, etm)) << " " << etm.point(target(next(h1, etm), etm)) << " " << etm.point(source(h1, etm)) << "\n"; + std::cerr << "DEBUG: " << etm.point(source(h2, etm)) << " " << etm.point(target(h2, etm)) << " " << etm.point(target(next(h2, etm), etm)) << " " << etm.point(source(h2, etm)) << "\n"; + }; +#endif + //TODO: double check me auto skip_faces = [&](const std::pair& p) { @@ -190,13 +201,25 @@ bool is_output_valid(TriangleMesh& tm , VPM vpm, TID_Map tid_map, Is_degen_map i if (is_border_map[source(h1, etm)]) bv1.push_back(prev(h1, etm)); if (is_border_map[target(h1, etm)]) bv1.push_back(h1); if (is_border_map[target(next(h1, etm), etm)]) bv1.push_back(next(h1, etm)); - if (bv1.empty()) return false; + if (bv1.empty()) + { +#ifdef CGAL_DEBUG_PMP_AUTOREFINE + verbose_fail_msg(1, p); +#endif + return false; + } boost::container::small_vector bv2; if (is_border_map[source(h2, etm)]) bv2.push_back(prev(h2, etm)); if (is_border_map[target(h2, etm)]) bv2.push_back(h2); if (is_border_map[target(next(h2, etm), etm)]) bv2.push_back(next(h2, etm)); - if (bv2.empty()) return false; + if (bv2.empty()) + { +#ifdef CGAL_DEBUG_PMP_AUTOREFINE + verbose_fail_msg(2, p); +#endif + return false; + } //collect identical border vertices boost::container::small_vector, 3> common; @@ -205,7 +228,13 @@ bool is_output_valid(TriangleMesh& tm , VPM vpm, TID_Map tid_map, Is_degen_map i if (etm.point(target(h1, etm))==etm.point(target(h2,etm))) common.push_back(std::make_pair(h1,h2)); - if (common.empty()) return false; + if (common.empty()) + { +#ifdef CGAL_DEBUG_PMP_AUTOREFINE + verbose_fail_msg(3, p); +#endif + return false; + } switch (common.size()) { @@ -223,7 +252,12 @@ bool is_output_valid(TriangleMesh& tm , VPM vpm, TID_Map tid_map, Is_degen_map i const typename EK::Segment_3 s2(etm.point(source(common[0].second,etm)), etm.point(target(next(common[0].second,etm),etm))); if(do_intersect(t1, s2) || do_intersect(t2, s1)) + { +#ifdef CGAL_DEBUG_PMP_AUTOREFINE + verbose_fail_msg(4, p); +#endif return false; + } return true; } case 2: @@ -244,6 +278,9 @@ bool is_output_valid(TriangleMesh& tm , VPM vpm, TID_Map tid_map, Is_degen_map i etm.point(target(etm.next(h1),etm)), etm.point(source(h1,etm))) == CGAL::POSITIVE) { +#ifdef CGAL_DEBUG_PMP_AUTOREFINE + verbose_fail_msg(5, p); +#endif return false; } return true; @@ -251,6 +288,9 @@ bool is_output_valid(TriangleMesh& tm , VPM vpm, TID_Map tid_map, Is_degen_map i else { // TODO: 2 identical border vertices, no common edge on the boundary. Not sure what to do +#ifdef CGAL_DEBUG_PMP_AUTOREFINE + verbose_fail_msg(6, p); +#endif return false; } } From 85368c43c6258e67aca26af6985fb57884642901 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 2 Jan 2023 19:38:10 +0100 Subject: [PATCH 007/329] use all vertices in the check --- .../Polygon_mesh_processing/autorefinement.h | 79 ++++++------------- 1 file changed, 23 insertions(+), 56 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 8dd8d28fcfcc..fd5e7312c263 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -173,13 +173,6 @@ bool is_output_valid(TriangleMesh& tm , VPM vpm, TID_Map tid_map, Is_degen_map i Exact_mesh etm; orient_polygon_soup(soup_points, soup_triangles); polygon_soup_to_polygon_mesh(soup_points, soup_triangles, etm); - typename Exact_mesh::Property_map is_border_map = - etm.template add_property_map("v:is_border", false).first; - for(typename Exact_mesh::Halfedge_index h : etm.halfedges()) - { - if (CGAL::is_border(h, etm)) - is_border_map[target(h, etm)] = true; - } #ifdef CGAL_DEBUG_PMP_AUTOREFINE std::cerr << std::setprecision(17); @@ -197,41 +190,27 @@ bool is_output_valid(TriangleMesh& tm , VPM vpm, TID_Map tid_map, Is_degen_map i { typename Exact_mesh::Halfedge_index h1 = etm.halfedge(p.first), h2=etm.halfedge(p.second); - boost::container::small_vector bv1; - if (is_border_map[source(h1, etm)]) bv1.push_back(prev(h1, etm)); - if (is_border_map[target(h1, etm)]) bv1.push_back(h1); - if (is_border_map[target(next(h1, etm), etm)]) bv1.push_back(next(h1, etm)); - if (bv1.empty()) - { -#ifdef CGAL_DEBUG_PMP_AUTOREFINE - verbose_fail_msg(1, p); -#endif - return false; - } + boost::container::small_vector v1; + v1.push_back(prev(h1, etm)); + v1.push_back(h1); + v1.push_back(next(h1, etm)); - boost::container::small_vector bv2; - if (is_border_map[source(h2, etm)]) bv2.push_back(prev(h2, etm)); - if (is_border_map[target(h2, etm)]) bv2.push_back(h2); - if (is_border_map[target(next(h2, etm), etm)]) bv2.push_back(next(h2, etm)); - if (bv2.empty()) - { -#ifdef CGAL_DEBUG_PMP_AUTOREFINE - verbose_fail_msg(2, p); -#endif - return false; - } + boost::container::small_vector v2; + v2.push_back(prev(h2, etm)); + v2.push_back(h2); + v2.push_back(next(h2, etm)); - //collect identical border vertices + //collect identical vertices boost::container::small_vector, 3> common; - for(typename Exact_mesh::Halfedge_index h1 : bv1) - for(typename Exact_mesh::Halfedge_index h2 : bv2) + for(typename Exact_mesh::Halfedge_index h1 : v1) + for(typename Exact_mesh::Halfedge_index h2 : v2) if (etm.point(target(h1, etm))==etm.point(target(h2,etm))) common.push_back(std::make_pair(h1,h2)); if (common.empty()) { #ifdef CGAL_DEBUG_PMP_AUTOREFINE - verbose_fail_msg(3, p); + verbose_fail_msg(1, p); #endif return false; } @@ -254,7 +233,7 @@ bool is_output_valid(TriangleMesh& tm , VPM vpm, TID_Map tid_map, Is_degen_map i if(do_intersect(t1, s2) || do_intersect(t2, s1)) { #ifdef CGAL_DEBUG_PMP_AUTOREFINE - verbose_fail_msg(4, p); + verbose_fail_msg(2, p); #endif return false; } @@ -266,33 +245,21 @@ bool is_output_valid(TriangleMesh& tm , VPM vpm, TID_Map tid_map, Is_degen_map i h1 = next(common[0].first, etm) == common[1].first ? common[1].first : common[0].first; h2 = next(common[0].second, etm) == common[1].second ? common[1].second : common[0].second; - if ( is_border(etm.opposite(h1), etm) && - is_border(etm.opposite(h2), etm) ) + if( CGAL::coplanar(etm.point(source(h1,etm)), + etm.point(target(h1,etm)), + etm.point(target(etm.next(h1),etm)), + etm.point(source(h1,etm))) && + CGAL::coplanar_orientation(etm.point(source(h1,etm)), + etm.point(target(h1,etm)), + etm.point(target(etm.next(h1),etm)), + etm.point(source(h1,etm))) == CGAL::POSITIVE) { - if( CGAL::coplanar(etm.point(source(h1,etm)), - etm.point(target(h1,etm)), - etm.point(target(etm.next(h1),etm)), - etm.point(source(h1,etm))) && - CGAL::coplanar_orientation(etm.point(source(h1,etm)), - etm.point(target(h1,etm)), - etm.point(target(etm.next(h1),etm)), - etm.point(source(h1,etm))) == CGAL::POSITIVE) - { #ifdef CGAL_DEBUG_PMP_AUTOREFINE - verbose_fail_msg(5, p); -#endif - return false; - } - return true; - } - else - { - // TODO: 2 identical border vertices, no common edge on the boundary. Not sure what to do -#ifdef CGAL_DEBUG_PMP_AUTOREFINE - verbose_fail_msg(6, p); + verbose_fail_msg(3, p); #endif return false; } + return true; } default: // size == 3 return true; From 944475f169213f38a04637480f0be7aaa080b98c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 2 Jan 2023 19:38:38 +0100 Subject: [PATCH 008/329] triangulate input faces --- .../examples/Polygon_mesh_processing/soup_autorefinement.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp index fa1f5d686907..8ca983aa31c3 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -30,6 +31,7 @@ int main(int argc, char** argv) Mesh mesh; PMP::orient_polygon_soup(input_points, input_triangles); PMP::polygon_soup_to_polygon_mesh(input_points, input_triangles, mesh); + PMP::triangulate_faces(mesh); PMP::autorefine(mesh); From 2b77fcd094859cd07853b1ae02434b05d5a277a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 3 Jan 2023 18:22:14 +0100 Subject: [PATCH 009/329] faster implementation + fix intersection segments + check --- .../Polygon_mesh_processing/autorefinement.h | 246 ++++++++++-------- 1 file changed, 133 insertions(+), 113 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index fd5e7312c263..01188d4d6b14 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -26,7 +27,7 @@ #include #include -#ifndef NDEBUG +#ifdef CGAL_DEBUG_PMP_AUTOREFINE // debug #include #endif @@ -46,12 +47,42 @@ void generate_subtriangles(const typename EK::Triangle_3& t, std::vector& new_triangles) { typedef CGAL::Projection_traits_3 P_traits; - // typedef CGAL::Exact_intersections_tag Itag; - typedef CGAL::No_constraint_intersection_requiring_constructions_tag Itag; - typedef CGAL::Constrained_Delaunay_triangulation_2 CDT; - - - P_traits cdt_traits(normal(t[0], t[1], t[2])); + typedef CGAL::Exact_intersections_tag Itag; + //typedef CGAL::No_constraint_intersection_requiring_constructions_tag Itag; + typedef CGAL::Constrained_Delaunay_triangulation_2 CDT_base; + typedef CGAL::Constrained_triangulation_plus_2 CDT; + + typename EK::Vector_3 n = normal(t[0], t[1], t[2]); + //~ bool orientation_flipped = false; + //~ if (n.x() < 0) + //~ { + //~ orientation_flipped = true; + //~ n = -n; + //~ } + //~ else + //~ { + //~ if (n.x()==0) + //~ { + //~ if (n.y() < 0) + //~ { + //~ orientation_flipped = true; + //~ n = -n; + //~ } + //~ else + //~ { + //~ if (n.y()==0) + //~ { + //~ if (n.z() < 0) + //~ { + //~ orientation_flipped = true; + //~ n = -n; + //~ } + //~ } + //~ } + //~ } + //~ } + + P_traits cdt_traits(n); CDT cdt(cdt_traits); cdt.insert_outside_affine_hull(t[0]); @@ -65,12 +96,41 @@ void generate_subtriangles(const typename EK::Triangle_3& t, for (const typename EK::Point_3& p : points) cdt.insert(p); - for (typename CDT::Face_handle fh : cdt.finite_face_handles()) - { - new_triangles.emplace_back(fh->vertex(0)->point(), - fh->vertex(cdt.ccw(0))->point(), - fh->vertex(cdt.cw(0))->point()); - } + //~ if (orientation_flipped) + //~ for (typename CDT::Face_handle fh : cdt.finite_face_handles()) + //~ { + //~ new_triangles.emplace_back(fh->vertex(0)->point(), + //~ fh->vertex(cdt.cw(0))->point(), + //~ fh->vertex(cdt.ccw(0))->point()); + //~ } + //~ else +#ifdef CGAL_DEBUG_PMP_AUTOREFINE_DUMP_TRIANGULATIONS + static int k = 0; + std::stringstream buffer; + buffer.precision(17); + int nbt=0; +#endif + for (typename CDT::Face_handle fh : cdt.finite_face_handles()) + { + new_triangles.emplace_back(fh->vertex(0)->point(), + fh->vertex(cdt.ccw(0))->point(), + fh->vertex(cdt.cw(0))->point()); +#ifdef CGAL_DEBUG_PMP_AUTOREFINE_DUMP_TRIANGULATIONS + ++nbt; + buffer << fh->vertex(0)->point() << "\n"; + buffer << fh->vertex(cdt.ccw(0))->point() << "\n"; + buffer << fh->vertex(cdt.cw(0))->point() << "\n"; +#endif + } + +#ifdef CGAL_DEBUG_PMP_AUTOREFINE_DUMP_TRIANGULATIONS + std::ofstream dump("triangulation_"+std::to_string(k)+".off"); + dump << "OFF\n" << 3*nbt << " " << nbt << " 0\n"; + dump << buffer.str(); + for (int i=0; i @@ -106,69 +166,31 @@ struct Intersection_visitor void operator()(const typename EK::Triangle_3& t) { - for (std::size_t i=1; i<3; ++i) + for (std::size_t i=0; i<3; ++i) { - typename EK::Segment_3 s(t[i-1], t[i]); + typename EK::Segment_3 s(t[i], t[(i+1)%3]); all_segments_1.push_back(s); all_segments_2.push_back(s); } + } void operator()(const std::vector& poly) { std::size_t nbp = poly.size(); - for (std::size_t i=1; i -bool is_output_valid(TriangleMesh& tm , VPM vpm, TID_Map tid_map, Is_degen_map is_degen, const std::vector< std::vector>>& triangles) +template +bool is_output_valid(std::vector> soup_points, + std::vector > soup_triangles) { - typedef typename Kernel_traits::value_type>::type IK; - typedef boost::graph_traits Graph_traits; - typedef typename Graph_traits::face_descriptor face_descriptor; - typedef typename Graph_traits::halfedge_descriptor halfedge_descriptor; - - std::vector soup_points; - std::vector > soup_triangles; - Cartesian_converter to_exact; - std::map point_id_map; - - auto get_point_id = [&](const typename EK::Point_3& pt) - { - auto insert_res = point_id_map.insert(std::make_pair(pt, soup_points.size())); - if (insert_res.second) - soup_points.push_back(pt); - return insert_res.first->second; - }; - - for (face_descriptor f : faces(tm)) - { - if (get(is_degen, f)) continue; // skip degenerate faces - int tid = get(tid_map, f); - if (tid == -1) - { - halfedge_descriptor h = halfedge(f, tm); - soup_triangles.emplace_back( - CGAL::make_array(get_point_id(to_exact(get(vpm,source(h, tm)))), - get_point_id(to_exact(get(vpm,target(h, tm)))), - get_point_id(to_exact(get(vpm,target(next(h, tm), tm))))) - ); - } - else - { - for (const typename EK::Triangle_3& t : triangles[tid]) - { - soup_triangles.emplace_back(CGAL::make_array(get_point_id(t[0]), get_point_id(t[1]), get_point_id(t[2]))); - } - } - } - typedef Surface_mesh Exact_mesh; Exact_mesh etm; orient_polygon_soup(soup_points, soup_triangles); @@ -248,11 +270,11 @@ bool is_output_valid(TriangleMesh& tm , VPM vpm, TID_Map tid_map, Is_degen_map i if( CGAL::coplanar(etm.point(source(h1,etm)), etm.point(target(h1,etm)), etm.point(target(etm.next(h1),etm)), - etm.point(source(h1,etm))) && + etm.point(target(etm.next(h2),etm))) && CGAL::coplanar_orientation(etm.point(source(h1,etm)), etm.point(target(h1,etm)), etm.point(target(etm.next(h1),etm)), - etm.point(source(h1,etm))) == CGAL::POSITIVE) + etm.point(target(etm.next(h2),etm))) == CGAL::POSITIVE) { #ifdef CGAL_DEBUG_PMP_AUTOREFINE verbose_fail_msg(3, p); @@ -346,18 +368,22 @@ void autorefine_soup_output(const TriangleMesh& tm, // init the vector of triangles used for the autorefinement of triangles typedef CGAL::Exact_predicates_exact_constructions_kernel EK; - std::vector< std::vector > triangles(tid+1); + std::vector< EK::Triangle_3 > triangles(tid+1); Cartesian_converter to_exact; for(face_descriptor f : intersected_faces) { halfedge_descriptor h = halfedge(f, tm); - triangles[get(tid_map, f)].emplace_back( + triangles[get(tid_map, f)]= EK::Triangle_3( to_exact( get(vpm, source(h, tm)) ), to_exact( get(vpm, target(h, tm)) ), to_exact( get(vpm, target(next(h, tm), tm)) ) ); } + std::vector< std::vector > all_segments(triangles.size()); + std::vector< std::vector > all_points(triangles.size()); + + typename EK::Intersect_3 intersection = EK().intersect_3_object(); for (const Pair_of_faces& p : si_pairs) { @@ -366,73 +392,59 @@ void autorefine_soup_output(const TriangleMesh& tm, if (i1==-1 || i2==-1) continue; //skip degenerate faces - std::size_t nbt_1 = triangles[i1].size(), - nbt_2 = triangles[i2].size(); + const EK::Triangle_3& t1 = triangles[i1]; + const EK::Triangle_3& t2 = triangles[i2]; - std::vector< std::vector > all_segments_1(nbt_1); - std::vector< std::vector > all_segments_2(nbt_2); - std::vector< std::vector > all_points_1(nbt_1); - std::vector< std::vector > all_points_2(nbt_2); + auto inter = intersection(t1, t2); - std::vector t1_subtriangles, t2_subtriangles; - for (std::size_t it1=0; it1 intersection_visitor(all_segments_1[it1], all_segments_2[it2], - all_points_1[it1], all_points_2[it2]); + autorefine_impl::Intersection_visitor intersection_visitor(all_segments[i1], all_segments[i2], + all_points[i1], all_points[i2]); - boost::apply_visitor(intersection_visitor, *inter); - } - } + boost::apply_visitor(intersection_visitor, *inter); } + } - // now refine triangles - std::vector new_triangles; - for(std::size_t it1=0; it1(triangles[i1][it1], all_segments_1[it1], all_points_1[it1], new_triangles); - } - triangles[i1].swap(new_triangles); - new_triangles.clear(); - for(std::size_t it2=0; it2(triangles[i2][it2], all_segments_2[it2], all_points_2[it2], new_triangles); - } - triangles[i2].swap(new_triangles); + // now refine triangles + std::vector new_triangles; + for(std::size_t ti=0; ti(triangles[ti], all_segments[ti], all_points[ti], new_triangles); } - CGAL_assertion( autorefine_impl::is_output_valid(tm, vpm, tid_map, is_degen, triangles) ); // brute force output: create a soup, orient and to-mesh - // WARNING: there is no reason when using double that identical exact points are identical in double Cartesian_converter to_input; std::map point_id_map; +#if ! defined(CGAL_NDEBUG) || defined(CGAL_DEBUG_PMP_AUTOREFINE) + std::vector exact_soup_points; +#endif for (vertex_descriptor v : vertices(tm)) { if (point_id_map.insert(std::make_pair(to_exact(get(vpm,v)), soup_points.size())).second) + { soup_points.push_back(get(vpm,v)); +#if ! defined(CGAL_NDEBUG) || defined(CGAL_DEBUG_PMP_AUTOREFINE) + exact_soup_points.push_back(to_exact(get(vpm,v))); +#endif + } } auto get_point_id = [&](const typename EK::Point_3& pt) { auto insert_res = point_id_map.insert(std::make_pair(pt, soup_points.size())); if (insert_res.second) + { soup_points.push_back(to_input(pt)); +#if ! defined(CGAL_NDEBUG) || defined(CGAL_DEBUG_PMP_AUTOREFINE) + exact_soup_points.push_back(pt); +#endif + } return insert_res.first->second; }; @@ -450,14 +462,22 @@ void autorefine_soup_output(const TriangleMesh& tm, get_point_id(to_exact(get(vpm,target(next(h, tm), tm))))) ); } - else - { - for (const typename EK::Triangle_3& t : triangles[tid]) - { - soup_triangles.emplace_back(CGAL::make_array(get_point_id(t[0]), get_point_id(t[1]), get_point_id(t[2]))); - } - } } + for (const typename EK::Triangle_3& t : new_triangles) + { + soup_triangles.emplace_back(CGAL::make_array(get_point_id(t[0]), get_point_id(t[1]), get_point_id(t[2]))); + } + + +#ifndef CGAL_NDEBUG + CGAL_assertion( autorefine_impl::is_output_valid(exact_soup_points, soup_triangles) ); +#endif + +#ifdef CGAL_DEBUG_PMP_AUTOREFINE + autorefine_impl::is_output_valid(exact_soup_points, soup_triangles); + throw std::runtime_error("invalid output"); +#endif + } #endif From d92d37c476c40e909db3b8a27b20e3968c4e1f28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 3 Jan 2023 18:44:52 +0100 Subject: [PATCH 010/329] fix condition --- .../include/CGAL/Polygon_mesh_processing/autorefinement.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 01188d4d6b14..d18826fc2f1e 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -474,7 +474,7 @@ void autorefine_soup_output(const TriangleMesh& tm, #endif #ifdef CGAL_DEBUG_PMP_AUTOREFINE - autorefine_impl::is_output_valid(exact_soup_points, soup_triangles); + if (!autorefine_impl::is_output_valid(exact_soup_points, soup_triangles)) throw std::runtime_error("invalid output"); #endif From 34e8d7ee420489459d88a90a83a277cc9e071caa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 4 Jan 2023 16:51:55 +0100 Subject: [PATCH 011/329] disable CDT+ that is slower and add debug --- .../Polygon_mesh_processing/autorefinement.h | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index d18826fc2f1e..3ec807450421 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -32,6 +32,10 @@ #include #endif +#ifndef CGAL_PMP_AUTOREFINE_VERBOSE +#define CGAL_PMP_AUTOREFINE_VERBOSE(MSG) +#endif + #include namespace CGAL { @@ -49,8 +53,12 @@ void generate_subtriangles(const typename EK::Triangle_3& t, typedef CGAL::Projection_traits_3 P_traits; typedef CGAL::Exact_intersections_tag Itag; //typedef CGAL::No_constraint_intersection_requiring_constructions_tag Itag; - typedef CGAL::Constrained_Delaunay_triangulation_2 CDT_base; - typedef CGAL::Constrained_triangulation_plus_2 CDT; + + + //typedef CGAL::Constrained_Delaunay_triangulation_2 CDT_base; + //typedef CGAL::Constrained_triangulation_plus_2 CDT; + + typedef CGAL::Constrained_Delaunay_triangulation_2 CDT; typename EK::Vector_3 n = normal(t[0], t[1], t[2]); //~ bool orientation_flipped = false; @@ -329,6 +337,7 @@ void autorefine_soup_output(const TriangleMesh& tm, std::vector si_pairs; // collect intersecting pairs of triangles + CGAL_PMP_AUTOREFINE_VERBOSE("collect intersecting pairs"); self_intersections(tm, std::back_inserter(si_pairs), np); if (si_pairs.empty()) return; @@ -384,6 +393,7 @@ void autorefine_soup_output(const TriangleMesh& tm, std::vector< std::vector > all_points(triangles.size()); + CGAL_PMP_AUTOREFINE_VERBOSE("compute intersections"); typename EK::Intersect_3 intersection = EK().intersect_3_object(); for (const Pair_of_faces& p : si_pairs) { @@ -406,6 +416,7 @@ void autorefine_soup_output(const TriangleMesh& tm, } } + CGAL_PMP_AUTOREFINE_VERBOSE("triangulate faces"); // now refine triangles std::vector new_triangles; for(std::size_t ti=0; ti to_input; std::map point_id_map; #if ! defined(CGAL_NDEBUG) || defined(CGAL_DEBUG_PMP_AUTOREFINE) @@ -468,16 +480,17 @@ void autorefine_soup_output(const TriangleMesh& tm, soup_triangles.emplace_back(CGAL::make_array(get_point_id(t[0]), get_point_id(t[1]), get_point_id(t[2]))); } - #ifndef CGAL_NDEBUG + CGAL_PMP_AUTOREFINE_VERBOSE("check soup"); CGAL_assertion( autorefine_impl::is_output_valid(exact_soup_points, soup_triangles) ); #endif #ifdef CGAL_DEBUG_PMP_AUTOREFINE + CGAL_PMP_AUTOREFINE_VERBOSE("check soup"); if (!autorefine_impl::is_output_valid(exact_soup_points, soup_triangles)) throw std::runtime_error("invalid output"); #endif - + CGAL_PMP_AUTOREFINE_VERBOSE("done"); } #endif From e94c7be4aa72ca2b481e15265ec30f5bad92abec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 5 Jan 2023 08:44:32 +0100 Subject: [PATCH 012/329] update doc + TODOs --- .../Polygon_mesh_processing/autorefinement.h | 31 +++---------------- 1 file changed, 4 insertions(+), 27 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 3ec807450421..0711ad71e21c 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -1,3 +1,5 @@ +//TODO: add for soup face the id of the input face. not sure it is easy to report intersection edge as a pair of vertex id + // Copyright (c) 2023 GeometryFactory (France). // All rights reserved. // @@ -347,6 +349,7 @@ void autorefine_soup_output(const TriangleMesh& tm, typedef typename boost::property_map::const_type Is_degen_map; Is_degen_map is_degen = get(Degen_property_tag(), tm); +// TODO: we already have this test in bbox inter when it report (f,f) for(face_descriptor f : faces(tm)) put(is_degen, f, is_degenerate_triangle_face(f, tm, np)); @@ -496,10 +499,7 @@ void autorefine_soup_output(const TriangleMesh& tm, /** * \ingroup PMP_corefinement_grp - * \link coref_def_subsec autorefines \endlink `tm`. Refines a triangle mesh - * so that no triangles intersects in their interior. - * Self-intersection edges will be marked as constrained. If an edge that was marked as - * constrained is split, its sub-edges will be marked as constrained as well. + * refines a triangle mesh so that no triangles intersects in their interior. * * @tparam TriangleMesh a model of `HalfedgeListGraph`, `FaceListGraph`, and `MutableFaceGraph` * @tparam NamedParameters a sequence of \ref namedparameters @@ -524,29 +524,6 @@ void autorefine_soup_output(const TriangleMesh& tm, * must be available in `TriangleMesh`.} * \cgalParamNEnd * - * \cgalParamNBegin{edge_is_constrained_map} - * \cgalParamDescription{a property map containing the constrained-or-not status of each edge of `tm`} - * \cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits::%edge_descriptor` - * as key type and `bool` as value type} - * \cgalParamDefault{a constant property map returning `false` for any edge} - * \cgalParamNEnd - * - * \cgalParamNBegin{face_index_map} - * \cgalParamDescription{a property map associating to each face of `tm` a unique index between `0` and `num_faces(tm) - 1`} - * \cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits::%face_descriptor` - * as key type and `std::size_t` as value type} - * \cgalParamDefault{an automatically indexed internal map} - * \cgalParamExtra{If the property map is writable, the indices of the faces of `tm1` and `tm2` - * will be set after the corefinement is done.} - * \cgalParamNEnd - * - * \cgalParamNBegin{visitor} - * \cgalParamDescription{a visitor used to track the creation of new faces} - * \cgalParamType{a class model of `PMPCorefinementVisitor`} - * \cgalParamDefault{`Corefinement::Default_visitor`} - * \cgalParamNEnd - * \cgalNamedParamsEnd - * */ template From 370d9134a08db1f422e6038dfa7e94ea695efea2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 9 Jan 2023 17:59:56 +0100 Subject: [PATCH 013/329] use insertion by range --- .../CGAL/Polygon_mesh_processing/autorefinement.h | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 0711ad71e21c..b2786386205f 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -54,13 +54,10 @@ void generate_subtriangles(const typename EK::Triangle_3& t, { typedef CGAL::Projection_traits_3 P_traits; typedef CGAL::Exact_intersections_tag Itag; - //typedef CGAL::No_constraint_intersection_requiring_constructions_tag Itag; - - //typedef CGAL::Constrained_Delaunay_triangulation_2 CDT_base; + typedef CGAL::Constrained_Delaunay_triangulation_2 CDT_2; //typedef CGAL::Constrained_triangulation_plus_2 CDT; - - typedef CGAL::Constrained_Delaunay_triangulation_2 CDT; + typedef CDT_2 CDT; typename EK::Vector_3 n = normal(t[0], t[1], t[2]); //~ bool orientation_flipped = false; @@ -100,11 +97,9 @@ void generate_subtriangles(const typename EK::Triangle_3& t, typename CDT::Vertex_handle v = cdt.tds().insert_dim_up(cdt.infinite_vertex(), false); v->set_point(t[2]); - for (const typename EK::Segment_3& s : segments) - cdt.insert_constraint(s[0], s[1]); + cdt.insert_constraints(segments.begin(), segments.end()); + cdt.insert(points.begin(), points.end()); - for (const typename EK::Point_3& p : points) - cdt.insert(p); //~ if (orientation_flipped) //~ for (typename CDT::Face_handle fh : cdt.finite_face_handles()) From 9ba370a22902afb08d0af7629b7383bba785ac57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 10 Jan 2023 14:40:02 +0100 Subject: [PATCH 014/329] use a canonical orientation --- .../Polygon_mesh_processing/autorefinement.h | 58 ++++++------------- 1 file changed, 17 insertions(+), 41 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index b2786386205f..881ffcc8796b 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -60,55 +60,26 @@ void generate_subtriangles(const typename EK::Triangle_3& t, typedef CDT_2 CDT; typename EK::Vector_3 n = normal(t[0], t[1], t[2]); - //~ bool orientation_flipped = false; - //~ if (n.x() < 0) - //~ { - //~ orientation_flipped = true; - //~ n = -n; - //~ } - //~ else - //~ { - //~ if (n.x()==0) - //~ { - //~ if (n.y() < 0) - //~ { - //~ orientation_flipped = true; - //~ n = -n; - //~ } - //~ else - //~ { - //~ if (n.y()==0) - //~ { - //~ if (n.z() < 0) - //~ { - //~ orientation_flipped = true; - //~ n = -n; - //~ } - //~ } - //~ } - //~ } - //~ } + typename EK::Point_3 o(0,0,0); + + bool orientation_flipped = false; + if ( typename EK::Less_xyz_3()(o+n,o) ) + { + n=-n; + orientation_flipped = true; + } P_traits cdt_traits(n); CDT cdt(cdt_traits); cdt.insert_outside_affine_hull(t[0]); cdt.insert_outside_affine_hull(t[1]); - typename CDT::Vertex_handle v = cdt.tds().insert_dim_up(cdt.infinite_vertex(), false); + typename CDT::Vertex_handle v = cdt.tds().insert_dim_up(cdt.infinite_vertex(), orientation_flipped); v->set_point(t[2]); cdt.insert_constraints(segments.begin(), segments.end()); cdt.insert(points.begin(), points.end()); - - //~ if (orientation_flipped) - //~ for (typename CDT::Face_handle fh : cdt.finite_face_handles()) - //~ { - //~ new_triangles.emplace_back(fh->vertex(0)->point(), - //~ fh->vertex(cdt.cw(0))->point(), - //~ fh->vertex(cdt.ccw(0))->point()); - //~ } - //~ else #ifdef CGAL_DEBUG_PMP_AUTOREFINE_DUMP_TRIANGULATIONS static int k = 0; std::stringstream buffer; @@ -117,9 +88,14 @@ void generate_subtriangles(const typename EK::Triangle_3& t, #endif for (typename CDT::Face_handle fh : cdt.finite_face_handles()) { - new_triangles.emplace_back(fh->vertex(0)->point(), - fh->vertex(cdt.ccw(0))->point(), - fh->vertex(cdt.cw(0))->point()); + if (orientation_flipped) + new_triangles.emplace_back(fh->vertex(0)->point(), + fh->vertex(cdt.cw(0))->point(), + fh->vertex(cdt.ccw(0))->point()); + else + new_triangles.emplace_back(fh->vertex(0)->point(), + fh->vertex(cdt.ccw(0))->point(), + fh->vertex(cdt.cw(0))->point()); #ifdef CGAL_DEBUG_PMP_AUTOREFINE_DUMP_TRIANGULATIONS ++nbt; buffer << fh->vertex(0)->point() << "\n"; From f9668e279f5f7f2acb49a735adb9f6c15e110841 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 11 Jan 2023 11:14:05 +0100 Subject: [PATCH 015/329] use self-intersection test for soup for checking the validity of the output on some cases it seems twice faster --- .../Polygon_mesh_processing/autorefinement.h | 122 +----------------- 1 file changed, 4 insertions(+), 118 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 881ffcc8796b..9393e197a195 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -29,11 +29,6 @@ #include #include -#ifdef CGAL_DEBUG_PMP_AUTOREFINE -// debug -#include -#endif - #ifndef CGAL_PMP_AUTOREFINE_VERBOSE #define CGAL_PMP_AUTOREFINE_VERBOSE(MSG) #endif @@ -168,115 +163,6 @@ struct Intersection_visitor } }; -template -bool is_output_valid(std::vector> soup_points, - std::vector > soup_triangles) -{ - typedef Surface_mesh Exact_mesh; - Exact_mesh etm; - orient_polygon_soup(soup_points, soup_triangles); - polygon_soup_to_polygon_mesh(soup_points, soup_triangles, etm); - -#ifdef CGAL_DEBUG_PMP_AUTOREFINE - std::cerr << std::setprecision(17); - auto verbose_fail_msg = [&](int i, const std::pair& p) - { - typename Exact_mesh::Halfedge_index h1 = halfedge(p.first, etm), h2 = halfedge(p.second, etm); - std::cerr << "DEBUG: failing at check #" << i << "\n"; - std::cerr << "DEBUG: " << etm.point(source(h1, etm)) << " " << etm.point(target(h1, etm)) << " " << etm.point(target(next(h1, etm), etm)) << " " << etm.point(source(h1, etm)) << "\n"; - std::cerr << "DEBUG: " << etm.point(source(h2, etm)) << " " << etm.point(target(h2, etm)) << " " << etm.point(target(next(h2, etm), etm)) << " " << etm.point(source(h2, etm)) << "\n"; - }; -#endif - - //TODO: double check me - auto skip_faces = [&](const std::pair& p) - { - typename Exact_mesh::Halfedge_index h1 = etm.halfedge(p.first), h2=etm.halfedge(p.second); - - boost::container::small_vector v1; - v1.push_back(prev(h1, etm)); - v1.push_back(h1); - v1.push_back(next(h1, etm)); - - boost::container::small_vector v2; - v2.push_back(prev(h2, etm)); - v2.push_back(h2); - v2.push_back(next(h2, etm)); - - //collect identical vertices - boost::container::small_vector, 3> common; - for(typename Exact_mesh::Halfedge_index h1 : v1) - for(typename Exact_mesh::Halfedge_index h2 : v2) - if (etm.point(target(h1, etm))==etm.point(target(h2,etm))) - common.push_back(std::make_pair(h1,h2)); - - if (common.empty()) - { -#ifdef CGAL_DEBUG_PMP_AUTOREFINE - verbose_fail_msg(1, p); -#endif - return false; - } - - switch (common.size()) - { - case 1: - { - // geometric check if the opposite segments intersect the triangles - const typename EK::Triangle_3 t1(etm.point(source(h1,etm)), - etm.point(target(h1,etm)), - etm.point(target(next(h1,etm),etm))); - const typename EK::Triangle_3 t2(etm.point(source(h2,etm)), - etm.point(target(h2,etm)), - etm.point(target(next(h2,etm),etm))); - - const typename EK::Segment_3 s1(etm.point(source(common[0].first,etm)), etm.point(target(next(common[0].first,etm),etm))); - const typename EK::Segment_3 s2(etm.point(source(common[0].second,etm)), etm.point(target(next(common[0].second,etm),etm))); - - if(do_intersect(t1, s2) || do_intersect(t2, s1)) - { -#ifdef CGAL_DEBUG_PMP_AUTOREFINE - verbose_fail_msg(2, p); -#endif - return false; - } - return true; - } - case 2: - { - // shared edge - h1 = next(common[0].first, etm) == common[1].first ? common[1].first : common[0].first; - h2 = next(common[0].second, etm) == common[1].second ? common[1].second : common[0].second; - - if( CGAL::coplanar(etm.point(source(h1,etm)), - etm.point(target(h1,etm)), - etm.point(target(etm.next(h1),etm)), - etm.point(target(etm.next(h2),etm))) && - CGAL::coplanar_orientation(etm.point(source(h1,etm)), - etm.point(target(h1,etm)), - etm.point(target(etm.next(h1),etm)), - etm.point(target(etm.next(h2),etm))) == CGAL::POSITIVE) - { -#ifdef CGAL_DEBUG_PMP_AUTOREFINE - verbose_fail_msg(3, p); -#endif - return false; - } - return true; - } - default: // size == 3 - return true; - } - }; - - std::vector< std::pair > si_faces; - self_intersections(etm, - CGAL::filter_output_iterator(std::back_inserter(si_faces), - skip_faces)); - - return si_faces.empty(); -} - } // end of autorefine_impl template @@ -456,13 +342,13 @@ void autorefine_soup_output(const TriangleMesh& tm, #ifndef CGAL_NDEBUG CGAL_PMP_AUTOREFINE_VERBOSE("check soup"); - CGAL_assertion( autorefine_impl::is_output_valid(exact_soup_points, soup_triangles) ); -#endif - + CGAL_assertion( !does_triangle_soup_self_intersect(exact_soup_points, soup_triangles) ); +#else #ifdef CGAL_DEBUG_PMP_AUTOREFINE CGAL_PMP_AUTOREFINE_VERBOSE("check soup"); - if (!autorefine_impl::is_output_valid(exact_soup_points, soup_triangles)) + if (does_triangle_soup_self_intersect(exact_soup_points, soup_triangles)) throw std::runtime_error("invalid output"); +#endif #endif CGAL_PMP_AUTOREFINE_VERBOSE("done"); } From 7d1582ddbb9ad7bf6e7d8872eb08101254b7e68a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 11 Jan 2023 14:00:32 +0100 Subject: [PATCH 016/329] avoid doing twice the degenerate test --- .../include/CGAL/Polygon_mesh_processing/autorefinement.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 9393e197a195..283e139eb1c6 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -206,9 +206,11 @@ void autorefine_soup_output(const TriangleMesh& tm, typedef typename boost::property_map::const_type Is_degen_map; Is_degen_map is_degen = get(Degen_property_tag(), tm); -// TODO: we already have this test in bbox inter when it report (f,f) for(face_descriptor f : faces(tm)) - put(is_degen, f, is_degenerate_triangle_face(f, tm, np)); + put(is_degen, f, false); + for (const Pair_of_faces& p : si_pairs) + if (p.first==p.second) // bbox inter reports (f,f) for degenerate faces + put(is_degen, p.first, true); // assign an id per triangle involved in an intersection // + the faces involved in the intersection From 822e65b3cf93b51855d14349d96cdbcf09cff85f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 13 Jan 2023 09:35:51 +0100 Subject: [PATCH 017/329] build visitor once for all --- .../Polygon_mesh_processing/autorefinement.h | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 283e139eb1c6..ea1c0de07eba 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -54,6 +54,7 @@ void generate_subtriangles(const typename EK::Triangle_3& t, //typedef CGAL::Constrained_triangulation_plus_2 CDT; typedef CDT_2 CDT; + // positive triangle normal typename EK::Vector_3 n = normal(t[0], t[1], t[2]); typename EK::Point_3 o(0,0,0); @@ -112,32 +113,32 @@ void generate_subtriangles(const typename EK::Triangle_3& t, template struct Intersection_visitor { - std::vector& all_segments_1; - std::vector& all_segments_2; - std::vector& all_points_1; - std::vector& all_points_2; - - Intersection_visitor(std::vector& all_segments_1, - std::vector& all_segments_2, - std::vector& all_points_1, - std::vector& all_points_2) - : all_segments_1(all_segments_1) - , all_segments_2(all_segments_2) - , all_points_1(all_points_1) - , all_points_2(all_points_2) + std::vector< std::vector >& all_segments; + std::vector< std::vector >& all_points; + std::pair ids; + + Intersection_visitor(std::vector< std::vector >& all_segments, + std::vector< std::vector >& all_points) + : all_segments (all_segments) + , all_points(all_points) {} + void set_triangle_ids(int i1, int i2) + { + ids = {i1, i2}; + } + typedef void result_type; void operator()(const typename EK::Point_3& p) { - all_points_1.push_back(p); - all_points_2.push_back(p); + all_points[ids.first].push_back(p); + all_points[ids.second].push_back(p); } void operator()(const typename EK::Segment_3& s) { - all_segments_1.push_back(s); - all_segments_2.push_back(s); + all_segments[ids.first].push_back(s); + all_segments[ids.second].push_back(s); } void operator()(const typename EK::Triangle_3& t) @@ -145,8 +146,8 @@ struct Intersection_visitor for (std::size_t i=0; i<3; ++i) { typename EK::Segment_3 s(t[i], t[(i+1)%3]); - all_segments_1.push_back(s); - all_segments_2.push_back(s); + all_segments[ids.first].push_back(s); + all_segments[ids.second].push_back(s); } } @@ -157,8 +158,8 @@ struct Intersection_visitor for (std::size_t i=0; i > all_segments(triangles.size()); std::vector< std::vector > all_points(triangles.size()); - CGAL_PMP_AUTOREFINE_VERBOSE("compute intersections"); typename EK::Intersect_3 intersection = EK().intersect_3_object(); + autorefine_impl::Intersection_visitor intersection_visitor(all_segments, all_points); + for (const Pair_of_faces& p : si_pairs) { int i1 = get(tid_map, p.first), @@ -271,9 +273,7 @@ void autorefine_soup_output(const TriangleMesh& tm, if (inter != boost::none) { - autorefine_impl::Intersection_visitor intersection_visitor(all_segments[i1], all_segments[i2], - all_points[i1], all_points[i2]); - + intersection_visitor.set_triangle_ids(i1, i2); boost::apply_visitor(intersection_visitor, *inter); } } From 9c2de3ee7974a1ccd5e72c73bbf60e03366d5523 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 13 Jan 2023 11:42:14 +0100 Subject: [PATCH 018/329] handle soup as input --- .../Polygon_mesh_processing/autorefinement.h | 123 ++++++++---------- 1 file changed, 53 insertions(+), 70 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index ea1c0de07eba..290dde253324 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -28,6 +28,7 @@ // output #include #include +#include #ifndef CGAL_PMP_AUTOREFINE_VERBOSE #define CGAL_PMP_AUTOREFINE_VERBOSE(MSG) @@ -166,8 +167,9 @@ struct Intersection_visitor } // end of autorefine_impl -template -void autorefine_soup_output(const TriangleMesh& tm, +template +void autorefine_soup_output(const PointRange& input_points, + const TriIdsRange& id_triples, std::vector& soup_points, std::vector >& soup_triangles, const NamedParameters& np = parameters::default_values()) @@ -175,12 +177,9 @@ void autorefine_soup_output(const TriangleMesh& tm, using parameters::choose_parameter; using parameters::get_parameter; - typedef typename GetGeomTraits::type GT; - GT traits = choose_parameter(get_parameter(np, internal_np::geom_traits)); - - typedef typename GetVertexPointMap::const_type VPM; - VPM vpm = choose_parameter(get_parameter(np, internal_np::vertex_point), - get_const_property_map(vertex_point, tm)); + typedef typename GetPolygonSoupGeomTraits::type GT; + typedef typename GetPointMap::const_type Point_map; + Point_map pm = choose_parameter(get_parameter(np, internal_np::point_map)); typedef typename internal_np::Lookup_named_param_def < internal_np::concurrency_tag_t, @@ -188,68 +187,54 @@ void autorefine_soup_output(const TriangleMesh& tm, Sequential_tag > ::type Concurrency_tag; - typedef boost::graph_traits Graph_traits; - typedef typename Graph_traits::face_descriptor face_descriptor; - typedef typename Graph_traits::halfedge_descriptor halfedge_descriptor; - typedef typename Graph_traits::vertex_descriptor vertex_descriptor; - typedef std::pair Pair_of_faces; + typedef std::size_t Input_TID; + typedef std::pair Pair_of_triangle_ids; - std::vector si_pairs; + std::vector si_pairs; // collect intersecting pairs of triangles CGAL_PMP_AUTOREFINE_VERBOSE("collect intersecting pairs"); - self_intersections(tm, std::back_inserter(si_pairs), np); + triangle_soup_self_intersections(input_points, id_triples, std::back_inserter(si_pairs), np); if (si_pairs.empty()) return; // mark degenerate faces so that we can ignore them - typedef CGAL::dynamic_face_property_t Degen_property_tag; - typedef typename boost::property_map::const_type Is_degen_map; - Is_degen_map is_degen = get(Degen_property_tag(), tm); + std::vector is_degen(id_triples.size(), false); - for(face_descriptor f : faces(tm)) - put(is_degen, f, false); - for (const Pair_of_faces& p : si_pairs) + for (const Pair_of_triangle_ids& p : si_pairs) if (p.first==p.second) // bbox inter reports (f,f) for degenerate faces - put(is_degen, p.first, true); + is_degen[p.first] = true; // assign an id per triangle involved in an intersection // + the faces involved in the intersection - typedef CGAL::dynamic_face_property_t TID_property_tag; - typedef typename boost::property_map::const_type Triangle_id_map; - - Triangle_id_map tid_map = get(TID_property_tag(), tm); - for (face_descriptor f : faces(tm)) - put(tid_map, f, -1); - - std::vector intersected_faces; - int tid=-1; - for (const Pair_of_faces& p : si_pairs) + std::vector tri_inter_ids(id_triples.size(), -1); + std::vector intersected_faces; + int tiid=-1; + for (const Pair_of_triangle_ids& p : si_pairs) { - if (get(tid_map, p.first)==-1 && !get(is_degen, p.first)) + if (tri_inter_ids[p.first]==-1 && !is_degen[p.first]) { - put(tid_map, p.first, ++tid); + tri_inter_ids[p.first]=++tiid; intersected_faces.push_back(p.first); } - if (get(tid_map, p.second)==-1 && !get(is_degen, p.second)) + if (tri_inter_ids[p.second]==-1 && !is_degen[p.second]) { - put(tid_map, p.second, ++tid); + tri_inter_ids[p.second]=++tiid; intersected_faces.push_back(p.second); } } // init the vector of triangles used for the autorefinement of triangles typedef CGAL::Exact_predicates_exact_constructions_kernel EK; - std::vector< EK::Triangle_3 > triangles(tid+1); + std::vector< EK::Triangle_3 > triangles(tiid+1); Cartesian_converter to_exact; - for(face_descriptor f : intersected_faces) + for(Input_TID f : intersected_faces) { - halfedge_descriptor h = halfedge(f, tm); - triangles[get(tid_map, f)]= EK::Triangle_3( - to_exact( get(vpm, source(h, tm)) ), - to_exact( get(vpm, target(h, tm)) ), - to_exact( get(vpm, target(next(h, tm), tm)) ) ); + triangles[tri_inter_ids[f]]= EK::Triangle_3( + to_exact( get(pm, input_points[id_triples[f][0]]) ), + to_exact( get(pm, input_points[id_triples[f][1]]) ), + to_exact( get(pm, input_points[id_triples[f][2]]) ) ); } std::vector< std::vector > all_segments(triangles.size()); @@ -259,10 +244,10 @@ void autorefine_soup_output(const TriangleMesh& tm, typename EK::Intersect_3 intersection = EK().intersect_3_object(); autorefine_impl::Intersection_visitor intersection_visitor(all_segments, all_points); - for (const Pair_of_faces& p : si_pairs) + for (const Pair_of_triangle_ids& p : si_pairs) { - int i1 = get(tid_map, p.first), - i2 = get(tid_map, p.second); + int i1 = tri_inter_ids[p.first], + i2 = tri_inter_ids[p.second]; if (i1==-1 || i2==-1) continue; //skip degenerate faces @@ -298,17 +283,6 @@ void autorefine_soup_output(const TriangleMesh& tm, std::vector exact_soup_points; #endif - for (vertex_descriptor v : vertices(tm)) - { - if (point_id_map.insert(std::make_pair(to_exact(get(vpm,v)), soup_points.size())).second) - { - soup_points.push_back(get(vpm,v)); -#if ! defined(CGAL_NDEBUG) || defined(CGAL_DEBUG_PMP_AUTOREFINE) - exact_soup_points.push_back(to_exact(get(vpm,v))); -#endif - } - } - auto get_point_id = [&](const typename EK::Point_3& pt) { auto insert_res = point_id_map.insert(std::make_pair(pt, soup_points.size())); @@ -322,18 +296,22 @@ void autorefine_soup_output(const TriangleMesh& tm, return insert_res.first->second; }; - for (face_descriptor f : faces(tm)) + std::vector input_point_ids; + input_point_ids.reserve(input_points.size()); + for (const auto& p : input_points) + input_point_ids.push_back(get_point_id(to_exact(get(pm,p)))); + + for (Input_TID f=0; f::type GT; GT traits = choose_parameter(get_parameter(np, internal_np::geom_traits)); - std::vector soup_points; - std::vector > soup_triangles; + std::vector in_soup_points; + std::vector > in_soup_triangles; + std::vector out_soup_points; + std::vector > out_soup_triangles; + + polygon_mesh_to_polygon_soup(tm, in_soup_points, in_soup_triangles); - autorefine_soup_output(tm, soup_points, soup_triangles, np); + autorefine_soup_output(in_soup_points, in_soup_triangles, + out_soup_points, out_soup_triangles); clear(tm); - orient_polygon_soup(soup_points, soup_triangles); - polygon_soup_to_polygon_mesh(soup_points, soup_triangles, tm); + orient_polygon_soup(out_soup_points, out_soup_triangles); + polygon_soup_to_polygon_mesh(out_soup_points, out_soup_triangles, tm); } From b4887272e85bfde8bebf0093a9169cc897bca5ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 13 Jan 2023 11:56:36 +0100 Subject: [PATCH 019/329] use soup as input/output in example --- .../soup_autorefinement.cpp | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp index 8ca983aa31c3..297875c9ec89 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp @@ -23,19 +23,14 @@ int main(int argc, char** argv) : std::string(argv[1]); std::vector input_points; - std::vector > input_triangles; - + std::vector> input_triangles; CGAL::IO::read_polygon_soup(filename, input_points, input_triangles); - PMP::repair_polygon_soup(input_points, input_triangles); - - Mesh mesh; - PMP::orient_polygon_soup(input_points, input_triangles); - PMP::polygon_soup_to_polygon_mesh(input_points, input_triangles, mesh); - PMP::triangulate_faces(mesh); - PMP::autorefine(mesh); + std::vector output_points; + std::vector> output_triangles; + PMP::autorefine_soup_output(input_points, input_triangles, output_points, output_triangles); - CGAL::IO::write_polygon_mesh("autorefined.off", mesh, CGAL::parameters::stream_precision(17)); + CGAL::IO::write_polygon_soup("autorefined.off", output_points, output_triangles, CGAL::parameters::stream_precision(17)); return 0; } From d979121cd29c42c203609ab3bc4956601e9b0512 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 13 Jan 2023 15:41:33 +0100 Subject: [PATCH 020/329] repair soup is still recommanded --- .../examples/Polygon_mesh_processing/soup_autorefinement.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp index 297875c9ec89..9ade96e3be84 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp @@ -3,7 +3,6 @@ #include #include -#include #include #include #include @@ -25,6 +24,7 @@ int main(int argc, char** argv) std::vector input_points; std::vector> input_triangles; CGAL::IO::read_polygon_soup(filename, input_points, input_triangles); + PMP::repair_polygon_soup(input_points, input_triangles); std::vector output_points; std::vector> output_triangles; From 4bc74c399cac5ce0ac84ba894e1b5e996960d605 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 16 Jan 2023 22:59:18 +0100 Subject: [PATCH 021/329] WIP: start improving intersect computation --- .../Polygon_mesh_processing/autorefinement.h | 269 ++++++++++++++++-- 1 file changed, 248 insertions(+), 21 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 290dde253324..80b964ad8590 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -1,5 +1,5 @@ //TODO: add for soup face the id of the input face. not sure it is easy to report intersection edge as a pair of vertex id - +//TODO: only return intersection segments // Copyright (c) 2023 GeometryFactory (France). // All rights reserved. // @@ -43,21 +43,26 @@ namespace Polygon_mesh_processing { namespace autorefine_impl { template -void generate_subtriangles(const typename EK::Triangle_3& t, - const std::vector& segments, +void generate_subtriangles(std::size_t ti, + std::vector& segments, const std::vector& points, + const std::vector& in_triangle_ids, + const std::set >& intersecting_triangles, + const std::vector& triangles, std::vector& new_triangles) { typedef CGAL::Projection_traits_3 P_traits; typedef CGAL::Exact_intersections_tag Itag; - typedef CGAL::Constrained_Delaunay_triangulation_2 CDT_2; + typedef CGAL::Constrained_Delaunay_triangulation_2 CDT_2; //typedef CGAL::Constrained_triangulation_plus_2 CDT; typedef CDT_2 CDT; + const typename EK::Triangle_3& t = triangles[ti]; + // positive triangle normal typename EK::Vector_3 n = normal(t[0], t[1], t[2]); - typename EK::Point_3 o(0,0,0); + typename EK::Point_3 o(CGAL::ORIGIN); bool orientation_flipped = false; if ( typename EK::Less_xyz_3()(o+n,o) ) @@ -74,6 +79,184 @@ void generate_subtriangles(const typename EK::Triangle_3& t, typename CDT::Vertex_handle v = cdt.tds().insert_dim_up(cdt.infinite_vertex(), orientation_flipped); v->set_point(t[2]); +#if 1 + //~ static std::ofstream debug("inter_segments.polylines.txt"); + //~ debug.precision(17); + + // pre-compute segment intersections + if (!segments.empty()) + { + std::size_t nbs = segments.size(); + //~ std::cout << "nbs " << nbs << "\n"; + + //~ if (nbs==8) + //~ { + //~ for (std::size_t i = 0; i > points_on_segments(nbs); + for (std::size_t i = 0; i(&(*res))) + { + points_on_segments[i].push_back(*pt_ptr); + points_on_segments[j].push_back(*pt_ptr); + + //~ std::cout << "new inter " << *pt_ptr << "\n"; + + } + else + { + // We can have hard cases if two triangles are coplanar.... + + //~ std::cout << "coplanar inter: " << i << " " << j << "\n"; + + auto inter = CGAL::intersection(segments[i], segments[j]); + if (const typename EK::Point_3* pt_ptr = boost::get(&(*inter))) + { + points_on_segments[i].push_back(*pt_ptr); + points_on_segments[j].push_back(*pt_ptr); + + //~ std::cout << "new inter bis" << *pt_ptr << "\n"; + } + else + { + if (const typename EK::Segment_3* seg_ptr = boost::get(&(*inter))) + { + points_on_segments[i].push_back(seg_ptr->source()); + points_on_segments[j].push_back(seg_ptr->source()); + points_on_segments[i].push_back(seg_ptr->target()); + points_on_segments[j].push_back(seg_ptr->target()); + + } + else + std::cerr <<"ERROR!\n"; + } + + #if 0 + //this code works if triangles are not coplanar + // coplanar intersection that is not a point + int coord = 0; + const typename EK::Segment_3& s = segments[i]; + typename EK::Point_3 src = s.source(), tgt=s.target(); + if (src.x()==tgt.x()) + { + coord=1; + if (src.y()==tgt.y()) + coord==2; + } + + std::vector tmp_pts = { + src, tgt, segments[j][0], segments[j][1] }; + + std::sort(tmp_pts.begin(), tmp_pts.end(), + [coord](const typename EK::Point_3& p, const typename EK::Point_3& q) + {return p[coord] cst_points; + std::vector> csts; + for (std::size_t i = 0; itgt[coord]) + std::swap(src, tgt); + + std::sort(points_on_segments[i].begin(), points_on_segments[i].end(), [coord](const typename EK::Point_3& p, const typename EK::Point_3& q){return p[coord] no_inter_segments; + no_inter_segments.reserve(nbs); + for (std::size_t i = 0; i >& all_segments; std::vector< std::vector >& all_points; + std::vector< std::vector >& all_in_triangle_ids; std::pair ids; Intersection_visitor(std::vector< std::vector >& all_segments, - std::vector< std::vector >& all_points) + std::vector< std::vector >& all_points, + std::vector< std::vector >& all_in_triangle_ids) : all_segments (all_segments) , all_points(all_points) + , all_in_triangle_ids(all_in_triangle_ids) {} void set_triangle_ids(int i1, int i2) @@ -140,6 +326,8 @@ struct Intersection_visitor { all_segments[ids.first].push_back(s); all_segments[ids.second].push_back(s); + all_in_triangle_ids[ids.first].push_back(ids.second); + all_in_triangle_ids[ids.second].push_back(ids.first); } void operator()(const typename EK::Triangle_3& t) @@ -149,6 +337,8 @@ struct Intersection_visitor typename EK::Segment_3 s(t[i], t[(i+1)%3]); all_segments[ids.first].push_back(s); all_segments[ids.second].push_back(s); + all_in_triangle_ids[ids.first].push_back(ids.second); + all_in_triangle_ids[ids.second].push_back(ids.first); } } @@ -161,6 +351,8 @@ struct Intersection_visitor typename EK::Segment_3 s(poly[i], poly[(i+1)%nbp]); all_segments[ids.first].push_back(s); all_segments[ids.second].push_back(s); + all_in_triangle_ids[ids.first].push_back(ids.second); + all_in_triangle_ids[ids.second].push_back(ids.first); } } }; @@ -239,11 +431,13 @@ void autorefine_soup_output(const PointRange& input_points, std::vector< std::vector > all_segments(triangles.size()); std::vector< std::vector > all_points(triangles.size()); + std::vector< std::vector > all_in_triangle_ids(triangles.size()); CGAL_PMP_AUTOREFINE_VERBOSE("compute intersections"); typename EK::Intersect_3 intersection = EK().intersect_3_object(); - autorefine_impl::Intersection_visitor intersection_visitor(all_segments, all_points); + autorefine_impl::Intersection_visitor intersection_visitor(all_segments, all_points, all_in_triangle_ids); + std::set > intersecting_triangles; for (const Pair_of_triangle_ids& p : si_pairs) { int i1 = tri_inter_ids[p.first], @@ -258,25 +452,13 @@ void autorefine_soup_output(const PointRange& input_points, if (inter != boost::none) { + intersecting_triangles.insert(CGAL::make_sorted_pair(i1, i2)); intersection_visitor.set_triangle_ids(i1, i2); boost::apply_visitor(intersection_visitor, *inter); } } - CGAL_PMP_AUTOREFINE_VERBOSE("triangulate faces"); - // now refine triangles - std::vector new_triangles; - for(std::size_t ti=0; ti(triangles[ti], all_segments[ti], all_points[ti], new_triangles); - } - - - // brute force output: create a soup, orient and to-mesh - CGAL_PMP_AUTOREFINE_VERBOSE("create output soup"); + // deduplicate inserted segments Cartesian_converter to_input; std::map point_id_map; #if ! defined(CGAL_NDEBUG) || defined(CGAL_DEBUG_PMP_AUTOREFINE) @@ -296,6 +478,51 @@ void autorefine_soup_output(const PointRange& input_points, return insert_res.first->second; }; + // filter duplicated segments + for(std::size_t ti=0; ti filtered_segments; + std::vector filtered_in_triangle_ids; + filtered_segments.reserve(nbs); + std::set> segset; + for (std::size_t si=0; si new_triangles; + for(std::size_t ti=0; ti(ti, all_segments[ti], all_points[ti], all_in_triangle_ids[ti], intersecting_triangles, triangles, new_triangles); + } + + + // brute force output: create a soup, orient and to-mesh + CGAL_PMP_AUTOREFINE_VERBOSE("create output soup"); + std::vector input_point_ids; input_point_ids.reserve(input_points.size()); for (const auto& p : input_points) From 842b6282b5c7a0b9f9c9551dfa443edd4f5319f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 23 Jan 2023 15:39:01 +0100 Subject: [PATCH 022/329] STILL WIP: copy/paste code for coplanar intersection --- .../Polygon_mesh_processing/autorefinement.h | 44 +++++++++++++++++-- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 80b964ad8590..6d97f7521ded 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -36,12 +36,43 @@ #include +#define TEST_RESOLVE_INTERSECTION +#define DEDUPLICATE_SEGMENTS + namespace CGAL { namespace Polygon_mesh_processing { #ifndef DOXYGEN_RUNNING namespace autorefine_impl { +template +bool do_coplanar_segments_intersect(const typename K::Segment_3& s1, + const typename K::Segment_3& s2, + const K& k = K()) +{ + // supporting_line intersects: points are coplanar + 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]) || + 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])); + } + + return false; +} + template void generate_subtriangles(std::size_t ti, std::vector& segments, @@ -54,7 +85,11 @@ void generate_subtriangles(std::size_t ti, typedef CGAL::Projection_traits_3 P_traits; typedef CGAL::Exact_intersections_tag Itag; - typedef CGAL::Constrained_Delaunay_triangulation_2 CDT_2; + typedef CGAL::Constrained_Delaunay_triangulation_2 CDT_2; //typedef CGAL::Constrained_triangulation_plus_2 CDT; typedef CDT_2 CDT; @@ -79,7 +114,7 @@ void generate_subtriangles(std::size_t ti, typename CDT::Vertex_handle v = cdt.tds().insert_dim_up(cdt.infinite_vertex(), orientation_flipped); v->set_point(t[2]); -#if 1 +#ifdef TEST_RESOLVE_INTERSECTION //~ static std::ofstream debug("inter_segments.polylines.txt"); //~ debug.precision(17); @@ -102,7 +137,7 @@ void generate_subtriangles(std::size_t ti, { if (intersecting_triangles.count(CGAL::make_sorted_pair(in_triangle_ids[i], in_triangle_ids[j]))!=0) { - if (CGAL::do_intersect(segments[i], segments[j])) + if (do_coplanar_segments_intersect(segments[i], segments[j])) { auto res = CGAL::intersection(triangles[in_triangle_ids[i]].supporting_plane(), triangles[in_triangle_ids[j]].supporting_plane(), @@ -479,6 +514,7 @@ void autorefine_soup_output(const PointRange& input_points, }; // filter duplicated segments +#ifdef DEDUPLICATE_SEGMENTS for(std::size_t ti=0; ti(ti, all_segments[ti], all_points[ti], all_in_triangle_ids[ti], intersecting_triangles, triangles, new_triangles); } - // brute force output: create a soup, orient and to-mesh CGAL_PMP_AUTOREFINE_VERBOSE("create output soup"); From 39d7bbc57fee319e45f8c51c75794f7828cc21d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 24 Jan 2023 14:54:20 +0100 Subject: [PATCH 023/329] WIP import intersection computation from coref code --- .../Polygon_mesh_processing/autorefinement.h | 363 +++++++++++++----- 1 file changed, 259 insertions(+), 104 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 6d97f7521ded..afbe0c3479d7 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -36,8 +36,8 @@ #include -#define TEST_RESOLVE_INTERSECTION -#define DEDUPLICATE_SEGMENTS +// #define TEST_RESOLVE_INTERSECTION +// #define DEDUPLICATE_SEGMENTS namespace CGAL { namespace Polygon_mesh_processing { @@ -45,10 +45,13 @@ namespace Polygon_mesh_processing { #ifndef DOXYGEN_RUNNING namespace autorefine_impl { +enum Segment_inter_type { NO_INTERSECTION=0, COPLANAR_SEGMENTS, POINT_INTERSECTION }; + template -bool do_coplanar_segments_intersect(const typename K::Segment_3& s1, - const typename K::Segment_3& s2, - const K& k = K()) +Segment_inter_type +do_coplanar_segments_intersect(const typename K::Segment_3& s1, + const typename K::Segment_3& s2, + const K& k = K()) { // supporting_line intersects: points are coplanar typename K::Coplanar_orientation_3 cpl_orient=k.coplanar_orientation_3_object(); @@ -61,26 +64,207 @@ bool do_coplanar_segments_intersect(const typename K::Segment_3& s1, 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]) || cln_order(s1[0], s2[1], s1[1]) || - cln_order(s2[0], s1[0], s2[1])); + cln_order(s2[0], s1[0], s2[1])) ? COPLANAR_SEGMENTS : NO_INTERSECTION; } if(or1 != or2) { or1 = cpl_orient(s2[0], s2[1], s1[0]); - return (or1 == COLLINEAR || or1 != cpl_orient(s2[0], s2[1], s1[1])); + return (or1 == COLLINEAR || or1 != cpl_orient(s2[0], s2[1], s1[1])) ? POINT_INTERSECTION : NO_INTERSECTION; + } + + return NO_INTERSECTION; +} + +////////////////////////////////// +////////////////////////////////// +////////////////////////////////// +////////////////////////////////// +////////////////////////////////// + +// imported from Polygon_mesh_processing/internal/Corefinement/intersect_triangle_segment_3.h + +template +void +find_intersection(const typename K::Point_3& p, const typename K::Point_3& q, //segment + const typename K::Point_3& a, const typename K::Point_3& b, const typename K::Point_3& c, //triangle + std::vector& inter_pts, + bool is_p_coplanar=false, bool is_q_coplanar=false) // note that in coref this was wrt a halfedge not p/q +{ + Orientation ab=orientation(p,q,a,b); + Orientation bc=orientation(p,q,b,c); + Orientation ca=orientation(p,q,c,a); + + if ( ab==POSITIVE || bc==POSITIVE || ca==POSITIVE ) + return; + + int nb_coplanar=(ab==COPLANAR?1:0) + (bc==COPLANAR?1:0) + (ca==COPLANAR?1:0); + +/* + if ( nb_coplanar==0 ) + return result_type(ON_FACE,hd,is_src_coplanar,is_tgt_coplanar); + + if (nb_coplanar==1){ + if (ab==COPLANAR) + // intersection is ab + return result_type(ON_EDGE,next(hd,tm),is_src_coplanar,is_tgt_coplanar); + if (bc==COPLANAR) + // intersection is bc + return result_type(ON_EDGE,prev(hd,tm),is_src_coplanar,is_tgt_coplanar); + CGAL_assertion(ca==COPLANAR); + // intersection is ca + return result_type(ON_EDGE,hd,is_src_coplanar,is_tgt_coplanar); + } +*/ + + if (is_p_coplanar) + { + inter_pts.push_back(p); + return; + } + if (is_q_coplanar) + { + inter_pts.push_back(q); + return; + } + + if (nb_coplanar!=2) + { + inter_pts.push_back( + typename K::Construct_plane_line_intersection_point_3()(a, b, c, p, q) + ); + } + else + { + if (ab!=COPLANAR) + { + // intersection is c + inter_pts.push_back(c); + return; + } + + if (bc!=COPLANAR) + { + // intersection is a + inter_pts.push_back(a); + return; + } + CGAL_assertion(ca!=COPLANAR); + // intersection is b + inter_pts.push_back(b); } +} - return false; +template +void test_edge(const typename K::Point_3& p, const typename K::Point_3& q, + const typename K::Point_3& a, const typename K::Point_3& b, const typename K::Point_3& c, + const Orientation abcp, + const Orientation abcq, + std::vector& inter_pts) +{ + switch ( abcp ) { + case POSITIVE: + switch ( abcq ) { + case POSITIVE: + // the segment lies in the positive open halfspaces defined by the + // triangle's supporting plane + break; + case NEGATIVE: + // p sees the triangle in counterclockwise order + find_intersection(p,q,a,b,c,inter_pts); + break; + //case COPLANAR: + default: + // q belongs to the triangle's supporting plane + // p sees the triangle in counterclockwise order + find_intersection(p,q,a,b,c,inter_pts,false,true); + } + break; + case NEGATIVE: + switch ( abcq ) { + case POSITIVE: + // q sees the triangle in counterclockwise order + find_intersection(q,p,a,b,c,inter_pts); + break; + case NEGATIVE: + // the segment lies in the negative open halfspaces defined by the + // triangle's supporting plane + break; + // case COPLANAR: + default: + // q belongs to the triangle's supporting plane + // p sees the triangle in clockwise order + find_intersection(q,p,a,b,c,inter_pts,true,false); + } + break; + default: + //case COPLANAR: // p belongs to the triangle's supporting plane + switch ( abcq ) { + case POSITIVE: + // q sees the triangle in counterclockwise order + find_intersection(q,p,a,b,c,inter_pts,false, true); + break; + case NEGATIVE: + // q sees the triangle in clockwise order + find_intersection(p,q,a,b,c,inter_pts,true); + break; + //case COPLANAR: + default: + // the segment is coplanar with the triangle's supporting plane + // we test whether the segment intersects the triangle in the common + // supporting plane + if ( ::CGAL::Intersections::internal::do_intersect_coplanar(a,b,c,p,q,K()) ) + { + //handle coplanar intersection + // TODO: use coref function + throw std::runtime_error("coplanar intersection"); + return; + } + } + } } +template +void collect_intersections(const std::array& t1, + const std::array& t2, + std::vector& inter_pts) +{ + // test edges of t1 vs t2 + std::array ori; + for (int i=0; i<3; ++i) + ori[i] = orientation(t2[0],t2[1],t2[2],t1[i]); + for (int i=0; i<3; ++i) + { + int j=(i+1)%3; + test_edge(t1[i], t1[j], t2[0], t2[1], t2[2], ori[i], ori[j], inter_pts); + if (inter_pts.size()>1) return; + } + + // test edges of t2 vs t1 + for (int i=0; i<3; ++i) + ori[i] = orientation(t1[0],t1[1],t1[2],t2[i]); + for (int i=0; i<3; ++i) + { + int j=(i+1)%3; + test_edge(t2[i], t2[j], t1[0], t1[1], t1[2], ori[i], ori[j], inter_pts); + if (inter_pts.size()>1) return; + } +} + +////////////////////////////////// +////////////////////////////////// +////////////////////////////////// +////////////////////////////////// +////////////////////////////////// + template void generate_subtriangles(std::size_t ti, std::vector& segments, const std::vector& points, const std::vector& in_triangle_ids, const std::set >& intersecting_triangles, - const std::vector& triangles, - std::vector& new_triangles) + const std::vector>& triangles, + std::vector>& new_triangles) { typedef CGAL::Projection_traits_3 P_traits; typedef CGAL::Exact_intersections_tag Itag; @@ -93,7 +277,7 @@ void generate_subtriangles(std::size_t ti, //typedef CGAL::Constrained_triangulation_plus_2 CDT; typedef CDT_2 CDT; - const typename EK::Triangle_3& t = triangles[ti]; + const std::array& t = triangles[ti]; // positive triangle normal typename EK::Vector_3 n = normal(t[0], t[1], t[2]); @@ -130,6 +314,11 @@ void generate_subtriangles(std::size_t ti, //~ std::ofstream("cst_"+std::to_string(i)+".polylines.txt") << std::setprecision(17) << "2 " << segments[i] << "\n"; //~ } + auto supporting_plane = [](const std::array& t) + { + return typename EK::Plane_3(t[0], t[1], t[2]); + }; + std::vector< std::vector > points_on_segments(nbs); for (std::size_t i = 0; i(segments[i], segments[j])) + Segment_inter_type seg_inter_type = do_coplanar_segments_intersect(segments[i], segments[j]); + switch(seg_inter_type) { - auto res = CGAL::intersection(triangles[in_triangle_ids[i]].supporting_plane(), - triangles[in_triangle_ids[j]].supporting_plane(), - triangles[ti].supporting_plane()); - - if (const typename EK::Point_3* pt_ptr = boost::get(&(*res))) + case POINT_INTERSECTION: { - points_on_segments[i].push_back(*pt_ptr); - points_on_segments[j].push_back(*pt_ptr); + auto res = CGAL::intersection(supporting_plane(triangles[in_triangle_ids[i]]), + supporting_plane(triangles[in_triangle_ids[j]]), + supporting_plane(triangles[ti])); + + if (const typename EK::Point_3* pt_ptr = boost::get(&(*res))) + { + points_on_segments[i].push_back(*pt_ptr); + points_on_segments[j].push_back(*pt_ptr); - //~ std::cout << "new inter " << *pt_ptr << "\n"; + //~ std::cout << "new inter " << *pt_ptr << "\n"; + } } - else + // break; No break because of the coplanar case + case COPLANAR_SEGMENTS: { // We can have hard cases if two triangles are coplanar.... //~ std::cout << "coplanar inter: " << i << " " << j << "\n"; auto inter = CGAL::intersection(segments[i], segments[j]); + + if (inter == boost::none) throw std::runtime_error("Unexpected case #2"); + if (const typename EK::Point_3* pt_ptr = boost::get(&(*inter))) { points_on_segments[i].push_back(*pt_ptr); @@ -224,6 +421,9 @@ void generate_subtriangles(std::size_t ti, //~ debug << "4 " << triangles[ti] << " " << triangles[ti][0] << "\n"; //~ exit(1); } + break; + default: + break; } } } @@ -304,13 +504,13 @@ void generate_subtriangles(std::size_t ti, for (typename CDT::Face_handle fh : cdt.finite_face_handles()) { if (orientation_flipped) - new_triangles.emplace_back(fh->vertex(0)->point(), - fh->vertex(cdt.cw(0))->point(), - fh->vertex(cdt.ccw(0))->point()); + new_triangles.push_back( CGAL::make_array(fh->vertex(0)->point(), + fh->vertex(cdt.cw(0))->point(), + fh->vertex(cdt.ccw(0))->point()) ); else - new_triangles.emplace_back(fh->vertex(0)->point(), - fh->vertex(cdt.ccw(0))->point(), - fh->vertex(cdt.cw(0))->point()); + new_triangles.push_back( CGAL::make_array(fh->vertex(0)->point(), + fh->vertex(cdt.ccw(0))->point(), + fh->vertex(cdt.cw(0))->point()) ); #ifdef CGAL_DEBUG_PMP_AUTOREFINE_DUMP_TRIANGULATIONS ++nbt; buffer << fh->vertex(0)->point() << "\n"; @@ -329,69 +529,6 @@ void generate_subtriangles(std::size_t ti, #endif } -template -struct Intersection_visitor -{ - std::vector< std::vector >& all_segments; - std::vector< std::vector >& all_points; - std::vector< std::vector >& all_in_triangle_ids; - std::pair ids; - - Intersection_visitor(std::vector< std::vector >& all_segments, - std::vector< std::vector >& all_points, - std::vector< std::vector >& all_in_triangle_ids) - : all_segments (all_segments) - , all_points(all_points) - , all_in_triangle_ids(all_in_triangle_ids) - {} - - void set_triangle_ids(int i1, int i2) - { - ids = {i1, i2}; - } - - typedef void result_type; - void operator()(const typename EK::Point_3& p) - { - all_points[ids.first].push_back(p); - all_points[ids.second].push_back(p); - } - - void operator()(const typename EK::Segment_3& s) - { - all_segments[ids.first].push_back(s); - all_segments[ids.second].push_back(s); - all_in_triangle_ids[ids.first].push_back(ids.second); - all_in_triangle_ids[ids.second].push_back(ids.first); - } - - void operator()(const typename EK::Triangle_3& t) - { - for (std::size_t i=0; i<3; ++i) - { - typename EK::Segment_3 s(t[i], t[(i+1)%3]); - all_segments[ids.first].push_back(s); - all_segments[ids.second].push_back(s); - all_in_triangle_ids[ids.first].push_back(ids.second); - all_in_triangle_ids[ids.second].push_back(ids.first); - } - - } - - void operator()(const std::vector& poly) - { - std::size_t nbp = poly.size(); - for (std::size_t i=0; i @@ -453,24 +590,22 @@ void autorefine_soup_output(const PointRange& input_points, // init the vector of triangles used for the autorefinement of triangles typedef CGAL::Exact_predicates_exact_constructions_kernel EK; - std::vector< EK::Triangle_3 > triangles(tiid+1); + std::vector< std::array > triangles(tiid+1); Cartesian_converter to_exact; for(Input_TID f : intersected_faces) { - triangles[tri_inter_ids[f]]= EK::Triangle_3( + triangles[tri_inter_ids[f]]= CGAL::make_array( to_exact( get(pm, input_points[id_triples[f][0]]) ), to_exact( get(pm, input_points[id_triples[f][1]]) ), to_exact( get(pm, input_points[id_triples[f][2]]) ) ); } - std::vector< std::vector > all_segments(triangles.size()); + std::vector< std::vector > all_segments(triangles.size()); // TODO use std::pair std::vector< std::vector > all_points(triangles.size()); std::vector< std::vector > all_in_triangle_ids(triangles.size()); CGAL_PMP_AUTOREFINE_VERBOSE("compute intersections"); - typename EK::Intersect_3 intersection = EK().intersect_3_object(); - autorefine_impl::Intersection_visitor intersection_visitor(all_segments, all_points, all_in_triangle_ids); std::set > intersecting_triangles; for (const Pair_of_triangle_ids& p : si_pairs) @@ -480,16 +615,36 @@ void autorefine_soup_output(const PointRange& input_points, if (i1==-1 || i2==-1) continue; //skip degenerate faces - const EK::Triangle_3& t1 = triangles[i1]; - const EK::Triangle_3& t2 = triangles[i2]; + const std::array& t1 = triangles[i1]; + const std::array& t2 = triangles[i2]; - auto inter = intersection(t1, t2); + std::vector inter_pts; + autorefine_impl::collect_intersections(t1, t2, inter_pts); - if (inter != boost::none) + if (!inter_pts.empty()) { - intersecting_triangles.insert(CGAL::make_sorted_pair(i1, i2)); - intersection_visitor.set_triangle_ids(i1, i2); - boost::apply_visitor(intersection_visitor, *inter); + std::size_t nbi = inter_pts.size(); + switch(nbi) + { + case 1: + all_points[i1].push_back(inter_pts[0]); + all_points[i2].push_back(inter_pts[0]); + break; + case 2: + all_segments[i1].push_back({inter_pts[0], inter_pts[1]}); + all_segments[i2].push_back({inter_pts[0], inter_pts[1]}); + all_in_triangle_ids[i1].push_back(i2); + all_in_triangle_ids[i2].push_back(i1); + break; + default: + for (std::size_t i=0;i new_triangles; + std::vector> new_triangles; for(std::size_t ti=0; ti& t : new_triangles) { soup_triangles.emplace_back(CGAL::make_array(get_point_id(t[0]), get_point_id(t[1]), get_point_id(t[2]))); } From 10252faf1df2480f21c25959c1980e68819099a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 24 Jan 2023 16:04:43 +0100 Subject: [PATCH 024/329] WIP use segments --- .../Polygon_mesh_processing/autorefinement.h | 46 ++++++++++--------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index afbe0c3479d7..c9bb3f3ffa81 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -36,8 +36,8 @@ #include -// #define TEST_RESOLVE_INTERSECTION -// #define DEDUPLICATE_SEGMENTS +//#define TEST_RESOLVE_INTERSECTION +//#define DEDUPLICATE_SEGMENTS namespace CGAL { namespace Polygon_mesh_processing { @@ -49,8 +49,8 @@ enum Segment_inter_type { NO_INTERSECTION=0, COPLANAR_SEGMENTS, POINT_INTERSECTI template Segment_inter_type -do_coplanar_segments_intersect(const typename K::Segment_3& s1, - const typename K::Segment_3& s2, +do_coplanar_segments_intersect(const std::array& s1, + const std::array& s2, const K& k = K()) { // supporting_line intersects: points are coplanar @@ -259,7 +259,7 @@ void collect_intersections(const std::array& t1, template void generate_subtriangles(std::size_t ti, - std::vector& segments, + std::vector>& segments, const std::vector& points, const std::vector& in_triangle_ids, const std::set >& intersecting_triangles, @@ -351,7 +351,9 @@ void generate_subtriangles(std::size_t ti, //~ std::cout << "coplanar inter: " << i << " " << j << "\n"; - auto inter = CGAL::intersection(segments[i], segments[j]); + typename EK::Segment_3 s1(segments[i][0], segments[i][1]); + typename EK::Segment_3 s2(segments[j][0], segments[j][1]);// TODO: avoid this construction + auto inter = CGAL::intersection(s1, s2); if (inter == boost::none) throw std::runtime_error("Unexpected case #2"); @@ -381,7 +383,7 @@ void generate_subtriangles(std::size_t ti, // coplanar intersection that is not a point int coord = 0; const typename EK::Segment_3& s = segments[i]; - typename EK::Point_3 src = s.source(), tgt=s.target(); + typename EK::Point_3 src = s[0], tgt=s[1]; if (src.x()==tgt.x()) { coord=1; @@ -401,10 +403,10 @@ void generate_subtriangles(std::size_t ti, points_on_segments[j].push_back(tmp_pts[1]); points_on_segments[j].push_back(tmp_pts[2]); #endif - //~ std::cout << "new inter coli " << segments[j].source() << "\n"; - //~ std::cout << "new inter coli " << segments[j].target() << "\n"; - //~ std::cout << "new inter coli " << segments[i].source() << "\n"; - //~ std::cout << "new inter coli " << segments[i].target() << "\n"; + //~ std::cout << "new inter coli " << segments[j][0] << "\n"; + //~ std::cout << "new inter coli " << segments[j][1] << "\n"; + //~ std::cout << "new inter coli " << segments[i][0] << "\n"; + //~ std::cout << "new inter coli " << segments[i][1] << "\n"; //~ points_on_segments[j].push_back(*pt_ptr); @@ -437,8 +439,8 @@ void generate_subtriangles(std::size_t ti, { // TODO: predicate on input triangles int coord = 0; - const typename EK::Segment_3& s = segments[i]; - typename EK::Point_3 src = s.source(), tgt=s.target(); + const std::array& s = segments[i]; + typename EK::Point_3 src = s[0], tgt=s[1]; if (src.x()==tgt.x()) { coord=1; @@ -482,7 +484,7 @@ void generate_subtriangles(std::size_t ti, cdt.insert_constraints(cst_points.begin(), cst_points.end(), csts.begin(), csts.end()); - std::vector no_inter_segments; + std::vector> no_inter_segments; no_inter_segments.reserve(nbs); for (std::size_t i = 0; i > all_segments(triangles.size()); // TODO use std::pair + std::vector< std::vector > > all_segments(triangles.size()); std::vector< std::vector > all_points(triangles.size()); std::vector< std::vector > all_in_triangle_ids(triangles.size()); @@ -631,16 +633,16 @@ void autorefine_soup_output(const PointRange& input_points, all_points[i2].push_back(inter_pts[0]); break; case 2: - all_segments[i1].push_back({inter_pts[0], inter_pts[1]}); - all_segments[i2].push_back({inter_pts[0], inter_pts[1]}); + all_segments[i1].push_back(CGAL::make_array(inter_pts[0], inter_pts[1])); + all_segments[i2].push_back(CGAL::make_array(inter_pts[0], inter_pts[1])); all_in_triangle_ids[i1].push_back(i2); all_in_triangle_ids[i2].push_back(i1); break; default: for (std::size_t i=0;i filtered_segments; + std::vector> filtered_segments; std::vector filtered_in_triangle_ids; filtered_segments.reserve(nbs); std::set> segset; for (std::size_t si=0; si Date: Tue, 24 Jan 2023 16:04:54 +0100 Subject: [PATCH 025/329] always std::array as cst --- Triangulation_2/include/CGAL/Constrained_triangulation_2.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Triangulation_2/include/CGAL/Constrained_triangulation_2.h b/Triangulation_2/include/CGAL/Constrained_triangulation_2.h index 42867cfbb074..047c8526afc5 100644 --- a/Triangulation_2/include/CGAL/Constrained_triangulation_2.h +++ b/Triangulation_2/include/CGAL/Constrained_triangulation_2.h @@ -330,11 +330,11 @@ class Constrained_triangulation_2 #if 1 template static decltype(auto) get_source(const Segment_2& segment){ - return segment.source(); + return segment[0]; } template static decltype(auto) get_target(const Segment_2& segment){ - return segment.target(); + return segment[1]; } static const Point& get_source(const Constraint& cst){ From 810715778223710a066d3161e2a4ec453475eaf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 24 Jan 2023 18:04:10 +0100 Subject: [PATCH 026/329] WIP handle coplanar --- .../Polygon_mesh_processing/autorefinement.h | 47 +++++++++++++++---- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index c9bb3f3ffa81..f412c2ea298e 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -82,8 +82,30 @@ do_coplanar_segments_intersect(const std::array& s1, ////////////////////////////////// ////////////////////////////////// -// imported from Polygon_mesh_processing/internal/Corefinement/intersect_triangle_segment_3.h +// imported from Intersections_3/include/CGAL/Intersections_3/internal/Triangle_3_Triangle_3_intersection.h + +template +void coplanar_intersections(const std::array& t1, + const std::array& t2, + std::vector& inter_pts) +{ + const typename K::Point_3& p = t1[0], q = t1[1], r = t1[2]; + + std::list l_inter_pts; + l_inter_pts.push_back(t2[0]); + l_inter_pts.push_back(t2[1]); + l_inter_pts.push_back(t2[2]); + //intersect t2 with the three half planes which intersection defines t1 + K k; + Intersections::internal::intersection_coplanar_triangles_cutoff(p,q,r,k,l_inter_pts); //line pq + Intersections::internal::intersection_coplanar_triangles_cutoff(q,r,p,k,l_inter_pts); //line qr + Intersections::internal::intersection_coplanar_triangles_cutoff(r,p,q,k,l_inter_pts); //line rp + + inter_pts.assign(l_inter_pts.begin(), l_inter_pts.end()); +} + +// imported from Polygon_mesh_processing/internal/Corefinement/intersect_triangle_segment_3.h template void find_intersection(const typename K::Point_3& p, const typename K::Point_3& q, //segment @@ -162,7 +184,7 @@ void test_edge(const typename K::Point_3& p, const typename K::Point_3& q, const Orientation abcq, std::vector& inter_pts) { - switch ( abcp ) { + switch ( abcp ) { case POSITIVE: switch ( abcq ) { case POSITIVE: @@ -213,13 +235,13 @@ void test_edge(const typename K::Point_3& p, const typename K::Point_3& q, // the segment is coplanar with the triangle's supporting plane // we test whether the segment intersects the triangle in the common // supporting plane - if ( ::CGAL::Intersections::internal::do_intersect_coplanar(a,b,c,p,q,K()) ) - { + //if ( ::CGAL::Intersections::internal::do_intersect_coplanar(a,b,c,p,q,K()) ) + //{ //handle coplanar intersection - // TODO: use coref function - throw std::runtime_error("coplanar intersection"); - return; - } + // nothing done as coplanar case handle in collect_intersections + // and other intersection points will be collected with non-coplanar edges + //} + break; } } } @@ -233,6 +255,13 @@ void collect_intersections(const std::array& t1, std::array ori; for (int i=0; i<3; ++i) ori[i] = orientation(t2[0],t2[1],t2[2],t1[i]); + + if (ori[0]== COPLANAR && ori[1]==COPLANAR && ori[2]==COPLANAR) + { + coplanar_intersections(t1, t2, inter_pts); + return; + } + for (int i=0; i<3; ++i) { int j=(i+1)%3; @@ -378,7 +407,7 @@ void generate_subtriangles(std::size_t ti, std::cerr <<"ERROR!\n"; } - #if 0 +#if 0 //this code works if triangles are not coplanar // coplanar intersection that is not a point int coord = 0; From fa662e7dea97c5f33c8872c71817c18f51df0894 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 25 Jan 2023 14:45:12 +0100 Subject: [PATCH 027/329] WIP handle duplicated intersections + add in intersection list --- .../Polygon_mesh_processing/autorefinement.h | 45 +++++++++++++++---- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index f412c2ea298e..ae9858ae77d5 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -1,5 +1,5 @@ //TODO: add for soup face the id of the input face. not sure it is easy to report intersection edge as a pair of vertex id -//TODO: only return intersection segments +//TODO: only return intersection segments (pay attention to degenerate triangles that are currently ignored) // Copyright (c) 2023 GeometryFactory (France). // All rights reserved. // @@ -36,8 +36,8 @@ #include -//#define TEST_RESOLVE_INTERSECTION -//#define DEDUPLICATE_SEGMENTS +// #define TEST_RESOLVE_INTERSECTION +// #define DEDUPLICATE_SEGMENTS namespace CGAL { namespace Polygon_mesh_processing { @@ -266,7 +266,7 @@ void collect_intersections(const std::array& t1, { int j=(i+1)%3; test_edge(t1[i], t1[j], t2[0], t2[1], t2[2], ori[i], ori[j], inter_pts); - if (inter_pts.size()>1) return; + //~ if (inter_pts.size()>1) return; } // test edges of t2 vs t1 @@ -276,8 +276,13 @@ void collect_intersections(const std::array& t1, { int j=(i+1)%3; test_edge(t2[i], t2[j], t1[0], t1[1], t1[2], ori[i], ori[j], inter_pts); - if (inter_pts.size()>1) return; + //~ if (inter_pts.size()>1) return; } + + // because we don't handle intersection type and can have edge-edge edge-vertex duplicates + std::sort(inter_pts.begin(), inter_pts.end()); + auto last = std::unique(inter_pts.begin(), inter_pts.end()); + inter_pts.erase(last, inter_pts.end()); } ////////////////////////////////// @@ -288,7 +293,7 @@ void collect_intersections(const std::array& t1, template void generate_subtriangles(std::size_t ti, - std::vector>& segments, + std::vector>& segments, const std::vector& points, const std::vector& in_triangle_ids, const std::set >& intersecting_triangles, @@ -331,6 +336,27 @@ void generate_subtriangles(std::size_t ti, //~ static std::ofstream debug("inter_segments.polylines.txt"); //~ debug.precision(17); + //~ std::cout << "points.size() " << points.size() << "\n"; + //~ std::set all_triangles_indices(in_triangle_ids.begin(), in_triangle_ids.end()); + //~ all_triangles_indices.insert(ti); + + //~ std::ofstream debug("triangles.polylines.txt"); + //~ debug << std::setprecision(17); + //~ for (std::size_t i : all_triangles_indices) + //~ debug << "4 " + //~ << triangles[i][0] << " " + //~ << triangles[i][1] << " " + //~ << triangles[i][2] << " " + //~ << triangles[i][0] << "\n"; + //~ debug.close(); + //~ debug.open("triangle.off"); + //~ debug << std::setprecision(17); + //~ debug << "OFF\n3 1 0\n"; + //~ debug << triangles[ti][0] << "\n" + //~ << triangles[ti][1] << "\n" + //~ << triangles[ti][2] << "\n 3 0 1 2\n"; + //~ debug.close(); + // pre-compute segment intersections if (!segments.empty()) { @@ -340,7 +366,7 @@ void generate_subtriangles(std::size_t ti, //~ if (nbs==8) //~ { //~ for (std::size_t i = 0; i& t) @@ -404,7 +430,7 @@ void generate_subtriangles(std::size_t ti, } else - std::cerr <<"ERROR!\n"; + throw std::runtime_error("BOOM\n"); } #if 0 @@ -671,11 +697,12 @@ void autorefine_soup_output(const PointRange& input_points, for (std::size_t i=0;i Date: Thu, 2 Feb 2023 11:14:18 +0100 Subject: [PATCH 028/329] WIP new coplanar intersection --- .../Triangle_3_Triangle_3_intersection.h | 297 +++++++++++++++--- .../Polygon_mesh_processing/autorefinement.h | 36 ++- 2 files changed, 285 insertions(+), 48 deletions(-) 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 424e1fc93616..d4e467a07986 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 @@ -31,54 +31,257 @@ namespace CGAL { namespace Intersections { namespace internal{ +template +typename K::FT +coplanar_segment_segment_alpha_intersection(const typename K::Point_3& p1, const typename K::Point_3& p2, // segment 1 + const typename K::Point_3& p3, const typename K::Point_3& p4, // segment 2 + const K& k) +{ + const typename K::Vector_3 v1 = p2-p1; + const typename K::Vector_3 v2 = p4-p3; + + CGAL_assertion(k.coplanar_3_object()(p1,p2,p3,p4)); + + const typename K::Vector_3 v3 = p3 - p1; + const typename K::Vector_3 v3v2 = cross_product(v3,v2); + const typename K::Vector_3 v1v2 = cross_product(v1,v2); + const typename K::FT sl = v1v2.squared_length(); + CGAL_assertion(!certainly(is_zero(sl))); + + const typename K::FT t = ((v3v2.x()*v1v2.x()) + (v3v2.y()*v1v2.y()) + (v3v2.z()*v1v2.z())) / sl; + return t; // p1 + (p2-p1) * t +} + +template +struct Point_on_triangle +{ + static + inline + const typename Kernel::Point_3& + point_from_id(const typename Kernel::Point_3& p, + const typename Kernel::Point_3& q, + const typename Kernel::Point_3& r, + int id) + { + switch(id) + { + case 0: + return p; + case 1: + return q; + default: + return r; + } + } + + Point_on_triangle(int i1, int i2=-1, int sign=0, typename Kernel::FT alpha = 0.) // TODO add global zero()? + : t1_t2_ids(i1,i2) + , sign(sign) + {} + + // (id, -1) point on t1 + // (-1, id) point on t2 + // (id1, id2) intersection of edges + std::pair t1_t2_ids; + int sign; + typename Kernel::FT alpha; + + Orientation + orientation (const typename Kernel::Point_3& p1, // source of edge edge_ids1 + const typename Kernel::Point_3& q1, // target of edge edge_ids1 + const typename Kernel::Point_3& r1, + int edge_id1, + const typename Kernel::Point_3& p2, + const typename Kernel::Point_3& q2, + const typename Kernel::Point_3& r2, + const Kernel& k) const + { + if (t1_t2_ids.first!=-1) + { + if (t1_t2_ids.second==-1) return ZERO; // it is a point on t1 + // this is an intersection point + if (sign == 0) + return POSITIVE; + if (sign == -1) + return edge_id1==t1_t2_ids.first+1?POSITIVE:NEGATIVE; + else + return edge_id1==t1_t2_ids.first+1?NEGATIVE:POSITIVE; + } + else + { + //this is an input point of t2 + typename Kernel::Coplanar_orientation_3 orient = k.coplanar_orientation_3_object(); + const typename Kernel::Point_3& query = point_from_id(p2,q2,r2,t1_t2_ids.second); + return orient(p1,q1,r1,query); + } + } + + int id1() const { return t1_t2_ids.first; } + int id2() const { return t1_t2_ids.second; } + + typename Kernel::Point_3 + point(const typename Kernel::Point_3& p1, + const typename Kernel::Point_3& q1, + const typename Kernel::Point_3& r1, + const typename Kernel::Point_3& p2, + const typename Kernel::Point_3& q2, + const typename Kernel::Point_3& r2, + const Kernel& k) const + { + if (t1_t2_ids.first==-1) + return point_from_id(p2,q2,r2,t1_t2_ids.second); + if (t1_t2_ids.second==-1) + return point_from_id(p1,q1,r1,t1_t2_ids.first); + + return k.construct_barycenter_3_object()(point_from_id(p2,q2,r2,(t1_t2_ids.second+1)%3), alpha, point_from_id(p2,q2,r2,t1_t2_ids.second)) ; + } +}; + template -void intersection_coplanar_triangles_cutoff(const typename Kernel::Point_3& p, - const typename Kernel::Point_3& q, - const typename Kernel::Point_3& r, +Point_on_triangle +intersection(const Point_on_triangle& p, + const Point_on_triangle& q, + int edge_id_t1, + const typename Kernel::Point_3& p1, + const typename Kernel::Point_3& q1, +// const typename Kernel::Point_3& r1, + const typename Kernel::Point_3& p2, + const typename Kernel::Point_3& q2, + const typename Kernel::Point_3& r2, + const Kernel& k) +{ + typedef Point_on_triangle Pot; + switch(p.id1()) + { + case -1: + { + switch(q.id1()) + { + case -1: // (-1, ip2) - (-1, iq2) + { + typename Kernel::FT alpha = + coplanar_segment_segment_alpha_intersection(p1, q1, + Pot::point_from_id(p2, q2, r2, p.id2()), + Pot::point_from_id(p2, q2, r2, q.id2()), k); + int sgn = sign(alpha); + return Point_on_triangle(edge_id_t1, p.id2(), sgn, alpha); // intersection with an original edge of t2 + } + default: + if (q.id2()!=-1) // (-1, ip2) - (iq1, iq2) + { + // we shorten an already cut edge + CGAL_assertion((p.id2()+1)%3 == q.id2()); + + typename Kernel::FT alpha = + coplanar_segment_segment_alpha_intersection(p1, q1, + Pot::point_from_id(p2, q2, r2, p.id2()), + Pot::point_from_id(p2, q2, r2, q.id2()), k); + int sgn = sign(alpha); + return Point_on_triangle(edge_id_t1, p.id2(), sgn, alpha); + } + // (-1, ip2) - (iq1, -1) + //vertex of t1, special case t1 edge passed thru a vertex of t2 + CGAL_assertion(edge_id_t1 == 2); + return Point_on_triangle(2, -1); // point on t1 has to be created from the intersection of edge 0 and edge 1 + } + } + default: + { + switch(p.id2()) + { + case -1: + { + switch(q.id1()) + { + case -1: // (ip1, -1) - (-1, iq2) + //vertex of t1, special case t1 edge passed thru a vertex of t2 + return Point_on_triangle(0, -1); + default: + { + CGAL_assertion(q.id2()!=-1); // (ip1, -1) - (iq2, -1) + //(ip1,-1), (iq1, iq2) + CGAL_assertion(edge_id_t1==2 && p.id1()==1); + return Point_on_triangle(q.id1()==1?2:0,-1); // vertex of t1 + } + } + } + default: + { + switch(q.id1()) + { + case -1: // (ip1, ip2) - (-1, iq2) + { + // we shorten an already cut edge + CGAL_assertion((q.id2()+1)%3 == p.id2()); + + typename Kernel::FT alpha = + coplanar_segment_segment_alpha_intersection(p1, q1, + Pot::point_from_id(p2, q2, r2, q.id2()), + Pot::point_from_id(p2, q2, r2, p.id2()), k); + int sgn = sign(alpha); + return Point_on_triangle(edge_id_t1, p.id2(), sgn, alpha); + } + default: + { + switch(q.id2()) + { + case -1: // (ip1, ip2) - (iq1, -1) + { + CGAL_assertion(edge_id_t1==2 && q.id1()==1); + return Point_on_triangle(p.id1()==1?2:0); // vertex of t1 + } + default: // (ip1, ip2) - (iq1, iq2) + return Point_on_triangle((p.id1()+1)%3==q.id1()?q.id1():p.id1(), -1); // vertex of t1 + } + } + } + } + } + } + } +} + +template +void intersection_coplanar_triangles_cutoff(const typename Kernel::Point_3& p1, + const typename Kernel::Point_3& q1, + const typename Kernel::Point_3& r1, + int edge_id, + const typename Kernel::Point_3& p2, + const typename Kernel::Point_3& q2, + const typename Kernel::Point_3& r2, const Kernel& k, - std::list& inter_pts) + std::list>& inter_pts) { - typedef typename std::list::iterator Iterator; + typedef typename std::list>::iterator Iterator; if(inter_pts.empty()) return; - typename Kernel::Coplanar_orientation_3 orient = k.coplanar_orientation_3_object(); - typename Kernel::Construct_line_3 line = k.construct_line_3_object(); - - //orient(p,q,r,r) is POSITIVE - std::map orientations; - for (Iterator it=inter_pts.begin();it!=inter_pts.end();++it) - orientations[ &(*it) ]=orient(p,q,r,*it); + //orient(p1,q1,r1,r1) is POSITIVE + std::map*,Orientation> orientations; // TODO skip map + for (const Point_on_triangle& pot : inter_pts) + orientations[ &pot ]=pot.orientation(p1,q1,r1,edge_id,p2,q2,r2,k); - CGAL_kernel_assertion_code(int pt_added = 0;) + CGAL_kernel_assertion_code(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()); + Iterator prev = std::prev(inter_pts.end()); + Iterator stop = inter_pts.size() > 2 ? inter_pts.end() : std::prev(inter_pts.end()); for(Iterator it=inter_pts.begin(); it!=stop; ++it) { - const typename Kernel::Point_3& curr = *it; - Orientation or_prev = orientations[prev], - or_curr = orientations[&curr]; + Orientation or_prev = orientations[&(*prev)], + or_curr = orientations[&(*it)]; if((or_prev == POSITIVE && or_curr == NEGATIVE) || (or_prev == NEGATIVE && or_curr == POSITIVE)) { - typename Intersection_traits::result_type - obj = intersection(line(p,q), line(*prev,curr), k); - - // assert "not empty" - CGAL_kernel_assertion(bool(obj)); + Point_on_triangle new_pt = intersection(*prev, *it, edge_id, p1, q1, p2, q2, r2, k); - const typename Kernel::Point_3* inter = intersect_get(obj); - CGAL_kernel_assertion(inter != nullptr); - - prev = &(*inter_pts.insert(it,*inter)); - orientations[prev] = COLLINEAR; - CGAL_kernel_assertion_code(++pt_added;) + prev = inter_pts.insert(it,new_pt); + orientations[&(*prev)] = COLLINEAR; + CGAL_assertion_code(++pt_added); } - prev = &(*it); + prev = it; } CGAL_kernel_assertion(pt_added<3); @@ -98,35 +301,41 @@ intersection_coplanar_triangles(const typename K::Triangle_3& t1, const typename K::Triangle_3& t2, const K& k) { - const typename K::Point_3& p = t1.vertex(0), - q = t1.vertex(1), - r = t1.vertex(2); + const typename K::Point_3& p1 = t1.vertex(0), + q1 = t1.vertex(1), + r1 = t1.vertex(2); + + const typename K::Point_3& p2 = t2.vertex(0), + q2 = t2.vertex(1), + r2 = t2.vertex(2); - std::list inter_pts; - inter_pts.push_back(t2.vertex(0)); - inter_pts.push_back(t2.vertex(1)); - inter_pts.push_back(t2.vertex(2)); + std::list> inter_pts; + inter_pts.push_back(Point_on_triangle(-1,0)); + inter_pts.push_back(Point_on_triangle(-1,1)); + inter_pts.push_back(Point_on_triangle(-1,2)); //intersect t2 with the three half planes which intersection defines t1 - 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 + intersection_coplanar_triangles_cutoff(p1,q1,r1,0,p2,q2,r2,k,inter_pts); //line pq + intersection_coplanar_triangles_cutoff(q1,r1,p1,1,p2,q2,r2,k,inter_pts); //line qr + intersection_coplanar_triangles_cutoff(r1,p1,q1,2,p2,q2,r2,k,inter_pts); //line rp + auto point = [&](const Point_on_triangle& pot){ return pot.point(p1,q1,r1,p2,q2,r2,k); }; switch(inter_pts.size()) { case 0: return intersection_return(); case 1: - return intersection_return(*inter_pts.begin()); + return intersection_return(point(*inter_pts.begin())); case 2: return intersection_return( - k.construct_segment_3_object()(*inter_pts.begin(), *boost::next(inter_pts.begin())) ); + k.construct_segment_3_object()(point(*inter_pts.begin()), point(*std::next(inter_pts.begin()))) ); case 3: return intersection_return( - k.construct_triangle_3_object()(*inter_pts.begin(), *boost::next(inter_pts.begin()), *boost::prior(inter_pts.end())) ); + k.construct_triangle_3_object()(point(*inter_pts.begin()), point(*std::next(inter_pts.begin())), point(*std::prev(inter_pts.end()))) ); default: return intersection_return( - std::vector(inter_pts.begin(),inter_pts.end())); + std::vector(boost::make_transform_iterator(inter_pts.begin(), point), + boost::make_transform_iterator(inter_pts.end(), point))); } } diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index ae9858ae77d5..6d0334d93661 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -36,8 +36,8 @@ #include -// #define TEST_RESOLVE_INTERSECTION -// #define DEDUPLICATE_SEGMENTS +//#define TEST_RESOLVE_INTERSECTION +//#define DEDUPLICATE_SEGMENTS namespace CGAL { namespace Polygon_mesh_processing { @@ -259,6 +259,9 @@ void collect_intersections(const std::array& t1, if (ori[0]== COPLANAR && ori[1]==COPLANAR && ori[2]==COPLANAR) { coplanar_intersections(t1, t2, inter_pts); + for (auto p : inter_pts) + if (depth(p)>2) throw std::runtime_error("Depth is not 2: "+std::to_string(depth(p))); + return; } @@ -283,6 +286,11 @@ void collect_intersections(const std::array& t1, std::sort(inter_pts.begin(), inter_pts.end()); auto last = std::unique(inter_pts.begin(), inter_pts.end()); inter_pts.erase(last, inter_pts.end()); + + + for (auto p : inter_pts) + if (depth(p)>2) throw std::runtime_error("Depth is not 2: "+std::to_string(depth(p))); + } ////////////////////////////////// @@ -300,6 +308,10 @@ void generate_subtriangles(std::size_t ti, const std::vector>& triangles, std::vector>& new_triangles) { + //~ std::cout << "generate_subtriangles()\n"; + std::cout << std::setprecision(17); + + typedef CGAL::Projection_traits_3 P_traits; typedef CGAL::Exact_intersections_tag Itag; @@ -395,7 +407,7 @@ void generate_subtriangles(std::size_t ti, points_on_segments[i].push_back(*pt_ptr); points_on_segments[j].push_back(*pt_ptr); - //~ std::cout << "new inter " << *pt_ptr << "\n"; + //~ std::cout << "new inter " << *pt_ptr << " (" << depth(points_on_segments[i].back()) << ")" << "\n"; } } @@ -417,7 +429,7 @@ void generate_subtriangles(std::size_t ti, points_on_segments[i].push_back(*pt_ptr); points_on_segments[j].push_back(*pt_ptr); - //~ std::cout << "new inter bis" << *pt_ptr << "\n"; + //~ std::cout << "new inter bis " << *pt_ptr << " (" << depth(points_on_segments[i].back()) << ")" << "\n"; } else { @@ -428,6 +440,8 @@ void generate_subtriangles(std::size_t ti, points_on_segments[i].push_back(seg_ptr->target()); points_on_segments[j].push_back(seg_ptr->target()); + //~ std::cout << "new inter seg " << *seg_ptr << " (" << depth(*seg_ptr) << ")" << "\n"; + } else throw std::runtime_error("BOOM\n"); @@ -537,6 +551,20 @@ void generate_subtriangles(std::size_t ti, } } + //~ int max_degree = 0; + //~ for (const auto p : cst_points) + //~ max_degree = std::max(max_degree, depth(p)); + //~ std::cout << "max_degree " << max_degree << "\n"; + + //~ if (max_degree > 10){ + //~ for (const auto p : cst_points) + //~ std::cout << " -- " << p << "(" << depth(p) << ")\n"; + //~ std::cout << "segments:\n"; + //~ for (auto s : segments) + //~ std::cout << " " << depth(s[0]) << " " << depth(s[1]) << "\n"; + //~ exit(1); + //~ } + cdt.insert_constraints(cst_points.begin(), cst_points.end(), csts.begin(), csts.end()); std::vector> no_inter_segments; From 8e050bdb49c5268af0e12bb48bcf34edd01db96c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 1 Mar 2023 15:39:28 +0100 Subject: [PATCH 029/329] fix various bug and add debug triangle_3_triangle_3_intersection now passes --- .../Triangle_3_Triangle_3_intersection.h | 131 +++++++++++++----- 1 file changed, 98 insertions(+), 33 deletions(-) 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 d4e467a07986..55610e867ff3 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 @@ -14,6 +14,8 @@ #ifndef CGAL_INTERNAL_INTERSECTIONS_TRIANGLE_3_TRIANGLE_3_INTERSECTION_H #define CGAL_INTERNAL_INTERSECTIONS_TRIANGLE_3_TRIANGLE_3_INTERSECTION_H +//#define CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + #include #include #include @@ -74,21 +76,20 @@ struct Point_on_triangle } } - Point_on_triangle(int i1, int i2=-1, int sign=0, typename Kernel::FT alpha = 0.) // TODO add global zero()? + Point_on_triangle(int i1, int i2=-1, typename Kernel::FT alpha = 0.) // TODO add global zero()? : t1_t2_ids(i1,i2) - , sign(sign) + , alpha(alpha) {} // (id, -1) point on t1 // (-1, id) point on t2 // (id1, id2) intersection of edges std::pair t1_t2_ids; - int sign; typename Kernel::FT alpha; Orientation - orientation (const typename Kernel::Point_3& p1, // source of edge edge_ids1 - const typename Kernel::Point_3& q1, // target of edge edge_ids1 + orientation (const typename Kernel::Point_3& p1, // source of edge edge_id1 + const typename Kernel::Point_3& q1, // target of edge edge_id1 const typename Kernel::Point_3& r1, int edge_id1, const typename Kernel::Point_3& p2, @@ -98,15 +99,21 @@ struct Point_on_triangle { if (t1_t2_ids.first!=-1) { - if (t1_t2_ids.second==-1) return ZERO; // it is a point on t1 + if (t1_t2_ids.second==-1) + return (edge_id1==t1_t2_ids.first || (edge_id1+1)%3==t1_t2_ids.first) ? ZERO:POSITIVE; // it is a point on t1 // this is an intersection point - if (sign == 0) - return POSITIVE; - if (sign == -1) - return edge_id1==t1_t2_ids.first+1?POSITIVE:NEGATIVE; - else - return edge_id1==t1_t2_ids.first+1?NEGATIVE:POSITIVE; - } + + if (t1_t2_ids.first==edge_id1) + return ZERO; + if (t1_t2_ids.first==(edge_id1+1)%3) + { + if (alpha==0) return ZERO; + return alpha>=0 ? POSITIVE:NEGATIVE; + } + CGAL_assertion((t1_t2_ids.first+1)%3==edge_id1); + if (alpha==1) return ZERO; + return alpha<=1?POSITIVE:NEGATIVE; + } else { //this is an input point of t2 @@ -150,6 +157,11 @@ intersection(const Point_on_triangle& p, const typename Kernel::Point_3& r2, const Kernel& k) { +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + std::cout << " calling intersection: "; + std::cout << " (" << p.id1() << "," << p.id2() << ",[" << p.alpha << "])-"; + std::cout << " (" << q.id1() << "," << q.id2() << ",[" << q.alpha << "]) || e" << edge_id_t1 << "\n"; +#endif typedef Point_on_triangle Pot; switch(p.id1()) { @@ -163,21 +175,23 @@ intersection(const Point_on_triangle& p, coplanar_segment_segment_alpha_intersection(p1, q1, Pot::point_from_id(p2, q2, r2, p.id2()), Pot::point_from_id(p2, q2, r2, q.id2()), k); - int sgn = sign(alpha); - return Point_on_triangle(edge_id_t1, p.id2(), sgn, alpha); // intersection with an original edge of t2 + return Point_on_triangle(edge_id_t1, p.id2(), alpha); // intersection with an original edge of t2 } default: if (q.id2()!=-1) // (-1, ip2) - (iq1, iq2) { - // we shorten an already cut edge - CGAL_assertion((p.id2()+1)%3 == q.id2()); - - typename Kernel::FT alpha = - coplanar_segment_segment_alpha_intersection(p1, q1, - Pot::point_from_id(p2, q2, r2, p.id2()), - Pot::point_from_id(p2, q2, r2, q.id2()), k); - int sgn = sign(alpha); - return Point_on_triangle(edge_id_t1, p.id2(), sgn, alpha); + if (p.id2() == q.id2() || p.id2() == (q.id2()+1)%3) + { + // points are on the same edge of t2 --> we shorten an already cut edge + typename Kernel::FT alpha = + coplanar_segment_segment_alpha_intersection(p1, q1, + Pot::point_from_id(p2, q2, r2, q.id2()), + Pot::point_from_id(p2, q2, r2, (q.id2()+1)%3), k); + + return Point_on_triangle(edge_id_t1, q.id2(), alpha); + } + // point of t1 + return Point_on_triangle((q.id1()+1)%3==edge_id_t1?edge_id_t1:(edge_id_t1+1)%3 , -1); } // (-1, ip2) - (iq1, -1) //vertex of t1, special case t1 edge passed thru a vertex of t2 @@ -211,15 +225,18 @@ intersection(const Point_on_triangle& p, { case -1: // (ip1, ip2) - (-1, iq2) { - // we shorten an already cut edge - CGAL_assertion((q.id2()+1)%3 == p.id2()); + if (q.id2() == p.id2() || q.id2() == (p.id2()+1)%3) + { + // points are on the same edge of t2 --> we shorten an already cut edge + typename Kernel::FT alpha = + coplanar_segment_segment_alpha_intersection(p1, q1, + Pot::point_from_id(p2, q2, r2, p.id2()), + Pot::point_from_id(p2, q2, r2, (p.id2()+1)%3), k); - typename Kernel::FT alpha = - coplanar_segment_segment_alpha_intersection(p1, q1, - Pot::point_from_id(p2, q2, r2, q.id2()), - Pot::point_from_id(p2, q2, r2, p.id2()), k); - int sgn = sign(alpha); - return Point_on_triangle(edge_id_t1, p.id2(), sgn, alpha); + return Point_on_triangle(edge_id_t1, p.id2(), alpha); + } + // point of t1 + return Point_on_triangle((p.id1()+1)%3==edge_id_t1?edge_id_t1:(edge_id_t1+1)%3 , -1); } default: { @@ -231,7 +248,8 @@ intersection(const Point_on_triangle& p, return Point_on_triangle(p.id1()==1?2:0); // vertex of t1 } default: // (ip1, ip2) - (iq1, iq2) - return Point_on_triangle((p.id1()+1)%3==q.id1()?q.id1():p.id1(), -1); // vertex of t1 + CGAL_assertion(p.id1()==q.id1()); + return Point_on_triangle((p.id1()+1)%3==edge_id_t1?edge_id_t1:(edge_id_t1+1)%3, -1); // vertex of t1 } } } @@ -252,6 +270,11 @@ void intersection_coplanar_triangles_cutoff(const typename Kernel::Point_3& p1, const Kernel& k, std::list>& inter_pts) { +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + std::cout << " cutoff using e" << edge_id << ": " + << to_double(p1.x()) << " " << to_double(p1.y()) << " " << to_double(p1.z()) << " " + << to_double(q1.x()) << " " << to_double(q1.y()) << " " << to_double(q1.z()) << "\n"; +#endif typedef typename std::list>::iterator Iterator; if(inter_pts.empty()) @@ -262,6 +285,12 @@ void intersection_coplanar_triangles_cutoff(const typename Kernel::Point_3& p1, for (const Point_on_triangle& pot : inter_pts) orientations[ &pot ]=pot.orientation(p1,q1,r1,edge_id,p2,q2,r2,k); +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + std::cout << " Orientations:"; + for (const Point_on_triangle& pot : inter_pts) + std::cout << " " << orientations[ &pot ]; + std::cout << "\n"; +#endif CGAL_kernel_assertion_code(int pt_added = 0); Iterator prev = std::prev(inter_pts.end()); @@ -301,6 +330,22 @@ intersection_coplanar_triangles(const typename K::Triangle_3& t1, const typename K::Triangle_3& t2, const K& k) { +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + auto to_string = [](const typename K::Triangle_3& t) + { + std::stringstream sstr; + sstr << "4 " + << to_double(t[0].x()) << " " << to_double(t[0].y()) << " " << to_double(t[0].z()) << " " + << to_double(t[1].x()) << " " << to_double(t[1].y()) << " " << to_double(t[1].z()) << " " + << to_double(t[2].x()) << " " << to_double(t[2].y()) << " " << to_double(t[2].z()) << " " + << to_double(t[0].x()) << " " << to_double(t[0].y()) << " " << to_double(t[0].z()) << "\n"; + return sstr.str(); + }; + + std::cout << "intersection_coplanar_triangles\n"; + std::ofstream("/tmp/t1.polylines.txt") << to_string(t1) << "\n"; + std::ofstream("/tmp/t2.polylines.txt") << to_string(t2) << "\n"; +#endif const typename K::Point_3& p1 = t1.vertex(0), q1 = t1.vertex(1), r1 = t1.vertex(2); @@ -314,10 +359,30 @@ intersection_coplanar_triangles(const typename K::Triangle_3& t1, inter_pts.push_back(Point_on_triangle(-1,1)); inter_pts.push_back(Point_on_triangle(-1,2)); +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + auto print_points = [&]() + { + for(auto p : inter_pts) std::cout << " (" << p.id1() << "," << p.id2() << ",[" << p.alpha << "]) "; std::cout <<"\n"; + }; + std::cout << " ipts size: " << inter_pts.size() << "\n"; + print_points(); +#endif //intersect t2 with the three half planes which intersection defines t1 intersection_coplanar_triangles_cutoff(p1,q1,r1,0,p2,q2,r2,k,inter_pts); //line pq +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + std::cout << " ipts size: " << inter_pts.size() << "\n"; + print_points(); +#endif intersection_coplanar_triangles_cutoff(q1,r1,p1,1,p2,q2,r2,k,inter_pts); //line qr +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + std::cout << " ipts size: " << inter_pts.size() << "\n"; + print_points(); +#endif intersection_coplanar_triangles_cutoff(r1,p1,q1,2,p2,q2,r2,k,inter_pts); //line rp +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + std::cout << " ipts size: " << inter_pts.size() << "\n"; + print_points(); +#endif auto point = [&](const Point_on_triangle& pot){ return pot.point(p1,q1,r1,p2,q2,r2,k); }; switch(inter_pts.size()) From 0bf300d5c51ea71657925aec1a3e6721729cc3c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 1 Mar 2023 17:19:35 +0100 Subject: [PATCH 030/329] plug new coplanar triangle intersection code --- .../Polygon_mesh_processing/autorefinement.h | 38 ++++++++++++++----- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 6d0334d93661..b87a04c8a6a2 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -83,26 +83,44 @@ do_coplanar_segments_intersect(const std::array& s1, ////////////////////////////////// // imported from Intersections_3/include/CGAL/Intersections_3/internal/Triangle_3_Triangle_3_intersection.h - template void coplanar_intersections(const std::array& t1, const std::array& t2, std::vector& inter_pts) { - const typename K::Point_3& p = t1[0], q = t1[1], r = t1[2]; + const typename K::Point_3& p1 = t1[0], q1 = t1[1], r1 = t1[2]; + const typename K::Point_3& p2 = t2[0], q2 = t2[1], r2 = t2[2]; + + std::list> l_inter_pts; + l_inter_pts.push_back(Intersections::internal::Point_on_triangle(-1,0)); + l_inter_pts.push_back(Intersections::internal::Point_on_triangle(-1,1)); + l_inter_pts.push_back(Intersections::internal::Point_on_triangle(-1,2)); + +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + auto to_string = [](const auto& t) + { + std::stringstream sstr; + sstr << "4 " + << to_double(t[0].x()) << " " << to_double(t[0].y()) << " " << to_double(t[0].z()) << " " + << to_double(t[1].x()) << " " << to_double(t[1].y()) << " " << to_double(t[1].z()) << " " + << to_double(t[2].x()) << " " << to_double(t[2].y()) << " " << to_double(t[2].z()) << " " + << to_double(t[0].x()) << " " << to_double(t[0].y()) << " " << to_double(t[0].z()) << "\n"; + return sstr.str(); + }; - std::list l_inter_pts; - l_inter_pts.push_back(t2[0]); - l_inter_pts.push_back(t2[1]); - l_inter_pts.push_back(t2[2]); + std::cout << "intersection_coplanar_triangles\n"; + std::ofstream("/tmp/t1.polylines.txt") << to_string(t1) << "\n"; + std::ofstream("/tmp/t2.polylines.txt") << to_string(t2) << "\n"; +#endif //intersect t2 with the three half planes which intersection defines t1 K k; - Intersections::internal::intersection_coplanar_triangles_cutoff(p,q,r,k,l_inter_pts); //line pq - Intersections::internal::intersection_coplanar_triangles_cutoff(q,r,p,k,l_inter_pts); //line qr - Intersections::internal::intersection_coplanar_triangles_cutoff(r,p,q,k,l_inter_pts); //line rp + intersection_coplanar_triangles_cutoff(p1,q1,r1,0,p2,q2,r2,k,l_inter_pts); //line p1q1 + intersection_coplanar_triangles_cutoff(q1,r1,p1,1,p2,q2,r2,k,l_inter_pts); //line q1r1 + intersection_coplanar_triangles_cutoff(r1,p1,q1,2,p2,q2,r2,k,l_inter_pts); //line r1p1 - inter_pts.assign(l_inter_pts.begin(), l_inter_pts.end()); + for (const Intersections::internal::Point_on_triangle& pot : l_inter_pts) + inter_pts.push_back( pot.point(p1,q1,r1,p2,q2,r2,k) ); } // imported from Polygon_mesh_processing/internal/Corefinement/intersect_triangle_segment_3.h From 4fa600bc5fbf357f071817c7e8a775e89d9b2fa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 3 Mar 2023 10:33:16 +0100 Subject: [PATCH 031/329] bug fix --- .../internal/Triangle_3_Triangle_3_intersection.h | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) 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 55610e867ff3..7c6ad7b95f82 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 @@ -33,6 +33,7 @@ namespace CGAL { namespace Intersections { namespace internal{ +//TODO: move into a functor template typename K::FT coplanar_segment_segment_alpha_intersection(const typename K::Point_3& p1, const typename K::Point_3& p2, // segment 1 @@ -248,8 +249,18 @@ intersection(const Point_on_triangle& p, return Point_on_triangle(p.id1()==1?2:0); // vertex of t1 } default: // (ip1, ip2) - (iq1, iq2) - CGAL_assertion(p.id1()==q.id1()); - return Point_on_triangle((p.id1()+1)%3==edge_id_t1?edge_id_t1:(edge_id_t1+1)%3, -1); // vertex of t1 + { + CGAL_assertion(p.id1()==q.id1() || p.id2()==q.id2() ); + + if (p.id1()==q.id1()) + return Point_on_triangle((p.id1()+1)%3==edge_id_t1?edge_id_t1:(edge_id_t1+1)%3, -1); // vertex of t1 + + typename Kernel::FT alpha = + coplanar_segment_segment_alpha_intersection(p1, q1, + Pot::point_from_id(p2, q2, r2, q.id2()), + Pot::point_from_id(p2, q2, r2, (q.id2()+1)%3), k); + return Point_on_triangle(edge_id_t1, q.id2(), alpha); + } } } } From 2fade292146be00a4d383c8a0356802de81aa708 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 3 Mar 2023 10:35:42 +0100 Subject: [PATCH 032/329] add more debug --- .../Polygon_mesh_processing/autorefinement.h | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index b87a04c8a6a2..c5f3ebb78905 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -38,6 +38,7 @@ //#define TEST_RESOLVE_INTERSECTION //#define DEDUPLICATE_SEGMENTS +//#define DEBUG_DEPTH namespace CGAL { namespace Polygon_mesh_processing { @@ -111,13 +112,31 @@ void coplanar_intersections(const std::array& t1, std::cout << "intersection_coplanar_triangles\n"; std::ofstream("/tmp/t1.polylines.txt") << to_string(t1) << "\n"; std::ofstream("/tmp/t2.polylines.txt") << to_string(t2) << "\n"; + auto print_points = [&]() + { + for(auto p : l_inter_pts) std::cout << " (" << p.id1() << "," << p.id2() << ",[" << p.alpha << "]) "; std::cout <<"\n"; + }; + std::cout << " ipts size: " << l_inter_pts.size() << "\n"; + print_points(); #endif //intersect t2 with the three half planes which intersection defines t1 K k; intersection_coplanar_triangles_cutoff(p1,q1,r1,0,p2,q2,r2,k,l_inter_pts); //line p1q1 +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + std::cout << " ipts size: " << l_inter_pts.size() << "\n"; + print_points(); +#endif intersection_coplanar_triangles_cutoff(q1,r1,p1,1,p2,q2,r2,k,l_inter_pts); //line q1r1 +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + std::cout << " ipts size: " << l_inter_pts.size() << "\n"; + print_points(); +#endif intersection_coplanar_triangles_cutoff(r1,p1,q1,2,p2,q2,r2,k,l_inter_pts); //line r1p1 +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + std::cout << " ipts size: " << l_inter_pts.size() << "\n"; + print_points(); +#endif for (const Intersections::internal::Point_on_triangle& pot : l_inter_pts) inter_pts.push_back( pot.point(p1,q1,r1,p2,q2,r2,k) ); @@ -277,8 +296,10 @@ void collect_intersections(const std::array& t1, if (ori[0]== COPLANAR && ori[1]==COPLANAR && ori[2]==COPLANAR) { coplanar_intersections(t1, t2, inter_pts); +#ifdef DEBUG_DEPTH for (auto p : inter_pts) - if (depth(p)>2) throw std::runtime_error("Depth is not 2: "+std::to_string(depth(p))); + if (depth(p)>2) throw std::runtime_error("Depth is not 4: "+std::to_string(depth(p))); +#endif return; } @@ -308,7 +329,6 @@ void collect_intersections(const std::array& t1, for (auto p : inter_pts) if (depth(p)>2) throw std::runtime_error("Depth is not 2: "+std::to_string(depth(p))); - } ////////////////////////////////// From f3e4a60f96be4fe94124a8c945a0bd3bd2f5ffb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 6 Mar 2023 14:03:24 +0100 Subject: [PATCH 033/329] fix intersection point computation --- .../internal/Triangle_3_Triangle_3_intersection.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) 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 7c6ad7b95f82..ac376f443506 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 @@ -141,7 +141,7 @@ struct Point_on_triangle if (t1_t2_ids.second==-1) return point_from_id(p1,q1,r1,t1_t2_ids.first); - return k.construct_barycenter_3_object()(point_from_id(p2,q2,r2,(t1_t2_ids.second+1)%3), alpha, point_from_id(p2,q2,r2,t1_t2_ids.second)) ; + return k.construct_barycenter_3_object()(point_from_id(p1,q1,r1,(t1_t2_ids.first+1)%3), alpha, point_from_id(p1,q1,r1,t1_t2_ids.first)) ; } }; @@ -160,8 +160,8 @@ intersection(const Point_on_triangle& p, { #ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION std::cout << " calling intersection: "; - std::cout << " (" << p.id1() << "," << p.id2() << ",[" << p.alpha << "])-"; - std::cout << " (" << q.id1() << "," << q.id2() << ",[" << q.alpha << "]) || e" << edge_id_t1 << "\n"; + std::cout << " (" << p.id1() << "," << p.id2() << ",[" << p.alpha << "]) -"; + std::cout << " (" << q.id1() << "," << q.id2() << ",[" << q.alpha << "]) || e" << edge_id_t1 << "\n"; #endif typedef Point_on_triangle Pot; switch(p.id1()) @@ -354,8 +354,8 @@ intersection_coplanar_triangles(const typename K::Triangle_3& t1, }; std::cout << "intersection_coplanar_triangles\n"; - std::ofstream("/tmp/t1.polylines.txt") << to_string(t1) << "\n"; - std::ofstream("/tmp/t2.polylines.txt") << to_string(t2) << "\n"; + std::ofstream("/tmp/t1.polylines.txt") << std::setprecision(17) << to_string(t1) << "\n"; + std::ofstream("/tmp/t2.polylines.txt") << std::setprecision(17) << to_string(t2) << "\n"; #endif const typename K::Point_3& p1 = t1.vertex(0), q1 = t1.vertex(1), From f499c392664483298fb4c26bc587cce758671b37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 6 Mar 2023 19:30:07 +0100 Subject: [PATCH 034/329] add a version with fixed dimension for projection --- .../Polygon_mesh_processing/autorefinement.h | 54 +++++++++++++++++-- 1 file changed, 49 insertions(+), 5 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index c5f3ebb78905..7524c9c7f342 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -38,8 +38,13 @@ //#define TEST_RESOLVE_INTERSECTION //#define DEDUPLICATE_SEGMENTS +//#define USE_FIXED_PROJECTION_TRAITS //#define DEBUG_DEPTH +#ifdef USE_FIXED_PROJECTION_TRAITS +#include +#endif + namespace CGAL { namespace Polygon_mesh_processing { @@ -337,7 +342,11 @@ void collect_intersections(const std::array& t1, ////////////////////////////////// ////////////////////////////////// -template +template void generate_subtriangles(std::size_t ti, std::vector>& segments, const std::vector& points, @@ -349,8 +358,11 @@ void generate_subtriangles(std::size_t ti, //~ std::cout << "generate_subtriangles()\n"; std::cout << std::setprecision(17); - +#ifdef USE_FIXED_PROJECTION_TRAITS + typedef ::CGAL::internal::Projection_traits_3 P_traits; +#else typedef CGAL::Projection_traits_3 P_traits; +#endif typedef CGAL::Exact_intersections_tag Itag; typedef CGAL::Constrained_Delaunay_triangulation_2set_point(t[2]); +#endif #ifdef TEST_RESOLVE_INTERSECTION //~ static std::ofstream debug("inter_segments.polylines.txt"); @@ -832,7 +852,31 @@ void autorefine_soup_output(const PointRange& input_points, if (all_segments[ti].empty() && all_points[ti].empty()) new_triangles.push_back(triangles[ti]); else + { + #ifdef USE_FIXED_PROJECTION_TRAITS + const std::array& t = triangles[ti]; + auto is_constant_in_dim = [](const std::array& t, int dim) + { + return t[0][dim]==t[1][dim] && t[0][dim]!=t[2][dim]; + }; + + typename EK::Vector_3 orth = CGAL::normal(t[0], t[1], t[2]); // TODO::avoid construction? + int c = CGAL::abs(orth[0]) > CGAL::abs(orth[1]) ? 0 : 1; + c = CGAL::abs(orth[2]) > CGAL::abs(orth[c]) ? 2 : c; + + if(c == 0) { + autorefine_impl::generate_subtriangles(ti, all_segments[ti], all_points[ti], all_in_triangle_ids[ti], intersecting_triangles, triangles, new_triangles); + } else if(c == 1) { + autorefine_impl::generate_subtriangles(ti, all_segments[ti], all_points[ti], all_in_triangle_ids[ti], intersecting_triangles, triangles, new_triangles); + } else if(c == 2) { + autorefine_impl::generate_subtriangles(ti, all_segments[ti], all_points[ti], all_in_triangle_ids[ti], intersecting_triangles, triangles, new_triangles); + } + #else autorefine_impl::generate_subtriangles(ti, all_segments[ti], all_points[ti], all_in_triangle_ids[ti], intersecting_triangles, triangles, new_triangles); + #endif + } + + } // brute force output: create a soup, orient and to-mesh From 3abf7c401b67eefc2a2408dbac40c11f7e933203 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 6 Mar 2023 19:31:26 +0100 Subject: [PATCH 035/329] add debug --- .../CGAL/Polygon_mesh_processing/autorefinement.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 7524c9c7f342..e5a7dbbb139e 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -145,6 +145,19 @@ void coplanar_intersections(const std::array& t1, for (const Intersections::internal::Point_on_triangle& pot : l_inter_pts) inter_pts.push_back( pot.point(p1,q1,r1,p2,q2,r2,k) ); + +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + std::ofstream debug("interpts.xyz"); + debug << std::setprecision(17); + debug << l_inter_pts.size() << "\n"; + for (auto pot : l_inter_pts) + debug << pot.point(p1,q1,r1,p2,q2,r2,k) << "\n"; + debug.close(); + std::cout <<"check!\n"; + int i; + std::cin >> i; +#endif + } // imported from Polygon_mesh_processing/internal/Corefinement/intersect_triangle_segment_3.h From 8ff9f17a415524a52aa253b3c148ad45459de656 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 13 Mar 2023 15:33:35 +0100 Subject: [PATCH 036/329] restore traits creation --- .../include/CGAL/Polygon_mesh_processing/autorefinement.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index e5a7dbbb139e..3bb845854ec2 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -401,13 +401,14 @@ void generate_subtriangles(std::size_t ti, cdt.insert(t[1]); cdt.insert(t[2]); #else - P_traits cdt_traits(n); bool orientation_flipped = false; if ( typename EK::Less_xyz_3()(o+n,o) ) { n=-n; orientation_flipped = true; } + + P_traits cdt_traits(n); CDT cdt(cdt_traits); cdt.insert_outside_affine_hull(t[0]); cdt.insert_outside_affine_hull(t[1]); From 14105bbdd4319109f83b256b7af86e855870a487 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 14 Mar 2023 13:56:54 +0100 Subject: [PATCH 037/329] always use local indices for range insertion of constraints --- .../Polygon_mesh_processing/autorefinement.h | 253 ++++++++++++------ 1 file changed, 167 insertions(+), 86 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 3bb845854ec2..a81b00f65a48 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -37,7 +37,8 @@ #include //#define TEST_RESOLVE_INTERSECTION -//#define DEDUPLICATE_SEGMENTS +#define DEDUPLICATE_SEGMENTS +//#define DEBUG_COUNTERS //#define USE_FIXED_PROJECTION_TRAITS //#define DEBUG_DEPTH @@ -45,6 +46,10 @@ #include #endif +#ifdef DEBUG_COUNTERS +#include +#endif + namespace CGAL { namespace Polygon_mesh_processing { @@ -55,28 +60,28 @@ enum Segment_inter_type { NO_INTERSECTION=0, COPLANAR_SEGMENTS, POINT_INTERSECTI template Segment_inter_type -do_coplanar_segments_intersect(const std::array& s1, - const std::array& s2, +do_coplanar_segments_intersect(const typename K::Point_3& s1_0, const typename K::Point_3& s1_1, + const typename K::Point_3& s2_0, const typename K::Point_3& s2_1, const K& k = K()) { // supporting_line intersects: points are coplanar 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]); + ::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]) || - cln_order(s1[0], s2[1], s1[1]) || - cln_order(s2[0], s1[0], s2[1])) ? COPLANAR_SEGMENTS : NO_INTERSECTION; + 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)) ? COPLANAR_SEGMENTS : NO_INTERSECTION; } if(or1 != or2) { - or1 = cpl_orient(s2[0], s2[1], s1[0]); - return (or1 == COLLINEAR || or1 != cpl_orient(s2[0], s2[1], s1[1])) ? POINT_INTERSECTION : NO_INTERSECTION; + or1 = cpl_orient(s2_0, s2_1, s1_0); + return (or1 == COLLINEAR || or1 != cpl_orient(s2_0, s2_1, s1_1)) ? POINT_INTERSECTION : NO_INTERSECTION; } return NO_INTERSECTION; @@ -361,8 +366,8 @@ template void generate_subtriangles(std::size_t ti, - std::vector>& segments, - const std::vector& points, + std::vector>& segments, + std::vector& points, const std::vector& in_triangle_ids, const std::set >& intersecting_triangles, const std::vector>& triangles, @@ -376,13 +381,14 @@ void generate_subtriangles(std::size_t ti, #else typedef CGAL::Projection_traits_3 P_traits; #endif - typedef CGAL::Exact_intersections_tag Itag; - typedef CGAL::Constrained_Delaunay_triangulation_2 CDT_2; + + typedef CGAL::Constrained_Delaunay_triangulation_2 CDT_2; //typedef CGAL::Constrained_triangulation_plus_2 CDT; typedef CDT_2 CDT; @@ -416,6 +422,35 @@ void generate_subtriangles(std::size_t ti, v->set_point(t[2]); #endif +#ifdef DEBUG_COUNTERS + struct Counter + { + int c1=0; + int c2=0; + int c3=0; + int c4=0; + int total=0; + ~Counter() + { + std::cout << "intersection of 3 planes: " << c1 << "\n"; + std::cout << "coplanar segment intersection : " << c2 << "\n"; + std::cout << "coplanar segment overlap: " << c3 << "\n"; + std::cout << "no intersection: " << c4 << "\n"; + std::cout << "# pairs of segments : " << total << "\n"; + std::cout << "time computing segment intersections: " << timer1.time() << "\n"; + std::cout << "time sorting intersection points: " << timer2.time() << "\n"; + std::cout << "time for cdt of constraints: " << timer3.time() << "\n"; + } + CGAL::Real_timer timer1, timer2, timer3; + }; + + static Counter counter; +#define COUNTER_INSTRUCTION(X) X +#else +#define COUNTER_INSTRUCTION(X) +#endif + + #ifdef TEST_RESOLVE_INTERSECTION //~ static std::ofstream debug("inter_segments.polylines.txt"); //~ debug.precision(17); @@ -458,14 +493,33 @@ void generate_subtriangles(std::size_t ti, return typename EK::Plane_3(t[0], t[1], t[2]); }; - std::vector< std::vector > points_on_segments(nbs); + std::vector< std::vector > points_on_segments(nbs); + + COUNTER_INSTRUCTION(counter.timer1.start();) + + std::map point_id_map; + + for (std::size_t pid=0; pidsecond; + }; + + for (std::size_t i = 0; i(segments[i], segments[j]); + Segment_inter_type seg_inter_type = + do_coplanar_segments_intersect(points[segments[i].first], points[segments[i].second], + points[segments[j].first], points[segments[j].second]); switch(seg_inter_type) { case POINT_INTERSECTION: @@ -476,9 +530,11 @@ void generate_subtriangles(std::size_t ti, if (const typename EK::Point_3* pt_ptr = boost::get(&(*res))) { - points_on_segments[i].push_back(*pt_ptr); - points_on_segments[j].push_back(*pt_ptr); - + COUNTER_INSTRUCTION(++counter.c1;) + std::size_t pid = get_point_id(*pt_ptr); + points_on_segments[i].push_back(pid); + points_on_segments[j].push_back(pid); + break; //~ std::cout << "new inter " << *pt_ptr << " (" << depth(points_on_segments[i].back()) << ")" << "\n"; } @@ -490,30 +546,35 @@ void generate_subtriangles(std::size_t ti, //~ std::cout << "coplanar inter: " << i << " " << j << "\n"; - typename EK::Segment_3 s1(segments[i][0], segments[i][1]); - typename EK::Segment_3 s2(segments[j][0], segments[j][1]);// TODO: avoid this construction + typename EK::Segment_3 s1(points[segments[i].first], points[segments[i].second]); + typename EK::Segment_3 s2(points[segments[j].first], points[segments[j].second]);// TODO: avoid this construction auto inter = CGAL::intersection(s1, s2); if (inter == boost::none) throw std::runtime_error("Unexpected case #2"); if (const typename EK::Point_3* pt_ptr = boost::get(&(*inter))) { - points_on_segments[i].push_back(*pt_ptr); - points_on_segments[j].push_back(*pt_ptr); - + COUNTER_INSTRUCTION(++counter.c2;) + std::size_t pid = get_point_id(*pt_ptr); + points_on_segments[i].push_back(pid); + points_on_segments[j].push_back(pid); + break; //~ std::cout << "new inter bis " << *pt_ptr << " (" << depth(points_on_segments[i].back()) << ")" << "\n"; } else { if (const typename EK::Segment_3* seg_ptr = boost::get(&(*inter))) { - points_on_segments[i].push_back(seg_ptr->source()); - points_on_segments[j].push_back(seg_ptr->source()); - points_on_segments[i].push_back(seg_ptr->target()); - points_on_segments[j].push_back(seg_ptr->target()); - + //TODO HERE WE SHOULD IMPROVE TO AVOID RECOMPUTING SEGMENTS ENDPOINTS + COUNTER_INSTRUCTION(++counter.c3;) + std::size_t src_pid = get_point_id(seg_ptr->source()); + std::size_t tgt_pid = get_point_id(seg_ptr->target()); + points_on_segments[i].push_back(src_pid); + points_on_segments[j].push_back(src_pid); + points_on_segments[i].push_back(tgt_pid); + points_on_segments[j].push_back(tgt_pid); + break; //~ std::cout << "new inter seg " << *seg_ptr << " (" << depth(*seg_ptr) << ")" << "\n"; - } else throw std::runtime_error("BOOM\n"); @@ -564,24 +625,26 @@ void generate_subtriangles(std::size_t ti, //~ debug << "4 " << triangles[ti] << " " << triangles[ti][0] << "\n"; //~ exit(1); } - break; +// break; default: + COUNTER_INSTRUCTION(++counter.c4;) break; } } + COUNTER_INSTRUCTION(++counter.total;) } } - - std::vector cst_points; - std::vector> csts; + COUNTER_INSTRUCTION(counter.timer1.stop();) + COUNTER_INSTRUCTION(counter.timer2.start();) + std::size_t nb_new_segments=0; for (std::size_t i = 0; i& s = segments[i]; - typename EK::Point_3 src = s[0], tgt=s[1]; + std::size_t src_id = segments[i].first, tgt_id = segments[i].second; + typename EK::Point_3 src = points[src_id], tgt=points[tgt_id]; if (src.x()==tgt.x()) { coord=1; @@ -589,15 +652,23 @@ void generate_subtriangles(std::size_t ti, coord==2; } if (src[coord]>tgt[coord]) + { + std::swap(src_id, tgt_id); std::swap(src, tgt); + } - std::sort(points_on_segments[i].begin(), points_on_segments[i].end(), [coord](const typename EK::Point_3& p, const typename EK::Point_3& q){return p[coord]> no_inter_segments; - no_inter_segments.reserve(nbs); + // now fill segments with new segments + segments.reserve(segments.size()+nb_new_segments); for (std::size_t i = 0; i to_input; - std::map point_id_map; -#if ! defined(CGAL_NDEBUG) || defined(CGAL_DEBUG_PMP_AUTOREFINE) - std::vector exact_soup_points; -#endif - - auto get_point_id = [&](const typename EK::Point_3& pt) - { - auto insert_res = point_id_map.insert(std::make_pair(pt, soup_points.size())); - if (insert_res.second) - { - soup_points.push_back(to_input(pt)); -#if ! defined(CGAL_NDEBUG) || defined(CGAL_DEBUG_PMP_AUTOREFINE) - exact_soup_points.push_back(pt); -#endif - } - return insert_res.first->second; - }; - - // filter duplicated segments #ifdef DEDUPLICATE_SEGMENTS + // deduplicate inserted segments + std::vector>> all_segments_ids(all_segments.size()); for(std::size_t ti=0; ti point_id_map; + auto get_point_id = [&](const typename EK::Point_3& pt) + { + auto insert_res = point_id_map.insert(std::make_pair(pt, all_points[ti].size())); + if (insert_res.second) + all_points[ti].push_back(pt); + return insert_res.first->second; + }; + std::size_t nbs = all_segments[ti].size(); std::vector> filtered_segments; std::vector filtered_in_triangle_ids; @@ -841,19 +904,16 @@ void autorefine_soup_output(const PointRange& input_points, { EK::Point_3 src = all_segments[ti][si][0], tgt = all_segments[ti][si][1]; + std::size_t src_id = get_point_id(src), tgt_id=get_point_id(tgt); if (segset.insert( - CGAL::make_sorted_pair( get_point_id(src), - get_point_id(tgt))).second) + CGAL::make_sorted_pair(src_id, tgt_id)).second) { - filtered_segments.push_back(all_segments[ti][si]); + all_segments_ids[ti].emplace_back(src_id, tgt_id); filtered_in_triangle_ids.push_back(all_in_triangle_ids[ti][si]); } } - if (filtered_segments.size()!=nbs) - { - filtered_segments.swap(all_segments[ti]); + if (all_segments_ids[ti].size()!=nbs) filtered_in_triangle_ids.swap(all_in_triangle_ids[ti]); - } } } #endif @@ -886,7 +946,7 @@ void autorefine_soup_output(const PointRange& input_points, autorefine_impl::generate_subtriangles(ti, all_segments[ti], all_points[ti], all_in_triangle_ids[ti], intersecting_triangles, triangles, new_triangles); } #else - autorefine_impl::generate_subtriangles(ti, all_segments[ti], all_points[ti], all_in_triangle_ids[ti], intersecting_triangles, triangles, new_triangles); + autorefine_impl::generate_subtriangles(ti, all_segments_ids[ti], all_points[ti], all_in_triangle_ids[ti], intersecting_triangles, triangles, new_triangles); #endif } @@ -896,11 +956,31 @@ void autorefine_soup_output(const PointRange& input_points, // brute force output: create a soup, orient and to-mesh CGAL_PMP_AUTOREFINE_VERBOSE("create output soup"); + Cartesian_converter to_input; + std::map point_id_map; +#if ! defined(CGAL_NDEBUG) || defined(CGAL_DEBUG_PMP_AUTOREFINE) + std::vector exact_soup_points; +#endif + + auto get_point_id = [&](const typename EK::Point_3& pt) + { + auto insert_res = point_id_map.insert(std::make_pair(pt, soup_points.size())); + if (insert_res.second) + { + soup_points.push_back(to_input(pt)); +#if ! defined(CGAL_NDEBUG) || defined(CGAL_DEBUG_PMP_AUTOREFINE) + exact_soup_points.push_back(pt); +#endif + } + return insert_res.first->second; + }; + std::vector input_point_ids; input_point_ids.reserve(input_points.size()); for (const auto& p : input_points) input_point_ids.push_back(get_point_id(to_exact(get(pm,p)))); + // raw copy of input triangles with no intersection for (Input_TID f=0; f& t : new_triangles) { soup_triangles.emplace_back(CGAL::make_array(get_point_id(t[0]), get_point_id(t[1]), get_point_id(t[2]))); From 003910ee220262b370b31bfe525ecb20bf2e8a27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 14 Mar 2023 18:10:04 +0100 Subject: [PATCH 038/329] fix typo --- .../include/CGAL/Polygon_mesh_processing/autorefinement.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index a81b00f65a48..e18cf1982b2b 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -663,7 +663,7 @@ void generate_subtriangles(std::size_t ti, [&](std::size_t id1, std::size_t id2) { if (id1==id2) return false; - return points[id1][coord] Date: Tue, 14 Mar 2023 18:32:31 +0100 Subject: [PATCH 039/329] dramatic typo --- .../include/CGAL/Polygon_mesh_processing/autorefinement.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index e18cf1982b2b..d40fce82d2bc 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -649,7 +649,7 @@ void generate_subtriangles(std::size_t ti, { coord=1; if (src.y()==tgt.y()) - coord==2; + coord=2; } if (src[coord]>tgt[coord]) { From 5defd784cc0dae96083708f8b2454c2249509dad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 15 Mar 2023 14:24:37 +0100 Subject: [PATCH 040/329] better treatment of intersection between segments --- .../Polygon_mesh_processing/autorefinement.h | 447 ++++++++++++++---- 1 file changed, 346 insertions(+), 101 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index d40fce82d2bc..711c3d82ce0a 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -56,13 +56,59 @@ namespace Polygon_mesh_processing { #ifndef DOXYGEN_RUNNING namespace autorefine_impl { -enum Segment_inter_type { NO_INTERSECTION=0, COPLANAR_SEGMENTS, POINT_INTERSECTION }; + +enum Segment_inter_type_old { NO_INTERSECTION_OLD=0, COPLANAR_SEGMENTS, POINT_INTERSECTION_OLD }; +enum Segment_inter_type { NO_INTERSECTION=0, + POINT_INTERSECTION, + POINT_P, + POINT_Q, + POINT_R, + POINT_S, + COPLANAR_SEGMENT_PQ, + COPLANAR_SEGMENT_RS, + COPLANAR_SEGMENT_PS, + COPLANAR_SEGMENT_QS, + COPLANAR_SEGMENT_PR, + COPLANAR_SEGMENT_QR, + }; + + + +std::string print_enum(Segment_inter_type_old s) +{ + switch(s) + { + case NO_INTERSECTION_OLD: return "NO_INTERSECTION_OLD"; + case COPLANAR_SEGMENTS: return "COPLANAR_SEGMENTS"; + case POINT_INTERSECTION_OLD: return "POINT_INTERSECTION_OLD"; + } +} + +std::string print_enum(Segment_inter_type s) +{ + switch(s) + { + case NO_INTERSECTION: return "NO_INTERSECTION"; + case POINT_INTERSECTION: return "POINT_INTERSECTION"; + case POINT_P: return "POINT_P"; + case POINT_Q: return "POINT_Q"; + case POINT_R: return "POINT_R"; + case POINT_S: return "POINT_S"; + case COPLANAR_SEGMENT_PQ: return "COPLANAR_SEGMENT_PQ"; + case COPLANAR_SEGMENT_RS: return "COPLANAR_SEGMENT_RS"; + case COPLANAR_SEGMENT_PS: return "COPLANAR_SEGMENT_PS"; + case COPLANAR_SEGMENT_QS: return "COPLANAR_SEGMENT_QS"; + case COPLANAR_SEGMENT_PR: return "COPLANAR_SEGMENT_PR"; + case COPLANAR_SEGMENT_QR: return "COPLANAR_SEGMENT_QR"; + } +} + template -Segment_inter_type -do_coplanar_segments_intersect(const typename K::Point_3& s1_0, const typename K::Point_3& s1_1, - const typename K::Point_3& s2_0, const typename K::Point_3& s2_1, - const K& k = K()) +Segment_inter_type_old +do_coplanar_segments_intersect_old(const typename K::Point_3& s1_0, const typename K::Point_3& s1_1, + const typename K::Point_3& s2_0, const typename K::Point_3& s2_1, + const K& k = K()) { // supporting_line intersects: points are coplanar typename K::Coplanar_orientation_3 cpl_orient=k.coplanar_orientation_3_object(); @@ -75,13 +121,155 @@ do_coplanar_segments_intersect(const typename K::Point_3& s1_0, const typename K 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) || cln_order(s1_0, s2_1, s1_1) || - cln_order(s2_0, s1_0, s2_1)) ? COPLANAR_SEGMENTS : NO_INTERSECTION; + cln_order(s2_0, s1_0, s2_1)) ? COPLANAR_SEGMENTS : NO_INTERSECTION_OLD; } if(or1 != or2) { or1 = cpl_orient(s2_0, s2_1, s1_0); - return (or1 == COLLINEAR || or1 != cpl_orient(s2_0, s2_1, s1_1)) ? POINT_INTERSECTION : NO_INTERSECTION; + return (or1 == COLLINEAR || or1 != cpl_orient(s2_0, s2_1, s1_1)) ? POINT_INTERSECTION_OLD : NO_INTERSECTION_OLD; + } + + return NO_INTERSECTION_OLD; +} + + +// test intersection in the interior of segment pq and rs with pq and rs being coplanar segments +// note that for coplanar cases, we might report identical endpoints +template +Segment_inter_type +do_coplanar_segments_intersect(std::size_t pi, std::size_t qi, + std::size_t ri, std::size_t si, + const std::vector& points, + const K& k = K()) +{ + typename K::Collinear_are_ordered_along_line_3 cln_order = k.collinear_are_ordered_along_line_3_object(); + typename K::Coplanar_orientation_3 cpl_orient=k.coplanar_orientation_3_object(); + + const typename K::Point_3& p=points[pi]; + const typename K::Point_3& q=points[qi]; + const typename K::Point_3& r=points[ri]; + const typename K::Point_3& s=points[si]; + + // first handle case of shared endpoints + if (pi==ri) + { + if (si==qi || cpl_orient(p, q, s)!=COPLANAR) return NO_INTERSECTION; + // can be s, q or nothing + if (cln_order(p,s,q)) + return POINT_S; + if (cln_order(p,q,s)) + return POINT_Q; + return NO_INTERSECTION; + } + else + { + if(pi==si) + { + if (qi==ri || cpl_orient(p, q, r)!=COPLANAR) return NO_INTERSECTION; + // can be r, q or nothing + if (cln_order(p,r,q)) + return POINT_R; + if (cln_order(p,q,r)) + return POINT_Q; + return NO_INTERSECTION; + } + else + { + if (qi==ri) + { + if (pi==si || cpl_orient(p, q, s)!=COPLANAR) return NO_INTERSECTION; + // can be p, s or nothing + if (cln_order(p,s,q)) + return POINT_S; + if (cln_order(q,p,s)) + return POINT_P; + return NO_INTERSECTION; + } + else + { + if (qi==si) + { + if (pi==ri || cpl_orient(p, q, r)!=COPLANAR) return NO_INTERSECTION; + // can be p, r or nothing + if (cln_order(p,r,q)) + return POINT_R; + if (cln_order(q,p,r)) + return POINT_P; + return NO_INTERSECTION; + } + } + } + } + + // supporting_line intersects: points are coplanar + ::CGAL::Orientation pqr = cpl_orient(p, q, r); + ::CGAL::Orientation pqs = cpl_orient(p, q, s); + + if(pqr == COLLINEAR && pqs == COLLINEAR) + { + // segments are collinear + bool r_in_pq = cln_order(p, r, q), + s_in_pq = cln_order(p, s, q), + p_in_rs = cln_order(r, p, s); + + if (r_in_pq) + { + // intersection could be rs, pr or qr + if (s_in_pq) + return COPLANAR_SEGMENT_RS; + if (p_in_rs) + return COPLANAR_SEGMENT_PR; + CGAL_assertion(cln_order(r, q, s)); + return COPLANAR_SEGMENT_QR; + } + else + { + if (s_in_pq) + { + // intersection could be ps or qs + if (p_in_rs) + return COPLANAR_SEGMENT_PS; + CGAL_assertion(cln_order(r, q, s)); + return COPLANAR_SEGMENT_QS; + } + else + if (p_in_rs) + { + CGAL_assertion(cln_order(r, q, s)); + return COPLANAR_SEGMENT_PQ; + } + } + return NO_INTERSECTION; + } + + if(pqr != pqs) + { + ::CGAL::Orientation rsp = cpl_orient(r, s, p); + + if (rsp==COLLINEAR) + { + if (pqr==COLLINEAR || pqs==COLLINEAR) + { + throw std::runtime_error("no expected #1"); + } + return POINT_P; + } + ::CGAL::Orientation rsq = cpl_orient(r, s, q); + if (rsq==COLLINEAR) + { + if (pqr==COLLINEAR || pqs==COLLINEAR) + { + throw std::runtime_error("no expected #2"); + } + return POINT_Q; + } + if (rsp!=rsq) + { + if (pqr==COLLINEAR) return POINT_R; + if (pqs==COLLINEAR) return POINT_S; + return POINT_INTERSECTION; + } } return NO_INTERSECTION; @@ -429,6 +617,7 @@ void generate_subtriangles(std::size_t ti, int c2=0; int c3=0; int c4=0; + int c5=0; int total=0; ~Counter() { @@ -436,6 +625,7 @@ void generate_subtriangles(std::size_t ti, std::cout << "coplanar segment intersection : " << c2 << "\n"; std::cout << "coplanar segment overlap: " << c3 << "\n"; std::cout << "no intersection: " << c4 << "\n"; + std::cout << "intersection filtered with bboxes: " << c5 << "\n"; std::cout << "# pairs of segments : " << total << "\n"; std::cout << "time computing segment intersections: " << timer1.time() << "\n"; std::cout << "time sorting intersection points: " << timer2.time() << "\n"; @@ -480,13 +670,6 @@ void generate_subtriangles(std::size_t ti, if (!segments.empty()) { std::size_t nbs = segments.size(); - //~ std::cout << "nbs " << nbs << "\n"; - - //~ if (nbs==8) - //~ { - //~ for (std::size_t i = 0; i& t) { @@ -510,20 +693,69 @@ void generate_subtriangles(std::size_t ti, return insert_res.first->second; }; - + std::vector point_boxes(points.size()); + for (std::size_t i = 0; i segment_boxes(nbs); + for (std::size_t i = 0; i(points[segments[i].first], points[segments[i].second], - points[segments[j].first], points[segments[j].second]); + do_coplanar_segments_intersect(segments[i].first, segments[i].second, + segments[j].first, segments[j].second, + points); + + + //~ Segment_inter_type_old seg_inter_type_old = + //~ do_coplanar_segments_intersect_old(points[segments[i].first], points[segments[i].second], + //~ points[segments[j].first], points[segments[j].second]); + + + //~ std::cout << std::setprecision(17); + //~ std::cout << points[segments[i].first] << " " << points[segments[i].second] << "\n"; + //~ std::cout << points[segments[j].first] << " " << points[segments[j].second] << "\n"; + //~ std::cout << "OLD: " << print_enum(seg_inter_type_old) << "\n"; + //~ std::cout << "NEW: " << print_enum(seg_inter_type) << "\n"; + switch(seg_inter_type) { + case POINT_P: + { + points_on_segments[j].push_back(segments[i].first); + break; + } + case POINT_Q: + { + points_on_segments[j].push_back(segments[i].second); + break; + } + case POINT_R: + { + points_on_segments[i].push_back(segments[j].first); + break; + } + case POINT_S: + { + points_on_segments[i].push_back(segments[j].second); + break; + } case POINT_INTERSECTION: { + // TODO: use version with no variant auto res = CGAL::intersection(supporting_plane(triangles[in_triangle_ids[i]]), supporting_plane(triangles[in_triangle_ids[j]]), supporting_plane(triangles[ti])); @@ -534,101 +766,78 @@ void generate_subtriangles(std::size_t ti, std::size_t pid = get_point_id(*pt_ptr); points_on_segments[i].push_back(pid); points_on_segments[j].push_back(pid); - break; - //~ std::cout << "new inter " << *pt_ptr << " (" << depth(points_on_segments[i].back()) << ")" << "\n"; - - } - } - // break; No break because of the coplanar case - case COPLANAR_SEGMENTS: - { - // We can have hard cases if two triangles are coplanar.... - - //~ std::cout << "coplanar inter: " << i << " " << j << "\n"; - - typename EK::Segment_3 s1(points[segments[i].first], points[segments[i].second]); - typename EK::Segment_3 s2(points[segments[j].first], points[segments[j].second]);// TODO: avoid this construction - auto inter = CGAL::intersection(s1, s2); - - if (inter == boost::none) throw std::runtime_error("Unexpected case #2"); - - if (const typename EK::Point_3* pt_ptr = boost::get(&(*inter))) - { - COUNTER_INSTRUCTION(++counter.c2;) - std::size_t pid = get_point_id(*pt_ptr); - points_on_segments[i].push_back(pid); - points_on_segments[j].push_back(pid); - break; - //~ std::cout << "new inter bis " << *pt_ptr << " (" << depth(points_on_segments[i].back()) << ")" << "\n"; } else { - if (const typename EK::Segment_3* seg_ptr = boost::get(&(*inter))) + COUNTER_INSTRUCTION(++counter.c2;) + //TODO find better! + typename EK::Segment_3 s1(points[segments[i].first], points[segments[i].second]); + typename EK::Segment_3 s2(points[segments[j].first], points[segments[j].second]);// TODO: avoid this construction + auto inter = CGAL::intersection(s1, s2); + if (inter == boost::none) throw std::runtime_error("Unexpected case #2"); + if (const typename EK::Point_3* pt_ptr = boost::get(&(*inter))) { - //TODO HERE WE SHOULD IMPROVE TO AVOID RECOMPUTING SEGMENTS ENDPOINTS - COUNTER_INSTRUCTION(++counter.c3;) - std::size_t src_pid = get_point_id(seg_ptr->source()); - std::size_t tgt_pid = get_point_id(seg_ptr->target()); - points_on_segments[i].push_back(src_pid); - points_on_segments[j].push_back(src_pid); - points_on_segments[i].push_back(tgt_pid); - points_on_segments[j].push_back(tgt_pid); + std::size_t pid = get_point_id(*pt_ptr); + points_on_segments[i].push_back(pid); + points_on_segments[j].push_back(pid); break; - //~ std::cout << "new inter seg " << *seg_ptr << " (" << depth(*seg_ptr) << ")" << "\n"; } else - throw std::runtime_error("BOOM\n"); - } - -#if 0 - //this code works if triangles are not coplanar - // coplanar intersection that is not a point - int coord = 0; - const typename EK::Segment_3& s = segments[i]; - typename EK::Point_3 src = s[0], tgt=s[1]; - if (src.x()==tgt.x()) - { - coord=1; - if (src.y()==tgt.y()) - coord==2; + throw std::runtime_error("Unexpected case 1"); + //~ std::ofstream debug ("/tmp/triangles.polylines.txt"); + //~ debug << "4 " << triangles[ti][0] << " " << triangles[ti][1] << " " << triangles[ti][2] << " " << triangles[ti][0] << "\n"; + //~ debug << "4 " << triangles[in_triangle_ids[i]][0] << " " << triangles[in_triangle_ids[i]][1] << " " << triangles[in_triangle_ids[i]][2] << " " << triangles[in_triangle_ids[i]][0] << "\n"; + //~ debug << "4 " << triangles[in_triangle_ids[j]][0] << " " << triangles[in_triangle_ids[j]][1] << " " << triangles[in_triangle_ids[j]][2] << " " << triangles[in_triangle_ids[j]][0] << "\n"; + //~ debug.close(); + //~ throw std::runtime_error("Unexpected case 1"); } - - std::vector tmp_pts = { - src, tgt, segments[j][0], segments[j][1] }; - - std::sort(tmp_pts.begin(), tmp_pts.end(), - [coord](const typename EK::Point_3& p, const typename EK::Point_3& q) - {return p[coord](points_on_segments[i].begin(), points_on_segments[i].end()).size()!= points_on_segments[i].size()) + { + std::cout << "coord = " << coord << "\n"; + std::cout << "(src.x()==tgt.x()) " << (src.x()==tgt.x()) << "\n"; + std::cout << "(src.y()==tgt.y()) " << (src.y()==tgt.y()) << "\n"; + std::cout << "(src.z()==tgt.z()) " << (src.z()==tgt.z()) << "\n"; + + for (auto v : points_on_segments[i]) + std::cout << " " << v; + std::cout << std::endl; + for (auto v : points_on_segments[i]) + std::cout << points[v] << "\n"; + std::cout << std::endl; + throw std::runtime_error("unique failed!"); + } + + nb_new_segments+=points_on_segments[i].size()-2; //~ { @@ -721,6 +948,24 @@ void generate_subtriangles(std::size_t ti, //~ std::cout << "done\n"; #endif + // TODO: sorted pair to be constructed when pushing_back + for (std::pair& s : segments) + if (s.second < s.first) + std::swap(s.first,s.second); + std::sort(segments.begin(), segments.end()); + auto last = std::unique(segments.begin(), segments.end()); + segments.erase(last, segments.end()); + + + std::ofstream("/tmp/tri.xyz") << std::setprecision(17) << triangles[ti][0] << "\n" + << triangles[ti][1] << "\n" + << triangles[ti][2] << "\n"; + std::ofstream debug("/tmp/cst.polylines.txt"); + debug << std::setprecision(17); + for(auto s : segments) + debug << "2 " << points[s.first] << " " << points[s.second] << "\n"; + debug.close(); + COUNTER_INSTRUCTION(counter.timer3.start();) cdt.insert_constraints(points.begin(), points.end(), segments.begin(), segments.end()); COUNTER_INSTRUCTION(counter.timer3.stop();) From 48c49add1cd8100ed08cbff3a97f11de244f3fa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 15 Mar 2023 15:48:44 +0100 Subject: [PATCH 041/329] more debug and enum fix --- .../Polygon_mesh_processing/autorefinement.h | 41 ++++++++----------- 1 file changed, 16 insertions(+), 25 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 711c3d82ce0a..8cc1dd7ff9f8 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -154,7 +154,7 @@ do_coplanar_segments_intersect(std::size_t pi, std::size_t qi, // first handle case of shared endpoints if (pi==ri) { - if (si==qi || cpl_orient(p, q, s)!=COPLANAR) return NO_INTERSECTION; + if (si==qi || cpl_orient(p, q, s)!=COLLINEAR) return NO_INTERSECTION; // can be s, q or nothing if (cln_order(p,s,q)) return POINT_S; @@ -166,7 +166,7 @@ do_coplanar_segments_intersect(std::size_t pi, std::size_t qi, { if(pi==si) { - if (qi==ri || cpl_orient(p, q, r)!=COPLANAR) return NO_INTERSECTION; + if (qi==ri || cpl_orient(p, q, r)!=COLLINEAR) return NO_INTERSECTION; // can be r, q or nothing if (cln_order(p,r,q)) return POINT_R; @@ -178,7 +178,7 @@ do_coplanar_segments_intersect(std::size_t pi, std::size_t qi, { if (qi==ri) { - if (pi==si || cpl_orient(p, q, s)!=COPLANAR) return NO_INTERSECTION; + if (pi==si || cpl_orient(p, q, s)!=COLLINEAR) return NO_INTERSECTION; // can be p, s or nothing if (cln_order(p,s,q)) return POINT_S; @@ -190,7 +190,7 @@ do_coplanar_segments_intersect(std::size_t pi, std::size_t qi, { if (qi==si) { - if (pi==ri || cpl_orient(p, q, r)!=COPLANAR) return NO_INTERSECTION; + if (pi==ri || cpl_orient(p, q, r)!=COLLINEAR) return NO_INTERSECTION; // can be p, r or nothing if (cln_order(p,r,q)) return POINT_R; @@ -577,7 +577,7 @@ void generate_subtriangles(std::size_t ti, #endif typedef CGAL::Constrained_Delaunay_triangulation_2 CDT_2; - //typedef CGAL::Constrained_triangulation_plus_2 CDT; + //typedef CGAL::Constrained_triangulation_plus_2 CDT; typedef CDT_2 CDT; const std::array& t = triangles[ti]; @@ -630,8 +630,11 @@ void generate_subtriangles(std::size_t ti, std::cout << "time computing segment intersections: " << timer1.time() << "\n"; std::cout << "time sorting intersection points: " << timer2.time() << "\n"; std::cout << "time for cdt of constraints: " << timer3.time() << "\n"; + std::cout << "time coplanar segment intersections: " << timer4.time() << "\n"; + std::cout << "time of do_coplanar_segments_intersect: " << timer5.time() << "\n"; + std::cout << "time of triplane intersection: " << timer6.time() << "\n"; } - CGAL::Real_timer timer1, timer2, timer3; + CGAL::Real_timer timer1, timer2, timer3, timer4, timer5, timer6; }; static Counter counter; @@ -713,11 +716,12 @@ void generate_subtriangles(std::size_t ti, continue; } - // TODO: use point ids to skip some test? + COUNTER_INSTRUCTION(counter.timer5.start();) Segment_inter_type seg_inter_type = do_coplanar_segments_intersect(segments[i].first, segments[i].second, segments[j].first, segments[j].second, points); + COUNTER_INSTRUCTION(counter.timer5.stop();) //~ Segment_inter_type_old seg_inter_type_old = @@ -756,9 +760,11 @@ void generate_subtriangles(std::size_t ti, case POINT_INTERSECTION: { // TODO: use version with no variant + COUNTER_INSTRUCTION(counter.timer6.start();) auto res = CGAL::intersection(supporting_plane(triangles[in_triangle_ids[i]]), supporting_plane(triangles[in_triangle_ids[j]]), supporting_plane(triangles[ti])); + COUNTER_INSTRUCTION(counter.timer6.stop();) if (const typename EK::Point_3* pt_ptr = boost::get(&(*res))) { @@ -770,6 +776,7 @@ void generate_subtriangles(std::size_t ti, else { COUNTER_INSTRUCTION(++counter.c2;) + COUNTER_INSTRUCTION(counter.timer4.start();) //TODO find better! typename EK::Segment_3 s1(points[segments[i].first], points[segments[i].second]); typename EK::Segment_3 s2(points[segments[j].first], points[segments[j].second]);// TODO: avoid this construction @@ -784,6 +791,7 @@ void generate_subtriangles(std::size_t ti, } else throw std::runtime_error("Unexpected case 1"); + COUNTER_INSTRUCTION(counter.timer4.stop();) //~ std::ofstream debug ("/tmp/triangles.polylines.txt"); //~ debug << "4 " << triangles[ti][0] << " " << triangles[ti][1] << " " << triangles[ti][2] << " " << triangles[ti][0] << "\n"; //~ debug << "4 " << triangles[in_triangle_ids[i]][0] << " " << triangles[in_triangle_ids[i]][1] << " " << triangles[in_triangle_ids[i]][2] << " " << triangles[in_triangle_ids[i]][0] << "\n"; @@ -877,24 +885,6 @@ void generate_subtriangles(std::size_t ti, points_on_segments[i].push_back(tgt_id); auto last = std::unique(points_on_segments[i].begin(), points_on_segments[i].end()); points_on_segments[i].erase(last, points_on_segments[i].end()); - - if (std::set(points_on_segments[i].begin(), points_on_segments[i].end()).size()!= points_on_segments[i].size()) - { - std::cout << "coord = " << coord << "\n"; - std::cout << "(src.x()==tgt.x()) " << (src.x()==tgt.x()) << "\n"; - std::cout << "(src.y()==tgt.y()) " << (src.y()==tgt.y()) << "\n"; - std::cout << "(src.z()==tgt.z()) " << (src.z()==tgt.z()) << "\n"; - - for (auto v : points_on_segments[i]) - std::cout << " " << v; - std::cout << std::endl; - for (auto v : points_on_segments[i]) - std::cout << points[v] << "\n"; - std::cout << std::endl; - throw std::runtime_error("unique failed!"); - } - - nb_new_segments+=points_on_segments[i].size()-2; //~ { @@ -1240,6 +1230,7 @@ void autorefine_soup_output(const PointRange& input_points, ); } } + // import refined triangles for (const std::array& t : new_triangles) { From ebb051f0b6e5bd89b17e4eb48f5c0cfdd2b6f1fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 16 Mar 2023 10:26:06 +0100 Subject: [PATCH 042/329] remove debug --- .../Polygon_mesh_processing/autorefinement.h | 96 ++----------------- 1 file changed, 10 insertions(+), 86 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 8cc1dd7ff9f8..f6b7bac57bb4 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -36,9 +36,9 @@ #include -//#define TEST_RESOLVE_INTERSECTION +#define TEST_RESOLVE_INTERSECTION #define DEDUPLICATE_SEGMENTS -//#define DEBUG_COUNTERS +#define DEBUG_COUNTERS //#define USE_FIXED_PROJECTION_TRAITS //#define DEBUG_DEPTH @@ -56,8 +56,6 @@ namespace Polygon_mesh_processing { #ifndef DOXYGEN_RUNNING namespace autorefine_impl { - -enum Segment_inter_type_old { NO_INTERSECTION_OLD=0, COPLANAR_SEGMENTS, POINT_INTERSECTION_OLD }; enum Segment_inter_type { NO_INTERSECTION=0, POINT_INTERSECTION, POINT_P, @@ -72,68 +70,6 @@ enum Segment_inter_type { NO_INTERSECTION=0, COPLANAR_SEGMENT_QR, }; - - -std::string print_enum(Segment_inter_type_old s) -{ - switch(s) - { - case NO_INTERSECTION_OLD: return "NO_INTERSECTION_OLD"; - case COPLANAR_SEGMENTS: return "COPLANAR_SEGMENTS"; - case POINT_INTERSECTION_OLD: return "POINT_INTERSECTION_OLD"; - } -} - -std::string print_enum(Segment_inter_type s) -{ - switch(s) - { - case NO_INTERSECTION: return "NO_INTERSECTION"; - case POINT_INTERSECTION: return "POINT_INTERSECTION"; - case POINT_P: return "POINT_P"; - case POINT_Q: return "POINT_Q"; - case POINT_R: return "POINT_R"; - case POINT_S: return "POINT_S"; - case COPLANAR_SEGMENT_PQ: return "COPLANAR_SEGMENT_PQ"; - case COPLANAR_SEGMENT_RS: return "COPLANAR_SEGMENT_RS"; - case COPLANAR_SEGMENT_PS: return "COPLANAR_SEGMENT_PS"; - case COPLANAR_SEGMENT_QS: return "COPLANAR_SEGMENT_QS"; - case COPLANAR_SEGMENT_PR: return "COPLANAR_SEGMENT_PR"; - case COPLANAR_SEGMENT_QR: return "COPLANAR_SEGMENT_QR"; - } -} - - -template -Segment_inter_type_old -do_coplanar_segments_intersect_old(const typename K::Point_3& s1_0, const typename K::Point_3& s1_1, - const typename K::Point_3& s2_0, const typename K::Point_3& s2_1, - const K& k = K()) -{ - // supporting_line intersects: points are coplanar - 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) || - cln_order(s1_0, s2_1, s1_1) || - cln_order(s2_0, s1_0, s2_1)) ? COPLANAR_SEGMENTS : NO_INTERSECTION_OLD; - } - - if(or1 != or2) - { - or1 = cpl_orient(s2_0, s2_1, s1_0); - return (or1 == COLLINEAR || or1 != cpl_orient(s2_0, s2_1, s1_1)) ? POINT_INTERSECTION_OLD : NO_INTERSECTION_OLD; - } - - return NO_INTERSECTION_OLD; -} - - // test intersection in the interior of segment pq and rs with pq and rs being coplanar segments // note that for coplanar cases, we might report identical endpoints template @@ -723,18 +659,6 @@ void generate_subtriangles(std::size_t ti, points); COUNTER_INSTRUCTION(counter.timer5.stop();) - - //~ Segment_inter_type_old seg_inter_type_old = - //~ do_coplanar_segments_intersect_old(points[segments[i].first], points[segments[i].second], - //~ points[segments[j].first], points[segments[j].second]); - - - //~ std::cout << std::setprecision(17); - //~ std::cout << points[segments[i].first] << " " << points[segments[i].second] << "\n"; - //~ std::cout << points[segments[j].first] << " " << points[segments[j].second] << "\n"; - //~ std::cout << "OLD: " << print_enum(seg_inter_type_old) << "\n"; - //~ std::cout << "NEW: " << print_enum(seg_inter_type) << "\n"; - switch(seg_inter_type) { case POINT_P: @@ -947,14 +871,14 @@ void generate_subtriangles(std::size_t ti, segments.erase(last, segments.end()); - std::ofstream("/tmp/tri.xyz") << std::setprecision(17) << triangles[ti][0] << "\n" - << triangles[ti][1] << "\n" - << triangles[ti][2] << "\n"; - std::ofstream debug("/tmp/cst.polylines.txt"); - debug << std::setprecision(17); - for(auto s : segments) - debug << "2 " << points[s.first] << " " << points[s.second] << "\n"; - debug.close(); + //~ std::ofstream("/tmp/tri.xyz") << std::setprecision(17) << triangles[ti][0] << "\n" + //~ << triangles[ti][1] << "\n" + //~ << triangles[ti][2] << "\n"; + //~ std::ofstream debug("/tmp/cst.polylines.txt"); + //~ debug << std::setprecision(17); + //~ for(auto s : segments) + //~ debug << "2 " << points[s.first] << " " << points[s.second] << "\n"; + //~ debug.close(); COUNTER_INSTRUCTION(counter.timer3.start();) cdt.insert_constraints(points.begin(), points.end(), segments.begin(), segments.end()); From b31dc68889c704f0120e6286fb3bbbacdf19da48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 16 Mar 2023 10:28:24 +0100 Subject: [PATCH 043/329] add another option coplanar orientation --- .../Polygon_mesh_processing/autorefinement.h | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index f6b7bac57bb4..7432f1f7d35e 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -38,7 +38,7 @@ #define TEST_RESOLVE_INTERSECTION #define DEDUPLICATE_SEGMENTS -#define DEBUG_COUNTERS +//#define DEBUG_COUNTERS //#define USE_FIXED_PROJECTION_TRAITS //#define DEBUG_DEPTH @@ -77,10 +77,20 @@ Segment_inter_type do_coplanar_segments_intersect(std::size_t pi, std::size_t qi, std::size_t ri, std::size_t si, const std::vector& points, + const typename K::Vector_3& plane_normal, const K& k = K()) { typename K::Collinear_are_ordered_along_line_3 cln_order = k.collinear_are_ordered_along_line_3_object(); +#ifdef USE_PROJECTED_ORIENTATION_2_FOR_COPLANAR_ORIENTATION_TESTS + auto cpl_orient = + [&plane_normal](const typename K::Point_3& p, const typename K::Point_3& q, const typename K::Point_3& r) + { + return ::CGAL::orientation(q-p, r-p, plane_normal); + }; +#else typename K::Coplanar_orientation_3 cpl_orient=k.coplanar_orientation_3_object(); + CGAL_USE(plane_normal); +#endif const typename K::Point_3& p=points[pi]; const typename K::Point_3& q=points[qi]; @@ -638,7 +648,7 @@ void generate_subtriangles(std::size_t ti, std::vector segment_boxes(nbs); for (std::size_t i = 0; i(segments[i].first, segments[i].second, segments[j].first, segments[j].second, - points); + points, n); COUNTER_INSTRUCTION(counter.timer5.stop();) switch(seg_inter_type) @@ -767,9 +777,10 @@ void generate_subtriangles(std::size_t ti, points_on_segments[j].push_back(segments[i].second); break; } -// break; case NO_INTERSECTION: + { COUNTER_INSTRUCTION(++counter.c4;) + } } } COUNTER_INSTRUCTION(++counter.total;) @@ -859,7 +870,6 @@ void generate_subtriangles(std::size_t ti, } } } - //~ std::cout << "done\n"; #endif // TODO: sorted pair to be constructed when pushing_back From 38a92ead67a2b471b68ecfc23367b72b710739ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 16 Mar 2023 14:59:08 +0100 Subject: [PATCH 044/329] make the message clearer --- .../include/CGAL/Polygon_mesh_processing/autorefinement.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 7432f1f7d35e..a54e4d299712 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -36,7 +36,7 @@ #include -#define TEST_RESOLVE_INTERSECTION +//#define TEST_RESOLVE_INTERSECTION #define DEDUPLICATE_SEGMENTS //#define DEBUG_COUNTERS //#define USE_FIXED_PROJECTION_TRAITS @@ -1178,7 +1178,7 @@ void autorefine_soup_output(const PointRange& input_points, #ifdef CGAL_DEBUG_PMP_AUTOREFINE CGAL_PMP_AUTOREFINE_VERBOSE("check soup"); if (does_triangle_soup_self_intersect(exact_soup_points, soup_triangles)) - throw std::runtime_error("invalid output"); + throw std::runtime_error("ERROR: invalid output, there is most probably a bug"); #endif #endif CGAL_PMP_AUTOREFINE_VERBOSE("done"); From 6139fc4119b0c80bd6285e4c1cf1c7c269b85721 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 16 Mar 2023 19:10:05 +0100 Subject: [PATCH 045/329] insert points even if no constraints --- .../Polygon_mesh_processing/autorefinement.h | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index a54e4d299712..734a47fcf562 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -465,7 +465,6 @@ void collect_intersections(const std::array& t1, { int j=(i+1)%3; test_edge(t1[i], t1[j], t2[0], t2[1], t2[2], ori[i], ori[j], inter_pts); - //~ if (inter_pts.size()>1) return; } // test edges of t2 vs t1 @@ -475,7 +474,6 @@ void collect_intersections(const std::array& t1, { int j=(i+1)%3; test_edge(t2[i], t2[j], t1[0], t1[1], t1[2], ori[i], ori[j], inter_pts); - //~ if (inter_pts.size()>1) return; } // because we don't handle intersection type and can have edge-edge edge-vertex duplicates @@ -483,9 +481,10 @@ void collect_intersections(const std::array& t1, auto last = std::unique(inter_pts.begin(), inter_pts.end()); inter_pts.erase(last, inter_pts.end()); - +#ifdef DEBUG_DEPTH for (auto p : inter_pts) if (depth(p)>2) throw std::runtime_error("Depth is not 2: "+std::to_string(depth(p))); +#endif } ////////////////////////////////// @@ -507,8 +506,8 @@ void generate_subtriangles(std::size_t ti, const std::vector>& triangles, std::vector>& new_triangles) { - //~ std::cout << "generate_subtriangles()\n"; - std::cout << std::setprecision(17); + // std::cout << "generate_subtriangles()\n"; + // std::cout << std::setprecision(17); #ifdef USE_FIXED_PROJECTION_TRAITS typedef ::CGAL::internal::Projection_traits_3 P_traits; @@ -870,16 +869,16 @@ void generate_subtriangles(std::size_t ti, } } } -#endif // TODO: sorted pair to be constructed when pushing_back + // TODO: only needed in case of coplanar segments? for (std::pair& s : segments) if (s.second < s.first) std::swap(s.first,s.second); std::sort(segments.begin(), segments.end()); auto last = std::unique(segments.begin(), segments.end()); segments.erase(last, segments.end()); - +#endif //~ std::ofstream("/tmp/tri.xyz") << std::setprecision(17) << triangles[ti][0] << "\n" //~ << triangles[ti][1] << "\n" @@ -891,7 +890,10 @@ void generate_subtriangles(std::size_t ti, //~ debug.close(); COUNTER_INSTRUCTION(counter.timer3.start();) - cdt.insert_constraints(points.begin(), points.end(), segments.begin(), segments.end()); + if (segments.empty()) + cdt.insert(points.begin(), points.end()); + else + cdt.insert_constraints(points.begin(), points.end(), segments.begin(), segments.end()); COUNTER_INSTRUCTION(counter.timer3.stop();) #ifdef CGAL_DEBUG_PMP_AUTOREFINE_DUMP_TRIANGULATIONS From 85b3f7ed5732f203905086d630b7e35c521e7c23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 27 Mar 2023 17:52:09 +0200 Subject: [PATCH 046/329] working around non-triangular polygons --- .../Polygon_mesh_processing/soup_autorefinement.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp index 9ade96e3be84..a46fc6e711c7 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp @@ -7,6 +7,8 @@ #include #include +#include + #include typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; @@ -22,10 +24,13 @@ int main(int argc, char** argv) : std::string(argv[1]); std::vector input_points; - std::vector> input_triangles; + std::vector> input_triangles; CGAL::IO::read_polygon_soup(filename, input_points, input_triangles); PMP::repair_polygon_soup(input_points, input_triangles); + for (const auto& c : input_triangles) + if (c.size()!=3) return 0; // skipt for now + std::vector output_points; std::vector> output_triangles; PMP::autorefine_soup_output(input_points, input_triangles, output_points, output_triangles); From b06ed794e6e7ffa1f3112ec16ba556128be2ba79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 27 Mar 2023 17:53:36 +0200 Subject: [PATCH 047/329] add more debug --- .../Polygon_mesh_processing/autorefinement.h | 159 +++++++++++++++++- 1 file changed, 155 insertions(+), 4 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 734a47fcf562..7cd083e83388 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -36,7 +36,7 @@ #include -//#define TEST_RESOLVE_INTERSECTION +#define TEST_RESOLVE_INTERSECTION #define DEDUPLICATE_SEGMENTS //#define DEBUG_COUNTERS //#define USE_FIXED_PROJECTION_TRAITS @@ -227,6 +227,69 @@ do_coplanar_segments_intersect(std::size_t pi, std::size_t qi, ////////////////////////////////// ////////////////////////////////// +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION +template +void old_intersection_coplanar_triangles_cutoff(const typename Kernel::Point_3& p, + const typename Kernel::Point_3& q, + const typename Kernel::Point_3& r, + const Kernel& k, + std::list& inter_pts) +{ + typedef typename std::list::iterator Iterator; + + if(inter_pts.empty()) + return; + + typename Kernel::Coplanar_orientation_3 orient = k.coplanar_orientation_3_object(); + typename Kernel::Construct_line_3 line = k.construct_line_3_object(); + + //orient(p,q,r,r) is POSITIVE + std::map orientations; + for (Iterator it=inter_pts.begin();it!=inter_pts.end();++it) + orientations[ &(*it) ]=orient(p,q,r,*it); + + CGAL_kernel_assertion_code(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) + { + const typename Kernel::Point_3& curr = *it; + Orientation or_prev = orientations[prev], + or_curr = orientations[&curr]; + + if((or_prev == POSITIVE && or_curr == NEGATIVE) || + (or_prev == NEGATIVE && or_curr == POSITIVE)) + { + typename Intersection_traits::result_type + obj = ::CGAL::Intersections::internal::intersection(line(p,q), line(*prev,curr), k); + + // assert "not empty" + CGAL_kernel_assertion(bool(obj)); + + const typename Kernel::Point_3* inter = ::CGAL::Intersections::internal::intersect_get(obj); + CGAL_kernel_assertion(inter != nullptr); + + prev = &(*inter_pts.insert(it,*inter)); + orientations[prev] = COLLINEAR; + CGAL_kernel_assertion_code(++pt_added;) + } + + prev = &(*it); + } + + CGAL_kernel_assertion(pt_added<3); + Iterator it = inter_pts.begin(); + while(it!=inter_pts.end()) + { + if(orientations[&(*it)] == NEGATIVE) + inter_pts.erase(it++); + else + ++it; + } +} +#endif + // imported from Intersections_3/include/CGAL/Intersections_3/internal/Triangle_3_Triangle_3_intersection.h template void coplanar_intersections(const std::array& t1, @@ -242,6 +305,19 @@ void coplanar_intersections(const std::array& t1, l_inter_pts.push_back(Intersections::internal::Point_on_triangle(-1,2)); #ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + std::list old_l_inter_pts; + old_l_inter_pts.push_back(p2); + old_l_inter_pts.push_back(q2); + old_l_inter_pts.push_back(r2); + + + auto enum_to_string = [](CGAL::Orientation o) + { + if (o==COLLINEAR) return std::string("COLLINEAR"); + if (o==POSITIVE) return std::string("POSITIVE"); + return std::string("NEGATIVE"); + }; + auto to_string = [](const auto& t) { std::stringstream sstr; @@ -256,6 +332,32 @@ void coplanar_intersections(const std::array& t1, std::cout << "intersection_coplanar_triangles\n"; std::ofstream("/tmp/t1.polylines.txt") << to_string(t1) << "\n"; std::ofstream("/tmp/t2.polylines.txt") << to_string(t2) << "\n"; + + std::cout << "Position of vertices of t1: "; + std::cout << enum_to_string( coplanar_orientation(p2,q2,r2,p1)) << " - "; + std::cout << enum_to_string( coplanar_orientation(p2,q2,r2,q1)) << " - "; + std::cout << enum_to_string( coplanar_orientation(p2,q2,r2,r1)) << "\n"; + std::cout << " "; + std::cout << enum_to_string( coplanar_orientation(q2,r2,p2,p1)) << " - "; + std::cout << enum_to_string( coplanar_orientation(q2,r2,p2,q1)) << " - "; + std::cout << enum_to_string( coplanar_orientation(q2,r2,p2,r1)) << "\n"; + std::cout << " "; + std::cout << enum_to_string( coplanar_orientation(r2,p2,q2,p1)) << " - "; + std::cout << enum_to_string( coplanar_orientation(r2,p2,q2,q1)) << " - "; + std::cout << enum_to_string( coplanar_orientation(r2,p2,q2,r1)) << "\n"; + std::cout << "Position of vertices of t2: "; + std::cout << enum_to_string( coplanar_orientation(p1,q1,r1,p2)) << " - "; + std::cout << enum_to_string( coplanar_orientation(p1,q1,r1,q2)) << " - "; + std::cout << enum_to_string( coplanar_orientation(p1,q1,r1,r2)) << "\n"; + std::cout << " "; + std::cout << enum_to_string( coplanar_orientation(q1,r1,p1,p2)) << " - "; + std::cout << enum_to_string( coplanar_orientation(q1,r1,p1,q2)) << " - "; + std::cout << enum_to_string( coplanar_orientation(q1,r1,p1,r2)) << "\n"; + std::cout << " "; + std::cout << enum_to_string( coplanar_orientation(r1,p1,q1,p2)) << " - "; + std::cout << enum_to_string( coplanar_orientation(r1,p1,q1,q2)) << " - "; + std::cout << enum_to_string( coplanar_orientation(r1,p1,q1,r2)) << "\n"; + auto print_points = [&]() { for(auto p : l_inter_pts) std::cout << " (" << p.id1() << "," << p.id2() << ",[" << p.alpha << "]) "; std::cout <<"\n"; @@ -270,31 +372,76 @@ void coplanar_intersections(const std::array& t1, #ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION std::cout << " ipts size: " << l_inter_pts.size() << "\n"; print_points(); + old_intersection_coplanar_triangles_cutoff(p1,q1,r1,k,old_l_inter_pts); + CGAL_assertion(l_inter_pts.size()==old_l_inter_pts.size()); + for (std::size_t i=0; ipoint(p1,q1,r1,p2,q2,r2,k)) + { + std::cout <<"ERROR with point #" << i << "\n"; + throw std::runtime_error("invalid output 0"); + } + } #endif intersection_coplanar_triangles_cutoff(q1,r1,p1,1,p2,q2,r2,k,l_inter_pts); //line q1r1 #ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION std::cout << " ipts size: " << l_inter_pts.size() << "\n"; print_points(); + old_intersection_coplanar_triangles_cutoff(q1,r1,p1,k,old_l_inter_pts); + CGAL_assertion(l_inter_pts.size()==old_l_inter_pts.size()); + for (std::size_t i=0; ipoint(p1,q1,r1,p2,q2,r2,k)) + { + std::cout <<"ERROR with point #" << i << "\n"; + throw std::runtime_error("invalid output 1"); + } + } #endif intersection_coplanar_triangles_cutoff(r1,p1,q1,2,p2,q2,r2,k,l_inter_pts); //line r1p1 #ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION std::cout << " ipts size: " << l_inter_pts.size() << "\n"; print_points(); + old_intersection_coplanar_triangles_cutoff(r1,p1,q1,k,old_l_inter_pts); + CGAL_assertion(l_inter_pts.size()==old_l_inter_pts.size()); + for (std::size_t i=0; ipoint(p1,q1,r1,p2,q2,r2,k)) + { + std::cout <<"ERROR with point #" << i << "\n"; + throw std::runtime_error("invalid output 2"); + } + } +#endif + +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + std::size_t start=inter_pts.size(); #endif for (const Intersections::internal::Point_on_triangle& pot : l_inter_pts) inter_pts.push_back( pot.point(p1,q1,r1,p2,q2,r2,k) ); #ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + for (std::size_t i=0; i> i; + // std::cout <<"check!\n"; + // int i; + // std::cin >> i; #endif } @@ -1022,6 +1169,10 @@ void autorefine_soup_output(const PointRange& input_points, std::vector inter_pts; autorefine_impl::collect_intersections(t1, t2, inter_pts); + CGAL_assertion( + CGAL::do_intersect(typename EK::Triangle_3(t1[0], t1[1], t1[2]), typename EK::Triangle_3(t2[0], t2[1], t2[2])) + != inter_pts.empty()); + if (!inter_pts.empty()) { std::size_t nbi = inter_pts.size(); From bd967e7cec9885afb9cee799ae6b39a16abfa609 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 27 Mar 2023 17:53:50 +0200 Subject: [PATCH 048/329] avoid duplicated tangency point --- .../Polygon_mesh_processing/autorefinement.h | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 7cd083e83388..c90ba515271c 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -778,7 +778,13 @@ void generate_subtriangles(std::size_t ti, std::map point_id_map; for (std::size_t pid=0; pid(points.begin(), points.end()).size()); + CGAL_assertion(points.size()==point_id_map.size()); } // TODO: sorted pair to be constructed when pushing_back @@ -1217,6 +1226,14 @@ void autorefine_soup_output(const PointRange& input_points, return insert_res.first->second; }; + if (!all_points[ti].empty()) + { + std::vector tmp; + tmp.swap(all_points[ti]); + for (const typename EK::Point_3& pt : tmp) + get_point_id(pt); + } + std::size_t nbs = all_segments[ti].size(); std::vector> filtered_segments; std::vector filtered_in_triangle_ids; From 2b74b8f10d561a335e159857e14f109a92aeed50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 28 Mar 2023 14:35:40 +0200 Subject: [PATCH 049/329] fix some bugs --- .../Triangle_3_Triangle_3_intersection.h | 98 ++++++++++++++----- 1 file changed, 76 insertions(+), 22 deletions(-) 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 ac376f443506..35aa4f8f0a53 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 @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -86,6 +87,7 @@ struct Point_on_triangle // (-1, id) point on t2 // (id1, id2) intersection of edges std::pair t1_t2_ids; + boost::container::flat_set extra_t1; typename Kernel::FT alpha; Orientation @@ -161,7 +163,7 @@ intersection(const Point_on_triangle& p, #ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION std::cout << " calling intersection: "; std::cout << " (" << p.id1() << "," << p.id2() << ",[" << p.alpha << "]) -"; - std::cout << " (" << q.id1() << "," << q.id2() << ",[" << q.alpha << "]) || e" << edge_id_t1 << "\n"; + std::cout << " (" << q.id1() << "," << q.id2() << ",[" << q.alpha << "]) || e" << edge_id_t1; #endif typedef Point_on_triangle Pot; switch(p.id1()) @@ -172,17 +174,26 @@ intersection(const Point_on_triangle& p, { case -1: // (-1, ip2) - (-1, iq2) { + CGAL_assertion((p.id2()+1)%3 == q.id2() || (q.id2()+1)%3 == p.id2()); +// CGAL_assertion(p.extra_t1.empty() && q.extra_t1.empty()); // TMP to see if it's worth implementing special case +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + std::cout << " -- case 1\n"; +#endif typename Kernel::FT alpha = coplanar_segment_segment_alpha_intersection(p1, q1, Pot::point_from_id(p2, q2, r2, p.id2()), Pot::point_from_id(p2, q2, r2, q.id2()), k); - return Point_on_triangle(edge_id_t1, p.id2(), alpha); // intersection with an original edge of t2 + int id2 = (p.id2()+1)%3 == q.id2() ? p.id2() : q.id2(); + return Point_on_triangle(edge_id_t1, id2, alpha); // intersection with an original edge of t2 } default: if (q.id2()!=-1) // (-1, ip2) - (iq1, iq2) { if (p.id2() == q.id2() || p.id2() == (q.id2()+1)%3) { +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + std::cout << " -- case 2\n"; +#endif // points are on the same edge of t2 --> we shorten an already cut edge typename Kernel::FT alpha = coplanar_segment_segment_alpha_intersection(p1, q1, @@ -191,13 +202,23 @@ intersection(const Point_on_triangle& p, return Point_on_triangle(edge_id_t1, q.id2(), alpha); } - // point of t1 - return Point_on_triangle((q.id1()+1)%3==edge_id_t1?edge_id_t1:(edge_id_t1+1)%3 , -1); +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + std::cout << " -- case 3\n"; +#endif + // point of t1: look for an edge of t1 containing both points + CGAL_assertion( p.extra_t1.count(q.id1())!=0 || p.extra_t1.count(3-q.id1()-edge_id_t1)!=0 ); + int eid1 = p.extra_t1.count(q.id1())!=0 ? q.id1() : 3-q.id1()-edge_id_t1; + return Point_on_triangle((eid1+1)%3==edge_id_t1?edge_id_t1:(edge_id_t1+1)%3, -1); // vertex of t1 } // (-1, ip2) - (iq1, -1) //vertex of t1, special case t1 edge passed thru a vertex of t2 CGAL_assertion(edge_id_t1 == 2); - return Point_on_triangle(2, -1); // point on t1 has to be created from the intersection of edge 0 and edge 1 +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + std::cout << " -- case 4\n"; +#endif + CGAL_assertion(q.id1()==1); + CGAL_assertion(!p.extra_t1.empty()); + return Point_on_triangle(p.extra_t1.count(0)==1?0:2,-1); } } default: @@ -210,13 +231,24 @@ intersection(const Point_on_triangle& p, { case -1: // (ip1, -1) - (-1, iq2) //vertex of t1, special case t1 edge passed thru a vertex of t2 - return Point_on_triangle(0, -1); +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + std::cout << " -- case 5\n"; +#endif + CGAL_assertion(edge_id_t1 == 2); + CGAL_assertion(p.id1()==1); + CGAL_assertion(!q.extra_t1.empty()); + return Point_on_triangle(q.extra_t1.count(0)==1?0:2,-1); default: { +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + std::cout << " -- case 6\n"; +#endif CGAL_assertion(q.id2()!=-1); // (ip1, -1) - (iq2, -1) //(ip1,-1), (iq1, iq2) - CGAL_assertion(edge_id_t1==2 && p.id1()==1); - return Point_on_triangle(q.id1()==1?2:0,-1); // vertex of t1 + CGAL_assertion(edge_id_t1==2); + // p and q are on the same edge of t1 + CGAL_assertion(p.id1()==q.id1() || p.id1()==(q.id1()+1)%3); + return Point_on_triangle((q.id1()+1)%3==edge_id_t1?edge_id_t1:(edge_id_t1+1)%3 , -1); } } } @@ -228,6 +260,9 @@ intersection(const Point_on_triangle& p, { if (q.id2() == p.id2() || q.id2() == (p.id2()+1)%3) { +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + std::cout << " -- case 7\n"; +#endif // points are on the same edge of t2 --> we shorten an already cut edge typename Kernel::FT alpha = coplanar_segment_segment_alpha_intersection(p1, q1, @@ -236,8 +271,14 @@ intersection(const Point_on_triangle& p, return Point_on_triangle(edge_id_t1, p.id2(), alpha); } +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + std::cout << " -- case 8\n"; +#endif // point of t1 - return Point_on_triangle((p.id1()+1)%3==edge_id_t1?edge_id_t1:(edge_id_t1+1)%3 , -1); + //std::cout << "q.extra_t1: "; for(int qet1 : q.extra_t1) std::cout << " " << qet1; std::cout << "\n"; + CGAL_assertion( q.extra_t1.count(p.id1())!=0 || q.extra_t1.count(3-p.id1()-edge_id_t1)!=0 ); + int eid1 = q.extra_t1.count(p.id1())!=0 ? p.id1() : 3-p.id1()-edge_id_t1; + return Point_on_triangle((eid1+1)%3==edge_id_t1?edge_id_t1:(edge_id_t1+1)%3, -1); // vertex of t1 } default: { @@ -245,21 +286,30 @@ intersection(const Point_on_triangle& p, { case -1: // (ip1, ip2) - (iq1, -1) { - CGAL_assertion(edge_id_t1==2 && q.id1()==1); - return Point_on_triangle(p.id1()==1?2:0); // vertex of t1 + // p and q are on the same edge of t1 + CGAL_assertion(q.id1()==p.id1() || q.id1()==(p.id1()+1)%3); +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + std::cout << " -- case 9\n"; +#endif + return Point_on_triangle((p.id1()+1)%3==edge_id_t1?edge_id_t1:(edge_id_t1+1)%3 , -1); } default: // (ip1, ip2) - (iq1, iq2) { - CGAL_assertion(p.id1()==q.id1() || p.id2()==q.id2() ); - - if (p.id1()==q.id1()) - return Point_on_triangle((p.id1()+1)%3==edge_id_t1?edge_id_t1:(edge_id_t1+1)%3, -1); // vertex of t1 - - typename Kernel::FT alpha = - coplanar_segment_segment_alpha_intersection(p1, q1, - Pot::point_from_id(p2, q2, r2, q.id2()), - Pot::point_from_id(p2, q2, r2, (q.id2()+1)%3), k); - return Point_on_triangle(edge_id_t1, q.id2(), alpha); + if (p.id2()==q.id2()) + { +#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION + std::cout << " -- case 10\n"; +#endif + typename Kernel::FT alpha = + coplanar_segment_segment_alpha_intersection(p1, q1, + Pot::point_from_id(p2, q2, r2, q.id2()), + Pot::point_from_id(p2, q2, r2, (q.id2()+1)%3), k); + return Point_on_triangle(edge_id_t1, q.id2(), alpha); + } + // we are intersecting an edge of t1 + CGAL_assertion(p.id1()==q.id1() || edge_id_t1==2); + int eid1 = p.id1()==q.id1() ? p.id1() : 1; + return Point_on_triangle((eid1+1)%3==edge_id_t1?edge_id_t1:(edge_id_t1+1)%3, -1); // vertex of t1 } } } @@ -293,8 +343,12 @@ void intersection_coplanar_triangles_cutoff(const typename Kernel::Point_3& p1, //orient(p1,q1,r1,r1) is POSITIVE std::map*,Orientation> orientations; // TODO skip map - for (const Point_on_triangle& pot : inter_pts) + for (Point_on_triangle& pot : inter_pts) + { orientations[ &pot ]=pot.orientation(p1,q1,r1,edge_id,p2,q2,r2,k); + if (pot.id1()==-1 && orientations[ &pot ]==COLLINEAR) + pot.extra_t1.insert(edge_id); + } #ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION std::cout << " Orientations:"; From e29d52421e624a416b741e3416d75bc65ee1e101 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 28 Mar 2023 16:43:35 +0200 Subject: [PATCH 050/329] fix doc --- .../Polygon_mesh_processing/autorefinement.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index c90ba515271c..c7e067916d59 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -1360,19 +1360,18 @@ void autorefine_soup_output(const PointRange& input_points, * refines a triangle mesh so that no triangles intersects in their interior. * * @tparam TriangleMesh a model of `HalfedgeListGraph`, `FaceListGraph`, and `MutableFaceGraph` - * @tparam NamedParameters a sequence of \ref namedparameters + * @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" * * @param tm input triangulated surface mesh * @param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below * - * \cgalParamNBegin{geom_traits} - * \cgalParamDescription{an instance of a geometric traits class} - * \cgalParamType{a class model of `PMPSelfIntersectionTraits`} - * \cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`} - * \cgalParamExtra{The geometric traits class must be compatible with the vertex point type.} - * \cgalParamNEnd - * * \cgalNamedParamsBegin + * \cgalParamNBegin{geom_traits} + * \cgalParamDescription{an instance of a geometric traits class} + * \cgalParamType{a class model of `PMPSelfIntersectionTraits`} + * \cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`} + * \cgalParamExtra{The geometric traits class must be compatible with the vertex point type.} + * \cgalParamNEnd * \cgalParamNBegin{vertex_point_map} * \cgalParamDescription{a property map associating points to the vertices of `tm`} * \cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits::%vertex_descriptor` @@ -1380,7 +1379,8 @@ void autorefine_soup_output(const PointRange& input_points, * \cgalParamDefault{`boost::get(CGAL::vertex_point, tm)`} * \cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t` * must be available in `TriangleMesh`.} - * \cgalParamNEnd + * \cgalParamNEnd + * \cgalNamedParamsEnd * */ template Date: Wed, 29 Mar 2023 16:38:34 +0200 Subject: [PATCH 051/329] triangulate soup --- .../examples/Polygon_mesh_processing/soup_autorefinement.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp index a46fc6e711c7..d955734853bf 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp @@ -27,9 +27,7 @@ int main(int argc, char** argv) std::vector> input_triangles; CGAL::IO::read_polygon_soup(filename, input_points, input_triangles); PMP::repair_polygon_soup(input_points, input_triangles); - - for (const auto& c : input_triangles) - if (c.size()!=3) return 0; // skipt for now + PMP::triangulate_polygons(input_points, input_triangles); std::vector output_points; std::vector> output_triangles; From 2a791d2625c885b96f6d12b890d6b482918b48d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 31 Mar 2023 10:24:42 +0200 Subject: [PATCH 052/329] add optional progress display --- .../CGAL/Polygon_mesh_processing/autorefinement.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index c7e067916d59..4f56b8a0d817 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -25,6 +25,10 @@ #include #include +#ifdef USE_PROGRESS_DISPLAY +#include +#endif + // output #include #include @@ -1260,6 +1264,11 @@ void autorefine_soup_output(const PointRange& input_points, CGAL_PMP_AUTOREFINE_VERBOSE("triangulate faces"); // now refine triangles std::vector> new_triangles; + +#ifdef USE_PROGRESS_DISPLAY + boost::timer::progress_display pd(triangles.size()); +#endif + for(std::size_t ti=0; ti Date: Fri, 31 Mar 2023 10:26:21 +0200 Subject: [PATCH 053/329] repair soup before orient + to mesh --- .../include/CGAL/Polygon_mesh_processing/autorefinement.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 4f56b8a0d817..e38f64ff3010 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -1417,6 +1418,7 @@ autorefine( TriangleMesh& tm, out_soup_points, out_soup_triangles); clear(tm); + repair_polygon_soup(out_soup_points, out_soup_triangles); orient_polygon_soup(out_soup_points, out_soup_triangles); polygon_soup_to_polygon_mesh(out_soup_points, out_soup_triangles, tm); } From 55f8bcb12202de6fb6fe70ee3096d979b8f95dbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 6 Apr 2023 18:24:59 +0200 Subject: [PATCH 054/329] fix assertion --- .../internal/Triangle_3_Triangle_3_intersection.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 35aa4f8f0a53..4cc5f9be5600 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 @@ -372,7 +372,7 @@ void intersection_coplanar_triangles_cutoff(const typename Kernel::Point_3& p1, prev = inter_pts.insert(it,new_pt); orientations[&(*prev)] = COLLINEAR; - CGAL_assertion_code(++pt_added); + CGAL_kernel_assertion_code(++pt_added); } prev = it; From a15956d231a5639cd850c6dde9f37891fdad1e25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 24 May 2023 16:09:31 +0200 Subject: [PATCH 055/329] add clear function and input must mesh should be const in principle --- .../Non_manifold_feature_map.h | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/Non_manifold_feature_map.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/Non_manifold_feature_map.h index 8177a02d178b..e8901ebd727b 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/Non_manifold_feature_map.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/Non_manifold_feature_map.h @@ -28,8 +28,8 @@ struct Non_manifold_feature_map typedef typename Graph_traits::halfedge_descriptor halfedge_descriptor; typedef dynamic_edge_property_t Edge_to_id_tag; typedef dynamic_vertex_property_t Vertex_to_id_tag; - typedef typename boost::property_map::type Edge_to_nm_id; - typedef typename boost::property_map::type Vertex_to_nm_id; + typedef typename boost::property_map::const_type Edge_to_nm_id; + typedef typename boost::property_map::const_type Vertex_to_nm_id; Edge_to_nm_id e_nm_id; Vertex_to_nm_id v_nm_id; std::vector< std::vector > non_manifold_edges; @@ -39,7 +39,7 @@ struct Non_manifold_feature_map {} template - Non_manifold_feature_map(PolygonMesh& pm, Vpm vpm) + Non_manifold_feature_map(const PolygonMesh& pm, Vpm vpm) : e_nm_id(get(Edge_to_id_tag(), pm)) , v_nm_id(get(Vertex_to_id_tag(), pm)) { @@ -99,6 +99,14 @@ struct Non_manifold_feature_map } } } + + void clear() + { + non_manifold_edges.clear(); + non_manifold_vertices.clear(); + e_nm_id = Edge_to_nm_id(); + v_nm_id = Vertex_to_nm_id(); + } }; } } // end of CGAL::Polygon_mesh_processing From 5d73a7addd778919f50b60b37d87e70886703035 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 25 May 2023 10:06:51 +0200 Subject: [PATCH 056/329] add TODOs for parallelism --- .../examples/Polygon_mesh_processing/CMakeLists.txt | 1 + .../CGAL/Polygon_mesh_processing/autorefinement.h | 13 +++++++++---- 2 files changed, 10 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 d2faeb70cb28..306e216be408 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt @@ -120,6 +120,7 @@ if(TARGET CGAL::TBB_support) target_link_libraries(self_intersections_example PUBLIC CGAL::TBB_support) target_link_libraries(hausdorff_distance_remeshing_example PUBLIC CGAL::TBB_support) target_link_libraries(hausdorff_bounded_error_distance_example PUBLIC CGAL::TBB_support) + target_link_libraries(soup_autorefinement PUBLIC CGAL::TBB_support) create_single_source_cgal_program("corefinement_parallel_union_meshes.cpp") target_link_libraries(corefinement_parallel_union_meshes PUBLIC CGAL::TBB_support) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index e38f64ff3010..a46f2664803f 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -1116,7 +1116,7 @@ void autorefine_soup_output(const PointRange& input_points, typedef std::size_t Input_TID; typedef std::pair Pair_of_triangle_ids; - std::vector si_pairs; + std::vector si_pairs; // TODO: check std::vector is fine with Parallel_tag // collect intersecting pairs of triangles CGAL_PMP_AUTOREFINE_VERBOSE("collect intersecting pairs"); @@ -1170,6 +1170,7 @@ void autorefine_soup_output(const PointRange& input_points, CGAL_PMP_AUTOREFINE_VERBOSE("compute intersections"); std::set > intersecting_triangles; + //TODO: PARALLEL_FOR #2 for (const Pair_of_triangle_ids& p : si_pairs) { int i1 = tri_inter_ids[p.first], @@ -1217,6 +1218,7 @@ void autorefine_soup_output(const PointRange& input_points, #ifdef DEDUPLICATE_SEGMENTS // deduplicate inserted segments + //TODO: PARALLEL_FOR #3 std::vector>> all_segments_ids(all_segments.size()); for(std::size_t ti=0; ti> new_triangles; + std::vector> new_triangles; // Need to be threadsafe #ifdef USE_PROGRESS_DISPLAY boost::timer::progress_display pd(triangles.size()); #endif + //TODO: PARALLEL_FOR #1 for(std::size_t ti=0; ti to_input; + // TODO: reuse the fact that maps per triangle are already sorted std::map point_id_map; #if ! defined(CGAL_NDEBUG) || defined(CGAL_DEBUG_PMP_AUTOREFINE) std::vector exact_soup_points; @@ -1348,6 +1352,7 @@ void autorefine_soup_output(const PointRange& input_points, } // import refined triangles + //TODO: PARALLEL_FOR #4 for (const std::array& t : new_triangles) { soup_triangles.emplace_back(CGAL::make_array(get_point_id(t[0]), get_point_id(t[1]), get_point_id(t[2]))); @@ -1355,11 +1360,11 @@ void autorefine_soup_output(const PointRange& input_points, #ifndef CGAL_NDEBUG CGAL_PMP_AUTOREFINE_VERBOSE("check soup"); - CGAL_assertion( !does_triangle_soup_self_intersect(exact_soup_points, soup_triangles) ); + CGAL_assertion( !does_triangle_soup_self_intersect(exact_soup_points, soup_triangles) ); #else #ifdef CGAL_DEBUG_PMP_AUTOREFINE CGAL_PMP_AUTOREFINE_VERBOSE("check soup"); - if (does_triangle_soup_self_intersect(exact_soup_points, soup_triangles)) + if (does_triangle_soup_self_intersect(exact_soup_points, soup_triangles)) throw std::runtime_error("ERROR: invalid output, there is most probably a bug"); #endif #endif From 278e1867aa322600cd236413ba305f96b013258e Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Fri, 26 May 2023 17:12:28 +0100 Subject: [PATCH 057/329] parallize #1 --- .../soup_autorefinement.cpp | 7 +- .../Polygon_mesh_processing/autorefinement.h | 89 +++++++++++++------ 2 files changed, 65 insertions(+), 31 deletions(-) diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp index d955734853bf..f12306689485 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include @@ -29,11 +30,13 @@ int main(int argc, char** argv) PMP::repair_polygon_soup(input_points, input_triangles); PMP::triangulate_polygons(input_points, input_triangles); + CGAL::Real_timer t; + t.start(); std::vector output_points; std::vector> output_triangles; PMP::autorefine_soup_output(input_points, input_triangles, output_points, output_triangles); - - CGAL::IO::write_polygon_soup("autorefined.off", output_points, output_triangles, CGAL::parameters::stream_precision(17)); + std::cout << "#points = " << output_points.size() << " and #triangles = " << output_triangles.size() << " in " << t.time() << " sec." << std::endl; + // CGAL::IO::write_polygon_soup("autorefined.off", output_points, output_triangles, CGAL::parameters::stream_precision(17)); return 0; } diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index a46f2664803f..e862d6839609 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -39,6 +39,11 @@ #define CGAL_PMP_AUTOREFINE_VERBOSE(MSG) #endif +#ifdef CGAL_LINKED_WITH_TBB +#include +#include +#endif + #include #define TEST_RESOLVE_INTERSECTION @@ -656,7 +661,12 @@ void generate_subtriangles(std::size_t ti, const std::vector& in_triangle_ids, const std::set >& intersecting_triangles, const std::vector>& triangles, - std::vector>& new_triangles) +#ifdef CGAL_LINKED_WITH_TBB + tbb::concurrent_vector>& new_triangles +#else + std::vector>& new_triangles +#endif + ) { // std::cout << "generate_subtriangles()\n"; // std::cout << std::setprecision(17); @@ -1266,46 +1276,67 @@ void autorefine_soup_output(const PointRange& input_points, CGAL_PMP_AUTOREFINE_VERBOSE("triangulate faces"); // now refine triangles - std::vector> new_triangles; // Need to be threadsafe +#ifdef CGAL_LINKED_WITH_TBB + tbb::concurrent_vector> new_triangles; +#else + std::vector> new_triangles; +#endif #ifdef USE_PROGRESS_DISPLAY boost::timer::progress_display pd(triangles.size()); #endif - //TODO: PARALLEL_FOR #1 - for(std::size_t ti=0; ti& t = triangles[ti]; - auto is_constant_in_dim = [](const std::array& t, int dim) - { - return t[0][dim]==t[1][dim] && t[0][dim]!=t[2][dim]; - }; + if (all_segments[ti].empty() && all_points[ti].empty()) + new_triangles.push_back(triangles[ti]); + else + { +#ifdef USE_FIXED_PROJECTION_TRAITS + const std::array& t = triangles[ti]; + auto is_constant_in_dim = [](const std::array& t, int dim) + { + return t[0][dim] == t[1][dim] && t[0][dim] != t[2][dim]; + }; - typename EK::Vector_3 orth = CGAL::normal(t[0], t[1], t[2]); // TODO::avoid construction? - int c = CGAL::abs(orth[0]) > CGAL::abs(orth[1]) ? 0 : 1; - c = CGAL::abs(orth[2]) > CGAL::abs(orth[c]) ? 2 : c; + typename EK::Vector_3 orth = CGAL::normal(t[0], t[1], t[2]); // TODO::avoid construction? + int c = CGAL::abs(orth[0]) > CGAL::abs(orth[1]) ? 0 : 1; + c = CGAL::abs(orth[2]) > CGAL::abs(orth[c]) ? 2 : c; - if(c == 0) { - autorefine_impl::generate_subtriangles(ti, all_segments[ti], all_points[ti], all_in_triangle_ids[ti], intersecting_triangles, triangles, new_triangles); - } else if(c == 1) { - autorefine_impl::generate_subtriangles(ti, all_segments[ti], all_points[ti], all_in_triangle_ids[ti], intersecting_triangles, triangles, new_triangles); - } else if(c == 2) { - autorefine_impl::generate_subtriangles(ti, all_segments[ti], all_points[ti], all_in_triangle_ids[ti], intersecting_triangles, triangles, new_triangles); - } - #else - autorefine_impl::generate_subtriangles(ti, all_segments_ids[ti], all_points[ti], all_in_triangle_ids[ti], intersecting_triangles, triangles, new_triangles); - #endif - } + if (c == 0) { + autorefine_impl::generate_subtriangles(ti, all_segments[ti], all_points[ti], all_in_triangle_ids[ti], intersecting_triangles, triangles, new_triangles); + } + else if (c == 1) { + autorefine_impl::generate_subtriangles(ti, all_segments[ti], all_points[ti], all_in_triangle_ids[ti], intersecting_triangles, triangles, new_triangles); + } + else if (c == 2) { + autorefine_impl::generate_subtriangles(ti, all_segments[ti], all_points[ti], all_in_triangle_ids[ti], intersecting_triangles, triangles, new_triangles); + } +#else + autorefine_impl::generate_subtriangles(ti, all_segments_ids[ti], all_points[ti], all_in_triangle_ids[ti], intersecting_triangles, triangles, new_triangles); +#endif + } #ifdef USE_PROGRESS_DISPLAY - ++pd; + ++pd; #endif + }; + +#ifdef CGAL_LINKED_WITH_TBB + tbb::parallel_for(tbb::blocked_range(0, triangles.size()), + [&](const tbb::blocked_range& r) { + for (size_t ti = r.begin(); ti != r.end(); ++ti) + func(ti); + } + ); +#else + for (std::size_t ti = 0; ti < triangles.size(); ++ti) { + func(ti); } +#endif + + // brute force output: create a soup, orient and to-mesh CGAL_PMP_AUTOREFINE_VERBOSE("create output soup"); From 319743abf9126d413f6ad9feb99988896094e1f9 Mon Sep 17 00:00:00 2001 From: Efi Fogel Date: Sun, 28 May 2023 15:24:35 +0300 Subject: [PATCH 058/329] Simplified test data and eliminated no. of faces (which is not used) --- .../{CompareCurveList.h => Compare_curves.h} | 0 .../DATA/segments_tight/test00.txt | 36 ++-- .../DATA/segments_tight/test01.txt | 50 ++--- .../DATA/segments_tight/test02.txt | 39 ++-- .../DATA/segments_tight/test03.txt | 27 ++- .../DATA/segments_tight/test04.txt | 39 ++-- .../DATA/segments_tight/test05.txt | 39 ++-- .../DATA/segments_tight/test06.txt | 87 ++++---- .../DATA/segments_tight/test07.txt | 26 +-- .../DATA/segments_tight/test08.txt | 24 +-- .../DATA/segments_tight/test09.txt | 25 ++- .../DATA/segments_tight/test10.txt | 26 ++- .../DATA/segments_tight/test11.txt | 26 ++- .../DATA/segments_tight/test12.txt | 40 ++-- .../DATA/segments_tight/test13.txt | 39 ++-- .../DATA/segments_tight/test14.txt | 70 +++---- .../DATA/segments_tight/test15.txt | 53 +++-- .../DATA/segments_tight/test16.txt | 90 ++++----- .../DATA/segments_tight/test17.txt | 27 ++- .../DATA/segments_tight/test18.txt | 38 ++-- .../DATA/segments_tight/test19.txt | 24 +-- .../DATA/segments_tight/test20.txt | 40 ++-- .../DATA/segments_tight/test21.txt | 42 ++-- .../DATA/segments_tight/test22.txt | 36 ++-- .../DATA/segments_tight/test23.txt | 29 ++- .../DATA/segments_tight/test24.txt | 28 +-- .../DATA/segments_tight/test25.txt | 29 ++- .../DATA/segments_tight/test26.txt | 60 +++--- .../DATA/segments_tight/test27.txt | 48 ++--- .../DATA/segments_tight/test28.txt | 58 +++--- .../DATA/segments_tight/test29.txt | 36 ++-- .../DATA/segments_tight/test30.txt | 30 +-- .../DATA/segments_tight/test31.txt | 50 ++--- .../DATA/segments_tight/test32.txt | 50 ++--- .../DATA/segments_tight/test33.txt | 18 +- .../DATA/segments_tight/test34.txt | 18 +- .../DATA/segments_tight/test35.txt | 66 +++--- .../DATA/segments_tight/test36.txt | 66 +++--- .../DATA/segments_tight/test37.txt | 86 ++++---- .../DATA/segments_tight/test40.txt | 24 +-- .../DATA/segments_tight/test41.txt | 24 +-- .../DATA/segments_tight/test42.txt | 30 +-- .../DATA/segments_tight/test43.txt | 16 +- .../DATA/segments_tight/test44.txt | 27 ++- .../DATA/segments_tight/test45.txt | 16 +- .../DATA/segments_tight/test46.txt | 26 +-- .../DATA/segments_tight/test47.txt | 24 +-- .../DATA/segments_tight/test48.txt | 46 ++--- .../DATA/segments_tight/test49.txt | 16 +- .../DATA/segments_tight/test50.txt | 42 ++-- .../DATA/segments_tight/test51.txt | 190 +++++++++--------- .../DATA/segments_tight/test52.txt | 38 ++-- .../DATA/segments_tight/test53.txt | 23 +-- .../DATA/segments_tight/test54.txt | 30 +-- .../DATA/segments_tight/test55.txt | 39 ++-- .../DATA/segments_tight/test56.txt | 37 ++-- .../DATA/segments_tight/test60.txt | 29 ++- .../DATA/segments_tight/test61.txt | 50 ++--- .../DATA/segments_tight/test62.txt | 14 +- .../DATA/segments_tight/test63.txt | 32 +-- .../DATA/segments_tight/test64.txt | 14 +- .../DATA/segments_tight/test65.txt | 30 +-- .../DATA/segments_tight/test66.txt | 34 ++-- .../DATA/segments_tight/test67.txt | 47 +++-- .../DATA/segments_tight/test68.txt | 70 +++---- .../DATA/segments_tight/test69.txt | 49 +++-- .../DATA/segments_tight/test70.txt | 62 +++--- .../DATA/segments_tight/test71.txt | 38 ++-- .../DATA/segments_tight/test72.txt | 114 +++++------ .../DATA/segments_tight/test73.txt | 28 +-- .../DATA/segments_tight/test74.txt | 50 ++--- .../DATA/segments_tight/test75.txt | 34 ++-- .../DATA/segments_tight/test76.txt | 42 ++-- .../DATA/segments_tight/test77.txt | 21 +- .../DATA/segments_tight/test78.txt | 106 +++++----- .../DATA/segments_tight/test79.txt | 50 ++--- .../DATA/segments_tight/test80.txt | 36 ++-- .../DATA/segments_tight/test81.txt | 78 +++---- .../DATA/segments_tight/test82.txt | 30 +-- .../DATA/segments_tight/test83.txt | 38 ++-- .../DATA/segments_tight/test84.txt | 42 ++-- .../DATA/segments_tight/test85.txt | 33 ++- .../DATA/segments_tight/test86.txt | 32 ++- .../DATA/segments_tight/test87.txt | 31 ++- .../DATA/segments_tight/test88.txt | 37 ++-- 85 files changed, 1744 insertions(+), 1790 deletions(-) rename Surface_sweep_2/test/Surface_sweep_2/{CompareCurveList.h => Compare_curves.h} (100%) diff --git a/Surface_sweep_2/test/Surface_sweep_2/CompareCurveList.h b/Surface_sweep_2/test/Surface_sweep_2/Compare_curves.h similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/CompareCurveList.h rename to Surface_sweep_2/test/Surface_sweep_2/Compare_curves.h diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test00.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test00.txt index 420b718d1e7b..7d48df57242c 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test00.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test00.txt @@ -1,23 +1,27 @@ +# No. of input segments followed by segments 2 -1 1 1 -1 1 1 -1 -1 +# No. of output segments followed by segments 4 -0/8 0/8 -1/1 -1/1 --1/1 1/1 0/8 0/8 -0/8 0/8 1/1 -1/1 -1/1 1/1 0/8 0/8 +0 0 -1 -1 +-1 1 0 0 +0 0 1 -1 +1 1 0 0 +# No. of output points followed by points 5 --1/1 -1/1 --1/1 1/1 -0/8 0/8 -1/1 -1/1 -1/1 1/1 -1 -0/8 0/8 +-1 -1 +-1 1 +0 0 +1 -1 +1 1 +# No. of intersection points followed by points 1 +0 0 +# No of faces: 1 +# No. of output segments with overlaps followed by segments 4 -0/8 0/8 -1/1 -1/1 --1/1 1/1 0/8 0/8 -0/8 0/8 1/1 -1/1 -1/1 1/1 0/8 0/8 - +0 0 -1 -1 +-1 1 0 0 +0 0 1 -1 +1 1 0 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test01.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test01.txt index b8f61bf90c6c..b5e69de02428 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test01.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test01.txt @@ -4,47 +4,47 @@ 5 0 1 2 1 0 3 4 12 -1/1 0/1 36/20 32/20 -36/20 32/20 1/1 2/1 +1 0 36/20 32/20 +36/20 32/20 1 2 36/20 32/20 44/20 48/20 -1/1 3/1 44/20 48/20 -44/20 48/20 3/1 4/1 -82/26 24/26 3/1 0/1 +1 3 44/20 48/20 +44/20 48/20 3 4 +82/26 24/26 3 0 82/26 24/26 36/20 32/20 86/26 48/26 82/26 24/26 44/20 48/20 86/26 48/26 -4/1 6/1 86/26 48/26 -5/1 0/1 82/26 24/26 -86/26 48/26 5/1 1/1 +4 6 86/26 48/26 +5 0 82/26 24/26 +86/26 48/26 5 1 12 -1/1 0/1 -1/1 2/1 -1/1 3/1 +1 0 +1 2 +1 3 36/20 32/20 44/20 48/20 -3/1 0/1 -3/1 4/1 +3 0 +3 4 82/26 24/26 86/26 48/26 -4/1 6/1 -5/1 0/1 -5/1 1/1 +4 6 +5 0 +5 1 4 36/20 32/20 44/20 48/20 82/26 24/26 86/26 48/26 -2 +# No. of faces: 2 12 -1/1 0/1 36/20 32/20 -36/20 32/20 1/1 2/1 +1 0 36/20 32/20 +36/20 32/20 1 2 36/20 32/20 44/20 48/20 -1/1 3/1 44/20 48/20 -44/20 48/20 3/1 4/1 -82/26 24/26 3/1 0/1 +1 3 44/20 48/20 +44/20 48/20 3 4 +82/26 24/26 3 0 82/26 24/26 36/20 32/20 86/26 48/26 82/26 24/26 44/20 48/20 86/26 48/26 -4/1 6/1 86/26 48/26 -5/1 0/1 82/26 24/26 -86/26 48/26 5/1 1/1 +4 6 86/26 48/26 +5 0 82/26 24/26 +86/26 48/26 5 1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test02.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test02.txt index 9f96ea0d395d..5c505dbd01f9 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test02.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test02.txt @@ -3,32 +3,31 @@ 7 4 1 3 5 2 3 7 7 -0/1 6/1 153/43 241/43 -153/43 241/43 3/1 7/1 -140/32 114/32 1/1 3/1 +0 6 153/43 241/43 +153/43 241/43 3 7 +140/32 114/32 1 3 140/32 114/32 153/43 241/43 -5/1 2/1 140/32 114/32 -7/1 4/1 140/32 114/32 -153/43 241/43 9/1 5/1 +5 2 140/32 114/32 +7 4 140/32 114/32 +153/43 241/43 9 5 8 -0/1 6/1 -1/1 3/1 -3/1 7/1 +0 6 +1 3 +3 7 153/43 241/43 140/32 114/32 -5/1 2/1 -7/1 4/1 -9/1 5/1 +5 2 +7 4 +9 5 2 153/43 241/43 140/32 114/32 -1 +# No. of faces: 1 7 -0/1 6/1 153/43 241/43 -153/43 241/43 3/1 7/1 -140/32 114/32 1/1 3/1 +0 6 153/43 241/43 +153/43 241/43 3 7 +140/32 114/32 1 3 140/32 114/32 153/43 241/43 -5/1 2/1 140/32 114/32 -7/1 4/1 140/32 114/32 -153/43 241/43 9/1 5/1 - +5 2 140/32 114/32 +7 4 140/32 114/32 +153/43 241/43 9 5 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test03.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test03.txt index 9fc24d516679..15cc231bb28d 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test03.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test03.txt @@ -3,20 +3,19 @@ 1 2 5 2 1 3 5 3 3 -1/1 1/1 5/1 1/1 -1/1 2/1 5/1 2/1 -1/1 3/1 5/1 3/1 +1 1 5 1 +1 2 5 2 +1 3 5 3 6 -1/1 1/1 -1/1 2/1 -1/1 3/1 -5/1 1/1 -5/1 2/1 -5/1 3/1 +1 1 +1 2 +1 3 +5 1 +5 2 +5 3 0 -1 +# No. of faces: 1 3 -1/1 1/1 5/1 1/1 -1/1 2/1 5/1 2/1 -1/1 3/1 5/1 3/1 - +1 1 5 1 +1 2 5 2 +1 3 5 3 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test04.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test04.txt index 953c0bdeaafe..8ea66e0df9fe 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test04.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test04.txt @@ -3,32 +3,31 @@ 2 2 9 2 3 7 8 1 7 -2/1 2/1 63/21 42/21 -1/1 4/1 63/21 42/21 -63/21 42/21 4/1 1/1 +2 2 63/21 42/21 +1 4 63/21 42/21 +63/21 42/21 4 1 63/21 42/21 301/42 84/42 -3/1 7/1 301/42 84/42 -301/42 84/42 8/1 1/1 -301/42 84/42 9/1 2/1 +3 7 301/42 84/42 +301/42 84/42 8 1 +301/42 84/42 9 2 8 -1/1 4/1 -2/1 2/1 +1 4 +2 2 63/21 42/21 -3/1 7/1 -4/1 1/1 +3 7 +4 1 301/42 84/42 -8/1 1/1 -9/1 2/1 +8 1 +9 2 2 63/21 42/21 301/42 84/42 -1 +# No. of faces: 1 7 -2/1 2/1 63/21 42/21 -1/1 4/1 63/21 42/21 -63/21 42/21 4/1 1/1 +2 2 63/21 42/21 +1 4 63/21 42/21 +63/21 42/21 4 1 63/21 42/21 301/42 84/42 -3/1 7/1 301/42 84/42 -301/42 84/42 8/1 1/1 -301/42 84/42 9/1 2/1 - +3 7 301/42 84/42 +301/42 84/42 8 1 +301/42 84/42 9 2 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test05.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test05.txt index 46d7e73e4d6f..187550ca704f 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test05.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test05.txt @@ -3,38 +3,37 @@ 3 2 10 6 1 3 14 3 9 -3/1 2/1 247/52 156/52 -1/1 3/1 247/52 156/52 +3 2 247/52 156/52 +1 3 247/52 156/52 247/52 156/52 681/87 414/87 -2/1 7/1 681/87 414/87 -681/87 414/87 10/1 6/1 +2 7 681/87 414/87 +681/87 414/87 10 6 247/52 156/52 806/65 195/65 681/87 414/87 806/65 195/65 -806/65 195/65 14/1 3/1 -806/65 195/65 15/1 2/1 +806/65 195/65 14 3 +806/65 195/65 15 2 9 -1/1 3/1 -2/1 7/1 -3/1 2/1 +1 3 +2 7 +3 2 247/52 156/52 681/87 414/87 -10/1 6/1 +10 6 806/65 195/65 -14/1 3/1 -15/1 2/1 +14 3 +15 2 3 247/52 156/52 681/87 414/87 806/65 195/65 -2 +# No. of faces: 2 9 -3/1 2/1 247/52 156/52 -1/1 3/1 247/52 156/52 +3 2 247/52 156/52 +1 3 247/52 156/52 247/52 156/52 681/87 414/87 -2/1 7/1 681/87 414/87 -681/87 414/87 10/1 6/1 +2 7 681/87 414/87 +681/87 414/87 10 6 247/52 156/52 806/65 195/65 681/87 414/87 806/65 195/65 -806/65 195/65 14/1 3/1 -806/65 195/65 15/1 2/1 - +806/65 195/65 14 3 +806/65 195/65 15 2 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test06.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test06.txt index cd0e00f2585d..2f9455a5a350 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test06.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test06.txt @@ -6,56 +6,55 @@ 6 2 3 7 5 7 3 5 14 -60/16 92/16 3/1 5/1 -60/16 92/16 3/1 7/1 -213/45 185/45 1/1 1/1 +60/16 92/16 3 5 +60/16 92/16 3 7 +213/45 185/45 1 1 213/45 185/45 60/16 92/16 -5/1 7/1 60/16 92/16 -6/1 2/1 213/45 185/45 -7/1 6/1 213/45 185/45 -156/15 60/15 9/1 4/1 -156/15 60/15 8/1 6/1 -58/5 15/5 11/1 3/1 -58/5 15/5 156/15 60/15 -12/1 3/1 58/5 15/5 -12/1 4/1 156/15 60/15 -14/1 1/1 58/5 15/5 +5 7 60/16 92/16 +6 2 213/45 185/45 +7 6 213/45 185/45 +156/15 4 9 4 +156/15 4 8 6 +58/5 3 11 3 +58/5 3 156/15 4 +12 3 58/5 3 +12 4 156/15 4 +14 1 58/5 3 16 -1/1 1/1 -3/1 5/1 -3/1 7/1 +1 1 +3 5 +3 7 60/16 92/16 213/45 185/45 -5/1 7/1 -6/1 2/1 -7/1 6/1 -8/1 6/1 -9/1 4/1 -156/15 60/15 -11/1 3/1 -58/5 15/5 -12/1 3/1 -12/1 4/1 -14/1 1/1 +5 7 +6 2 +7 6 +8 6 +9 4 +156/15 4 +11 3 +58/5 3 +12 3 +12 4 +14 1 4 60/16 92/16 213/45 185/45 -156/15 60/15 -58/5 15/5 -1 +156/15 4 +58/5 3 +# No. of faces: 1 14 -60/16 92/16 3/1 5/1 -60/16 92/16 3/1 7/1 -213/45 185/45 1/1 1/1 +60/16 92/16 3 5 +60/16 92/16 3 7 +213/45 185/45 1 1 213/45 185/45 60/16 92/16 -5/1 7/1 60/16 92/16 -6/1 2/1 213/45 185/45 -7/1 6/1 213/45 185/45 -156/15 60/15 9/1 4/1 -156/15 60/15 8/1 6/1 -58/5 15/5 11/1 3/1 -58/5 15/5 156/15 60/15 -12/1 3/1 58/5 15/5 -12/1 4/1 156/15 60/15 -14/1 1/1 58/5 15/5 - +5 7 60/16 92/16 +6 2 213/45 185/45 +7 6 213/45 185/45 +156/15 4 9 4 +156/15 4 8 6 +58/5 3 11 3 +58/5 3 156/15 4 +12 3 58/5 3 +12 4 156/15 4 +14 1 58/5 3 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test07.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test07.txt index c94c53eece64..b95f6e3998ca 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test07.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test07.txt @@ -4,19 +4,19 @@ 7 1 9 4 5 5 9 4 4 -5/1 5/1 2/1 3/1 -7/1 1/1 2/1 3/1 -7/1 1/1 9/1 4/1 -5/1 5/1 9/1 4/1 +5 5 2 3 +7 1 2 3 +7 1 9 4 +5 5 9 4 4 -2/1 3/1 -5/1 5/1 -7/1 1/1 -9/1 4/1 +2 3 +5 5 +7 1 +9 4 0 -2 +# No. of faces: 2 4 -5/1 5/1 2/1 3/1 -7/1 1/1 2/1 3/1 -7/1 1/1 9/1 4/1 -5/1 5/1 9/1 4/1 +5 5 2 3 +7 1 2 3 +7 1 9 4 +5 5 9 4 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test08.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test08.txt index 2aa0735bf044..10db8ae63eaa 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test08.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test08.txt @@ -2,18 +2,18 @@ 1 2 4 2 3 0 5 4 3 -3/1 0/1 4/1 2/1 -1/1 2/1 4/1 2/1 -4/1 2/1 5/1 4/1 +3 0 4 2 +1 2 4 2 +4 2 5 4 4 -1/1 2/1 -3/1 0/1 -4/1 2/1 -5/1 4/1 -1 -4/1 2/1 +1 2 +3 0 +4 2 +5 4 1 +4 2 +# No. of faces: 1 3 -3/1 0/1 4/1 2/1 -1/1 2/1 4/1 2/1 -4/1 2/1 5/1 4/1 +3 0 4 2 +1 2 4 2 +4 2 5 4 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test09.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test09.txt index e9f6371753e0..8e0635e3ca68 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test09.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test09.txt @@ -2,19 +2,18 @@ 1 1 7 1 3 1 5 4 3 -1/1 1/1 3/1 1/1 -3/1 1/1 5/1 4/1 -3/1 1/1 7/1 1/1 +1 1 3 1 +3 1 5 4 +3 1 7 1 4 -1/1 1/1 -3/1 1/1 -5/1 4/1 -7/1 1/1 -1 -3/1 1/1 +1 1 +3 1 +5 4 +7 1 1 +3 1 +# No. of faces: 1 3 -1/1 1/1 3/1 1/1 -3/1 1/1 5/1 4/1 -3/1 1/1 7/1 1/1 - +1 1 3 1 +3 1 5 4 +3 1 7 1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test10.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test10.txt index f01134605549..47e21732fd62 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test10.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test10.txt @@ -2,20 +2,18 @@ 6 1 1 1 4 -2 3 1 3 -3/1 1/1 1/1 1/1 -4/1 -2/1 3/1 1/1 -6/1 1/1 3/1 1/1 +3 1 1 1 +4 -2 3 1 +6 1 3 1 4 -1/1 1/1 -3/1 1/1 -4/1 -2/1 -6/1 1/1 -1 -3/1 1/1 +1 1 +3 1 +4 -2 +6 1 1 +3 1 +# No. of faces: 1 3 -3/1 1/1 1/1 1/1 -4/1 -2/1 3/1 1/1 -6/1 1/1 3/1 1/1 - - +3 1 1 1 +4 -2 3 1 +6 1 3 1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test11.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test11.txt index 78140996955a..e389d4a7db70 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test11.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test11.txt @@ -2,20 +2,18 @@ 1 1 3 5 5 3 2 3 3 -1/1 1/1 2/1 3/1 -2/1 3/1 3/1 5/1 -5/1 3/1 2/1 3/1 +1 1 2 3 +2 3 3 5 +5 3 2 3 4 -1/1 1/1 -2/1 3/1 -3/1 5/1 -5/1 3/1 -1 -2/1 3/1 +1 1 +2 3 +3 5 +5 3 1 +2 3 +# No. of faces: 1 3 -1/1 1/1 2/1 3/1 -2/1 3/1 3/1 5/1 -5/1 3/1 2/1 3/1 - - +1 1 2 3 +2 3 3 5 +5 3 2 3 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test12.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test12.txt index 39d22990f454..4710b27995dd 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test12.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test12.txt @@ -3,27 +3,25 @@ 7 1 1 1 1 4 5 4 5 -1/1 4/1 2/1 4/1 -4/1 1/1 1/1 1/1 -2/1 4/1 4/1 1/1 -2/1 4/1 5/1 4/1 -7/1 1/1 4/1 1/1 +1 4 2 4 +4 1 1 1 +2 4 4 1 +2 4 5 4 +7 1 4 1 6 -1/1 1/1 -1/1 4/1 -2/1 4/1 -4/1 1/1 -5/1 4/1 -7/1 1/1 +1 1 +1 4 +2 4 +4 1 +5 4 +7 1 2 -2/1 4/1 -4/1 1/1 -1 +2 4 +4 1 +# No. of faces: 1 5 -1/1 4/1 2/1 4/1 -4/1 1/1 1/1 1/1 -2/1 4/1 4/1 1/1 -2/1 4/1 5/1 4/1 -7/1 1/1 4/1 1/1 - - +1 4 2 4 +4 1 1 1 +2 4 4 1 +2 4 5 4 +7 1 4 1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test13.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test13.txt index 69f7c821d955..3fad0655447f 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test13.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test13.txt @@ -3,26 +3,25 @@ 1 5 9 -1 7 4 3 0 5 -0/1 2/1 4/1 2/1 -280/56 112/56 3/1 0/1 -1/1 5/1 280/56 112/56 -7/1 4/1 280/56 112/56 -280/56 112/56 9/1 -1/1 +0 2 4 2 +5 2 3 0 +1 5 5 2 +7 4 5 2 +5 2 9 -1 7 -0/1 2/1 -1/1 5/1 -3/1 0/1 -4/1 2/1 -280/56 112/56 -7/1 4/1 -9/1 -1/1 -1 -280/56 112/56 +0 2 +1 5 +3 0 +4 2 +5 2 +7 4 +9 -1 1 +5 2 +# No. of faces: 1 5 -0/1 2/1 4/1 2/1 -280/56 112/56 3/1 0/1 -1/1 5/1 280/56 112/56 -7/1 4/1 280/56 112/56 -280/56 112/56 9/1 -1/1 - +0 2 4 2 +5 2 3 0 +1 5 5 2 +7 4 5 2 +5 2 9 -1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test14.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test14.txt index 6252c3b96dc4..01535344d7c1 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test14.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test14.txt @@ -7,41 +7,41 @@ 3 -1 5 -1 3 -2 5 -2 9 -0/1 2/1 4/1 2/1 -3/1 -2/1 5/1 -2/1 -3/1 -1/1 5/1 -1/1 -280/56 112/56 3/1 0/1 -1/1 5/1 280/56 112/56 -3/1 4/1 5/1 4/1 -3/1 5/1 5/1 5/1 -7/1 4/1 280/56 112/56 -280/56 112/56 9/1 -1/1 +0 2 4 2 +3 -2 5 -2 +3 -1 5 -1 +5 2 3 0 +1 5 5 2 +3 4 5 4 +3 5 5 5 +7 4 5 2 +5 2 9 -1 15 -0/1 2/1 -1/1 5/1 -3/1 -2/1 -3/1 -1/1 -3/1 0/1 -3/1 4/1 -3/1 5/1 -4/1 2/1 -5/1 -2/1 -5/1 -1/1 -280/56 112/56 -5/1 4/1 -5/1 5/1 -7/1 4/1 -9/1 -1/1 -1 -280/56 112/56 +0 2 +1 5 +3 -2 +3 -1 +3 0 +3 4 +3 5 +4 2 +5 -2 +5 -1 +5 2 +5 4 +5 5 +7 4 +9 -1 1 +5 2 +# No. of faces: 1 9 -0/1 2/1 4/1 2/1 -3/1 -2/1 5/1 -2/1 -3/1 -1/1 5/1 -1/1 -280/56 112/56 3/1 0/1 -1/1 5/1 280/56 112/56 -3/1 4/1 5/1 4/1 -3/1 5/1 5/1 5/1 -7/1 4/1 280/56 112/56 -280/56 112/56 9/1 -1/1 +0 2 4 2 +3 -2 5 -2 +3 -1 5 -1 +5 2 3 0 +1 5 5 2 +3 4 5 4 +3 5 5 5 +7 4 5 2 +5 2 9 -1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test15.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test15.txt index bc9ee1611370..f7b36b054329 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test15.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test15.txt @@ -9,33 +9,32 @@ 8 2 5 -1 4 3 5 -1 9 -3/1 -3/1 0/1 0/1 -4/1 -4/1 3/1 -3/1 -0/1 0/1 4/1 3/1 -4/1 -4/1 5/1 -1/1 -3/1 -3/1 5/1 -1/1 -4/1 3/1 5/1 -1/1 -8/1 2/1 5/1 -1/1 -5/1 -1/1 9/1 -1/1 -8/1 2/1 9/1 -1/1 +3 -3 0 0 +4 -4 3 -3 +0 0 4 3 +4 -4 5 -1 +3 -3 5 -1 +4 3 5 -1 +8 2 5 -1 +5 -1 9 -1 +8 2 9 -1 7 -0/1 0/1 -3/1 -3/1 -4/1 -4/1 -4/1 3/1 -5/1 -1/1 -8/1 2/1 -9/1 -1/1 +0 0 +3 -3 +4 -4 +4 3 +5 -1 +8 2 +9 -1 0 -4 +# No. of faces: 4 9 -3/1 -3/1 0/1 0/1 -4/1 -4/1 3/1 -3/1 -0/1 0/1 4/1 3/1 -4/1 -4/1 5/1 -1/1 -3/1 -3/1 5/1 -1/1 -4/1 3/1 5/1 -1/1 -8/1 2/1 5/1 -1/1 -5/1 -1/1 9/1 -1/1 -8/1 2/1 9/1 -1/1 - +3 -3 0 0 +4 -4 3 -3 +0 0 4 3 +4 -4 5 -1 +3 -3 5 -1 +4 3 5 -1 +8 2 5 -1 +5 -1 9 -1 +8 2 9 -1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test16.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test16.txt index d174c920fc29..3bc6a8ce5476 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test16.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test16.txt @@ -7,51 +7,51 @@ 0 2 6 4 1 4 5 2 14 -2/1 0/1 36/12 36/12 -36/12 36/12 1/1 1/1 -0/1 2/1 36/12 36/12 -36/12 36/12 0/1 3/1 -1/1 4/1 36/12 36/12 -36/12 36/12 1/1 5/1 -36/12 36/12 2/1 6/1 -4/1 0/1 36/12 36/12 -36/12 36/12 4/1 6/1 -5/1 1/1 36/12 36/12 -36/12 36/12 5/1 2/1 -5/1 5/1 36/12 36/12 -6/1 3/1 36/12 36/12 -36/12 36/12 6/1 4/1 +2 0 3 3 +3 3 1 1 +0 2 3 3 +3 3 0 3 +1 4 3 3 +3 3 1 5 +3 3 2 6 +4 0 3 3 +3 3 4 6 +5 1 3 3 +3 3 5 2 +5 5 3 3 +6 3 3 3 +3 3 6 4 15 -0/1 2/1 -0/1 3/1 -1/1 1/1 -1/1 4/1 -1/1 5/1 -2/1 0/1 -2/1 6/1 -36/12 36/12 -4/1 0/1 -4/1 6/1 -5/1 1/1 -5/1 2/1 -5/1 5/1 -6/1 3/1 -6/1 4/1 -1 -36/12 36/12 +0 2 +0 3 +1 1 +1 4 +1 5 +2 0 +2 6 +3 3 +4 0 +4 6 +5 1 +5 2 +5 5 +6 3 +6 4 1 +3 3 +# No. of faces: 1 14 -2/1 0/1 36/12 36/12 -36/12 36/12 1/1 1/1 -0/1 2/1 36/12 36/12 -36/12 36/12 0/1 3/1 -1/1 4/1 36/12 36/12 -36/12 36/12 1/1 5/1 -36/12 36/12 2/1 6/1 -4/1 0/1 36/12 36/12 -36/12 36/12 4/1 6/1 -5/1 1/1 36/12 36/12 -36/12 36/12 5/1 2/1 -5/1 5/1 36/12 36/12 -6/1 3/1 36/12 36/12 -36/12 36/12 6/1 4/1 +2 0 3 3 +3 3 1 1 +0 2 3 3 +3 3 0 3 +1 4 3 3 +3 3 1 5 +3 3 2 6 +4 0 3 3 +3 3 4 6 +5 1 3 3 +3 3 5 2 +5 5 3 3 +6 3 3 3 +3 3 6 4 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test17.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test17.txt index 32cf9a98c6c8..34351b917acf 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test17.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test17.txt @@ -4,20 +4,19 @@ 1 3 0 4 1 3 2 4 4 -1/1 3/1 0/1 4/1 -1/1 5/1 0/1 4/1 -1/1 3/1 2/1 4/1 -1/1 5/1 2/1 4/1 +1 3 0 4 +1 5 0 4 +1 3 2 4 +1 5 2 4 4 -0/1 4/1 -1/1 3/1 -1/1 5/1 -2/1 4/1 +0 4 +1 3 +1 5 +2 4 0 -2 +# No. of faces: 2 4 -1/1 3/1 0/1 4/1 -1/1 5/1 0/1 4/1 -1/1 3/1 2/1 4/1 -1/1 5/1 2/1 4/1 - +1 3 0 4 +1 5 0 4 +1 3 2 4 +1 5 2 4 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test18.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test18.txt index 049c8e10a28d..23c2db7d18f9 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test18.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test18.txt @@ -3,25 +3,25 @@ 0 2 3 2 2 -1 4 1 5 -2/1 -1/1 36/12 0/12 -0/1 0/1 36/12 0/12 -0/1 2/1 3/1 2/1 -36/12 0/12 4/1 1/1 -36/12 0/12 6/1 0/1 +2 -1 3 0 +0 0 3 0 +0 2 3 2 +3 0 4 1 +3 0 6 0 7 -0/1 0/1 -0/1 2/1 -2/1 -1/1 -36/12 0/12 -3/1 2/1 -4/1 1/1 -6/1 0/1 -1 -36/12 0/12 +0 0 +0 2 +2 -1 +3 0 +3 2 +4 1 +6 0 1 +3 0 +# No. of faces: 1 5 -2/1 -1/1 36/12 0/12 -0/1 0/1 36/12 0/12 -0/1 2/1 3/1 2/1 -36/12 0/12 4/1 1/1 -36/12 0/12 6/1 0/1 +2 -1 3 0 +0 0 3 0 +0 2 3 2 +3 0 4 1 +3 0 6 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test19.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test19.txt index b21e9b2a1077..a6cf55f80253 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test19.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test19.txt @@ -3,19 +3,17 @@ 3 0 5 0 5 0 8 0 3 -0/1 0/1 3/1 0/1 -3/1 0/1 5/1 0/1 -5/1 0/1 8/1 0/1 +0 0 3 0 +3 0 5 0 +5 0 8 0 4 -0/1 0/1 -3/1 0/1 -5/1 0/1 -8/1 0/1 +0 0 +3 0 +5 0 +8 0 0 -1 +# No. of faces: 1 3 -0/1 0/1 3/1 0/1 -3/1 0/1 5/1 0/1 -5/1 0/1 8/1 0/1 - - +0 0 3 0 +3 0 5 0 +5 0 8 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test20.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test20.txt index 9075a5d1fb56..2c261cad7d14 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test20.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test20.txt @@ -3,28 +3,24 @@ 3 0 5 4 3 4 5 0 5 -3/1 0/1 4/1 2/1 -1/1 2/1 4/1 2/1 -3/1 4/1 4/1 2/1 -4/1 2/1 5/1 0/1 -4/1 2/1 5/1 4/1 +3 0 4 2 +1 2 4 2 +3 4 4 2 +4 2 5 0 +4 2 5 4 6 -1/1 2/1 -3/1 0/1 -3/1 4/1 -4/1 2/1 -5/1 0/1 -5/1 4/1 -1 -4/1 2/1 +1 2 +3 0 +3 4 +4 2 +5 0 +5 4 1 +4 2 +# No. of faces: 1 5 -3/1 0/1 4/1 2/1 -1/1 2/1 4/1 2/1 -3/1 4/1 4/1 2/1 -4/1 2/1 5/1 0/1 -4/1 2/1 5/1 4/1 - - - - +3 0 4 2 +1 2 4 2 +3 4 4 2 +4 2 5 0 +4 2 5 4 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test21.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test21.txt index 445b25d3b6ef..ad795ac780e4 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test21.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test21.txt @@ -3,27 +3,27 @@ 9 3 0 3 2 1 6 5 6 -2/1 1/1 180/45 135/45 -180/45 135/45 0/1 3/1 -180/45 135/45 1/1 6/1 -6/1 1/1 180/45 135/45 -180/45 135/45 6/1 5/1 -9/1 3/1 180/45 135/45 +2 1 4 3 +4 3 0 3 +4 3 1 6 +6 1 4 3 +4 3 6 5 +9 3 4 3 7 -0/1 3/1 -1/1 6/1 -2/1 1/1 -180/45 135/45 -6/1 1/1 -6/1 5/1 -9/1 3/1 -1 -180/45 135/45 +0 3 +1 6 +2 1 +4 3 +6 1 +6 5 +9 3 1 +4 3 +# No. of faces: 1 6 -2/1 1/1 180/45 135/45 -180/45 135/45 0/1 3/1 -180/45 135/45 1/1 6/1 -6/1 1/1 180/45 135/45 -180/45 135/45 6/1 5/1 -9/1 3/1 180/45 135/45 +2 1 4 3 +4 3 0 3 +4 3 1 6 +6 1 4 3 +4 3 6 5 +9 3 4 3 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test22.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test22.txt index 738953c643b9..e6ac95bc0179 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test22.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test22.txt @@ -5,25 +5,23 @@ 0 0 -1 -3 0 0 -3 4 5 -0/1 0/1 -1/1 -3/1 -0/1 0/1 -3/1 4/1 -0/1 0/1 1/1 1/1 -0/1 0/1 2/1 3/1 -0/1 0/1 9/1 8/1 +0 0 -1 -3 +0 0 -3 4 +0 0 1 1 +0 0 2 3 +0 0 9 8 6 --3/1 4/1 --1/1 -3/1 -0/1 0/1 -1/1 1/1 -2/1 3/1 -9/1 8/1 +-3 4 +-1 -3 +0 0 +1 1 +2 3 +9 8 0 -1 +# No. of faces: 1 5 -0/1 0/1 -1/1 -3/1 -0/1 0/1 -3/1 4/1 -0/1 0/1 1/1 1/1 -0/1 0/1 2/1 3/1 -0/1 0/1 9/1 8/1 - - +0 0 -1 -3 +0 0 -3 4 +0 0 1 1 +0 0 2 3 +0 0 9 8 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test23.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test23.txt index 8c692cc93a41..633acf5e4672 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test23.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test23.txt @@ -4,21 +4,20 @@ 0 0 4 0 0 0 2 -2 4 -1/1 2/1 0/1 0/1 -0/1 0/1 2/1 -2/1 -3/1 2/1 0/1 0/1 -0/1 0/1 4/1 0/1 +1 2 0 0 +0 0 2 -2 +3 2 0 0 +0 0 4 0 5 -0/1 0/1 -1/1 2/1 -2/1 -2/1 -3/1 2/1 -4/1 0/1 +0 0 +1 2 +2 -2 +3 2 +4 0 0 -1 +# No. of faces: 1 4 -1/1 2/1 0/1 0/1 -0/1 0/1 2/1 -2/1 -3/1 2/1 0/1 0/1 -0/1 0/1 4/1 0/1 - +1 2 0 0 +0 0 2 -2 +3 2 0 0 +0 0 4 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test24.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test24.txt index 601e8cfbf8a0..c1b674a8f00b 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test24.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test24.txt @@ -4,20 +4,20 @@ -2 -2 0 0 0 0 -2 -4 4 -0/1 0/1 -2/1 -4/1 --2/1 -2/1 0/1 0/1 --3/1 0/1 0/1 0/1 --3/1 2/1 0/1 0/1 +0 0 -2 -4 +-2 -2 0 0 +-3 0 0 0 +-3 2 0 0 5 --3/1 0/1 --3/1 2/1 --2/1 -4/1 --2/1 -2/1 -0/1 0/1 +-3 0 +-3 2 +-2 -4 +-2 -2 +0 0 0 -1 +# No. of faces: 1 4 -0/1 0/1 -2/1 -4/1 --2/1 -2/1 0/1 0/1 --3/1 0/1 0/1 0/1 --3/1 2/1 0/1 0/1 +0 0 -2 -4 +-2 -2 0 0 +-3 0 0 0 +-3 2 0 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test25.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test25.txt index 3b52e2164d7e..c679dad3f340 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test25.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test25.txt @@ -4,21 +4,20 @@ 6 0 3 3 0 6 3 3 4 -0/1 0/1 3/1 3/1 -0/1 6/1 3/1 3/1 -6/1 0/1 3/1 3/1 -3/1 3/1 6/1 6/1 +0 0 3 3 +0 6 3 3 +6 0 3 3 +3 3 6 6 5 -0/1 0/1 -0/1 6/1 -3/1 3/1 -6/1 0/1 -6/1 6/1 +0 0 +0 6 +3 3 +6 0 +6 6 0 -1 +# No. of faces: 1 4 -0/1 0/1 3/1 3/1 -0/1 6/1 3/1 3/1 -6/1 0/1 3/1 3/1 -3/1 3/1 6/1 6/1 - +0 0 3 3 +0 6 3 3 +6 0 3 3 +3 3 6 6 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test26.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test26.txt index fc3cfb4fc30c..2cfe803179b2 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test26.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test26.txt @@ -7,36 +7,36 @@ 0 1 4 1 1 4 3 6 8 -1/1 4/1 2/1 5/1 -0/1 5/1 2/1 5/1 -0/1 7/1 2/1 5/1 -2/1 5/1 3/1 6/1 -0/1 1/1 4/1 1/1 -2/1 4/1 4/1 2/1 -2/1 4/1 4/1 4/1 -2/1 7/1 4/1 9/1 +1 4 2 5 +0 5 2 5 +0 7 2 5 +2 5 3 6 +0 1 4 1 +2 4 4 2 +2 4 4 4 +2 7 4 9 12 -0/1 1/1 -0/1 5/1 -0/1 7/1 -1/1 4/1 -2/1 4/1 -2/1 5/1 -2/1 7/1 -3/1 6/1 -4/1 1/1 -4/1 2/1 -4/1 4/1 -4/1 9/1 -1 -2/1 5/1 +0 1 +0 5 +0 7 +1 4 +2 4 +2 5 +2 7 +3 6 +4 1 +4 2 +4 4 +4 9 1 +2 5 +# No. of faces: 1 8 -1/1 4/1 2/1 5/1 -0/1 5/1 2/1 5/1 -0/1 7/1 2/1 5/1 -2/1 5/1 3/1 6/1 -0/1 1/1 4/1 1/1 -2/1 4/1 4/1 2/1 -2/1 4/1 4/1 4/1 -2/1 7/1 4/1 9/1 +1 4 2 5 +0 5 2 5 +0 7 2 5 +2 5 3 6 +0 1 4 1 +2 4 4 2 +2 4 4 4 +2 7 4 9 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test27.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test27.txt index 1d25c06c8c44..09d93ba7d9b6 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test27.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test27.txt @@ -8,30 +8,30 @@ 1 3 2 2 1 1 2 2 8 -0/1 2/1 1/1 1/1 -0/1 2/1 1/1 3/1 -1/1 3/1 0/1 4/1 -1/1 5/1 0/1 4/1 -1/1 1/1 2/1 2/1 -1/1 3/1 2/1 2/1 -1/1 3/1 2/1 4/1 -1/1 5/1 2/1 4/1 +0 2 1 1 +0 2 1 3 +1 3 0 4 +1 5 0 4 +1 1 2 2 +1 3 2 2 +1 3 2 4 +1 5 2 4 7 -0/1 2/1 -0/1 4/1 -1/1 1/1 -1/1 3/1 -1/1 5/1 -2/1 2/1 -2/1 4/1 +0 2 +0 4 +1 1 +1 3 +1 5 +2 2 +2 4 0 -3 +# No. of faces: 3 8 -0/1 2/1 1/1 1/1 -0/1 2/1 1/1 3/1 -1/1 3/1 0/1 4/1 -1/1 5/1 0/1 4/1 -1/1 1/1 2/1 2/1 -1/1 3/1 2/1 2/1 -1/1 3/1 2/1 4/1 -1/1 5/1 2/1 4/1 +0 2 1 1 +0 2 1 3 +1 3 0 4 +1 5 0 4 +1 1 2 2 +1 3 2 2 +1 3 2 4 +1 5 2 4 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test28.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test28.txt index ed905e724c2d..d945734fca4f 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test28.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test28.txt @@ -10,35 +10,35 @@ 2 1 3 0 2 -1 3 0 10 -0/1 -1/1 -1/1 0/1 --1/1 0/1 0/1 1/1 -0/1 -1/1 1/1 0/1 -1/1 0/1 0/1 1/1 -0/1 1/1 1/1 2/1 -1/1 0/1 2/1 -1/1 -1/1 0/1 2/1 1/1 -2/1 1/1 1/1 2/1 -2/1 -1/1 3/1 0/1 -2/1 1/1 3/1 0/1 +0 -1 -1 0 +-1 0 0 1 +0 -1 1 0 +1 0 0 1 +0 1 1 2 +1 0 2 -1 +1 0 2 1 +2 1 1 2 +2 -1 3 0 +2 1 3 0 8 --1/1 0/1 -0/1 -1/1 -0/1 1/1 -1/1 0/1 -1/1 2/1 -2/1 -1/1 -2/1 1/1 -3/1 0/1 +-1 0 +0 -1 +0 1 +1 0 +1 2 +2 -1 +2 1 +3 0 0 -4 +# No. of faces: 4 10 -0/1 -1/1 -1/1 0/1 --1/1 0/1 0/1 1/1 -0/1 -1/1 1/1 0/1 -1/1 0/1 0/1 1/1 -0/1 1/1 1/1 2/1 -1/1 0/1 2/1 -1/1 -1/1 0/1 2/1 1/1 -2/1 1/1 1/1 2/1 -2/1 -1/1 3/1 0/1 -2/1 1/1 3/1 0/1 +0 -1 -1 0 +-1 0 0 1 +0 -1 1 0 +1 0 0 1 +0 1 1 2 +1 0 2 -1 +1 0 2 1 +2 1 1 2 +2 -1 3 0 +2 1 3 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test29.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test29.txt index 37aca71a59c4..44a64a0247f6 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test29.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test29.txt @@ -3,24 +3,24 @@ 0 0 4 4 2 2 5 2 5 -0/1 0/1 2/1 2/1 -0/1 4/1 2/1 2/1 -2/1 2/1 4/1 0/1 -2/1 2/1 4/1 4/1 -2/1 2/1 5/1 2/1 +0 0 2 2 +0 4 2 2 +2 2 4 0 +2 2 4 4 +2 2 5 2 6 -0/1 0/1 -0/1 4/1 -2/1 2/1 -4/1 0/1 -4/1 4/1 -5/1 2/1 -1 -2/1 2/1 +0 0 +0 4 +2 2 +4 0 +4 4 +5 2 1 +2 2 +# No. of faces: 1 5 -0/1 0/1 2/1 2/1 -0/1 4/1 2/1 2/1 -2/1 2/1 4/1 0/1 -2/1 2/1 4/1 4/1 -2/1 2/1 5/1 2/1 +0 0 2 2 +0 4 2 2 +2 2 4 0 +2 2 4 4 +2 2 5 2 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test30.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test30.txt index e6a784c9d3d5..93f5204f2623 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test30.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test30.txt @@ -2,21 +2,21 @@ 0 0 5 0 2 -2 2 3 4 -2/1 -2/1 50/25 0/25 -0/1 0/1 50/25 0/25 -50/25 0/25 2/1 3/1 -50/25 0/25 5/1 0/1 +2 -2 2 0 +0 0 2 0 +2 0 2 3 +2 0 5 0 5 -0/1 0/1 -2/1 -2/1 -50/25 0/25 -2/1 3/1 -5/1 0/1 -1 -50/25 0/25 +0 0 +2 -2 +2 0 +2 3 +5 0 1 +2 0 +# No. of faces: 1 4 -2/1 -2/1 50/25 0/25 -0/1 0/1 50/25 0/25 -50/25 0/25 2/1 3/1 -50/25 0/25 5/1 0/1 +2 -2 2 0 +0 0 2 0 +2 0 2 3 +2 0 5 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test31.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test31.txt index 3185f80ec7b8..42f4208cf9a4 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test31.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test31.txt @@ -3,31 +3,31 @@ 0 0 5 0 2 4 2 -2 7 -60/30 0/30 2/1 -2/1 -0/1 0/1 60/30 0/30 -24/12 24/12 60/30 0/30 -1/1 2/1 24/12 24/12 -2/1 4/1 24/12 24/12 -24/12 24/12 3/1 2/1 -60/30 0/30 5/1 0/1 +2 0 2 -2 +0 0 2 0 +2 2 2 0 +1 2 2 2 +2 4 2 2 +2 2 3 2 +2 0 5 0 8 -0/1 0/1 -1/1 2/1 -2/1 -2/1 -60/30 0/30 -24/12 24/12 -2/1 4/1 -3/1 2/1 -5/1 0/1 +0 0 +1 2 +2 -2 +2 0 +2 2 +2 4 +3 2 +5 0 2 -60/30 0/30 -24/12 24/12 -1 +2 0 +2 2 +# No. of faces: 1 7 -60/30 0/30 2/1 -2/1 -0/1 0/1 60/30 0/30 -24/12 24/12 60/30 0/30 -1/1 2/1 24/12 24/12 -2/1 4/1 24/12 24/12 -24/12 24/12 3/1 2/1 -60/30 0/30 5/1 0/1 +2 0 2 -2 +0 0 2 0 +2 2 2 0 +1 2 2 2 +2 4 2 2 +2 2 3 2 +2 0 5 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test32.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test32.txt index 830d83f2e599..822e3789c289 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test32.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test32.txt @@ -3,31 +3,31 @@ 0 0 5 0 2 -2 2 4 7 -2/1 -2/1 2/1 0/1 -0/1 0/1 2/1 0/1 -2/1 0/1 2/1 2/1 -1/1 2/1 2/1 2/1 -2/1 2/1 2/1 4/1 -2/1 2/1 3/1 2/1 -2/1 0/1 5/1 0/1 +2 -2 2 0 +0 0 2 0 +2 0 2 2 +1 2 2 2 +2 2 2 4 +2 2 3 2 +2 0 5 0 8 -0/1 0/1 -1/1 2/1 -2/1 -2/1 -60/30 0/30 -24/12 24/12 -2/1 4/1 -3/1 2/1 -5/1 0/1 +0 0 +1 2 +2 -2 +2 0 +2 2 +2 4 +3 2 +5 0 2 -60/30 0/30 -24/12 24/12 -1 +2 0 +2 2 +# No. of faces: 1 7 -2/1 -2/1 2/1 0/1 -0/1 0/1 2/1 0/1 -2/1 0/1 2/1 2/1 -1/1 2/1 2/1 2/1 -2/1 2/1 2/1 4/1 -2/1 2/1 3/1 2/1 -2/1 0/1 5/1 0/1 +2 -2 2 0 +0 0 2 0 +2 0 2 2 +1 2 2 2 +2 2 2 4 +2 2 3 2 +2 0 5 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test33.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test33.txt index 52b22ae49a6f..6db47eaf9eda 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test33.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test33.txt @@ -2,15 +2,15 @@ 1 5 1 2 0 0 3 2 2 -1/1 5/1 1/1 2/1 -0/1 0/1 3/1 2/1 +1 5 1 2 +0 0 3 2 4 -0/1 0/1 -1/1 2/1 -1/1 5/1 -3/1 2/1 +0 0 +1 2 +1 5 +3 2 0 -1 +# No. of faces: 1 2 -1/1 5/1 1/1 2/1 -0/1 0/1 3/1 2/1 +1 5 1 2 +0 0 3 2 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test34.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test34.txt index 9587d1b15dc6..47ced43d85b2 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test34.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test34.txt @@ -2,15 +2,15 @@ -1 2 1 4 0 0 0 2 2 -0/1 0/1 0/1 2/1 --1/1 2/1 1/1 4/1 +0 0 0 2 +-1 2 1 4 4 --1/1 2/1 -0/1 0/1 -0/1 2/1 -1/1 4/1 +-1 2 +0 0 +0 2 +1 4 0 -1 +# No. of faces: 1 2 -0/1 0/1 0/1 2/1 --1/1 2/1 1/1 4/1 +0 0 0 2 +-1 2 1 4 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test35.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test35.txt index 58b53d159913..c8a3dd025bc0 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test35.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test35.txt @@ -5,39 +5,39 @@ 1 3 3 3 1 0 3 0 9 -2/1 3/1 2/1 2/1 -1/1 3/1 2/1 3/1 -2/1 4/1 2/1 3/1 -0/1 4/1 2/1 4/1 -2/1 6/1 2/1 4/1 -1/1 0/1 3/1 0/1 -2/1 3/1 3/1 3/1 -1/1 7/1 3/1 7/1 -2/1 4/1 4/1 4/1 +2 3 2 2 +1 3 2 3 +2 4 2 3 +0 4 2 4 +2 6 2 4 +1 0 3 0 +2 3 3 3 +1 7 3 7 +2 4 4 4 12 -0/1 4/1 -1/1 0/1 -1/1 3/1 -1/1 7/1 -2/1 2/1 -16/8 24/8 -32/16 64/16 -2/1 6/1 -3/1 0/1 -3/1 3/1 -3/1 7/1 -4/1 4/1 +0 4 +1 0 +1 3 +1 7 +2 2 +2 3 +2 4 +2 6 +3 0 +3 3 +3 7 +4 4 2 -16/8 24/8 -32/16 64/16 -1 +2 3 +2 4 +# No. of faces: 1 9 -2/1 3/1 2/1 2/1 -1/1 3/1 2/1 3/1 -2/1 4/1 2/1 3/1 -0/1 4/1 2/1 4/1 -2/1 6/1 2/1 4/1 -1/1 0/1 3/1 0/1 -2/1 3/1 3/1 3/1 -1/1 7/1 3/1 7/1 -2/1 4/1 4/1 4/1 +2 3 2 2 +1 3 2 3 +2 4 2 3 +0 4 2 4 +2 6 2 4 +1 0 3 0 +2 3 3 3 +1 7 3 7 +2 4 4 4 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test36.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test36.txt index 2c4c5a96f292..03fbb7e16eaf 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test36.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test36.txt @@ -4,43 +4,43 @@ 0 4 4 2 1 2 4 5 11 -2/1 0/1 2/1 3/1 -1/1 2/1 2/1 3/1 -0/1 4/1 2/1 3/1 -2/1 3/1 2/1 6/1 -1/1 7/1 2/1 6/1 -2/1 6/1 2/1 9/1 -2/1 3/1 7/2 9/2 -2/1 6/1 7/2 9/2 -2/1 3/1 4/1 2/1 -7/2 9/2 4/1 5/1 -7/2 9/2 5/1 3/1 +2 0 2 3 +1 2 2 3 +0 4 2 3 +2 3 2 6 +1 7 2 6 +2 6 2 9 +2 3 7/2 9/2 +2 6 7/2 9/2 +2 3 4 2 +7/2 9/2 4 5 +7/2 9/2 5 3 11 -0/1 4/1 -1/1 2/1 -1/1 7/1 -2/1 0/1 -36/18 54/18 +0 4 +1 2 +1 7 +2 0 +2 3 72/36 216/36 -2/1 9/1 +2 9 84/24 108/24 -4/1 2/1 -4/1 5/1 -5/1 3/1 +4 2 +4 5 +5 3 3 -36/18 54/18 +2 3 72/36 216/36 84/24 108/24 -2 +# No. of faces: 2 11 -2/1 0/1 2/1 3/1 -1/1 2/1 2/1 3/1 -0/1 4/1 2/1 3/1 -2/1 3/1 2/1 6/1 -1/1 7/1 2/1 6/1 -2/1 6/1 2/1 9/1 -2/1 3/1 7/2 9/2 -2/1 6/1 7/2 9/2 -2/1 3/1 4/1 2/1 -7/2 9/2 4/1 5/1 -7/2 9/2 5/1 3/1 +2 0 2 3 +1 2 2 3 +0 4 2 3 +2 3 2 6 +1 7 2 6 +2 6 2 9 +2 3 7/2 9/2 +2 6 7/2 9/2 +2 3 4 2 +7/2 9/2 4 5 +7/2 9/2 5 3 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test37.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test37.txt index bf946526e36a..2c10412d83b6 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test37.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test37.txt @@ -5,51 +5,51 @@ -2 4 1 6 -1 6 -1 1 13 --1/1 6/5 -1/1 1/1 --3/1 2/1 -1/1 6/5 --1/1 14/3 -1/1 6/5 --2/1 4/1 -1/1 14/3 --1/1 6/1 -1/1 14/3 -0/1 0/1 0/1 4/5 --1/1 6/5 0/1 4/5 -0/1 4/5 0/1 3/1 -0/1 4/1 0/1 16/3 --1/1 14/3 0/1 16/3 -0/1 16/3 0/1 6/1 -0/1 16/3 1/1 6/1 -0/1 4/5 2/1 0/1 +-1 6/5 -1 1 +-3 2 -1 6/5 +-1 14/3 -1 6/5 +-2 4 -1 14/3 +-1 6 -1 14/3 +0 0 0 4/5 +-1 6/5 0 4/5 +0 4/5 0 3 +0 4 0 16/3 +-1 14/3 0 16/3 +0 16/3 0 6 +0 16/3 1 6 +0 4/5 2 0 14 --3/1 2/1 --2/1 4/1 --1/1 1/1 +-3 2 +-2 4 +-1 1 -25/25 30/25 --15/15 70/15 --1/1 6/1 -0/1 0/1 -0/15 12/15 -0/1 3/1 -0/1 4/1 -0/6 32/6 -0/1 6/1 -1/1 6/1 -2/1 0/1 +-1 70/15 +-1 6 +0 0 +0 12/15 +0 3 +0 4 +0 32/6 +0 6 +1 6 +2 0 4 -25/25 30/25 --15/15 70/15 -0/15 12/15 -0/6 32/6 -1 +-1 70/15 +0 12/15 +0 32/6 +# No. of faces: 1 13 --1/1 6/5 -1/1 1/1 --3/1 2/1 -1/1 6/5 --1/1 14/3 -1/1 6/5 --2/1 4/1 -1/1 14/3 --1/1 6/1 -1/1 14/3 -0/1 0/1 0/1 4/5 --1/1 6/5 0/1 4/5 -0/1 4/5 0/1 3/1 -0/1 4/1 0/1 16/3 --1/1 14/3 0/1 16/3 -0/1 16/3 0/1 6/1 -0/1 16/3 1/1 6/1 -0/1 4/5 2/1 0/1 +-1 6/5 -1 1 +-3 2 -1 6/5 +-1 14/3 -1 6/5 +-2 4 -1 14/3 +-1 6 -1 14/3 +0 0 0 4/5 +-1 6/5 0 4/5 +0 4/5 0 3 +0 4 0 16/3 +-1 14/3 0 16/3 +0 16/3 0 6 +0 16/3 1 6 +0 4/5 2 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test40.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test40.txt index beea62f7afb4..2cb778d38b75 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test40.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test40.txt @@ -2,18 +2,18 @@ 0 0 0 6 0 3 3 3 3 -0/1 0/1 0/1 3/1 -0/1 3/1 0/1 6/1 -0/1 3/1 3/1 3/1 +0 0 0 3 +0 3 0 6 +0 3 3 3 4 -0/1 0/1 -0/1 3/1 -0/1 6/1 -3/1 3/1 -1 -0/1 3/1 +0 0 +0 3 +0 6 +3 3 1 +0 3 +# No. of faces: 1 3 -0/1 0/1 0/1 3/1 -0/1 3/1 0/1 6/1 -0/1 3/1 3/1 3/1 +0 0 0 3 +0 3 0 6 +0 3 3 3 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test41.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test41.txt index 3651988bd29b..f9cefcc2116e 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test41.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test41.txt @@ -2,18 +2,18 @@ -3 3 0 3 0 0 0 6 3 -0/1 0/1 0/1 3/1 --3/1 3/1 0/1 3/1 -0/1 3/1 0/1 6/1 +0 0 0 3 +-3 3 0 3 +0 3 0 6 4 --3/1 3/1 -0/1 0/1 -0/1 3/1 -0/1 6/1 -1 -0/1 3/1 +-3 3 +0 0 +0 3 +0 6 1 +0 3 +# No. of faces: 1 3 -0/1 0/1 0/1 3/1 --3/1 3/1 0/1 3/1 -0/1 3/1 0/1 6/1 +0 0 0 3 +-3 3 0 3 +0 3 0 6 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test42.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test42.txt index b83c0b96d1c3..4cfeb604b7fe 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test42.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test42.txt @@ -3,21 +3,21 @@ -2 2 0 2 0 2 2 2 4 -0/1 0/1 0/1 2/1 --2/1 2/1 0/1 2/1 -0/1 2/1 0/1 4/1 -0/1 2/1 2/1 2/1 +0 0 0 2 +-2 2 0 2 +0 2 0 4 +0 2 2 2 5 --2/1 2/1 -0/1 0/1 -0/1 2/1 -0/1 4/1 -2/1 2/1 -1 -0/1 2/1 +-2 2 +0 0 +0 2 +0 4 +2 2 1 +0 2 +# No. of faces: 1 4 -0/1 0/1 0/1 2/1 --2/1 2/1 0/1 2/1 -0/1 2/1 0/1 4/1 -0/1 2/1 2/1 2/1 +0 0 0 2 +-2 2 0 2 +0 2 0 4 +0 2 2 2 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test43.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test43.txt index a78d9c4bdea3..90afe463752b 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test43.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test43.txt @@ -2,14 +2,14 @@ 0 5 4 5 4 5 4 1 2 -4/1 5/1 4/1 1/1 -0/1 5/1 4/1 5/1 +4 5 4 1 +0 5 4 5 3 -0/1 5/1 -4/1 1/1 -4/1 5/1 +0 5 +4 1 +4 5 0 -1 +# No. of faces: 1 2 -4/1 5/1 4/1 1/1 -0/1 5/1 4/1 5/1 +4 5 4 1 +0 5 4 5 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test44.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test44.txt index 0aff3e7b1810..19a28bae19dc 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test44.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test44.txt @@ -4,20 +4,19 @@ 0 0 4 0 0 4 0 0 4 -0/1 4/1 0/1 0/1 -0/1 0/1 4/1 0/1 -4/1 4/1 4/1 0/1 -0/1 4/1 4/1 4/1 +0 4 0 0 +0 0 4 0 +4 4 4 0 +0 4 4 4 4 -0/1 0/1 -0/1 4/1 -4/1 0/1 -4/1 4/1 +0 0 +0 4 +4 0 +4 4 0 -2 +# No. of faces: 2 4 -0/1 4/1 0/1 0/1 -0/1 0/1 4/1 0/1 -4/1 4/1 4/1 0/1 -0/1 4/1 4/1 4/1 - +0 4 0 0 +0 0 4 0 +4 4 4 0 +0 4 4 4 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test45.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test45.txt index 431f41756eb6..24188d25fa0f 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test45.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test45.txt @@ -2,14 +2,14 @@ 0 0 4 0 0 4 0 0 2 -0/1 4/1 0/1 0/1 -0/1 0/1 4/1 0/1 +0 4 0 0 +0 0 4 0 3 -0/1 0/1 -0/1 4/1 -4/1 0/1 +0 0 +0 4 +4 0 0 -1 +# No. of faces: 1 2 -0/1 4/1 0/1 0/1 -0/1 0/1 4/1 0/1 +0 4 0 0 +0 0 4 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test46.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test46.txt index ed0e785f55ba..512151f3428d 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test46.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test46.txt @@ -3,19 +3,19 @@ 2 5 2 2 2 1 4 1 3 -2/1 5/1 2/1 2/1 -0/1 6/1 2/1 6/1 -2/1 1/1 4/1 1/1 +2 5 2 2 +0 6 2 6 +2 1 4 1 6 -0/1 6/1 -2/1 1/1 -2/1 2/1 -2/1 5/1 -2/1 6/1 -4/1 1/1 +0 6 +2 1 +2 2 +2 5 +2 6 +4 1 0 -1 +# No. of faces: 1 3 -2/1 5/1 2/1 2/1 -0/1 6/1 2/1 6/1 -2/1 1/1 4/1 1/1 +2 5 2 2 +0 6 2 6 +2 1 4 1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test47.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test47.txt index 5861e7d3583d..1624ab365376 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test47.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test47.txt @@ -2,18 +2,18 @@ 2 0 2 3 4 0 0 0 3 -2/1 0/1 0/1 0/1 -2/1 0/1 2/1 3/1 -4/1 0/1 2/1 0/1 +2 0 0 0 +2 0 2 3 +4 0 2 0 4 -0/1 0/1 -2/1 0/1 -2/1 3/1 -4/1 0/1 -1 -2/1 0/1 +0 0 +2 0 +2 3 +4 0 1 +2 0 +# No. of faces: 1 3 -2/1 0/1 0/1 0/1 -2/1 0/1 2/1 3/1 -4/1 0/1 2/1 0/1 +2 0 0 0 +2 0 2 3 +4 0 2 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test48.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test48.txt index 8546ccf6f28b..9884d9b633fe 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test48.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test48.txt @@ -4,29 +4,29 @@ 7 3 12 3 9 3 9 0 6 -0/1 0/1 2/1 0/1 -2/1 3/1 2/1 0/1 -2/1 0/1 5/1 0/1 -9/1 3/1 9/1 0/1 -7/1 3/1 9/1 3/1 -9/1 3/1 12/1 3/1 +0 0 2 0 +2 3 2 0 +2 0 5 0 +9 3 9 0 +7 3 9 3 +9 3 12 3 8 -0/1 0/1 -2/1 0/1 -2/1 3/1 -5/1 0/1 -7/1 3/1 -9/1 0/1 -9/1 3/1 -12/1 3/1 +0 0 +2 0 +2 3 +5 0 +7 3 +9 0 +9 3 +12 3 2 -2/1 0/1 -9/1 3/1 -1 +2 0 +9 3 +# No. of faces: 1 6 -0/1 0/1 2/1 0/1 -2/1 3/1 2/1 0/1 -2/1 0/1 5/1 0/1 -9/1 3/1 9/1 0/1 -7/1 3/1 9/1 3/1 -9/1 3/1 12/1 3/1 +0 0 2 0 +2 3 2 0 +2 0 5 0 +9 3 9 0 +7 3 9 3 +9 3 12 3 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test49.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test49.txt index 38fdef6d37bf..937d78e447e4 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test49.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test49.txt @@ -2,14 +2,14 @@ 0 0 4 0 4 0 4 4 2 -0/1 0/1 4/1 0/1 -4/1 0/1 4/1 4/1 +0 0 4 0 +4 0 4 4 3 -0/1 0/1 -4/1 0/1 -4/1 4/1 +0 0 +4 0 +4 4 0 -1 +# No. of faces: 1 2 -0/1 0/1 4/1 0/1 -4/1 0/1 4/1 4/1 +0 0 4 0 +4 0 4 4 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test50.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test50.txt index 47db121f373e..11d3fd8a787f 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test50.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test50.txt @@ -5,27 +5,27 @@ 8 6 9 7 8 6 9 5 6 -5/1 5/1 8/1 5/1 -8/1 6/1 8/1 5/1 -8/1 7/1 8/1 6/1 -4/1 7/1 8/1 7/1 -8/1 6/1 9/1 5/1 -8/1 6/1 9/1 7/1 +5 5 8 5 +8 6 8 5 +8 7 8 6 +4 7 8 7 +8 6 9 5 +8 6 9 7 7 -4/1 7/1 -5/1 5/1 -8/1 5/1 -8/1 6/1 -8/1 7/1 -9/1 5/1 -9/1 7/1 -1 -8/1 6/1 +4 7 +5 5 +8 5 +8 6 +8 7 +9 5 +9 7 1 +8 6 +# No. of faces: 1 6 -5/1 5/1 8/1 5/1 -8/1 6/1 8/1 5/1 -8/1 7/1 8/1 6/1 -4/1 7/1 8/1 7/1 -8/1 6/1 9/1 5/1 -8/1 6/1 9/1 7/1 +5 5 8 5 +8 6 8 5 +8 7 8 6 +4 7 8 7 +8 6 9 5 +8 6 9 7 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test51.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test51.txt index cf9cd7243ce9..0acf50538185 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test51.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test51.txt @@ -16,103 +16,103 @@ 2 0 6 4 2 10 6 8 30 -2/1 3/1 2/1 0/1 -0/1 1/1 2/1 3/1 -2/1 4/1 2/1 3/1 -2/1 4/1 0/1 3/1 -0/1 6/1 2/1 6/1 -2/1 6/1 2/1 8/1 -1/1 7/1 2/1 8/1 -0/1 8/1 2/1 8/1 -2/1 8/1 2/1 10/1 -2/1 3/1 3/1 4/1 -2/1 8/1 10/3 28/3 -2/1 10/1 10/3 28/3 -2/1 3/1 4/1 3/1 -10/3 28/3 4/1 10/1 -2/1 0/1 6/1 4/1 -6/1 5/1 6/1 4/1 -6/1 5/1 5/1 5/1 -6/1 6/1 6/1 5/1 -6/1 6/1 2/1 4/1 -2/1 6/1 6/1 6/1 -6/1 7/1 6/1 6/1 -4/1 7/1 6/1 7/1 -6/1 8/1 6/1 7/1 -10/3 28/3 6/1 8/1 -8/1 5/1 6/1 5/1 -8/1 6/1 8/1 5/1 -8/1 7/1 8/1 6/1 -6/1 7/1 8/1 7/1 -9/1 5/1 8/1 6/1 -9/1 7/1 8/1 6/1 +2 3 2 0 +0 1 2 3 +2 4 2 3 +2 4 0 3 +0 6 2 6 +2 6 2 8 +1 7 2 8 +0 8 2 8 +2 8 2 10 +2 3 3 4 +2 8 10/3 28/3 +2 10 10/3 28/3 +2 3 4 3 +10/3 28/3 4 10 +2 0 6 4 +6 5 6 4 +6 5 5 5 +6 6 6 5 +6 6 2 4 +2 6 6 6 +6 7 6 6 +4 7 6 7 +6 8 6 7 +10/3 28/3 6 8 +8 5 6 5 +8 6 8 5 +8 7 8 6 +6 7 8 7 +9 5 8 6 +9 7 8 6 27 -0/1 1/1 -0/1 3/1 -0/1 6/1 -0/1 8/1 -1/1 7/1 -2/1 0/1 -2/1 3/1 -2/1 4/1 -2/1 6/1 -2/1 8/1 -2/1 10/1 -3/1 4/1 +0 1 +0 3 +0 6 +0 8 +1 7 +2 0 +2 3 +2 4 +2 6 +2 8 +2 10 +3 4 60/18 168/18 -4/1 3/1 -4/1 7/1 -4/1 10/1 -5/1 5/1 -6/1 4/1 -72/12 60/12 -6/1 6/1 -96/16 112/16 -6/1 8/1 -8/1 5/1 -8/1 6/1 -8/1 7/1 -9/1 5/1 -9/1 7/1 +4 3 +4 7 +4 10 +5 5 +6 4 +6 5 +6 6 +6 7 +6 8 +8 5 +8 6 +8 7 +9 5 +9 7 9 -2/1 3/1 -2/1 4/1 -2/1 6/1 -2/1 8/1 +2 3 +2 4 +2 6 +2 8 60/18 168/18 -72/12 60/12 -6/1 6/1 -96/16 112/16 -8/1 6/1 -5 +6 5 +6 6 +6 7 +8 6 +# No. of faces: 5 30 -2/1 3/1 2/1 0/1 -0/1 1/1 2/1 3/1 -2/1 4/1 2/1 3/1 -2/1 4/1 0/1 3/1 -0/1 6/1 2/1 6/1 -2/1 6/1 2/1 8/1 -1/1 7/1 2/1 8/1 -0/1 8/1 2/1 8/1 -2/1 8/1 2/1 10/1 -2/1 3/1 3/1 4/1 -2/1 8/1 10/3 28/3 -2/1 10/1 10/3 28/3 -2/1 3/1 4/1 3/1 -10/3 28/3 4/1 10/1 -2/1 0/1 6/1 4/1 -6/1 5/1 6/1 4/1 -6/1 5/1 5/1 5/1 -6/1 6/1 6/1 5/1 -6/1 6/1 2/1 4/1 -2/1 6/1 6/1 6/1 -6/1 7/1 6/1 6/1 -4/1 7/1 6/1 7/1 -6/1 8/1 6/1 7/1 -10/3 28/3 6/1 8/1 -8/1 5/1 6/1 5/1 -8/1 6/1 8/1 5/1 -8/1 7/1 8/1 6/1 -6/1 7/1 8/1 7/1 -9/1 5/1 8/1 6/1 -9/1 7/1 8/1 6/1 +2 3 2 0 +0 1 2 3 +2 4 2 3 +2 4 0 3 +0 6 2 6 +2 6 2 8 +1 7 2 8 +0 8 2 8 +2 8 2 10 +2 3 3 4 +2 8 10/3 28/3 +2 10 10/3 28/3 +2 3 4 3 +10/3 28/3 4 10 +2 0 6 4 +6 5 6 4 +6 5 5 5 +6 6 6 5 +6 6 2 4 +2 6 6 6 +6 7 6 6 +4 7 6 7 +6 8 6 7 +10/3 28/3 6 8 +8 5 6 5 +8 6 8 5 +8 7 8 6 +6 7 8 7 +9 5 8 6 +9 7 8 6 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test52.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test52.txt index 519eff3c8c95..e54693b507ca 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test52.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test52.txt @@ -3,27 +3,27 @@ 0 0 4 4 2 5 2 -1 6 -2/1 2/1 2/1 -1/1 -0/1 0/1 2/1 2/1 -0/1 4/1 2/1 2/1 -2/1 5/1 2/1 2/1 -2/1 2/1 4/1 0/1 -2/1 2/1 4/1 4/1 +2 2 2 -1 +0 0 2 2 +0 4 2 2 +2 5 2 2 +2 2 4 0 +2 2 4 4 7 -0/1 0/1 -0/1 4/1 -2/1 -1/1 +0 0 +0 4 +2 -1 64/32 64/32 -2/1 5/1 -4/1 0/1 -4/1 4/1 +2 5 +4 0 +4 4 1 64/32 64/32 -1 +# No. of faces: 1 6 -2/1 2/1 2/1 -1/1 -0/1 0/1 2/1 2/1 -0/1 4/1 2/1 2/1 -2/1 5/1 2/1 2/1 -2/1 2/1 4/1 0/1 -2/1 2/1 4/1 4/1 +2 2 2 -1 +0 0 2 2 +0 4 2 2 +2 5 2 2 +2 2 4 0 +2 2 4 4 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test53.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test53.txt index 79d174935580..03bc28fe6cab 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test53.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test53.txt @@ -3,18 +3,17 @@ 0 3 0 2 0 2 0 0 3 -0/1 2/1 0/1 0/1 -0/1 3/1 0/1 2/1 -0/1 5/1 0/1 3/1 +0 2 0 0 +0 3 0 2 +0 5 0 3 4 -0/1 0/1 -0/1 2/1 -0/1 3/1 -0/1 5/1 +0 0 +0 2 +0 3 +0 5 0 -1 +# No. of faces: 1 3 -0/1 2/1 0/1 0/1 -0/1 3/1 0/1 2/1 -0/1 5/1 0/1 3/1 - +0 2 0 0 +0 3 0 2 +0 5 0 3 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test54.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test54.txt index ce10a30cb75c..75d469762858 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test54.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test54.txt @@ -3,21 +3,21 @@ 8 6 9 7 8 6 9 5 4 -8/1 6/1 8/1 5/1 -8/1 7/1 8/1 6/1 -8/1 6/1 9/1 5/1 -8/1 6/1 9/1 7/1 +8 6 8 5 +8 7 8 6 +8 6 9 5 +8 6 9 7 5 -8/1 5/1 -8/1 6/1 -8/1 7/1 -9/1 5/1 -9/1 7/1 -1 -8/1 6/1 +8 5 +8 6 +8 7 +9 5 +9 7 1 +8 6 +# No. of faces: 1 4 -8/1 6/1 8/1 5/1 -8/1 7/1 8/1 6/1 -8/1 6/1 9/1 5/1 -8/1 6/1 9/1 7/1 +8 6 8 5 +8 7 8 6 +8 6 9 5 +8 6 9 7 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test55.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test55.txt index 1065362fc19d..f2f078a93299 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test55.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test55.txt @@ -3,26 +3,25 @@ 0 1 2 1 2 0 2 2 5 -0/1 0/1 0/1 1/1 -0/1 1/1 0/1 2/1 -2/1 0/1 2/1 1/1 -0/1 1/1 2/1 1/1 -2/1 1/1 2/1 2/1 +0 0 0 1 +0 1 0 2 +2 0 2 1 +0 1 2 1 +2 1 2 2 6 -0/1 0/1 -0/1 1/1 -0/1 2/1 -2/1 0/1 -2/1 1/1 -2/1 2/1 +0 0 +0 1 +0 2 +2 0 +2 1 +2 2 2 -0/1 1/1 -2/1 1/1 -1 +0 1 +2 1 +# No. of faces: 1 5 -0/1 0/1 0/1 1/1 -0/1 1/1 0/1 2/1 -2/1 0/1 2/1 1/1 -0/1 1/1 2/1 1/1 -2/1 1/1 2/1 2/1 - +0 0 0 1 +0 1 0 2 +2 0 2 1 +0 1 2 1 +2 1 2 2 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test56.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test56.txt index adc296648a43..bac5d28e69c2 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test56.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test56.txt @@ -3,25 +3,24 @@ 0 1 6 5 3 3 7 3 5 -3/1 0/1 3/1 3/1 -0/1 1/1 3/1 3/1 -3/1 3/1 3/1 6/1 -3/1 3/1 6/1 5/1 -3/1 3/1 7/1 3/1 +3 0 3 3 +0 1 3 3 +3 3 3 6 +3 3 6 5 +3 3 7 3 6 -0/1 1/1 -3/1 0/1 -3/1 3/1 -3/1 6/1 -6/1 5/1 -7/1 3/1 -1 -3/1 3/1 +0 1 +3 0 +3 3 +3 6 +6 5 +7 3 1 +3 3 +# No. of faces: 1 5 -3/1 0/1 3/1 3/1 -0/1 1/1 3/1 3/1 -3/1 3/1 3/1 6/1 -3/1 3/1 6/1 5/1 -3/1 3/1 7/1 3/1 - +3 0 3 3 +0 1 3 3 +3 3 3 6 +3 3 6 5 +3 3 7 3 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test60.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test60.txt index 92beb4090a24..580ad8751274 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test60.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test60.txt @@ -2,21 +2,20 @@ 0 0 4 0 3 0 7 0 3 -0/1 0/1 3/1 0/1 -3/1 0/1 4/1 0/1 -4/1 0/1 7/1 0/1 +0 0 3 0 +3 0 4 0 +4 0 7 0 4 -0/1 0/1 -3/1 0/1 -4/1 0/1 -7/1 0/1 +0 0 +3 0 +4 0 +7 0 2 -3/1 0/1 -4/1 0/1 -1 +3 0 +4 0 +# No. of faces: 1 4 -0/1 0/1 3/1 0/1 -3/1 0/1 4/1 0/1 -3/1 0/1 4/1 0/1 -4/1 0/1 7/1 0/1 - +0 0 3 0 +3 0 4 0 +3 0 4 0 +4 0 7 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test61.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test61.txt index 6db6035cbc7f..56f8052dbd5c 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test61.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test61.txt @@ -3,31 +3,31 @@ 0 0 4 0 2 0 8 0 5 -0/1 0/1 2/1 0/1 -2/1 0/1 3/1 0/1 -3/1 0/1 4/1 0/1 -4/1 0/1 6/1 0/1 -6/1 0/1 8/1 0/1 +0 0 2 0 +2 0 3 0 +3 0 4 0 +4 0 6 0 +6 0 8 0 6 -0/1 0/1 -2/1 0/1 -3/1 0/1 -4/1 0/1 -6/1 0/1 -8/1 0/1 +0 0 +2 0 +3 0 +4 0 +6 0 +8 0 4 -2/1 0/1 -3/1 0/1 -4/1 0/1 -6/1 0/1 -1 +2 0 +3 0 +4 0 +6 0 +# No. of faces: 1 9 -0/1 0/1 2/1 0/1 -2/1 0/1 3/1 0/1 -2/1 0/1 3/1 0/1 -3/1 0/1 4/1 0/1 -3/1 0/1 4/1 0/1 -3/1 0/1 4/1 0/1 -4/1 0/1 6/1 0/1 -4/1 0/1 6/1 0/1 -6/1 0/1 8/1 0/1 \ No newline at end of file +0 0 2 0 +2 0 3 0 +2 0 3 0 +3 0 4 0 +3 0 4 0 +3 0 4 0 +4 0 6 0 +4 0 6 0 +6 0 8 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test62.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test62.txt index ee6c49c399e5..a975379f310d 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test62.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test62.txt @@ -2,14 +2,12 @@ 0 0 3 0 0 0 3 0 1 -0/1 0/1 3/1 0/1 +0 0 3 0 2 -0/1 0/1 -3/1 0/1 +0 0 +3 0 0 -1 +# No. of faces: 1 2 -0/1 0/1 3/1 0/1 -0/1 0/1 3/1 0/1 - - +0 0 3 0 +0 0 3 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test63.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test63.txt index 8923f049d153..0bf64d49d7fe 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test63.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test63.txt @@ -4,22 +4,22 @@ 0 0 5 0 2 0 3 0 3 -0/1 0/1 2/1 0/1 -2/1 0/1 3/1 0/1 -3/1 0/1 5/1 0/1 +0 0 2 0 +2 0 3 0 +3 0 5 0 4 -0/1 0/1 -2/1 0/1 -3/1 0/1 -5/1 0/1 +0 0 +2 0 +3 0 +5 0 2 -2/1 0/1 -3/1 0/1 -1 +2 0 +3 0 +# No. of faces: 1 6 -0/1 0/1 2/1 0/1 -0/1 0/1 2/1 0/1 -2/1 0/1 3/1 0/1 -2/1 0/1 3/1 0/1 -3/1 0/1 5/1 0/1 -3/1 0/1 5/1 0/1 +0 0 2 0 +0 0 2 0 +2 0 3 0 +2 0 3 0 +3 0 5 0 +3 0 5 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test64.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test64.txt index f2825be57f25..b27adefbb3b2 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test64.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test64.txt @@ -3,13 +3,13 @@ 0 0 6 6 6 6 0 0 1 -0/1 0/1 6/1 6/1 +0 0 6 6 2 -0/1 0/1 -6/1 6/1 +0 0 +6 6 0 -1 +# No. of faces: 1 3 -0/1 0/1 6/1 6/1 -0/1 0/1 6/1 6/1 -6/1 6/1 0/1 0/1 +0 0 6 6 +0 0 6 6 +6 6 0 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test65.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test65.txt index e83cce072aee..d1ebcea2dc15 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test65.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test65.txt @@ -3,23 +3,23 @@ 0 0 4 4 0 4 4 0 4 -0/1 0/1 64/32 64/32 -0/1 4/1 64/32 64/32 -64/32 64/32 4/1 0/1 -64/32 64/32 4/1 4/1 +0 0 64/32 64/32 +0 4 64/32 64/32 +64/32 64/32 4 0 +64/32 64/32 4 4 5 -0/1 0/1 -0/1 4/1 +0 0 +0 4 64/32 64/32 -4/1 0/1 -4/1 4/1 +4 0 +4 4 1 64/32 64/32 -1 +# No. of faces: 1 6 -0/1 0/1 64/32 64/32 -0/1 0/1 64/32 64/32 -0/1 4/1 64/32 64/32 -64/32 64/32 4/1 0/1 -64/32 64/32 4/1 4/1 -64/32 64/32 4/1 4/1 +0 0 64/32 64/32 +0 0 64/32 64/32 +0 4 64/32 64/32 +64/32 64/32 4 0 +64/32 64/32 4 4 +64/32 64/32 4 4 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test66.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test66.txt index 7725cef46c2a..420a030dada6 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test66.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test66.txt @@ -4,25 +4,25 @@ 0 4 4 0 0 4 4 0 4 -0/1 0/1 64/32 64/32 -0/1 4/1 64/32 64/32 -64/32 64/32 4/1 0/1 -64/32 64/32 4/1 4/1 +0 0 64/32 64/32 +0 4 64/32 64/32 +64/32 64/32 4 0 +64/32 64/32 4 4 5 -0/1 0/1 -0/1 4/1 +0 0 +0 4 64/32 64/32 -4/1 0/1 -4/1 4/1 +4 0 +4 4 1 64/32 64/32 -1 +# No. of faces: 1 8 -0/1 0/1 64/32 64/32 -0/1 0/1 64/32 64/32 -0/1 4/1 64/32 64/32 -0/1 4/1 64/32 64/32 -64/32 64/32 4/1 0/1 -64/32 64/32 4/1 0/1 -64/32 64/32 4/1 4/1 -64/32 64/32 4/1 4/1 +0 0 64/32 64/32 +0 0 64/32 64/32 +0 4 64/32 64/32 +0 4 64/32 64/32 +64/32 64/32 4 0 +64/32 64/32 4 0 +64/32 64/32 4 4 +64/32 64/32 4 4 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test67.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test67.txt index b380b5e7cbda..cdd01dcd1193 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test67.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test67.txt @@ -5,32 +5,31 @@ 0 4 4 0 -1 2 5 2 6 -0/1 0/1 48/24 48/24 --1/1 2/1 48/24 48/24 -0/1 4/1 48/24 48/24 -48/24 48/24 4/1 0/1 -48/24 48/24 4/1 4/1 -48/24 48/24 5/1 2/1 +0 0 48/24 48/24 +-1 2 48/24 48/24 +0 4 48/24 48/24 +48/24 48/24 4 0 +48/24 48/24 4 4 +48/24 48/24 5 2 7 --1/1 2/1 -0/1 0/1 -0/1 4/1 +-1 2 +0 0 +0 4 48/24 48/24 -4/1 0/1 -4/1 4/1 -5/1 2/1 +4 0 +4 4 +5 2 1 48/24 48/24 -1 +# No. of faces: 1 10 -0/1 0/1 48/24 48/24 -0/1 0/1 48/24 48/24 --1/1 2/1 48/24 48/24 -0/1 4/1 48/24 48/24 -0/1 4/1 48/24 48/24 -48/24 48/24 4/1 0/1 -48/24 48/24 4/1 0/1 -48/24 48/24 4/1 4/1 -48/24 48/24 4/1 4/1 -48/24 48/24 5/1 2/1 - +0 0 48/24 48/24 +0 0 48/24 48/24 +-1 2 48/24 48/24 +0 4 48/24 48/24 +0 4 48/24 48/24 +48/24 48/24 4 0 +48/24 48/24 4 0 +48/24 48/24 4 4 +48/24 48/24 4 4 +48/24 48/24 5 2 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test68.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test68.txt index 54feabc43bac..4d739e20e788 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test68.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test68.txt @@ -6,43 +6,43 @@ -1 2 5 2 1 1 3 3 8 -0/1 0/1 1/1 1/1 -1/1 1/1 48/24 48/24 --1/1 2/1 48/24 48/24 -0/1 4/1 48/24 48/24 -48/24 48/24 3/1 3/1 -48/24 48/24 4/1 0/1 -3/1 3/1 4/1 4/1 -48/24 48/24 5/1 2/1 +0 0 1 1 +1 1 48/24 48/24 +-1 2 48/24 48/24 +0 4 48/24 48/24 +48/24 48/24 3 3 +48/24 48/24 4 0 +3 3 4 4 +48/24 48/24 5 2 9 --1/1 2/1 -0/1 0/1 -0/1 4/1 -1/1 1/1 +-1 2 +0 0 +0 4 +1 1 48/24 48/24 -3/1 3/1 -4/1 0/1 -4/1 4/1 -5/1 2/1 +3 3 +4 0 +4 4 +5 2 3 -1/1 1/1 +1 1 48/24 48/24 -3/1 3/1 -1 +3 3 +# No. of faces: 1 16 -0/1 0/1 1/1 1/1 -0/1 0/1 1/1 1/1 -1/1 1/1 48/24 48/24 -1/1 1/1 48/24 48/24 -1/1 1/1 48/24 48/24 --1/1 2/1 48/24 48/24 -0/1 4/1 48/24 48/24 -0/1 4/1 48/24 48/24 -48/24 48/24 3/1 3/1 -48/24 48/24 3/1 3/1 -48/24 48/24 3/1 3/1 -48/24 48/24 4/1 0/1 -48/24 48/24 4/1 0/1 -3/1 3/1 4/1 4/1 -3/1 3/1 4/1 4/1 -48/24 48/24 5/1 2/1 +0 0 1 1 +0 0 1 1 +1 1 48/24 48/24 +1 1 48/24 48/24 +1 1 48/24 48/24 +-1 2 48/24 48/24 +0 4 48/24 48/24 +0 4 48/24 48/24 +48/24 48/24 3 3 +48/24 48/24 3 3 +48/24 48/24 3 3 +48/24 48/24 4 0 +48/24 48/24 4 0 +3 3 4 4 +3 3 4 4 +48/24 48/24 5 2 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test69.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test69.txt index cc0683ad7ad8..c353837bfed8 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test69.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test69.txt @@ -8,31 +8,30 @@ 1 1 2 1 2 1 1 1 7 -0/1 0/1 1/1 1/1 -1/1 1/1 0/1 1/1 -1/1 1/1 0/1 2/1 -1/1 1/1 2/1 1/1 -3/1 0/1 2/1 1/1 -2/1 1/1 3/1 1/1 -3/1 2/1 2/1 1/1 +0 0 1 1 +1 1 0 1 +1 1 0 2 +1 1 2 1 +3 0 2 1 +2 1 3 1 +3 2 2 1 8 -0/1 0/1 -0/1 1/1 -0/1 2/1 -1/1 1/1 -2/1 1/1 -3/1 0/1 -3/1 1/1 -3/1 2/1 +0 0 +0 1 +0 2 +1 1 +2 1 +3 0 +3 1 +3 2 0 -1 +# No. of faces: 1 8 -0/1 0/1 1/1 1/1 -1/1 1/1 0/1 1/1 -1/1 1/1 0/1 2/1 -1/1 1/1 2/1 1/1 -2/1 1/1 1/1 1/1 -3/1 0/1 2/1 1/1 -2/1 1/1 3/1 1/1 -3/1 2/1 2/1 1/1 - +0 0 1 1 +1 1 0 1 +1 1 0 2 +1 1 2 1 +2 1 1 1 +3 0 2 1 +2 1 3 1 +3 2 2 1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test70.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test70.txt index c6b68c4163b5..cfc1576cd41e 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test70.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test70.txt @@ -5,37 +5,37 @@ 1 0 4 0 0 0 3 0 6 -0/1 0/1 1/1 0/1 -1/1 0/1 2/1 0/1 -2/1 0/1 3/1 0/1 -3/1 0/1 4/1 0/1 -4/1 0/1 5/1 0/1 -5/1 0/1 7/1 0/1 +0 0 1 0 +1 0 2 0 +2 0 3 0 +3 0 4 0 +4 0 5 0 +5 0 7 0 7 -0/1 0/1 -1/1 0/1 -2/1 0/1 -3/1 0/1 -4/1 0/1 -5/1 0/1 -7/1 0/1 +0 0 +1 0 +2 0 +3 0 +4 0 +5 0 +7 0 5 -1/1 0/1 -2/1 0/1 -3/1 0/1 -4/1 0/1 -5/1 0/1 -1 +1 0 +2 0 +3 0 +4 0 +5 0 +# No. of faces: 1 12 -0/1 0/1 1/1 0/1 -1/1 0/1 2/1 0/1 -1/1 0/1 2/1 0/1 -2/1 0/1 3/1 0/1 -2/1 0/1 3/1 0/1 -2/1 0/1 3/1 0/1 -3/1 0/1 4/1 0/1 -3/1 0/1 4/1 0/1 -3/1 0/1 4/1 0/1 -4/1 0/1 5/1 0/1 -4/1 0/1 5/1 0/1 -5/1 0/1 7/1 0/1 +0 0 1 0 +1 0 2 0 +1 0 2 0 +2 0 3 0 +2 0 3 0 +2 0 3 0 +3 0 4 0 +3 0 4 0 +3 0 4 0 +4 0 5 0 +4 0 5 0 +5 0 7 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test71.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test71.txt index 7ac58ab7917a..726cdc2d9d49 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test71.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test71.txt @@ -3,27 +3,23 @@ 0 2 4 2 0 2 4 2 4 -2/1 2/1 2/1 0/1 -0/1 2/1 2/1 2/1 -2/1 4/1 2/1 2/1 -2/1 2/1 4/1 2/1 +2 2 2 0 +0 2 2 2 +2 4 2 2 +2 2 4 2 5 -0/1 2/1 -2/1 0/1 -32/16 32/16 -2/1 4/1 -4/1 2/1 -1 -32/16 32/16 +0 2 +2 0 +2 2 +2 4 +4 2 1 +2 2 +# No. of faces: 1 6 -2/1 2/1 2/1 0/1 -0/1 2/1 2/1 2/1 -0/1 2/1 2/1 2/1 -2/1 4/1 2/1 2/1 -2/1 2/1 4/1 2/1 -2/1 2/1 4/1 2/1 - - - - +2 2 2 0 +0 2 2 2 +0 2 2 2 +2 4 2 2 +2 2 4 2 +2 2 4 2 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test72.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test72.txt index c231c7b4f77a..212a77a0f3cc 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test72.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test72.txt @@ -13,69 +13,69 @@ 10 0 14 4 10 0 14 4 15 --1/1 2/1 1/1 2/1 -0/1 0/1 64/32 64/32 -0/1 4/1 64/32 64/32 -64/32 64/32 4/1 0/1 -64/32 64/32 4/1 4/1 -4/1 2/1 6/1 2/1 -5/1 0/1 224/32 64/32 -5/1 4/1 224/32 64/32 -224/32 64/32 9/1 0/1 -224/32 64/32 9/1 4/1 -9/1 2/1 11/1 2/1 -10/1 0/1 384/32 64/32 -10/1 4/1 384/32 64/32 -384/32 64/32 14/1 0/1 -384/32 64/32 14/1 4/1 +-1 2 1 2 +0 0 64/32 64/32 +0 4 64/32 64/32 +64/32 64/32 4 0 +64/32 64/32 4 4 +4 2 6 2 +5 0 224/32 64/32 +5 4 224/32 64/32 +224/32 64/32 9 0 +224/32 64/32 9 4 +9 2 11 2 +10 0 384/32 64/32 +10 4 384/32 64/32 +384/32 64/32 14 0 +384/32 64/32 14 4 21 --1/1 2/1 -0/1 0/1 -0/1 4/1 -1/1 2/1 +-1 2 +0 0 +0 4 +1 2 64/32 64/32 -4/1 0/1 -4/1 2/1 -4/1 4/1 -5/1 0/1 -5/1 4/1 -6/1 2/1 +4 0 +4 2 +4 4 +5 0 +5 4 +6 2 224/32 64/32 -9/1 0/1 -9/1 2/1 -9/1 4/1 -10/1 0/1 -10/1 4/1 -11/1 2/1 +9 0 +9 2 +9 4 +10 0 +10 4 +11 2 384/32 64/32 -14/1 0/1 -14/1 4/1 +14 0 +14 4 3 64/32 64/32 224/32 64/32 384/32 64/32 -1 +# No. of faces: 1 23 --1/1 2/1 1/1 2/1 -0/1 0/1 64/32 64/32 -0/1 0/1 64/32 64/32 -0/1 4/1 64/32 64/32 -0/1 4/1 64/32 64/32 -64/32 64/32 4/1 0/1 -64/32 64/32 4/1 0/1 -64/32 64/32 4/1 4/1 -64/32 64/32 4/1 4/1 -4/1 2/1 6/1 2/1 -5/1 0/1 224/32 64/32 -5/1 4/1 224/32 64/32 -5/1 4/1 224/32 64/32 -224/32 64/32 9/1 0/1 -224/32 64/32 9/1 0/1 -224/32 64/32 9/1 4/1 -9/1 2/1 11/1 2/1 -10/1 0/1 384/32 64/32 -10/1 0/1 384/32 64/32 -10/1 4/1 384/32 64/32 -384/32 64/32 14/1 0/1 -384/32 64/32 14/1 4/1 -384/32 64/32 14/1 4/1 +-1 2 1 2 +0 0 64/32 64/32 +0 0 64/32 64/32 +0 4 64/32 64/32 +0 4 64/32 64/32 +64/32 64/32 4 0 +64/32 64/32 4 0 +64/32 64/32 4 4 +64/32 64/32 4 4 +4 2 6 2 +5 0 224/32 64/32 +5 4 224/32 64/32 +5 4 224/32 64/32 +224/32 64/32 9 0 +224/32 64/32 9 0 +224/32 64/32 9 4 +9 2 11 2 +10 0 384/32 64/32 +10 0 384/32 64/32 +10 4 384/32 64/32 +384/32 64/32 14 0 +384/32 64/32 14 4 +384/32 64/32 14 4 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test73.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test73.txt index 0a95db80faca..5e2b5aafab2b 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test73.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test73.txt @@ -2,20 +2,20 @@ 3 0 3 4 3 2 3 7 3 -3/1 0/1 3/1 2/1 -3/1 2/1 3/1 4/1 -3/1 4/1 3/1 7/1 +3 0 3 2 +3 2 3 4 +3 4 3 7 4 -3/1 0/1 -3/1 2/1 -3/1 4/1 -3/1 7/1 +3 0 +3 2 +3 4 +3 7 2 -3/1 2/1 -3/1 4/1 -1 +3 2 +3 4 +# No. of faces: 1 4 -3/1 0/1 3/1 2/1 -3/1 2/1 3/1 4/1 -3/1 2/1 3/1 4/1 -3/1 4/1 3/1 7/1 +3 0 3 2 +3 2 3 4 +3 2 3 4 +3 4 3 7 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test74.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test74.txt index 4cc18dcb0214..c48b428b7915 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test74.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test74.txt @@ -3,31 +3,31 @@ 2 4 2 0 0 3 4 3 6 -2/1 2/1 2/1 0/1 -2/1 2/1 2/1 3/1 -0/1 3/1 2/1 3/1 -2/1 3/1 2/1 4/1 -2/1 7/1 2/1 4/1 -2/1 3/1 4/1 3/1 +2 2 2 0 +2 2 2 3 +0 3 2 3 +2 3 2 4 +2 7 2 4 +2 3 4 3 7 -0/1 3/1 -2/1 0/1 -2/1 2/1 -32/16 48/16 -2/1 4/1 -2/1 7/1 -4/1 3/1 +0 3 +2 0 +2 2 +2 3 +2 4 +2 7 +4 3 3 -2/1 2/1 -32/16 48/16 -2/1 4/1 -1 +2 2 +2 3 +2 4 +# No. of faces: 1 8 -2/1 2/1 2/1 0/1 -2/1 2/1 2/1 3/1 -2/1 2/1 2/1 3/1 -0/1 3/1 2/1 3/1 -2/1 3/1 2/1 4/1 -2/1 3/1 2/1 4/1 -2/1 7/1 2/1 4/1 -2/1 3/1 4/1 3/1 +2 2 2 0 +2 2 2 3 +2 2 2 3 +0 3 2 3 +2 3 2 4 +2 3 2 4 +2 7 2 4 +2 3 4 3 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test75.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test75.txt index 50fe97fa3830..2b7af6f80e7e 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test75.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test75.txt @@ -3,23 +3,23 @@ 2 4 2 0 0 2 4 2 4 -2/1 0/1 2/1 2/1 -0/1 2/1 2/1 2/1 -2/1 2/1 2/1 4/1 -2/1 2/1 4/1 2/1 +2 0 2 2 +0 2 2 2 +2 2 2 4 +2 2 4 2 5 -0/1 2/1 -2/1 0/1 -32/16 32/16 -2/1 4/1 -4/1 2/1 -1 -32/16 32/16 +0 2 +2 0 +2 2 +2 4 +4 2 1 +2 2 +# No. of faces: 1 6 -2/1 0/1 2/1 2/1 -2/1 0/1 2/1 2/1 -0/1 2/1 2/1 2/1 -2/1 2/1 2/1 4/1 -2/1 2/1 2/1 4/1 -2/1 2/1 4/1 2/1 +2 0 2 2 +2 0 2 2 +0 2 2 2 +2 2 2 4 +2 2 2 4 +2 2 4 2 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test76.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test76.txt index e33576bb8159..97bfc5d24fdc 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test76.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test76.txt @@ -3,31 +3,31 @@ 4 4 4 0 0 2 6 2 7 -2/1 2/1 2/1 0/1 -0/1 2/1 2/1 2/1 -2/1 4/1 2/1 2/1 -4/1 2/1 4/1 0/1 -2/1 2/1 4/1 2/1 -4/1 4/1 4/1 2/1 -4/1 2/1 6/1 2/1 +2 2 2 0 +0 2 2 2 +2 4 2 2 +4 2 4 0 +2 2 4 2 +4 4 4 2 +4 2 6 2 8 -0/1 2/1 -2/1 0/1 +0 2 +2 0 48/24 48/24 -2/1 4/1 -4/1 0/1 +2 4 +4 0 96/24 48/24 -4/1 4/1 -6/1 2/1 +4 4 +6 2 2 48/24 48/24 96/24 48/24 -1 +# No. of faces: 1 7 -2/1 2/1 2/1 0/1 -0/1 2/1 2/1 2/1 -2/1 4/1 2/1 2/1 -4/1 2/1 4/1 0/1 -2/1 2/1 4/1 2/1 -4/1 4/1 4/1 2/1 -4/1 2/1 6/1 2/1 +2 2 2 0 +0 2 2 2 +2 4 2 2 +4 2 4 0 +2 2 4 2 +4 4 4 2 +4 2 6 2 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test77.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test77.txt index 52ed98b070e4..b3ec36e67447 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test77.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test77.txt @@ -2,17 +2,16 @@ 0 3 0 0 0 2 0 0 2 -0/1 2/1 0/1 0/1 -0/1 3/1 0/1 2/1 +0 2 0 0 +0 3 0 2 3 -0/1 0/1 -0/1 2/1 -0/1 3/1 -1 -0/1 2/1 +0 0 +0 2 +0 3 1 +0 2 +# No. of faces: 1 3 -0/1 2/1 0/1 0/1 -0/1 2/1 0/1 0/1 -0/1 3/1 0/1 2/1 - +0 2 0 0 +0 2 0 0 +0 3 0 2 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test78.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test78.txt index 194577128a5b..a91fe60a7391 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test78.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test78.txt @@ -6,59 +6,59 @@ 0 3 5 3 0 1 5 1 14 -1/1 1/1 1/1 0/1 -0/1 1/1 1/1 1/1 -1/1 2/1 1/1 1/1 -1/1 2/1 1/1 3/1 -0/1 3/1 1/1 3/1 -1/1 3/1 1/1 5/1 -4/1 0/1 4/1 1/1 -1/1 1/1 4/1 1/1 -4/1 1/1 4/1 2/1 -4/1 2/1 4/1 3/1 -1/1 3/1 4/1 3/1 -4/1 3/1 4/1 4/1 -4/1 1/1 5/1 1/1 -4/1 3/1 5/1 3/1 +1 1 1 0 +0 1 1 1 +1 2 1 1 +1 2 1 3 +0 3 1 3 +1 3 1 5 +4 0 4 1 +1 1 4 1 +4 1 4 2 +4 2 4 3 +1 3 4 3 +4 3 4 4 +4 1 5 1 +4 3 5 3 14 -0/1 1/1 -0/1 3/1 -1/1 0/1 -25/25 25/25 -1/1 2/1 -25/25 75/25 -1/1 5/1 -4/1 0/1 -80/20 20/20 -4/1 2/1 -80/20 60/20 -4/1 4/1 -5/1 1/1 -5/1 3/1 +0 1 +0 3 +1 0 +1 1 +1 2 +1 3 +1 5 +4 0 +4 1 +4 2 +4 3 +4 4 +5 1 +5 3 6 -25/25 25/25 -1/1 2/1 -25/25 75/25 -80/20 20/20 -4/1 2/1 -80/20 60/20 -2 +1 1 +1 2 +1 3 +4 1 +4 2 +4 3 +# No. of faces: 2 18 -1/1 1/1 1/1 0/1 -0/1 1/1 1/1 1/1 -1/1 2/1 1/1 1/1 -1/1 2/1 1/1 3/1 -1/1 2/1 1/1 3/1 -0/1 3/1 1/1 3/1 -1/1 3/1 1/1 5/1 -1/1 3/1 1/1 5/1 -4/1 0/1 4/1 1/1 -1/1 1/1 4/1 1/1 -4/1 1/1 4/1 2/1 -4/1 2/1 4/1 3/1 -4/1 2/1 4/1 3/1 -1/1 3/1 4/1 3/1 -4/1 3/1 4/1 4/1 -4/1 3/1 4/1 4/1 -4/1 1/1 5/1 1/1 -4/1 3/1 5/1 3/1 +1 1 1 0 +0 1 1 1 +1 2 1 1 +1 2 1 3 +1 2 1 3 +0 3 1 3 +1 3 1 5 +1 3 1 5 +4 0 4 1 +1 1 4 1 +4 1 4 2 +4 2 4 3 +4 2 4 3 +1 3 4 3 +4 3 4 4 +4 3 4 4 +4 1 5 1 +4 3 5 3 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test79.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test79.txt index dc9b76b12841..9390c7cc6087 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test79.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test79.txt @@ -4,31 +4,31 @@ 0 3 3 3 0 1 3 1 6 -0/1 1/1 0/1 0/1 -0/1 2/1 0/1 1/1 -0/1 2/1 0/1 3/1 -0/1 3/1 0/1 5/1 -0/1 1/1 3/1 1/1 -0/1 3/1 3/1 3/1 +0 1 0 0 +0 2 0 1 +0 2 0 3 +0 3 0 5 +0 1 3 1 +0 3 3 3 7 -0/1 0/1 -0/1 1/1 -0/1 2/1 -0/1 3/1 -0/1 5/1 -3/1 1/1 -3/1 3/1 +0 0 +0 1 +0 2 +0 3 +0 5 +3 1 +3 3 3 -0/1 1/1 -0/1 2/1 -0/1 3/1 -1 +0 1 +0 2 +0 3 +# No. of faces: 1 8 -0/1 1/1 0/1 0/1 -0/1 2/1 0/1 1/1 -0/1 2/1 0/1 3/1 -0/1 2/1 0/1 3/1 -0/1 3/1 0/1 5/1 -0/1 3/1 0/1 5/1 -0/1 1/1 3/1 1/1 -0/1 3/1 3/1 3/1 +0 1 0 0 +0 2 0 1 +0 2 0 3 +0 2 0 3 +0 3 0 5 +0 3 0 5 +0 1 3 1 +0 3 3 3 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test80.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test80.txt index 57300a903c32..3181a33c4986 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test80.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test80.txt @@ -8,25 +8,23 @@ 0 4 0 0 0 4 0 0 4 -0/1 0/1 0/1 4/1 -0/1 0/1 4/1 0/1 -4/1 0/1 4/1 4/1 -0/1 4/1 4/1 4/1 +0 0 0 4 +0 0 4 0 +4 0 4 4 +0 4 4 4 4 -0/1 0/1 -0/1 4/1 -4/1 0/1 -4/1 4/1 +0 0 +0 4 +4 0 +4 4 0 -2 +# No. of faces: 2 8 -0/1 0/1 0/1 4/1 -0/1 0/1 0/1 4/1 -0/1 0/1 4/1 0/1 -0/1 0/1 4/1 0/1 -4/1 0/1 4/1 4/1 -4/1 0/1 4/1 4/1 -0/1 4/1 4/1 4/1 -0/1 4/1 4/1 4/1 - - +0 0 0 4 +0 0 0 4 +0 0 4 0 +0 0 4 0 +4 0 4 4 +4 0 4 4 +0 4 4 4 +0 4 4 4 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test81.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test81.txt index 4c27222b4150..4f7bc3a18d5b 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test81.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test81.txt @@ -6,45 +6,45 @@ 1 7 6 7 1 7 6 7 10 -0/1 2/1 144/72 288/72 -0/1 6/1 144/72 288/72 -1/1 1/1 150/30 30/30 -144/72 288/72 150/30 30/30 -144/72 288/72 150/30 210/30 -1/1 7/1 150/30 210/30 -150/30 30/30 6/1 0/1 -150/30 30/30 6/1 1/1 -150/30 210/30 6/1 7/1 -150/30 210/30 6/1 8/1 +0 2 2 4 +0 6 2 4 +1 1 5 1 +2 4 5 1 +2 4 5 7 +1 7 5 7 +5 1 6 0 +5 1 6 1 +5 7 6 7 +5 7 6 8 11 -0/1 2/1 -0/1 6/1 -1/1 1/1 -1/1 7/1 -144/72 288/72 -150/30 30/30 -150/30 210/30 -6/1 0/1 -6/1 1/1 -6/1 7/1 -6/1 8/1 +0 2 +0 6 +1 1 +1 7 +2 4 +5 1 +5 7 +6 0 +6 1 +6 7 +6 8 3 -144/72 288/72 -150/30 30/30 -150/30 210/30 -1 +2 4 +5 1 +5 7 +# No. of faces: 1 14 -0/1 2/1 144/72 288/72 -0/1 6/1 144/72 288/72 -1/1 1/1 150/30 30/30 -1/1 1/1 150/30 30/30 -144/72 288/72 150/30 30/30 -144/72 288/72 150/30 210/30 -1/1 7/1 150/30 210/30 -1/1 7/1 150/30 210/30 -150/30 30/30 6/1 0/1 -150/30 30/30 6/1 1/1 -150/30 30/30 6/1 1/1 -150/30 210/30 6/1 7/1 -150/30 210/30 6/1 7/1 -150/30 210/30 6/1 8/1 +0 2 2 4 +0 6 2 4 +1 1 5 1 +1 1 5 1 +2 4 5 1 +2 4 5 7 +1 7 5 7 +1 7 5 7 +5 1 6 0 +5 1 6 1 +5 1 6 1 +5 7 6 7 +5 7 6 7 +5 7 6 8 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test82.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test82.txt index e4dbeb073c2c..723bf69b8ff2 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test82.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test82.txt @@ -3,23 +3,23 @@ 0 4 4 0 -1 2 5 2 4 --1/1 2/1 48/24 48/24 -0/1 4/1 48/24 48/24 -48/24 48/24 4/1 0/1 -48/24 48/24 5/1 2/1 +-1 2 48/24 48/24 +0 4 48/24 48/24 +48/24 48/24 4 0 +48/24 48/24 5 2 5 --1/1 2/1 -0/1 4/1 +-1 2 +0 4 48/24 48/24 -4/1 0/1 -5/1 2/1 +4 0 +5 2 1 48/24 48/24 -1 +# No. of faces: 1 6 --1/1 2/1 48/24 48/24 -0/1 4/1 48/24 48/24 -0/1 4/1 48/24 48/24 -48/24 48/24 4/1 0/1 -48/24 48/24 4/1 0/1 -48/24 48/24 5/1 2/1 +-1 2 48/24 48/24 +0 4 48/24 48/24 +0 4 48/24 48/24 +48/24 48/24 4 0 +48/24 48/24 4 0 +48/24 48/24 5 2 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test83.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test83.txt index 67a74747e524..5ef7d44396bd 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test83.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test83.txt @@ -5,26 +5,24 @@ 0 2 5 1 0 4 5 5 5 -0/1 2/1 5/1 1/1 -0/1 3/1 5/1 1/1 -0/1 3/1 5/1 5/1 -0/1 4/1 5/1 5/1 -0/1 1/1 7/1 0/1 +0 2 5 1 +0 3 5 1 +0 3 5 5 +0 4 5 5 +0 1 7 0 7 -0/1 1/1 -0/1 2/1 -0/1 3/1 -0/1 4/1 -5/1 1/1 -5/1 5/1 -7/1 0/1 +0 1 +0 2 +0 3 +0 4 +5 1 +5 5 +7 0 0 -1 +# No. of faces: 1 5 -0/1 2/1 5/1 1/1 -0/1 3/1 5/1 1/1 -0/1 3/1 5/1 5/1 -0/1 4/1 5/1 5/1 -0/1 1/1 7/1 0/1 - - +0 2 5 1 +0 3 5 1 +0 3 5 5 +0 4 5 5 +0 1 7 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test84.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test84.txt index 419bf09b9ebd..b7d779ff1b14 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test84.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test84.txt @@ -4,27 +4,27 @@ 3 2 5 4 3 2 5 0 6 -0/1 0/1 3/1 2/1 -0/1 4/1 3/1 2/1 -3/1 2/1 5/1 0/1 -3/1 2/1 5/1 4/1 -3/1 2/1 6/1 0/1 -3/1 2/1 6/1 4/1 +0 0 3 2 +0 4 3 2 +3 2 5 0 +3 2 5 4 +3 2 6 0 +3 2 6 4 7 -0/1 0/1 -0/1 4/1 -3/1 2/1 -5/1 0/1 -5/1 4/1 -6/1 0/1 -6/1 4/1 -1 -3/1 2/1 +0 0 +0 4 +3 2 +5 0 +5 4 +6 0 +6 4 1 +3 2 +# No. of faces: 1 6 -0/1 0/1 3/1 2/1 -0/1 4/1 3/1 2/1 -3/1 2/1 5/1 0/1 -3/1 2/1 5/1 4/1 -3/1 2/1 6/1 0/1 -3/1 2/1 6/1 4/1 +0 0 3 2 +0 4 3 2 +3 2 5 0 +3 2 5 4 +3 2 6 0 +3 2 6 4 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test85.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test85.txt index 79d9d1bd8be6..53e394fb9dc3 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test85.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test85.txt @@ -3,24 +3,21 @@ 2 0 4 3 2 0 5 2 4 -0/1 0/1 2/1 0/1 -2/1 0/1 4/1 3/1 -2/1 0/1 5/1 2/1 -2/1 0/1 6/1 0/1 +0 0 2 0 +2 0 4 3 +2 0 5 2 +2 0 6 0 5 -0/1 0/1 -2/1 0/1 -4/1 3/1 -5/1 2/1 -6/1 0/1 -1 -2/1 0/1 +0 0 +2 0 +4 3 +5 2 +6 0 1 +2 0 +# No. of faces: 1 4 -0/1 0/1 2/1 0/1 -2/1 0/1 4/1 3/1 -2/1 0/1 5/1 2/1 -2/1 0/1 6/1 0/1 - - - +0 0 2 0 +2 0 4 3 +2 0 5 2 +2 0 6 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test86.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test86.txt index bb28d85698ca..85ef8c50bc4f 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test86.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test86.txt @@ -3,23 +3,21 @@ 3 3 6 1 3 3 6 0 4 -0/1 3/1 3/1 3/1 -3/1 3/1 6/1 0/1 -3/1 3/1 6/1 1/1 -3/1 3/1 6/1 3/1 +0 3 3 3 +3 3 6 0 +3 3 6 1 +3 3 6 3 5 -0/1 3/1 -3/1 3/1 -6/1 0/1 -6/1 1/1 -6/1 3/1 -1 -3/1 3/1 +0 3 +3 3 +6 0 +6 1 +6 3 1 +3 3 +# No. of faces: 1 4 -0/1 3/1 3/1 3/1 -3/1 3/1 6/1 0/1 -3/1 3/1 6/1 1/1 -3/1 3/1 6/1 3/1 - - +0 3 3 3 +3 3 6 0 +3 3 6 1 +3 3 6 3 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test87.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test87.txt index 2d84b028ae6a..029e8e04e931 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test87.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test87.txt @@ -3,22 +3,21 @@ 3 3 5 0 3 3 6 6 4 -3/1 3/1 0/1 3/1 -3/1 3/1 5/1 0/1 -3/1 3/1 6/1 6/1 -7/1 3/1 3/1 3/1 +3 3 0 3 +3 3 5 0 +3 3 6 6 +7 3 3 3 5 -0/1 3/1 -3/1 3/1 -5/1 0/1 -6/1 6/1 -7/1 3/1 -1 -3/1 3/1 +0 3 +3 3 +5 0 +6 6 +7 3 1 +3 3 +# No. of faces: 1 4 -3/1 3/1 0/1 3/1 -3/1 3/1 5/1 0/1 -3/1 3/1 6/1 6/1 -7/1 3/1 3/1 3/1 - +3 3 0 3 +3 3 5 0 +3 3 6 6 +7 3 3 3 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test88.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test88.txt index 911adaeaab2b..036b8c8b6bdf 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test88.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test88.txt @@ -3,25 +3,24 @@ 1 0 5 8 3 4 6 6 5 -1/1 0/1 3/1 4/1 -0/1 4/1 3/1 4/1 -3/1 4/1 5/1 8/1 -3/1 4/1 6/1 6/1 -3/1 4/1 7/1 4/1 +1 0 3 4 +0 4 3 4 +3 4 5 8 +3 4 6 6 +3 4 7 4 6 -0/1 4/1 -1/1 0/1 -3/1 4/1 -5/1 8/1 -6/1 6/1 -7/1 4/1 -1 -3/1 4/1 +0 4 +1 0 +3 4 +5 8 +6 6 +7 4 1 +3 4 +# No. of faces: 1 5 -1/1 0/1 3/1 4/1 -0/1 4/1 3/1 4/1 -3/1 4/1 5/1 8/1 -3/1 4/1 6/1 6/1 -3/1 4/1 7/1 4/1 - +1 0 3 4 +0 4 3 4 +3 4 5 8 +3 4 6 6 +3 4 7 4 From b781d6a2f83b152eacb1d0aae8b47aaf044fcb7c Mon Sep 17 00:00:00 2001 From: Efi Fogel Date: Sun, 28 May 2023 17:25:06 +0300 Subject: [PATCH 059/329] Fixed default polyline traits --- .../include/CGAL/Surface_sweep_2_algorithms.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Surface_sweep_2/include/CGAL/Surface_sweep_2_algorithms.h b/Surface_sweep_2/include/CGAL/Surface_sweep_2_algorithms.h index f18f1018db3e..18f5554dde7c 100644 --- a/Surface_sweep_2/include/CGAL/Surface_sweep_2_algorithms.h +++ b/Surface_sweep_2/include/CGAL/Surface_sweep_2_algorithms.h @@ -33,6 +33,7 @@ #include #include #include +#include namespace CGAL { @@ -54,11 +55,13 @@ struct Default_arr_traits > typedef CGAL::Arr_segment_traits_2 Traits; }; -template -struct Default_arr_traits > +template +struct Default_arr_traits, + typename Kernel::Point_2>> { - typedef CGAL::Arr_polyline_traits_2 Traits; + using Subtraits = CGAL::Arr_segment_traits_2; + typedef CGAL::Arr_polyline_traits_2 Traits; }; template From f247756bfbc21eaa5126453d85fe45c8a000c434 Mon Sep 17 00:00:00 2001 From: Efi Fogel Date: Sun, 28 May 2023 17:26:04 +0300 Subject: [PATCH 060/329] Enhanced test --- .../test/Surface_sweep_2/CMakeLists.txt | 17 +- .../test/Surface_sweep_2/Compare_curves.h | 53 ++- .../test/Surface_sweep_2/cgal_test_base | 26 +- .../test/Surface_sweep_2/cgal_test_with_cmake | 1 - .../test/Surface_sweep_2/test_sweep.cpp | 314 +++++++++--------- 5 files changed, 207 insertions(+), 204 deletions(-) diff --git a/Surface_sweep_2/test/Surface_sweep_2/CMakeLists.txt b/Surface_sweep_2/test/Surface_sweep_2/CMakeLists.txt index 6bc64ec76019..3471c16f7155 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/CMakeLists.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/CMakeLists.txt @@ -7,7 +7,6 @@ project(Surface_sweep_2_Tests) find_package(CGAL REQUIRED COMPONENTS Core) set(CGAL_SEGMENT_TRAITS 1) -set(CGAL_SEGMENT_LEDA_TRAITS 2) set(CGAL_POLYLINE_TRAITS 11) set(CGAL_CONIC_TRAITS 21) @@ -38,16 +37,18 @@ function(compile_and_run_sweep name source_file point_location traits data_set) file( GLOB files RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} - "${CMAKE_CURRENT_SOURCE_DIR}/${data_set}/*") + "${CMAKE_CURRENT_SOURCE_DIR}/${data_set}/*.txt") foreach(file ${files}) - # message("test ${source_file} ${file}") + # message("test ${source_file} ${file}") string(MAKE_C_IDENTIFIER "${name} ${file}" test_name) - # message(" --> ${test_name}") + # message(" --> ${test_name}") cgal_add_test(${name} TEST_NAME ${test_name} ARGUMENTS ${file}) endforeach() endfunction() -compile_and_run_sweep(test_sweep test_sweep.cpp ${NAIVE} ${CGAL_SEGMENT_TRAITS} - "DATA/segments_tight") -compile_and_run_sweep(test_sweep_conic test_sweep_conic.cpp ${NAIVE} - ${CGAL_CONIC_TRAITS} "DATA/conics") +# compile_and_run_sweep(test_sweep test_sweep.cpp ${NAIVE} ${CGAL_SEGMENT_TRAITS} +# "DATA/segments_tight") +# compile_and_run_sweep(test_sweep_conic test_sweep_conic.cpp ${NAIVE} +# ${CGAL_CONIC_TRAITS} "DATA/conics") +compile_and_run_sweep(test_sweep_polyline test_sweep.cpp ${NAIVE} + ${CGAL_POLYLINE_TRAITS} "DATA/polylines") diff --git a/Surface_sweep_2/test/Surface_sweep_2/Compare_curves.h b/Surface_sweep_2/test/Surface_sweep_2/Compare_curves.h index ff43d9b73a4d..311f26746d4c 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/Compare_curves.h +++ b/Surface_sweep_2/test/Surface_sweep_2/Compare_curves.h @@ -1,47 +1,44 @@ -#ifndef _COMPARE_CURVE_LIST_H -#define _COMPARE_CURVE_LIST_H +#ifndef _COMPARE_CURVES_H +#define _COMPARE_CURVES_H #include #include - -template -class Equal_pred -{ +template +class Equal_pred { public: - typedef typename Traits::Point_2 Point_2; - typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2; + using Point_2 = typename Traits::Point_2; + using X_monotone_curve_2 = typename Traits::X_monotone_curve_2; + + Equal_pred(const Traits& traits) : m_traits(traits) {} bool operator()(const Point_2& p1, const Point_2& p2) - { - return(Traits().equal_2_object()(p1, p2)); - } + { return(m_traits.equal_2_object()(p1, p2)); } bool operator()(const X_monotone_curve_2& c1, const X_monotone_curve_2& c2) - { - return(Traits().equal_2_object()(c1, c2)); - } -}; + { return(m_traits.equal_2_object()(c1, c2)); } +private: + const Traits& m_traits; +}; -template - bool compare_lists(const List& list1, const List& list2, Traits& /*tr*/) -{ - typedef typename List::const_iterator Iter; - Iter begin1 = list1.begin(); - Iter end1 = list1.end(); - - Iter begin2 = list2.begin(); - if(! (list1.size() == list2.size())) - { - std::cout << "The lists are not of the same lengths (" +template +bool compare_lists(const List& list1, const List& list2, Traits& traits) { + if(! (list1.size() == list2.size())) { + std::cerr << "Error: The lists are not of the same lengths (" << list1.size() << "," << list2.size() << ")\n"; return false; } - Equal_pred eq; - return std::equal(begin1, end1, begin2, eq); + Equal_pred eq(traits); + auto rc = std::equal(list1.begin(), list1.end(), list2.begin(), eq); + if (! rc) { + std::cerr << "Error: The curves do not match\n"; + return false; + } + + return true; } diff --git a/Surface_sweep_2/test/Surface_sweep_2/cgal_test_base b/Surface_sweep_2/test/Surface_sweep_2/cgal_test_base index c6c8af71e9aa..2612c02c50f1 100755 --- a/Surface_sweep_2/test/Surface_sweep_2/cgal_test_base +++ b/Surface_sweep_2/test/Surface_sweep_2/cgal_test_base @@ -78,12 +78,11 @@ compile() compile_and_run() { - echo "---$1---" # running general test if compile $1 $2 $3 ; then - echo " compilation of $1 succeeded" >> $ERRORFILE + echo " compilation of $1 succeeded" >> $ERRORFILE SUBCURVES="" run $1 $2 $3 $4 SUBCURVES="subcurves" @@ -93,14 +92,13 @@ compile_and_run() fi eval "2>&1 ${MAKE_CMD} CGAL_MAKEFILE=$CGAL_MAKEFILE clean > /dev/null " - } clean_tests() { if [ "${TEST_WITH_CMAKE}" != "FALSE" ]; then # - # The clean target generated by CMake under cygwin + # The clean target generated by CMake under cygwin # always fails for some reason # if ! ( uname | grep -q "CYGWIN" ) ; then @@ -117,7 +115,7 @@ compile_and_run_sweep() # running general test if compile $1 $2 $3 ; then - echo " compilation of $1 succeeded" >> $ERRORFILE + echo " compilation of $1 succeeded" >> $ERRORFILE run $1 $2 $3 $4 else echo " ERROR: compilation of $1 failed" >> $ERRORFILE @@ -134,7 +132,7 @@ run() for DATAFILE in ${datafiles} do if [ -d $DATAFILE ]; then - echo "$DATEFILE is a directory" + echo "$DATEFILE is a directory" continue fi @@ -158,7 +156,6 @@ run() echo " ERROR: could not execute $1 $DATAFILE $SUBCURVES" >> $ERRORFILE fi done - } run_io() @@ -178,20 +175,20 @@ run_io() for DATAFILE in ${datafiles} do - + if [ -d $DATAFILE ]; then - echo "$DATEFILE is a directory" + echo "$DATEFILE is a directory" continue fi - + IOFILE="${iofiles}`basename ${DATAFILE}`_${SUFFIO}" echo $IOFILE - + if [ -f $1 ] ; then rm -f arr.txt - + DATANAME=`basename $DATAFILE` - IONAME=`basename $IOFILE` + IONAME=`basename $IOFILE` OUTPUTFILE=ProgramOutput.$3.$1.$DATANAME.$PLATFORM.$2 rm -f $OUTPUTFILE @@ -246,6 +243,7 @@ TRAP=1 # Trapezoidal decomposition NAIVE=2 WALK=3 - #run the test for new sweep +#run the test for new sweep (compile_and_run_sweep test_sweep $NAIVE $CGAL_SEGMENT_TRAITS "DATA/segments_tight") (compile_and_run_sweep test_sweep_conic $NAIVE $CGAL_CONIC_TRAITS "DATA/conics") +(compile_and_run_sweep test_sweep $NAIVE $CGAL_POLYLINE_TRAITS "DATA/polylines diff --git a/Surface_sweep_2/test/Surface_sweep_2/cgal_test_with_cmake b/Surface_sweep_2/test/Surface_sweep_2/cgal_test_with_cmake index 8c72a52e3326..60483af61d6c 100755 --- a/Surface_sweep_2/test/Surface_sweep_2/cgal_test_with_cmake +++ b/Surface_sweep_2/test/Surface_sweep_2/cgal_test_with_cmake @@ -1,4 +1,3 @@ #! /bin/bash ./cgal_test_base -cmake - diff --git a/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp b/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp index 23ceebf559d1..7af2076d7a8d 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp +++ b/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp @@ -1,6 +1,5 @@ // examples/Pm_with_intersections/example4 // --------------------------------------- -#include #include #include #include @@ -8,10 +7,12 @@ #include #include +#include + #define CGAL_SEGMENT_TRAITS 1 -#define CGAL_SEGMENT_LEDA_TRAITS 2 #define CGAL_POLYLINE_TRAITS 11 #define CGAL_CONIC_TRAITS 21 +#define CGAL_POLYCONIC_TRAITS 22 // Picking a default Traits class (this, with the // PL flag enables the running of the test independently of cgal_make.) @@ -19,13 +20,12 @@ #define CGAL_ARR_TEST_TRAITS CGAL_SEGMENT_TRAITS #endif -// Making sure test doesn't fail if LEDA is not installed -#if ! defined(CGAL_USE_LEDA) && \ - (CGAL_ARR_TEST_TRAITS == CGAL_SEGMENT_LEDA_TRAITS || \ - CGAL_ARR_TEST_TRAITS == CGAL_CONIC_TRAITS ) +// Making sure test doesn't fail if CORE is not installed +#if ! defined(CGAL_USE_CORE) && \ + ((CGAL_ARR_TEST_TRAITS == CGAL_CONIC_TRAITS) || \ + (CGAL_ARR_TEST_TRAITS == CGAL_POLYCONIC_TRAITS)) -int main() -{ +int main() { std::cout << "A try to run test with LEDA traits but LEDA is not installed."; std::cout << std::endl; std::cout << "Test is not performed."; @@ -33,11 +33,12 @@ int main() return 0; } + #elif ! defined(CGAL_USE_GMP) && \ - (CGAL_ARR_TEST_TRAITS == CGAL_SEGMENT_TRAITS) + ((CGAL_ARR_TEST_TRAITS == CGAL_SEGMENT_TRAITS) || \ + (CGAL_ARR_TEST_TRAITS == CGAL_POLYLINE_TRAITS)) -int main() -{ +int main() { std::cout << "A try to run test with GMP number type but GMP is not installed."; std::cout << std::endl; std::cout << "Test is not performed."; @@ -48,117 +49,123 @@ int main() #else - - // Choose traits #if CGAL_ARR_TEST_TRAITS==CGAL_SEGMENT_TRAITS #include -#include -#include +#include #include -#include -#elif CGAL_ARR_TEST_TRAITS == CGAL_SEGMENT_LEDA_TRAITS -#include -#include -#include #elif CGAL_ARR_TEST_TRAITS == CGAL_POLYLINE_TRAITS +#include #include -#include -#include #include #include #elif CGAL_ARR_TEST_TRAITS == CGAL_CONIC_TRAITS #include -#include #include +#elif CGAL_ARR_TEST_TRAITS == CGAL_POLYCONIC_TRAITS +#include +#include +#include #else #error No traits defined for test #endif #include #include + #include -#include "CompareCurveList.h" -#if CGAL_ARR_TEST_TRAITS==CGAL_SEGMENT_TRAITS +#include "Compare_curves.h" + +#if CGAL_ARR_TEST_TRAITS == CGAL_SEGMENT_TRAITS typedef CGAL::Gmpq NT; typedef CGAL::Cartesian Kernel; typedef CGAL::Arr_segment_traits_2 Traits; -#elif CGAL_ARR_TEST_TRAITS == CGAL_SEGMENT_LEDA_TRAITS - typedef leda_rational NT; - typedef CGAL::Pm_segment_traits_leda_kernel_2 Kernel; - typedef CGAL::Arr_leda_segment_traits_2 Traits; - #elif CGAL_ARR_TEST_TRAITS == CGAL_POLYLINE_TRAITS - typedef CGAL::Quotient NT; + typedef CGAL::Gmpq NT; typedef CGAL::Cartesian Kernel; - typedef CGAL::Arr_segment_cached_traits_2 Seg_traits; + typedef CGAL::Arr_segment_traits_2 Seg_traits; typedef CGAL::Arr_polyline_traits_2 Traits; #elif CGAL_ARR_TEST_TRAITS == CGAL_CONIC_TRAITS -typedef leda_real NT; -typedef CGAL::Cartesian Kernel; -typedef CGAL::Arr_conic_traits_2 Traits; -#endif - -typedef Traits::Point_2 Point_2; -typedef Traits::X_monotone_curve_2 X_monotone_curve_2; + typedef CGAL::Arr_conic_traits_2 Traits; -typedef std::list PointList; -typedef PointList::iterator PointListIter; +#elif CGAL_ARR_TEST_TRAITS == CGAL_POLYCURVE_TRAITS + typedef CGAL::Arr_conic_traits_2 Conic_traits; + typedef CGAL::Arr_polycurve_traits_2 Traits; -typedef std::list CurveList; -typedef CurveList::iterator CurveListIter; +#endif -void ReadCurveList(std::ifstream &inp, CurveList &clist); -void ReadCurveListRational(std::ifstream &inp, CurveList &clist); -void ReadPointList(std::ifstream &inp, PointList &plist); -bool IsCurveListIdentical(CurveList &list1, CurveList &list2); -bool IsPointListIdentical(PointList &list1, PointList &list2); +typedef Traits::Point_2 Point_2; +typedef Traits::Curve_2 Curve_2; +typedef Traits::X_monotone_curve_2 X_monotone_curve_2; + +typedef std::list Points; +typedef std::list Curves; +typedef std::list X_monotone_curves; + +bool read_curves(std::ifstream& inp, Curves& curves, const Traits& traits); +bool read_xcurves(std::ifstream& inp, X_monotone_curves& xcurves, + const Traits& traits); +bool read_points(std::ifstream& inp, Points& points, const Traits& traits); +bool curves_identical(X_monotone_curves& list1, X_monotone_curves& list2); +bool points_identical(Points& list1, Points& list2); + +// istream modifier skips chars until end of line. +std::istream& skip_until_eol(std::istream& in) { + if (in.eof()) return in; + char c; + while (in.get(c) && (c != '\n')); + return in; +} -int main(int argc, char * argv[]) -{ +// istream modifier that checks for OFF comments and removes them. +std::istream& skip_comment(std::istream& in) { + char c; + while ((in >> c) && (c == '#')) in >> skip_until_eol; + in.putback(c); + return in; +} - if ( argc != 2 ) - { +int main(int argc, char* argv[]) { + if (argc != 2) { std::cout << "Specify a file name " << std::endl; return -1; } std::ifstream inp(argv[1]); - if (!inp.is_open()) { - std::cerr << "Cannot open file " << argv[1] << "!" << std::endl; + if (! inp.is_open()) { + std::cerr << "Error: Cannot open file " << argv[1] << "!" << std::endl; return -1; } - CurveList curves; - ReadCurveList(inp, curves); - Traits tr; + Curves curves; + if (! read_curves(inp, curves, tr)) return -1; + // get subcurves w/o overlapping - CurveList curves_no_overlap_list_out; - CGAL::compute_subcurves(curves.begin(), - curves.end(), - std::back_inserter(curves_no_overlap_list_out)); + X_monotone_curves curves_no_overlap_out; + CGAL::compute_subcurves(curves.begin(), curves.end(), + std::back_inserter(curves_no_overlap_out), + false, tr); // get subcurves w/ overlapping - CurveList curves_with_overlap_list_out; - CGAL::compute_subcurves(curves.begin(), - curves.end(), - std::back_inserter(curves_with_overlap_list_out), - true); - - /*std::copy(curves_no_overlap_list_out.begin(), - curves_no_overlap_list_out.end(), + X_monotone_curves curves_with_overlap_out; + CGAL::compute_subcurves(curves.begin(), curves.end(), + std::back_inserter(curves_with_overlap_out), + true, tr); + + /*std::copy(curves_no_overlap_out.begin(), + curves_no_overlap_out.end(), std::ostream_iterator(std::cout, "\n")); std::cout<<"\n\n*******************\n\n"; - std::copy(curves_with_overlap_list_out.begin(), - curves_with_overlap_list_out.end(), + std::copy(curves_with_overlap_out.begin(), + curves_with_overlap_out.end(), std::ostream_iterator(std::cout, "\n")); return 0;*/ @@ -166,134 +173,135 @@ int main(int argc, char * argv[]) // get intersection points (with endpoints) - PointList points_with_ends_list_out; - CGAL::compute_intersection_points(curves.begin(), - curves.end(), - std::back_inserter(points_with_ends_list_out), - true); + Points points_with_ends_out; + CGAL::compute_intersection_points(curves.begin(), curves.end(), + std::back_inserter(points_with_ends_out), + true, tr); // get intersection points w/o end points - PointList points_without_ends_list_out; - CGAL::compute_intersection_points(curves.begin(), - curves.end(), - std::back_inserter(points_without_ends_list_out), - false); - std::cout << points_without_ends_list_out.size() - << " points_without_ends_list_out(size)\n"; + Points points_without_ends_out; + CGAL::compute_intersection_points(curves.begin(), curves.end(), + std::back_inserter(points_without_ends_out), + false, tr); + + std::cout << points_without_ends_out.size() + << " points_without_ends_out(size)\n"; // check the do_curves_intersecting method bool do_intersect_out = CGAL::do_curves_intersect(curves.begin(), curves.end()); - // read curves and points from file - CurveList curves_no_overlap_list; - ReadCurveListRational(inp, curves_no_overlap_list); - - PointList points_with_ends_list; - ReadPointList(inp, points_with_ends_list); + X_monotone_curves curves_no_overlap; + if (! read_xcurves(inp, curves_no_overlap, tr)) return -1; - PointList points_without_ends_list; - ReadPointList(inp, points_without_ends_list); + Points points_with_ends; + if (! read_points(inp, points_with_ends, tr)) return -1; - int num_faces; - inp >> num_faces; + Points points_without_ends; + if (! read_points(inp, points_without_ends, tr)) return -1; - CurveList curves_with_overlap_list; - ReadCurveListRational(inp, curves_with_overlap_list); + X_monotone_curves curves_with_overlap; + if (! read_xcurves(inp, curves_with_overlap, tr)) return -1; - if ( !compare_lists(curves_no_overlap_list_out, - curves_no_overlap_list, tr) ) + if (! compare_lists(curves_no_overlap_out, curves_no_overlap, tr)) return -1; - if ( !compare_lists(curves_with_overlap_list_out, - curves_with_overlap_list, tr) ) + if (! compare_lists(curves_with_overlap_out, curves_with_overlap, tr)) return -1; - if ( !compare_lists(points_with_ends_list_out, - points_with_ends_list, tr)) + if (! compare_lists(points_with_ends_out, points_with_ends, tr)) return -1; - if ( !compare_lists(points_without_ends_list_out, - points_without_ends_list, tr)) + if (! compare_lists(points_without_ends_out, points_without_ends, tr)) return -1; bool do_intersect = false; - if((points_without_ends_list.size() != 0) || - (curves_no_overlap_list_out.size() != - curves_with_overlap_list_out.size())) + if ((points_without_ends.size() != 0) || + (curves_no_overlap_out.size() != curves_with_overlap_out.size())) do_intersect = true; - if (do_intersect_out != do_intersect) + if (do_intersect_out != do_intersect) { + std::cerr << "Error: do_intersect()\n"; return -1; + } - std::cout<<"OK\n"; + std::cout << "OK\n"; return 0; } -void ReadCurveList(std::ifstream& inp, CurveList& clist) -{ +#if CGAL_ARR_TEST_TRAITS == CGAL_SEGMENT_TRAITS + +bool read_curves(std::ifstream& inp, Curves& curves, const Traits&) { int count; - inp >> count; - //std::cout << "ReadCurveList " << count << "\n"; + inp >> skip_comment >> count; + std::cout << "read_curves " << count << "\n"; - for (int i = 0; i < count; i++) { + for (int i = 0; i < count; ++i) { NT x0, y0, x1, y1; - int ix0, iy0, ix1, iy1; - inp >> ix0 >> iy0 >> ix1 >> iy1; - x0 = ix0; y0 = iy0; x1 = ix1; y1 = iy1; - + inp >> skip_comment >> x0 >> y0 >> x1 >> y1; Point_2 p1(x0, y0); Point_2 p2(x1, y1); - X_monotone_curve_2 curve(p1, p2); - clist.push_back(curve); - //std::cout << curve << "\n"; + Curve_2 curve(p1, p2); + curves.push_back(curve); + std::cout << curve << "\n"; } + return true; } -void ReadCurveListRational(std::ifstream& inp, CurveList& clist) -{ - int count; - inp >> count; - std::cout << "ReadCurveListRational " << count << "\n"; - char ch; - - for (int i = 0; i < count; i++) { - int a, b; - inp >> a >> ch >> b; - NT x0(a,b); - inp >> a >> ch >> b; - NT y0(a,b); - Point_2 p1(x0, y0); +bool read_xcurves(std::ifstream& inp, X_monotone_curves& xcurves, + const Traits& traits) +{ return read_curves(inp, xcurves, traits); } - inp >> a >> ch >> b; - NT x1(a,b); - inp >> a >> ch >> b; - NT y1(a,b); - Point_2 p2(x1, y1); +#elif CGAL_ARR_TEST_TRAITS == CGAL_POLYLINE_TRAITS - X_monotone_curve_2 curve(p1, p2); - clist.push_back(curve); - std::cout << curve << "\n"; +template +bool read_curves_(std::ifstream& inp, Curves_& curves, const Traits& traits, + const Ctr& ctr) { + int count; + inp >> skip_comment >> count; + std::cout << "read_curves " << count << "\n"; + for (int i = 0; i < count; ++i) { + Points points; + auto rc = read_points(inp, points, traits); + if (! rc) return false; + auto cv = ctr(points.begin(), points.end()); + std::cout << cv << "\n"; + curves.push_back(cv); } + return true; +} + +bool read_curves(std::ifstream& inp, Curves& curves, const Traits& traits) { + auto ctr_cv = traits.construct_curve_2_object(); + return read_curves_(inp, curves, traits, ctr_cv); +} + +bool read_xcurves(std::ifstream& inp, X_monotone_curves& xcurves, + const Traits& traits) { + auto ctr_xcv = traits.construct_x_monotone_curve_2_object(); + return read_curves_(inp, xcurves, traits, ctr_xcv); } -void ReadPointList(std::ifstream &inp, PointList &plist) -{ + +#else +#error No traits defined for test +#endif + +bool read_points(std::ifstream& inp, Points& points, const Traits&) { int count; - inp >> count; + inp >> skip_comment >> count; char ch; - std::cout << "ReadPointList " << count << "\n"; + std::cout << "read_points " << count << "\n"; for (int i = 0; i < count; i++) { - int a, b; - inp >> a >> ch >> b; - NT x0(a,b); - inp >> a >> ch >> b; - NT y0(a,b); - Point_2 p(x0, y0); - plist.push_back(p); + NT x, y; + inp >> skip_comment >> x >> y; + Point_2 p(x, y); + points.push_back(p); + std::cout << p << "\n"; } + return true; } #endif From 81fd350a79c4788a34024fa27aad8aa2f10935f5 Mon Sep 17 00:00:00 2001 From: Efi Fogel Date: Sun, 28 May 2023 21:52:40 +0300 Subject: [PATCH 061/329] Fixed 1st test --- .../test/Surface_sweep_2/Compare_curves.h | 2 +- .../DATA/polylines/big_overlap.txt | 31 ++++++ .../test/Surface_sweep_2/test_sweep.cpp | 94 +++++++++---------- 3 files changed, 78 insertions(+), 49 deletions(-) create mode 100644 Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/big_overlap.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/Compare_curves.h b/Surface_sweep_2/test/Surface_sweep_2/Compare_curves.h index 311f26746d4c..2727e737570d 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/Compare_curves.h +++ b/Surface_sweep_2/test/Surface_sweep_2/Compare_curves.h @@ -34,7 +34,7 @@ bool compare_lists(const List& list1, const List& list2, Traits& traits) { Equal_pred eq(traits); auto rc = std::equal(list1.begin(), list1.end(), list2.begin(), eq); if (! rc) { - std::cerr << "Error: The curves do not match\n"; + std::cerr << "Error: The lists do not match\n"; return false; } diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/big_overlap.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/big_overlap.txt new file mode 100644 index 000000000000..60cda75d7fd1 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/big_overlap.txt @@ -0,0 +1,31 @@ +# No. of input polylines followed by polylines +2 +5 0 0 20 0 30 20 40 0 60 0 +6 10 10 25 10 30 20 40 0 50 0 50 -10 +# No. of output polylines followed by polylines +5 +3 0 0 20 0 25 10 +2 10 10 25 10 +2 50 0 50 -10 +4 25 10 30 20 40 0 50 0 +2 50 0 60 0 +# No. of output points followed by points +6 +0 0 +10 10 +25 10 +50 -10 +50 0 +60 0 +# No. of intersection points followed by points +2 +25 10 +50 0 +# No. of output polylines with overlaps followed by polylines +6 +3 0 0 20 0 25 10 +2 10 10 25 10 +2 50 0 50 -10 +4 25 10 30 20 40 0 50 0 +4 25 10 30 20 40 0 50 0 +2 50 0 60 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp b/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp index 7af2076d7a8d..d85bf455ccf4 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp +++ b/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp @@ -146,76 +146,70 @@ int main(int argc, char* argv[]) { Curves curves; if (! read_curves(inp, curves, tr)) return -1; - // get subcurves w/o overlapping + // Test subcurves w/o overlapping X_monotone_curves curves_no_overlap_out; CGAL::compute_subcurves(curves.begin(), curves.end(), std::back_inserter(curves_no_overlap_out), false, tr); - // get subcurves w/ overlapping - X_monotone_curves curves_with_overlap_out; - CGAL::compute_subcurves(curves.begin(), curves.end(), - std::back_inserter(curves_with_overlap_out), - true, tr); - - /*std::copy(curves_no_overlap_out.begin(), - curves_no_overlap_out.end(), - std::ostream_iterator(std::cout, "\n")); - std::cout<<"\n\n*******************\n\n"; - - std::copy(curves_with_overlap_out.begin(), - curves_with_overlap_out.end(), - std::ostream_iterator(std::cout, "\n")); - return 0;*/ - - //std::cout << mylist1.size() << " curves\n"; + X_monotone_curves curves_no_overlap; + if (! read_xcurves(inp, curves_no_overlap, tr)) return -1; + if (! compare_lists(curves_no_overlap_out, curves_no_overlap, tr)) { + std::cerr << "Curves w/o overlapping do not match!\n"; + for (const auto& xcv : curves_no_overlap_out) std::cerr << xcv << std::endl; + return -1; + } - // get intersection points (with endpoints) + // Test intersection points (with endpoints) Points points_with_ends_out; CGAL::compute_intersection_points(curves.begin(), curves.end(), std::back_inserter(points_with_ends_out), true, tr); + Points points_with_ends; + if (! read_points(inp, points_with_ends, tr)) return -1; + + if (! compare_lists(points_with_ends_out, points_with_ends, tr)) { + std::cerr << "Endpoints do not match!\n"; + for (const auto& p : points_with_ends_out) std::cerr << p << std::endl; + return -1; + } - // get intersection points w/o end points + // Test intersection points w/o end points Points points_without_ends_out; CGAL::compute_intersection_points(curves.begin(), curves.end(), std::back_inserter(points_without_ends_out), false, tr); - std::cout << points_without_ends_out.size() - << " points_without_ends_out(size)\n"; - - // check the do_curves_intersecting method - bool do_intersect_out = - CGAL::do_curves_intersect(curves.begin(), curves.end()); - - // read curves and points from file - X_monotone_curves curves_no_overlap; - if (! read_xcurves(inp, curves_no_overlap, tr)) return -1; - - Points points_with_ends; - if (! read_points(inp, points_with_ends, tr)) return -1; - Points points_without_ends; if (! read_points(inp, points_without_ends, tr)) return -1; - X_monotone_curves curves_with_overlap; - if (! read_xcurves(inp, curves_with_overlap, tr)) return -1; - - if (! compare_lists(curves_no_overlap_out, curves_no_overlap, tr)) + if (! compare_lists(points_without_ends_out, points_without_ends, tr)) { + std::cerr << "Intersection points do not match!\n"; + for (const auto& p : points_without_ends_out) std::cerr << p << std::endl; return -1; + } - if (! compare_lists(curves_with_overlap_out, curves_with_overlap, tr)) - return -1; + // Test subcurves w/ overlapping + X_monotone_curves curves_with_overlap_out; + CGAL::compute_subcurves(curves.begin(), curves.end(), + std::back_inserter(curves_with_overlap_out), + true, tr); - if (! compare_lists(points_with_ends_out, points_with_ends, tr)) - return -1; + X_monotone_curves curves_with_overlap; + if (! read_xcurves(inp, curves_with_overlap, tr)) return -1; - if (! compare_lists(points_without_ends_out, points_without_ends, tr)) + if (! compare_lists(curves_with_overlap_out, curves_with_overlap, tr)) { + std::cerr << "Curves w/ overlapping do not match!\n"; + for (const auto& xcv : curves_with_overlap_out) std::cerr << xcv << std::endl; return -1; + } + + // Test the do_curves_intersecting method + bool do_intersect_out = + CGAL::do_curves_intersect(curves.begin(), curves.end()); bool do_intersect = false; if ((points_without_ends.size() != 0) || @@ -227,7 +221,7 @@ int main(int argc, char* argv[]) { return -1; } - std::cout << "OK\n"; + std::cout << "Passed\n"; return 0; } @@ -261,23 +255,27 @@ bool read_curves_(std::ifstream& inp, Curves_& curves, const Traits& traits, const Ctr& ctr) { int count; inp >> skip_comment >> count; - std::cout << "read_curves " << count << "\n"; + // std::cout << "read_curves " << count << "\n"; for (int i = 0; i < count; ++i) { Points points; auto rc = read_points(inp, points, traits); if (! rc) return false; auto cv = ctr(points.begin(), points.end()); - std::cout << cv << "\n"; + // std::cout << cv << "\n"; curves.push_back(cv); } return true; } +/*! Read curves. + */ bool read_curves(std::ifstream& inp, Curves& curves, const Traits& traits) { auto ctr_cv = traits.construct_curve_2_object(); return read_curves_(inp, curves, traits, ctr_cv); } +/*! Read x-monotone curves. + */ bool read_xcurves(std::ifstream& inp, X_monotone_curves& xcurves, const Traits& traits) { auto ctr_xcv = traits.construct_x_monotone_curve_2_object(); @@ -293,13 +291,13 @@ bool read_points(std::ifstream& inp, Points& points, const Traits&) { inp >> skip_comment >> count; char ch; - std::cout << "read_points " << count << "\n"; + // std::cout << "read_points " << count << "\n"; for (int i = 0; i < count; i++) { NT x, y; inp >> skip_comment >> x >> y; Point_2 p(x, y); + // std::cout << p << "\n"; points.push_back(p); - std::cout << p << "\n"; } return true; } From 28c669dd9c24a09391d077f2adaab85b64811520 Mon Sep 17 00:00:00 2001 From: Efi Fogel Date: Sun, 28 May 2023 23:41:37 +0300 Subject: [PATCH 062/329] 1st revision --- .../Surface_sweep_2/DATA/polylines/test00.txt | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/test00.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/test00.txt b/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/test00.txt new file mode 100644 index 000000000000..a024e6ccf8f4 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/test00.txt @@ -0,0 +1,56 @@ +# No. of input polylines followed by polylines +4 +3 0 1 1 0 4 0 +3 1 1 2 0 8 0 +3 1 2 3 0 6 0 +3 4 1 5 0 7 0 +# No. of output polylines followed by polylines +10 +3 0 1 1 0 2 0 +2 1 1 2 0 +2 2 0 3 0 +2 1 2 3 0 +2 3 0 4 0 +2 4 0 5 0 +2 4 1 5 0 +2 5 0 6 0 +2 6 0 7 0 +2 7 0 8 0 +# No. of output points followed by points +11 +0 1 +1 1 +1 2 +2 0 +3 0 +4 0 +4 1 +5 0 +6 0 +7 0 +8 0 +# No. of intersection points followed by points +4 +2 0 +4 0 +6 0 +7 0 +# No. of output polylines with overlaps followed by polylines +17 +3 0 1 1 0 2 0 +2 1 1 2 0 +2 2 0 3 0 +2 2 0 3 0 +2 1 2 3 0 +2 3 0 4 0 +2 3 0 4 0 +2 3 0 4 0 +2 4 0 5 0 +2 4 0 5 0 +2 4 1 5 0 +2 5 0 6 0 +2 5 0 6 0 +2 5 0 6 0 +2 6 0 7 0 +2 6 0 7 0 +2 7 0 8 0 From ebdada0b29d73308d2f80b40ec76a8901a43af02 Mon Sep 17 00:00:00 2001 From: Efi Fogel Date: Sun, 28 May 2023 23:52:17 +0300 Subject: [PATCH 063/329] Updated (renamed DATA => data) --- .../test/Surface_sweep_2/CMakeLists.txt | 11 ++--- .../{DATA => data}/conics/con01.txt | 0 .../{DATA => data}/conics/con02.txt | 0 .../{DATA => data}/conics/con03.txt | 0 .../{DATA => data}/conics/con04.txt | 0 .../{DATA => data}/conics/con05.txt | 0 .../{DATA => data}/conics/con06.txt | 0 .../{DATA => data}/conics/con07.txt | 0 .../{DATA => data}/conics/con08.txt | 0 .../{DATA => data}/conics/con09.txt | 0 .../{DATA => data}/conics/con10.txt | 0 .../{DATA => data}/polylines/big_overlap | 0 .../{DATA => data}/polylines/big_overlap.txt | 0 .../{DATA => data}/polylines/big_overlap2 | 0 .../{DATA => data}/polylines/closed_polyline | 0 .../{DATA => data}/polylines/collinears | 0 .../polylines/edge_vertex_intersection | 0 .../polylines/endpoint_intersection | 0 .../{DATA => data}/polylines/partial_overlap | 0 .../{DATA => data}/polylines/partial_overlap2 | 0 .../{DATA => data}/polylines/segment_overlap | 0 .../{DATA => data}/polylines/self_cut | 0 .../polylines/simple_intersection | 0 .../{DATA => data}/polylines/test00.txt | 0 .../{DATA => data}/polylines/total_overlap | 0 .../{DATA => data}/polylines/triangle | 0 .../{DATA => data}/polylines/two_segments | 0 .../polylines/vertex_intersection | 0 .../{DATA => data}/polylines/vertical_segment | 0 .../segment_circles/edge_vertex_intersection | 0 .../segment_circles/segs_and_circles | 0 .../segment_circles/simple_intersection | 0 .../{DATA => data}/segment_circles/triangle | 0 .../segment_circles/two_segments | 0 .../segment_circles/vertex_intersection | 0 .../segment_circles/vertical_segment | 0 .../{DATA => data}/segments/H_degeneracy | 0 .../segments/edge_vertex_intersection | 0 .../segments/simple_intersection | 0 .../{DATA => data}/segments/star_4 | 0 .../{DATA => data}/segments/triangle | 0 .../{DATA => data}/segments/two_segments | 0 .../segments/vertex_intersection | 0 .../{DATA => data}/segments/vertical_segment | 0 .../{DATA => data}/segments_tight/test00.txt | 0 .../{DATA => data}/segments_tight/test01.txt | 0 .../{DATA => data}/segments_tight/test02.txt | 0 .../{DATA => data}/segments_tight/test03.txt | 0 .../{DATA => data}/segments_tight/test04.txt | 0 .../{DATA => data}/segments_tight/test05.txt | 0 .../{DATA => data}/segments_tight/test06.txt | 0 .../{DATA => data}/segments_tight/test07.txt | 0 .../{DATA => data}/segments_tight/test08.txt | 0 .../{DATA => data}/segments_tight/test09.txt | 0 .../{DATA => data}/segments_tight/test10.txt | 0 .../{DATA => data}/segments_tight/test11.txt | 0 .../{DATA => data}/segments_tight/test12.txt | 0 .../{DATA => data}/segments_tight/test13.txt | 0 .../{DATA => data}/segments_tight/test14.txt | 0 .../{DATA => data}/segments_tight/test15.txt | 0 .../{DATA => data}/segments_tight/test16.txt | 0 .../{DATA => data}/segments_tight/test17.txt | 0 .../{DATA => data}/segments_tight/test18.txt | 0 .../{DATA => data}/segments_tight/test19.txt | 0 .../{DATA => data}/segments_tight/test20.txt | 0 .../{DATA => data}/segments_tight/test21.txt | 0 .../{DATA => data}/segments_tight/test22.txt | 0 .../{DATA => data}/segments_tight/test23.txt | 0 .../{DATA => data}/segments_tight/test24.txt | 0 .../{DATA => data}/segments_tight/test25.txt | 0 .../{DATA => data}/segments_tight/test26.txt | 0 .../{DATA => data}/segments_tight/test27.txt | 0 .../{DATA => data}/segments_tight/test28.txt | 0 .../{DATA => data}/segments_tight/test29.txt | 0 .../{DATA => data}/segments_tight/test30.txt | 0 .../{DATA => data}/segments_tight/test31.txt | 0 .../{DATA => data}/segments_tight/test32.txt | 0 .../{DATA => data}/segments_tight/test33.txt | 0 .../{DATA => data}/segments_tight/test34.txt | 0 .../{DATA => data}/segments_tight/test35.txt | 0 .../{DATA => data}/segments_tight/test36.txt | 0 .../{DATA => data}/segments_tight/test37.txt | 0 .../{DATA => data}/segments_tight/test40.txt | 0 .../{DATA => data}/segments_tight/test41.txt | 0 .../{DATA => data}/segments_tight/test42.txt | 0 .../{DATA => data}/segments_tight/test43.txt | 0 .../{DATA => data}/segments_tight/test44.txt | 0 .../{DATA => data}/segments_tight/test45.txt | 0 .../{DATA => data}/segments_tight/test46.txt | 0 .../{DATA => data}/segments_tight/test47.txt | 0 .../{DATA => data}/segments_tight/test48.txt | 0 .../{DATA => data}/segments_tight/test49.txt | 0 .../{DATA => data}/segments_tight/test50.txt | 0 .../{DATA => data}/segments_tight/test51.txt | 0 .../{DATA => data}/segments_tight/test52.txt | 0 .../{DATA => data}/segments_tight/test53.txt | 0 .../{DATA => data}/segments_tight/test54.txt | 0 .../{DATA => data}/segments_tight/test55.txt | 0 .../{DATA => data}/segments_tight/test56.txt | 0 .../{DATA => data}/segments_tight/test60.txt | 0 .../{DATA => data}/segments_tight/test61.txt | 0 .../{DATA => data}/segments_tight/test62.txt | 0 .../{DATA => data}/segments_tight/test63.txt | 0 .../{DATA => data}/segments_tight/test64.txt | 0 .../{DATA => data}/segments_tight/test65.txt | 0 .../{DATA => data}/segments_tight/test66.txt | 0 .../{DATA => data}/segments_tight/test67.txt | 0 .../{DATA => data}/segments_tight/test68.txt | 0 .../{DATA => data}/segments_tight/test69.txt | 0 .../{DATA => data}/segments_tight/test70.txt | 0 .../{DATA => data}/segments_tight/test71.txt | 0 .../{DATA => data}/segments_tight/test72.txt | 0 .../{DATA => data}/segments_tight/test73.txt | 0 .../{DATA => data}/segments_tight/test74.txt | 0 .../{DATA => data}/segments_tight/test75.txt | 0 .../{DATA => data}/segments_tight/test76.txt | 0 .../{DATA => data}/segments_tight/test77.txt | 0 .../{DATA => data}/segments_tight/test78.txt | 0 .../{DATA => data}/segments_tight/test79.txt | 0 .../{DATA => data}/segments_tight/test80.txt | 0 .../{DATA => data}/segments_tight/test81.txt | 0 .../{DATA => data}/segments_tight/test82.txt | 0 .../{DATA => data}/segments_tight/test83.txt | 0 .../{DATA => data}/segments_tight/test84.txt | 0 .../{DATA => data}/segments_tight/test85.txt | 0 .../{DATA => data}/segments_tight/test86.txt | 0 .../{DATA => data}/segments_tight/test87.txt | 0 .../{DATA => data}/segments_tight/test88.txt | 0 .../test/Surface_sweep_2/test_sweep.cpp | 44 ++++++++++++++----- 129 files changed, 38 insertions(+), 17 deletions(-) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/conics/con01.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/conics/con02.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/conics/con03.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/conics/con04.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/conics/con05.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/conics/con06.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/conics/con07.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/conics/con08.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/conics/con09.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/conics/con10.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/polylines/big_overlap (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/polylines/big_overlap.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/polylines/big_overlap2 (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/polylines/closed_polyline (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/polylines/collinears (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/polylines/edge_vertex_intersection (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/polylines/endpoint_intersection (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/polylines/partial_overlap (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/polylines/partial_overlap2 (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/polylines/segment_overlap (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/polylines/self_cut (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/polylines/simple_intersection (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/polylines/test00.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/polylines/total_overlap (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/polylines/triangle (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/polylines/two_segments (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/polylines/vertex_intersection (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/polylines/vertical_segment (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segment_circles/edge_vertex_intersection (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segment_circles/segs_and_circles (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segment_circles/simple_intersection (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segment_circles/triangle (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segment_circles/two_segments (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segment_circles/vertex_intersection (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segment_circles/vertical_segment (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments/H_degeneracy (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments/edge_vertex_intersection (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments/simple_intersection (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments/star_4 (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments/triangle (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments/two_segments (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments/vertex_intersection (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments/vertical_segment (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test00.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test01.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test02.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test03.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test04.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test05.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test06.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test07.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test08.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test09.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test10.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test11.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test12.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test13.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test14.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test15.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test16.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test17.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test18.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test19.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test20.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test21.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test22.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test23.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test24.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test25.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test26.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test27.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test28.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test29.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test30.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test31.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test32.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test33.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test34.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test35.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test36.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test37.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test40.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test41.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test42.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test43.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test44.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test45.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test46.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test47.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test48.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test49.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test50.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test51.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test52.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test53.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test54.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test55.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test56.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test60.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test61.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test62.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test63.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test64.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test65.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test66.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test67.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test68.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test69.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test70.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test71.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test72.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test73.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test74.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test75.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test76.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test77.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test78.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test79.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test80.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test81.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test82.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test83.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test84.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test85.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test86.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test87.txt (100%) rename Surface_sweep_2/test/Surface_sweep_2/{DATA => data}/segments_tight/test88.txt (100%) diff --git a/Surface_sweep_2/test/Surface_sweep_2/CMakeLists.txt b/Surface_sweep_2/test/Surface_sweep_2/CMakeLists.txt index 3471c16f7155..ac96a58ca421 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/CMakeLists.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/CMakeLists.txt @@ -9,6 +9,7 @@ find_package(CGAL REQUIRED COMPONENTS Core) set(CGAL_SEGMENT_TRAITS 1) set(CGAL_POLYLINE_TRAITS 11) set(CGAL_CONIC_TRAITS 21) +set(CGAL_POLYCONIC_TRAITS 22) set(TRAP 1) # Trapezoidal decomposition set(NAIVE 2) @@ -46,9 +47,9 @@ function(compile_and_run_sweep name source_file point_location traits data_set) endforeach() endfunction() -# compile_and_run_sweep(test_sweep test_sweep.cpp ${NAIVE} ${CGAL_SEGMENT_TRAITS} -# "DATA/segments_tight") -# compile_and_run_sweep(test_sweep_conic test_sweep_conic.cpp ${NAIVE} -# ${CGAL_CONIC_TRAITS} "DATA/conics") +compile_and_run_sweep(test_sweep test_sweep.cpp ${NAIVE} + ${CGAL_SEGMENT_TRAITS} "data/segments_tight") +compile_and_run_sweep(test_sweep_conic test_sweep_conic.cpp ${NAIVE} + ${CGAL_CONIC_TRAITS} "data/conics") compile_and_run_sweep(test_sweep_polyline test_sweep.cpp ${NAIVE} - ${CGAL_POLYLINE_TRAITS} "DATA/polylines") + ${CGAL_POLYLINE_TRAITS} "data/polylines") diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con01.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con01.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con01.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/conics/con01.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con02.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con02.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con02.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/conics/con02.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con03.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con03.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con03.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/conics/con03.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con04.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con04.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con04.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/conics/con04.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con05.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con05.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con05.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/conics/con05.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con06.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con06.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con06.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/conics/con06.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con07.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con07.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con07.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/conics/con07.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con08.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con08.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con08.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/conics/con08.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con09.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con09.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con09.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/conics/con09.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con10.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con10.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/conics/con10.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/conics/con10.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/big_overlap b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/big_overlap similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/big_overlap rename to Surface_sweep_2/test/Surface_sweep_2/data/polylines/big_overlap diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/big_overlap.txt b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/big_overlap.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/big_overlap.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/polylines/big_overlap.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/big_overlap2 b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/big_overlap2 similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/big_overlap2 rename to Surface_sweep_2/test/Surface_sweep_2/data/polylines/big_overlap2 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/closed_polyline b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/closed_polyline similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/closed_polyline rename to Surface_sweep_2/test/Surface_sweep_2/data/polylines/closed_polyline diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/collinears b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/collinears similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/collinears rename to Surface_sweep_2/test/Surface_sweep_2/data/polylines/collinears diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/edge_vertex_intersection b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/edge_vertex_intersection similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/edge_vertex_intersection rename to Surface_sweep_2/test/Surface_sweep_2/data/polylines/edge_vertex_intersection diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/endpoint_intersection b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/endpoint_intersection similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/endpoint_intersection rename to Surface_sweep_2/test/Surface_sweep_2/data/polylines/endpoint_intersection diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/partial_overlap b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/partial_overlap similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/partial_overlap rename to Surface_sweep_2/test/Surface_sweep_2/data/polylines/partial_overlap diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/partial_overlap2 b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/partial_overlap2 similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/partial_overlap2 rename to Surface_sweep_2/test/Surface_sweep_2/data/polylines/partial_overlap2 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/segment_overlap b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/segment_overlap similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/segment_overlap rename to Surface_sweep_2/test/Surface_sweep_2/data/polylines/segment_overlap diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/self_cut b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/self_cut similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/self_cut rename to Surface_sweep_2/test/Surface_sweep_2/data/polylines/self_cut diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/simple_intersection b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/simple_intersection similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/simple_intersection rename to Surface_sweep_2/test/Surface_sweep_2/data/polylines/simple_intersection diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/test00.txt b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/test00.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/test00.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/polylines/test00.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/total_overlap b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/total_overlap similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/total_overlap rename to Surface_sweep_2/test/Surface_sweep_2/data/polylines/total_overlap diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/triangle b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/triangle similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/triangle rename to Surface_sweep_2/test/Surface_sweep_2/data/polylines/triangle diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/two_segments b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/two_segments similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/two_segments rename to Surface_sweep_2/test/Surface_sweep_2/data/polylines/two_segments diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/vertex_intersection b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/vertex_intersection similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/vertex_intersection rename to Surface_sweep_2/test/Surface_sweep_2/data/polylines/vertex_intersection diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/vertical_segment b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/vertical_segment similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/polylines/vertical_segment rename to Surface_sweep_2/test/Surface_sweep_2/data/polylines/vertical_segment diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segment_circles/edge_vertex_intersection b/Surface_sweep_2/test/Surface_sweep_2/data/segment_circles/edge_vertex_intersection similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segment_circles/edge_vertex_intersection rename to Surface_sweep_2/test/Surface_sweep_2/data/segment_circles/edge_vertex_intersection diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segment_circles/segs_and_circles b/Surface_sweep_2/test/Surface_sweep_2/data/segment_circles/segs_and_circles similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segment_circles/segs_and_circles rename to Surface_sweep_2/test/Surface_sweep_2/data/segment_circles/segs_and_circles diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segment_circles/simple_intersection b/Surface_sweep_2/test/Surface_sweep_2/data/segment_circles/simple_intersection similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segment_circles/simple_intersection rename to Surface_sweep_2/test/Surface_sweep_2/data/segment_circles/simple_intersection diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segment_circles/triangle b/Surface_sweep_2/test/Surface_sweep_2/data/segment_circles/triangle similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segment_circles/triangle rename to Surface_sweep_2/test/Surface_sweep_2/data/segment_circles/triangle diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segment_circles/two_segments b/Surface_sweep_2/test/Surface_sweep_2/data/segment_circles/two_segments similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segment_circles/two_segments rename to Surface_sweep_2/test/Surface_sweep_2/data/segment_circles/two_segments diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segment_circles/vertex_intersection b/Surface_sweep_2/test/Surface_sweep_2/data/segment_circles/vertex_intersection similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segment_circles/vertex_intersection rename to Surface_sweep_2/test/Surface_sweep_2/data/segment_circles/vertex_intersection diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segment_circles/vertical_segment b/Surface_sweep_2/test/Surface_sweep_2/data/segment_circles/vertical_segment similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segment_circles/vertical_segment rename to Surface_sweep_2/test/Surface_sweep_2/data/segment_circles/vertical_segment diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments/H_degeneracy b/Surface_sweep_2/test/Surface_sweep_2/data/segments/H_degeneracy similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments/H_degeneracy rename to Surface_sweep_2/test/Surface_sweep_2/data/segments/H_degeneracy diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments/edge_vertex_intersection b/Surface_sweep_2/test/Surface_sweep_2/data/segments/edge_vertex_intersection similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments/edge_vertex_intersection rename to Surface_sweep_2/test/Surface_sweep_2/data/segments/edge_vertex_intersection diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments/simple_intersection b/Surface_sweep_2/test/Surface_sweep_2/data/segments/simple_intersection similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments/simple_intersection rename to Surface_sweep_2/test/Surface_sweep_2/data/segments/simple_intersection diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments/star_4 b/Surface_sweep_2/test/Surface_sweep_2/data/segments/star_4 similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments/star_4 rename to Surface_sweep_2/test/Surface_sweep_2/data/segments/star_4 diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments/triangle b/Surface_sweep_2/test/Surface_sweep_2/data/segments/triangle similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments/triangle rename to Surface_sweep_2/test/Surface_sweep_2/data/segments/triangle diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments/two_segments b/Surface_sweep_2/test/Surface_sweep_2/data/segments/two_segments similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments/two_segments rename to Surface_sweep_2/test/Surface_sweep_2/data/segments/two_segments diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments/vertex_intersection b/Surface_sweep_2/test/Surface_sweep_2/data/segments/vertex_intersection similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments/vertex_intersection rename to Surface_sweep_2/test/Surface_sweep_2/data/segments/vertex_intersection diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments/vertical_segment b/Surface_sweep_2/test/Surface_sweep_2/data/segments/vertical_segment similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments/vertical_segment rename to Surface_sweep_2/test/Surface_sweep_2/data/segments/vertical_segment diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test00.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test00.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test00.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test00.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test01.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test01.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test01.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test01.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test02.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test02.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test02.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test02.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test03.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test03.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test03.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test03.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test04.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test04.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test04.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test04.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test05.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test05.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test05.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test05.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test06.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test06.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test06.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test06.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test07.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test07.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test07.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test07.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test08.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test08.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test08.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test08.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test09.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test09.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test09.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test09.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test10.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test10.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test10.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test10.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test11.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test11.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test11.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test11.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test12.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test12.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test12.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test12.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test13.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test13.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test13.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test13.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test14.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test14.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test14.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test14.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test15.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test15.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test15.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test15.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test16.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test16.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test16.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test16.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test17.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test17.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test17.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test17.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test18.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test18.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test18.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test18.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test19.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test19.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test19.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test19.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test20.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test20.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test20.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test20.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test21.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test21.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test21.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test21.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test22.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test22.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test22.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test22.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test23.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test23.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test23.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test23.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test24.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test24.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test24.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test24.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test25.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test25.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test25.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test25.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test26.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test26.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test26.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test26.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test27.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test27.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test27.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test27.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test28.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test28.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test28.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test28.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test29.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test29.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test29.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test29.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test30.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test30.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test30.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test30.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test31.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test31.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test31.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test31.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test32.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test32.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test32.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test32.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test33.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test33.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test33.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test33.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test34.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test34.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test34.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test34.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test35.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test35.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test35.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test35.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test36.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test36.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test36.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test36.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test37.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test37.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test37.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test37.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test40.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test40.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test40.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test40.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test41.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test41.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test41.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test41.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test42.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test42.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test42.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test42.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test43.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test43.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test43.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test43.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test44.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test44.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test44.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test44.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test45.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test45.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test45.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test45.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test46.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test46.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test46.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test46.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test47.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test47.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test47.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test47.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test48.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test48.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test48.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test48.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test49.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test49.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test49.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test49.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test50.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test50.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test50.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test50.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test51.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test51.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test51.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test51.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test52.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test52.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test52.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test52.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test53.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test53.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test53.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test53.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test54.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test54.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test54.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test54.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test55.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test55.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test55.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test55.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test56.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test56.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test56.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test56.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test60.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test60.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test60.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test60.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test61.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test61.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test61.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test61.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test62.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test62.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test62.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test62.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test63.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test63.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test63.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test63.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test64.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test64.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test64.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test64.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test65.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test65.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test65.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test65.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test66.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test66.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test66.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test66.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test67.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test67.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test67.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test67.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test68.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test68.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test68.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test68.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test69.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test69.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test69.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test69.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test70.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test70.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test70.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test70.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test71.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test71.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test71.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test71.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test72.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test72.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test72.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test72.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test73.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test73.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test73.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test73.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test74.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test74.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test74.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test74.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test75.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test75.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test75.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test75.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test76.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test76.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test76.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test76.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test77.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test77.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test77.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test77.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test78.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test78.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test78.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test78.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test79.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test79.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test79.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test79.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test80.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test80.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test80.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test80.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test81.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test81.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test81.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test81.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test82.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test82.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test82.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test82.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test83.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test83.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test83.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test83.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test84.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test84.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test84.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test84.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test85.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test85.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test85.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test85.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test86.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test86.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test86.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test86.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test87.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test87.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test87.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test87.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test88.txt b/Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test88.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/DATA/segments_tight/test88.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/segments_tight/test88.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp b/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp index d85bf455ccf4..97265afa626b 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp +++ b/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp @@ -63,9 +63,11 @@ int main() { #elif CGAL_ARR_TEST_TRAITS == CGAL_CONIC_TRAITS #include #include +#include #elif CGAL_ARR_TEST_TRAITS == CGAL_POLYCONIC_TRAITS #include #include +#include #include #else #error No traits defined for test @@ -79,22 +81,39 @@ int main() { #include "Compare_curves.h" #if CGAL_ARR_TEST_TRAITS == CGAL_SEGMENT_TRAITS - typedef CGAL::Gmpq NT; - typedef CGAL::Cartesian Kernel; - typedef CGAL::Arr_segment_traits_2 Traits; +typedef CGAL::Gmpq NT; +typedef CGAL::Cartesian Kernel; +typedef CGAL::Arr_segment_traits_2 Traits; #elif CGAL_ARR_TEST_TRAITS == CGAL_POLYLINE_TRAITS - typedef CGAL::Gmpq NT; - typedef CGAL::Cartesian Kernel; - typedef CGAL::Arr_segment_traits_2 Seg_traits; - typedef CGAL::Arr_polyline_traits_2 Traits; +typedef CGAL::Gmpq NT; +typedef CGAL::Cartesian Kernel; +typedef CGAL::Arr_segment_traits_2 Seg_traits; +typedef CGAL::Arr_polyline_traits_2 Traits; #elif CGAL_ARR_TEST_TRAITS == CGAL_CONIC_TRAITS - typedef CGAL::Arr_conic_traits_2 Traits; - +typedef CGAL::CORE_algebraic_number_traits Nt_traits; +typedef Nt_traits::Rational Rational; +typedef Nt_traits::Algebraic Algebraic; +typedef CGAL::Cartesian Rat_kernel; +typedef Rat_kernel::Point_2 Rat_point_2; +typedef Rat_kernel::Segment_2 Rat_segment_2; +typedef Rat_kernel::Circle_2 Rat_circle_2; +typedef CGAL::Cartesian Alg_kernel; +typedef CGAL::Arr_conic_traits_2 + Traits_2; #elif CGAL_ARR_TEST_TRAITS == CGAL_POLYCURVE_TRAITS - typedef CGAL::Arr_conic_traits_2 Conic_traits; - typedef CGAL::Arr_polycurve_traits_2 Traits; +typedef CGAL::CORE_algebraic_number_traits Nt_traits; +typedef Nt_traits::Rational Rational; +typedef Nt_traits::Algebraic Algebraic; +typedef CGAL::Cartesian Rat_kernel; +typedef Rat_kernel::Point_2 Rat_point_2; +typedef Rat_kernel::Segment_2 Rat_segment_2; +typedef Rat_kernel::Circle_2 Rat_circle_2; +typedef CGAL::Cartesian Alg_kernel; +typedef CGAL::Arr_conic_traits_2 + Conic_traits; +typedef CGAL::Arr_polycurve_traits_2 Traits; #endif @@ -203,7 +222,8 @@ int main(int argc, char* argv[]) { if (! compare_lists(curves_with_overlap_out, curves_with_overlap, tr)) { std::cerr << "Curves w/ overlapping do not match!\n"; - for (const auto& xcv : curves_with_overlap_out) std::cerr << xcv << std::endl; + for (const auto& xcv : curves_with_overlap_out) + std::cerr << xcv << std::endl; return -1; } From 1c1ed53c76457c841dab781f76f3eacfb299071c Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 30 May 2023 08:03:29 +0100 Subject: [PATCH 064/329] Parallelize deduplicate_segments() --- .../Polygon_mesh_processing/autorefinement.h | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index e862d6839609..ad88f3a6aceb 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -1178,7 +1178,8 @@ void autorefine_soup_output(const PointRange& input_points, std::vector< std::vector > all_in_triangle_ids(triangles.size()); CGAL_PMP_AUTOREFINE_VERBOSE("compute intersections"); - + Real_timer t; + t.start(); std::set > intersecting_triangles; //TODO: PARALLEL_FOR #2 for (const Pair_of_triangle_ids& p : si_pairs) @@ -1225,16 +1226,22 @@ void autorefine_soup_output(const PointRange& input_points, intersecting_triangles.insert(CGAL::make_sorted_pair(i1, i2)); } } + std::cout << t.time() << " sec. for #2" << std::endl; #ifdef DEDUPLICATE_SEGMENTS // deduplicate inserted segments //TODO: PARALLEL_FOR #3 + Real_timer t3; + t3.start(); std::vector>> all_segments_ids(all_segments.size()); - for(std::size_t ti=0; ti point_id_map; + + auto get_point_id = [&](const typename EK::Point_3& pt) { auto insert_res = point_id_map.insert(std::make_pair(pt, all_points[ti].size())); @@ -1243,6 +1250,7 @@ void autorefine_soup_output(const PointRange& input_points, return insert_res.first->second; }; + if (!all_points[ti].empty()) { std::vector tmp; @@ -1271,9 +1279,25 @@ void autorefine_soup_output(const PointRange& input_points, if (all_segments_ids[ti].size()!=nbs) filtered_in_triangle_ids.swap(all_in_triangle_ids[ti]); } + }; + +#ifdef CGAL_LINKED_WITH_TBB + tbb::parallel_for(tbb::blocked_range(0, triangles.size()), + [&](const tbb::blocked_range& r) { + for (size_t ti = r.begin(); ti != r.end(); ++ti) + deduplicate_inserted_segments(ti); + } + ); +#else + for (std::size_t ti = 0; ti < triangles.size(); ++ti) { + deduplicate_inserted_segments(ti); } #endif + + std::cout << t.time() << " sec. for #3" << std::endl; +#endif + CGAL_PMP_AUTOREFINE_VERBOSE("triangulate faces"); // now refine triangles #ifdef CGAL_LINKED_WITH_TBB From 2695834873b41052bb2b8669d74e93de41fb89ea Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 30 May 2023 08:10:06 +0100 Subject: [PATCH 065/329] Rename lambdas --- .../Polygon_mesh_processing/soup_autorefinement.cpp | 2 +- .../CGAL/Polygon_mesh_processing/autorefinement.h | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp index f12306689485..d5ebeb78c3f5 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp @@ -36,7 +36,7 @@ int main(int argc, char** argv) std::vector> output_triangles; PMP::autorefine_soup_output(input_points, input_triangles, output_points, output_triangles); std::cout << "#points = " << output_points.size() << " and #triangles = " << output_triangles.size() << " in " << t.time() << " sec." << std::endl; - // CGAL::IO::write_polygon_soup("autorefined.off", output_points, output_triangles, CGAL::parameters::stream_precision(17)); + CGAL::IO::write_polygon_soup("autorefined.off", output_points, output_triangles, CGAL::parameters::stream_precision(17)); return 0; } diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index ad88f3a6aceb..40a3ed87cbc7 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -1226,7 +1226,7 @@ void autorefine_soup_output(const PointRange& input_points, intersecting_triangles.insert(CGAL::make_sorted_pair(i1, i2)); } } - std::cout << t.time() << " sec. for #2" << std::endl; + std::cout << t.time() << " sec. for compute_intersections()" << std::endl; #ifdef DEDUPLICATE_SEGMENTS // deduplicate inserted segments @@ -1295,7 +1295,7 @@ void autorefine_soup_output(const PointRange& input_points, #endif - std::cout << t.time() << " sec. for #3" << std::endl; + std::cout << t.time() << " sec. for deduplicate_segments()" << std::endl; #endif CGAL_PMP_AUTOREFINE_VERBOSE("triangulate faces"); @@ -1311,7 +1311,7 @@ void autorefine_soup_output(const PointRange& input_points, #endif - auto func = [&](std::size_t ti) + auto refine_triangles = [&](std::size_t ti) { if (all_segments[ti].empty() && all_points[ti].empty()) new_triangles.push_back(triangles[ti]); @@ -1351,12 +1351,12 @@ void autorefine_soup_output(const PointRange& input_points, tbb::parallel_for(tbb::blocked_range(0, triangles.size()), [&](const tbb::blocked_range& r) { for (size_t ti = r.begin(); ti != r.end(); ++ti) - func(ti); + refine_triangles(ti); } ); #else for (std::size_t ti = 0; ti < triangles.size(); ++ti) { - func(ti); + refine_triangles(ti); } #endif From e34a79864a78c7a19402af066698881d54a22d28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 30 May 2023 10:13:28 +0200 Subject: [PATCH 066/329] debug macro --- .../Polygon_mesh_processing/autorefinement.h | 38 ++++++++++++++++--- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 40a3ed87cbc7..eb24d60804a7 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -48,15 +48,20 @@ #define TEST_RESOLVE_INTERSECTION #define DEDUPLICATE_SEGMENTS +#define USE_DEBUG_PARALLEL_TIMERS //#define DEBUG_COUNTERS //#define USE_FIXED_PROJECTION_TRAITS //#define DEBUG_DEPTH +#ifdef USE_DEBUG_PARALLEL_TIMERS +#include +#endif + #ifdef USE_FIXED_PROJECTION_TRAITS #include #endif -#ifdef DEBUG_COUNTERS +#if defined(DEBUG_COUNTERS) || defined(USE_DEBUG_PARALLEL_TIMERS) #include #endif @@ -1178,8 +1183,10 @@ void autorefine_soup_output(const PointRange& input_points, std::vector< std::vector > all_in_triangle_ids(triangles.size()); CGAL_PMP_AUTOREFINE_VERBOSE("compute intersections"); +#ifdef USE_DEBUG_PARALLEL_TIMERS Real_timer t; t.start(); +#endif std::set > intersecting_triangles; //TODO: PARALLEL_FOR #2 for (const Pair_of_triangle_ids& p : si_pairs) @@ -1226,7 +1233,9 @@ void autorefine_soup_output(const PointRange& input_points, intersecting_triangles.insert(CGAL::make_sorted_pair(i1, i2)); } } - std::cout << t.time() << " sec. for compute_intersections()" << std::endl; +#ifdef USE_DEBUG_PARALLEL_TIMERS + std::cout << t.time() << " sec. for #2" << std::endl; +#endif #ifdef DEDUPLICATE_SEGMENTS // deduplicate inserted segments @@ -1294,8 +1303,9 @@ void autorefine_soup_output(const PointRange& input_points, } #endif - - std::cout << t.time() << " sec. for deduplicate_segments()" << std::endl; +#ifdef USE_DEBUG_PARALLEL_TIMERS + std::cout << t.time() << " sec. for #3" << std::endl; +#endif #endif CGAL_PMP_AUTOREFINE_VERBOSE("triangulate faces"); @@ -1347,6 +1357,11 @@ void autorefine_soup_output(const PointRange& input_points, #endif }; + +#ifdef USE_DEBUG_PARALLEL_TIMERS + t.reset(); + t.start(); +#endif #ifdef CGAL_LINKED_WITH_TBB tbb::parallel_for(tbb::blocked_range(0, triangles.size()), [&](const tbb::blocked_range& r) { @@ -1360,7 +1375,11 @@ void autorefine_soup_output(const PointRange& input_points, } #endif - +#ifdef USE_DEBUG_PARALLEL_TIMERS + t.stop(); + std::cout << t.time() << " sec. for #1" << std::endl; + t.reset(); +#endif // brute force output: create a soup, orient and to-mesh CGAL_PMP_AUTOREFINE_VERBOSE("create output soup"); @@ -1408,10 +1427,19 @@ void autorefine_soup_output(const PointRange& input_points, // import refined triangles //TODO: PARALLEL_FOR #4 +#ifdef USE_DEBUG_PARALLEL_TIMERS + t.reset(); + t.start(); +#endif for (const std::array& t : new_triangles) { soup_triangles.emplace_back(CGAL::make_array(get_point_id(t[0]), get_point_id(t[1]), get_point_id(t[2]))); } +#ifdef USE_DEBUG_PARALLEL_TIMERS + t.stop(); + std::cout << t.time() << " sec. for #4" << std::endl; + t.reset(); +#endif #ifndef CGAL_NDEBUG CGAL_PMP_AUTOREFINE_VERBOSE("check soup"); From 3d6d9b3edce9890d2b0dae38c2d1231602f98411 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 30 May 2023 11:10:36 +0100 Subject: [PATCH 067/329] parallelize unique points --- .../Polygon_mesh_processing/autorefinement.h | 73 ++++++++++++++++++- 1 file changed, 70 insertions(+), 3 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index eb24d60804a7..e5f96d26c3bd 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -41,6 +41,7 @@ #ifdef CGAL_LINKED_WITH_TBB #include +#include #include #endif @@ -1386,11 +1387,18 @@ void autorefine_soup_output(const PointRange& input_points, Cartesian_converter to_input; // TODO: reuse the fact that maps per triangle are already sorted + +#ifdef CGAL_LINKED_WITH_TBB + tbb::concurrent_map point_id_map; +#else std::map point_id_map; +#endif + #if ! defined(CGAL_NDEBUG) || defined(CGAL_DEBUG_PMP_AUTOREFINE) std::vector exact_soup_points; #endif + /// Lambda get_point_id() auto get_point_id = [&](const typename EK::Point_3& pt) { auto insert_res = point_id_map.insert(std::make_pair(pt, soup_points.size())); @@ -1404,6 +1412,8 @@ void autorefine_soup_output(const PointRange& input_points, return insert_res.first->second; }; + + std::vector input_point_ids; input_point_ids.reserve(input_points.size()); for (const auto& p : input_points) @@ -1431,13 +1441,70 @@ void autorefine_soup_output(const PointRange& input_points, t.reset(); t.start(); #endif - for (const std::array& t : new_triangles) - { + + bool sequential = +#ifdef CGAL_LINKED_WITH_TBB + false; +#else + true; +#endif + + + std::size_t offset = soup_triangles.size(); + std::string mode; + if(sequential || new_triangles.size() < 100){ + mode = "sequential"; + soup_triangles.reserve(offset + new_triangles.size()); + for (const std::array& t : new_triangles) + { soup_triangles.emplace_back(CGAL::make_array(get_point_id(t[0]), get_point_id(t[1]), get_point_id(t[2]))); + } } + else { + mode = "parallel"; +#ifdef CGAL_LINKED_WITH_TBB + + tbb::concurrent_vector concurrent_soup_points; + /// Lambda concurrent_get_point_id() + auto concurrent_get_point_id = [&](const typename EK::Point_3& pt) + { + auto insert_res = point_id_map.insert(std::make_pair(pt, concurrent_soup_points.size())); + if (insert_res.second) + { + concurrent_soup_points.push_back(to_input(pt)); +#if ! defined(CGAL_NDEBUG) || defined(CGAL_DEBUG_PMP_AUTOREFINE) + exact_soup_points.push_back(pt); +#endif + } + return insert_res.first->second; + }; + + + soup_triangles.resize(offset + new_triangles.size()); + std::cout << "soup_triangles.size() = " << soup_triangles.size() << std::endl; + std::cout << "new_triangles.size() = " << new_triangles.size() << std::endl; + tbb::parallel_for(tbb::blocked_range(0, new_triangles.size()), + [&](const tbb::blocked_range& r) { + for (size_t ti = r.begin(); ti != r.end(); ++ti) { + if (offset + ti > soup_triangles.size()) { + std::cout << "ti = " << ti << std::endl; + } + const std::array& t = new_triangles[ti]; + soup_triangles[offset + ti] = CGAL::make_array(concurrent_get_point_id(t[0]), concurrent_get_point_id(t[1]), concurrent_get_point_id(t[2])); + } + } + ); + + soup_points.reserve(soup_points.size() + concurrent_soup_points.size()); + soup_points.insert(soup_points.end(), concurrent_soup_points.begin(), concurrent_soup_points.end()); + } +#endif + + + #ifdef USE_DEBUG_PARALLEL_TIMERS t.stop(); - std::cout << t.time() << " sec. for #4" << std::endl; + std::cout << t.time() << " sec. for #4 (" << mode << ")" << std::endl; t.reset(); #endif From a1fbd105dacff034f89de7db2b5086c2f24999ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 30 May 2023 15:07:13 +0200 Subject: [PATCH 068/329] add TODO --- .../include/CGAL/Polygon_mesh_processing/autorefinement.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index e5f96d26c3bd..16c788c22ecc 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -164,7 +164,9 @@ do_coplanar_segments_intersect(std::size_t pi, std::size_t qi, } } + // supporting_line intersects: points are coplanar + // TODO: check if we can write a dedicated predicate taking advantage of p,q being shared ::CGAL::Orientation pqr = cpl_orient(p, q, r); ::CGAL::Orientation pqs = cpl_orient(p, q, s); From 4b2f3e6ec7c10e0d7acf8d40608f4e548db7e091 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 30 May 2023 16:01:05 +0200 Subject: [PATCH 069/329] take np into account for concurrency --- .../soup_autorefinement.cpp | 4 +- .../Polygon_mesh_processing/autorefinement.h | 211 ++++++++++-------- 2 files changed, 115 insertions(+), 100 deletions(-) diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp index d5ebeb78c3f5..823c50974dcc 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp @@ -34,7 +34,9 @@ int main(int argc, char** argv) t.start(); std::vector output_points; std::vector> output_triangles; - PMP::autorefine_soup_output(input_points, input_triangles, output_points, output_triangles); + PMP::autorefine_soup_output(input_points, input_triangles, + output_points, output_triangles, + CGAL::parameters::concurrency_tag(CGAL::Parallel_if_available_tag())); std::cout << "#points = " << output_points.size() << " and #triangles = " << output_triangles.size() << " in " << t.time() << " sec." << std::endl; CGAL::IO::write_polygon_soup("autorefined.off", output_points, output_triangles, CGAL::parameters::stream_precision(17)); diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 16c788c22ecc..ae383a4af293 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -658,10 +658,11 @@ void collect_intersections(const std::array& t1, ////////////////////////////////// ////////////////////////////////// -template void generate_subtriangles(std::size_t ti, std::vector>& segments, @@ -669,11 +670,7 @@ void generate_subtriangles(std::size_t ti, const std::vector& in_triangle_ids, const std::set >& intersecting_triangles, const std::vector>& triangles, -#ifdef CGAL_LINKED_WITH_TBB - tbb::concurrent_vector>& new_triangles -#else - std::vector>& new_triangles -#endif + PointVector& new_triangles ) { // std::cout << "generate_subtriangles()\n"; @@ -1131,6 +1128,14 @@ void autorefine_soup_output(const PointRange& input_points, Sequential_tag > ::type Concurrency_tag; + constexpr bool parallel_execution = std::is_same_v; + +#ifndef CGAL_LINKED_WITH_TBB + CGAL_static_assertion_msg (parallel_execution, + "Parallel_tag is enabled but TBB is unavailable."); +#endif + + typedef std::size_t Input_TID; typedef std::pair Pair_of_triangle_ids; @@ -1294,16 +1299,20 @@ void autorefine_soup_output(const PointRange& input_points, }; #ifdef CGAL_LINKED_WITH_TBB - tbb::parallel_for(tbb::blocked_range(0, triangles.size()), - [&](const tbb::blocked_range& r) { - for (size_t ti = r.begin(); ti != r.end(); ++ti) - deduplicate_inserted_segments(ti); - } - ); -#else - for (std::size_t ti = 0; ti < triangles.size(); ++ti) { - deduplicate_inserted_segments(ti); + if (parallel_execution) + { + tbb::parallel_for(tbb::blocked_range(0, triangles.size()), + [&](const tbb::blocked_range& r) { + for (size_t ti = r.begin(); ti != r.end(); ++ti) + deduplicate_inserted_segments(ti); + } + ); } + else +#else + for (std::size_t ti = 0; ti < triangles.size(); ++ti) { + deduplicate_inserted_segments(ti); + } #endif #ifdef USE_DEBUG_PARALLEL_TIMERS @@ -1314,7 +1323,9 @@ void autorefine_soup_output(const PointRange& input_points, CGAL_PMP_AUTOREFINE_VERBOSE("triangulate faces"); // now refine triangles #ifdef CGAL_LINKED_WITH_TBB - tbb::concurrent_vector> new_triangles; + std::conditional_t>, + std::vector>> new_triangles; #else std::vector> new_triangles; #endif @@ -1325,40 +1336,40 @@ void autorefine_soup_output(const PointRange& input_points, auto refine_triangles = [&](std::size_t ti) + { + if (all_segments[ti].empty() && all_points[ti].empty()) + new_triangles.push_back(triangles[ti]); + else { - if (all_segments[ti].empty() && all_points[ti].empty()) - new_triangles.push_back(triangles[ti]); - else - { #ifdef USE_FIXED_PROJECTION_TRAITS - const std::array& t = triangles[ti]; - auto is_constant_in_dim = [](const std::array& t, int dim) - { - return t[0][dim] == t[1][dim] && t[0][dim] != t[2][dim]; - }; + const std::array& t = triangles[ti]; + auto is_constant_in_dim = [](const std::array& t, int dim) + { + return t[0][dim] == t[1][dim] && t[0][dim] != t[2][dim]; + }; - typename EK::Vector_3 orth = CGAL::normal(t[0], t[1], t[2]); // TODO::avoid construction? - int c = CGAL::abs(orth[0]) > CGAL::abs(orth[1]) ? 0 : 1; - c = CGAL::abs(orth[2]) > CGAL::abs(orth[c]) ? 2 : c; + typename EK::Vector_3 orth = CGAL::normal(t[0], t[1], t[2]); // TODO::avoid construction? + int c = CGAL::abs(orth[0]) > CGAL::abs(orth[1]) ? 0 : 1; + c = CGAL::abs(orth[2]) > CGAL::abs(orth[c]) ? 2 : c; - if (c == 0) { - autorefine_impl::generate_subtriangles(ti, all_segments[ti], all_points[ti], all_in_triangle_ids[ti], intersecting_triangles, triangles, new_triangles); - } - else if (c == 1) { - autorefine_impl::generate_subtriangles(ti, all_segments[ti], all_points[ti], all_in_triangle_ids[ti], intersecting_triangles, triangles, new_triangles); - } - else if (c == 2) { - autorefine_impl::generate_subtriangles(ti, all_segments[ti], all_points[ti], all_in_triangle_ids[ti], intersecting_triangles, triangles, new_triangles); - } + if (c == 0) { + autorefine_impl::generate_subtriangles(ti, all_segments[ti], all_points[ti], all_in_triangle_ids[ti], intersecting_triangles, triangles, new_triangles); + } + else if (c == 1) { + autorefine_impl::generate_subtriangles(ti, all_segments[ti], all_points[ti], all_in_triangle_ids[ti], intersecting_triangles, triangles, new_triangles); + } + else if (c == 2) { + autorefine_impl::generate_subtriangles(ti, all_segments[ti], all_points[ti], all_in_triangle_ids[ti], intersecting_triangles, triangles, new_triangles); + } #else - autorefine_impl::generate_subtriangles(ti, all_segments_ids[ti], all_points[ti], all_in_triangle_ids[ti], intersecting_triangles, triangles, new_triangles); + autorefine_impl::generate_subtriangles(ti, all_segments_ids[ti], all_points[ti], all_in_triangle_ids[ti], intersecting_triangles, triangles, new_triangles); #endif - } + } #ifdef USE_PROGRESS_DISPLAY - ++pd; + ++pd; #endif - }; + }; #ifdef USE_DEBUG_PARALLEL_TIMERS @@ -1366,16 +1377,20 @@ void autorefine_soup_output(const PointRange& input_points, t.start(); #endif #ifdef CGAL_LINKED_WITH_TBB - tbb::parallel_for(tbb::blocked_range(0, triangles.size()), - [&](const tbb::blocked_range& r) { - for (size_t ti = r.begin(); ti != r.end(); ++ti) - refine_triangles(ti); - } - ); -#else - for (std::size_t ti = 0; ti < triangles.size(); ++ti) { - refine_triangles(ti); + if (parallel_execution) + { + tbb::parallel_for(tbb::blocked_range(0, triangles.size()), + [&](const tbb::blocked_range& r) { + for (size_t ti = r.begin(); ti != r.end(); ++ti) + refine_triangles(ti); + } + ); } + else +#else + for (std::size_t ti = 0; ti < triangles.size(); ++ti) { + refine_triangles(ti); + } #endif #ifdef USE_DEBUG_PARALLEL_TIMERS @@ -1391,7 +1406,9 @@ void autorefine_soup_output(const PointRange& input_points, // TODO: reuse the fact that maps per triangle are already sorted #ifdef CGAL_LINKED_WITH_TBB - tbb::concurrent_map point_id_map; + std::conditional_t, + std::map> point_id_map; #else std::map point_id_map; #endif @@ -1444,63 +1461,59 @@ void autorefine_soup_output(const PointRange& input_points, t.start(); #endif - bool sequential = -#ifdef CGAL_LINKED_WITH_TBB - false; -#else - true; + std::size_t offset = soup_triangles.size(); +#ifdef USE_DEBUG_PARALLEL_TIMERS + std::string mode = "parallel"; #endif - - std::size_t offset = soup_triangles.size(); - std::string mode; - if(sequential || new_triangles.size() < 100){ - mode = "sequential"; - soup_triangles.reserve(offset + new_triangles.size()); - for (const std::array& t : new_triangles) - { - soup_triangles.emplace_back(CGAL::make_array(get_point_id(t[0]), get_point_id(t[1]), get_point_id(t[2]))); - } - } - else { - mode = "parallel"; + //TODO: 100 should be fined tune and depends on #threads #ifdef CGAL_LINKED_WITH_TBB - - tbb::concurrent_vector concurrent_soup_points; - /// Lambda concurrent_get_point_id() - auto concurrent_get_point_id = [&](const typename EK::Point_3& pt) - { - auto insert_res = point_id_map.insert(std::make_pair(pt, concurrent_soup_points.size())); - if (insert_res.second) - { - concurrent_soup_points.push_back(to_input(pt)); + if(parallel_execution && new_triangles.size() > 100) + { + tbb::concurrent_vector concurrent_soup_points; + /// Lambda concurrent_get_point_id() + auto concurrent_get_point_id = [&](const typename EK::Point_3& pt) + { + auto insert_res = point_id_map.insert(std::make_pair(pt, concurrent_soup_points.size())); + if (insert_res.second) + { + concurrent_soup_points.push_back(to_input(pt)); #if ! defined(CGAL_NDEBUG) || defined(CGAL_DEBUG_PMP_AUTOREFINE) - exact_soup_points.push_back(pt); + exact_soup_points.push_back(pt); #endif - } - return insert_res.first->second; - }; + } + return insert_res.first->second; + }; - soup_triangles.resize(offset + new_triangles.size()); - std::cout << "soup_triangles.size() = " << soup_triangles.size() << std::endl; - std::cout << "new_triangles.size() = " << new_triangles.size() << std::endl; - tbb::parallel_for(tbb::blocked_range(0, new_triangles.size()), - [&](const tbb::blocked_range& r) { - for (size_t ti = r.begin(); ti != r.end(); ++ti) { - if (offset + ti > soup_triangles.size()) { - std::cout << "ti = " << ti << std::endl; - } - const std::array& t = new_triangles[ti]; - soup_triangles[offset + ti] = CGAL::make_array(concurrent_get_point_id(t[0]), concurrent_get_point_id(t[1]), concurrent_get_point_id(t[2])); - } - } - ); + soup_triangles.resize(offset + new_triangles.size()); + std::cout << "soup_triangles.size() = " << soup_triangles.size() << std::endl; + std::cout << "new_triangles.size() = " << new_triangles.size() << std::endl; + tbb::parallel_for(tbb::blocked_range(0, new_triangles.size()), + [&](const tbb::blocked_range& r) { + for (size_t ti = r.begin(); ti != r.end(); ++ti) { + if (offset + ti > soup_triangles.size()) { + std::cout << "ti = " << ti << std::endl; + } + const std::array& t = new_triangles[ti]; + soup_triangles[offset + ti] = CGAL::make_array(concurrent_get_point_id(t[0]), concurrent_get_point_id(t[1]), concurrent_get_point_id(t[2])); + } + } + ); - soup_points.reserve(soup_points.size() + concurrent_soup_points.size()); - soup_points.insert(soup_points.end(), concurrent_soup_points.begin(), concurrent_soup_points.end()); + soup_points.reserve(soup_points.size() + concurrent_soup_points.size()); + soup_points.insert(soup_points.end(), concurrent_soup_points.begin(), concurrent_soup_points.end()); } + else +#endif + { +#ifdef USE_DEBUG_PARALLEL_TIMERS + mode = "sequential"; #endif + soup_triangles.reserve(offset + new_triangles.size()); + for (const std::array& t : new_triangles) + soup_triangles.emplace_back(CGAL::make_array(get_point_id(t[0]), get_point_id(t[1]), get_point_id(t[2]))); + } From 2e99b211b0e22579f76093eec62cfbb1697e17d9 Mon Sep 17 00:00:00 2001 From: Efi Fogel Date: Tue, 30 May 2023 17:10:58 +0300 Subject: [PATCH 070/329] Ported test_sweep_conic to test_sweep and fixed the conic test cases --- .../test/Surface_sweep_2/CMakeLists.txt | 2 +- .../Surface_sweep_2/data/conics/con01.txt | 1 - .../Surface_sweep_2/data/conics/con02.txt | 2 - .../Surface_sweep_2/data/conics/con03.txt | 5 - .../Surface_sweep_2/data/conics/con04.txt | 4 +- .../Surface_sweep_2/data/conics/con05.txt | 4 - .../Surface_sweep_2/data/conics/con06.txt | 1 - .../Surface_sweep_2/data/conics/con07.txt | 1 - .../Surface_sweep_2/data/conics/con08.txt | 2 - .../Surface_sweep_2/data/conics/con09.txt | 3 +- .../Surface_sweep_2/data/conics/con10.txt | 3 +- .../polylines/{big_overlap.txt => test01.txt} | 0 .../Surface_sweep_2/data/polylines/test02.txt | 51 +++ .../test/Surface_sweep_2/test_sweep.cpp | 430 +++++++++++++----- .../test/Surface_sweep_2/test_sweep_conic.cpp | 279 ------------ 15 files changed, 374 insertions(+), 414 deletions(-) rename Surface_sweep_2/test/Surface_sweep_2/data/polylines/{big_overlap.txt => test01.txt} (100%) create mode 100644 Surface_sweep_2/test/Surface_sweep_2/data/polylines/test02.txt delete mode 100644 Surface_sweep_2/test/Surface_sweep_2/test_sweep_conic.cpp diff --git a/Surface_sweep_2/test/Surface_sweep_2/CMakeLists.txt b/Surface_sweep_2/test/Surface_sweep_2/CMakeLists.txt index ac96a58ca421..9e96fa6dc1c7 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/CMakeLists.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/CMakeLists.txt @@ -49,7 +49,7 @@ endfunction() compile_and_run_sweep(test_sweep test_sweep.cpp ${NAIVE} ${CGAL_SEGMENT_TRAITS} "data/segments_tight") -compile_and_run_sweep(test_sweep_conic test_sweep_conic.cpp ${NAIVE} +compile_and_run_sweep(test_sweep_conic test_sweep.cpp ${NAIVE} ${CGAL_CONIC_TRAITS} "data/conics") compile_and_run_sweep(test_sweep_polyline test_sweep.cpp ${NAIVE} ${CGAL_POLYLINE_TRAITS} "data/polylines") diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con01.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con01.txt index a3464614b95f..1ff457efdb12 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con01.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con01.txt @@ -8,4 +8,3 @@ e 3 3 7 5 4 5 10 5 {1*x^2 + 1*y^2 + 0*xy + -14*x + -10*y + 65} : (4.66667,6.88562) --cw--> (10,5) 5 1 - diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con02.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con02.txt index f3ca4fd2817a..c404b51caa16 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con02.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con02.txt @@ -10,5 +10,3 @@ e 3 3 4 9 7 9 1 9 {1*x^2 + 1*y^2 + 0*xy + -8*x + -18*y + 88} : (7,9) --cw--> (5.45237,6.375) 6 2 - - diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con03.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con03.txt index 6ed5fcbab23b..599a66f9b14e 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con03.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con03.txt @@ -12,8 +12,3 @@ f 3 3 4 9 {1*x^2 + 1*y^2 + 0*xy + -8*x + -18*y + 88} : (1,9) --cw--> (7,9) 6 2 - - - - - diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con04.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con04.txt index d9a9875cdeb0..eb6a5c187110 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con04.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con04.txt @@ -12,6 +12,4 @@ f 1 1 3 2 {1*x^2 + 1*y^2 + 0*xy + -6*x + -4*y + 12} : (4,2) --cw--> (2,2) {1*x^2 + 1*y^2 + 0*xy + -6*x + -4*y + 12} : (2,2) --cw--> (4,2) 6 -0 - - +1 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con05.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con05.txt index 224bbc2397af..e68e06cb4881 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con05.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con05.txt @@ -12,7 +12,3 @@ f 3 3 4 9 {1*x^2 + 1*y^2 + 0*xy + -8*x + -18*y + 88} : (1,9) --cw--> (7,9) 6 2 - - - - diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con06.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con06.txt index 59ac8c5f663a..f82851db1c19 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con06.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con06.txt @@ -14,4 +14,3 @@ f 1 1 1 1 {1*x^2 + 1*y^2 + 0*xy + -4*x + 0*y + 3} : (2,1) --cw--> (3,0) 5 3 - diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con07.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con07.txt index 2b2253b55948..e884bd401544 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con07.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con07.txt @@ -10,4 +10,3 @@ f 2 2 2 2 {1*x^2 + 1*y^2 + 0*xy + -4*x + -4*y + 4} : (0,2) --cw--> (4,2) 5 1 - diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con08.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con08.txt index 54aae8118a02..630633469109 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con08.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con08.txt @@ -26,5 +26,3 @@ f 3 1 0 0 {4*x^2 + 25*y^2 + 0*xy + -16*x + 0*y + -84} : (2.75552,1.97704) --cw--> (7,0) 10 6 - - diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con09.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con09.txt index 543d1cff8130..6afc8ee809ca 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con09.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con09.txt @@ -121,5 +121,4 @@ f 1 1 -4 0 {1*x^2 + 1*y^2 + 0*xy + -8*x + 0*y + 0} : (8,0) --cw--> (4.5,-3.96863) {1*x^2 + 1*y^2 + 0*xy + -8*x + 0*y + 0} : (4.5,3.96863) --cw--> (8,0) 59 -34 - +41 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con10.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con10.txt index 51c9e3ffb2ae..d5f29cc31017 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con10.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con10.txt @@ -18,5 +18,4 @@ s 7 -2 3 2 {1*x^2 + 1*y^2 + 0*xy + -14*x + 2*y + 49} : (8,-1) --cw--> (7,-2) {1*x^2 + 1*y^2 + 0*xy + -14*x + 2*y + 49} : (7,0) --cw--> (8,-1) 8 -7 - +5 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/polylines/big_overlap.txt b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/test01.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/data/polylines/big_overlap.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/polylines/test01.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/polylines/test02.txt b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/test02.txt new file mode 100644 index 000000000000..7af88f99c7ad --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/test02.txt @@ -0,0 +1,51 @@ +# No. of input polylines followed by polylines +4 +2 0 0 7 0 +2 1 0 6 0 +2 2 0 5 0 +2 3 0 4 0 +# No. of output polylines followed by polylines +7 +2 0 0 1 0 +2 1 0 2 0 +2 2 0 3 0 +2 3 0 4 0 +2 4 0 5 0 +2 5 0 6 0 +2 6 0 7 0 +# No. of output points followed by points +8 +0 0 +1 0 +2 0 +3 0 +4 0 +5 0 +6 0 +7 0 +# No. of intersection points followed by points +6 +1 0 +2 0 +3 0 +4 0 +5 0 +6 0 +# No. of output polylines with overlaps followed by polylines +16 +2 0 0 1 0 +2 1 0 2 0 +2 1 0 2 0 +2 2 0 3 0 +2 2 0 3 0 +2 2 0 3 0 +2 3 0 4 0 +2 3 0 4 0 +2 3 0 4 0 +2 3 0 4 0 +2 4 0 5 0 +2 4 0 5 0 +2 4 0 5 0 +2 5 0 6 0 +2 5 0 6 0 +2 6 0 7 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp b/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp index 97265afa626b..cc11bbabac3f 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp +++ b/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp @@ -101,8 +101,8 @@ typedef Rat_kernel::Segment_2 Rat_segment_2; typedef Rat_kernel::Circle_2 Rat_circle_2; typedef CGAL::Cartesian Alg_kernel; typedef CGAL::Arr_conic_traits_2 - Traits_2; -#elif CGAL_ARR_TEST_TRAITS == CGAL_POLYCURVE_TRAITS + Traits; +#elif CGAL_ARR_TEST_TRAITS == CGAL_POLYCONIC_TRAITS typedef CGAL::CORE_algebraic_number_traits Nt_traits; typedef Nt_traits::Rational Rational; typedef Nt_traits::Algebraic Algebraic; @@ -125,10 +125,6 @@ typedef std::list Points; typedef std::list Curves; typedef std::list X_monotone_curves; -bool read_curves(std::ifstream& inp, Curves& curves, const Traits& traits); -bool read_xcurves(std::ifstream& inp, X_monotone_curves& xcurves, - const Traits& traits); -bool read_points(std::ifstream& inp, Points& points, const Traits& traits); bool curves_identical(X_monotone_curves& list1, X_monotone_curves& list2); bool points_identical(Points& list1, Points& list2); @@ -148,109 +144,32 @@ std::istream& skip_comment(std::istream& in) { return in; } -int main(int argc, char* argv[]) { - if (argc != 2) { - std::cout << "Specify a file name " << std::endl; - return -1; - } - - std::ifstream inp(argv[1]); - if (! inp.is_open()) { - std::cerr << "Error: Cannot open file " << argv[1] << "!" << std::endl; - return -1; - } - - Traits tr; - - Curves curves; - if (! read_curves(inp, curves, tr)) return -1; - - // Test subcurves w/o overlapping - X_monotone_curves curves_no_overlap_out; - CGAL::compute_subcurves(curves.begin(), curves.end(), - std::back_inserter(curves_no_overlap_out), - false, tr); - - - X_monotone_curves curves_no_overlap; - if (! read_xcurves(inp, curves_no_overlap, tr)) return -1; - - if (! compare_lists(curves_no_overlap_out, curves_no_overlap, tr)) { - std::cerr << "Curves w/o overlapping do not match!\n"; - for (const auto& xcv : curves_no_overlap_out) std::cerr << xcv << std::endl; - return -1; - } - - // Test intersection points (with endpoints) - Points points_with_ends_out; - CGAL::compute_intersection_points(curves.begin(), curves.end(), - std::back_inserter(points_with_ends_out), - true, tr); - - Points points_with_ends; - if (! read_points(inp, points_with_ends, tr)) return -1; - - if (! compare_lists(points_with_ends_out, points_with_ends, tr)) { - std::cerr << "Endpoints do not match!\n"; - for (const auto& p : points_with_ends_out) std::cerr << p << std::endl; - return -1; - } - - // Test intersection points w/o end points - Points points_without_ends_out; - CGAL::compute_intersection_points(curves.begin(), curves.end(), - std::back_inserter(points_without_ends_out), - false, tr); - - Points points_without_ends; - if (! read_points(inp, points_without_ends, tr)) return -1; - - if (! compare_lists(points_without_ends_out, points_without_ends, tr)) { - std::cerr << "Intersection points do not match!\n"; - for (const auto& p : points_without_ends_out) std::cerr << p << std::endl; - return -1; - } - - // Test subcurves w/ overlapping - X_monotone_curves curves_with_overlap_out; - CGAL::compute_subcurves(curves.begin(), curves.end(), - std::back_inserter(curves_with_overlap_out), - true, tr); - - X_monotone_curves curves_with_overlap; - if (! read_xcurves(inp, curves_with_overlap, tr)) return -1; - - if (! compare_lists(curves_with_overlap_out, curves_with_overlap, tr)) { - std::cerr << "Curves w/ overlapping do not match!\n"; - for (const auto& xcv : curves_with_overlap_out) - std::cerr << xcv << std::endl; - return -1; - } - - // Test the do_curves_intersecting method - bool do_intersect_out = - CGAL::do_curves_intersect(curves.begin(), curves.end()); +#if CGAL_ARR_TEST_TRAITS != CGAL_CONIC_TRAITS - bool do_intersect = false; - if ((points_without_ends.size() != 0) || - (curves_no_overlap_out.size() != curves_with_overlap_out.size())) - do_intersect = true; +bool read_points(std::ifstream& inp, Points& points, const Traits&) { + int count; + inp >> skip_comment >> count; + char ch; - if (do_intersect_out != do_intersect) { - std::cerr << "Error: do_intersect()\n"; - return -1; + // std::cout << "read_points " << count << "\n"; + for (int i = 0; i < count; i++) { + NT x, y; + inp >> skip_comment >> x >> y; + Point_2 p(x, y); + // std::cout << p << "\n"; + points.push_back(p); } - - std::cout << "Passed\n"; - return 0; + return true; } +#endif + #if CGAL_ARR_TEST_TRAITS == CGAL_SEGMENT_TRAITS bool read_curves(std::ifstream& inp, Curves& curves, const Traits&) { int count; inp >> skip_comment >> count; - std::cout << "read_curves " << count << "\n"; + // std::cout << "read_curves " << count << "\n"; for (int i = 0; i < count; ++i) { NT x0, y0, x1, y1; @@ -259,7 +178,7 @@ bool read_curves(std::ifstream& inp, Curves& curves, const Traits&) { Point_2 p2(x1, y1); Curve_2 curve(p1, p2); curves.push_back(curve); - std::cout << curve << "\n"; + // std::cout << curve << "\n"; } return true; } @@ -302,24 +221,313 @@ bool read_xcurves(std::ifstream& inp, X_monotone_curves& xcurves, return read_curves_(inp, xcurves, traits, ctr_xcv); } +#elif CGAL_ARR_TEST_TRAITS == CGAL_CONIC_TRAITS + +void read_curve(std::ifstream& is, Curve_2& cv) { + // Read a line from the input file. + char one_line[128]; + + is >> skip_comment; + is.getline(one_line, 128); + std::string stringvalues(one_line); + std::istringstream str_line(stringvalues, std::istringstream::in); + + // Get the arc type. + // Supported types are: 'f' - Full ellipse (or circle). + // 'e' - Elliptic arc (or circular arc). + // 's' - Line segment. + char type; + bool is_circle = false; // Is this a circle. + Rat_circle_2 circle; + Rational r, s, t, u, v, w; // The conic coefficients. + + str_line >> type; + + // An ellipse (full ellipse or a partial ellipse): + if (type == 'f' || type == 'F' || type == 'e' || type == 'E') { + // Read the ellipse (using the format "a b x0 y0"): + // + // x - x0 2 y - y0 2 + // ( -------- ) + ( -------- ) = 1 + // a b + // + int a, b, x0, y0; + + str_line >> a >> b >> x0 >> y0; + + Rational a_sq = Rational(a*a); + Rational b_sq = Rational(b*b); + + if (a == b) { + is_circle = true; + circle = + Rat_circle_2(Rat_point_2(Rational(x0), Rational(y0)), Rational(a*b)); + } + else { + r = b_sq; + s = a_sq; + t = 0; + u = Rational(-2*x0*b_sq); + v = Rational(-2*y0*a_sq); + w = Rational(x0*x0*b_sq + y0*y0*a_sq - a_sq*b_sq); + } + + if (type == 'f' || type == 'F') { + // Create a full ellipse (or circle). + if (is_circle) cv = Curve_2 (circle); + else cv = Curve_2(r, s, t, u, v, w); + } + else { + // Read the endpointd of the arc. + int x1, y1, x2, y2; + + str_line >> x1 >> y1 >> x2 >> y2; + + Point_2 source = Point_2(Algebraic(x1), Algebraic(y1)); + Point_2 target = Point_2(Algebraic(x2), Algebraic(y2)); + + // Create the arc. Note that it is always clockwise oriented. + if (is_circle) cv = Curve_2(circle, CGAL::CLOCKWISE, source, target); + else cv = Curve_2(r, s, t, u, v, w, CGAL::CLOCKWISE, source, target); + } + } + else if (type == 's' || type == 'S') { + // Read a segment, given by its endpoints (x1,y1) and (x2,y2); + int x1, y1, x2, y2; + + str_line >> x1 >> y1 >> x2 >> y2; + + // Create the segment. + Rat_point_2 source = Rat_point_2 (Rational(x1), Rational(y1)); + Rat_point_2 target = Rat_point_2 (Rational(x2), Rational(y2)); + + cv = Curve_2(Rat_segment_2 (source, target)); + } + + // std::cout << cv << std::endl; +} + +/*! Read curves. + */ +bool read_curves(std::ifstream& inp, Curves& curves, const Traits&) { + // auto ctr_cv = traits.construct_curve_2_object(); + int count; + inp >> skip_comment >> count; + Curve_2 cv; + char dummy[256]; + inp.getline(dummy, sizeof(dummy)); + for (int i = 0; i < count; ++i) { + read_curve(inp, cv); + curves.push_back(cv); + } + return true; +} + #else #error No traits defined for test #endif -bool read_points(std::ifstream& inp, Points& points, const Traits&) { - int count; - inp >> skip_comment >> count; - char ch; +#if CGAL_ARR_TEST_TRAITS != CGAL_CONIC_TRAITS - // std::cout << "read_points " << count << "\n"; - for (int i = 0; i < count; i++) { - NT x, y; - inp >> skip_comment >> x >> y; - Point_2 p(x, y); - // std::cout << p << "\n"; - points.push_back(p); +// Test subcurves w/o overlapping +bool test_curves_no_overlap(std::ifstream& inp, Curves& curves, + const X_monotone_curves& curves_no_overlap_out, + const Traits& tr) { + X_monotone_curves curves_no_overlap; + if (! read_xcurves(inp, curves_no_overlap, tr)) return false; + + if (! compare_lists(curves_no_overlap_out, curves_no_overlap, tr)) { + std::cerr << "Error: Curves w/o overlapping do not match!\n"; + for (const auto& xcv : curves_no_overlap_out) std::cerr << xcv << std::endl; + return false; } + + return true; +} + +// Test subcurves w/ overlapping +bool test_curves_with_overlap(std::ifstream& inp, Curves& curves, + const X_monotone_curves& curves_with_overlap_out, + const Traits& tr) { + X_monotone_curves curves_with_overlap; + if (! read_xcurves(inp, curves_with_overlap, tr)) return false; + + if (! compare_lists(curves_with_overlap_out, curves_with_overlap, tr)) { + std::cerr << "Error: Curves w/ overlapping do not match!\n"; + for (const auto& xcv : curves_with_overlap_out) + std::cerr << xcv << std::endl; + return false; + } + + return true; +} + +// Test intersection points (with endpoints) +bool test_points_with_ends(std::ifstream& inp, Curves& curves, + const Points& points_with_ends_out, + const Traits& tr) { + Points points_with_ends; + if (! read_points(inp, points_with_ends, tr)) return false; + + if (! compare_lists(points_with_ends_out, points_with_ends, tr)) { + std::cerr << "Error: Endpoints do not match!\n"; + for (const auto& p : points_with_ends_out) std::cerr << p << std::endl; + return false; + } + + return true; +} + +// Test intersection points w/o end points +bool test_points_no_ends(std::ifstream& inp, Curves& curves, + const Points& points_no_ends_out, + const Traits& tr) { + Points points_no_ends; + if (! read_points(inp, points_no_ends, tr)) return -1; + + if (! compare_lists(points_no_ends_out, points_no_ends, tr)) { + std::cerr << "Error: Intersection points do not match!\n"; + for (const auto& p : points_no_ends_out) std::cerr << p << std::endl; + return false; + } + + return true; +} + +#else + +/*! Test the surface sweep with conic traits. + */ +bool test_conic(std::ifstream& inp, Curves& curves, + const X_monotone_curves& curves_no_overlap_out, + const Points& points_with_ends_out, + const Points& points_no_ends_out, + const Traits&) { + char dummy[256]; + + CGAL::Bbox_2 bbox = curves.front().bbox(); + for (auto it = std::next(curves.begin()); it != curves.end(); ++it) + bbox = bbox + it->bbox(); + + // generate the string for the output + std::stringstream out1; + for (const auto& xcv : curves_no_overlap_out) out1 << xcv << "\n"; + + // read the output from the file + std::stringstream out2; + char buf[1024]; + int count = 0; + + inp >> count; + inp.getline(buf, 1024); // to get rid of the new line + for (int i = 0; i < count; ++i) { + inp.getline(buf, 1024); + out2 << buf << "\n"; + } + + // std::cout << "Result: \n" << curves_no_overlap_out.size() << "\n"; + // for (const auto& xcv : curves_no_overlap_out) + // std::cout << xcv << "\n"; + + std::string calculated = out1.str(); + std::string infile = out2.str(); + + if (infile != calculated) { + std::cerr << "Error\n"; + std::cerr << "\ncalculated:\n"; + std::cerr << calculated << std::endl; + std::cerr << "\nin file:\n"; + std::cerr << infile << std::endl; + std::cerr << "--" << std::endl; + return false; + } + + std::size_t points_with_ends_size, points_no_ends_size; + inp >> skip_comment >> points_with_ends_size >> points_no_ends_size; + + auto points_with_ends_out_size = points_with_ends_out.size(); + if (points_with_ends_size != points_with_ends_out_size ) { + std::cerr << "Error: Number of endpoints do not match (" + << points_with_ends_out_size << ", " + << points_with_ends_size << ")\n"; + return false; + } + + auto points_no_ends_out_size = points_no_ends_out.size(); + if (points_no_ends_size != points_no_ends_out_size) { + std::cerr << "Error: Number of intersection points do not match (" + << points_no_ends_out_size << ", " + << points_no_ends_size << ")\n"; + return false; + } + return true; } #endif + +int main(int argc, char* argv[]) { + if (argc != 2) { + std::cout << "Specify a file name " << std::endl; + return -1; + } + + std::ifstream inp(argv[1]); + if (! inp.is_open()) { + std::cerr << "Error: Cannot open file " << argv[1] << "!" << std::endl; + return -1; + } + + Traits tr; + + Curves curves; + if (! read_curves(inp, curves, tr)) return -1; + + X_monotone_curves curves_no_overlap_out; + CGAL::compute_subcurves(curves.begin(), curves.end(), + std::back_inserter(curves_no_overlap_out), + false, tr); + + X_monotone_curves curves_with_overlap_out; + CGAL::compute_subcurves(curves.begin(), curves.end(), + std::back_inserter(curves_with_overlap_out), + true, tr); + + Points points_with_ends_out; + CGAL::compute_intersection_points(curves.begin(), curves.end(), + std::back_inserter(points_with_ends_out), + true, tr); + + Points points_no_ends_out; + CGAL::compute_intersection_points(curves.begin(), curves.end(), + std::back_inserter(points_no_ends_out), + false, tr); + +#if CGAL_ARR_TEST_TRAITS == CGAL_CONIC_TRAITS + if (! test_conic(inp, curves, curves_no_overlap_out, + points_with_ends_out, points_no_ends_out, tr)) + return -1; +#else + if (! test_curves_no_overlap(inp, curves, curves_no_overlap_out, tr)) + return -1; + if (! test_points_with_ends(inp, curves, points_with_ends_out, tr)) return -1; + if (! test_points_no_ends(inp, curves, points_no_ends_out, tr)) return -1; + if (! test_curves_with_overlap(inp, curves, curves_with_overlap_out, tr)) + return -1; +#endif + + // Test the do_curves_intersecting method + bool do_intersect_out = + CGAL::do_curves_intersect(curves.begin(), curves.end()); + bool do_intersect = ! points_no_ends_out.empty() || + (curves_no_overlap_out.size() != curves_with_overlap_out.size()); + if (do_intersect_out != do_intersect) { + std::cerr << "Error: do_intersect()\n"; + return -1; + } + + std::cout << "Passed\n"; + return 0; +} + +#endif diff --git a/Surface_sweep_2/test/Surface_sweep_2/test_sweep_conic.cpp b/Surface_sweep_2/test/Surface_sweep_2/test_sweep_conic.cpp deleted file mode 100644 index 45ae95448515..000000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/test_sweep_conic.cpp +++ /dev/null @@ -1,279 +0,0 @@ -#include - -#if !defined(CGAL_USE_CORE) -#include -int main() -{ - std::cout << "CORE is not installed. Test aborted!" << std::endl; - return 0; -} -#else - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -typedef CGAL::CORE_algebraic_number_traits Nt_traits; -typedef Nt_traits::Rational Rational; -typedef Nt_traits::Algebraic Algebraic; -typedef CGAL::Cartesian Rat_kernel; -typedef Rat_kernel::Point_2 Rat_point_2; -typedef Rat_kernel::Segment_2 Rat_segment_2; -typedef Rat_kernel::Circle_2 Rat_circle_2; -typedef CGAL::Cartesian Alg_kernel; -typedef CGAL::Arr_conic_traits_2 - Traits_2; - -typedef Traits_2::Curve_2 Curve_2; -typedef Traits_2::X_monotone_curve_2 X_monotone_curve_2; -typedef Traits_2::Point_2 Point_2; -typedef std::list CurveList; - -typedef std::list PointList; -typedef PointList::iterator PointListIter; - - -/*! Conic reader */ -template -class Conic_reader { -public: - int ReadData(const char* filename, CurveList& curves, CGAL::Bbox_2& bbox) - { - Curve_2 cv; - char dummy[256]; - - std::ifstream inp(filename); - if (!inp.is_open()) { - std::cerr << "Cannot open file " << filename << "!" << std::endl; - return -1; - } - int count; - inp >> count; - inp.getline(dummy, sizeof(dummy)); - for (int i = 0; i < count; i++) { - ReadCurve(inp, cv); - curves.push_back(cv); - CGAL::Bbox_2 curve_bbox = cv.bbox(); - if (i == 0) bbox = curve_bbox; - else bbox = bbox + curve_bbox; - } - inp.close(); - return 0; - } - - void ReadCurve(std::ifstream & is, Curve_2 & cv) - { - // Read a line from the input file. - char one_line[128]; - - skip_comments (is, one_line); - std::string stringvalues(one_line); - std::istringstream str_line (stringvalues, std::istringstream::in); - - // Get the arc type. - // Supported types are: 'f' - Full ellipse (or circle). - // 'e' - Elliptic arc (or circular arc). - // 's' - Line segment. - char type; - bool is_circle = false; // Is this a circle. - Rat_circle_2 circle; - Rational r, s, t, u, v, w; // The conic coefficients. - - str_line >> type; - - // An ellipse (full ellipse or a partial ellipse): - if (type == 'f' || type == 'F' || type == 'e' || type == 'E') - { - // Read the ellipse (using the format "a b x0 y0"): - // - // x - x0 2 y - y0 2 - // ( -------- ) + ( -------- ) = 1 - // a b - // - int a, b, x0, y0; - - str_line >> a >> b >> x0 >> y0; - - Rational a_sq = Rational(a*a); - Rational b_sq = Rational(b*b); - - if (a == b) - { - is_circle = true; - circle = Rat_circle_2 (Rat_point_2 (Rational(x0), Rational(y0)), - Rational(a*b)); - } - else - { - r = b_sq; - s = a_sq; - t = 0; - u = Rational(-2*x0*b_sq); - v = Rational(-2*y0*a_sq); - w = Rational(x0*x0*b_sq + y0*y0*a_sq - a_sq*b_sq); - } - - if (type == 'f' || type == 'F') - { - // Create a full ellipse (or circle). - if (is_circle) - cv = Curve_2 (circle); - else - cv = Curve_2 (r, s, t, u, v, w); - } - else - { - // Read the endpointd of the arc. - int x1, y1, x2, y2; - - str_line >> x1 >> y1 >> x2 >> y2; - - Point_2 source = Point_2 (Algebraic(x1), Algebraic(y1)); - Point_2 target = Point_2 (Algebraic(x2), Algebraic(y2)); - - // Create the arc. Note that it is always clockwise oriented. - if (is_circle) - cv = Curve_2 (circle, - CGAL::CLOCKWISE, - source, target); - else - cv = Curve_2 (r, s, t, u, v, w, - CGAL::CLOCKWISE, - source, target); - } - } - else if (type == 's' || type == 'S') - { - // Read a segment, given by its endpoints (x1,y1) and (x2,y2); - int x1, y1, x2, y2; - - str_line >> x1 >> y1 >> x2 >> y2; - - // Create the segment. - Rat_point_2 source = Rat_point_2 (Rational(x1), Rational(y1)); - Rat_point_2 target = Rat_point_2 (Rational(x2), Rational(y2)); - - cv = Curve_2(Rat_segment_2 (source, target)); - } - - return; - } - - void skip_comments( std::ifstream& is, char* one_line ) - { - while( !is.eof() ){ - is.getline( one_line, 128 ); - if( one_line[0] != '#' ){ - break; - } - } - } -}; - -//--------------------------------------------------------------------------- -// The main: -// -int main (int argc, char** argv) -{ - bool verbose = false; - - // Define a test objects to read the conic arcs from it. - if (argc<2) - { - std::cerr << "Usage: Conic_traits_test " << std::endl; - exit(1); - } - - CGAL::Bbox_2 bbox; - CurveList curves; - - Conic_reader reader; - reader.ReadData(argv[1], curves, bbox); - - // run the sweep - std::list mylist; - - CGAL::compute_subcurves(curves.begin(), curves.end(), - std::back_inserter(mylist), false); - - - PointList point_list_with_ends; - CGAL::compute_intersection_points(curves.begin(), curves.end(), - std::back_inserter(point_list_with_ends), true); - std::size_t point_count_with_ends_calculated = point_list_with_ends.size(); - - // generate the string for the output - std::stringstream out1; - for ( std::list::iterator iter = mylist.begin() ; - iter != mylist.end() ; ++iter ) - { - out1 << *iter << "\n"; - } - - // read the output from the file - std::stringstream out2; - char buf[1024]; - int count = 0; - - std::ifstream in_file(argv[1]); - in_file >> count; - in_file.getline(buf, 1024); // to get rid of the new line - for ( int i = 0 ; i < count ; i++ ) { - in_file.getline(buf, 1024); - } - in_file >> count; - in_file.getline(buf, 1024); // to get rid of the new line - for (int i = 0; i < count; i++) { - in_file.getline(buf, 1024); - out2 << buf << "\n"; - } - std::size_t point_count_with_ends_from_file = 0; - in_file >> point_count_with_ends_from_file; - in_file.close(); - - if ( verbose ) - { - std::cout << "Result: \n" << mylist.size() << "\n"; - for ( std::list::iterator i = mylist.begin() ; - i != mylist.end() ; ++i ) - { - std::cout << *i << "\n"; - } - } - - std::string calculated = out1.str(); - std::string infile = out2.str(); - - if ( infile == calculated ) { - if ( point_count_with_ends_from_file != - point_count_with_ends_calculated ) { - std::cout << "number of intersection points (with ends):" - << point_count_with_ends_calculated << ". Should be " - << point_count_with_ends_from_file << "\n"; - std::cout << argv[1] << " Error\n"; - return -1; - } else { - std::cout << argv[1] << " OK!\n"; - } - } else { - std::cout << argv[1] << " Error\n"; - std::cout << "\ncalculated:\n"; - std::cout << calculated << std::endl; - std::cout << "\nin file:\n"; - std::cout << infile << std::endl; - std::cout << "--" << std::endl; - return -1; - } - - return 0; -} - -#endif From 3d6c0da44cdf28be1ebfc4e7818ba78987c7209c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 31 May 2023 09:14:42 +0200 Subject: [PATCH 071/329] remove debug --- .../include/CGAL/Polygon_mesh_processing/autorefinement.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index ae383a4af293..18bbfa2ce40f 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -1323,9 +1323,9 @@ void autorefine_soup_output(const PointRange& input_points, CGAL_PMP_AUTOREFINE_VERBOSE("triangulate faces"); // now refine triangles #ifdef CGAL_LINKED_WITH_TBB - std::conditional_t>, - std::vector>> new_triangles; + std::conditional_t>, + std::vector>> new_triangles; #else std::vector> new_triangles; #endif @@ -1487,8 +1487,6 @@ void autorefine_soup_output(const PointRange& input_points, soup_triangles.resize(offset + new_triangles.size()); - std::cout << "soup_triangles.size() = " << soup_triangles.size() << std::endl; - std::cout << "new_triangles.size() = " << new_triangles.size() << std::endl; tbb::parallel_for(tbb::blocked_range(0, new_triangles.size()), [&](const tbb::blocked_range& r) { for (size_t ti = r.begin(); ti != r.end(); ++ti) { From 854aacd671b9936730e97f8bf003bf2969e016fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 6 Jun 2023 15:31:19 +0200 Subject: [PATCH 072/329] add comments --- .../Triangle_3_Triangle_3_intersection.h | 48 ++++++++++++------- 1 file changed, 31 insertions(+), 17 deletions(-) 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 4cc5f9be5600..99dcd24ff457 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 @@ -59,6 +59,19 @@ coplanar_segment_segment_alpha_intersection(const typename K::Point_3& p1, const template struct Point_on_triangle { + // triangle points are not stored in this class but are expected + // to always be passed in the same order. For a triangle pqr, + // edge 0 is pq, edge 1 qr and edge 2 rp. Point 0 is p, 1 is q and 2 is r. + // + // (id, -1) point on t1 + // (-1, id) point on t2 + // (id1, id2) intersection of edges + std::pair t1_t2_ids; + boost::container::flat_set extra_t1; // store other ids of edges containing the point + typename Kernel::FT alpha; // + +////// + static inline const typename Kernel::Point_3& @@ -83,13 +96,7 @@ struct Point_on_triangle , alpha(alpha) {} - // (id, -1) point on t1 - // (-1, id) point on t2 - // (id1, id2) intersection of edges - std::pair t1_t2_ids; - boost::container::flat_set extra_t1; - typename Kernel::FT alpha; - + // orientation of the current point wrt to edge id1 (p1q1) Orientation orientation (const typename Kernel::Point_3& p1, // source of edge edge_id1 const typename Kernel::Point_3& q1, // target of edge edge_id1 @@ -116,7 +123,7 @@ struct Point_on_triangle CGAL_assertion((t1_t2_ids.first+1)%3==edge_id1); if (alpha==1) return ZERO; return alpha<=1?POSITIVE:NEGATIVE; - } + } else { //this is an input point of t2 @@ -129,6 +136,7 @@ struct Point_on_triangle int id1() const { return t1_t2_ids.first; } int id2() const { return t1_t2_ids.second; } + // construct the intersection point from the info stored typename Kernel::Point_3 point(const typename Kernel::Point_3& p1, const typename Kernel::Point_3& q1, @@ -147,6 +155,12 @@ struct Point_on_triangle } }; +// the intersection of two triangles is computed by interatively intersection t2 +// with halfspaces defined by edges of t1. The following function is called +// for each each on t1 on edge of the current intersection. +// pq is such an edge and p1q1 from t1 defines the halfspace intersection +// we are currently interseted in. We return the intersection point of +// pq with p1q1 template Point_on_triangle intersection(const Point_on_triangle& p, @@ -172,7 +186,7 @@ intersection(const Point_on_triangle& p, { switch(q.id1()) { - case -1: // (-1, ip2) - (-1, iq2) + case -1: // A: (-1, ip2) - (-1, iq2) { CGAL_assertion((p.id2()+1)%3 == q.id2() || (q.id2()+1)%3 == p.id2()); // CGAL_assertion(p.extra_t1.empty() && q.extra_t1.empty()); // TMP to see if it's worth implementing special case @@ -187,7 +201,7 @@ intersection(const Point_on_triangle& p, return Point_on_triangle(edge_id_t1, id2, alpha); // intersection with an original edge of t2 } default: - if (q.id2()!=-1) // (-1, ip2) - (iq1, iq2) + if (q.id2()!=-1) // B: (-1, ip2) - (iq1, iq2) { if (p.id2() == q.id2() || p.id2() == (q.id2()+1)%3) { @@ -210,7 +224,7 @@ intersection(const Point_on_triangle& p, int eid1 = p.extra_t1.count(q.id1())!=0 ? q.id1() : 3-q.id1()-edge_id_t1; return Point_on_triangle((eid1+1)%3==edge_id_t1?edge_id_t1:(edge_id_t1+1)%3, -1); // vertex of t1 } - // (-1, ip2) - (iq1, -1) + // C: (-1, ip2) - (iq1, -1) //vertex of t1, special case t1 edge passed thru a vertex of t2 CGAL_assertion(edge_id_t1 == 2); #ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION @@ -229,7 +243,7 @@ intersection(const Point_on_triangle& p, { switch(q.id1()) { - case -1: // (ip1, -1) - (-1, iq2) + case -1: // G: (ip1, -1) - (-1, iq2) //vertex of t1, special case t1 edge passed thru a vertex of t2 #ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION std::cout << " -- case 5\n"; @@ -243,8 +257,8 @@ intersection(const Point_on_triangle& p, #ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION std::cout << " -- case 6\n"; #endif - CGAL_assertion(q.id2()!=-1); // (ip1, -1) - (iq2, -1) - //(ip1,-1), (iq1, iq2) + CGAL_assertion(q.id2()!=-1); // I: (ip1, -1) - (iq2, -1) + //H: (ip1,-1), (iq1, iq2) CGAL_assertion(edge_id_t1==2); // p and q are on the same edge of t1 CGAL_assertion(p.id1()==q.id1() || p.id1()==(q.id1()+1)%3); @@ -256,7 +270,7 @@ intersection(const Point_on_triangle& p, { switch(q.id1()) { - case -1: // (ip1, ip2) - (-1, iq2) + case -1: // D: (ip1, ip2) - (-1, iq2) { if (q.id2() == p.id2() || q.id2() == (p.id2()+1)%3) { @@ -284,7 +298,7 @@ intersection(const Point_on_triangle& p, { switch(q.id2()) { - case -1: // (ip1, ip2) - (iq1, -1) + case -1: // F: (ip1, ip2) - (iq1, -1) { // p and q are on the same edge of t1 CGAL_assertion(q.id1()==p.id1() || q.id1()==(p.id1()+1)%3); @@ -293,7 +307,7 @@ intersection(const Point_on_triangle& p, #endif return Point_on_triangle((p.id1()+1)%3==edge_id_t1?edge_id_t1:(edge_id_t1+1)%3 , -1); } - default: // (ip1, ip2) - (iq1, iq2) + default: // E: (ip1, ip2) - (iq1, iq2) { if (p.id2()==q.id2()) { From 0551cefa5d315c4071dec5c1118bceaaa6bdfcdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 7 Jun 2023 15:02:10 +0200 Subject: [PATCH 073/329] add more test from errors while testing thingi10k models --- .../triangle_3_triangle_3_intersection.cpp | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/Intersections_3/test/Intersections_3/triangle_3_triangle_3_intersection.cpp b/Intersections_3/test/Intersections_3/triangle_3_triangle_3_intersection.cpp index 0098bcd01422..f0875a55ee8b 100644 --- a/Intersections_3/test/Intersections_3/triangle_3_triangle_3_intersection.cpp +++ b/Intersections_3/test/Intersections_3/triangle_3_triangle_3_intersection.cpp @@ -96,6 +96,13 @@ void test_coplanar_triangles(){ assert(CGAL::object_cast(&obj)!=nullptr); obj=CGAL::intersection(t2,t1); assert(CGAL::object_cast(&obj)!=nullptr); + // TK10 case C' + t1=Triangle(Point(88.7921, 89.0007, 1.25), Point(88.1912, 88.3997, 1.25), Point(89.8224, 90.031, 1.25)); + t2=Triangle(Point(88.0497, 88.2583, 1.25), Point(82.9292, 81.8747, 1.25), Point(91.1726, 91.3812, 1.25)); + obj=CGAL::intersection(t1,t2); + assert(CGAL::object_cast(&obj)!=nullptr); + obj=CGAL::intersection(t2,t1); + assert(CGAL::object_cast(&obj)!=nullptr); //Intersection is a point //edges are collinear, one vertex in common t1=Triangle( Point(0,0,0),Point(0,1,0),Point(1,0,0) ); @@ -153,6 +160,13 @@ void test_coplanar_triangles(){ assert(CGAL::object_cast(&obj)!=nullptr); obj=CGAL::intersection(t2,t1); assert(CGAL::object_cast(&obj)!=nullptr); + // TK10 case D + t1=Triangle(Point(-34.893700000000003, -16.0351, 3.1334899999999998e-12), Point(-34.893700000000003, -18.5351, 3.1334899999999998e-12), Point(-42.393700000000003, -16.0351, 3.1334899999999998e-12)); + t2=Triangle(Point(-34.893700000000003, -32.0351, 3.1334899999999998e-12), Point(-34.893700000000003, -9.7851400000000002, 3.1334899999999998e-12), Point(-31.643699999999999, -17.201799999999999, 3.1334899999999998e-12)); + obj=CGAL::intersection(t1,t2); + assert(CGAL::object_cast(&obj)!=nullptr); + obj=CGAL::intersection(t2,t1); + assert(CGAL::object_cast(&obj)!=nullptr); //Intersection is a polygon //David's star t1=Triangle( Point(0,0,0),Point(1,0,0),Point(0.5,1.5,0) ); @@ -181,6 +195,51 @@ void test_coplanar_triangles(){ obj=CGAL::intersection(t2,t1); assert(CGAL::object_cast(&obj)!=nullptr); assert(CGAL::object_cast(&obj)->size()==4); + // TK10 case A + t1=Triangle(Point(3.74861, 12.4822, 14.0112), Point(5.40582, 12.4822, 15.6895), Point(5.37748, 12.4822, 15.7206)); + t2=Triangle(Point(5.49972, 12.4822, 13.491), Point(5.27627, 12.4822, 15.8106), Point(5.32119, 12.4822, 15.8126)); + obj=CGAL::intersection(t1,t2); + assert(CGAL::object_cast(&obj)!=nullptr); + assert(CGAL::object_cast(&obj)->size()==4); + obj=CGAL::intersection(t2,t1); + assert(CGAL::object_cast(&obj)!=nullptr); + assert(CGAL::object_cast(&obj)->size()==4); + // TK10 case C + t1=Triangle(Point(5, -94.6659, 3.85175), Point(5, -94.5682, 3.08638), Point(5, -94.8182, 3.08638)); + t2=Triangle(Point(5, -94.4317, 3.76399), Point(5, -97.6182, 3.08638), Point(5, -94.5659, 2.99682)); + obj=CGAL::intersection(t1,t2); + assert(CGAL::object_cast(&obj)!=nullptr); + assert(CGAL::object_cast(&obj)->size()==4); + obj=CGAL::intersection(t2,t1); + assert(CGAL::object_cast(&obj)!=nullptr); + assert(CGAL::object_cast(&obj)->size()==4); + // TK10 case E + t1=Triangle(Point(-955.858, -45.032, -0.016), Point(-955.856, -45.032, -0.004), Point(-955.856, -45.032, -0.002)); + t2=Triangle(Point(-955.856, -45.032, 0.006), Point(-955.854, -45.032, -0.002), Point(-955.876, -45.032, -0.034)); + obj=CGAL::intersection(t1,t2); + assert(CGAL::object_cast(&obj)!=nullptr); + assert(CGAL::object_cast(&obj)->size()==4); + obj=CGAL::intersection(t2,t1); + assert(CGAL::object_cast(&obj)!=nullptr); + assert(CGAL::object_cast(&obj)->size()==4); + // TK10 case F + t1=Triangle(Point(141.172, 20.576, 155.764), Point(141.172, 20.588, 155.766), Point(141.172, 20.59, 155.766)); + t2=Triangle(Point(141.172, 20.602, 155.768), Point(141.172, 20.594, 155.766), Point(141.172, 20.574, 155.764)); + obj=CGAL::intersection(t1,t2); + assert(CGAL::object_cast(&obj)!=nullptr); + assert(CGAL::object_cast(&obj)->size()==4); + obj=CGAL::intersection(t2,t1); + assert(CGAL::object_cast(&obj)!=nullptr); + assert(CGAL::object_cast(&obj)->size()==4); + // TK10 case D + t1=Triangle(Point(152.864, 126.324, 0.950001), Point(152.77, 126.483, 0.950001), Point(153.072, 125.973, 0.950001)); + t2=Triangle(Point(153.322, 125.551, 0.950001), Point(152.218, 127.415, 0.950001), Point(153.66, 124.768, 0.950001)); + obj=CGAL::intersection(t1,t2); + assert(CGAL::object_cast(&obj)!=nullptr); + assert(CGAL::object_cast(&obj)->size()==4); + obj=CGAL::intersection(t2,t1); + assert(CGAL::object_cast(&obj)!=nullptr); + assert(CGAL::object_cast(&obj)->size()==4); //Intersection is empty t1=Triangle( Point(0,0,0),Point(0,1,0),Point(1,0,0) ); t2=Triangle( Point(-0.1,-0.1,0),Point(-0.1,-0.9,0),Point(-1,-0.1,0) ); From 48712f7862f02ce63558de039c603e0d018ae31d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 8 Jun 2023 14:04:55 +0200 Subject: [PATCH 074/329] don't use c++17 features --- .../include/CGAL/Polygon_mesh_processing/autorefinement.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 18bbfa2ce40f..6b664ec360bc 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -1128,7 +1128,7 @@ void autorefine_soup_output(const PointRange& input_points, Sequential_tag > ::type Concurrency_tag; - constexpr bool parallel_execution = std::is_same_v; + constexpr bool parallel_execution = std::is_same::value; #ifndef CGAL_LINKED_WITH_TBB CGAL_static_assertion_msg (parallel_execution, From 003bf47781ef69354d9cd388f2fce00168c2e762 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 8 Jun 2023 14:05:09 +0200 Subject: [PATCH 075/329] move alpha computation into a functor --- .../Triangle_3_Triangle_3_intersection.h | 52 +++++-------------- .../include/CGAL/Kernel/function_objects.h | 31 +++++++++++ .../include/CGAL/Kernel/interface_macros.h | 2 + .../Polygon_mesh_processing/autorefinement.h | 6 +-- 4 files changed, 50 insertions(+), 41 deletions(-) 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 99dcd24ff457..68166f18c6e2 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 @@ -34,28 +34,6 @@ namespace CGAL { namespace Intersections { namespace internal{ -//TODO: move into a functor -template -typename K::FT -coplanar_segment_segment_alpha_intersection(const typename K::Point_3& p1, const typename K::Point_3& p2, // segment 1 - const typename K::Point_3& p3, const typename K::Point_3& p4, // segment 2 - const K& k) -{ - const typename K::Vector_3 v1 = p2-p1; - const typename K::Vector_3 v2 = p4-p3; - - CGAL_assertion(k.coplanar_3_object()(p1,p2,p3,p4)); - - const typename K::Vector_3 v3 = p3 - p1; - const typename K::Vector_3 v3v2 = cross_product(v3,v2); - const typename K::Vector_3 v1v2 = cross_product(v1,v2); - const typename K::FT sl = v1v2.squared_length(); - CGAL_assertion(!certainly(is_zero(sl))); - - const typename K::FT t = ((v3v2.x()*v1v2.x()) + (v3v2.y()*v1v2.y()) + (v3v2.z()*v1v2.z())) / sl; - return t; // p1 + (p2-p1) * t -} - template struct Point_on_triangle { @@ -179,6 +157,8 @@ intersection(const Point_on_triangle& p, std::cout << " (" << p.id1() << "," << p.id2() << ",[" << p.alpha << "]) -"; std::cout << " (" << q.id1() << "," << q.id2() << ",[" << q.alpha << "]) || e" << edge_id_t1; #endif + typename Kernel::Compute_alpha_for_coplanar_triangle_intersection_3 compute_alpha + = k.compute_alpha_for_coplanar_triangle_intersection_3_object(); typedef Point_on_triangle Pot; switch(p.id1()) { @@ -193,10 +173,9 @@ intersection(const Point_on_triangle& p, #ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION std::cout << " -- case 1\n"; #endif - typename Kernel::FT alpha = - coplanar_segment_segment_alpha_intersection(p1, q1, - Pot::point_from_id(p2, q2, r2, p.id2()), - Pot::point_from_id(p2, q2, r2, q.id2()), k); + typename Kernel::FT alpha = compute_alpha(p1, q1, + Pot::point_from_id(p2, q2, r2, p.id2()), + Pot::point_from_id(p2, q2, r2, q.id2())); int id2 = (p.id2()+1)%3 == q.id2() ? p.id2() : q.id2(); return Point_on_triangle(edge_id_t1, id2, alpha); // intersection with an original edge of t2 } @@ -209,10 +188,9 @@ intersection(const Point_on_triangle& p, std::cout << " -- case 2\n"; #endif // points are on the same edge of t2 --> we shorten an already cut edge - typename Kernel::FT alpha = - coplanar_segment_segment_alpha_intersection(p1, q1, - Pot::point_from_id(p2, q2, r2, q.id2()), - Pot::point_from_id(p2, q2, r2, (q.id2()+1)%3), k); + typename Kernel::FT alpha = compute_alpha(p1, q1, + Pot::point_from_id(p2, q2, r2, q.id2()), + Pot::point_from_id(p2, q2, r2, (q.id2()+1)%3)); return Point_on_triangle(edge_id_t1, q.id2(), alpha); } @@ -278,10 +256,9 @@ intersection(const Point_on_triangle& p, std::cout << " -- case 7\n"; #endif // points are on the same edge of t2 --> we shorten an already cut edge - typename Kernel::FT alpha = - coplanar_segment_segment_alpha_intersection(p1, q1, - Pot::point_from_id(p2, q2, r2, p.id2()), - Pot::point_from_id(p2, q2, r2, (p.id2()+1)%3), k); + typename Kernel::FT alpha = compute_alpha(p1, q1, + Pot::point_from_id(p2, q2, r2, p.id2()), + Pot::point_from_id(p2, q2, r2, (p.id2()+1)%3)); return Point_on_triangle(edge_id_t1, p.id2(), alpha); } @@ -314,10 +291,9 @@ intersection(const Point_on_triangle& p, #ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION std::cout << " -- case 10\n"; #endif - typename Kernel::FT alpha = - coplanar_segment_segment_alpha_intersection(p1, q1, - Pot::point_from_id(p2, q2, r2, q.id2()), - Pot::point_from_id(p2, q2, r2, (q.id2()+1)%3), k); + typename Kernel::FT alpha = compute_alpha(p1, q1, + Pot::point_from_id(p2, q2, r2, q.id2()), + Pot::point_from_id(p2, q2, r2, (q.id2()+1)%3)); return Point_on_triangle(edge_id_t1, q.id2(), alpha); } // we are intersecting an edge of t1 diff --git a/Kernel_23/include/CGAL/Kernel/function_objects.h b/Kernel_23/include/CGAL/Kernel/function_objects.h index 71aa268e6d35..780c0b2d4e50 100644 --- a/Kernel_23/include/CGAL/Kernel/function_objects.h +++ b/Kernel_23/include/CGAL/Kernel/function_objects.h @@ -2149,6 +2149,37 @@ namespace CommonKernelFunctors { } }; + template + class Compute_alpha_for_coplanar_triangle_intersection_3 + { + typedef typename K::Point_3 Point_3; + typedef typename K::Vector_3 Vector_3; + public: + typedef typename K::FT result_type; + result_type + operator()(const Point_3& p1, const Point_3& p2, // segment 1 + const Point_3& p3, const Point_3& p4) const // segment 2 + { + typename K::Construct_vector_3 vector = K().construct_vector_3_object(); + typename K::Construct_cross_product_vector_3 cross_product = + K().construct_cross_product_vector_3_object(); + + const Vector_3 v1 = vector(p1, p2); + const Vector_3 v2 = vector(p3, p4); + + CGAL_assertion(K().coplanar_3_object()(p1,p2,p3,p4)); + + const Vector_3 v3 = vector(p1, p3); + const Vector_3 v3v2 = cross_product(v3,v2); + const Vector_3 v1v2 = cross_product(v1,v2); + const typename K::FT sl = K().compute_squared_length_3_object()(v1v2); + CGAL_assertion(!certainly(is_zero(sl))); + + const typename K::FT t = ((v3v2.x()*v1v2.x()) + (v3v2.y()*v1v2.y()) + (v3v2.z()*v1v2.z())) / sl; + return t; // p1 + (p2-p1) * t + } + }; + template class Construct_point_on_2 { diff --git a/Kernel_23/include/CGAL/Kernel/interface_macros.h b/Kernel_23/include/CGAL/Kernel/interface_macros.h index 9c85643a977e..e5a2ebf81210 100644 --- a/Kernel_23/include/CGAL/Kernel/interface_macros.h +++ b/Kernel_23/include/CGAL/Kernel/interface_macros.h @@ -396,6 +396,8 @@ CGAL_Kernel_cons(Construct_plane_3, construct_plane_3_object) CGAL_Kernel_cons(Construct_plane_line_intersection_point_3, construct_plane_line_intersection_point_3_object) +CGAL_Kernel_cons(Compute_alpha_for_coplanar_triangle_intersection_3, + compute_alpha_for_coplanar_triangle_intersection_3_object) CGAL_Kernel_cons(Construct_point_on_2, construct_point_on_2_object) CGAL_Kernel_cons(Construct_point_on_3, diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 6b664ec360bc..6c8ba3f8cd27 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -386,7 +386,7 @@ void coplanar_intersections(const std::array& t1, //intersect t2 with the three half planes which intersection defines t1 K k; - intersection_coplanar_triangles_cutoff(p1,q1,r1,0,p2,q2,r2,k,l_inter_pts); //line p1q1 + Intersections::internal::intersection_coplanar_triangles_cutoff(p1,q1,r1,0,p2,q2,r2,k,l_inter_pts); //line p1q1 #ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION std::cout << " ipts size: " << l_inter_pts.size() << "\n"; print_points(); @@ -401,7 +401,7 @@ void coplanar_intersections(const std::array& t1, } } #endif - intersection_coplanar_triangles_cutoff(q1,r1,p1,1,p2,q2,r2,k,l_inter_pts); //line q1r1 + Intersections::internal::intersection_coplanar_triangles_cutoff(q1,r1,p1,1,p2,q2,r2,k,l_inter_pts); //line q1r1 #ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION std::cout << " ipts size: " << l_inter_pts.size() << "\n"; print_points(); @@ -416,7 +416,7 @@ void coplanar_intersections(const std::array& t1, } } #endif - intersection_coplanar_triangles_cutoff(r1,p1,q1,2,p2,q2,r2,k,l_inter_pts); //line r1p1 + Intersections::internal::intersection_coplanar_triangles_cutoff(r1,p1,q1,2,p2,q2,r2,k,l_inter_pts); //line r1p1 #ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION std::cout << " ipts size: " << l_inter_pts.size() << "\n"; print_points(); From 0684bd203fa818c1dbf6cb4b3fae839e08da94a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 8 Jun 2023 14:17:18 +0200 Subject: [PATCH 076/329] hide debug --- .../include/CGAL/Polygon_mesh_processing/autorefinement.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 6c8ba3f8cd27..90174e42753d 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -49,7 +49,7 @@ #define TEST_RESOLVE_INTERSECTION #define DEDUPLICATE_SEGMENTS -#define USE_DEBUG_PARALLEL_TIMERS +//#define USE_DEBUG_PARALLEL_TIMERS //#define DEBUG_COUNTERS //#define USE_FIXED_PROJECTION_TRAITS //#define DEBUG_DEPTH @@ -1248,8 +1248,6 @@ void autorefine_soup_output(const PointRange& input_points, #ifdef DEDUPLICATE_SEGMENTS // deduplicate inserted segments //TODO: PARALLEL_FOR #3 - Real_timer t3; - t3.start(); std::vector>> all_segments_ids(all_segments.size()); auto deduplicate_inserted_segments = [&](std::size_t ti) From c5fab1c874248e87abe1f769616f624f8bd0efdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 8 Jun 2023 14:21:59 +0200 Subject: [PATCH 077/329] fix sequential run --- .../CGAL/Polygon_mesh_processing/autorefinement.h | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 90174e42753d..11b15fa4ec47 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -1307,11 +1307,10 @@ void autorefine_soup_output(const PointRange& input_points, ); } else -#else - for (std::size_t ti = 0; ti < triangles.size(); ++ti) { - deduplicate_inserted_segments(ti); - } #endif + for (std::size_t ti = 0; ti < triangles.size(); ++ti) { + deduplicate_inserted_segments(ti); + } #ifdef USE_DEBUG_PARALLEL_TIMERS std::cout << t.time() << " sec. for #3" << std::endl; @@ -1385,11 +1384,10 @@ void autorefine_soup_output(const PointRange& input_points, ); } else -#else - for (std::size_t ti = 0; ti < triangles.size(); ++ti) { - refine_triangles(ti); - } #endif + for (std::size_t ti = 0; ti < triangles.size(); ++ti) { + refine_triangles(ti); + } #ifdef USE_DEBUG_PARALLEL_TIMERS t.stop(); From 45c7b0015f8f54e8f2fb517b6f5bc54181979467 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 12 Jun 2023 10:55:56 +0200 Subject: [PATCH 078/329] add stop --- .../examples/Polygon_mesh_processing/soup_autorefinement.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp index 823c50974dcc..9e4999287f7b 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp @@ -37,6 +37,7 @@ int main(int argc, char** argv) PMP::autorefine_soup_output(input_points, input_triangles, output_points, output_triangles, CGAL::parameters::concurrency_tag(CGAL::Parallel_if_available_tag())); + t.stop(); std::cout << "#points = " << output_points.size() << " and #triangles = " << output_triangles.size() << " in " << t.time() << " sec." << std::endl; CGAL::IO::write_polygon_soup("autorefined.off", output_points, output_triangles, CGAL::parameters::stream_precision(17)); From 41449d71cd3c3d7b8be578f0e3f56a3a14fc5842 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 12 Jun 2023 11:05:11 +0200 Subject: [PATCH 079/329] fix bug when setting the ids of points 2 options, one with mutex and one without. As this section is not critical, we do not really see a runtime difference (without mutex seems faster so I pick that one as default) --- .../Polygon_mesh_processing/autorefinement.h | 127 ++++++++++++++---- 1 file changed, 102 insertions(+), 25 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 11b15fa4ec47..9bbc67efb487 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -43,6 +43,9 @@ #include #include #include +#ifdef SET_POINT_IDS_USING_MUTEX +#include +#endif #endif #include @@ -1242,12 +1245,17 @@ void autorefine_soup_output(const PointRange& input_points, } } #ifdef USE_DEBUG_PARALLEL_TIMERS + t.stop(); std::cout << t.time() << " sec. for #2" << std::endl; + t.reset(); #endif #ifdef DEDUPLICATE_SEGMENTS +#ifdef USE_DEBUG_PARALLEL_TIMERS + t.start(); +#endif + // deduplicate inserted segments - //TODO: PARALLEL_FOR #3 std::vector>> all_segments_ids(all_segments.size()); auto deduplicate_inserted_segments = [&](std::size_t ti) @@ -1313,7 +1321,9 @@ void autorefine_soup_output(const PointRange& input_points, } #ifdef USE_DEBUG_PARALLEL_TIMERS + t.stop(); std::cout << t.time() << " sec. for #3" << std::endl; + t.reset(); #endif #endif @@ -1370,7 +1380,6 @@ void autorefine_soup_output(const PointRange& input_points, #ifdef USE_DEBUG_PARALLEL_TIMERS - t.reset(); t.start(); #endif #ifdef CGAL_LINKED_WITH_TBB @@ -1427,8 +1436,7 @@ void autorefine_soup_output(const PointRange& input_points, return insert_res.first->second; }; - - + // TODO: parallel_for? std::vector input_point_ids; input_point_ids.reserve(input_points.size()); for (const auto& p : input_points) @@ -1451,9 +1459,7 @@ void autorefine_soup_output(const PointRange& input_points, } // import refined triangles - //TODO: PARALLEL_FOR #4 #ifdef USE_DEBUG_PARALLEL_TIMERS - t.reset(); t.start(); #endif @@ -1466,37 +1472,108 @@ void autorefine_soup_output(const PointRange& input_points, #ifdef CGAL_LINKED_WITH_TBB if(parallel_execution && new_triangles.size() > 100) { - tbb::concurrent_vector concurrent_soup_points; + +#ifdef SET_POINT_IDS_USING_MUTEX + //option 1 (using a mutex) + CGAL_MUTEX point_container_mutex; /// Lambda concurrent_get_point_id() - auto concurrent_get_point_id = [&](const typename EK::Point_3& pt) + auto concurrent_get_point_id = [&](const typename EK::Point_3 pt) { - auto insert_res = point_id_map.insert(std::make_pair(pt, concurrent_soup_points.size())); - if (insert_res.second) - { - concurrent_soup_points.push_back(to_input(pt)); + auto insert_res = point_id_map.insert(std::make_pair(pt, -1)); + + if (insert_res.second) + { + CGAL_SCOPED_LOCK(point_container_mutex); + insert_res.first->second=soup_points.size(); + soup_points.push_back(to_input(pt)); #if ! defined(CGAL_NDEBUG) || defined(CGAL_DEBUG_PMP_AUTOREFINE) - exact_soup_points.push_back(pt); + exact_soup_points.push_back(pt); #endif - } - return insert_res.first->second; + } + return insert_res.first; }; + soup_triangles.resize(offset + new_triangles.size()); + //use map iterator triple for triangles to create them concurrently and safely + std::vector::iterator, 3>> triangle_buffer(new_triangles.size()); + tbb::parallel_for(tbb::blocked_range(0, new_triangles.size()), + [&](const tbb::blocked_range& r) { + for (size_t ti = r.begin(); ti != r.end(); ++ti) { + const std::array& t = new_triangles[ti]; + triangle_buffer[ti] = CGAL::make_array(concurrent_get_point_id(t[0]), concurrent_get_point_id(t[1]), concurrent_get_point_id(t[2])); + } + } + ); + tbb::parallel_for(tbb::blocked_range(0, new_triangles.size()), + [&](const tbb::blocked_range& r) { + for (size_t ti = r.begin(); ti != r.end(); ++ti) + { + soup_triangles[offset + ti] = + CGAL::make_array(triangle_buffer[ti][0]->second, + triangle_buffer[ti][1]->second, + triangle_buffer[ti][2]->second); + } + } + ); +#else + //option 2 (without mutex) + /// Lambda concurrent_get_point_id() + tbb::concurrent_vector::iterator> iterators; + auto concurrent_get_point_id = [&](const typename EK::Point_3 pt) + { + auto insert_res = point_id_map.insert(std::make_pair(pt, -1)); + if (insert_res.second) + iterators.push_back(insert_res.first); + return insert_res.first; + }; + //use map iterator triple for triangles to create them concurrently and safely soup_triangles.resize(offset + new_triangles.size()); + std::vector::iterator, 3>> triangle_buffer(new_triangles.size()); tbb::parallel_for(tbb::blocked_range(0, new_triangles.size()), - [&](const tbb::blocked_range& r) { - for (size_t ti = r.begin(); ti != r.end(); ++ti) { - if (offset + ti > soup_triangles.size()) { - std::cout << "ti = " << ti << std::endl; - } - const std::array& t = new_triangles[ti]; - soup_triangles[offset + ti] = CGAL::make_array(concurrent_get_point_id(t[0]), concurrent_get_point_id(t[1]), concurrent_get_point_id(t[2])); - } + [&](const tbb::blocked_range& r) { + for (size_t ti = r.begin(); ti != r.end(); ++ti) { + if (offset + ti > soup_triangles.size()) { + std::cout << "ti = " << ti << std::endl; + } + const std::array& t = new_triangles[ti]; + triangle_buffer[ti] = CGAL::make_array(concurrent_get_point_id(t[0]), concurrent_get_point_id(t[1]), concurrent_get_point_id(t[2])); + } + } + ); + + // the map is now filled we can safely set the point ids + std::size_t pid_offset=soup_points.size(); + soup_points.resize(pid_offset+iterators.size()); +#if ! defined(CGAL_NDEBUG) || defined(CGAL_DEBUG_PMP_AUTOREFINE) + exact_soup_points.resize(soup_points.size()); +#endif + + tbb::parallel_for(tbb::blocked_range(0, iterators.size()), + [&](const tbb::blocked_range& r) { + for (size_t ti = r.begin(); ti != r.end(); ++ti) + { + soup_points[pid_offset+ti] = to_input(iterators[ti]->first); +#if ! defined(CGAL_NDEBUG) || defined(CGAL_DEBUG_PMP_AUTOREFINE) + exact_soup_points[pid_offset+ti] = iterators[ti]->first; +#endif + iterators[ti]->second=pid_offset+ti; } + } ); - soup_points.reserve(soup_points.size() + concurrent_soup_points.size()); - soup_points.insert(soup_points.end(), concurrent_soup_points.begin(), concurrent_soup_points.end()); + tbb::parallel_for(tbb::blocked_range(0, new_triangles.size()), + [&](const tbb::blocked_range& r) { + for (size_t ti = r.begin(); ti != r.end(); ++ti) + { + soup_triangles[offset + ti] = + CGAL::make_array(triangle_buffer[ti][0]->second, + triangle_buffer[ti][1]->second, + triangle_buffer[ti][2]->second); + } + } + ); +#endif } else #endif From a8a3d8ab36cf3ad0880aa21dc49c2d29c96df656 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 6 Jul 2023 15:39:08 +0200 Subject: [PATCH 080/329] add functor to compute the intersection of 3 independant planes --- .../include/CGAL/Kernel/function_objects.h | 36 +++++++++++++++++++ .../include/CGAL/Kernel/interface_macros.h | 2 ++ 2 files changed, 38 insertions(+) diff --git a/Kernel_23/include/CGAL/Kernel/function_objects.h b/Kernel_23/include/CGAL/Kernel/function_objects.h index e307e28ae1f5..438dc0de14be 100644 --- a/Kernel_23/include/CGAL/Kernel/function_objects.h +++ b/Kernel_23/include/CGAL/Kernel/function_objects.h @@ -2192,6 +2192,42 @@ namespace CommonKernelFunctors { } }; + template + class Construct_planes_intersection_point_3 + { + typedef typename K::Plane_3 Plane; + typedef typename K::Point_3 Point; + typename K::Construct_plane_3 construct_plane; + public: + typedef Point result_type; + + Point + operator()(const Point& p1, const Point& q1, const Point& r1, + const Point& p2, const Point& q2, const Point& r2, + const Point& p3, const Point& q3, const Point& r3) const + { + Plane plane1 = construct_plane(p1, q1, r1); + Plane plane2 = construct_plane(p2, q2, r2); + Plane plane3 = construct_plane(p3, q3, r3); + + const auto res = typename K::Intersect_3()(plane1, plane2, plane3); + CGAL_assertion(res!=boost::none); + const Point* e_pt = boost::get(&(*res)); + CGAL_assertion(e_pt!=nullptr); + return *e_pt; + } + + Point + operator()(const Plane& plane1, const Plane& plane2, const Plane& plane3) const + { + const auto res = typename K::Intersect_3()(plane1, plane2, plane3); + CGAL_assertion(res!=boost::none); + const Point* e_pt = boost::get(&(*res)); + CGAL_assertion(e_pt!=nullptr); + return *e_pt; + } + }; + template class Compute_alpha_for_coplanar_triangle_intersection_3 { diff --git a/Kernel_23/include/CGAL/Kernel/interface_macros.h b/Kernel_23/include/CGAL/Kernel/interface_macros.h index 1360aa1bbcdf..0acc0a4c6909 100644 --- a/Kernel_23/include/CGAL/Kernel/interface_macros.h +++ b/Kernel_23/include/CGAL/Kernel/interface_macros.h @@ -398,6 +398,8 @@ CGAL_Kernel_cons(Construct_plane_3, construct_plane_3_object) CGAL_Kernel_cons(Construct_plane_line_intersection_point_3, construct_plane_line_intersection_point_3_object) +CGAL_Kernel_cons(Construct_planes_intersection_point_3, + construct_planes_intersection_point_3_object) CGAL_Kernel_cons(Compute_alpha_for_coplanar_triangle_intersection_3, compute_alpha_for_coplanar_triangle_intersection_3_object) CGAL_Kernel_cons(Construct_point_on_2, From a0658b6423c95f108868f6ce5c65ad1b7b1149ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 6 Jul 2023 15:51:04 +0200 Subject: [PATCH 081/329] track coplanar triangles and use direct point construction --- .../Polygon_mesh_processing/autorefinement.h | 43 ++++++++++--------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 9bbc67efb487..68241773f374 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -167,9 +167,7 @@ do_coplanar_segments_intersect(std::size_t pi, std::size_t qi, } } - // supporting_line intersects: points are coplanar - // TODO: check if we can write a dedicated predicate taking advantage of p,q being shared ::CGAL::Orientation pqr = cpl_orient(p, q, r); ::CGAL::Orientation pqs = cpl_orient(p, q, s); @@ -609,7 +607,7 @@ void test_edge(const typename K::Point_3& p, const typename K::Point_3& q, } template -void collect_intersections(const std::array& t1, +bool collect_intersections(const std::array& t1, const std::array& t2, std::vector& inter_pts) { @@ -626,7 +624,7 @@ void collect_intersections(const std::array& t1, if (depth(p)>2) throw std::runtime_error("Depth is not 4: "+std::to_string(depth(p))); #endif - return; + return true; } for (int i=0; i<3; ++i) @@ -653,6 +651,8 @@ void collect_intersections(const std::array& t1, for (auto p : inter_pts) if (depth(p)>2) throw std::runtime_error("Depth is not 2: "+std::to_string(depth(p))); #endif + + return false; } ////////////////////////////////// @@ -672,6 +672,7 @@ void generate_subtriangles(std::size_t ti, std::vector& points, const std::vector& in_triangle_ids, const std::set >& intersecting_triangles, + const std::set >& coplanar_triangles, const std::vector>& triangles, PointVector& new_triangles ) @@ -789,11 +790,6 @@ void generate_subtriangles(std::size_t ti, { std::size_t nbs = segments.size(); - auto supporting_plane = [](const std::array& t) - { - return typename EK::Plane_3(t[0], t[1], t[2]); - }; - std::vector< std::vector > points_on_segments(nbs); COUNTER_INSTRUCTION(counter.timer1.start();) @@ -868,17 +864,19 @@ void generate_subtriangles(std::size_t ti, } case POINT_INTERSECTION: { - // TODO: use version with no variant - COUNTER_INSTRUCTION(counter.timer6.start();) - auto res = CGAL::intersection(supporting_plane(triangles[in_triangle_ids[i]]), - supporting_plane(triangles[in_triangle_ids[j]]), - supporting_plane(triangles[ti])); - COUNTER_INSTRUCTION(counter.timer6.stop();) - - if (const typename EK::Point_3* pt_ptr = boost::get(&(*res))) + if ( coplanar_triangles.count(CGAL::make_sorted_pair(in_triangle_ids[i], in_triangle_ids[j])) == 0 + && coplanar_triangles.count(CGAL::make_sorted_pair(ti, in_triangle_ids[j])) == 0 + && coplanar_triangles.count(CGAL::make_sorted_pair(in_triangle_ids[i], ti)) == 0) { + COUNTER_INSTRUCTION(counter.timer6.start();) + typename EK::Point_3 pt = typename EK::Construct_planes_intersection_point_3()( + triangles[in_triangle_ids[i]][0], triangles[in_triangle_ids[i]][1],triangles[in_triangle_ids[i]][2], + triangles[in_triangle_ids[j]][0], triangles[in_triangle_ids[j]][1],triangles[in_triangle_ids[j]][2], + triangles[ti][0], triangles[ti][1],triangles[ti][2]); + COUNTER_INSTRUCTION(counter.timer6.stop();) + COUNTER_INSTRUCTION(++counter.c1;) - std::size_t pid = get_point_id(*pt_ptr); + std::size_t pid = get_point_id(pt); points_on_segments[i].push_back(pid); points_on_segments[j].push_back(pid); } @@ -1198,7 +1196,8 @@ void autorefine_soup_output(const PointRange& input_points, Real_timer t; t.start(); #endif - std::set > intersecting_triangles; + std::set > intersecting_triangles; // TODO replace with vector>> + std::set > coplanar_triangles; // TODO replace with vector>> //TODO: PARALLEL_FOR #2 for (const Pair_of_triangle_ids& p : si_pairs) { @@ -1211,7 +1210,7 @@ void autorefine_soup_output(const PointRange& input_points, const std::array& t2 = triangles[i2]; std::vector inter_pts; - autorefine_impl::collect_intersections(t1, t2, inter_pts); + bool triangles_are_coplanar = autorefine_impl::collect_intersections(t1, t2, inter_pts); CGAL_assertion( CGAL::do_intersect(typename EK::Triangle_3(t1[0], t1[1], t1[2]), typename EK::Triangle_3(t2[0], t2[1], t2[2])) @@ -1242,6 +1241,8 @@ void autorefine_soup_output(const PointRange& input_points, } } intersecting_triangles.insert(CGAL::make_sorted_pair(i1, i2)); + if (triangles_are_coplanar) + coplanar_triangles.insert(CGAL::make_sorted_pair(i1, i2)); } } #ifdef USE_DEBUG_PARALLEL_TIMERS @@ -1369,7 +1370,7 @@ void autorefine_soup_output(const PointRange& input_points, autorefine_impl::generate_subtriangles(ti, all_segments[ti], all_points[ti], all_in_triangle_ids[ti], intersecting_triangles, triangles, new_triangles); } #else - autorefine_impl::generate_subtriangles(ti, all_segments_ids[ti], all_points[ti], all_in_triangle_ids[ti], intersecting_triangles, triangles, new_triangles); + autorefine_impl::generate_subtriangles(ti, all_segments_ids[ti], all_points[ti], all_in_triangle_ids[ti], intersecting_triangles, coplanar_triangles, triangles, new_triangles); #endif } From bab2c72674903679a632566debb595c34505efe8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 6 Jul 2023 16:53:51 +0200 Subject: [PATCH 082/329] add functor to compute intersection point of coplanar segments --- .../include/CGAL/Kernel/function_objects.h | 34 +++++++++++++++++++ .../include/CGAL/Kernel/interface_macros.h | 2 ++ 2 files changed, 36 insertions(+) diff --git a/Kernel_23/include/CGAL/Kernel/function_objects.h b/Kernel_23/include/CGAL/Kernel/function_objects.h index 438dc0de14be..6917a06edcf3 100644 --- a/Kernel_23/include/CGAL/Kernel/function_objects.h +++ b/Kernel_23/include/CGAL/Kernel/function_objects.h @@ -2228,6 +2228,40 @@ namespace CommonKernelFunctors { } }; + template + class Construct_coplanar_segments_intersection_point_3 + { + typedef typename K::Segment_3 Segment; + typedef typename K::Point_3 Point; + typename K::Construct_segment_3 construct_segment; + public: + typedef Point result_type; + + Point + operator()(const Point& p1, const Point& q1, + const Point& p2, const Point& q2) const + { + Segment s1 = construct_segment(p1, q1); + Segment s2 = construct_segment(p2, q2); + + const auto res = typename K::Intersect_3()(s1, s2); + CGAL_assertion(res!=boost::none); + const Point* e_pt = boost::get(&(*res)); + CGAL_assertion(e_pt!=nullptr); + return *e_pt; + } + + Point + operator()(const Segment& s1, const Segment& s2) const + { + const auto res = typename K::Intersect_3()(s1, s2); + CGAL_assertion(res!=boost::none); + const Point* e_pt = boost::get(&(*res)); + CGAL_assertion(e_pt!=nullptr); + return *e_pt; + } + }; + template class Compute_alpha_for_coplanar_triangle_intersection_3 { diff --git a/Kernel_23/include/CGAL/Kernel/interface_macros.h b/Kernel_23/include/CGAL/Kernel/interface_macros.h index 0acc0a4c6909..a2314aef1b79 100644 --- a/Kernel_23/include/CGAL/Kernel/interface_macros.h +++ b/Kernel_23/include/CGAL/Kernel/interface_macros.h @@ -400,6 +400,8 @@ CGAL_Kernel_cons(Construct_plane_line_intersection_point_3, construct_plane_line_intersection_point_3_object) CGAL_Kernel_cons(Construct_planes_intersection_point_3, construct_planes_intersection_point_3_object) +CGAL_Kernel_cons(Construct_coplanar_segments_intersection_point_3, + construct_coplanar_segments_intersection_point_3_object) CGAL_Kernel_cons(Compute_alpha_for_coplanar_triangle_intersection_3, compute_alpha_for_coplanar_triangle_intersection_3_object) CGAL_Kernel_cons(Construct_point_on_2, From e7490ee31fe90b243c558b3742614bd0785f9796 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 6 Jul 2023 16:54:37 +0200 Subject: [PATCH 083/329] use direct construction of coplanar segment intersection --- .../Polygon_mesh_processing/autorefinement.h | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 68241773f374..693c00676f05 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -884,20 +884,13 @@ void generate_subtriangles(std::size_t ti, { COUNTER_INSTRUCTION(++counter.c2;) COUNTER_INSTRUCTION(counter.timer4.start();) - //TODO find better! - typename EK::Segment_3 s1(points[segments[i].first], points[segments[i].second]); - typename EK::Segment_3 s2(points[segments[j].first], points[segments[j].second]);// TODO: avoid this construction - auto inter = CGAL::intersection(s1, s2); - if (inter == boost::none) throw std::runtime_error("Unexpected case #2"); - if (const typename EK::Point_3* pt_ptr = boost::get(&(*inter))) - { - std::size_t pid = get_point_id(*pt_ptr); - points_on_segments[i].push_back(pid); - points_on_segments[j].push_back(pid); - break; - } - else - throw std::runtime_error("Unexpected case 1"); + typename EK::Point_3 pt = typename EK::Construct_coplanar_segments_intersection_point_3()( + points[segments[i].first], points[segments[i].second], + points[segments[j].first], points[segments[j].second]); + + std::size_t pid = get_point_id(pt); + points_on_segments[i].push_back(pid); + points_on_segments[j].push_back(pid); COUNTER_INSTRUCTION(counter.timer4.stop();) //~ std::ofstream debug ("/tmp/triangles.polylines.txt"); //~ debug << "4 " << triangles[ti][0] << " " << triangles[ti][1] << " " << triangles[ti][2] << " " << triangles[ti][0] << "\n"; From 806ffa9385e985216b34f870ad21b32982c2272e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 6 Jul 2023 17:40:28 +0200 Subject: [PATCH 084/329] remove TODO I don't think a predicate sorting planes along a ray would be faster than directly using intersection coordinates --- .../include/CGAL/Polygon_mesh_processing/autorefinement.h | 1 - 1 file changed, 1 deletion(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 693c00676f05..122c595b13e8 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -959,7 +959,6 @@ void generate_subtriangles(std::size_t ti, { if(!points_on_segments[i].empty()) { - // TODO: predicate on input triangles int coord = 0; std::size_t src_id = segments[i].first, tgt_id = segments[i].second; typename EK::Point_3 src = points[src_id], tgt=points[tgt_id]; From fdb6b799a9f41d5cfea056801196504351b4da5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 21 Jul 2023 13:32:25 +0200 Subject: [PATCH 085/329] add doc + do the autorefine inplace for the soup --- .../PackageDescription.txt | 2 + .../soup_autorefinement.cpp | 11 +- .../Polygon_mesh_processing/autorefinement.h | 168 ++++++++++++------ 3 files changed, 116 insertions(+), 65 deletions(-) diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt index b17c41399d0b..95d8794cca1e 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt @@ -109,6 +109,8 @@ The page \ref bgl_namedparameters "Named Parameters" describes their usage. - `CGAL::Polygon_mesh_processing::surface_intersection()` - `CGAL::Polygon_mesh_processing::clip()` - `CGAL::Polygon_mesh_processing::split()` +- `CGAL::Polygon_mesh_processing::autorefine_triangle_soup()` +- `CGAL::Polygon_mesh_processing::autorefine()` \cgalCRPSection{Meshing Functions} - \link PMP_meshing_grp `CGAL::Polygon_mesh_processing::isotropic_remeshing()` \endlink diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp index 9e4999287f7b..a44d47c8b6d1 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp @@ -32,14 +32,11 @@ int main(int argc, char** argv) CGAL::Real_timer t; t.start(); - std::vector output_points; - std::vector> output_triangles; - PMP::autorefine_soup_output(input_points, input_triangles, - output_points, output_triangles, - CGAL::parameters::concurrency_tag(CGAL::Parallel_if_available_tag())); + PMP::autorefine_triangle_soup(input_points, input_triangles, + CGAL::parameters::concurrency_tag(CGAL::Parallel_if_available_tag())); t.stop(); - std::cout << "#points = " << output_points.size() << " and #triangles = " << output_triangles.size() << " in " << t.time() << " sec." << std::endl; - CGAL::IO::write_polygon_soup("autorefined.off", output_points, output_triangles, CGAL::parameters::stream_precision(17)); + std::cout << "#points = " << input_points.size() << " and #triangles = " << input_triangles.size() << " in " << t.time() << " sec." << std::endl; + CGAL::IO::write_polygon_soup("autorefined.off", input_points, input_triangles, CGAL::parameters::stream_precision(17)); return 0; } diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 122c595b13e8..bfa65df1c73e 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -31,10 +31,15 @@ #endif // output -#include +#include #include #include + +#ifdef CGAL_PMP_AUTOREFINE_USE_DEFAULT_VERBOSE +#define CGAL_PMP_AUTOREFINE_VERBOSE(X) std::cout << X << "\n"; +#endif + #ifndef CGAL_PMP_AUTOREFINE_VERBOSE #define CGAL_PMP_AUTOREFINE_VERBOSE(MSG) #endif @@ -1100,13 +1105,54 @@ void generate_subtriangles(std::size_t ti, } } // end of autorefine_impl +#endif -template -void autorefine_soup_output(const PointRange& input_points, - const TriIdsRange& id_triples, - std::vector& soup_points, - std::vector >& soup_triangles, - const NamedParameters& np = parameters::default_values()) +/** +* \ingroup PMP_corefinement_grp +* +* refines a soup of triangles so that no pair of triangles intersects in their interior. +* Note that points in `input_points` can only be added (intersection points) a the end of the container, with the initial order preserved. +* Note that if `input_points` contains two or more identical points and only the first copy (following the order in the `input_points`) +* will be used in `id_triples`. +* `id_triples` will be updated to contain both the input triangles and the new subdivides triangles. Degenerate triangles will be removed. +* Also triangles in `id_triples` will be triangles without intersection first, followed by triangles coming from a subdivision induced +* by an intersection. The named parameter `visitor()` can be used to track +* +* @tparam PointRange a model of the concept `RandomAccessContainer` +* whose value type is the point type +* @tparam TriIdsRange a model of the concepts `RandomAccessContainer`, `BackInsertionSequence` and `Swappable`, whose +* value type is a model of the concept `RandomAccessContainer` whose value type is convertible to `std::size_t` and that +* is constructible from an `std::initializer_list` of size 3. +* @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" +* +* @param input_points points of the soup of polygons +* @param id_triples each element in the range describes a triangle using the indexed position of the points in `input_points` +* @param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below +* +* \cgalNamedParamsBegin +* \cgalParamNBegin{point_map} +* \cgalParamDescription{a property map associating points to the elements of the range `input_points`} +* \cgalParamType{a model of `ReadWritePropertyMap` whose value type is a point type} +* \cgalParamDefault{`CGAL::Identity_property_map`} +* \cgalParamNEnd +* \cgalParamNBegin{geom_traits} +* \cgalParamDescription{an instance of a geometric traits class} +* \cgalParamType{a class model of `Kernel`} +* \cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`} +* \cgalParamExtra{The geometric traits class must be compatible with the point type.} +* \cgalParamNEnd +* \cgalParamNBegin{visitor} +* \cgalParamDescription{a visitor used to track the creation of new faces} +* \cgalParamType{a class model of `PMPFooBar`} +* \cgalParamDefault{`Autorefinement::Default_visitor`} +* \cgalParamNEnd +* \cgalNamedParamsEnd +* +*/ +template +void autorefine_triangle_soup(PointRange& input_points, + TriIdsRange& id_triples, + const NamedParameters& np = parameters::default_values()) { using parameters::choose_parameter; using parameters::get_parameter; @@ -1121,14 +1167,13 @@ void autorefine_soup_output(const PointRange& input_points, Sequential_tag > ::type Concurrency_tag; - constexpr bool parallel_execution = std::is_same::value; + constexpr bool parallel_execution = std::is_same_v; #ifndef CGAL_LINKED_WITH_TBB - CGAL_static_assertion_msg (parallel_execution, - "Parallel_tag is enabled but TBB is unavailable."); + static_assert (!parallel_execution, + "Parallel_tag is enabled but TBB is unavailable."); #endif - typedef std::size_t Input_TID; typedef std::pair Pair_of_triangle_ids; @@ -1334,7 +1379,6 @@ void autorefine_soup_output(const PointRange& input_points, boost::timer::progress_display pd(triangles.size()); #endif - auto refine_triangles = [&](std::size_t ti) { if (all_segments[ti].empty() && all_points[ti].empty()) @@ -1371,7 +1415,6 @@ void autorefine_soup_output(const PointRange& input_points, #endif }; - #ifdef USE_DEBUG_PARALLEL_TIMERS t.start(); #endif @@ -1415,25 +1458,22 @@ void autorefine_soup_output(const PointRange& input_points, std::vector exact_soup_points; #endif - /// Lambda get_point_id() - auto get_point_id = [&](const typename EK::Point_3& pt) + // TODO: parallel_for? + // for input points, we on purpose keep duplicated points and isolated points + for (std::size_t pid = 0; pidsecond; - }; + point_id_map.insert( + std::make_pair(to_exact(get(pm,input_points[pid])), pid)); +#if ! defined(CGAL_NDEBUG) || defined(CGAL_DEBUG_PMP_AUTOREFINE) + exact_soup_points.push_back(insert_res.first->first); +#endif + } - // TODO: parallel_for? - std::vector input_point_ids; - input_point_ids.reserve(input_points.size()); - for (const auto& p : input_points) - input_point_ids.push_back(get_point_id(to_exact(get(pm,p)))); + TriIdsRange soup_triangles; + soup_triangles.reserve(id_triples.size()); // TODO: remove #deg tri? // raw copy of input triangles with no intersection for (Input_TID f=0; fsecond; + }; + #ifdef USE_DEBUG_PARALLEL_TIMERS t.start(); #endif @@ -1465,7 +1518,6 @@ void autorefine_soup_output(const PointRange& input_points, #ifdef CGAL_LINKED_WITH_TBB if(parallel_execution && new_triangles.size() > 100) { - #ifdef SET_POINT_IDS_USING_MUTEX //option 1 (using a mutex) CGAL_MUTEX point_container_mutex; @@ -1477,8 +1529,8 @@ void autorefine_soup_output(const PointRange& input_points, if (insert_res.second) { CGAL_SCOPED_LOCK(point_container_mutex); - insert_res.first->second=soup_points.size(); - soup_points.push_back(to_input(pt)); + insert_res.first->second=input_points.size(); + input_points.push_back(to_input(pt)); #if ! defined(CGAL_NDEBUG) || defined(CGAL_DEBUG_PMP_AUTOREFINE) exact_soup_points.push_back(pt); #endif @@ -1502,9 +1554,9 @@ void autorefine_soup_output(const PointRange& input_points, for (size_t ti = r.begin(); ti != r.end(); ++ti) { soup_triangles[offset + ti] = - CGAL::make_array(triangle_buffer[ti][0]->second, - triangle_buffer[ti][1]->second, - triangle_buffer[ti][2]->second); + { triangle_buffer[ti][0]->second, + triangle_buffer[ti][1]->second, + triangle_buffer[ti][2]->second }; } } ); @@ -1536,17 +1588,17 @@ void autorefine_soup_output(const PointRange& input_points, ); // the map is now filled we can safely set the point ids - std::size_t pid_offset=soup_points.size(); - soup_points.resize(pid_offset+iterators.size()); + std::size_t pid_offset=input_points.size(); + input_points.resize(pid_offset+iterators.size()); #if ! defined(CGAL_NDEBUG) || defined(CGAL_DEBUG_PMP_AUTOREFINE) - exact_soup_points.resize(soup_points.size()); + exact_soup_points.resize(input_points.size()); #endif tbb::parallel_for(tbb::blocked_range(0, iterators.size()), [&](const tbb::blocked_range& r) { for (size_t ti = r.begin(); ti != r.end(); ++ti) { - soup_points[pid_offset+ti] = to_input(iterators[ti]->first); + input_points[pid_offset+ti] = to_input(iterators[ti]->first); #if ! defined(CGAL_NDEBUG) || defined(CGAL_DEBUG_PMP_AUTOREFINE) exact_soup_points[pid_offset+ti] = iterators[ti]->first; #endif @@ -1560,9 +1612,9 @@ void autorefine_soup_output(const PointRange& input_points, for (size_t ti = r.begin(); ti != r.end(); ++ti) { soup_triangles[offset + ti] = - CGAL::make_array(triangle_buffer[ti][0]->second, - triangle_buffer[ti][1]->second, - triangle_buffer[ti][2]->second); + { triangle_buffer[ti][0]->second, + triangle_buffer[ti][1]->second, + triangle_buffer[ti][2]->second }; } } ); @@ -1576,7 +1628,7 @@ void autorefine_soup_output(const PointRange& input_points, #endif soup_triangles.reserve(offset + new_triangles.size()); for (const std::array& t : new_triangles) - soup_triangles.emplace_back(CGAL::make_array(get_point_id(t[0]), get_point_id(t[1]), get_point_id(t[2]))); + soup_triangles.push_back({ get_point_id(t[0]), get_point_id(t[1]), get_point_id(t[2])}); } @@ -1597,9 +1649,11 @@ void autorefine_soup_output(const PointRange& input_points, throw std::runtime_error("ERROR: invalid output, there is most probably a bug"); #endif #endif + using std::swap; + swap(id_triples, soup_triangles); + CGAL_PMP_AUTOREFINE_VERBOSE("done"); } -#endif /** * \ingroup PMP_corefinement_grp @@ -1639,22 +1693,20 @@ autorefine( TriangleMesh& tm, using parameters::get_parameter; typedef typename GetGeomTraits::type GT; - GT traits = choose_parameter(get_parameter(np, internal_np::geom_traits)); + // GT traits = choose_parameter(get_parameter(np, internal_np::geom_traits)); - std::vector in_soup_points; - std::vector > in_soup_triangles; - std::vector out_soup_points; - std::vector > out_soup_triangles; + std::vector soup_points; + std::vector > soup_triangles; - polygon_mesh_to_polygon_soup(tm, in_soup_points, in_soup_triangles); + polygon_mesh_to_polygon_soup(tm, soup_points, soup_triangles, np); - autorefine_soup_output(in_soup_points, in_soup_triangles, - out_soup_points, out_soup_triangles); + autorefine_triangle_soup(soup_points, soup_triangles); clear(tm); - repair_polygon_soup(out_soup_points, out_soup_triangles); - orient_polygon_soup(out_soup_points, out_soup_triangles); - polygon_soup_to_polygon_mesh(out_soup_points, out_soup_triangles, tm); + repair_polygon_soup(soup_points, soup_triangles); + + duplicate_non_manifold_edges_in_polygon_soup(soup_points, soup_triangles); + polygon_soup_to_polygon_mesh(soup_points, soup_triangles, tm); } From d6fdc85be9bb5c95b4fdf59379a67033a98b2d36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 21 Jul 2023 13:38:10 +0200 Subject: [PATCH 086/329] rename variables --- .../Polygon_mesh_processing/autorefinement.h | 84 +++++++++---------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index bfa65df1c73e..0054a9dcdb2d 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -1111,11 +1111,11 @@ void generate_subtriangles(std::size_t ti, * \ingroup PMP_corefinement_grp * * refines a soup of triangles so that no pair of triangles intersects in their interior. -* Note that points in `input_points` can only be added (intersection points) a the end of the container, with the initial order preserved. -* Note that if `input_points` contains two or more identical points and only the first copy (following the order in the `input_points`) -* will be used in `id_triples`. -* `id_triples` will be updated to contain both the input triangles and the new subdivides triangles. Degenerate triangles will be removed. -* Also triangles in `id_triples` will be triangles without intersection first, followed by triangles coming from a subdivision induced +* Note that points in `soup_points` can only be added (intersection points) a the end of the container, with the initial order preserved. +* Note that if `soup_points` contains two or more identical points and only the first copy (following the order in the `soup_points`) +* will be used in `soup_triangles`. +* `soup_triangles` will be updated to contain both the input triangles and the new subdivides triangles. Degenerate triangles will be removed. +* Also triangles in `soup_triangles` will be triangles without intersection first, followed by triangles coming from a subdivision induced * by an intersection. The named parameter `visitor()` can be used to track * * @tparam PointRange a model of the concept `RandomAccessContainer` @@ -1125,13 +1125,13 @@ void generate_subtriangles(std::size_t ti, * is constructible from an `std::initializer_list` of size 3. * @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" * -* @param input_points points of the soup of polygons -* @param id_triples each element in the range describes a triangle using the indexed position of the points in `input_points` +* @param soup_points points of the soup of polygons +* @param soup_triangles each element in the range describes a triangle using the indexed position of the points in `soup_points` * @param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below * * \cgalNamedParamsBegin * \cgalParamNBegin{point_map} -* \cgalParamDescription{a property map associating points to the elements of the range `input_points`} +* \cgalParamDescription{a property map associating points to the elements of the range `soup_points`} * \cgalParamType{a model of `ReadWritePropertyMap` whose value type is a point type} * \cgalParamDefault{`CGAL::Identity_property_map`} * \cgalParamNEnd @@ -1150,8 +1150,8 @@ void generate_subtriangles(std::size_t ti, * */ template -void autorefine_triangle_soup(PointRange& input_points, - TriIdsRange& id_triples, +void autorefine_triangle_soup(PointRange& soup_points, + TriIdsRange& soup_triangles, const NamedParameters& np = parameters::default_values()) { using parameters::choose_parameter; @@ -1181,12 +1181,12 @@ void autorefine_triangle_soup(PointRange& input_points, // collect intersecting pairs of triangles CGAL_PMP_AUTOREFINE_VERBOSE("collect intersecting pairs"); - triangle_soup_self_intersections(input_points, id_triples, std::back_inserter(si_pairs), np); + triangle_soup_self_intersections(soup_points, soup_triangles, std::back_inserter(si_pairs), np); if (si_pairs.empty()) return; // mark degenerate faces so that we can ignore them - std::vector is_degen(id_triples.size(), false); + std::vector is_degen(soup_triangles.size(), false); for (const Pair_of_triangle_ids& p : si_pairs) if (p.first==p.second) // bbox inter reports (f,f) for degenerate faces @@ -1194,7 +1194,7 @@ void autorefine_triangle_soup(PointRange& input_points, // assign an id per triangle involved in an intersection // + the faces involved in the intersection - std::vector tri_inter_ids(id_triples.size(), -1); + std::vector tri_inter_ids(soup_triangles.size(), -1); std::vector intersected_faces; int tiid=-1; for (const Pair_of_triangle_ids& p : si_pairs) @@ -1219,9 +1219,9 @@ void autorefine_triangle_soup(PointRange& input_points, for(Input_TID f : intersected_faces) { triangles[tri_inter_ids[f]]= CGAL::make_array( - to_exact( get(pm, input_points[id_triples[f][0]]) ), - to_exact( get(pm, input_points[id_triples[f][1]]) ), - to_exact( get(pm, input_points[id_triples[f][2]]) ) ); + to_exact( get(pm, soup_points[soup_triangles[f][0]]) ), + to_exact( get(pm, soup_points[soup_triangles[f][1]]) ), + to_exact( get(pm, soup_points[soup_triangles[f][2]]) ) ); } std::vector< std::vector > > all_segments(triangles.size()); @@ -1460,31 +1460,31 @@ void autorefine_triangle_soup(PointRange& input_points, // TODO: parallel_for? // for input points, we on purpose keep duplicated points and isolated points - for (std::size_t pid = 0; pidfirst); #endif } - TriIdsRange soup_triangles; - soup_triangles.reserve(id_triples.size()); // TODO: remove #deg tri? + TriIdsRange soup_triangles_out; + soup_triangles_out.reserve(soup_triangles.size()); // TODO: remove #deg tri? // raw copy of input triangles with no intersection - for (Input_TID f=0; fsecond=input_points.size(); - input_points.push_back(to_input(pt)); + insert_res.first->second=soup_points.size(); + soup_points.push_back(to_input(pt)); #if ! defined(CGAL_NDEBUG) || defined(CGAL_DEBUG_PMP_AUTOREFINE) exact_soup_points.push_back(pt); #endif @@ -1538,7 +1538,7 @@ void autorefine_triangle_soup(PointRange& input_points, return insert_res.first; }; - soup_triangles.resize(offset + new_triangles.size()); + soup_triangles_out.resize(offset + new_triangles.size()); //use map iterator triple for triangles to create them concurrently and safely std::vector::iterator, 3>> triangle_buffer(new_triangles.size()); tbb::parallel_for(tbb::blocked_range(0, new_triangles.size()), @@ -1553,7 +1553,7 @@ void autorefine_triangle_soup(PointRange& input_points, [&](const tbb::blocked_range& r) { for (size_t ti = r.begin(); ti != r.end(); ++ti) { - soup_triangles[offset + ti] = + soup_triangles_out[offset + ti] = { triangle_buffer[ti][0]->second, triangle_buffer[ti][1]->second, triangle_buffer[ti][2]->second }; @@ -1573,12 +1573,12 @@ void autorefine_triangle_soup(PointRange& input_points, }; //use map iterator triple for triangles to create them concurrently and safely - soup_triangles.resize(offset + new_triangles.size()); + soup_triangles_out.resize(offset + new_triangles.size()); std::vector::iterator, 3>> triangle_buffer(new_triangles.size()); tbb::parallel_for(tbb::blocked_range(0, new_triangles.size()), [&](const tbb::blocked_range& r) { for (size_t ti = r.begin(); ti != r.end(); ++ti) { - if (offset + ti > soup_triangles.size()) { + if (offset + ti > soup_triangles_out.size()) { std::cout << "ti = " << ti << std::endl; } const std::array& t = new_triangles[ti]; @@ -1588,17 +1588,17 @@ void autorefine_triangle_soup(PointRange& input_points, ); // the map is now filled we can safely set the point ids - std::size_t pid_offset=input_points.size(); - input_points.resize(pid_offset+iterators.size()); + std::size_t pid_offset=soup_points.size(); + soup_points.resize(pid_offset+iterators.size()); #if ! defined(CGAL_NDEBUG) || defined(CGAL_DEBUG_PMP_AUTOREFINE) - exact_soup_points.resize(input_points.size()); + exact_soup_points.resize(soup_points.size()); #endif tbb::parallel_for(tbb::blocked_range(0, iterators.size()), [&](const tbb::blocked_range& r) { for (size_t ti = r.begin(); ti != r.end(); ++ti) { - input_points[pid_offset+ti] = to_input(iterators[ti]->first); + soup_points[pid_offset+ti] = to_input(iterators[ti]->first); #if ! defined(CGAL_NDEBUG) || defined(CGAL_DEBUG_PMP_AUTOREFINE) exact_soup_points[pid_offset+ti] = iterators[ti]->first; #endif @@ -1611,7 +1611,7 @@ void autorefine_triangle_soup(PointRange& input_points, [&](const tbb::blocked_range& r) { for (size_t ti = r.begin(); ti != r.end(); ++ti) { - soup_triangles[offset + ti] = + soup_triangles_out[offset + ti] = { triangle_buffer[ti][0]->second, triangle_buffer[ti][1]->second, triangle_buffer[ti][2]->second }; @@ -1626,9 +1626,9 @@ void autorefine_triangle_soup(PointRange& input_points, #ifdef USE_DEBUG_PARALLEL_TIMERS mode = "sequential"; #endif - soup_triangles.reserve(offset + new_triangles.size()); + soup_triangles_out.reserve(offset + new_triangles.size()); for (const std::array& t : new_triangles) - soup_triangles.push_back({ get_point_id(t[0]), get_point_id(t[1]), get_point_id(t[2])}); + soup_triangles_out.push_back({ get_point_id(t[0]), get_point_id(t[1]), get_point_id(t[2])}); } @@ -1641,16 +1641,16 @@ void autorefine_triangle_soup(PointRange& input_points, #ifndef CGAL_NDEBUG CGAL_PMP_AUTOREFINE_VERBOSE("check soup"); - CGAL_assertion( !does_triangle_soup_self_intersect(exact_soup_points, soup_triangles) ); + CGAL_assertion( !does_triangle_soup_self_intersect(exact_soup_points, soup_triangles_out) ); #else #ifdef CGAL_DEBUG_PMP_AUTOREFINE CGAL_PMP_AUTOREFINE_VERBOSE("check soup"); - if (does_triangle_soup_self_intersect(exact_soup_points, soup_triangles)) + if (does_triangle_soup_self_intersect(exact_soup_points, soup_triangles_out)) throw std::runtime_error("ERROR: invalid output, there is most probably a bug"); #endif #endif using std::swap; - swap(id_triples, soup_triangles); + swap(soup_triangles, soup_triangles_out); CGAL_PMP_AUTOREFINE_VERBOSE("done"); } From e1d7105c1cf58cabbd38d71cc3a5be8aa871ddf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 21 Jul 2023 16:47:03 +0200 Subject: [PATCH 087/329] add visitor + add calls to the visitor --- .../Concepts/PMPAutorefinementVisitor.h | 25 +++++++ .../Polygon_mesh_processing/autorefinement.h | 75 +++++++++++++++---- 2 files changed, 84 insertions(+), 16 deletions(-) create mode 100644 Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPAutorefinementVisitor.h diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPAutorefinementVisitor.h b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPAutorefinementVisitor.h new file mode 100644 index 000000000000..e3ef90e9be03 --- /dev/null +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPAutorefinementVisitor.h @@ -0,0 +1,25 @@ +/// \ingroup PkgPolygonMeshProcessingConcepts +/// \cgalConcept +/// +/// The concept `PMPAutorefinementVisitor` defines the requirements for the visitor +/// used in `CGAL::Polygon_mesh_processing::autorefine_triangle_soup()` to track +/// the creation of new triangles. +/// +/// \cgalRefines{CopyConstructible} +/// \cgalHasModel `CGAL::Polygon_mesh_processing::Autorefinement::Default_visitor`. + +class PMPAutorefinementVisitor{ +public: + +/// @name Functions called only if at least one intersection has been found +/// @{ + /// called when the final number of output triangles is known, `nbt` being the total number of triangles in the output. + void number_of_output_triangles(std::size_t nbt); + /// called for triangle with no intersection, `tgt_id` is the position in the triangle container after calling + /// `autorefine_triangle_soup()`, while `src_id` was its position before calling the function. + void verbatim_triangle_copy(std::size_t tgt_id, std::size_t src_id); + /// called for each subtriangle created from a triangle with intersection, `tgt_id` is the position in the triangle container after calling + /// `autorefine_triangle_soup()` of the subtriangle, while `src_id` was the position of the original support triangle before calling the function. + void new_subtriangle(std::size_t tgt_id, std::size_t src_id); +/// @} +}; diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 0054a9dcdb2d..166c950a9830 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -77,6 +77,24 @@ namespace CGAL { namespace Polygon_mesh_processing { +namespace Autorefinement { + +/** \ingroup PMP_corefinement_grp + * %Default visitor model of `PMPAutorefinementVisitor`. + * All of its functions have an empty body. This class can be used as a + * base class if only some of the functions of the concept require to be + * overridden. + */ +struct Default_visitor +{ + inline void number_of_output_triangles(std::size_t /*nbt*/) {} + inline void verbatim_triangle_copy(std::size_t /*tgt_id*/, std::size_t /*src_id*/) {} + inline void new_subtriangle(std::size_t /*tgt_id*/, std::size_t /*src_id*/) {} +}; + +} // end of Autorefinement visitor + + #ifndef DOXYGEN_RUNNING namespace autorefine_impl { @@ -1079,13 +1097,13 @@ void generate_subtriangles(std::size_t ti, for (typename CDT::Face_handle fh : cdt.finite_face_handles()) { if (orientation_flipped) - new_triangles.push_back( CGAL::make_array(fh->vertex(0)->point(), - fh->vertex(cdt.cw(0))->point(), - fh->vertex(cdt.ccw(0))->point()) ); + new_triangles.push_back( { CGAL::make_array(fh->vertex(0)->point(), + fh->vertex(cdt.cw(0))->point(), + fh->vertex(cdt.ccw(0))->point()), ti } ); else - new_triangles.push_back( CGAL::make_array(fh->vertex(0)->point(), - fh->vertex(cdt.ccw(0))->point(), - fh->vertex(cdt.cw(0))->point()) ); + new_triangles.push_back( { CGAL::make_array(fh->vertex(0)->point(), + fh->vertex(cdt.ccw(0))->point(), + fh->vertex(cdt.cw(0))->point()), ti } ); #ifdef CGAL_DEBUG_PMP_AUTOREFINE_DUMP_TRIANGULATIONS ++nbt; buffer << fh->vertex(0)->point() << "\n"; @@ -1143,8 +1161,9 @@ void generate_subtriangles(std::size_t ti, * \cgalParamNEnd * \cgalParamNBegin{visitor} * \cgalParamDescription{a visitor used to track the creation of new faces} -* \cgalParamType{a class model of `PMPFooBar`} -* \cgalParamDefault{`Autorefinement::Default_visitor`} +* \cgalParamType{a class model of `PMPAutorefinementVisitor`} +* \cgalParamDefault{`Autorefinement::Default_visitor`} +* \cgalParamExtra{The visitor will be copied.} * \cgalParamNEnd * \cgalNamedParamsEnd * @@ -1167,6 +1186,15 @@ void autorefine_triangle_soup(PointRange& soup_points, Sequential_tag > ::type Concurrency_tag; + // visitor + typedef typename internal_np::Lookup_named_param_def < + internal_np::visitor_t, + NamedParameters, + Autorefinement::Default_visitor//default + > ::type Visitor; + Visitor visitor(choose_parameter(get_parameter(np, internal_np::visitor))); + + constexpr bool parallel_execution = std::is_same_v; #ifndef CGAL_LINKED_WITH_TBB @@ -1369,10 +1397,10 @@ void autorefine_triangle_soup(PointRange& soup_points, // now refine triangles #ifdef CGAL_LINKED_WITH_TBB std::conditional_t>, - std::vector>> new_triangles; + tbb::concurrent_vector, std::size_t>>, + std::vector, std::size_t>>> new_triangles; #else - std::vector> new_triangles; + std::vector, std::size_t>> new_triangles; #endif #ifdef USE_PROGRESS_DISPLAY @@ -1382,7 +1410,7 @@ void autorefine_triangle_soup(PointRange& soup_points, auto refine_triangles = [&](std::size_t ti) { if (all_segments[ti].empty() && all_points[ti].empty()) - new_triangles.push_back(triangles[ti]); + new_triangles.push_back({triangles[ti], ti}); else { #ifdef USE_FIXED_PROJECTION_TRAITS @@ -1475,7 +1503,10 @@ void autorefine_triangle_soup(PointRange& soup_points, TriIdsRange soup_triangles_out; soup_triangles_out.reserve(soup_triangles.size()); // TODO: remove #deg tri? + visitor.number_of_output_triangles(soup_triangles.size()+new_triangles.size()); + // raw copy of input triangles with no intersection + std::vector tri_inter_ids_inverse(triangles.size()); for (Input_TID f=0; f(0, new_triangles.size()), [&](const tbb::blocked_range& r) { for (size_t ti = r.begin(); ti != r.end(); ++ti) { - const std::array& t = new_triangles[ti]; + const std::array& t = new_triangles[ti].first; + visitor.new_subtriangle(offset+ti, tri_inter_ids_inverse[new_triangles[ti].second]); triangle_buffer[ti] = CGAL::make_array(concurrent_get_point_id(t[0]), concurrent_get_point_id(t[1]), concurrent_get_point_id(t[2])); } } @@ -1581,7 +1618,8 @@ void autorefine_triangle_soup(PointRange& soup_points, if (offset + ti > soup_triangles_out.size()) { std::cout << "ti = " << ti << std::endl; } - const std::array& t = new_triangles[ti]; + const std::array& t = new_triangles[ti].first; + visitor.new_subtriangle(offset+ti, tri_inter_ids_inverse[new_triangles[ti].second]); triangle_buffer[ti] = CGAL::make_array(concurrent_get_point_id(t[0]), concurrent_get_point_id(t[1]), concurrent_get_point_id(t[2])); } } @@ -1627,8 +1665,13 @@ void autorefine_triangle_soup(PointRange& soup_points, mode = "sequential"; #endif soup_triangles_out.reserve(offset + new_triangles.size()); - for (const std::array& t : new_triangles) - soup_triangles_out.push_back({ get_point_id(t[0]), get_point_id(t[1]), get_point_id(t[2])}); + for (const std::pair, std::size_t>& t_and_id : new_triangles) + { + visitor.new_subtriangle(soup_triangles_out.size(), tri_inter_ids_inverse[t_and_id.second]); + soup_triangles_out.push_back({ get_point_id(t_and_id.first[0]), + get_point_id(t_and_id.first[1]), + get_point_id(t_and_id.first[2]) }); + } } From 9822f371dded06a2538281c5f97b0d343a5c0939 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 21 Jul 2023 16:54:21 +0200 Subject: [PATCH 088/329] doc precision --- .../include/CGAL/Polygon_mesh_processing/autorefinement.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 166c950a9830..6bbb5571e7a1 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -1702,6 +1702,9 @@ void autorefine_triangle_soup(PointRange& soup_points, * \ingroup PMP_corefinement_grp * refines a triangle mesh so that no triangles intersects in their interior. * + * Note that this function is only provided as a shortcut for calling `autorefine_triangle_soup()` + * with a mesh. For any advance usage the aforementioned function should be called directly. + * * @tparam TriangleMesh a model of `HalfedgeListGraph`, `FaceListGraph`, and `MutableFaceGraph` * @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" * @@ -1745,7 +1748,7 @@ autorefine( TriangleMesh& tm, autorefine_triangle_soup(soup_points, soup_triangles); - clear(tm); + clear(tm); //TODO: keep properties repair_polygon_soup(soup_points, soup_triangles); duplicate_non_manifold_edges_in_polygon_soup(soup_points, soup_triangles); From d1779ca36d18ecc1be5d1fb50e9f66a66d47ea61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 21 Jul 2023 17:03:34 +0200 Subject: [PATCH 089/329] doc concurrency_tag --- .../CGAL/Polygon_mesh_processing/autorefinement.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 6bbb5571e7a1..0fb843c31c00 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -1148,6 +1148,11 @@ void generate_subtriangles(std::size_t ti, * @param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below * * \cgalNamedParamsBegin +* \cgalParamNBegin{concurrency_tag} +* \cgalParamDescription{a tag indicating if the task should be done using one or several threads.} +* \cgalParamType{Either `CGAL::Sequential_tag`, or `CGAL::Parallel_tag`, or `CGAL::Parallel_if_available_tag`} +* \cgalParamDefault{`CGAL::Sequential_tag`} +* \cgalParamNEnd * \cgalParamNBegin{point_map} * \cgalParamDescription{a property map associating points to the elements of the range `soup_points`} * \cgalParamType{a model of `ReadWritePropertyMap` whose value type is a point type} @@ -1712,6 +1717,11 @@ void autorefine_triangle_soup(PointRange& soup_points, * @param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below * * \cgalNamedParamsBegin + * \cgalParamNBegin{concurrency_tag} + * \cgalParamDescription{a tag indicating if the task should be done using one or several threads.} + * \cgalParamType{Either `CGAL::Sequential_tag`, or `CGAL::Parallel_tag`, or `CGAL::Parallel_if_available_tag`} + * \cgalParamDefault{`CGAL::Sequential_tag`} + * \cgalParamNEnd * \cgalParamNBegin{geom_traits} * \cgalParamDescription{an instance of a geometric traits class} * \cgalParamType{a class model of `PMPSelfIntersectionTraits`} @@ -1746,7 +1756,7 @@ autorefine( TriangleMesh& tm, polygon_mesh_to_polygon_soup(tm, soup_points, soup_triangles, np); - autorefine_triangle_soup(soup_points, soup_triangles); + autorefine_triangle_soup(soup_points, soup_triangles, np); clear(tm); //TODO: keep properties repair_polygon_soup(soup_points, soup_triangles); From 1f61a84e495f62b71570ad5962411adf4680eb54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 2 Aug 2023 10:30:05 +0200 Subject: [PATCH 090/329] add demo plugin that support refinement of one or several items (soup or mesh) --- .../Polyhedron/Plugins/PMP/CMakeLists.txt | 6 +- .../Plugins/PMP/Repair_polyhedron_plugin.cpp | 105 +++++++++++++++++- 2 files changed, 105 insertions(+), 6 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt index 152d84952ae7..658458acaadf 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt @@ -119,7 +119,11 @@ target_link_libraries( qt5_wrap_ui( repairUI_FILES RemoveNeedlesDialog.ui SelfSnapDialog.ui) polyhedron_demo_plugin(repair_polyhedron_plugin Repair_polyhedron_plugin ${repairUI_FILES} KEYWORDS PMP) -target_link_libraries(repair_polyhedron_plugin PUBLIC scene_points_with_normal_item scene_surface_mesh_item) +target_link_libraries(repair_polyhedron_plugin PUBLIC scene_points_with_normal_item scene_surface_mesh_item scene_polygon_soup_item) +if(TARGET CGAL::TBB_support) + target_link_libraries(repair_polyhedron_plugin PUBLIC CGAL::TBB_support) +endif() + qt5_wrap_ui(isotropicRemeshingUI_FILES Isotropic_remeshing_dialog.ui) polyhedron_demo_plugin(isotropic_remeshing_plugin Isotropic_remeshing_plugin diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Repair_polyhedron_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Repair_polyhedron_plugin.cpp index 5ecc8921433e..dd4acb434272 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Repair_polyhedron_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Repair_polyhedron_plugin.cpp @@ -1,6 +1,7 @@ #include #include "Scene_surface_mesh_item.h" +#include "Scene_polygon_soup_item.h" #include "Scene_points_with_normal_item.h" #include #include @@ -19,6 +20,8 @@ #include #include #include +#include +#include #include "ui_RemoveNeedlesDialog.h" #include "ui_SelfSnapDialog.h" @@ -52,8 +55,9 @@ class Polyhedron_demo_repair_polyhedron_plugin : actionDuplicateNMVertices = new QAction(tr("Duplicate Non-Manifold Vertices"), mw); actionExtractNMVertices = new QAction(tr("Extract 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); + actionAutorefine = new QAction(tr("Autorefine Mesh (Deprecated)"), mw); + actionNewAutorefine = new QAction(tr("Autorefine"), mw); + actionAutorefineAndRMSelfIntersections = new QAction(tr("Autorefine and Remove Self-Intersections (Deprecated)"), mw); actionRemoveNeedlesAndCaps = new QAction(tr("Remove Needles And Caps")); actionSnapBorders = new QAction(tr("Snap Boundaries")); @@ -65,6 +69,7 @@ class Polyhedron_demo_repair_polyhedron_plugin : actionExtractNMVertices->setObjectName("actionExtractNMVertices"); actionMergeDuplicatedVerticesOnBoundaryCycles->setObjectName("actionMergeDuplicatedVerticesOnBoundaryCycles"); actionAutorefine->setObjectName("actionAutorefine"); + actionNewAutorefine->setObjectName("actionNewAutorefine"); actionAutorefineAndRMSelfIntersections->setObjectName("actionAutorefineAndRMSelfIntersections"); actionRemoveNeedlesAndCaps->setObjectName("actionRemoveNeedlesAndCaps"); actionSnapBorders->setObjectName("actionSnapBorders"); @@ -77,6 +82,7 @@ class Polyhedron_demo_repair_polyhedron_plugin : actionExtractNMVertices->setProperty("subMenuName", "Polygon Mesh Processing/Repair"); actionMergeDuplicatedVerticesOnBoundaryCycles->setProperty("subMenuName", "Polygon Mesh Processing/Repair"); actionAutorefine->setProperty("subMenuName", "Polygon Mesh Processing/Repair/Experimental"); + actionNewAutorefine->setProperty("subMenuName", "Polygon Mesh Processing/Repair"); actionAutorefineAndRMSelfIntersections->setProperty("subMenuName", "Polygon Mesh Processing/Repair/Experimental"); actionSnapBorders->setProperty("subMenuName", "Polygon Mesh Processing/Repair/Experimental"); @@ -93,16 +99,29 @@ class Polyhedron_demo_repair_polyhedron_plugin : << actionExtractNMVertices << actionMergeDuplicatedVerticesOnBoundaryCycles << actionAutorefine + << actionNewAutorefine << actionAutorefineAndRMSelfIntersections << actionRemoveNeedlesAndCaps << actionSnapBorders; } - bool applicable(QAction*) const + bool applicable(QAction* action) const { - int item_id = scene->mainSelectionIndex(); - return qobject_cast(scene->item(item_id)); + if (action!=actionNewAutorefine) + { + int item_id = scene->mainSelectionIndex(); + return qobject_cast(scene->item(item_id)); + } + for (Scene_interface::Item_id index : scene->selectionIndices()) + { + if (qobject_cast(scene->item(index))) + return true; + if (qobject_cast(scene->item(index))) + return true; + } + return false; } + template void on_actionRemoveIsolatedVertices_triggered(Scene_interface::Item_id index); template @@ -120,6 +139,8 @@ class Polyhedron_demo_repair_polyhedron_plugin : template void on_actionAutorefine_triggered(Scene_interface::Item_id index); template + void on_actionNewAutorefine_triggered(const std::vector& indices); + template void on_actionAutorefineAndRMSelfIntersections_triggered(Scene_interface::Item_id index); public Q_SLOTS: @@ -131,6 +152,7 @@ public Q_SLOTS: void on_actionExtractNMVertices_triggered(); void on_actionMergeDuplicatedVerticesOnBoundaryCycles_triggered(); void on_actionAutorefine_triggered(); + void on_actionNewAutorefine_triggered(); void on_actionAutorefineAndRMSelfIntersections_triggered(); void on_actionRemoveNeedlesAndCaps_triggered(); void on_actionSnapBorders_triggered(); @@ -144,6 +166,7 @@ public Q_SLOTS: QAction* actionExtractNMVertices; QAction* actionMergeDuplicatedVerticesOnBoundaryCycles; QAction* actionAutorefine; + QAction* actionNewAutorefine; QAction* actionAutorefineAndRMSelfIntersections; QAction* actionRemoveNeedlesAndCaps; QAction* actionSnapBorders; @@ -421,6 +444,78 @@ void Polyhedron_demo_repair_polyhedron_plugin::on_actionAutorefine_triggered() QApplication::restoreOverrideCursor(); } +template +void Polyhedron_demo_repair_polyhedron_plugin::on_actionNewAutorefine_triggered(const std::vector& indices) +{ + namespace PMP = CGAL::Polygon_mesh_processing; + Polygon_soup::Points points; + Polygon_soup::Polygons polygons; + + if (indices.size()==1) + { + if (Scene_surface_mesh_item* smi_ptr = qobject_cast(scene->item(indices[0]))) + PMP::polygon_mesh_to_polygon_soup(*smi_ptr->polyhedron(), points, polygons); + else if (Scene_polygon_soup_item* spi_ptr = qobject_cast(scene->item(indices[0]))) + { + points = spi_ptr->points(); + polygons = spi_ptr->polygons(); + } + } + else + { + for (Scene_interface::Item_id id : indices) + { + Polygon_soup::Points l_points; + Polygon_soup::Polygons l_polygons; + + if (Scene_surface_mesh_item* smi_ptr = qobject_cast(scene->item(id))) + PMP::polygon_mesh_to_polygon_soup(*smi_ptr->polyhedron(), l_points, l_polygons); + else if (Scene_polygon_soup_item* spi_ptr = qobject_cast(scene->item(id))) + { + l_points = spi_ptr->points(); + l_polygons = spi_ptr->polygons(); + } + std::size_t offset=points.size(); + points.insert(points.end(), l_points.begin(), l_points.end()); + std::size_t psize=polygons.size(); + polygons.insert(polygons.end(), l_polygons.begin(), l_polygons.end()); + for (std::size_t i=psize; iload(points, polygons); + QString name = scene->item(indices[0])->name(); + for (std::size_t k=1; kitem(indices[k])->name(); + new_item->setName(name+" autorefined"); + + scene->addItem(new_item); + new_item->invalidateOpenGLBuffers(); + Q_EMIT new_item->itemChanged(); +} + +void Polyhedron_demo_repair_polyhedron_plugin::on_actionNewAutorefine_triggered() +{ + std::vector indices; + for (Scene_interface::Item_id index : scene->selectionIndices()) + { + if (qobject_cast(scene->item(index))) + indices.push_back(index); + else if (qobject_cast(scene->item(index))) + indices.push_back(index); + } + QApplication::setOverrideCursor(Qt::WaitCursor); + on_actionNewAutorefine_triggered(indices); + QApplication::restoreOverrideCursor(); +} + template void Polyhedron_demo_repair_polyhedron_plugin::on_actionAutorefineAndRMSelfIntersections_triggered(Scene_interface::Item_id index) { From 8076e20b71bc83407ec94d6e399d6e41f163c8de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 1 Aug 2023 13:07:55 +0200 Subject: [PATCH 091/329] Add debug code --- .../CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 14 ++++++++------ .../test_AW3_cavity_initializations.cpp | 1 + .../test/Alpha_wrap_3/test_AW3_manifoldness.cpp | 1 + .../test/Alpha_wrap_3/test_AW3_multiple_calls.cpp | 1 + .../test/Alpha_wrap_3/test_alpha_wrap_3_mesh.cpp | 2 +- 5 files changed, 12 insertions(+), 7 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index e88e00fafe0c..1e9674276fa8 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -1362,7 +1362,12 @@ class Alpha_wrap_3 for(Vertex_handle v : m_dt.finite_vertex_handles()) { if(is_non_manifold(v)) + { +#ifdef CGAL_AW3_DEBUG_MANIFOLDNESS_PP + std::cout << v->point() << " is non-manifold" << std::endl; +#endif non_manifold_vertices.push(v); + } } // Some lambdas for the comparer @@ -1412,23 +1417,19 @@ class Alpha_wrap_3 squared_distance(m_dt.point(c, 2), m_dt.point(c, 3)) }); }; -#ifdef CGAL_AW3_DEBUG_MANIFOLDNESS +#ifdef CGAL_AW3_DEBUG_MANIFOLDNESS_PP std::cout << non_manifold_vertices.size() << " initial NMV" << std::endl; #endif while(!non_manifold_vertices.empty()) { -#ifdef CGAL_AW3_DEBUG_MANIFOLDNESS +#ifdef CGAL_AW3_DEBUG_MANIFOLDNESS_PP std::cout << non_manifold_vertices.size() << " NMV in queue" << std::endl; #endif Vertex_handle v = non_manifold_vertices.top(); non_manifold_vertices.pop(); -#ifdef CGAL_AW3_DEBUG_MANIFOLDNESS - std::cout << "·"; -#endif - if(!is_non_manifold(v)) continue; @@ -1503,6 +1504,7 @@ class Alpha_wrap_3 void check_queue_sanity() { std::cout << "Check queue sanity..." << std::endl; + std::vector queue_gates; Gate previous_top_gate = m_queue.top(); while(!m_queue.empty()) diff --git a/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_cavity_initializations.cpp b/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_cavity_initializations.cpp index d7567bab205b..c6591e000df1 100644 --- a/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_cavity_initializations.cpp +++ b/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_cavity_initializations.cpp @@ -1,5 +1,6 @@ #define CGAL_AW3_TIMER #define CGAL_AW3_DEBUG +#define CGAL_AW3_DEBUG_MANIFOLDNESS // #define CGAL_AW3_DEBUG_INITIALIZATION #include diff --git a/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_manifoldness.cpp b/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_manifoldness.cpp index 928cade64959..8ac2e422d878 100644 --- a/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_manifoldness.cpp +++ b/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_manifoldness.cpp @@ -1,5 +1,6 @@ #define CGAL_AW3_TIMER #define CGAL_AW3_DEBUG +#define CGAL_AW3_DEBUG_MANIFOLDNESS //#define CGAL_AW3_DEBUG_STEINER_COMPUTATION //#define CGAL_AW3_DEBUG_INITIALIZATION //#define CGAL_AW3_DEBUG_QUEUE diff --git a/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_multiple_calls.cpp b/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_multiple_calls.cpp index e2abc6f1f12f..eda64a8376a4 100644 --- a/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_multiple_calls.cpp +++ b/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_multiple_calls.cpp @@ -1,5 +1,6 @@ #define CGAL_AW3_TIMER #define CGAL_AW3_DEBUG +#define CGAL_AW3_DEBUG_MANIFOLDNESS #include diff --git a/Alpha_wrap_3/test/Alpha_wrap_3/test_alpha_wrap_3_mesh.cpp b/Alpha_wrap_3/test/Alpha_wrap_3/test_alpha_wrap_3_mesh.cpp index 5091934b62f0..302494d8c304 100644 --- a/Alpha_wrap_3/test/Alpha_wrap_3/test_alpha_wrap_3_mesh.cpp +++ b/Alpha_wrap_3/test/Alpha_wrap_3/test_alpha_wrap_3_mesh.cpp @@ -1,6 +1,6 @@ #define CGAL_AW3_TIMER //#define CGAL_AW3_DEBUG -//#define CGAL_AW3_DEBUG_MANIFOLDNESS +#define CGAL_AW3_DEBUG_MANIFOLDNESS //#define CGAL_AW3_DEBUG_STEINER_COMPUTATION //#define CGAL_AW3_DEBUG_INITIALIZATION //#define CGAL_AW3_DEBUG_QUEUE From c7b9317a96117f874aa88b6ca9cd6b376f4d10cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 1 Aug 2023 13:16:18 +0200 Subject: [PATCH 092/329] Simplify choice of cells to un-carve while enforcing manifoldness This combinatorial choice seemed like a good idea, but it can have nasty cascading effects, adding very large tetrahedra. See this issue: https://github.com/CGAL/cgal/issues/7625 In the end, the only thing we care about is small volumes being added. I keep the artificial vertex for now, but I am not fully convinced these should be actually kept too. --- .../include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index 1e9674276fa8..1b0a6968c092 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -1445,11 +1445,6 @@ class Alpha_wrap_3 if(has_artificial_vertex(r)) return true; - const int l_bf_count = count_boundary_facets(l, v); - const int r_bf_count = count_boundary_facets(r, v); - if(l_bf_count != r_bf_count) - return l_bf_count > r_bf_count; - return sq_longest_edge(l) < sq_longest_edge(r); }; From b4e207ab00237bffbd221bc7f4bd4b0bb2e69c47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 2 Aug 2023 10:00:34 +0200 Subject: [PATCH 093/329] Add some comments on AW3 manifoldness heuristics criteria --- .../CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 43 +++++++++++-------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index 1b0a6968c092..a21925cdc6d8 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -1380,25 +1380,27 @@ class Alpha_wrap_3 return false; }; - auto is_on_boundary = [](Cell_handle c, int i) -> bool - { - return (c->info().is_outside != c->neighbor(i)->info().is_outside); - }; - - auto count_boundary_facets = [&](Cell_handle c, Vertex_handle v) -> int - { - const int v_index_in_c = c->index(v); - int boundary_facets = 0; - for(int i=0; i<3; ++i) // also take into account the opposite facet? - { - if(i == v_index_in_c) - continue; - - boundary_facets += is_on_boundary(c, i); - } - - return boundary_facets; - }; + // This seemed like a good idea, but in the end it can have strong cascading issues, + // whereas some cells with much lower volume would have solved the non-manifoldness. +// auto is_on_boundary = [](Cell_handle c, int i) -> bool +// { +// return (c->info().is_outside != c->neighbor(i)->info().is_outside); +// }; +// +// auto count_boundary_facets = [&](Cell_handle c, Vertex_handle v) -> int +// { +// const int v_index_in_c = c->index(v); +// int boundary_facets = 0; +// for(int i=0; i<3; ++i) // also take into account the opposite facet? +// { +// if(i == v_index_in_c) +// continue; +// +// boundary_facets += is_on_boundary(c, i); +// } +// +// return boundary_facets; +// }; // longest edge works better // auto sq_circumradius = [&](Cell_handle c) -> FT @@ -1407,6 +1409,9 @@ class Alpha_wrap_3 // return geom_traits().compute_squared_distance_3_object()(m_dt.point(c, 0), cc); // }; + // the reasonning behind using longest edge rather than volume is that we want to avoid + // spikes (which would have a small volume), and can often happen since we do not spend + // any care on the quality of tetrahedra. auto sq_longest_edge = [&](Cell_handle c) -> FT { return (std::max)({ squared_distance(m_dt.point(c, 0), m_dt.point(c, 1)), From 330ff2e65776a9be1f7ca757a813e5055e0a1994 Mon Sep 17 00:00:00 2001 From: Mael Date: Wed, 2 Aug 2023 10:23:12 +0200 Subject: [PATCH 094/329] Fix spelling Thanks @albert-github! --- Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index a21925cdc6d8..6d544be058d6 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -1409,7 +1409,7 @@ class Alpha_wrap_3 // return geom_traits().compute_squared_distance_3_object()(m_dt.point(c, 0), cc); // }; - // the reasonning behind using longest edge rather than volume is that we want to avoid + // the reasoning behind using longest edge rather than volume is that we want to avoid // spikes (which would have a small volume), and can often happen since we do not spend // any care on the quality of tetrahedra. auto sq_longest_edge = [&](Cell_handle c) -> FT From 49d6821d9bf3ad827ad664e739c90e0cd8c24909 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 28 Aug 2023 13:51:57 +0200 Subject: [PATCH 095/329] accomodate update to c++17 STL --- Kernel_23/include/CGAL/Kernel/function_objects.h | 16 ++++++++-------- .../Polygon_mesh_processing/autorefinement.h | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Kernel_23/include/CGAL/Kernel/function_objects.h b/Kernel_23/include/CGAL/Kernel/function_objects.h index 8974b762dcb4..8309a3c97ce7 100644 --- a/Kernel_23/include/CGAL/Kernel/function_objects.h +++ b/Kernel_23/include/CGAL/Kernel/function_objects.h @@ -2211,8 +2211,8 @@ namespace CommonKernelFunctors { Plane plane3 = construct_plane(p3, q3, r3); const auto res = typename K::Intersect_3()(plane1, plane2, plane3); - CGAL_assertion(res!=boost::none); - const Point* e_pt = boost::get(&(*res)); + CGAL_assertion(res!=std::nullopt); + const Point* e_pt = std::get_if(&(*res)); CGAL_assertion(e_pt!=nullptr); return *e_pt; } @@ -2221,8 +2221,8 @@ namespace CommonKernelFunctors { operator()(const Plane& plane1, const Plane& plane2, const Plane& plane3) const { const auto res = typename K::Intersect_3()(plane1, plane2, plane3); - CGAL_assertion(res!=boost::none); - const Point* e_pt = boost::get(&(*res)); + CGAL_assertion(res!=std::nullopt); + const Point* e_pt = std::get_if(&(*res)); CGAL_assertion(e_pt!=nullptr); return *e_pt; } @@ -2245,8 +2245,8 @@ namespace CommonKernelFunctors { Segment s2 = construct_segment(p2, q2); const auto res = typename K::Intersect_3()(s1, s2); - CGAL_assertion(res!=boost::none); - const Point* e_pt = boost::get(&(*res)); + CGAL_assertion(res!=std::nullopt); + const Point* e_pt = std::get_if(&(*res)); CGAL_assertion(e_pt!=nullptr); return *e_pt; } @@ -2255,8 +2255,8 @@ namespace CommonKernelFunctors { operator()(const Segment& s1, const Segment& s2) const { const auto res = typename K::Intersect_3()(s1, s2); - CGAL_assertion(res!=boost::none); - const Point* e_pt = boost::get(&(*res)); + CGAL_assertion(res!=std::nullopt); + const Point* e_pt = std::get_if(&(*res)); CGAL_assertion(e_pt!=nullptr); return *e_pt; } diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 0fb843c31c00..b3133304bb96 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -292,8 +292,8 @@ void old_intersection_coplanar_triangles_cutoff(const typename Kernel::Point_3& CGAL_kernel_assertion_code(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()); + const typename Kernel::Point_3* prev = &(*std::prev(inter_pts.end())); + Iterator stop = inter_pts.size() > 2 ? inter_pts.end() : std::prev(inter_pts.end()); for(Iterator it=inter_pts.begin(); it!=stop; ++it) { const typename Kernel::Point_3& curr = *it; From 4dc2ad3f36a9f2023e3e0ceaa5e44bf38b7332ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 4 Sep 2023 14:05:18 +0200 Subject: [PATCH 096/329] fix map type --- .../CGAL/Polygon_mesh_processing/autorefinement.h | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index b3133304bb96..32765252a6f2 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -1480,12 +1480,13 @@ void autorefine_triangle_soup(PointRange& soup_points, // TODO: reuse the fact that maps per triangle are already sorted #ifdef CGAL_LINKED_WITH_TBB - std::conditional_t, - std::map> point_id_map; + typedef std::conditional_t, + std::map> Point_id_map; #else - std::map point_id_map; + typedef std::map Point_id_map; #endif + Point_id_map point_id_map; #if ! defined(CGAL_NDEBUG) || defined(CGAL_DEBUG_PMP_AUTOREFINE) std::vector exact_soup_points; @@ -1605,7 +1606,7 @@ void autorefine_triangle_soup(PointRange& soup_points, #else //option 2 (without mutex) /// Lambda concurrent_get_point_id() - tbb::concurrent_vector::iterator> iterators; + tbb::concurrent_vector iterators; auto concurrent_get_point_id = [&](const typename EK::Point_3 pt) { auto insert_res = point_id_map.insert(std::make_pair(pt, -1)); @@ -1616,7 +1617,7 @@ void autorefine_triangle_soup(PointRange& soup_points, //use map iterator triple for triangles to create them concurrently and safely soup_triangles_out.resize(offset + new_triangles.size()); - std::vector::iterator, 3>> triangle_buffer(new_triangles.size()); + std::vector> triangle_buffer(new_triangles.size()); tbb::parallel_for(tbb::blocked_range(0, new_triangles.size()), [&](const tbb::blocked_range& r) { for (size_t ti = r.begin(); ti != r.end(); ++ti) { From 9d68f5350e491bb1b23a42f14027285477a18780 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 4 Sep 2023 14:58:47 +0200 Subject: [PATCH 097/329] doc + changes --- Installation/CHANGES.md | 6 ++++++ .../include/CGAL/Polygon_mesh_processing/autorefinement.h | 5 +++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Installation/CHANGES.md b/Installation/CHANGES.md index 479984002682..b361d15dec76 100644 --- a/Installation/CHANGES.md +++ b/Installation/CHANGES.md @@ -35,6 +35,12 @@ Release date: October 2023 - Removed the class templates `Gray_image_mesh_domain_3`, `Implicit_mesh_domain_3`, and `Labeled_image_mesh_domain_3` which are deprecated since CGAL-4.13. +### [Polygon Mesh Processing](https://doc.cgal.org/6.0/Manual/packages.html#PkgPolygonMeshProcessing) + +- Added the function + `CGAL::Polygon_mesh_processing::autorefine_triangle_soup()` that refines a soup of triangles so that no pair of triangles intersects + (they can share an edge or a vertex). Also added, the function `autorefine()` operating directly on a triangle mesh and updating it + using the aforementioned function on triangle soup. [Release 5.6](https://github.com/CGAL/cgal/releases/tag/v5.6) ----------- diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 32765252a6f2..884ce3477aa8 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -1128,8 +1128,9 @@ void generate_subtriangles(std::size_t ti, /** * \ingroup PMP_corefinement_grp * -* refines a soup of triangles so that no pair of triangles intersects in their interior. -* Note that points in `soup_points` can only be added (intersection points) a the end of the container, with the initial order preserved. +* refines a soup of triangles so that no pair of triangles intersects. +* Output triangles may share a common edge or a common vertex (but with the same indexed position in `points`). +* Note that points in `soup_points` can only be added (intersection points) at the end of the container, with the initial order preserved. * Note that if `soup_points` contains two or more identical points and only the first copy (following the order in the `soup_points`) * will be used in `soup_triangles`. * `soup_triangles` will be updated to contain both the input triangles and the new subdivides triangles. Degenerate triangles will be removed. From 88bcd4096625b172d1091e33cfb37118513e50a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 20 Sep 2023 12:48:42 +0200 Subject: [PATCH 098/329] Enable changing the oracle in the AW3 builder --- .../CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index f12ad06804b1..86010b27dfcf 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -173,7 +173,7 @@ class Alpha_wrap_3 using Alpha_PQ = Modifiable_priority_queue, CGAL_BOOST_PAIRING_HEAP>; protected: - const Oracle m_oracle; + Oracle m_oracle; SC_Iso_cuboid_3 m_bbox; FT m_alpha, m_sq_alpha; @@ -183,10 +183,12 @@ class Alpha_wrap_3 Alpha_PQ m_queue; public: - // Main constructor + Alpha_wrap_3() + : m_queue(4096) + { } + Alpha_wrap_3(const Oracle& oracle) - : - m_oracle(oracle), + : m_oracle(oracle), m_dt(Geom_traits(oracle.geom_traits())), // used to set up the initial MPQ, use some arbitrary not-too-small value m_queue(4096) @@ -198,6 +200,8 @@ class Alpha_wrap_3 public: const Geom_traits& geom_traits() const { return m_dt.geom_traits(); } + Oracle& oracle() { return m_oracle; } + const Oracle& oracle() const { return m_oracle; } Dt& triangulation() { return m_dt; } const Dt& triangulation() const { return m_dt; } const Alpha_PQ& queue() const { return m_queue; } From 4512b0e6f44ec1ac42ae0854bba2abb12588b7b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 20 Sep 2023 12:52:20 +0200 Subject: [PATCH 099/329] Rewrite the extraction of possibly non-manifold wraps --- .../CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 295 ++++++++++++------ 1 file changed, 193 insertions(+), 102 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index 86010b27dfcf..6e8e323e85a9 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -648,165 +648,256 @@ class Alpha_wrap_3 return true; } -public: - // Manifoldness is tolerated while debugging and extracting at intermediate states - // Not the preferred way because it uses 3*nv storage - template - void extract_possibly_non_manifold_surface(OutputMesh& output_mesh, - OVPM ovpm) const +private: + void extract_boundary(std::vector& points, + std::vector >& faces) const { - namespace PMP = Polygon_mesh_processing; - -#ifdef CGAL_AW3_DEBUG - std::cout << "> Extract possibly non-manifold wrap... ()" << std::endl; -#endif - - clear(output_mesh); - - CGAL_assertion_code(for(auto cit=m_dt.finite_cells_begin(), cend=m_dt.finite_cells_end(); cit!=cend; ++cit)) - CGAL_assertion(cit->tds_data().is_clear()); + std::unordered_map vertex_to_id; - for(auto cit=m_dt.finite_cells_begin(), cend=m_dt.finite_cells_end(); cit!=cend; ++cit) + for(auto fit=m_dt.all_facets_begin(), fend=m_dt.all_facets_end(); fit!=fend; ++fit) { - Cell_handle seed = cit; - if(seed->info().is_outside || seed->tds_data().processed()) + Facet f = *fit; + if(!f.first->info().is_outside) + f = m_dt.mirror_facet(f); + + const Cell_handle ch = f.first; + const int s = f.second; + const Cell_handle nh = ch->neighbor(s); + if(ch->info().is_outside == nh->info().is_outside) continue; - std::queue to_visit; - to_visit.push(seed); + std::array ids; + for(int pos=0; pos<3; ++pos) + { + Vertex_handle vh = ch->vertex(Dt::vertex_triple_index(s, pos)); + auto insertion_res = vertex_to_id.emplace(vh, vertex_to_id.size()); + if(insertion_res.second) // successful insertion, never-seen-before vertex + points.push_back(m_dt.point(vh)); - std::vector points; - std::vector > faces; - std::size_t idx = 0; + ids[pos] = insertion_res.first->second; + } - while(!to_visit.empty()) - { - const Cell_handle cell = to_visit.front(); - CGAL_assertion(!cell->info().is_outside && !m_dt.is_infinite(cell)); + faces.emplace_back(std::array{ids[0], ids[1], ids[2]}); + } + } - to_visit.pop(); + template + void extract_manifold_surface(OutputMesh& output_mesh, + OVPM ovpm) const + { + namespace PMP = Polygon_mesh_processing; - if(cell->tds_data().processed()) - continue; +#ifdef CGAL_AW3_DEBUG + std::cout << "> Extract manifold wrap... ()" << std::endl; +#endif - cell->tds_data().mark_processed(); + CGAL_assertion_code(for(Vertex_handle v : m_dt.finite_vertex_handles())) + CGAL_assertion(!is_non_manifold(v)); - for(int fid=0; fid<4; ++fid) - { - const Cell_handle neighbor = cell->neighbor(fid); - if(neighbor->info().is_outside) - { - // There shouldn't be any artificial vertex on the inside/outside boundary - // (past initialization) -// CGAL_assertion(cell->vertex((fid + 1)&3)->info() == DEFAULT); -// CGAL_assertion(cell->vertex((fid + 2)&3)->info() == DEFAULT); -// CGAL_assertion(cell->vertex((fid + 3)&3)->info() == DEFAULT); - - points.push_back(m_dt.point(cell, Dt::vertex_triple_index(fid, 0))); - points.push_back(m_dt.point(cell, Dt::vertex_triple_index(fid, 1))); - points.push_back(m_dt.point(cell, Dt::vertex_triple_index(fid, 2))); - faces.push_back({idx, idx + 1, idx + 2}); - idx += 3; - } - else - { - to_visit.push(neighbor); - } - } - } + clear(output_mesh); - PMP::duplicate_non_manifold_edges_in_polygon_soup(points, faces); + std::vector points; + std::vector > faces; + extract_boundary(points, faces); - CGAL_assertion(PMP::is_polygon_soup_a_polygon_mesh(faces)); - PMP::polygon_soup_to_polygon_mesh(points, faces, output_mesh, - CGAL::parameters::default_values(), - CGAL::parameters::vertex_point_map(ovpm)); + if(faces.empty()) + { +#ifdef CGAL_AW3_DEBUG + std::cout << "Empty wrap?..." << std::endl; +#endif + return; + } - PMP::stitch_borders(output_mesh, CGAL::parameters::vertex_point_map(ovpm)); - CGAL_assertion(is_closed(output_mesh)); + if(!PMP::is_polygon_soup_a_polygon_mesh(faces)) + { + CGAL_warning_msg(false, "Failed to extract a manifold boundary!"); + return; } - for(auto cit=m_dt.finite_cells_begin(), cend=m_dt.finite_cells_end(); cit!=cend; ++cit) - cit->tds_data().clear(); + PMP::polygon_soup_to_polygon_mesh(points, faces, output_mesh, + CGAL::parameters::default_values(), + CGAL::parameters::vertex_point_map(ovpm)); CGAL_postcondition(!is_empty(output_mesh)); CGAL_postcondition(is_valid_polygon_mesh(output_mesh)); CGAL_postcondition(is_closed(output_mesh)); - - PMP::orient_to_bound_a_volume(output_mesh, CGAL::parameters::vertex_point_map(ovpm)); + CGAL_postcondition(PMP::does_bound_a_volume(output_mesh, CGAL::parameters::vertex_point_map(ovpm))); } template - void extract_manifold_surface(OutputMesh& output_mesh, - OVPM ovpm) const + void extract_possibly_non_manifold_surface(OutputMesh& output_mesh, + OVPM ovpm) const { namespace PMP = Polygon_mesh_processing; + using vertex_descriptor = typename boost::graph_traits::vertex_descriptor; + using halfedge_descriptor = typename boost::graph_traits::halfedge_descriptor; + using face_descriptor = typename boost::graph_traits::face_descriptor; + #ifdef CGAL_AW3_DEBUG - std::cout << "> Extract wrap... ()" << std::endl; + std::cout << "> Extract possibly non-manifold wrap... ()" << std::endl; #endif - CGAL_assertion_code(for(Vertex_handle v : m_dt.finite_vertex_handles())) - CGAL_assertion(!is_non_manifold(v)); - clear(output_mesh); - // boundary faces to polygon soup std::vector points; - std::vector > faces; + std::vector > polygons; - std::unordered_map vertex_to_id; - std::size_t nv = 0; + // Explode the polygon soup into indepent triangles, and stitch back edge by edge by walking along the exterior + std::map facet_ids; + std::size_t idx = 0; - for(auto fit=m_dt.finite_facets_begin(), fend=m_dt.finite_facets_end(); fit!=fend; ++fit) + for(auto fit=m_dt.all_facets_begin(), fend=m_dt.all_facets_end(); fit!=fend; ++fit) { Facet f = *fit; if(!f.first->info().is_outside) f = m_dt.mirror_facet(f); - const Cell_handle c = f.first; + const Cell_handle ch = f.first; const int s = f.second; - const Cell_handle nh = c->neighbor(s); - if(c->info().is_outside == nh->info().is_outside) + const Cell_handle nh = ch->neighbor(s); + if(ch->info().is_outside == nh->info().is_outside) continue; - std::array ids; - for(int pos=0; pos<3; ++pos) - { - Vertex_handle vh = c->vertex(Dt::vertex_triple_index(s, pos)); - auto insertion_res = vertex_to_id.emplace(vh, nv); - if(insertion_res.second) // successful insertion, never-seen-before vertex - { - points.push_back(m_dt.point(vh)); - ++nv; - } + facet_ids[f] = idx / 3; - ids[pos] = insertion_res.first->second; - } + points.push_back(m_dt.point(ch, Dt::vertex_triple_index(s, 0))); + points.push_back(m_dt.point(ch, Dt::vertex_triple_index(s, 1))); + points.push_back(m_dt.point(ch, Dt::vertex_triple_index(s, 2))); + polygons.push_back({idx, idx + 1, idx + 2}); - faces.emplace_back(std::array{ids[0], ids[1], ids[2]}); + idx += 3; } - if(faces.empty()) - return; - - if(!PMP::is_polygon_soup_a_polygon_mesh(faces)) + if(polygons.empty()) { - CGAL_warning_msg(false, "Could NOT extract mesh..."); +#ifdef CGAL_AW3_DEBUG + std::cout << "Empty wrap?..." << std::endl; +#endif return; } - PMP::polygon_soup_to_polygon_mesh(points, faces, output_mesh, - CGAL::parameters::default_values(), + CGAL_assertion(PMP::is_polygon_soup_a_polygon_mesh(polygons)); + + std::unordered_map i2f; + PMP::polygon_soup_to_polygon_mesh(points, polygons, output_mesh, + CGAL::parameters::polygon_to_face_output_iterator(std::inserter(i2f, i2f.end())), CGAL::parameters::vertex_point_map(ovpm)); + auto face_to_facet = get(CGAL::dynamic_face_property_t(), output_mesh); + + idx = 0; + for(auto fit=m_dt.all_facets_begin(), fend=m_dt.all_facets_end(); fit!=fend; ++fit) + { + Facet f = *fit; + if(!f.first->info().is_outside) + f = m_dt.mirror_facet(f); + + const Cell_handle ch = f.first; + const int s = f.second; + const Cell_handle nh = ch->neighbor(s); + if(ch->info().is_outside == nh->info().is_outside) + continue; + + put(face_to_facet, i2f[idx++], f); + } + + // grab the stitchable halfedges + std::vector > to_stitch; + + for(face_descriptor f : faces(output_mesh)) + { + const Facet& tr_f = get(face_to_facet, f); + const Cell_handle ch = tr_f.first; + CGAL_assertion(ch->info().is_outside); + + for(halfedge_descriptor h : halfedges_around_face(halfedge(f, output_mesh), output_mesh)) + { + const vertex_descriptor sv = source(h, output_mesh); + const vertex_descriptor tv = target(h, output_mesh); + + // only need the pair of halfedges once + if(get(ovpm, sv) > get(ovpm, tv)) + continue; + + // One could avoid these point comparisons by using the fact that we know that the graph + // has faces built in a specific order (through BGL::add_face()), but it's better to make + // this code more generic (and it is not very costly). + auto graph_descriptor_to_triangulation_handle = [&](const vertex_descriptor v) + { + const Point_3& p = get(ovpm, v); + for(int i=0; i<4; ++i) + if(ch->vertex(i)->point() == p) + return ch->vertex(i); + + CGAL_assertion(false); + return Vertex_handle(); + }; + + const Vertex_handle s_vh = graph_descriptor_to_triangulation_handle(sv); + const Vertex_handle t_vh = graph_descriptor_to_triangulation_handle(tv); + CGAL_assertion(get(ovpm, sv) == m_dt.point(s_vh)); + CGAL_assertion(get(ovpm, tv) == m_dt.point(t_vh)); + + const int facet_third_id = 6 - (ch->index(s_vh) + ch->index(t_vh) + tr_f.second); // 0 + 1 + 2 + 3 = 6 + Vertex_handle third_vh = ch->vertex(facet_third_id); + + // walk around the edge (in the exterior of the wrap) till meeting an inside cell + Cell_handle start_ch = ch, curr_ch = ch; + do + { + const int i = curr_ch->index(s_vh); + const int j = curr_ch->index(t_vh); + + // the facet is incident to the outside cell, and we walk in the exterior + const int facet_third_id = 6 - (curr_ch->index(s_vh) + curr_ch->index(t_vh) + curr_ch->index(third_vh)); + third_vh = curr_ch->vertex(facet_third_id); + curr_ch = curr_ch->neighbor(Dt::next_around_edge(i,j)); + + if(!curr_ch->info().is_outside) + break; + } + while(curr_ch != start_ch); + + CGAL_assertion(curr_ch != start_ch); + CGAL_assertion(!curr_ch->info().is_outside); + + const int opp_id = 6 - (curr_ch->index(s_vh) + curr_ch->index(t_vh) + curr_ch->index(third_vh)); + const Facet tr_f2 = m_dt.mirror_facet(Facet(curr_ch, opp_id)); + CGAL_assertion(facet_ids.count(Facet(curr_ch, opp_id)) == 0); + CGAL_assertion(tr_f2.first->info().is_outside); + CGAL_assertion(tr_f2.first->neighbor(tr_f2.second) == curr_ch); + CGAL_assertion(tr_f2.first->has_vertex(s_vh) && tr_f2.first->has_vertex(t_vh)); + + const face_descriptor f2 = i2f[facet_ids.at(tr_f2)]; + halfedge_descriptor h2 = halfedge(f2, output_mesh), done = h2; + while(get(ovpm, target(h2, output_mesh)) != get(ovpm, source(h, output_mesh))) + { + h2 = next(h2, output_mesh); + CGAL_assertion(h2 != done); + if(h2 == done) + break; + } + + CGAL_assertion(get(ovpm, source(h, output_mesh)) == get(ovpm, target(h2, output_mesh))); + CGAL_assertion(get(ovpm, target(h, output_mesh)) == get(ovpm, source(h2, output_mesh))); + CGAL_assertion(get(ovpm, target(next(h2, output_mesh), output_mesh)) == m_dt.point(third_vh)); + + to_stitch.emplace_back(opposite(h, output_mesh), opposite(h2, output_mesh)); + } + } + + PMP::internal::stitch_halfedge_range(to_stitch, output_mesh, ovpm); + + collect_garbage(output_mesh); + CGAL_postcondition(!is_empty(output_mesh)); CGAL_postcondition(is_valid_polygon_mesh(output_mesh)); CGAL_postcondition(is_closed(output_mesh)); - - PMP::orient_to_bound_a_volume(output_mesh, CGAL::parameters::vertex_point_map(ovpm)); + CGAL_postcondition(PMP::does_bound_a_volume(output_mesh, CGAL::parameters::vertex_point_map(ovpm))); } +public: template void extract_surface(OutputMesh& output_mesh, OVPM ovpm, From 4d50ec46b361ca0c912f3725d91fe673ff6ed869 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 20 Sep 2023 12:53:12 +0200 Subject: [PATCH 100/329] Consider all cases in facet_status In a normal run of the algorithm, we shall never ask the facet status of a facet that is already outside, but it's better to be complete and it costs nothing. --- .../include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index 6e8e323e85a9..7c48a51ba6c5 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -1027,6 +1027,15 @@ class Alpha_wrap_3 // skip if neighbor is OUTSIDE or infinite const Cell_handle ch = f.first; const int id = f.second; + + if(!ch->info().is_outside) + { +#ifdef CGAL_AW3_DEBUG_FACET_STATUS + std::cout << "Facet is inside" << std::endl; +#endif + return IRRELEVANT; + } + const Cell_handle nh = ch->neighbor(id); if(m_dt.is_infinite(nh)) return TRAVERSABLE; From bff07b2fc9ef0c26209475deae428ed77c29fecf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 20 Sep 2023 12:55:11 +0200 Subject: [PATCH 101/329] Simplify the gate comparer: we can also sort artificial facets like normal facets Artificial facets are *not* infinite facets. --- .../include/CGAL/Alpha_wrap_3/internal/gate_priority_queue.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/gate_priority_queue.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/gate_priority_queue.h index 8d63e34c9e3b..824d27bc2c10 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/gate_priority_queue.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/gate_priority_queue.h @@ -68,11 +68,6 @@ struct Less_gate template bool operator()(const Gate& a, const Gate& b) const { - // @fixme? make it a total order by comparing addresses if both gates are bbox facets - if(a.is_artificial_facet()) - return true; - else if(b.is_artificial_facet()) - return false; return a.priority() > b.priority(); } }; From 5304f739b9f4e26c49630a1fe2970e5c5711b20e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 20 Sep 2023 12:57:02 +0200 Subject: [PATCH 102/329] Enable restarting from a previous wrap --- .../CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 82 ++++++++++++++++--- .../internal/parameters_interface.h | 1 + 2 files changed, 73 insertions(+), 10 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index 7c48a51ba6c5..9a0ee2ddb619 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -176,8 +176,8 @@ class Alpha_wrap_3 Oracle m_oracle; SC_Iso_cuboid_3 m_bbox; - FT m_alpha, m_sq_alpha; - FT m_offset, m_sq_offset; + FT m_alpha = FT(-1), m_sq_alpha = FT(-1); + FT m_offset = FT(-1), m_sq_offset = FT(-1); Dt m_dt; Alpha_PQ m_queue; @@ -268,6 +268,20 @@ class Alpha_wrap_3 const bool do_enforce_manifoldness = choose_parameter(get_parameter(in_np, internal_np::do_enforce_manifoldness), true); + // This parameter enables avoiding recomputing the triangulation from scratch when wrapping + // the same meshes for multiple values of alpha (and typically the same offset values). + // + // /!\ Warning /!\ + // + // If this is enabled, the 3D triangulation will NEVER be cleared and re-initialized + // at launch. This means that the triangulation is NOT cleared, even when: + // - the triangulation is empty; you will get nothing. + // - you use an alpha value that is greater than what was used in a previous run; you will + // obtain a denser result than what you might expect. + // - you use a different offset value between runs, you might then get points that are not + // on the offset surface corresponding to your latter offset value. + const bool resuming = choose_parameter(get_parameter(in_np, internal_np::refine_triangulation), false); + #ifdef CGAL_AW3_TIMER CGAL::Real_timer t; t.start(); @@ -275,7 +289,7 @@ class Alpha_wrap_3 visitor.on_alpha_wrapping_begin(*this); - if(!initialize(alpha, offset, seeds)) + if(!initialize(alpha, offset, seeds, resuming)) return; #ifdef CGAL_AW3_DEBUG_DUMP_EVERY_STEP @@ -648,6 +662,35 @@ class Alpha_wrap_3 return true; } + // This function is used in the case of resumption of a previous run: m_dt is not cleared, + // and we fill the queue with the new parameters. + bool initialize_from_existing_triangulation() + { + std::cout << "restart from a DT of " << m_dt.number_of_cells() << " cells" << std::endl; + + Real_timer t; + t.start(); + + for(Cell_handle ch : m_dt.all_cell_handles()) + { + if(!ch->info().is_outside) + continue; + + for(int i=0; i<4; ++i) + { + if(ch->neighbor(i)->info().is_outside) + continue; + + push_facet(std::make_pair(ch, i)); + } + } + + t.stop(); + std::cout << t.time() << " for scanning" << std::endl; + + return true; + } + private: void extract_boundary(std::vector& points, std::vector >& faces) const @@ -1105,7 +1148,8 @@ class Alpha_wrap_3 template bool initialize(const double alpha, const double offset, - const SeedRange& seeds) + const SeedRange& seeds, + const bool resuming = false) { #ifdef CGAL_AW3_DEBUG std::cout << "> Initialize..." << std::endl; @@ -1121,20 +1165,38 @@ class Alpha_wrap_3 return false; } + if(resuming) + { + if(offset != m_offset) + { +#ifdef CGAL_AW3_DEBUG + std::cerr << "Warning: resuming with a different offset!" << std::endl; +#endif + } + } + m_alpha = FT(alpha); m_sq_alpha = square(m_alpha); m_offset = FT(offset); m_sq_offset = square(m_offset); - m_dt.clear(); m_queue.clear(); - insert_bbox_corners(); - - if(seeds.empty()) - return initialize_from_infinity(); + if(resuming) + { + return initialize_from_existing_triangulation(); + } else - return initialize_with_cavities(seeds); + { + m_dt.clear(); + + insert_bbox_corners(); + + if(seeds.empty()) + return initialize_from_infinity(); + else + return initialize_with_cavities(seeds); + } } template diff --git a/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h b/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h index 7792ad5cdb60..435075df6e2a 100644 --- a/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h +++ b/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h @@ -237,6 +237,7 @@ CGAL_add_named_parameter(smooth_constrained_edges_t, smooth_constrained_edges, s // List of named parameters used in Alpha_wrap_3 CGAL_add_named_parameter(do_enforce_manifoldness_t, do_enforce_manifoldness, do_enforce_manifoldness) CGAL_add_named_parameter(seed_points_t, seed_points, seed_points) +CGAL_add_named_parameter(refine_triangulation_t, refine_triangulation, refine_triangulation) // SMDS_3 parameters CGAL_add_named_parameter(surface_facets_t, surface_facets, surface_facets) From 36017331c2e12a62a055943732b1cfed4d128eb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 20 Sep 2023 12:58:30 +0200 Subject: [PATCH 103/329] Add an example of successive AW3 restarts --- .../examples/Alpha_wrap_3/CMakeLists.txt | 1 + .../Alpha_wrap_3/successive_wraps.cpp | 151 ++++++++++++++++++ 2 files changed, 152 insertions(+) create mode 100644 Alpha_wrap_3/examples/Alpha_wrap_3/successive_wraps.cpp diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/CMakeLists.txt b/Alpha_wrap_3/examples/Alpha_wrap_3/CMakeLists.txt index 2014b9baa7ca..11dec5f4134d 100644 --- a/Alpha_wrap_3/examples/Alpha_wrap_3/CMakeLists.txt +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/CMakeLists.txt @@ -12,3 +12,4 @@ create_single_source_cgal_program("triangle_soup_wrap.cpp") create_single_source_cgal_program("point_set_wrap.cpp") create_single_source_cgal_program("wrap_from_cavity.cpp") create_single_source_cgal_program("mixed_inputs_wrap.cpp") +create_single_source_cgal_program("successive_wraps.cpp") diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/successive_wraps.cpp b/Alpha_wrap_3/examples/Alpha_wrap_3/successive_wraps.cpp new file mode 100644 index 000000000000..600d533ee411 --- /dev/null +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/successive_wraps.cpp @@ -0,0 +1,151 @@ +#define CGAL_AW3_TIMER + +#include +#include + +#include +#include +#include +#include + +#include +#include + +namespace PMP = CGAL::Polygon_mesh_processing; + +using K = CGAL::Exact_predicates_inexact_constructions_kernel; +using FT = K::FT; +using Point_3 = K::Point_3; + +using Mesh = CGAL::Surface_mesh; + +// We want decreasing alphas, and these are relative ratios, so they need to be increasing +const std::vector relative_alphas = { 1, 2/*50, 100, 150, 200, 250*/ }; +const FT relative_offset = 600; + +int main(int argc, char** argv) +{ + std::cout.precision(17); + std::cerr.precision(17); + + // Read the input + const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/cube.off"); + std::cout << "Reading " << filename << "..." << std::endl; + + Mesh mesh; + if(!PMP::IO::read_polygon_mesh(filename, mesh) || is_empty(mesh) || !is_triangle_mesh(mesh)) + { + std::cerr << "Invalid input." << std::endl; + return EXIT_FAILURE; + } + + std::cout << "Input: " << num_vertices(mesh) << " vertices, " << num_faces(mesh) << " faces" << std::endl; + + const CGAL::Bbox_3 bbox = CGAL::Polygon_mesh_processing::bbox(mesh); + const double diag_length = std::sqrt(CGAL::square(bbox.xmax() - bbox.xmin()) + + CGAL::square(bbox.ymax() - bbox.ymin()) + + CGAL::square(bbox.zmax() - bbox.zmin())); + + // =============================================================================================== + // Naive approach: + + CGAL::Real_timer t; + double total_time = 0.; + + for(std::size_t i=0; i>> [" << i << "] alpha: " << alpha << " offset: " << offset << std::endl; + + Mesh wrap; + CGAL::alpha_wrap_3(mesh, alpha, offset, wrap, + CGAL::parameters::do_enforce_manifoldness(false)); + + t.stop(); + std::cout << " Result: " << num_vertices(wrap) << " vertices, " << num_faces(wrap) << " faces" << std::endl; + std::cout << " Elapsed time: " << t.time() << " s." << std::endl; + + std::string input_name = std::string(filename); + input_name = input_name.substr(input_name.find_last_of("/") + 1, input_name.length() - 1); + input_name = input_name.substr(0, input_name.find_last_of(".")); + std::string output_name = input_name + + "_" + std::to_string(static_cast(relative_alphas[i])) + + "_" + std::to_string(static_cast(relative_offset)) + ".off"; + std::cout << "Writing to " << output_name << std::endl; + CGAL::IO::write_polygon_mesh(output_name, wrap, CGAL::parameters::stream_precision(17)); + + total_time += t.time(); + } + + std::cout << "Total elapsed time (naive): " << total_time << " s.\n" << std::endl; + + // =============================================================================================== + // Re-use approach + // + // Here, we restart from the triangulation of the previous state, and carve according + // to a (smaller) alpha value. This enables considerable speed-up: the cumulated time taken + // to run `n` successive instances of `{alpha_wrap(alpha_i)}_(i=1...n)` will be equal to the + // time taken to run alpha_wrap(alpha_n) from scratch. + // + // For example: + // naive: + // alpha_wrap(alpha_1, ...) ---> 2s + // alpha_wrap(alpha_2, ...) ---> 4s + // alpha_wrap(alpha_3, ...) ---> 8s + // will become with reusability: + // alpha_wrap(alpha_1, ..., reuse) ---> 2s + // alpha_wrap(alpha_2, ..., reuse) ---> 2s // 2+2 = 4s = naive alpha_2 + // alpha_wrap(alpha_3, ..., reuse) ---> 4s // 2+2+4 = 8s = naive alpha_3 + // Thus, if we care about the intermediate results, we save 6s (8s instead of 14s). + // The speed-up increases with the number of intermediate results, and if the alpha values + // are close. + // + // !! Warning !! + // The result of alpha_wrap(alpha_1, ...) followed by alpha_wrap(alpha_2, ...) with alpha_2 + // smaller than alpha_1 is going to be close but NOT exactly equal to that produced by calling + // alpha_wrap(alpha_2, ...) directly. + + total_time = 0.; + t.reset(); + + using Oracle = CGAL::Alpha_wraps_3::internal::Triangle_mesh_oracle; + using Wrapper = CGAL::Alpha_wraps_3::internal::Alpha_wrap_3; + Wrapper wrapper; // contains the triangulation that is being refined iteratively + + for(std::size_t i=0; i>> [" << i << "] alpha: " << alpha << " offset: " << offset << std::endl; + + // The triangle mesh oracle can be initialized with alpha to internally perform a split + // of too-big facets while building the AABB Tree. This split in fact yields a significant + // speed-up for meshes with elements that are large compared to alpha. This speed-up makes it + // faster to re-build the AABB tree for every value of alpha than to use a non-optimized tree. + Oracle oracle(alpha); + oracle.add_triangle_mesh(mesh, CGAL::parameters::default_values()); + wrapper.oracle() = oracle; + + Mesh wrap; + wrapper(alpha, offset, wrap, + CGAL::parameters::do_enforce_manifoldness(false) + .refine_triangulation((i != 0))); + + t.stop(); + std::cout << " Result: " << num_vertices(wrap) << " vertices, " << num_faces(wrap) << " faces" << std::endl; + std::cout << " Elapsed time: " << t.time() << " s." << std::endl; + + total_time += t.time(); + } + + std::cout << "Total elapsed time (successive): " << total_time << " s." << std::endl; + + return EXIT_SUCCESS; +} From 19cb693a1b9ff119593057c76402493b03e474e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 20 Sep 2023 12:59:46 +0200 Subject: [PATCH 104/329] Improve debug code --- .../CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 84 +++++++++++++------ 1 file changed, 60 insertions(+), 24 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index 9a0ee2ddb619..0579297c4335 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -1053,6 +1053,24 @@ class Alpha_wrap_3 TRAVERSABLE }; + inline const char* get_status_message(const Facet_queue_status status) + { + constexpr std::size_t status_count = 3; + + // Messages corresponding to Error_code list above. Must be kept in sync! + static const char* message[status_count] = { + "Irrelevant facet", + "Artificial facet", + "Traversable facet" + }; + + if(status > status_count || status < 0) + return "Unknown status"; + else + return message[status]; + } + +public: // @speed some decent time may be spent constructing Facet (pairs) for no reason as it's always // just to grab the .first and .second as soon as it's constructed, and not due to API requirements // e.g. from DT3 @@ -1062,9 +1080,9 @@ class Alpha_wrap_3 #ifdef CGAL_AW3_DEBUG_FACET_STATUS std::cout << "facet status: " - << f.first->vertex((f.second + 1)&3)->point() << " " - << f.first->vertex((f.second + 2)&3)->point() << " " - << f.first->vertex((f.second + 3)&3)->point() << std::endl; + << m_dt.point(f.first, Dt::vertex_triple_index(f.second, 0)) << " " + << m_dt.point(f.first, Dt::vertex_triple_index(f.second, 1)) << " " + << m_dt.point(f.first, Dt::vertex_triple_index(f.second, 2)) << std::endl; #endif // skip if neighbor is OUTSIDE or infinite @@ -1119,6 +1137,7 @@ class Alpha_wrap_3 return IRRELEVANT; } +private: bool push_facet(const Facet& f) { CGAL_precondition(f.first->info().is_outside); @@ -1127,19 +1146,29 @@ class Alpha_wrap_3 if(m_queue.contains_with_bounds_check(Gate(f))) return false; - const Facet_queue_status s = facet_status(f); - if(s == IRRELEVANT) + const Facet_queue_status status = facet_status(f); + if(status == IRRELEVANT) return false; const Cell_handle ch = f.first; - const int id = f.second; - const Point_3& p0 = m_dt.point(ch, (id+1)&3); - const Point_3& p1 = m_dt.point(ch, (id+2)&3); - const Point_3& p2 = m_dt.point(ch, (id+3)&3); + const int s = f.second; + const Point_3& p0 = m_dt.point(ch, Dt::vertex_triple_index(s, 0)); + const Point_3& p1 = m_dt.point(ch, Dt::vertex_triple_index(s, 1)); + const Point_3& p2 = m_dt.point(ch, Dt::vertex_triple_index(s, 2)); - // @todo should prob be the real value we compare to alpha instead of squared_radius + // @todo should prob be the real value that we compare to alpha instead of squared_radius const FT sqr = geom_traits().compute_squared_radius_3_object()(p0, p1, p2); - m_queue.resize_and_push(Gate(f, sqr, (s == ARTIFICIAL_FACET))); + m_queue.resize_and_push(Gate(f, sqr, (status == ARTIFICIAL_FACET))); + +#ifdef CGAL_AW3_DEBUG_QUEUE + static int gid = 0; + std::cout << "Queue insertion #" << gid++ << "\n" + << " ch = " << &*ch << " (" << m_dt.is_infinite(ch) << ") " << "\n" + << "\t" << p0 << "\n\t" << p1 << "\n\t" << p2 << std::endl; + std::cout << " Status: " << get_status_message(status) << std::endl; + std::cout << " SQR: " << sqr << std::endl; + std::cout << " Artificiality: " << (status == ARTIFICIAL_FACET) << std::endl; +#endif return true; } @@ -1160,7 +1189,7 @@ class Alpha_wrap_3 if(!is_positive(alpha) || !is_positive(offset)) { #ifdef CGAL_AW3_DEBUG - std::cout << "Error: invalid input parameters" << std::endl; + std::cerr << "Error: invalid input parameters: " << alpha << " and" << offset << std::endl; #endif return false; } @@ -1230,7 +1259,9 @@ class Alpha_wrap_3 std::cout << m_queue.size() << " facets in the queue" << std::endl; std::cout << "Face " << fid++ << "\n" << "c = " << &*ch << " (" << m_dt.is_infinite(ch) << "), n = " << &*neighbor << " (" << m_dt.is_infinite(neighbor) << ")" << "\n" - << m_dt.point(ch, (id+1)&3) << "\n" << m_dt.point(ch, (id+2)&3) << "\n" << m_dt.point(ch, (id+3)&3) << std::endl; + << m_dt.point(ch, Dt::vertex_triple_index(id, 0)) << "\n" + << m_dt.point(ch, Dt::vertex_triple_index(id, 1)) << "\n" + << m_dt.point(ch, Dt::vertex_triple_index(id, 2)) << std::endl; std::cout << "Priority: " << gate.priority() << std::endl; #endif @@ -1246,7 +1277,9 @@ class Alpha_wrap_3 std::string face_name = "results/steps/face_" + std::to_string(static_cast(i++)) + ".xyz"; std::ofstream face_out(face_name); face_out.precision(17); - face_out << "3\n" << m_dt.point(ch, (id+1)&3) << "\n" << m_dt.point(ch, (id+2)&3) << "\n" << m_dt.point(ch, (id+3)&3) << std::endl; + face_out << "3\n" << m_dt.point(ch, Dt::vertex_triple_index(id, 0)) << "\n" + << m_dt.point(ch, Dt::vertex_triple_index(id, 1)) << "\n" + << m_dt.point(ch, Dt::vertex_triple_index(id, 2)) << std::endl; face_out.close(); #endif @@ -1373,7 +1406,7 @@ class Alpha_wrap_3 inc_cells.reserve(64); m_dt.incident_cells(v, std::back_inserter(inc_cells)); - // Flood one inside and outside CC. + // Flood one inside and outside CC within the cell umbrella of the vertex. // Process both an inside and an outside CC to also detect edge pinching. // If there are still unprocessed afterwards, there is a non-manifoldness issue. // @@ -1664,7 +1697,8 @@ class Alpha_wrap_3 private: void check_queue_sanity() { - std::cout << "Check queue sanity..." << std::endl; + std::cout << "\t~~~ Check queue sanity ~~~" << std::endl; + std::vector queue_gates; Gate previous_top_gate = m_queue.top(); while(!m_queue.empty()) @@ -1674,15 +1708,16 @@ class Alpha_wrap_3 const Facet& current_f = current_gate.facet(); const Cell_handle ch = current_f.first; const int id = current_f.second; - const Point_3& p0 = m_dt.point(ch, (id+1)&3); - const Point_3& p1 = m_dt.point(ch, (id+2)&3); - const Point_3& p2 = m_dt.point(ch, (id+3)&3); + const Point_3& p0 = m_dt.point(ch, Dt::vertex_triple_index(id, 0)); + const Point_3& p1 = m_dt.point(ch, Dt::vertex_triple_index(id, 1)); + const Point_3& p2 = m_dt.point(ch, Dt::vertex_triple_index(id, 2)); const FT sqr = geom_traits().compute_squared_radius_3_object()(p0, p1, p2); - std::cout << "At Facet with VID " << get(Gate_ID_PM
(), current_gate) << std::endl; - - if(current_gate.priority() != sqr) - std::cerr << "Error: facet in queue has wrong priority" << std::endl; + std::cout << "At Facet with VID " << get(Gate_ID_PM
(), current_gate) << "\n"; + std::cout << "\t" << p0 << "\n\t" << p1 << "\n\t" << p2 << "\n"; + std::cout << " Artificiality: " << current_gate.is_artificial_facet() << "\n"; + std::cout << " SQR: " << sqr << "\n"; + std::cout << " Priority " << current_gate.priority() << std::endl; if(Less_gate()(current_gate, previous_top_gate)) std::cerr << "Error: current gate has higher priority than the previous top" << std::endl; @@ -1691,7 +1726,8 @@ class Alpha_wrap_3 m_queue.pop(); } - std::cout << "End sanity check" << std::endl; + + std::cout << "\t~~~ End queue sanity check ~~~" << std::endl; // Rebuild CGAL_assertion(m_queue.empty()); From 87003941220f792096961bb9a3896afc5afdfb2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Sun, 24 Sep 2023 22:52:20 +0200 Subject: [PATCH 105/329] boost::mpl::if_ -> std::conditional --- .../CGAL/AABB_face_graph_triangle_primitive.h | 9 ++- .../AABB_halfedge_graph_segment_primitive.h | 9 ++- .../include/CGAL/number_utils.h | 16 ++--- .../include/CGAL/Arr_batched_point_location.h | 3 +- .../include/CGAL/Arr_overlay_2.h | 5 +- .../include/CGAL/Arr_tags.h | 59 +++++++++---------- .../CGAL/Arr_vertical_decomposition_2.h | 3 +- .../Arr_traits_adaptor_2_dispatching.h | 23 +++----- .../Arrangement_on_surface_2_global.h | 10 ++-- .../Arrangement_on_surface_2/test_tags.cpp | 1 - .../test_traits_dispatching.cpp | 1 - .../internal/OM_iterator_from_circulator.h | 29 ++++----- .../internal/initialized_index_maps_helpers.h | 4 +- .../CGAL/boost/graph/named_params_helper.h | 18 +++--- BGL/include/CGAL/boost/graph/properties.h | 10 ++-- .../CGAL/boost/graph/properties_OpenMesh.h | 15 +++-- BGL/include/CGAL/boost/graph/property_maps.h | 1 - .../CGAL/Combinatorial_map_iterators_base.h | 34 +++++------ .../CGAL/Compact_container_with_index.h | 11 ++-- Filtered_kernel/include/CGAL/Lazy_kernel.h | 1 - .../CGAL/Generalized_map_iterators_base.h | 1 - .../include/CGAL/sibson_gradient_fitting.h | 1 - Kernel_23/include/CGAL/Kernel_traits.h | 1 - Mesh_3/benchmark/Mesh_3/StdAfx.h | 2 - .../Implicit_to_labeling_function_wrapper.h | 7 +-- .../Image_to_labeled_function_wrapper.h | 1 - Mesh_3/include/CGAL/Mesh_3/Refine_cells_3.h | 7 +-- Mesh_3/include/CGAL/Mesh_3/Refine_facets_3.h | 7 +-- .../CGAL/Mesh_3/Triangulation_helpers.h | 1 - .../CGAL/NewKernel_d/Cartesian_filter_K.h | 1 - .../NewKernel_d/Cartesian_static_filters.h | 7 +-- .../CGAL/NewKernel_d/KernelD_converter.h | 9 ++- .../include/CGAL/NewKernel_d/functor_tags.h | 3 +- NewKernel_d/include/CGAL/NewKernel_d/utils.h | 8 +-- NewKernel_d/test/NewKernel_d/Epick_d.cpp | 4 +- Number_types/include/CGAL/Lazy_exact_nt.h | 10 ++-- Number_types/include/CGAL/Quotient.h | 8 +-- .../Algebraic_structure_traits.h | 8 +-- .../CGAL/Sqrt_extension/Coercion_traits.h | 4 +- ...t_to_labeled_subdomains_function_wrapper.h | 7 +-- .../CGAL/Periodic_3_function_wrapper.h | 7 +-- .../CGAL/Periodic_3_regular_triangulation_3.h | 1 - ...ABB_traversal_traits_with_transformation.h | 1 - .../internal/Corefinement/face_graph_utils.h | 7 +-- .../Polygon_mesh_processing/intersection.h | 1 - .../CGAL/Polygon_mesh_processing/locate.h | 1 - .../include/CGAL/Polygon_mesh_slicer.h | 9 ++- Polynomial/include/CGAL/Polynomial.h | 1 - .../include/CGAL/Polynomial/Polynomial_type.h | 6 +- Polynomial/include/CGAL/Polynomial_traits_d.h | 6 +- .../include/CGAL/Dynamic_property_map.h | 7 +-- .../CGAL/Mesh_complex_3_in_triangulation_3.h | 1 - .../include/CGAL/Compact_container.h | 10 ++-- .../CGAL/Concurrent_compact_container.h | 4 +- .../include/CGAL/Handle_with_policy.h | 6 +- .../include/CGAL/Named_function_parameters.h | 13 ++-- .../include/CGAL/transforming_iterator.h | 7 +-- .../include/CGAL/Skin_surface_base_3.h | 1 - .../include/CGAL/Fuzzy_iso_box.h | 2 - .../include/CGAL/Search_traits_adapter.h | 12 ++-- .../Straight_skeleton_aux.h | 11 ++-- .../CGAL/Constrained_triangulation_2.h | 5 +- .../include/CGAL/Regular_triangulation_2.h | 1 - .../include/CGAL/Triangulation_hierarchy_2.h | 1 - .../include/CGAL/Regular_triangulation_3.h | 1 - ...n_cell_base_with_weighted_circumcenter_3.h | 1 - .../include/CGAL/Triangulation_3.h | 1 - .../include/CGAL/Triangulation_hierarchy_3.h | 1 - .../include/CGAL/_test_cls_delaunay_3.h | 1 - .../CGAL/_test_cls_parallel_triangulation_3.h | 1 - .../test_regular_insert_range_with_info.cpp | 18 +++--- 71 files changed, 212 insertions(+), 292 deletions(-) diff --git a/AABB_tree/include/CGAL/AABB_face_graph_triangle_primitive.h b/AABB_tree/include/CGAL/AABB_face_graph_triangle_primitive.h index 5422c84b2ae6..021cdc6270ab 100644 --- a/AABB_tree/include/CGAL/AABB_face_graph_triangle_primitive.h +++ b/AABB_tree/include/CGAL/AABB_face_graph_triangle_primitive.h @@ -21,7 +21,6 @@ #include #include #include -#include namespace CGAL { @@ -57,9 +56,9 @@ template < class FaceGraph, class CacheDatum=Tag_false > class AABB_face_graph_triangle_primitive #ifndef DOXYGEN_RUNNING - : public AABB_primitive::face_descriptor, - std::pair::face_descriptor, const FaceGraph*> >::type, + : public AABB_primitive::face_descriptor, + std::pair::face_descriptor, const FaceGraph*> >, Triangle_from_face_descriptor_map< FaceGraph, typename Default::Get::const_type >::type VertexPointPMap_; typedef typename boost::graph_traits::face_descriptor FD; - typedef typename boost::mpl::if_ >::type Id_; + typedef std::conditional_t > Id_; typedef Triangle_from_face_descriptor_map Triangle_property_map; typedef One_point_from_face_descriptor_map Point_property_map; diff --git a/AABB_tree/include/CGAL/AABB_halfedge_graph_segment_primitive.h b/AABB_tree/include/CGAL/AABB_halfedge_graph_segment_primitive.h index 135682273199..3f5481d0cfe1 100644 --- a/AABB_tree/include/CGAL/AABB_halfedge_graph_segment_primitive.h +++ b/AABB_tree/include/CGAL/AABB_halfedge_graph_segment_primitive.h @@ -24,7 +24,6 @@ #include #include #include -#include #include @@ -70,9 +69,9 @@ template < class HalfedgeGraph, class CacheDatum = Tag_false > class AABB_halfedge_graph_segment_primitive #ifndef DOXYGEN_RUNNING - : public AABB_primitive< typename boost::mpl::if_::edge_descriptor, - std::pair::edge_descriptor, const HalfedgeGraph*> >::type, + : public AABB_primitive< std::conditional_t::edge_descriptor, + std::pair::edge_descriptor, const HalfedgeGraph*> >, Segment_from_edge_descriptor_map< HalfedgeGraph, typename Default::Get::const_type >::type VertexPointPMap_; typedef typename boost::graph_traits::edge_descriptor ED; - typedef typename boost::mpl::if_ >::type Id_; + typedef std::conditional_t > Id_; typedef Segment_from_edge_descriptor_map Segment_property_map; typedef Source_point_from_edge_descriptor_map Point_property_map; diff --git a/Algebraic_foundations/include/CGAL/number_utils.h b/Algebraic_foundations/include/CGAL/number_utils.h index c17823d72b9d..5a5bc2d242d3 100644 --- a/Algebraic_foundations/include/CGAL/number_utils.h +++ b/Algebraic_foundations/include/CGAL/number_utils.h @@ -194,21 +194,21 @@ root_of( int k, Input_iterator begin, Input_iterator end ) { template< class Number_type > inline // select a Is_zero functor -typename boost::mpl::if_c< - ::std::is_same< typename Algebraic_structure_traits< Number_type >::Is_zero, - Null_functor >::value , +typename std::conditional_t< + std::is_same_v< typename Algebraic_structure_traits< Number_type >::Is_zero, + Null_functor >, typename Real_embeddable_traits< Number_type >::Is_zero, typename Algebraic_structure_traits< Number_type >::Is_zero ->::type::result_type +>::result_type is_zero( const Number_type& x ) { // We take the Algebraic_structure_traits<>::Is_zero functor by default. If it // is not available, we take the Real_embeddable_traits functor - typename ::boost::mpl::if_c< - ::std::is_same< + std::conditional_t< + std::is_same_v< typename Algebraic_structure_traits< Number_type >::Is_zero, - Null_functor >::value , + Null_functor > , typename Real_embeddable_traits< Number_type >::Is_zero, - typename Algebraic_structure_traits< Number_type >::Is_zero >::type + typename Algebraic_structure_traits< Number_type >::Is_zero > is_zero; return is_zero( x ); } diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_batched_point_location.h b/Arrangement_on_surface_2/include/CGAL/Arr_batched_point_location.h index 42715621e4b2..85ba6ccc235f 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_batched_point_location.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_batched_point_location.h @@ -26,7 +26,6 @@ #include #include -#include #include namespace CGAL { @@ -120,7 +119,7 @@ locate(const Arrangement_on_surface_2& arr, * Use the form 'A a(*b);' and not ''A a = b;' to handle the case where A has * only an implicit constructor, (which takes *b as a parameter). */ - typename boost::mpl::if_, const Bgt2&, Bgt2>::type + std::conditional_t, const Bgt2&, Bgt2> ex_traits(*geom_traits); // Define the sweep-line visitor and perform the sweep. diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_overlay_2.h b/Arrangement_on_surface_2/include/CGAL/Arr_overlay_2.h index 2951b1983fe8..dfa6fb89ffc1 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_overlay_2.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_overlay_2.h @@ -25,7 +25,6 @@ #include #include -#include #include #include @@ -247,8 +246,8 @@ overlay(const Arrangement_on_surface_2& arr1 * Use the form 'A a(*b);' and not ''A a = b;' to handle the case where A has * only an implicit constructor, (which takes *b as a parameter). */ - typename boost::mpl::if_, - const Ovl_gt2&, Ovl_gt2>::type + std::conditional_t, + const Ovl_gt2&, Ovl_gt2> ex_traits(*traits_adaptor); Ovl_visitor visitor(&arr1, &arr2, &arr, &ovl_tr); diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_tags.h b/Arrangement_on_surface_2/include/CGAL/Arr_tags.h index 91313be6c5d8..1aac06155855 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_tags.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_tags.h @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -246,14 +245,14 @@ struct Arr_all_sides_not_finite_tag : struct Arr_not_all_sides_not_finite_tag : public virtual Arr_not_all_sides_oblivious_tag {}; -typedef boost::mpl::bool_ Arr_true; -typedef boost::mpl::bool_ Arr_false; +typedef std::true_type Arr_true; +typedef std::false_type Arr_false; template struct Arr_is_side_oblivious { typedef ArrSideCategory Side_cat; typedef std::is_same Is_same; - typedef boost::mpl::if_ result; + typedef std::conditional result; typedef typename result::type type; }; @@ -261,7 +260,7 @@ template struct Arr_is_side_open { typedef ArrSideCategory Side_cat; typedef std::is_same Is_same; - typedef boost::mpl::if_ result; + typedef std::conditional result; typedef typename result::type type; }; @@ -269,7 +268,7 @@ template struct Arr_is_side_identified { typedef ArrSideCategory Side_cat; typedef std::is_same Is_same; - typedef boost::mpl::if_ result; + typedef std::conditional result; typedef typename result::type type; }; @@ -277,7 +276,7 @@ template struct Arr_is_side_contracted { typedef ArrSideCategory Side_cat; typedef std::is_same Is_same; - typedef boost::mpl::if_ result; + typedef std::conditional result; typedef typename result::type type; }; @@ -285,7 +284,7 @@ template struct Arr_is_side_closed { typedef ArrSideCategory Side_cat; typedef std::is_same Is_same; - typedef boost::mpl::if_ result; + typedef std::conditional result; typedef typename result::type type; }; @@ -307,10 +306,10 @@ struct Arr_all_sides_oblivious_category { /*! Boolean tag that is Arr_all_sides_oblivious_tag if all sides are * oblivious, otherwise Arr_not_all_sides_oblivious_tag */ - typedef typename boost::mpl::if_, - Arr_all_sides_oblivious_tag, - Arr_not_all_sides_oblivious_tag>::type + typedef std::conditional_t result; }; @@ -340,10 +339,10 @@ struct Arr_all_sides_not_open_category { /*! Boolean tag that is Arr_all_sides_not_open_tag if all sides are not-open, * otherwise Arr_not_all_sides_not_open_tag */ - typedef typename boost::mpl::if_, - Arr_all_sides_not_open_tag, - Arr_not_all_sides_not_open_tag>::type + typedef std::conditional_t result; }; @@ -379,18 +378,18 @@ struct Arr_sides_category { typedef boost::mpl::or_ Bot_obl_or_ope; typedef boost::mpl::or_ Top_obl_or_ope; - typedef typename boost::mpl::if_, - Arr_all_sides_not_finite_tag, - Arr_not_all_sides_not_finite_tag>::type + typedef std::conditional_t tmp; public: - typedef typename boost::mpl::if_, - Arr_all_sides_oblivious_tag, tmp>::type + typedef std::conditional_t result; }; @@ -532,11 +531,11 @@ struct Arr_two_sides_category { Is_open; public: - typedef typename boost::mpl::if_::type>::type>::type>::type + typedef std::conditional_t>>> result; }; diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_vertical_decomposition_2.h b/Arrangement_on_surface_2/include/CGAL/Arr_vertical_decomposition_2.h index 75c8f25e0c96..099f44192ee5 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_vertical_decomposition_2.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_vertical_decomposition_2.h @@ -24,7 +24,6 @@ #include #include -#include #include namespace CGAL { @@ -124,7 +123,7 @@ decompose(const Arrangement_on_surface_2& arr, * Use the form 'A a(*b);' and not ''A a = b;' to handle the case where A has * only an implicit constructor, (which takes *b as a parameter). */ - typename boost::mpl::if_, const Vgt2&, Vgt2>::type + std::conditional_t, const Vgt2&, Vgt2> ex_traits(*geom_traits); // Define the sweep-line visitor and perform the sweep. diff --git a/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arr_traits_adaptor_2_dispatching.h b/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arr_traits_adaptor_2_dispatching.h index e4533596dd2b..283b2dc66b5c 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arr_traits_adaptor_2_dispatching.h +++ b/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arr_traits_adaptor_2_dispatching.h @@ -17,7 +17,6 @@ #include -#include #include #include #include @@ -59,25 +58,21 @@ struct Or_traits { private: - typedef boost::mpl::bool_< true > true_; - typedef boost::mpl::bool_< false > false_; + typedef std::conditional< + std::is_same_v< Arr_smaller_implementation_tag, Arr_use_traits_tag >, + std::true_type, std::false_type > Smaller_traits; - typedef boost::mpl::if_< - std::is_same< Arr_smaller_implementation_tag, Arr_use_traits_tag >, - true_, false_ > Smaller_traits; - - typedef boost::mpl::if_< - std::is_same< Arr_larger_implementation_tag, Arr_use_traits_tag >, - true_, false_ > Larger_traits; + typedef std::conditional_t_< + std::is_same_v< Arr_larger_implementation_tag, Arr_use_traits_tag >, + std::true_type, std::false_type > Larger_traits; public: //! the result type (if one side asks for traits, then ask traits! //! Or vice versa: If both ask for dummy, then dummy!) - typedef typename boost::mpl::if_< - boost::mpl::or_< Smaller_traits, Larger_traits >, - Arr_use_traits_tag, - Arr_use_dummy_tag >::type type; + typedef std::conditional_t< + Smaller_traits, Larger_traits >::value || Arr_use_traits_tag::value, + Arr_use_dummy_tag > type; }; diff --git a/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arrangement_on_surface_2_global.h b/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arrangement_on_surface_2_global.h index 0f2957d47149..ee072c95778c 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arrangement_on_surface_2_global.h +++ b/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arrangement_on_surface_2_global.h @@ -23,8 +23,6 @@ #include #include -#include -#include #include #include @@ -271,7 +269,7 @@ insert_empty(Arrangement_on_surface_2& arr, * Use the form 'A a(*b);' and not ''A a = b;' to handle the case where A has * only an implicit constructor, (which takes *b as a parameter). */ - typename boost::mpl::if_, const Cgt2&, Cgt2>::type + std::conditional_t, const Cgt2&, Cgt2> traits(*geom_traits); // Define a surface-sweep instance and perform the sweep: @@ -326,7 +324,7 @@ void insert_empty(Arrangement_on_surface_2& * Use the form 'A a(*b);' and not ''A a = b;' to handle the case where A has * only an implicit constructor, (which takes *b as a parameter). */ - typename boost::mpl::if_, const Cgt2&, Cgt2>::type + std::conditional_t, const Cgt2&, Cgt2> traits(*geom_traits); // Define a surface-sweep instance and perform the sweep. @@ -379,7 +377,7 @@ void insert_non_empty(Arrangement_on_surface_2, const Igt2&, Igt2>::type + std::conditional_t, const Igt2&, Igt2> traits(*geom_traits); // Create a set of existing as well as new curves and points. @@ -979,7 +977,7 @@ non_intersecting_insert_non_empty(Arrangement_on_surface_2, const Igt2&, Igt2>::type + std::conditional_t, const Igt2&, Igt2> traits(*geom_traits); // Create a set of existing as well as new curves and points. diff --git a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/test_tags.cpp b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/test_tags.cpp index 81eae4204966..a86325de2afc 100644 --- a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/test_tags.cpp +++ b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/test_tags.cpp @@ -6,7 +6,6 @@ #include #include -#include struct Traits1 { typedef CGAL::Arr_open_side_tag Left_side_category; diff --git a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/test_traits_dispatching.cpp b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/test_traits_dispatching.cpp index 5c8e19fa12e0..ce17f3b9105e 100644 --- a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/test_traits_dispatching.cpp +++ b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/test_traits_dispatching.cpp @@ -4,7 +4,6 @@ #include #include -#include int dispatch(CGAL::Arr_use_dummy_tag) { return 0; diff --git a/BGL/include/CGAL/boost/graph/internal/OM_iterator_from_circulator.h b/BGL/include/CGAL/boost/graph/internal/OM_iterator_from_circulator.h index e726e161a6bd..01104c546804 100644 --- a/BGL/include/CGAL/boost/graph/internal/OM_iterator_from_circulator.h +++ b/BGL/include/CGAL/boost/graph/internal/OM_iterator_from_circulator.h @@ -20,8 +20,6 @@ #include #include -#include - namespace CGAL { // adapted from circulator.h, does not support @@ -45,23 +43,20 @@ class OM_iterator_from_circulator { typedef typename I__traits::iterator_category iterator_category; - typedef typename - boost::mpl::if_c< Prevent_deref - , C - , typename C::value_type - >::type value_type; + typedef std::conditional_t< Prevent_deref + , C + , typename C::value_type> + value_type; typedef typename C::difference_type difference_type; - typedef typename - boost::mpl::if_c< Prevent_deref - , C& - , typename C::reference - >::type reference; - typedef typename - boost::mpl::if_c< Prevent_deref - , C* - , typename C::reference - >::type pointer; + typedef std::conditional_t< Prevent_deref + , C& + , typename C::reference + > reference; + typedef std::conditional_t< Prevent_deref + , C* + , typename C::reference + > pointer; OM_iterator_from_circulator(){} diff --git a/BGL/include/CGAL/boost/graph/internal/initialized_index_maps_helpers.h b/BGL/include/CGAL/boost/graph/internal/initialized_index_maps_helpers.h index 2d85e38d35c1..eddefcec7fb2 100644 --- a/BGL/include/CGAL/boost/graph/internal/initialized_index_maps_helpers.h +++ b/BGL/include/CGAL/boost/graph/internal/initialized_index_maps_helpers.h @@ -276,8 +276,8 @@ class GetInitializedIndexMap { public: // Check if there is an internal property map; if not, we must a dynamic property map - typedef typename boost::mpl::if_c< - CGAL::graph_has_property::value, Tag, DynamicTag>::type Final_tag; + typedef std::conditional_t< + CGAL::graph_has_property::value, Tag, DynamicTag> Final_tag; typedef typename internal_np::Lookup_named_param_def< PropertyTag, diff --git a/BGL/include/CGAL/boost/graph/named_params_helper.h b/BGL/include/CGAL/boost/graph/named_params_helper.h index 1e0efd6faa60..4dce0049b1ab 100644 --- a/BGL/include/CGAL/boost/graph/named_params_helper.h +++ b/BGL/include/CGAL/boost/graph/named_params_helper.h @@ -20,7 +20,6 @@ #include #include -#include #include #include @@ -43,11 +42,10 @@ class property_map_selector { public: typedef typename graph_has_property::type Has_internal_pmap; - typedef typename boost::mpl::if_c::type, - typename boost::cgal_no_property::type - >::type type; - typedef typename boost::mpl::if_c::type, + typename boost::cgal_no_property::type> type; + typedef std::conditional_t::const_type, typename boost::cgal_no_property::const_type >::type const_type; @@ -209,10 +207,10 @@ struct GetGeomTraits_impl::value, - typename GetK::Kernel, - Fake_GT>::type type; + typedef std::conditional_t::value, + typename GetK::Kernel, + Fake_GT> type; }; template typedef ValueType value_type; typedef Handle key_type; - typedef typename boost::mpl::if_< std::is_reference, - ValueType&, - ValueType >::type Reference; + typedef std::conditional_t< std::is_reference, + ValueType&, + ValueType > Reference; Point_accessor() {} Point_accessor(Point_accessor) {} @@ -172,9 +172,9 @@ struct Is_writable_property_map // property map must define. template struct Is_writable_property_map - : boost::mpl::if_c::reference>::type>::value, - CGAL::Tag_false, CGAL::Tag_true>::type + CGAL::Tag_false, CGAL::Tag_true> { }; } // namespace internal diff --git a/BGL/include/CGAL/boost/graph/properties_OpenMesh.h b/BGL/include/CGAL/boost/graph/properties_OpenMesh.h index 861f5aea98b6..f6f56cea7ef8 100644 --- a/BGL/include/CGAL/boost/graph/properties_OpenMesh.h +++ b/BGL/include/CGAL/boost/graph/properties_OpenMesh.h @@ -13,7 +13,6 @@ #include #include #include -#include #ifndef OPEN_MESH_CLASS #error OPEN_MESH_CLASS is not defined @@ -29,13 +28,13 @@ namespace CGAL { template class OM_pmap { public: - typedef typename boost::mpl::if_::vertex_descriptor>, - OpenMesh::VPropHandleT, - typename boost::mpl::if_::face_descriptor>, - OpenMesh::FPropHandleT, - typename boost::mpl::if_::halfedge_descriptor>, - OpenMesh::HPropHandleT, - OpenMesh::EPropHandleT >::type>::type>::type H; + typedef std::conditional_t::vertex_descriptor>, + OpenMesh::VPropHandleT, + std::conditional_t::face_descriptor>, + OpenMesh::FPropHandleT, + std::conditional_t::halfedge_descriptor>, + OpenMesh::HPropHandleT, + OpenMesh::EPropHandleT >>> H; typedef boost::lvalue_property_map_tag category; diff --git a/BGL/include/CGAL/boost/graph/property_maps.h b/BGL/include/CGAL/boost/graph/property_maps.h index aab29d9b8811..b6973feb65c8 100644 --- a/BGL/include/CGAL/boost/graph/property_maps.h +++ b/BGL/include/CGAL/boost/graph/property_maps.h @@ -15,7 +15,6 @@ #include #include -#include namespace CGAL{ diff --git a/Combinatorial_map/include/CGAL/Combinatorial_map_iterators_base.h b/Combinatorial_map/include/CGAL/Combinatorial_map_iterators_base.h index a50266f76592..555dc554c58e 100644 --- a/Combinatorial_map/include/CGAL/Combinatorial_map_iterators_base.h +++ b/Combinatorial_map/include/CGAL/Combinatorial_map_iterators_base.h @@ -18,7 +18,6 @@ #include #include -#include #include @@ -68,24 +67,24 @@ namespace CGAL { class CMap_dart_iterator; template < typename Map_,bool Const> - class CMap_dart_iterator: public boost::mpl::if_c< Const, + class CMap_dart_iterator: public std::conditional_t< Const, typename Map_::Dart_container::const_iterator, - typename Map_::Dart_container::iterator>::type + typename Map_::Dart_container::iterator> //public internal::CC_iterator { public: typedef CMap_dart_iterator Self; - typedef typename boost::mpl::if_c< Const, + typedef std::conditional_t< Const, typename Map_::Dart_container::const_iterator, - typename Map_::Dart_container::iterator>::type Base; + typename Map_::Dart_container::iterator> Base; // typedef internal::CC_iterator Base; - typedef typename boost::mpl::if_c< Const, - typename Map_::Dart_const_descriptor, - typename Map_::Dart_descriptor>::type + typedef std::conditional_t< Const, + typename Map_::Dart_const_descriptor, + typename Map_::Dart_descriptor> Dart_descriptor; - typedef typename boost::mpl::if_c< Const, const Map_, Map_>::type Map; + typedef std::conditional_t< Const, const Map_, Map_> Map; typedef std::input_iterator_tag iterator_category; typedef typename Base::value_type value_type; @@ -180,25 +179,24 @@ namespace CGAL { template < typename Map_,bool Const > class CMap_dart_iterator: - /*public boost::mpl::if_c< Const, + /*public std::conditional_t< Const, typename Map_::Dart_container::const_iterator, - typename Map_::Dart_container::iterator>::type*/ + typename Map_::Dart_container::iterator>*/ public internal::CC_iterator_with_index { public: typedef CMap_dart_iterator Self; - /*typedef typename boost::mpl::if_c< Const, + /*typedef std::conditional_t< Const, typename Map_::Dart_container::const_iterator, - typename Map_::Dart_container::iterator>::type Base;*/ + typename Map_::Dart_container::iterator> Base;*/ typedef internal::CC_iterator_with_index Base; - typedef typename boost::mpl::if_c< Const, - typename Map_::Dart_const_descriptor, - typename Map_::Dart_descriptor>::type + typedef std::conditional_t< Const, + typename Map_::Dart_const_descriptor, + typename Map_::Dart_descriptor> Dart_descriptor; - typedef typename boost::mpl::if_c< Const, const Map_, - Map_>::type Map; + typedef std::conditional_t< Const, const Map_, Map_> Map; typedef std::input_iterator_tag iterator_category; typedef typename Base::value_type value_type; diff --git a/Combinatorial_map/include/CGAL/Compact_container_with_index.h b/Combinatorial_map/include/CGAL/Compact_container_with_index.h index d3d67c57a88d..dbb9aa8bae6d 100644 --- a/Combinatorial_map/include/CGAL/Compact_container_with_index.h +++ b/Combinatorial_map/include/CGAL/Compact_container_with_index.h @@ -861,14 +861,13 @@ namespace internal { typedef typename DSC::value_type value_type; typedef typename DSC::size_type size_type; typedef typename DSC::difference_type difference_type; - typedef typename boost::mpl::if_c< Const, const value_type*, - value_type*>::type pointer; - typedef typename boost::mpl::if_c< Const, const value_type&, - value_type&>::type reference; + typedef std::conditional_t< Const, const value_type*, + value_type*> pointer; + typedef std::conditional_t< Const, const value_type&, + value_type&> reference; typedef std::bidirectional_iterator_tag iterator_category; - typedef typename boost::mpl::if_c< Const, const DSC*, DSC*>::type - cc_pointer; + typedef std::conditional_t< Const, const DSC*, DSC*> cc_pointer; CC_iterator_with_index(): m_ptr_to_cc(nullptr), m_index(0) diff --git a/Filtered_kernel/include/CGAL/Lazy_kernel.h b/Filtered_kernel/include/CGAL/Lazy_kernel.h index 911a86debc30..c6b6cb2444ab 100644 --- a/Filtered_kernel/include/CGAL/Lazy_kernel.h +++ b/Filtered_kernel/include/CGAL/Lazy_kernel.h @@ -27,7 +27,6 @@ #include #include #include -#include #include #include diff --git a/Generalized_map/include/CGAL/Generalized_map_iterators_base.h b/Generalized_map/include/CGAL/Generalized_map_iterators_base.h index 034b1600f936..1747f89f354b 100644 --- a/Generalized_map/include/CGAL/Generalized_map_iterators_base.h +++ b/Generalized_map/include/CGAL/Generalized_map_iterators_base.h @@ -19,7 +19,6 @@ #include #include #include -#include namespace CGAL { diff --git a/Interpolation/include/CGAL/sibson_gradient_fitting.h b/Interpolation/include/CGAL/sibson_gradient_fitting.h index f08600a4603c..f6d6d0559dd8 100644 --- a/Interpolation/include/CGAL/sibson_gradient_fitting.h +++ b/Interpolation/include/CGAL/sibson_gradient_fitting.h @@ -23,7 +23,6 @@ #include #include -#include #include #include diff --git a/Kernel_23/include/CGAL/Kernel_traits.h b/Kernel_23/include/CGAL/Kernel_traits.h index 4839184ff304..e12d38503bca 100644 --- a/Kernel_23/include/CGAL/Kernel_traits.h +++ b/Kernel_23/include/CGAL/Kernel_traits.h @@ -19,7 +19,6 @@ #include #include -#include namespace CGAL { diff --git a/Mesh_3/benchmark/Mesh_3/StdAfx.h b/Mesh_3/benchmark/Mesh_3/StdAfx.h index 57890430a5b2..9648697498aa 100644 --- a/Mesh_3/benchmark/Mesh_3/StdAfx.h +++ b/Mesh_3/benchmark/Mesh_3/StdAfx.h @@ -42,11 +42,9 @@ #include #include #include -#include #include #include #include -#include #include #include #include diff --git a/Mesh_3/include/CGAL/Implicit_to_labeling_function_wrapper.h b/Mesh_3/include/CGAL/Implicit_to_labeling_function_wrapper.h index 7e3af3de705e..3ab3f0d3ba5f 100644 --- a/Mesh_3/include/CGAL/Implicit_to_labeling_function_wrapper.h +++ b/Mesh_3/include/CGAL/Implicit_to_labeling_function_wrapper.h @@ -33,7 +33,6 @@ #include #include -#include #include #include @@ -67,9 +66,9 @@ class Implicit_to_labeling_function_wrapper } private: - typedef typename boost::mpl::if_, - Function_*, - Function_>::type Stored_function; + typedef std::conditional_t, + Function_*, + Function_> Stored_function; /// Function to wrap Stored_function f_; diff --git a/Mesh_3/include/CGAL/Mesh_3/Image_to_labeled_function_wrapper.h b/Mesh_3/include/CGAL/Mesh_3/Image_to_labeled_function_wrapper.h index 45246e4463db..3d1c030ff08b 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Image_to_labeled_function_wrapper.h +++ b/Mesh_3/include/CGAL/Mesh_3/Image_to_labeled_function_wrapper.h @@ -26,7 +26,6 @@ #include #include #include -#include namespace CGAL { 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 44e4f82b82d2..ad023df618e2 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Refine_cells_3.h +++ b/Mesh_3/include/CGAL/Mesh_3/Refine_cells_3.h @@ -37,7 +37,6 @@ #include #include -#include #include #include @@ -172,9 +171,9 @@ template::value, + std::is_convertible_v, // Parallel # ifdef CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE @@ -209,7 +208,7 @@ template # endif - >::type // boost::if (parallel/sequential) + > // std::conditional (parallel/sequential) #else // !CGAL_LINKED_WITH_TBB 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 b4e2af503757..50e0a6cef08d 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Refine_facets_3.h +++ b/Mesh_3/include/CGAL/Mesh_3/Refine_facets_3.h @@ -46,7 +46,6 @@ #include #include #include -#include #include #include #include @@ -640,9 +639,9 @@ template class Base_ = Refine_facets_3_base, #ifdef CGAL_LINKED_WITH_TBB - class Container_ = typename boost::mpl::if_c // (parallel/sequential?) + class Container_ = std::conditional_t // (parallel/sequential?) < - std::is_convertible::value, + std::is_convertible_v, // Parallel # ifdef CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE Meshes::Filtered_deque_container @@ -679,7 +678,7 @@ template # endif - >::type // boost::if (parallel/sequential) + > // std::conditional (parallel/sequential) #else // !CGAL_LINKED_WITH_TBB diff --git a/Mesh_3/include/CGAL/Mesh_3/Triangulation_helpers.h b/Mesh_3/include/CGAL/Mesh_3/Triangulation_helpers.h index db2dde5b6d3d..e8517c94945a 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Triangulation_helpers.h +++ b/Mesh_3/include/CGAL/Mesh_3/Triangulation_helpers.h @@ -23,7 +23,6 @@ #include #include -#include #include #include diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_filter_K.h b/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_filter_K.h index c02efa6dcc65..25ec0c4f25c4 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_filter_K.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_filter_K.h @@ -15,7 +15,6 @@ #include #include #include -#include #include namespace CGAL { diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_static_filters.h b/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_static_filters.h index 5c3a64287d28..122cfe90885b 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_static_filters.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_static_filters.h @@ -16,7 +16,6 @@ #include // bug, should be included by the next one #include #include -#include namespace CGAL { namespace SFA { // static filter adapter @@ -98,9 +97,9 @@ struct Cartesian_static_filters, R_, Derived_> : public R_ { template struct Functor : Inherit_functor {}; template struct Functor { typedef - //typename boost::mpl::if_ < - //std::is_same, - //typename Get_functor::type, + //std::conditional_t < + //std::is_same_v, + //typename Get_functor, SFA::Orientation_of_points_2 // >::type type; diff --git a/NewKernel_d/include/CGAL/NewKernel_d/KernelD_converter.h b/NewKernel_d/include/CGAL/NewKernel_d/KernelD_converter.h index d62b8215cc52..edfb15ae9e95 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/KernelD_converter.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/KernelD_converter.h @@ -23,7 +23,6 @@ #include #include #include -#include #include #include @@ -80,12 +79,12 @@ class KernelD_converter_ // Explicit calls to boost::mpl functions to avoid parenthesis // warning on some versions of GCC - typedef typename boost::mpl::if_ < + typedef std::conditional_t < // If Point==Vector, keep only one conversion - boost::mpl::or_, + duplicate::value || // For iterator objects, the default is make_transforming_iterator - boost::mpl::bool_<(iterator_tag_traits::is_iterator && no_converter::value)> >, - Do_not_use,K1_Obj>::type argument_type; + (iterator_tag_traits::is_iterator && no_converter::value), + Do_not_use,K1_Obj> argument_type; //typedef typename KOC::argument_type K1_Obj; //typedef typename KOC::result_type K2_Obj; public: diff --git a/NewKernel_d/include/CGAL/NewKernel_d/functor_tags.h b/NewKernel_d/include/CGAL/NewKernel_d/functor_tags.h index a3255d25eb00..4eb0e8900631 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/functor_tags.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/functor_tags.h @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -233,7 +232,7 @@ namespace CGAL { #undef CGAL_DECL_ITER_OBJ templatestruct Get_functor_category,B,C> : - boost::mpl::if_c::is_iterator, + std::conditional::is_iterator, Construct_iterator_tag, Construct_tag> {}; diff --git a/NewKernel_d/include/CGAL/NewKernel_d/utils.h b/NewKernel_d/include/CGAL/NewKernel_d/utils.h index a1ac6faeddd2..f2e6a2f3ada5 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/utils.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/utils.h @@ -145,11 +145,11 @@ struct Has_type_different_from #define CGAL_KD_DEFAULT_FUNCTOR(Tg,Name,ReqTyp,ReqFun) \ template \ struct Get_functor::value \ || !Provides_types >::value \ || !Provides_functors >::value \ - , int, void>::type> \ + , int, void>> \ { \ typedef CGAL_STRIP_PAREN_ Name type; \ typedef K Bound_kernel; \ @@ -159,11 +159,11 @@ struct Has_type_different_from #define CGAL_KD_DEFAULT_TYPE(Tg,Name,ReqTyp,ReqFun) \ template \ struct Get_type::value \ || !Provides_types >::value \ || !Provides_functors >::value \ - , int, void>::type> \ + , int, void>> \ { \ typedef CGAL_STRIP_PAREN_ Name type; \ typedef K Bound_kernel; \ diff --git a/NewKernel_d/test/NewKernel_d/Epick_d.cpp b/NewKernel_d/test/NewKernel_d/Epick_d.cpp index 18ac1657ee63..5693977869a4 100644 --- a/NewKernel_d/test/NewKernel_d/Epick_d.cpp +++ b/NewKernel_d/test/NewKernel_d/Epick_d.cpp @@ -509,8 +509,8 @@ void test3(){ ; CP_ cp_ Kinit(construct_point_d_object); CV_ cv_ Kinit(construct_vector_d_object); - typename boost::mpl::if_,Construct_point3_helper,CP_>::type cp(cp_); - typename boost::mpl::if_,Construct_point3_helper,CV_>::type cv(cv_); + std::conditional_t,Construct_point3_helper,CP_> cp(cp_); + std::conditional_t,Construct_point3_helper,CV_> cv(cv_); CCI ci Kinit(construct_cartesian_const_iterator_d_object); CC cc Kinit(compute_coordinate_d_object); CL cl Kinit(compare_lexicographically_d_object); diff --git a/Number_types/include/CGAL/Lazy_exact_nt.h b/Number_types/include/CGAL/Lazy_exact_nt.h index 3f06ef3fb329..3f8a2812968a 100644 --- a/Number_types/include/CGAL/Lazy_exact_nt.h +++ b/Number_types/include/CGAL/Lazy_exact_nt.h @@ -19,7 +19,6 @@ #include // for Root_of functor #include -#include #include #include @@ -1179,12 +1178,11 @@ struct Coercion_traits< Lazy_exact_nt, Lazy_exact_nt > Are_implicit_interoperable; \ private: \ static const bool interoperable \ - =std::is_same< Are_implicit_interoperable, Tag_false>::value; \ + =std::is_same< Are_implicit_interoperable, Tag_false>::value; \ public: \ - typedef typename boost::mpl::if_c \ - ::type Type; \ - typedef typename boost::mpl::if_c >::type Cast; \ + typedef std::conditional_t Type; \ + typedef std::conditional_t > Cast; \ }; \ \ template \ diff --git a/Number_types/include/CGAL/Quotient.h b/Number_types/include/CGAL/Quotient.h index e91e22208a50..8c117c2fb6d8 100644 --- a/Number_types/include/CGAL/Quotient.h +++ b/Number_types/include/CGAL/Quotient.h @@ -627,13 +627,13 @@ template< class NT > class Algebraic_structure_traits_quotient_base< Quotient::Sqrt, - Null_functor >::value, + typedef std::conditional_t< + !std::is_same_v< typename Algebraic_structure_traits::Sqrt, + Null_functor >, typename INTERN_QUOTIENT::Sqrt_selector< Type, Is_exact >::Sqrt, Null_functor - >::type Sqrt; + > Sqrt; class Simplify : public CGAL::cpp98::unary_function< Type&, void > { diff --git a/Number_types/include/CGAL/Sqrt_extension/Algebraic_structure_traits.h b/Number_types/include/CGAL/Sqrt_extension/Algebraic_structure_traits.h index b0913afb1b6f..b1500148b598 100644 --- a/Number_types/include/CGAL/Sqrt_extension/Algebraic_structure_traits.h +++ b/Number_types/include/CGAL/Sqrt_extension/Algebraic_structure_traits.h @@ -204,10 +204,10 @@ class Algebraic_structure_traits< Sqrt_extension< COEFF_, ROOT_, ACDE_TAG,FP_TAG typedef Sqrt_extension< COEFF_, ROOT_, ACDE_TAG,FP_TAG > Type; // Tag_true if COEFF and ROOT are exact - typedef typename ::boost::mpl::if_c< - bool( ::std::is_same::Is_exact,::CGAL::Tag_true>::value )&& - bool( ::std::is_same::Is_exact,::CGAL::Tag_true>::value ) - ,::CGAL::Tag_true,::CGAL::Tag_false>::type Is_exact; + typedef std::conditional_t< + std::is_same_v::Is_exact,::CGAL::Tag_true> && + std::is_same::Is_exact,::CGAL::Tag_true> + ,::CGAL::Tag_true,::CGAL::Tag_false> Is_exact; typedef typename Algebraic_structure_traits::Is_numerical_sensitive Is_numerical_sensitive; diff --git a/Number_types/include/CGAL/Sqrt_extension/Coercion_traits.h b/Number_types/include/CGAL/Sqrt_extension/Coercion_traits.h index 6b4344348d4d..5b5ddfa45c69 100644 --- a/Number_types/include/CGAL/Sqrt_extension/Coercion_traits.h +++ b/Number_types/include/CGAL/Sqrt_extension/Coercion_traits.h @@ -178,7 +178,7 @@ template struct CT_ext_not_to_fwsqrt; // template struct Coercion_traits_for_level, B , CTL_SQRT_EXT> -:public ::boost::mpl::if_c< +:public std::conditional_t< // if B is fwsqrt ::boost::is_base_and_derived< Field_with_sqrt_tag, @@ -192,7 +192,7 @@ typename Algebraic_structure_traits::Algebraic_category >::value , //else take Intern::Coercion_traits not for fwsqrt INTERN_CT::CT_ext_not_to_fwsqrt< Sqrt_extension ,B> - >::type + > {}; // diff --git a/Periodic_3_mesh_3/include/CGAL/Implicit_to_labeled_subdomains_function_wrapper.h b/Periodic_3_mesh_3/include/CGAL/Implicit_to_labeled_subdomains_function_wrapper.h index a96c2eafa366..d821ab2fe3f9 100644 --- a/Periodic_3_mesh_3/include/CGAL/Implicit_to_labeled_subdomains_function_wrapper.h +++ b/Periodic_3_mesh_3/include/CGAL/Implicit_to_labeled_subdomains_function_wrapper.h @@ -15,7 +15,6 @@ #include #include -#include #if defined(BOOST_MSVC) # pragma warning(push) @@ -47,9 +46,9 @@ class Implicit_to_labeled_subdomains_function_wrapper } private: - typedef typename boost::mpl::if_, - Function_*, - Function_>::type Stored_function; + typedef std::conditional_t, + Function_*, + Function_> Stored_function; /// Function to wrap Stored_function f_; diff --git a/Periodic_3_mesh_3/include/CGAL/Periodic_3_function_wrapper.h b/Periodic_3_mesh_3/include/CGAL/Periodic_3_function_wrapper.h index 2780d6183932..b1ee5e650654 100644 --- a/Periodic_3_mesh_3/include/CGAL/Periodic_3_function_wrapper.h +++ b/Periodic_3_mesh_3/include/CGAL/Periodic_3_function_wrapper.h @@ -18,7 +18,6 @@ #include #include -#include namespace CGAL { @@ -46,9 +45,9 @@ class Periodic_3_function_wrapper } private: - typedef typename boost::mpl::if_, - Function_*, - Function_>::type Stored_function; + typedef std::conditional_t, + Function_*, + Function_>: Stored_function; /// Function to wrap Stored_function f_; diff --git a/Periodic_3_triangulation_3/include/CGAL/Periodic_3_regular_triangulation_3.h b/Periodic_3_triangulation_3/include/CGAL/Periodic_3_regular_triangulation_3.h index 7eed15886cd0..63fb94044699 100644 --- a/Periodic_3_triangulation_3/include/CGAL/Periodic_3_regular_triangulation_3.h +++ b/Periodic_3_triangulation_3/include/CGAL/Periodic_3_regular_triangulation_3.h @@ -31,7 +31,6 @@ #include #include -#include #include #include #include diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/AABB_traversal_traits_with_transformation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/AABB_traversal_traits_with_transformation.h index 838842771364..7dad2004ecd0 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/AABB_traversal_traits_with_transformation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/AABB_traversal_traits_with_transformation.h @@ -27,7 +27,6 @@ #include #include -#include namespace CGAL { diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h index 4a15d9e59c74..68f0c9e5e6c8 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h @@ -18,7 +18,6 @@ #include #include -#include #include #include #include @@ -388,12 +387,12 @@ struct TweakedGetVertexPointMap typedef typename std::is_same::value_type>::type Use_default_tag; - typedef typename boost::mpl::if_< - Use_default_tag, + typedef std::conditional_t< + Use_default_tag::value, Default_map, Dummy_default_vertex_point_map::vertex_descriptor > - >::type type; + > type; }; template diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/intersection.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/intersection.h index 26e205ea43d9..f32f9d907a98 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/intersection.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/intersection.h @@ -29,7 +29,6 @@ #include #include -#include #include #include diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h index ef361b175299..b99ed460a6f6 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h @@ -30,7 +30,6 @@ #include #include -#include #include #include diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_slicer.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_slicer.h index f1b88540a606..a608179f49ae 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_slicer.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_slicer.h @@ -30,7 +30,6 @@ #include #include -#include #include #include @@ -79,12 +78,12 @@ template::type >::type, + typename boost::property_map< TriangleMesh, vertex_point_t>::type >, Default, - VertexPointMap>::type> > >, + VertexPointMap>>>>, bool UseParallelPlaneOptimization=true> class Polygon_mesh_slicer { diff --git a/Polynomial/include/CGAL/Polynomial.h b/Polynomial/include/CGAL/Polynomial.h index b3681eb43b5f..ad61432cd405 100644 --- a/Polynomial/include/CGAL/Polynomial.h +++ b/Polynomial/include/CGAL/Polynomial.h @@ -34,7 +34,6 @@ #include #include #include -#include #include #include diff --git a/Polynomial/include/CGAL/Polynomial/Polynomial_type.h b/Polynomial/include/CGAL/Polynomial/Polynomial_type.h index e2529d2e3495..de6bcdc447bd 100644 --- a/Polynomial/include/CGAL/Polynomial/Polynomial_type.h +++ b/Polynomial/include/CGAL/Polynomial/Polynomial_type.h @@ -486,9 +486,9 @@ class Polynomial // and NT would be changed by NTX typedef typename Fraction_traits::Is_fraction Is_fraction; typedef typename Coercion_traits::Type Type; - typedef typename ::boost::mpl::if_c< - ::std::is_same::value, Is_fraction, CGAL::Tag_false - >::type If_decomposable_AND_Type_equals_NT; + typedef std::conditional_t< + std::is_same_v, Is_fraction, CGAL::Tag_false + > If_decomposable_AND_Type_equals_NT; return sign_at_(x,If_decomposable_AND_Type_equals_NT()); } diff --git a/Polynomial/include/CGAL/Polynomial_traits_d.h b/Polynomial/include/CGAL/Polynomial_traits_d.h index 6eb4f0d6e3f2..dfbf7cf31357 100644 --- a/Polynomial/include/CGAL/Polynomial_traits_d.h +++ b/Polynomial/include/CGAL/Polynomial_traits_d.h @@ -999,7 +999,7 @@ class Polynomial_traits_d_base< Polynomial< Coefficient_type_ >, // Sign_at, Sign_at_homogeneous, Compare // define XXX_ even though ICoeff may not be Real_embeddable - // select propoer XXX among XXX_ or Null_functor using ::boost::mpl::if_ + // select propoer XXX among XXX_ or Null_functor using ::std::conditional_t private: struct Sign_at_ { private: @@ -1036,8 +1036,8 @@ class Polynomial_traits_d_base< Polynomial< Coefficient_type_ >, typedef Real_embeddable_traits RET_IC; typedef typename RET_IC::Is_real_embeddable IC_is_real_embeddable; public: - typedef typename ::boost::mpl::if_::type Sign_at; - typedef typename ::boost::mpl::if_::type Sign_at_homogeneous; + typedef std::conditional_t Sign_at; + typedef std::conditional_t Sign_at_homogeneous; typedef typename Real_embeddable_traits::Compare Compare; diff --git a/Property_map/include/CGAL/Dynamic_property_map.h b/Property_map/include/CGAL/Dynamic_property_map.h index a7dc48b5354a..bca414e19b00 100644 --- a/Property_map/include/CGAL/Dynamic_property_map.h +++ b/Property_map/include/CGAL/Dynamic_property_map.h @@ -19,7 +19,6 @@ #include #include -#include #include @@ -127,9 +126,9 @@ struct Dynamic_with_index { typedef Key key_type; typedef Value value_type; - typedef typename boost::mpl::if_< std::is_same, - value_type, - value_type&>::type reference; + typedef std::conditional_t< std::is_same_v, + value_type, + value_type&> reference; typedef boost::read_write_property_map_tag category; Dynamic_with_index() diff --git a/SMDS_3/include/CGAL/Mesh_complex_3_in_triangulation_3.h b/SMDS_3/include/CGAL/Mesh_complex_3_in_triangulation_3.h index f77f1d9c07f3..ef7c6164f2d0 100644 --- a/SMDS_3/include/CGAL/Mesh_complex_3_in_triangulation_3.h +++ b/SMDS_3/include/CGAL/Mesh_complex_3_in_triangulation_3.h @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include diff --git a/STL_Extension/include/CGAL/Compact_container.h b/STL_Extension/include/CGAL/Compact_container.h index 24f7ef91c721..81ff5cf1bce2 100644 --- a/STL_Extension/include/CGAL/Compact_container.h +++ b/STL_Extension/include/CGAL/Compact_container.h @@ -35,8 +35,6 @@ #include #include -#include - // An STL like container with the following properties : // - to achieve compactness, it requires access to a pointer stored in T, // specified by a traits. This pointer is supposed to be 4 bytes aligned @@ -866,10 +864,10 @@ namespace internal { typedef typename DSC::value_type value_type; typedef typename DSC::size_type size_type; typedef typename DSC::difference_type difference_type; - typedef typename boost::mpl::if_c< Const, const value_type*, - value_type*>::type pointer; - typedef typename boost::mpl::if_c< Const, const value_type&, - value_type&>::type reference; + typedef std::conditional_t< Const, const value_type*, + value_type*> pointer; + typedef std::conditional_t< Const, const value_type&, + value_type&> reference; typedef std::bidirectional_iterator_tag iterator_category; // the initialization with nullptr is required by our Handle concept. diff --git a/STL_Extension/include/CGAL/Concurrent_compact_container.h b/STL_Extension/include/CGAL/Concurrent_compact_container.h index 7f18ab80f57e..e6a2a5dbecf1 100644 --- a/STL_Extension/include/CGAL/Concurrent_compact_container.h +++ b/STL_Extension/include/CGAL/Concurrent_compact_container.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012 INRIA Sophia-Antipolis (France). +3// Copyright (c) 2012 INRIA Sophia-Antipolis (France). // All rights reserved. // // This file is part of CGAL (www.cgal.org) @@ -36,8 +36,6 @@ #include #include -#include - namespace CGAL { #define CGAL_GENERATE_MEMBER_DETECTOR(X) \ diff --git a/STL_Extension/include/CGAL/Handle_with_policy.h b/STL_Extension/include/CGAL/Handle_with_policy.h index 5f952a66e15f..528bf8061d10 100644 --- a/STL_Extension/include/CGAL/Handle_with_policy.h +++ b/STL_Extension/include/CGAL/Handle_with_policy.h @@ -21,8 +21,6 @@ #include #include -#include - #include #ifdef CGAL_USE_LEDA @@ -728,10 +726,10 @@ class Handle_with_policy { static Bind bind; // Define type that is used for function matching - typedef typename ::boost::mpl::if_c< + typedef std::conditional_t< is_class_hierarchy, ::CGAL::Tag_true, - ::CGAL::Tag_false >::type + ::CGAL::Tag_false > Class_hierarchy; //! the internal representation, i.e., \c T plus a reference count diff --git a/STL_Extension/include/CGAL/Named_function_parameters.h b/STL_Extension/include/CGAL/Named_function_parameters.h index d0f1648f816e..7558aae88f25 100644 --- a/STL_Extension/include/CGAL/Named_function_parameters.h +++ b/STL_Extension/include/CGAL/Named_function_parameters.h @@ -19,7 +19,6 @@ #include #include -#include #include #include @@ -143,14 +142,14 @@ struct Lookup_named_param_def typedef typename internal_np::Get_param::type NP_type; typedef typename internal_np::Get_param::reference NP_reference; - typedef typename boost::mpl::if_< - std::is_same, - D, NP_type>::type + typedef std::conditional_t< + std::is_same_v, + D, NP_type> type; - typedef typename boost::mpl::if_< - std::is_same, - D&, NP_reference>::type + typedef std::conditional_t< + std::is_same_v, + D&, NP_reference> reference; }; diff --git a/STL_Extension/include/CGAL/transforming_iterator.h b/STL_Extension/include/CGAL/transforming_iterator.h index bd94ad33c4fd..21d88e8f69cf 100644 --- a/STL_Extension/include/CGAL/transforming_iterator.h +++ b/STL_Extension/include/CGAL/transforming_iterator.h @@ -12,7 +12,6 @@ #ifndef CGAL_TRANSFORMING_ITERATOR_H #define CGAL_TRANSFORMING_ITERATOR_H #include -#include #include #include #include @@ -55,10 +54,8 @@ class transforming_iterator_helper typedef typename Default::Get>>::type value_type; // Crappy heuristic. If we have *it that returns a Weighted_point and F that returns a reference to the Point contained in the Weighted_point it takes as argument, we do NOT want the transformed iterator to return a reference to the temporary *it. On the other hand, if *it returns an int n, and F returns a reference to array[n] it is not so good to lose the reference. This probably should be done elsewhere and should at least be made optional... - typedef typename boost::mpl::if_< - boost::mpl::or_, - std::is_integral >, - reference_, value_type>::type reference; + typedef std::conditional_t || std::is_integral_v, + reference_, value_type> reference; public: typedef boost::iterator_adaptor< diff --git a/Skin_surface_3/include/CGAL/Skin_surface_base_3.h b/Skin_surface_3/include/CGAL/Skin_surface_base_3.h index 6962b1ec8f21..528ea1e0e832 100644 --- a/Skin_surface_3/include/CGAL/Skin_surface_base_3.h +++ b/Skin_surface_3/include/CGAL/Skin_surface_base_3.h @@ -42,7 +42,6 @@ #include -#include #include namespace CGAL { diff --git a/Spatial_searching/include/CGAL/Fuzzy_iso_box.h b/Spatial_searching/include/CGAL/Fuzzy_iso_box.h index 0b34898eff93..08cc1da0063c 100644 --- a/Spatial_searching/include/CGAL/Fuzzy_iso_box.h +++ b/Spatial_searching/include/CGAL/Fuzzy_iso_box.h @@ -22,8 +22,6 @@ #include #include -#include - #include diff --git a/Spatial_searching/include/CGAL/Search_traits_adapter.h b/Spatial_searching/include/CGAL/Search_traits_adapter.h index ff640dc639a4..7a518cf68eed 100644 --- a/Spatial_searching/include/CGAL/Search_traits_adapter.h +++ b/Spatial_searching/include/CGAL/Search_traits_adapter.h @@ -224,16 +224,16 @@ class Search_traits_adapter : public Base_traits{ // Select type of iterator + construct class depending on whether // point map is lvalue or not - typedef typename boost::mpl::if_< - std::is_reference::reference>, + typedef std::conditional_t< + std::is_reference_v::reference>, typename Base::Cartesian_const_iterator_d, - No_lvalue_iterator>::type + No_lvalue_iterator> Cartesian_const_iterator_d; - typedef typename boost::mpl::if_< - std::is_reference::reference>, + typedef std::conditional_t< + std::is_reference_v::reference>, Construct_cartesian_const_iterator_d_lvalue, - Construct_cartesian_const_iterator_d_no_lvalue>::type + Construct_cartesian_const_iterator_d_no_lvalue> Construct_cartesian_const_iterator_d; struct Construct_iso_box_d: public Base::Construct_iso_box_d{ diff --git a/Straight_skeleton_2/include/CGAL/Straight_skeleton_2/Straight_skeleton_aux.h b/Straight_skeleton_2/include/CGAL/Straight_skeleton_2/Straight_skeleton_aux.h index a799eccda60b..30b1e25de59a 100644 --- a/Straight_skeleton_2/include/CGAL/Straight_skeleton_2/Straight_skeleton_aux.h +++ b/Straight_skeleton_2/include/CGAL/Straight_skeleton_2/Straight_skeleton_aux.h @@ -20,7 +20,6 @@ #include #include -#include #include #include @@ -36,12 +35,10 @@ struct Has_inexact_constructions { typedef typename K::FT FT ; - typedef typename boost::mpl::if_< boost::mpl::or_< std::is_same - , std::is_same - > - , Tag_true - , Tag_false - >::type type ; + typedef std::conditional_t< std::is_same_v || std::is_same_v + , Tag_true + , Tag_false + > type ; } ; template diff --git a/Triangulation_2/include/CGAL/Constrained_triangulation_2.h b/Triangulation_2/include/CGAL/Constrained_triangulation_2.h index 4ce20796d1ab..02b050f790ad 100644 --- a/Triangulation_2/include/CGAL/Constrained_triangulation_2.h +++ b/Triangulation_2/include/CGAL/Constrained_triangulation_2.h @@ -34,7 +34,6 @@ #include #include -#include #include #include @@ -96,9 +95,9 @@ namespace internal { template struct Itag { - typedef typename boost::mpl::if_::Is_exact, + typedef std::conditional_t<(typename Algebraic_structure_traits::Is_exact)::value, Exact_intersections_tag, - Exact_predicates_tag>::type type; + Exact_predicates_tag> type; }; } // namespace internal diff --git a/Triangulation_2/include/CGAL/Regular_triangulation_2.h b/Triangulation_2/include/CGAL/Regular_triangulation_2.h index f7e4a653060b..c3ab2223a0ad 100644 --- a/Triangulation_2/include/CGAL/Regular_triangulation_2.h +++ b/Triangulation_2/include/CGAL/Regular_triangulation_2.h @@ -23,7 +23,6 @@ #include #include -#include #include #include diff --git a/Triangulation_2/include/CGAL/Triangulation_hierarchy_2.h b/Triangulation_2/include/CGAL/Triangulation_hierarchy_2.h index 93e00b1680ff..295132483846 100644 --- a/Triangulation_2/include/CGAL/Triangulation_hierarchy_2.h +++ b/Triangulation_2/include/CGAL/Triangulation_hierarchy_2.h @@ -26,7 +26,6 @@ #include #include -#include #include #include #include diff --git a/Triangulation_3/include/CGAL/Regular_triangulation_3.h b/Triangulation_3/include/CGAL/Regular_triangulation_3.h index aa58c124ed1f..7795840a2e6d 100644 --- a/Triangulation_3/include/CGAL/Regular_triangulation_3.h +++ b/Triangulation_3/include/CGAL/Regular_triangulation_3.h @@ -54,7 +54,6 @@ #include #endif -#include #include #include #include diff --git a/Triangulation_3/include/CGAL/Regular_triangulation_cell_base_with_weighted_circumcenter_3.h b/Triangulation_3/include/CGAL/Regular_triangulation_cell_base_with_weighted_circumcenter_3.h index 3a73305b380e..f2c945342e8e 100644 --- a/Triangulation_3/include/CGAL/Regular_triangulation_cell_base_with_weighted_circumcenter_3.h +++ b/Triangulation_3/include/CGAL/Regular_triangulation_cell_base_with_weighted_circumcenter_3.h @@ -22,7 +22,6 @@ #include #include -#include #include namespace CGAL { diff --git a/Triangulation_3/include/CGAL/Triangulation_3.h b/Triangulation_3/include/CGAL/Triangulation_3.h index 7b8ef9ab6c8a..fd4b530c7a88 100644 --- a/Triangulation_3/include/CGAL/Triangulation_3.h +++ b/Triangulation_3/include/CGAL/Triangulation_3.h @@ -48,7 +48,6 @@ #include #include #include -#include #include #include #include diff --git a/Triangulation_3/include/CGAL/Triangulation_hierarchy_3.h b/Triangulation_3/include/CGAL/Triangulation_hierarchy_3.h index 021e40e2ffef..c852a4bed75c 100644 --- a/Triangulation_3/include/CGAL/Triangulation_hierarchy_3.h +++ b/Triangulation_3/include/CGAL/Triangulation_hierarchy_3.h @@ -48,7 +48,6 @@ #include #include #include -#include #include #include diff --git a/Triangulation_3/test/Triangulation_3/include/CGAL/_test_cls_delaunay_3.h b/Triangulation_3/test/Triangulation_3/include/CGAL/_test_cls_delaunay_3.h index 78b8822f5984..01f08ac186ce 100644 --- a/Triangulation_3/test/Triangulation_3/include/CGAL/_test_cls_delaunay_3.h +++ b/Triangulation_3/test/Triangulation_3/include/CGAL/_test_cls_delaunay_3.h @@ -25,7 +25,6 @@ #include #include -#include #include #include diff --git a/Triangulation_3/test/Triangulation_3/include/CGAL/_test_cls_parallel_triangulation_3.h b/Triangulation_3/test/Triangulation_3/include/CGAL/_test_cls_parallel_triangulation_3.h index e93418c19cf1..20c4351bc498 100644 --- a/Triangulation_3/test/Triangulation_3/include/CGAL/_test_cls_parallel_triangulation_3.h +++ b/Triangulation_3/test/Triangulation_3/include/CGAL/_test_cls_parallel_triangulation_3.h @@ -16,7 +16,6 @@ #include #include -#include template diff --git a/Triangulation_3/test/Triangulation_3/test_regular_insert_range_with_info.cpp b/Triangulation_3/test/Triangulation_3/test_regular_insert_range_with_info.cpp index e4f80d9149f0..c1b00d9aca9b 100644 --- a/Triangulation_3/test/Triangulation_3/test_regular_insert_range_with_info.cpp +++ b/Triangulation_3/test/Triangulation_3/test_regular_insert_range_with_info.cpp @@ -37,9 +37,9 @@ struct Tester void test_iterator_on_pair() const { typedef std::vector > Container; - typedef typename boost::mpl::if_, - std::add_const_t, - Container>::type Cast_type; + typedef std::conditional_t, + Container> Cast_type; Container points; points.push_back(std::make_pair(Weighted_point(Bare_point(0.160385, 0.599679, 0.374932), -0.118572), 0)); @@ -90,9 +90,9 @@ struct Tester void test_zip_iterator() const { typedef std::vector Container; - typedef typename boost::mpl::if_, - std::add_const_t, - Container >::type Cast_type; + typedef std::conditional_t, + Container > Cast_type; Container points; points.push_back(Weighted_point(Bare_point(0,0,0),1)); @@ -156,9 +156,9 @@ struct Tester void test_transform_iterator() const { typedef std::vector< Weighted_point > Container; - typedef typename boost::mpl::if_, - std::add_const_t, - Container >::type Cast_type; + typedef std::conditional_t, + Container > Cast_type; Container points; points.push_back(Weighted_point(Bare_point(0,0,0),1)); From c82f2a9d9c2c082f477b7d5e2af7f57e319e3acf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 27 Sep 2023 10:11:31 +0200 Subject: [PATCH 106/329] Update some variable names to reflect the genericity of the triangulation --- .../CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 9 +-- .../internal/gate_priority_queue.h | 16 ++--- .../Alpha_wrap_3/internal/geometry_utils.h | 62 +++++++++---------- 3 files changed, 44 insertions(+), 43 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index f2ad170c95e7..8f7b1f5efc9c 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -290,7 +290,7 @@ class Alpha_wrap_3 extract_surface(output_mesh, ovpm, true /*tolerate non manifoldness*/); #ifdef CGAL_AW3_DEBUG_DUMP_EVERY_STEP - dump_triangulation_faces("intermediate_dt3.off", false /*only_boundary_faces*/); + dump_triangulation_faces("intermediate_tr.off", false /*only_boundary_faces*/); IO::write_polygon_mesh("intermediate.off", output_mesh, CGAL::parameters::vertex_point_map(ovpm).stream_precision(17)); #endif @@ -350,7 +350,7 @@ class Alpha_wrap_3 #ifdef CGAL_AW3_DEBUG_DUMP_EVERY_STEP IO::write_polygon_mesh("final.off", output_mesh, CGAL::parameters::stream_precision(17)); - dump_triangulation_faces("final_dt3.off", false /*only_boundary_faces*/); + dump_triangulation_faces("final_tr.off", false /*only_boundary_faces*/); #endif #endif @@ -643,7 +643,9 @@ class Alpha_wrap_3 // and we fill the queue with the new parameters. bool initialize_from_existing_triangulation() { - std::cout << "restart from a DT of " << m_tr.number_of_cells() << " cells" << std::endl; +#ifdef CGAL_AW3_DEBUG_INITIALIZATION + std::cout << "Restart from a DT of " << m_tr.number_of_cells() << " cells" << std::endl; +#endif Real_timer t; t.start(); @@ -1050,7 +1052,6 @@ class Alpha_wrap_3 public: // @speed some decent time may be spent constructing Facet (pairs) for no reason as it's always // just to grab the .first and .second as soon as it's constructed, and not due to API requirements - // e.g. from DT3 Facet_queue_status facet_status(const Facet& f) const { CGAL_precondition(!m_tr.is_infinite(f)); diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/gate_priority_queue.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/gate_priority_queue.h index 824d27bc2c10..5e14a4d08ea1 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/gate_priority_queue.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/gate_priority_queue.h @@ -28,11 +28,11 @@ namespace Alpha_wraps_3 { namespace internal { // Represents an alpha-traversable facet in the mutable priority queue -template +template class Gate { - using Facet = typename DT3::Facet; - using FT = typename DT3::Geom_traits::FT; + using Facet = typename Tr::Facet; + using FT = typename Tr::Geom_traits::FT; private: Facet m_facet; @@ -65,24 +65,24 @@ class Gate struct Less_gate { - template - bool operator()(const Gate& a, const Gate& b) const + template + bool operator()(const Gate& a, const Gate& b) const { return a.priority() > b.priority(); } }; -template +template struct Gate_ID_PM { - using key_type = Gate; + using key_type = Gate; using value_type = std::size_t; using reference = std::size_t; using category = boost::readable_property_map_tag; inline friend value_type get(Gate_ID_PM, const key_type& k) { - using Facet = typename DT3::Facet; + using Facet = typename Tr::Facet; const Facet& f = k.facet(); return (4 * f.first->time_stamp() + f.second); diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/geometry_utils.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/geometry_utils.h index d3814d0f3b25..7d66cfd19f41 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/geometry_utils.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/geometry_utils.h @@ -40,16 +40,16 @@ struct Orientation_of_circumcenter } }; -template +template bool -less_squared_radius_of_min_empty_sphere(typename Dt::Geom_traits::FT sq_alpha, - const typename Dt::Facet& fh, - const Dt& dt) +less_squared_radius_of_min_empty_sphere(typename Tr::Geom_traits::FT sq_alpha, + const typename Tr::Facet& fh, + const Tr& tr) { - using Cell_handle = typename Dt::Cell_handle; - using Point = typename Dt::Point; + using Cell_handle = typename Tr::Cell_handle; + using Point = typename Tr::Point; - using CK = typename Dt::Geom_traits; + using CK = typename Tr::Geom_traits; using Exact_kernel = typename Exact_kernel_selector::Exact_kernel; using Approximate_kernel = Simple_cartesian; using C2A = Cartesian_converter; @@ -65,17 +65,17 @@ less_squared_radius_of_min_empty_sphere(typename Dt::Geom_traits::FT sq_alpha, const int ic = fh.second; const Cell_handle n = c->neighbor(ic); - const Point& p1 = dt.point(c, Dt::vertex_triple_index(ic,0)); - const Point& p2 = dt.point(c, Dt::vertex_triple_index(ic,1)); - const Point& p3 = dt.point(c, Dt::vertex_triple_index(ic,2)); + const Point& p1 = tr.point(c, Tr::vertex_triple_index(ic,0)); + const Point& p2 = tr.point(c, Tr::vertex_triple_index(ic,1)); + const Point& p3 = tr.point(c, Tr::vertex_triple_index(ic,2)); // This is not actually possible in the context of alpha wrapping, but keeping it for genericity // and because it does not cost anything. - if(dt.is_infinite(n)) + if(tr.is_infinite(n)) { Orientation ori = orientation_of_circumcenter(p1, p2, p3, - dt.point(c, 0), dt.point(c, 1), - dt.point(c, 2), dt.point(c, 3)); + tr.point(c, 0), tr.point(c, 1), + tr.point(c, 2), tr.point(c, 3)); if(ori == POSITIVE) { @@ -84,18 +84,18 @@ less_squared_radius_of_min_empty_sphere(typename Dt::Geom_traits::FT sq_alpha, } else { - Comparison_result cr = compare_squared_radius(dt.point(c, 0), dt.point(c, 1), - dt.point(c, 2), dt.point(c, 3), + Comparison_result cr = compare_squared_radius(tr.point(c, 0), tr.point(c, 1), + tr.point(c, 2), tr.point(c, 3), sq_alpha); return cr == LARGER; } } - if(dt.is_infinite(c)) + if(tr.is_infinite(c)) { Orientation ori = orientation_of_circumcenter(p1, p2, p3, - dt.point(n, 0), dt.point(n, 1), - dt.point(n, 2), dt.point(n, 3)); + tr.point(n, 0), tr.point(n, 1), + tr.point(n, 2), tr.point(n, 3)); if(ori == NEGATIVE) { @@ -104,8 +104,8 @@ less_squared_radius_of_min_empty_sphere(typename Dt::Geom_traits::FT sq_alpha, } else { - Comparison_result cr = compare_squared_radius(dt.point(n, 0), dt.point(n, 1), - dt.point(n, 2), dt.point(n, 3), + Comparison_result cr = compare_squared_radius(tr.point(n, 0), tr.point(n, 1), + tr.point(n, 2), tr.point(n, 3), sq_alpha); return cr == LARGER; } @@ -113,40 +113,40 @@ less_squared_radius_of_min_empty_sphere(typename Dt::Geom_traits::FT sq_alpha, // both c and n are finite if(orientation_of_circumcenter(p1, p2, p3, - dt.point(c, 0), dt.point(c, 1), dt.point(c, 2), dt.point(c, 3)) != + tr.point(c, 0), tr.point(c, 1), tr.point(c, 2), tr.point(c, 3)) != orientation_of_circumcenter(p1, p2, p3, - dt.point(n, 0), dt.point(n, 1), dt.point(n, 2), dt.point(n, 3))) + tr.point(n, 0), tr.point(n, 1), tr.point(n, 2), tr.point(n, 3))) { Comparison_result cr = compare_squared_radius(p1, p2, p3, sq_alpha); #ifdef CGAL_AW3_DEBUG_TRAVERSABILITY std::cout << "dual crosses the face; CR: " - << typename Dt::Geom_traits().compute_squared_radius_3_object()(p1, p2, p3) + << typename Tr::Geom_traits().compute_squared_radius_3_object()(p1, p2, p3) << " sq alpha " << sq_alpha << std::endl; #endif return cr == LARGER; } else { - Comparison_result cr = compare_squared_radius(dt.point(c, 0), dt.point(c, 1), - dt.point(c, 2), dt.point(c, 3), + Comparison_result cr = compare_squared_radius(tr.point(c, 0), tr.point(c, 1), + tr.point(c, 2), tr.point(c, 3), sq_alpha); #ifdef CGAL_AW3_DEBUG_TRAVERSABILITY std::cout << "dual does not cross the face; CR(c): " - << typename Dt::Geom_traits().compute_squared_radius_3_object()(dt.point(c, 0), dt.point(c, 1), - dt.point(c, 2), dt.point(c, 3)) + << typename Tr::Geom_traits().compute_squared_radius_3_object()(tr.point(c, 0), tr.point(c, 1), + tr.point(c, 2), tr.point(c, 3)) << " sq alpha " << sq_alpha << std::endl; #endif if(cr != LARGER) return false; - cr = compare_squared_radius(dt.point(n, 0), dt.point(n, 1), - dt.point(n, 2), dt.point(n, 3), + cr = compare_squared_radius(tr.point(n, 0), tr.point(n, 1), + tr.point(n, 2), tr.point(n, 3), sq_alpha); #ifdef CGAL_AW3_DEBUG_TRAVERSABILITY std::cout << "dual does not cross the face; CR(n): " - << typename Dt::Geom_traits().compute_squared_radius_3_object()(dt.point(n, 0), dt.point(n, 1), - dt.point(n, 2), dt.point(n, 3)) + << typename Tr::Geom_traits().compute_squared_radius_3_object()(tr.point(n, 0), tr.point(n, 1), + tr.point(n, 2), tr.point(n, 3)) << " sq alpha " << sq_alpha << std::endl; #endif From 62bb2a58d098dc08076f2165d104670dfa65388a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 27 Sep 2023 10:13:39 +0200 Subject: [PATCH 107/329] Put the warnings outside of verbosity macros (too important) --- .../CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index 8f7b1f5efc9c..3ee6061d0d89 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -1173,15 +1173,11 @@ class Alpha_wrap_3 return false; } - if(resuming) - { - if(offset != m_offset) - { -#ifdef CGAL_AW3_DEBUG - std::cerr << "Warning: resuming with a different offset!" << std::endl; -#endif - } - } + if(resuming && alpha > m_alpha) + std::cerr << "Warning: resuming with an alpha greater than last iteration!" << std::endl; + + if(resuming && offset != m_offset) + std::cerr << "Warning: resuming with a different offset!" << std::endl; m_alpha = FT(alpha); m_sq_alpha = square(m_alpha); From bc8351f15678b90955a9d5c2a5cc4b0389b49642 Mon Sep 17 00:00:00 2001 From: Mael Date: Wed, 27 Sep 2023 11:06:49 +0200 Subject: [PATCH 108/329] Fix typo --- Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index 6d544be058d6..639c9a3f4685 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -1418,7 +1418,7 @@ class Alpha_wrap_3 squared_distance(m_dt.point(c, 0), m_dt.point(c, 2)), squared_distance(m_dt.point(c, 0), m_dt.point(c, 3)), squared_distance(m_dt.point(c, 1), m_dt.point(c, 2)), - squared_distance(m_dt.point(c, 3), m_dt.point(c, 3)), + squared_distance(m_dt.point(c, 1), m_dt.point(c, 3)), squared_distance(m_dt.point(c, 2), m_dt.point(c, 3)) }); }; From 00f167a8357ab5fe72fb22e0a547c5543f8f1d0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 29 Sep 2023 11:02:47 +0200 Subject: [PATCH 109/329] Add benchmarking scripts --- .../benchmark/Alpha_wrap_3/CMakeLists.txt | 15 + .../compute_performance_benchmark_data.py | 61 ++++ .../generate_performance_benchmark_charts.py | 156 ++++++++++ .../Performance/performance_benchmark.cpp | 65 +++++ .../Quality/compute_quality_benchmark_data.py | 54 ++++ .../Alpha_wrap_3/Quality/distance_utils.h | 151 ++++++++++ .../generate_quality_benchmark_charts.py | 182 ++++++++++++ .../Quality/quality_benchmark.cpp | 271 ++++++++++++++++++ .../compute_robustness_benchmark_data.py | 96 +++++++ .../generate_robustness_benchmark_charts.py | 154 ++++++++++ .../Robustness/robustness_benchmark.cpp | 106 +++++++ .../benchmark/Alpha_wrap_3/benchmarking.sh | 86 ++++++ .../CGAL/Alpha_wrap_3/internal/validation.h} | 0 .../test_AW3_cavity_initializations.cpp | 2 +- .../Alpha_wrap_3/test_AW3_manifoldness.cpp | 2 +- .../Alpha_wrap_3/test_AW3_multiple_calls.cpp | 2 +- .../Alpha_wrap_3/test_alpha_wrap_3_mesh.cpp | 2 +- 17 files changed, 1401 insertions(+), 4 deletions(-) create mode 100644 Alpha_wrap_3/benchmark/Alpha_wrap_3/CMakeLists.txt create mode 100644 Alpha_wrap_3/benchmark/Alpha_wrap_3/Performance/compute_performance_benchmark_data.py create mode 100644 Alpha_wrap_3/benchmark/Alpha_wrap_3/Performance/generate_performance_benchmark_charts.py create mode 100644 Alpha_wrap_3/benchmark/Alpha_wrap_3/Performance/performance_benchmark.cpp create mode 100644 Alpha_wrap_3/benchmark/Alpha_wrap_3/Quality/compute_quality_benchmark_data.py create mode 100644 Alpha_wrap_3/benchmark/Alpha_wrap_3/Quality/distance_utils.h create mode 100644 Alpha_wrap_3/benchmark/Alpha_wrap_3/Quality/generate_quality_benchmark_charts.py create mode 100644 Alpha_wrap_3/benchmark/Alpha_wrap_3/Quality/quality_benchmark.cpp create mode 100755 Alpha_wrap_3/benchmark/Alpha_wrap_3/Robustness/compute_robustness_benchmark_data.py create mode 100644 Alpha_wrap_3/benchmark/Alpha_wrap_3/Robustness/generate_robustness_benchmark_charts.py create mode 100644 Alpha_wrap_3/benchmark/Alpha_wrap_3/Robustness/robustness_benchmark.cpp create mode 100755 Alpha_wrap_3/benchmark/Alpha_wrap_3/benchmarking.sh rename Alpha_wrap_3/{test/Alpha_wrap_3/alpha_wrap_validation.h => include/CGAL/Alpha_wrap_3/internal/validation.h} (100%) diff --git a/Alpha_wrap_3/benchmark/Alpha_wrap_3/CMakeLists.txt b/Alpha_wrap_3/benchmark/Alpha_wrap_3/CMakeLists.txt new file mode 100644 index 000000000000..a9aa0d1d63cb --- /dev/null +++ b/Alpha_wrap_3/benchmark/Alpha_wrap_3/CMakeLists.txt @@ -0,0 +1,15 @@ +# Created by the script cgal_create_cmake_script +# This is the CMake script for compiling a CGAL application. + +cmake_minimum_required(VERSION 3.1...3.20) +project(Alpha_wrap_3_Benchmark) + +find_package(CGAL REQUIRED) + +include_directories (BEFORE ../../include ./Quality ./Robustness) # AW3 includes +include_directories (BEFORE ../../../CGAL-Patches/include) + +# create a target per cppfile +create_single_source_cgal_program("Performance/performance_benchmark.cpp") +create_single_source_cgal_program("Quality/quality_benchmark.cpp") +create_single_source_cgal_program("Robustness/robustness_benchmark.cpp") diff --git a/Alpha_wrap_3/benchmark/Alpha_wrap_3/Performance/compute_performance_benchmark_data.py b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Performance/compute_performance_benchmark_data.py new file mode 100644 index 000000000000..86c57d351465 --- /dev/null +++ b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Performance/compute_performance_benchmark_data.py @@ -0,0 +1,61 @@ +# Copyright (c) 2019-2023 Google LLC (USA). +# All rights reserved. +# +# This file is part of CGAL (www.cgal.org). +# +# $URL$ +# $Id$ +# SPDX-License-Identifier: GPL-3.0-or-later +# +# +# Author(s) : Pierre Alliez +# Michael Hemmer +# Cedric Portaneri +# +#!/usr/bin/python + +import os, sys, subprocess, datetime, time, getopt + +def compute_performance_benchmark_data(execname, filename, alpha): + + output = "" + cmd = ("/usr/bin/time", "-v", + execname, "-i", + filename, "-a", alpha) + proc = subprocess.Popen( + cmd, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + start_new_session=True) + + outs, errs = proc.communicate() + output = outs.decode("utf-8") + errs.decode("utf-8") + + for output_line in output.split("\n"): + if "User time (seconds): " in output_line: + print(output_line[len("User time (seconds): "):]) + continue + if "Maximum resident set size (kbytes): " in output_line: + print(output_line[len("Maximum resident set size (kbytes): "):]) + continue + +def main(argv): + execname="" + filename="" + alpha="" + try: + opts, args = getopt.getopt(sys.argv[1:], 'e:i:a:') + except getopt.GetoptError: + sys.exit(2) + for opt, arg in opts: + if opt == "-e": + execname = arg + elif opt == "-i": + filename = arg + elif opt == "-a": + alpha = arg + + compute_performance_benchmark_data(execname, filename, alpha) + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/Alpha_wrap_3/benchmark/Alpha_wrap_3/Performance/generate_performance_benchmark_charts.py b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Performance/generate_performance_benchmark_charts.py new file mode 100644 index 000000000000..445b69232778 --- /dev/null +++ b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Performance/generate_performance_benchmark_charts.py @@ -0,0 +1,156 @@ +# Copyright (c) 2019-2023 Google LLC (USA). +# All rights reserved. +# +# This file is part of CGAL (www.cgal.org). +# +# $URL$ +# $Id$ +# SPDX-License-Identifier: GPL-3.0-or-later +# +# +# Author(s) : Pierre Alliez +# Michael Hemmer +# Cedric Portaneri +# +#!/usr/bin/python + +import os, sys, subprocess, datetime, time, signal, getopt +import numpy as np +import matplotlib.pyplot as plt + +def main(argv): + + inputdir="" + outputdir="" + commit_hash="" + alpha="" + do_diff=False + diffdir="" + diff_hash="" + try: + opts, args = getopt.getopt(sys.argv[1:], 'i:a:o:c:d:p:') + except getopt.GetoptError: + sys.exit(2) + for opt, arg in opts: + if opt == "-i": + inputdir = arg + elif opt == "-a": + alpha = arg + elif opt == "-o": + outputdir = arg + elif opt == "-c": + commit_hash = arg + elif opt == "-d": + diff_hash = arg + do_diff = True + elif opt == "-p": + diffdir = arg + + all_metric = { + "Time_(second)" : {}, + "Memory_Peak_(kbytes)" : {}} + num_input = 0 + for filename in os.listdir(inputdir) : + new_path = os.path.join(inputdir,filename) + new_file = open(new_path) + is_empty_new = os.path.getsize(new_path) <= 1 + if do_diff : + old_path = os.path.join(diffdir,filename) + old_file = open(old_path) + is_empty_old = os.path.getsize(old_path) <= 1 + for key in all_metric: + if is_empty_new or is_empty_old : + new_val = 0. + old_val = 0. + else : + new_val = float(new_file.readline().rstrip('\n')) + old_val = float(old_file.readline().rstrip('\n')) + mesh_id = str(filename.split('.')[0]) + all_metric[key][mesh_id] = [new_val, old_val] + else : + for key in all_metric: + if is_empty_new : + new_val = 0. + else : + new_val = float(new_file.readline().rstrip('\n')) + mesh_id = str(filename.split('.')[0]) + all_metric[key][mesh_id] = [new_val, new_val] + num_input = num_input+1 + + # update .pdf chart + date_now = datetime.datetime.now() + date_for_filename = str(date_now.year) +"_"+ str(date_now.month) +"_"+ str(date_now.day) +"_"+ str(date_now.hour) +"h"+ str(date_now.minute) +"mn" + for key in all_metric: + goal = 0 + num_el = range(len(all_metric[key])) + avg_diff_to_goal = 0. + avg = 0. + x1 = [] + x2 = [] + for value in all_metric[key].values() : + avg += value[0] + diff_to_goal = abs(value[1]-goal) - abs(value[0]-goal) + avg_diff_to_goal += diff_to_goal + x1.append(value[0]) + x2.append(value[1]) + avg_diff_to_goal /= float(len(all_metric[key])) + avg /= float(len(all_metric[key])) + + plt.figure(figsize=(8,8)) + if do_diff : + plt.hist(x2, bins=100, color='tab:green', alpha=0.5) + plt.hist(x1, bins=100, color='tab:blue', alpha=0.5) + plt.vlines(x = goal, ymin=plt.ylim()[0], ymax=plt.ylim()[1], linestyles='dashed') + + title = "" + if do_diff : + title += "Diff between " + commit_hash + " and " + diff_hash + " on " + str(num_input) + " meshes from Thingi10K\nAlpha = Bbox diag length / " + alpha + else : + title += "Benchmarking on " + str(num_input) + " meshes from Thingi10K\nAlpha = Bbox diag length / " + alpha + + avg_str = str(format(abs(avg), '.2f')) + if key == "Time_(second)" : + title += "\nIn average we spend " + avg_str + " seconds" + else : + title += "\nIn average we use up to " + avg_str + " kbytes" + + if do_diff and avg_diff_to_goal == 0. : + title += "\nNo change between the two commits" + elif do_diff : + avg_diff_str = str(format(abs(avg_diff_to_goal), '.2f')) + if key == "Time_(second)" : + if avg_diff_to_goal < 0 : + title += "\nIn average we get slower by " + else : + title += "\nIn average we get faster " + title += avg_diff_str + " seconds" + else : + if avg_diff_to_goal < 0 : + title += "\nIn average we use " + avg_diff_str + " more" + else : + title += "\nIn average we use " + avg_diff_str + " less" + title += " kbytes" + + plt.title(title, fontsize=15) + plt.xlabel(key.replace("_"," "), fontsize=14) + plt.ylabel("# of meshes", fontsize=14) + plt.tick_params(axis="x", labelsize=9) + plt.tick_params(axis="y", labelsize=9) + + chart_filename = "" + if do_diff : + chart_filename += "diff_"+commit_hash+"_"+diff_hash+"_"+key+"_"+date_for_filename+".pdf" + else : + chart_filename += "results_"+commit_hash+"_"+key+"_"+date_for_filename+".pdf" + chart_path = os.path.join(outputdir+"/charts",chart_filename) + if os.path.isfile(chart_path) : + os.remove(chart_path) + plt.savefig(chart_path, bbox_inches="tight") + plt.close() + + print("pdf updated") + + sys.exit() + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/Alpha_wrap_3/benchmark/Alpha_wrap_3/Performance/performance_benchmark.cpp b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Performance/performance_benchmark.cpp new file mode 100644 index 000000000000..207b4704635a --- /dev/null +++ b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Performance/performance_benchmark.cpp @@ -0,0 +1,65 @@ +#include +#include + +#include + +#include + +#include +#include +#include +#include + +using K = CGAL::Exact_predicates_inexact_constructions_kernel; +using Point_3 = K::Point_3; +using Vector_3 = K::Vector_3; + +using Mesh = CGAL::Surface_mesh; + +namespace PMP = CGAL::Polygon_mesh_processing; + +int main(int argc, char** argv) +{ + const int argc_check = argc - 1; + const char* entry_name_ptr = nullptr; + double relative_alpha_ratio = 20., relative_offset_ratio = 600.; + + for(int i=1; i points; + std::vector > faces; + if(!CGAL::IO::read_polygon_soup(entry_name_ptr, points, faces) || faces.empty()) + { + std::cerr << "Error: Invalid input data." << std::endl; + return EXIT_FAILURE; + } + + CGAL::Bbox_3 bbox; + for(const Point_3& p : points) + bbox += p.bbox(); + + const double diag_length = std::sqrt(CGAL::square(bbox.xmax() - bbox.xmin()) + + CGAL::square(bbox.ymax() - bbox.ymin()) + + CGAL::square(bbox.zmax() - bbox.zmin())); + const double alpha = diag_length / relative_alpha_ratio; + const double offset = diag_length / relative_offset_ratio; + + Mesh wrap; + CGAL::alpha_wrap_3(points, faces, alpha, offset, wrap); + + return EXIT_SUCCESS; +} diff --git a/Alpha_wrap_3/benchmark/Alpha_wrap_3/Quality/compute_quality_benchmark_data.py b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Quality/compute_quality_benchmark_data.py new file mode 100644 index 000000000000..3b996cb57490 --- /dev/null +++ b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Quality/compute_quality_benchmark_data.py @@ -0,0 +1,54 @@ +# Copyright (c) 2019-2023 Google LLC (USA). +# All rights reserved. +# +# This file is part of CGAL (www.cgal.org). +# +# $URL$ +# $Id$ +# SPDX-License-Identifier: GPL-3.0-or-later +# +# +# Author(s) : Pierre Alliez +# Michael Hemmer +# Cedric Portaneri +# +#!/usr/bin/python + +import os, sys, subprocess, datetime, time, getopt + +def compute_quality_benchmark_data(execname, filename, alpha): + + output = "" + cmd = (execname, "-i", + filename, "-a", alpha) + proc = subprocess.Popen( + cmd, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + start_new_session=True) + + outs, errs = proc.communicate() + output = outs.decode("utf-8") + errs.decode("utf-8") + + print(output) + +def main(argv): + execname="" + filename="" + alpha="" + try: + opts, args = getopt.getopt(sys.argv[1:], 'e:i:a:') + except getopt.GetoptError: + sys.exit(2) + for opt, arg in opts: + if opt == "-e": + execname = arg + elif opt == "-i": + filename = arg + elif opt == "-a": + alpha = arg + + compute_quality_benchmark_data(execname, filename, alpha) + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/Alpha_wrap_3/benchmark/Alpha_wrap_3/Quality/distance_utils.h b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Quality/distance_utils.h new file mode 100644 index 000000000000..379573e9c90a --- /dev/null +++ b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Quality/distance_utils.h @@ -0,0 +1,151 @@ +// Copyright (c) 2019-2022 Google LLC (USA). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// Author(s) : Pierre Alliez +// Michael Hemmer +// Cedric Portaneri + +#ifndef CGAL_ALPHA_WRAP_3_BENCHMARK_ALPHA_WRAP_3_QUALITY_DISTANCE_H_ +#define CGAL_ALPHA_WRAP_3_BENCHMARK_ALPHA_WRAP_3_QUALITY_DISTANCE_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Aw3i { + +enum Distance_metric { HAUSDORFF = 0, MEAN = 1, RMS = 2 }; + +template +inline double approximate_hausdorff_distance(const std::vector& sample_points, + const AABBTree& tree, + Point& hint) +{ + double hdist = 0; + for(const Point& pt : sample_points) + { + hint = tree.closest_point(pt, hint); + auto dist = CGAL::squared_distance(hint, pt); + double d = CGAL::to_double(CGAL::approximate_sqrt(dist)); + if(d > hdist) + hdist = d; + } + + return hdist; +} + +template +inline double approximate_mean_distance(const std::vector& sample_points, + const AABBTree& tree, + Point& hint) +{ + double mdist = 0; + for(const Point& pt : sample_points) + { + hint = tree.closest_point(pt, hint); + auto dist = CGAL::squared_distance(hint, pt); + double d = CGAL::to_double(CGAL::approximate_sqrt(dist)); + mdist += d; + } + + return mdist / sample_points.size(); +} + +template +inline double approximate_rms_distance(const std::vector& sample_points, + const AABBTree& tree, + Point& hint) +{ + double rmsdist = 0; + for(const Point& pt : sample_points) + { + hint = tree.closest_point(pt, hint); + auto dist = CGAL::squared_distance(hint, pt); + rmsdist += CGAL::to_double(dist); + } + + return CGAL::to_double(CGAL::approximate_sqrt(rmsdist / sample_points.size())); +} + +template +inline double approximate_distance(const TriangleMesh& tm1, + const TriangleMesh& tm2, + const Distance_metric& metric) +{ + using GT = typename CGAL::GetGeomTraits::type; + using Point_3 = typename GT::Point_3; + + using Primitive = CGAL::AABB_face_graph_triangle_primitive; + using AABB_traits = CGAL::AABB_traits; + using AABB_tree = CGAL::AABB_tree; + + using CGAL::parameters::choose_parameter; + using CGAL::parameters::get_parameter; + + std::vector original_sample_points; + CGAL::Polygon_mesh_processing::sample_triangle_mesh(tm1, std::back_inserter(original_sample_points), + CGAL::parameters::all_default()); + + std::vector sample_points(std::begin(original_sample_points), + std::end(original_sample_points)); + CGAL::spatial_sort(sample_points.begin(), sample_points.end()); + + AABB_tree tree(faces(tm2).first, faces(tm2).second, tm2); + tree.build(); + + auto vpm_2 = get(CGAL::vertex_point, tm2); + Point_3 hint = get(vpm_2, *vertices(tm2).first); + + if(metric == HAUSDORFF) + return approximate_hausdorff_distance(sample_points, tree, hint); + else if(metric == MEAN) + return approximate_mean_distance(sample_points, tree, hint); + else if(metric == RMS) + return approximate_rms_distance(sample_points, tree, hint); + else + std::cerr << "Metric unknown\n" << std::endl; + + return -1.0; +} + +template +double get_longest_diag_bbox(const TriangleMesh& tm) +{ + CGAL::Bbox_3 bbox = CGAL::Polygon_mesh_processing::bbox(tm); + return std::sqrt(CGAL::square(bbox.xmax() - bbox.xmin()) + + CGAL::square(bbox.ymax() - bbox.ymin()) + + CGAL::square(bbox.zmax() - bbox.zmin())); +} + +template +inline double approximate_distance_relative_to_bbox(const TriangleMesh& tm1, + const TriangleMesh& tm2, + const Distance_metric& metric) +{ + double longest_diag_length = get_longest_diag_bbox(tm1); + return approximate_distance(tm1, tm2, metric) / longest_diag_length; +} + +template +inline double approximate_distance_relative_to_bbox(const TriangleMesh& tm1, + const TriangleMesh& tm2, + const Distance_metric& metric, + const FT& longest_diag_length) +{ + return approximate_distance(tm1, tm2, metric) / CGAL::to_double(longest_diag_length); +} + +} // namespace Aw3i + +#endif // CGAL_CGAL_ALPHA_WRAP_3_BENCHMARK_ALPHA_WRAP_3_QUALITY_DISTANCE_H_ diff --git a/Alpha_wrap_3/benchmark/Alpha_wrap_3/Quality/generate_quality_benchmark_charts.py b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Quality/generate_quality_benchmark_charts.py new file mode 100644 index 000000000000..0df5ed5e0f4e --- /dev/null +++ b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Quality/generate_quality_benchmark_charts.py @@ -0,0 +1,182 @@ +# Copyright (c) 2019-2023 Google LLC (USA). +# All rights reserved. +# +# This file is part of CGAL (www.cgal.org). +# +# $URL$ +# $Id$ +# SPDX-License-Identifier: GPL-3.0-or-later +# +# +# Author(s) : Pierre Alliez +# Michael Hemmer +# Cedric Portaneri +# +#!/usr/bin/python + +import os, sys, subprocess, datetime, time, signal, getopt +import numpy as np +import matplotlib.pyplot as plt + +def main(argv): + + inputdir="" + outputdir="" + commit_hash="" + alpha="" + do_diff=False + diffdir="" + diff_hash="" + try: + opts, args = getopt.getopt(sys.argv[1:], 'i:a:o:c:d:p:') + except getopt.GetoptError: + sys.exit(2) + for opt, arg in opts: + if opt == "-i": + inputdir = arg + elif opt == "-a": + alpha = arg + elif opt == "-o": + outputdir = arg + elif opt == "-c": + commit_hash = arg + elif opt == "-d": + diff_hash = arg + do_diff = True + elif opt == "-p": + diffdir = arg + + all_metric = { + "Mean_Min_Angle_(degree)" : {}, + "Mean_Max_Angle_(degree)" : {}, + "Mean_Radius_Ratio" : {}, + "Mean_Edge_Ratio" : {}, + "Mean_Aspect_Ratio" : {}, + "Complexity_(#_of_triangle)" : {}, + "#_of_almost_degenerate_triangle" : {}, + "Hausdorff_distance_output_to_input_(%_of_bbox_diag)" : {}} + num_input = 0 + print("inputdir = ", inputdir) + for filename in os.listdir(inputdir) : + new_path = os.path.join(inputdir,filename) + new_file = open(new_path) + if do_diff : + old_path = os.path.join(diffdir,filename) + old_file = open(old_path) + is_empty_old = os.path.getsize(old_path) <= 1 + for key in all_metric : + try : + new_val = float(new_file.readline().rstrip('\n')) + old_val = float(old_file.readline().rstrip('\n')) + mesh_id = str(filename.split('.')[0]) + all_metric[key][mesh_id] = [new_val, old_val] + except ValueError: + pass + else : + for key in all_metric : + try : + new_val = float(new_file.readline().rstrip('\n')) + mesh_id = str(filename.split('.')[0]) + all_metric[key][mesh_id] = [new_val, new_val] + except ValueError: + pass + num_input = num_input+1 + + # update .pdf chart + date_now = datetime.datetime.now() + date_for_filename = str(date_now.year) +"_"+ str(date_now.month) +"_"+ str(date_now.day) +"_"+ str(date_now.hour) +"h"+ str(date_now.minute) +"mn" + for key in all_metric: + goal = 0 + if key == "Mean_Min_Angle_(degree)" or key == "Mean_Max_Angle_(degree)": + goal = 60 + elif key == "Mean_Radius_Ratio" or key == "Mean_Edge_Ratio" or key == "Mean_Aspect_Ratio" : + goal = 1 + + num_el = range(len(all_metric[key])) + avg_diff_to_goal = 0. + avg = 0. + x1 = [] + x2 = [] + for value in all_metric[key].values() : + avg += value[0] + diff_to_goal = abs(value[1]-goal) - abs(value[0]-goal) + avg_diff_to_goal += diff_to_goal + x1.append(value[0]) + x2.append(value[1]) + avg_diff_to_goal /= float(len(all_metric[key])) + avg /= float(len(all_metric[key])) + + plt.figure(figsize=(8,8)) + if do_diff : + plt.hist(x2, bins=100, color='tab:green', alpha=0.5) + plt.hist(x1, bins=100, color='tab:blue', alpha=0.5) + plt.vlines(x = goal, ymin=plt.ylim()[0], ymax=plt.ylim()[1], linestyles='dashed') + + title = "" + if do_diff : + title += "Diff between " + commit_hash + " and " + diff_hash + " on " + str(num_input) + " meshes from Thingi10K\nAlpha = Bbox diag length / " + alpha + else : + title += "Benchmarking on " + str(num_input) + " meshes from Thingi10K\nAlpha = Bbox diag length / " + alpha + + avg_str = str(format(abs(avg), '.2f')) + if key == "Mean_Min_Angle_(degree)" or key == "Mean_Max_Angle_(degree)": + title += "\nIn average we have " + avg_str + "°" + elif key == "Mean_Radius_Ratio" or key == "Mean_Edge_Ratio" or key == "Mean_Aspect_Ratio" : + title += "\nIn average we have a ratio of " + avg_str + elif key == "Hausdorff_distance_output_to_input_(%_of_bbox_diag)" : + title += "\nIn average we have a distance of " + avg_str + "% of bbox diag" + elif key == "Complexity_(#_of_triangle)" or key == "#_of_almost_degenerate_triangle" : + title += "\nIn average we have " + avg_str + " triangles" + + if do_diff and avg_diff_to_goal == 0. : + title += "\nNo change between the two commits" + elif do_diff : + avg_diff_str = str(format(abs(avg_diff_to_goal), '.2f')) + if key == "Mean_Min_Angle_(degree)" or key == "Mean_Max_Angle_(degree)": + if avg_diff_to_goal < 0 : + title += "\nIn average we loose " + else : + title += "\nIn average we gain " + title += avg_diff_str + "° toward 60°" + elif key == "Mean_Radius_Ratio" or key == "Mean_Edge_Ratio" or key == "Mean_Aspect_Ratio" : + if avg_diff_to_goal < 0 : + title += "\nIn average we loose " + else : + title += "\nIn average we gain " + title += avg_diff_str + " of ratio toward 1" + elif key == "Hausdorff_distance_output_to_input_(%_of_bbox_diag)" : + if avg_diff_to_goal < 0 : + title += "\nIn average we increase by " + else : + title += "\nIn average we reduce by " + title += avg_diff_str + " the bbox ratio" + elif key == "Complexity_(#_of_triangle)" or key == "#_of_almost_degenerate_triangle" : + if avg_diff_to_goal < 0 : + title += "\nIn average we get " + avg_diff_str + " more" + else : + title += "\nIn average we get " + avg_diff_str + " less" + title += " triangles" + + plt.title(title, fontsize=15) + plt.xlabel(key.replace("_"," "), fontsize=14) + plt.ylabel("# of meshes", fontsize=14) + plt.tick_params(axis="x", labelsize=9) + plt.tick_params(axis="y", labelsize=9) + + chart_filename = "" + if do_diff : + chart_filename += "diff_"+commit_hash+"_"+diff_hash+"_"+key+"_"+date_for_filename+".pdf" + else : + chart_filename += "results_"+commit_hash+"_"+key+"_"+date_for_filename+".pdf" + chart_path = os.path.join(outputdir+"/charts",chart_filename) + if os.path.isfile(chart_path) : + os.remove(chart_path) + plt.savefig(chart_path, bbox_inches="tight") + plt.close() + + print("pdf updated") + + sys.exit() + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/Alpha_wrap_3/benchmark/Alpha_wrap_3/Quality/quality_benchmark.cpp b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Quality/quality_benchmark.cpp new file mode 100644 index 000000000000..4565cca641a1 --- /dev/null +++ b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Quality/quality_benchmark.cpp @@ -0,0 +1,271 @@ +#include + +#include +#include + +#include + +#include + +#include +#include +#include + +using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel; +using Point_3 = Kernel::Point_3; +using Vector_3 = Kernel::Vector_3; +using Triangle_3 = Kernel::Triangle_3; +using FT = Kernel::FT; + +using Mesh = CGAL::Surface_mesh; +using face_descriptor = boost::graph_traits::face_descriptor; + +using Oracle = CGAL::Alpha_wraps_3::internal::Triangle_mesh_oracle; +using Dt = CGAL::Alpha_wraps_3::internal::Alpha_wrap_3::Triangulation; + +namespace PMP = CGAL::Polygon_mesh_processing; + +std::array triangle_angles(const Triangle_3& tr) +{ + FT sq_a = CGAL::squared_distance(tr[0], tr[1]); + FT sq_b = CGAL::squared_distance(tr[1], tr[2]); + FT sq_c = CGAL::squared_distance(tr[2], tr[0]); + + FT two_ab = 2. * CGAL::sqrt(sq_a) * CGAL::sqrt(sq_b); + FT two_bc = 2. * CGAL::sqrt(sq_b) * CGAL::sqrt(sq_c); + FT two_ca = 2. * CGAL::sqrt(sq_c) * CGAL::sqrt(sq_a); + + FT angle_a = (sq_b + sq_c - sq_a) / two_bc; + FT angle_b = (sq_c + sq_a - sq_b) / two_ca; + FT angle_c = (sq_a + sq_b - sq_c) / two_ab; + if(angle_a < -1.) angle_a = -1.; + if(angle_b < -1.) angle_b = -1.; + if(angle_c < -1.) angle_c = -1.; + if(angle_a > 1.) angle_a = 1.; + if(angle_b > 1.) angle_b = 1.; + if(angle_c > 1.) angle_c = 1.; + angle_a = std::acos(angle_a); + angle_b = std::acos(angle_b); + angle_c = std::acos(angle_c); + + return {angle_a, angle_b, angle_c}; +} + +bool is_almost_degenerate(const Triangle_3& tr, + double threshold) +{ + FT sq_area = tr.squared_area(); + return (CGAL::sqrt(CGAL::to_double(sq_area)) < threshold); +} + +auto surface_mesh_face_to_triangle(const face_descriptor fd, + const Mesh& sm) +{ + typename boost::graph_traits::halfedge_descriptor hd = halfedge(fd,sm); + return Triangle_3(sm.point(target(hd,sm)), + sm.point(target(next(hd,sm),sm)), + sm.point(target(next(next(hd,sm),sm),sm))); +} + +double mean_min_angle(const Mesh& mesh) +{ + double mean_min_angle = 0.; + for(const face_descriptor f : faces(mesh)) + { + const Triangle_3 tr = surface_mesh_face_to_triangle(f, mesh); + std::array angles = triangle_angles(tr); + + FT min_angle = std::min({angles[0], angles[1], angles[2]}); + + min_angle = min_angle * (180.0 / CGAL_PI); + mean_min_angle += min_angle; + } + + mean_min_angle /= static_cast(mesh.number_of_faces()); + return mean_min_angle; +} + +double mean_max_angle(const Mesh& mesh) +{ + double mean_max_angle = 0.; + for(const face_descriptor f : faces(mesh)) + { + const Triangle_3 tr = surface_mesh_face_to_triangle(f, mesh); + std::array angles = triangle_angles(tr); + + FT max_angle = std::max({angles[0], angles[1], angles[2]}); + + max_angle = max_angle * (180.0 / CGAL_PI); + mean_max_angle += max_angle; + } + + mean_max_angle /= static_cast(mesh.number_of_faces()); + return mean_max_angle; +} + +double mean_radius_ratio(const Mesh& mesh, + double degenerate_threshold) +{ + double mean_radius_ratio = 0.; + size_t num_almost_degenerate_tri = 0; + for(const face_descriptor f : faces(mesh)) + { + const Triangle_3 tr = surface_mesh_face_to_triangle(f, mesh); + if(is_almost_degenerate(tr, degenerate_threshold)) + { + ++num_almost_degenerate_tri; + continue; + } + + FT circumsphere_radius = std::sqrt(CGAL::squared_radius(tr[0], tr[1], tr[2])); + + FT a = std::sqrt(CGAL::squared_distance(tr[0], tr[1])); + FT b = std::sqrt(CGAL::squared_distance(tr[1], tr[2])); + FT c = std::sqrt(CGAL::squared_distance(tr[2], tr[0])); + FT s = 0.5 * (a + b + c); + FT inscribed_radius = std::sqrt((s * (s - a) * (s - b) * (s - c)) / s); + FT radius_ratio = circumsphere_radius / inscribed_radius; + radius_ratio /= 2.; // normalized + mean_radius_ratio += radius_ratio; + } + + mean_radius_ratio /= static_cast(mesh.number_of_faces() - num_almost_degenerate_tri); + return mean_radius_ratio; +} + +double mean_edge_ratio(const Mesh& mesh, + double degenerate_threshold) +{ + double mean_edge_ratio = 0.; + size_t num_almost_degenerate_tri = 0; + + for(const face_descriptor f : faces(mesh)) + { + const Triangle_3 tr = surface_mesh_face_to_triangle(f, mesh); + if(is_almost_degenerate(tr, degenerate_threshold)) + { + ++num_almost_degenerate_tri; + continue; + } + + FT a = std::sqrt(CGAL::squared_distance(tr[0], tr[1])); + FT b = std::sqrt(CGAL::squared_distance(tr[1], tr[2])); + FT c = std::sqrt(CGAL::squared_distance(tr[2], tr[0])); + FT min_edge = std::min({a, b, c}); + FT max_edge = std::max({a, b, c}); + FT edge_ratio = max_edge / min_edge; + + mean_edge_ratio += edge_ratio; + } + + mean_edge_ratio /= static_cast(mesh.number_of_faces() - num_almost_degenerate_tri); + return mean_edge_ratio; +} + +double mean_aspect_ratio(const Mesh& mesh, + double degenerate_threshold) +{ + double mean_aspect_ratio = 0.; + size_t num_almost_degenerate_tri = 0; + for(const face_descriptor f : faces(mesh)) + { + const Triangle_3 tr = surface_mesh_face_to_triangle(f, mesh); + if(is_almost_degenerate(tr, degenerate_threshold)) + { + ++num_almost_degenerate_tri; + continue; + } + + FT a = std::sqrt(CGAL::squared_distance(tr[0], tr[1])); + FT b = std::sqrt(CGAL::squared_distance(tr[1], tr[2])); + FT c = std::sqrt(CGAL::squared_distance(tr[2], tr[0])); + FT s = 0.5 * (a + b + c); + FT inscribed_radius = std::sqrt((s * (s - a) * (s - b) * (s - c)) / s); + FT max_edge = std::max({a, b, c}); + FT aspect_ratio = max_edge / inscribed_radius; + aspect_ratio /= (2. * std::sqrt(3.)); // normalized + mean_aspect_ratio += aspect_ratio; + } + + mean_aspect_ratio /= static_cast(mesh.number_of_faces() - num_almost_degenerate_tri); + return mean_aspect_ratio; +} + +size_t num_almost_degenerate_tri(const Mesh& mesh, + double degenerate_threshold) +{ + size_t num_almost_degenerate_tri = 0; + for(const face_descriptor f : faces(mesh)) + { + const Triangle_3 tr = surface_mesh_face_to_triangle(f, mesh); + if(is_almost_degenerate(tr, degenerate_threshold)) + { + ++num_almost_degenerate_tri; + } + } + return num_almost_degenerate_tri; +} + +int main(int argc, char** argv) +{ + const int argc_check = argc - 1; + char *entry_name_ptr = nullptr; + double relative_alpha_ratio = 20.; + double relative_offset_ratio = 600.; + + for(int i=1; i +#include + +#include +#include + +#include + +using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel; +using Point_3 = Kernel::Point_3; +using Mesh = CGAL::Surface_mesh; + +namespace CGAL { +namespace Alpha_wraps_3 { +namespace internal { +namespace { + +enum Robustness_benchmark_exit_code +{ + // Success + VALID_SOLID_OUTPUT = 0, + + // Failure + OUTPUT_IS_NOT_TRIANGLE_MESH = 1, + OUTPUT_IS_COMBINATORIAL_NON_MANIFOLD = 2, + OUTPUT_HAS_BORDERS = 3, + OUTPUT_HAS_DEGENERATED_FACES = 4, + OUTPUT_HAS_GEOMETRIC_SELF_INTERSECTIONS = 5, + OUTPUT_DOES_NOT_BOUND_VOLUME = 6, + OUTPUT_DOES_NOT_CONTAIN_INPUT = 7, + OUTPUT_DISTANCE_IS_TOO_LARGE = 8, +}; + +} // namespace +} // namespace internal +} // namespace Alpha_wraps_3 +} // namespace CGAL + +namespace PMP = CGAL::Polygon_mesh_processing; +namespace AW3i = CGAL::Alpha_wraps_3::internal; + +int main(int argc, char** argv) +{ + const int argc_check = argc - 1; + char* entry_name_ptr = nullptr; + double relative_alpha_ratio = 20.; + double relative_offset_ratio = 600.; + + for(int i=1; i $2/Robustness/results/$5/$filename.log + + python3 $1/Alpha_wrap_3/benchmark/Alpha_wrap_3/Performance/compute_performance_benchmark_data.py \ + -e $1/Alpha_wrap_3/benchmark/Alpha_wrap_3/build-release/performance_benchmark -i $6 -a $3 \ + > $2/Performance/results/$5/$filename.log + + python3 $1/Alpha_wrap_3/benchmark/Alpha_wrap_3/Quality/compute_quality_benchmark_data.py \ + -e $1/Alpha_wrap_3/benchmark/Alpha_wrap_3/build-release/quality_benchmark -i $6 -a $3 \ + > $2/Quality/results/$5/$filename.log +} +export -f compute_benchmark_data + +# $1: directory containing the alpha wrap project +# $2: directory containing the input data folder +# $3: directory containing the output results +# $4: alpha value +# $5: timeout value for robustness benchmark in seconds +# $6: number of virtual thread used +# $7: hash of the latest commit +# $8: hash of a commit to perform the diff with latest +cd $1 + +mkdir -p $3/Robustness/results/$7 +mkdir -p $3/Performance/results/$7 +mkdir -p $3/Quality/results/$7 +mkdir -p $3/Robustness/charts_data +mkdir -p $3/Performance/charts_data +mkdir -p $3/Quality/charts_data +mkdir -p $3/Robustness/charts +mkdir -p $3/Performance/charts +mkdir -p $3/Quality/charts +mkdir -p $3/Robustness/log +mkdir -p $3/Performance/log +mkdir -p $3/Quality/log +mkdir -p $3/charts + +find $2 -mindepth 1 | parallel -j$6 compute_benchmark_data $1 $3 $4 $5 $7 ::: + +python3 $1/Alpha_wrap_3/benchmark/Alpha_wrap_3/Robustness/generate_robustness_benchmark_charts.py -i $3/Robustness/results/$7 -o $3/Robustness -a $4 -c $7 + +if [ -z "$8" ]; then + python3 $1/Alpha_wrap_3/benchmark/Alpha_wrap_3/Performance/generate_performance_benchmark_charts.py -i $3/Performance/results/$7 -o $3/Performance -a $4 -c $7; +else + python3 $1/Alpha_wrap_3/benchmark/Alpha_wrap_3/Performance/generate_performance_benchmark_charts.py -i $3/Performance/results/$7 -o $3/Performance -a $4 -c $7 -p $3/Performance/results/$8 -d $8; +fi + +if [ -z "$8" ]; then + python3 $1/Alpha_wrap_3/benchmark/Alpha_wrap_3/Quality/generate_quality_benchmark_charts.py -i $3/Quality/results/$7 -o $3/Quality -a $4 -c $7; +else + python3 $1/Alpha_wrap_3/benchmark/Alpha_wrap_3/Quality/generate_quality_benchmark_charts.py -i $3/Quality/results/$7 -o $3/Quality -a $4 -c $7 -p $3/Quality/results/$8 -d $8; +fi + +charts_path="$(ls "$3/Robustness/charts"/* -dArt | tail -n 1) $(ls "$3/Performance/charts"/* -dArt | tail -n 2) $(ls "$3/Quality/charts"/* -dArt | tail -n 9)" + +pdfjam --nup 2x6 $charts_path --outfile $3/charts/results_$7_$8_alpha_$4_$(date '+%Y-%m-%d_%H:%M:%S').pdf diff --git a/Alpha_wrap_3/test/Alpha_wrap_3/alpha_wrap_validation.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/validation.h similarity index 100% rename from Alpha_wrap_3/test/Alpha_wrap_3/alpha_wrap_validation.h rename to Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/validation.h diff --git a/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_cavity_initializations.cpp b/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_cavity_initializations.cpp index d7567bab205b..1e37919756ab 100644 --- a/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_cavity_initializations.cpp +++ b/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_cavity_initializations.cpp @@ -6,7 +6,7 @@ #include #include -#include "alpha_wrap_validation.h" +#include #include diff --git a/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_manifoldness.cpp b/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_manifoldness.cpp index 638431e30567..189cc73fa2dc 100644 --- a/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_manifoldness.cpp +++ b/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_manifoldness.cpp @@ -5,7 +5,7 @@ //#define CGAL_AW3_DEBUG_QUEUE #include -#include "alpha_wrap_validation.h" +#include #include #include diff --git a/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_multiple_calls.cpp b/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_multiple_calls.cpp index e2abc6f1f12f..a7abdf6674e5 100644 --- a/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_multiple_calls.cpp +++ b/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_multiple_calls.cpp @@ -4,7 +4,7 @@ #include #include -#include "alpha_wrap_validation.h" +#include #include #include diff --git a/Alpha_wrap_3/test/Alpha_wrap_3/test_alpha_wrap_3_mesh.cpp b/Alpha_wrap_3/test/Alpha_wrap_3/test_alpha_wrap_3_mesh.cpp index 470d48e40d44..e7a362fc7098 100644 --- a/Alpha_wrap_3/test/Alpha_wrap_3/test_alpha_wrap_3_mesh.cpp +++ b/Alpha_wrap_3/test/Alpha_wrap_3/test_alpha_wrap_3_mesh.cpp @@ -6,7 +6,7 @@ //#define CGAL_AW3_DEBUG_QUEUE #include -#include "alpha_wrap_validation.h" +#include #include #include From 53c89475a379a29e6516b0d93746653c4b255e28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 29 Sep 2023 11:12:17 +0200 Subject: [PATCH 110/329] Rename a variable --- Alpha_wrap_3/examples/Alpha_wrap_3/mixed_inputs_wrap.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/mixed_inputs_wrap.cpp b/Alpha_wrap_3/examples/Alpha_wrap_3/mixed_inputs_wrap.cpp index ffcedc7f1cbb..4e96d6c1116c 100644 --- a/Alpha_wrap_3/examples/Alpha_wrap_3/mixed_inputs_wrap.cpp +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/mixed_inputs_wrap.cpp @@ -105,8 +105,8 @@ int main(int argc, char** argv) CGAL::Alpha_wraps_3::internal::Alpha_wrap_3 aw3(oracle); - Mesh output_mesh; - aw3(alpha, offset, output_mesh); + Mesh wrap; + aw3(alpha, offset, wrap); t.stop(); std::cout << "Took " << t.time() << std::endl; @@ -123,7 +123,7 @@ int main(int argc, char** argv) std::string output_name = ts_name + "_" + ss_name + "_" + ps_name + "_" + std::to_string(static_cast(relative_alpha)) + "_" + std::to_string(static_cast(relative_offset)) + ".off"; std::cout << "Writing to " << output_name << std::endl; - CGAL::IO::write_polygon_mesh(output_name, output_mesh, CGAL::parameters::stream_precision(17)); + CGAL::IO::write_polygon_mesh(output_name, wrap, CGAL::parameters::stream_precision(17)); return EXIT_SUCCESS; } From e3854f68e3269da5d3ecb472c0f1a69f5f78999c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 29 Sep 2023 11:12:31 +0200 Subject: [PATCH 111/329] Expose useful typedefs from Alpha_wrapper_3 --- .../include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index 3ee6061d0d89..3aaabefd94fc 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -124,8 +124,13 @@ class Alpha_wrap_3 using Default_Tds = CGAL::Triangulation_data_structure_3; using Default_Triangulation = CGAL::Delaunay_triangulation_3; +public: using Triangulation = typename Default::Get::type; + // Use the geom traits from the triangulation, and trust the (advanced) user that provided it + using Geom_traits = typename Triangulation::Geom_traits; + +private: using Cell_handle = typename Triangulation::Cell_handle; using Facet = typename Triangulation::Facet; using Vertex_handle = typename Triangulation::Vertex_handle; @@ -134,9 +139,6 @@ class Alpha_wrap_3 using Gate = internal::Gate; using Alpha_PQ = Modifiable_priority_queue, CGAL_BOOST_PAIRING_HEAP>; - // Use the geom traits from the triangulation, and trust the (advanced) user that provided it - using Geom_traits = typename Triangulation::Geom_traits; - using FT = typename Geom_traits::FT; using Point_3 = typename Geom_traits::Point_3; using Vector_3 = typename Geom_traits::Vector_3; From cfae913d77ec5e346aed9e5d3c90e3d591dea4ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 29 Sep 2023 11:13:31 +0200 Subject: [PATCH 112/329] Complete the sort functor in AW3's main queue --- .../internal/gate_priority_queue.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/gate_priority_queue.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/gate_priority_queue.h index 5e14a4d08ea1..a9bdd7e0491b 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/gate_priority_queue.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/gate_priority_queue.h @@ -68,6 +68,24 @@ struct Less_gate template bool operator()(const Gate& a, const Gate& b) const { + // If one is artificial and the other is not, give priority to the artificial facet + // + // The artificial facet are given highest priority because they need to be treated + // regardless of their circumradius. Treating them first allow the part that depends + // on alpha to be treated uniformly in a way: whatever the alpha, we'll do the same + // first treatmen + if(a.is_artificial_facet() != b.is_artificial_facet()) + return a.is_artificial_facet(); + + if(a.priority() == b.priority()) + { + // arbitrary, the sole purpose is to make it a total order for determinism + if(a.facet().first->time_stamp() == b.facet().first->time_stamp()) + return a.facet().second < b.facet().second; + + return a.facet().first->time_stamp() < b.facet().first->time_stamp(); + } + return a.priority() > b.priority(); } }; From 7e2386f97e9d935bd61d3120736832eca3200f78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 29 Sep 2023 11:14:42 +0200 Subject: [PATCH 113/329] Use the real circumradius value to sort the facets Meaning, use the value that we compare against alpha, and not simply the radius of the smallest circumscribing ball. This strongly changes the order of the queue and thus thus results are very different, but still the same (same guarantees, same element quality, only a little bit more elements, etc.) Also a massive, ~35% speed-up, that needs to be investigated. --- .../CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 11 +-- .../Alpha_wrap_3/internal/geometry_utils.h | 74 +++++++++++++++++++ 2 files changed, 80 insertions(+), 5 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index 3aaabefd94fc..14ad83cdbd36 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -1131,17 +1131,16 @@ class Alpha_wrap_3 if(status == IRRELEVANT) return false; + const FT sqr = smallest_squared_radius_3(f, m_tr); + m_queue.resize_and_push(Gate(f, sqr, (status == ARTIFICIAL_FACET))); + +#ifdef CGAL_AW3_DEBUG_QUEUE const Cell_handle ch = f.first; const int s = f.second; const Point_3& p0 = m_tr.point(ch, Triangulation::vertex_triple_index(s, 0)); const Point_3& p1 = m_tr.point(ch, Triangulation::vertex_triple_index(s, 1)); const Point_3& p2 = m_tr.point(ch, Triangulation::vertex_triple_index(s, 2)); - // @todo should prob be the real value that we compare to alpha instead of squared_radius - const FT sqr = geom_traits().compute_squared_radius_3_object()(p0, p1, p2); - m_queue.resize_and_push(Gate(f, sqr, (status == ARTIFICIAL_FACET))); - -#ifdef CGAL_AW3_DEBUG_QUEUE static int gid = 0; std::cout << "Queue insertion #" << gid++ << "\n" << " ch = " << &*ch << " (" << m_tr.is_infinite(ch) << ") " << "\n" @@ -1151,6 +1150,8 @@ class Alpha_wrap_3 std::cout << " Artificiality: " << (status == ARTIFICIAL_FACET) << std::endl; #endif + CGAL_assertion(status == ARTIFICIAL_FACET || sqr >= m_sq_alpha); + return true; } diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/geometry_utils.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/geometry_utils.h index 7d66cfd19f41..f39a47012862 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/geometry_utils.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/geometry_utils.h @@ -154,6 +154,80 @@ less_squared_radius_of_min_empty_sphere(typename Tr::Geom_traits::FT sq_alpha, } } +template +bool +smallest_squared_radius_3(const typename Tr::Facet& fh, + const Tr& tr) +{ + using Cell_handle = typename Tr::Cell_handle; + using Point = typename Tr::Point; + using FT = typename Tr::Geom_traits::FT; + + using CK = typename Tr::Geom_traits; + using Exact_kernel = typename Exact_kernel_selector::Exact_kernel; + using Approximate_kernel = Simple_cartesian; + using C2A = Cartesian_converter; + using C2E = typename Exact_kernel_selector::C2E; + + using Orientation_of_circumcenter = Filtered_predicate, + Orientation_of_circumcenter, + C2E, C2A>; + + Orientation_of_circumcenter orientation_of_circumcenter; + + auto squared_radius = tr.geom_traits().compute_squared_radius_3_object(); + + const Cell_handle c = fh.first; + const int ic = fh.second; + const Cell_handle n = c->neighbor(ic); + + const Point& p1 = tr.point(c, Tr::vertex_triple_index(ic,0)); + const Point& p2 = tr.point(c, Tr::vertex_triple_index(ic,1)); + const Point& p3 = tr.point(c, Tr::vertex_triple_index(ic,2)); + + // This is not actually possible in the context of alpha wrapping, but keeping it for genericity + // and because it does not cost anything. + if(tr.is_infinite(n)) + { + Orientation ori = orientation_of_circumcenter(p1, p2, p3, + tr.point(c, 0), tr.point(c, 1), + tr.point(c, 2), tr.point(c, 3)); + if(ori == POSITIVE) + return squared_radius(p1, p2, p3); + else + return squared_radius(tr.point(c, 0), tr.point(c, 1), tr.point(c, 2), tr.point(c, 3)); + } + + if(tr.is_infinite(c)) + { + Orientation ori = orientation_of_circumcenter(p1, p2, p3, + tr.point(n, 0), tr.point(n, 1), + tr.point(n, 2), tr.point(n, 3)); + if(ori == NEGATIVE) + return squared_radius(p1, p2, p3); + else + return squared_radius(tr.point(n, 0), tr.point(n, 1), tr.point(n, 2), tr.point(n, 3)); + } + + // both c and n are finite + if(orientation_of_circumcenter(p1, p2, p3, + tr.point(c, 0), tr.point(c, 1), tr.point(c, 2), tr.point(c, 3)) != + orientation_of_circumcenter(p1, p2, p3, + tr.point(n, 0), tr.point(n, 1), tr.point(n, 2), tr.point(n, 3))) + { + // Dual crosses the face + return squared_radius(p1, p2, p3); + } + else + { + // Dual does not crosses the face + FT cr = squared_radius(tr.point(c, 0), tr.point(c, 1), tr.point(c, 2), tr.point(c, 3)); + FT cnr = squared_radius(tr.point(n, 0), tr.point(n, 1), tr.point(n, 2), tr.point(n, 3)); + return (CGAL::min)(cr, cnr); + } +} + + } // namespace internal } // namespace Alpha_wraps_3 } // namespace CGAL From be42e0fbe887abff709b4c18d5070b5261ad71ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 29 Sep 2023 11:19:39 +0200 Subject: [PATCH 114/329] Minor debug code cleaning --- .../CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index 14ad83cdbd36..a7130c2a3774 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -1228,8 +1228,10 @@ class Alpha_wrap_3 CGAL_precondition(!m_tr.is_infinite(f)); const Cell_handle ch = f.first; - const int id = f.second; - const Cell_handle neighbor = ch->neighbor(id); + const int s = f.second; + CGAL_precondition(ch->is_outside()); + + const Cell_handle neighbor = ch->neighbor(s); #ifdef CGAL_AW3_DEBUG_QUEUE static int fid = 0; @@ -1237,10 +1239,11 @@ class Alpha_wrap_3 std::cout << m_queue.size() << " facets in the queue" << std::endl; std::cout << "Face " << fid++ << "\n" << "c = " << &*ch << " (" << m_tr.is_infinite(ch) << "), n = " << &*neighbor << " (" << m_tr.is_infinite(neighbor) << ")" << "\n" - << m_tr.point(ch, Triangulation::vertex_triple_index(id, 0)) << "\n" - << m_tr.point(ch, Triangulation::vertex_triple_index(id, 1)) << "\n" - << m_tr.point(ch, Triangulation::vertex_triple_index(id, 2)) << std::endl; - std::cout << "Priority: " << gate.priority() << std::endl; + << m_tr.point(ch, Triangulation::vertex_triple_index(s, 0)) << "\n" + << m_tr.point(ch, Triangulation::vertex_triple_index(s, 1)) << "\n" + << m_tr.point(ch, Triangulation::vertex_triple_index(s, 2)) << std::endl; + std::cout << "Artificiality: " << gate.is_artificial_facet() << std::endl; + std::cout << "Priority: " << gate.priority() << " (sq alpha: " << m_sq_alpha << ")" << std::endl; #endif visitor.before_facet_treatment(*this, gate); @@ -1255,9 +1258,9 @@ class Alpha_wrap_3 std::string face_name = "results/steps/face_" + std::to_string(static_cast(i++)) + ".xyz"; std::ofstream face_out(face_name); face_out.precision(17); - face_out << "3\n" << m_tr.point(ch, Triangulation::vertex_triple_index(id, 0)) << "\n" - << m_tr.point(ch, Triangulation::vertex_triple_index(id, 1)) << "\n" - << m_tr.point(ch, Triangulation::vertex_triple_index(id, 2)) << std::endl; + face_out << "3\n" << m_tr.point(ch, Triangulation::vertex_triple_index(s, 0)) << "\n" + << m_tr.point(ch, Triangulation::vertex_triple_index(s, 1)) << "\n" + << m_tr.point(ch, Triangulation::vertex_triple_index(s, 2)) << std::endl; face_out.close(); #endif From 8ccce4c536ea7c3e04f1a15d34e6ca362ae84bf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 29 Sep 2023 11:19:52 +0200 Subject: [PATCH 115/329] Avoid one useless facet check This doesn't bring any speed-up because it was a very fast exit in push_facet(): the neighbor was necessarily outside (since we come from it), and we are done. --- .../include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index a7130c2a3774..2174363240b6 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -1355,15 +1355,16 @@ class Alpha_wrap_3 } } } - else + else // no need for a Steiner point, carve through and continue { // tag neighbor as OUTSIDE neighbor->is_outside() = true; // for each finite facet of neighbor, push it to the queue - for(int i=0; i<4; ++i) + const int mi = m_tr.mirror_index(ch, s); + for(int i=1; i<4; ++i) { - const Facet neighbor_f = std::make_pair(neighbor, i); + const Facet neighbor_f = std::make_pair(neighbor, (mi+i)&3); push_facet(neighbor_f); } } From 05e11d381f952251538a134bd114871b1eb90173 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 9 Aug 2021 17:32:43 +0200 Subject: [PATCH 116/329] add experimental function to refine a mesh along an isocurve --- .../internal/refine_mesh_at_isolevel.h | 129 ++++++++++++++++++ .../Polygon_mesh_processing/CMakeLists.txt | 5 + .../test_geodesic_isolevel_refinement.cmd | 1 + .../test_geodesic_isolevel_refinement.cpp | 63 +++++++++ 4 files changed, 198 insertions(+) create mode 100644 Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/refine_mesh_at_isolevel.h create mode 100644 Polygon_mesh_processing/test/Polygon_mesh_processing/test_geodesic_isolevel_refinement.cmd create mode 100644 Polygon_mesh_processing/test/Polygon_mesh_processing/test_geodesic_isolevel_refinement.cpp diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/refine_mesh_at_isolevel.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/refine_mesh_at_isolevel.h new file mode 100644 index 000000000000..f4b0f7cc6497 --- /dev/null +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/refine_mesh_at_isolevel.h @@ -0,0 +1,129 @@ +// Copyright (c) 2021 GeometryFactory (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Sebastien Loriot + +#ifndef CGAL_POLYGON_MESH_PROCESSING_CLIP_H +#define CGAL_POLYGON_MESH_PROCESSING_CLIP_H + +#include + +#include + +namespace CGAL { +namespace Polygon_mesh_processing { +namespace experimental { + + +template +void refine_mesh_at_isolevel(PolygonMesh& pm, + ValueMap value_map, + typename boost::property_traits::value_type isovalue, + const NamedParameters& np) +{ + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits::edge_descriptor edge_descriptor; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::face_descriptor face_descriptor; + + using parameters::choose_parameter; + using parameters::get_parameter; + using parameters::is_default_parameter; + + typedef Static_boolean_property_map Default_ECM; + typedef typename internal_np::Lookup_named_param_def::type ECM; + typedef typename GetVertexPointMap < PolygonMesh, NamedParameters>::type VPM; + + VPM vpm = choose_parameter(get_parameter(np, internal_np::vertex_point), + get_property_map(vertex_point, pm)); + + ECM ecm = choose_parameter(get_parameter(np, internal_np::edge_is_constrained), Default_ECM()); + + std::unordered_map > faces_to_split; + std::vector to_split; + for (edge_descriptor e : edges(pm)) + { + vertex_descriptor src = source(e, pm), tgt = target(e, pm); + if (get(value_map, src)==isovalue) + { + for (halfedge_descriptor h : halfedges_around_source(halfedge(e, pm), pm)) + { + face_descriptor f = face(h, pm); + if (f!=boost::graph_traits::null_face()) + faces_to_split[f].push_back(opposite(h, pm)); + } + continue; + } + if (get(value_map, tgt)==isovalue) + { + for (halfedge_descriptor h : halfedges_around_target(halfedge(e, pm), pm)) + { + face_descriptor f = face(h, pm); + if (f!=boost::graph_traits::null_face()) + faces_to_split[f].push_back(h); + } + continue; + } + if ( (get(value_map, tgt) < isovalue) != (get(value_map, src) < isovalue) ) + { + to_split.push_back(e); + } + } + + for (edge_descriptor e : to_split) + { + vertex_descriptor src = source(e, pm), tgt = target(e, pm); + double ds = get(value_map, src); + double dt = get(value_map, tgt); + double alpha = (isovalue - dt) / (ds - dt); + halfedge_descriptor hnew = CGAL::Euler::split_edge(halfedge(e, pm), pm); + put(vpm, target(hnew, pm), barycenter(get(vpm,src), alpha, get(vpm, tgt), 1-alpha)); + put(value_map, target(hnew, pm) , isovalue); + face_descriptor f = face(hnew, pm); + if (f!=boost::graph_traits::null_face()) + faces_to_split[f].push_back(hnew); + hnew=pm.prev(opposite(hnew, pm)); + f = face(hnew, pm); + if (f!=boost::graph_traits::null_face()) + faces_to_split[f].push_back(hnew); + } + + for (const auto& p : faces_to_split) + { + if(p.second.size()!=2) continue; + + std::pair res = edge(target(p.second[0],pm), + target(p.second[1],pm), pm); + if (res.second) + { + // no split as the edge already exists (the two vertices are on the isolevel) + put(ecm, res.first, true); + continue; + } + + halfedge_descriptor hnew = CGAL::Euler::split_face(p.second[0], p.second[1], pm); + put(ecm, edge(hnew, pm), true); + } +} + +template +void refine_mesh_at_isolevel(PolygonMesh& pm, + ValueMap value_map, + typename boost::property_traits::value_type iso_level) +{ + refine_mesh_at_isolevel(pm, value_map, iso_level, parameters::all_default()); +} + +} } } // end of CGAL::Polygon_mesh_processing::experimental + + +#endif diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt b/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt index eb9b98cbe593..6f5d1e7c7ce9 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt @@ -125,6 +125,11 @@ else() message(STATUS "NOTICE: Tests are not using Ceres.") endif() +if (TARGET CGAL::Eigen3_support) + create_single_source_cgal_program("test_geodesic_isolevel_refinement.cpp") + target_link_libraries( test_geodesic_isolevel_refinement PUBLIC CGAL::Eigen3_support) +endif() + if(BUILD_TESTING) set_tests_properties( "execution of triangulate_hole_Polyhedron_3_no_delaunay_test" diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_geodesic_isolevel_refinement.cmd b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_geodesic_isolevel_refinement.cmd new file mode 100644 index 000000000000..36105ee3a020 --- /dev/null +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_geodesic_isolevel_refinement.cmd @@ -0,0 +1 @@ +${CGAL_DATA_DIR}/meshes/elephant.off 0.001 0.01 0.05 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 10 diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_geodesic_isolevel_refinement.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_geodesic_isolevel_refinement.cpp new file mode 100644 index 000000000000..a2098c63e3b9 --- /dev/null +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_geodesic_isolevel_refinement.cpp @@ -0,0 +1,63 @@ +#include +#include + +#include + +#include +#include + +#include +#include + +typedef CGAL::Simple_cartesian Kernel; +typedef Kernel::Point_3 Point_3; +typedef CGAL::Surface_mesh Triangle_mesh; + +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::edge_descriptor edge_descriptor; + +typedef Triangle_mesh::Property_map Vertex_distance_map; +typedef CGAL::Heat_method_3::Surface_mesh_geodesic_distances_3 Heat_method; + +int main(int argc, char* argv[]) +{ + const char* filename = argv[1]; + + Triangle_mesh tm; + if(!CGAL::IO::read_polygon_mesh(filename, tm) || + CGAL::is_empty(tm) || !CGAL::is_triangle_mesh(tm)) + { + std::cerr << "Invalid input file." << std::endl; + return EXIT_FAILURE; + } + + //property map for the distance values to the source set + Vertex_distance_map vertex_distance = tm.add_property_map("v:distance", 0).first; + + Heat_method hm(tm); + + //add the first vertex as the source set + vertex_descriptor s = *(vertices(tm).first); + hm.add_source(s); + hm.estimate_geodesic_distances(vertex_distance); + + //property map for the constrained status of edges + auto ecm = tm.add_property_map("e:is_constrained", 0).first; + + + for (int i=2; i splitted; + + CGAL::Polygon_mesh_processing::split_connected_components(tm, splitted, CGAL::parameters::edge_is_constrained_map(ecm)); + +#ifdef CGAL_TEST_SUITE + assert(splitted.size() == 22); +#else + for(std::size_t i=0; i Date: Sat, 30 Sep 2023 08:41:07 +0200 Subject: [PATCH 117/329] add doc --- .../internal/refine_mesh_at_isolevel.h | 51 ++++++++++++++----- 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/refine_mesh_at_isolevel.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/refine_mesh_at_isolevel.h index f4b0f7cc6497..8bb6502865f7 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/refine_mesh_at_isolevel.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/refine_mesh_at_isolevel.h @@ -10,10 +10,10 @@ // // Author(s) : Sebastien Loriot -#ifndef CGAL_POLYGON_MESH_PROCESSING_CLIP_H -#define CGAL_POLYGON_MESH_PROCESSING_CLIP_H +#ifndef CGAL_POLYGON_MESH_PROCESSING_REFINE_MESH_AT_ISOLEVEL_H +#define CGAL_POLYGON_MESH_PROCESSING_REFINE_MESH_AT_ISOLEVEL_H -#include +#include #include @@ -21,12 +21,43 @@ namespace CGAL { namespace Polygon_mesh_processing { namespace experimental { - -template +/*! \ingroup PkgPolygonMeshProcessingRef + * Function object that computes the intersection of a plane with + * a triangulated surface mesh. + * + * @tparam PolygonMesh a model of the concepts `EdgeListGraph` and `FaceListGraph` + * @tparam ValueMap a model of the concept `ReadablePropertyMap` with `boost::graph_traits::%vertex_descriptor` + * as key type and with its value type being model of `LessThanComparable`. + * @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" for `pm` + * + * @param pm the polygon mesh to be refined + * @param value_map the property map containing value at each vertex for a given function defined over the mesh + * @param isovalue the value used to defined the cut locus of edges having their incident vertices associated with + * values respectively larger and smaller than `isovalue` in `value_map` + * @param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below + * + * \cgalNamedParamsBegin + * \cgalParamNBegin{edge_is_constrained_map} + * \cgalParamDescription{an ouput property map associating `true` to all new edges added by the cut, and false to input edges. + * \cgalParamType{a class model of `WritablePropertyMap` with `boost::graph_traits::%edge_descriptor` + * as key type and `bool` as value type} + * \cgalParamDefault{No marks on edges will be put} + * \cgalParamNBegin{vertex_point_map} + * \cgalParamDescription{a property map associating points to the vertices of `pm`} + * \cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits::%vertex_descriptor` + * as key type and `%Point_3` as value type} + * \cgalParamDefault{`boost::get(CGAL::vertex_point, pm)`} + * \cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t` + * must be available in `PolygonMesh`.} + * \cgalParamNEnd + * \cgalNamedParamsEnd + * + */ +template void refine_mesh_at_isolevel(PolygonMesh& pm, ValueMap value_map, typename boost::property_traits::value_type isovalue, - const NamedParameters& np) + const NamedParameters& np = parameters::default_values()) { typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; typedef typename boost::graph_traits::edge_descriptor edge_descriptor; @@ -115,14 +146,6 @@ void refine_mesh_at_isolevel(PolygonMesh& pm, } } -template -void refine_mesh_at_isolevel(PolygonMesh& pm, - ValueMap value_map, - typename boost::property_traits::value_type iso_level) -{ - refine_mesh_at_isolevel(pm, value_map, iso_level, parameters::all_default()); -} - } } } // end of CGAL::Polygon_mesh_processing::experimental From c17841356a3228ff9509a6edc58bc22fee672071 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 2 Oct 2023 13:10:38 +0200 Subject: [PATCH 118/329] Minor error message tweak --- Alpha_wrap_3/examples/Alpha_wrap_3/point_set_wrap.cpp | 2 +- Alpha_wrap_3/examples/Alpha_wrap_3/successive_wraps.cpp | 2 +- Alpha_wrap_3/examples/Alpha_wrap_3/triangle_mesh_wrap.cpp | 2 +- Alpha_wrap_3/examples/Alpha_wrap_3/triangle_soup_wrap.cpp | 2 +- Alpha_wrap_3/examples/Alpha_wrap_3/volumetric_wrap.cpp | 2 +- Alpha_wrap_3/examples/Alpha_wrap_3/wrap_from_cavity.cpp | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/point_set_wrap.cpp b/Alpha_wrap_3/examples/Alpha_wrap_3/point_set_wrap.cpp index 8742a2a20011..aeb47b80152e 100644 --- a/Alpha_wrap_3/examples/Alpha_wrap_3/point_set_wrap.cpp +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/point_set_wrap.cpp @@ -23,7 +23,7 @@ int main(int argc, char** argv) Point_container points; if(!CGAL::IO::read_points(filename, std::back_inserter(points)) || points.empty()) { - std::cerr << "Invalid input." << std::endl; + std::cerr << "Invalid input:" << filename << std::endl; return EXIT_FAILURE; } diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/successive_wraps.cpp b/Alpha_wrap_3/examples/Alpha_wrap_3/successive_wraps.cpp index 600d533ee411..59010d1212ea 100644 --- a/Alpha_wrap_3/examples/Alpha_wrap_3/successive_wraps.cpp +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/successive_wraps.cpp @@ -35,7 +35,7 @@ int main(int argc, char** argv) Mesh mesh; if(!PMP::IO::read_polygon_mesh(filename, mesh) || is_empty(mesh) || !is_triangle_mesh(mesh)) { - std::cerr << "Invalid input." << std::endl; + std::cerr << "Invalid input:" << filename << std::endl; return EXIT_FAILURE; } diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/triangle_mesh_wrap.cpp b/Alpha_wrap_3/examples/Alpha_wrap_3/triangle_mesh_wrap.cpp index 00e2e4fd9fc5..369cf375a6ff 100644 --- a/Alpha_wrap_3/examples/Alpha_wrap_3/triangle_mesh_wrap.cpp +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/triangle_mesh_wrap.cpp @@ -25,7 +25,7 @@ int main(int argc, char** argv) Mesh mesh; if(!PMP::IO::read_polygon_mesh(filename, mesh) || is_empty(mesh) || !is_triangle_mesh(mesh)) { - std::cerr << "Invalid input." << std::endl; + std::cerr << "Invalid input:" << filename << std::endl; return EXIT_FAILURE; } diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/triangle_soup_wrap.cpp b/Alpha_wrap_3/examples/Alpha_wrap_3/triangle_soup_wrap.cpp index 626e3bdc3ba4..6e1321c302dd 100644 --- a/Alpha_wrap_3/examples/Alpha_wrap_3/triangle_soup_wrap.cpp +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/triangle_soup_wrap.cpp @@ -30,7 +30,7 @@ int main(int argc, char** argv) std::vector > faces; if(!CGAL::IO::read_polygon_soup(filename, points, faces) || faces.empty()) { - std::cerr << "Invalid input." << std::endl; + std::cerr << "Invalid input:" << filename << std::endl; return EXIT_FAILURE; } diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/volumetric_wrap.cpp b/Alpha_wrap_3/examples/Alpha_wrap_3/volumetric_wrap.cpp index 113215b631a1..682cffac3390 100644 --- a/Alpha_wrap_3/examples/Alpha_wrap_3/volumetric_wrap.cpp +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/volumetric_wrap.cpp @@ -70,7 +70,7 @@ int main(int argc, char** argv) Faces faces; if(!CGAL::IO::read_polygon_soup(filename, points, faces) || faces.empty()) { - std::cerr << "Invalid input." << std::endl; + std::cerr << "Invalid input:" << filename << std::endl; return EXIT_FAILURE; } diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/wrap_from_cavity.cpp b/Alpha_wrap_3/examples/Alpha_wrap_3/wrap_from_cavity.cpp index 1c1d6c7b3d72..9de47aefbcd2 100644 --- a/Alpha_wrap_3/examples/Alpha_wrap_3/wrap_from_cavity.cpp +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/wrap_from_cavity.cpp @@ -25,7 +25,7 @@ int main(int argc, char** argv) if(!PMP::IO::read_polygon_mesh(filename, input) || is_empty(input) || !is_triangle_mesh(input)) { - std::cerr << "Invalid input." << std::endl; + std::cerr << "Invalid input:" << filename << std::endl; return EXIT_FAILURE; } From 9fa445f21754a1ac7923f2b5d190647ebd818dea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 2 Oct 2023 13:13:40 +0200 Subject: [PATCH 119/329] Change nomenclature to clarify the different types of gate permissiveness --- .../CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 39 +++++++++++-------- .../internal/gate_priority_queue.h | 16 ++++---- .../Alpha_wrap_3/Alpha_wrap_3_plugin.cpp | 6 +-- 3 files changed, 33 insertions(+), 28 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index 2174363240b6..7c9509b9185a 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -523,7 +523,7 @@ class Alpha_wrap_3 continue; } - // Mark the seeds and icosahedron vertices as "artificial vertices" such that the facets + // Mark the seeds and icosahedron vertices as "scaffolding vertices" such that the facets // incident to these vertices are always traversable regardless of their circumcenter. // This is done because otherwise some cavities can appear on the mesh: non-traversable facets // with two vertices on the offset, and the third being a deeper inside seed / ico_seed. @@ -592,11 +592,12 @@ class Alpha_wrap_3 std::vector inc_cells; inc_cells.reserve(64); m_tr.incident_cells(seed_v, std::back_inserter(inc_cells)); + for(Cell_handle ch : inc_cells) ch->is_outside() = cavity_cell_outside_tag(ch); } - // Might as well go through the full triangulation since only seeds should have been inserted + // Should be cheap enough to go through the full triangulation as only seeds have been inserted for(Cell_handle ch : m_tr.all_cell_handles()) { if(!ch->is_outside()) @@ -1027,21 +1028,24 @@ class Alpha_wrap_3 } private: + // A permissive gate is a gate that we can traverse without checking its circumradius enum Facet_queue_status { IRRELEVANT = 0, - ARTIFICIAL_FACET, + HAS_INFINITE_NEIGHBOR, // the cell incident to the mirrored facet is infinite (permissive) + SCAFFOLDING, // incident to a SEED or BBOX vertex (permissive) TRAVERSABLE }; inline const char* get_status_message(const Facet_queue_status status) { - constexpr std::size_t status_count = 3; + constexpr std::size_t status_count = 4; // Messages corresponding to Error_code list above. Must be kept in sync! static const char* message[status_count] = { "Irrelevant facet", - "Artificial facet", + "Facet incident to infinite neighbor", + "Facet with a bbox/seed vertex", "Traversable facet" }; @@ -1079,7 +1083,7 @@ class Alpha_wrap_3 const Cell_handle nh = ch->neighbor(id); if(m_tr.is_infinite(nh)) - return TRAVERSABLE; + return HAS_INFINITE_NEIGHBOR; if(nh->is_outside()) { @@ -1089,7 +1093,7 @@ class Alpha_wrap_3 return IRRELEVANT; } - // push if facet is connected to artificial vertices + // push if facet is connected to scaffolding vertices for(int i=0; i<3; ++i) { const Vertex_handle vh = ch->vertex(Triangulation::vertex_triple_index(id, i)); @@ -1097,9 +1101,9 @@ class Alpha_wrap_3 vh->type() == AW3i::Vertex_type:: SEED_VERTEX) { #ifdef CGAL_AW3_DEBUG_FACET_STATUS - std::cout << "artificial facet due to artificial vertex #" << i << std::endl; + std::cout << "Scaffolding facet due to vertex #" << i << std::endl; #endif - return ARTIFICIAL_FACET; + return SCAFFOLDING; } } @@ -1132,7 +1136,8 @@ class Alpha_wrap_3 return false; const FT sqr = smallest_squared_radius_3(f, m_tr); - m_queue.resize_and_push(Gate(f, sqr, (status == ARTIFICIAL_FACET))); + const bool is_permissive = (status == HAS_INFINITE_NEIGHBOR || status == SCAFFOLDING); + m_queue.resize_and_push(Gate(f, sqr, is_permissive)); #ifdef CGAL_AW3_DEBUG_QUEUE const Cell_handle ch = f.first; @@ -1147,10 +1152,10 @@ class Alpha_wrap_3 << "\t" << p0 << "\n\t" << p1 << "\n\t" << p2 << std::endl; std::cout << " Status: " << get_status_message(status) << std::endl; std::cout << " SQR: " << sqr << std::endl; - std::cout << " Artificiality: " << (status == ARTIFICIAL_FACET) << std::endl; + std::cout << " Permissiveness: " << is_permissive << std::endl; #endif - CGAL_assertion(status == ARTIFICIAL_FACET || sqr >= m_sq_alpha); + CGAL_assertion(is_permissive || sqr >= m_sq_alpha); return true; } @@ -1242,8 +1247,8 @@ class Alpha_wrap_3 << m_tr.point(ch, Triangulation::vertex_triple_index(s, 0)) << "\n" << m_tr.point(ch, Triangulation::vertex_triple_index(s, 1)) << "\n" << m_tr.point(ch, Triangulation::vertex_triple_index(s, 2)) << std::endl; - std::cout << "Artificiality: " << gate.is_artificial_facet() << std::endl; std::cout << "Priority: " << gate.priority() << " (sq alpha: " << m_sq_alpha << ")" << std::endl; + std::cout << "Permissiveness: " << gate.is_permissive_facet() << std::endl; #endif visitor.before_facet_treatment(*this, gate); @@ -1547,7 +1552,7 @@ class Alpha_wrap_3 } // Some lambdas for the comparer - auto has_artificial_vertex = [](Cell_handle c) -> bool + auto has_scaffolding_vertex = [](Cell_handle c) -> bool { for(int i=0; i<4; ++i) { @@ -1625,9 +1630,9 @@ class Alpha_wrap_3 // @todo give topmost priority to cells with > 1 non-manifold vertex? auto comparer = [&](Cell_handle l, Cell_handle r) -> bool { - if(has_artificial_vertex(l)) + if(has_scaffolding_vertex(l)) return false; - if(has_artificial_vertex(r)) + if(has_scaffolding_vertex(r)) return true; const int l_bf_count = count_boundary_facets(l, v); @@ -1706,7 +1711,7 @@ class Alpha_wrap_3 std::cout << "At Facet with VID " << get(Gate_ID_PM(), current_gate) << "\n"; std::cout << "\t" << p0 << "\n\t" << p1 << "\n\t" << p2 << "\n"; - std::cout << " Artificiality: " << current_gate.is_artificial_facet() << "\n"; + std::cout << " Permissiveness: " << current_gate.is_permissive_facet() << "\n"; std::cout << " SQR: " << sqr << "\n"; std::cout << " Priority " << current_gate.priority() << std::endl; diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/gate_priority_queue.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/gate_priority_queue.h index a9bdd7e0491b..b091b2cabe24 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/gate_priority_queue.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/gate_priority_queue.h @@ -37,17 +37,17 @@ class Gate private: Facet m_facet; FT m_priority; // circumsphere sq_radius - bool m_is_artificial_facet; + bool m_is_permissive_facet; public: // Constructors Gate(const Facet& facet, const FT& priority, - const bool is_artificial_facet) + const bool is_permissive_facet) : m_facet(facet), m_priority(priority), - m_is_artificial_facet(is_artificial_facet) + m_is_permissive_facet(is_permissive_facet) { CGAL_assertion(priority >= 0); } @@ -60,7 +60,7 @@ class Gate public: const Facet& facet() const { return m_facet; } const FT& priority() const { return m_priority; } - bool is_artificial_facet() const { return m_is_artificial_facet; } + bool is_permissive_facet() const { return m_is_permissive_facet; } }; struct Less_gate @@ -68,14 +68,14 @@ struct Less_gate template bool operator()(const Gate& a, const Gate& b) const { - // If one is artificial and the other is not, give priority to the artificial facet + // If one is permissive and the other is not, give priority to the permissive facet // - // The artificial facet are given highest priority because they need to be treated + // The permissive facet are given highest priority because they need to be treated // regardless of their circumradius. Treating them first allow the part that depends // on alpha to be treated uniformly in a way: whatever the alpha, we'll do the same // first treatmen - if(a.is_artificial_facet() != b.is_artificial_facet()) - return a.is_artificial_facet(); + if(a.is_permissive_facet() != b.is_permissive_facet()) + return a.is_permissive_facet(); if(a.priority() == b.priority()) { diff --git a/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp index a1b29fd5689d..e66d6c83dd3f 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp @@ -113,10 +113,10 @@ struct Iterative_AW3_visualization_visitor if(!points || !faces || !fcolors || !vcolors) return; - // If the next top of the queue has vertices on the bbox, don't draw (as to avoid producing + // If the next top of the queue has vertices on the bbox, don't draw (try to avoid producing // spikes in the visualization) // const auto& gate = wrapper.queue().top(); -// if(wrapper.triangulation().number_of_vertices() > 500 && gate.is_artificial_facet()) +// if(wrapper.triangulation().number_of_vertices() > 500 && gate.is_permissive_facet()) // return; // Skip some... @@ -216,7 +216,7 @@ struct AW3_interrupter_visitor { } // Only overload this one because it gives a better state of the wrap (for other visitor calls, - // we often get tetrahedral spikes because there are artificial gates in the queue) + // we often get tetrahedral spikes because there are scaffolding gates in the queue) template void before_Steiner_point_insertion(const Wrapper& wrapper, const Point& p) { From 7d12160e185cfe8b7cde24138d6e4372197ef626 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 3 Oct 2023 11:52:04 +0200 Subject: [PATCH 120/329] update doc --- .../PackageDescription.txt | 1 + .../Polygon_mesh_processing/CMakeLists.txt | 2 + .../geodesic_isolevel_refinement.cpp} | 33 +++++++++----- .../{internal => }/refine_mesh_at_isolevel.h | 44 ++++++++++++------- .../Polygon_mesh_processing/CMakeLists.txt | 5 --- .../test_geodesic_isolevel_refinement.cmd | 1 - 6 files changed, 51 insertions(+), 35 deletions(-) rename Polygon_mesh_processing/{test/Polygon_mesh_processing/test_geodesic_isolevel_refinement.cpp => examples/Polygon_mesh_processing/geodesic_isolevel_refinement.cpp} (65%) rename Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/{internal => }/refine_mesh_at_isolevel.h (79%) delete mode 100644 Polygon_mesh_processing/test/Polygon_mesh_processing/test_geodesic_isolevel_refinement.cmd diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt index b17c41399d0b..1d17b286dc5c 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt @@ -258,6 +258,7 @@ The page \ref bgl_namedparameters "Named Parameters" describes their usage. - `CGAL::Polygon_mesh_processing::triangle()` - `CGAL::Polygon_mesh_processing::region_growing_of_planes_on_faces()` - `CGAL::Polygon_mesh_processing::detect_corners_of_regions()` +- `CGAL::Polygon_mesh_processing::refine_mesh_at_isolevel()` \cgalCRPSection{I/O Functions} - \link PMP_IO_grp `CGAL::Polygon_mesh_processing::IO::read_polygon_mesh()`\endlink diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt b/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt index c755ecf63e8e..0ad5f79a261b 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt @@ -73,6 +73,8 @@ if(TARGET CGAL::Eigen3_support) target_link_libraries(delaunay_remeshing_example PUBLIC CGAL::Eigen3_support) create_single_source_cgal_program("remesh_almost_planar_patches.cpp") target_link_libraries(remesh_almost_planar_patches PUBLIC CGAL::Eigen3_support) + create_single_source_cgal_program("geodesic_isolevel_refinement.cpp") + target_link_libraries(geodesic_isolevel_refinement PUBLIC CGAL::Eigen3_support) else() message(STATUS "NOTICE: Examples that use Eigen will not be compiled.") endif() diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_geodesic_isolevel_refinement.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/geodesic_isolevel_refinement.cpp similarity index 65% rename from Polygon_mesh_processing/test/Polygon_mesh_processing/test_geodesic_isolevel_refinement.cpp rename to Polygon_mesh_processing/examples/Polygon_mesh_processing/geodesic_isolevel_refinement.cpp index a2098c63e3b9..76f97bf3dc66 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_geodesic_isolevel_refinement.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/geodesic_isolevel_refinement.cpp @@ -3,7 +3,7 @@ #include -#include +#include #include #include @@ -21,7 +21,7 @@ typedef CGAL::Heat_method_3::Surface_mesh_geodesic_distances_3 He int main(int argc, char* argv[]) { - const char* filename = argv[1]; + const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/elephant.off"); Triangle_mesh tm; if(!CGAL::IO::read_polygon_mesh(filename, tm) || @@ -31,33 +31,42 @@ int main(int argc, char* argv[]) return EXIT_FAILURE; } + // default isovalues for cutting the mesh + std::vector isovalues = {0.001, 0.01, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 10}; + + if (argc>2) + { + isovalues.clear(); + for (int i=2; i("v:distance", 0).first; Heat_method hm(tm); - //add the first vertex as the source set + //use heat method to compute approximated geodesic distances to the source vertex `s` vertex_descriptor s = *(vertices(tm).first); hm.add_source(s); hm.estimate_geodesic_distances(vertex_distance); - //property map for the constrained status of edges + // property map to flag new cut edge added in the mesh auto ecm = tm.add_property_map("e:is_constrained", 0).first; + // refine the mesh along isovalues + for (double isovalue : isovalues) + CGAL::Polygon_mesh_processing::refine_mesh_at_isolevel(tm, vertex_distance, isovalue, CGAL::parameters::edge_is_constrained_map(ecm)); - for (int i=2; i splitted; - CGAL::Polygon_mesh_processing::split_connected_components(tm, splitted, CGAL::parameters::edge_is_constrained_map(ecm)); -#ifdef CGAL_TEST_SUITE - assert(splitted.size() == 22); -#else + assert(argc!=1 || splitted.size() == 22); + + // export each submesh in a file for(std::size_t i=0; i::%vertex_descriptor` - * as key type and with its value type being model of `LessThanComparable`. + * @tparam ValueMap a model of the concept `ReadWritePropertyMap` with `boost::graph_traits::%vertex_descriptor` + * as key type and with its value type being the type of the coordinates of points associated with vertices + * in the vertex map provided to the `vertex_point_map()` named parameter. * @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" for `pm` * - * @param pm the polygon mesh to be refined - * @param value_map the property map containing value at each vertex for a given function defined over the mesh - * @param isovalue the value used to defined the cut locus of edges having their incident vertices associated with - * values respectively larger and smaller than `isovalue` in `value_map` + * @param pm the polygon mesh to be refined. + * @param value_map the property map containing value at each vertex for a given function defined over the mesh. + * @param isovalue the value used to defined * @param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below * * \cgalNamedParamsBegin * \cgalParamNBegin{edge_is_constrained_map} - * \cgalParamDescription{an ouput property map associating `true` to all new edges added by the cut, and false to input edges. + * \cgalParamDescription{an ouput property map associating `true` to all new edges added by the cut, and false to input edges.} * \cgalParamType{a class model of `WritablePropertyMap` with `boost::graph_traits::%edge_descriptor` * as key type and `bool` as value type} * \cgalParamDefault{No marks on edges will be put} + * \cgalParamNEnd + * * \cgalParamNBegin{vertex_point_map} * \cgalParamDescription{a property map associating points to the vertices of `pm`} * \cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits::%vertex_descriptor` @@ -53,7 +62,7 @@ namespace experimental { * \cgalNamedParamsEnd * */ -template +template void refine_mesh_at_isolevel(PolygonMesh& pm, ValueMap value_map, typename boost::property_traits::value_type isovalue, @@ -63,6 +72,7 @@ void refine_mesh_at_isolevel(PolygonMesh& pm, typedef typename boost::graph_traits::edge_descriptor edge_descriptor; typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::face_descriptor face_descriptor; + typedef typename boost::property_map::value_type FT; using parameters::choose_parameter; using parameters::get_parameter; @@ -113,9 +123,9 @@ void refine_mesh_at_isolevel(PolygonMesh& pm, for (edge_descriptor e : to_split) { vertex_descriptor src = source(e, pm), tgt = target(e, pm); - double ds = get(value_map, src); - double dt = get(value_map, tgt); - double alpha = (isovalue - dt) / (ds - dt); + FT ds = get(value_map, src); + FT dt = get(value_map, tgt); + FT alpha = (isovalue - dt) / (ds - dt); halfedge_descriptor hnew = CGAL::Euler::split_edge(halfedge(e, pm), pm); put(vpm, target(hnew, pm), barycenter(get(vpm,src), alpha, get(vpm, tgt), 1-alpha)); put(value_map, target(hnew, pm) , isovalue); @@ -146,7 +156,7 @@ void refine_mesh_at_isolevel(PolygonMesh& pm, } } -} } } // end of CGAL::Polygon_mesh_processing::experimental +} } // end of CGAL::Polygon_mesh_processing #endif diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt b/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt index 6f5d1e7c7ce9..eb9b98cbe593 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt @@ -125,11 +125,6 @@ else() message(STATUS "NOTICE: Tests are not using Ceres.") endif() -if (TARGET CGAL::Eigen3_support) - create_single_source_cgal_program("test_geodesic_isolevel_refinement.cpp") - target_link_libraries( test_geodesic_isolevel_refinement PUBLIC CGAL::Eigen3_support) -endif() - if(BUILD_TESTING) set_tests_properties( "execution of triangulate_hole_Polyhedron_3_no_delaunay_test" diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_geodesic_isolevel_refinement.cmd b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_geodesic_isolevel_refinement.cmd deleted file mode 100644 index 36105ee3a020..000000000000 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_geodesic_isolevel_refinement.cmd +++ /dev/null @@ -1 +0,0 @@ -${CGAL_DATA_DIR}/meshes/elephant.off 0.001 0.01 0.05 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 10 From 42b5aab4b170761f473d8464eea4bba75ee8d7cd Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 3 Oct 2023 11:18:58 +0200 Subject: [PATCH 121/329] Update Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/refine_mesh_at_isolevel.h --- .../CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h index 7e916fc76980..8a649b15ead4 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h @@ -45,7 +45,7 @@ namespace Polygon_mesh_processing { * * \cgalNamedParamsBegin * \cgalParamNBegin{edge_is_constrained_map} - * \cgalParamDescription{an ouput property map associating `true` to all new edges added by the cut, and false to input edges.} + * \cgalParamDescription{an output property map associating `true` to all new edges added by the cut, and `false` to input edges.} * \cgalParamType{a class model of `WritablePropertyMap` with `boost::graph_traits::%edge_descriptor` * as key type and `bool` as value type} * \cgalParamDefault{No marks on edges will be put} From ad5ae27c42ccf59683cd84a6ac52c6d6c6043d0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 4 Oct 2023 22:49:06 +0200 Subject: [PATCH 122/329] Factorize code generating filenames out of examples --- .../Alpha_wrap_3/mixed_inputs_wrap.cpp | 5 +++-- .../examples/Alpha_wrap_3/output_helper.h | 19 +++++++++++++++++++ .../examples/Alpha_wrap_3/point_set_wrap.cpp | 8 +++----- .../Alpha_wrap_3/successive_wraps.cpp | 9 +++------ .../Alpha_wrap_3/triangle_mesh_wrap.cpp | 9 +++------ .../Alpha_wrap_3/triangle_soup_wrap.cpp | 9 +++------ .../examples/Alpha_wrap_3/volumetric_wrap.cpp | 9 +++------ .../Alpha_wrap_3/wrap_from_cavity.cpp | 8 +++----- 8 files changed, 40 insertions(+), 36 deletions(-) create mode 100644 Alpha_wrap_3/examples/Alpha_wrap_3/output_helper.h diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/mixed_inputs_wrap.cpp b/Alpha_wrap_3/examples/Alpha_wrap_3/mixed_inputs_wrap.cpp index 4e96d6c1116c..fdba4de5f514 100644 --- a/Alpha_wrap_3/examples/Alpha_wrap_3/mixed_inputs_wrap.cpp +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/mixed_inputs_wrap.cpp @@ -120,8 +120,9 @@ int main(int argc, char** argv) std::string ps_name = std::string(ps_filename); ps_name = ps_name.substr(ps_name.find_last_of("/") + 1, ps_name.length() - 1); ps_name = ps_name.substr(0, ps_name.find_last_of(".")); - std::string output_name = ts_name + "_" + ss_name + "_" + ps_name + "_" + std::to_string(static_cast(relative_alpha)) - + "_" + std::to_string(static_cast(relative_offset)) + ".off"; + std::string output_name = ts_name + "_" + ss_name + "_" + ps_name + "_" + + std::to_string(static_cast(relative_alpha)) + "_" + + std::to_string(static_cast(relative_offset)) + ".off"; std::cout << "Writing to " << output_name << std::endl; CGAL::IO::write_polygon_mesh(output_name, wrap, CGAL::parameters::stream_precision(17)); diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/output_helper.h b/Alpha_wrap_3/examples/Alpha_wrap_3/output_helper.h new file mode 100644 index 000000000000..3ce1155f4ef5 --- /dev/null +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/output_helper.h @@ -0,0 +1,19 @@ +#ifndef CGAL_ALPHA_WRAP_3_EXAMPLES_OUTPUT_HELPER_H +#define CGAL_ALPHA_WRAP_3_EXAMPLES_OUTPUT_HELPER_H + +#include + +std::string generate_output_name(std::string input_name, + const double alpha, + const double offset) +{ + input_name = input_name.substr(input_name.find_last_of("/") + 1, input_name.length() - 1); + input_name = input_name.substr(0, input_name.find_last_of(".")); + std::string output_name = input_name + + "_" + std::to_string(static_cast(alpha)) + + "_" + std::to_string(static_cast(offset)) + ".off"; + + return output_name; +} + +#endif // CGAL_ALPHA_WRAP_3_EXAMPLES_OUTPUT_HELPER_H \ No newline at end of file diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/point_set_wrap.cpp b/Alpha_wrap_3/examples/Alpha_wrap_3/point_set_wrap.cpp index aeb47b80152e..a602cf5c58bf 100644 --- a/Alpha_wrap_3/examples/Alpha_wrap_3/point_set_wrap.cpp +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/point_set_wrap.cpp @@ -1,3 +1,5 @@ +#include "output_helper.h" + #include #include @@ -53,11 +55,7 @@ int main(int argc, char** argv) std::cout << "Took " << t.time() << " s." << std::endl; // Save the result - std::string input_name = std::string(filename); - input_name = input_name.substr(input_name.find_last_of("/") + 1, input_name.length() - 1); - input_name = input_name.substr(0, input_name.find_last_of(".")); - std::string output_name = input_name + "_" + std::to_string(static_cast(relative_alpha)) - + "_" + std::to_string(static_cast(relative_offset)) + ".off"; + const std::string output_name = generate_output_name(filename, relative_alpha, relative_offset); std::cout << "Writing to " << output_name << std::endl; CGAL::IO::write_polygon_mesh(output_name, wrap, CGAL::parameters::stream_precision(17)); diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/successive_wraps.cpp b/Alpha_wrap_3/examples/Alpha_wrap_3/successive_wraps.cpp index 59010d1212ea..f9b35f88b1f7 100644 --- a/Alpha_wrap_3/examples/Alpha_wrap_3/successive_wraps.cpp +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/successive_wraps.cpp @@ -1,5 +1,7 @@ #define CGAL_AW3_TIMER +#include "output_helper.h" + #include #include @@ -69,12 +71,7 @@ int main(int argc, char** argv) std::cout << " Result: " << num_vertices(wrap) << " vertices, " << num_faces(wrap) << " faces" << std::endl; std::cout << " Elapsed time: " << t.time() << " s." << std::endl; - std::string input_name = std::string(filename); - input_name = input_name.substr(input_name.find_last_of("/") + 1, input_name.length() - 1); - input_name = input_name.substr(0, input_name.find_last_of(".")); - std::string output_name = input_name - + "_" + std::to_string(static_cast(relative_alphas[i])) - + "_" + std::to_string(static_cast(relative_offset)) + ".off"; + const std::string output_name = generate_output_name(filename, relative_alphas[i], relative_offset); std::cout << "Writing to " << output_name << std::endl; CGAL::IO::write_polygon_mesh(output_name, wrap, CGAL::parameters::stream_precision(17)); diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/triangle_mesh_wrap.cpp b/Alpha_wrap_3/examples/Alpha_wrap_3/triangle_mesh_wrap.cpp index 369cf375a6ff..d49534904461 100644 --- a/Alpha_wrap_3/examples/Alpha_wrap_3/triangle_mesh_wrap.cpp +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/triangle_mesh_wrap.cpp @@ -1,3 +1,5 @@ +#include "output_helper.h" + #include #include @@ -56,12 +58,7 @@ int main(int argc, char** argv) std::cout << "Took " << t.time() << " s." << std::endl; // Save the result - std::string input_name = std::string(filename); - input_name = input_name.substr(input_name.find_last_of("/") + 1, input_name.length() - 1); - input_name = input_name.substr(0, input_name.find_last_of(".")); - std::string output_name = input_name - + "_" + std::to_string(static_cast(relative_alpha)) - + "_" + std::to_string(static_cast(relative_offset)) + ".off"; + const std::string output_name = generate_output_name(filename, relative_alpha, relative_offset); std::cout << "Writing to " << output_name << std::endl; CGAL::IO::write_polygon_mesh(output_name, wrap, CGAL::parameters::stream_precision(17)); diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/triangle_soup_wrap.cpp b/Alpha_wrap_3/examples/Alpha_wrap_3/triangle_soup_wrap.cpp index 6e1321c302dd..51e04974c28a 100644 --- a/Alpha_wrap_3/examples/Alpha_wrap_3/triangle_soup_wrap.cpp +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/triangle_soup_wrap.cpp @@ -1,3 +1,5 @@ +#include "output_helper.h" + #include #include @@ -63,12 +65,7 @@ int main(int argc, char** argv) std::cout << "Took " << t.time() << " s." << std::endl; // Save the result - std::string input_name = std::string(filename); - input_name = input_name.substr(input_name.find_last_of("/") + 1, input_name.length() - 1); - input_name = input_name.substr(0, input_name.find_last_of(".")); - std::string output_name = input_name - + "_" + std::to_string(static_cast(relative_alpha)) - + "_" + std::to_string(static_cast(relative_offset)) + ".off"; + const std::string output_name = generate_output_name(filename, relative_alpha, relative_offset); std::cout << "Writing to " << output_name << std::endl; CGAL::IO::write_polygon_mesh(output_name, wrap, CGAL::parameters::stream_precision(17)); diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/volumetric_wrap.cpp b/Alpha_wrap_3/examples/Alpha_wrap_3/volumetric_wrap.cpp index 682cffac3390..3ac28de33022 100644 --- a/Alpha_wrap_3/examples/Alpha_wrap_3/volumetric_wrap.cpp +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/volumetric_wrap.cpp @@ -1,3 +1,5 @@ +#include "output_helper.h" + #include #include @@ -113,12 +115,7 @@ int main(int argc, char** argv) auto dt = aw3.triangulation(); // Save the result - std::string input_name = std::string(filename); - input_name = input_name.substr(input_name.find_last_of("/") + 1, input_name.length() - 1); - input_name = input_name.substr(0, input_name.find_last_of(".")); - std::string output_name = input_name - + "_" + std::to_string(static_cast(relative_alpha)) - + "_" + std::to_string(static_cast(relative_offset)) + ".off"; + const std::string output_name = generate_output_name(filename, relative_alpha, relative_offset); std::cout << "Writing to " << output_name << std::endl; CGAL::IO::write_polygon_mesh(output_name, wrap, CGAL::parameters::stream_precision(17)); diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/wrap_from_cavity.cpp b/Alpha_wrap_3/examples/Alpha_wrap_3/wrap_from_cavity.cpp index 9de47aefbcd2..9422e4d969be 100644 --- a/Alpha_wrap_3/examples/Alpha_wrap_3/wrap_from_cavity.cpp +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/wrap_from_cavity.cpp @@ -1,3 +1,5 @@ +#include "output_helper.h" + #include #include @@ -64,11 +66,7 @@ int main(int argc, char** argv) std::cout << "Took " << t.time() << " s." << std::endl; // Save the result - std::string input_name = std::string(filename); - input_name = input_name.substr(input_name.find_last_of("/") + 1, input_name.length() - 1); - input_name = input_name.substr(0, input_name.find_last_of(".")); - std::string output_name = input_name + "_cavity_" + std::to_string(static_cast(relative_alpha)) - + "_" + std::to_string(static_cast(relative_offset)) + ".off"; + const std::string output_name = generate_output_name(filename, relative_alpha, relative_offset); std::cout << "Writing to " << output_name << std::endl; CGAL::IO::write_polygon_mesh(output_name, wrap, CGAL::parameters::stream_precision(17)); From 660d6203308e7e32bbe37b0aea020f9a818459a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 4 Oct 2023 22:52:32 +0200 Subject: [PATCH 123/329] Accelerate trees manually to avoid skewing timers in flood_fill() If one day this becomes annoying because one wishes to call oracle.add_XXX() multiple times AND it's a significant runtime burden, we can just add a function add_XXXs() with a single call of accelerate_distance_queries() --- .../include/CGAL/Alpha_wrap_3/internal/Point_set_oracle.h | 6 ++++++ .../CGAL/Alpha_wrap_3/internal/Segment_soup_oracle.h | 6 ++++++ .../CGAL/Alpha_wrap_3/internal/Triangle_mesh_oracle.h | 6 ++++++ .../CGAL/Alpha_wrap_3/internal/Triangle_soup_oracle.h | 6 ++++++ 4 files changed, 24 insertions(+) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Point_set_oracle.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Point_set_oracle.h index 7bad2ff313d4..8ccbf049a33e 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Point_set_oracle.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Point_set_oracle.h @@ -115,6 +115,12 @@ class Point_set_oracle this->tree().insert(std::next(std::cbegin(m_points), old_size), std::cend(m_points)); + // Manually constructing it here purely for profiling reasons: if we keep the lazy approach, + // it will be done at the first treatment of a facet that needs a Steiner point. + // So if one wanted to bench the flood fill runtime, it would be skewed by the time it takes + // to accelerate the tree. + this->tree().accelerate_distance_queries(); + CGAL_postcondition(this->tree().size() == m_points.size()); } }; diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Segment_soup_oracle.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Segment_soup_oracle.h index d02a9f9faaf8..08e76dc6f5d3 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Segment_soup_oracle.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Segment_soup_oracle.h @@ -113,6 +113,12 @@ class Segment_soup_oracle #endif this->tree().insert(std::next(std::cbegin(m_segments), old_size), std::cend(m_segments)); + // Manually constructing it here purely for profiling reasons: if we keep the lazy approach, + // it will be done at the first treatment of a facet that needs a Steiner point. + // So if one wanted to bench the flood fill runtime, it would be skewed by the time it takes + // to accelerate the tree. + this->tree().accelerate_distance_queries(); + CGAL_postcondition(this->tree().size() == m_segments.size()); } }; diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_mesh_oracle.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_mesh_oracle.h index c87f82ac75fe..869c108693d2 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_mesh_oracle.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_mesh_oracle.h @@ -164,6 +164,12 @@ class Triangle_mesh_oracle Splitter_base::split_and_insert_datum(tr, this->tree(), this->geom_traits()); } + // Manually constructing it here purely for profiling reasons: if we keep the lazy approach, + // it will be done at the first treatment of a facet that needs a Steiner point. + // So if one wanted to bench the flood fill runtime, it would be skewed by the time it takes + // to accelerate the tree. + this->tree().accelerate_distance_queries(); + #ifdef CGAL_AW3_DEBUG std::cout << "Tree: " << this->tree().size() << " primitives (" << num_faces(tmesh) << " faces in input)" << std::endl; #endif diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_soup_oracle.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_soup_oracle.h index 0a8f589fc2df..35966be46447 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_soup_oracle.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_soup_oracle.h @@ -169,6 +169,12 @@ class Triangle_soup_oracle Splitter_base::split_and_insert_datum(tr, this->tree(), this->geom_traits()); } + // Manually constructing it here purely for profiling reasons: if we keep the lazy approach, + // it will be done at the first treatment of a facet that needs a Steiner point. + // So if one wanted to bench the flood fill runtime, it would be skewed by the time it takes + // to accelerate the tree. + this->tree().accelerate_distance_queries(); + #ifdef CGAL_AW3_DEBUG std::cout << "Tree: " << this->tree().size() << " primitives (" << faces.size() << " faces in input)" << std::endl; #endif From 88468764767950cda8daae96f5ab47885776afa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 4 Oct 2023 22:54:06 +0200 Subject: [PATCH 124/329] Check for degenerate segments + add warnings --- .../internal/Segment_soup_oracle.h | 20 +++++++++++++++++-- .../internal/Triangle_mesh_oracle.h | 5 +++++ .../internal/Triangle_soup_oracle.h | 10 ++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Segment_soup_oracle.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Segment_soup_oracle.h index 08e76dc6f5d3..63f3532cf67e 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Segment_soup_oracle.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Segment_soup_oracle.h @@ -40,7 +40,8 @@ struct SS_oracle_traits { using Geom_traits = Alpha_wrap_AABB_geom_traits; // Wrap the kernel to add Ball_3 + custom Do_intersect_3 - using Segments = std::vector; + using Segment = typename GT_::Segment_3; + using Segments = std::vector; using SR_iterator = typename Segments::const_iterator; using Primitive = AABB_primitive; @@ -105,8 +107,22 @@ class Segment_soup_oracle return; } + typename Geom_traits::Is_degenerate_3 is_degenerate = this->geom_traits().is_degenerate_3_object(); + const std::size_t old_size = m_segments.size(); - m_segments.insert(std::cend(m_segments), std::cbegin(segments), std::cend(segments)); + + for(const Segment& s : segments) + { + if(is_degenerate(s)) + { +#ifdef CGAL_AW3_DEBUG + std::cerr << "Warning: ignoring degenerate segment " << s << std::endl; +#endif + continue; + } + + m_segments.push_back(s); + } #ifdef CGAL_AW3_DEBUG std::cout << "Insert into AABB tree (segments)..." << std::endl; diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_mesh_oracle.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_mesh_oracle.h index 869c108693d2..ffd8326a44f6 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_mesh_oracle.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_mesh_oracle.h @@ -153,7 +153,12 @@ class Triangle_mesh_oracle for(face_descriptor f : faces(tmesh)) { if(Polygon_mesh_processing::is_degenerate_triangle_face(f, tmesh, np)) + { +#ifdef CGAL_AW3_DEBUG + std::cerr << "Warning: ignoring degenerate face " << f << std::endl; +#endif continue; + } const Point_ref p0 = get(vpm, source(halfedge(f, tmesh), tmesh)); const Point_ref p1 = get(vpm, target(halfedge(f, tmesh), tmesh)); diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_soup_oracle.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_soup_oracle.h index 35966be46447..27322a554e36 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_soup_oracle.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_soup_oracle.h @@ -164,7 +164,12 @@ class Triangle_soup_oracle const Triangle_3 tr = triangle(p0, p1, p2); if(is_degenerate(tr)) + { +#ifdef CGAL_AW3_DEBUG + std::cerr << "Warning: ignoring degenerate face " << tr << std::endl; +#endif continue; + } Splitter_base::split_and_insert_datum(tr, this->tree(), this->geom_traits()); } @@ -190,7 +195,12 @@ class Triangle_soup_oracle for(const Triangle_3& tr : triangles) { if(is_degenerate(tr)) + { +#ifdef CGAL_AW3_DEBUG + std::cerr << "Warning: ignoring degenerate triangle " << tr << std::endl; +#endif continue; + } Splitter_base::split_and_insert_datum(tr, this->tree(), this->geom_traits()); } From 8e36b7b37e6dd2e14d55e3997d70d1ec3b0af26e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 5 Oct 2023 09:32:22 +0200 Subject: [PATCH 125/329] the map is either const or take by copy --- Property_map/include/CGAL/property_map.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Property_map/include/CGAL/property_map.h b/Property_map/include/CGAL/property_map.h index 12fd06503fee..f1115cbf05a8 100644 --- a/Property_map/include/CGAL/property_map.h +++ b/Property_map/include/CGAL/property_map.h @@ -661,7 +661,7 @@ struct Boolean_property_map return pm.set_ptr->count(k) != 0; } - friend void put(Boolean_property_map& pm, const key_type& k, bool v) + friend void put(Boolean_property_map pm, const key_type& k, bool v) { CGAL_assertion(pm.set_ptr!=nullptr); if (v) From 85c53f203ddf9ee118e401e8dae11bb84c8bfa63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Thu, 5 Oct 2023 14:33:47 +0200 Subject: [PATCH 126/329] Add a new function to the AW3 visitor: go_further() --- .../CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index 7c9509b9185a..c103a4e4c41e 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -92,6 +92,9 @@ struct Wrapping_default_visitor template void on_flood_fill_begin(const AlphaWrapper&) { } + template + constexpr bool go_further(const Wrapper& wrapper) { return true; } + template void before_facet_treatment(const AlphaWrapper&, const Gate&) { } @@ -1212,7 +1215,7 @@ class Alpha_wrap_3 } template - void alpha_flood_fill(Visitor& visitor) + bool alpha_flood_fill(Visitor& visitor) { #ifdef CGAL_AW3_DEBUG std::cout << "> Flood fill..." << std::endl; @@ -1251,10 +1254,6 @@ class Alpha_wrap_3 std::cout << "Permissiveness: " << gate.is_permissive_facet() << std::endl; #endif - visitor.before_facet_treatment(*this, gate); - - m_queue.pop(); - #ifdef CGAL_AW3_DEBUG_DUMP_EVERY_STEP static int i = 0; std::string step_name = "results/steps/step_" + std::to_string(static_cast(i)) + ".off"; @@ -1269,6 +1268,13 @@ class Alpha_wrap_3 face_out.close(); #endif + if(!visitor.go_further(*this)) + return false; + + visitor.before_facet_treatment(*this, gate); + + m_queue.pop(); + if(m_tr.is_infinite(neighbor)) { neighbor->is_outside() = true; @@ -1384,6 +1390,8 @@ class Alpha_wrap_3 CGAL_postcondition_code( if(!fit->first->is_outside()) f = m_tr.mirror_facet(f);) CGAL_postcondition( facet_status(f) == IRRELEVANT); CGAL_postcondition_code(}) + + return true; } private: From 3ff06d5099471c39a9e0c364138e38f7dc75634d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Thu, 5 Oct 2023 14:34:29 +0200 Subject: [PATCH 127/329] Fix return type of function returning smallest circumradius --- .../include/CGAL/Alpha_wrap_3/internal/geometry_utils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/geometry_utils.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/geometry_utils.h index f39a47012862..991f9e48e25a 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/geometry_utils.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/geometry_utils.h @@ -155,7 +155,7 @@ less_squared_radius_of_min_empty_sphere(typename Tr::Geom_traits::FT sq_alpha, } template -bool +typename Tr::Geom_traits::FT smallest_squared_radius_3(const typename Tr::Facet& fh, const Tr& tr) { From 76add8023e6bec512e7cdb7f6e234fd6835f20ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Thu, 5 Oct 2023 14:35:42 +0200 Subject: [PATCH 128/329] Add debug code --- .../CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 2 +- .../Alpha_wrap_3/internal/geometry_utils.h | 41 +++++++++++++++++-- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index c103a4e4c41e..9792b828a610 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -671,7 +671,7 @@ class Alpha_wrap_3 } t.stop(); - std::cout << t.time() << " for scanning" << std::endl; + std::cout << t.time() << " for scanning a queue of size " << m_queue.size() << std::endl; return true; } diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/geometry_utils.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/geometry_utils.h index 991f9e48e25a..7f5f60de701c 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/geometry_utils.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/geometry_utils.h @@ -61,6 +61,10 @@ less_squared_radius_of_min_empty_sphere(typename Tr::Geom_traits::FT sq_alpha, Orientation_of_circumcenter orientation_of_circumcenter; +#ifdef CGAL_AW3_DEBUG_TRAVERSABILITY + std::cout << "Checking for traversability of facet" << std::endl; +#endif + const Cell_handle c = fh.first; const int ic = fh.second; const Cell_handle n = c->neighbor(ic); @@ -73,6 +77,11 @@ less_squared_radius_of_min_empty_sphere(typename Tr::Geom_traits::FT sq_alpha, // and because it does not cost anything. if(tr.is_infinite(n)) { +#ifdef CGAL_AW3_DEBUG_TRAVERSABILITY + std::cerr << "Warning: computing less_squared_radius_of_min_empty_sphere() with an infinite neighbor?" << std::endl; +#endif + CGAL_assertion(!tr.is_infinite(c)); + Orientation ori = orientation_of_circumcenter(p1, p2, p3, tr.point(c, 0), tr.point(c, 1), tr.point(c, 2), tr.point(c, 3)); @@ -97,6 +106,10 @@ less_squared_radius_of_min_empty_sphere(typename Tr::Geom_traits::FT sq_alpha, tr.point(n, 0), tr.point(n, 1), tr.point(n, 2), tr.point(n, 3)); +#ifdef CGAL_AW3_DEBUG_TRAVERSABILITY + std::cout << "Cell 'c' is infinite; Orientation: " << ori << std::endl; +#endif + if(ori == NEGATIVE) { Comparison_result cr = compare_squared_radius(p1, p2, p3, sq_alpha); @@ -177,6 +190,12 @@ smallest_squared_radius_3(const typename Tr::Facet& fh, auto squared_radius = tr.geom_traits().compute_squared_radius_3_object(); +#ifdef CGAL_AW3_DEBUG_TRAVERSABILITY + std::cout << "Computing circumradius of facet" << std::endl; +#endif + + CGAL_precondition(!tr.is_infinite(fh)); + const Cell_handle c = fh.first; const int ic = fh.second; const Cell_handle n = c->neighbor(ic); @@ -189,6 +208,8 @@ smallest_squared_radius_3(const typename Tr::Facet& fh, // and because it does not cost anything. if(tr.is_infinite(n)) { + CGAL_assertion(!tr.is_infinite(c)); + Orientation ori = orientation_of_circumcenter(p1, p2, p3, tr.point(c, 0), tr.point(c, 1), tr.point(c, 2), tr.point(c, 3)); @@ -203,6 +224,11 @@ smallest_squared_radius_3(const typename Tr::Facet& fh, Orientation ori = orientation_of_circumcenter(p1, p2, p3, tr.point(n, 0), tr.point(n, 1), tr.point(n, 2), tr.point(n, 3)); + +#ifdef CGAL_AW3_DEBUG_TRAVERSABILITY + std::cout << "Cell 'c' is infinite; Orientation: " << ori << std::endl; +#endif + if(ori == NEGATIVE) return squared_radius(p1, p2, p3); else @@ -215,14 +241,21 @@ smallest_squared_radius_3(const typename Tr::Facet& fh, orientation_of_circumcenter(p1, p2, p3, tr.point(n, 0), tr.point(n, 1), tr.point(n, 2), tr.point(n, 3))) { - // Dual crosses the face +#ifdef CGAL_AW3_DEBUG_TRAVERSABILITY + std::cout << "dual crosses the face; CR: " << squared_radius(p1, p2, p3) << std::endl; +#endif + return squared_radius(p1, p2, p3); } else { - // Dual does not crosses the face - FT cr = squared_radius(tr.point(c, 0), tr.point(c, 1), tr.point(c, 2), tr.point(c, 3)); - FT cnr = squared_radius(tr.point(n, 0), tr.point(n, 1), tr.point(n, 2), tr.point(n, 3)); + const FT cr = squared_radius(tr.point(c, 0), tr.point(c, 1), tr.point(c, 2), tr.point(c, 3)); + const FT cnr = squared_radius(tr.point(n, 0), tr.point(n, 1), tr.point(n, 2), tr.point(n, 3)); + +#ifdef CGAL_AW3_DEBUG_TRAVERSABILITY + std::cout << "dual does not cross the face; CR(c): " << cr << " CRn: " << cnr << std::endl; +#endif + return (CGAL::min)(cr, cnr); } } From fb3623cfa90f95e0163ac454352dcf427ab6fddd Mon Sep 17 00:00:00 2001 From: Sebastien Loriot Date: Mon, 9 Oct 2023 05:10:30 +0200 Subject: [PATCH 129/329] Apply suggestions from code review Co-authored-by: Andreas Fabri --- .../Polygon_mesh_processing/refine_mesh_at_isolevel.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h index 8a649b15ead4..7a3b2c0765e5 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h @@ -28,8 +28,8 @@ namespace Polygon_mesh_processing { * The placement of new vertices on edges will be done by linear interpolation * using the aforementioned values. * New vertices will be associated `isovalue` in `value_map` when created. - * Additionally new edges will be added by connecting new vertices created sharing - * a common incident face. Note that in case more that two new vertices are added + * Additionally, new edges will be added by connecting new vertices created sharing + * a common incident face. Note that in case more than two new vertices are added * on a face boundary, no edges will be created in that face. * * @tparam PolygonMesh a model of the concepts `EdgeListGraph` and `FaceListGraph` @@ -39,7 +39,7 @@ namespace Polygon_mesh_processing { * @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" for `pm` * * @param pm the polygon mesh to be refined. - * @param value_map the property map containing value at each vertex for a given function defined over the mesh. + * @param value_map the property map containing a value at each vertex for a given function defined over the mesh. * @param isovalue the value used to defined * @param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below * @@ -72,7 +72,7 @@ void refine_mesh_at_isolevel(PolygonMesh& pm, typedef typename boost::graph_traits::edge_descriptor edge_descriptor; typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::face_descriptor face_descriptor; - typedef typename boost::property_map::value_type FT; + typedef typename boost::property_traits::value_type FT; using parameters::choose_parameter; using parameters::get_parameter; From 1c91f49cbdafc980f1e6f32a74fb24b98bf12fa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 9 Oct 2023 05:14:38 +0200 Subject: [PATCH 130/329] update changes --- Installation/CHANGES.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Installation/CHANGES.md b/Installation/CHANGES.md index 8ee04d38577d..ef51234bb6e7 100644 --- a/Installation/CHANGES.md +++ b/Installation/CHANGES.md @@ -52,6 +52,10 @@ Release date: October 2023 `CGAL::Simplicial_mesh_cell_base_3` have been modified to enable passing a geometric traits and a custom cell base class. +### [Polygon Mesh Processing](https://doc.cgal.org/6.0/Manual/packages.html#PkgPolygonMeshProcessing) +- added the function `CGAL::Polygon_mesh_processing::refine_mesh_at_isolevel()` that refines a polygon mesh + along an isocurve. + [Release 5.6](https://github.com/CGAL/cgal/releases/tag/v5.6) ----------- From 584771e6a752d45d4089e33bfc01cef98f584aea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 9 Oct 2023 05:34:55 +0200 Subject: [PATCH 131/329] rename --- .../geodesic_isolevel_refinement.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/geodesic_isolevel_refinement.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/geodesic_isolevel_refinement.cpp index 76f97bf3dc66..29f43453e87a 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/geodesic_isolevel_refinement.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/geodesic_isolevel_refinement.cpp @@ -59,14 +59,14 @@ int main(int argc, char* argv[]) CGAL::Polygon_mesh_processing::refine_mesh_at_isolevel(tm, vertex_distance, isovalue, CGAL::parameters::edge_is_constrained_map(ecm)); // split the mesh in connected components bounded by the isocurves - std::vector splitted; - CGAL::Polygon_mesh_processing::split_connected_components(tm, splitted, CGAL::parameters::edge_is_constrained_map(ecm)); + std::vector edges_split; + CGAL::Polygon_mesh_processing::split_connected_components(tm, edges_split, CGAL::parameters::edge_is_constrained_map(ecm)); - assert(argc!=1 || splitted.size() == 22); + assert(argc!=1 || edges_split.size() == 22); // export each submesh in a file - for(std::size_t i=0; i Date: Mon, 9 Oct 2023 09:08:31 +0200 Subject: [PATCH 132/329] implement comments from review --- Installation/CHANGES.md | 4 ++-- .../CGAL/Polygon_mesh_processing/autorefinement.h | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Installation/CHANGES.md b/Installation/CHANGES.md index b361d15dec76..8748eda2db0a 100644 --- a/Installation/CHANGES.md +++ b/Installation/CHANGES.md @@ -39,8 +39,8 @@ Release date: October 2023 - Added the function `CGAL::Polygon_mesh_processing::autorefine_triangle_soup()` that refines a soup of triangles so that no pair of triangles intersects - (they can share an edge or a vertex). Also added, the function `autorefine()` operating directly on a triangle mesh and updating it - using the aforementioned function on triangle soup. + in their interiors. Also added, the function `autorefine()` operating directly on a triangle mesh and updating it + using the aforementioned function on a triangle soup. [Release 5.6](https://github.com/CGAL/cgal/releases/tag/v5.6) ----------- diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 884ce3477aa8..5b9cad98277d 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -1131,15 +1131,15 @@ void generate_subtriangles(std::size_t ti, * refines a soup of triangles so that no pair of triangles intersects. * Output triangles may share a common edge or a common vertex (but with the same indexed position in `points`). * Note that points in `soup_points` can only be added (intersection points) at the end of the container, with the initial order preserved. -* Note that if `soup_points` contains two or more identical points and only the first copy (following the order in the `soup_points`) +* Note that if `soup_points` contains two or more identical points then only the first copy (following the order in the `soup_points`) * will be used in `soup_triangles`. -* `soup_triangles` will be updated to contain both the input triangles and the new subdivides triangles. Degenerate triangles will be removed. +* `soup_triangles` will be updated to contain both the input triangles and the new subdivided triangles. Degenerate triangles will be removed. * Also triangles in `soup_triangles` will be triangles without intersection first, followed by triangles coming from a subdivision induced * by an intersection. The named parameter `visitor()` can be used to track * * @tparam PointRange a model of the concept `RandomAccessContainer` * whose value type is the point type -* @tparam TriIdsRange a model of the concepts `RandomAccessContainer`, `BackInsertionSequence` and `Swappable`, whose +* @tparam TriangleRange a model of the concepts `RandomAccessContainer`, `BackInsertionSequence` and `Swappable`, whose * value type is a model of the concept `RandomAccessContainer` whose value type is convertible to `std::size_t` and that * is constructible from an `std::initializer_list` of size 3. * @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" @@ -1174,9 +1174,9 @@ void generate_subtriangles(std::size_t ti, * \cgalNamedParamsEnd * */ -template +template void autorefine_triangle_soup(PointRange& soup_points, - TriIdsRange& soup_triangles, + TriangleRange& soup_triangles, const NamedParameters& np = parameters::default_values()) { using parameters::choose_parameter; @@ -1507,7 +1507,7 @@ void autorefine_triangle_soup(PointRange& soup_points, #endif } - TriIdsRange soup_triangles_out; + TriangleRange soup_triangles_out; soup_triangles_out.reserve(soup_triangles.size()); // TODO: remove #deg tri? visitor.number_of_output_triangles(soup_triangles.size()+new_triangles.size()); From 7de4f442e8ff9067d0ea3637fa504d9528d5bfcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 9 Oct 2023 12:12:31 +0200 Subject: [PATCH 133/329] Remove obsolete sort at every iteration There was a need for sorting at every iteration when the sorting used criteria which were changing with every iteration. This is no longer the case after c7b9317. Also make it deterministic. --- .../CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index 639c9a3f4685..ba4635889b4b 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -1440,15 +1440,17 @@ class Alpha_wrap_3 // Prioritize: // - cells without bbox vertices - // - cells that already have a large number of boundary facets // - small cells when equal number of boundary facets - // @todo give topmost priority to cells with > 1 non-manifold vertex? + // + // Note that these are properties that do not depend on where the surface is, so we can + // sort once. However, if a criterion such as the number of inside cells were added, + // one would need to sort again after each modification of is_outside() statuses. auto comparer = [&](Cell_handle l, Cell_handle r) -> bool { - if(has_artificial_vertex(l)) - return false; - if(has_artificial_vertex(r)) - return true; + CGAL_precondition(!m_dt.is_infinite(l) && !m_dt.is_infinite(r)); + + if(has_artificial_vertex(l) != has_artificial_vertex(r)) + return has_artificial_vertex(r); return sq_longest_edge(l) < sq_longest_edge(r); }; @@ -1457,17 +1459,13 @@ class Alpha_wrap_3 inc_cells.reserve(64); m_dt.finite_incident_cells(v, std::back_inserter(inc_cells)); -#define CGAL_AW3_USE_BRUTE_FORCE_MUTABLE_PRIORITY_QUEUE -#ifndef CGAL_AW3_USE_BRUTE_FORCE_MUTABLE_PRIORITY_QUEUE - std::sort(inc_cells.begin(), inc_cells.end(), comparer); // sort once -#endif + // 'std::stable_sort' to have determinism without having to write something like: + // if(longest_edge(l) == longest_edge(r)) return ... + // in the comparer. It's a small range, so the cost does not matter. + std::stable_sort(inc_cells.begin(), inc_cells.end(), comparer); for(auto cit=inc_cells.begin(), cend=inc_cells.end(); cit!=cend; ++cit) { -#ifdef CGAL_AW3_USE_BRUTE_FORCE_MUTABLE_PRIORITY_QUEUE - // sort at every iteration since the number of boundary facets evolves - std::sort(cit, cend, comparer); -#endif Cell_handle ic = *cit; CGAL_assertion(!m_dt.is_infinite(ic)); From 2f1992f131dd107d4c7cd3251181afb92cee12fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 9 Oct 2023 15:16:10 +0200 Subject: [PATCH 134/329] Add LIFO queue But keep the old one, because we might need something sorted in the future. Also it is needed to do interrupting, because the intermediate is really ugly for a LIFO queue. --- .../CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 72 +++++++++++++++---- .../Alpha_wrap_triangulation_cell_base_3.h | 27 ++++++- .../internal/gate_priority_queue.h | 40 +++++++++++ 3 files changed, 124 insertions(+), 15 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index 9792b828a610..08f09fcdd4ce 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -49,7 +49,9 @@ #include #include #include -#include +#ifdef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE + #include +#endif #include #include #include @@ -140,7 +142,18 @@ class Alpha_wrap_3 using Locate_type = typename Triangulation::Locate_type; using Gate = internal::Gate; + + // A sorted queue is a priority queue sorted by circumradius, and is experimentally much slower, + // but intermediate results are visually nice: somewhat uniform meshes. + // + // An unsorted queue is a LIFO queue, and is experimentally much faster (~35%), + // but intermediate results are not useful: a LIFO will mean carving is done very deep + // before than wide +#ifdef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE using Alpha_PQ = Modifiable_priority_queue, CGAL_BOOST_PAIRING_HEAP>; +#else + using Alpha_PQ = std::stack; +#endif using FT = typename Geom_traits::FT; using Point_3 = typename Geom_traits::Point_3; @@ -166,20 +179,27 @@ class Alpha_wrap_3 public: Alpha_wrap_3() +#ifdef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE + // '4096' is an arbitrary, not-too-small value for the largest ID in queue initialization : m_queue(4096) - { } - - Alpha_wrap_3(const Oracle& oracle) - : m_oracle(oracle), - m_tr(Geom_traits(oracle.geom_traits())), - // used to set up the initial MPQ, use some arbitrary not-too-small value - m_queue(4096) +#endif { // Due to the Steiner point computation being a dichotomy, the algorithm is inherently inexact // and passing exact kernels is explicitly disabled to ensure no misunderstanding. static_assert(std::is_floating_point::value); } + Alpha_wrap_3(const Oracle& oracle) + : +#ifdef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE + m_queue(4096), +#endif + m_oracle(oracle), + m_tr(Geom_traits(oracle.geom_traits())) + { + static_assert(std::is_floating_point::value); + } + public: const Geom_traits& geom_traits() const { return m_tr.geom_traits(); } Oracle& oracle() { return m_oracle; } @@ -1130,17 +1150,23 @@ class Alpha_wrap_3 { CGAL_precondition(f.first->is_outside()); +#ifdef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE // skip if f is already in queue if(m_queue.contains_with_bounds_check(Gate(f))) return false; +#endif const Facet_queue_status status = facet_status(f); if(status == IRRELEVANT) return false; +#ifdef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE const FT sqr = smallest_squared_radius_3(f, m_tr); const bool is_permissive = (status == HAS_INFINITE_NEIGHBOR || status == SCAFFOLDING); m_queue.resize_and_push(Gate(f, sqr, is_permissive)); +#else + m_queue.push(Gate(f, m_tr)); +#endif #ifdef CGAL_AW3_DEBUG_QUEUE const Cell_handle ch = f.first; @@ -1154,11 +1180,13 @@ class Alpha_wrap_3 << " ch = " << &*ch << " (" << m_tr.is_infinite(ch) << ") " << "\n" << "\t" << p0 << "\n\t" << p1 << "\n\t" << p2 << std::endl; std::cout << " Status: " << get_status_message(status) << std::endl; + #ifdef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE std::cout << " SQR: " << sqr << std::endl; std::cout << " Permissiveness: " << is_permissive << std::endl; -#endif CGAL_assertion(is_permissive || sqr >= m_sq_alpha); + #endif // CGAL_AW3_USE_SORTED_PRIORITY_QUEUE +#endif // CGAL_AW3_DEBUG_QUEUE return true; } @@ -1195,7 +1223,11 @@ class Alpha_wrap_3 m_offset = FT(offset); m_sq_offset = square(m_offset); +#ifdef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE m_queue.clear(); +#else + m_queue = { }; +#endif if(resuming) { @@ -1232,6 +1264,15 @@ class Alpha_wrap_3 // const& to something that will be popped, but safe as `ch` && `id` are extracted before the pop const Gate& gate = m_queue.top(); + +#ifndef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE + if(gate.is_zombie()) + { + m_queue.pop(); + continue; + } +#endif + const Facet& f = gate.facet(); CGAL_precondition(!m_tr.is_infinite(f)); @@ -1304,6 +1345,7 @@ class Alpha_wrap_3 std::back_inserter(boundary_facets), std::back_inserter(conflict_zone)); +#ifdef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE // Purge the queue of facets that will be deleted/modified by the Steiner point insertion, // and which might have been gates for(const Cell_handle& cch : conflict_zone) @@ -1322,6 +1364,7 @@ class Alpha_wrap_3 if(m_queue.contains_with_bounds_check(Gate(mf))) m_queue.erase(Gate(mf)); } +#endif visitor.before_Steiner_point_insertion(*this, steiner_point); @@ -1715,18 +1758,23 @@ class Alpha_wrap_3 const Point_3& p0 = m_tr.point(ch, Triangulation::vertex_triple_index(id, 0)); const Point_3& p1 = m_tr.point(ch, Triangulation::vertex_triple_index(id, 1)); const Point_3& p2 = m_tr.point(ch, Triangulation::vertex_triple_index(id, 2)); - const FT sqr = geom_traits().compute_squared_radius_3_object()(p0, p1, p2); - std::cout << "At Facet with VID " << get(Gate_ID_PM(), current_gate) << "\n"; + std::cout << "Facet with VID " << get(Gate_ID_PM(), current_gate) << "\n"; std::cout << "\t" << p0 << "\n\t" << p1 << "\n\t" << p2 << "\n"; + +#ifdef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE std::cout << " Permissiveness: " << current_gate.is_permissive_facet() << "\n"; - std::cout << " SQR: " << sqr << "\n"; + std::cout << " SQR: " << geom_traits().compute_squared_radius_3_object()(p0, p1, p2) << "\n"; std::cout << " Priority " << current_gate.priority() << std::endl; if(Less_gate()(current_gate, previous_top_gate)) std::cerr << "Error: current gate has higher priority than the previous top" << std::endl; previous_top_gate = current_gate; +#else + if(current_gate.is_zombie()) + std::cout << "Gate is a zombie!" << std::endl; +#endif m_queue.pop(); } diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_triangulation_cell_base_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_triangulation_cell_base_3.h index db1df61c8f65..b586d495f0d3 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_triangulation_cell_base_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_triangulation_cell_base_3.h @@ -25,9 +25,6 @@ template < typename GT, class Alpha_wrap_triangulation_cell_base_3 : public Cb { -private: - bool outside = false; - public: typedef typename Cb::Vertex_handle Vertex_handle; typedef typename Cb::Cell_handle Cell_handle; @@ -39,6 +36,14 @@ class Alpha_wrap_triangulation_cell_base_3 using Other = Alpha_wrap_triangulation_cell_base_3; }; +private: + bool outside = false; + +#ifndef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE + unsigned int m_erase_counter; +#endif + +public: Alpha_wrap_triangulation_cell_base_3() : Cb() {} @@ -55,8 +60,24 @@ class Alpha_wrap_triangulation_cell_base_3 : Cb(v0, v1, v2, v3, n0, n1, n2, n3) {} +public: bool is_outside() const { return outside; } bool& is_outside() { return outside; } + +#ifndef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE + unsigned int erase_counter() const + { + return m_erase_counter; + } + void set_erase_counter(unsigned int c) + { + m_erase_counter = c; + } + void increment_erase_counter() + { + ++m_erase_counter; + } +#endif }; template diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/gate_priority_queue.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/gate_priority_queue.h index b091b2cabe24..f017f9be8cf4 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/gate_priority_queue.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/gate_priority_queue.h @@ -27,6 +27,8 @@ namespace CGAL { namespace Alpha_wraps_3 { namespace internal { +#ifdef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE + // Represents an alpha-traversable facet in the mutable priority queue template class Gate @@ -90,6 +92,44 @@ struct Less_gate } }; +#else // CGAL_AW3_USE_SORTED_PRIORITY_QUEUE + +// Represents an alpha-traversable facet in the mutable priority queue +template +class Gate +{ + using Facet = typename Tr::Facet; + using FT = typename Tr::Geom_traits::FT; + +private: + Facet m_facet, m_mirror_facet; + const unsigned int m_erase_counter_mem; + const unsigned int m_mirror_erase_counter_mem; + +public: + // Constructors + Gate(const Facet& facet, + const Tr& tr) + : + m_facet(facet), + m_mirror_facet(tr.mirror_facet(facet)), + m_erase_counter_mem(m_facet.first->erase_counter()), + m_mirror_erase_counter_mem(m_mirror_facet.first->erase_counter()) + { + } + +public: + const Facet& facet() const { return m_facet; } + + const bool is_zombie() const + { + return (m_facet.first->erase_counter() != m_erase_counter_mem) || + (m_mirror_facet.first->erase_counter() != m_mirror_erase_counter_mem); + } +}; + +#endif // CGAL_AW3_USE_SORTED_PRIORITY_QUEUE + template struct Gate_ID_PM { From 7d2de68d1cf7665acaa415dcaffc507dccd9f15f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 9 Oct 2023 16:55:57 -0700 Subject: [PATCH 135/329] add missing include directive --- .../CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h index 7a3b2c0765e5..4e9082996e49 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h @@ -15,6 +15,7 @@ #include +#include #include namespace CGAL { From 0e9da7ab960b4abebf6738547d260c3c5e0af5d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 10 Oct 2023 12:19:44 +0200 Subject: [PATCH 136/329] Debug code and minor cleaning --- .../CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 117 +++++++++++------- .../internal/gate_priority_queue.h | 4 +- 2 files changed, 72 insertions(+), 49 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index 08f09fcdd4ce..2764546c3181 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -175,6 +175,7 @@ class Alpha_wrap_3 FT m_offset = FT(-1), m_sq_offset = FT(-1); Triangulation m_tr; + Alpha_PQ m_queue; public: @@ -250,24 +251,33 @@ class Alpha_wrap_3 using parameters::get_parameter_reference; using parameters::choose_parameter; + // using OVPM = typename CGAL::GetVertexPointMap::type; OVPM ovpm = choose_parameter(get_parameter(out_np, internal_np::vertex_point), get_property_map(vertex_point, output_mesh)); - typedef typename internal_np::Lookup_named_param_def < - internal_np::visitor_t, - InputNamedParameters, - Wrapping_default_visitor // default - >::reference Visitor; + // + using Visitor = typename internal_np::Lookup_named_param_def< + internal_np::visitor_t, + InputNamedParameters, + Wrapping_default_visitor // default + >::reference; Wrapping_default_visitor default_visitor; Visitor visitor = choose_parameter(get_parameter_reference(in_np, internal_np::visitor), default_visitor); - std::vector no_seeds; + // using Seeds = typename internal_np::Lookup_named_param_def< - internal_np::seed_points_t, InputNamedParameters, std::vector >::reference; + internal_np::seed_points_t, + InputNamedParameters, + std::vector >::reference; + + std::vector no_seeds; Seeds seeds = choose_parameter(get_parameter_reference(in_np, internal_np::seed_points), no_seeds); + // Whether or not some cells should be reflagged as "inside" after the refinement+carving loop + // as ended, as to ensure that the result is not only combinatorially manifold, but also + // geometrically manifold. const bool do_enforce_manifoldness = choose_parameter(get_parameter(in_np, internal_np::do_enforce_manifoldness), true); // This parameter enables avoiding recomputing the triangulation from scratch when wrapping @@ -294,9 +304,16 @@ class Alpha_wrap_3 if(!initialize(alpha, offset, seeds, resuming)) return; +#ifdef CGAL_AW3_TIMER + t.stop(); + std::cout << "Initialization took: " << t.time() << " s." << std::endl; + t.reset(); + t.start(); +#endif + #ifdef CGAL_AW3_DEBUG_DUMP_EVERY_STEP extract_surface(output_mesh, ovpm, true /*tolerate non manifoldness*/); - CGAL::IO::write_polygon_mesh("initial_cavities.off", output_mesh, + CGAL::IO::write_polygon_mesh("starting_wrap.off", output_mesh, CGAL::parameters::vertex_point_map(ovpm).stream_precision(17)); #endif @@ -305,20 +322,20 @@ class Alpha_wrap_3 #ifdef CGAL_AW3_TIMER t.stop(); std::cout << "Flood filling took: " << t.time() << " s." << std::endl; + t.reset(); + t.start(); #endif if(do_enforce_manifoldness) { -#ifdef CGAL_AW3_DEBUG_MANIFOLDNESS - std::cout << "> Make manifold..." << std::endl; - +#ifdef CGAL_AW3_DEBUG extract_surface(output_mesh, ovpm, true /*tolerate non manifoldness*/); -#ifdef CGAL_AW3_DEBUG_DUMP_EVERY_STEP - dump_triangulation_faces("intermediate_tr.off", false /*only_boundary_faces*/); - IO::write_polygon_mesh("intermediate.off", output_mesh, + #ifdef CGAL_AW3_DEBUG_DUMP_EVERY_STEP + dump_triangulation_faces("carved_tr.off", false /*only_boundary_faces*/); + IO::write_polygon_mesh("carved_wrap.off", output_mesh, CGAL::parameters::vertex_point_map(ovpm).stream_precision(17)); -#endif + #endif FT base_vol = 0; if(is_closed(output_mesh)) // might not be due to manifoldness @@ -327,19 +344,16 @@ class Alpha_wrap_3 std::cerr << "Warning: couldn't compute volume before manifoldness fixes (mesh is not closed)" << std::endl; #endif -#ifdef CGAL_AW3_TIMER - t.reset(); - t.start(); -#endif - make_manifold(); #ifdef CGAL_AW3_TIMER t.stop(); - std::cout << "\nManifoldness post-processing took: " << t.time() << " s." << std::endl; + std::cout << "Manifoldness post-processing took: " << t.time() << " s." << std::endl; + t.reset(); + t.start(); #endif -#ifdef CGAL_AW3_DEBUG_MANIFOLDNESS +#ifdef CGAL_AW3_DEBUG if(!is_zero(base_vol)) { extract_surface(output_mesh, ovpm, false /*do not tolerate non-manifoldness*/); @@ -751,7 +765,7 @@ class Alpha_wrap_3 if(faces.empty()) { #ifdef CGAL_AW3_DEBUG - std::cout << "Empty wrap?..." << std::endl; + std::cerr << "Warning: empty wrap?..." << std::endl; #endif return; } @@ -791,7 +805,8 @@ class Alpha_wrap_3 std::vector points; std::vector > polygons; - // Explode the polygon soup into indepent triangles, and stitch back edge by edge by walking along the exterior + // Explode the polygon soup into indepent triangles, and stitch it back + // edge by edge by walking along the exterior std::map facet_ids; std::size_t idx = 0; @@ -817,10 +832,15 @@ class Alpha_wrap_3 idx += 3; } +#ifdef CGAL_AW3_DEBUG + std::cout << "\t" << points.size() << " points" << std::endl; + std::cout << "\t" << polygons.size() << " polygons" << std::endl; +#endif + if(polygons.empty()) { #ifdef CGAL_AW3_DEBUG - std::cout << "Empty wrap?..." << std::endl; + std::cerr << "Warning: empty wrap?..." << std::endl; #endif return; } @@ -1280,14 +1300,14 @@ class Alpha_wrap_3 const int s = f.second; CGAL_precondition(ch->is_outside()); - const Cell_handle neighbor = ch->neighbor(s); + const Cell_handle nh = ch->neighbor(s); #ifdef CGAL_AW3_DEBUG_QUEUE static int fid = 0; std::cout << m_tr.number_of_vertices() << " DT vertices" << std::endl; std::cout << m_queue.size() << " facets in the queue" << std::endl; std::cout << "Face " << fid++ << "\n" - << "c = " << &*ch << " (" << m_tr.is_infinite(ch) << "), n = " << &*neighbor << " (" << m_tr.is_infinite(neighbor) << ")" << "\n" + << "c = " << &*ch << " (" << m_tr.is_infinite(ch) << "), n = " << &*nh << " (" << m_tr.is_infinite(nh) << ")" << "\n" << m_tr.point(ch, Triangulation::vertex_triple_index(s, 0)) << "\n" << m_tr.point(ch, Triangulation::vertex_triple_index(s, 1)) << "\n" << m_tr.point(ch, Triangulation::vertex_triple_index(s, 2)) << std::endl; @@ -1316,14 +1336,14 @@ class Alpha_wrap_3 m_queue.pop(); - if(m_tr.is_infinite(neighbor)) + if(m_tr.is_infinite(nh)) { - neighbor->is_outside() = true; + nh->is_outside() = true; continue; } Point_3 steiner_point; - if(compute_steiner_point(ch, neighbor, steiner_point)) + if(compute_steiner_point(ch, nh, steiner_point)) { // std::cout << CGAL::abs(CGAL::approximate_sqrt(m_oracle.squared_distance(steiner_point)) - m_offset) // << " vs " << 1e-2 * m_offset << std::endl; @@ -1332,7 +1352,7 @@ class Alpha_wrap_3 // locate cells that are going to be destroyed and remove their facet from the queue int li, lj = 0; Locate_type lt; - const Cell_handle conflict_cell = m_tr.locate(steiner_point, lt, li, lj, neighbor); + const Cell_handle conflict_cell = m_tr.locate(steiner_point, lt, li, lj, nh); CGAL_assertion(lt != Triangulation::VERTEX); // Using small vectors like in Triangulation_3 does not bring any runtime improvement @@ -1379,10 +1399,10 @@ class Alpha_wrap_3 std::vector new_cells; new_cells.reserve(32); m_tr.incident_cells(vh, std::back_inserter(new_cells)); - for(const Cell_handle& ch : new_cells) + for(const Cell_handle& new_ch : new_cells) { - // std::cout << "new cell has time stamp " << ch->time_stamp() << std::endl; - ch->is_outside() = m_tr.is_infinite(ch); + // std::cout << "new cell has time stamp " << new_ch->time_stamp() << std::endl; + new_ch->is_outside() = m_tr.is_infinite(new_ch); } // Push all new boundary facets to the queue. @@ -1390,19 +1410,19 @@ class Alpha_wrap_3 // because we need to handle internal facets, infinite facets, and also more subtle changes // such as a new cell being marked inside which now creates a boundary // with its incident "outside" flagged cell. - for(Cell_handle ch : new_cells) + for(Cell_handle new_ch : new_cells) { for(int i=0; i<4; ++i) { - if(m_tr.is_infinite(ch, i)) + if(m_tr.is_infinite(new_ch, i)) continue; - const Cell_handle nh = ch->neighbor(i); - if(nh->is_outside() == ch->is_outside()) // not on the boundary + const Cell_handle new_nh = new_ch->neighbor(i); + if(new_nh->is_outside() == new_ch->is_outside()) // not on the boundary continue; - const Facet boundary_f = std::make_pair(ch, i); - if(ch->is_outside()) + const Facet boundary_f = std::make_pair(new_ch, i); + if(new_ch->is_outside()) push_facet(boundary_f); else push_facet(m_tr.mirror_facet(boundary_f)); @@ -1411,14 +1431,13 @@ class Alpha_wrap_3 } else // no need for a Steiner point, carve through and continue { - // tag neighbor as OUTSIDE - neighbor->is_outside() = true; + nh->is_outside() = true; // for each finite facet of neighbor, push it to the queue const int mi = m_tr.mirror_index(ch, s); for(int i=1; i<4; ++i) { - const Facet neighbor_f = std::make_pair(neighbor, (mi+i)&3); + const Facet neighbor_f = std::make_pair(nh, (mi+i)&3); push_facet(neighbor_f); } } @@ -1590,6 +1609,10 @@ class Alpha_wrap_3 { namespace PMP = Polygon_mesh_processing; +#ifdef CGAL_AW3_DEBUG + std::cout << "> Make manifold..." << std::endl; +#endif + // This seems more harmful than useful after the priority queue has been introduced since // it adds a lot of flat cells into the triangulation, which then get added to the mesh // during manifoldness fixing. @@ -1802,17 +1825,17 @@ class Alpha_wrap_3 for(auto fit=m_tr.finite_facets_begin(), fend=m_tr.finite_facets_end(); fit!=fend; ++fit) { - Cell_handle c = fit->first; + Cell_handle ch = fit->first; int s = fit->second; - Cell_handle nc = c->neighbor(s); - if(only_boundary_faces && (c->is_outside() == nc->is_outside())) + Cell_handle nh = ch->neighbor(s); + if(only_boundary_faces && (ch->is_outside() == nh->is_outside())) continue; std::array ids; for(std::size_t pos=0; pos<3; ++pos) { - Vertex_handle v = c->vertex((s+pos+1)&3); + Vertex_handle v = ch->vertex((s+pos+1)&3); auto insertion_res = vertex_to_id.emplace(v, nv); if(insertion_res.second) { diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/gate_priority_queue.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/gate_priority_queue.h index f017f9be8cf4..9c29ac9e7226 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/gate_priority_queue.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/gate_priority_queue.h @@ -74,8 +74,8 @@ struct Less_gate // // The permissive facet are given highest priority because they need to be treated // regardless of their circumradius. Treating them first allow the part that depends - // on alpha to be treated uniformly in a way: whatever the alpha, we'll do the same - // first treatmen + // on alpha to be treated uniformly in a way: whatever the alpha, all scaffolding faces + // will first be treated if(a.is_permissive_facet() != b.is_permissive_facet()) return a.is_permissive_facet(); From 48d2057f40309e576a31a28564def43fee81e183 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 10 Oct 2023 12:58:14 +0200 Subject: [PATCH 137/329] Add a third type of cell label to distinguish relabeling for manifoldness --- .../CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 139 +++++++++++------- .../Alpha_wrap_triangulation_cell_base_3.h | 19 ++- 2 files changed, 102 insertions(+), 56 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index 2764546c3181..f22fbfaa1f31 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -438,6 +438,20 @@ class Alpha_wrap_3 return bbox; } +private: + // The distinction between inside boundary and outside boundary is the presence of cells + // being flagged for manifoldness: inside boundary considers those outside, and outside + // boundary considers them inside. + bool is_on_inside_boundary(Cell_handle ch, Cell_handle nh) const + { + return (ch->is_inside() != nh->is_inside()); // one is INSIDE, the other is not + } + + bool is_on_outside_boundary(Cell_handle ch, Cell_handle nh) const + { + return (ch->is_outside() != nh->is_outside()); // one is OUTSIDE, the other is not + } + private: // Adjust the bbox & insert its corners to construct the starting triangulation void insert_bbox_corners() @@ -465,20 +479,20 @@ class Alpha_wrap_3 // - Cells whose circumcenter is in the offset volume are inside: this is because // we need to have outside cell circumcenters outside of the volume to ensure // that the refinement point is separated from the existing point set. - bool cavity_cell_outside_tag(const Cell_handle ch) + Cell_label cavity_cell_label(const Cell_handle ch) { CGAL_precondition(!m_tr.is_infinite(ch)); const Tetrahedron_with_outside_info tet(ch, geom_traits()); if(m_oracle.do_intersect(tet)) - return false; + return Cell_label::INSIDE; const Point_3& ch_cc = circumcenter(ch); typename Geom_traits::Construct_ball_3 ball = geom_traits().construct_ball_3_object(); const Ball_3 ch_cc_offset_ball = ball(ch_cc, m_sq_offset); const bool is_cc_in_offset = m_oracle.do_intersect(ch_cc_offset_ball); - return !is_cc_in_offset; + return is_cc_in_offset ? Cell_label::INSIDE : Cell_label::OUTSIDE; } // Create a cavity using seeds rather than starting from the infinity. @@ -631,16 +645,17 @@ class Alpha_wrap_3 m_tr.incident_cells(seed_v, std::back_inserter(inc_cells)); for(Cell_handle ch : inc_cells) - ch->is_outside() = cavity_cell_outside_tag(ch); + ch->label() = cavity_cell_label(ch); } // Should be cheap enough to go through the full triangulation as only seeds have been inserted for(Cell_handle ch : m_tr.all_cell_handles()) { - if(!ch->is_outside()) + if(ch->is_inside()) continue; - // When the algorithm starts from a manually dug hole, infinite cells are tagged "inside" + // When the algorithm starts from a manually dug hole, infinite cells are initialized + // as INSIDE such that they do not appear on the boundary CGAL_assertion(!m_tr.is_infinite(ch)); for(int i=0; i<4; ++i) @@ -666,19 +681,26 @@ class Alpha_wrap_3 { if(m_tr.is_infinite(ch)) { - ch->is_outside() = true; + ch->label() = Cell_label::OUTSIDE; const int inf_index = ch->index(m_tr.infinite_vertex()); push_facet(std::make_pair(ch, inf_index)); } else { - ch->is_outside() = false; + ch->label() = Cell_label::INSIDE; } } return true; } + void reset_manifold_labels() + { + for(Cell_handle ch : m_tr.all_cell_handles()) + if(ch->label() == Cell_label::MANIFOLD) + ch->label() = Cell_label::OUTSIDE; + } + // This function is used in the case of resumption of a previous run: m_tr is not cleared, // and we fill the queue with the new parameters. bool initialize_from_existing_triangulation() @@ -692,7 +714,7 @@ class Alpha_wrap_3 for(Cell_handle ch : m_tr.all_cell_handles()) { - if(!ch->is_outside()) + if(ch->is_inside()) continue; for(int i=0; i<4; ++i) @@ -711,9 +733,24 @@ class Alpha_wrap_3 } private: - void extract_boundary(std::vector& points, - std::vector >& faces) const + template + void extract_manifold_surface(OutputMesh& output_mesh, + OVPM ovpm) const { + namespace PMP = Polygon_mesh_processing; + +#ifdef CGAL_AW3_DEBUG + std::cout << "> Extract manifold wrap... ()" << std::endl; +#endif + + CGAL_assertion_code(for(Vertex_handle v : m_tr.finite_vertex_handles())) + CGAL_assertion(!is_non_manifold(v)); + + clear(output_mesh); + + std::vector points; + std::vector > faces; + std::unordered_map vertex_to_id; for(auto fit=m_tr.all_facets_begin(), fend=m_tr.all_facets_end(); fit!=fend; ++fit) @@ -725,7 +762,7 @@ class Alpha_wrap_3 const Cell_handle ch = f.first; const int s = f.second; const Cell_handle nh = ch->neighbor(s); - if(ch->is_outside() == nh->is_outside()) + if(!is_on_outside_boundary(ch, nh)) continue; std::array ids; @@ -741,27 +778,12 @@ class Alpha_wrap_3 faces.emplace_back(std::array{ids[0], ids[1], ids[2]}); } - } - - template - void extract_manifold_surface(OutputMesh& output_mesh, - OVPM ovpm) const - { - namespace PMP = Polygon_mesh_processing; #ifdef CGAL_AW3_DEBUG - std::cout << "> Extract manifold wrap... ()" << std::endl; + std::cout << "\t" << points.size() << " points" << std::endl; + std::cout << "\t" << faces.size() << " faces" << std::endl; #endif - CGAL_assertion_code(for(Vertex_handle v : m_tr.finite_vertex_handles())) - CGAL_assertion(!is_non_manifold(v)); - - clear(output_mesh); - - std::vector points; - std::vector > faces; - extract_boundary(points, faces); - if(faces.empty()) { #ifdef CGAL_AW3_DEBUG @@ -787,8 +809,8 @@ class Alpha_wrap_3 } template - void extract_possibly_non_manifold_surface(OutputMesh& output_mesh, - OVPM ovpm) const + void extract_inside_boundary(OutputMesh& output_mesh, + OVPM ovpm) const { namespace PMP = Polygon_mesh_processing; @@ -810,16 +832,20 @@ class Alpha_wrap_3 std::map facet_ids; std::size_t idx = 0; + // Looks identical to the block in extract_manifold_surface(), but there are + // two significant differences: + // - Boundary considers MANIFOLD outside here + // - There is no attempt to re-use the same vertex in multiple faces for(auto fit=m_tr.finite_facets_begin(), fend=m_tr.finite_facets_end(); fit!=fend; ++fit) { Facet f = *fit; - if(!f.first->is_outside()) + if(f.first->is_inside()) // need f.first to be OUTSIDE or MANIFOLD f = m_tr.mirror_facet(f); const Cell_handle ch = f.first; const int s = f.second; const Cell_handle nh = ch->neighbor(s); - if(ch->is_outside() == nh->is_outside()) + if(!is_on_inside_boundary(ch, nh)) // MANIFOLD here is outside continue; facet_ids[f] = idx / 3; @@ -858,13 +884,13 @@ class Alpha_wrap_3 for(auto fit=m_tr.all_facets_begin(), fend=m_tr.all_facets_end(); fit!=fend; ++fit) { Facet f = *fit; - if(!f.first->is_outside()) + if(f.first->is_inside()) // f.first must be MANIFOLD or OUTSIDE f = m_tr.mirror_facet(f); const Cell_handle ch = f.first; const int s = f.second; const Cell_handle nh = ch->neighbor(s); - if(ch->is_outside() == nh->is_outside()) + if(!is_on_inside_boundary(ch, nh)) // MANIFOLD here is outside continue; put(face_to_facet, i2f[idx++], f); @@ -877,7 +903,7 @@ class Alpha_wrap_3 { const Facet& tr_f = get(face_to_facet, f); const Cell_handle ch = tr_f.first; - CGAL_assertion(ch->is_outside()); + CGAL_assertion(!ch->is_inside()); // OUTSIDE or MANIFOLD for(halfedge_descriptor h : halfedges_around_face(halfedge(f, output_mesh), output_mesh)) { @@ -922,18 +948,18 @@ class Alpha_wrap_3 third_vh = curr_ch->vertex(facet_third_id); curr_ch = curr_ch->neighbor(Triangulation::next_around_edge(i,j)); - if(!curr_ch->is_outside()) + if(curr_ch->is_inside()) break; } while(curr_ch != start_ch); CGAL_assertion(curr_ch != start_ch); - CGAL_assertion(!curr_ch->is_outside()); + CGAL_assertion(curr_ch->is_inside()); const int opp_id = 6 - (curr_ch->index(s_vh) + curr_ch->index(t_vh) + curr_ch->index(third_vh)); const Facet tr_f2 = m_tr.mirror_facet(Facet(curr_ch, opp_id)); CGAL_assertion(facet_ids.count(Facet(curr_ch, opp_id)) == 0); - CGAL_assertion(tr_f2.first->is_outside()); + CGAL_assertion(!tr_f2.first->is_inside()); CGAL_assertion(tr_f2.first->neighbor(tr_f2.second) == curr_ch); CGAL_assertion(tr_f2.first->has_vertex(s_vh) && tr_f2.first->has_vertex(t_vh)); @@ -972,7 +998,7 @@ class Alpha_wrap_3 const bool tolerate_non_manifoldness = false) const { if(tolerate_non_manifoldness) - extract_possibly_non_manifold_surface(output_mesh, ovpm); + extract_inside_boundary(output_mesh, ovpm); else extract_manifold_surface(output_mesh, ovpm); } @@ -1115,8 +1141,9 @@ class Alpha_wrap_3 // skip if neighbor is OUTSIDE or infinite const Cell_handle ch = f.first; const int id = f.second; + CGAL_precondition(ch->label() == Cell_label::INSIDE || ch->label() == Cell_label::OUTSIDE); - if(!ch->is_outside()) + if(!ch->is_outside()) // INSIDE or MANIFOLD { #ifdef CGAL_AW3_DEBUG_FACET_STATUS std::cout << "Facet is inside" << std::endl; @@ -1125,6 +1152,8 @@ class Alpha_wrap_3 } const Cell_handle nh = ch->neighbor(id); + CGAL_precondition(ch->label() == Cell_label::INSIDE || ch->label() == Cell_label::OUTSIDE); + if(m_tr.is_infinite(nh)) return HAS_INFINITE_NEIGHBOR; @@ -1301,6 +1330,7 @@ class Alpha_wrap_3 CGAL_precondition(ch->is_outside()); const Cell_handle nh = ch->neighbor(s); + CGAL_precondition(nh->label() == Cell_label::INSIDE || nh->label() == Cell_label::OUTSIDE); #ifdef CGAL_AW3_DEBUG_QUEUE static int fid = 0; @@ -1338,7 +1368,7 @@ class Alpha_wrap_3 if(m_tr.is_infinite(nh)) { - nh->is_outside() = true; + nh->label() = Cell_label::OUTSIDE; continue; } @@ -1402,7 +1432,7 @@ class Alpha_wrap_3 for(const Cell_handle& new_ch : new_cells) { // std::cout << "new cell has time stamp " << new_ch->time_stamp() << std::endl; - new_ch->is_outside() = m_tr.is_infinite(new_ch); + new_ch->label() = m_tr.is_infinite(new_ch) ? Cell_label::OUTSIDE : Cell_label::INSIDE; } // Push all new boundary facets to the queue. @@ -1418,7 +1448,7 @@ class Alpha_wrap_3 continue; const Cell_handle new_nh = new_ch->neighbor(i); - if(new_nh->is_outside() == new_ch->is_outside()) // not on the boundary + if(new_nh->label() == new_ch->label()) // not on a boundary continue; const Facet boundary_f = std::make_pair(new_ch, i); @@ -1431,7 +1461,7 @@ class Alpha_wrap_3 } else // no need for a Steiner point, carve through and continue { - nh->is_outside() = true; + nh->label() = Cell_label::OUTSIDE; // for each finite facet of neighbor, push it to the queue const int mi = m_tr.mirror_index(ch, s); @@ -1447,9 +1477,10 @@ class Alpha_wrap_3 // Check that no useful facet has been ignored CGAL_postcondition_code(for(auto fit=m_tr.finite_facets_begin(), fend=m_tr.finite_facets_end(); fit!=fend; ++fit) {) - CGAL_postcondition_code( if(fit->first->is_outside() == fit->first->neighbor(fit->second)->is_outside()) continue;) + CGAL_postcondition_code( Cell_handle ch = fit->first; Cell_handle nh = fit->first->neighbor(fit->second); ) + CGAL_postcondition_code( if(ch->label() == nh->label()) continue;) CGAL_postcondition_code( Facet f = *fit;) - CGAL_postcondition_code( if(!fit->first->is_outside()) f = m_tr.mirror_facet(f);) + CGAL_postcondition_code( if(ch->is_inside()) f = m_tr.mirror_facet(f);) CGAL_postcondition( facet_status(f) == IRRELEVANT); CGAL_postcondition_code(}) @@ -1481,7 +1512,7 @@ class Alpha_wrap_3 if(ic->is_outside()) outside_start = ic; else if(inside_start == Cell_handle()) - inside_start = ic; + inside_start = ic; // can be INSIDE or MANIFOLD } // fully inside / outside @@ -1513,8 +1544,10 @@ class Alpha_wrap_3 CGAL_assertion(neigh_c->has_vertex(v)); if(neigh_c->tds_data().processed() || - neigh_c->is_outside() != curr_c->is_outside()) // do not cross the boundary + is_on_outside_boundary(neigh_c, curr_c)) // do not cross the boundary + { continue; + } cells_to_visit.push(neigh_c); } @@ -1640,9 +1673,9 @@ class Alpha_wrap_3 return false; }; - auto is_on_boundary = [](Cell_handle c, int i) -> bool + auto is_on_boundary = [&](Cell_handle c, int i) -> bool { - return (c->is_outside() != c->neighbor(i)->is_outside()); + return is_on_outside_boundary(c, c->neighbor(i)); }; auto count_boundary_facets = [&](Cell_handle c, Vertex_handle v) -> int @@ -1736,7 +1769,7 @@ class Alpha_wrap_3 CGAL_assertion(!m_tr.is_infinite(ic)); // This is where new material is added - ic->is_outside() = false; + ic->label() = Cell_label::MANIFOLD; #ifdef CGAL_AW3_DEBUG_DUMP_EVERY_STEP static int i = 0; @@ -1829,7 +1862,7 @@ class Alpha_wrap_3 int s = fit->second; Cell_handle nh = ch->neighbor(s); - if(only_boundary_faces && (ch->is_outside() == nh->is_outside())) + if(only_boundary_faces && ch->label() == nh->label()) continue; std::array ids; diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_triangulation_cell_base_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_triangulation_cell_base_3.h index b586d495f0d3..f5636b798795 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_triangulation_cell_base_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_triangulation_cell_base_3.h @@ -20,6 +20,16 @@ namespace CGAL { namespace Alpha_wraps_3 { namespace internal { +enum class Cell_label +{ + // Cells that have been carved + OUTSIDE, + // Cells that have not yet been carved + INSIDE, + // OUTSIDE cells that have been labeled "inside" again as to make the result manifold + MANIFOLD +}; + template < typename GT, typename Cb = CGAL::Delaunay_triangulation_cell_base_with_circumcenter_3 > class Alpha_wrap_triangulation_cell_base_3 @@ -29,6 +39,7 @@ class Alpha_wrap_triangulation_cell_base_3 typedef typename Cb::Vertex_handle Vertex_handle; typedef typename Cb::Cell_handle Cell_handle; +public: template < typename TDS2 > struct Rebind_TDS { @@ -37,7 +48,7 @@ class Alpha_wrap_triangulation_cell_base_3 }; private: - bool outside = false; + Cell_label m_label = Cell_label::INSIDE; #ifndef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE unsigned int m_erase_counter; @@ -61,8 +72,10 @@ class Alpha_wrap_triangulation_cell_base_3 {} public: - bool is_outside() const { return outside; } - bool& is_outside() { return outside; } + Cell_label label() const { return m_label; } + Cell_label& label() { return m_label; } + bool is_inside() const { return m_label == Cell_label::INSIDE; } + bool is_outside() const { return m_label == Cell_label::OUTSIDE; } #ifndef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE unsigned int erase_counter() const From 49f26abd65fae1e9248bdbc7d22c91eb2c6137c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 10 Oct 2023 13:15:01 +0200 Subject: [PATCH 138/329] enum > enum class --- .../CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index f22fbfaa1f31..a6244eef2edd 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -1098,7 +1098,7 @@ class Alpha_wrap_3 private: // A permissive gate is a gate that we can traverse without checking its circumradius - enum Facet_queue_status + enum class Facet_status { IRRELEVANT = 0, HAS_INFINITE_NEIGHBOR, // the cell incident to the mirrored facet is infinite (permissive) @@ -1106,7 +1106,7 @@ class Alpha_wrap_3 TRAVERSABLE }; - inline const char* get_status_message(const Facet_queue_status status) + inline const char* get_status_message(const Facet_status status) { constexpr std::size_t status_count = 4; @@ -1127,7 +1127,7 @@ class Alpha_wrap_3 public: // @speed some decent time may be spent constructing Facet (pairs) for no reason as it's always // just to grab the .first and .second as soon as it's constructed, and not due to API requirements - Facet_queue_status facet_status(const Facet& f) const + Facet_status facet_status(const Facet& f) const { CGAL_precondition(!m_tr.is_infinite(f)); @@ -1148,21 +1148,21 @@ class Alpha_wrap_3 #ifdef CGAL_AW3_DEBUG_FACET_STATUS std::cout << "Facet is inside" << std::endl; #endif - return IRRELEVANT; + return Facet_status::IRRELEVANT; } const Cell_handle nh = ch->neighbor(id); CGAL_precondition(ch->label() == Cell_label::INSIDE || ch->label() == Cell_label::OUTSIDE); if(m_tr.is_infinite(nh)) - return HAS_INFINITE_NEIGHBOR; + return Facet_status::HAS_INFINITE_NEIGHBOR; if(nh->is_outside()) { #ifdef CGAL_AW3_DEBUG_FACET_STATUS std::cout << "Neighbor already outside" << std::endl; #endif - return IRRELEVANT; + return Facet_status::IRRELEVANT; } // push if facet is connected to scaffolding vertices @@ -1175,7 +1175,7 @@ class Alpha_wrap_3 #ifdef CGAL_AW3_DEBUG_FACET_STATUS std::cout << "Scaffolding facet due to vertex #" << i << std::endl; #endif - return SCAFFOLDING; + return Facet_status::SCAFFOLDING; } } @@ -1185,13 +1185,13 @@ class Alpha_wrap_3 #ifdef CGAL_AW3_DEBUG_FACET_STATUS std::cout << "traversable" << std::endl; #endif - return TRAVERSABLE; + return Facet_status::TRAVERSABLE; } #ifdef CGAL_AW3_DEBUG_FACET_STATUS std::cout << "not traversable" << std::endl; #endif - return IRRELEVANT; + return Facet_status::IRRELEVANT; } private: @@ -1205,13 +1205,14 @@ class Alpha_wrap_3 return false; #endif - const Facet_queue_status status = facet_status(f); - if(status == IRRELEVANT) + const Facet_status status = facet_status(f); + if(status == Facet_status::IRRELEVANT) return false; #ifdef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE const FT sqr = smallest_squared_radius_3(f, m_tr); - const bool is_permissive = (status == HAS_INFINITE_NEIGHBOR || status == SCAFFOLDING); + const bool is_permissive = (status == Facet_status::HAS_INFINITE_NEIGHBOR || + status == Facet_status::SCAFFOLDING); m_queue.resize_and_push(Gate(f, sqr, is_permissive)); #else m_queue.push(Gate(f, m_tr)); @@ -1481,7 +1482,7 @@ class Alpha_wrap_3 CGAL_postcondition_code( if(ch->label() == nh->label()) continue;) CGAL_postcondition_code( Facet f = *fit;) CGAL_postcondition_code( if(ch->is_inside()) f = m_tr.mirror_facet(f);) - CGAL_postcondition( facet_status(f) == IRRELEVANT); + CGAL_postcondition( facet_status(f) == Facet_status::IRRELEVANT); CGAL_postcondition_code(}) return true; From 67e1b32c21d6c98320af26e2319fa09d94ac1539 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 10 Oct 2023 13:22:20 +0200 Subject: [PATCH 139/329] Do not recompute the queue when resuming --- .../CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 65 ++++++++++++------- 1 file changed, 42 insertions(+), 23 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index a6244eef2edd..beb2bc7708cf 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -281,18 +281,16 @@ class Alpha_wrap_3 const bool do_enforce_manifoldness = choose_parameter(get_parameter(in_np, internal_np::do_enforce_manifoldness), true); // This parameter enables avoiding recomputing the triangulation from scratch when wrapping - // the same meshes for multiple values of alpha (and typically the same offset values). - // + // the same input for multiple values of alpha (and typically the same offset values). // /!\ Warning /!\ // - // If this is enabled, the 3D triangulation will NEVER be cleared and re-initialized - // at launch. This means that the triangulation is NOT cleared, even when: - // - the triangulation is empty; you will get nothing. + // If this is enabled, the 3D triangulation will NOT be re-initialized + // at launch. This means that the triangulation is NOT cleared, even if: // - you use an alpha value that is greater than what was used in a previous run; you will - // obtain a denser result than what you might expect. + // obtain the same result as the last run. // - you use a different offset value between runs, you might then get points that are not - // on the offset surface corresponding to your latter offset value. - const bool resuming = choose_parameter(get_parameter(in_np, internal_np::refine_triangulation), false); + // on the offset surface corresponding to that corresponding to the latter offset value. + const bool refining = choose_parameter(get_parameter(in_np, internal_np::refine_triangulation), false); #ifdef CGAL_AW3_TIMER CGAL::Real_timer t; @@ -301,7 +299,7 @@ class Alpha_wrap_3 visitor.on_alpha_wrapping_begin(*this); - if(!initialize(alpha, offset, seeds, resuming)) + if(!initialize(alpha, offset, seeds, refining)) return; #ifdef CGAL_AW3_TIMER @@ -368,13 +366,14 @@ class Alpha_wrap_3 if(ratio > 1.1) // more than 10% extra volume std::cerr << "Warning: large increase of volume after manifoldness resolution" << std::endl; } -#endif - } // do_enforce_manifoldness -#ifdef CGAL_AW3_TIMER - t.reset(); - t.start(); + std::size_t nm_cells_counter = 0; + for(Cell_handle ch : m_tr.all_cell_handles()) + if(ch->label() == Cell_label::MANIFOLD) + ++nm_cells_counter; + std::cout << "Number of added cells: " << nm_cells_counter << std::endl; #endif + } extract_surface(output_mesh, ovpm, !do_enforce_manifoldness); @@ -1246,12 +1245,19 @@ class Alpha_wrap_3 bool initialize(const double alpha, const double offset, const SeedRange& seeds, - const bool resuming = false) + const bool refining) { #ifdef CGAL_AW3_DEBUG std::cout << "> Initialize..." << std::endl; - std::cout << "Alpha: " << alpha << std::endl; - std::cout << "Offset: " << offset << std::endl; +#endif + + const bool resuming = refining && (alpha == m_alpha) && (offset == m_offset); + +#ifdef CGAL_AW3_DEBUG + std::cout << "\tAlpha: " << alpha << std::endl; + std::cout << "\tOffset: " << offset << std::endl; + std::cout << "\tRefining? " << refining << std::endl; + std::cout << "\tResuming? " << resuming << std::endl; #endif if(!is_positive(alpha) || !is_positive(offset)) @@ -1262,31 +1268,44 @@ class Alpha_wrap_3 return false; } - if(resuming && alpha > m_alpha) - std::cerr << "Warning: resuming with an alpha greater than last iteration!" << std::endl; - - if(resuming && offset != m_offset) - std::cerr << "Warning: resuming with a different offset!" << std::endl; + if(refining && alpha > m_alpha) + std::cerr << "Warning: refining with an alpha greater than the last iteration's!" << std::endl; + if(refining && offset != m_offset) + std::cerr << "Warning: refining with a different offset value!" << std::endl; m_alpha = FT(alpha); m_sq_alpha = square(m_alpha); m_offset = FT(offset); m_sq_offset = square(m_offset); + // Resuming means that we do not need to re-initialize the queue: either we have finished + // and there is nothing to do, or the interruption was due to a user callback in the visitor, + // and we can resume with the current queue + if(resuming) + { + reset_manifold_labels(); + return true; + } + #ifdef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE m_queue.clear(); #else m_queue = { }; #endif - if(resuming) + if(refining) { + // If we are re-using the triangulation, change the label of the extra elements + // that we have added to ensure a manifold result back to external (MANIFOLD -> OUTSIDE) + reset_manifold_labels(); + return initialize_from_existing_triangulation(); } else { m_tr.clear(); + insert_bbox_corners(); if(seeds.empty()) From c19799aa59ae4e1cab686b5b00b9a245c9cb8e55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 10 Oct 2023 13:23:05 +0200 Subject: [PATCH 140/329] Move "go_further()" check up So it doesn't purge zombies or print gate info that would not be refined --- .../include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index beb2bc7708cf..d61ca129ae21 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -1327,6 +1327,9 @@ class Alpha_wrap_3 // Explore all finite cells that are reachable from one of the initial outside cells. while(!m_queue.empty()) { + if(!visitor.go_further(*this)) + return false; + #ifdef CGAL_AW3_DEBUG_QUEUE_PP check_queue_sanity(); #endif @@ -1379,9 +1382,6 @@ class Alpha_wrap_3 face_out.close(); #endif - if(!visitor.go_further(*this)) - return false; - visitor.before_facet_treatment(*this, gate); m_queue.pop(); From e03116953432a8b0376060ce0ea189926f87155b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 11 Oct 2023 16:50:48 +0200 Subject: [PATCH 141/329] Fix merge issue --- Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index c851ef559bcf..646ec7951e87 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -1765,7 +1765,7 @@ class Alpha_wrap_3 // one would need to sort again after each modification of is_outside() statuses. auto comparer = [&](Cell_handle l, Cell_handle r) -> bool { - CGAL_precondition(!m_dt.is_infinite(l) && !m_dt.is_infinite(r)); + CGAL_precondition(!m_tr.is_infinite(l) && !m_tr.is_infinite(r)); if(has_scaffolding_vertex(l) != has_scaffolding_vertex(r)) return has_scaffolding_vertex(r); From 1066a9622f8595982b26475d0d75427f583af193 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 11 Oct 2023 16:51:09 +0200 Subject: [PATCH 142/329] Only flag outside cells during manifold enforcement Otherwise, it creates holes if we reset manifold flags... --- .../CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index 646ec7951e87..4543277de725 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -1777,15 +1777,19 @@ class Alpha_wrap_3 inc_cells.reserve(64); m_tr.finite_incident_cells(v, std::back_inserter(inc_cells)); + std::vector finite_outside_inc_cells; + finite_outside_inc_cells.reserve(64); + std::copy_if(inc_cells.begin(), inc_cells.end(), std::back_inserter(finite_outside_inc_cells), + [&](Cell_handle c) -> bool { return !m_tr.is_infinite(c) && c->is_outside(); }); + // 'std::stable_sort' to have determinism without having to write something like: // if(longest_edge(l) == longest_edge(r)) return ... // in the comparer. It's a small range, so the cost does not matter. - std::stable_sort(inc_cells.begin(), inc_cells.end(), comparer); + std::stable_sort(finite_outside_inc_cells.begin(), finite_outside_inc_cells.end(), comparer); - for(auto cit=inc_cells.begin(), cend=inc_cells.end(); cit!=cend; ++cit) + for(Cell_handle ic : finite_outside_inc_cells) { - Cell_handle ic = *cit; - CGAL_assertion(!m_tr.is_infinite(ic)); + CGAL_assertion(!m_tr.is_infinite(ic) && ic->is_outside()); // This is where new material is added ic->label() = Cell_label::MANIFOLD; From 318258963fd8dd71179aedd8ad9d3c7a403d1c13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 13 Oct 2023 10:53:11 +0200 Subject: [PATCH 143/329] Add a generic, empty collect_garbage(Graph) --- BGL/include/CGAL/boost/graph/helpers.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/BGL/include/CGAL/boost/graph/helpers.h b/BGL/include/CGAL/boost/graph/helpers.h index 76135fd82a7c..43016f9889fb 100644 --- a/BGL/include/CGAL/boost/graph/helpers.h +++ b/BGL/include/CGAL/boost/graph/helpers.h @@ -953,6 +953,11 @@ void swap_edges(const typename boost::graph_traits::halfedge_descript if (fo2 != nf && halfedge(fo2, g)==oh2) set_halfedge(fo2, oh1, g); } +template +void collect_garbage(Graph&) +{ + // nothing by default +} } //end of internal namespace From 205fcff14156cb097c1c515e49c81cf53883eb82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 13 Oct 2023 10:53:56 +0200 Subject: [PATCH 144/329] Make seeds a member of the wrapper --- .../CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 29 ++++++++----------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index 4543277de725..c781319c07e5 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -167,6 +167,8 @@ class Alpha_wrap_3 using SC_Iso_cuboid_3 = SC::Iso_cuboid_3; using SC2GT = Cartesian_converter; + using Seeds = std::vector; + protected: Oracle m_oracle; SC_Iso_cuboid_3 m_bbox; @@ -174,6 +176,8 @@ class Alpha_wrap_3 FT m_alpha = FT(-1), m_sq_alpha = FT(-1); FT m_offset = FT(-1), m_sq_offset = FT(-1); + Seeds m_seeds; + Triangulation m_tr; Alpha_PQ m_queue; @@ -267,13 +271,7 @@ class Alpha_wrap_3 Visitor visitor = choose_parameter(get_parameter_reference(in_np, internal_np::visitor), default_visitor); // - using Seeds = typename internal_np::Lookup_named_param_def< - internal_np::seed_points_t, - InputNamedParameters, - std::vector >::reference; - - std::vector no_seeds; - Seeds seeds = choose_parameter(get_parameter_reference(in_np, internal_np::seed_points), no_seeds); + m_seeds = choose_parameter(get_parameter_reference(in_np, internal_np::seed_points), Seeds()); // Whether or not some cells should be reflagged as "inside" after the refinement+carving loop // as ended, as to ensure that the result is not only combinatorially manifold, but also @@ -299,7 +297,7 @@ class Alpha_wrap_3 visitor.on_alpha_wrapping_begin(*this); - if(!initialize(alpha, offset, seeds, refining)) + if(!initialize(alpha, offset, refining)) return; #ifdef CGAL_AW3_TIMER @@ -530,15 +528,14 @@ class Alpha_wrap_3 // // Another way is to simply make faces incident to the seed always traversable, and then // we only have to ensure faces opposite of the seed are traversable (i.e., radius ~= 1.65 * alpha) - template - bool initialize_with_cavities(const SeedRange& seeds) + bool initialize_with_cavities() { #ifdef CGAL_AW3_DEBUG_INITIALIZATION std::cout << "> Dig cavities" << std::endl; - std::cout << seeds.size() << " seed(s)" << std::endl; + std::cout << m_seeds.size() << " seed(s)" << std::endl; #endif - CGAL_precondition(!seeds.empty()); + CGAL_precondition(!m_seeds.empty()); // Get a double value approximating the scaling factors // std::cout << sqrt(3) * sin(2pi / 5) << std::endl; @@ -547,7 +544,7 @@ class Alpha_wrap_3 Iso_cuboid_3 bbox = SC2GT()(m_bbox); std::vector seed_vs; - for(const Point_3& seed_p : seeds) + for(const Point_3& seed_p : m_seeds) { #ifdef CGAL_AW3_DEBUG_INITIALIZATION std::cout << "Initialize from seed " << seed_p << std::endl; @@ -1241,10 +1238,8 @@ class Alpha_wrap_3 } private: - template bool initialize(const double alpha, const double offset, - const SeedRange& seeds, const bool refining) { #ifdef CGAL_AW3_DEBUG @@ -1308,10 +1303,10 @@ class Alpha_wrap_3 insert_bbox_corners(); - if(seeds.empty()) + if(m_seeds.empty()) return initialize_from_infinity(); else - return initialize_with_cavities(seeds); + return initialize_with_cavities(); } } From 91c679234bef76e6c3bcbbd7e9224a5456fcecbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 13 Oct 2023 10:56:58 +0200 Subject: [PATCH 145/329] Rename the builder class --- .../benchmark/Alpha_wrap_3/Quality/quality_benchmark.cpp | 2 +- Alpha_wrap_3/examples/Alpha_wrap_3/mixed_inputs_wrap.cpp | 2 +- Alpha_wrap_3/examples/Alpha_wrap_3/successive_wraps.cpp | 2 +- Alpha_wrap_3/examples/Alpha_wrap_3/volumetric_wrap.cpp | 2 +- .../include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 6 +++--- Alpha_wrap_3/include/CGAL/alpha_wrap_3.h | 6 +++--- .../test/Alpha_wrap_3/test_AW3_cavity_initializations.cpp | 4 ++-- Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_multiple_calls.cpp | 2 +- .../Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp | 2 +- 9 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Alpha_wrap_3/benchmark/Alpha_wrap_3/Quality/quality_benchmark.cpp b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Quality/quality_benchmark.cpp index 4565cca641a1..f8e54c488a49 100644 --- a/Alpha_wrap_3/benchmark/Alpha_wrap_3/Quality/quality_benchmark.cpp +++ b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Quality/quality_benchmark.cpp @@ -21,7 +21,7 @@ using Mesh = CGAL::Surface_mesh; using face_descriptor = boost::graph_traits::face_descriptor; using Oracle = CGAL::Alpha_wraps_3::internal::Triangle_mesh_oracle; -using Dt = CGAL::Alpha_wraps_3::internal::Alpha_wrap_3::Triangulation; +using Dt = CGAL::Alpha_wraps_3::internal::Alpha_wrapper_3::Triangulation; namespace PMP = CGAL::Polygon_mesh_processing; diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/mixed_inputs_wrap.cpp b/Alpha_wrap_3/examples/Alpha_wrap_3/mixed_inputs_wrap.cpp index fdba4de5f514..90b488e0407c 100644 --- a/Alpha_wrap_3/examples/Alpha_wrap_3/mixed_inputs_wrap.cpp +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/mixed_inputs_wrap.cpp @@ -103,7 +103,7 @@ int main(int argc, char** argv) oracle.add_segment_soup(segments, CGAL::parameters::default_values()); oracle.add_point_set(ps_points, CGAL::parameters::default_values()); - CGAL::Alpha_wraps_3::internal::Alpha_wrap_3 aw3(oracle); + CGAL::Alpha_wraps_3::internal::Alpha_wrapper_3 aw3(oracle); Mesh wrap; aw3(alpha, offset, wrap); diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/successive_wraps.cpp b/Alpha_wrap_3/examples/Alpha_wrap_3/successive_wraps.cpp index f9b35f88b1f7..f8533fb9cda9 100644 --- a/Alpha_wrap_3/examples/Alpha_wrap_3/successive_wraps.cpp +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/successive_wraps.cpp @@ -110,7 +110,7 @@ int main(int argc, char** argv) t.reset(); using Oracle = CGAL::Alpha_wraps_3::internal::Triangle_mesh_oracle; - using Wrapper = CGAL::Alpha_wraps_3::internal::Alpha_wrap_3; + using Wrapper = CGAL::Alpha_wraps_3::internal::Alpha_wrapper_3; Wrapper wrapper; // contains the triangulation that is being refined iteratively for(std::size_t i=0; i aw3(oracle); + CGAL::Alpha_wraps_3::internal::Alpha_wrapper_3 aw3(oracle); Mesh wrap; aw3(alpha, offset, wrap); diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index c781319c07e5..1f7a9fdcbebb 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -115,7 +115,7 @@ struct Wrapping_default_visitor template -class Alpha_wrap_3 +class Alpha_wrapper_3 { using Oracle = Oracle_; @@ -183,7 +183,7 @@ class Alpha_wrap_3 Alpha_PQ m_queue; public: - Alpha_wrap_3() + Alpha_wrapper_3() #ifdef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE // '4096' is an arbitrary, not-too-small value for the largest ID in queue initialization : m_queue(4096) @@ -194,7 +194,7 @@ class Alpha_wrap_3 static_assert(std::is_floating_point::value); } - Alpha_wrap_3(const Oracle& oracle) + Alpha_wrapper_3(const Oracle& oracle) : #ifdef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE m_queue(4096), diff --git a/Alpha_wrap_3/include/CGAL/alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/alpha_wrap_3.h index 638c5fb9fa17..8be78675422e 100644 --- a/Alpha_wrap_3/include/CGAL/alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/alpha_wrap_3.h @@ -105,7 +105,7 @@ void alpha_wrap_3(const PointRange& points, using NP_helper = Point_set_processing_3_np_helper; using Geom_traits = typename NP_helper::Geom_traits; using Oracle = Alpha_wraps_3::internal::Triangle_soup_oracle; - using AW3 = Alpha_wraps_3::internal::Alpha_wrap_3; + using AW3 = Alpha_wraps_3::internal::Alpha_wrapper_3; Geom_traits gt = choose_parameter(get_parameter(in_np, internal_np::geom_traits)); @@ -254,7 +254,7 @@ void alpha_wrap_3(const TriangleMesh& tmesh, using Geom_traits = typename GetGeomTraits::type; using Oracle = Alpha_wraps_3::internal::Triangle_mesh_oracle; - using AW3 = Alpha_wraps_3::internal::Alpha_wrap_3; + using AW3 = Alpha_wraps_3::internal::Alpha_wrapper_3; Geom_traits gt = choose_parameter(get_parameter(in_np, internal_np::geom_traits)); @@ -350,7 +350,7 @@ void alpha_wrap_3(const PointRange& points, using NP_helper = Point_set_processing_3_np_helper; using Geom_traits = typename NP_helper::Geom_traits; using Oracle = Alpha_wraps_3::internal::Point_set_oracle; - using AW3 = Alpha_wraps_3::internal::Alpha_wrap_3; + using AW3 = Alpha_wraps_3::internal::Alpha_wrapper_3; Geom_traits gt = choose_parameter(get_parameter(in_np, internal_np::geom_traits)); diff --git a/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_cavity_initializations.cpp b/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_cavity_initializations.cpp index 847799522f2a..af94eecd25ae 100644 --- a/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_cavity_initializations.cpp +++ b/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_cavity_initializations.cpp @@ -28,7 +28,7 @@ void generate_random_seeds(const Oracle& oracle, Seeds& seeds, CGAL::Random& r) { - const auto bbox = CGAL::Alpha_wraps_3::internal::Alpha_wrap_3(oracle).construct_bbox(offset); + const auto bbox = CGAL::Alpha_wraps_3::internal::Alpha_wrapper_3(oracle).construct_bbox(offset); const double sq_offset = CGAL::square(offset); while(seeds.size() < 3) @@ -70,7 +70,7 @@ void alpha_wrap_triangle_mesh(Mesh& input_mesh, Oracle oracle; oracle.add_triangle_mesh(input_mesh); - AW3::internal::Alpha_wrap_3 aw3(oracle); + AW3::internal::Alpha_wrapper_3 aw3(oracle); if(seeds.empty()) generate_random_seeds(oracle, offset, seeds, r); diff --git a/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_multiple_calls.cpp b/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_multiple_calls.cpp index 739d131189cf..35a954f17b20 100644 --- a/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_multiple_calls.cpp +++ b/Alpha_wrap_3/test/Alpha_wrap_3/test_AW3_multiple_calls.cpp @@ -53,7 +53,7 @@ void alpha_wrap_triangle_soup(Points& pr, // AW3 Oracle oracle; oracle.add_triangle_soup(pr, fr); - AW3::internal::Alpha_wrap_3 aw3(oracle); + AW3::internal::Alpha_wrapper_3 aw3(oracle); Mesh wrap; aw3(alpha, offset, wrap, CGAL::parameters::do_enforce_manifoldness(false)); diff --git a/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp index e66d6c83dd3f..0ff34cc54ec3 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp @@ -35,7 +35,7 @@ using TS_Oracle = CGAL::Alpha_wraps_3::internal::Triangle_soup_oracle; using SS_Oracle = CGAL::Alpha_wraps_3::internal::Segment_soup_oracle; using Oracle = CGAL::Alpha_wraps_3::internal::Point_set_oracle; -using Wrapper = CGAL::Alpha_wraps_3::internal::Alpha_wrap_3; +using Wrapper = CGAL::Alpha_wraps_3::internal::Alpha_wrapper_3; // Here is the pipeline for the interruption box: // - The main window is connected to a wrapping thread, which performs the wrapping. From 76aeec9805e66f163a1216f48bfca1b439ea0817 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 13 Oct 2023 10:59:29 +0200 Subject: [PATCH 146/329] Replace try-catch with go_further() --- .../Alpha_wrap_3/Alpha_wrap_3_plugin.cpp | 49 ++++++------------- 1 file changed, 16 insertions(+), 33 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp index 0ff34cc54ec3..f40130dedb12 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp @@ -40,8 +40,8 @@ using Wrapper = CGAL::Alpha_wraps_3::internal::Alpha_wrapper_3; // Here is the pipeline for the interruption box: // - The main window is connected to a wrapping thread, which performs the wrapping. // - The wrapping has a visitor, AW3_interrupter_visitor, which has a shared_ptr to a Boolean -// - When the user clicks the box, the Boolean is switched to *false*, and the visitor throws -// - The wrapping thread catches the exception, and creates the wip mesh +// - When the user clicks the box, the Boolean is switched to *false* +// - The wrapping thread creates the wip mesh // Here is the pipeline for the iterative visualization: // - The main window is connected to a wrapping thread, which performs the wrapping. @@ -201,9 +201,6 @@ struct Iterative_AW3_visualization_visitor } }; -// Use a throw to get out of the AW3 refinement loop -class Out_of_patience_exception : public std::exception { }; - template struct AW3_interrupter_visitor : BaseVisitor @@ -215,15 +212,10 @@ struct AW3_interrupter_visitor : BaseVisitor(base) { } - // Only overload this one because it gives a better state of the wrap (for other visitor calls, - // we often get tetrahedral spikes because there are scaffolding gates in the queue) - template - void before_Steiner_point_insertion(const Wrapper& wrapper, const Point& p) + template + constexpr bool go_further(const Wrapper& wrapper) { - if(*should_stop) - throw Out_of_patience_exception(); - - return BaseVisitor::before_Steiner_point_insertion(wrapper, p); + return !(*should_stop); } }; @@ -273,25 +265,14 @@ struct Wrapper_thread QElapsedTimer elapsed_timer; elapsed_timer.start(); - // try-catch because the stop visitor currently uses a throw - try - { - wrapper(alpha, offset, wrap, - CGAL::parameters::do_enforce_manifoldness(enforce_manifoldness) - .visitor(visitor)); + wrapper(alpha, offset, wrap, + CGAL::parameters::do_enforce_manifoldness(enforce_manifoldness) + .visitor(visitor)); + if(wrapper.queue().empty()) Q_EMIT done(this); - } - catch(const Out_of_patience_exception&) - { - if(enforce_manifoldness) - wrapper.make_manifold(); - - // extract the wrap in its current state - wrapper.extract_surface(wrap, CGAL::get(CGAL::vertex_point, wrap), !enforce_manifoldness); - + else Q_EMIT interrupted(this); - } std::cout << "Wrapping took " << elapsed_timer.elapsed() / 1000. << "s" << std::endl; } @@ -761,10 +742,6 @@ public Q_SLOTS: return; } - // Switch from 'wait' to 'busy' - QApplication::restoreOverrideCursor(); - QApplication::setOverrideCursor(Qt::BusyCursor); - Q_FOREACH(int index, this->scene->selectionIndices()) { Scene_surface_mesh_item* sm_item = qobject_cast(this->scene->item(index)); @@ -824,6 +801,10 @@ public Q_SLOTS: // Create message box with stop button if(use_message_box) { + // Switch from 'wait' to 'busy' + QApplication::restoreOverrideCursor(); + QApplication::setOverrideCursor(Qt::BusyCursor); + m_message_box = new QMessageBox(QMessageBox::NoIcon, "Wrapping", "Wrapping in progress...", @@ -841,6 +822,8 @@ public Q_SLOTS: } // Actual start + QApplication::setOverrideCursor(Qt::WaitCursor); + wrapper_thread->start(); CGAL::Three::Three::getMutex()->lock(); From 8f3cc5c86bc4367ad0975585f40c8a7c017b0d0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 16 Oct 2023 10:18:01 +0200 Subject: [PATCH 147/329] Simplify volume check in make_manifold() --- .../CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 82 ++++++++++--------- 1 file changed, 42 insertions(+), 40 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index 1f7a9fdcbebb..a3976a7ab55c 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -324,53 +324,18 @@ class Alpha_wrapper_3 if(do_enforce_manifoldness) { -#ifdef CGAL_AW3_DEBUG - extract_surface(output_mesh, ovpm, true /*tolerate non manifoldness*/); - - #ifdef CGAL_AW3_DEBUG_DUMP_EVERY_STEP - dump_triangulation_faces("carved_tr.off", false /*only_boundary_faces*/); - IO::write_polygon_mesh("carved_wrap.off", output_mesh, - CGAL::parameters::vertex_point_map(ovpm).stream_precision(17)); - #endif + make_manifold(); - FT base_vol = 0; - if(is_closed(output_mesh)) // might not be due to manifoldness - base_vol = PMP::volume(output_mesh, CGAL::parameters::vertex_point_map(ovpm)); - else - std::cerr << "Warning: couldn't compute volume before manifoldness fixes (mesh is not closed)" << std::endl; +#ifdef CGAL_AW3_DEBUG_DUMP_INTERMEDIATE_WRAPS + dump_triangulation_faces("manifold_wrap.off", true /*only_boundary_faces*/); #endif - make_manifold(); - #ifdef CGAL_AW3_TIMER t.stop(); std::cout << "Manifoldness post-processing took: " << t.time() << " s." << std::endl; t.reset(); t.start(); #endif - -#ifdef CGAL_AW3_DEBUG - if(!is_zero(base_vol)) - { - extract_surface(output_mesh, ovpm, false /*do not tolerate non-manifoldness*/); - - const FT manifold_vol = PMP::volume(output_mesh, CGAL::parameters::vertex_point_map(ovpm)); - const FT ratio = manifold_vol / base_vol; - - std::cout << "Volumes post-manifoldness fix:\n" - << "before: " << base_vol << "\n" - << "after: " << manifold_vol << "\n" - << "ratio: " << ratio << std::endl; - if(ratio > 1.1) // more than 10% extra volume - std::cerr << "Warning: large increase of volume after manifoldness resolution" << std::endl; - } - - std::size_t nm_cells_counter = 0; - for(Cell_handle ch : m_tr.all_cell_handles()) - if(ch->label() == Cell_label::MANIFOLD) - ++nm_cells_counter; - std::cout << "Number of added cells: " << nm_cells_counter << std::endl; -#endif } extract_surface(output_mesh, ovpm, !do_enforce_manifoldness); @@ -1655,10 +1620,26 @@ class Alpha_wrapper_3 // Not the best complexity, but it's very cheap compared to the rest of the algorithm. void make_manifold() { - namespace PMP = Polygon_mesh_processing; - #ifdef CGAL_AW3_DEBUG std::cout << "> Make manifold..." << std::endl; + + auto wrap_volume = [&]() + { + FT vol = 0; + for(Cell_handle ch : m_tr.all_cell_handles()) + if(!ch->is_outside()) + vol += volume(m_tr.point(ch, 0), m_tr.point(ch, 1), m_tr.point(ch, 2), m_tr.point(ch, 3)); + + return vol; + }; + + #ifdef CGAL_AW3_DEBUG_DUMP_INTERMEDIATE_WRAPS + dump_triangulation_faces("carved_tr.off", true /*only_boundary_faces*/); + #endif + + FT base_vol = wrap_volume(); + if(!is_positive(base_vol)) + std::cerr << "Warning: empty wrap?" << std::endl; #endif // This seems more harmful than useful after the priority queue has been introduced since @@ -1813,6 +1794,27 @@ class Alpha_wrapper_3 CGAL_assertion_code(for(Vertex_handle v : m_tr.finite_vertex_handles())) CGAL_assertion(!is_non_manifold(v)); + +#ifdef CGAL_AW3_DEBUG + std::size_t nm_cells_counter = 0; + for(Cell_handle ch : m_tr.all_cell_handles()) + if(ch->label() == Cell_label::MANIFOLD) + ++nm_cells_counter; + std::cout << "Number of added cells: " << nm_cells_counter << std::endl; + + if(!is_zero(base_vol)) + { + const FT manifold_vol = wrap_volume(); + const FT ratio = manifold_vol / base_vol; + + std::cout << "Volumes post-manifoldness fix:\n" + << "before: " << base_vol << "\n" + << "after: " << manifold_vol << "\n" + << "ratio: " << ratio << std::endl; + if(ratio > 1.1) // more than 10% extra volume + std::cerr << "Warning: large increase of volume after manifoldness resolution" << std::endl; + } +#endif } private: From f43c4ec58abeb6d05afc642bc53684ed3669381a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 16 Oct 2023 11:05:48 +0200 Subject: [PATCH 148/329] Minor example fix --- Alpha_wrap_3/examples/Alpha_wrap_3/wrap_from_cavity.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/wrap_from_cavity.cpp b/Alpha_wrap_3/examples/Alpha_wrap_3/wrap_from_cavity.cpp index 9422e4d969be..970bb583484f 100644 --- a/Alpha_wrap_3/examples/Alpha_wrap_3/wrap_from_cavity.cpp +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/wrap_from_cavity.cpp @@ -33,7 +33,7 @@ int main(int argc, char** argv) std::cout << "Input: " << num_vertices(input) << " vertices, " << num_faces(input) << " faces" << std::endl; - const double relative_alpha = (argc > 2) ? std::stod(argv[2]) : 30.; + const double relative_alpha = (argc > 2) ? std::stod(argv[2]) : 40.; const double relative_offset = (argc > 3) ? std::stod(argv[3]) : 600.; // Compute the alpha and offset values @@ -66,7 +66,11 @@ int main(int argc, char** argv) std::cout << "Took " << t.time() << " s." << std::endl; // Save the result - const std::string output_name = generate_output_name(filename, relative_alpha, relative_offset); + std::string input_name = std::string(filename); + input_name = input_name.substr(input_name.find_last_of("/") + 1, input_name.length() - 1); + input_name = input_name.substr(0, input_name.find_last_of(".")); + std::string output_name = input_name + "_cavity_" + std::to_string(static_cast(relative_alpha)) + + "_" + std::to_string(static_cast(relative_offset)) + ".off"; std::cout << "Writing to " << output_name << std::endl; CGAL::IO::write_polygon_mesh(output_name, wrap, CGAL::parameters::stream_precision(17)); From da6b202869a0a80b3f312d92e51d3b07e712b7ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 16 Oct 2023 11:06:11 +0200 Subject: [PATCH 149/329] Add a function to purge inner (useless) CCs --- .../CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 102 ++++++++++++++++-- 1 file changed, 96 insertions(+), 6 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index a3976a7ab55c..a1f82e6e3bd4 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -307,14 +307,22 @@ class Alpha_wrapper_3 t.start(); #endif -#ifdef CGAL_AW3_DEBUG_DUMP_EVERY_STEP - extract_surface(output_mesh, ovpm, true /*tolerate non manifoldness*/); - CGAL::IO::write_polygon_mesh("starting_wrap.off", output_mesh, - CGAL::parameters::vertex_point_map(ovpm).stream_precision(17)); +#ifdef CGAL_AW3_DEBUG_DUMP_INTERMEDIATE_WRAPS + dump_triangulation_faces("starting_wrap.off", true /*only_boundary_faces*/); #endif alpha_flood_fill(visitor); +#ifdef CGAL_AW3_DEBUG_DUMP_INTERMEDIATE_WRAPS + dump_triangulation_faces("flood_filled_wrap.off", true /*only_boundary_faces*/); +#endif + + purge_inner_islands(); + +#ifdef CGAL_AW3_DEBUG_DUMP_INTERMEDIATE_WRAPS + dump_triangulation_faces("purged_wrap.off", true /*only_boundary_faces*/); +#endif + #ifdef CGAL_AW3_TIMER t.stop(); std::cout << "Flood filling took: " << t.time() << " s." << std::endl; @@ -330,6 +338,12 @@ class Alpha_wrapper_3 dump_triangulation_faces("manifold_wrap.off", true /*only_boundary_faces*/); #endif + purge_inner_islands(); + +#ifdef CGAL_AW3_DEBUG_DUMP_INTERMEDIATE_WRAPS + dump_triangulation_faces("purged_manifold_wrap.off", true /*only_boundary_faces*/); +#endif + #ifdef CGAL_AW3_TIMER t.stop(); std::cout << "Manifoldness post-processing took: " << t.time() << " s." << std::endl; @@ -349,8 +363,8 @@ class Alpha_wrapper_3 std::cout << "Alpha wrap vertices: " << vertices(output_mesh).size() << std::endl; std::cout << "Alpha wrap faces: " << faces(output_mesh).size() << std::endl; - #ifdef CGAL_AW3_DEBUG_DUMP_EVERY_STEP - IO::write_polygon_mesh("final.off", output_mesh, CGAL::parameters::stream_precision(17)); + #ifdef CGAL_AW3_DEBUG_DUMP_INTERMEDIATE_WRAPS + IO::write_polygon_mesh("final_wrap.off", output_mesh, CGAL::parameters::stream_precision(17)); dump_triangulation_faces("final_tr.off", false /*only_boundary_faces*/); #endif #endif @@ -1467,6 +1481,82 @@ class Alpha_wrapper_3 return true; } + // Any outside cell that isn't reachable from infinity is a cavity that can + // be discarded. This also removes some difficult non-manifoldness onfigurations + std::size_t purge_inner_islands() + { +#ifdef CGAL_AW3_DEBUG + std::cout << "> Purge inner islands..." << std::endl; +#endif + + std::size_t label_change_counter = 0; + + std::stack cells_to_visit; + + if(!m_seeds.empty()) + { + for(const Point_3& seed : m_seeds) + { + Locate_type lt; + int li, lj; + Cell_handle ch = m_tr.locate(seed, lt, li, lj); + + if(!ch->is_outside()) + { + std::cerr << "Warning: cell containing seed is not outside?!" << std::endl; + continue; + } + + cells_to_visit.push(ch); + } + } + else // typical flooding from outside + { + std::stack cells_to_visit; + cells_to_visit.push(m_tr.infinite_vertex()->cell()); + } + + while(!cells_to_visit.empty()) + { + Cell_handle curr_c = cells_to_visit.top(); + cells_to_visit.pop(); + + CGAL_assertion(curr_c->is_outside()); + + if(curr_c->tds_data().processed()) + continue; + curr_c->tds_data().mark_processed(); + + for(int j=0; j<4; ++j) + { + Cell_handle neigh_c = curr_c->neighbor(j); + if(neigh_c->tds_data().processed() || !neigh_c->is_outside()) + continue; + + cells_to_visit.push(neigh_c); + } + } + + for(Cell_handle ch : m_tr.all_cell_handles()) + { + if(ch->tds_data().is_clear() && ch->is_outside()) + { + ch->label() = Cell_label::INSIDE; + ++label_change_counter; + } + } + + // reset the conflict flags + for(Cell_handle ch : m_tr.all_cell_handles()) + ch->tds_data().clear(); + +#ifdef CGAL_AW3_DEBUG + std::cout << label_change_counter << " label changes" << std::endl; +#endif + + return label_change_counter; + } + private: bool is_non_manifold(Vertex_handle v) const { From c19975bef7190e6b6940a7faf89dfcad6bdc17f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 16 Oct 2023 11:06:36 +0200 Subject: [PATCH 150/329] Revert to the previous non-manifold extraction code Neither are able to produce a closed, combinatorial manifold surface 100% of the time, so minimize the diff. --- .../CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 270 ++++++------------ 1 file changed, 87 insertions(+), 183 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index a1f82e6e3bd4..8192dd063d36 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -708,6 +708,91 @@ class Alpha_wrapper_3 } private: + // Manifoldness is tolerated while debugging and extracting at intermediate states + // Not the preferred way because it uses 3*nv storage + template + void extract_possibly_non_manifold_surface(OutputMesh& output_mesh, + OVPM ovpm) const + { + namespace PMP = Polygon_mesh_processing; + +#ifdef CGAL_AW3_DEBUG + std::cout << "> Extract possibly non-manifold wrap... ()" << std::endl; +#endif + + clear(output_mesh); + + CGAL_assertion_code(for(auto cit=m_tr.finite_cells_begin(), cend=m_tr.finite_cells_end(); cit!=cend; ++cit)) + CGAL_assertion(cit->tds_data().is_clear()); + + for(auto cit=m_tr.finite_cells_begin(), cend=m_tr.finite_cells_end(); cit!=cend; ++cit) + { + Cell_handle seed = cit; + if(seed->is_outside() || seed->tds_data().processed()) + continue; + + std::queue to_visit; + to_visit.push(seed); + + std::vector points; + std::vector > faces; + std::size_t idx = 0; + + while(!to_visit.empty()) + { + const Cell_handle cell = to_visit.front(); + CGAL_assertion(!cell->is_outside() && !m_tr.is_infinite(cell)); + + to_visit.pop(); + + if(cell->tds_data().processed()) + continue; + + cell->tds_data().mark_processed(); + + for(int fid=0; fid<4; ++fid) + { + const Cell_handle neighbor = cell->neighbor(fid); + if(neighbor->is_outside()) + { + // There shouldn't be any artificial vertex on the inside/outside boundary + // (past initialization) +// CGAL_assertion(cell->vertex((fid + 1)&3)->type() == AW3i::Vertex_type:: DEFAULT); +// CGAL_assertion(cell->vertex((fid + 2)&3)->type() == AW3i::Vertex_type:: DEFAULT); +// CGAL_assertion(cell->vertex((fid + 3)&3)->type() == AW3i::Vertex_type:: DEFAULT); + + points.push_back(m_tr.point(cell, Triangulation::vertex_triple_index(fid, 0))); + points.push_back(m_tr.point(cell, Triangulation::vertex_triple_index(fid, 1))); + points.push_back(m_tr.point(cell, Triangulation::vertex_triple_index(fid, 2))); + faces.push_back({idx, idx + 1, idx + 2}); + idx += 3; + } + else + { + to_visit.push(neighbor); + } + } + } + + CGAL_assertion(PMP::is_polygon_soup_a_polygon_mesh(faces)); + PMP::polygon_soup_to_polygon_mesh(points, faces, output_mesh, + CGAL::parameters::default_values(), + CGAL::parameters::vertex_point_map(ovpm)); + + PMP::stitch_borders(output_mesh, CGAL::parameters::vertex_point_map(ovpm)); + CGAL_assertion(is_closed(output_mesh)); + } + + for(auto cit=m_tr.finite_cells_begin(), cend=m_tr.finite_cells_end(); cit!=cend; ++cit) + cit->tds_data().clear(); + + CGAL_postcondition(!is_empty(output_mesh)); + CGAL_postcondition(is_valid_polygon_mesh(output_mesh)); + CGAL_postcondition(is_closed(output_mesh)); + + PMP::orient_to_bound_a_volume(output_mesh, CGAL::parameters::vertex_point_map(ovpm)); + } + template void extract_manifold_surface(OutputMesh& output_mesh, OVPM ovpm) const @@ -781,189 +866,8 @@ class Alpha_wrapper_3 CGAL_postcondition(is_valid_polygon_mesh(output_mesh)); CGAL_postcondition(is_closed(output_mesh)); CGAL_postcondition(PMP::does_bound_a_volume(output_mesh, CGAL::parameters::vertex_point_map(ovpm))); - } - - template - void extract_inside_boundary(OutputMesh& output_mesh, - OVPM ovpm) const - { - namespace PMP = Polygon_mesh_processing; - - using vertex_descriptor = typename boost::graph_traits::vertex_descriptor; - using halfedge_descriptor = typename boost::graph_traits::halfedge_descriptor; - using face_descriptor = typename boost::graph_traits::face_descriptor; - -#ifdef CGAL_AW3_DEBUG - std::cout << "> Extract possibly non-manifold wrap... ()" << std::endl; -#endif - - clear(output_mesh); - - std::vector points; - std::vector > polygons; - - // Explode the polygon soup into indepent triangles, and stitch it back - // edge by edge by walking along the exterior - std::map facet_ids; - std::size_t idx = 0; - - // Looks identical to the block in extract_manifold_surface(), but there are - // two significant differences: - // - Boundary considers MANIFOLD outside here - // - There is no attempt to re-use the same vertex in multiple faces - for(auto fit=m_tr.finite_facets_begin(), fend=m_tr.finite_facets_end(); fit!=fend; ++fit) - { - Facet f = *fit; - if(f.first->is_inside()) // need f.first to be OUTSIDE or MANIFOLD - f = m_tr.mirror_facet(f); - - const Cell_handle ch = f.first; - const int s = f.second; - const Cell_handle nh = ch->neighbor(s); - if(!is_on_inside_boundary(ch, nh)) // MANIFOLD here is outside - continue; - facet_ids[f] = idx / 3; - - points.push_back(m_tr.point(ch, Triangulation::vertex_triple_index(s, 0))); - points.push_back(m_tr.point(ch, Triangulation::vertex_triple_index(s, 1))); - points.push_back(m_tr.point(ch, Triangulation::vertex_triple_index(s, 2))); - polygons.push_back({idx, idx + 1, idx + 2}); - - idx += 3; - } - -#ifdef CGAL_AW3_DEBUG - std::cout << "\t" << points.size() << " points" << std::endl; - std::cout << "\t" << polygons.size() << " polygons" << std::endl; -#endif - - if(polygons.empty()) - { -#ifdef CGAL_AW3_DEBUG - std::cerr << "Warning: empty wrap?..." << std::endl; -#endif - return; - } - - CGAL_assertion(PMP::is_polygon_soup_a_polygon_mesh(polygons)); - - std::unordered_map i2f; - PMP::polygon_soup_to_polygon_mesh(points, polygons, output_mesh, - CGAL::parameters::polygon_to_face_output_iterator(std::inserter(i2f, i2f.end())), - CGAL::parameters::vertex_point_map(ovpm)); - - auto face_to_facet = get(CGAL::dynamic_face_property_t(), output_mesh); - - idx = 0; - for(auto fit=m_tr.all_facets_begin(), fend=m_tr.all_facets_end(); fit!=fend; ++fit) - { - Facet f = *fit; - if(f.first->is_inside()) // f.first must be MANIFOLD or OUTSIDE - f = m_tr.mirror_facet(f); - - const Cell_handle ch = f.first; - const int s = f.second; - const Cell_handle nh = ch->neighbor(s); - if(!is_on_inside_boundary(ch, nh)) // MANIFOLD here is outside - continue; - - put(face_to_facet, i2f[idx++], f); - } - - // grab the stitchable halfedges - std::vector > to_stitch; - - for(face_descriptor f : faces(output_mesh)) - { - const Facet& tr_f = get(face_to_facet, f); - const Cell_handle ch = tr_f.first; - CGAL_assertion(!ch->is_inside()); // OUTSIDE or MANIFOLD - - for(halfedge_descriptor h : halfedges_around_face(halfedge(f, output_mesh), output_mesh)) - { - const vertex_descriptor sv = source(h, output_mesh); - const vertex_descriptor tv = target(h, output_mesh); - - // only need the pair of halfedges once - if(get(ovpm, sv) > get(ovpm, tv)) - continue; - - // One could avoid these point comparisons by using the fact that we know that the graph - // has faces built in a specific order (through BGL::add_face()), but it's better to make - // this code more generic (and it is not very costly). - auto graph_descriptor_to_triangulation_handle = [&](const vertex_descriptor v) - { - const Point_3& p = get(ovpm, v); - for(int i=0; i<4; ++i) - if(ch->vertex(i)->point() == p) - return ch->vertex(i); - - CGAL_assertion(false); - return Vertex_handle(); - }; - - const Vertex_handle s_vh = graph_descriptor_to_triangulation_handle(sv); - const Vertex_handle t_vh = graph_descriptor_to_triangulation_handle(tv); - CGAL_assertion(get(ovpm, sv) == m_tr.point(s_vh)); - CGAL_assertion(get(ovpm, tv) == m_tr.point(t_vh)); - - const int facet_third_id = 6 - (ch->index(s_vh) + ch->index(t_vh) + tr_f.second); // 0 + 1 + 2 + 3 = 6 - Vertex_handle third_vh = ch->vertex(facet_third_id); - - // walk around the edge (in the exterior of the wrap) till meeting an inside cell - Cell_handle start_ch = ch, curr_ch = ch; - do - { - const int i = curr_ch->index(s_vh); - const int j = curr_ch->index(t_vh); - - // the facet is incident to the outside cell, and we walk in the exterior - const int facet_third_id = 6 - (curr_ch->index(s_vh) + curr_ch->index(t_vh) + curr_ch->index(third_vh)); - third_vh = curr_ch->vertex(facet_third_id); - curr_ch = curr_ch->neighbor(Triangulation::next_around_edge(i,j)); - - if(curr_ch->is_inside()) - break; - } - while(curr_ch != start_ch); - - CGAL_assertion(curr_ch != start_ch); - CGAL_assertion(curr_ch->is_inside()); - - const int opp_id = 6 - (curr_ch->index(s_vh) + curr_ch->index(t_vh) + curr_ch->index(third_vh)); - const Facet tr_f2 = m_tr.mirror_facet(Facet(curr_ch, opp_id)); - CGAL_assertion(facet_ids.count(Facet(curr_ch, opp_id)) == 0); - CGAL_assertion(!tr_f2.first->is_inside()); - CGAL_assertion(tr_f2.first->neighbor(tr_f2.second) == curr_ch); - CGAL_assertion(tr_f2.first->has_vertex(s_vh) && tr_f2.first->has_vertex(t_vh)); - - const face_descriptor f2 = i2f[facet_ids.at(tr_f2)]; - halfedge_descriptor h2 = halfedge(f2, output_mesh), done = h2; - while(get(ovpm, target(h2, output_mesh)) != get(ovpm, source(h, output_mesh))) - { - h2 = next(h2, output_mesh); - CGAL_assertion(h2 != done); - if(h2 == done) - break; - } - - CGAL_assertion(get(ovpm, source(h, output_mesh)) == get(ovpm, target(h2, output_mesh))); - CGAL_assertion(get(ovpm, target(h, output_mesh)) == get(ovpm, source(h2, output_mesh))); - CGAL_assertion(get(ovpm, target(next(h2, output_mesh), output_mesh)) == m_tr.point(third_vh)); - - to_stitch.emplace_back(opposite(h, output_mesh), opposite(h2, output_mesh)); - } - } - - PMP::internal::stitch_halfedge_range(to_stitch, output_mesh, ovpm); - - collect_garbage(output_mesh); - - CGAL_postcondition(!is_empty(output_mesh)); - CGAL_postcondition(is_valid_polygon_mesh(output_mesh)); - CGAL_postcondition(is_closed(output_mesh)); - CGAL_postcondition(PMP::does_bound_a_volume(output_mesh, CGAL::parameters::vertex_point_map(ovpm))); + PMP::orient_to_bound_a_volume(output_mesh, CGAL::parameters::vertex_point_map(ovpm)); } public: @@ -973,7 +877,7 @@ class Alpha_wrapper_3 const bool tolerate_non_manifoldness = false) const { if(tolerate_non_manifoldness) - extract_inside_boundary(output_mesh, ovpm); + extract_possibly_non_manifold_surface(output_mesh, ovpm); else extract_manifold_surface(output_mesh, ovpm); } From 29846572e3fcd3eb7b59b19c7e78d07d879456b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 16 Oct 2023 16:56:46 +0200 Subject: [PATCH 151/329] Increment erase counter for cells changing labels during flooding Makes it easier to detect faces that no longer need to be treated (zombies). --- .../CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 28 +++++++++++++------ .../Alpha_wrap_triangulation_cell_base_3.h | 2 +- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index 8192dd063d36..b4be5907d1cb 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -620,7 +620,7 @@ class Alpha_wrapper_3 m_tr.incident_cells(seed_v, std::back_inserter(inc_cells)); for(Cell_handle ch : inc_cells) - ch->label() = cavity_cell_label(ch); + ch->set_label(cavity_cell_label(ch)); } // Should be cheap enough to go through the full triangulation as only seeds have been inserted @@ -656,13 +656,13 @@ class Alpha_wrapper_3 { if(m_tr.is_infinite(ch)) { - ch->label() = Cell_label::OUTSIDE; + ch->set_label(Cell_label::OUTSIDE); const int inf_index = ch->index(m_tr.infinite_vertex()); push_facet(std::make_pair(ch, inf_index)); } else { - ch->label() = Cell_label::INSIDE; + ch->set_label(Cell_label::INSIDE); } } @@ -671,9 +671,10 @@ class Alpha_wrapper_3 void reset_manifold_labels() { + // No erase counter increment, or it will mess up with a possibly non-empty queue. for(Cell_handle ch : m_tr.all_cell_handles()) if(ch->label() == Cell_label::MANIFOLD) - ch->label() = Cell_label::OUTSIDE; + ch->set_label(Cell_label::OUTSIDE); } // This function is used in the case of resumption of a previous run: m_tr is not cleared, @@ -1266,7 +1267,10 @@ class Alpha_wrapper_3 if(m_tr.is_infinite(nh)) { - nh->label() = Cell_label::OUTSIDE; + nh->set_label(Cell_label::OUTSIDE); +#ifndef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE + nh->increment_erase_counter(); +#endif continue; } @@ -1330,7 +1334,7 @@ class Alpha_wrapper_3 for(const Cell_handle& new_ch : new_cells) { // std::cout << "new cell has time stamp " << new_ch->time_stamp() << std::endl; - new_ch->label() = m_tr.is_infinite(new_ch) ? Cell_label::OUTSIDE : Cell_label::INSIDE; + new_ch->set_label(m_tr.is_infinite(new_ch) ? Cell_label::OUTSIDE : Cell_label::INSIDE); } // Push all new boundary facets to the queue. @@ -1359,7 +1363,10 @@ class Alpha_wrapper_3 } else // no need for a Steiner point, carve through and continue { - nh->label() = Cell_label::OUTSIDE; + nh->set_label(Cell_label::OUTSIDE); +#ifndef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE + nh->increment_erase_counter(); +#endif // for each finite facet of neighbor, push it to the queue const int mi = m_tr.mirror_index(ch, s); @@ -1445,7 +1452,10 @@ class Alpha_wrapper_3 { if(ch->tds_data().is_clear() && ch->is_outside()) { - ch->label() = Cell_label::INSIDE; + ch->set_label(Cell_label::INSIDE); +#ifndef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE + ch->increment_erase_counter(); +#endif ++label_change_counter; } } @@ -1762,7 +1772,7 @@ class Alpha_wrapper_3 CGAL_assertion(!m_tr.is_infinite(ic) && ic->is_outside()); // This is where new material is added - ic->label() = Cell_label::MANIFOLD; + ic->set_label(Cell_label::MANIFOLD); #ifdef CGAL_AW3_DEBUG_DUMP_EVERY_STEP static int i = 0; diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_triangulation_cell_base_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_triangulation_cell_base_3.h index f5636b798795..efaeb82d330f 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_triangulation_cell_base_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_triangulation_cell_base_3.h @@ -73,7 +73,7 @@ class Alpha_wrap_triangulation_cell_base_3 public: Cell_label label() const { return m_label; } - Cell_label& label() { return m_label; } + void set_label(const Cell_label label) { m_label = label; } bool is_inside() const { return m_label == Cell_label::INSIDE; } bool is_outside() const { return m_label == Cell_label::OUTSIDE; } From 8f409f03ffc856393e7d6d0b2d04b4ee570fce96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 16 Oct 2023 16:57:45 +0200 Subject: [PATCH 152/329] Avoid producing a mesh with garbage in the non-manifold case --- Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index b4be5907d1cb..a986e5c6a38a 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -792,6 +792,8 @@ class Alpha_wrapper_3 CGAL_postcondition(is_closed(output_mesh)); PMP::orient_to_bound_a_volume(output_mesh, CGAL::parameters::vertex_point_map(ovpm)); + + collect_garbage(output_mesh); } template From 00acf4f75203ea95dd628b8e65018b599b5f7d96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 16 Oct 2023 16:58:17 +0200 Subject: [PATCH 153/329] Fix compilation after change of Facet_status to strong enum --- .../include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index a986e5c6a38a..fc580aa561ce 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -1000,10 +1000,11 @@ class Alpha_wrapper_3 "Traversable facet" }; - if(status > status_count || status < 0) + const std::size_t status_id = static_cast(status); + if(status_id > status_count || status_id < 0) return "Unknown status"; else - return message[status]; + return message[status_id]; } public: From 116bb2beb9a6fda4e055779fde54b9730a77bf43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 16 Oct 2023 17:00:57 +0200 Subject: [PATCH 154/329] Fix shadowing variable --- Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 1 - 1 file changed, 1 deletion(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index fc580aa561ce..675e6e303944 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -1426,7 +1426,6 @@ class Alpha_wrapper_3 } else // typical flooding from outside { - std::stack cells_to_visit; cells_to_visit.push(m_tr.infinite_vertex()->cell()); } From 18154a758b5ad165d96b83ddb25717f4b093c7d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 16 Oct 2023 17:02:05 +0200 Subject: [PATCH 155/329] Loop only finite faces in the volume computation For outward wrapping --- Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index 675e6e303944..31870dd01470 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -1632,7 +1632,7 @@ class Alpha_wrapper_3 auto wrap_volume = [&]() { FT vol = 0; - for(Cell_handle ch : m_tr.all_cell_handles()) + for(Cell_handle ch : m_tr.finite_cell_handles()) if(!ch->is_outside()) vol += volume(m_tr.point(ch, 0), m_tr.point(ch, 1), m_tr.point(ch, 2), m_tr.point(ch, 3)); From b1ffdb00e1196675950864a2a21f90f49c35fbc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 16 Oct 2023 17:04:00 +0200 Subject: [PATCH 156/329] Add an example of pausing and restarting a wrapping process --- .../examples/Alpha_wrap_3/CMakeLists.txt | 3 +- .../pause_and_resume_wrapping.cpp | 164 ++++++++++++++++++ 2 files changed, 166 insertions(+), 1 deletion(-) create mode 100644 Alpha_wrap_3/examples/Alpha_wrap_3/pause_and_resume_wrapping.cpp diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/CMakeLists.txt b/Alpha_wrap_3/examples/Alpha_wrap_3/CMakeLists.txt index 34674777b401..40187ca194cb 100644 --- a/Alpha_wrap_3/examples/Alpha_wrap_3/CMakeLists.txt +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/CMakeLists.txt @@ -12,5 +12,6 @@ create_single_source_cgal_program("triangle_soup_wrap.cpp") create_single_source_cgal_program("point_set_wrap.cpp") create_single_source_cgal_program("wrap_from_cavity.cpp") create_single_source_cgal_program("mixed_inputs_wrap.cpp") -create_single_source_cgal_program("successive_wraps.cpp") create_single_source_cgal_program("volumetric_wrap.cpp") +create_single_source_cgal_program("successive_wraps.cpp") +create_single_source_cgal_program("pause_and_resume_wrapping.cpp") diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/pause_and_resume_wrapping.cpp b/Alpha_wrap_3/examples/Alpha_wrap_3/pause_and_resume_wrapping.cpp new file mode 100644 index 000000000000..5663bce16847 --- /dev/null +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/pause_and_resume_wrapping.cpp @@ -0,0 +1,164 @@ +// This example demonstrates how to interrupt the wrapping process before it has terminated, +// and how to resume afterwards. +// +// -------------------------------- !! Warning !! -------------------------------------------------- +// By default, the wrap uses an unsorted LIFO queue of faces to refine. This means that +// the intermediate result is not very useful because the algorithm carves deep and not wide +// (somewhat like a DFS vs a BFS). +// +// The sorted queue option is enabled with the macro below to make the refinement algorithm +// more uniform. The downside is that it is slower. +// ------------------------------------------------------------------------------------------------- +#define CGAL_AW3_USE_SORTED_PRIORITY_QUEUE + +#include "output_helper.h" + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +namespace AW3 = CGAL::Alpha_wraps_3; +namespace PMP = CGAL::Polygon_mesh_processing; + +using K = CGAL::Exact_predicates_inexact_constructions_kernel; +using Point_3 = K::Point_3; + +using Points = std::vector; +using Polygon = std::array; +using Polygons = std::vector; + +using Mesh = CGAL::Surface_mesh; +using face_descriptor = boost::graph_traits::face_descriptor; + +struct Interrupter_visitor + : public AW3::internal::Wrapping_default_visitor +{ + using Base = AW3::internal::Wrapping_default_visitor; + + CGAL::Real_timer timer; + double max_time = -1; // in seconds + +public: + void set_max_time(double t) { max_time = t; } + +public: + template + void on_flood_fill_begin(const AlphaWrapper&) + { + std::cout << "Starting timer..." << std::endl; + timer.start(); + } + + template + bool go_further(const Wrapper&) + { + if(timer.time() > max_time) + { + timer.stop(); + std::cout << "Paused after " << timer.time() << " s." << std::endl; + return false; + } + + return true; + } +}; + +int main(int argc, char** argv) +{ + std::cout.precision(17); + std::cerr.precision(17); + + CGAL::Random rng; + std::cout << "Random seed = " << rng.get_seed() << std::endl; + + const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/armadillo.off"); + + // = read the soup + Points points; + Polygons polygons; + if(!CGAL::IO::read_polygon_soup(filename, points, polygons) || polygons.empty()) + { + std::cerr << "Invalid soup input: " << filename << std::endl; + return EXIT_FAILURE; + } + + std::cout << "Input: " << points.size() << " points, " << polygons.size() << " faces" << std::endl; + + // Compute the alpha and offset values + const double relative_alpha = (argc > 2) ? std::stod(argv[2]) : rng.get_double(150., 200.); + const double relative_offset = (argc > 3) ? std::stod(argv[3]) : 600.; + std::cout << "relative_alpha = " << relative_alpha << std::endl; + + CGAL::Bbox_3 bbox; + for(const Point_3& p : points) + bbox += p.bbox(); + + const double diag_length = std::sqrt(CGAL::square(bbox.xmax() - bbox.xmin()) + + CGAL::square(bbox.ymax() - bbox.ymin()) + + CGAL::square(bbox.zmax() - bbox.zmin())); + + const double alpha = diag_length / relative_alpha; + const double offset = diag_length / relative_offset; + + // Build the wrapper + using Oracle = CGAL::Alpha_wraps_3::internal::Triangle_soup_oracle; + Oracle oracle(alpha); + oracle.add_triangle_soup(points, polygons, CGAL::parameters::default_values()); + CGAL::Alpha_wraps_3::internal::Alpha_wrapper_3 aw3(oracle); + + // --- Launch the wrapping, and pause when the algorithm has spent 1s flooding + Interrupter_visitor interrupter; + interrupter.set_max_time(1.); + + Mesh wrap; + aw3(alpha, offset, wrap, CGAL::parameters::visitor(interrupter)); + std::cout << ">>> The current wrap has " << num_vertices(wrap) << " vertices" << std::endl; + CGAL::IO::write_polygon_mesh("stopped_1.off", wrap, CGAL::parameters::stream_precision(17)); + + // --- Restart from the previous state, and pause a bit further + interrupter.set_max_time(2.); + aw3(alpha, offset, wrap, CGAL::parameters::visitor(interrupter) + .refine_triangulation(true)); + std::cout << ">>> The current wrap has " << num_vertices(wrap) << " vertices" << std::endl; + CGAL::IO::write_polygon_mesh("stopped_2.off", wrap, CGAL::parameters::stream_precision(17)); + + // --- Restart from the previous state, and let it finish + aw3(alpha, offset, wrap, CGAL::parameters::refine_triangulation(true)); + std::cout << ">>> The final (resumed) wrap has " << num_vertices(wrap) << " vertices" << std::endl; + std::string output_name = generate_output_name(filename, relative_alpha, relative_offset); + std::cout << "Writing to " << "resumed_" + output_name << std::endl; + CGAL::IO::write_polygon_mesh("resumed_" + output_name, wrap, CGAL::parameters::stream_precision(17)); + + // --- Get the final wrap, in one go: + Mesh single_pass_wrap; + CGAL::alpha_wrap_3(points, polygons, alpha, offset, single_pass_wrap); + std::cout << ">>> The final (from scratch) wrap has " << num_vertices(single_pass_wrap) << " vertices" << std::endl; + + output_name = generate_output_name(filename, relative_alpha, relative_offset); + std::cout << "Writing to " << output_name << std::endl; + CGAL::IO::write_polygon_mesh(output_name, single_pass_wrap, CGAL::parameters::stream_precision(17)); + + // --- Compare the results to ensure both approaches yield identical meshes + std::vector > common; + std::vector m1_only; + std::vector m2_only; + PMP::match_faces(wrap, single_pass_wrap, + std::back_inserter(common), + std::back_inserter(m1_only), + std::back_inserter(m2_only)); + if(!m1_only.empty() || !m2_only.empty()) + { + std::cerr << "Error: The two wraps should have been identical!" << std::endl; + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} From 021d1fe8bdec6ac00268d8726094c3c58ac10e6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 16 Oct 2023 17:05:38 +0200 Subject: [PATCH 157/329] Use the sorted priority queue in the plugin --- .../Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp index f40130dedb12..f9eba756bf83 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp @@ -9,6 +9,10 @@ #include "Scene_polylines_item.h" #include "Scene_points_with_normal_item.h" +// Since we want to do visualization and interruption, it's better to use the sorted priority queue, +// even if it is slower +#define CGAL_AW3_USE_SORTED_PRIORITY_QUEUE + #include #include From 847795ec00214884ec7c04ef6f6ad947d5ae937f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 17 Oct 2023 13:01:18 +0200 Subject: [PATCH 158/329] Hide cavity behind a named parameter --- .../CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 44 ++++++++++++------- .../internal/parameters_interface.h | 1 + 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index 31870dd01470..98313249efda 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -278,6 +278,10 @@ class Alpha_wrapper_3 // geometrically manifold. const bool do_enforce_manifoldness = choose_parameter(get_parameter(in_np, internal_np::do_enforce_manifoldness), true); + // Whether to keep pockets of OUTSIDE cells that are not connected to the exterior (or to the + // initial cavities, if used). + const bool keep_inner_ccs = choose_parameter(get_parameter(in_np, internal_np::keep_inner_connected_components), true); + // This parameter enables avoiding recomputing the triangulation from scratch when wrapping // the same input for multiple values of alpha (and typically the same offset values). // /!\ Warning /!\ @@ -317,12 +321,6 @@ class Alpha_wrapper_3 dump_triangulation_faces("flood_filled_wrap.off", true /*only_boundary_faces*/); #endif - purge_inner_islands(); - -#ifdef CGAL_AW3_DEBUG_DUMP_INTERMEDIATE_WRAPS - dump_triangulation_faces("purged_wrap.off", true /*only_boundary_faces*/); -#endif - #ifdef CGAL_AW3_TIMER t.stop(); std::cout << "Flood filling took: " << t.time() << " s." << std::endl; @@ -338,12 +336,6 @@ class Alpha_wrapper_3 dump_triangulation_faces("manifold_wrap.off", true /*only_boundary_faces*/); #endif - purge_inner_islands(); - -#ifdef CGAL_AW3_DEBUG_DUMP_INTERMEDIATE_WRAPS - dump_triangulation_faces("purged_manifold_wrap.off", true /*only_boundary_faces*/); -#endif - #ifdef CGAL_AW3_TIMER t.stop(); std::cout << "Manifoldness post-processing took: " << t.time() << " s." << std::endl; @@ -352,6 +344,17 @@ class Alpha_wrapper_3 #endif } + if(!keep_inner_ccs) + { + // We could purge *before* manifold enforcement, but making the mesh manifold is + // very cheap in most cases, so it is better to keep the code simpler. + purge_inner_connected_components(); + +#ifdef CGAL_AW3_DEBUG_DUMP_INTERMEDIATE_WRAPS + dump_triangulation_faces("purged_wrap.off", true /*only_boundary_faces*/); +#endif + } + extract_surface(output_mesh, ovpm, !do_enforce_manifoldness); #ifdef CGAL_AW3_TIMER @@ -1395,12 +1398,17 @@ class Alpha_wrapper_3 return true; } - // Any outside cell that isn't reachable from infinity is a cavity that can - // be discarded. This also removes some difficult non-manifoldness onfigurations - std::size_t purge_inner_islands() + // Any outside cell that isn't reachable from infinity is a cavity that can be discarded. + std::size_t purge_inner_connected_components() { #ifdef CGAL_AW3_DEBUG std::cout << "> Purge inner islands..." << std::endl; + + std::size_t pre_counter = 0; + for(Cell_handle ch : m_tr.all_cell_handles()) + if(ch->is_outside()) + ++pre_counter; + std::cout << pre_counter << " / " << m_tr.all_cell_handles().size() << " (pre purge)" << std::endl; #endif std::size_t label_change_counter = 0; @@ -1467,6 +1475,12 @@ class Alpha_wrapper_3 ch->tds_data().clear(); #ifdef CGAL_AW3_DEBUG + std::size_t post_counter = 0; + for(Cell_handle ch : m_tr.all_cell_handles()) + if(ch->is_outside()) + ++post_counter; + std::cout << post_counter << " / " << m_tr.all_cell_handles().size() << " (pre purge)" << std::endl; + std::cout << label_change_counter << " label changes" << std::endl; #endif diff --git a/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h b/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h index 435075df6e2a..a164053aabbc 100644 --- a/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h +++ b/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h @@ -238,6 +238,7 @@ CGAL_add_named_parameter(smooth_constrained_edges_t, smooth_constrained_edges, s CGAL_add_named_parameter(do_enforce_manifoldness_t, do_enforce_manifoldness, do_enforce_manifoldness) CGAL_add_named_parameter(seed_points_t, seed_points, seed_points) CGAL_add_named_parameter(refine_triangulation_t, refine_triangulation, refine_triangulation) +CGAL_add_named_parameter(keep_inner_connected_components_t, keep_inner_connected_components, keep_inner_connected_components) // SMDS_3 parameters CGAL_add_named_parameter(surface_facets_t, surface_facets, surface_facets) From d51d71a563f12269e7dbcf6835d1295a66d3bc2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 17 Oct 2023 13:12:24 +0200 Subject: [PATCH 159/329] Misc minor improvements --- .../examples/Alpha_wrap_3/output_helper.h | 2 +- .../pause_and_resume_wrapping.cpp | 2 +- .../Alpha_wrap_3/successive_wraps.cpp | 63 ++++++-------- .../CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 82 +++++++++---------- .../internal/gate_priority_queue.h | 6 +- 5 files changed, 70 insertions(+), 85 deletions(-) diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/output_helper.h b/Alpha_wrap_3/examples/Alpha_wrap_3/output_helper.h index 3ce1155f4ef5..581ac82bff02 100644 --- a/Alpha_wrap_3/examples/Alpha_wrap_3/output_helper.h +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/output_helper.h @@ -16,4 +16,4 @@ std::string generate_output_name(std::string input_name, return output_name; } -#endif // CGAL_ALPHA_WRAP_3_EXAMPLES_OUTPUT_HELPER_H \ No newline at end of file +#endif // CGAL_ALPHA_WRAP_3_EXAMPLES_OUTPUT_HELPER_H diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/pause_and_resume_wrapping.cpp b/Alpha_wrap_3/examples/Alpha_wrap_3/pause_and_resume_wrapping.cpp index 5663bce16847..b22b21d817bc 100644 --- a/Alpha_wrap_3/examples/Alpha_wrap_3/pause_and_resume_wrapping.cpp +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/pause_and_resume_wrapping.cpp @@ -2,7 +2,7 @@ // and how to resume afterwards. // // -------------------------------- !! Warning !! -------------------------------------------------- -// By default, the wrap uses an unsorted LIFO queue of faces to refine. This means that +// By default, the wrapper uses an unsorted LIFO queue of faces to refine. This means that // the intermediate result is not very useful because the algorithm carves deep and not wide // (somewhat like a DFS vs a BFS). // diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/successive_wraps.cpp b/Alpha_wrap_3/examples/Alpha_wrap_3/successive_wraps.cpp index f8533fb9cda9..301aec46e2d5 100644 --- a/Alpha_wrap_3/examples/Alpha_wrap_3/successive_wraps.cpp +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/successive_wraps.cpp @@ -1,4 +1,21 @@ -#define CGAL_AW3_TIMER +// In this example, we reuse the underlying triangulation of the previous state, and carve using +// a new (smaller) alpha value. This enables considerable speed-up: the cumulated time taken +// to run `n` successive instances of `{alpha_wrap(alpha_i)}_(i=1...n)` will be roughly equal +// to the time taken to the single instance of alpha_wrap(alpha_n) from scratch. +// +// The speed-up increases with the number of intermediate results, and on the gap between +// alpha values: if alpha_2 is close to alpha_1, practically no new computation are required, +// and the speed-up is almost 100%. +// +// -------------------------------- !! Warning !! -------------------------------------------------- +// The result of: +// > alpha_wrap(alpha_1, ...) +// > alpha_wrap(alpha_2, ..., reuse) +// is not exactly identical to calling directly: +// > alpha_wrap(alpha_2, ..., do_not_reuse) +// because the queues are sorted slightly differently and the AABB tree is rebuilt differently +// to optimize the runtime. +// ------------------------------------------------------------------------------------------------- #include "output_helper.h" @@ -21,10 +38,6 @@ using Point_3 = K::Point_3; using Mesh = CGAL::Surface_mesh; -// We want decreasing alphas, and these are relative ratios, so they need to be increasing -const std::vector relative_alphas = { 1, 2/*50, 100, 150, 200, 250*/ }; -const FT relative_offset = 600; - int main(int argc, char** argv) { std::cout.precision(17); @@ -48,6 +61,10 @@ int main(int argc, char** argv) CGAL::square(bbox.ymax() - bbox.ymin()) + CGAL::square(bbox.zmax() - bbox.zmin())); + // We want decreasing alphas, and these are relative ratios, so they need to be increasing + const std::vector relative_alphas = { 1, 50, 100, 150, 200, 250 }; + const FT relative_offset = 600; + // =============================================================================================== // Naive approach: @@ -64,17 +81,12 @@ int main(int argc, char** argv) std::cout << ">>> [" << i << "] alpha: " << alpha << " offset: " << offset << std::endl; Mesh wrap; - CGAL::alpha_wrap_3(mesh, alpha, offset, wrap, - CGAL::parameters::do_enforce_manifoldness(false)); + CGAL::alpha_wrap_3(mesh, alpha, offset, wrap); t.stop(); std::cout << " Result: " << num_vertices(wrap) << " vertices, " << num_faces(wrap) << " faces" << std::endl; std::cout << " Elapsed time: " << t.time() << " s." << std::endl; - const std::string output_name = generate_output_name(filename, relative_alphas[i], relative_offset); - std::cout << "Writing to " << output_name << std::endl; - CGAL::IO::write_polygon_mesh(output_name, wrap, CGAL::parameters::stream_precision(17)); - total_time += t.time(); } @@ -82,29 +94,6 @@ int main(int argc, char** argv) // =============================================================================================== // Re-use approach - // - // Here, we restart from the triangulation of the previous state, and carve according - // to a (smaller) alpha value. This enables considerable speed-up: the cumulated time taken - // to run `n` successive instances of `{alpha_wrap(alpha_i)}_(i=1...n)` will be equal to the - // time taken to run alpha_wrap(alpha_n) from scratch. - // - // For example: - // naive: - // alpha_wrap(alpha_1, ...) ---> 2s - // alpha_wrap(alpha_2, ...) ---> 4s - // alpha_wrap(alpha_3, ...) ---> 8s - // will become with reusability: - // alpha_wrap(alpha_1, ..., reuse) ---> 2s - // alpha_wrap(alpha_2, ..., reuse) ---> 2s // 2+2 = 4s = naive alpha_2 - // alpha_wrap(alpha_3, ..., reuse) ---> 4s // 2+2+4 = 8s = naive alpha_3 - // Thus, if we care about the intermediate results, we save 6s (8s instead of 14s). - // The speed-up increases with the number of intermediate results, and if the alpha values - // are close. - // - // !! Warning !! - // The result of alpha_wrap(alpha_1, ...) followed by alpha_wrap(alpha_2, ...) with alpha_2 - // smaller than alpha_1 is going to be close but NOT exactly equal to that produced by calling - // alpha_wrap(alpha_2, ...) directly. total_time = 0.; t.reset(); @@ -122,7 +111,7 @@ int main(int argc, char** argv) const double offset = diag_length / relative_offset; std::cout << ">>> [" << i << "] alpha: " << alpha << " offset: " << offset << std::endl; - // The triangle mesh oracle can be initialized with alpha to internally perform a split + // The triangle mesh oracle should be initialized with alpha to internally perform a split // of too-big facets while building the AABB Tree. This split in fact yields a significant // speed-up for meshes with elements that are large compared to alpha. This speed-up makes it // faster to re-build the AABB tree for every value of alpha than to use a non-optimized tree. @@ -131,9 +120,7 @@ int main(int argc, char** argv) wrapper.oracle() = oracle; Mesh wrap; - wrapper(alpha, offset, wrap, - CGAL::parameters::do_enforce_manifoldness(false) - .refine_triangulation((i != 0))); + wrapper(alpha, offset, wrap, CGAL::parameters::refine_triangulation((i != 0))); t.stop(); std::cout << " Result: " << num_vertices(wrap) << " vertices, " << num_faces(wrap) << " faces" << std::endl; diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index 98313249efda..45834cd6b61f 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -125,7 +125,7 @@ class Alpha_wrapper_3 using Default_Vb = Alpha_wrap_triangulation_vertex_base_3; using Default_Cb = Alpha_wrap_triangulation_cell_base_3; - using Default_Cbt = Cell_base_with_timestamp; // determinism + using Default_Cbt = Cell_base_with_timestamp; // for determinism using Default_Tds = CGAL::Triangulation_data_structure_3; using Default_Triangulation = CGAL::Delaunay_triangulation_3; @@ -143,12 +143,13 @@ class Alpha_wrapper_3 using Gate = internal::Gate; - // A sorted queue is a priority queue sorted by circumradius, and is experimentally much slower, - // but intermediate results are visually nice: somewhat uniform meshes. + // A sorted queue is a priority queue sorted by circumradius, and is experimentally significantly + // slower. However, intermediate results are usable: at each point of the algorithm, the wrap + // has a somewhat uniform mesh element size. // // An unsorted queue is a LIFO queue, and is experimentally much faster (~35%), - // but intermediate results are not useful: a LIFO will mean carving is done very deep - // before than wide + // but intermediate results are not useful: a LIFO carves deep before than wide, + // and can thus for example leave scaffolding faces till almost the end of the refinement. #ifdef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE using Alpha_PQ = Modifiable_priority_queue, CGAL_BOOST_PAIRING_HEAP>; #else @@ -270,7 +271,7 @@ class Alpha_wrapper_3 Wrapping_default_visitor default_visitor; Visitor visitor = choose_parameter(get_parameter_reference(in_np, internal_np::visitor), default_visitor); - // + // Points used to create initial cavities m_seeds = choose_parameter(get_parameter_reference(in_np, internal_np::seed_points), Seeds()); // Whether or not some cells should be reflagged as "inside" after the refinement+carving loop @@ -278,16 +279,16 @@ class Alpha_wrapper_3 // geometrically manifold. const bool do_enforce_manifoldness = choose_parameter(get_parameter(in_np, internal_np::do_enforce_manifoldness), true); - // Whether to keep pockets of OUTSIDE cells that are not connected to the exterior (or to the + // Whether to keep pockets of "outside" cells that are not connected to the exterior (or to the // initial cavities, if used). const bool keep_inner_ccs = choose_parameter(get_parameter(in_np, internal_np::keep_inner_connected_components), true); // This parameter enables avoiding recomputing the triangulation from scratch when wrapping // the same input for multiple values of alpha (and typically the same offset values). - // /!\ Warning /!\ // - // If this is enabled, the 3D triangulation will NOT be re-initialized - // at launch. This means that the triangulation is NOT cleared, even if: + // /!\ Warning /!\ + // If this is enabled, the 3D triangulation will NOT be re-initialized at launch. + // This means that the triangulation is NOT cleared, even if: // - you use an alpha value that is greater than what was used in a previous run; you will // obtain the same result as the last run. // - you use a different offset value between runs, you might then get points that are not @@ -423,12 +424,12 @@ class Alpha_wrapper_3 // boundary considers them inside. bool is_on_inside_boundary(Cell_handle ch, Cell_handle nh) const { - return (ch->is_inside() != nh->is_inside()); // one is INSIDE, the other is not + return (ch->is_inside() != nh->is_inside()); // one is "inside", the other is not } bool is_on_outside_boundary(Cell_handle ch, Cell_handle nh) const { - return (ch->is_outside() != nh->is_outside()); // one is OUTSIDE, the other is not + return (ch->is_outside() != nh->is_outside()); // one is "outside", the other is not } private: @@ -552,7 +553,7 @@ class Alpha_wrapper_3 continue; } - // Mark the seeds and icosahedron vertices as "scaffolding vertices" such that the facets + // Mark the seeds and icosahedron vertices as "scaffolding" vertices such that the facets // incident to these vertices are always traversable regardless of their circumcenter. // This is done because otherwise some cavities can appear on the mesh: non-traversable facets // with two vertices on the offset, and the third being a deeper inside seed / ico_seed. @@ -633,7 +634,7 @@ class Alpha_wrapper_3 continue; // When the algorithm starts from a manually dug hole, infinite cells are initialized - // as INSIDE such that they do not appear on the boundary + // as "inside" such that they do not appear on the boundary CGAL_assertion(!m_tr.is_infinite(ch)); for(int i=0; i<4; ++i) @@ -651,7 +652,7 @@ class Alpha_wrapper_3 return true; } - // tag all infinite cells OUTSIDE and all finite cells INSIDE + // tag all infinite cells "outside" and all finite cells "inside" // init queue with all convex hull facets bool initialize_from_infinity() { @@ -688,9 +689,6 @@ class Alpha_wrapper_3 std::cout << "Restart from a DT of " << m_tr.number_of_cells() << " cells" << std::endl; #endif - Real_timer t; - t.start(); - for(Cell_handle ch : m_tr.all_cell_handles()) { if(ch->is_inside()) @@ -698,16 +696,12 @@ class Alpha_wrapper_3 for(int i=0; i<4; ++i) { - if(ch->neighbor(i)->is_outside()) - continue; + if(ch->neighbor(i)->is_inside()) + push_facet(std::make_pair(ch, i)); - push_facet(std::make_pair(ch, i)); } } - t.stop(); - std::cout << t.time() << " for scanning a queue of size " << m_queue.size() << std::endl; - return true; } @@ -751,7 +745,6 @@ class Alpha_wrapper_3 if(cell->tds_data().processed()) continue; - cell->tds_data().mark_processed(); for(int fid=0; fid<4; ++fid) @@ -1024,12 +1017,12 @@ class Alpha_wrapper_3 << m_tr.point(f.first, Triangulation::vertex_triple_index(f.second, 2)) << std::endl; #endif - // skip if neighbor is OUTSIDE or infinite + // skip if neighbor is "outside" or infinite const Cell_handle ch = f.first; const int id = f.second; CGAL_precondition(ch->label() == Cell_label::INSIDE || ch->label() == Cell_label::OUTSIDE); - if(!ch->is_outside()) // INSIDE or MANIFOLD + if(!ch->is_outside()) // "inside" or "manifold" { #ifdef CGAL_AW3_DEBUG_FACET_STATUS std::cout << "Facet is inside" << std::endl; @@ -1168,6 +1161,10 @@ class Alpha_wrapper_3 // and we can resume with the current queue if(resuming) { +#ifdef CGAL_AW3_DEBUG + std::cout << "Resuming with a queue of size: " << m_queue.size() << std::endl; +#endif + reset_manifold_labels(); return true; } @@ -1181,7 +1178,7 @@ class Alpha_wrapper_3 if(refining) { // If we are re-using the triangulation, change the label of the extra elements - // that we have added to ensure a manifold result back to external (MANIFOLD -> OUTSIDE) + // that we have added to ensure a manifold result back to external ("manifold" -> "outside") reset_manifold_labels(); return initialize_from_existing_triangulation(); @@ -1190,7 +1187,6 @@ class Alpha_wrapper_3 { m_tr.clear(); - insert_bbox_corners(); if(m_seeds.empty()) @@ -1512,7 +1508,7 @@ class Alpha_wrapper_3 if(ic->is_outside()) outside_start = ic; else if(inside_start == Cell_handle()) - inside_start = ic; // can be INSIDE or MANIFOLD + inside_start = ic; // can be "inside" or "manifold" } // fully inside / outside @@ -1659,12 +1655,12 @@ class Alpha_wrapper_3 FT base_vol = wrap_volume(); if(!is_positive(base_vol)) - std::cerr << "Warning: empty wrap?" << std::endl; + std::cerr << "Warning: wrap with non-positive volume?" << std::endl; #endif - // This seems more harmful than useful after the priority queue has been introduced since - // it adds a lot of flat cells into the triangulation, which then get added to the mesh - // during manifoldness fixing. + // This ends up more harmful than useful after the priority queue has been introduced since + // it usually results in a lot of flat cells into the triangulation, which then get added + // to the mesh during manifoldness fixing. // remove_bbox_vertices(); std::stack non_manifold_vertices; // @todo sort somehow? @@ -1694,8 +1690,8 @@ class Alpha_wrapper_3 return false; }; - // This seemed like a good idea, but in the end it can have strong cascading issues, - // whereas some cells with much lower volume would have solved the non-manifoldness. + // This originally seemed like a good idea, but in the end it can have strong cascading issues, + // whereas some cells with much smaller volume could have solved the non-manifoldness. // auto is_on_boundary = [](Cell_handle c, int i) -> bool // { // return is_on_outside_boundary(c, c->neighbor(i)); @@ -1716,14 +1712,14 @@ class Alpha_wrapper_3 // return boundary_facets; // }; - // longest edge works better + // Experimentally, longest edge works better // auto sq_circumradius = [&](Cell_handle c) -> FT // { // const Point_3& cc = circumcenter(c); // return geom_traits().compute_squared_distance_3_object()(m_tr.point(c, 0), cc); // }; - // the reasoning behind using longest edge rather than volume is that we want to avoid + // The reasoning behind using longest edge rather than volume is that we want to avoid // spikes (which would have a small volume), and can often happen since we do not spend // any care on the quality of tetrahedra. auto sq_longest_edge = [&](Cell_handle c) -> FT @@ -1756,9 +1752,9 @@ class Alpha_wrapper_3 // - cells without bbox vertices // - small cells when equal number of boundary facets // - // Note that these are properties that do not depend on where the surface is, so we can - // sort once. However, if a criterion such as the number of inside cells were added, - // one would need to sort again after each modification of is_outside() statuses. + // Note that these are properties that do not depend on the cell labels, and so we only need + // to sort once. However, if a criterion such as the number of incident inside cells were added, + // we would need to sort after each modification of "inside"/"outside" labels. auto comparer = [&](Cell_handle l, Cell_handle r) -> bool { CGAL_precondition(!m_tr.is_infinite(l) && !m_tr.is_infinite(r)); @@ -1780,7 +1776,7 @@ class Alpha_wrapper_3 // 'std::stable_sort' to have determinism without having to write something like: // if(longest_edge(l) == longest_edge(r)) return ... - // in the comparer. It's a small range, so the cost does not matter. + // in the comparer. It's almost always a small range, so the extra cost does not matter. std::stable_sort(finite_outside_inc_cells.begin(), finite_outside_inc_cells.end(), comparer); for(Cell_handle ic : finite_outside_inc_cells) @@ -1803,6 +1799,8 @@ class Alpha_wrapper_3 CGAL_assertion(!is_non_manifold(v)); + // Check if the new material has not created a non-manifold configuration. + // @speed this could be done on only the vertices of cells whose labels have changed. std::vector adj_vertices; adj_vertices.reserve(64); m_tr.finite_adjacent_vertices(v, std::back_inserter(adj_vertices)); diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/gate_priority_queue.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/gate_priority_queue.h index 9c29ac9e7226..f7947f246a4b 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/gate_priority_queue.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/gate_priority_queue.h @@ -70,12 +70,12 @@ struct Less_gate template bool operator()(const Gate& a, const Gate& b) const { - // If one is permissive and the other is not, give priority to the permissive facet + // If one is permissive and the other is not, give priority to the permissive facet. // // The permissive facet are given highest priority because they need to be treated // regardless of their circumradius. Treating them first allow the part that depends - // on alpha to be treated uniformly in a way: whatever the alpha, all scaffolding faces - // will first be treated + // on alpha to be treated uniformly in a way: whatever the alpha, all permissive faces + // will first be treated. if(a.is_permissive_facet() != b.is_permissive_facet()) return a.is_permissive_facet(); From f753c8928c2608f13d1e21d632a7cccd03338bb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 17 Oct 2023 17:15:13 +0200 Subject: [PATCH 160/329] Minor compilation fix --- .../include/CGAL/Alpha_wrap_3/internal/validation.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/validation.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/validation.h index c9445c9e9c50..6d9a9191d5f4 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/validation.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/validation.h @@ -117,7 +117,7 @@ bool has_expected_Hausdorff_distance(const TriangleMesh& wrap, template bool is_valid_wrap(const TriangleMesh& wrap, - const bool check_manifoldness = true, + const bool check_manifoldness, const NamedParameters& np = parameters::default_values()) { namespace PMP = CGAL::Polygon_mesh_processing; @@ -203,6 +203,13 @@ bool is_valid_wrap(const TriangleMesh& wrap, return true; } +template +bool is_valid_wrap(const TriangleMesh& wrap, + const NamedParameters& np = parameters::default_values()) +{ + return is_valid_wrap(wrap, true /*consider manifoldness*/, np); +} + template From c7af977fd24d499ac28e1624ae28b166c3b0f51f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 18 Oct 2023 09:43:20 +0200 Subject: [PATCH 161/329] Add code in benchmarks to enable ignoring inputs that have degeneracies --- .../compute_robustness_benchmark_data.py | 25 ++++++++--------- .../generate_robustness_benchmark_charts.py | 26 +++++++++--------- .../Robustness/robustness_benchmark.cpp | 27 +++++++++++-------- 3 files changed, 43 insertions(+), 35 deletions(-) diff --git a/Alpha_wrap_3/benchmark/Alpha_wrap_3/Robustness/compute_robustness_benchmark_data.py b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Robustness/compute_robustness_benchmark_data.py index 9e5fead9f864..9def2bb6cc16 100755 --- a/Alpha_wrap_3/benchmark/Alpha_wrap_3/Robustness/compute_robustness_benchmark_data.py +++ b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Robustness/compute_robustness_benchmark_data.py @@ -23,18 +23,19 @@ def compute_robustness_benchmark_data(execname, filename, alpha, max_time): exit_codes = { 0 : "VALID_SOLID_OUTPUT", - 1 : "OUTPUT_IS_NOT_TRIANGLE_MESH", - 2 : "OUTPUT_IS_COMBINATORIAL_NON_MANIFOLD", - 3 : "OUTPUT_HAS_BORDERS", - 4 : "OUTPUT_HAS_DEGENERATED_FACES", - 5 : "OUTPUT_HAS_GEOMETRIC_SELF_INTERSECTIONS", - 6 : "OUTPUT_DOES_NOT_BOUND_VOLUME", - 7 : "OUTPUT_DOES_NOT_CONTAIN_INPUT", - 8 : "OUTPUT_DISTANCE_IS_TOO_LARGE", - 9 : "SIGSEGV", - 10 : "SIGABRT", - 11 : "SIGFPE", - 12 : "TIMEOUT" + 1 : "INPUT_IS_INVALID", + 2 : "OUTPUT_IS_NOT_TRIANGLE_MESH", + 3 : "OUTPUT_IS_COMBINATORIAL_NON_MANIFOLD", + 4 : "OUTPUT_HAS_BORDERS", + 5 : "OUTPUT_HAS_DEGENERATED_FACES", + 6 : "OUTPUT_HAS_GEOMETRIC_SELF_INTERSECTIONS", + 7 : "OUTPUT_DOES_NOT_BOUND_VOLUME", + 8 : "OUTPUT_DOES_NOT_CONTAIN_INPUT", + 9 : "OUTPUT_DISTANCE_IS_TOO_LARGE", + 10 : "SIGSEGV", + 11 : "SIGABRT", + 12 : "SIGFPE", + 13 : "TIMEOUT" } exit_code = 0 diff --git a/Alpha_wrap_3/benchmark/Alpha_wrap_3/Robustness/generate_robustness_benchmark_charts.py b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Robustness/generate_robustness_benchmark_charts.py index da313069594f..f9938d4fc7b6 100644 --- a/Alpha_wrap_3/benchmark/Alpha_wrap_3/Robustness/generate_robustness_benchmark_charts.py +++ b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Robustness/generate_robustness_benchmark_charts.py @@ -40,22 +40,24 @@ def main(argv): exit_codes = { 0 : "VALID_SOLID_OUTPUT", - 1 : "OUTPUT_IS_NOT_TRIANGLE_MESH", - 2 : "OUTPUT_IS_COMBINATORIAL_NON_MANIFOLD", - 3 : "OUTPUT_HAS_BORDERS", - 4 : "OUTPUT_HAS_DEGENERATED_FACES", - 5 : "OUTPUT_HAS_GEOMETRIC_SELF_INTERSECTIONS", - 6 : "OUTPUT_DOES_NOT_BOUND_VOLUME", - 7 : "OUTPUT_DOES_NOT_CONTAIN_INPUT", - 8 : "OUTPUT_DISTANCE_IS_TOO_LARGE", - 9 : "SIGSEGV", - 10 : "SIGABRT", - 11 : "SIGFPE", - 12 : "TIMEOUT" + 1 : "INPUT_IS_INVALID", + 2 : "OUTPUT_IS_NOT_TRIANGLE_MESH", + 3 : "OUTPUT_IS_COMBINATORIAL_NON_MANIFOLD", + 4 : "OUTPUT_HAS_BORDERS", + 5 : "OUTPUT_HAS_DEGENERATED_FACES", + 6 : "OUTPUT_HAS_GEOMETRIC_SELF_INTERSECTIONS", + 7 : "OUTPUT_DOES_NOT_BOUND_VOLUME", + 8 : "OUTPUT_DOES_NOT_CONTAIN_INPUT", + 9 : "OUTPUT_DISTANCE_IS_TOO_LARGE", + 10 : "SIGSEGV", + 11 : "SIGABRT", + 12 : "SIGFPE", + 13 : "TIMEOUT" } current_run_data = { "VALID_SOLID_OUTPUT" : 0, + "INPUT_IS_INVALID" : 0, "OUTPUT_IS_NOT_TRIANGLE_MESH" : 0, "OUTPUT_IS_COMBINATORIAL_NON_MANIFOLD" : 0, "OUTPUT_HAS_BORDERS" : 0, diff --git a/Alpha_wrap_3/benchmark/Alpha_wrap_3/Robustness/robustness_benchmark.cpp b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Robustness/robustness_benchmark.cpp index 57f58b342bd5..353e5569d1f9 100644 --- a/Alpha_wrap_3/benchmark/Alpha_wrap_3/Robustness/robustness_benchmark.cpp +++ b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Robustness/robustness_benchmark.cpp @@ -21,14 +21,15 @@ enum Robustness_benchmark_exit_code VALID_SOLID_OUTPUT = 0, // Failure - OUTPUT_IS_NOT_TRIANGLE_MESH = 1, - OUTPUT_IS_COMBINATORIAL_NON_MANIFOLD = 2, - OUTPUT_HAS_BORDERS = 3, - OUTPUT_HAS_DEGENERATED_FACES = 4, - OUTPUT_HAS_GEOMETRIC_SELF_INTERSECTIONS = 5, - OUTPUT_DOES_NOT_BOUND_VOLUME = 6, - OUTPUT_DOES_NOT_CONTAIN_INPUT = 7, - OUTPUT_DISTANCE_IS_TOO_LARGE = 8, + INTPUT_IS_INVALID = 1, + OUTPUT_IS_NOT_TRIANGLE_MESH = 2, + OUTPUT_IS_COMBINATORIAL_NON_MANIFOLD = 3, + OUTPUT_HAS_BORDERS = 4, + OUTPUT_HAS_DEGENERATED_FACES = 5, + OUTPUT_HAS_GEOMETRIC_SELF_INTERSECTIONS = 6, + OUTPUT_DOES_NOT_BOUND_VOLUME = 7, + OUTPUT_DOES_NOT_CONTAIN_INPUT = 8, + OUTPUT_DISTANCE_IS_TOO_LARGE = 9, }; } // namespace @@ -58,14 +59,18 @@ int main(int argc, char** argv) } if(argc < 3 || relative_alpha_ratio <= 0.) - return AW3i::VALID_SOLID_OUTPUT; + return AW3i::INTPUT_IS_INVALID; Mesh input_mesh; if(!PMP::IO::read_polygon_mesh(entry_name_ptr, input_mesh) || is_empty(input_mesh) || - !is_triangle_mesh(input_mesh)) + !is_triangle_mesh(input_mesh) +#ifndef CGAL_ALPHA_WRAP_3_TOLERATE_DEGENERACIES + || AW3i::has_degenerated_faces(input_mesh) +#endif + ) { - return AW3i::VALID_SOLID_OUTPUT; + return AW3i::INTPUT_IS_INVALID; } const CGAL::Bbox_3 bbox = PMP::bbox(input_mesh); From e6b84d48513ab52a4b0b6d973509d03d22f251b3 Mon Sep 17 00:00:00 2001 From: Sebastien Loriot Date: Wed, 18 Oct 2023 10:19:23 +0200 Subject: [PATCH 162/329] typo Co-authored-by: Jane Tournois --- .../CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h index 4e9082996e49..8cd6dc4f6ccc 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h @@ -41,7 +41,7 @@ namespace Polygon_mesh_processing { * * @param pm the polygon mesh to be refined. * @param value_map the property map containing a value at each vertex for a given function defined over the mesh. - * @param isovalue the value used to defined + * @param isovalue the value used to refine * @param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below * * \cgalNamedParamsBegin From 2c19ffcd8bce9eef3a5a6a35189dfc5bc2358c19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 18 Oct 2023 10:29:28 +0200 Subject: [PATCH 163/329] Add a warning --- Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index 45834cd6b61f..94694034cdd1 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -281,6 +281,9 @@ class Alpha_wrapper_3 // Whether to keep pockets of "outside" cells that are not connected to the exterior (or to the // initial cavities, if used). + // + // /!\ Warning /!\ + // If you refine or pause while removing pockets, you will get valid but different wraps. const bool keep_inner_ccs = choose_parameter(get_parameter(in_np, internal_np::keep_inner_connected_components), true); // This parameter enables avoiding recomputing the triangulation from scratch when wrapping From 08fa9f8a58fb24ae9119e06e1d188b3a21b1c568 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 20 Oct 2023 08:57:07 +0200 Subject: [PATCH 164/329] fix wording --- .../CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h index 8cd6dc4f6ccc..f1ceb6e59d33 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h @@ -46,7 +46,8 @@ namespace Polygon_mesh_processing { * * \cgalNamedParamsBegin * \cgalParamNBegin{edge_is_constrained_map} - * \cgalParamDescription{an output property map associating `true` to all new edges added by the cut, and `false` to input edges.} + * \cgalParamDescription{an output property map associating `true` to all new edges connecting vertices on the isolevel, + * and `false` for all other edges.} * \cgalParamType{a class model of `WritablePropertyMap` with `boost::graph_traits::%edge_descriptor` * as key type and `bool` as value type} * \cgalParamDefault{No marks on edges will be put} From fe28c0d64acd1fc151a7792a934f05155350a520 Mon Sep 17 00:00:00 2001 From: Sebastien Loriot Date: Fri, 20 Oct 2023 11:46:39 +0200 Subject: [PATCH 165/329] doc bugs Co-authored-by: Andreas Fabri --- .../CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h index f1ceb6e59d33..293d791a47cd 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h @@ -46,7 +46,7 @@ namespace Polygon_mesh_processing { * * \cgalNamedParamsBegin * \cgalParamNBegin{edge_is_constrained_map} - * \cgalParamDescription{an output property map associating `true` to all new edges connecting vertices on the isolevel, + * \cgalParamDescription{an output property map associating `true` to all edges connecting vertices on the isolevel, * and `false` for all other edges.} * \cgalParamType{a class model of `WritablePropertyMap` with `boost::graph_traits::%edge_descriptor` * as key type and `bool` as value type} @@ -55,7 +55,7 @@ namespace Polygon_mesh_processing { * * \cgalParamNBegin{vertex_point_map} * \cgalParamDescription{a property map associating points to the vertices of `pm`} - * \cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits::%vertex_descriptor` + * \cgalParamType{a class model of `ReadWritePropertyMap` with `boost::graph_traits::%vertex_descriptor` * as key type and `%Point_3` as value type} * \cgalParamDefault{`boost::get(CGAL::vertex_point, pm)`} * \cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t` From 48ee7cad903bee2dc37049782755344ad5b8b419 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 25 Oct 2023 10:03:14 +0100 Subject: [PATCH 166/329] Add read_VTK() so that we can also read non-xml *.vtk files --- Stream_support/include/CGAL/IO/VTK.h | 58 ++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/Stream_support/include/CGAL/IO/VTK.h b/Stream_support/include/CGAL/IO/VTK.h index 585cc9d96854..49cdb33da9ce 100644 --- a/Stream_support/include/CGAL/IO/VTK.h +++ b/Stream_support/include/CGAL/IO/VTK.h @@ -26,8 +26,10 @@ #include #include #include +#include #include #include +#include #endif #if defined(CGAL_USE_VTK) || defined(DOXYGEN_RUNNING) @@ -140,6 +142,62 @@ bool read_VTP(const std::string& fname, PointRange& points, PolygonRange& polygo return read_VTP(fname, points, polygons, parameters::default_values()); } + +template +bool read_VTK(const std::string& fname, + PointRange& points, + PolygonRange& polygons, + const NamedParameters& np) +{ + std::ifstream test(fname); + if(!test.good()) + { + std::cerr<<"File doesn't exist."< data; + vtkSmartPointer obs = + vtkSmartPointer::New(); + vtkSmartPointer reader = + CGAL::IO::internal::read_vtk_file(fname,obs); + data = vtkPolyData::SafeDownCast(reader->GetOutput()); + if (!data) + data = vtkUnstructuredGrid::SafeDownCast(reader->GetOutput()); + + if (obs->GetError()) + return false; + + return internal::vtkPointSet_to_polygon_soup(data, points, polygons, np); +} + +/*! + * \ingroup PkgStreamSupportIoFuncsVTP + * + * \brief reads the content of the input file into `points` and `polygons`, using the \ref IOStreamVTK. + * + * \attention The polygon soup is not cleared, and the data from the file are appended. + * + * \tparam PointRange a model of the concepts `RandomAccessContainer` and `BackInsertionSequence` + * whose value type is the point type + * \tparam PolygonRange a model of the concepts `SequenceContainer` and `BackInsertionSequence` + * whose `value_type` is itself a model of the concept `SequenceContainer` + * and `BackInsertionSequence` whose `value_type` is an unsigned integer type + * convertible to `std::size_t` + * + * \param fname the path to the input file + * \param points points of the soup of polygons + * \param polygons a range of polygons. Each element in it describes a polygon + * using the indices of the points in `points`. + * + * \returns `true` if the reading was successful, `false` otherwise. + */ +template +bool read_VTK(const std::string& fname, PointRange& points, PolygonRange& polygons) +{ + return read_VTK(fname, points, polygons, parameters::default_values()); +} + //////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////// // Write From c9eed8c4ece829b195013aa3723358e62bfe29db Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 26 Oct 2023 16:04:05 +0100 Subject: [PATCH 167/329] backtick --- Stream_support/include/CGAL/IO/VTK.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Stream_support/include/CGAL/IO/VTK.h b/Stream_support/include/CGAL/IO/VTK.h index 49cdb33da9ce..d0f605834db2 100644 --- a/Stream_support/include/CGAL/IO/VTK.h +++ b/Stream_support/include/CGAL/IO/VTK.h @@ -123,7 +123,7 @@ bool read_VTP(const std::string& fname, * \attention The polygon soup is not cleared, and the data from the file are appended. * * \tparam PointRange a model of the concepts `RandomAccessContainer` and `BackInsertionSequence` - * whose value type is the point type + * whose `value_type` is the point type * \tparam PolygonRange a model of the concepts `SequenceContainer` and `BackInsertionSequence` * whose `value_type` is itself a model of the concept `SequenceContainer` * and `BackInsertionSequence` whose `value_type` is an unsigned integer type @@ -179,7 +179,7 @@ bool read_VTK(const std::string& fname, * \attention The polygon soup is not cleared, and the data from the file are appended. * * \tparam PointRange a model of the concepts `RandomAccessContainer` and `BackInsertionSequence` - * whose value type is the point type + * whose `value_type` is the point type * \tparam PolygonRange a model of the concepts `SequenceContainer` and `BackInsertionSequence` * whose `value_type` is itself a model of the concept `SequenceContainer` * and `BackInsertionSequence` whose `value_type` is an unsigned integer type @@ -402,7 +402,7 @@ void write_soup_polys_points(std::ostream& os, * * \brief writes the content of `points` and `polygons` in `out`, using the \ref IOStreamVTK. * - * \tparam PointRange a model of the concept `RandomAccessContainer` whose value type is the point type + * \tparam PointRange a model of the concept `RandomAccessContainer` whose `value_type` is the point type * \tparam PolygonRange a model of the concept `SequenceContainer` * whose `value_type` is itself a model of the concept `SequenceContainer` * whose `value_type` is an unsigned integer type convertible to `std::size_t` @@ -490,7 +490,7 @@ bool write_VTP(std::ostream& os, * * \brief writes the content of `points` and `polygons` in a file named `fname`, using the \ref IOStreamVTK. * - * \tparam PointRange a model of the concept `RandomAccessContainer` whose value type is the point type + * \tparam PointRange a model of the concept `RandomAccessContainer` whose `valuetype` is the point type * \tparam PolygonRange a model of the concept `SequenceContainer` * whose `value_type` is itself a model of the concept `SequenceContainer` * whose `value_type` is an unsigned integer type convertible to `std::size_t` From 21fddd1c13fc1bf57d701246891e5df894fa6e94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 30 Oct 2023 23:40:12 +0100 Subject: [PATCH 168/329] Fix default values' bbox not being computed for point set items --- .../Alpha_wrap_3/Alpha_wrap_3_plugin.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp index f9eba756bf83..86a879835623 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp @@ -547,8 +547,6 @@ public Q_SLOTS: triangles.emplace_back(get(vpm, target(h, *pMesh)), get(vpm, target(next(h, *pMesh), *pMesh)), get(vpm, source(h, *pMesh))); - - m_wrap_bbox += triangles.back().bbox(); } continue; @@ -571,8 +569,6 @@ public Q_SLOTS: triangles.emplace_back(soup_item->points()[p[0]], soup_item->points()[p[1]], soup_item->points()[p[2]]); - - m_wrap_bbox += triangles.back().bbox(); } continue; @@ -599,8 +595,6 @@ public Q_SLOTS: triangles.emplace_back(get(vpm, target(h, *pMesh)), get(vpm, target(next(h, *pMesh), *pMesh)), get(vpm, source(h, *pMesh))); - - m_wrap_bbox += triangles.back().bbox(); } segments.reserve(segments.size() + selection_item->selected_edges.size()); @@ -608,16 +602,12 @@ public Q_SLOTS: { segments.emplace_back(get(vpm, target(halfedge(e, *pMesh), *pMesh)), get(vpm, target(opposite(halfedge(e, *pMesh), *pMesh), *pMesh))); - - m_wrap_bbox += segments.back().bbox(); } points.reserve(points.size() + selection_item->selected_vertices.size()); for(const auto& v : selection_item->selected_vertices) { points.push_back(get(vpm, v)); - - m_wrap_bbox += points.back().bbox(); } continue; @@ -656,6 +646,15 @@ public Q_SLOTS: std::cout << segments.size() << " edges" << std::endl; std::cout << points.size() << " points" << std::endl; + for(const Kernel::Triangle_3& tr : triangles) + m_wrap_bbox += tr.bbox(); + for(const Kernel::Segment_3& sg : segments) + m_wrap_bbox += sg.bbox(); + for(const Kernel::Point_3& pt : points) + m_wrap_bbox += pt.bbox(); + + std::cout << "Bbox:\n" << m_wrap_bbox << std::endl; + // The relative value uses the bbox of the full scene and not that of selected items to wrap // This is intentional, both because it's tedious to make it otherwise, and because it seems // to be simpler to compare between "all wrapped" / "some wrapped" From fb682fe9eb7a24339a6e4004da6a07bffbdfe639 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 30 Oct 2023 23:43:54 +0100 Subject: [PATCH 169/329] Fix memory issues in PS/SS oracles after no longer taking oracles by const& --- .../Alpha_wrap_3/internal/Point_set_oracle.h | 27 +++++++++++-------- .../internal/Segment_soup_oracle.h | 27 +++++++++++-------- 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Point_set_oracle.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Point_set_oracle.h index 8ccbf049a33e..37ff14955604 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Point_set_oracle.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Point_set_oracle.h @@ -28,6 +28,7 @@ #include #include #include +#include #include namespace CGAL { @@ -41,6 +42,7 @@ struct PS_oracle_traits using Geom_traits = Alpha_wrap_AABB_geom_traits; // Wrap the kernel to add Ball_3 + custom Do_intersect_3 using Points = std::vector; + using Points_ptr = std::shared_ptr; using PR_iterator = typename Points::const_iterator; using Primitive = AABB_primitive; private: - Points m_points; + Points_ptr m_points_ptr; public: // Constructors - Point_set_oracle() - : Oracle_base(BaseOracle(), Base_GT()) - { } - Point_set_oracle(const BaseOracle& base_oracle, const Base_GT& gt = Base_GT()) : Oracle_base(base_oracle, gt) - { } + { + m_points_ptr = std::make_shared(); + } Point_set_oracle(const Base_GT& gt, const BaseOracle& base_oracle = BaseOracle()) - : Oracle_base(base_oracle, gt) + : Point_set_oracle(gt, base_oracle) + { } + + Point_set_oracle() + : Point_set_oracle(BaseOracle(), Base_GT()) { } public: @@ -106,14 +111,14 @@ class Point_set_oracle return; } - const std::size_t old_size = m_points.size(); - m_points.insert(std::cend(m_points), std::cbegin(points), std::cend(points)); + const std::size_t old_size = m_points_ptr->size(); + m_points_ptr->insert(std::cend(*m_points_ptr), std::cbegin(points), std::cend(points)); #ifdef CGAL_AW3_DEBUG std::cout << "Insert into AABB tree (points)..." << std::endl; #endif - this->tree().insert(std::next(std::cbegin(m_points), old_size), std::cend(m_points)); + this->tree().insert(std::next(std::cbegin(*m_points_ptr), old_size), std::cend(*m_points_ptr)); // Manually constructing it here purely for profiling reasons: if we keep the lazy approach, // it will be done at the first treatment of a facet that needs a Steiner point. @@ -121,7 +126,7 @@ class Point_set_oracle // to accelerate the tree. this->tree().accelerate_distance_queries(); - CGAL_postcondition(this->tree().size() == m_points.size()); + CGAL_postcondition(this->tree().size() == m_points_ptr->size()); } }; diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Segment_soup_oracle.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Segment_soup_oracle.h index 63f3532cf67e..f4d1c338b62f 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Segment_soup_oracle.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Segment_soup_oracle.h @@ -28,6 +28,7 @@ #include #include #include +#include #include namespace CGAL { @@ -42,6 +43,7 @@ struct SS_oracle_traits using Segment = typename GT_::Segment_3; using Segments = std::vector; + using Segments_ptr = std::shared_ptr; using SR_iterator = typename Segments::const_iterator; using Primitive = AABB_primitive; private: - Segments m_segments; + Segments_ptr m_segments_ptr; public: // Constructors - Segment_soup_oracle() - : Oracle_base(BaseOracle(), Base_GT()) - { } - Segment_soup_oracle(const BaseOracle& base_oracle, const Base_GT& gt = Base_GT()) : Oracle_base(base_oracle, gt) - { } + { + m_segments_ptr = std::make_shared(); + } Segment_soup_oracle(const Base_GT& gt, const BaseOracle& base_oracle = BaseOracle()) - : Oracle_base(base_oracle, gt) + : Segment_soup_oracle(base_oracle, gt) + { } + + Segment_soup_oracle() + : Segment_soup_oracle(BaseOracle(), Base_GT()) { } public: @@ -109,7 +114,7 @@ class Segment_soup_oracle typename Geom_traits::Is_degenerate_3 is_degenerate = this->geom_traits().is_degenerate_3_object(); - const std::size_t old_size = m_segments.size(); + const std::size_t old_size = m_segments_ptr->size(); for(const Segment& s : segments) { @@ -121,13 +126,13 @@ class Segment_soup_oracle continue; } - m_segments.push_back(s); + m_segments_ptr->push_back(s); } #ifdef CGAL_AW3_DEBUG std::cout << "Insert into AABB tree (segments)..." << std::endl; #endif - this->tree().insert(std::next(std::cbegin(m_segments), old_size), std::cend(m_segments)); + this->tree().insert(std::next(std::cbegin(*m_segments_ptr), old_size), std::cend(*m_segments_ptr)); // Manually constructing it here purely for profiling reasons: if we keep the lazy approach, // it will be done at the first treatment of a facet that needs a Steiner point. @@ -135,7 +140,7 @@ class Segment_soup_oracle // to accelerate the tree. this->tree().accelerate_distance_queries(); - CGAL_postcondition(this->tree().size() == m_segments.size()); + CGAL_postcondition(this->tree().size() == m_segments_ptr->size()); } }; From 3879b13c0ed8b4f4677065b8b7ae6e5d0d4e93a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 30 Oct 2023 23:46:46 +0100 Subject: [PATCH 170/329] Misc minor improvements --- .../CGAL/Alpha_wrap_3/internal/Oracle_base.h | 1 - .../Alpha_wrap_3/internal/Point_set_oracle.h | 2 +- .../Alpha_wrap_3/internal/Segment_soup_oracle.h | 2 +- .../Alpha_wrap_3/internal/Triangle_mesh_oracle.h | 2 +- .../Alpha_wrap_3/internal/Triangle_soup_oracle.h | 16 +++++++++++++++- .../Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp | 4 ++-- 6 files changed, 20 insertions(+), 7 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Oracle_base.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Oracle_base.h index 85bd11c00b6c..7f3534a484cf 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Oracle_base.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Oracle_base.h @@ -321,7 +321,6 @@ class AABB_tree_oracle typename AABB_tree::Bounding_box bbox() const { CGAL_precondition(!empty()); - return tree().bbox(); } diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Point_set_oracle.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Point_set_oracle.h index 37ff14955604..ad04a43f720e 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Point_set_oracle.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Point_set_oracle.h @@ -106,7 +106,7 @@ class Point_set_oracle if(points.empty()) { #ifdef CGAL_AW3_DEBUG - std::cout << "Warning: Input is empty " << std::endl; + std::cout << "Warning: Input is empty (PS)" << std::endl; #endif return; } diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Segment_soup_oracle.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Segment_soup_oracle.h index f4d1c338b62f..349cd012ef7a 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Segment_soup_oracle.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Segment_soup_oracle.h @@ -107,7 +107,7 @@ class Segment_soup_oracle if(segments.empty()) { #ifdef CGAL_AW3_DEBUG - std::cout << "Warning: Input is empty " << std::endl; + std::cout << "Warning: Input is empty (SS)" << std::endl; #endif return; } diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_mesh_oracle.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_mesh_oracle.h index ffd8326a44f6..d7f325e1428f 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_mesh_oracle.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_mesh_oracle.h @@ -135,7 +135,7 @@ class Triangle_mesh_oracle if(is_empty(tmesh)) { #ifdef CGAL_AW3_DEBUG - std::cout << "Warning: Input is empty " << std::endl; + std::cout << "Warning: Input is empty (TM)" << std::endl; #endif return; } diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_soup_oracle.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_soup_oracle.h index 27322a554e36..dadfb5d8be10 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_soup_oracle.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Triangle_soup_oracle.h @@ -133,7 +133,7 @@ class Triangle_soup_oracle if(points.empty() || faces.empty()) { #ifdef CGAL_AW3_DEBUG - std::cout << "Warning: Input is empty " << std::endl; + std::cout << "Warning: Input is empty (TS)" << std::endl; #endif return; } @@ -190,8 +190,22 @@ class Triangle_soup_oracle void add_triangle_soup(const TriangleRange& triangles, const CGAL_NP_CLASS& /*np*/ = CGAL::parameters::default_values()) { + if(triangles.empty()) + { +#ifdef CGAL_AW3_DEBUG + std::cout << "Warning: Input is empty (TS)" << std::endl; +#endif + return; + } + +#ifdef CGAL_AW3_DEBUG + std::cout << "Insert into AABB Tree (triangles)..." << std::endl; +#endif + typename Geom_traits::Is_degenerate_3 is_degenerate = this->geom_traits().is_degenerate_3_object(); + Splitter_base::reserve(triangles.size()); + for(const Triangle_3& tr : triangles) { if(is_degenerate(tr)) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp index 86a879835623..383d1103778f 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp @@ -687,8 +687,8 @@ public Q_SLOTS: const bool use_message_box = ui.enableMessageBox->isChecked(); - std::cout << "Wrapping edges? " << std::boolalpha << wrap_segments << std::endl; std::cout << "Wrapping faces? " << std::boolalpha << wrap_triangles << std::endl; + std::cout << "Wrapping edges? " << std::boolalpha << wrap_segments << std::endl; if(!wrap_triangles) { @@ -740,7 +740,7 @@ public Q_SLOTS: if(alpha <= 0. || offset <= 0.) { - print_message("Warning: alpha/offset must be strictly positive - nothing to wrap"); + print_message("Warning: alpha/offset must be strictly positive"); QApplication::restoreOverrideCursor(); return; } From 4444fdf2d43f55eee71e16c111502ac742772904 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 31 Oct 2023 10:59:05 +0100 Subject: [PATCH 171/329] Fix compilation --- .../include/CGAL/Alpha_wrap_3/internal/Point_set_oracle.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Point_set_oracle.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Point_set_oracle.h index ad04a43f720e..33f8a52b178b 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Point_set_oracle.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Point_set_oracle.h @@ -89,7 +89,7 @@ class Point_set_oracle Point_set_oracle(const Base_GT& gt, const BaseOracle& base_oracle = BaseOracle()) - : Point_set_oracle(gt, base_oracle) + : Point_set_oracle(base_oracle, gt) { } Point_set_oracle() From 361c5c50094a36bda8d09ba8a2aedd7d2cf4c42d Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 2 Nov 2023 14:13:07 +0100 Subject: [PATCH 172/329] remove all the _sizing_field parameters that have never been used they were removed from the documentation before being merged in the master branch see SVN commit https://github.com/CGAL/cgal-attic/commit/1614a89e32693a9f33394083d75ed11f06209947 --- Mesh_3/include/CGAL/Mesh_criteria_3.h | 12 +++--------- .../STL_Extension/internal/parameters_interface.h | 4 ---- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/Mesh_3/include/CGAL/Mesh_criteria_3.h b/Mesh_3/include/CGAL/Mesh_criteria_3.h index 96511da5520c..d950cfb6d828 100644 --- a/Mesh_3/include/CGAL/Mesh_criteria_3.h +++ b/Mesh_3/include/CGAL/Mesh_criteria_3.h @@ -70,22 +70,16 @@ class Mesh_criteria_3_impl // is not a problem template Mesh_criteria_3_impl(const CGAL_NP_CLASS& np) - :edge_criteria_(parameters::choose_parameter(parameters::get_parameter(np, internal_np::edge_size_param), - parameters::choose_parameter(parameters::get_parameter_reference(np, internal_np::edge_sizing_field_param), - parameters::choose_parameter(parameters::get_parameter(np, internal_np::sizing_field_param), FT(DBL_MAX)))), + :edge_criteria_(parameters::choose_parameter(parameters::get_parameter(np, internal_np::edge_size_param), FT(DBL_MAX)), parameters::choose_parameter(parameters::get_parameter(np, internal_np::edge_min_size_param), FT(0))), facet_criteria_(parameters::choose_parameter(parameters::get_parameter(np, internal_np::facet_angle_param), FT(0)), - parameters::choose_parameter(parameters::get_parameter(np, internal_np::facet_size_param), - parameters::choose_parameter(parameters::get_parameter_reference(np, internal_np::facet_sizing_field_param), - parameters::choose_parameter(parameters::get_parameter(np, internal_np::sizing_field_param), FT(0)))), + parameters::choose_parameter(parameters::get_parameter(np, internal_np::facet_size_param), FT(0)), parameters::choose_parameter(parameters::get_parameter_reference(np, internal_np::facet_distance_param), FT(0)), parameters::choose_parameter(parameters::get_parameter(np, internal_np::facet_topology_param), CGAL::FACET_VERTICES_ON_SURFACE), parameters::choose_parameter(parameters::get_parameter(np, internal_np::facet_min_size_param), FT(0))), cell_criteria_(parameters::choose_parameter(parameters::get_parameter(np, internal_np::cell_radius_edge_ratio_param), parameters::choose_parameter(parameters::get_parameter(np, internal_np::cell_radius_edge_param), FT(0))), - parameters::choose_parameter(parameters::get_parameter(np, internal_np::cell_size_param), - parameters::choose_parameter(parameters::get_parameter_reference(np, internal_np::cell_sizing_field_param), - parameters::choose_parameter(parameters::get_parameter_reference(np, internal_np::sizing_field_param), FT(0)))), + parameters::choose_parameter(parameters::get_parameter(np, internal_np::cell_size_param), FT(0)), parameters::choose_parameter(parameters::get_parameter(np, internal_np::cell_min_size_param), FT(0))) { } diff --git a/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h b/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h index 7792ad5cdb60..621e551c40f4 100644 --- a/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h +++ b/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h @@ -337,19 +337,15 @@ CGAL_add_named_parameter_with_compatibility(features_detector_param_t, features_ CGAL_add_named_parameter_with_compatibility(input_features_param_t, input_features_param, input_features) CGAL_add_named_parameter_with_compatibility(edge_size_param_t, edge_size_param, edge_size) -CGAL_add_named_parameter_with_compatibility_cref_only(edge_sizing_field_param_t, edge_sizing_field_param, edge_sizing_field) CGAL_add_named_parameter_with_compatibility(edge_min_size_param_t, edge_min_size_param, edge_min_size) CGAL_add_named_parameter_with_compatibility(facet_angle_param_t, facet_angle_param, facet_angle) CGAL_add_named_parameter_with_compatibility(facet_size_param_t, facet_size_param, facet_size) -CGAL_add_named_parameter_with_compatibility_cref_only(facet_sizing_field_param_t, facet_sizing_field_param, facet_sizing_field) CGAL_add_named_parameter_with_compatibility_cref_only(facet_distance_param_t, facet_distance_param, facet_distance) CGAL_add_named_parameter_with_compatibility(facet_min_size_param_t, facet_min_size_param, facet_min_size) CGAL_add_named_parameter_with_compatibility(facet_topology_param_t, facet_topology_param, facet_topology) CGAL_add_named_parameter_with_compatibility(cell_radius_edge_param_t, cell_radius_edge_param, cell_radius_edge) CGAL_add_named_parameter_with_compatibility(cell_radius_edge_ratio_param_t, cell_radius_edge_ratio_param, cell_radius_edge_ratio) CGAL_add_named_parameter_with_compatibility(cell_size_param_t, cell_size_param, cell_size) -CGAL_add_named_parameter_with_compatibility_cref_only(cell_sizing_field_param_t, cell_sizing_field_param, cell_sizing_field) -CGAL_add_named_parameter_with_compatibility_cref_only(sizing_field_param_t, sizing_field_param, sizing_field) CGAL_add_named_parameter_with_compatibility(cell_min_size_param_t, cell_min_size_param, cell_min_size) CGAL_add_named_parameter_with_compatibility(function_param_t, function_param, function) From 093660ce4343e3a3b8ca65fe8e2a860907e7d69f Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 2 Nov 2023 14:27:31 +0100 Subject: [PATCH 173/329] remove unused and undocumented criterion cell_radius_edge --- Mesh_3/include/CGAL/Mesh_criteria_3.h | 3 +-- .../include/CGAL/STL_Extension/internal/parameters_interface.h | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/Mesh_3/include/CGAL/Mesh_criteria_3.h b/Mesh_3/include/CGAL/Mesh_criteria_3.h index d950cfb6d828..12e0e4222075 100644 --- a/Mesh_3/include/CGAL/Mesh_criteria_3.h +++ b/Mesh_3/include/CGAL/Mesh_criteria_3.h @@ -77,8 +77,7 @@ class Mesh_criteria_3_impl parameters::choose_parameter(parameters::get_parameter_reference(np, internal_np::facet_distance_param), FT(0)), parameters::choose_parameter(parameters::get_parameter(np, internal_np::facet_topology_param), CGAL::FACET_VERTICES_ON_SURFACE), parameters::choose_parameter(parameters::get_parameter(np, internal_np::facet_min_size_param), FT(0))), - cell_criteria_(parameters::choose_parameter(parameters::get_parameter(np, internal_np::cell_radius_edge_ratio_param), - parameters::choose_parameter(parameters::get_parameter(np, internal_np::cell_radius_edge_param), FT(0))), + cell_criteria_(parameters::choose_parameter(parameters::get_parameter(np, internal_np::cell_radius_edge_ratio_param), FT(0)), parameters::choose_parameter(parameters::get_parameter(np, internal_np::cell_size_param), FT(0)), parameters::choose_parameter(parameters::get_parameter(np, internal_np::cell_min_size_param), FT(0))) { } diff --git a/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h b/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h index 621e551c40f4..d656b63a0069 100644 --- a/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h +++ b/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h @@ -343,7 +343,6 @@ CGAL_add_named_parameter_with_compatibility(facet_size_param_t, facet_size_param CGAL_add_named_parameter_with_compatibility_cref_only(facet_distance_param_t, facet_distance_param, facet_distance) CGAL_add_named_parameter_with_compatibility(facet_min_size_param_t, facet_min_size_param, facet_min_size) CGAL_add_named_parameter_with_compatibility(facet_topology_param_t, facet_topology_param, facet_topology) -CGAL_add_named_parameter_with_compatibility(cell_radius_edge_param_t, cell_radius_edge_param, cell_radius_edge) CGAL_add_named_parameter_with_compatibility(cell_radius_edge_ratio_param_t, cell_radius_edge_ratio_param, cell_radius_edge_ratio) CGAL_add_named_parameter_with_compatibility(cell_size_param_t, cell_size_param, cell_size) CGAL_add_named_parameter_with_compatibility(cell_min_size_param_t, cell_min_size_param, cell_min_size) From 5b6bf127457be9335b79ef73d0443fa6c9612e4c Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 2 Nov 2023 14:39:34 +0100 Subject: [PATCH 174/329] use get_parameter_reference for all the possibly-field parameters --- Mesh_3/include/CGAL/Mesh_criteria_3.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Mesh_3/include/CGAL/Mesh_criteria_3.h b/Mesh_3/include/CGAL/Mesh_criteria_3.h index 12e0e4222075..c2d5d3d9b139 100644 --- a/Mesh_3/include/CGAL/Mesh_criteria_3.h +++ b/Mesh_3/include/CGAL/Mesh_criteria_3.h @@ -70,15 +70,15 @@ class Mesh_criteria_3_impl // is not a problem template Mesh_criteria_3_impl(const CGAL_NP_CLASS& np) - :edge_criteria_(parameters::choose_parameter(parameters::get_parameter(np, internal_np::edge_size_param), FT(DBL_MAX)), + :edge_criteria_(parameters::choose_parameter(parameters::get_parameter_reference(np, internal_np::edge_size_param), FT(DBL_MAX)), parameters::choose_parameter(parameters::get_parameter(np, internal_np::edge_min_size_param), FT(0))), facet_criteria_(parameters::choose_parameter(parameters::get_parameter(np, internal_np::facet_angle_param), FT(0)), - parameters::choose_parameter(parameters::get_parameter(np, internal_np::facet_size_param), FT(0)), + parameters::choose_parameter(parameters::get_parameter_reference(np, internal_np::facet_size_param), FT(0)), parameters::choose_parameter(parameters::get_parameter_reference(np, internal_np::facet_distance_param), FT(0)), parameters::choose_parameter(parameters::get_parameter(np, internal_np::facet_topology_param), CGAL::FACET_VERTICES_ON_SURFACE), parameters::choose_parameter(parameters::get_parameter(np, internal_np::facet_min_size_param), FT(0))), cell_criteria_(parameters::choose_parameter(parameters::get_parameter(np, internal_np::cell_radius_edge_ratio_param), FT(0)), - parameters::choose_parameter(parameters::get_parameter(np, internal_np::cell_size_param), FT(0)), + parameters::choose_parameter(parameters::get_parameter_reference(np, internal_np::cell_size_param), FT(0)), parameters::choose_parameter(parameters::get_parameter(np, internal_np::cell_min_size_param), FT(0))) { } From 08b25d8778a06ffc5c82118a3dd4c1a41bf8da6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 2 Nov 2023 16:08:37 +0100 Subject: [PATCH 175/329] prevent a warning with older versions of TBB --- .../CGAL/Polygon_mesh_processing/autorefinement.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 5b9cad98277d..d25ea95fe905 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -46,6 +46,10 @@ #ifdef CGAL_LINKED_WITH_TBB #include +#if TBB_INTERFACE_VERSION < 12010 && !defined(TBB_PREVIEW_CONCURRENT_ORDERED_CONTAINERS) +#define CGAL_HAS_DEFINED_TBB_PREVIEW_CONCURRENT_ORDERED_CONTAINERS +#define TBB_PREVIEW_CONCURRENT_ORDERED_CONTAINERS +#endif #include #include #ifdef SET_POINT_IDS_USING_MUTEX @@ -1770,4 +1774,10 @@ autorefine( TriangleMesh& tm, } } // end of CGAL::Polygon_mesh_processing +#ifdef CGAL_LINKED_WITH_TBB +#ifdef CGAL_HAS_DEFINED_TBB_PREVIEW_CONCURRENT_ORDERED_CONTAINERS +#undef TBB_PREVIEW_CONCURRENT_ORDERED_CONTAINERS +#endif +#endif + #endif // CGAL_POLYGON_MESH_PROCESSING_AUTOREFINEMENT_H From 3176178224785f0dd241ce9d4f78d06449d58cb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Sun, 5 Nov 2023 22:52:44 -0800 Subject: [PATCH 176/329] fix compilation issues --- .../include/CGAL/Arr_tags.h | 44 ++++++++++--------- .../Arr_traits_adaptor_2_dispatching.h | 7 +-- .../Arrangement_on_surface_2_global.h | 12 ++--- .../Surface_sweep_2/Arr_overlay_ss_visitor.h | 18 ++++---- .../test/Arrangement_on_surface_2/utils.h | 4 +- .../CGAL/boost/graph/named_params_helper.h | 6 +-- BGL/include/CGAL/boost/graph/properties.h | 2 +- .../Algebraic_structure_traits.h | 2 +- .../CGAL/Concurrent_compact_container.h | 2 +- STL_Extension/include/CGAL/Container_helper.h | 4 +- .../CGAL/Constrained_triangulation_2.h | 7 +-- 11 files changed, 57 insertions(+), 51 deletions(-) diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_tags.h b/Arrangement_on_surface_2/include/CGAL/Arr_tags.h index 1aac06155855..8ba336b1e192 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_tags.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_tags.h @@ -252,7 +252,7 @@ template struct Arr_is_side_oblivious { typedef ArrSideCategory Side_cat; typedef std::is_same Is_same; - typedef std::conditional result; + typedef std::bool_constant result; typedef typename result::type type; }; @@ -260,7 +260,7 @@ template struct Arr_is_side_open { typedef ArrSideCategory Side_cat; typedef std::is_same Is_same; - typedef std::conditional result; + typedef std::bool_constant result; typedef typename result::type type; }; @@ -268,7 +268,7 @@ template struct Arr_is_side_identified { typedef ArrSideCategory Side_cat; typedef std::is_same Is_same; - typedef std::conditional result; + typedef std::bool_constant result; typedef typename result::type type; }; @@ -276,7 +276,7 @@ template struct Arr_is_side_contracted { typedef ArrSideCategory Side_cat; typedef std::is_same Is_same; - typedef std::conditional result; + typedef std::bool_constant result; typedef typename result::type type; }; @@ -284,7 +284,7 @@ template struct Arr_is_side_closed { typedef ArrSideCategory Side_cat; typedef std::is_same Is_same; - typedef std::conditional result; + typedef std::bool_constant result; typedef typename result::type type; }; @@ -423,11 +423,12 @@ struct Arr_sane_identified_tagging { typedef boost::mpl::or_ LR_ok; typedef boost::mpl::or_ BT_ok; - /*! Boolean tag that is bool_ if opposite sides are either + /*! Boolean tag that is bool_constant if opposite sides are either * both identified or both not-identified, - * otherwise bool_ + * otherwise bool_constant */ - typedef boost::mpl::and_ result; + typedef std::bool_constant result; static constexpr bool value = result::value; }; @@ -447,10 +448,10 @@ struct Arr_has_identified_sides { typedef typename Arr_is_side_identified::result Side_one_ide; typedef typename Arr_is_side_identified::result Side_two_ide; - /*! Boolean tag that is bool_ if one side is identified, - * otherwise bool_ + /*! Boolean tag that is bool_constant if one side is identified, + * otherwise bool_constant */ - typedef boost::mpl::or_ result; + typedef std::bool_constant result; }; /*! Checks whether one of two boundary sides are contracted @@ -463,10 +464,11 @@ struct Arr_has_contracted_sides_two { typedef typename Arr_is_side_contracted::result Side_one_con; typedef typename Arr_is_side_contracted::result Side_two_con; - /*!\ Boolean tag that is bool_ if one side is identified, - * otherwise bool_ + /*!\ Boolean tag that is bool_constant if one side is identified, + * otherwise bool_constant */ - typedef boost::mpl::or_ result; + typedef std::bool_constant result; }; /*! Checks whether one of two boundary sides are closed @@ -479,10 +481,11 @@ struct Arr_has_closed_sides_two { typedef typename Arr_is_side_closed::result Side_one_clo; typedef typename Arr_is_side_closed::result Side_two_clo; - /*! Boolean tag that is bool_ if one side is identified, - * otherwise bool_ + /*! Boolean tag that is bool_constant if one side is identified, + * otherwise bool_constant */ - typedef boost::mpl::or_ result; + typedef std::bool_constant result; }; /*! Checks whether one of two boundary sides are open @@ -495,10 +498,11 @@ struct Arr_has_open_sides_two { typedef typename Arr_is_side_open::result Side_one_ope; typedef typename Arr_is_side_open::result Side_two_ope; - /*! Boolean tag that is bool_ if one side is identified, - * otherwise bool_ + /*! Boolean tag that is bool_constant if one side is identified, + * otherwise bool_constant */ - typedef boost::mpl::or_ result; + typedef std::bool_constant result; }; /*! Categorizes two boundary sides: diff --git a/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arr_traits_adaptor_2_dispatching.h b/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arr_traits_adaptor_2_dispatching.h index 283b2dc66b5c..9bcabf985d68 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arr_traits_adaptor_2_dispatching.h +++ b/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arr_traits_adaptor_2_dispatching.h @@ -58,11 +58,11 @@ struct Or_traits { private: - typedef std::conditional< + typedef std::conditional_t< std::is_same_v< Arr_smaller_implementation_tag, Arr_use_traits_tag >, std::true_type, std::false_type > Smaller_traits; - typedef std::conditional_t_< + typedef std::conditional_t< std::is_same_v< Arr_larger_implementation_tag, Arr_use_traits_tag >, std::true_type, std::false_type > Larger_traits; @@ -71,7 +71,8 @@ struct Or_traits { //! the result type (if one side asks for traits, then ask traits! //! Or vice versa: If both ask for dummy, then dummy!) typedef std::conditional_t< - Smaller_traits, Larger_traits >::value || Arr_use_traits_tag::value, + Smaller_traits::value || Larger_traits::value, + Arr_use_traits_tag, Arr_use_dummy_tag > type; }; diff --git a/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arrangement_on_surface_2_global.h b/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arrangement_on_surface_2_global.h index ee072c95778c..5bc8054c5254 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arrangement_on_surface_2_global.h +++ b/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arrangement_on_surface_2_global.h @@ -64,7 +64,7 @@ namespace Ss2 = Surface_sweep_2; // // error: no matching function for call to `do_intersect(Arrangement_2<>&, // const Arr_segment_2&, const Arr_walk_along_line_point_location<>&, -// mpl_::bool_< true>)' +// std::bool_constant< true>)' // template @@ -135,7 +135,7 @@ void insert(Arrangement_on_surface_2& arr, // // error: no matching function for call to `do_intersect(Arrangement_2<>&, // const Arr_segment_2&, const Arr_walk_along_line_point_location<>&, -// mpl_::bool_< true>)' +// std::bool_constant< true>)' // // template &, // const Arr_segment_2&, const Arr_walk_along_line_point_location<>&, -// mpl_::bool_< true>)' +// std::bool_constant< true>)' // template @@ -463,7 +463,7 @@ void insert(Arrangement_on_surface_2& arr, // // error: no matching function for call to `do_intersect(Arrangement_2<>&, // const Arr_segment_2&, const Arr_walk_along_line_point_location<>&, -// mpl_::bool_< true>)' +// std::bool_constant< true>)' // template @@ -1524,7 +1524,7 @@ zone(Arrangement_on_surface_2& arr, // workaround since it didn't compile in FC3_g++-3.4.4 with the error of: // // error: no matching function for call to `do_intersect(Arrangement_on_surface_2<>&, -// const Arr_segment_2&, const Arr_walk_along_line_point_location<>&, mpl_::bool_< true>)' +// const Arr_segment_2&, const Arr_walk_along_line_point_location<>&, std::bool_constant< true>)' // template @@ -1562,7 +1562,7 @@ do_intersect(Arrangement_on_surface_2& arr, // // error: no matching function for call to // `do_intersect(Arrangement_on_surface_2<>&, -// const Arr_segment_2&, const Arr_walk_along_line_point_location<>&, mpl_::bool_< true>)' +// const Arr_segment_2&, const Arr_walk_along_line_point_location<>&, std::bool_constant< true>)' // template diff --git a/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_overlay_ss_visitor.h b/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_overlay_ss_visitor.h index 30c8b38b4a0d..06052a8f19d7 100644 --- a/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_overlay_ss_visitor.h +++ b/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_overlay_ss_visitor.h @@ -295,7 +295,7 @@ class Arr_overlay_ss_visitor : * \param tag The tag used for dispatching. */ void _map_boundary_vertices(Event* event, Vertex_handle v, - boost::mpl::bool_ /* tag */); + std::bool_constant /* tag */); /*! * Update the boundary vertices map. @@ -306,7 +306,7 @@ class Arr_overlay_ss_visitor : * \param tag The tag used for dispatching. */ void _map_boundary_vertices(Event* event, Vertex_handle v, - boost::mpl::bool_ /* tag */); + std::bool_constant /* tag */); /*! * Update a newly created vertex using the overlay traits. @@ -319,7 +319,7 @@ class Arr_overlay_ss_visitor : * \param tag The tag used for dispatching. */ void _create_vertex(Event* event, Vertex_handle res_v, Subcurve* sc, - boost::mpl::bool_ /* tag */); + std::bool_constant /* tag */); /*! * Update a newly created vertex using the overlay traits. @@ -331,7 +331,7 @@ class Arr_overlay_ss_visitor : * \param tag The tag used for dispatching. */ void _create_vertex(Event* event, Vertex_handle res_v, Subcurve* sc, - boost::mpl::bool_ /* tag */); + std::bool_constant /* tag */); /*! * Update a newly created edge using the overlay traits. @@ -922,7 +922,7 @@ _map_halfedge_and_twin(Halfedge_handle he, // template void Arr_overlay_ss_visitor:: -_map_boundary_vertices(Event* event, Vertex_handle v, boost::mpl::bool_) +_map_boundary_vertices(Event* event, Vertex_handle v, std::bool_constant) { // Update the red and blue object if the last event on sc is on the boundary. if ((event->parameter_space_in_x() != ARR_INTERIOR) || @@ -960,7 +960,7 @@ _map_boundary_vertices(Event* event, Vertex_handle v, boost::mpl::bool_) template void Arr_overlay_ss_visitor:: _map_boundary_vertices(Event* /* event */, Vertex_handle /* v */, - boost::mpl::bool_) + std::bool_constant) {} /* Notify the overlay traits about a newly created vertex. @@ -974,7 +974,7 @@ void Arr_overlay_ss_visitor:: _create_vertex(Event* event, Vertex_handle new_v, Subcurve* sc, - boost::mpl::bool_) + std::bool_constant) { const Point_2& pt = event->point(); const Cell_handle_red* red_handle = pt.red_cell_handle(); @@ -1011,7 +1011,7 @@ _create_vertex(Event* event, return; } - _create_vertex(event, new_v, sc, boost::mpl::bool_()); + _create_vertex(event, new_v, sc, std::bool_constant()); } /* Notify the overlay traits about a newly created vertex. */ @@ -1020,7 +1020,7 @@ void Arr_overlay_ss_visitor:: _create_vertex(Event* event, Vertex_handle new_v, Subcurve* sc, - boost::mpl::bool_) + std::bool_constant) { const Point_2& pt = event->point(); const Cell_handle_red* red_handle = pt.red_cell_handle(); diff --git a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/utils.h b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/utils.h index f49b92f4c01c..f4975fb14283 100644 --- a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/utils.h +++ b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/utils.h @@ -55,13 +55,13 @@ class Point_compare { // This function is invoked for traits classes where at least one // boundary is not oblivious and all boundaries are not identified. bool operator()(const Point_2& p1, const Point_2& p2, - boost::mpl::bool_) const + std::bool_constant) const { return (m_traits.compare_xy_2_object()(p1, p2) == CGAL::SMALLER); } // This function should be invoked for traits classes where at least one // boundary is identified. bool operator()(const Point_2& p1, const Point_2& p2, - boost::mpl::bool_) const + std::bool_constant) const { // Compare in y boundaries: CGAL::Arr_parameter_space ps_y1 = diff --git a/BGL/include/CGAL/boost/graph/named_params_helper.h b/BGL/include/CGAL/boost/graph/named_params_helper.h index 4dce0049b1ab..7dd7edd08875 100644 --- a/BGL/include/CGAL/boost/graph/named_params_helper.h +++ b/BGL/include/CGAL/boost/graph/named_params_helper.h @@ -46,9 +46,9 @@ class property_map_selector typename boost::property_map::type, typename boost::cgal_no_property::type> type; typedef std::conditional_t::const_type, - typename boost::cgal_no_property::const_type - >::type const_type; + typename boost::property_map::const_type, + typename boost::cgal_no_property::const_type + > const_type; type get_pmap(const PropertyTag& p, PolygonMesh& pmesh) { diff --git a/BGL/include/CGAL/boost/graph/properties.h b/BGL/include/CGAL/boost/graph/properties.h index 1fd71599ad10..e8ab8b8bc432 100644 --- a/BGL/include/CGAL/boost/graph/properties.h +++ b/BGL/include/CGAL/boost/graph/properties.h @@ -140,7 +140,7 @@ struct Point_accessor typedef ValueType value_type; typedef Handle key_type; - typedef std::conditional_t< std::is_reference, + typedef std::conditional_t< std::is_reference_v, ValueType&, ValueType > Reference; diff --git a/Number_types/include/CGAL/Sqrt_extension/Algebraic_structure_traits.h b/Number_types/include/CGAL/Sqrt_extension/Algebraic_structure_traits.h index b1500148b598..c2175bc9439e 100644 --- a/Number_types/include/CGAL/Sqrt_extension/Algebraic_structure_traits.h +++ b/Number_types/include/CGAL/Sqrt_extension/Algebraic_structure_traits.h @@ -206,7 +206,7 @@ class Algebraic_structure_traits< Sqrt_extension< COEFF_, ROOT_, ACDE_TAG,FP_TAG // Tag_true if COEFF and ROOT are exact typedef std::conditional_t< std::is_same_v::Is_exact,::CGAL::Tag_true> && - std::is_same::Is_exact,::CGAL::Tag_true> + std::is_same_v::Is_exact,::CGAL::Tag_true> ,::CGAL::Tag_true,::CGAL::Tag_false> Is_exact; typedef typename Algebraic_structure_traits::Is_numerical_sensitive diff --git a/STL_Extension/include/CGAL/Concurrent_compact_container.h b/STL_Extension/include/CGAL/Concurrent_compact_container.h index e6a2a5dbecf1..7f5533f92b72 100644 --- a/STL_Extension/include/CGAL/Concurrent_compact_container.h +++ b/STL_Extension/include/CGAL/Concurrent_compact_container.h @@ -1,4 +1,4 @@ -3// Copyright (c) 2012 INRIA Sophia-Antipolis (France). +// Copyright (c) 2012 INRIA Sophia-Antipolis (France). // All rights reserved. // // This file is part of CGAL (www.cgal.org) diff --git a/STL_Extension/include/CGAL/Container_helper.h b/STL_Extension/include/CGAL/Container_helper.h index aeb66ea052ba..9f5ac5a84cb2 100644 --- a/STL_Extension/include/CGAL/Container_helper.h +++ b/STL_Extension/include/CGAL/Container_helper.h @@ -50,8 +50,8 @@ void resize(Container& CGAL_assertion_code(array), std::size_t CGAL_assertion_co template void resize(Container&, std::size_t, std::enable_if_t< - !boost::mpl::or_, - has_size >::value >* = nullptr) + !(has_resize::value || + has_size::value)>* = nullptr) { } diff --git a/Triangulation_2/include/CGAL/Constrained_triangulation_2.h b/Triangulation_2/include/CGAL/Constrained_triangulation_2.h index 02b050f790ad..3cc571689711 100644 --- a/Triangulation_2/include/CGAL/Constrained_triangulation_2.h +++ b/Triangulation_2/include/CGAL/Constrained_triangulation_2.h @@ -95,9 +95,10 @@ namespace internal { template struct Itag { - typedef std::conditional_t<(typename Algebraic_structure_traits::Is_exact)::value, - Exact_intersections_tag, - Exact_predicates_tag> type; + using Is_exact = typename Algebraic_structure_traits::Is_exact; + typedef std::conditional_t type; }; } // namespace internal From 25233e8f67f84d4d21df2ba7ce4e85612b14b611 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 7 Nov 2023 09:15:18 +0100 Subject: [PATCH 177/329] undo bad change --- Periodic_3_mesh_3/include/CGAL/Periodic_3_function_wrapper.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Periodic_3_mesh_3/include/CGAL/Periodic_3_function_wrapper.h b/Periodic_3_mesh_3/include/CGAL/Periodic_3_function_wrapper.h index b1ee5e650654..bfb4b4e87166 100644 --- a/Periodic_3_mesh_3/include/CGAL/Periodic_3_function_wrapper.h +++ b/Periodic_3_mesh_3/include/CGAL/Periodic_3_function_wrapper.h @@ -47,7 +47,7 @@ class Periodic_3_function_wrapper private: typedef std::conditional_t, Function_*, - Function_>: Stored_function; + Function_> Stored_function; /// Function to wrap Stored_function f_; From 2277013d8479336f114a3d5fdc859d427d6e4324 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 10 Nov 2023 16:06:03 +0100 Subject: [PATCH 178/329] replace boost::mpl::and_ --- .../internal/Is_ray_intersection_geomtraits.h | 10 +++--- .../include/CGAL/Arr_tags.h | 34 +++++++++---------- .../include/CGAL/Homogeneous/PointH2.h | 4 +-- .../include/CGAL/Homogeneous/PointH3.h | 6 ++-- .../include/CGAL/Homogeneous/VectorH2.h | 4 +-- .../include/CGAL/Homogeneous/VectorH3.h | 6 ++-- .../CGAL/NewKernel_d/Cartesian_filter_K.h | 8 ++--- .../include/CGAL/NewKernel_d/Lazy_cartesian.h | 6 ++-- .../include/CGAL/NewKernel_d/functor_tags.h | 12 +++---- Number_types/include/CGAL/Lazy_exact_nt.h | 6 ++-- .../CGAL/Sqrt_extension/Sqrt_extension_type.h | 8 ++--- .../Periodic_2_Delaunay_triangulation_2.h | 7 ++-- STL_Extension/include/CGAL/Container_helper.h | 6 ++-- .../include/CGAL/type_traits/is_iterator.h | 15 ++++---- Stream_support/include/CGAL/IO/helpers.h | 10 +++--- .../Constrained_Delaunay_triangulation_2.h | 6 ++-- .../include/CGAL/Delaunay_triangulation_2.h | 6 ++-- .../include/CGAL/Regular_triangulation_2.h | 6 ++-- .../include/CGAL/Triangulation_2.h | 6 ++-- .../include/CGAL/Delaunay_triangulation_3.h | 6 ++-- .../include/CGAL/Regular_triangulation_3.h | 7 ++-- .../include/CGAL/Triangulation_3.h | 6 ++-- .../include/CGAL/Triangulation_hierarchy_3.h | 6 ++-- 23 files changed, 85 insertions(+), 106 deletions(-) diff --git a/AABB_tree/include/CGAL/AABB_tree/internal/Is_ray_intersection_geomtraits.h b/AABB_tree/include/CGAL/AABB_tree/internal/Is_ray_intersection_geomtraits.h index e662b13be90c..3d02204b9d03 100644 --- a/AABB_tree/include/CGAL/AABB_tree/internal/Is_ray_intersection_geomtraits.h +++ b/AABB_tree/include/CGAL/AABB_tree/internal/Is_ray_intersection_geomtraits.h @@ -32,11 +32,11 @@ BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_cartesian_const_iterator_3,Cartesian_const template struct Is_ray_intersection_geomtraits -: boost::mpl::and_< Has_ray_3, - Has_construct_source_3, - Has_vector_3, - Has_construct_cartesian_const_iterator_3, - Has_cartesian_const_iterator_3 >::type +: std::bool_constant< Has_ray_3::value && + Has_construct_source_3::value && + Has_vector_3::value && + Has_construct_cartesian_const_iterator_3::value && + Has_cartesian_const_iterator_3::value > {}; diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_tags.h b/Arrangement_on_surface_2/include/CGAL/Arr_tags.h index 8ba336b1e192..94ea503e244b 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_tags.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_tags.h @@ -272,6 +272,10 @@ struct Arr_is_side_identified { typedef typename result::type type; }; +template +inline constexpr bool Arr_is_side_identified_v = + Arr_is_side_identified::type::value; + template struct Arr_is_side_contracted { typedef ArrSideCategory Side_cat; @@ -403,33 +407,27 @@ struct Arr_sane_identified_tagging { typedef ArrBottomSideCategory Bot_side_cat; typedef ArrTopSideCategory Top_side_cat; - typedef typename Arr_is_side_identified::result Lef_ide; - typedef typename Arr_is_side_identified::result Rig_ide; - typedef typename Arr_is_side_identified::result Bot_ide; - typedef typename Arr_is_side_identified::result Top_ide; - - typedef boost::mpl::and_ LR_ide; - typedef boost::mpl::and_ BT_ide; + static inline constexpr bool lef_ide = Arr_is_side_identified_v; + static inline constexpr bool rig_ide = Arr_is_side_identified_v; + static inline constexpr bool bot_ide = Arr_is_side_identified_v; + static inline constexpr bool top_ide = Arr_is_side_identified_v; - typedef boost::mpl::not_ Lef_not_ide; - typedef boost::mpl::not_ Rig_not_ide; - typedef boost::mpl::not_ Bot_not_ide; - typedef boost::mpl::not_ Top_not_ide; + static inline constexpr bool lr_ide = lef_ide && rig_ide; + static inline constexpr bool bt_ide = bot_ide && top_ide; - typedef boost::mpl::and_ LR_not_ide; + static inline constexpr bool lr_not_ide = !lef_ide && !rig_ide; - typedef boost::mpl::and_ BT_not_ide; + static inline constexpr bool bt_not_ide = !bot_ide && !top_ide; - typedef boost::mpl::or_ LR_ok; - typedef boost::mpl::or_ BT_ok; + static inline constexpr bool lr_ok = lr_ide || lr_not_ide; + static inline constexpr bool bt_ok = bt_ide || bt_not_ide; /*! Boolean tag that is bool_constant if opposite sides are either * both identified or both not-identified, * otherwise bool_constant */ - typedef std::bool_constant result; - static constexpr bool value = result::value; + typedef std::bool_constant result; + static inline constexpr bool value = result::value; }; /*! Checks whether one of two boundary sides are identified diff --git a/Homogeneous_kernel/include/CGAL/Homogeneous/PointH2.h b/Homogeneous_kernel/include/CGAL/Homogeneous/PointH2.h index afb6bff830e9..06ff55945fe6 100644 --- a/Homogeneous_kernel/include/CGAL/Homogeneous/PointH2.h +++ b/Homogeneous_kernel/include/CGAL/Homogeneous/PointH2.h @@ -53,8 +53,8 @@ class PointH2 template < typename Tx, typename Ty > PointH2(const Tx & x, const Ty & y, - std::enable_if_t< boost::mpl::and_, - std::is_convertible >::value >* = 0) + std::enable_if_t< std::is_convertible_v && + std::is_convertible_v >* = 0) : base(x, y) {} PointH2(const FT& x, const FT& y) diff --git a/Homogeneous_kernel/include/CGAL/Homogeneous/PointH3.h b/Homogeneous_kernel/include/CGAL/Homogeneous/PointH3.h index 87da02cabff1..f64d5b64c9a2 100644 --- a/Homogeneous_kernel/include/CGAL/Homogeneous/PointH3.h +++ b/Homogeneous_kernel/include/CGAL/Homogeneous/PointH3.h @@ -52,9 +52,9 @@ class PointH3 template < typename Tx, typename Ty, typename Tz > PointH3(const Tx & x, const Ty & y, const Tz & z, - std::enable_if_t< boost::mpl::and_< boost::mpl::and_< std::is_convertible, - std::is_convertible >, - std::is_convertible >::value >* = 0) + std::enable_if_t && + std::is_convertible_v && + std::is_convertible_v>* = 0) : base(x, y, z) {} PointH3(const FT& x, const FT& y, const FT& z) diff --git a/Homogeneous_kernel/include/CGAL/Homogeneous/VectorH2.h b/Homogeneous_kernel/include/CGAL/Homogeneous/VectorH2.h index 81cd31075952..92afeec79414 100644 --- a/Homogeneous_kernel/include/CGAL/Homogeneous/VectorH2.h +++ b/Homogeneous_kernel/include/CGAL/Homogeneous/VectorH2.h @@ -57,8 +57,8 @@ class VectorH2 template < typename Tx, typename Ty > VectorH2(const Tx & x, const Ty & y, - std::enable_if_t< boost::mpl::and_, - std::is_convertible >::value >* = 0) + std::enable_if_t && + std::is_convertible_v>* = 0) : base(CGAL::make_array(x, y, RT(1))) {} VectorH2(const FT& x, const FT& y) diff --git a/Homogeneous_kernel/include/CGAL/Homogeneous/VectorH3.h b/Homogeneous_kernel/include/CGAL/Homogeneous/VectorH3.h index 5228d5251ade..aecd718d41aa 100644 --- a/Homogeneous_kernel/include/CGAL/Homogeneous/VectorH3.h +++ b/Homogeneous_kernel/include/CGAL/Homogeneous/VectorH3.h @@ -67,9 +67,9 @@ class VectorH3 template < typename Tx, typename Ty, typename Tz > VectorH3(const Tx & x, const Ty & y, const Tz & z, - std::enable_if_t< boost::mpl::and_< boost::mpl::and_< std::is_convertible, - std::is_convertible >, - std::is_convertible >::value >* = 0) + std::enable_if_t< std::is_convertible_v && + std::is_convertible_v && + std::is_convertible_v>* = 0) : base(CGAL::make_array(x, y, z, RT(1))) {} VectorH3(const FT& x, const FT& y, const FT& z) diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_filter_K.h b/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_filter_K.h index 25ec0c4f25c4..ef44403f9f51 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_filter_K.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_filter_K.h @@ -64,10 +64,10 @@ struct Cartesian_filter_K : public Base_ EK_rt exact_kernel()const{return sek.kernel();} // MSVC is too dumb to perform the empty base optimization. - typedef boost::mpl::and_< - internal::Do_not_store_kernel, - internal::Do_not_store_kernel, - internal::Do_not_store_kernel > Do_not_store_kernel; + typedef std::bool_constant< + internal::Do_not_store_kernel::value && + internal::Do_not_store_kernel::value && + internal::Do_not_store_kernel::value > Do_not_store_kernel; //TODO: C2A/C2E could be able to convert *this into this->kernel() or this->kernel2(). typedef KernelD_converter C2A; diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Lazy_cartesian.h b/NewKernel_d/include/CGAL/NewKernel_d/Lazy_cartesian.h index 6e6b496840e1..67ea76e11fb5 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Lazy_cartesian.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Lazy_cartesian.h @@ -260,9 +260,9 @@ struct Lazy_cartesian : void set_dimension(int dim){ak.set_dimension(dim);ek.set_dimension(dim);} // For compilers that do not handle [[no_unique_address]] - typedef boost::mpl::and_< - internal::Do_not_store_kernel, - internal::Do_not_store_kernel > Do_not_store_kernel; + typedef std::bool_constant< + internal::Do_not_store_kernel::value && + internal::Do_not_store_kernel::value > Do_not_store_kernel; typedef typename EK_::Dimension Dimension; // ? typedef Lazy_cartesian Self; diff --git a/NewKernel_d/include/CGAL/NewKernel_d/functor_tags.h b/NewKernel_d/include/CGAL/NewKernel_d/functor_tags.h index 4eb0e8900631..b32308585738 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/functor_tags.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/functor_tags.h @@ -64,16 +64,16 @@ namespace CGAL { : Has_type_different_from, Null_functor> {}; template::type::value> - struct Provides_functors : boost::mpl::and_ < - Provides_functor::type>, - Provides_functors::type> > {}; + struct Provides_functors : std::bool_constant< + Provides_functor::type>::value && + Provides_functors::type>::value > {}; template struct Provides_functors : std::true_type {}; template::type::value> - struct Provides_types : boost::mpl::and_ < - Provides_type::type>, - Provides_types::type> > {}; + struct Provides_types : std::bool_constant< + Provides_type::type>::value && + Provides_types::type>::value > {}; template struct Provides_types : std::true_type {}; diff --git a/Number_types/include/CGAL/Lazy_exact_nt.h b/Number_types/include/CGAL/Lazy_exact_nt.h index 3f8a2812968a..d15c11a73bd7 100644 --- a/Number_types/include/CGAL/Lazy_exact_nt.h +++ b/Number_types/include/CGAL/Lazy_exact_nt.h @@ -382,9 +382,9 @@ public : // Also check that ET and AT are constructible from T? template - Lazy_exact_nt (T i, std::enable_if_t, std::is_enum >, - boost::mpl::not_ > >::value,void*> = 0) + Lazy_exact_nt (T i, std::enable_if_t< + (std::is_arithmetic_v || std::is_enum_v) && + !std::is_same_v,void*> = 0) : Base(new Lazy_exact_Cst(i)) {} Lazy_exact_nt (const ET & e) diff --git a/Number_types/include/CGAL/Sqrt_extension/Sqrt_extension_type.h b/Number_types/include/CGAL/Sqrt_extension/Sqrt_extension_type.h index 4a562530c75a..6b87205b5018 100644 --- a/Number_types/include/CGAL/Sqrt_extension/Sqrt_extension_type.h +++ b/Number_types/include/CGAL/Sqrt_extension/Sqrt_extension_type.h @@ -178,10 +178,10 @@ class Sqrt_extension : public internal::Interval_optional_caching, */ template explicit Sqrt_extension(const NTX& a, const NTX& b, const NTX& c, const bool is_smaller, - std::enable_if_t< boost::mpl::and_< - std::is_same< typename Fraction_traits::Numerator_type,NTX >, - std::is_same< typename Fraction_traits::Numerator_type,NTX > - >::value >* = 0 ) + std::enable_if_t< + std::is_same_v< typename Fraction_traits::Numerator_type,NTX > && + std::is_same_v< typename Fraction_traits::Numerator_type,NTX > + >* = 0 ) { typename Fraction_traits::Compose compose_nt; typename Fraction_traits::Compose compose_root; diff --git a/Periodic_2_triangulation_2/include/CGAL/Periodic_2_Delaunay_triangulation_2.h b/Periodic_2_triangulation_2/include/CGAL/Periodic_2_Delaunay_triangulation_2.h index 1232e426aed9..c83be87df905 100644 --- a/Periodic_2_triangulation_2/include/CGAL/Periodic_2_Delaunay_triangulation_2.h +++ b/Periodic_2_triangulation_2/include/CGAL/Periodic_2_Delaunay_triangulation_2.h @@ -435,10 +435,9 @@ class Periodic_2_Delaunay_triangulation_2 boost::zip_iterator< boost::tuple > last, bool is_large_point_set = true, std::enable_if_t < - boost::mpl::and_ < - std::is_convertible< typename std::iterator_traits::value_type, Point >, - std::is_convertible< typename std::iterator_traits::value_type, typename internal::Info_check::type > - >::value >* = nullptr) + std::is_convertible_v< typename std::iterator_traits::value_type, Point > && + std::is_convertible_v< typename std::iterator_traits::value_type, typename internal::Info_check::type > + >* = nullptr) { return insert_with_info< boost::tuple::type> >(first, last, is_large_point_set); } diff --git a/STL_Extension/include/CGAL/Container_helper.h b/STL_Extension/include/CGAL/Container_helper.h index 9f5ac5a84cb2..18a98dfa456b 100644 --- a/STL_Extension/include/CGAL/Container_helper.h +++ b/STL_Extension/include/CGAL/Container_helper.h @@ -38,10 +38,8 @@ void resize(Container& c, std::size_t size, // Container without a resize() function, but with a size() function (e.g. an array) template void resize(Container& CGAL_assertion_code(array), std::size_t CGAL_assertion_code(size), - std::enable_if_t< - boost::mpl::and_< - boost::mpl::not_ >, - has_size >::value >* = nullptr) + std::enable_if_t::value && + has_size::value >* = nullptr) { CGAL_assertion(array.size() == size); } diff --git a/STL_Extension/include/CGAL/type_traits/is_iterator.h b/STL_Extension/include/CGAL/type_traits/is_iterator.h index 6630dd8ceb1e..8d476da20363 100644 --- a/STL_Extension/include/CGAL/type_traits/is_iterator.h +++ b/STL_Extension/include/CGAL/type_traits/is_iterator.h @@ -35,14 +35,13 @@ BOOST_MPL_HAS_XXX_TRAIT_DEF(reference) //provide all 5 nested types provided by iterator_traits template struct is_iterator_ - : public boost::mpl::or_< - boost::mpl::and_< - has_iterator_category, - has_value_type, - has_difference_type, - has_pointer, - has_reference >, - std::is_pointer > + : public std::bool_constant< + ( has_iterator_category::value && + has_value_type::value && + has_difference_type::value && + has_pointer::value && + has_reference::value) || + std::is_pointer_v > { }; template ::value> diff --git a/Stream_support/include/CGAL/IO/helpers.h b/Stream_support/include/CGAL/IO/helpers.h index bba12aa85a74..015c5f047c72 100644 --- a/Stream_support/include/CGAL/IO/helpers.h +++ b/Stream_support/include/CGAL/IO/helpers.h @@ -77,10 +77,10 @@ struct is_Point_set_3 : has_Point_set { }; // Point_set_3 and strings also functions as ranges, but we want to match polygon soups here template struct is_Range - : public boost::mpl::and_< - boost::has_range_const_iterator, // should be a range - boost::mpl::not_ >, // but not a Point_set_3 - boost::mpl::not_ > > // or a std::string / char [x] + : public std::bool_constant< + boost::has_range_const_iterator::value && // should be a range + !is_Point_set_3::value && // but not a Point_set_3 + !std::is_convertible_v > // or a std::string / char [x] { }; template @@ -89,7 +89,7 @@ inline constexpr bool is_Range_v = is_Range::value; // For polygon meshes template struct is_Point_set_or_Range_or_Iterator - : public boost::mpl::or_, is_Range, is_iterator > + : public bool_constant::value || is_Range::value || is_iterator::value > { }; template diff --git a/Triangulation_2/include/CGAL/Constrained_Delaunay_triangulation_2.h b/Triangulation_2/include/CGAL/Constrained_Delaunay_triangulation_2.h index a96be0e6d76d..52c14ea54b78 100644 --- a/Triangulation_2/include/CGAL/Constrained_Delaunay_triangulation_2.h +++ b/Triangulation_2/include/CGAL/Constrained_Delaunay_triangulation_2.h @@ -413,10 +413,8 @@ class Constrained_Delaunay_triangulation_2 insert( boost::zip_iterator< boost::tuple > first, boost::zip_iterator< boost::tuple > last, std::enable_if_t< - boost::mpl::and_< - std::is_convertible< typename std::iterator_traits::value_type, Point >, - std::is_convertible< typename std::iterator_traits::value_type, typename internal::Info_check::type > - >::value + std::is_convertible_v< typename std::iterator_traits::value_type, Point > && + std::is_convertible_v< typename std::iterator_traits::value_type, typename internal::Info_check::type > >* =nullptr ) { diff --git a/Triangulation_2/include/CGAL/Delaunay_triangulation_2.h b/Triangulation_2/include/CGAL/Delaunay_triangulation_2.h index 34a282b91626..617e8c23a8a4 100644 --- a/Triangulation_2/include/CGAL/Delaunay_triangulation_2.h +++ b/Triangulation_2/include/CGAL/Delaunay_triangulation_2.h @@ -385,10 +385,8 @@ class Delaunay_triangulation_2 insert(boost::zip_iterator< boost::tuple > first, boost::zip_iterator< boost::tuple > last, std::enable_if_t< - boost::mpl::and_< - std::is_convertible< typename std::iterator_traits::value_type, Point >, - std::is_convertible< typename std::iterator_traits::value_type, typename internal::Info_check::type > - >::value + std::is_convertible_v< typename std::iterator_traits::value_type, Point > && + std::is_convertible_v< typename std::iterator_traits::value_type, typename internal::Info_check::type > >* = nullptr) { return insert_with_info< boost::tuple::type> >(first,last); diff --git a/Triangulation_2/include/CGAL/Regular_triangulation_2.h b/Triangulation_2/include/CGAL/Regular_triangulation_2.h index c3ab2223a0ad..d5d1a6c5917a 100644 --- a/Triangulation_2/include/CGAL/Regular_triangulation_2.h +++ b/Triangulation_2/include/CGAL/Regular_triangulation_2.h @@ -528,10 +528,8 @@ class Regular_triangulation_2 insert(boost::zip_iterator< boost::tuple > first, boost::zip_iterator< boost::tuple > last, std::enable_if_t< - boost::mpl::and_< - typename std::is_convertible< typename std::iterator_traits::value_type, Weighted_point >, - typename std::is_convertible< typename std::iterator_traits::value_type, typename internal::Info_check::type > - >::value + typename std::is_convertible_v< typename std::iterator_traits::value_type, Weighted_point > && + typename std::is_convertible_v< typename std::iterator_traits::value_type, typename internal::Info_check::type > >* =nullptr ) {return insert_with_info< boost::tuple::type> >(first,last);} diff --git a/Triangulation_2/include/CGAL/Triangulation_2.h b/Triangulation_2/include/CGAL/Triangulation_2.h index c79aa0128d2b..14e8604640f1 100644 --- a/Triangulation_2/include/CGAL/Triangulation_2.h +++ b/Triangulation_2/include/CGAL/Triangulation_2.h @@ -710,10 +710,8 @@ std::ptrdiff_t insert(InputIterator first, InputIterator last, insert(boost::zip_iterator< boost::tuple > first, boost::zip_iterator< boost::tuple > last, std::enable_if_t< - boost::mpl::and_< - std::is_convertible< typename std::iterator_traits::value_type, Point >, - std::is_convertible< typename std::iterator_traits::value_type, typename internal::Info_check::type > - >::value + std::is_convertible_v< typename std::iterator_traits::value_type, Point > && + std::is_convertible_v< typename std::iterator_traits::value_type, typename internal::Info_check::type > >* = NULL) { return insert_with_info< boost::tuple::type> >(first,last); diff --git a/Triangulation_3/include/CGAL/Delaunay_triangulation_3.h b/Triangulation_3/include/CGAL/Delaunay_triangulation_3.h index 8b22fddd3493..63ade11b5e8a 100644 --- a/Triangulation_3/include/CGAL/Delaunay_triangulation_3.h +++ b/Triangulation_3/include/CGAL/Delaunay_triangulation_3.h @@ -494,10 +494,8 @@ class Delaunay_triangulation_3 insert(boost::zip_iterator< boost::tuple > first, boost::zip_iterator< boost::tuple > last, std::enable_if_t< - boost::mpl::and_< - std::is_convertible< typename std::iterator_traits::value_type, Point >, - std::is_convertible< typename std::iterator_traits::value_type, typename internal::Info_check::type > - >::value + std::is_convertible_v< typename std::iterator_traits::value_type, Point > && + std::is_convertible_v< typename std::iterator_traits::value_type, typename internal::Info_check::type > >* =nullptr) { return insert_with_info< boost::tuple > first, boost::zip_iterator< boost::tuple > last, std::enable_if_t< - boost::mpl::and_< - typename std::is_convertible< typename std::iterator_traits::value_type, Weighted_point >, - typename std::is_convertible< typename std::iterator_traits::value_type, typename internal::Info_check::type > - >::value >* =nullptr) + typename std::is_convertible_v< typename std::iterator_traits::value_type, Weighted_point > && + typename std::is_convertible_v< typename std::iterator_traits::value_type, typename internal::Info_check::type > + >* =nullptr) { return insert_with_info< boost::tuple > first, boost::zip_iterator< boost::tuple > last, std::enable_if_t< - boost::mpl::and_< - std::is_convertible< typename std::iterator_traits::value_type, Point >, - std::is_convertible< typename std::iterator_traits::value_type, typename internal::Info_check::type > - >::value + std::is_convertible_v< typename std::iterator_traits::value_type, Point > && + std::is_convertible_v< typename std::iterator_traits::value_type, typename internal::Info_check::type > >* =NULL) { return insert_with_info< boost::tuple > first, boost::zip_iterator< boost::tuple > last, std::enable_if_t< - boost::mpl::and_< - std::is_convertible< typename std::iterator_traits::value_type, Point >, - std::is_convertible< typename std::iterator_traits::value_type, typename internal::Info_check::type > - >::value + std::is_convertible_v< typename std::iterator_traits::value_type, Point > && + std::is_convertible_v< typename std::iterator_traits::value_type, typename internal::Info_check::type > >* =nullptr ) { From 4344c3cc27a869018c400adc149cd36539f19a8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 10 Nov 2023 16:34:19 +0100 Subject: [PATCH 179/329] replace boost::mpl::or_ --- .../include/CGAL/Arr_tags.h | 18 +++++++++--------- .../include/CGAL/CGAL_Ipelet_base_v6.h | 11 +++++------ .../include/CGAL/CGAL_Ipelet_base_v7.h | 11 +++++------ Filtered_kernel/include/CGAL/Lazy_kernel.h | 6 +++--- .../CGAL/NewKernel_d/Wrapper/Cartesian_wrap.h | 4 ++-- .../Polygon_mesh_processing/intersection.h | 14 ++++++-------- STL_Extension/include/CGAL/type_traits.h | 8 ++++---- Stream_support/include/CGAL/IO/helpers.h | 2 +- 8 files changed, 35 insertions(+), 39 deletions(-) diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_tags.h b/Arrangement_on_surface_2/include/CGAL/Arr_tags.h index 94ea503e244b..384666f80fa1 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_tags.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_tags.h @@ -377,15 +377,15 @@ struct Arr_sides_category { typedef typename Arr_is_side_open::result Bot_ope; typedef typename Arr_is_side_open::result Top_ope; - typedef boost::mpl::or_ Lef_obl_or_ope; - typedef boost::mpl::or_ Rig_obl_or_ope; - typedef boost::mpl::or_ Bot_obl_or_ope; - typedef boost::mpl::or_ Top_obl_or_ope; - - typedef std::conditional_t tmp; diff --git a/CGAL_ipelets/include/CGAL/CGAL_Ipelet_base_v6.h b/CGAL_ipelets/include/CGAL/CGAL_Ipelet_base_v6.h index 48572f24118b..9876131f47b0 100644 --- a/CGAL_ipelets/include/CGAL/CGAL_Ipelet_base_v6.h +++ b/CGAL_ipelets/include/CGAL/CGAL_Ipelet_base_v6.h @@ -636,12 +636,11 @@ namespace CGAL{ template void draw_in_ipe(const iterator begin,const iterator end,const Iso_rectangle_2& bbox,bool make_grp=true,bool deselect_all=false, - std::enable_if_t< boost::mpl::or_< std::is_same::value_type,Point_2> , - boost::mpl::or_< std::is_same::value_type,Segment_2> , - boost::mpl::or_< std::is_same::value_type,Circle_2> , - boost::mpl::or_< std::is_same::value_type,Circular_arc_2> , - std::is_same::value_type,Polygon_2> - > > > >::value + std::enable_if_t< std::is_same_v::value_type,Point_2> || + std::is_same_v::value_type,Segment_2> || + std::is_same_v::value_type,Circle_2> || + std::is_same_v::value_type,Circular_arc_2> || + std::is_same_v::value_type,Polygon_2> >* = nullptr) const { for (iterator it=begin;it!=end;++it) diff --git a/CGAL_ipelets/include/CGAL/CGAL_Ipelet_base_v7.h b/CGAL_ipelets/include/CGAL/CGAL_Ipelet_base_v7.h index 5373b0a3445f..3dc51367d33e 100644 --- a/CGAL_ipelets/include/CGAL/CGAL_Ipelet_base_v7.h +++ b/CGAL_ipelets/include/CGAL/CGAL_Ipelet_base_v7.h @@ -645,12 +645,11 @@ namespace CGAL{ template void draw_in_ipe(const iterator begin,const iterator end,const Iso_rectangle_2& bbox,bool make_grp=true,bool deselect_all=false, - std::enable_if_t< boost::mpl::or_< std::is_same::value_type,Point_2> , - boost::mpl::or_< std::is_same::value_type,Segment_2> , - boost::mpl::or_< std::is_same::value_type,Circle_2> , - boost::mpl::or_< std::is_same::value_type,Circular_arc_2> , - std::is_same::value_type,Polygon_2> - > > > >::value + std::enable_if_t< std::is_same_v::value_type,Point_2> || + std::is_same_v::value_type,Segment_2> || + std::is_same_v::value_type,Circle_2> || + std::is_same_v::value_type,Circular_arc_2> || + std::is_same_v::value_type,Polygon_2> >* = nullptr) const { for (iterator it=begin;it!=end;++it) diff --git a/Filtered_kernel/include/CGAL/Lazy_kernel.h b/Filtered_kernel/include/CGAL/Lazy_kernel.h index c6b6cb2444ab..8f43a8a1af13 100644 --- a/Filtered_kernel/include/CGAL/Lazy_kernel.h +++ b/Filtered_kernel/include/CGAL/Lazy_kernel.h @@ -198,9 +198,9 @@ class Lazy_kernel_generic_base : protected internal::Enum_holder boost::mpl::eval_if< std::is_same< typename internal::Lazy_result_type::type, CGAL::Object >, boost::mpl::int_, - boost::mpl::eval_if< boost::mpl::or_< - std::is_same< typename internal::Lazy_result_type::type, CGAL::Bbox_2 >, - std::is_same< typename internal::Lazy_result_type::type, CGAL::Bbox_3 > >, + boost::mpl::eval_if< std::bool_constant< + std::is_same_v< typename internal::Lazy_result_type::type, CGAL::Bbox_2 > || + std::is_same_v< typename internal::Lazy_result_type::type, CGAL::Bbox_3 > >, boost::mpl::int_, boost::mpl::int_ > > >, boost::mpl::int_ >::type {}; diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Wrapper/Cartesian_wrap.h b/NewKernel_d/include/CGAL/NewKernel_d/Wrapper/Cartesian_wrap.h index 9ddd7953e24b..50d9a8c8b00c 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Wrapper/Cartesian_wrap.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Wrapper/Cartesian_wrap.h @@ -83,8 +83,8 @@ template struct result_{typedef transforming_iterator struct result; template struct result : result_ {}; -template std::enable_if_t,Is_wrapper_iterator >::value,T> const& operator()(T const& t) const {return t;} -template std::enable_if_t,Is_wrapper_iterator >::value,T>& operator()(T& t) const {return t;} +template std::enable_if_t::value || Is_wrapper_iterator::value,T> const& operator()(T const& t) const {return t;} +template std::enable_if_t::value || Is_wrapper_iterator::value,T>& operator()(T& t) const {return t;} template typename T::Rep const& operator()(T const& t, std::enable_if_t::value >* = 0) const {return t.rep();} diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/intersection.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/intersection.h index f32f9d907a98..a72d9ffaafc9 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/intersection.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/intersection.h @@ -1426,18 +1426,16 @@ bool do_intersect(const TriangleMesh& tm, const Polyline& polyline, const CGAL_NP_CLASS& np = parameters::default_values() #ifndef DOXYGEN_RUNNING - , const std::enable_if_t< - ! boost::mpl::or_< - typename std::is_same::type, // Added to please MSVC 2015 - typename boost::mpl::not_::type>::type, // not a range - typename boost::has_range_iterator< + , const std::enable_if_t || // Added to please MSVC 2015 + !boost::has_range_iterator::type>::value || // not a range + boost::has_range_iterator< typename boost::mpl::eval_if< boost::has_range_iterator, boost::range_value, std::false_type - >::type - >::type // not a range of a range - >::value + >::value + ) >* = 0 #endif ) diff --git a/STL_Extension/include/CGAL/type_traits.h b/STL_Extension/include/CGAL/type_traits.h index 59aae8a03079..c68386c7f76c 100644 --- a/STL_Extension/include/CGAL/type_traits.h +++ b/STL_Extension/include/CGAL/type_traits.h @@ -21,10 +21,10 @@ namespace CGAL { template< class Base, class Derived > struct is_same_or_derived : - public ::boost::mpl::or_< - ::std::is_same< Base, Derived >, - ::boost::is_base_and_derived< Base, Derived > - >::type + public std::bool_constant< + ::std::is_same_v< Base, Derived > || + ::boost::is_base_and_derived< Base, Derived >::value + > {}; namespace cpp20 { diff --git a/Stream_support/include/CGAL/IO/helpers.h b/Stream_support/include/CGAL/IO/helpers.h index 015c5f047c72..7382ebabd667 100644 --- a/Stream_support/include/CGAL/IO/helpers.h +++ b/Stream_support/include/CGAL/IO/helpers.h @@ -89,7 +89,7 @@ inline constexpr bool is_Range_v = is_Range::value; // For polygon meshes template struct is_Point_set_or_Range_or_Iterator - : public bool_constant::value || is_Range::value || is_iterator::value > + : public std::bool_constant::value || is_Range::value || is_iterator::value > { }; template From 2f104a6f76ac233f58fb23b885747385cf3d1eab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 10 Nov 2023 16:38:24 +0100 Subject: [PATCH 180/329] replace boost::mpl::not_ --- Arrangement_on_surface_2/include/CGAL/Arr_tags.h | 12 ++++++------ NewKernel_d/include/CGAL/NewKernel_d/utils.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_tags.h b/Arrangement_on_surface_2/include/CGAL/Arr_tags.h index 384666f80fa1..8f3c78095f4d 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_tags.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_tags.h @@ -334,17 +334,17 @@ struct Arr_all_sides_not_open_category { typedef typename Arr_is_side_open::result Bot_ope; typedef typename Arr_is_side_open::result Top_ope; - typedef boost::mpl::not_ Lef_not_ope; - typedef boost::mpl::not_ Rig_not_ope; - typedef boost::mpl::not_ Bot_not_ope; - typedef boost::mpl::not_ Top_not_ope; + static inline constexpr bool lef_not_ope = !Lef_ope::value; + static inline constexpr bool rig_not_ope = !Rig_ope::value; + static inline constexpr bool bot_not_ope = !Bot_ope::value; + static inline constexpr bool top_not_ope = !Top_ope::value; public: /*! Boolean tag that is Arr_all_sides_not_open_tag if all sides are not-open, * otherwise Arr_not_all_sides_not_open_tag */ - typedef std::conditional_t result; diff --git a/NewKernel_d/include/CGAL/NewKernel_d/utils.h b/NewKernel_d/include/CGAL/NewKernel_d/utils.h index f2e6a2f3ada5..4296f179462d 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/utils.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/utils.h @@ -38,7 +38,7 @@ template ::value /*false*/> struct Has_type_different_from : std::false_type {}; template struct Has_type_different_from -: boost::mpl::not_ > {}; +: std::bool_constant> {}; template struct Wrap_type { typedef T type; }; From e4e13e2f571adf44fe2107d064ed801b18067ba5 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Tue, 14 Nov 2023 12:28:18 +0100 Subject: [PATCH 181/329] do not check the graph of features after protection when minimal_size is set when minimal_size is set, the graph of features is likely to be invalid or at least inconsistent with the input graph so checking its topology does not make any sense and could lead to - assertions failing in debug mode, - hanging in release mode --- Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 721984601811..4cd4d1c3af41 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 @@ -1456,7 +1456,7 @@ refine_balls() dump_c3t3_edges(c3t3_, "dump-before-check_and_repopulate_edges"); #endif // Check edges - if(!forced_stop()) { + if(!forced_stop() && minimal_size_ == FT()) { check_and_repopulate_edges(); } } From 710ef72e27fe0b4315f9301d1d64e3885e767e05 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 14 Nov 2023 13:26:08 +0000 Subject: [PATCH 182/329] Move code to initializer list --- Nef_S2/include/CGAL/Nef_S2/Sphere_segment.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Nef_S2/include/CGAL/Nef_S2/Sphere_segment.h b/Nef_S2/include/CGAL/Nef_S2/Sphere_segment.h index e6ff36dd0ce7..a526ec5085d5 100644 --- a/Nef_S2/include/CGAL/Nef_S2/Sphere_segment.h +++ b/Nef_S2/include/CGAL/Nef_S2/Sphere_segment.h @@ -33,7 +33,10 @@ template class Sphere_segment_rep typedef Sphere_segment_rep Rep; friend class Sphere_segment; public: -Sphere_segment_rep() { ps_ = pt_ = Point(); c_ = Circle(); } + +Sphere_segment_rep() : + ps_(), pt_(), c_() +{} Sphere_segment_rep(const Point& p1, const Point& p2, bool shorter_arc=true) : From 73bd84ddd1ab845643705d63f94e5eac33d162af Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Fri, 17 Nov 2023 11:25:44 +0100 Subject: [PATCH 183/329] Improve add_toc_to_github_wiki_page.py - reformat using `black` - add an option `--max-level` - quote anchors (for accentuated character) - fix linter errors --- .../add_toc_to_github_wiki_page.py | 191 +++++++++--------- 1 file changed, 98 insertions(+), 93 deletions(-) diff --git a/Scripts/developer_scripts/add_toc_to_github_wiki_page.py b/Scripts/developer_scripts/add_toc_to_github_wiki_page.py index ce61f49db7e1..494878cca738 100644 --- a/Scripts/developer_scripts/add_toc_to_github_wiki_page.py +++ b/Scripts/developer_scripts/add_toc_to_github_wiki_page.py @@ -1,125 +1,130 @@ -from sys import argv -from sys import exit import codecs import re import argparse +import sys +from urllib.parse import quote parser = argparse.ArgumentParser() -parser.add_argument("filename", - help="the Mardown file to process") -parser.add_argument("--codebase", - help="for a Markdown file of Codebase instead of Github", - action="store_true") -parser.add_argument("--h1", - help="support level one sections (h1)", - action="store_true") +parser.add_argument("filename", help="the Mardown file to process") +parser.add_argument( + "--codebase", + help="for a Markdown file of Codebase instead of Github", + action="store_true", +) +parser.add_argument("--h1", help="support level one sections (h1)", action="store_true") +parser.add_argument("--max-level", help="maximum level of sections", type=int, default = 5) args = parser.parse_args() + # a probably incomplete version to generate an anchor from a section name def get_anchor(s): - s = s.replace("`","") - s = s.replace("(","") - s = s.replace(")","") - s = s.replace(".","") - s = s.replace("#","") - s = s.replace(":","") - s = s.replace(",","") - s = s.replace(";","") - if args.codebase: - s = s.replace("/","-") - else: - s = s.replace("/","") - s = s.replace("<","") - s = s.replace(">","") - s = s.replace("+","") - s = s.replace("=","") - s = s.replace("?","") - s = s.replace("@","") - s = s.lstrip(" ") - s = s.rstrip("\n") - s = s.rstrip(" ") - s = re.sub(r'\s+','-',s) - if not args.codebase: - s = s.lower() - if args.codebase: - s = s.replace("'","-and-39-") - return "#"+s + s = s.replace("`", "") + s = s.replace("(", "") + s = s.replace(")", "") + s = s.replace(".", "") + s = s.replace("#", "") + s = s.replace(":", "") + s = s.replace(",", "") + s = s.replace(";", "") + if args.codebase: + s = s.replace("/", "-") + else: + s = s.replace("/", "") + s = s.replace("<", "") + s = s.replace(">", "") + s = s.replace("+", "") + s = s.replace("=", "") + s = s.replace("?", "") + s = s.replace("@", "") + s = s.lstrip(" ") + s = s.rstrip("\n") + s = s.rstrip(" ") + s = re.sub(r"\s+", "-", s) + if not args.codebase: + s = s.lower() + if args.codebase: + s = s.replace("'", "-and-39-") + return "#" + quote(s) + # indices the nesting level (first level allowed is ##) def get_level(s): - m = re.search('^(#+)\s', s) - if m: - return len(m.group(1)) - else: - return 0 + m = re.search(r"^(#+)\s", s) + if m: + return len(m.group(1)) + else: + return 0 + def get_name(s): - m = re.search('^#+\s+(.*)\s*$', s) - if m: - return m.group(1) - else: - return "ERROR: Section name extraction" + m = re.search(r"^#+\s+(.*)\s*$", s) + if m: + return m.group(1) + else: + return "ERROR: Section name extraction" + -#generate the entry for one section +# generate the entry for one section def get_toc_entry(s): - name = get_name(s) - if args.h1: - level = get_level(s)-1 - else: - level = get_level(s)-2 - anchor = get_anchor(s) + name = get_name(s) + if args.h1: + level = get_level(s) - 1 + else: + level = get_level(s) - 2 + anchor = get_anchor(s) + + if level < 0: + return "ERROR: h1 sections are not allowed" - if level<0: - return "ERROR: h1 sections are not allowed" + res = "* [" + name + "](" + anchor + ")" + for _ in range(0, level): + res = " " + res + return res - res="* ["+name+"]("+anchor+")" - for i in range(0,level): - res=" "+res - return res -#now the main -input = args.filename +# now the main +filename = args.filename -f = codecs.open(input, 'r', encoding='utf-8') +f = codecs.open(filename, "r", encoding="utf-8") if not f: - print("Cannot open "+input+"\n") - exit() + print("Cannot open " + input + "\n") + sys.exit() -#look for the begin of the file -line=f.readline() -if line.find("")==-1: - exit() +# look for the begin of the file +line = f.readline() +if line.find("") == -1: + sys.exit() -#skip current TOC -line=f.readline() -while line and line.find("")==-1: - line=f.readline() +# skip current TOC +line = f.readline() +while line and line.find("") == -1: + line = f.readline() if not line: - exit() + sys.exit() -buffer="" -TOC="\n\n# Table of Contents\n" +buffer = "" +TOC = "\n\n# Table of Contents\n" -verbatim_mode=False # to ignore verbatim mode while looking for sections -TOC_empty=True +verbatim_mode = False # to ignore verbatim mode while looking for sections +TOC_empty = True for line in f.readlines(): - buffer+=line - if verbatim_mode: - if line[:3]=="```": - verbatim_mode=False - else: - if line[:3]=="```": - verbatim_mode=True + buffer += line + if verbatim_mode: + if line[:3] == "```": + verbatim_mode = False else: - if line[0]=="#": - TOC+=(get_toc_entry(line)+"\n") - TOC_empty=False -TOC+="\n\n" + if line[:3] == "```": + verbatim_mode = True + else: + if line[0] == "#" and get_level(line) <= args.max_level: + TOC += get_toc_entry(line) + "\n" + TOC_empty = False +TOC += "\n\n" if not TOC_empty: - f.close() - f = codecs.open(input, 'w', encoding='utf-8') - f.write(TOC) - f.write(buffer) + f.close() + f = codecs.open(filename, "w", encoding="utf-8") + f.write(TOC) + f.write(buffer) From fa96bf86232add30f1896390a9a82af76180498e Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Fri, 17 Nov 2023 17:11:46 +0100 Subject: [PATCH 184/329] fix other linter warnings --- .../add_toc_to_github_wiki_page.py | 84 ++++++++++--------- 1 file changed, 44 insertions(+), 40 deletions(-) diff --git a/Scripts/developer_scripts/add_toc_to_github_wiki_page.py b/Scripts/developer_scripts/add_toc_to_github_wiki_page.py index 494878cca738..928703c502e8 100644 --- a/Scripts/developer_scripts/add_toc_to_github_wiki_page.py +++ b/Scripts/developer_scripts/add_toc_to_github_wiki_page.py @@ -5,7 +5,7 @@ from urllib.parse import quote parser = argparse.ArgumentParser() -parser.add_argument("filename", help="the Mardown file to process") +parser.add_argument("filename", help="the Markdown file to process") parser.add_argument( "--codebase", help="for a Markdown file of Codebase instead of Github", @@ -83,48 +83,52 @@ def get_toc_entry(s): # now the main -filename = args.filename +def main(): + filename = args.filename -f = codecs.open(filename, "r", encoding="utf-8") + f = codecs.open(filename, "r", encoding="utf-8") -if not f: - print("Cannot open " + input + "\n") - sys.exit() + if not f: + print("Cannot open " + input + "\n") + sys.exit() -# look for the begin of the file -line = f.readline() -if line.find("") == -1: - sys.exit() - -# skip current TOC -line = f.readline() -while line and line.find("") == -1: + # look for the begin of the file line = f.readline() + if line.find("") == -1: + sys.exit() -if not line: - sys.exit() - -buffer = "" -TOC = "\n\n# Table of Contents\n" - -verbatim_mode = False # to ignore verbatim mode while looking for sections -TOC_empty = True -for line in f.readlines(): - buffer += line - if verbatim_mode: - if line[:3] == "```": - verbatim_mode = False - else: - if line[:3] == "```": - verbatim_mode = True + # skip current TOC + line = f.readline() + while line and line.find("") == -1: + line = f.readline() + + if not line: + sys.exit() + + buffer = "" + toc = "\n\n# Table of Contents\n" + + verbatim_mode = False # to ignore verbatim mode while looking for sections + toc_empty = True + for line in f.readlines(): + buffer += line + if verbatim_mode: + if line[:3] == "```": + verbatim_mode = False else: - if line[0] == "#" and get_level(line) <= args.max_level: - TOC += get_toc_entry(line) + "\n" - TOC_empty = False -TOC += "\n\n" - -if not TOC_empty: - f.close() - f = codecs.open(filename, "w", encoding="utf-8") - f.write(TOC) - f.write(buffer) + if line[:3] == "```": + verbatim_mode = True + else: + if line[0] == "#" and get_level(line) <= args.max_level: + toc += get_toc_entry(line) + "\n" + toc_empty = False + toc += "\n\n" + + if not toc_empty: + f.close() + f = codecs.open(filename, "w", encoding="utf-8") + f.write(toc) + f.write(buffer) + +if __name__ == "__main__": + main() From 730bbba98bbce3c9983644e02a66fb45c508cdf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 20 Nov 2023 10:03:16 +0100 Subject: [PATCH 185/329] add an example with a dummy custom sizing field --- .../Polygon_mesh_processing/CMakeLists.txt | 1 + ...c_remeshing_with_custom_sizing_example.cpp | 102 ++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 Polygon_mesh_processing/examples/Polygon_mesh_processing/isotropic_remeshing_with_custom_sizing_example.cpp diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt b/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt index 590305c0c8ad..38d1bce078b0 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt @@ -51,6 +51,7 @@ create_single_source_cgal_program("match_faces.cpp") create_single_source_cgal_program("cc_compatible_orientations.cpp") create_single_source_cgal_program("hausdorff_distance_remeshing_example.cpp") create_single_source_cgal_program("hausdorff_bounded_error_distance_example.cpp") +create_single_source_cgal_program("isotropic_remeshing_with_custom_sizing_example.cpp") find_package(Eigen3 3.2.0 QUIET) #(requires 3.2.0 or greater) include(CGAL_Eigen3_support) diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/isotropic_remeshing_with_custom_sizing_example.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/isotropic_remeshing_with_custom_sizing_example.cpp new file mode 100644 index 000000000000..1fc70906f7d7 --- /dev/null +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/isotropic_remeshing_with_custom_sizing_example.cpp @@ -0,0 +1,102 @@ +#include +#include +#include +#include +#include + +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef CGAL::Surface_mesh Mesh; + +namespace PMP = CGAL::Polygon_mesh_processing; + +// a sizing fied that is increasing the size of edge along the y-axis +// starting at a minimum size at y-max and ending at a maximum size at +// y-min, with a linear interpolation of sizes in between the two extreme +// sizing values +struct My_sizing_field +{ + double min_size, max_size; + double ymin, ymax; + const Mesh& mesh; + + My_sizing_field(double min_size, double max_size, double ymin, double ymax, const Mesh& mesh) + : min_size(min_size) + , max_size(max_size) + , ymin(ymin) + , ymax(ymax) + , mesh(mesh) + {} + + double at(K::Point_3 p) const + { + double y=p.y(); + return CGAL::square( (y-ymin)/(ymax-ymin) * (min_size - max_size) + max_size ); + } + double at(const Mesh::Vertex_index v) const { return at(mesh.point(v)); } + + std::optional is_too_long(const Mesh::Vertex_index va, + const Mesh::Vertex_index vb) const + { + // TODO: no mesh as parameters? + K::Point_3 mp = CGAL::midpoint(mesh.point(va), mesh.point(vb)); + double sql_at = at(mp); + double sql = CGAL::squared_distance(mesh.point(va), mesh.point(vb)); + if (sql > sql_at) + return sql / sql_at; + return std::nullopt; + } + + std::optional is_too_short(const Mesh::Halfedge_index h, + const Mesh&) const + { + K::Point_3 mp = CGAL::midpoint(mesh.point(source(h, mesh)), mesh.point(target(h, mesh))); + double sql_at = at(mp); + double sql = CGAL::squared_distance(mesh.point(source(h, mesh)), mesh.point(target(h, mesh))); + if (sql < sql_at) + return sql / sql_at; + return std::nullopt; + } + + K::Point_3 split_placement(const Mesh::Halfedge_index h, + const Mesh&) const + { + return CGAL::midpoint(mesh.point(source(h, mesh)), mesh.point(target(h, mesh))); + } + + void update(const Mesh::Vertex_index, const Mesh&) {} +}; + + +int main(int argc, char* argv[]) +{ + const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/elk.off"); + + Mesh mesh; + if (!PMP::IO::read_polygon_mesh(filename, mesh) || !CGAL::is_triangle_mesh(mesh)) { + std::cerr << "Not a valid input file." << std::endl; + return 1; + } + + std::cout << "Start remeshing of " << filename + << " (" << num_faces(mesh) << " faces)..." << std::endl; + + CGAL::Bbox_3 bb = PMP::bbox(mesh); + My_sizing_field sizing_field(0.1, 30, bb.ymin(), bb.ymax(), mesh); + unsigned int nb_iter = 5; + + PMP::isotropic_remeshing( + faces(mesh), + sizing_field, + mesh, + CGAL::parameters::number_of_iterations(nb_iter) + .number_of_relaxation_steps(3) + ); + + CGAL::IO::write_polygon_mesh("custom_remesh_out.off", mesh, CGAL::parameters::stream_precision(17)); + + std::cout << "Remeshing done." << std::endl; + + return 0; +} From 37fb95b5cd7619848b829677de5dd64d6f97a6d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 20 Nov 2023 11:28:50 +0100 Subject: [PATCH 186/329] improve concept --- .../Concepts/PMPSizingField.h | 27 ++++++++++--------- ...c_remeshing_with_custom_sizing_example.cpp | 17 ++++++------ .../Adaptive_sizing_field.h | 6 ++--- .../Uniform_sizing_field.h | 6 ++--- .../Isotropic_remeshing/remesh_impl.h | 24 ++++++++--------- .../internal/Sizing_field_base.h | 7 ++--- .../tangential_relaxation.h | 6 ++--- 7 files changed, 48 insertions(+), 45 deletions(-) diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPSizingField.h b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPSizingField.h index 8641c30c6caf..02822cea9e70 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPSizingField.h +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPSizingField.h @@ -16,6 +16,7 @@ class PMPSizingField{ public: /// @name Types +/// These types are used for the documentation of the functions of the concept and not needed implementation wise. /// @{ /// Vertex descriptor type @@ -38,27 +39,29 @@ typedef unspecified_type FT; /// @name Functions /// @{ -/// a function that returns the sizing value at `v`. -FT at(const vertex_descriptor v) const; +/// returns the sizing value at `v` (used during tangential relaxation). +FT at(const vertex_descriptor v, const PolygonMesh& pmesh) const; -/// a function controlling edge split and edge collapse, -/// returning the ratio of the current edge length and the local target edge length between -/// the points of `va` and `vb` in case the current edge is too long, and `std::nullopt` otherwise. +/// returns the ratio of the current edge squared length and the local target edge squared length between +/// the points of `va` and `vb` in case the current edge is too long, and `std::nullopt` otherwise +/// (used for triggering edge splits and preventing some edge collapses). std::optional is_too_long(const vertex_descriptor va, - const vertex_descriptor vb) const; + const vertex_descriptor vb, + const PolygonMesh& pmesh) const; -/// a function controlling edge collapse by returning the ratio of the squared length of `h` and the -/// local target edge length if it is too short, and `std::nullopt` otherwise. +/// returns the ratio of the squared length of `h` and the +/// local target edge squared length if it is too short, and `std::nullopt` otherwise +/// (used for triggering edge collapses). std::optional is_too_short(const halfedge_descriptor h, const PolygonMesh& pmesh) const; -/// a function returning the location of the split point of the edge of `h`. +/// returns the position of the new vertex created when splitting the edge of `h`. Point_3 split_placement(const halfedge_descriptor h, const PolygonMesh& pmesh) const; -/// a function that updates the sizing field value at the vertex `v`. -void update(const vertex_descriptor v, - const PolygonMesh& pmesh); +/// function called after the addition of the split vertex `v` in `pmesh`. +void register_split_vertex(const vertex_descriptor v, + const PolygonMesh& pmesh); /// @} }; diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/isotropic_remeshing_with_custom_sizing_example.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/isotropic_remeshing_with_custom_sizing_example.cpp index 1fc70906f7d7..53d70af603ff 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/isotropic_remeshing_with_custom_sizing_example.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/isotropic_remeshing_with_custom_sizing_example.cpp @@ -19,14 +19,12 @@ struct My_sizing_field { double min_size, max_size; double ymin, ymax; - const Mesh& mesh; - My_sizing_field(double min_size, double max_size, double ymin, double ymax, const Mesh& mesh) + My_sizing_field(double min_size, double max_size, double ymin, double ymax) : min_size(min_size) , max_size(max_size) , ymin(ymin) , ymax(ymax) - , mesh(mesh) {} double at(K::Point_3 p) const @@ -34,10 +32,11 @@ struct My_sizing_field double y=p.y(); return CGAL::square( (y-ymin)/(ymax-ymin) * (min_size - max_size) + max_size ); } - double at(const Mesh::Vertex_index v) const { return at(mesh.point(v)); } + double at(const Mesh::Vertex_index v, const Mesh& mesh) const { return at(mesh.point(v)); } std::optional is_too_long(const Mesh::Vertex_index va, - const Mesh::Vertex_index vb) const + const Mesh::Vertex_index vb, + const Mesh& mesh) const { // TODO: no mesh as parameters? K::Point_3 mp = CGAL::midpoint(mesh.point(va), mesh.point(vb)); @@ -49,7 +48,7 @@ struct My_sizing_field } std::optional is_too_short(const Mesh::Halfedge_index h, - const Mesh&) const + const Mesh& mesh) const { K::Point_3 mp = CGAL::midpoint(mesh.point(source(h, mesh)), mesh.point(target(h, mesh))); double sql_at = at(mp); @@ -60,12 +59,12 @@ struct My_sizing_field } K::Point_3 split_placement(const Mesh::Halfedge_index h, - const Mesh&) const + const Mesh& mesh) const { return CGAL::midpoint(mesh.point(source(h, mesh)), mesh.point(target(h, mesh))); } - void update(const Mesh::Vertex_index, const Mesh&) {} + void register_split_vertex(const Mesh::Vertex_index, const Mesh&) {} }; @@ -83,7 +82,7 @@ int main(int argc, char* argv[]) << " (" << num_faces(mesh) << " faces)..." << std::endl; CGAL::Bbox_3 bb = PMP::bbox(mesh); - My_sizing_field sizing_field(0.1, 30, bb.ymin(), bb.ymax(), mesh); + My_sizing_field sizing_field(0.1, 30, bb.ymin(), bb.ymax()); unsigned int nb_iter = 5; PMP::isotropic_remeshing( diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/Adaptive_sizing_field.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/Adaptive_sizing_field.h index a61edc699d06..d576df0e447b 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/Adaptive_sizing_field.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/Adaptive_sizing_field.h @@ -213,13 +213,13 @@ class Adaptive_sizing_field } public: - FT at(const vertex_descriptor v) const + FT at(const vertex_descriptor v, const PolygonMesh& /* pmesh */) const { CGAL_assertion(get(m_vertex_sizing_map, v)); return get(m_vertex_sizing_map, v); } - std::optional is_too_long(const vertex_descriptor va, const vertex_descriptor vb) const + std::optional is_too_long(const vertex_descriptor va, const vertex_descriptor vb, const PolygonMesh& /* pmesh */) const { const FT sqlen = sqlength(va, vb); FT sqtarg_len = CGAL::square(4./3. * (CGAL::min)(get(m_vertex_sizing_map, va), @@ -251,7 +251,7 @@ class Adaptive_sizing_field get(m_vpmap, source(h, pmesh))); } - void update(const vertex_descriptor v, const PolygonMesh& pmesh) + void register_split_vertex(const vertex_descriptor v, const PolygonMesh& pmesh) { // calculating it as the average of two vertices on other ends // of halfedges as updating is done during an edge split diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/Uniform_sizing_field.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/Uniform_sizing_field.h index a4144ceee650..d14f4be9666d 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/Uniform_sizing_field.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/Uniform_sizing_field.h @@ -102,12 +102,12 @@ class Uniform_sizing_field } public: - FT at(const vertex_descriptor /* v */) const + FT at(const vertex_descriptor /* v */, const PolygonMesh& /* pmesh */) const { return m_size; } - std::optional is_too_long(const vertex_descriptor va, const vertex_descriptor vb) const + std::optional is_too_long(const vertex_descriptor va, const vertex_descriptor vb, const PolygonMesh& /* pmesh */) const { const FT sqlen = sqlength(va, vb); if (sqlen > m_sq_long) @@ -133,7 +133,7 @@ class Uniform_sizing_field get(m_vpmap, source(h, pmesh))); } - void update(const vertex_descriptor /* v */, const PolygonMesh& /* pmesh */) + void register_split_vertex(const vertex_descriptor /* v */, const PolygonMesh& /* pmesh */) {} private: diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/remesh_impl.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/remesh_impl.h index c1696428d756..30d201d1ef51 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/remesh_impl.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/remesh_impl.h @@ -246,7 +246,7 @@ namespace internal { get(ecmap, e) || get(fpm, face(h,pmesh))!=get(fpm, face(opposite(h,pmesh),pmesh)) ) { - if (sizing.is_too_long(source(h, pmesh), target(h, pmesh))) + if (sizing.is_too_long(source(h, pmesh), target(h, pmesh), pmesh)) { return false; } @@ -400,7 +400,7 @@ namespace internal { for(edge_descriptor e : edge_range) { const halfedge_descriptor he = halfedge(e, mesh_); - std::optional sqlen = sizing.is_too_long(source(he, mesh_), target(he, mesh_)); + std::optional sqlen = sizing.is_too_long(source(he, mesh_), target(he, mesh_), mesh_); if(sqlen != std::nullopt) long_edges.emplace(he, sqlen.value()); } @@ -433,16 +433,16 @@ namespace internal { std::cout << " refinement point : " << refinement_point << std::endl; #endif //update sizing field with the new point - sizing.update(vnew, mesh_); + sizing.register_split_vertex(vnew, mesh_); //check sub-edges //if it was more than twice the "long" threshold, insert them - std::optional sqlen_new = sizing.is_too_long(source(hnew, mesh_), target(hnew, mesh_)); + std::optional sqlen_new = sizing.is_too_long(source(hnew, mesh_), target(hnew, mesh_), mesh_); if(sqlen_new != std::nullopt) long_edges.emplace(hnew, sqlen_new.value()); const halfedge_descriptor hnext = next(hnew, mesh_); - sqlen_new = sizing.is_too_long(source(hnext, mesh_), target(hnext, mesh_)); + sqlen_new = sizing.is_too_long(source(hnext, mesh_), target(hnext, mesh_), mesh_); if (sqlen_new != std::nullopt) long_edges.emplace(hnext, sqlen_new.value()); @@ -500,7 +500,7 @@ namespace internal { if (!is_split_allowed(e)) continue; const halfedge_descriptor he = halfedge(e, mesh_); - std::optional sqlen = sizing.is_too_long(source(he, mesh_), target(he, mesh_)); + std::optional sqlen = sizing.is_too_long(source(he, mesh_), target(he, mesh_), mesh_); if(sqlen != std::nullopt) long_edges.emplace(halfedge(e, mesh_), sqlen.value()); } @@ -550,16 +550,16 @@ namespace internal { halfedge_added(hnew_opp, status(opposite(he, mesh_))); //update sizing field with the new point - sizing.update(vnew, mesh_); + sizing.register_split_vertex(vnew, mesh_); //check sub-edges //if it was more than twice the "long" threshold, insert them - std::optional sqlen_new = sizing.is_too_long(source(hnew, mesh_), target(hnew, mesh_)); + std::optional sqlen_new = sizing.is_too_long(source(hnew, mesh_), target(hnew, mesh_), mesh_); if(sqlen_new != std::nullopt) long_edges.emplace(hnew, sqlen_new.value()); const halfedge_descriptor hnext = next(hnew, mesh_); - sqlen_new = sizing.is_too_long(source(hnext, mesh_), target(hnext, mesh_)); + sqlen_new = sizing.is_too_long(source(hnext, mesh_), target(hnext, mesh_), mesh_); if (sqlen_new != std::nullopt) long_edges.emplace(hnext, sqlen_new.value()); @@ -580,7 +580,7 @@ namespace internal { if (snew == PATCH) { - std::optional sql = sizing.is_too_long(source(hnew2, mesh_), target(hnew2, mesh_)); + std::optional sql = sizing.is_too_long(source(hnew2, mesh_), target(hnew2, mesh_), mesh_); if(sql != std::nullopt) long_edges.emplace(hnew2, sql.value()); } @@ -603,7 +603,7 @@ namespace internal { if (snew == PATCH) { - std::optional sql = sizing.is_too_long(source(hnew2, mesh_), target(hnew2, mesh_)); + std::optional sql = sizing.is_too_long(source(hnew2, mesh_), target(hnew2, mesh_), mesh_); if (sql != std::nullopt) long_edges.emplace(hnew2, sql.value()); } @@ -747,7 +747,7 @@ namespace internal { for(halfedge_descriptor ha : halfedges_around_target(va, mesh_)) { vertex_descriptor va_i = source(ha, mesh_); - std::optional sqha = sizing.is_too_long(vb, va_i); + std::optional sqha = sizing.is_too_long(vb, va_i, mesh_); if (sqha != std::nullopt) { collapse_ok = false; diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Sizing_field_base.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Sizing_field_base.h index f13135cd873e..c06f0568e681 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Sizing_field_base.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Sizing_field_base.h @@ -60,13 +60,14 @@ class Sizing_field_base typedef typename K::FT FT; public: - virtual FT at(const vertex_descriptor v) const = 0; + virtual FT at(const vertex_descriptor v, const PolygonMesh&) const = 0; virtual std::optional is_too_long(const vertex_descriptor va, - const vertex_descriptor vb) const = 0; + const vertex_descriptor vb, + const PolygonMesh&) const = 0; virtual std::optional is_too_short(const halfedge_descriptor h, const PolygonMesh& pmesh) const = 0; virtual Point_3 split_placement(const halfedge_descriptor h, const PolygonMesh& pmesh) const = 0; - virtual void update(const vertex_descriptor v, const PolygonMesh& pmesh) = 0; + virtual void register_split_vertex(const vertex_descriptor v, const PolygonMesh& pmesh) = 0; }; diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/tangential_relaxation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/tangential_relaxation.h index 6693524324a9..145d5a24135f 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/tangential_relaxation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/tangential_relaxation.h @@ -288,9 +288,9 @@ void tangential_relaxation(const VertexRange& vertices, const double tri_area = gt_area(get(vpm, v), get(vpm, v1), get(vpm, v2)); const double face_weight = tri_area - / (1. / 3. * (sizing.at(v) - + sizing.at(v1) - + sizing.at(v2))); + / (1. / 3. * (sizing.at(v, tm) + + sizing.at(v1, tm) + + sizing.at(v2, tm))); weight += face_weight; const Point_3 centroid = gt_centroid(get(vpm, v), get(vpm, v1), get(vpm, v2)); From fe32ee586e5ee817cc32fa81421745ed2092fe3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 20 Nov 2023 11:36:06 +0100 Subject: [PATCH 187/329] at Eigen dependency --- .../CGAL/Polygon_mesh_processing/Adaptive_sizing_field.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/Adaptive_sizing_field.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/Adaptive_sizing_field.h index d576df0e447b..5c3a99efef5b 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/Adaptive_sizing_field.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/Adaptive_sizing_field.h @@ -38,6 +38,8 @@ namespace Polygon_mesh_processing * Edges too long with respect to the local target edge length are split in two, while * edges that are too short are collapsed. * +* This class depends on the Eigen library. +* * \cgalModels{PMPSizingField} * * \sa `isotropic_remeshing()` From 2363e94f7db77ff0a0c8afb5c4a8f4e089e0f774 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 22 Nov 2023 13:30:28 +0100 Subject: [PATCH 188/329] Do not use "Polygon" typedef --- .../Alpha_wrap_3/pause_and_resume_wrapping.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Alpha_wrap_3/examples/Alpha_wrap_3/pause_and_resume_wrapping.cpp b/Alpha_wrap_3/examples/Alpha_wrap_3/pause_and_resume_wrapping.cpp index b22b21d817bc..cee169048c32 100644 --- a/Alpha_wrap_3/examples/Alpha_wrap_3/pause_and_resume_wrapping.cpp +++ b/Alpha_wrap_3/examples/Alpha_wrap_3/pause_and_resume_wrapping.cpp @@ -32,8 +32,8 @@ using K = CGAL::Exact_predicates_inexact_constructions_kernel; using Point_3 = K::Point_3; using Points = std::vector; -using Polygon = std::array; -using Polygons = std::vector; +using Face = std::array; +using Faces = std::vector; using Mesh = CGAL::Surface_mesh; using face_descriptor = boost::graph_traits::face_descriptor; @@ -83,14 +83,14 @@ int main(int argc, char** argv) // = read the soup Points points; - Polygons polygons; - if(!CGAL::IO::read_polygon_soup(filename, points, polygons) || polygons.empty()) + Faces faces; + if(!CGAL::IO::read_polygon_soup(filename, points, faces) || faces.empty()) { std::cerr << "Invalid soup input: " << filename << std::endl; return EXIT_FAILURE; } - std::cout << "Input: " << points.size() << " points, " << polygons.size() << " faces" << std::endl; + std::cout << "Input: " << points.size() << " points, " << faces.size() << " faces" << std::endl; // Compute the alpha and offset values const double relative_alpha = (argc > 2) ? std::stod(argv[2]) : rng.get_double(150., 200.); @@ -111,7 +111,7 @@ int main(int argc, char** argv) // Build the wrapper using Oracle = CGAL::Alpha_wraps_3::internal::Triangle_soup_oracle; Oracle oracle(alpha); - oracle.add_triangle_soup(points, polygons, CGAL::parameters::default_values()); + oracle.add_triangle_soup(points, faces, CGAL::parameters::default_values()); CGAL::Alpha_wraps_3::internal::Alpha_wrapper_3 aw3(oracle); // --- Launch the wrapping, and pause when the algorithm has spent 1s flooding @@ -139,7 +139,7 @@ int main(int argc, char** argv) // --- Get the final wrap, in one go: Mesh single_pass_wrap; - CGAL::alpha_wrap_3(points, polygons, alpha, offset, single_pass_wrap); + CGAL::alpha_wrap_3(points, faces, alpha, offset, single_pass_wrap); std::cout << ">>> The final (from scratch) wrap has " << num_vertices(single_pass_wrap) << " vertices" << std::endl; output_name = generate_output_name(filename, relative_alpha, relative_offset); From e4f669561890ae46c61ed238ca8bc1df8ef06a8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 22 Nov 2023 13:30:37 +0100 Subject: [PATCH 189/329] Avoid /!\ in comments --- .../include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index 94694034cdd1..2bfae11f3b72 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -282,14 +282,14 @@ class Alpha_wrapper_3 // Whether to keep pockets of "outside" cells that are not connected to the exterior (or to the // initial cavities, if used). // - // /!\ Warning /!\ + // -- Warning -- // If you refine or pause while removing pockets, you will get valid but different wraps. const bool keep_inner_ccs = choose_parameter(get_parameter(in_np, internal_np::keep_inner_connected_components), true); // This parameter enables avoiding recomputing the triangulation from scratch when wrapping // the same input for multiple values of alpha (and typically the same offset values). // - // /!\ Warning /!\ + // -- Warning -- // If this is enabled, the 3D triangulation will NOT be re-initialized at launch. // This means that the triangulation is NOT cleared, even if: // - you use an alpha value that is greater than what was used in a previous run; you will From 22c2318a55d1589bc581b6110b39f6a527b3a4c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 22 Nov 2023 13:30:48 +0100 Subject: [PATCH 190/329] Add a todo --- Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index 2bfae11f3b72..8529af0b0f22 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -1087,6 +1087,9 @@ class Alpha_wrapper_3 return false; #endif + // @todo could avoid useless facet_status() calls by doing it after the zombie check + // for the unsorted priority queue, but AFAIR, it doesn't save noticeable time (and that + // increases the queue size). const Facet_status status = facet_status(f); if(status == Facet_status::IRRELEVANT) return false; From 2bc087a139d19802686da58ff434b38fef85792f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 22 Nov 2023 13:33:45 +0100 Subject: [PATCH 191/329] Fix warnings --- Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 2 +- .../include/CGAL/Alpha_wrap_3/internal/gate_priority_queue.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index 8529af0b0f22..d3d2beb6c6e4 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -95,7 +95,7 @@ struct Wrapping_default_visitor void on_flood_fill_begin(const AlphaWrapper&) { } template - constexpr bool go_further(const Wrapper& wrapper) { return true; } + constexpr bool go_further(const Wrapper&) { return true; } template void before_facet_treatment(const AlphaWrapper&, const Gate&) { } diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/gate_priority_queue.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/gate_priority_queue.h index f7947f246a4b..ec48b4f458b6 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/gate_priority_queue.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/gate_priority_queue.h @@ -121,7 +121,7 @@ class Gate public: const Facet& facet() const { return m_facet; } - const bool is_zombie() const + bool is_zombie() const { return (m_facet.first->erase_counter() != m_erase_counter_mem) || (m_mirror_facet.first->erase_counter() != m_mirror_erase_counter_mem); From dac83a571769dfc7313e278866eb1720512a1e42 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 22 Nov 2023 15:11:11 +0000 Subject: [PATCH 192/329] PMP examples: unify type names --- .../compute_normals_example.cpp | 14 +++++++------- .../compute_normals_example_Polyhedron.cpp | 8 ++++---- .../Polygon_mesh_processing/corefinement_LCC.cpp | 4 ++-- .../examples/Polygon_mesh_processing/extrude.cpp | 14 +++++++------- .../hole_filling_example.cpp | 10 +++++----- .../hole_filling_example_LCC.cpp | 10 +++++----- .../interpolated_corrected_curvatures_PH.cpp | 12 ++++++------ .../interpolated_corrected_curvatures_SM.cpp | 11 ++++++----- .../interpolated_corrected_curvatures_vertex.cpp | 8 +++++--- .../orient_polygon_soup_example.cpp | 6 +++--- .../point_inside_example.cpp | 10 +++++----- .../polyhedral_envelope.cpp | 6 +++--- .../polyhedral_envelope_mesh_containment.cpp | 10 +++++----- .../random_perturbation_SM_example.cpp | 8 ++++---- .../refine_fair_example.cpp | 12 ++++++------ .../remesh_almost_planar_patches.cpp | 6 +++--- .../remesh_planar_patches.cpp | 10 +++++----- .../stitch_borders_example.cpp | 4 ++-- .../stitch_borders_example_OM.cpp | 2 +- .../triangulate_faces_example.cpp | 6 +++--- .../triangulate_faces_split_visitor_example.cpp | 13 ++++++------- .../volume_connected_components.cpp | 13 +++++++------ 22 files changed, 100 insertions(+), 97 deletions(-) diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/compute_normals_example.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/compute_normals_example.cpp index c7e1fbdb21c4..949fcc8dd649 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/compute_normals_example.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/compute_normals_example.cpp @@ -7,14 +7,14 @@ #include #include -typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef K::Point_3 Point; -typedef K::Vector_3 Vector; +typedef K::Point_3 Point; +typedef K::Vector_3 Vector; -typedef CGAL::Surface_mesh Surface_mesh; -typedef boost::graph_traits::vertex_descriptor vertex_descriptor; -typedef boost::graph_traits::face_descriptor face_descriptor; +typedef CGAL::Surface_mesh Mesh; +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::face_descriptor face_descriptor; namespace PMP = CGAL::Polygon_mesh_processing; @@ -22,7 +22,7 @@ int main(int argc, char* argv[]) { const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/eight.off"); - Surface_mesh mesh; + Mesh mesh; if(!PMP::IO::read_polygon_mesh(filename, mesh)) { std::cerr << "Invalid input." << std::endl; diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/compute_normals_example_Polyhedron.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/compute_normals_example_Polyhedron.cpp index d21d675eb2b8..4418c6096d1b 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/compute_normals_example_Polyhedron.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/compute_normals_example_Polyhedron.cpp @@ -16,9 +16,9 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef K::Point_3 Point; typedef K::Vector_3 Vector; -typedef CGAL::Polyhedron_3 Polyhedron; -typedef boost::graph_traits::vertex_descriptor vertex_descriptor; -typedef boost::graph_traits::face_descriptor face_descriptor; +typedef CGAL::Polyhedron_3 Mesh; +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::face_descriptor face_descriptor; namespace PMP = CGAL::Polygon_mesh_processing; @@ -26,7 +26,7 @@ int main(int argc, char* argv[]) { const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/eight.off"); - Polyhedron mesh; + Mesh mesh; if(!PMP::IO::read_polygon_mesh(filename, mesh)) { std::cerr << "Invalid input." << std::endl; diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/corefinement_LCC.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/corefinement_LCC.cpp index 232164a1b957..d4d774d1105f 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/corefinement_LCC.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/corefinement_LCC.cpp @@ -12,7 +12,7 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; typedef Kernel::Point_3 Point; typedef CGAL::Linear_cell_complex_traits<3, Kernel> MyTraits; -typedef CGAL::Linear_cell_complex_for_bgl_combinatorial_map_helper<2, 3, MyTraits>::type LCC; +typedef CGAL::Linear_cell_complex_for_bgl_combinatorial_map_helper<2, 3, MyTraits>::type Mesh; namespace PMP = CGAL::Polygon_mesh_processing; @@ -21,7 +21,7 @@ int main(int argc, char* argv[]) const std::string filename1 = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/blobby.off"); const std::string filename2 = (argc > 2) ? argv[2] : CGAL::data_file_path("meshes/eight.off"); - LCC mesh1, mesh2; + Mesh mesh1, mesh2; if(!PMP::IO::read_polygon_mesh(filename1, mesh1) || !PMP::IO::read_polygon_mesh(filename2, mesh2)) { std::cerr << "Invalid input." << std::endl; diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/extrude.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/extrude.cpp index aa7c2bd40eab..baaa0612452d 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/extrude.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/extrude.cpp @@ -8,13 +8,13 @@ #include #include -typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; -typedef CGAL::Surface_mesh SM; -typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; +typedef CGAL::Surface_mesh Mesh; +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; -typedef Kernel::Vector_3 Vector; -typedef boost::property_map::type VPMap; -typedef SM::template Property_map VNMap; +typedef Kernel::Vector_3 Vector; +typedef boost::property_map::type VPMap; +typedef Mesh::template Property_map VNMap; struct Bottom { @@ -52,7 +52,7 @@ struct Top int main(int argc, char* argv[]) { - SM in, out; + Mesh in, out; std::string filename = (argc > 1) ? std::string(argv[1]) : CGAL::data_file_path("meshes/cube-ouvert.off"); double vlen = (argc > 2) ? std::stod(argv[2]) : 0.1; diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/hole_filling_example.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/hole_filling_example.cpp index 8c7d009461be..194db942db7c 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/hole_filling_example.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/hole_filling_example.cpp @@ -12,11 +12,11 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; -typedef CGAL::Polyhedron_3 Polyhedron; +typedef CGAL::Polyhedron_3 Mesh; -typedef Polyhedron::Vertex_handle Vertex_handle; -typedef Polyhedron::Halfedge_handle Halfedge_handle; -typedef Polyhedron::Facet_handle Facet_handle; +typedef Mesh::Vertex_handle Vertex_handle; +typedef Mesh::Halfedge_handle Halfedge_handle; +typedef Mesh::Facet_handle Facet_handle; namespace PMP = CGAL::Polygon_mesh_processing; @@ -24,7 +24,7 @@ int main(int argc, char* argv[]) { const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/mech-holes-shark.off"); - Polyhedron poly; + Mesh poly; if(!PMP::IO::read_polygon_mesh(filename, poly)) { std::cerr << "Invalid input." << std::endl; diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/hole_filling_example_LCC.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/hole_filling_example_LCC.cpp index be7b6166e4e1..898256005108 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/hole_filling_example_LCC.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/hole_filling_example_LCC.cpp @@ -14,11 +14,11 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; typedef Kernel::Point_3 Point; typedef CGAL::Linear_cell_complex_traits<3, Kernel> MyTraits; -typedef CGAL::Linear_cell_complex_for_bgl_combinatorial_map_helper<2, 3, MyTraits>::type LCC; +typedef CGAL::Linear_cell_complex_for_bgl_combinatorial_map_helper<2, 3, MyTraits>::type Mesh; -typedef boost::graph_traits::vertex_descriptor vertex_descriptor; -typedef boost::graph_traits::halfedge_descriptor halfedge_descriptor; -typedef boost::graph_traits::face_descriptor face_descriptor; +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::halfedge_descriptor halfedge_descriptor; +typedef boost::graph_traits::face_descriptor face_descriptor; namespace PMP = CGAL::Polygon_mesh_processing; @@ -26,7 +26,7 @@ int main(int argc, char* argv[]) { const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/mech-holes-shark.off"); - LCC mesh; + Mesh mesh; if(!PMP::IO::read_polygon_mesh(filename, mesh)) { std::cerr << "Invalid input." << std::endl; diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/interpolated_corrected_curvatures_PH.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/interpolated_corrected_curvatures_PH.cpp index 09bc213068d1..678597ad255c 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/interpolated_corrected_curvatures_PH.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/interpolated_corrected_curvatures_PH.cpp @@ -7,17 +7,17 @@ #include #include -#include +#include namespace PMP = CGAL::Polygon_mesh_processing; typedef CGAL::Exact_predicates_inexact_constructions_kernel Epic_kernel; -typedef CGAL::Polyhedron_3 Polyhedron; -typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef CGAL::Polyhedron_3 Mesh; +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; int main(int argc, char* argv[]) { - Polyhedron polyhedron; + Mesh polyhedron; const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/sphere.off"); @@ -29,11 +29,11 @@ int main(int argc, char* argv[]) } // define property map to store curvature value and directions - boost::property_map>::type + boost::property_map>::type mean_curvature_map = get(CGAL::dynamic_vertex_property_t(), polyhedron), Gaussian_curvature_map = get(CGAL::dynamic_vertex_property_t(), polyhedron); - boost::property_map>>::type + boost::property_map>>::type principal_curvatures_and_directions_map = get(CGAL::dynamic_vertex_property_t>(), polyhedron); diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/interpolated_corrected_curvatures_SM.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/interpolated_corrected_curvatures_SM.cpp index 74a678ea0624..ac8378781fe4 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/interpolated_corrected_curvatures_SM.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/interpolated_corrected_curvatures_SM.cpp @@ -11,12 +11,12 @@ namespace PMP = CGAL::Polygon_mesh_processing; typedef CGAL::Exact_predicates_inexact_constructions_kernel Epic_kernel; -typedef CGAL::Surface_mesh Surface_Mesh; -typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef CGAL::Surface_mesh Mesh; +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; int main(int argc, char* argv[]) { - Surface_Mesh smesh; + Mesh smesh; const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/sphere.off"); @@ -29,7 +29,7 @@ int main(int argc, char* argv[]) // creating and tying surface mesh property maps for curvatures (with defaults = 0) bool created = false; - Surface_Mesh::Property_map + Mesh::Property_map mean_curvature_map, Gaussian_curvature_map; boost::tie(mean_curvature_map, created) = @@ -41,7 +41,7 @@ int main(int argc, char* argv[]) assert(created); // we use a tuple of 2 scalar values and 2 vectors for principal curvatures and directions - Surface_Mesh::Property_map> + Mesh::Property_map> principal_curvatures_and_directions_map; boost::tie(principal_curvatures_and_directions_map, created) = @@ -67,4 +67,5 @@ int main(int argc, char* argv[]) << ", GC = " << Gaussian_curvature_map[v] << "\n" << ", PC = [ " << PC.min_curvature << " , " << PC.max_curvature << " ]\n"; } + return 0; } diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/interpolated_corrected_curvatures_vertex.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/interpolated_corrected_curvatures_vertex.cpp index bdcdba6b7fd0..dc78152059b7 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/interpolated_corrected_curvatures_vertex.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/interpolated_corrected_curvatures_vertex.cpp @@ -6,17 +6,18 @@ #include #include +#include namespace PMP = CGAL::Polygon_mesh_processing; typedef CGAL::Exact_predicates_inexact_constructions_kernel Epic_kernel; -typedef CGAL::Surface_mesh Surface_Mesh; -typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef CGAL::Surface_mesh Mesh; +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; int main(int argc, char* argv[]) { // instantiating and reading mesh - Surface_Mesh smesh; + Mesh smesh; const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/sphere.off"); @@ -47,4 +48,5 @@ int main(int argc, char* argv[]) << ", GC = " << g << "\n" << ", PC = [ " << p.min_curvature << " , " << p.max_curvature << " ]\n"; } + return 0; } diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/orient_polygon_soup_example.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/orient_polygon_soup_example.cpp index f603925bb6b3..072ec4c6360a 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/orient_polygon_soup_example.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/orient_polygon_soup_example.cpp @@ -15,7 +15,7 @@ #include typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef CGAL::Polyhedron_3 Polyhedron; +typedef CGAL::Polyhedron_3 Mesh; // Optional visitor for orientating a polygon soup to demonstrate usage for some functions. // inherits from the default class as some functions are not overloaded @@ -59,12 +59,12 @@ int main(int argc, char* argv[]) Visitor visitor; CGAL::Polygon_mesh_processing::orient_polygon_soup(points, polygons, CGAL::parameters::visitor(visitor)); - Polyhedron mesh; + Mesh mesh; CGAL::Polygon_mesh_processing::polygon_soup_to_polygon_mesh(points, polygons, mesh); // Number the faces because 'orient_to_bound_a_volume' needs a face <--> index map int index = 0; - for(Polyhedron::Face_iterator fb=mesh.facets_begin(), fe=mesh.facets_end(); fb!=fe; ++fb) + for(Mesh::Face_iterator fb=mesh.facets_begin(), fe=mesh.facets_end(); fb!=fe; ++fb) fb->id() = index++; if(CGAL::is_closed(mesh)) diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/point_inside_example.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/point_inside_example.cpp index 93b158ce1923..1a8b207cd6bb 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/point_inside_example.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/point_inside_example.cpp @@ -12,14 +12,14 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef K::Point_3 Point; -typedef CGAL::Polyhedron_3 Polyhedron; +typedef CGAL::Polyhedron_3 Mesh; namespace PMP = CGAL::Polygon_mesh_processing; -double max_coordinate(const Polyhedron& poly) +double max_coordinate(const Mesh& poly) { double max_coord = -std::numeric_limits::infinity(); - for(Polyhedron::Vertex_handle v : vertices(poly)) + for(Mesh::Vertex_handle v : vertices(poly)) { Point p = v->point(); max_coord = (std::max)(max_coord, CGAL::to_double(p.x())); @@ -33,14 +33,14 @@ int main(int argc, char* argv[]) { const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/eight.off"); - Polyhedron poly; + Mesh poly; if(!PMP::IO::read_polygon_mesh(filename, poly) || CGAL::is_empty(poly) || !CGAL::is_triangle_mesh(poly)) { std::cerr << "Invalid input." << std::endl; return 1; } - CGAL::Side_of_triangle_mesh inside(poly); + CGAL::Side_of_triangle_mesh inside(poly); double size = max_coordinate(poly); diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/polyhedral_envelope.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/polyhedral_envelope.cpp index afbb938afb51..5cc9379992f8 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/polyhedral_envelope.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/polyhedral_envelope.cpp @@ -9,13 +9,13 @@ int main(int argc, char* argv[]) { typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; typedef Kernel::Point_3 Point_3; - typedef CGAL::Surface_mesh Surface_mesh; - typedef boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef CGAL::Surface_mesh Mesh; + typedef boost::graph_traits::vertex_descriptor vertex_descriptor; typedef CGAL::Polyhedral_envelope Envelope; std::ifstream in((argc>1) ? argv[1] : CGAL::data_file_path("meshes/blobby.off")); - Surface_mesh tmesh; + Mesh tmesh; in >> tmesh; diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/polyhedral_envelope_mesh_containment.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/polyhedral_envelope_mesh_containment.cpp index 4e814c7dccd5..ede5edf61e8f 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/polyhedral_envelope_mesh_containment.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/polyhedral_envelope_mesh_containment.cpp @@ -13,19 +13,19 @@ int main(int argc, char* argv[]) { typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; typedef Kernel::Point_3 Point_3; - typedef CGAL::Surface_mesh Surface_mesh; + typedef CGAL::Surface_mesh Mesh; typedef CGAL::Polyhedral_envelope Envelope; std::ifstream in((argc>1) ? argv[1] : CGAL::data_file_path("meshes/blobby.off")); - Surface_mesh tmesh; + Mesh tmesh; in >> tmesh; // remesh the input using the longest edge size as target edge length - Surface_mesh query = tmesh; - Surface_mesh::Edge_iterator longest_edge_it = + Mesh query = tmesh; + Mesh::Edge_iterator longest_edge_it = std::max_element(edges(query).begin(), edges(query).end(), - [&query](Surface_mesh::Edge_index e1, Surface_mesh::Edge_index e2) + [&query](Mesh::Edge_index e1, Mesh::Edge_index e2) { return PMP::edge_length(halfedge(e1, query), query) < PMP::edge_length(halfedge(e2, query), query); diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/random_perturbation_SM_example.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/random_perturbation_SM_example.cpp index 742685e7485c..e043f6a9a770 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/random_perturbation_SM_example.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/random_perturbation_SM_example.cpp @@ -10,9 +10,9 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef K::Point_3 Point; -typedef CGAL::Surface_mesh Surface_mesh; -typedef boost::graph_traits::vertex_descriptor vertex_descriptor; -typedef boost::graph_traits::face_descriptor face_descriptor; +typedef CGAL::Surface_mesh Mesh; +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::face_descriptor face_descriptor; namespace PMP = CGAL::Polygon_mesh_processing; @@ -20,7 +20,7 @@ int main(int argc, char* argv[]) { const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/eight.off"); - Surface_mesh mesh; + Mesh mesh; if(!PMP::IO::read_polygon_mesh(filename, mesh)) { std::cerr << "Invalid input." << std::endl; diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/refine_fair_example.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/refine_fair_example.cpp index 23053a6766c3..30f1ed16a14c 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/refine_fair_example.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/refine_fair_example.cpp @@ -13,8 +13,8 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; -typedef CGAL::Polyhedron_3 Polyhedron; -typedef Polyhedron::Vertex_handle Vertex_handle; +typedef CGAL::Polyhedron_3 Mesh; +typedef Mesh::Vertex_handle Vertex_handle; namespace PMP = CGAL::Polygon_mesh_processing; @@ -34,7 +34,7 @@ void extract_k_ring(Vertex_handle v, { v = qv[current_index++]; - Polyhedron::Halfedge_around_vertex_circulator e(v->vertex_begin()), e_end(e); + Mesh::Halfedge_around_vertex_circulator e(v->vertex_begin()), e_end(e); do { Vertex_handle new_v = e->opposite()->vertex(); if (D.insert(std::make_pair(new_v, dist_v + 1)).second) @@ -47,14 +47,14 @@ int main(int argc, char* argv[]) { const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/blobby.off"); - Polyhedron poly; + Mesh poly; if(!PMP::IO::read_polygon_mesh(filename, poly) || !CGAL::is_triangle_mesh(poly)) { std::cerr << "Invalid input." << std::endl; return 1; } - std::vector new_facets; + std::vector new_facets; std::vector new_vertices; PMP::refine(poly, faces(poly), @@ -68,7 +68,7 @@ int main(int argc, char* argv[]) refined_off.close(); std::cout << "Refinement added " << new_vertices.size() << " vertices." << std::endl; - Polyhedron::Vertex_iterator v = poly.vertices_begin(); + Mesh::Vertex_iterator v = poly.vertices_begin(); std::advance(v, 82/*e.g.*/); std::vector region; extract_k_ring(v, 12/*e.g.*/, region); diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/remesh_almost_planar_patches.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/remesh_almost_planar_patches.cpp index e3924c3e095c..381183d0c997 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/remesh_almost_planar_patches.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/remesh_almost_planar_patches.cpp @@ -14,13 +14,13 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; typedef Kernel::Point_3 Point_3; -typedef CGAL::Surface_mesh Surface_mesh; +typedef CGAL::Surface_mesh Mesh; namespace PMP = CGAL::Polygon_mesh_processing; int main() { - Surface_mesh sm; + Mesh sm; CGAL::IO::read_polygon_mesh(CGAL::data_file_path("meshes/fandisk.off"), sm); //apply a perturbation to input vertices so that points are no longer coplanar @@ -51,7 +51,7 @@ int main() edge_is_constrained_map(CGAL::make_random_access_property_map(ecm))); // run the remeshing algorithm using filled properties - Surface_mesh out; + Mesh out; PMP::remesh_almost_planar_patches(sm, out, nb_regions, nb_corners, diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/remesh_planar_patches.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/remesh_planar_patches.cpp index 9f591e6a2696..92aa3b15c6fd 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/remesh_planar_patches.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/remesh_planar_patches.cpp @@ -12,12 +12,12 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; typedef Kernel::Point_3 Point_3; -typedef CGAL::Surface_mesh Surface_mesh; +typedef CGAL::Surface_mesh Mesh; namespace PMP = CGAL::Polygon_mesh_processing; int main() { - Surface_mesh sm; + Mesh sm; CGAL::IO::read_polygon_mesh(CGAL::data_file_path("meshes/cube_quad.off"), sm); // triangulate faces; @@ -25,8 +25,8 @@ int main() std::cout << "Input mesh has " << faces(sm).size() << " faces" << std::endl; assert(faces(sm).size()==12); - Surface_mesh::Property_map ecm = - sm.add_property_map("ecm",false).first; + Mesh::Property_map ecm = + sm.add_property_map("ecm",false).first; // detect sharp edges of the cube PMP::detect_sharp_edges(sm, 60, ecm); @@ -37,7 +37,7 @@ int main() assert(faces(sm).size()>100); // decimate the mesh - Surface_mesh out; + Mesh out; PMP::remesh_planar_patches(sm, out); CGAL::IO::write_polygon_mesh("cube_decimated.off", out, CGAL::parameters::stream_precision(17)); diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/stitch_borders_example.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/stitch_borders_example.cpp index a7afc963ed70..28d770626e2c 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/stitch_borders_example.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/stitch_borders_example.cpp @@ -9,7 +9,7 @@ #include typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef CGAL::Polyhedron_3 Polyhedron; +typedef CGAL::Polyhedron_3 Mesh; namespace PMP = CGAL::Polygon_mesh_processing; @@ -17,7 +17,7 @@ int main(int argc, char* argv[]) { const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/quads_to_stitch.off"); - Polyhedron mesh; + Mesh mesh; if(!PMP::IO::read_polygon_mesh(filename, mesh)) { std::cerr << "Invalid input." << std::endl; diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/stitch_borders_example_OM.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/stitch_borders_example_OM.cpp index b731e8c02201..cf97918fd3b8 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/stitch_borders_example_OM.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/stitch_borders_example_OM.cpp @@ -10,8 +10,8 @@ #include typedef CGAL::Exact_predicates_inexact_constructions_kernel K; - typedef OpenMesh::PolyMesh_ArrayKernelT< > Mesh; + int main(int argc, char* argv[]) { const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/quads_to_stitch.off"); diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/triangulate_faces_example.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/triangulate_faces_example.cpp index 7587d0123638..9c7ef677bc0a 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/triangulate_faces_example.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/triangulate_faces_example.cpp @@ -11,7 +11,7 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; typedef Kernel::Point_3 Point; -typedef CGAL::Surface_mesh Surface_mesh; +typedef CGAL::Surface_mesh Mesh; namespace PMP = CGAL::Polygon_mesh_processing; @@ -20,7 +20,7 @@ int main(int argc, char* argv[]) const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/P.off"); const char* outfilename = (argc > 2) ? argv[2] : "P_tri.off"; - Surface_mesh mesh; + Mesh mesh; if(!PMP::IO::read_polygon_mesh(filename, mesh)) { std::cerr << "Error: Invalid input." << std::endl; @@ -41,7 +41,7 @@ int main(int argc, char* argv[]) PMP::triangulate_faces(mesh); // Confirm that all faces are triangles. - for(boost::graph_traits::face_descriptor f : faces(mesh)) + for(boost::graph_traits::face_descriptor f : faces(mesh)) { if(!CGAL::is_triangle(halfedge(f, mesh), mesh)) std::cerr << "Error: non-triangular face left in mesh." << std::endl; diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/triangulate_faces_split_visitor_example.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/triangulate_faces_split_visitor_example.cpp index 9b246f7678df..84695b32e325 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/triangulate_faces_split_visitor_example.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/triangulate_faces_split_visitor_example.cpp @@ -6,15 +6,14 @@ #include #include -#include #include #include #include typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; -typedef Kernel::Point_3 Point; -typedef CGAL::Surface_mesh Surface_mesh; -typedef boost::graph_traits::face_descriptor face_descriptor; +typedef Kernel::Point_3 Point; +typedef CGAL::Surface_mesh Mesh; +typedef boost::graph_traits::face_descriptor face_descriptor; class Insert_iterator { @@ -41,7 +40,7 @@ class Insert_iterator }; -struct Visitor : public CGAL::Polygon_mesh_processing::Triangulate_faces::Default_visitor +struct Visitor : public CGAL::Polygon_mesh_processing::Triangulate_faces::Default_visitor { typedef std::unordered_map Container; @@ -78,7 +77,7 @@ int main(int argc, char* argv[]) const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/P.off"); std::ifstream input(filename); - Surface_mesh mesh; + Mesh mesh; if (!input || !(input >> mesh) || mesh.is_empty()) { std::cerr << "Not a valid off file." << std::endl; @@ -87,7 +86,7 @@ int main(int argc, char* argv[]) std::unordered_map t2q; - Surface_mesh copy; + Mesh copy; CGAL::copy_face_graph(mesh, copy, CGAL::parameters::face_to_face_output_iterator(Insert_iterator(t2q))); 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 bd4181c3ff48..e07c803b83e6 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 @@ -12,7 +12,7 @@ #include typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; -typedef CGAL::Surface_mesh Surface_mesh; +typedef CGAL::Surface_mesh Mesh; namespace PMP = CGAL::Polygon_mesh_processing; namespace params = CGAL::parameters; @@ -21,7 +21,7 @@ int main(int argc, char** argv) { const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/blobby.off"); - Surface_mesh mesh; + Mesh mesh; if(!PMP::IO::read_polygon_mesh(filename, mesh)) { std::cerr << "Invalid input." << std::endl; @@ -29,8 +29,8 @@ int main(int argc, char** argv) } // property map to assign a volume id for each face - Surface_mesh::Property_map vol_id_map = - mesh.add_property_map().first; + Mesh::Property_map vol_id_map = + mesh.add_property_map().first; // fill the volume id map std::vector err_codes; @@ -39,7 +39,7 @@ int main(int argc, char** argv) std::cout << "Found " << nb_vol << " volumes\n"; // write each volume in an OFF file - typedef CGAL::Face_filtered_graph Filtered_graph; + typedef CGAL::Face_filtered_graph Filtered_graph; Filtered_graph vol_mesh(mesh, 0, vol_id_map); for(std::size_t id = 0; id < nb_vol; ++id) { @@ -49,11 +49,12 @@ int main(int argc, char** argv) if(id > 0) vol_mesh.set_selected_faces(id, vol_id_map); - Surface_mesh out; + Mesh out; CGAL::copy_face_graph(vol_mesh, out); std::ostringstream oss; oss << "vol_" << id <<".off"; std::ofstream os(oss.str().data()); os << out; } + return 0; } From f042f5a8eb2559146df06b535808af25683d6fe3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 22 Nov 2023 16:13:21 +0100 Subject: [PATCH 193/329] Fix initialization warning --- .../include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index d3d2beb6c6e4..5adf81dc443a 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -197,11 +197,11 @@ class Alpha_wrapper_3 Alpha_wrapper_3(const Oracle& oracle) : -#ifdef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE - m_queue(4096), -#endif m_oracle(oracle), m_tr(Geom_traits(oracle.geom_traits())) +#ifdef CGAL_AW3_USE_SORTED_PRIORITY_QUEUE + , m_queue(4096) +#endif { static_assert(std::is_floating_point::value); } From d9bdf5cfc5eacb36c0c012d2c77651bf7b5dbbcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 23 Nov 2023 09:38:28 +0100 Subject: [PATCH 194/329] remove extra typename --- Triangulation_2/include/CGAL/Regular_triangulation_2.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Triangulation_2/include/CGAL/Regular_triangulation_2.h b/Triangulation_2/include/CGAL/Regular_triangulation_2.h index d5d1a6c5917a..3353b7d76037 100644 --- a/Triangulation_2/include/CGAL/Regular_triangulation_2.h +++ b/Triangulation_2/include/CGAL/Regular_triangulation_2.h @@ -528,8 +528,8 @@ class Regular_triangulation_2 insert(boost::zip_iterator< boost::tuple > first, boost::zip_iterator< boost::tuple > last, std::enable_if_t< - typename std::is_convertible_v< typename std::iterator_traits::value_type, Weighted_point > && - typename std::is_convertible_v< typename std::iterator_traits::value_type, typename internal::Info_check::type > + std::is_convertible_v< typename std::iterator_traits::value_type, Weighted_point > && + std::is_convertible_v< typename std::iterator_traits::value_type, typename internal::Info_check::type > >* =nullptr ) {return insert_with_info< boost::tuple::type> >(first,last);} From 6cd28f751ed670181c76660623e1e5d6185ce2e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 23 Nov 2023 09:39:17 +0100 Subject: [PATCH 195/329] use std integral_constant --- STL_Extension/include/CGAL/tags.h | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/STL_Extension/include/CGAL/tags.h b/STL_Extension/include/CGAL/tags.h index 6aa1988e1cc7..eba9ffdc7215 100644 --- a/STL_Extension/include/CGAL/tags.h +++ b/STL_Extension/include/CGAL/tags.h @@ -19,26 +19,13 @@ #define CGAL_TAGS_H #include -#include namespace CGAL { struct Void {}; -// Boolean_tag is a model of the Boost Integral Constant concept. -// https://www.boost.org/libs/mpl/doc/refmanual/integral-constant.html template -struct Boolean_tag { - typedef boost::mpl::integral_c_tag tag; - typedef bool value_type; - static const bool value = b; - typedef Boolean_tag type; - operator bool() const { return this->value; } -}; -/* In C++11, try: -template -using Boolean_tag = std::integral_constant; -*/ +using Boolean_tag = std::bool_constant; typedef Boolean_tag Tag_true; typedef Boolean_tag Tag_false; From 16de47d1e6543e08259f68e83f6625790ceaf2d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 23 Nov 2023 14:55:30 +0100 Subject: [PATCH 196/329] more fixes --- .../include/CGAL/Polygon_mesh_processing/intersection.h | 4 ++-- QP_solver/test/QP_solver/test_solver.cpp | 1 + Triangulation_3/include/CGAL/Regular_triangulation_3.h | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/intersection.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/intersection.h index a72d9ffaafc9..a996edae6483 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/intersection.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/intersection.h @@ -1428,12 +1428,12 @@ bool do_intersect(const TriangleMesh& tm, #ifndef DOXYGEN_RUNNING , const std::enable_if_t || // Added to please MSVC 2015 - !boost::has_range_iterator::type>::value || // not a range + !boost::has_range_iterator::value || // not a range boost::has_range_iterator< typename boost::mpl::eval_if< boost::has_range_iterator, boost::range_value, - std::false_type + std::false_type>::type >::value ) >* = 0 diff --git a/QP_solver/test/QP_solver/test_solver.cpp b/QP_solver/test/QP_solver/test_solver.cpp index ad298449b551..4fc641cc2867 100644 --- a/QP_solver/test/QP_solver/test_solver.cpp +++ b/QP_solver/test/QP_solver/test_solver.cpp @@ -282,6 +282,7 @@ bool process(const std::string& filename, { using std::cout; using std::endl; + using CGAL::check_tag; // extract verbosity: const int verbosity = options.find("Verbosity")->second; diff --git a/Triangulation_3/include/CGAL/Regular_triangulation_3.h b/Triangulation_3/include/CGAL/Regular_triangulation_3.h index b4ff7de189cf..180269625203 100644 --- a/Triangulation_3/include/CGAL/Regular_triangulation_3.h +++ b/Triangulation_3/include/CGAL/Regular_triangulation_3.h @@ -612,8 +612,8 @@ class Regular_triangulation_3 insert(boost::zip_iterator< boost::tuple > first, boost::zip_iterator< boost::tuple > last, std::enable_if_t< - typename std::is_convertible_v< typename std::iterator_traits::value_type, Weighted_point > && - typename std::is_convertible_v< typename std::iterator_traits::value_type, typename internal::Info_check::type > + std::is_convertible_v< typename std::iterator_traits::value_type, Weighted_point > && + std::is_convertible_v< typename std::iterator_traits::value_type, typename internal::Info_check::type > >* =nullptr) { return insert_with_info< From 7fdc36dbbef57506c9431f248c16ee3eeb1d1c58 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 23 Nov 2023 15:48:46 +0100 Subject: [PATCH 197/329] remove *_sizing_field criteria from test --- .../Mesh_3/test_mesh_criteria_creation.cpp | 84 ++++--------------- 1 file changed, 16 insertions(+), 68 deletions(-) diff --git a/Mesh_3/test/Mesh_3/test_mesh_criteria_creation.cpp b/Mesh_3/test/Mesh_3/test_mesh_criteria_creation.cpp index b81befd7a56a..fb74fa720e4b 100644 --- a/Mesh_3/test/Mesh_3/test_mesh_criteria_creation.cpp +++ b/Mesh_3/test/Mesh_3/test_mesh_criteria_creation.cpp @@ -75,28 +75,12 @@ int main() Mc ec1(edge_size = 1); assert( ec1.edge_criteria_object().sizing_field(bp1,1,index) == 1 ); - Mc ec2(edge_sizing_field = Esf(2)); + Mc ec2(edge_size = Esf(2)); assert( ec2.edge_criteria_object().sizing_field(bp1,1,index) == 2 ); - Mc ec3(edge_sizing_field = 3.); + Mc ec3(edge_size = 3.); assert( ec3.edge_criteria_object().sizing_field(bp1,1,index) == 3 ); - Mc ec4(edge_size = 4., - edge_sizing_field = Esf(5.)); - assert( ec4.edge_criteria_object().sizing_field(bp1,1,index) == 4. ); - - Mc ec5(sizing_field = 5.); - assert( ec5.edge_criteria_object().sizing_field(bp1,1,index) == 5 ); - - Mc ec6(sizing_field = 6., - edge_sizing_field = 7.); - assert( ec6.edge_criteria_object().sizing_field(bp1,1,index) == 7. ); - - Mc ec7(sizing_field = 7., - edge_size = 8.); - assert( ec7.edge_criteria_object().sizing_field(bp1,1,index) == 8. ); - - // ----------------------------------- // Test facet criteria // ----------------------------------- @@ -114,43 +98,25 @@ int main() Mc fc1(facet_size = facet_size_ok); assert( ! fc1.facet_criteria_object()(tr, f) ); - Mc fc2(facet_sizing_field = facet_size_ok); - assert( ! fc2.facet_criteria_object()(tr, f) ); - - Mc fc3(facet_sizing_field = Fsf(facet_size_ok)); + Mc fc3(facet_size = Fsf(facet_size_ok)); assert( ! fc3.facet_criteria_object()(tr, f) ); - Mc fc4(facet_sizing_field = facet_size_nok, - facet_size = facet_size_ok); - assert( ! fc4.facet_criteria_object()(tr, f) ); - - Mc fc5(sizing_field = facet_size_ok); - assert( ! fc5.facet_criteria_object()(tr, f) ); - - Mc fc6(facet_size = facet_size_ok, - facet_sizing_field = facet_size_nok, - sizing_field = facet_size_nok); - assert( ! fc6.facet_criteria_object()(tr, f) ); - - Mc fc7(facet_sizing_field = Fsf(facet_size_ok), - sizing_field = facet_size_nok); - assert( ! fc7.facet_criteria_object()(tr, f) ); - Mc fc8(facet_distance = 8.); Mc fc9(facet_angle = 9.); Mc fc10(facet_angle = 10.1, facet_distance = 10.2, facet_size = 10.3, - facet_min_size = 0.2, - facet_sizing_field = Fsf(10.4), - sizing_field = 10.5); + facet_min_size = 0.2); + Mc fc1Ob(facet_angle = 10.11, + facet_distance = 10.12, + facet_min_size = 0.3, + facet_size = Fsf(10.14)); // Test construction from int Mc fc11(facet_size = 11); Mc fc11b(facet_size = 11, facet_min_size = 1); - Mc fc12(facet_sizing_field = 12); - Mc fc12b(facet_sizing_field = 12, facet_min_size = 2); - Mc fc13(sizing_field = 13); + Mc fc12(facet_size = Fsf(12)); + Mc fc12b(facet_size = Fsf(12), facet_min_size = 1); // Test topological criterion creation Mc fc14(facet_topology = CGAL::FACET_VERTICES_ON_SURFACE); @@ -173,41 +139,23 @@ int main() Mc cc1(cell_size = cell_size_ok); assert( ! cc1.cell_criteria_object()(tr, ch) ); - Mc cc2(cell_sizing_field = cell_size_ok); - assert( ! cc2.cell_criteria_object()(tr, ch) ); - - Mc cc3(cell_sizing_field = Fsf(cell_size_ok)); + Mc cc3(cell_size = Fsf(cell_size_ok)); assert( ! cc3.cell_criteria_object()(tr, ch) ); - Mc cc4(cell_sizing_field = cell_size_nok, - cell_size = cell_size_ok); - assert( ! cc4.cell_criteria_object()(tr, ch) ); - - Mc cc5(sizing_field = cell_size_ok); - assert( ! cc5.cell_criteria_object()(tr, ch) ); - - Mc cc6(cell_size = cell_size_ok, - cell_sizing_field = cell_size_nok, - sizing_field = cell_size_nok); - assert( ! cc6.cell_criteria_object()(tr, ch) ); - - Mc cc7(cell_sizing_field = Csf(cell_size_ok), - sizing_field = cell_size_nok); + Mc cc7(cell_size = Csf(cell_size_ok)); assert( ! cc7.cell_criteria_object()(tr, ch) ); Mc cc8(cell_radius_edge_ratio = 8.); Mc cc9(cell_radius_edge_ratio = 9.1, - sizing_field = Csf(9.2) ); + cell_size = Csf(9.2) ); Mc cc10(cell_radius_edge_ratio = 10.1, cell_size = 10.2, + cell_min_size = 0.1); + Mc cc10b(cell_radius_edge_ratio = 10.1, cell_min_size = 0.1, - cell_sizing_field = Csf(10.3), - sizing_field = 10.4); + cell_size = Csf(10.3)); // Test construction from int Mc cc11(cell_size = 11); Mc cc11b(cell_size = 11, cell_min_size = 1); - Mc cc12(cell_sizing_field = 12); - Mc cc12b(cell_sizing_field = 12, cell_min_size = 2); - Mc cc13(sizing_field = 13); } From 25e597ac795e37dbc2326bac7ed1783766ef6c8b Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 23 Nov 2023 15:22:20 +0000 Subject: [PATCH 198/329] Poisson Surface Reconstruction: Enable Structural Filtering --- .../include/CGAL/Reconstruction_triangulation_3.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Poisson_surface_reconstruction_3/include/CGAL/Reconstruction_triangulation_3.h b/Poisson_surface_reconstruction_3/include/CGAL/Reconstruction_triangulation_3.h index 9f605978f7ca..5b625f8042ec 100644 --- a/Poisson_surface_reconstruction_3/include/CGAL/Reconstruction_triangulation_3.h +++ b/Poisson_surface_reconstruction_3/include/CGAL/Reconstruction_triangulation_3.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -148,6 +149,12 @@ struct Reconstruction_triangulation_default_geom_traits_3 : public BaseGt }; +template < class BaseGt > +struct Triangulation_structural_filtering_traits > { + typedef typename Triangulation_structural_filtering_traits::Use_structural_filtering_tag Use_structural_filtering_tag; +}; + + /// \internal /// The Reconstruction_triangulation_3 class /// provides the interface requested by the Poisson_reconstruction_function class: From 8f8280ce34531e9ba720a76096e6d219c56d0cce Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 23 Nov 2023 19:37:23 +0000 Subject: [PATCH 199/329] Add structural filtering to Robust circumcenter traits --- .../CGAL/Robust_weighted_circumcenter_filtered_traits_3.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Triangulation_3/include/CGAL/Robust_weighted_circumcenter_filtered_traits_3.h b/Triangulation_3/include/CGAL/Robust_weighted_circumcenter_filtered_traits_3.h index 0ab43248e21c..beddf4c0b3db 100644 --- a/Triangulation_3/include/CGAL/Robust_weighted_circumcenter_filtered_traits_3.h +++ b/Triangulation_3/include/CGAL/Robust_weighted_circumcenter_filtered_traits_3.h @@ -18,6 +18,7 @@ #include #include #include +#include #include namespace CGAL { @@ -531,6 +532,13 @@ class Robust_circumcenter_filtered_traits_3 Robust_circumcenter_filtered_traits_3(const Kernel& k = Kernel()) : Kernel(k) { } }; + +template < class BaseGt > +struct Triangulation_structural_filtering_traits > { + typedef typename Triangulation_structural_filtering_traits::Use_structural_filtering_tag Use_structural_filtering_tag; +}; + + template class Robust_weighted_circumcenter_filtered_traits_3 : public Robust_circumcenter_filtered_traits_3 From 30fe1ed629dcd31fe7f30f39c57afd8d9305bffc Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Fri, 24 Nov 2023 11:16:05 +0100 Subject: [PATCH 200/329] shape criterion renamed --- .../test/Periodic_3_mesh_3/test_implicit_shapes_bunch.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Periodic_3_mesh_3/test/Periodic_3_mesh_3/test_implicit_shapes_bunch.cpp b/Periodic_3_mesh_3/test/Periodic_3_mesh_3/test_implicit_shapes_bunch.cpp index f09fffd0d4f1..87669ceb91d5 100644 --- a/Periodic_3_mesh_3/test/Periodic_3_mesh_3/test_implicit_shapes_bunch.cpp +++ b/Periodic_3_mesh_3/test/Periodic_3_mesh_3/test_implicit_shapes_bunch.cpp @@ -230,7 +230,7 @@ int main() Periodic_mesh_criteria criteria(facet_angle = 30, facet_size = 0.05, facet_distance = 0.025, - cell_radius_edge = 2, + cell_radius_edge_ratio = 2, cell_size = 0.05); // Mesh generation From 65621c2e9e744b78f0889ab33b43ac63d4d8e5e0 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Mon, 27 Nov 2023 12:51:20 +0000 Subject: [PATCH 201/329] Spatial Searching: Add example storing triangulation vertices --- Spatial_searching/doc/Spatial_searching/examples.txt | 1 + Spatial_searching/examples/Spatial_searching/CMakeLists.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/Spatial_searching/doc/Spatial_searching/examples.txt b/Spatial_searching/doc/Spatial_searching/examples.txt index defc30a2079e..8c3c7920ff77 100644 --- a/Spatial_searching/doc/Spatial_searching/examples.txt +++ b/Spatial_searching/doc/Spatial_searching/examples.txt @@ -11,6 +11,7 @@ \example Spatial_searching/searching_with_circular_query.cpp \example Spatial_searching/searching_surface_mesh_vertices.cpp \example Spatial_searching/searching_polyhedron_vertices.cpp +\example Spatial_searching/searching_triangulation_vertices.cpp \example Spatial_searching/searching_with_point_with_info.cpp \example Spatial_searching/searching_with_point_with_info_inplace.cpp \example Spatial_searching/searching_with_point_with_info_pmap.cpp diff --git a/Spatial_searching/examples/Spatial_searching/CMakeLists.txt b/Spatial_searching/examples/Spatial_searching/CMakeLists.txt index f9546507bd49..b273ac3477bf 100644 --- a/Spatial_searching/examples/Spatial_searching/CMakeLists.txt +++ b/Spatial_searching/examples/Spatial_searching/CMakeLists.txt @@ -23,6 +23,7 @@ create_single_source_cgal_program("searching_with_point_with_info_inplace.cpp") create_single_source_cgal_program("searching_with_point_with_info_pmap.cpp") create_single_source_cgal_program("searching_surface_mesh_vertices.cpp") create_single_source_cgal_program("searching_polyhedron_vertices.cpp") +create_single_source_cgal_program("searching_triangulation_vertices.cpp") create_single_source_cgal_program("searching_polyhedron_vertices_with_fuzzy_sphere.cpp") create_single_source_cgal_program("user_defined_point_and_distance.cpp") create_single_source_cgal_program("using_fair_splitting_rule.cpp") From c018e0fe7c4f6c28f4854756968738e93bbf618c Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Mon, 27 Nov 2023 12:54:26 +0000 Subject: [PATCH 202/329] The example itself --- .../searching_triangulation_vertices.cpp | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 Spatial_searching/examples/Spatial_searching/searching_triangulation_vertices.cpp diff --git a/Spatial_searching/examples/Spatial_searching/searching_triangulation_vertices.cpp b/Spatial_searching/examples/Spatial_searching/searching_triangulation_vertices.cpp new file mode 100644 index 000000000000..a045313f3f56 --- /dev/null +++ b/Spatial_searching/examples/Spatial_searching/searching_triangulation_vertices.cpp @@ -0,0 +1,65 @@ +#include +#include +#include +#include +#include +#include + +#include + +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; +typedef Kernel::Point_3 Point_3; +typedef CGAL::Delaunay_triangulation_3 Delaunay; +typedef Delaunay::Vertex_handle Vertex_handle; + + +struct Project { + typedef Vertex_handle argument_type; + typedef const Point_3& Point; + typedef Point result_type; + const Point& operator()( Vertex_handle v) const { return v->point(); } +}; + + +typedef boost::function_property_map Vertex_point_pmap; +typedef CGAL::Search_traits_3 Traits_base; +typedef CGAL::Search_traits_adapter Traits; +typedef CGAL::Orthogonal_k_neighbor_search K_neighbor_search; +typedef K_neighbor_search::Tree Tree; +typedef Tree::Splitter Splitter; +typedef K_neighbor_search::Distance Distance; + +int main(int argc, char* argv[]) +{ + std::ifstream in((argc>1)?argv[1]:CGAL::data_file_path("points_3/kitten.xyz")); + std::vector points; + Point_3 p; + while(in >> p){ + points.push_back(p); + } + + Delaunay dt(points.begin(), points.end()); + + const unsigned int K = 5; + + Project project; + Vertex_point_pmap vppmap(project); + + // Insert number_of_data_points in the tree + Tree tree(dt.finite_vertex_handles().begin(), dt.finite_vertex_handles().end(), Splitter(), Traits(vppmap)); + + // search K nearest neighbors + Point_3 query(0.0, 0.0, 0.0); + Distance tr_dist(vppmap); + + K_neighbor_search search(tree, query, K,0,true,tr_dist); + std::cout <<"The "<< K << " nearest vertices to the query point at (0,0,0) are:" << std::endl; + for(K_neighbor_search::iterator it = search.begin(); it != search.end(); it++){ + std::cout << "vertex " << &*(it->first) << " : " << vppmap[it->first] << " at distance " + << tr_dist.inverse_of_transformed_distance(it->second) << std::endl; + } + + return 0; +} From f36693c48e10dcb008a3916e4bae267964ffb2db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 28 Nov 2023 10:29:46 +0100 Subject: [PATCH 203/329] Fix warning --- .../Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp index 383d1103778f..ddc84bc5002f 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp @@ -217,7 +217,7 @@ struct AW3_interrupter_visitor { } template - constexpr bool go_further(const Wrapper& wrapper) + constexpr bool go_further(const Wrapper&) { return !(*should_stop); } From 6b570f767e9631bc02be240fd61deb6b15e2d693 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 28 Nov 2023 17:45:54 +0100 Subject: [PATCH 204/329] fix sign --- .../include/CGAL/Kernel/function_objects.h | 2 +- .../test_approximate_dihedral_angle_3.cpp | 35 +++++++++++++++---- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/Kernel_23/include/CGAL/Kernel/function_objects.h b/Kernel_23/include/CGAL/Kernel/function_objects.h index 9b6af428e25b..bb476ded1f25 100644 --- a/Kernel_23/include/CGAL/Kernel/function_objects.h +++ b/Kernel_23/include/CGAL/Kernel/function_objects.h @@ -934,7 +934,7 @@ namespace CommonKernelFunctors { const double l_ab = CGAL::sqrt(CGAL::to_double(sq_distance(a,b))); const double y = l_ab * CGAL::to_double(scalar_product(ac,abad)); - return FT(std::atan2(y, x) * 180 / CGAL_PI ); + return -FT(std::atan2(y, x) * 180 / CGAL_PI ); } }; diff --git a/Kernel_23/test/Kernel_23/test_approximate_dihedral_angle_3.cpp b/Kernel_23/test/Kernel_23/test_approximate_dihedral_angle_3.cpp index b39ce5c01e72..dfa703b86f7e 100644 --- a/Kernel_23/test/Kernel_23/test_approximate_dihedral_angle_3.cpp +++ b/Kernel_23/test/Kernel_23/test_approximate_dihedral_angle_3.cpp @@ -10,20 +10,41 @@ struct query { double expected_angle; }; +void sign_test() +{ + K::Point_3 a(0,0,0), b(1,0,0), c(0,1, 0), d(0,0,1); + + assert( CGAL::approximate_dihedral_angle(a, b, c, d) > 0); + assert( CGAL::approximate_dihedral_angle(c, a, b, d) > 0); + assert( CGAL::approximate_dihedral_angle(a, d, b, c) > 0); + assert( CGAL::approximate_dihedral_angle(c, b, d, a) > 0); + assert( CGAL::approximate_dihedral_angle(d, b, a, c) > 0); + assert( CGAL::approximate_dihedral_angle(d, c, b, a) > 0); + + assert( CGAL::approximate_dihedral_angle(a, b, d, c) < 0); + assert( CGAL::approximate_dihedral_angle(c, a, d, b) < 0); + assert( CGAL::approximate_dihedral_angle(a, d, c, b) < 0); + assert( CGAL::approximate_dihedral_angle(c, b, a, d) < 0); + assert( CGAL::approximate_dihedral_angle(d, b, c, a) < 0); + assert( CGAL::approximate_dihedral_angle(d, c, a, b) < 0); +} + int main() { + sign_test(); + Point_3 a = {0, 0, 0}; Point_3 b = {0, 1, 0}; Point_3 c = {1, 0, 0}; const query queries[] = { { { 1, 0, 0}, 0.}, - { { 1, 0, 1}, 45.}, - { { 0, 0, 1}, 90.}, - { { -1, 0, 1}, 135.}, - { { -1, 0, 0}, 180.}, - { { -1, 0, -1}, -135.}, - { { 0, 0, -1}, -90.}, - { { 1, 0, -1}, -45.}, + { { 1, 0, 1}, -45.}, + { { 0, 0, 1}, -90.}, + { { -1, 0, 1}, -135.}, + { { -1, 0, 0}, -180.}, + { { -1, 0, -1}, 135.}, + { { 0, 0, -1}, 90.}, + { { 1, 0, -1}, 45.}, }; for(auto query: queries) { From abbbb53096037c75c3ffa4da3fed159406ab3827 Mon Sep 17 00:00:00 2001 From: Sven Oesau Date: Wed, 29 Nov 2023 11:03:50 +0100 Subject: [PATCH 205/329] added missing dependency to OSQP when default solver is used --- .../include/CGAL/Shape_regularization/regularize_segments.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Shape_regularization/include/CGAL/Shape_regularization/regularize_segments.h b/Shape_regularization/include/CGAL/Shape_regularization/regularize_segments.h index 2042cff97b52..ad290801019a 100644 --- a/Shape_regularization/include/CGAL/Shape_regularization/regularize_segments.h +++ b/Shape_regularization/include/CGAL/Shape_regularization/regularize_segments.h @@ -70,6 +70,9 @@ namespace Segments { that should be addressed. The function is based on the class `QP_regularization`. Please refer to that class and these concepts for more information. + This class requires a `QPSolver` model which defaults to the \ref thirdpartyOSQP "OSQP" + library, which must be available on the system. + \tparam InputRange a model of `ConstRange` whose iterator type is `RandomAccessIterator` From 0145bafbc5079ea98e91f82d528220a7ce91123a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 29 Nov 2023 12:22:46 +0100 Subject: [PATCH 206/329] update formula will add comments in a upcoming commit --- Kernel_23/include/CGAL/Kernel/function_objects.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Kernel_23/include/CGAL/Kernel/function_objects.h b/Kernel_23/include/CGAL/Kernel/function_objects.h index bb476ded1f25..ab23552b6821 100644 --- a/Kernel_23/include/CGAL/Kernel/function_objects.h +++ b/Kernel_23/include/CGAL/Kernel/function_objects.h @@ -930,11 +930,12 @@ namespace CommonKernelFunctors { const Vector_3 ad = vector(a,d); const Vector_3 abad = cross_product(ab,ad); - const double x = CGAL::to_double(scalar_product(cross_product(ab,ac), abad)); + const Vector_3 abac = cross_product(ab,ac); const double l_ab = CGAL::sqrt(CGAL::to_double(sq_distance(a,b))); - const double y = l_ab * CGAL::to_double(scalar_product(ac,abad)); + const double y = l_ab * CGAL::to_double(scalar_product(abac, abad)); + const double z = CGAL::to_double(scalar_product(cross_product(ab,abac),abad)); - return -FT(std::atan2(y, x) * 180 / CGAL_PI ); + return FT(std::atan2(z, y) * 180 / CGAL_PI ); } }; From 0e3f3a33d1165fa1462f4cabd6973c9a87cb6e4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 29 Nov 2023 12:27:34 +0100 Subject: [PATCH 207/329] test to be fixed --> tetra orientation is 0 --- Kernel_23/test/Kernel_23/test_approximate_dihedral_angle_3.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Kernel_23/test/Kernel_23/test_approximate_dihedral_angle_3.cpp b/Kernel_23/test/Kernel_23/test_approximate_dihedral_angle_3.cpp index dfa703b86f7e..ec352fb21ddb 100644 --- a/Kernel_23/test/Kernel_23/test_approximate_dihedral_angle_3.cpp +++ b/Kernel_23/test/Kernel_23/test_approximate_dihedral_angle_3.cpp @@ -41,7 +41,7 @@ int main() { { { 1, 0, 1}, -45.}, { { 0, 0, 1}, -90.}, { { -1, 0, 1}, -135.}, - { { -1, 0, 0}, -180.}, + //{ { -1, 0, 0}, -180.}, { { -1, 0, -1}, 135.}, { { 0, 0, -1}, 90.}, { { 1, 0, -1}, 45.}, From 5879bb72c63a5a8f0a15a75da806778c6ad20dbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 29 Nov 2023 13:11:21 +0100 Subject: [PATCH 208/329] add comments about the formula --- .../include/CGAL/Kernel/function_objects.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Kernel_23/include/CGAL/Kernel/function_objects.h b/Kernel_23/include/CGAL/Kernel/function_objects.h index ab23552b6821..73f6c672d155 100644 --- a/Kernel_23/include/CGAL/Kernel/function_objects.h +++ b/Kernel_23/include/CGAL/Kernel/function_objects.h @@ -931,6 +931,23 @@ namespace CommonKernelFunctors { const Vector_3 abad = cross_product(ab,ad); const Vector_3 abac = cross_product(ab,ac); + + // The dihedral angle we are interested in is the angle around the edge ab which is + // the same as the angle between the vectors abac and abad + // (abac points inside the tetra abcd if its orientation is positive and outside otherwise) + // In order to increase the numerical precision of the computation, we consider the + // vector abad in the basis defined by (ab, abac, ab^abac). + // In this basis, adab=(ab * abad, abac * abad, [ab^abac] * abad), as all basis vector are orthogonal. + // We have ab * abad = 0, so in the plane (zy) of the new basis + // the dihedral angle is the angle between the z axis and abad + // which is the arctan of y/z (up to normalization) + // (Note that ab^abac is in the plane abc, pointing inside the tetra if its orientation is positive and outside otherwise). + // For the normalization, abad appears in both scalar products + // in the quotient so we can ignore its norm. For the second + // terms of the scalar products, we are left with ab^abac and abac. + // Since ab and abac are orthogonal the sinus of the angle between the vector is 1 + // so the norms are ||ab||.||abac|| vs ||abac||, which is why we have a multiplication by ||ab|| + // in y below. const double l_ab = CGAL::sqrt(CGAL::to_double(sq_distance(a,b))); const double y = l_ab * CGAL::to_double(scalar_product(abac, abad)); const double z = CGAL::to_double(scalar_product(cross_product(ab,abac),abad)); From 4bed66e82f142e02066ade584e27e93f5f136559 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 29 Nov 2023 13:17:10 +0100 Subject: [PATCH 209/329] fix description --- Kernel_23/include/CGAL/Kernel/function_objects.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Kernel_23/include/CGAL/Kernel/function_objects.h b/Kernel_23/include/CGAL/Kernel/function_objects.h index 73f6c672d155..55620fd2ed33 100644 --- a/Kernel_23/include/CGAL/Kernel/function_objects.h +++ b/Kernel_23/include/CGAL/Kernel/function_objects.h @@ -937,11 +937,11 @@ namespace CommonKernelFunctors { // (abac points inside the tetra abcd if its orientation is positive and outside otherwise) // In order to increase the numerical precision of the computation, we consider the // vector abad in the basis defined by (ab, abac, ab^abac). - // In this basis, adab=(ab * abad, abac * abad, [ab^abac] * abad), as all basis vector are orthogonal. - // We have ab * abad = 0, so in the plane (zy) of the new basis - // the dihedral angle is the angle between the z axis and abad + // In this basis, adab=(ab * abad, abac * abad, [ab^abac] * abad), as all basis vectors are orthogonal. + // We have ab * abad = 0, so in the plane (yz) of the new basis + // the dihedral angle is the angle between the y axis and abad // which is the arctan of y/z (up to normalization) - // (Note that ab^abac is in the plane abc, pointing inside the tetra if its orientation is positive and outside otherwise). + // (Note that ab^abac is in the plane abc, pointing outside the tetra if its orientation is positive and inside otherwise). // For the normalization, abad appears in both scalar products // in the quotient so we can ignore its norm. For the second // terms of the scalar products, we are left with ab^abac and abac. From e3e5bcd34448a62c7e8d5e129ea8041dff359560 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 29 Nov 2023 15:25:44 +0100 Subject: [PATCH 210/329] accomodate handle sign face orientation was inversed and somehow matched the bug in the dihedral angle computation function --- .../internal/Surface_mesh_segmentation.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Surface_mesh_segmentation/include/CGAL/Surface_mesh_segmentation/internal/Surface_mesh_segmentation.h b/Surface_mesh_segmentation/include/CGAL/Surface_mesh_segmentation/internal/Surface_mesh_segmentation.h index d0a77fa1a78e..a2a2228f6f59 100644 --- a/Surface_mesh_segmentation/include/CGAL/Surface_mesh_segmentation/internal/Surface_mesh_segmentation.h +++ b/Surface_mesh_segmentation/include/CGAL/Surface_mesh_segmentation/internal/Surface_mesh_segmentation.h @@ -324,8 +324,8 @@ class Surface_mesh_segmentation CGAL_precondition( (! (face(edge,mesh)==boost::graph_traits::null_face())) && (! (face(opposite(edge,mesh),mesh)==boost::graph_traits::null_face())) ); - const Point a = get(vertex_point_pmap,target(edge,mesh)); - const Point b = get(vertex_point_pmap,target(prev(edge,mesh),mesh)); + const Point a = get(vertex_point_pmap,source(edge,mesh)); + const Point b = get(vertex_point_pmap,target(edge,mesh)); const Point c = get(vertex_point_pmap,target(next(edge,mesh),mesh)); const Point d = get(vertex_point_pmap,target(next(opposite(edge,mesh),mesh),mesh)); // As far as I check: if, say, dihedral angle is 5, this returns 175, From df4eed9302f873bf92f30941c9d7de374b69be14 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Wed, 29 Nov 2023 15:27:57 +0100 Subject: [PATCH 211/329] add tests for the dihedral angle --- Data/data/meshes/regular_tetrahedron.off | 11 ++++ .../include/CGAL/Kernel/function_objects.h | 37 +++++++---- .../test_approximate_dihedral_angle_3.cpp | 66 ++++++++++++++----- 3 files changed, 87 insertions(+), 27 deletions(-) create mode 100644 Data/data/meshes/regular_tetrahedron.off diff --git a/Data/data/meshes/regular_tetrahedron.off b/Data/data/meshes/regular_tetrahedron.off new file mode 100644 index 000000000000..08a25ad43b38 --- /dev/null +++ b/Data/data/meshes/regular_tetrahedron.off @@ -0,0 +1,11 @@ +OFF +4 4 0 +-1 0 -0.707107 +1 0 -0.707107 +0 -1 0.707107 +0 1 0.707107 +3 0 1 2 +3 0 3 1 +3 0 2 3 +3 1 3 2 + diff --git a/Kernel_23/include/CGAL/Kernel/function_objects.h b/Kernel_23/include/CGAL/Kernel/function_objects.h index 55620fd2ed33..6bc98833dab4 100644 --- a/Kernel_23/include/CGAL/Kernel/function_objects.h +++ b/Kernel_23/include/CGAL/Kernel/function_objects.h @@ -932,22 +932,35 @@ namespace CommonKernelFunctors { const Vector_3 abad = cross_product(ab,ad); const Vector_3 abac = cross_product(ab,ac); - // The dihedral angle we are interested in is the angle around the edge ab which is - // the same as the angle between the vectors abac and abad + // The dihedral angle we are interested in is the angle around the oriented + // edge ab which is the same (in absolute value) as the angle between the + // vectors ab^ac and ab^ad (cross-products). // (abac points inside the tetra abcd if its orientation is positive and outside otherwise) - // In order to increase the numerical precision of the computation, we consider the - // vector abad in the basis defined by (ab, abac, ab^abac). - // In this basis, adab=(ab * abad, abac * abad, [ab^abac] * abad), as all basis vectors are orthogonal. - // We have ab * abad = 0, so in the plane (yz) of the new basis - // the dihedral angle is the angle between the y axis and abad - // which is the arctan of y/z (up to normalization) - // (Note that ab^abac is in the plane abc, pointing outside the tetra if its orientation is positive and inside otherwise). + // + // We consider the vector abad in the basis defined by the three vectors + // (, , ) + // where denote the normalized vector u/|u|. + // + // In this orthonormal basis, the vector adab has the coordinates + // x = * abad + // y = * abad + // z = * abad + // We have x == 0, because abad and ab are orthogonal, and then abad is in + // the plane (yz) of the new basis. + // + // In that basic, the dihedral angle is the angle between the y axis and abad + // which is the arctan of y/z, or atan2(z, y). + // + // (Note that ab^abac is in the plane abc, pointing outside the tetra if + // its orientation is positive and inside otherwise). + // // For the normalization, abad appears in both scalar products // in the quotient so we can ignore its norm. For the second // terms of the scalar products, we are left with ab^abac and abac. - // Since ab and abac are orthogonal the sinus of the angle between the vector is 1 - // so the norms are ||ab||.||abac|| vs ||abac||, which is why we have a multiplication by ||ab|| - // in y below. + // Since ab and abac are orthogonal, the sinus of the angle between the + // two vectors is 1. + // So the norms are |ab|.|abac| vs |abac|, which is why we have a + // multiplication by |ab| in y below. const double l_ab = CGAL::sqrt(CGAL::to_double(sq_distance(a,b))); const double y = l_ab * CGAL::to_double(scalar_product(abac, abad)); const double z = CGAL::to_double(scalar_product(cross_product(ab,abac),abad)); diff --git a/Kernel_23/test/Kernel_23/test_approximate_dihedral_angle_3.cpp b/Kernel_23/test/Kernel_23/test_approximate_dihedral_angle_3.cpp index ec352fb21ddb..9ad255befacc 100644 --- a/Kernel_23/test/Kernel_23/test_approximate_dihedral_angle_3.cpp +++ b/Kernel_23/test/Kernel_23/test_approximate_dihedral_angle_3.cpp @@ -29,29 +29,65 @@ void sign_test() assert( CGAL::approximate_dihedral_angle(d, c, a, b) < 0); } +auto almost_equal_angle(double a, double b) { + return std::min(std::abs(a - b), std::abs(a + 360 - b)) < 0.1; +} + +void test_regular_tetrahedron() +{ + auto half_root_of_2 = std::sqrt(2) / 2; + + // Regular tetrahedron + Point_3 a{ -1, 0, -half_root_of_2}; + Point_3 b{ 1, 0, -half_root_of_2}; + Point_3 c{ 0, 1, half_root_of_2}; + Point_3 d{ 0, -1, half_root_of_2}; + assert(orientation(a, b, c, d) == CGAL::POSITIVE); + assert(almost_equal_angle(CGAL::approximate_dihedral_angle(a, b, c, d), 70.5288)); +} + int main() { + std::cout.precision(17); sign_test(); + test_regular_tetrahedron(); Point_3 a = {0, 0, 0}; - Point_3 b = {0, 1, 0}; - Point_3 c = {1, 0, 0}; + Point_3 b = {0, -1, 0}; // ab is oriented so that it sees the plan xz positively. + [[maybe_unused]] Point_3 c = {1, 0, 0}; + // c can be any point in the half-plane xy, with x>0 const query queries[] = { { { 1, 0, 0}, 0.}, - { { 1, 0, 1}, -45.}, - { { 0, 0, 1}, -90.}, - { { -1, 0, 1}, -135.}, - //{ { -1, 0, 0}, -180.}, - { { -1, 0, -1}, 135.}, - { { 0, 0, -1}, 90.}, - { { 1, 0, -1}, 45.}, + { { 1, 0, 1}, 45.}, + { { 0, 0, 1}, 90.}, + { { -1, 0, 1}, 135.}, + { { -1, 0, 0}, 180.}, + { { -1, 0, -1}, -135.}, + { { 0, 0, -1}, -90.}, + { { 1, 0, -1}, -45.}, }; - for(auto query: queries) { - const auto& expected = query.expected_angle; - const auto& p = query.p; - auto approx = CGAL::approximate_dihedral_angle(a, b, c, p); - std::cout << approx << " -- " << expected << '\n'; - assert( std::abs(approx - expected) < 0.1 ); + auto cnt = 0u; + for(double yc = -10; yc < 10; yc += 0.1) { + Point_3 c{1, yc, 0}; + // std::cout << "c = " << c << '\n'; + for(const auto& query : queries) { + for(double yp = -10; yp < 10; yp += 0.3) { + const auto& expected = query.expected_angle; + const Point_3 p{query.p.x(), yp, query.p.z()}; + // std::cout << "p = " << p << '\n'; + auto approx = CGAL::approximate_dihedral_angle(a, b, c, p); + // std::cout << approx << " -- " << expected << '\n'; + if(!almost_equal_angle(approx, expected)) { + std::cout << "ERROR:\n"; + std::cout << "CGAL::approximate_dihedral_angle(" << a << ", " << b << ", " << c << ", " << p << ") = " << approx << '\n'; + std::cout << "expected: " << expected << '\n'; + return 1; + } + ++cnt; + } + } } + std::cout << "OK (" << cnt << " tests)\n"; + assert(cnt > 10000); } From 46877d41341d7426ec67aeded87530988a882299 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Wed, 29 Nov 2023 15:34:36 +0100 Subject: [PATCH 212/329] fix two typos --- Kernel_23/include/CGAL/Kernel/function_objects.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Kernel_23/include/CGAL/Kernel/function_objects.h b/Kernel_23/include/CGAL/Kernel/function_objects.h index 6bc98833dab4..7848f55e94c8 100644 --- a/Kernel_23/include/CGAL/Kernel/function_objects.h +++ b/Kernel_23/include/CGAL/Kernel/function_objects.h @@ -945,10 +945,10 @@ namespace CommonKernelFunctors { // x = * abad // y = * abad // z = * abad - // We have x == 0, because abad and ab are orthogonal, and then abad is in + // We have x == 0, because abad and ab are orthogonal, and thus abad is in // the plane (yz) of the new basis. // - // In that basic, the dihedral angle is the angle between the y axis and abad + // In that basis, the dihedral angle is the angle between the y axis and abad // which is the arctan of y/z, or atan2(z, y). // // (Note that ab^abac is in the plane abc, pointing outside the tetra if From 7b7918947ad3e99b3d046013da409a71a3ff48e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 29 Nov 2023 16:54:43 +0100 Subject: [PATCH 213/329] Fix bbox initialization --- .../Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp index db6845db100c..91390c759ddb 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Alpha_wrap_3/Alpha_wrap_3_plugin.cpp @@ -646,6 +646,13 @@ public Q_SLOTS: std::cout << segments.size() << " edges" << std::endl; std::cout << points.size() << " points" << std::endl; + if(!triangles.empty()) + m_wrap_bbox = triangles.front().bbox(); + else if(!segments.empty()) + m_wrap_bbox = segments.front().bbox(); + else if(!points.empty()) + m_wrap_bbox = points.front().bbox(); + for(const Kernel::Triangle_3& tr : triangles) m_wrap_bbox += tr.bbox(); for(const Kernel::Segment_3& sg : segments) From bef03396715f48b90cdbd5ab414a9817334e16db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 29 Nov 2023 17:43:17 +0100 Subject: [PATCH 214/329] fixes for edges entirely on the isoline --- .../refine_mesh_at_isolevel.h | 27 +++++--- .../Polygon_mesh_processing/CMakeLists.txt | 1 + .../test_isolevel_refinement.cpp | 68 +++++++++++++++++++ 3 files changed, 86 insertions(+), 10 deletions(-) create mode 100644 Polygon_mesh_processing/test/Polygon_mesh_processing/test_isolevel_refinement.cpp diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h index 293d791a47cd..2c91a8ad5efe 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h @@ -93,27 +93,24 @@ void refine_mesh_at_isolevel(PolygonMesh& pm, std::unordered_map > faces_to_split; std::vector to_split; + std::unordered_set vertices_on_isoline; for (edge_descriptor e : edges(pm)) { vertex_descriptor src = source(e, pm), tgt = target(e, pm); + if (get(value_map, src)==isovalue) { - for (halfedge_descriptor h : halfedges_around_source(halfedge(e, pm), pm)) + vertices_on_isoline.insert(src); + if (get(value_map, tgt)==isovalue) { - face_descriptor f = face(h, pm); - if (f!=boost::graph_traits::null_face()) - faces_to_split[f].push_back(opposite(h, pm)); + put(ecm, e, true); // special case for faces entirely on an isovalue + continue; } continue; } if (get(value_map, tgt)==isovalue) { - for (halfedge_descriptor h : halfedges_around_target(halfedge(e, pm), pm)) - { - face_descriptor f = face(h, pm); - if (f!=boost::graph_traits::null_face()) - faces_to_split[f].push_back(h); - } + vertices_on_isoline.insert(tgt); continue; } if ( (get(value_map, tgt) < isovalue) != (get(value_map, src) < isovalue) ) @@ -140,6 +137,16 @@ void refine_mesh_at_isolevel(PolygonMesh& pm, faces_to_split[f].push_back(hnew); } + for (vertex_descriptor vh : vertices_on_isoline) + { + for (halfedge_descriptor h : halfedges_around_target(vh, pm)) + { + face_descriptor f = face(h, pm); + if (f!=boost::graph_traits::null_face()) + faces_to_split[f].push_back(h); + } + } + for (const auto& p : faces_to_split) { if(p.second.size()!=2) continue; diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt b/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt index eb9b98cbe593..f2e13399444a 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt @@ -65,6 +65,7 @@ create_single_source_cgal_program("triangulate_hole_with_cdt_2_test.cpp") create_single_source_cgal_program("test_pmp_polyhedral_envelope.cpp") create_single_source_cgal_program("test_pmp_np_function.cpp") create_single_source_cgal_program("test_degenerate_pmp_clip_split_corefine.cpp") +create_single_source_cgal_program("test_isolevel_refinement.cpp") # create_single_source_cgal_program("test_pmp_repair_self_intersections.cpp") find_package(Eigen3 3.2.0 QUIET) #(requires 3.2.0 or greater) diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_isolevel_refinement.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_isolevel_refinement.cpp new file mode 100644 index 000000000000..9e07c8314352 --- /dev/null +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_isolevel_refinement.cpp @@ -0,0 +1,68 @@ +#include +#include + +#include +#include + +#include +#include + +typedef CGAL::Simple_cartesian Kernel; +typedef Kernel::Point_3 Point_3; +typedef CGAL::Surface_mesh Triangle_mesh; + +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::edge_descriptor edge_descriptor; + +typedef Triangle_mesh::Property_map Vertex_distance_map; + +int main() +{ + const std::string filename = CGAL::data_file_path("meshes/elephant.off"); + + Triangle_mesh tm; + if(!CGAL::IO::read_polygon_mesh(filename, tm) || + CGAL::is_empty(tm) || !CGAL::is_triangle_mesh(tm)) + { + std::cerr << "Invalid input file." << std::endl; + return EXIT_FAILURE; + } + //property map for the distance values to the source set + Vertex_distance_map vertex_distance = tm.add_property_map("v:distance", 5).first; + std::vector zero_vids={ + /*a closed polyline*/ 2144,145,2690,1752,339,215,1395,338,77,2145,2052,2054,343,1936,22,1751,214,1499,142,358,2694,1750,301,65,59,2650,2060,205,2651,2061,2490,1939,898,13,298, + /*two adjacent triangles*/ 532, 185, 534, 2735, + /*another patch with missing crossed edges*/134,73,1883,2533,72,532,185,131,534 + }; + + std::vector minus_vids = {132, 364}; + + for (int i : zero_vids) + put(vertex_distance, Triangle_mesh::Vertex_index(i), 0); + for (int i : minus_vids) + put(vertex_distance, Triangle_mesh::Vertex_index(i), -5); + + // property map to flag new cut edge added in the mesh + auto ecm = tm.add_property_map("e:is_constrained", 0).first; + + CGAL::Polygon_mesh_processing::refine_mesh_at_isolevel(tm, vertex_distance, 0, CGAL::parameters::edge_is_constrained_map(ecm)); + + std::ofstream debug("edges.polylines.txt"); + for (Triangle_mesh::Edge_index e : edges(tm)) + if (get(ecm, e)) + debug << "2 " << tm.point(source(e, tm)) << " " << tm.point(target(e, tm)) << "\n"; + debug.close(); + + // split the mesh in connected components bounded by the isocurves + std::vector edges_split; + CGAL::Polygon_mesh_processing::split_connected_components(tm, edges_split, CGAL::parameters::edge_is_constrained_map(ecm)); + + // export each submesh in a file + for(std::size_t i=0; i Date: Thu, 30 Nov 2023 09:20:53 +0100 Subject: [PATCH 215/329] protect from macro substitution Co-authored-by: Andreas Fabri --- Kernel_23/test/Kernel_23/test_approximate_dihedral_angle_3.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Kernel_23/test/Kernel_23/test_approximate_dihedral_angle_3.cpp b/Kernel_23/test/Kernel_23/test_approximate_dihedral_angle_3.cpp index 9ad255befacc..dc3ccdaf9899 100644 --- a/Kernel_23/test/Kernel_23/test_approximate_dihedral_angle_3.cpp +++ b/Kernel_23/test/Kernel_23/test_approximate_dihedral_angle_3.cpp @@ -30,7 +30,7 @@ void sign_test() } auto almost_equal_angle(double a, double b) { - return std::min(std::abs(a - b), std::abs(a + 360 - b)) < 0.1; + return (std::min)(std::abs(a - b), std::abs(a + 360 - b)) < 0.1; } void test_regular_tetrahedron() From fd37bc3a16070374bfbeaf83ab5e34336a0dff77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 30 Nov 2023 09:25:04 +0100 Subject: [PATCH 216/329] add missing include --- .../CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h index 2c91a8ad5efe..eb52b7816679 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h @@ -18,6 +18,8 @@ #include #include +#include + namespace CGAL { namespace Polygon_mesh_processing { From a207e3af2e118400b15f0946dc06606a814fc7bc Mon Sep 17 00:00:00 2001 From: Sebastien Loriot Date: Thu, 30 Nov 2023 09:35:56 +0100 Subject: [PATCH 217/329] wrong header Co-authored-by: Andreas Fabri --- .../CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h index eb52b7816679..cc0738a365bb 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h @@ -17,7 +17,8 @@ #include #include - +#include +#include #include namespace CGAL { From 8a4c99f19b4942c0bd6e8f1083004013c9c58dee Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 30 Nov 2023 09:53:04 +0100 Subject: [PATCH 218/329] remove unused variables now there is only one possible sizing definition left, they have become useless --- Mesh_3/test/Mesh_3/test_mesh_criteria_creation.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/Mesh_3/test/Mesh_3/test_mesh_criteria_creation.cpp b/Mesh_3/test/Mesh_3/test_mesh_criteria_creation.cpp index fb74fa720e4b..8436b51c64d9 100644 --- a/Mesh_3/test/Mesh_3/test_mesh_criteria_creation.cpp +++ b/Mesh_3/test/Mesh_3/test_mesh_criteria_creation.cpp @@ -93,7 +93,6 @@ int main() cp(tr.point(ch, k+3)))); FT facet_size_ok = radius_facet*FT(10); - FT facet_size_nok = radius_facet/FT(10); Mc fc1(facet_size = facet_size_ok); assert( ! fc1.facet_criteria_object()(tr, f) ); @@ -134,7 +133,6 @@ int main() cp(tr.point(ch, 3)))); FT cell_size_ok = radius_cell*FT(10); - FT cell_size_nok = radius_cell/FT(10); Mc cc1(cell_size = cell_size_ok); assert( ! cc1.cell_criteria_object()(tr, ch) ); From c7ab2ba750bdad57977d79cb652f0df019cb58eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 30 Nov 2023 09:50:40 +0100 Subject: [PATCH 219/329] fix include --- .../CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h index cc0738a365bb..d86b470a2605 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine_mesh_at_isolevel.h @@ -17,9 +17,9 @@ #include #include + #include #include -#include namespace CGAL { namespace Polygon_mesh_processing { From 6ad37cd2e6e7526f7cd562db10c91e19036d3b05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Thu, 30 Nov 2023 11:37:48 +0100 Subject: [PATCH 220/329] Enable pocket purging by default Reasoning is: this is what users expect. --- .../include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index 5adf81dc443a..727691a80218 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -283,8 +283,9 @@ class Alpha_wrapper_3 // initial cavities, if used). // // -- Warning -- - // If you refine or pause while removing pockets, you will get valid but different wraps. - const bool keep_inner_ccs = choose_parameter(get_parameter(in_np, internal_np::keep_inner_connected_components), true); + // Pockets of "outside" cells will be purged even if the wrapping is interrupted (and + // this option is enabled). + const bool keep_inner_ccs = choose_parameter(get_parameter(in_np, internal_np::keep_inner_connected_components), false); // This parameter enables avoiding recomputing the triangulation from scratch when wrapping // the same input for multiple values of alpha (and typically the same offset values). From fae9bcd5f1d39a090aeb97f790e21abd9bb10154 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Thu, 30 Nov 2023 11:38:18 +0100 Subject: [PATCH 221/329] Add some comments --- .../include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h index 727691a80218..d6ca4fb356c3 100644 --- a/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h +++ b/Alpha_wrap_3/include/CGAL/Alpha_wrap_3/internal/Alpha_wrap_3.h @@ -94,6 +94,7 @@ struct Wrapping_default_visitor template void on_flood_fill_begin(const AlphaWrapper&) { } + // Whether the flood filling process should continue template constexpr bool go_further(const Wrapper&) { return true; } @@ -277,6 +278,10 @@ class Alpha_wrapper_3 // Whether or not some cells should be reflagged as "inside" after the refinement+carving loop // as ended, as to ensure that the result is not only combinatorially manifold, but also // geometrically manifold. + // + // -- Warning -- + // Manifoldness postprocessing will be performed even if the wrapping is interrupted (and + // this option is enabled). const bool do_enforce_manifoldness = choose_parameter(get_parameter(in_np, internal_np::do_enforce_manifoldness), true); // Whether to keep pockets of "outside" cells that are not connected to the exterior (or to the From 642ea59de7133f7d4847aab74e0d68c50e0354bf Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Fri, 1 Dec 2023 10:21:57 +0100 Subject: [PATCH 222/329] add tooltip for bounds of approximation value --- Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp | 2 ++ 1 file changed, 2 insertions(+) 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 b75f648be33e..6056951eba95 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp @@ -610,6 +610,8 @@ void Mesh_3_plugin::mesh_3(const Mesh_type mesh_type, ui.approx->setRange(diag * 10e-7, // min diag); // max ui.approx->setValue(approx); + ui.approx->setToolTip(tr("Approximation error: in [%1; %2]") + .arg(diag * 10e-7).arg(diag)); ui.protect->setEnabled(features_protection_available); ui.protect->setChecked(features_protection_available); From 1ca77d32afa89ef18c065dce44dc95e39d662f10 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Fri, 1 Dec 2023 10:23:44 +0100 Subject: [PATCH 223/329] fix DoubleEdit with Qt6 - let the user add as many digits as wanted (using -1 in setRange) - use standard notation, not scientific (which was the default) - comment QDoubleValidator::fixup that for some reason blocks the edition of the field --- Polyhedron/demo/Polyhedron/CGAL_double_edit.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/CGAL_double_edit.cpp b/Polyhedron/demo/Polyhedron/CGAL_double_edit.cpp index a50aef4180b2..c452186e1fa5 100644 --- a/Polyhedron/demo/Polyhedron/CGAL_double_edit.cpp +++ b/Polyhedron/demo/Polyhedron/CGAL_double_edit.cpp @@ -9,13 +9,14 @@ class DoubleValidator : public QDoubleValidator : QDoubleValidator(parent) { setLocale(QLocale::C); + setNotation(QDoubleValidator::StandardNotation); } void fixup ( QString & input ) const { input.replace(".", locale().decimalPoint()); input.replace(",", locale().decimalPoint()); - QDoubleValidator::fixup(input); +// QDoubleValidator::fixup(input); } QValidator::State validate ( QString & input, int & pos ) const { @@ -59,7 +60,7 @@ class DoubleValidator : public QDoubleValidator void DoubleEdit::setRange(double rmin, double rmax) { - this->validator->setRange(rmin, rmax, this->validator->decimals()); + this->validator->setRange(rmin, rmax, -1); } double DoubleEdit::getValue() From 3fc14d8d56e4fb2649fc63a5173e8c2042276d54 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Fri, 1 Dec 2023 11:22:39 +0100 Subject: [PATCH 224/329] use QDoubleValidator::fixup() in DoubleEdit::fixup() with this version the user can write with scientific notation or standard notation, using . or , Note that when input is invalid, value() returns 0 --- Polyhedron/demo/Polyhedron/CGAL_double_edit.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/CGAL_double_edit.cpp b/Polyhedron/demo/Polyhedron/CGAL_double_edit.cpp index c452186e1fa5..9f6f4c9b5a27 100644 --- a/Polyhedron/demo/Polyhedron/CGAL_double_edit.cpp +++ b/Polyhedron/demo/Polyhedron/CGAL_double_edit.cpp @@ -9,18 +9,16 @@ class DoubleValidator : public QDoubleValidator : QDoubleValidator(parent) { setLocale(QLocale::C); - setNotation(QDoubleValidator::StandardNotation); } void fixup ( QString & input ) const { input.replace(".", locale().decimalPoint()); input.replace(",", locale().decimalPoint()); -// QDoubleValidator::fixup(input); + QDoubleValidator::fixup(input); } QValidator::State validate ( QString & input, int & pos ) const { - fixup(input); return QDoubleValidator::validate(input, pos); } }; From f9e405f00454c72c7aff02dda0d232e4c5dfb0ae Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Fri, 1 Dec 2023 11:20:12 +0000 Subject: [PATCH 225/329] Adress warning --- .../Spatial_searching/searching_triangulation_vertices.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Spatial_searching/examples/Spatial_searching/searching_triangulation_vertices.cpp b/Spatial_searching/examples/Spatial_searching/searching_triangulation_vertices.cpp index a045313f3f56..0dfd38e71e1e 100644 --- a/Spatial_searching/examples/Spatial_searching/searching_triangulation_vertices.cpp +++ b/Spatial_searching/examples/Spatial_searching/searching_triangulation_vertices.cpp @@ -19,7 +19,7 @@ struct Project { typedef Vertex_handle argument_type; typedef const Point_3& Point; typedef Point result_type; - const Point& operator()( Vertex_handle v) const { return v->point(); } + Point operator()( Vertex_handle v) const { return v->point(); } }; From 07f2f2912bc177a72ea229647a575fe0f10f8fff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Fri, 1 Dec 2023 22:08:15 +0100 Subject: [PATCH 226/329] Fix exit codes in benchmark scripts --- .../Robustness/compute_robustness_benchmark_data.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Alpha_wrap_3/benchmark/Alpha_wrap_3/Robustness/compute_robustness_benchmark_data.py b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Robustness/compute_robustness_benchmark_data.py index 9def2bb6cc16..afd8d6912ab2 100755 --- a/Alpha_wrap_3/benchmark/Alpha_wrap_3/Robustness/compute_robustness_benchmark_data.py +++ b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Robustness/compute_robustness_benchmark_data.py @@ -56,18 +56,18 @@ def compute_robustness_benchmark_data(execname, filename, alpha, max_time): for output_line in output.split("\n"): if output_line == "Command terminated by signal 11": - exit_code = 9 + exit_code = 10 continue elif output_line == "Command terminated by signal 6": - exit_code = 10 + exit_code = 11 continue elif output_line == "Command terminated by signal 8": - exit_code = 11 + exit_code = 12 continue except subprocess.TimeoutExpired: os.killpg(os.getpgid(proc.pid), signal.SIGTERM) - exit_code = 12 + exit_code = 13 output = "process ran too long" print(exit_codes[exit_code]) From ac3f6e689228562f6f814a1acb1e80270a8dc281 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Mon, 4 Dec 2023 13:09:22 +0100 Subject: [PATCH 227/329] improve the Mesh_3 log in demo --- .../Mesh_3/Mesh_3_plugin_cgal_code.cpp | 7 ++- .../Polyhedron/Plugins/Mesh_3/Mesh_function.h | 48 +++++++++++++------ 2 files changed, 40 insertions(+), 15 deletions(-) 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 abc82f150339..d48aef5bb1f9 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 @@ -134,6 +134,8 @@ Meshing_thread* cgal_code_mesh_3(QList pMeshes, param.manifold = manifold; param.protect_features = protect_features || protect_borders; param.use_sizing_field_with_aabb_tree = polylines.empty() && protect_features; + param.image_3_ptr = nullptr; + param.weights_ptr = nullptr; typedef ::Mesh_function Mesh_function; @@ -237,6 +239,8 @@ Meshing_thread* cgal_code_mesh_3(const QList pMeshes, param.manifold = manifold; param.protect_features = protect_features || protect_borders; param.use_sizing_field_with_aabb_tree = protect_features; + param.image_3_ptr = nullptr; + param.weights_ptr = nullptr; typedef ::Mesh_function Mesh_function; @@ -292,7 +296,8 @@ Meshing_thread* cgal_code_mesh_3(const Implicit_function_interface* pfunction, param.manifold = manifold; param.detect_connected_components = false; // to avoid random values // in the debug displays - + param.image_3_ptr = nullptr; + param.weights_ptr = nullptr; typedef ::Mesh_function Mesh_function; diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_function.h b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_function.h index dfd31aadd849..8bc5a6c3ff68 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_function.h +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_function.h @@ -138,20 +138,40 @@ QStringList Mesh_parameters:: log() const { - return QStringList() - << QString("edge max size: %1").arg(edge_sizing) - << QString("edge min size: %1").arg(edge_min_sizing) - << QString("facet min angle: %1").arg(facet_angle) - << QString("facet max size: %1").arg(facet_sizing) - << QString("facet min size: %1").arg(facet_min_sizing) - << QString("facet approx error: %1").arg(facet_approx) - << QString("tet shape (radius-edge): %1").arg(tet_shape) - << QString("tet max size: %1").arg(tet_sizing) - << QString("tet min size: %1").arg(tet_min_sizing) - << QString("detect connected components: %1") - .arg(detect_connected_components) - << QString("use weights: %1").arg(weights_ptr != nullptr) - << QString("protect features: %1").arg(protect_features); + QStringList res("Mesh criteria"); + + // doubles + if(edge_sizing > 0) + res << QString("edge max size: %1").arg(edge_sizing); + if(edge_min_sizing > 0) + res << QString("edge min size: %1").arg(edge_min_sizing); + if(facet_angle > 0) + res << QString("facet min angle: %1").arg(facet_angle); + if(facet_sizing > 0) + res << QString("facet max size: %1").arg(facet_sizing); + if(facet_min_sizing > 0) + res << QString("facet min size: %1").arg(facet_min_sizing); + if(facet_approx > 0) + res << QString("facet approx error: %1").arg(facet_approx); + if(tet_shape > 0) + res << QString("tet shape (radius-edge): %1").arg(tet_shape); + if(tet_sizing > 0) + res << QString("tet max size: %1").arg(tet_sizing); + if(tet_min_sizing > 0) + res << QString("tet min size: %1").arg(tet_min_sizing); + + // booleans + res << QString("protect features: %1").arg(protect_features); + if(image_3_ptr != nullptr) + { + res << QString("detect connected components: %1") + .arg(detect_connected_components); + res << QString("use weights: %1").arg(weights_ptr != nullptr); + } + res << QString("use aabb tree: %1").arg(use_sizing_field_with_aabb_tree); + res << QString("manifold: %1").arg(manifold); + + return res; } From 9c2eba3320a98eebe5e120e840043e122c1da3fb Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Mon, 4 Dec 2023 14:46:14 +0100 Subject: [PATCH 228/329] simplify example code using Boolean_property_map --- .../tetrahedral_remeshing_with_features.cpp | 65 +++---------------- 1 file changed, 10 insertions(+), 55 deletions(-) diff --git a/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/tetrahedral_remeshing_with_features.cpp b/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/tetrahedral_remeshing_with_features.cpp index 032cca7e1d30..4cb187d96f26 100644 --- a/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/tetrahedral_remeshing_with_features.cpp +++ b/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/tetrahedral_remeshing_with_features.cpp @@ -12,59 +12,16 @@ #include "tetrahedral_remeshing_generate_input.h" -typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +using K = CGAL::Exact_predicates_inexact_constructions_kernel; -typedef CGAL::Tetrahedral_remeshing::Remeshing_triangulation_3 Remeshing_triangulation; +using Remeshing_triangulation = CGAL::Tetrahedral_remeshing::Remeshing_triangulation_3; +using Point = Remeshing_triangulation::Point; +using Vertex_handle = Remeshing_triangulation::Vertex_handle; -typedef Remeshing_triangulation::Point Point; -typedef Remeshing_triangulation::Vertex_handle Vertex_handle; -typedef Remeshing_triangulation::Cell_handle Cell_handle; -typedef Remeshing_triangulation::Edge Edge; +using Vertex_pair = std::pair; +using Constraints_set = std::unordered_set>; +using Constraints_pmap = CGAL::Boolean_property_map; -class Constrained_edges_property_map -{ -public: - typedef bool value_type; - typedef bool reference; - typedef std::pair key_type; - typedef boost::read_write_property_map_tag category; - -private: - std::unordered_set>* m_set_ptr; - -public: - Constrained_edges_property_map() - : m_set_ptr(nullptr) - {} - Constrained_edges_property_map(std::unordered_set>* set_) - : m_set_ptr(set_) - {} - -public: - friend void put(Constrained_edges_property_map& map, - const key_type& k, - const bool b) - { - assert(map.m_set_ptr != nullptr); - assert(k.first < k.second); - if (b) map.m_set_ptr->insert(k); - else map.m_set_ptr->erase(k); - } - - friend value_type get(const Constrained_edges_property_map& map, - const key_type& k) - { - assert(map.m_set_ptr != nullptr); - assert(k.first < k.second); - return (map.m_set_ptr->count(k) > 0); - } -}; - -void set_subdomain(Remeshing_triangulation& tr, const int index) -{ - for (auto cit : tr.finite_cell_handles()) - cit->set_subdomain_index(index); -} int main(int argc, char* argv[]) { @@ -73,16 +30,14 @@ int main(int argc, char* argv[]) const int nbv = (argc > 3) ? atoi(argv[3]) : 500; Remeshing_triangulation t3; - typedef std::pair Vertex_pair; - std::unordered_set> constraints; + Constraints_set constraints; CGAL::Tetrahedral_remeshing::generate_input_cube(nbv, t3, constraints); make_constraints_from_cube_edges(t3, constraints); CGAL::tetrahedral_isotropic_remeshing(t3, target_edge_length, - CGAL::parameters::edge_is_constrained_map( - Constrained_edges_property_map(&constraints)) - .number_of_iterations(nb_iter)); + CGAL::parameters::edge_is_constrained_map(Constraints_pmap(constraints)) + .number_of_iterations(nb_iter)); return EXIT_SUCCESS; } From ab2afb24eaea6c625917e18e6ed7d32cae391bc4 Mon Sep 17 00:00:00 2001 From: albert-github Date: Mon, 4 Dec 2023 16:34:45 +0100 Subject: [PATCH 229/329] Incorrect link to "Perturbations for Delaunay and weighted Delaunay 3D Triangulations" The link for the document "Perturbations for Delaunay and weighted Delaunay 3D Triangulations" was in #7781 (based on #7762) changed but it is not available at he address "https://theses.hal.science/inria-00560388/" but at "https://hal.science/inria-00560388/". (The other changes were correct). Found in Triangulation_3/citelist.html --- Documentation/doc/biblio/cgal_manual.bib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/doc/biblio/cgal_manual.bib b/Documentation/doc/biblio/cgal_manual.bib index e16202c69ddf..51dfb1090046 100644 --- a/Documentation/doc/biblio/cgal_manual.bib +++ b/Documentation/doc/biblio/cgal_manual.bib @@ -778,7 +778,7 @@ @article{cgal:dt-pvrdr-06 , volume = 44 , year = 2011 , pages = "160--168" -, url = "https://theses.hal.science/inria-00560388/" +, url = "https://hal.science/inria-00560388/" , doi = "10.1016/j.comgeo.2010.09.010" } From b87ecf7aab7ec43fbe0869709c4f7df9d2804a40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 5 Dec 2023 09:06:47 +0100 Subject: [PATCH 230/329] prevent out-of-bound warnings --- TDS_3/include/CGAL/Triangulation_utils_3.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/TDS_3/include/CGAL/Triangulation_utils_3.h b/TDS_3/include/CGAL/Triangulation_utils_3.h index 8b99c725a65f..d656b5e75c55 100644 --- a/TDS_3/include/CGAL/Triangulation_utils_3.h +++ b/TDS_3/include/CGAL/Triangulation_utils_3.h @@ -35,10 +35,10 @@ struct Triangulation_utils_base_3 template < class T > const char Triangulation_utils_base_3::tab_next_around_edge[4][4] = { - {5, 2, 3, 1}, - {3, 5, 0, 2}, - {1, 3, 5, 0}, - {2, 0, 1, 5} }; + {-0, 2, 3, 1}, + {3, -0, 0, 2}, + {1, 3, -0, 0}, + {2, 0, 1, -0} }; template < class T > const int Triangulation_utils_base_3::tab_vertex_triple_index[4][3] = { From a66999d932d55fd8db0295e8b4f2e26f599b614f Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Tue, 5 Dec 2023 11:10:19 +0100 Subject: [PATCH 231/329] fill the edge_is_constrained_map based on the c3t3 complex edges --- .../include/CGAL/tetrahedral_remeshing.h | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/Tetrahedral_remeshing/include/CGAL/tetrahedral_remeshing.h b/Tetrahedral_remeshing/include/CGAL/tetrahedral_remeshing.h index 8a8ebe925b3b..133d06a39183 100644 --- a/Tetrahedral_remeshing/include/CGAL/tetrahedral_remeshing.h +++ b/Tetrahedral_remeshing/include/CGAL/tetrahedral_remeshing.h @@ -316,15 +316,37 @@ void tetrahedral_isotropic_remeshing( template + typename CurveIndex, + typename NamedParameters = parameters::Default_named_parameters> CGAL::Triangulation_3 convert_to_triangulation_3( - CGAL::Mesh_complex_3_in_triangulation_3 c3t3) + CGAL::Mesh_complex_3_in_triangulation_3 c3t3, + const NamedParameters& np = parameters::default_values()) { using GT = typename Tr::Geom_traits; using TDS = typename Tr::Triangulation_data_structure; + using Vertex_handle = typename Tr::Vertex_handle; + using Edge_vv = std::pair; + using Default_pmap = Constant_property_map; + using ECMap = typename internal_np::Lookup_named_param_def < + internal_np::edge_is_constrained_t, + NamedParameters, + Default_pmap + >::type; + ECMap ecmap = choose_parameter(get_parameter(np, internal_np::edge_is_constrained), + Default_pmap(false)); + + if (!std::is_same_v) + { + for (auto e : c3t3.edges_in_complex()) + { + const Edge_vv evv{e.first->vertex(e.second), e.first->vertex(e.third)}; + put(ecmap, evv, true); + } + } + CGAL::Triangulation_3 tr; tr.swap(c3t3.triangulation()); return tr; From 4ad8027db5b60c052c7a5e3057dd5187bd7cb7bf Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Tue, 5 Dec 2023 11:16:06 +0100 Subject: [PATCH 232/329] add example using edge_is_constrained_map in convert_to_triangulation_3 --- .../Tetrahedral_remeshing.txt | 6 ++ .../doc/Tetrahedral_remeshing/examples.txt | 1 + .../Tetrahedral_remeshing/CMakeLists.txt | 4 + ...dral_domain_with_features_from_complex.cpp | 96 +++++++++++++++++++ 4 files changed, 107 insertions(+) create mode 100644 Tetrahedral_remeshing/examples/Tetrahedral_remeshing/mesh_and_remesh_polyhedral_domain_with_features_from_complex.cpp diff --git a/Tetrahedral_remeshing/doc/Tetrahedral_remeshing/Tetrahedral_remeshing.txt b/Tetrahedral_remeshing/doc/Tetrahedral_remeshing/Tetrahedral_remeshing.txt index 0500556f0746..e7b717fd001e 100644 --- a/Tetrahedral_remeshing/doc/Tetrahedral_remeshing/Tetrahedral_remeshing.txt +++ b/Tetrahedral_remeshing/doc/Tetrahedral_remeshing/Tetrahedral_remeshing.txt @@ -103,6 +103,12 @@ setting the named parameter `remesh_boundaries` to `false`. \cgalExample{Tetrahedral_remeshing/tetrahedral_remeshing_with_features.cpp } +It is also possible to define the polyline features as the ones +stored as complex edges in a `Mesh_complex_3_in_triangulation_3` +(e.g. generated by the \ref PkgMesh3 package mesh generation algorithms). + +\cgalExample{Tetrahedral_remeshing/tetrahedral_remeshing_with_features_from_complex.cpp } + \subsection ssecEx4 Tetrahedral Remeshing After Mesh Generation diff --git a/Tetrahedral_remeshing/doc/Tetrahedral_remeshing/examples.txt b/Tetrahedral_remeshing/doc/Tetrahedral_remeshing/examples.txt index 018dde267674..06b69b82469a 100644 --- a/Tetrahedral_remeshing/doc/Tetrahedral_remeshing/examples.txt +++ b/Tetrahedral_remeshing/doc/Tetrahedral_remeshing/examples.txt @@ -4,5 +4,6 @@ \example Tetrahedral_remeshing/tetrahedral_remeshing_of_one_subdomain.cpp \example Tetrahedral_remeshing/tetrahedral_remeshing_with_features.cpp \example Tetrahedral_remeshing/mesh_and_remesh_polyhedral_domain_with_features.cpp +\example Tetrahedral_remeshing/mesh_and_remesh_polyhedral_domain_with_features_from_complex.cpp \example Tetrahedral_remeshing/tetrahedral_remeshing_from_mesh.cpp */ diff --git a/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/CMakeLists.txt b/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/CMakeLists.txt index b5c4c1da2ab8..4448fd6bde71 100644 --- a/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/CMakeLists.txt +++ b/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/CMakeLists.txt @@ -31,9 +31,13 @@ if(TARGET CGAL::Eigen3_support) create_single_source_cgal_program( "mesh_and_remesh_polyhedral_domain_with_features.cpp" ) target_link_libraries(mesh_and_remesh_polyhedral_domain_with_features PUBLIC CGAL::Eigen3_support) + create_single_source_cgal_program("mesh_and_remesh_polyhedral_domain_with_features_from_complex.cpp") + target_link_libraries(mesh_and_remesh_polyhedral_domain_with_features_from_complex PUBLIC CGAL::Eigen3_support) + if(CGAL_ACTIVATE_CONCURRENT_MESH_3 AND TARGET CGAL::TBB_support) message(STATUS "Found TBB") target_link_libraries(mesh_and_remesh_polyhedral_domain_with_features PRIVATE CGAL::TBB_support) + target_link_libraries(mesh_and_remesh_polyhedral_domain_with_features_from_complex PRIVATE CGAL::TBB_support) endif() else() message(STATUS "NOTICE: Some examples require Eigen 3.1 (or greater), and will not be compiled.") diff --git a/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/mesh_and_remesh_polyhedral_domain_with_features_from_complex.cpp b/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/mesh_and_remesh_polyhedral_domain_with_features_from_complex.cpp new file mode 100644 index 000000000000..b5a10784e929 --- /dev/null +++ b/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/mesh_and_remesh_polyhedral_domain_with_features_from_complex.cpp @@ -0,0 +1,96 @@ +#include + +#include +#include +#include + +#include +#include + +#include + +#include + +// Domain +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef CGAL::Mesh_polyhedron_3::type Polyhedron; +typedef CGAL::Polyhedral_mesh_domain_with_features_3 Mesh_domain; + +#ifdef CGAL_CONCURRENT_MESH_3 +typedef CGAL::Parallel_tag Concurrency_tag; +#else +typedef CGAL::Sequential_tag Concurrency_tag; +#endif + +// Triangulation for Meshing +typedef CGAL::Mesh_triangulation_3::type Tr; +typedef CGAL::Mesh_complex_3_in_triangulation_3< + Tr, Mesh_domain::Corner_index, Mesh_domain::Curve_index> C3t3; + +// Criteria +typedef CGAL::Mesh_criteria_3 Mesh_criteria; + +// Triangulation for Remeshing +typedef CGAL::Triangulation_3 Triangulation_3; +using Vertex_handle = Triangulation_3::Vertex_handle; + +using Vertex_pair = std::pair; +using Constraints_set = std::unordered_set>; +using Constraints_pmap = CGAL::Boolean_property_map; + + +// To avoid verbose function and named parameters call +using namespace CGAL::parameters; + +int main(int argc, char* argv[]) +{ + const std::string fname = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/fandisk.off"); + std::ifstream input(fname); + Polyhedron polyhedron; + input >> polyhedron; + if (input.fail() || !CGAL::is_triangle_mesh(polyhedron)) { + std::cerr << "Error: Input invalid " << fname << std::endl; + return EXIT_FAILURE; + } + + // Create domain + Mesh_domain domain(polyhedron); + + // Get sharp features + domain.detect_features(); + + // Mesh criteria + Mesh_criteria criteria(edge_size = 0.025, + facet_angle = 25, facet_size = 0.05, facet_distance = 0.005, + cell_radius_edge_ratio = 3, cell_size = 0.05); + + // Mesh generation + C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria); + + CGAL::dump_c3t3(c3t3, "out"); + + Constraints_set constraints; + Constraints_pmap constraints_pmap(constraints); + + Triangulation_3 tr = CGAL::convert_to_triangulation_3(std::move(c3t3), + CGAL::parameters::edge_is_constrained_map(constraints_pmap)); + + //note we use the move semantic, with std::move(c3t3), + // to avoid a copy of the triangulation by the function + // `CGAL::convert_to_triangulation_3()` + // After the call to this function, c3t3 is an empty and valid C3t3. + //It is possible to use : CGAL::convert_to_triangulation_3(c3t3), + // Then the triangulation is copied and duplicated, and c3t3 remains as is. + + const double target_edge_length = 0.1;//coarsen the mesh + CGAL::tetrahedral_isotropic_remeshing(tr, target_edge_length, + CGAL::parameters::number_of_iterations(3) + .edge_is_constrained_map(constraints_pmap)); + + std::ofstream out("out_remeshed.mesh"); + CGAL::IO::write_MEDIT(out, tr); + out.close(); + + return EXIT_SUCCESS; +} From 3ebe548cada33a3b6266cbabda885db9ca05c25a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 5 Dec 2023 11:18:13 +0100 Subject: [PATCH 233/329] Revert "prevent out-of-bound warnings" This reverts commit b87ecf7aab7ec43fbe0869709c4f7df9d2804a40. --- TDS_3/include/CGAL/Triangulation_utils_3.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/TDS_3/include/CGAL/Triangulation_utils_3.h b/TDS_3/include/CGAL/Triangulation_utils_3.h index d656b5e75c55..8b99c725a65f 100644 --- a/TDS_3/include/CGAL/Triangulation_utils_3.h +++ b/TDS_3/include/CGAL/Triangulation_utils_3.h @@ -35,10 +35,10 @@ struct Triangulation_utils_base_3 template < class T > const char Triangulation_utils_base_3::tab_next_around_edge[4][4] = { - {-0, 2, 3, 1}, - {3, -0, 0, 2}, - {1, 3, -0, 0}, - {2, 0, 1, -0} }; + {5, 2, 3, 1}, + {3, 5, 0, 2}, + {1, 3, 5, 0}, + {2, 0, 1, 5} }; template < class T > const int Triangulation_utils_base_3::tab_vertex_triple_index[4][3] = { From 95b6ef8d2ee6abf3e78ea13ebbc78d8cba064de4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 5 Dec 2023 11:19:31 +0100 Subject: [PATCH 234/329] try working around a warning --- TDS_3/include/CGAL/Triangulation_utils_3.h | 1 + 1 file changed, 1 insertion(+) diff --git a/TDS_3/include/CGAL/Triangulation_utils_3.h b/TDS_3/include/CGAL/Triangulation_utils_3.h index 8b99c725a65f..1c4c16c75911 100644 --- a/TDS_3/include/CGAL/Triangulation_utils_3.h +++ b/TDS_3/include/CGAL/Triangulation_utils_3.h @@ -80,6 +80,7 @@ struct Triangulation_utils_3 CGAL_triangulation_precondition( ( i >= 0 && i < 4 ) && ( j >= 0 && j < 4 ) && ( i != j ) ); + CGAL_assume(i!=j); return tab_next_around_edge[i][j]; } From ef7ab56229c363fb2b246bdbf6a6a84f93879ead Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Tue, 5 Dec 2023 14:41:22 +0100 Subject: [PATCH 235/329] add missing using --- Tetrahedral_remeshing/include/CGAL/tetrahedral_remeshing.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Tetrahedral_remeshing/include/CGAL/tetrahedral_remeshing.h b/Tetrahedral_remeshing/include/CGAL/tetrahedral_remeshing.h index 133d06a39183..1f2cc574ca9d 100644 --- a/Tetrahedral_remeshing/include/CGAL/tetrahedral_remeshing.h +++ b/Tetrahedral_remeshing/include/CGAL/tetrahedral_remeshing.h @@ -324,6 +324,9 @@ convert_to_triangulation_3( CGAL::Mesh_complex_3_in_triangulation_3 c3t3, const NamedParameters& np = parameters::default_values()) { + using parameters::get_parameter; + using parameters::choose_parameter; + using GT = typename Tr::Geom_traits; using TDS = typename Tr::Triangulation_data_structure; From a91f8d038ed67056944ccd552dcda2efcaa6c914 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Tue, 5 Dec 2023 15:08:03 +0100 Subject: [PATCH 236/329] doc --- .../include/CGAL/tetrahedral_remeshing.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Tetrahedral_remeshing/include/CGAL/tetrahedral_remeshing.h b/Tetrahedral_remeshing/include/CGAL/tetrahedral_remeshing.h index 1f2cc574ca9d..ae67f4ddde53 100644 --- a/Tetrahedral_remeshing/include/CGAL/tetrahedral_remeshing.h +++ b/Tetrahedral_remeshing/include/CGAL/tetrahedral_remeshing.h @@ -310,8 +310,25 @@ void tetrahedral_isotropic_remeshing( * @tparam CurveIndex is the type of the indices for feature curves. * If `c3t3` has been generated using `CGAL::make_mesh_3()`, it must match * `MeshDomainWithFeatures_3::Curve_index`. +* @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" * * @param c3t3 the complex containing the triangulation to be remeshed. +* @param np optional sequence of \ref bgl_namedparameters "Named Parameters" +* among the ones listed below +* +* \cgalNamedParamsBegin +* \cgalParamNBegin{edge_is_constrained_map} +* \cgalParamDescription{a property map containing the constrained-or-not status of each edge of +* `c3t3.triangulation()`. +* For each edge `e` for which `c3t3.is_in_complex(e)` returns `true`, +* the constrained status of `e` is set to `true`.} +* \cgalParamType{a class model of `ReadWritePropertyMap` +* with `std::pair` +* as key type and `bool` as value type. It must be default constructible.} +* \cgalParamDefault{a default property map where no edge is constrained} +* \cgalParamNEnd +* +* \cgalNamedParamsEnd */ template Date: Tue, 5 Dec 2023 14:17:38 +0000 Subject: [PATCH 237/329] Polyhedron demo: Add sampling plugin --- .../Operations_on_polyhedra/CMakeLists.txt | 7 ++ .../Point_set_from_sampling_plugin.cpp | 105 ++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Point_set_from_sampling_plugin.cpp diff --git a/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/CMakeLists.txt index 2e030be7f6df..8c27fa77cad8 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/CMakeLists.txt @@ -13,6 +13,13 @@ target_link_libraries( PUBLIC scene_surface_mesh_item scene_polygon_soup_item scene_points_with_normal_item) +polyhedron_demo_plugin(point_set_from_sampling_plugin + Point_set_from_sampling_plugin) +target_link_libraries( + point_set_from_sampling_plugin + PUBLIC scene_surface_mesh_item scene_polygon_soup_item + scene_points_with_normal_item) + polyhedron_demo_plugin(diff_between_meshes_plugin Diff_between_meshes_plugin) target_link_libraries(diff_between_meshes_plugin PUBLIC scene_surface_mesh_item) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Point_set_from_sampling_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Point_set_from_sampling_plugin.cpp new file mode 100644 index 000000000000..ae439ee013a7 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Point_set_from_sampling_plugin.cpp @@ -0,0 +1,105 @@ +#include +#include +#include +#include +#include +#include + +#include "Scene_points_with_normal_item.h" +#include "Scene_surface_mesh_item.h" +#include "Scene_polygon_soup_item.h" + +#include +#include "Messages_interface.h" + +#include + +using namespace CGAL::Three; +class Polyhedron_demo_point_set_from_sampling_plugin : + public QObject, + public Polyhedron_demo_plugin_interface +{ + Q_OBJECT + Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") + +public: + void init(QMainWindow* mainWindow, + CGAL::Three::Scene_interface* scene_interface, Messages_interface*); + + bool applicable(QAction*) const { + const CGAL::Three::Scene_interface::Item_id index = scene->mainSelectionIndex(); + + return qobject_cast(scene->item(index)) + || qobject_cast(scene->item(index)); + } + + QList actions() const; + +public Q_SLOTS: + void createPointSet(); + +private: + CGAL::Three::Scene_interface* scene; + QAction* actionPointSetFromSampling; + + +}; // end Polyhedron_demo_point_set_from_sampling_plugin + +void Polyhedron_demo_point_set_from_sampling_plugin::init(QMainWindow* mainWindow, + CGAL::Three::Scene_interface* scene_interface, + Messages_interface*) +{ + scene = scene_interface; + actionPointSetFromSampling = new QAction(tr("&Create Point Set from Sampling"), mainWindow); + actionPointSetFromSampling->setObjectName("actionPointSetFromSampling"); + connect(actionPointSetFromSampling, SIGNAL(triggered()), + this, SLOT(createPointSet())); +} + +QList Polyhedron_demo_point_set_from_sampling_plugin::actions() const { + return QList() << actionPointSetFromSampling; +} + + + +void Polyhedron_demo_point_set_from_sampling_plugin::createPointSet() +{ + QApplication::setOverrideCursor(Qt::WaitCursor); + const CGAL::Three::Scene_interface::Item_id index = scene->mainSelectionIndex(); + + Scene_points_with_normal_item* points = new Scene_points_with_normal_item(); + std::vector pts; + + if (points){ + points->setColor(Qt::blue); + }else{ + return; + } + Scene_surface_mesh_item* sm_item = + qobject_cast(scene->item(index)); + + if (sm_item){ + points->setName(QString("%1 (sampled)").arg(sm_item->name())); + CGAL::Polygon_mesh_processing::sample_triangle_mesh(*sm_item->polyhedron(), + std::back_inserter(pts)); + } + + Scene_polygon_soup_item* soup_item = + qobject_cast(scene->item(index)); + + if (soup_item){ + points->setName(QString("%1 (sampled)").arg(soup_item->name())); + CGAL::Polygon_mesh_processing::sample_triangle_soup(soup_item->points(), + soup_item->polygons(), + std::back_inserter(pts)); + } + for (std::size_t i = 0; i < pts.size(); ++i){ + points->point_set()->insert(pts[i]); + } + scene->addItem(points); + QApplication::restoreOverrideCursor(); +} + + +#include "Point_set_from_sampling_plugin.moc" From 3584d3489d01090f2cc2a97461d5f1915bacef79 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Tue, 5 Dec 2023 15:19:29 +0100 Subject: [PATCH 238/329] fix example name --- .../doc/Tetrahedral_remeshing/Tetrahedral_remeshing.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tetrahedral_remeshing/doc/Tetrahedral_remeshing/Tetrahedral_remeshing.txt b/Tetrahedral_remeshing/doc/Tetrahedral_remeshing/Tetrahedral_remeshing.txt index e7b717fd001e..f0400342db1b 100644 --- a/Tetrahedral_remeshing/doc/Tetrahedral_remeshing/Tetrahedral_remeshing.txt +++ b/Tetrahedral_remeshing/doc/Tetrahedral_remeshing/Tetrahedral_remeshing.txt @@ -107,7 +107,7 @@ It is also possible to define the polyline features as the ones stored as complex edges in a `Mesh_complex_3_in_triangulation_3` (e.g. generated by the \ref PkgMesh3 package mesh generation algorithms). -\cgalExample{Tetrahedral_remeshing/tetrahedral_remeshing_with_features_from_complex.cpp } +\cgalExample{Tetrahedral_remeshing/mesh_and_remesh_polyhedral_domain_with_features_from_complex.cpp } \subsection ssecEx4 Tetrahedral Remeshing After Mesh Generation From 1d5bef39067ea8809f76a83c7e15306ed3c55d98 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Tue, 5 Dec 2023 17:29:24 +0100 Subject: [PATCH 239/329] use ordered pair --- Tetrahedral_remeshing/include/CGAL/tetrahedral_remeshing.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tetrahedral_remeshing/include/CGAL/tetrahedral_remeshing.h b/Tetrahedral_remeshing/include/CGAL/tetrahedral_remeshing.h index ae67f4ddde53..d0dbede067dc 100644 --- a/Tetrahedral_remeshing/include/CGAL/tetrahedral_remeshing.h +++ b/Tetrahedral_remeshing/include/CGAL/tetrahedral_remeshing.h @@ -362,7 +362,7 @@ convert_to_triangulation_3( { for (auto e : c3t3.edges_in_complex()) { - const Edge_vv evv{e.first->vertex(e.second), e.first->vertex(e.third)}; + const Edge_vv evv = make_vertex_pair(e);//ordered pair put(ecmap, evv, true); } } From d98a6233f0b781a259d1d5b5084ebafe7564c243 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Tue, 5 Dec 2023 17:32:26 +0100 Subject: [PATCH 240/329] collect features and use edge_is_constrained_map in demo code --- .../Tetrahedral_remeshing_plugin.cpp | 31 ++++++++++++++++--- .../internal/tetrahedral_remeshing_helpers.h | 21 +++++++++++++ 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Tetrahedral_remeshing/Tetrahedral_remeshing_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Tetrahedral_remeshing/Tetrahedral_remeshing_plugin.cpp index 05875d4e6ca5..a64a44fa331e 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Tetrahedral_remeshing/Tetrahedral_remeshing_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Tetrahedral_remeshing/Tetrahedral_remeshing_plugin.cpp @@ -12,6 +12,7 @@ #include "C3t3_type.h" #include +#include #include #include @@ -80,6 +81,7 @@ public Q_SLOTS: Scene_c3t3_item* c3t3_item = qobject_cast(scene->item(index)); + const auto& c3t3 = c3t3_item->c3t3(); if (c3t3_item) { @@ -100,18 +102,37 @@ public Q_SLOTS: bool protect = ui.protect_checkbox->isChecked(); bool smooth_edges = ui.smoothEdges_checkBox->isChecked(); + // collect constraints + using Vertex_handle = Tr::Vertex_handle; + using Vertex_pair = std::pair; + using Constraints_set = std::unordered_set>; + using Constraints_pmap = CGAL::Boolean_property_map; + // wait cursor QApplication::setOverrideCursor(Qt::WaitCursor); QElapsedTimer time; time.start(); + Constraints_set constraints; + for (const auto e : c3t3_item->c3t3().triangulation().finite_edges()) + { + if (c3t3_item->c3t3().is_in_complex(e) + || CGAL::Tetrahedral_remeshing::protecting_balls_intersect(e, c3t3)) + { + Vertex_pair evv = CGAL::Tetrahedral_remeshing::make_vertex_pair(e); + constraints.insert(evv); + } + } + CGAL::tetrahedral_isotropic_remeshing( - c3t3_item->c3t3(), - target_length, - CGAL::parameters::remesh_boundaries(!protect) - .number_of_iterations(nb_iter) - .smooth_constrained_edges(smooth_edges)); + c3t3_item->c3t3(), + target_length, + CGAL::parameters::remesh_boundaries(!protect) + .number_of_iterations(nb_iter) + .smooth_constrained_edges(smooth_edges) + .edge_is_constrained_map(Constraints_pmap(constraints)) + ); std::cout << "Remeshing done (" << time.elapsed() << " ms)" << std::endl; diff --git a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_remeshing_helpers.h b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_remeshing_helpers.h index f566ab1890fb..09787f05dfdd 100644 --- a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_remeshing_helpers.h +++ b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_remeshing_helpers.h @@ -589,6 +589,27 @@ bool is_edge_in_complex(const typename C3t3::Vertex_handle& v0, return false; } +template +bool protecting_balls_intersect(const typename C3t3::Edge& e, + const C3t3& c3t3) +{ + const auto vv = c3t3.triangulation().vertices(e); + if( c3t3.in_dimension(vv[0]) > 1 + || c3t3.in_dimension(vv[1]) > 1) + return false; + + const auto& p0 = vv[0]->point(); + const auto& p1 = vv[1]->point(); + if(p0.weight() == 0 || p1.weight() == 0) + return false; + + const auto r0 = CGAL::approximate_sqrt(p0.weight()); + const auto r1 = CGAL::approximate_sqrt(p1.weight()); + const auto d = CGAL::approximate_sqrt(CGAL::squared_distance(p0, p1)); + + return d < r0 + r1; +} + template OutputIterator incident_subdomains(const typename C3t3::Vertex_handle v, const C3t3& c3t3, From 43b8b694d0a8e053092781c8d0106b70436c92e5 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Tue, 5 Dec 2023 17:32:54 +0100 Subject: [PATCH 241/329] use is_in_complex() inside bigger condition --- .../internal/tetrahedral_adaptive_remeshing_impl.h | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_adaptive_remeshing_impl.h b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_adaptive_remeshing_impl.h index be3dfe8f276f..64e1db2ca603 100644 --- a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_adaptive_remeshing_impl.h +++ b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_adaptive_remeshing_impl.h @@ -471,17 +471,8 @@ class Adaptive_remesher const Curve_index default_curve_id = default_curve_index(); for (const Edge& e : tr().finite_edges()) { - if (m_c3t3.is_in_complex(e)) - { - CGAL_assertion(m_c3t3.in_dimension(e.first->vertex(e.second)) <= 1); - CGAL_assertion(m_c3t3.in_dimension(e.first->vertex(e.third)) <= 1); -#ifdef CGAL_TETRAHEDRAL_REMESHING_DEBUG - ++nbe; -#endif - continue; - } - if (get(ecmap, CGAL::Tetrahedral_remeshing::make_vertex_pair(e)) + || m_c3t3.is_in_complex(e) || nb_incident_subdomains(e, m_c3t3) > 2 || nb_incident_surface_patches(e, m_c3t3) > 1) { From f6a988664b91fa4b581923741f37e9ec1056c757 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Tue, 5 Dec 2023 18:08:15 +0100 Subject: [PATCH 242/329] add missing namespace --- Tetrahedral_remeshing/include/CGAL/tetrahedral_remeshing.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tetrahedral_remeshing/include/CGAL/tetrahedral_remeshing.h b/Tetrahedral_remeshing/include/CGAL/tetrahedral_remeshing.h index d0dbede067dc..b6688e22f097 100644 --- a/Tetrahedral_remeshing/include/CGAL/tetrahedral_remeshing.h +++ b/Tetrahedral_remeshing/include/CGAL/tetrahedral_remeshing.h @@ -362,7 +362,7 @@ convert_to_triangulation_3( { for (auto e : c3t3.edges_in_complex()) { - const Edge_vv evv = make_vertex_pair(e);//ordered pair + const Edge_vv evv = CGAL::Tetrahedral_remeshing::make_vertex_pair(e);//ordered pair put(ecmap, evv, true); } } From d09e1fe00bc1d48849d7c21e017f26e8e1cb70e4 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Tue, 5 Dec 2023 18:08:53 +0100 Subject: [PATCH 243/329] add missing template --- Tetrahedral_remeshing/include/CGAL/tetrahedral_remeshing.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Tetrahedral_remeshing/include/CGAL/tetrahedral_remeshing.h b/Tetrahedral_remeshing/include/CGAL/tetrahedral_remeshing.h index b6688e22f097..d11d72973b6a 100644 --- a/Tetrahedral_remeshing/include/CGAL/tetrahedral_remeshing.h +++ b/Tetrahedral_remeshing/include/CGAL/tetrahedral_remeshing.h @@ -362,7 +362,8 @@ convert_to_triangulation_3( { for (auto e : c3t3.edges_in_complex()) { - const Edge_vv evv = CGAL::Tetrahedral_remeshing::make_vertex_pair(e);//ordered pair + const Edge_vv evv + = CGAL::Tetrahedral_remeshing::make_vertex_pair(e);//ordered pair put(ecmap, evv, true); } } From 95825dba608a07d16fca1781ae1a974f80dbbea9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 5 Dec 2023 18:11:27 +0100 Subject: [PATCH 244/329] fix copy/paste errors --- .../CGAL/STL_Extension/internal/mesh_parameters_interface.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/STL_Extension/include/CGAL/STL_Extension/internal/mesh_parameters_interface.h b/STL_Extension/include/CGAL/STL_Extension/internal/mesh_parameters_interface.h index ece342c321b1..9aedf344d434 100644 --- a/STL_Extension/include/CGAL/STL_Extension/internal/mesh_parameters_interface.h +++ b/STL_Extension/include/CGAL/STL_Extension/internal/mesh_parameters_interface.h @@ -55,7 +55,7 @@ perturb(const CGAL_NP_CLASS& np = parameters::default_values()) } template -Named_function_parameters<::CGAL::parameters::internal::Exude_options, ::CGAL::internal_np::exude_options_param_t, CGAL_NP_BASE> +Named_function_parameters<::CGAL::parameters::internal::Perturb_options, ::CGAL::internal_np::perturb_options_param_t, CGAL_NP_BASE> perturb(const CGAL_NP_CLASS_1& np1, const CGAL_NP_CLASS_2& np2, const NP& ... nps) { return perturb(::CGAL::internal_np::combine_named_parameters(np1, np2, nps...)); @@ -91,7 +91,7 @@ exude(const CGAL_NP_CLASS& np = parameters::default_values()) using ::CGAL::parameters::choose_parameter; using ::CGAL::parameters::get_parameter; double time_limit = choose_parameter(get_parameter(np,::CGAL::internal_np::maximum_running_time),::CGAL::parameters::internal::undef_parameter); - double sliver_bound = choose_parameter(get_parameter(np,::CGAL::internal_np::lower_sliver_bound),::CGAL::parameters::default_values_for_mesh_3::perturb_sliver_bound); + double sliver_bound = choose_parameter(get_parameter(np,::CGAL::internal_np::lower_sliver_bound),::CGAL::parameters::default_values_for_mesh_3::exude_sliver_bound); ::CGAL::parameters::internal::Exude_options options(true); From dd0cc2ee5c108f5a0aef3eaac07db4986373421c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 5 Dec 2023 22:15:01 +0100 Subject: [PATCH 245/329] Fix a few copy-paste bugs --- .../CGAL/STL_Extension/internal/mesh_parameters_interface.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/STL_Extension/include/CGAL/STL_Extension/internal/mesh_parameters_interface.h b/STL_Extension/include/CGAL/STL_Extension/internal/mesh_parameters_interface.h index ece342c321b1..8fc2baca0c3a 100644 --- a/STL_Extension/include/CGAL/STL_Extension/internal/mesh_parameters_interface.h +++ b/STL_Extension/include/CGAL/STL_Extension/internal/mesh_parameters_interface.h @@ -55,7 +55,7 @@ perturb(const CGAL_NP_CLASS& np = parameters::default_values()) } template -Named_function_parameters<::CGAL::parameters::internal::Exude_options, ::CGAL::internal_np::exude_options_param_t, CGAL_NP_BASE> +Named_function_parameters<::CGAL::parameters::internal::Perturb_options, ::CGAL::internal_np::perturb_options_param_t, CGAL_NP_BASE> perturb(const CGAL_NP_CLASS_1& np1, const CGAL_NP_CLASS_2& np2, const NP& ... nps) { return perturb(::CGAL::internal_np::combine_named_parameters(np1, np2, nps...)); @@ -91,7 +91,7 @@ exude(const CGAL_NP_CLASS& np = parameters::default_values()) using ::CGAL::parameters::choose_parameter; using ::CGAL::parameters::get_parameter; double time_limit = choose_parameter(get_parameter(np,::CGAL::internal_np::maximum_running_time),::CGAL::parameters::internal::undef_parameter); - double sliver_bound = choose_parameter(get_parameter(np,::CGAL::internal_np::lower_sliver_bound),::CGAL::parameters::default_values_for_mesh_3::perturb_sliver_bound); + double sliver_bound = choose_parameter(get_parameter(np,::CGAL::internal_np::lower_sliver_bound),::CGAL::parameters::default_values_for_mesh_3::exude_sliver_bound); ::CGAL::parameters::internal::Exude_options options(true); @@ -304,7 +304,7 @@ mesh_3_options(const CGAL_NP_CLASS& np = parameters::default_values()) options.dump_after_refine_prefix=choose_parameter(get_parameter(np, ::CGAL::internal_np::dump_after_refine_prefix_param), ""); options.dump_after_glob_opt_prefix=choose_parameter(get_parameter(np, ::CGAL::internal_np::dump_after_glob_opt_prefix_param), ""); options.dump_after_perturb_prefix=choose_parameter(get_parameter(np, ::CGAL::internal_np::dump_after_perturb_prefix_param), ""); - options.dump_after_exude_prefix=choose_parameter(get_parameter(np, ::CGAL::internal_np::dump_after_refine_surface_prefix_param), ""); + options.dump_after_exude_prefix=choose_parameter(get_parameter(np, ::CGAL::internal_np::dump_after_exude_prefix_param), ""); options.number_of_initial_points=choose_parameter(get_parameter(np, ::CGAL::internal_np::number_of_initial_points_param), -1); options.nonlinear_growth_of_balls = choose_parameter(get_parameter(np, ::CGAL::internal_np::nonlinear_growth_of_balls_param), false); options.maximal_number_of_vertices=choose_parameter(get_parameter(np, ::CGAL::internal_np::maximal_number_of_vertices_param), 0); From b4d465ce8532df0913a4eecdd8df414be393768e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 5 Dec 2023 22:34:00 +0100 Subject: [PATCH 246/329] Add a test --- Mesh_3/test/Mesh_3/test_mesh_capsule_var_distance_bound.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Mesh_3/test/Mesh_3/test_mesh_capsule_var_distance_bound.cpp b/Mesh_3/test/Mesh_3/test_mesh_capsule_var_distance_bound.cpp index 14390abda0d0..9fa7eaad0c33 100644 --- a/Mesh_3/test/Mesh_3/test_mesh_capsule_var_distance_bound.cpp +++ b/Mesh_3/test/Mesh_3/test_mesh_capsule_var_distance_bound.cpp @@ -58,7 +58,9 @@ int main() facet_distance=field); // Mesh generation - C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria); + C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria, + perturb(time_limit = 0, sliver_bound = 0), + exude(time_limit = 0, sliver_bound = 0)); // // Output // std::ofstream medit_file("out.mesh"); From 4ecc6671dc543f7087cbc3846e82274836151ceb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 6 Dec 2023 12:42:00 +0100 Subject: [PATCH 247/329] increase precision of the result --- .../Plane_3_Plane_3_Plane_3_intersection.h | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Plane_3_Plane_3_Plane_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Plane_3_Plane_3_Plane_3_intersection.h index be6ca11f0690..5ac60201e266 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Plane_3_Plane_3_Plane_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Plane_3_Plane_3_Plane_3_intersection.h @@ -88,6 +88,13 @@ intersection(const typename K::Plane_3& plane1, typedef typename K::Line_3 Line_3; typedef typename K::Plane_3 Plane_3; + if(!is_zero(determinant(plane1.a(), plane1.b(), plane1.c(), + plane2.a(), plane2.b(), plane2.c(), + plane3.a(), plane3.b(), plane3.c()))) + { + return intersection_point(plane1,plane2,plane3, k); + } + // Intersection between plane1 and plane2 can either be // a line, a plane, or empty. typename Intersection_traits::result_type @@ -97,26 +104,19 @@ intersection(const typename K::Plane_3& plane1, { if(const Line_3* l = intersect_get(o12)) { - // either point or line - typename Intersection_traits::result_type - v = internal::intersection(plane3, *l, k); - if(v) - { - if(const Point_3* p = intersect_get(v)) - return result_type(*p); - else if(const Line_3* l = intersect_get(v)) - return result_type(*l); - } + if (internal::do_intersect(*l, plane3, k)) + return result_type(*l); } - else if(const Plane_3 *pl = intersect_get(o12)) + else { + CGAL_assertion(intersect_get(o12) != nullptr); // either line or plane typename Intersection_traits::result_type - v = internal::intersection(plane3, *pl, k); + v = internal::intersection(plane3, plane1, k); if(v) { - if(const Plane_3* p = intersect_get(v)) - return result_type(*p); + if( intersect_get(v)!=nullptr) + return result_type(plane1); else if(const Line_3* l = intersect_get(v)) return result_type(*l); } From 0ebc2bee422222eb81a31c9540d70b8e82c8d3d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 6 Dec 2023 14:17:24 +0100 Subject: [PATCH 248/329] remove the optional --- .../internal/Plane_3_Plane_3_Plane_3_intersection.h | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Plane_3_Plane_3_Plane_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Plane_3_Plane_3_Plane_3_intersection.h index 5ac60201e266..0e6f9acb0489 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Plane_3_Plane_3_Plane_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Plane_3_Plane_3_Plane_3_intersection.h @@ -27,7 +27,7 @@ namespace internal { // triple plane intersection template -boost::optional +typename K::Point_3 intersection_point(const typename K::Plane_3& plane1, const typename K::Plane_3& plane2, const typename K::Plane_3& plane3, @@ -55,10 +55,6 @@ intersection_point(const typename K::Plane_3& plane1, const FT den = minor_0*m22 - minor_1*m12 + minor_2*m02; // determinant of M - if(is_zero(den)){ - return boost::none; - } - const FT num3 = minor_0*b2 - minor_1*b1 + minor_2*b0; // determinant of M with M[x:2] swapped with [b0,b1,b2] // Minors common to two determinants @@ -70,7 +66,7 @@ intersection_point(const typename K::Plane_3& plane1, const FT num1 = - minor_3*m21 + minor_4*m11 - minor_5*m01; // determinant of M with M[x:0] swapped with [b0,b1,b2] const FT num2 = minor_3*m20 - minor_4*m10 + minor_5*m00; // determinant of M with M[x:1] swapped with [b0,b1,b2] - return boost::make_optional(typename K::Point_3(num1/den, num2/den, num3/den)); + return typename K::Point_3(num1/den, num2/den, num3/den); } template @@ -92,7 +88,7 @@ intersection(const typename K::Plane_3& plane1, plane2.a(), plane2.b(), plane2.c(), plane3.a(), plane3.b(), plane3.c()))) { - return intersection_point(plane1,plane2,plane3, k); + return result_type(intersection_point(plane1,plane2,plane3, k)); } // Intersection between plane1 and plane2 can either be From 560f02c921aab01856605232120b115e25ffbd20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 6 Dec 2023 15:29:17 +0100 Subject: [PATCH 249/329] add missing remove_const --- .../CGAL/Polygon_mesh_processing/remesh_planar_patches.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/remesh_planar_patches.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/remesh_planar_patches.h index 03171af70bcd..48ca74ba2652 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/remesh_planar_patches.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/remesh_planar_patches.h @@ -304,7 +304,7 @@ mark_constrained_edges( double coplanar_cos_threshold, const VertexPointMap& vpm) { - for(typename boost::graph_traits::edge_descriptor e : edges(tm)) + for(typename boost::graph_traits>::edge_descriptor e : edges(tm)) { if (!get(edge_is_constrained,e)) if (!is_edge_between_coplanar_faces(e, tm, coplanar_cos_threshold, vpm)) @@ -325,7 +325,7 @@ mark_corner_vertices( double coplanar_cos_threshold, const VertexPointMap& vpm) { - typedef boost::graph_traits graph_traits; + typedef boost::graph_traits> graph_traits; std::size_t corner_id = 0; for(typename graph_traits::edge_descriptor e : edges(tm)) { @@ -553,7 +553,7 @@ tag_corners_and_constrained_edges(TriangleMesh& tm, FaceCCIdMap& face_cc_ids, const VertexPointMap& vpm) { - typedef typename boost::graph_traits graph_traits; + typedef typename boost::graph_traits> graph_traits; // mark constrained edges mark_constrained_edges(tm, edge_is_constrained, coplanar_cos_threshold, vpm); From 63556d4faa3f98af3f0c17cd2ed920f6f489761f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 6 Dec 2023 15:50:14 +0100 Subject: [PATCH 250/329] use explicitly const meshes --- .../Polygon_mesh_processing/remesh_planar_patches.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/remesh_planar_patches.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/remesh_planar_patches.h index 48ca74ba2652..33514d6f2deb 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/remesh_planar_patches.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/remesh_planar_patches.h @@ -299,12 +299,12 @@ template void mark_constrained_edges( - TriangleMesh& tm, + const TriangleMesh& tm, EdgeIsConstrainedMap edge_is_constrained, double coplanar_cos_threshold, const VertexPointMap& vpm) { - for(typename boost::graph_traits>::edge_descriptor e : edges(tm)) + for(typename boost::graph_traits::edge_descriptor e : edges(tm)) { if (!get(edge_is_constrained,e)) if (!is_edge_between_coplanar_faces(e, tm, coplanar_cos_threshold, vpm)) @@ -319,13 +319,13 @@ template std::size_t mark_corner_vertices( - TriangleMesh& tm, + const TriangleMesh& tm, EdgeIsConstrainedMap& edge_is_constrained, VertexCornerIdMap& vertex_corner_id, double coplanar_cos_threshold, const VertexPointMap& vpm) { - typedef boost::graph_traits> graph_traits; + typedef boost::graph_traits graph_traits; std::size_t corner_id = 0; for(typename graph_traits::edge_descriptor e : edges(tm)) { @@ -546,14 +546,14 @@ template std::pair -tag_corners_and_constrained_edges(TriangleMesh& tm, +tag_corners_and_constrained_edges(const TriangleMesh& tm, double coplanar_cos_threshold, VertexCornerIdMap& vertex_corner_id, EdgeIsConstrainedMap& edge_is_constrained, FaceCCIdMap& face_cc_ids, const VertexPointMap& vpm) { - typedef typename boost::graph_traits> graph_traits; + typedef typename boost::graph_traits graph_traits; // mark constrained edges mark_constrained_edges(tm, edge_is_constrained, coplanar_cos_threshold, vpm); From 43213ee0e8fc9c3aec6f276afb83679db0ccbcd8 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 6 Dec 2023 16:13:58 +0100 Subject: [PATCH 251/329] Update Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Point_set_from_sampling_plugin.cpp Co-authored-by: Laurent Rineau --- .../Operations_on_polyhedra/Point_set_from_sampling_plugin.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Point_set_from_sampling_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Point_set_from_sampling_plugin.cpp index ae439ee013a7..c654a51cd6b1 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Point_set_from_sampling_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Point_set_from_sampling_plugin.cpp @@ -94,10 +94,11 @@ void Polyhedron_demo_point_set_from_sampling_plugin::createPointSet() soup_item->polygons(), std::back_inserter(pts)); } + points->point_set()->reserve(pts.size()); for (std::size_t i = 0; i < pts.size(); ++i){ points->point_set()->insert(pts[i]); } - scene->addItem(points); + scene->addItem(points); QApplication::restoreOverrideCursor(); } From d9d2dfc876950fd9f2cdc4362f955ef29370110b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 7 Dec 2023 09:59:24 +0100 Subject: [PATCH 252/329] remove unused type definition --- .../internal/Plane_3_Plane_3_Plane_3_intersection.h | 1 - 1 file changed, 1 deletion(-) diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Plane_3_Plane_3_Plane_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Plane_3_Plane_3_Plane_3_intersection.h index 0e6f9acb0489..2aa4e9b0bcb6 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Plane_3_Plane_3_Plane_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Plane_3_Plane_3_Plane_3_intersection.h @@ -80,7 +80,6 @@ intersection(const typename K::Plane_3& plane1, typename K::Line_3, typename K::Plane_3> > result_type; - typedef typename K::Point_3 Point_3; typedef typename K::Line_3 Line_3; typedef typename K::Plane_3 Plane_3; From 2574a13557ea82b059f27e60665c698a27c0411f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 7 Dec 2023 10:12:35 +0100 Subject: [PATCH 253/329] restore the optional as it is used by Polyhedral_envelope --- .../Plane_3_Plane_3_Plane_3_intersection.h | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Plane_3_Plane_3_Plane_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Plane_3_Plane_3_Plane_3_intersection.h index 2aa4e9b0bcb6..2f4b6e759063 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Plane_3_Plane_3_Plane_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Plane_3_Plane_3_Plane_3_intersection.h @@ -27,7 +27,7 @@ namespace internal { // triple plane intersection template -typename K::Point_3 +boost::optional intersection_point(const typename K::Plane_3& plane1, const typename K::Plane_3& plane2, const typename K::Plane_3& plane3, @@ -55,6 +55,10 @@ intersection_point(const typename K::Plane_3& plane1, const FT den = minor_0*m22 - minor_1*m12 + minor_2*m02; // determinant of M + if(is_zero(den)){ + return boost::none; + } + const FT num3 = minor_0*b2 - minor_1*b1 + minor_2*b0; // determinant of M with M[x:2] swapped with [b0,b1,b2] // Minors common to two determinants @@ -66,7 +70,7 @@ intersection_point(const typename K::Plane_3& plane1, const FT num1 = - minor_3*m21 + minor_4*m11 - minor_5*m01; // determinant of M with M[x:0] swapped with [b0,b1,b2] const FT num2 = minor_3*m20 - minor_4*m10 + minor_5*m00; // determinant of M with M[x:1] swapped with [b0,b1,b2] - return typename K::Point_3(num1/den, num2/den, num3/den); + return boost::make_optional(typename K::Point_3(num1/den, num2/den, num3/den)); } template @@ -83,12 +87,9 @@ intersection(const typename K::Plane_3& plane1, typedef typename K::Line_3 Line_3; typedef typename K::Plane_3 Plane_3; - if(!is_zero(determinant(plane1.a(), plane1.b(), plane1.c(), - plane2.a(), plane2.b(), plane2.c(), - plane3.a(), plane3.b(), plane3.c()))) - { - return result_type(intersection_point(plane1,plane2,plane3, k)); - } + auto res = intersection_point(plane1,plane2,plane3, k); + if (res != boost::none) + return result_type(*res); // Intersection between plane1 and plane2 can either be // a line, a plane, or empty. From 6dca71b428339132651463ef1747bee8b49ecdd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 7 Dec 2023 10:19:36 +0100 Subject: [PATCH 254/329] ease conflict resolution --- .../internal/Plane_3_Plane_3_Plane_3_intersection.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Plane_3_Plane_3_Plane_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Plane_3_Plane_3_Plane_3_intersection.h index 2f4b6e759063..6858672f19ff 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Plane_3_Plane_3_Plane_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Plane_3_Plane_3_Plane_3_intersection.h @@ -88,7 +88,7 @@ intersection(const typename K::Plane_3& plane1, typedef typename K::Plane_3 Plane_3; auto res = intersection_point(plane1,plane2,plane3, k); - if (res != boost::none) + if (res) return result_type(*res); // Intersection between plane1 and plane2 can either be From f0426b8aa6f3d9a73018e801a49aad51bd5613ae Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 7 Dec 2023 09:33:31 +0000 Subject: [PATCH 255/329] PMP: Write into different files to avoid concurrent writing --- ...angulate_hole_Polyhedron_3_no_delaunay_test.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/triangulate_hole_Polyhedron_3_no_delaunay_test.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/triangulate_hole_Polyhedron_3_no_delaunay_test.cpp index 1dcb214fe398..61b0ed153b43 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/triangulate_hole_Polyhedron_3_no_delaunay_test.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/triangulate_hole_Polyhedron_3_no_delaunay_test.cpp @@ -335,7 +335,7 @@ void test_triangulate_refine_and_fair_hole_compile() { std::vector patch_vertices; // use all param - read_poly_with_borders("elephant_quad_hole.off", poly, border_reps); + read_poly_with_borders("elephant_quad_hole_no_DT3.off", poly, border_reps); CGAL::Polygon_mesh_processing::triangulate_refine_and_fair_hole (poly, border_reps[0], back_inserter(patch_facets), back_inserter(patch_vertices), CGAL::parameters:: @@ -343,14 +343,14 @@ void test_triangulate_refine_and_fair_hole_compile() { sparse_linear_solver(Default_solver())); // default solver - read_poly_with_borders("elephant_quad_hole.off", poly, border_reps); + read_poly_with_borders("elephant_quad_hole_no_DT3.off", poly, border_reps); CGAL::Polygon_mesh_processing::triangulate_refine_and_fair_hole (poly, border_reps[0], back_inserter(patch_facets), back_inserter(patch_vertices), CGAL::parameters:: weight_calculator(CGAL::Weights::Uniform_weight())); // default solver and weight - read_poly_with_borders("elephant_quad_hole.off", poly, border_reps); + read_poly_with_borders("elephant_quad_hole_no_DT3.off", poly, border_reps); CGAL::Polygon_mesh_processing::triangulate_refine_and_fair_hole (poly, border_reps[0], back_inserter(patch_facets), back_inserter(patch_vertices)); } @@ -369,11 +369,11 @@ void generate_elephant_with_hole() { Halfedge_handle nh=opposite(halfedge(fd,poly), poly); CGAL::Euler::remove_face(halfedge(fd, poly), poly); - std::ofstream output("elephant_triangle_hole.off"); + std::ofstream output("elephant_triangle_hole_no_DT3.off"); output << poly; output.close(); CGAL::Euler::remove_face(nh, poly); - output.open("elephant_quad_hole.off"); + output.open("elephant_quad_hole_no_DT3.off"); output << poly; return; } @@ -389,8 +389,8 @@ typedef CGAL::Surface_mesh Polyhedron; generate_elephant_with_hole(); std::vector input_files; - input_files.push_back("elephant_triangle_hole.off"); - input_files.push_back("elephant_quad_hole.off"); + input_files.push_back("elephant_triangle_hole_no_DT3.off"); + input_files.push_back("elephant_quad_hole_no_DT3.off"); input_files.push_back(CGAL::data_file_path("meshes/mech-holes-shark.off")); // std::cerr.precision(15); for(std::vector::iterator it = input_files.begin(); it != input_files.end(); ++it) { From dc04e5baa58f856c386e4b5fa8bc4de84cbe6746 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 7 Dec 2023 11:30:17 +0100 Subject: [PATCH 256/329] use doxygen macro --- .../CGAL/Polygon_mesh_processing/Adaptive_sizing_field.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/Adaptive_sizing_field.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/Adaptive_sizing_field.h index 5c3a99efef5b..e673ac9dfbb7 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/Adaptive_sizing_field.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/Adaptive_sizing_field.h @@ -38,7 +38,7 @@ namespace Polygon_mesh_processing * Edges too long with respect to the local target edge length are split in two, while * edges that are too short are collapsed. * -* This class depends on the Eigen library. +* This class depends on the \eigen library. * * \cgalModels{PMPSizingField} * From 7aab407b8cfd3a39ecad5f207ea88403246d1735 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 7 Dec 2023 11:32:17 +0100 Subject: [PATCH 257/329] add user friendly use case --- .../doc/Polygon_mesh_processing/Concepts/PMPSizingField.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPSizingField.h b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPSizingField.h index 02822cea9e70..e3c647510c99 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPSizingField.h +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPSizingField.h @@ -60,6 +60,7 @@ Point_3 split_placement(const halfedge_descriptor h, const PolygonMesh& pmesh) const; /// function called after the addition of the split vertex `v` in `pmesh`. +/// This function can be used for exemple to update a pre-computed sizing field. void register_split_vertex(const vertex_descriptor v, const PolygonMesh& pmesh); From 076f04af4a8dda837263fc161e5f614317c3c366 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 7 Dec 2023 10:53:07 +0000 Subject: [PATCH 258/329] Add links to the new function --- .../File_formats/Supported_file_formats.txt | 13 +++++++++---- .../doc/Stream_support/PackageDescription.txt | 3 +-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt b/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt index 192e66ddf64f..04436239a407 100644 --- a/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt +++ b/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt @@ -453,23 +453,28 @@ A precise specification of those formats is available at Input Polygon Mesh Any model of `MutableFaceGraph` - \link PkgBGLIoFuncsVTP CGAL::IO::read_VTP(const char*, Graph&)\endlink + \link PkgBGLIoFuncsVTP CGAL::IO::read_VTP(const std::string&, Graph&)\endlink Polygon Soup Any point + polygon range - \link PkgStreamSupportIoFuncsVTP CGAL::IO::read_VTP(const char*, PointRange&, PolygonRange&)\endlink + \link PkgStreamSupportIoFuncsVTP CGAL::IO::read_VTP(const std::string&, PointRange&, PolygonRange&)\endlink + + + Polygon Soup + Any point + polygon range + \link PkgStreamSupportIoFuncsVTP CGAL::IO::read_VTK(const std::string&, PointRange&, PolygonRange&)\endlink Output Polygon Mesh Any model of `FaceGraph` - \link PkgBGLIoFuncsVTP CGAL::IO::write_VTP(const char*, Graph&)\endlink + \link PkgBGLIoFuncsVTP CGAL::IO::write_VTP(const std::string&, Graph&)\endlink Polygon Soup Any point + polygon range - \link PkgStreamSupportIoFuncsVTP CGAL::IO::write_VTP(const char*, PointRange&, PolygonRange&)\endlink + \link PkgStreamSupportIoFuncsVTP CGAL::IO::write_VTP(const std::string&, const PointRange&, const PolygonRange&)\endlink diff --git a/Stream_support/doc/Stream_support/PackageDescription.txt b/Stream_support/doc/Stream_support/PackageDescription.txt index 9d993ee47799..c41b35ef5f82 100644 --- a/Stream_support/doc/Stream_support/PackageDescription.txt +++ b/Stream_support/doc/Stream_support/PackageDescription.txt @@ -20,7 +20,7 @@ /// I/O Functions for the \ref IOStreamOFF /// \ingroup IOstreamFunctions -/// \defgroup PkgStreamSupportIoFuncsVTP VTP I/O Functions +/// \defgroup PkgStreamSupportIoFuncsVTP VTK I/O Functions /// I/O Functions for the \ref IOStreamVTK /// \ingroup IOstreamFunctions @@ -101,4 +101,3 @@ the printing mode. - \link PkgStreamSupportIoFuncsWKT I/O for WKT files \endlink */ - From 96955790a1fd1069343605b7dcb8752ad1e6309a Mon Sep 17 00:00:00 2001 From: Sebastien Loriot Date: Thu, 7 Dec 2023 11:57:42 +0100 Subject: [PATCH 259/329] typo Co-authored-by: Jane Tournois --- .../doc/Polygon_mesh_processing/Concepts/PMPSizingField.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPSizingField.h b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPSizingField.h index e3c647510c99..b1216f3281ea 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPSizingField.h +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPSizingField.h @@ -60,7 +60,7 @@ Point_3 split_placement(const halfedge_descriptor h, const PolygonMesh& pmesh) const; /// function called after the addition of the split vertex `v` in `pmesh`. -/// This function can be used for exemple to update a pre-computed sizing field. +/// This function can be used for example to update a pre-computed sizing field. void register_split_vertex(const vertex_descriptor v, const PolygonMesh& pmesh); From 07a06717bde265b60769bba933099128aecf5cd8 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 7 Dec 2023 11:35:03 +0000 Subject: [PATCH 260/329] Fix char*; Fix table --- .../File_formats/Supported_file_formats.txt | 83 +++++++++---------- 1 file changed, 39 insertions(+), 44 deletions(-) diff --git a/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt b/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt index 04436239a407..a1c15f1826f6 100644 --- a/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt +++ b/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt @@ -117,23 +117,23 @@ A precise specification of the format is available Input Polygon Mesh Any model of `MutableFaceGraph` - \link PkgBGLIoFuncsOBJ CGAL::IO::read_OBJ(const char*, Graph&)\endlink + \link PkgBGLIoFuncsOBJ CGAL::IO::read_OBJ(const std::string&, Graph&)\endlink Polygon Soup Any point + polygon range - \link PkgStreamSupportIoFuncsOBJ CGAL::IO::read_OBJ(const char*, PointRange&, PolygonRange&)\endlink + \link PkgStreamSupportIoFuncsOBJ CGAL::IO::read_OBJ(const std::string&, PointRange&, PolygonRange&)\endlink Output Polygon Mesh Any model of `FaceGraph` - \link PkgBGLIoFuncsOBJ CGAL::IO::write_OBJ(const char*, Graph&)\endlink + \link PkgBGLIoFuncsOBJ CGAL::IO::write_OBJ(const std::string&, Graph&)\endlink Polygon Soup Any point + polygon range - \link PkgStreamSupportIoFuncsOBJ CGAL::IO::write_OBJ(const char*, PointRange&, PolygonRange&)\endlink + \link PkgStreamSupportIoFuncsOBJ CGAL::IO::write_OBJ(const std::string&, PointRange&, PolygonRange&)\endlink @@ -158,23 +158,23 @@ A precise specification of those formats is available Input Polygon Mesh Any model of `MutableFaceGraph` - \link PkgBGLIoFuncsSTL CGAL::IO::read_STL(const char*, Graph&)\endlink + \link PkgBGLIoFuncsSTL CGAL::IO::read_STL(const std::string&, Graph&)\endlink Polygon Soup Any point + polygon range - \link PkgStreamSupportIoFuncsSTL CGAL::IO::read_STL(const char*, PointRange&, TriangleRange&)\endlink + \link PkgStreamSupportIoFuncsSTL CGAL::IO::read_STL(const std::string&, PointRange&, TriangleRange&)\endlink Output Polygon Mesh Any model of `FaceGraph` - \link PkgBGLIoFuncsSTL CGAL::IO::write_STL(const char*, Graph&)\endlink + \link PkgBGLIoFuncsSTL CGAL::IO::write_STL(const std::string&, Graph&)\endlink Polygon Soup Any point + polygon range - \link PkgStreamSupportIoFuncsSTL CGAL::IO::write_STL(const char*, PointRange&, TriangleRange&)\endlink + \link PkgStreamSupportIoFuncsSTL CGAL::IO::write_STL(const std::string&, PointRange&, TriangleRange&)\endlink @@ -202,49 +202,49 @@ A precise specification of those formats is available Input Polygon Mesh `CGAL::Surface_mesh` - \link PkgSurfaceMeshIOFuncPLY CGAL::IO::read_PLY(const char*, CGAL::Surface_mesh&)\endlink + \link PkgSurfaceMeshIOFuncPLY CGAL::IO::read_PLY(const std::string&, CGAL::Surface_mesh&)\endlink Any model of `MutableFaceGraph` - \link PkgBGLIoFuncsPLY CGAL::IO::read_PLY(const char*, Graph&)\endlink + \link PkgBGLIoFuncsPLY CGAL::IO::read_PLY(const std::string&, Graph&)\endlink Point Set `CGAL::Point_set_3` - \link PkgPointSet3IOPLY CGAL::IO::read_PLY(const char*, CGAL::Point_set_3&)\endlink + \link PkgPointSet3IOPLY CGAL::IO::read_PLY(const std::string&, CGAL::Point_set_3&)\endlink Any point range - \link PkgPointSetProcessing3IOPly CGAL::IO::read_PLY(const char*, PointRange&)\endlink + \link PkgPointSetProcessing3IOPly CGAL::IO::read_PLY(const std::string&, PointRange&)\endlink Polygon Soup Any point + polygon range - \link PkgStreamSupportIoFuncsPLY CGAL::IO::read_PLY(const char*, PointRange&, PolygonRange&)\endlink + \link PkgStreamSupportIoFuncsPLY CGAL::IO::read_PLY(const std::string&, PointRange&, PolygonRange&)\endlink Output Polygon Mesh `CGAL::Surface_mesh` - \link PkgSurfaceMeshIOFuncPLY CGAL::IO::write_PLY(const char*, CGAL::Surface_mesh&)\endlink + \link PkgSurfaceMeshIOFuncPLY CGAL::IO::write_PLY(const std::string&, CGAL::Surface_mesh&)\endlink Any model of `FaceGraph` - \link PkgBGLIoFuncsPLY CGAL::IO::write_PLY(const char*, Graph&)\endlink + \link PkgBGLIoFuncsPLY CGAL::IO::write_PLY(const std::string&, Graph&)\endlink Point Set `CGAL::Point_set_3` - \link PkgPointSet3IOPLY CGAL::IO::write_PLY(const char*, CGAL::Point_set_3&)\endlink + \link PkgPointSet3IOPLY CGAL::IO::write_PLY(const std::string&, CGAL::Point_set_3&)\endlink Any point range - \link PkgPointSetProcessing3IOPly CGAL::IO::write_PLY(const char*, PointRange&)\endlink + \link PkgPointSetProcessing3IOPly CGAL::IO::write_PLY(const std::string&, PointRange&)\endlink Polygon Soup Any point + polygon range - \link PkgStreamSupportIoFuncsPLY CGAL::IO::write_PLY(const char*, PointRange&, PolygonRange&)\endlink + \link PkgStreamSupportIoFuncsPLY CGAL::IO::write_PLY(const std::string&, PointRange&, PolygonRange&)\endlink @@ -270,21 +270,21 @@ A precise specification of those formats is available Input Point Set `CGAL::Point_set_3` - \link PkgPointSet3IOLAS CGAL::IO::read_LAS(const char*, CGAL::Point_set_3&)\endlink + \link PkgPointSet3IOLAS CGAL::IO::read_LAS(const std::string&, CGAL::Point_set_3&)\endlink Any point range - \link PkgPointSetProcessing3IOLas CGAL::IO::read_LAS(const char*, PointRange&)\endlink + \link PkgPointSetProcessing3IOLas CGAL::IO::read_LAS(const std::string&, PointRange&)\endlink Output Point Set `CGAL::Point_set_3` - \link PkgPointSet3IOLAS CGAL::IO::write_LAS(const char*, CGAL::Point_set_3&)\endlink + \link PkgPointSet3IOLAS CGAL::IO::write_LAS(const std::string&, CGAL::Point_set_3&)\endlink Any point range - \link PkgPointSetProcessing3IOLas CGAL::IO::write_LAS(const char*, PointRange&)\endlink + \link PkgPointSetProcessing3IOLas CGAL::IO::write_LAS(const std::string&, PointRange&)\endlink @@ -303,21 +303,21 @@ of its coordinates and other properties. Only coordinates and normals are curren Input Point Set `CGAL::Point_set_3` - \link PkgPointSet3IOXYZ CGAL::IO::read_XYZ(const char*, CGAL::Point_set_3&)\endlink + \link PkgPointSet3IOXYZ CGAL::IO::read_XYZ(const std::string&, CGAL::Point_set_3&)\endlink Any point range - \link PkgPointSetProcessing3IOXyz CGAL::IO::read_XYZ(const char*, PointRange&)\endlink + \link PkgPointSetProcessing3IOXyz CGAL::IO::read_XYZ(const std::string&, PointRange&)\endlink Output Point Set `CGAL::Point_set_3` - \link PkgPointSet3IOXYZ CGAL::IO::write_XYZ(const char*, CGAL::Point_set_3&)\endlink + \link PkgPointSet3IOXYZ CGAL::IO::write_XYZ(const std::string&, CGAL::Point_set_3&)\endlink Any point range - \link PkgPointSetProcessing3IOXyz CGAL::IO::write_XYZ(const char*, PointRange&)\endlink + \link PkgPointSetProcessing3IOXyz CGAL::IO::write_XYZ(const std::string&, PointRange&)\endlink @@ -337,23 +337,23 @@ A precise specification of the format is available Input Polygon Mesh Any model of `MutableFaceGraph` - \link PkgBGLIoFuncsGOCAD CGAL::IO::read_GOCAD(const char*, Graph&)\endlink + \link PkgBGLIoFuncsGOCAD CGAL::IO::read_GOCAD(const std::string&, Graph&)\endlink Polygon Soup Any point + polygon range - \link PkgStreamSupportIoFuncsGOCAD CGAL::IO::read_GOCAD(const char*, PointRange&, PolygonRange&)\endlink + \link PkgStreamSupportIoFuncsGOCAD CGAL::IO::read_GOCAD(const std::string&, PointRange&, PolygonRange&)\endlink Output Polygon Mesh Any model of `FaceGraph` - \link PkgBGLIoFuncsGOCAD CGAL::IO::write_GOCAD(const char*, Graph&)\endlink + \link PkgBGLIoFuncsGOCAD CGAL::IO::write_GOCAD(const std::string&, Graph&)\endlink Polygon Soup Any point + polygon range - \link PkgStreamSupportIoFuncsGOCAD CGAL::IO::write_GOCAD(const char*, PointRange&, PolygonRange&)\endlink + \link PkgStreamSupportIoFuncsGOCAD CGAL::IO::write_GOCAD(const std::string&, PointRange&, PolygonRange&)\endlink @@ -381,23 +381,23 @@ note that only versions `1.x` are currently supported in \cgal. Input Polygon Mesh `CGAL::Surface_mesh` - \link PkgSurfaceMeshIOFunc3MF CGAL::IO::read_3MF(const char*, Surface_meshRange&)\endlink + \link PkgSurfaceMeshIOFunc3MF CGAL::IO::read_3MF(const std::string&, Surface_meshRange&)\endlink Polygon Soup Any point + polygon range - \link PkgStreamSupportIoFuncs3MF CGAL::IO::read_3MF(const char*, PointRanges&, PolygonRanges&)\endlink + \link PkgStreamSupportIoFuncs3MF CGAL::IO::read_3MF(const std::string&, PointRanges&, PolygonRanges&)\endlink Output Polygon Mesh Any model of `FaceGraph` - \link PkgBGLIoFuncs3MF CGAL::IO::write_3MF(const char*, GraphRange&)\endlink + \link PkgBGLIoFuncs3MF CGAL::IO::write_3MF(const std::string&, GraphRange&)\endlink Polygon Soup Any point + polygon range - \link PkgStreamSupportIoFuncs3MF CGAL::IO::write_3MF(const char*, PointRanges&, PolygonRanges&)\endlink + \link PkgStreamSupportIoFuncs3MF CGAL::IO::write_3MF(const std::string&, PointRanges&, PolygonRanges&)\endlink @@ -416,13 +416,13 @@ A precise specification of the format is available - 3D Manufacturing Format (3MF) + 3D VRML Format (WRL) Output Polygon Mesh Any model of `FaceGraph` - \link PkgBGLIoFuncsWRL CGAL::IO::write_WRL(const char*, Graph&)\endlink + \link PkgBGLIoFuncsWRL CGAL::IO::write_WRL(const std::string&, Graph&)\endlink @@ -447,23 +447,18 @@ A precise specification of those formats is available at - + - - - - - - + - + From 79262a365eef6ce6cb2ca7191078cd64f604b108 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 7 Dec 2023 11:56:06 +0000 Subject: [PATCH 261/329] polish --- .../Stream_support/File_formats/Supported_file_formats.txt | 6 ++++-- Stream_support/include/CGAL/IO/VTK.h | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt b/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt index a1c15f1826f6..f626a2881c1f 100644 --- a/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt +++ b/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt @@ -426,7 +426,7 @@ A precise specification of the format is available VTK Libraries, it is the format - reserved to store `PolyData`, and in \cgal, we use it to store Polygon Meshes. + reserved to store `PolyData`, and in \cgal, we use it to store polygon meshes. + +We additionally provide a read function for the legacy non-XML file `VTK` file format for polygon meshes. A precise specification of those formats is available at vtk.org. diff --git a/Stream_support/include/CGAL/IO/VTK.h b/Stream_support/include/CGAL/IO/VTK.h index d0f605834db2..304987556980 100644 --- a/Stream_support/include/CGAL/IO/VTK.h +++ b/Stream_support/include/CGAL/IO/VTK.h @@ -174,7 +174,7 @@ bool read_VTK(const std::string& fname, /*! * \ingroup PkgStreamSupportIoFuncsVTP * - * \brief reads the content of the input file into `points` and `polygons`, using the \ref IOStreamVTK. + * \brief reads the content of the input file into `points` and `polygons`, using the legacy file format of the \ref IOStreamVTK. * * \attention The polygon soup is not cleared, and the data from the file are appended. * From 0991fc9d614dd06faec523e6eb4111d608c19b33 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 7 Dec 2023 12:53:39 +0000 Subject: [PATCH 262/329] fix tag --- .../File_formats/Supported_file_formats.txt | 10 +++++----- Stream_support/doc/Stream_support/IOstream.txt | 4 ++-- .../doc/Stream_support/PackageDescription.txt | 4 ++-- Stream_support/include/CGAL/IO/VTK.h | 8 ++++---- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt b/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt index f626a2881c1f..2eb124c86a7d 100644 --- a/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt +++ b/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt @@ -442,7 +442,7 @@ The VTK libraries use different file formats to handle data structures, but we o In the VTK Libraries, it is the format reserved to store `PolyData`, and in \cgal, we use it to store polygon meshes. -We additionally provide a read function for the legacy non-XML file `VTK` file format for polygon meshes. +We additionally provide a read function for the legacy non-XML `VTK` file format for polygon meshes. A precise specification of those formats is available at vtk.org. @@ -455,23 +455,23 @@ A precise specification of those formats is available at - + - + - + - +
VTK (VTU / VTP) File FormatsVTK (VTU / VTP / legacy) File Formats
Input Polygon Mesh Any model of `MutableFaceGraph`\link PkgBGLIoFuncsVTP CGAL::IO::read_VTP(const std::string&, Graph&)\endlink
Polygon SoupAny point + polygon range\link PkgStreamSupportIoFuncsVTP CGAL::IO::read_VTP(const std::string&, PointRange&, PolygonRange&)\endlink\link PkgBGLIoFuncsVTP CGAL::IO::read_VTP(const std::string&, Graph&)\endlink
Polygon Soup Any point + polygon range\link PkgStreamSupportIoFuncsVTP CGAL::IO::read_VTK(const std::string&, PointRange&, PolygonRange&)\endlink\link PkgStreamSupportIoFuncsVTP CGAL::IO::read_VTP(const std::string&, PointRange&, PolygonRange&)\endlink,
\link PkgStreamSupportIoFuncsVTP CGAL::IO::read_VTK(const std::string&, PointRange&, PolygonRange&)\endlink
OutputInput Polygon Mesh Any model of `MutableFaceGraph`\link PkgBGLIoFuncsVTP CGAL::IO::read_VTP(const std::string&, Graph&)\endlink\link PkgBGLIoFuncsVTK CGAL::IO::read_VTP(const std::string&, Graph&)\endlink
Polygon Soup Any point + polygon range\link PkgStreamSupportIoFuncsVTP CGAL::IO::read_VTP(const std::string&, PointRange&, PolygonRange&)\endlink,
\link PkgStreamSupportIoFuncsVTP CGAL::IO::read_VTK(const std::string&, PointRange&, PolygonRange&)\endlink
\link PkgStreamSupportIoFuncsVTK CGAL::IO::read_VTP(const std::string&, PointRange&, PolygonRange&)\endlink,
\link PkgStreamSupportIoFuncsVTK CGAL::IO::read_VTK(const std::string&, PointRange&, PolygonRange&)\endlink
Output Polygon Mesh Any model of `FaceGraph`\link PkgBGLIoFuncsVTP CGAL::IO::write_VTP(const std::string&, Graph&)\endlink\link PkgBGLIoFuncsVTK CGAL::IO::write_VTP(const std::string&, Graph&)\endlink
Polygon Soup Any point + polygon range\link PkgStreamSupportIoFuncsVTP CGAL::IO::write_VTP(const std::string&, const PointRange&, const PolygonRange&)\endlink\link PkgStreamSupportIoFuncsVTK CGAL::IO::write_VTP(const std::string&, const PointRange&, const PolygonRange&)\endlink
diff --git a/Stream_support/doc/Stream_support/IOstream.txt b/Stream_support/doc/Stream_support/IOstream.txt index be0f7ee02a9a..7d11ad3d16ad 100644 --- a/Stream_support/doc/Stream_support/IOstream.txt +++ b/Stream_support/doc/Stream_support/IOstream.txt @@ -386,7 +386,7 @@ their indices per face (i.e a vector of 3 integers represent a triangle face). \link PkgStreamSupportIoFuncsOBJ `read_OBJ()` \endlink \link PkgStreamSupportIoFuncsSTL `read_STL()` \endlink \link PkgStreamSupportIoFuncsPLY `read_PLY()` \endlink - \link PkgStreamSupportIoFuncsVTP `read_VTP()` \endlink + \link PkgStreamSupportIoFuncsVTK `read_VTP()` \endlink \link PkgStreamSupportIoFuncsGOCAD `read_GOCAD()` \endlink \link PkgStreamSupportIoFuncsWKT `read_WKT()` \endlink \link PkgStreamSupportIoFuncs3MF `read_3MF()` \endlink @@ -398,7 +398,7 @@ their indices per face (i.e a vector of 3 integers represent a triangle face). \link PkgStreamSupportIoFuncsOBJ `write_OBJ()` \endlink \link PkgStreamSupportIoFuncsSTL `write_STL()` \endlink \link PkgStreamSupportIoFuncsPLY `write_PLY()` \endlink - \link PkgStreamSupportIoFuncsVTP `write_VTP()` \endlink + \link PkgStreamSupportIoFuncsVTK `write_VTP()` \endlink \link PkgStreamSupportIoFuncsGOCAD `write_GOCAD()` \endlink \link PkgStreamSupportIoFuncsWKT `write_WKT()` \endlink \link PkgStreamSupportIoFuncs3MF `write_3MF()` \endlink diff --git a/Stream_support/doc/Stream_support/PackageDescription.txt b/Stream_support/doc/Stream_support/PackageDescription.txt index c41b35ef5f82..0cacc80c6312 100644 --- a/Stream_support/doc/Stream_support/PackageDescription.txt +++ b/Stream_support/doc/Stream_support/PackageDescription.txt @@ -20,7 +20,7 @@ /// I/O Functions for the \ref IOStreamOFF /// \ingroup IOstreamFunctions -/// \defgroup PkgStreamSupportIoFuncsVTP VTK I/O Functions +/// \defgroup PkgStreamSupportIoFuncsVTK VTK I/O Functions /// I/O Functions for the \ref IOStreamVTK /// \ingroup IOstreamFunctions @@ -96,7 +96,7 @@ the printing mode. - \link PkgStreamSupportIoFuncsOBJ I/O for OBJ files \endlink - \link PkgStreamSupportIoFuncsOFF I/O for OFF files \endlink - \link PkgStreamSupportIoFuncsGOCAD I/O for GOCAD files \endlink -- \link PkgStreamSupportIoFuncsVTP I/O for VTP files \endlink +- \link PkgStreamSupportIoFuncsVTK I/O for VTK files \endlink - \link PkgStreamSupportIoFuncs3MF I/O for 3MF files \endlink - \link PkgStreamSupportIoFuncsWKT I/O for WKT files \endlink diff --git a/Stream_support/include/CGAL/IO/VTK.h b/Stream_support/include/CGAL/IO/VTK.h index 304987556980..fd8f7accc45d 100644 --- a/Stream_support/include/CGAL/IO/VTK.h +++ b/Stream_support/include/CGAL/IO/VTK.h @@ -116,7 +116,7 @@ bool read_VTP(const std::string& fname, } /*! - * \ingroup PkgStreamSupportIoFuncsVTP + * \ingroup PkgStreamSupportIoFuncsVTK * * \brief reads the content of the input file into `points` and `polygons`, using the \ref IOStreamVTK. * @@ -172,7 +172,7 @@ bool read_VTK(const std::string& fname, } /*! - * \ingroup PkgStreamSupportIoFuncsVTP + * \ingroup PkgStreamSupportIoFuncsVTK * * \brief reads the content of the input file into `points` and `polygons`, using the legacy file format of the \ref IOStreamVTK. * @@ -398,7 +398,7 @@ void write_soup_polys_points(std::ostream& os, } // namespace internal /*! - * \ingroup PkgStreamSupportIoFuncsVTP + * \ingroup PkgStreamSupportIoFuncsVTK * * \brief writes the content of `points` and `polygons` in `out`, using the \ref IOStreamVTK. * @@ -486,7 +486,7 @@ bool write_VTP(std::ostream& os, } /*! - * \ingroup PkgStreamSupportIoFuncsVTP + * \ingroup PkgStreamSupportIoFuncsVTK * * \brief writes the content of `points` and `polygons` in a file named `fname`, using the \ref IOStreamVTK. * From 08b06ebefc3d144723bd40199303b8a1a12a9587 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 7 Dec 2023 13:16:53 +0000 Subject: [PATCH 263/329] fix tag --- .../Stream_support/File_formats/Supported_file_formats.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt b/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt index 2eb124c86a7d..cfc647bf7268 100644 --- a/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt +++ b/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt @@ -455,7 +455,7 @@ A precise specification of those formats is available at Input Polygon Mesh Any model of `MutableFaceGraph` - \link PkgBGLIoFuncsVTK CGAL::IO::read_VTP(const std::string&, Graph&)\endlink + \link PkgBGLIoFuncsVTP CGAL::IO::read_VTP(const std::string&, Graph&)\endlink Polygon Soup @@ -466,7 +466,7 @@ A precise specification of those formats is available at Output Polygon Mesh Any model of `FaceGraph` - \link PkgBGLIoFuncsVTK CGAL::IO::write_VTP(const std::string&, Graph&)\endlink + \link PkgBGLIoFuncsVTP CGAL::IO::write_VTP(const std::string&, Graph&)\endlink Polygon Soup From 0714c960bb8ebdcc0f1b9a11772cf87d4cd16f8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 7 Dec 2023 16:08:33 +0100 Subject: [PATCH 264/329] reset left event of curves after the deletion of the event --- .../include/CGAL/Surface_sweep_2/Default_subcurve.h | 11 +++++++++++ .../CGAL/Surface_sweep_2/Surface_sweep_2_impl.h | 8 ++++++++ 2 files changed, 19 insertions(+) diff --git a/Surface_sweep_2/include/CGAL/Surface_sweep_2/Default_subcurve.h b/Surface_sweep_2/include/CGAL/Surface_sweep_2/Default_subcurve.h index dd8215e67a1e..1fe4a21a06fb 100644 --- a/Surface_sweep_2/include/CGAL/Surface_sweep_2/Default_subcurve.h +++ b/Surface_sweep_2/include/CGAL/Surface_sweep_2/Default_subcurve.h @@ -104,6 +104,17 @@ class Default_subcurve_base : public: + + void reset_left_event() + { + this->set_left_event(static_cast(nullptr)); + if (m_orig_subcurve1) + { + m_orig_subcurve1->reset_left_event(); + m_orig_subcurve2->reset_left_event(); + } + } + /*! Get the subcurves that originate an overlap. */ Subcurve* originating_subcurve1() { return m_orig_subcurve1; } diff --git a/Surface_sweep_2/include/CGAL/Surface_sweep_2/Surface_sweep_2_impl.h b/Surface_sweep_2/include/CGAL/Surface_sweep_2/Surface_sweep_2_impl.h index 41d961803103..d720f763c574 100644 --- a/Surface_sweep_2/include/CGAL/Surface_sweep_2/Surface_sweep_2_impl.h +++ b/Surface_sweep_2/include/CGAL/Surface_sweep_2/Surface_sweep_2_impl.h @@ -307,6 +307,14 @@ void Surface_sweep_2::_handle_overlaps_in_right_curves() template void Surface_sweep_2::_handle_right_curves() { + + for(Event_subcurve_iterator sc_it = this->m_currentEvent->right_curves_begin(), + sc_it_end = this->m_currentEvent->right_curves_end(); + sc_it!=sc_it_end; ++sc_it) + { + (*sc_it)->reset_left_event(); + } + CGAL_SS_PRINT_START("handling right curves at ("); CGAL_SS_DEBUG(this->PrintEvent(this->m_currentEvent)); CGAL_SS_PRINT_TEXT(")"); From a54f18998063f83ecc8f33b8735cac799383b2ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 7 Dec 2023 16:09:31 +0100 Subject: [PATCH 265/329] Revert "more than one curve can be on the left of an event with overlapping curves on the right" This reverts commit 2260c4fab3756034d8fd80b1bbd7f079cae0b698. --- .../Surface_sweep_2/Surface_sweep_2_impl.h | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/Surface_sweep_2/include/CGAL/Surface_sweep_2/Surface_sweep_2_impl.h b/Surface_sweep_2/include/CGAL/Surface_sweep_2/Surface_sweep_2_impl.h index d720f763c574..cd36570d27b4 100644 --- a/Surface_sweep_2/include/CGAL/Surface_sweep_2/Surface_sweep_2_impl.h +++ b/Surface_sweep_2/include/CGAL/Surface_sweep_2/Surface_sweep_2_impl.h @@ -110,28 +110,19 @@ void Surface_sweep_2::_handle_left_curves() this->m_currentEvent->push_back_curve_to_right(sc); } else { + this->m_currentEvent->push_back_curve_to_left(sc); this->m_currentEvent->set_weak_intersection(); - auto status_line_it = this->m_status_line_insert_hint; - do{ - this->m_currentEvent->push_back_curve_to_left(sc); - this->m_visitor->update_event(this->m_currentEvent, sc); - _add_curve_to_right(this->m_currentEvent, sc); - ++status_line_it; - if (status_line_it==this->m_statusLine.end()) break; - if (this->m_statusLineCurveLess(this->m_currentEvent->point(), *status_line_it)!=EQUAL) - break; - sc = *status_line_it; - } - while(true); // the loop is only needed in case there are overlapping curve in right curves + this->m_visitor->update_event(this->m_currentEvent, sc); + _add_curve_to_right(this->m_currentEvent, sc); } - // some subcurves have been addded on the left + // sc is now on the left CGAL_SS_PRINT_TEXT("Event after update:"); CGAL_SS_PRINT_EOL(); CGAL_SS_PRINT_EVENT_INFO(this->m_currentEvent); CGAL_SS_PRINT_EOL(); CGAL_assertion(std::distance(this->m_currentEvent->left_curves_begin(), - this->m_currentEvent->left_curves_end())!=0); + this->m_currentEvent->left_curves_end())==1); } else { // The event is not located on any subcurve. From bcdc0f9f92093d0356afa3d3017150badd6ee74f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 8 Dec 2023 11:45:25 +0100 Subject: [PATCH 266/329] remove non needed include --- .../examples/Polygon_mesh_processing/soup_autorefinement.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp index a44d47c8b6d1..5baea1a3964d 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp @@ -1,6 +1,4 @@ #include -#include - #include #include #include From d620bcd61a7d7f05946f6bd6173a3b1fea917473 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 8 Dec 2023 13:20:23 +0100 Subject: [PATCH 267/329] user manual --- .../Polygon_mesh_processing.txt | 13 +++++++++++++ .../doc/Polygon_mesh_processing/examples.txt | 1 + 2 files changed, 14 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 00ccfd382f66..6a658a5829f2 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 @@ -864,6 +864,19 @@ vertices at identical positions, can be used to repair this configuration. \section PMPGeometricRepair Geometric Repair **************************************** +\subsection PMPAutoref Self-intersection Resolution (Autorefinement) in Triangle Soups +Given a soup of triangles, a self-intersection is defined as the intersection of two triangles from the soup +such that the intersection is not defined by the convex hull of one, two or three shared vertices. +In other words, it is an intersection that happens in the interior of one of the two triangles, or in the interior +of one their edges, except if identical points are associated to different vertices of the triangle soup which +would then also includes overlaps of duplicated points. + +The function `CGAL::Polygon_mesh_processing::autorefine_triangle_soup()` provides a way to refine a triangle soup +using the intersections of the triangles from the soup. In particular, if some points are duplicated they will be +merged. Note that if a kernel with exact predicates but inexact constructions is used, some new self-intersections +might be introduced due to rounding issues of points coordinates. +To guarantee that the triangle soup is free from self-intersections, a kernel with exact constructions must be used. + \subsection PMPRemoveCapsNeedles Removal of Almost Degenerate Triangle Faces Triangle faces of a mesh made up of almost collinear points are badly shaped elements that might not be desirable to have in a mesh. The function diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt index 146e1261ff41..c582dc76739b 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt @@ -43,4 +43,5 @@ \example Polygon_mesh_processing/cc_compatible_orientations.cpp \example Polygon_mesh_processing/remesh_planar_patches.cpp \example Polygon_mesh_processing/remesh_almost_planar_patches.cpp +\example Polygon_mesh_processing/soup_autorefinement.cpp */ From 9ac0ef686f157c9311bc5ea969abc1320992e7d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 8 Dec 2023 13:24:55 +0100 Subject: [PATCH 268/329] aspell check --- .../doc/Polygon_mesh_processing/Polygon_mesh_processing.txt | 4 ++-- 1 file changed, 2 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 6a658a5829f2..d52fd823cd4f 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 @@ -214,7 +214,7 @@ it can try to equalize the angles between incident edges, or (and) move vertices Border vertices are considered constrained and do not move at any step of the procedure. No vertices are inserted at any time. Angle and area smoothing algorithms are based on Surazhsky and Gotsman \cgalCite{cgal:sg-hqct-04}. Since area smoothing considers only areas as a smoothing criterion, it may result in long and skinny -triangles. To paliate this phenomenon, area smoothing is followed by an (optional) step of Delaunay-based edge flips. +triangles. To palliate this phenomenon, area smoothing is followed by an (optional) step of Delaunay-based edge flips. In any case, area smoothing is guaranteed to improve the spatial distribution of the vertices over the area that is being smoothed. A simple example can be found in \ref Polygon_mesh_processing/mesh_smoothing_example.cpp. @@ -434,7 +434,7 @@ depicted in red); (iii) `clip_volume=true`: clipping of the volume bounded by th \cgalFigureEnd \cgalFigureBegin{coref_clip_compact, clip_compact.png} -Clipping a cube with a halfspace: compacity of the clipper (`clip_volume=false` in both cases). +Clipping a cube with a halfspace: compactivity of the clipper (`clip_volume=false` in both cases). From left to right: (i) initial cube and the plane defining the clipping halfspace, note that a whole face of the cube (2 triangles) is exactly contained in the plane; (ii) `use_compact_clipper=true`: clipping of the surface mesh with a compact halfspace: coplanar faces are part of the output; From e352f2b17c0d871f56f9829bdd7a0c0ca60473fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 8 Dec 2023 13:27:04 +0100 Subject: [PATCH 269/329] fix doc --- .../Concepts/PMPAutorefinementVisitor.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPAutorefinementVisitor.h b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPAutorefinementVisitor.h index e3ef90e9be03..ef2f124329b5 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPAutorefinementVisitor.h +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Concepts/PMPAutorefinementVisitor.h @@ -6,7 +6,9 @@ /// the creation of new triangles. /// /// \cgalRefines{CopyConstructible} -/// \cgalHasModel `CGAL::Polygon_mesh_processing::Autorefinement::Default_visitor`. +/// \cgalHasModelsBegin +/// \cgalHasModels{CGAL::Polygon_mesh_processing::Autorefinement::Default_visitor} +/// \cgalHasModelsEnd class PMPAutorefinementVisitor{ public: From b0361f7e147f417b99f7fd6a8dbeef72666a7d86 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Fri, 8 Dec 2023 13:51:47 +0100 Subject: [PATCH 270/329] set_index(v) must be able dimension -1 to deal with far points far points inserted by concurrent Mesh_3 --- .../internal/tetrahedral_remeshing_helpers.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_remeshing_helpers.h b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_remeshing_helpers.h index 09787f05dfdd..9ea06ce7d4ee 100644 --- a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_remeshing_helpers.h +++ b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_remeshing_helpers.h @@ -568,6 +568,8 @@ void set_index(typename C3t3::Vertex_handle v, const C3t3& c3t3) case 0: v->set_index(Mesh_3::internal::get_index(v->index())); break; + case -1://far points from concurrent Mesh_3 + break; default: CGAL_assertion(false); } @@ -1289,6 +1291,18 @@ void check_surface_patch_indices(const C3t3& c3t3) } } +template +void count_far_points(const C3t3& c3t3) +{ + std::size_t count = 0; + for (auto v : c3t3.triangulation().finite_vertex_handles()) + { + if(c3t3.in_dimension(v) == -1) + ++count; + } + std::cout << "Nb far points : " << count << std::endl; +} + template bool are_cell_orientations_valid(const Tr& tr) { @@ -1699,13 +1713,17 @@ void dump_vertices_by_dimension(const Tr& tr, const char* prefix) typedef typename Tr::Vertex_handle Vertex_handle; std::vector< std::vector > vertices_per_dimension(4); + std::size_t nb_far_points = 0; for (typename Tr::Finite_vertices_iterator vit = tr.finite_vertices_begin(); vit != tr.finite_vertices_end(); ++vit) { if (vit->in_dimension() == -1) + { + ++nb_far_points; continue;//far point + } CGAL_assertion(vit->in_dimension() >= 0 && vit->in_dimension() < 4); vertices_per_dimension[vit->in_dimension()].push_back(vit); @@ -1733,6 +1751,7 @@ void dump_vertices_by_dimension(const Tr& tr, const char* prefix) ofs.close(); } + std::cout << "Nb far points : " << nb_far_points << std::endl; } template From 2874c2be608c6c97d62c21116ec3550cb2672b41 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Fri, 8 Dec 2023 13:52:09 +0100 Subject: [PATCH 271/329] add debug counting far points --- .../internal/tetrahedral_adaptive_remeshing_impl.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_adaptive_remeshing_impl.h b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_adaptive_remeshing_impl.h index 64e1db2ca603..f07a0a2d793d 100644 --- a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_adaptive_remeshing_impl.h +++ b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_adaptive_remeshing_impl.h @@ -530,6 +530,7 @@ class Adaptive_remesher CGAL::Tetrahedral_remeshing::debug::dump_vertices_by_dimension( m_c3t3.triangulation(), "0-c3t3_vertices_after_init_"); CGAL::Tetrahedral_remeshing::debug::check_surface_patch_indices(m_c3t3); + CGAL::Tetrahedral_remeshing::debug::count_far_points(m_c3t3); #endif } From 8d0a047685cfea8e1d2f272efe8aa8468b93b5c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 8 Dec 2023 14:22:41 +0100 Subject: [PATCH 272/329] remote debug code and abandonned alternatives --- .../Polygon_mesh_processing/autorefinement.h | 512 +++--------------- 1 file changed, 63 insertions(+), 449 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index d25ea95fe905..bb81855edd55 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -26,7 +26,7 @@ #include #include -#ifdef USE_PROGRESS_DISPLAY +#ifdef CGAL_AUTOREF_USE_PROGRESS_DISPLAY #include #endif @@ -52,29 +52,22 @@ #endif #include #include -#ifdef SET_POINT_IDS_USING_MUTEX +#ifdef CGAL_AUTOREF_SET_POINT_IDS_USING_MUTEX #include #endif #endif #include -#define TEST_RESOLVE_INTERSECTION -#define DEDUPLICATE_SEGMENTS -//#define USE_DEBUG_PARALLEL_TIMERS -//#define DEBUG_COUNTERS -//#define USE_FIXED_PROJECTION_TRAITS -//#define DEBUG_DEPTH +//#define CGAL_AUTOREF_USE_DEBUG_PARALLEL_TIMERS +//#define CGAL_AUTOREFINE_DEBUG_COUNTERS +//#define CGAL_AUTOREF_DEBUG_DEPTH -#ifdef USE_DEBUG_PARALLEL_TIMERS +#ifdef CGAL_AUTOREF_USE_DEBUG_PARALLEL_TIMERS #include #endif -#ifdef USE_FIXED_PROJECTION_TRAITS -#include -#endif - -#if defined(DEBUG_COUNTERS) || defined(USE_DEBUG_PARALLEL_TIMERS) +#if defined(CGAL_AUTOREFINE_DEBUG_COUNTERS) || defined(CGAL_AUTOREF_USE_DEBUG_PARALLEL_TIMERS) #include #endif @@ -123,20 +116,11 @@ Segment_inter_type do_coplanar_segments_intersect(std::size_t pi, std::size_t qi, std::size_t ri, std::size_t si, const std::vector& points, - const typename K::Vector_3& plane_normal, + const typename K::Vector_3& /* plane_normal */, const K& k = K()) { typename K::Collinear_are_ordered_along_line_3 cln_order = k.collinear_are_ordered_along_line_3_object(); -#ifdef USE_PROJECTED_ORIENTATION_2_FOR_COPLANAR_ORIENTATION_TESTS - auto cpl_orient = - [&plane_normal](const typename K::Point_3& p, const typename K::Point_3& q, const typename K::Point_3& r) - { - return ::CGAL::orientation(q-p, r-p, plane_normal); - }; -#else typename K::Coplanar_orientation_3 cpl_orient=k.coplanar_orientation_3_object(); - CGAL_USE(plane_normal); -#endif const typename K::Point_3& p=points[pi]; const typename K::Point_3& q=points[qi]; @@ -267,75 +251,6 @@ do_coplanar_segments_intersect(std::size_t pi, std::size_t qi, return NO_INTERSECTION; } -////////////////////////////////// -////////////////////////////////// -////////////////////////////////// -////////////////////////////////// -////////////////////////////////// - -#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION -template -void old_intersection_coplanar_triangles_cutoff(const typename Kernel::Point_3& p, - const typename Kernel::Point_3& q, - const typename Kernel::Point_3& r, - const Kernel& k, - std::list& inter_pts) -{ - typedef typename std::list::iterator Iterator; - - if(inter_pts.empty()) - return; - - typename Kernel::Coplanar_orientation_3 orient = k.coplanar_orientation_3_object(); - typename Kernel::Construct_line_3 line = k.construct_line_3_object(); - - //orient(p,q,r,r) is POSITIVE - std::map orientations; - for (Iterator it=inter_pts.begin();it!=inter_pts.end();++it) - orientations[ &(*it) ]=orient(p,q,r,*it); - - CGAL_kernel_assertion_code(int pt_added = 0;) - - const typename Kernel::Point_3* prev = &(*std::prev(inter_pts.end())); - Iterator stop = inter_pts.size() > 2 ? inter_pts.end() : std::prev(inter_pts.end()); - for(Iterator it=inter_pts.begin(); it!=stop; ++it) - { - const typename Kernel::Point_3& curr = *it; - Orientation or_prev = orientations[prev], - or_curr = orientations[&curr]; - - if((or_prev == POSITIVE && or_curr == NEGATIVE) || - (or_prev == NEGATIVE && or_curr == POSITIVE)) - { - typename Intersection_traits::result_type - obj = ::CGAL::Intersections::internal::intersection(line(p,q), line(*prev,curr), k); - - // assert "not empty" - CGAL_kernel_assertion(bool(obj)); - - const typename Kernel::Point_3* inter = ::CGAL::Intersections::internal::intersect_get(obj); - CGAL_kernel_assertion(inter != nullptr); - - prev = &(*inter_pts.insert(it,*inter)); - orientations[prev] = COLLINEAR; - CGAL_kernel_assertion_code(++pt_added;) - } - - prev = &(*it); - } - - CGAL_kernel_assertion(pt_added<3); - Iterator it = inter_pts.begin(); - while(it!=inter_pts.end()) - { - if(orientations[&(*it)] == NEGATIVE) - inter_pts.erase(it++); - else - ++it; - } -} -#endif - // imported from Intersections_3/include/CGAL/Intersections_3/internal/Triangle_3_Triangle_3_intersection.h template void coplanar_intersections(const std::array& t1, @@ -350,146 +265,14 @@ void coplanar_intersections(const std::array& t1, l_inter_pts.push_back(Intersections::internal::Point_on_triangle(-1,1)); l_inter_pts.push_back(Intersections::internal::Point_on_triangle(-1,2)); -#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION - std::list old_l_inter_pts; - old_l_inter_pts.push_back(p2); - old_l_inter_pts.push_back(q2); - old_l_inter_pts.push_back(r2); - - - auto enum_to_string = [](CGAL::Orientation o) - { - if (o==COLLINEAR) return std::string("COLLINEAR"); - if (o==POSITIVE) return std::string("POSITIVE"); - return std::string("NEGATIVE"); - }; - - auto to_string = [](const auto& t) - { - std::stringstream sstr; - sstr << "4 " - << to_double(t[0].x()) << " " << to_double(t[0].y()) << " " << to_double(t[0].z()) << " " - << to_double(t[1].x()) << " " << to_double(t[1].y()) << " " << to_double(t[1].z()) << " " - << to_double(t[2].x()) << " " << to_double(t[2].y()) << " " << to_double(t[2].z()) << " " - << to_double(t[0].x()) << " " << to_double(t[0].y()) << " " << to_double(t[0].z()) << "\n"; - return sstr.str(); - }; - - std::cout << "intersection_coplanar_triangles\n"; - std::ofstream("/tmp/t1.polylines.txt") << to_string(t1) << "\n"; - std::ofstream("/tmp/t2.polylines.txt") << to_string(t2) << "\n"; - - std::cout << "Position of vertices of t1: "; - std::cout << enum_to_string( coplanar_orientation(p2,q2,r2,p1)) << " - "; - std::cout << enum_to_string( coplanar_orientation(p2,q2,r2,q1)) << " - "; - std::cout << enum_to_string( coplanar_orientation(p2,q2,r2,r1)) << "\n"; - std::cout << " "; - std::cout << enum_to_string( coplanar_orientation(q2,r2,p2,p1)) << " - "; - std::cout << enum_to_string( coplanar_orientation(q2,r2,p2,q1)) << " - "; - std::cout << enum_to_string( coplanar_orientation(q2,r2,p2,r1)) << "\n"; - std::cout << " "; - std::cout << enum_to_string( coplanar_orientation(r2,p2,q2,p1)) << " - "; - std::cout << enum_to_string( coplanar_orientation(r2,p2,q2,q1)) << " - "; - std::cout << enum_to_string( coplanar_orientation(r2,p2,q2,r1)) << "\n"; - std::cout << "Position of vertices of t2: "; - std::cout << enum_to_string( coplanar_orientation(p1,q1,r1,p2)) << " - "; - std::cout << enum_to_string( coplanar_orientation(p1,q1,r1,q2)) << " - "; - std::cout << enum_to_string( coplanar_orientation(p1,q1,r1,r2)) << "\n"; - std::cout << " "; - std::cout << enum_to_string( coplanar_orientation(q1,r1,p1,p2)) << " - "; - std::cout << enum_to_string( coplanar_orientation(q1,r1,p1,q2)) << " - "; - std::cout << enum_to_string( coplanar_orientation(q1,r1,p1,r2)) << "\n"; - std::cout << " "; - std::cout << enum_to_string( coplanar_orientation(r1,p1,q1,p2)) << " - "; - std::cout << enum_to_string( coplanar_orientation(r1,p1,q1,q2)) << " - "; - std::cout << enum_to_string( coplanar_orientation(r1,p1,q1,r2)) << "\n"; - - auto print_points = [&]() - { - for(auto p : l_inter_pts) std::cout << " (" << p.id1() << "," << p.id2() << ",[" << p.alpha << "]) "; std::cout <<"\n"; - }; - std::cout << " ipts size: " << l_inter_pts.size() << "\n"; - print_points(); -#endif - //intersect t2 with the three half planes which intersection defines t1 K k; Intersections::internal::intersection_coplanar_triangles_cutoff(p1,q1,r1,0,p2,q2,r2,k,l_inter_pts); //line p1q1 -#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION - std::cout << " ipts size: " << l_inter_pts.size() << "\n"; - print_points(); - old_intersection_coplanar_triangles_cutoff(p1,q1,r1,k,old_l_inter_pts); - CGAL_assertion(l_inter_pts.size()==old_l_inter_pts.size()); - for (std::size_t i=0; ipoint(p1,q1,r1,p2,q2,r2,k)) - { - std::cout <<"ERROR with point #" << i << "\n"; - throw std::runtime_error("invalid output 0"); - } - } -#endif Intersections::internal::intersection_coplanar_triangles_cutoff(q1,r1,p1,1,p2,q2,r2,k,l_inter_pts); //line q1r1 -#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION - std::cout << " ipts size: " << l_inter_pts.size() << "\n"; - print_points(); - old_intersection_coplanar_triangles_cutoff(q1,r1,p1,k,old_l_inter_pts); - CGAL_assertion(l_inter_pts.size()==old_l_inter_pts.size()); - for (std::size_t i=0; ipoint(p1,q1,r1,p2,q2,r2,k)) - { - std::cout <<"ERROR with point #" << i << "\n"; - throw std::runtime_error("invalid output 1"); - } - } -#endif Intersections::internal::intersection_coplanar_triangles_cutoff(r1,p1,q1,2,p2,q2,r2,k,l_inter_pts); //line r1p1 -#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION - std::cout << " ipts size: " << l_inter_pts.size() << "\n"; - print_points(); - old_intersection_coplanar_triangles_cutoff(r1,p1,q1,k,old_l_inter_pts); - CGAL_assertion(l_inter_pts.size()==old_l_inter_pts.size()); - for (std::size_t i=0; ipoint(p1,q1,r1,p2,q2,r2,k)) - { - std::cout <<"ERROR with point #" << i << "\n"; - throw std::runtime_error("invalid output 2"); - } - } -#endif - -#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION - std::size_t start=inter_pts.size(); -#endif for (const Intersections::internal::Point_on_triangle& pot : l_inter_pts) inter_pts.push_back( pot.point(p1,q1,r1,p2,q2,r2,k) ); - -#ifdef CGAL_DEBUG_COPLANAR_T3_T3_INTERSECTION - for (std::size_t i=0; i> i; -#endif - } // imported from Polygon_mesh_processing/internal/Corefinement/intersect_triangle_segment_3.h @@ -509,23 +292,6 @@ find_intersection(const typename K::Point_3& p, const typename K::Point_3& q, / int nb_coplanar=(ab==COPLANAR?1:0) + (bc==COPLANAR?1:0) + (ca==COPLANAR?1:0); -/* - if ( nb_coplanar==0 ) - return result_type(ON_FACE,hd,is_src_coplanar,is_tgt_coplanar); - - if (nb_coplanar==1){ - if (ab==COPLANAR) - // intersection is ab - return result_type(ON_EDGE,next(hd,tm),is_src_coplanar,is_tgt_coplanar); - if (bc==COPLANAR) - // intersection is bc - return result_type(ON_EDGE,prev(hd,tm),is_src_coplanar,is_tgt_coplanar); - CGAL_assertion(ca==COPLANAR); - // intersection is ca - return result_type(ON_EDGE,hd,is_src_coplanar,is_tgt_coplanar); - } -*/ - if (is_p_coplanar) { inter_pts.push_back(p); @@ -646,7 +412,7 @@ bool collect_intersections(const std::array& t1, if (ori[0]== COPLANAR && ori[1]==COPLANAR && ori[2]==COPLANAR) { coplanar_intersections(t1, t2, inter_pts); -#ifdef DEBUG_DEPTH +#ifdef CGAL_AUTOREF_DEBUG_DEPTH for (auto p : inter_pts) if (depth(p)>2) throw std::runtime_error("Depth is not 4: "+std::to_string(depth(p))); #endif @@ -674,7 +440,7 @@ bool collect_intersections(const std::array& t1, auto last = std::unique(inter_pts.begin(), inter_pts.end()); inter_pts.erase(last, inter_pts.end()); -#ifdef DEBUG_DEPTH +#ifdef CGAL_AUTOREF_DEBUG_DEPTH for (auto p : inter_pts) if (depth(p)>2) throw std::runtime_error("Depth is not 2: "+std::to_string(depth(p))); #endif @@ -682,16 +448,7 @@ bool collect_intersections(const std::array& t1, return false; } -////////////////////////////////// -////////////////////////////////// -////////////////////////////////// -////////////////////////////////// -////////////////////////////////// - template void generate_subtriangles(std::size_t ti, @@ -704,20 +461,8 @@ void generate_subtriangles(std::size_t ti, PointVector& new_triangles ) { - // std::cout << "generate_subtriangles()\n"; - // std::cout << std::setprecision(17); - -#ifdef USE_FIXED_PROJECTION_TRAITS - typedef ::CGAL::internal::Projection_traits_3 P_traits; -#else typedef CGAL::Projection_traits_3 P_traits; -#endif - -#ifndef TEST_RESOLVE_INTERSECTION - typedef CGAL::Exact_intersections_tag Itag; -#else typedef CGAL::No_constraint_intersection_tag Itag; -#endif typedef CGAL::Constrained_Delaunay_triangulation_2 CDT_2; //typedef CGAL::Constrained_triangulation_plus_2 CDT; @@ -729,15 +474,6 @@ void generate_subtriangles(std::size_t ti, typename EK::Vector_3 n = normal(t[0], t[1], t[2]); typename EK::Point_3 o(CGAL::ORIGIN); -#ifdef USE_FIXED_PROJECTION_TRAITS - P_traits cdt_traits; - bool orientation_flipped = false; - CDT cdt(cdt_traits); - // TODO: still need to figure out why I can't make the orientation_flipped correctly - cdt.insert(t[0]); - cdt.insert(t[1]); - cdt.insert(t[2]); -#else bool orientation_flipped = false; if ( typename EK::Less_xyz_3()(o+n,o) ) { @@ -751,9 +487,8 @@ void generate_subtriangles(std::size_t ti, cdt.insert_outside_affine_hull(t[1]); typename CDT::Vertex_handle v = cdt.tds().insert_dim_up(cdt.infinite_vertex(), orientation_flipped); v->set_point(t[2]); -#endif -#ifdef DEBUG_COUNTERS +#ifdef CGAL_AUTOREFINE_DEBUG_COUNTERS struct Counter { int c1=0; @@ -781,37 +516,11 @@ void generate_subtriangles(std::size_t ti, }; static Counter counter; -#define COUNTER_INSTRUCTION(X) X +#define CGAL_AUTOREF_COUNTER_INSTRUCTION(X) X #else -#define COUNTER_INSTRUCTION(X) +#define CGAL_AUTOREF_COUNTER_INSTRUCTION(X) #endif - -#ifdef TEST_RESOLVE_INTERSECTION - //~ static std::ofstream debug("inter_segments.polylines.txt"); - //~ debug.precision(17); - - //~ std::cout << "points.size() " << points.size() << "\n"; - //~ std::set all_triangles_indices(in_triangle_ids.begin(), in_triangle_ids.end()); - //~ all_triangles_indices.insert(ti); - - //~ std::ofstream debug("triangles.polylines.txt"); - //~ debug << std::setprecision(17); - //~ for (std::size_t i : all_triangles_indices) - //~ debug << "4 " - //~ << triangles[i][0] << " " - //~ << triangles[i][1] << " " - //~ << triangles[i][2] << " " - //~ << triangles[i][0] << "\n"; - //~ debug.close(); - //~ debug.open("triangle.off"); - //~ debug << std::setprecision(17); - //~ debug << "OFF\n3 1 0\n"; - //~ debug << triangles[ti][0] << "\n" - //~ << triangles[ti][1] << "\n" - //~ << triangles[ti][2] << "\n 3 0 1 2\n"; - //~ debug.close(); - // pre-compute segment intersections if (!segments.empty()) { @@ -819,7 +528,7 @@ void generate_subtriangles(std::size_t ti, std::vector< std::vector > points_on_segments(nbs); - COUNTER_INSTRUCTION(counter.timer1.start();) + CGAL_AUTOREF_COUNTER_INSTRUCTION(counter.timer1.start();) std::map point_id_map; @@ -831,7 +540,6 @@ void generate_subtriangles(std::size_t ti, CGAL_assertion(insertion_ok); } - auto get_point_id = [&](const typename EK::Point_3& pt) { auto insert_res = point_id_map.insert(std::make_pair(pt, points.size())); @@ -855,17 +563,17 @@ void generate_subtriangles(std::size_t ti, { if ( !do_overlap(segment_boxes[i], segment_boxes[j]) ) { - COUNTER_INSTRUCTION(++counter.c5;) - COUNTER_INSTRUCTION(++counter.total;) + CGAL_AUTOREF_COUNTER_INSTRUCTION(++counter.c5;) + CGAL_AUTOREF_COUNTER_INSTRUCTION(++counter.total;) continue; } - COUNTER_INSTRUCTION(counter.timer5.start();) + CGAL_AUTOREF_COUNTER_INSTRUCTION(counter.timer5.start();) Segment_inter_type seg_inter_type = do_coplanar_segments_intersect(segments[i].first, segments[i].second, segments[j].first, segments[j].second, points, n); - COUNTER_INSTRUCTION(counter.timer5.stop();) + CGAL_AUTOREF_COUNTER_INSTRUCTION(counter.timer5.stop();) switch(seg_inter_type) { @@ -892,25 +600,25 @@ void generate_subtriangles(std::size_t ti, case POINT_INTERSECTION: { if ( coplanar_triangles.count(CGAL::make_sorted_pair(in_triangle_ids[i], in_triangle_ids[j])) == 0 - && coplanar_triangles.count(CGAL::make_sorted_pair(ti, in_triangle_ids[j])) == 0 - && coplanar_triangles.count(CGAL::make_sorted_pair(in_triangle_ids[i], ti)) == 0) + && coplanar_triangles.count(CGAL::make_sorted_pair(ti, in_triangle_ids[j])) == 0 + && coplanar_triangles.count(CGAL::make_sorted_pair(in_triangle_ids[i], ti)) == 0) { - COUNTER_INSTRUCTION(counter.timer6.start();) + CGAL_AUTOREF_COUNTER_INSTRUCTION(counter.timer6.start();) typename EK::Point_3 pt = typename EK::Construct_planes_intersection_point_3()( triangles[in_triangle_ids[i]][0], triangles[in_triangle_ids[i]][1],triangles[in_triangle_ids[i]][2], triangles[in_triangle_ids[j]][0], triangles[in_triangle_ids[j]][1],triangles[in_triangle_ids[j]][2], triangles[ti][0], triangles[ti][1],triangles[ti][2]); - COUNTER_INSTRUCTION(counter.timer6.stop();) + CGAL_AUTOREF_COUNTER_INSTRUCTION(counter.timer6.stop();) - COUNTER_INSTRUCTION(++counter.c1;) + CGAL_AUTOREF_COUNTER_INSTRUCTION(++counter.c1;) std::size_t pid = get_point_id(pt); points_on_segments[i].push_back(pid); points_on_segments[j].push_back(pid); } else { - COUNTER_INSTRUCTION(++counter.c2;) - COUNTER_INSTRUCTION(counter.timer4.start();) + CGAL_AUTOREF_COUNTER_INSTRUCTION(++counter.c2;) + CGAL_AUTOREF_COUNTER_INSTRUCTION(counter.timer4.start();) typename EK::Point_3 pt = typename EK::Construct_coplanar_segments_intersection_point_3()( points[segments[i].first], points[segments[i].second], points[segments[j].first], points[segments[j].second]); @@ -918,69 +626,63 @@ void generate_subtriangles(std::size_t ti, std::size_t pid = get_point_id(pt); points_on_segments[i].push_back(pid); points_on_segments[j].push_back(pid); - COUNTER_INSTRUCTION(counter.timer4.stop();) - //~ std::ofstream debug ("/tmp/triangles.polylines.txt"); - //~ debug << "4 " << triangles[ti][0] << " " << triangles[ti][1] << " " << triangles[ti][2] << " " << triangles[ti][0] << "\n"; - //~ debug << "4 " << triangles[in_triangle_ids[i]][0] << " " << triangles[in_triangle_ids[i]][1] << " " << triangles[in_triangle_ids[i]][2] << " " << triangles[in_triangle_ids[i]][0] << "\n"; - //~ debug << "4 " << triangles[in_triangle_ids[j]][0] << " " << triangles[in_triangle_ids[j]][1] << " " << triangles[in_triangle_ids[j]][2] << " " << triangles[in_triangle_ids[j]][0] << "\n"; - //~ debug.close(); - //~ throw std::runtime_error("Unexpected case 1"); + CGAL_AUTOREF_COUNTER_INSTRUCTION(counter.timer4.stop();) } break; } case COPLANAR_SEGMENT_PQ: { - COUNTER_INSTRUCTION(++counter.c3;) + CGAL_AUTOREF_COUNTER_INSTRUCTION(++counter.c3;) points_on_segments[j].push_back(segments[i].first); points_on_segments[j].push_back(segments[i].second); break; } case COPLANAR_SEGMENT_RS: { - COUNTER_INSTRUCTION(++counter.c3;) + CGAL_AUTOREF_COUNTER_INSTRUCTION(++counter.c3;) points_on_segments[i].push_back(segments[j].first); points_on_segments[i].push_back(segments[j].second); break; } case COPLANAR_SEGMENT_PR: { - COUNTER_INSTRUCTION(++counter.c3;) + CGAL_AUTOREF_COUNTER_INSTRUCTION(++counter.c3;) points_on_segments[i].push_back(segments[j].first); points_on_segments[j].push_back(segments[i].first); break; } case COPLANAR_SEGMENT_QS: { - COUNTER_INSTRUCTION(++counter.c3;) + CGAL_AUTOREF_COUNTER_INSTRUCTION(++counter.c3;) points_on_segments[i].push_back(segments[j].second); points_on_segments[j].push_back(segments[i].second); break; } case COPLANAR_SEGMENT_PS: { - COUNTER_INSTRUCTION(++counter.c3;) + CGAL_AUTOREF_COUNTER_INSTRUCTION(++counter.c3;) points_on_segments[i].push_back(segments[j].second); points_on_segments[j].push_back(segments[i].first); break; } case COPLANAR_SEGMENT_QR: { - COUNTER_INSTRUCTION(++counter.c3;) + CGAL_AUTOREF_COUNTER_INSTRUCTION(++counter.c3;) points_on_segments[i].push_back(segments[j].first); points_on_segments[j].push_back(segments[i].second); break; } case NO_INTERSECTION: { - COUNTER_INSTRUCTION(++counter.c4;) + CGAL_AUTOREF_COUNTER_INSTRUCTION(++counter.c4;) } } } - COUNTER_INSTRUCTION(++counter.total;) + CGAL_AUTOREF_COUNTER_INSTRUCTION(++counter.total;) } } - COUNTER_INSTRUCTION(counter.timer1.stop();) - COUNTER_INSTRUCTION(counter.timer2.start();) + CGAL_AUTOREF_COUNTER_INSTRUCTION(counter.timer1.stop();) + CGAL_AUTOREF_COUNTER_INSTRUCTION(counter.timer2.start();) std::size_t nb_new_segments=0; for (std::size_t i = 0; i 10){ - //~ for (const auto p : cst_points) - //~ std::cout << " -- " << p << "(" << depth(p) << ")\n"; - //~ std::cout << "segments:\n"; - //~ for (auto s : segments) - //~ std::cout << " " << depth(s[0]) << " " << depth(s[1]) << "\n"; - //~ exit(1); - //~ } + CGAL_AUTOREF_COUNTER_INSTRUCTION(counter.timer2.stop();) // now fill segments with new segments segments.reserve(segments.size()+nb_new_segments); @@ -1074,56 +743,25 @@ void generate_subtriangles(std::size_t ti, std::sort(segments.begin(), segments.end()); auto last = std::unique(segments.begin(), segments.end()); segments.erase(last, segments.end()); -#endif - - //~ std::ofstream("/tmp/tri.xyz") << std::setprecision(17) << triangles[ti][0] << "\n" - //~ << triangles[ti][1] << "\n" - //~ << triangles[ti][2] << "\n"; - //~ std::ofstream debug("/tmp/cst.polylines.txt"); - //~ debug << std::setprecision(17); - //~ for(auto s : segments) - //~ debug << "2 " << points[s.first] << " " << points[s.second] << "\n"; - //~ debug.close(); - COUNTER_INSTRUCTION(counter.timer3.start();) + CGAL_AUTOREF_COUNTER_INSTRUCTION(counter.timer3.start();) if (segments.empty()) cdt.insert(points.begin(), points.end()); else cdt.insert_constraints(points.begin(), points.end(), segments.begin(), segments.end()); - COUNTER_INSTRUCTION(counter.timer3.stop();) + CGAL_AUTOREF_COUNTER_INSTRUCTION(counter.timer3.stop();) -#ifdef CGAL_DEBUG_PMP_AUTOREFINE_DUMP_TRIANGULATIONS - static int k = 0; - std::stringstream buffer; - buffer.precision(17); - int nbt=0; -#endif - for (typename CDT::Face_handle fh : cdt.finite_face_handles()) - { - if (orientation_flipped) - new_triangles.push_back( { CGAL::make_array(fh->vertex(0)->point(), - fh->vertex(cdt.cw(0))->point(), - fh->vertex(cdt.ccw(0))->point()), ti } ); - else - new_triangles.push_back( { CGAL::make_array(fh->vertex(0)->point(), - fh->vertex(cdt.ccw(0))->point(), - fh->vertex(cdt.cw(0))->point()), ti } ); -#ifdef CGAL_DEBUG_PMP_AUTOREFINE_DUMP_TRIANGULATIONS - ++nbt; - buffer << fh->vertex(0)->point() << "\n"; - buffer << fh->vertex(cdt.ccw(0))->point() << "\n"; - buffer << fh->vertex(cdt.cw(0))->point() << "\n"; -#endif - } - -#ifdef CGAL_DEBUG_PMP_AUTOREFINE_DUMP_TRIANGULATIONS - std::ofstream dump("triangulation_"+std::to_string(k)+".off"); - dump << "OFF\n" << 3*nbt << " " << nbt << " 0\n"; - dump << buffer.str(); - for (int i=0; ivertex(0)->point(), + fh->vertex(cdt.cw(0))->point(), + fh->vertex(cdt.ccw(0))->point()), ti } ); + else + new_triangles.push_back( { CGAL::make_array(fh->vertex(0)->point(), + fh->vertex(cdt.ccw(0))->point(), + fh->vertex(cdt.cw(0))->point()), ti } ); + } } } // end of autorefine_impl @@ -1267,7 +905,7 @@ void autorefine_triangle_soup(PointRange& soup_points, std::vector< std::vector > all_in_triangle_ids(triangles.size()); CGAL_PMP_AUTOREFINE_VERBOSE("compute intersections"); -#ifdef USE_DEBUG_PARALLEL_TIMERS +#ifdef CGAL_AUTOREF_USE_DEBUG_PARALLEL_TIMERS Real_timer t; t.start(); #endif @@ -1320,14 +958,13 @@ void autorefine_triangle_soup(PointRange& soup_points, coplanar_triangles.insert(CGAL::make_sorted_pair(i1, i2)); } } -#ifdef USE_DEBUG_PARALLEL_TIMERS +#ifdef CGAL_AUTOREF_USE_DEBUG_PARALLEL_TIMERS t.stop(); std::cout << t.time() << " sec. for #2" << std::endl; t.reset(); #endif -#ifdef DEDUPLICATE_SEGMENTS -#ifdef USE_DEBUG_PARALLEL_TIMERS +#ifdef CGAL_AUTOREF_USE_DEBUG_PARALLEL_TIMERS t.start(); #endif @@ -1396,11 +1033,10 @@ void autorefine_triangle_soup(PointRange& soup_points, deduplicate_inserted_segments(ti); } -#ifdef USE_DEBUG_PARALLEL_TIMERS +#ifdef CGAL_AUTOREF_USE_DEBUG_PARALLEL_TIMERS t.stop(); std::cout << t.time() << " sec. for #3" << std::endl; t.reset(); -#endif #endif CGAL_PMP_AUTOREFINE_VERBOSE("triangulate faces"); @@ -1413,7 +1049,7 @@ void autorefine_triangle_soup(PointRange& soup_points, std::vector, std::size_t>> new_triangles; #endif -#ifdef USE_PROGRESS_DISPLAY +#ifdef CGAL_AUTOREF_USE_PROGRESS_DISPLAY boost::timer::progress_display pd(triangles.size()); #endif @@ -1423,37 +1059,15 @@ void autorefine_triangle_soup(PointRange& soup_points, new_triangles.push_back({triangles[ti], ti}); else { -#ifdef USE_FIXED_PROJECTION_TRAITS - const std::array& t = triangles[ti]; - auto is_constant_in_dim = [](const std::array& t, int dim) - { - return t[0][dim] == t[1][dim] && t[0][dim] != t[2][dim]; - }; - - typename EK::Vector_3 orth = CGAL::normal(t[0], t[1], t[2]); // TODO::avoid construction? - int c = CGAL::abs(orth[0]) > CGAL::abs(orth[1]) ? 0 : 1; - c = CGAL::abs(orth[2]) > CGAL::abs(orth[c]) ? 2 : c; - - if (c == 0) { - autorefine_impl::generate_subtriangles(ti, all_segments[ti], all_points[ti], all_in_triangle_ids[ti], intersecting_triangles, triangles, new_triangles); - } - else if (c == 1) { - autorefine_impl::generate_subtriangles(ti, all_segments[ti], all_points[ti], all_in_triangle_ids[ti], intersecting_triangles, triangles, new_triangles); - } - else if (c == 2) { - autorefine_impl::generate_subtriangles(ti, all_segments[ti], all_points[ti], all_in_triangle_ids[ti], intersecting_triangles, triangles, new_triangles); - } -#else autorefine_impl::generate_subtriangles(ti, all_segments_ids[ti], all_points[ti], all_in_triangle_ids[ti], intersecting_triangles, coplanar_triangles, triangles, new_triangles); -#endif } -#ifdef USE_PROGRESS_DISPLAY +#ifdef CGAL_AUTOREF_USE_PROGRESS_DISPLAY ++pd; #endif }; -#ifdef USE_DEBUG_PARALLEL_TIMERS +#ifdef CGAL_AUTOREF_USE_DEBUG_PARALLEL_TIMERS t.start(); #endif #ifdef CGAL_LINKED_WITH_TBB @@ -1472,7 +1086,7 @@ void autorefine_triangle_soup(PointRange& soup_points, refine_triangles(ti); } -#ifdef USE_DEBUG_PARALLEL_TIMERS +#ifdef CGAL_AUTOREF_USE_DEBUG_PARALLEL_TIMERS t.stop(); std::cout << t.time() << " sec. for #1" << std::endl; t.reset(); @@ -1552,12 +1166,12 @@ void autorefine_triangle_soup(PointRange& soup_points, return insert_res.first->second; }; -#ifdef USE_DEBUG_PARALLEL_TIMERS +#ifdef CGAL_AUTOREF_USE_DEBUG_PARALLEL_TIMERS t.start(); #endif std::size_t offset = soup_triangles_out.size(); -#ifdef USE_DEBUG_PARALLEL_TIMERS +#ifdef CGAL_AUTOREF_USE_DEBUG_PARALLEL_TIMERS std::string mode = "parallel"; #endif @@ -1565,7 +1179,7 @@ void autorefine_triangle_soup(PointRange& soup_points, #ifdef CGAL_LINKED_WITH_TBB if(parallel_execution && new_triangles.size() > 100) { -#ifdef SET_POINT_IDS_USING_MUTEX +#ifdef CGAL_AUTOREF_SET_POINT_IDS_USING_MUTEX //option 1 (using a mutex) CGAL_MUTEX point_container_mutex; /// Lambda concurrent_get_point_id() @@ -1672,7 +1286,7 @@ void autorefine_triangle_soup(PointRange& soup_points, else #endif { -#ifdef USE_DEBUG_PARALLEL_TIMERS +#ifdef CGAL_AUTOREF_USE_DEBUG_PARALLEL_TIMERS mode = "sequential"; #endif soup_triangles_out.reserve(offset + new_triangles.size()); @@ -1687,7 +1301,7 @@ void autorefine_triangle_soup(PointRange& soup_points, -#ifdef USE_DEBUG_PARALLEL_TIMERS +#ifdef CGAL_AUTOREF_USE_DEBUG_PARALLEL_TIMERS t.stop(); std::cout << t.time() << " sec. for #4 (" << mode << ")" << std::endl; t.reset(); From acd03b166c843928585947fae8a72350517b0db1 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Fri, 8 Dec 2023 17:09:00 +0000 Subject: [PATCH 273/329] write() operates on const& data --- .../Polyhedron/CGAL/IO/Polyhedron_iostream.h | 7 +-- .../File_formats/Supported_file_formats.txt | 58 +++++++++---------- 2 files changed, 32 insertions(+), 33 deletions(-) diff --git a/Polyhedron/doc/Polyhedron/CGAL/IO/Polyhedron_iostream.h b/Polyhedron/doc/Polyhedron/CGAL/IO/Polyhedron_iostream.h index 8114a141aa7a..a10c0e632bf2 100644 --- a/Polyhedron/doc/Polyhedron/CGAL/IO/Polyhedron_iostream.h +++ b/Polyhedron/doc/Polyhedron/CGAL/IO/Polyhedron_iostream.h @@ -75,7 +75,7 @@ This function overloads the generic function \link PkgBGLIoFuncsOFF `write_OFF(s \sa \link PkgPolyhedronIOFunc `operator>>(std::istream& in, Polyhedron_3& P)` \endlink */ template -bool write_OFF( std::ostream& out, Polyhedron_3& P); +bool write_OFF( std::ostream& out, const Polyhedron_3& P); /*! \relates Polyhedron_3 @@ -83,7 +83,7 @@ bool write_OFF( std::ostream& out, Polyhedron_3& P); \link PkgPolyhedronIOFunc `CGAL::IO::write_OFF(std::ostream&, Polyhedron_3&)` \endlink should be used instead. */ template -bool write_off( std::ostream& out, Polyhedron_3& P); +bool write_off( std::ostream& out, const Polyhedron_3& P); /*! \relates Polyhedron_3 @@ -91,7 +91,6 @@ bool write_off( std::ostream& out, Polyhedron_3& P); calls \link write_OFF() `write_OFF(out, P)` \endlink. */ template -std::ostream& operator<<( std::ostream& out, Polyhedron_3& P); +std::ostream& operator<<( std::ostream& out, const Polyhedron_3& P); } /* namespace CGAL */ - diff --git a/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt b/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt index cfc647bf7268..995c18794da5 100644 --- a/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt +++ b/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt @@ -47,25 +47,25 @@ The following table lists some \cgal data structures that have I/O functions com `CGAL::Polyhedron_3` - \link PkgPolyhedronIOFunc CGAL::IO::read_OFF(const char*, CGAL::Polyhedron_3&)\endlink + \link PkgPolyhedronIOFunc CGAL::IO::read_OFF(const std::string&, CGAL::Polyhedron_3&)\endlink Any model of `MutableFaceGraph` - \link PkgBGLIoFuncsOFF CGAL::IO::read_OFF(const char*, Graph&)\endlink + \link PkgBGLIoFuncsOFF CGAL::IO::read_OFF(const std::string&, Graph&)\endlink Point Set `CGAL::Point_set_3` - \link PkgPointSet3IOOFF CGAL::IO::read_OFF(const char*, CGAL::Point_set_3&)\endlink + \link PkgPointSet3IOOFF CGAL::IO::read_OFF(const std::string&, CGAL::Point_set_3&)\endlink Any point range - \link PkgPointSetProcessing3IOOff CGAL::IO::read_OFF(const char*, PointRange&)\endlink + \link PkgPointSetProcessing3IOOff CGAL::IO::read_OFF(const std::string&, PointRange&)\endlink Polygon Soup Any point + polygon range - \link PkgStreamSupportIoFuncsOFF CGAL::IO::read_OFF(const char*, PointRange&, PolygonRange&)\endlink + \link PkgStreamSupportIoFuncsOFF CGAL::IO::read_OFF(const std::string&, PointRange&, PolygonRange&)\endlink Output @@ -75,25 +75,25 @@ The following table lists some \cgal data structures that have I/O functions com `CGAL::Polyhedron_3` - \link PkgPolyhedronIOFunc CGAL::IO::write_OFF(const char*, CGAL::Polyhedron_3&)\endlink + \link PkgPolyhedronIOFunc CGAL::IO::write_OFF(const char*, const CGAL::Polyhedron_3&)\endlink Any model of `FaceGraph` - \link PkgBGLIoFuncsOFF CGAL::IO::write_OFF(const char*, Graph&)\endlink + \link PkgBGLIoFuncsOFF CGAL::IO::write_OFF(const std::string&, const Graph&)\endlink Point Set `CGAL::Point_set_3` - \link PkgPointSet3IOOFF CGAL::IO::write_OFF(const char*, CGAL::Point_set_3&)\endlink + \link PkgPointSet3IOOFF CGAL::IO::write_OFF(const std::string&, const CGAL::Point_set_3&)\endlink Any point range - \link PkgPointSetProcessing3IOOff CGAL::IO::write_OFF(const char*, PointRange&)\endlink + \link PkgPointSetProcessing3IOOff CGAL::IO::write_OFF(const std::string&, const PointRange&)\endlink Polygon Soup Any point + polygon range - \link PkgStreamSupportIoFuncsOFF CGAL::IO::write_OFF(const char*, PointRange&, PolygonRange&)\endlink + \link PkgStreamSupportIoFuncsOFF CGAL::IO::write_OFF(const std::string&, const PointRange&, const PolygonRange&)\endlink @@ -128,12 +128,12 @@ A precise specification of the format is available Output Polygon Mesh Any model of `FaceGraph` - \link PkgBGLIoFuncsOBJ CGAL::IO::write_OBJ(const std::string&, Graph&)\endlink + \link PkgBGLIoFuncsOBJ CGAL::IO::write_OBJ(const std::string&, const Graph&)\endlink Polygon Soup Any point + polygon range - \link PkgStreamSupportIoFuncsOBJ CGAL::IO::write_OBJ(const std::string&, PointRange&, PolygonRange&)\endlink + \link PkgStreamSupportIoFuncsOBJ CGAL::IO::write_OBJ(const std::string&, const PointRange&, const PolygonRange&)\endlink @@ -169,12 +169,12 @@ A precise specification of those formats is available Output Polygon Mesh Any model of `FaceGraph` - \link PkgBGLIoFuncsSTL CGAL::IO::write_STL(const std::string&, Graph&)\endlink + \link PkgBGLIoFuncsSTL CGAL::IO::write_STL(const std::string&, const Graph&)\endlink Polygon Soup Any point + polygon range - \link PkgStreamSupportIoFuncsSTL CGAL::IO::write_STL(const std::string&, PointRange&, TriangleRange&)\endlink + \link PkgStreamSupportIoFuncsSTL CGAL::IO::write_STL(const std::string&, const PointRange&, const TriangleRange&)\endlink @@ -226,25 +226,25 @@ A precise specification of those formats is available Output Polygon Mesh `CGAL::Surface_mesh` - \link PkgSurfaceMeshIOFuncPLY CGAL::IO::write_PLY(const std::string&, CGAL::Surface_mesh&)\endlink + \link PkgSurfaceMeshIOFuncPLY CGAL::IO::write_PLY(const std::string&, const CGAL::Surface_mesh&)\endlink Any model of `FaceGraph` - \link PkgBGLIoFuncsPLY CGAL::IO::write_PLY(const std::string&, Graph&)\endlink + \link PkgBGLIoFuncsPLY CGAL::IO::write_PLY(const std::string&, const Graph&)\endlink Point Set `CGAL::Point_set_3` - \link PkgPointSet3IOPLY CGAL::IO::write_PLY(const std::string&, CGAL::Point_set_3&)\endlink + \link PkgPointSet3IOPLY CGAL::IO::write_PLY(const std::string&, const CGAL::Point_set_3&)\endlink Any point range - \link PkgPointSetProcessing3IOPly CGAL::IO::write_PLY(const std::string&, PointRange&)\endlink + \link PkgPointSetProcessing3IOPly CGAL::IO::write_PLY(const std::string&, const PointRange&)\endlink Polygon Soup Any point + polygon range - \link PkgStreamSupportIoFuncsPLY CGAL::IO::write_PLY(const std::string&, PointRange&, PolygonRange&)\endlink + \link PkgStreamSupportIoFuncsPLY CGAL::IO::write_PLY(const std::string&, const PointRange&, PolygonRange&)\endlink @@ -280,11 +280,11 @@ A precise specification of those formats is available Output Point Set `CGAL::Point_set_3` - \link PkgPointSet3IOLAS CGAL::IO::write_LAS(const std::string&, CGAL::Point_set_3&)\endlink + \link PkgPointSet3IOLAS CGAL::IO::write_LAS(const std::string&, const CGAL::Point_set_3&)\endlink Any point range - \link PkgPointSetProcessing3IOLas CGAL::IO::write_LAS(const std::string&, PointRange&)\endlink + \link PkgPointSetProcessing3IOLas CGAL::IO::write_LAS(const std::string&, const PointRange&)\endlink @@ -313,11 +313,11 @@ of its coordinates and other properties. Only coordinates and normals are curren Output Point Set `CGAL::Point_set_3` - \link PkgPointSet3IOXYZ CGAL::IO::write_XYZ(const std::string&, CGAL::Point_set_3&)\endlink + \link PkgPointSet3IOXYZ CGAL::IO::write_XYZ(const std::string&, const CGAL::Point_set_3&)\endlink Any point range - \link PkgPointSetProcessing3IOXyz CGAL::IO::write_XYZ(const std::string&, PointRange&)\endlink + \link PkgPointSetProcessing3IOXyz CGAL::IO::write_XYZ(const std::string&, const PointRange&)\endlink @@ -348,12 +348,12 @@ A precise specification of the format is available Output Polygon Mesh Any model of `FaceGraph` - \link PkgBGLIoFuncsGOCAD CGAL::IO::write_GOCAD(const std::string&, Graph&)\endlink + \link PkgBGLIoFuncsGOCAD CGAL::IO::write_GOCAD(const std::string&, const Graph&)\endlink Polygon Soup Any point + polygon range - \link PkgStreamSupportIoFuncsGOCAD CGAL::IO::write_GOCAD(const std::string&, PointRange&, PolygonRange&)\endlink + \link PkgStreamSupportIoFuncsGOCAD CGAL::IO::write_GOCAD(const std::string&, const PointRange&, const PolygonRange&)\endlink @@ -392,12 +392,12 @@ note that only versions `1.x` are currently supported in \cgal. Output Polygon Mesh Any model of `FaceGraph` - \link PkgBGLIoFuncs3MF CGAL::IO::write_3MF(const std::string&, GraphRange&)\endlink + \link PkgBGLIoFuncs3MF CGAL::IO::write_3MF(const std::string&, const GraphRange&)\endlink Polygon Soup Any point + polygon range - \link PkgStreamSupportIoFuncs3MF CGAL::IO::write_3MF(const std::string&, PointRanges&, PolygonRanges&)\endlink + \link PkgStreamSupportIoFuncs3MF CGAL::IO::write_3MF(const std::string&, const PointRanges&, const PolygonRanges&)\endlink @@ -422,7 +422,7 @@ A precise specification of the format is available Output Polygon Mesh Any model of `FaceGraph` - \link PkgBGLIoFuncsWRL CGAL::IO::write_WRL(const std::string&, Graph&)\endlink + \link PkgBGLIoFuncsWRL CGAL::IO::write_WRL(const std::string&, const Graph&)\endlink @@ -466,7 +466,7 @@ A precise specification of those formats is available at Output Polygon Mesh Any model of `FaceGraph` - \link PkgBGLIoFuncsVTP CGAL::IO::write_VTP(const std::string&, Graph&)\endlink + \link PkgBGLIoFuncsVTP CGAL::IO::write_VTP(const std::string&, const Graph&)\endlink Polygon Soup From 38d9db972857d490b6055c17767505c642d876f4 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Fri, 8 Dec 2023 17:15:46 +0000 Subject: [PATCH 274/329] write() operates on const& data --- .../Stream_support/File_formats/Supported_file_formats.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt b/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt index 995c18794da5..dddf17673162 100644 --- a/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt +++ b/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt @@ -43,7 +43,7 @@ The following table lists some \cgal data structures that have I/O functions com Input Polygon Mesh `CGAL::Surface_mesh` - \link PkgSurfaceMeshIOFuncOFF CGAL::IO::read_OFF(const char*, CGAL::Surface_mesh&)\endlink + \link PkgSurfaceMeshIOFuncOFF CGAL::IO::read_OFF(const std::string&, CGAL::Surface_mesh&)\endlink `CGAL::Polyhedron_3` @@ -71,11 +71,11 @@ The following table lists some \cgal data structures that have I/O functions com Output Polygon Mesh `CGAL::Surface_mesh` - \link PkgSurfaceMeshIOFuncOFF CGAL::IO::write_OFF(const char*, CGAL::Surface_mesh&)\endlink + \link PkgSurfaceMeshIOFuncOFF CGAL::IO::write_OFF(const std::string, CGAL::Surface_mesh&)\endlink `CGAL::Polyhedron_3` - \link PkgPolyhedronIOFunc CGAL::IO::write_OFF(const char*, const CGAL::Polyhedron_3&)\endlink + \link PkgPolyhedronIOFunc CGAL::IO::write_OFF(const std::string&, const CGAL::Polyhedron_3&)\endlink Any model of `FaceGraph` From 33bb65ae17c0615f7f41558e94d1a73837c900a3 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Fri, 8 Dec 2023 18:03:22 +0000 Subject: [PATCH 275/329] PointRange -> PointOutputIterator --- .../doc/Stream_support/File_formats/Supported_file_formats.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt b/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt index dddf17673162..153d8ca086bb 100644 --- a/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt +++ b/Stream_support/doc/Stream_support/File_formats/Supported_file_formats.txt @@ -60,7 +60,7 @@ The following table lists some \cgal data structures that have I/O functions com Any point range - \link PkgPointSetProcessing3IOOff CGAL::IO::read_OFF(const std::string&, PointRange&)\endlink + \link PkgPointSetProcessing3IOOff CGAL::IO::read_OFF(const std::string&, PointOutputIterator)\endlink Polygon Soup From f4154836aea19da5ac29a4855ea24caec193168b Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Mon, 11 Dec 2023 08:35:02 +0000 Subject: [PATCH 276/329] Kernel_23: Deal with concurrent executions and IO --- .../test/Kernel_23/include/CGAL/_test_io.h | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_io.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_io.h index eebd53cd03f7..886832d0508a 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_io.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_io.h @@ -17,26 +17,19 @@ #ifndef CGAL__TEST_IO_H #define CGAL__TEST_IO_H -#include +#include #include -#ifndef TEST_FILENAME -# define TEST_FILENAME "Test_IO.out" -#endif - template void _test_io_for(const T& t) { - { - std::ofstream oFile(TEST_FILENAME, std::ios::out); - oFile << t << std::endl; - } + std::stringstream ss; + ss << t << std::endl; - std::ifstream iFile(TEST_FILENAME, std::ios::in); T u = t; - iFile >> u; - assert(!iFile.fail()); + ss >> u; + assert(! ss.fail() ); assert(u == t); } From 93a1549c6515be7b077d9267ca6ba1be377fed28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 11 Dec 2023 11:34:42 +0100 Subject: [PATCH 277/329] used typedef --- .../examples/Polygon_mesh_processing/soup_autorefinement.cpp | 2 -- .../include/CGAL/Polygon_mesh_processing/autorefinement.h | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp index 5baea1a3964d..a76e1254f6e2 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/soup_autorefinement.cpp @@ -13,8 +13,6 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; typedef Kernel::Point_3 Point; -typedef CGAL::Surface_mesh Mesh; - namespace PMP = CGAL::Polygon_mesh_processing; int main(int argc, char** argv) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index bb81855edd55..46f9ed9cbe7e 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -1126,7 +1126,7 @@ void autorefine_triangle_soup(PointRange& soup_points, } TriangleRange soup_triangles_out; - soup_triangles_out.reserve(soup_triangles.size()); // TODO: remove #deg tri? + soup_triangles_out.reserve(soup_triangles.size()); visitor.number_of_output_triangles(soup_triangles.size()+new_triangles.size()); From 20b99521ac05cfe27abf119f15a92d23b4d543a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Mon, 11 Dec 2023 12:17:49 +0100 Subject: [PATCH 278/329] Fix typo in benchmarks --- .../Alpha_wrap_3/Robustness/robustness_benchmark.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Alpha_wrap_3/benchmark/Alpha_wrap_3/Robustness/robustness_benchmark.cpp b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Robustness/robustness_benchmark.cpp index 353e5569d1f9..3bf23fe02012 100644 --- a/Alpha_wrap_3/benchmark/Alpha_wrap_3/Robustness/robustness_benchmark.cpp +++ b/Alpha_wrap_3/benchmark/Alpha_wrap_3/Robustness/robustness_benchmark.cpp @@ -21,7 +21,7 @@ enum Robustness_benchmark_exit_code VALID_SOLID_OUTPUT = 0, // Failure - INTPUT_IS_INVALID = 1, + INPUT_IS_INVALID = 1, OUTPUT_IS_NOT_TRIANGLE_MESH = 2, OUTPUT_IS_COMBINATORIAL_NON_MANIFOLD = 3, OUTPUT_HAS_BORDERS = 4, @@ -59,7 +59,7 @@ int main(int argc, char** argv) } if(argc < 3 || relative_alpha_ratio <= 0.) - return AW3i::INTPUT_IS_INVALID; + return AW3i::INPUT_IS_INVALID; Mesh input_mesh; if(!PMP::IO::read_polygon_mesh(entry_name_ptr, input_mesh) || @@ -70,7 +70,7 @@ int main(int argc, char** argv) #endif ) { - return AW3i::INTPUT_IS_INVALID; + return AW3i::INPUT_IS_INVALID; } const CGAL::Bbox_3 bbox = PMP::bbox(input_mesh); From f36bdda9fe88c8bce0986cc0032e19a80026d651 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 11 Dec 2023 13:42:54 +0100 Subject: [PATCH 279/329] doc thread-safety of output iterators --- .../CGAL/Polygon_mesh_processing/self_intersections.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h index 30d6190bdc8b..928129705aed 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h @@ -419,7 +419,8 @@ self_intersections_impl(const FaceRange& face_range, * @tparam FaceRange a model of `ConstRange` with value type `boost::graph_traits::%face_descriptor`. * @tparam TriangleMesh a model of `FaceListGraph` * @tparam FacePairOutputIterator a model of `OutputIterator` holding objects of type - * `std::pair::%face_descriptor, boost::graph_traits::%face_descriptor>` + * `std::pair::%face_descriptor, boost::graph_traits::%face_descriptor>`. + * It does need to be thread-safe. * @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" * * @param face_range the range of faces to check for self-intersection. @@ -485,7 +486,8 @@ self_intersections(const FaceRange& face_range, * Possible values are `Sequential_tag`, `Parallel_tag`, and `Parallel_if_available_tag`. * @tparam TriangleMesh a model of `FaceListGraph` * @tparam FacePairOutputIterator a model of `OutputIterator` holding objects of type - * `std::pair::%face_descriptor, boost::graph_traits::%face_descriptor>` + * `std::pair::%face_descriptor, boost::graph_traits::%face_descriptor>`. + * It does need to be thread-safe. * @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" * * @param tmesh the triangulated surface mesh to be checked From d0c224fafbc08c2156d184f6c9841c8a8545aae6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 11 Dec 2023 14:07:08 +0100 Subject: [PATCH 280/329] handle some todos --- .../Polygon_mesh_processing/autorefinement.h | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 46f9ed9cbe7e..05d05637b16a 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -1,5 +1,3 @@ -//TODO: add for soup face the id of the input face. not sure it is easy to report intersection edge as a pair of vertex id -//TODO: only return intersection segments (pay attention to degenerate triangles that are currently ignored) // Copyright (c) 2023 GeometryFactory (France). // All rights reserved. // @@ -735,8 +733,6 @@ void generate_subtriangles(std::size_t ti, CGAL_assertion(points.size()==point_id_map.size()); } - // TODO: sorted pair to be constructed when pushing_back - // TODO: only needed in case of coplanar segments? for (std::pair& s : segments) if (s.second < s.first) std::swap(s.first,s.second); @@ -853,7 +849,9 @@ void autorefine_triangle_soup(PointRange& soup_points, typedef std::size_t Input_TID; typedef std::pair Pair_of_triangle_ids; - std::vector si_pairs; // TODO: check std::vector is fine with Parallel_tag + // no need for a concurrent vector as the called function itself + // takes care of sequentially writing into the output iterator + std::vector si_pairs; // collect intersecting pairs of triangles CGAL_PMP_AUTOREFINE_VERBOSE("collect intersecting pairs"); @@ -909,8 +907,8 @@ void autorefine_triangle_soup(PointRange& soup_points, Real_timer t; t.start(); #endif - std::set > intersecting_triangles; // TODO replace with vector>> - std::set > coplanar_triangles; // TODO replace with vector>> + std::set > intersecting_triangles; + std::set > coplanar_triangles; //TODO: PARALLEL_FOR #2 for (const Pair_of_triangle_ids& p : si_pairs) { @@ -1096,7 +1094,6 @@ void autorefine_triangle_soup(PointRange& soup_points, CGAL_PMP_AUTOREFINE_VERBOSE("create output soup"); Cartesian_converter to_input; - // TODO: reuse the fact that maps per triangle are already sorted #ifdef CGAL_LINKED_WITH_TBB typedef std::conditional_t 100) + if(parallel_execution && new_triangles.size() > 50) { #ifdef CGAL_AUTOREF_SET_POINT_IDS_USING_MUTEX //option 1 (using a mutex) @@ -1336,6 +1335,8 @@ void autorefine_triangle_soup(PointRange& soup_points, * @param tm input triangulated surface mesh * @param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below * + * @warning `clear(tm)` will be called before filling `tm` with the refined mesh. + * * \cgalNamedParamsBegin * \cgalParamNBegin{concurrency_tag} * \cgalParamDescription{a tag indicating if the task should be done using one or several threads.} @@ -1378,7 +1379,7 @@ autorefine( TriangleMesh& tm, autorefine_triangle_soup(soup_points, soup_triangles, np); - clear(tm); //TODO: keep properties + clear(tm); repair_polygon_soup(soup_points, soup_triangles); duplicate_non_manifold_edges_in_polygon_soup(soup_points, soup_triangles); From 79123c8f53ce53516ea1414b8cd5d0287726dd4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 12 Dec 2023 08:31:46 +0100 Subject: [PATCH 281/329] hide forward declaration to doxygen --- Point_set_3/include/CGAL/Point_set_3/IO.h | 2 ++ Point_set_3/include/CGAL/Point_set_3/IO/OFF.h | 2 ++ Point_set_3/include/CGAL/Point_set_3/IO/PLY.h | 2 ++ Point_set_3/include/CGAL/Point_set_3/IO/XYZ.h | 2 ++ 4 files changed, 8 insertions(+) diff --git a/Point_set_3/include/CGAL/Point_set_3/IO.h b/Point_set_3/include/CGAL/Point_set_3/IO.h index 2e680a744f8a..8630788e7875 100644 --- a/Point_set_3/include/CGAL/Point_set_3/IO.h +++ b/Point_set_3/include/CGAL/Point_set_3/IO.h @@ -26,8 +26,10 @@ namespace CGAL { +#ifndef DOXYGEN_RUNNING template class Point_set_3; +#endif //////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Point_set_3/include/CGAL/Point_set_3/IO/OFF.h b/Point_set_3/include/CGAL/Point_set_3/IO/OFF.h index 5bd359416153..cff22686ae79 100644 --- a/Point_set_3/include/CGAL/Point_set_3/IO/OFF.h +++ b/Point_set_3/include/CGAL/Point_set_3/IO/OFF.h @@ -24,8 +24,10 @@ namespace CGAL { +#ifndef DOXYGEN_RUNNING template class Point_set_3; +#endif //////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Point_set_3/include/CGAL/Point_set_3/IO/PLY.h b/Point_set_3/include/CGAL/Point_set_3/IO/PLY.h index 76daf4494abe..b1f3e763b079 100644 --- a/Point_set_3/include/CGAL/Point_set_3/IO/PLY.h +++ b/Point_set_3/include/CGAL/Point_set_3/IO/PLY.h @@ -24,8 +24,10 @@ namespace CGAL { +#ifndef DOXYGEN_RUNNING template class Point_set_3; +#endif namespace IO { namespace internal { diff --git a/Point_set_3/include/CGAL/Point_set_3/IO/XYZ.h b/Point_set_3/include/CGAL/Point_set_3/IO/XYZ.h index 72c00bd528ec..ce968f49af64 100644 --- a/Point_set_3/include/CGAL/Point_set_3/IO/XYZ.h +++ b/Point_set_3/include/CGAL/Point_set_3/IO/XYZ.h @@ -23,8 +23,10 @@ namespace CGAL { +#ifndef DOXYGEN_RUNNING template class Point_set_3; +#endif //////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////// From 81972df60e11ff4fd4455177a89cf9f8041b80e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Tue, 12 Dec 2023 09:39:35 +0100 Subject: [PATCH 282/329] Add a convenience IO header --- BGL/examples/BGL_LCC/distance_lcc.cpp | 2 +- BGL/examples/BGL_LCC/incident_vertices_lcc.cpp | 2 +- BGL/examples/BGL_LCC/normals_lcc.cpp | 2 +- BGL/examples/BGL_LCC/range_lcc.cpp | 2 +- BGL/examples/BGL_LCC/transform_iterator_lcc.cpp | 2 +- BGL/examples/BGL_OpenMesh/TriMesh.cpp | 2 +- .../BGL_surface_mesh/surface_mesh_partition.cpp | 2 +- BGL/include/CGAL/IO/polygon_mesh_io.h | 16 ++++++++++++++++ .../cc_compatible_orientations.cpp | 2 +- .../examples/Polygon_mesh_processing/extrude.cpp | 2 +- .../Polygon_mesh_processing/IO/polygon_mesh_io.h | 2 +- .../orient_polygon_soup_test.cpp | 2 +- .../examples/Ridges_3/Ridges_Umbilics_LCC.cpp | 2 +- .../region_growing_lines_on_segment_set.cpp | 2 +- .../region_growing_planes_on_polygon_mesh.cpp | 2 +- .../Straight_skeleton_2/extrude_skeleton.cpp | 2 +- .../test_sls_extrude.cpp | 2 +- .../edge_collapse_garland_heckbert.cpp | 2 +- .../edge_collapse_linear_cell_complex.cpp | 2 +- .../test_edge_collapse_stability.cpp | 2 +- .../test_edge_deprecated_stop_predicates.cpp | 2 +- .../MCF_Skeleton_LCC_example.cpp | 2 +- .../simple_mcfskel_LCC_example.cpp | 2 +- 23 files changed, 38 insertions(+), 22 deletions(-) create mode 100644 BGL/include/CGAL/IO/polygon_mesh_io.h diff --git a/BGL/examples/BGL_LCC/distance_lcc.cpp b/BGL/examples/BGL_LCC/distance_lcc.cpp index 9e60c5bfb297..b19f0ab2b384 100644 --- a/BGL/examples/BGL_LCC/distance_lcc.cpp +++ b/BGL/examples/BGL_LCC/distance_lcc.cpp @@ -1,7 +1,7 @@ #include #include -#include +#include #include // wrapper to suppress a warning diff --git a/BGL/examples/BGL_LCC/incident_vertices_lcc.cpp b/BGL/examples/BGL_LCC/incident_vertices_lcc.cpp index f2b66d46ca03..af02d72a81b1 100644 --- a/BGL/examples/BGL_LCC/incident_vertices_lcc.cpp +++ b/BGL/examples/BGL_LCC/incident_vertices_lcc.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include diff --git a/BGL/examples/BGL_LCC/normals_lcc.cpp b/BGL/examples/BGL_LCC/normals_lcc.cpp index da1177a70624..b729b0b4792e 100644 --- a/BGL/examples/BGL_LCC/normals_lcc.cpp +++ b/BGL/examples/BGL_LCC/normals_lcc.cpp @@ -1,7 +1,7 @@ #include #include -#include +#include #include #include diff --git a/BGL/examples/BGL_LCC/range_lcc.cpp b/BGL/examples/BGL_LCC/range_lcc.cpp index 02a28d869a0c..cdf89714c30f 100644 --- a/BGL/examples/BGL_LCC/range_lcc.cpp +++ b/BGL/examples/BGL_LCC/range_lcc.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include diff --git a/BGL/examples/BGL_LCC/transform_iterator_lcc.cpp b/BGL/examples/BGL_LCC/transform_iterator_lcc.cpp index 0bfc08914376..988c0230bae2 100644 --- a/BGL/examples/BGL_LCC/transform_iterator_lcc.cpp +++ b/BGL/examples/BGL_LCC/transform_iterator_lcc.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include diff --git a/BGL/examples/BGL_OpenMesh/TriMesh.cpp b/BGL/examples/BGL_OpenMesh/TriMesh.cpp index 0f30d0c10a52..e474020cc67e 100644 --- a/BGL/examples/BGL_OpenMesh/TriMesh.cpp +++ b/BGL/examples/BGL_OpenMesh/TriMesh.cpp @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include diff --git a/BGL/examples/BGL_surface_mesh/surface_mesh_partition.cpp b/BGL/examples/BGL_surface_mesh/surface_mesh_partition.cpp index 57c96a907d8d..1f57a67524f4 100644 --- a/BGL/examples/BGL_surface_mesh/surface_mesh_partition.cpp +++ b/BGL/examples/BGL_surface_mesh/surface_mesh_partition.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include diff --git a/BGL/include/CGAL/IO/polygon_mesh_io.h b/BGL/include/CGAL/IO/polygon_mesh_io.h new file mode 100644 index 000000000000..0dce62b6a37d --- /dev/null +++ b/BGL/include/CGAL/IO/polygon_mesh_io.h @@ -0,0 +1,16 @@ +// Copyright (c) 2023 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) : Mael Rouxel-Labbé + +#ifndef CGAL_BOOST_GRAPH_POLYGON_MESH_IO_H +#define CGAL_BOOST_GRAPH_POLYGON_MESH_IO_H + +#include + +#endif // CGAL_BOOST_GRAPH_POLYGON_MESH_IO_H diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/cc_compatible_orientations.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/cc_compatible_orientations.cpp index 8a47239c5aa5..646e94e9468c 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/cc_compatible_orientations.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/cc_compatible_orientations.cpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/extrude.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/extrude.cpp index baaa0612452d..300d0182fdb3 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/extrude.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/extrude.cpp @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include #include diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/IO/polygon_mesh_io.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/IO/polygon_mesh_io.h index f2d93e83f01b..21600e50bfff 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/IO/polygon_mesh_io.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/IO/polygon_mesh_io.h @@ -21,7 +21,7 @@ #include #include -#include +#include #include #include #include diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/orient_polygon_soup_test.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/orient_polygon_soup_test.cpp index 02b5e000a5e9..f3c541ab65ca 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/orient_polygon_soup_test.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/orient_polygon_soup_test.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include #include #include #include diff --git a/Ridges_3/examples/Ridges_3/Ridges_Umbilics_LCC.cpp b/Ridges_3/examples/Ridges_3/Ridges_Umbilics_LCC.cpp index 5373ac5e3761..611be7e6c0bf 100644 --- a/Ridges_3/examples/Ridges_3/Ridges_Umbilics_LCC.cpp +++ b/Ridges_3/examples/Ridges_3/Ridges_Umbilics_LCC.cpp @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include namespace po = boost::program_options; diff --git a/Shape_detection/examples/Shape_detection/region_growing_lines_on_segment_set.cpp b/Shape_detection/examples/Shape_detection/region_growing_lines_on_segment_set.cpp index c283a4652fe3..270f53d3bda0 100644 --- a/Shape_detection/examples/Shape_detection/region_growing_lines_on_segment_set.cpp +++ b/Shape_detection/examples/Shape_detection/region_growing_lines_on_segment_set.cpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include "include/utils.h" // Typedefs. diff --git a/Shape_detection/examples/Shape_detection/region_growing_planes_on_polygon_mesh.cpp b/Shape_detection/examples/Shape_detection/region_growing_planes_on_polygon_mesh.cpp index 37245edcd9d3..43d7b5b291ae 100644 --- a/Shape_detection/examples/Shape_detection/region_growing_planes_on_polygon_mesh.cpp +++ b/Shape_detection/examples/Shape_detection/region_growing_planes_on_polygon_mesh.cpp @@ -6,7 +6,7 @@ #endif #include #include -#include +#include #include "include/utils.h" // Typedefs. diff --git a/Straight_skeleton_2/examples/Straight_skeleton_2/extrude_skeleton.cpp b/Straight_skeleton_2/examples/Straight_skeleton_2/extrude_skeleton.cpp index a50f2efc4da4..cc73aa7493b5 100644 --- a/Straight_skeleton_2/examples/Straight_skeleton_2/extrude_skeleton.cpp +++ b/Straight_skeleton_2/examples/Straight_skeleton_2/extrude_skeleton.cpp @@ -9,7 +9,7 @@ #include "CGAL/input_helpers.h" // polygon reading, random polygon with weights generation #include -#include +#include #include #include #include diff --git a/Straight_skeleton_extrusion_2/test/Straight_skeleton_extrusion_2/test_sls_extrude.cpp b/Straight_skeleton_extrusion_2/test/Straight_skeleton_extrusion_2/test_sls_extrude.cpp index eaa971ce880c..d6f68604517c 100644 --- a/Straight_skeleton_extrusion_2/test/Straight_skeleton_extrusion_2/test_sls_extrude.cpp +++ b/Straight_skeleton_extrusion_2/test/Straight_skeleton_extrusion_2/test_sls_extrude.cpp @@ -6,7 +6,7 @@ #include #include -#include +#include namespace PMP = ::CGAL::Polygon_mesh_processing; diff --git a/Surface_mesh_simplification/examples/Surface_mesh_simplification/edge_collapse_garland_heckbert.cpp b/Surface_mesh_simplification/examples/Surface_mesh_simplification/edge_collapse_garland_heckbert.cpp index 365fc39d2671..7d2f9500b5db 100644 --- a/Surface_mesh_simplification/examples/Surface_mesh_simplification/edge_collapse_garland_heckbert.cpp +++ b/Surface_mesh_simplification/examples/Surface_mesh_simplification/edge_collapse_garland_heckbert.cpp @@ -6,7 +6,7 @@ #include #include -#include +#include #include #include diff --git a/Surface_mesh_simplification/examples/Surface_mesh_simplification/edge_collapse_linear_cell_complex.cpp b/Surface_mesh_simplification/examples/Surface_mesh_simplification/edge_collapse_linear_cell_complex.cpp index 4bedf34619a1..19105b1833b7 100644 --- a/Surface_mesh_simplification/examples/Surface_mesh_simplification/edge_collapse_linear_cell_complex.cpp +++ b/Surface_mesh_simplification/examples/Surface_mesh_simplification/edge_collapse_linear_cell_complex.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include diff --git a/Surface_mesh_simplification/test/Surface_mesh_simplification/test_edge_collapse_stability.cpp b/Surface_mesh_simplification/test/Surface_mesh_simplification/test_edge_collapse_stability.cpp index 1a6a2786c6db..6566b233e610 100644 --- a/Surface_mesh_simplification/test/Surface_mesh_simplification/test_edge_collapse_stability.cpp +++ b/Surface_mesh_simplification/test/Surface_mesh_simplification/test_edge_collapse_stability.cpp @@ -7,7 +7,7 @@ #include #include -#include +#include //bbox #include diff --git a/Surface_mesh_simplification/test/Surface_mesh_simplification/test_edge_deprecated_stop_predicates.cpp b/Surface_mesh_simplification/test/Surface_mesh_simplification/test_edge_deprecated_stop_predicates.cpp index 238a796eb033..5a898efb4df9 100644 --- a/Surface_mesh_simplification/test/Surface_mesh_simplification/test_edge_deprecated_stop_predicates.cpp +++ b/Surface_mesh_simplification/test/Surface_mesh_simplification/test_edge_deprecated_stop_predicates.cpp @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include diff --git a/Surface_mesh_skeletonization/examples/Surface_mesh_skeletonization/MCF_Skeleton_LCC_example.cpp b/Surface_mesh_skeletonization/examples/Surface_mesh_skeletonization/MCF_Skeleton_LCC_example.cpp index bc2455499ad8..dd62887970c7 100644 --- a/Surface_mesh_skeletonization/examples/Surface_mesh_skeletonization/MCF_Skeleton_LCC_example.cpp +++ b/Surface_mesh_skeletonization/examples/Surface_mesh_skeletonization/MCF_Skeleton_LCC_example.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include diff --git a/Surface_mesh_skeletonization/examples/Surface_mesh_skeletonization/simple_mcfskel_LCC_example.cpp b/Surface_mesh_skeletonization/examples/Surface_mesh_skeletonization/simple_mcfskel_LCC_example.cpp index 522ce16fb445..83f07c3d25da 100644 --- a/Surface_mesh_skeletonization/examples/Surface_mesh_skeletonization/simple_mcfskel_LCC_example.cpp +++ b/Surface_mesh_skeletonization/examples/Surface_mesh_skeletonization/simple_mcfskel_LCC_example.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include From 07acb78d302fcad1e4f1264f0a7d7233695f3b2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 12 Dec 2023 09:41:44 +0100 Subject: [PATCH 283/329] add tests for autoref --- .../Polygon_mesh_processing/autorefinement.h | 34 ++++-- .../Polygon_mesh_processing/CMakeLists.txt | 1 + .../test_autorefinement.cmd | 56 +++++----- .../test_autorefinement.cpp | 103 +++++++++++++++--- 4 files changed, 144 insertions(+), 50 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 05d05637b16a..b2d8427875c7 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -46,7 +46,7 @@ #include #if TBB_INTERFACE_VERSION < 12010 && !defined(TBB_PREVIEW_CONCURRENT_ORDERED_CONTAINERS) #define CGAL_HAS_DEFINED_TBB_PREVIEW_CONCURRENT_ORDERED_CONTAINERS -#define TBB_PREVIEW_CONCURRENT_ORDERED_CONTAINERS +#define TBB_PREVIEW_CONCURRENT_ORDERED_CONTAINERS 1 #endif #include #include @@ -857,7 +857,16 @@ void autorefine_triangle_soup(PointRange& soup_points, CGAL_PMP_AUTOREFINE_VERBOSE("collect intersecting pairs"); triangle_soup_self_intersections(soup_points, soup_triangles, std::back_inserter(si_pairs), np); - if (si_pairs.empty()) return; + if (si_pairs.empty()) + { + if constexpr (!std::is_same_v) + { + visitor.number_of_output_triangles(soup_triangles.size()); + for(std::size_t i=0; i is_degen(soup_triangles.size(), false); @@ -1125,7 +1134,16 @@ void autorefine_triangle_soup(PointRange& soup_points, TriangleRange soup_triangles_out; soup_triangles_out.reserve(soup_triangles.size()); - visitor.number_of_output_triangles(soup_triangles.size()+new_triangles.size()); + if constexpr (!std::is_same_v) + { + std::size_t nbt=0; + for (Input_TID f=0; f tri_inter_ids_inverse(triangles.size()); @@ -1136,7 +1154,7 @@ void autorefine_triangle_soup(PointRange& soup_points, int tiid = tri_inter_ids[f]; if (tiid == -1) { - visitor.verbatim_triangle_copy(soup_triangles.size(), f); + visitor.verbatim_triangle_copy(soup_triangles_out.size(), f); soup_triangles_out.push_back( {soup_triangles[f][0], soup_triangles[f][1], soup_triangles[f][2]} ); @@ -1200,7 +1218,7 @@ void autorefine_triangle_soup(PointRange& soup_points, soup_triangles_out.resize(offset + new_triangles.size()); //use map iterator triple for triangles to create them concurrently and safely - std::vector::iterator, 3>> triangle_buffer(new_triangles.size()); + std::vector> triangle_buffer(new_triangles.size()); tbb::parallel_for(tbb::blocked_range(0, new_triangles.size()), [&](const tbb::blocked_range& r) { for (size_t ti = r.begin(); ti != r.end(); ++ti) { @@ -1238,10 +1256,8 @@ void autorefine_triangle_soup(PointRange& soup_points, std::vector> triangle_buffer(new_triangles.size()); tbb::parallel_for(tbb::blocked_range(0, new_triangles.size()), [&](const tbb::blocked_range& r) { - for (size_t ti = r.begin(); ti != r.end(); ++ti) { - if (offset + ti > soup_triangles_out.size()) { - std::cout << "ti = " << ti << std::endl; - } + for (size_t ti = r.begin(); ti != r.end(); ++ti) + { const std::array& t = new_triangles[ti].first; visitor.new_subtriangle(offset+ti, tri_inter_ids_inverse[new_triangles[ti].second]); triangle_buffer[ti] = CGAL::make_array(concurrent_get_point_id(t[0]), concurrent_get_point_id(t[1]), concurrent_get_point_id(t[2])); diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt b/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt index d9ea1a1cf37c..248831b50517 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt @@ -105,6 +105,7 @@ if(TARGET CGAL::TBB_support) target_link_libraries(test_pmp_distance PUBLIC CGAL::TBB_support) target_link_libraries(orient_polygon_soup_test PUBLIC CGAL::TBB_support) target_link_libraries(self_intersection_surface_mesh_test PUBLIC CGAL::TBB_support) + target_link_libraries(test_autorefinement PUBLIC CGAL::TBB_support) else() message(STATUS "NOTICE: Intel TBB was not found. Tests will use sequential code.") endif() diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_autorefinement.cmd b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_autorefinement.cmd index a2ffe2c25393..8c848a2f1065 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_autorefinement.cmd +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_autorefinement.cmd @@ -1,28 +1,28 @@ -data-autoref/test_01.off 0 0 4 1 4 0 -data-autoref/test_02.off 1 5 13 1 5 0 -data-autoref/test_03.off 4 8 18 0 18 0 -data-autoref/test_04.off 1 5 17 0 17 0 -data-autoref/test_05.off 1 5 17 0 17 0 -data-autoref/test_06.off 3 55 141 1 76 0 -data-autoref/test_07.off 1 4 10 1 4 0 -data-autoref/test_08.off 1 31 87 1 52 0 -data-autoref/test_09.off 1 4 5 1 4 0 -data-autoref/test_10.off 1 3 13 0 13 0 -data-autoref/test_11.off 1 3 12 0 12 0 -data-autoref/test_12.off 2 2 11 1 11 0 -data-autoref/test_13.off 1 5 16 1 8 0 -data-autoref/test_14.off 1 5 16 1 12 0 -data-autoref/test_15.off 3 8 16 1 12 0 -data-autoref/test_16.off 1 2 6 1 4 0 -data-autoref/test_17.off 1 2 6 1 4 0 -data-autoref/triple_inter_exception/triple.off 0 0 0 0 0 1 -data-autoref/triple_inter_exception/cubes_cpln_1.off 0 0 0 0 0 1 -data-autoref/triple_inter_exception/cubes_cpln_2.off 0 0 0 0 0 1 -data-autoref/triple_inter_exception/cubes_cpln_3.off 0 0 0 0 0 1 -data-autoref/open_01.off 1 65 1377 1 1313 0 -data-autoref/open_02.off 1 33 595 1 562 0 -data-autoref/cpln_01.off 18 42 48 1 30 0 -data-autoref/cpln_02.off 28 56 40 1 24 0 -data-autoref/cpln_03.off 15 35 42 1 27 0 -data-autoref/four_cubes.off 12 94 184 1 78 0 -data-autoref/spiral.off 7 14 26 0 26 0 +data-autoref/test_01.off 0 0 4 1 4 0 4 2 +data-autoref/test_02.off 1 5 13 1 5 0 10 17 +data-autoref/test_03.off 4 8 18 0 18 0 14 20 +data-autoref/test_04.off 1 5 17 0 17 0 13 20 +data-autoref/test_05.off 1 5 17 0 17 0 13 20 +data-autoref/test_06.off 3 55 141 1 76 0 92 248 +data-autoref/test_07.off 1 4 10 1 4 0 8 12 +data-autoref/test_08.off 1 31 87 1 52 0 57 148 +data-autoref/test_09.off 1 4 5 1 4 0 4 4 +data-autoref/test_10.off 1 3 13 0 13 0 10 13 +data-autoref/test_11.off 1 3 12 0 12 0 9 12 +data-autoref/test_12.off 2 2 11 1 11 0 9 6 +data-autoref/test_13.off 1 5 16 1 8 0 16 22 +data-autoref/test_14.off 1 5 16 1 12 0 16 22 +data-autoref/test_15.off 3 8 16 1 12 0 16 24 +data-autoref/test_16.off 1 2 6 1 4 0 6 2 +data-autoref/test_17.off 1 2 6 1 4 0 6 2 +data-autoref/triple_inter_exception/triple.off 0 0 0 0 0 1 15 18 +data-autoref/triple_inter_exception/cubes_cpln_1.off 0 0 0 0 0 1 66 224 +data-autoref/triple_inter_exception/cubes_cpln_2.off 0 0 0 0 0 1 54 196 +data-autoref/triple_inter_exception/cubes_cpln_3.off 0 0 0 0 0 1 61 204 +data-autoref/open_01.off 1 65 1377 1 1313 0 1317 2622 +data-autoref/open_02.off 1 33 595 1 562 0 565 1056 +data-autoref/cpln_01.off 18 42 48 1 30 0 30 88 +data-autoref/cpln_02.off 28 56 40 1 24 0 24 72 +data-autoref/cpln_03.off 15 35 42 1 27 0 27 76 +data-autoref/four_cubes.off 12 94 184 1 78 0 106 352 +data-autoref/spiral.off 7 14 26 0 26 0 19 31 diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_autorefinement.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_autorefinement.cpp index 9c908d7ec245..3af3402a5f22 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_autorefinement.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_autorefinement.cpp @@ -3,6 +3,10 @@ #include #include +#include +#include + +#include #include #include @@ -13,23 +17,64 @@ typedef CGAL::Surface_mesh Mesh; namespace PMP = CGAL::Polygon_mesh_processing; template -struct My_visitor : +struct My_exp_visitor : public CGAL::Polygon_mesh_processing::Corefinement::Default_visitor { void after_subface_creations(TriangleMesh&){++(*i);} - My_visitor() + My_exp_visitor() : i (new int(0) ) {} std::shared_ptr i; }; -void test(const char* fname, std::size_t nb_polylines, std::size_t total_nb_points, - std::size_t nb_vertices_after_autorefine, bool all_fixed, std::size_t nb_vertices_after_fix, - bool triple_intersection) +struct My_visitor { - std::cout << "Running tests on " << fname << "\n"; + My_visitor(std::size_t nb_input, std::size_t expected_nb_output) + : nb_input(nb_input) + , expected_nb_output(expected_nb_output) + {} + + ~My_visitor() + { + for(std::size_t i=0; i tgt_check; +}; + +void test_coref_based(const char* fname, std::size_t nb_polylines, std::size_t total_nb_points, + std::size_t nb_vertices_after_autorefine, bool all_fixed, std::size_t nb_vertices_after_fix, + bool triple_intersection) +{ + std::cout << "Running tests (coref based) on " << fname << "\n"; std::ifstream input(fname); Mesh mesh; @@ -41,7 +86,7 @@ void test(const char* fname, std::size_t nb_polylines, std::size_t total_nb_poin input.close(); std::size_t nb_vertices_before_autorefine = num_vertices(mesh); -// Testing surface_self_intersection() +// Testing PMP::experimental::surface_self_intersection() try{ std::vector< std::vector >polylines; PMP::experimental::surface_self_intersection(mesh, std::back_inserter(polylines)); @@ -57,9 +102,9 @@ void test(const char* fname, std::size_t nb_polylines, std::size_t total_nb_poin assert( triple_intersection ); } -// Testing autorefine() +// Testing PMP::experimental::autorefine() try{ - My_visitor visitor; + My_exp_visitor visitor; PMP::experimental::autorefine(mesh, CGAL::parameters::visitor(visitor)); mesh.collect_garbage(); @@ -72,7 +117,7 @@ void test(const char* fname, std::size_t nb_polylines, std::size_t total_nb_poin assert( triple_intersection ); } -// Testing autorefine_and_remove_self_intersections() +// Testing PMP::experimental::autorefine_and_remove_self_intersections() try{ input.open(fname); mesh.clear(); @@ -89,10 +134,42 @@ void test(const char* fname, std::size_t nb_polylines, std::size_t total_nb_poin } } +template +void test(const char* fname, std::size_t nb_vertices_after_autorefine, std::size_t expected_nb_output, Tag tag) +{ + std::cout << "Running tests on " << fname; + if (std::is_same_v) + std::cout << " (Sequential)\n"; + else + std::cout << " (Parallel)\n"; + + std::vector points; + std::vector< std::vector > triangles; + if (!CGAL::IO::read_polygon_soup(fname, points, triangles)) + { + std::cerr << " Input mesh is not a valid file." << std::endl; + exit(EXIT_FAILURE); + } + +// Testing autorefine() + My_visitor visitor(triangles.size(), expected_nb_output); + PMP::autorefine_triangle_soup(points, triangles, CGAL::parameters::visitor(visitor).concurrency_tag(tag)); + assert( nb_vertices_after_autorefine==points.size()); + assert( expected_nb_output==triangles.size()); + assert( !PMP::does_triangle_soup_self_intersect(points, triangles) ); +// CGAL::IO::write_polygon_soup("/tmp/debug.off", points, triangles); +} + int main(int argc, const char** argv) { // file nb_polylines total_nb_points nb_vertices_after_autorefine all_fixed nb_vertices_after_fix triple_intersection - for (int i=0;i<(argc-1)/7; ++i) - test(argv[1+7*i], atoi(argv[1+7*i+1]), atoi(argv[1+7*i+2]), - atoi(argv[1+7*i+3]), atoi(argv[1+7*i+4])==0?false:true, atoi(argv[1+7*i+5]), atoi(argv[1+7*i+6])==0?false:true); + for (int i=0;i<(argc-1)/9; ++i) + { + test_coref_based(argv[1+9*i], atoi(argv[1+9*i+1]), atoi(argv[1+9*i+2]), + atoi(argv[1+9*i+3]), atoi(argv[1+9*i+4])==0?false:true, atoi(argv[1+9*i+5]), atoi(argv[1+9*i+6])==0?false:true); + test(argv[1+9*i], atoi(argv[1+9*i+7]), atoi(argv[1+9*i+8]), CGAL::Sequential_tag()); +#ifdef CGAL_LINKED_WITH_TBB + test(argv[1+9*i], atoi(argv[1+9*i+7]), atoi(argv[1+9*i+8]), CGAL::Parallel_tag()); +#endif + } } From 6ca34b62109c9d8c30a0e905330d3c3e26d1bb1f Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 12 Dec 2023 08:44:12 +0000 Subject: [PATCH 284/329] Add example for sampling --- .../Polygon_mesh_processing/CMakeLists.txt | 1 + .../sample_example.cpp | 51 +++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 Polygon_mesh_processing/examples/Polygon_mesh_processing/sample_example.cpp diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt b/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt index 590305c0c8ad..5adc0de4597c 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt @@ -7,6 +7,7 @@ project(Polygon_mesh_processing_Examples) # CGAL and its components find_package(CGAL REQUIRED) +create_single_source_cgal_program("sample_example.cpp" ) create_single_source_cgal_program("extrude.cpp" ) create_single_source_cgal_program("polyhedral_envelope.cpp" ) create_single_source_cgal_program("polyhedral_envelope_of_triangle_soup.cpp" ) diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/sample_example.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/sample_example.cpp new file mode 100644 index 000000000000..474af00a16c5 --- /dev/null +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/sample_example.cpp @@ -0,0 +1,51 @@ +#include +#include +#include + +#include +#include +#include +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef K::Point_3 Point; + +typedef CGAL::Point_set_3 Point_set; + +typedef CGAL::Surface_mesh Mesh; +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::face_descriptor face_descriptor; + +namespace PMP = CGAL::Polygon_mesh_processing; + +int main(int argc, char* argv[]) +{ + const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/eight.off"); + + Mesh mesh; + if(!PMP::IO::read_polygon_mesh(filename, mesh)) + { + std::cerr << "Invalid input." << std::endl; + return 1; + } + + const double points_per_face = (argc > 2) ? atof(argv[2]) : 10; + + std::vector points; + + PMP::sample_triangle_mesh(mesh, std::back_inserter(points), CGAL::parameters::number_of_points_per_face(points_per_face)); + + std::cout.precision(17); + for(const Point& p : points){ + std::cout << p << std::endl; + } + + Point_set point_set; + PMP::sample_triangle_mesh(mesh, + point_set.point_back_inserter(), + CGAL::parameters::point_map(point_set.point_push_map())); + + std::cout << point_set.number_of_points() << std::endl; + return 0; +} From 4d9476ca5ba78f05c40d2b88d954e7c86407f185 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 12 Dec 2023 08:47:47 +0000 Subject: [PATCH 285/329] Add example for sampling --- .../doc/Polygon_mesh_processing/examples.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt index 6fdeda48ca4d..ba917e038361 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt @@ -46,4 +46,6 @@ \example Polygon_mesh_processing/cc_compatible_orientations.cpp \example Polygon_mesh_processing/remesh_planar_patches.cpp \example Polygon_mesh_processing/remesh_almost_planar_patches.cpp +\example Polygon_mesh_processing/sample_example.cpp +*/ */ From 796188e3510a317ab38a70d681bb66a159617f9b Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 12 Dec 2023 08:52:01 +0000 Subject: [PATCH 286/329] avoid intermediate vector --- .../Point_set_from_sampling_plugin.cpp | 47 +++++++++++++++---- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Point_set_from_sampling_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Point_set_from_sampling_plugin.cpp index c654a51cd6b1..8075bb003f13 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Point_set_from_sampling_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Point_set_from_sampling_plugin.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "Scene_points_with_normal_item.h" #include "Scene_surface_mesh_item.h" @@ -69,7 +70,7 @@ void Polyhedron_demo_point_set_from_sampling_plugin::createPointSet() const CGAL::Three::Scene_interface::Item_id index = scene->mainSelectionIndex(); Scene_points_with_normal_item* points = new Scene_points_with_normal_item(); - std::vector pts; + if (points){ points->setColor(Qt::blue); @@ -80,24 +81,50 @@ void Polyhedron_demo_point_set_from_sampling_plugin::createPointSet() qobject_cast(scene->item(index)); if (sm_item){ + int nf = num_faces(*sm_item->polyhedron()); + + bool ok; + int nb = 0; + nb = QInputDialog::getInt(QApplication::activeWindow(), "Sampling", + "Enter number of sample points:", + nf , 0, (std::numeric_limits::max)(), 1, &ok); + points->setName(QString("%1 (sampled)").arg(sm_item->name())); - CGAL::Polygon_mesh_processing::sample_triangle_mesh(*sm_item->polyhedron(), - std::back_inserter(pts)); + if( ok & (nb > 0)){ + points->point_set()->reserve(nb); + CGAL::Polygon_mesh_processing::sample_triangle_mesh(*sm_item->polyhedron(), + points->point_set()->point_back_inserter(), + CGAL::parameters::number_of_points_on_faces(nb) + .point_map(points->point_set()->point_push_map()) + .do_sample_vertices(false) + .do_sample_edges(false)); + } } Scene_polygon_soup_item* soup_item = qobject_cast(scene->item(index)); if (soup_item){ + int nf = soup_item->polygons().size(); + + bool ok; + int nb = 0; + nb = QInputDialog::getInt(QApplication::activeWindow(), "Sampling", + "Enter number of sample points:", + nf , 0, (std::numeric_limits::max)(), 1, &ok); points->setName(QString("%1 (sampled)").arg(soup_item->name())); - CGAL::Polygon_mesh_processing::sample_triangle_soup(soup_item->points(), - soup_item->polygons(), - std::back_inserter(pts)); - } - points->point_set()->reserve(pts.size()); - for (std::size_t i = 0; i < pts.size(); ++i){ - points->point_set()->insert(pts[i]); + if( ok & (nb > 0)){ + points->point_set()->reserve(nb); + CGAL::Polygon_mesh_processing::sample_triangle_soup(soup_item->points(), + soup_item->polygons(), + points->point_set()->point_back_inserter(), + CGAL::parameters::number_of_points_on_faces(nb) + .point_map(points->point_set()->point_push_map()) + .do_sample_vertices(false) + .do_sample_edges(false)); + } } + scene->addItem(points); QApplication::restoreOverrideCursor(); } From 935a0faf2fc4bf92ed996edd28830e5e971e062e Mon Sep 17 00:00:00 2001 From: Mael Date: Tue, 12 Dec 2023 10:09:06 +0100 Subject: [PATCH 287/329] Update macro name Co-authored-by: Sebastien Loriot --- BGL/include/CGAL/IO/polygon_mesh_io.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/BGL/include/CGAL/IO/polygon_mesh_io.h b/BGL/include/CGAL/IO/polygon_mesh_io.h index 0dce62b6a37d..c2cdcbc52ee8 100644 --- a/BGL/include/CGAL/IO/polygon_mesh_io.h +++ b/BGL/include/CGAL/IO/polygon_mesh_io.h @@ -8,9 +8,9 @@ // // Author(s) : Mael Rouxel-Labbé -#ifndef CGAL_BOOST_GRAPH_POLYGON_MESH_IO_H -#define CGAL_BOOST_GRAPH_POLYGON_MESH_IO_H +#ifndef CGAL_IO_POLYGON_MESH_IO_H +#define CGAL_IO_POLYGON_MESH_IO_H #include -#endif // CGAL_BOOST_GRAPH_POLYGON_MESH_IO_H +#endif // CGAL_IO_POLYGON_MESH_IO_H From 62a64ae870dc2832dcfdc97d33cef64e1ecc4485 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 12 Dec 2023 09:28:01 +0000 Subject: [PATCH 288/329] Add check that it faces are triangles --- .../sample_example.cpp | 7 +++-- .../CGAL/Polygon_mesh_processing/distance.h | 4 +-- .../Point_set_from_sampling_plugin.cpp | 29 +++++++++++++++---- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/sample_example.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/sample_example.cpp index 474af00a16c5..113845a9cb6b 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/sample_example.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/sample_example.cpp @@ -34,7 +34,9 @@ int main(int argc, char* argv[]) std::vector points; - PMP::sample_triangle_mesh(mesh, std::back_inserter(points), CGAL::parameters::number_of_points_per_face(points_per_face)); + PMP::sample_triangle_mesh(mesh, + std::back_inserter(points), + CGAL::parameters::number_of_points_per_face(points_per_face)); std::cout.precision(17); for(const Point& p : points){ @@ -43,8 +45,7 @@ int main(int argc, char* argv[]) Point_set point_set; PMP::sample_triangle_mesh(mesh, - point_set.point_back_inserter(), - CGAL::parameters::point_map(point_set.point_push_map())); + point_set.point_back_inserter()); std::cout << point_set.number_of_points() << std::endl; return 0; diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/distance.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/distance.h index 8b41ff2ecdb7..b3aaf70604f6 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/distance.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/distance.h @@ -747,7 +747,7 @@ struct Triangle_structure_sampler_for_triangle_soup * @tparam TriangleMesh a model of the concepts `EdgeListGraph` and `FaceListGraph` * @tparam PointOutputIterator a model of `OutputIterator` * holding objects of the same point type as - * the value type of the point type associated to the mesh `tm`, i.e. the value type of the vertex + * the value type of the point type associated to the mesh `tm`, i.e., the value type of the vertex * point map property map, if provided, or the value type of the internal point property map otherwise * @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" * @@ -1570,7 +1570,7 @@ bounded_error_squared_Hausdorff_distance_impl(const TriangleMesh1& tm1, candidate_triangles.pop(); // Only process the triangle if it can contribute to the Hausdorff distance, - // i.e. if its upper bound is higher than the currently known best lower bound + // i.e., if its upper bound is higher than the currently known best lower bound // and the difference between the bounds to be obtained is larger than the // user-given error. const auto& triangle_bounds = triangle_and_bounds.bounds; diff --git a/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Point_set_from_sampling_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Point_set_from_sampling_plugin.cpp index 8075bb003f13..33c07c12ec46 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Point_set_from_sampling_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Point_set_from_sampling_plugin.cpp @@ -1,3 +1,5 @@ + +#include #include #include #include @@ -14,6 +16,7 @@ #include "Messages_interface.h" #include +#include using namespace CGAL::Three; class Polyhedron_demo_point_set_from_sampling_plugin : @@ -52,7 +55,7 @@ void Polyhedron_demo_point_set_from_sampling_plugin::init(QMainWindow* mainWindo Messages_interface*) { scene = scene_interface; - actionPointSetFromSampling = new QAction(tr("&Create Point Set from Sampling"), mainWindow); + actionPointSetFromSampling = new QAction(tr("Create Point Set from Sampling"), mainWindow); actionPointSetFromSampling->setObjectName("actionPointSetFromSampling"); connect(actionPointSetFromSampling, SIGNAL(triggered()), this, SLOT(createPointSet())); @@ -75,18 +78,24 @@ void Polyhedron_demo_point_set_from_sampling_plugin::createPointSet() if (points){ points->setColor(Qt::blue); }else{ + QApplication::restoreOverrideCursor(); return; } Scene_surface_mesh_item* sm_item = qobject_cast(scene->item(index)); if (sm_item){ + if(! CGAL::is_triangle_mesh(*sm_item->polyhedron())){ + CGAL::Three::Three::error(QString("The mesh must have triangle faces")); + QApplication::restoreOverrideCursor(); + return; + } int nf = num_faces(*sm_item->polyhedron()); bool ok; int nb = 0; nb = QInputDialog::getInt(QApplication::activeWindow(), "Sampling", - "Enter number of sample points:", + "Number of sample points:", nf , 0, (std::numeric_limits::max)(), 1, &ok); points->setName(QString("%1 (sampled)").arg(sm_item->name())); @@ -95,9 +104,9 @@ void Polyhedron_demo_point_set_from_sampling_plugin::createPointSet() CGAL::Polygon_mesh_processing::sample_triangle_mesh(*sm_item->polyhedron(), points->point_set()->point_back_inserter(), CGAL::parameters::number_of_points_on_faces(nb) - .point_map(points->point_set()->point_push_map()) .do_sample_vertices(false) .do_sample_edges(false)); + scene->addItem(points); } } @@ -107,10 +116,18 @@ void Polyhedron_demo_point_set_from_sampling_plugin::createPointSet() if (soup_item){ int nf = soup_item->polygons().size(); + for(const auto& f : soup_item->polygons()){ + if(f.size() != 3){ + CGAL::Three::Three::error(QString("The polygons must be triangles")); + QApplication::restoreOverrideCursor(); + return; + } + } + bool ok; int nb = 0; nb = QInputDialog::getInt(QApplication::activeWindow(), "Sampling", - "Enter number of sample points:", + "Number of sample points:", nf , 0, (std::numeric_limits::max)(), 1, &ok); points->setName(QString("%1 (sampled)").arg(soup_item->name())); if( ok & (nb > 0)){ @@ -119,13 +136,13 @@ void Polyhedron_demo_point_set_from_sampling_plugin::createPointSet() soup_item->polygons(), points->point_set()->point_back_inserter(), CGAL::parameters::number_of_points_on_faces(nb) - .point_map(points->point_set()->point_push_map()) .do_sample_vertices(false) .do_sample_edges(false)); + scene->addItem(points); } } - scene->addItem(points); + QApplication::restoreOverrideCursor(); } From 10f4caa29638b86a15df361a4da9eba9db599391 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 12 Dec 2023 11:53:22 +0100 Subject: [PATCH 289/329] add missing ref --- .../include/CGAL/Polygon_mesh_processing/autorefinement.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index b2d8427875c7..c9751752d753 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -1200,7 +1200,7 @@ void autorefine_triangle_soup(PointRange& soup_points, //option 1 (using a mutex) CGAL_MUTEX point_container_mutex; /// Lambda concurrent_get_point_id() - auto concurrent_get_point_id = [&](const typename EK::Point_3 pt) + auto concurrent_get_point_id = [&](const typename EK::Point_3& pt) { auto insert_res = point_id_map.insert(std::make_pair(pt, -1)); @@ -1243,7 +1243,7 @@ void autorefine_triangle_soup(PointRange& soup_points, //option 2 (without mutex) /// Lambda concurrent_get_point_id() tbb::concurrent_vector iterators; - auto concurrent_get_point_id = [&](const typename EK::Point_3 pt) + auto concurrent_get_point_id = [&](const typename EK::Point_3& pt) { auto insert_res = point_id_map.insert(std::make_pair(pt, -1)); if (insert_res.second) From b267b31bea9737dffaaa4b34f0a284ca991d9174 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 12 Dec 2023 13:12:21 +0100 Subject: [PATCH 290/329] workaround MSVC 2022 bug --- .../include/CGAL/Polygon_mesh_processing/autorefinement.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index c9751752d753..ec3f02633c84 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -996,9 +996,10 @@ void autorefine_triangle_soup(PointRange& soup_points, if (!all_points[ti].empty()) { - std::vector tmp; + using EPoint_3 = EK::Point_3; // workaround for MSVC 2022 bug + std::vector tmp; tmp.swap(all_points[ti]); - for (const typename EK::Point_3& pt : tmp) + for (const EPoint_3& pt : tmp) get_point_id(pt); } From 814a92655dfe38b96032772f3eae5aa351becde2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 12 Dec 2023 13:12:45 +0100 Subject: [PATCH 291/329] remove non needed typenames + missing ref --- .../Polygon_mesh_processing/autorefinement.h | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index ec3f02633c84..8a61b92f7178 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -447,8 +447,7 @@ bool collect_intersections(const std::array& t1, } template + class PointVector> void generate_subtriangles(std::size_t ti, std::vector>& segments, std::vector& points, @@ -896,7 +895,7 @@ void autorefine_triangle_soup(PointRange& soup_points, // init the vector of triangles used for the autorefinement of triangles typedef CGAL::Exact_predicates_exact_constructions_kernel EK; - std::vector< std::array > triangles(tiid+1); + std::vector< std::array > triangles(tiid+1); Cartesian_converter to_exact; for(Input_TID f : intersected_faces) @@ -926,14 +925,14 @@ void autorefine_triangle_soup(PointRange& soup_points, if (i1==-1 || i2==-1) continue; //skip degenerate faces - const std::array& t1 = triangles[i1]; - const std::array& t2 = triangles[i2]; + const std::array& t1 = triangles[i1]; + const std::array& t2 = triangles[i2]; - std::vector inter_pts; + std::vector inter_pts; bool triangles_are_coplanar = autorefine_impl::collect_intersections(t1, t2, inter_pts); CGAL_assertion( - CGAL::do_intersect(typename EK::Triangle_3(t1[0], t1[1], t1[2]), typename EK::Triangle_3(t2[0], t2[1], t2[2])) + CGAL::do_intersect(EK::Triangle_3(t1[0], t1[1], t1[2]), EK::Triangle_3(t2[0], t2[1], t2[2])) != inter_pts.empty()); if (!inter_pts.empty()) @@ -985,7 +984,7 @@ void autorefine_triangle_soup(PointRange& soup_points, std::map point_id_map; - auto get_point_id = [&](const typename EK::Point_3& pt) + auto get_point_id = [&](const EK::Point_3& pt) { auto insert_res = point_id_map.insert(std::make_pair(pt, all_points[ti].size())); if (insert_res.second) @@ -1010,8 +1009,8 @@ void autorefine_triangle_soup(PointRange& soup_points, std::set> segset; for (std::size_t si=0; si iterators; - auto concurrent_get_point_id = [&](const typename EK::Point_3& pt) + auto concurrent_get_point_id = [&](const EK::Point_3& pt) { auto insert_res = point_id_map.insert(std::make_pair(pt, -1)); if (insert_res.second) From 35e845d8dcf7d88c25c33ac73d9f96052578ec43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 12 Dec 2023 15:11:40 +0100 Subject: [PATCH 292/329] do no use delete event --- .../CGAL/Surface_sweep_2/Surface_sweep_2_impl.h | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Surface_sweep_2/include/CGAL/Surface_sweep_2/Surface_sweep_2_impl.h b/Surface_sweep_2/include/CGAL/Surface_sweep_2/Surface_sweep_2_impl.h index cd36570d27b4..88ff82a63f57 100644 --- a/Surface_sweep_2/include/CGAL/Surface_sweep_2/Surface_sweep_2_impl.h +++ b/Surface_sweep_2/include/CGAL/Surface_sweep_2/Surface_sweep_2_impl.h @@ -573,10 +573,12 @@ void Surface_sweep_2::_intersect(Subcurve* c1, Subcurve* c2, Event* left_event = first_parent->left_event(); Event* right_event = first_parent->right_event(); - if (! second_parent->is_start_point(left_event)) - left_event->add_curve_to_left(second_parent); - else - left_event->remove_curve_from_right(second_parent); + if (left_event != nullptr) { + if (! second_parent->is_start_point(left_event)) + left_event->add_curve_to_left(second_parent); + else + left_event->remove_curve_from_right(second_parent); + } CGAL_SS_PRINT_CURVE(c1); CGAL_SS_PRINT_TEXT(" + "); @@ -596,7 +598,8 @@ void Surface_sweep_2::_intersect(Subcurve* c1, Subcurve* c2, // add the overlapping curve kept of the right of the left end right_event->add_curve_to_left(first_parent); - _add_curve_to_right(left_event, first_parent); + if (left_event != nullptr) + _add_curve_to_right(left_event, first_parent); this->m_visitor->found_overlap(c1, c2, first_parent); From 8cc75d642cff010f8166d7d23c82afe7b2efe41a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 12 Dec 2023 15:27:00 +0100 Subject: [PATCH 293/329] fix warnings --- Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp b/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp index cc11bbabac3f..d44a2bbdd344 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp +++ b/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp @@ -149,7 +149,6 @@ std::istream& skip_comment(std::istream& in) { bool read_points(std::ifstream& inp, Points& points, const Traits&) { int count; inp >> skip_comment >> count; - char ch; // std::cout << "read_points " << count << "\n"; for (int i = 0; i < count; i++) { @@ -330,7 +329,7 @@ bool read_curves(std::ifstream& inp, Curves& curves, const Traits&) { #if CGAL_ARR_TEST_TRAITS != CGAL_CONIC_TRAITS // Test subcurves w/o overlapping -bool test_curves_no_overlap(std::ifstream& inp, Curves& curves, +bool test_curves_no_overlap(std::ifstream& inp, Curves& /* curves */, const X_monotone_curves& curves_no_overlap_out, const Traits& tr) { X_monotone_curves curves_no_overlap; @@ -346,7 +345,7 @@ bool test_curves_no_overlap(std::ifstream& inp, Curves& curves, } // Test subcurves w/ overlapping -bool test_curves_with_overlap(std::ifstream& inp, Curves& curves, +bool test_curves_with_overlap(std::ifstream& inp, Curves& /* curves */, const X_monotone_curves& curves_with_overlap_out, const Traits& tr) { X_monotone_curves curves_with_overlap; @@ -363,7 +362,7 @@ bool test_curves_with_overlap(std::ifstream& inp, Curves& curves, } // Test intersection points (with endpoints) -bool test_points_with_ends(std::ifstream& inp, Curves& curves, +bool test_points_with_ends(std::ifstream& inp, Curves& /* curves */, const Points& points_with_ends_out, const Traits& tr) { Points points_with_ends; @@ -379,7 +378,7 @@ bool test_points_with_ends(std::ifstream& inp, Curves& curves, } // Test intersection points w/o end points -bool test_points_no_ends(std::ifstream& inp, Curves& curves, +bool test_points_no_ends(std::ifstream& inp, Curves& /* curves */, const Points& points_no_ends_out, const Traits& tr) { Points points_no_ends; @@ -403,7 +402,6 @@ bool test_conic(std::ifstream& inp, Curves& curves, const Points& points_with_ends_out, const Points& points_no_ends_out, const Traits&) { - char dummy[256]; CGAL::Bbox_2 bbox = curves.front().bbox(); for (auto it = std::next(curves.begin()); it != curves.end(); ++it) From fa052c3d84a647c95d610639fe07e04979475a2c Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Tue, 12 Dec 2023 11:48:14 +0100 Subject: [PATCH 294/329] move sliver peeling to its own header file # Conflicts: # Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_adaptive_remeshing_impl.h --- .../internal/peel_slivers.h | 117 ++++++++++++++++++ .../tetrahedral_adaptive_remeshing_impl.h | 79 +----------- 2 files changed, 121 insertions(+), 75 deletions(-) create mode 100644 Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/peel_slivers.h diff --git a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/peel_slivers.h b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/peel_slivers.h new file mode 100644 index 000000000000..9cbff2ba95a1 --- /dev/null +++ b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/peel_slivers.h @@ -0,0 +1,117 @@ +// Copyright (c) 2020 GeometryFactory (France) and Telecom Paris (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Jane Tournois, Noura Faraj, Jean-Marc Thiery, Tamy Boubekeur + +#ifndef CGAL_INTERNAL_PEEL_SLIVERS_H +#define CGAL_INTERNAL_PEEL_SLIVERS_H + +#include + +#include + +namespace CGAL +{ +namespace Tetrahedral_remeshing +{ + +template +std::size_t peel_slivers(C3T3& c3t3, + const typename C3T3::Triangulation::Geom_traits::FT& sliver_angle, + const CellSelector& cell_selector) +{ + using FT = typename C3T3::Triangulation::Geom_traits::FT; + using Cell_handle = typename C3T3::Triangulation::Cell_handle; + using Surface_patch_index = typename C3T3::Surface_patch_index; + + auto& tr = c3t3.triangulation(); + + std::size_t nb_slivers_peel = 0; + std::vector > > peelable_cells; + +#ifdef CGAL_TETRAHEDRAL_REMESHING_VERBOSE + FT mindh = FT(180); +#endif + for (Cell_handle cit : c3t3.cells_in_complex()) + { + if(!get(cell_selector, cit)) + continue; + + std::array facets_on_surface; + + const FT dh = min_dihedral_angle(tr, cit); + if (dh < sliver_angle && is_peelable(c3t3, cit, facets_on_surface)) + peelable_cells.push_back(std::make_pair(cit, facets_on_surface)); + +#ifdef CGAL_TETRAHEDRAL_REMESHING_VERBOSE + mindh = (std::min)(dh, mindh); +#endif + } + +#ifdef CGAL_TETRAHEDRAL_REMESHING_VERBOSE + std::cout << "Min dihedral angle : " << mindh << std::endl; + std::cout << "Peelable cells : " << peelable_cells.size() << std::endl; +#endif + + for (auto c_i : peelable_cells) + { + Cell_handle c = c_i.first; + const std::array& f_on_surface = c_i.second; + + boost::optional patch; + for (int i = 0; i < 4; ++i) + { + if (f_on_surface[i]) + { + Surface_patch_index spi = c3t3.surface_patch_index(c, i); + if (patch != boost::none && patch != spi) + { + patch = boost::none; + break; + } + else + { + patch = spi; + } + } + } + if (patch == boost::none) + continue; + + for (int i = 0; i < 4; ++i) + { + if (f_on_surface[i]) + c3t3.remove_from_complex(c, i); + else + c3t3.add_to_complex(c, i, patch.get()); + } + + c3t3.remove_from_complex(c); + ++nb_slivers_peel; + } + +#ifdef CGAL_TETRAHEDRAL_REMESHING_VERBOSE + mindh = FT(180); + for (Cell_handle cit : c3t3.cells_in_complex()) + { + const FT dh = min_dihedral_angle(tr, cit); + mindh = (std::min)(dh, mindh); + } + std::cout << "Peeling done (removed " << nb_slivers_peel << " slivers, " + << "min dihedral angle = " << mindh << ")." << std::endl; +#endif + + return nb_slivers_peel; +} + +} // end namespace Tetrahedral_remeshing +} // end namespace CGAL + +#endif // CGAL_INTERNAL_PEEL_SLIVERS_H diff --git a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_adaptive_remeshing_impl.h b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_adaptive_remeshing_impl.h index be3dfe8f276f..8b2cbe40a6e4 100644 --- a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_adaptive_remeshing_impl.h +++ b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/tetrahedral_adaptive_remeshing_impl.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -291,67 +292,8 @@ class Adaptive_remesher std::cout.flush(); #endif - std::size_t nb_slivers_peel = 0; - std::vector > > peelable_cells; -#ifdef CGAL_TETRAHEDRAL_REMESHING_VERBOSE - double mindh = 180.; -#endif - for (Cell_handle cit : tr().finite_cell_handles()) - { - std::array facets_on_surface; - if (m_c3t3.is_in_complex(cit)) - { - const double dh = min_dihedral_angle(tr(), cit); - if(dh < sliver_angle && is_peelable(m_c3t3, cit, facets_on_surface)) - peelable_cells.push_back(std::make_pair(cit, facets_on_surface)); - -#ifdef CGAL_TETRAHEDRAL_REMESHING_VERBOSE - mindh = (std::min)(dh, mindh); -#endif - } - } - -#ifdef CGAL_TETRAHEDRAL_REMESHING_VERBOSE - std::cout << "Min dihedral angle : " << mindh << std::endl; - std::cout << "Peelable cells : " << peelable_cells.size() << std::endl; -#endif - - for (auto c_i : peelable_cells) - { - Cell_handle c = c_i.first; - const std::array& f_on_surface = c_i.second; - - std::optional patch; - for (int i = 0; i < 4; ++i) - { - if (f_on_surface[i]) - { - Surface_patch_index spi = m_c3t3.surface_patch_index(c, i); - if (patch != std::nullopt && patch != spi) - { - patch = std::nullopt; - break; - } - else - { - patch = spi; - } - } - } - if(patch == std::nullopt) - continue; - - for (int i = 0; i < 4; ++i) - { - if(f_on_surface[i]) - m_c3t3.remove_from_complex(c, i); - else - m_c3t3.add_to_complex(c, i, patch.value()); - } - - m_c3t3.remove_from_complex(c); - ++nb_slivers_peel; - } + const std::size_t nb_peeled + = CGAL::Tetrahedral_remeshing::peel_slivers(m_c3t3, sliver_angle, m_cell_selector); #ifdef CGAL_TETRAHEDRAL_REMESHING_DEBUG CGAL_assertion(tr().tds().is_valid(true)); @@ -360,21 +302,8 @@ class Adaptive_remesher #ifdef CGAL_DUMP_REMESHING_STEPS CGAL::Tetrahedral_remeshing::debug::dump_c3t3(m_c3t3, "99-postprocess"); #endif -#ifdef CGAL_TETRAHEDRAL_REMESHING_VERBOSE - mindh = 180.; - for (Cell_handle cit : tr().finite_cell_handles()) - { - if (m_c3t3.is_in_complex(cit)) - { - const double dh = min_dihedral_angle(tr(), cit); - mindh = (std::min)(dh, mindh); - } - } - std::cout << "Peeling done (removed " << nb_slivers_peel << " slivers, " - << "min dihedral angle = " << mindh << ")." << std::endl; -#endif - return nb_slivers_peel; + return nb_peeled; } void finalize() From dac26de5c34734ed6e0bddaa555d0f0910e9395e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 12 Dec 2023 17:09:57 +0100 Subject: [PATCH 295/329] update test cc @efifogel --- Surface_sweep_2/test/Surface_sweep_2/data/polylines/test00.txt | 3 +-- Surface_sweep_2/test/Surface_sweep_2/data/polylines/test01.txt | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/polylines/test00.txt b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/test00.txt index a024e6ccf8f4..d2ae0552ae7a 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/data/polylines/test00.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/test00.txt @@ -30,8 +30,7 @@ 7 0 8 0 # No. of intersection points followed by points -4 -2 0 +3 4 0 6 0 7 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/polylines/test01.txt b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/test01.txt index 60cda75d7fd1..93d9d3227927 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/data/polylines/test01.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/test01.txt @@ -18,8 +18,7 @@ 50 0 60 0 # No. of intersection points followed by points -2 -25 10 +1 50 0 # No. of output polylines with overlaps followed by polylines 6 From f241f4b6efe82ee5b59a817c6292a8db9ba80f04 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Tue, 12 Dec 2023 17:41:37 +0100 Subject: [PATCH 296/329] rename example with shorter name error on windows testsuites : "The fully qualified file name must be less than 260 characters." --- .../doc/Tetrahedral_remeshing/Tetrahedral_remeshing.txt | 2 +- .../doc/Tetrahedral_remeshing/examples.txt | 2 +- .../examples/Tetrahedral_remeshing/CMakeLists.txt | 6 +++--- ...h_features_from_complex.cpp => mesh_and_remesh_c3t3.cpp} | 0 4 files changed, 5 insertions(+), 5 deletions(-) rename Tetrahedral_remeshing/examples/Tetrahedral_remeshing/{mesh_and_remesh_polyhedral_domain_with_features_from_complex.cpp => mesh_and_remesh_c3t3.cpp} (100%) diff --git a/Tetrahedral_remeshing/doc/Tetrahedral_remeshing/Tetrahedral_remeshing.txt b/Tetrahedral_remeshing/doc/Tetrahedral_remeshing/Tetrahedral_remeshing.txt index f0400342db1b..a2e1c0fb1368 100644 --- a/Tetrahedral_remeshing/doc/Tetrahedral_remeshing/Tetrahedral_remeshing.txt +++ b/Tetrahedral_remeshing/doc/Tetrahedral_remeshing/Tetrahedral_remeshing.txt @@ -107,7 +107,7 @@ It is also possible to define the polyline features as the ones stored as complex edges in a `Mesh_complex_3_in_triangulation_3` (e.g. generated by the \ref PkgMesh3 package mesh generation algorithms). -\cgalExample{Tetrahedral_remeshing/mesh_and_remesh_polyhedral_domain_with_features_from_complex.cpp } +\cgalExample{Tetrahedral_remeshing/mesh_and_remesh_c3t3.cpp } \subsection ssecEx4 Tetrahedral Remeshing After Mesh Generation diff --git a/Tetrahedral_remeshing/doc/Tetrahedral_remeshing/examples.txt b/Tetrahedral_remeshing/doc/Tetrahedral_remeshing/examples.txt index 06b69b82469a..17d90d1f20d8 100644 --- a/Tetrahedral_remeshing/doc/Tetrahedral_remeshing/examples.txt +++ b/Tetrahedral_remeshing/doc/Tetrahedral_remeshing/examples.txt @@ -4,6 +4,6 @@ \example Tetrahedral_remeshing/tetrahedral_remeshing_of_one_subdomain.cpp \example Tetrahedral_remeshing/tetrahedral_remeshing_with_features.cpp \example Tetrahedral_remeshing/mesh_and_remesh_polyhedral_domain_with_features.cpp -\example Tetrahedral_remeshing/mesh_and_remesh_polyhedral_domain_with_features_from_complex.cpp +\example Tetrahedral_remeshing/mesh_and_remesh_c3t3.cpp \example Tetrahedral_remeshing/tetrahedral_remeshing_from_mesh.cpp */ diff --git a/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/CMakeLists.txt b/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/CMakeLists.txt index 4448fd6bde71..94981f0550bc 100644 --- a/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/CMakeLists.txt +++ b/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/CMakeLists.txt @@ -31,13 +31,13 @@ if(TARGET CGAL::Eigen3_support) create_single_source_cgal_program( "mesh_and_remesh_polyhedral_domain_with_features.cpp" ) target_link_libraries(mesh_and_remesh_polyhedral_domain_with_features PUBLIC CGAL::Eigen3_support) - create_single_source_cgal_program("mesh_and_remesh_polyhedral_domain_with_features_from_complex.cpp") - target_link_libraries(mesh_and_remesh_polyhedral_domain_with_features_from_complex PUBLIC CGAL::Eigen3_support) + create_single_source_cgal_program("mesh_and_remesh_c3t3.cpp") + target_link_libraries(mesh_and_remesh_c3t3 PUBLIC CGAL::Eigen3_support) if(CGAL_ACTIVATE_CONCURRENT_MESH_3 AND TARGET CGAL::TBB_support) message(STATUS "Found TBB") target_link_libraries(mesh_and_remesh_polyhedral_domain_with_features PRIVATE CGAL::TBB_support) - target_link_libraries(mesh_and_remesh_polyhedral_domain_with_features_from_complex PRIVATE CGAL::TBB_support) + target_link_libraries(mesh_and_remesh_c3t3 PRIVATE CGAL::TBB_support) endif() else() message(STATUS "NOTICE: Some examples require Eigen 3.1 (or greater), and will not be compiled.") diff --git a/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/mesh_and_remesh_polyhedral_domain_with_features_from_complex.cpp b/Tetrahedral_remeshing/examples/Tetrahedral_remeshing/mesh_and_remesh_c3t3.cpp similarity index 100% rename from Tetrahedral_remeshing/examples/Tetrahedral_remeshing/mesh_and_remesh_polyhedral_domain_with_features_from_complex.cpp rename to Tetrahedral_remeshing/examples/Tetrahedral_remeshing/mesh_and_remesh_c3t3.cpp From ee1d222d45019179a9441202ffc7bbab75a7438e Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 13 Dec 2023 07:35:53 +0000 Subject: [PATCH 297/329] double -> int --- .../examples/Polygon_mesh_processing/sample_example.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/sample_example.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/sample_example.cpp index 113845a9cb6b..fa60ae6538f7 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/sample_example.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/sample_example.cpp @@ -30,18 +30,13 @@ int main(int argc, char* argv[]) return 1; } - const double points_per_face = (argc > 2) ? atof(argv[2]) : 10; + const int points_per_face = (argc > 2) ? std::stoi(argv[2]) : 10; std::vector points; - PMP::sample_triangle_mesh(mesh, std::back_inserter(points), CGAL::parameters::number_of_points_per_face(points_per_face)); - std::cout.precision(17); - for(const Point& p : points){ - std::cout << p << std::endl; - } Point_set point_set; PMP::sample_triangle_mesh(mesh, From a701dbc21cbb76d46dfb4d0a03eb9cf842f5b86e Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 13 Dec 2023 08:36:46 +0000 Subject: [PATCH 298/329] Deal with LAS.h --- Point_set_3/include/CGAL/Point_set_3/IO/LAS.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Point_set_3/include/CGAL/Point_set_3/IO/LAS.h b/Point_set_3/include/CGAL/Point_set_3/IO/LAS.h index 7ecf30255ba0..08afc1a220a3 100644 --- a/Point_set_3/include/CGAL/Point_set_3/IO/LAS.h +++ b/Point_set_3/include/CGAL/Point_set_3/IO/LAS.h @@ -25,8 +25,10 @@ namespace CGAL { +#ifndef DOXYGEN_RUNNING template class Point_set_3; +#endif //////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////// From 0f9e44621998984498ce1c81964227e4a0156854 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 13 Dec 2023 08:57:24 +0000 Subject: [PATCH 299/329] static_cast --- .../Operations_on_polyhedra/Point_set_from_sampling_plugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Point_set_from_sampling_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Point_set_from_sampling_plugin.cpp index 33c07c12ec46..aa6ea4c1ba01 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Point_set_from_sampling_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Point_set_from_sampling_plugin.cpp @@ -114,7 +114,7 @@ void Polyhedron_demo_point_set_from_sampling_plugin::createPointSet() qobject_cast(scene->item(index)); if (soup_item){ - int nf = soup_item->polygons().size(); + int nf = static_cast(soup_item->polygons().size()); for(const auto& f : soup_item->polygons()){ if(f.size() != 3){ From 61ad28c80ca736450c5bd8d56e051b07e31be398 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Wed, 13 Dec 2023 09:58:06 +0100 Subject: [PATCH 300/329] Swap the contents of CGAL/IO/polygon_mesh_io.h and CGAL/BGL/IO/polygon_mesh_io.h --- BGL/doc/BGL/Doxyfile.in | 3 +- BGL/include/CGAL/IO/polygon_mesh_io.h | 254 +++++++++++++++++- .../CGAL/boost/graph/IO/polygon_mesh_io.h | 253 +---------------- 3 files changed, 256 insertions(+), 254 deletions(-) diff --git a/BGL/doc/BGL/Doxyfile.in b/BGL/doc/BGL/Doxyfile.in index 4e5d35a91d2c..72d3e79168c8 100644 --- a/BGL/doc/BGL/Doxyfile.in +++ b/BGL/doc/BGL/Doxyfile.in @@ -1,7 +1,8 @@ @INCLUDE = ${CGAL_DOC_PACKAGE_DEFAULTS} PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - CGAL and the Boost Graph Library" -INPUT += ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/Euler_operations.h \ +INPUT += ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/IO/polygon_mesh_io.h \ + ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/Euler_operations.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/iterator.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/helpers.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/generators.h \ diff --git a/BGL/include/CGAL/IO/polygon_mesh_io.h b/BGL/include/CGAL/IO/polygon_mesh_io.h index c2cdcbc52ee8..b8b86d45f8f7 100644 --- a/BGL/include/CGAL/IO/polygon_mesh_io.h +++ b/BGL/include/CGAL/IO/polygon_mesh_io.h @@ -1,4 +1,4 @@ -// Copyright (c) 2023 GeometryFactory (France). All rights reserved. +// Copyright (c) 2020 GeometryFactory (France). All rights reserved. // // This file is part of CGAL (www.cgal.org) // @@ -6,11 +6,259 @@ // $Id$ // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // -// Author(s) : Mael Rouxel-Labbé +// Author(s) : Maxime Gimeno +// Mael Rouxel-Labbé #ifndef CGAL_IO_POLYGON_MESH_IO_H #define CGAL_IO_POLYGON_MESH_IO_H -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace CGAL { + +namespace IO { + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Read + +//not for now : some readers will return "ok" despite not managing to read anything +/* +template +bool read_polygon_mesh(std::istream& is, + Graph& g, + const NamedParameters& np = parameters::default_values()) +{ + bool ok = false; + ok = read_OFF(is, g, np, false); + if(ok) + return true; + g.clear(); + is.clear();//reset the error state + is.seekg (0, is.beg); + ok = read_OBJ(is, g, np, false); + if(ok) + return true; + g.clear(); + is.clear(); + is.seekg (0, is.beg); + ok = read_PLY(is, g, np, false); + if(ok) + return true; + g.clear(); + is.clear(); + is.seekg (0, is.beg); + ok = read_STL(is, g, np, false); + if(ok) + return true; + g.clear(); + is.clear(); + is.seekg (0, is.beg); + ok = read_GOCAD(is, g, np, false); + return ok; +} + +*/ + +/*! + * \ingroup PkgBGLIOFct + * + * \brief reads a polygon mesh from a file. + * + * Supported file formats are the following: + * - \ref IOStreamOFF (`.off`) + * - \ref IOStreamOBJ (`.obj`) + * - \ref IOStreamSTL (`.stl`) + * - \ref IOStreamPLY (`.ply`) + * - \ref IOStreamGocad (`.ts`) + * - \ref IOStreamVTK (`.vtp`) + * + * The format is detected from the filename extension (letter case is not important). + * + * The data is expected to represent a 2-manifold (possibly with borders). + * + * \tparam Graph a model of `MutableFaceGraph` + * \tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" + * + * \param fname the name of the file + * \param g the mesh + * \param np optional \ref bgl_namedparameters "Named Parameters" described below + * + * \cgalNamedParamsBegin + * \cgalParamNBegin{vertex_point_map} + * \cgalParamDescription{a property map associating points to the vertices of `g`} + * \cgalParamType{a class model of `WritablePropertyMap` with `boost::graph_traits::%vertex_descriptor` + * as key type and `%Point_3` as value type} + * \cgalParamDefault{`boost::get(CGAL::vertex_point, g)`} + * \cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t` + * must be available in `Graph`.} + * \cgalParamNEnd + * + * \cgalParamNBegin{verbose} + * \cgalParamDescription{whether extra information is printed when an incident occurs during reading} + * \cgalParamType{Boolean} + * \cgalParamDefault{`false`} + * \cgalParamNEnd + * \cgalNamedParamsEnd + * + * Other named parameters may be used according to the file extension, see \ref PkgBGLIOFct for an exhaustive list. + * + * \return `true` if reading was successful, `false` otherwise. + * + * \sa \link PMP_IO_grp `CGAL::Polygon_mesh_processing::IO::read_polygon_mesh()`\endlink if the data is not 2-manifold +*/ +template +bool read_polygon_mesh(const std::string& fname, + Graph& g, + const NamedParameters& np = parameters::default_values()) +{ + const bool verbose = parameters::choose_parameter(parameters::get_parameter(np, internal_np::verbose), false); + + const std::string ext = internal::get_file_extension(fname); + if(ext == std::string()) + { + if(verbose) + std::cerr << "Error: cannot read from file without extension" << std::endl; + return false; + } + + if(ext == "obj") + return read_OBJ(fname, g, np); + else if(ext == "off") + return read_OFF(fname, g, np); + else if(ext == "ply") + return read_PLY(fname, g, np); + else if(ext == "stl") + return read_STL(fname, g, np); + else if(ext == "ts") + return read_GOCAD(fname, g, np); +#ifdef CGAL_USE_VTK + else if(ext == "vtp") + return read_VTP(fname, g, np); +#endif + + if(verbose) + { + std::cerr << "Error: unknown input file extension: " << ext << "\n" + << "Please refer to the documentation for the list of supported file formats" << std::endl; + } + + return false; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Write + +/*! + * \ingroup PkgBGLIOFct + * + * \brief writes a polygon mesh in a file. + * + * Supported file formats are the following: + * - \ref IOStreamOFF (`.off`) + * - \ref IOStreamOBJ (`.obj`) + * - \ref IOStreamSTL (`.stl`) + * - \ref IOStreamPLY (`.ply`) + * - \ref IOStreamGocad (`.ts`) + * - \ref IOStreamVTK (`.vtp`) + * + * The format is detected from the filename extension (letter case is not important). + * + * \tparam Graph a model of `FaceListGraph` and `HalfedgeListGraph` + * \tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" + * + * \param fname the name of the file + * \param g the mesh to be output + * \param np optional \ref bgl_namedparameters "Named Parameters" described below + * + * \cgalNamedParamsBegin + * \cgalParamNBegin{vertex_point_map} + * \cgalParamDescription{a property map associating points to the vertices of `g`} + * \cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits::%vertex_descriptor` + * as key type and `%Point_3` as value type} + * \cgalParamDefault{`boost::get(CGAL::vertex_point, g)`} + * \cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t` + * must be available in `Graph`.} + * \cgalParamNEnd + * + * \cgalParamNBegin{stream_precision} + * \cgalParamDescription{a parameter used to set the precision (i.e. how many digits are generated) of the output stream} + * \cgalParamType{int} + * \cgalParamDefault{`6`} + * \cgalParamExtra{This parameter is only meaningful while using \ascii encoding.} + * \cgalParamNEnd + * + * \cgalParamNBegin{use_binary_mode} + * \cgalParamDescription{indicates whether data should be written in binary (`true`) or in \ascii (`false`)} + * \cgalParamType{Boolean} + * \cgalParamDefault{`true`} + * \cgalParamExtra{This parameter is only meaningful for formats that support binary encoding.} + * \cgalParamNEnd + * + * \cgalParamNBegin{verbose} + * \cgalParamDescription{whether extra information is printed when an incident occurs during reading} + * \cgalParamType{Boolean} + * \cgalParamDefault{`false`} + * \cgalParamNEnd + * \cgalNamedParamsEnd + * + * Other named parameters may be used according to the file extension, see \ref PkgBGLIOFct for an exhaustive list. + * + * \return `true` if writing was successful, `false` otherwise. + */ +template +bool write_polygon_mesh(const std::string& fname, + Graph& g, + const NamedParameters& np = parameters::default_values()) +{ + const bool verbose = parameters::choose_parameter(parameters::get_parameter(np, internal_np::verbose), false); + + const std::string ext = internal::get_file_extension(fname); + if(ext == std::string()) + { + if(verbose) + std::cerr << "Error: trying to output to file without extension" << std::endl; + return false; + } + + if(ext == "obj") + return write_OBJ(fname, g, np); + else if(ext == "off") + return write_OFF(fname, g, np); + else if(ext == "ply") + return write_PLY(fname, g, np); + else if(ext == "stl") + return write_STL(fname, g, np); + else if(ext == "ts") + return write_GOCAD(fname, g, np); +#ifdef CGAL_USE_VTK + else if(ext == "vtp") + return write_VTP(fname, g, np); +#endif + + if(verbose) + { + std::cerr << "Error: unknown output file extension: " << ext << "\n" + << "Please refer to the documentation for the list of supported file formats" << std::endl; + } + + return false; +} + +} // namespace IO +} // namespace CGAL #endif // CGAL_IO_POLYGON_MESH_IO_H diff --git a/BGL/include/CGAL/boost/graph/IO/polygon_mesh_io.h b/BGL/include/CGAL/boost/graph/IO/polygon_mesh_io.h index d60af3c9949e..84189cf7373b 100644 --- a/BGL/include/CGAL/boost/graph/IO/polygon_mesh_io.h +++ b/BGL/include/CGAL/boost/graph/IO/polygon_mesh_io.h @@ -1,4 +1,4 @@ -// Copyright (c) 2020 GeometryFactory (France). All rights reserved. +// Copyright (c) 2023 GeometryFactory (France). All rights reserved. // // This file is part of CGAL (www.cgal.org) // @@ -6,258 +6,11 @@ // $Id$ // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // -// Author(s) : Maxime Gimeno -// Mael Rouxel-Labbé +// Author(s) : Mael Rouxel-Labbé #ifndef CGAL_BOOST_GRAPH_POLYGON_MESH_IO_H #define CGAL_BOOST_GRAPH_POLYGON_MESH_IO_H -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -namespace CGAL { - -namespace IO { - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Read - -//not for now : some readers will return "ok" despite not managing to read anything -/* -template -bool read_polygon_mesh(std::istream& is, - Graph& g, - const NamedParameters& np = parameters::default_values()) -{ - bool ok = false; - ok = read_OFF(is, g, np, false); - if(ok) - return true; - g.clear(); - is.clear();//reset the error state - is.seekg (0, is.beg); - ok = read_OBJ(is, g, np, false); - if(ok) - return true; - g.clear(); - is.clear(); - is.seekg (0, is.beg); - ok = read_PLY(is, g, np, false); - if(ok) - return true; - g.clear(); - is.clear(); - is.seekg (0, is.beg); - ok = read_STL(is, g, np, false); - if(ok) - return true; - g.clear(); - is.clear(); - is.seekg (0, is.beg); - ok = read_GOCAD(is, g, np, false); - return ok; -} - -*/ - -/*! - * \ingroup PkgBGLIOFct - * - * \brief reads a polygon mesh from a file. - * - * Supported file formats are the following: - * - \ref IOStreamOFF (`.off`) - * - \ref IOStreamOBJ (`.obj`) - * - \ref IOStreamSTL (`.stl`) - * - \ref IOStreamPLY (`.ply`) - * - \ref IOStreamGocad (`.ts`) - * - \ref IOStreamVTK (`.vtp`) - * - * The format is detected from the filename extension (letter case is not important). - * - * The data is expected to represent a 2-manifold (possibly with borders). - * - * \tparam Graph a model of `MutableFaceGraph` - * \tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" - * - * \param fname the name of the file - * \param g the mesh - * \param np optional \ref bgl_namedparameters "Named Parameters" described below - * - * \cgalNamedParamsBegin - * \cgalParamNBegin{vertex_point_map} - * \cgalParamDescription{a property map associating points to the vertices of `g`} - * \cgalParamType{a class model of `WritablePropertyMap` with `boost::graph_traits::%vertex_descriptor` - * as key type and `%Point_3` as value type} - * \cgalParamDefault{`boost::get(CGAL::vertex_point, g)`} - * \cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t` - * must be available in `Graph`.} - * \cgalParamNEnd - * - * \cgalParamNBegin{verbose} - * \cgalParamDescription{whether extra information is printed when an incident occurs during reading} - * \cgalParamType{Boolean} - * \cgalParamDefault{`false`} - * \cgalParamNEnd - * \cgalNamedParamsEnd - * - * Other named parameters may be used according to the file extension, see \ref PkgBGLIOFct for an exhaustive list. - * - * \return `true` if reading was successful, `false` otherwise. - * - * \sa \link PMP_IO_grp `CGAL::Polygon_mesh_processing::IO::read_polygon_mesh()`\endlink if the data is not 2-manifold -*/ -template -bool read_polygon_mesh(const std::string& fname, - Graph& g, - const NamedParameters& np = parameters::default_values()) -{ - const bool verbose = parameters::choose_parameter(parameters::get_parameter(np, internal_np::verbose), false); - - const std::string ext = internal::get_file_extension(fname); - if(ext == std::string()) - { - if(verbose) - std::cerr << "Error: cannot read from file without extension" << std::endl; - return false; - } - - if(ext == "obj") - return read_OBJ(fname, g, np); - else if(ext == "off") - return read_OFF(fname, g, np); - else if(ext == "ply") - return read_PLY(fname, g, np); - else if(ext == "stl") - return read_STL(fname, g, np); - else if(ext == "ts") - return read_GOCAD(fname, g, np); -#ifdef CGAL_USE_VTK - else if(ext == "vtp") - return read_VTP(fname, g, np); -#endif - - if(verbose) - { - std::cerr << "Error: unknown input file extension: " << ext << "\n" - << "Please refer to the documentation for the list of supported file formats" << std::endl; - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Write - -/*! - * \ingroup PkgBGLIOFct - * - * \brief writes a polygon mesh in a file. - * - * Supported file formats are the following: - * - \ref IOStreamOFF (`.off`) - * - \ref IOStreamOBJ (`.obj`) - * - \ref IOStreamSTL (`.stl`) - * - \ref IOStreamPLY (`.ply`) - * - \ref IOStreamGocad (`.ts`) - * - \ref IOStreamVTK (`.vtp`) - * - * The format is detected from the filename extension (letter case is not important). - * - * \tparam Graph a model of `FaceListGraph` and `HalfedgeListGraph` - * \tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" - * - * \param fname the name of the file - * \param g the mesh to be output - * \param np optional \ref bgl_namedparameters "Named Parameters" described below - * - * \cgalNamedParamsBegin - * \cgalParamNBegin{vertex_point_map} - * \cgalParamDescription{a property map associating points to the vertices of `g`} - * \cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits::%vertex_descriptor` - * as key type and `%Point_3` as value type} - * \cgalParamDefault{`boost::get(CGAL::vertex_point, g)`} - * \cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t` - * must be available in `Graph`.} - * \cgalParamNEnd - * - * \cgalParamNBegin{stream_precision} - * \cgalParamDescription{a parameter used to set the precision (i.e. how many digits are generated) of the output stream} - * \cgalParamType{int} - * \cgalParamDefault{`6`} - * \cgalParamExtra{This parameter is only meaningful while using \ascii encoding.} - * \cgalParamNEnd - * - * \cgalParamNBegin{use_binary_mode} - * \cgalParamDescription{indicates whether data should be written in binary (`true`) or in \ascii (`false`)} - * \cgalParamType{Boolean} - * \cgalParamDefault{`true`} - * \cgalParamExtra{This parameter is only meaningful for formats that support binary encoding.} - * \cgalParamNEnd - * - * \cgalParamNBegin{verbose} - * \cgalParamDescription{whether extra information is printed when an incident occurs during reading} - * \cgalParamType{Boolean} - * \cgalParamDefault{`false`} - * \cgalParamNEnd - * \cgalNamedParamsEnd - * - * Other named parameters may be used according to the file extension, see \ref PkgBGLIOFct for an exhaustive list. - * - * \return `true` if writing was successful, `false` otherwise. - */ -template -bool write_polygon_mesh(const std::string& fname, - Graph& g, - const NamedParameters& np = parameters::default_values()) -{ - const bool verbose = parameters::choose_parameter(parameters::get_parameter(np, internal_np::verbose), false); - - const std::string ext = internal::get_file_extension(fname); - if(ext == std::string()) - { - if(verbose) - std::cerr << "Error: trying to output to file without extension" << std::endl; - return false; - } - - if(ext == "obj") - return write_OBJ(fname, g, np); - else if(ext == "off") - return write_OFF(fname, g, np); - else if(ext == "ply") - return write_PLY(fname, g, np); - else if(ext == "stl") - return write_STL(fname, g, np); - else if(ext == "ts") - return write_GOCAD(fname, g, np); -#ifdef CGAL_USE_VTK - else if(ext == "vtp") - return write_VTP(fname, g, np); -#endif - - if(verbose) - { - std::cerr << "Error: unknown output file extension: " << ext << "\n" - << "Please refer to the documentation for the list of supported file formats" << std::endl; - } - - return false; -} - -}} // namespace CGAL::IO +#include #endif // CGAL_BOOST_GRAPH_POLYGON_MESH_IO_H From 74c47e6222a160bd0e2e64b1bf08ef65ea9aeb43 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 13 Dec 2023 09:21:16 +0000 Subject: [PATCH 301/329] Add CGAL::IO:: for linking --- .../doc/Stream_support/IOstream.txt | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/Stream_support/doc/Stream_support/IOstream.txt b/Stream_support/doc/Stream_support/IOstream.txt index 7d11ad3d16ad..cc299f2540ab 100644 --- a/Stream_support/doc/Stream_support/IOstream.txt +++ b/Stream_support/doc/Stream_support/IOstream.txt @@ -345,7 +345,7 @@ The file formats supported for `CGAL::Point_set_3` are detailed in the table bel Input - `read_point_set()` + `CGAL::IO::read_point_set()` \link PkgPointSet3IOOFF `read_OFF()` \endlink \link PkgPointSet3IOXYZ `read_XYZ()` \endlink \link PkgPointSet3IOPLY `read_PLY()` \endlink @@ -353,7 +353,7 @@ The file formats supported for `CGAL::Point_set_3` are detailed in the table bel Output - `write_point_set()` + `CGAL::IO::write_point_set()` \link PkgPointSet3IOOFF `write_OFF()` \endlink \link PkgPointSet3IOXYZ `write_XYZ()` \endlink \link PkgPointSet3IOPLY `write_PLY()` \endlink @@ -381,7 +381,7 @@ their indices per face (i.e a vector of 3 integers represent a triangle face). Input - `read_polygon_soup()` + `CGAL::IO::read_polygon_soup()` \link PkgStreamSupportIoFuncsOFF `read_OFF()` \endlink \link PkgStreamSupportIoFuncsOBJ `read_OBJ()` \endlink \link PkgStreamSupportIoFuncsSTL `read_STL()` \endlink @@ -393,7 +393,7 @@ their indices per face (i.e a vector of 3 integers represent a triangle face). Output - `write_polygon_soup()` + `CGAL::IO::write_polygon_soup()` \link PkgStreamSupportIoFuncsOFF `write_OFF()` \endlink \link PkgStreamSupportIoFuncsOBJ `write_OBJ()` \endlink \link PkgStreamSupportIoFuncsSTL `write_STL()` \endlink @@ -424,7 +424,7 @@ The table above only lists the functions that work with any polygon mesh. Input - `read_polygon_mesh()` + `CGAL::IO::read_polygon_mesh()` `read_OFF()` `read_STL()` `read_VTP()` @@ -434,7 +434,7 @@ The table above only lists the functions that work with any polygon mesh. Output - `write_polygon_mesh()` + ``CGAL::IO::write_polygon_mesh()` `write_OFF()` `write_STL()` `write_VTP()` @@ -478,17 +478,17 @@ from the standard \cgal I/O functions. Input -read_WKT() -read_multi_point_WKT() -read_multi_linestring_WKT() -read_multi_polygon_WKT() +`CGAL::IO::read_WKT()` +`CGAL::IO::read_multi_point_WKT()` +`CGAL::IO::read_multi_linestring_WKT()` +`CGAL::IO::read_multi_polygon_WKT()` Output
-
-write_multi_point_WKT() -write_multi_linestring_WKT() -write_multi_polygon_WKT() +`CGAL::IO::write_multi_point_WKT()` +`CGAL::IO::write_multi_linestring_WKT()` +`CGAL::IO::write_multi_polygon_WKT()` From fd8e6372c7b1e061b2288c39e7281adeafaec51a Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 13 Dec 2023 09:31:25 +0000 Subject: [PATCH 302/329] Add CGAL::IO:: for linking --- .../doc/Stream_support/IOstream.txt | 84 +++++++++---------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/Stream_support/doc/Stream_support/IOstream.txt b/Stream_support/doc/Stream_support/IOstream.txt index cc299f2540ab..967ef41097f5 100644 --- a/Stream_support/doc/Stream_support/IOstream.txt +++ b/Stream_support/doc/Stream_support/IOstream.txt @@ -305,18 +305,18 @@ The following table shows which file formats can be read from and written for po Input `read_points()` - \link PkgPointSetProcessing3IOOff `read_OFF()` \endlink - \link PkgPointSetProcessing3IOXyz `read_XYZ()` \endlink - \link PkgPointSetProcessing3IOPly `read_PLY()` \endlink - \link PkgPointSetProcessing3IOLas `read_LAS()` \endlink + \link PkgPointSetProcessing3IOOff `CGAL::IO::read_OFF()` \endlink + \link PkgPointSetProcessing3IOXyz `GAL::IO::read_XYZ()` \endlink + \link PkgPointSetProcessing3IOPly `GAL::IO::read_PLY()` \endlink + \link PkgPointSetProcessing3IOLas `GAL::IO::read_LAS()` \endlink Output `write_points()` - \link PkgPointSetProcessing3IOOff `write_OFF()` \endlink - \link PkgPointSetProcessing3IOXyz `write_XYZ()` \endlink - \link PkgPointSetProcessing3IOPly `write_PLY()` \endlink - \link PkgPointSetProcessing3IOLas `write_LAS()` \endlink + \link PkgPointSetProcessing3IOOff `GAL::IO::write_OFF()` \endlink + \link PkgPointSetProcessing3IOXyz `GAL::IO::write_XYZ()` \endlink + \link PkgPointSetProcessing3IOPly `GAL::IO::write_PLY()` \endlink + \link PkgPointSetProcessing3IOLas `GAL::IO::write_LAS()` \endlink @@ -346,18 +346,18 @@ The file formats supported for `CGAL::Point_set_3` are detailed in the table bel Input `CGAL::IO::read_point_set()` - \link PkgPointSet3IOOFF `read_OFF()` \endlink - \link PkgPointSet3IOXYZ `read_XYZ()` \endlink - \link PkgPointSet3IOPLY `read_PLY()` \endlink - \link PkgPointSet3IOLAS `read_LAS()` \endlink + \link PkgPointSet3IOOFF `GAL::IO::read_OFF()` \endlink + \link PkgPointSet3IOXYZ `GAL::IO::read_XYZ()` \endlink + \link PkgPointSet3IOPLY `GAL::IO::read_PLY()` \endlink + \link PkgPointSet3IOLAS `GAL::IO::read_LAS()` \endlink Output `CGAL::IO::write_point_set()` - \link PkgPointSet3IOOFF `write_OFF()` \endlink - \link PkgPointSet3IOXYZ `write_XYZ()` \endlink - \link PkgPointSet3IOPLY `write_PLY()` \endlink - \link PkgPointSet3IOLAS `write_LAS()` \endlink + \link PkgPointSet3IOOFF `GAL::IO::write_OFF()` \endlink + \link PkgPointSet3IOXYZ `GAL::IO::write_XYZ()` \endlink + \link PkgPointSet3IOPLY `GAL::IO::write_PLY()` \endlink + \link PkgPointSet3IOLAS `GAL::IO::write_LAS()` \endlink @@ -382,26 +382,26 @@ their indices per face (i.e a vector of 3 integers represent a triangle face). Input `CGAL::IO::read_polygon_soup()` - \link PkgStreamSupportIoFuncsOFF `read_OFF()` \endlink - \link PkgStreamSupportIoFuncsOBJ `read_OBJ()` \endlink - \link PkgStreamSupportIoFuncsSTL `read_STL()` \endlink - \link PkgStreamSupportIoFuncsPLY `read_PLY()` \endlink - \link PkgStreamSupportIoFuncsVTK `read_VTP()` \endlink - \link PkgStreamSupportIoFuncsGOCAD `read_GOCAD()` \endlink - \link PkgStreamSupportIoFuncsWKT `read_WKT()` \endlink - \link PkgStreamSupportIoFuncs3MF `read_3MF()` \endlink + \link PkgStreamSupportIoFuncsOFF `GAL::IO::read_OFF()` \endlink + \link PkgStreamSupportIoFuncsOBJ `GAL::IO::read_OBJ()` \endlink + \link PkgStreamSupportIoFuncsSTL `GAL::IO::read_STL()` \endlink + \link PkgStreamSupportIoFuncsPLY `GAL::IO::read_PLY()` \endlink + \link PkgStreamSupportIoFuncsVTK `GAL::IO::read_VTP()` \endlink + \link PkgStreamSupportIoFuncsGOCAD `GAL::IO::read_GOCAD()` \endlink + \link PkgStreamSupportIoFuncsWKT `GAL::IO::read_WKT()` \endlink + \link PkgStreamSupportIoFuncs3MF `GAL::IO::read_3MF()` \endlink Output `CGAL::IO::write_polygon_soup()` - \link PkgStreamSupportIoFuncsOFF `write_OFF()` \endlink - \link PkgStreamSupportIoFuncsOBJ `write_OBJ()` \endlink - \link PkgStreamSupportIoFuncsSTL `write_STL()` \endlink - \link PkgStreamSupportIoFuncsPLY `write_PLY()` \endlink - \link PkgStreamSupportIoFuncsVTK `write_VTP()` \endlink - \link PkgStreamSupportIoFuncsGOCAD `write_GOCAD()` \endlink - \link PkgStreamSupportIoFuncsWKT `write_WKT()` \endlink - \link PkgStreamSupportIoFuncs3MF `write_3MF()` \endlink + \link PkgStreamSupportIoFuncsOFF `GAL::IO::write_OFF()` \endlink + \link PkgStreamSupportIoFuncsOBJ `GAL::IO::write_OBJ()` \endlink + \link PkgStreamSupportIoFuncsSTL `GAL::IO::write_STL()` \endlink + \link PkgStreamSupportIoFuncsPLY `GAL::IO::write_PLY()` \endlink + \link PkgStreamSupportIoFuncsVTK `GAL::IO::write_VTP()` \endlink + \link PkgStreamSupportIoFuncsGOCAD `GAL::IO::write_GOCAD()` \endlink + \link PkgStreamSupportIoFuncsWKT `GAL::IO::write_WKT()` \endlink + \link PkgStreamSupportIoFuncs3MF `GAL::IO::write_3MF()` \endlink @@ -425,21 +425,21 @@ The table above only lists the functions that work with any polygon mesh. Input `CGAL::IO::read_polygon_mesh()` - `read_OFF()` - `read_STL()` - `read_VTP()` - `read_OBJ()` - `read_GOCAD()` + `CGAL::IO::read_OFF()` + `CGAL::IO::read_STL()` + `CGAL::IO::read_VTP()` + `CGAL::IO::read_OBJ()` + `CGAL::IO::read_GOCAD()`
-
Output ``CGAL::IO::write_polygon_mesh()` - `write_OFF()` - `write_STL()` - `write_VTP()` - `write_OBJ()` - `write_GOCAD()` + `CGAL::IO::write_OFF()` + `CGAL::IO::write_STL()` + `CGAL::IO::write_VTP()` + `CGAL::IO::write_OBJ()` + `CGAL::IO::write_GOCAD()` `write_WRL()` From 2713fe3c41c5afbbcf2315622f46ae902af8c405 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 13 Dec 2023 10:00:44 +0000 Subject: [PATCH 303/329] give \link a try for linking --- Stream_support/doc/Stream_support/IOstream.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Stream_support/doc/Stream_support/IOstream.txt b/Stream_support/doc/Stream_support/IOstream.txt index 967ef41097f5..b868f7facb28 100644 --- a/Stream_support/doc/Stream_support/IOstream.txt +++ b/Stream_support/doc/Stream_support/IOstream.txt @@ -440,7 +440,7 @@ The table above only lists the functions that work with any polygon mesh. `CGAL::IO::write_VTP()` `CGAL::IO::write_OBJ()` `CGAL::IO::write_GOCAD()` - `write_WRL()` + \link CGAL::IO::write_WRL() `write_WRL()`\endlink From b1195233fae1532c0d0f222b7de7c8fb0a4a26ce Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 13 Dec 2023 10:45:08 +0000 Subject: [PATCH 304/329] Add CGAL::IO:: for linking --- Stream_support/doc/Stream_support/IOstream.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Stream_support/doc/Stream_support/IOstream.txt b/Stream_support/doc/Stream_support/IOstream.txt index b868f7facb28..fb4d9fe8afae 100644 --- a/Stream_support/doc/Stream_support/IOstream.txt +++ b/Stream_support/doc/Stream_support/IOstream.txt @@ -440,7 +440,7 @@ The table above only lists the functions that work with any polygon mesh. `CGAL::IO::write_VTP()` `CGAL::IO::write_OBJ()` `CGAL::IO::write_GOCAD()` - \link CGAL::IO::write_WRL() `write_WRL()`\endlink + `CGAL::IO::write_WRL()` From 93ba75b8a1a19d12dd94413e1f5b801cdc00e8b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 14 Dec 2023 08:47:54 +0100 Subject: [PATCH 305/329] add missing not --- .../include/CGAL/Polygon_mesh_processing/self_intersections.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h index 928129705aed..959bc75c5c8e 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h @@ -420,7 +420,7 @@ self_intersections_impl(const FaceRange& face_range, * @tparam TriangleMesh a model of `FaceListGraph` * @tparam FacePairOutputIterator a model of `OutputIterator` holding objects of type * `std::pair::%face_descriptor, boost::graph_traits::%face_descriptor>`. - * It does need to be thread-safe. + * It does not need to be thread-safe. * @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" * * @param face_range the range of faces to check for self-intersection. @@ -487,7 +487,7 @@ self_intersections(const FaceRange& face_range, * @tparam TriangleMesh a model of `FaceListGraph` * @tparam FacePairOutputIterator a model of `OutputIterator` holding objects of type * `std::pair::%face_descriptor, boost::graph_traits::%face_descriptor>`. - * It does need to be thread-safe. + * It does not need to be thread-safe. * @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" * * @param tmesh the triangulated surface mesh to be checked From 7935bcf42b4c8a9283d08d6637d6b75e5c999bd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 14 Dec 2023 10:10:17 +0100 Subject: [PATCH 306/329] fix mismatching cond/endcode remove useless previous patches --- Point_set_3/include/CGAL/Point_set_3.h | 2 -- Point_set_3/include/CGAL/Point_set_3/IO.h | 4 ++-- Point_set_3/include/CGAL/Point_set_3/IO/LAS.h | 2 -- Point_set_3/include/CGAL/Point_set_3/IO/OFF.h | 2 -- Point_set_3/include/CGAL/Point_set_3/IO/PLY.h | 2 -- Point_set_3/include/CGAL/Point_set_3/IO/XYZ.h | 2 -- 6 files changed, 2 insertions(+), 12 deletions(-) diff --git a/Point_set_3/include/CGAL/Point_set_3.h b/Point_set_3/include/CGAL/Point_set_3.h index c9e6ba4f0ba1..df85f0f36278 100644 --- a/Point_set_3/include/CGAL/Point_set_3.h +++ b/Point_set_3/include/CGAL/Point_set_3.h @@ -133,7 +133,6 @@ class Point_set_3 Index (const std::size_t& value) : value (static_cast(value)) { } Index () : value (static_cast(-1)) { } Index operator= (const Index& index) { value = index.value; return *this; } - /// \cond SKIP_IN_MANUAL operator std::size_t() const { return static_cast(value); } bool operator== (const Index& index) const { return value == index.value; } bool operator!= (const Index& index) const { return value != index.value; } @@ -694,7 +693,6 @@ class Point_set_3 \sa `number_of_removed_points()` */ std::size_t garbage_size () const { return number_of_removed_points(); } - /// \endcond /*! \brief returns `true` if there are elements marked as removed, `false` otherwise. diff --git a/Point_set_3/include/CGAL/Point_set_3/IO.h b/Point_set_3/include/CGAL/Point_set_3/IO.h index 8630788e7875..789d44921d51 100644 --- a/Point_set_3/include/CGAL/Point_set_3/IO.h +++ b/Point_set_3/include/CGAL/Point_set_3/IO.h @@ -26,10 +26,8 @@ namespace CGAL { -#ifndef DOXYGEN_RUNNING template class Point_set_3; -#endif //////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -163,6 +161,8 @@ bool read_point_set(const std::string& fname, \param ps the point set \return `os` + + \relates Point_set_3 */ template std::ostream& operator<<(std::ostream& os, diff --git a/Point_set_3/include/CGAL/Point_set_3/IO/LAS.h b/Point_set_3/include/CGAL/Point_set_3/IO/LAS.h index 08afc1a220a3..7ecf30255ba0 100644 --- a/Point_set_3/include/CGAL/Point_set_3/IO/LAS.h +++ b/Point_set_3/include/CGAL/Point_set_3/IO/LAS.h @@ -25,10 +25,8 @@ namespace CGAL { -#ifndef DOXYGEN_RUNNING template class Point_set_3; -#endif //////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Point_set_3/include/CGAL/Point_set_3/IO/OFF.h b/Point_set_3/include/CGAL/Point_set_3/IO/OFF.h index cff22686ae79..5bd359416153 100644 --- a/Point_set_3/include/CGAL/Point_set_3/IO/OFF.h +++ b/Point_set_3/include/CGAL/Point_set_3/IO/OFF.h @@ -24,10 +24,8 @@ namespace CGAL { -#ifndef DOXYGEN_RUNNING template class Point_set_3; -#endif //////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Point_set_3/include/CGAL/Point_set_3/IO/PLY.h b/Point_set_3/include/CGAL/Point_set_3/IO/PLY.h index b1f3e763b079..76daf4494abe 100644 --- a/Point_set_3/include/CGAL/Point_set_3/IO/PLY.h +++ b/Point_set_3/include/CGAL/Point_set_3/IO/PLY.h @@ -24,10 +24,8 @@ namespace CGAL { -#ifndef DOXYGEN_RUNNING template class Point_set_3; -#endif namespace IO { namespace internal { diff --git a/Point_set_3/include/CGAL/Point_set_3/IO/XYZ.h b/Point_set_3/include/CGAL/Point_set_3/IO/XYZ.h index ce968f49af64..72c00bd528ec 100644 --- a/Point_set_3/include/CGAL/Point_set_3/IO/XYZ.h +++ b/Point_set_3/include/CGAL/Point_set_3/IO/XYZ.h @@ -23,10 +23,8 @@ namespace CGAL { -#ifndef DOXYGEN_RUNNING template class Point_set_3; -#endif //////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////// From 54677b388c8fa8ad5cbae15c0948ac82c302ef81 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 14 Dec 2023 15:35:06 +0100 Subject: [PATCH 307/329] set default minimal_size_ to -1 and add helper function to check if it is set --- .../CGAL/Mesh_3/Protect_edges_sizing_field.h | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 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 4cd4d1c3af41..a04664e8de6c 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 @@ -139,7 +139,7 @@ class Protect_edges_sizing_field Protect_edges_sizing_field(C3T3& c3t3, const MeshDomain& domain, SizingFunction size=SizingFunction(), - const FT minimal_size = FT(), + const FT minimal_size = FT(-1), std::size_t maximal_number_of_vertices = 0, Mesh_error_code* error_code = 0 #ifndef CGAL_NO_ATOMIC @@ -455,12 +455,17 @@ class Protect_edges_sizing_field return s; } + bool use_minimal_size() const + { + return minimal_size_ != FT(-1); + } + private: C3T3& c3t3_; const MeshDomain& domain_; SizingFunction size_; - FT minimal_size_; - Weight minimal_weight_; + const FT minimal_size_; + const Weight minimal_weight_; std::set treated_edges_; Vertex_set unchecked_vertices_; int refine_balls_iteration_nb; @@ -540,7 +545,7 @@ operator()(const bool refine) std::cerr << "refine_balls() done. Nb of points in triangulation: " << c3t3_.triangulation().number_of_vertices() << std::endl; #endif - CGAL_assertion(minimal_size_ > 0 || c3t3_.is_valid()); + CGAL_assertion(use_minimal_size() || c3t3_.is_valid()); } // debug_dump_c3t3("dump-mesh-after-protect_edges.binary.cgal", c3t3_); @@ -760,10 +765,10 @@ smart_insert_point(const Bare_point& p, Weight w, int dim, const Index& index, while ( ! is_special(nearest_vh) && cwsr(c3t3_.triangulation().point(nearest_vh), - sq_d) == CGAL::SMALLER ) { - CGAL_assertion( minimal_size_ > 0 || sq_d > 0 ); + CGAL_assertion( use_minimal_size() || sq_d > 0); bool special_ball = false; - if(minimal_weight_ != Weight() && sq_d < minimal_weight_) + if(use_minimal_size() && sq_d < minimal_weight_) { sq_d = minimal_weight_; w = minimal_weight_; @@ -817,7 +822,7 @@ smart_insert_point(const Bare_point& p, Weight w, int dim, const Index& index, const FT sq_d = tr.min_squared_distance(p, cp(c3t3_.triangulation().point(v))); - if(minimal_weight_ != Weight() && sq_d < minimal_weight_) { + if(use_minimal_size() && sq_d < minimal_weight_) { insert_a_special_ball = true; #if CGAL_MESH_3_PROTECTION_DEBUG & 1 nearest_point = c3t3_.triangulation().point(v); @@ -876,7 +881,7 @@ smart_insert_point(const Bare_point& p, Weight w, int dim, const Index& index, if ( cwsr(it_wp, - sq_d) == CGAL::SMALLER ) { bool special_ball = false; - if(minimal_weight_ != Weight() && sq_d < minimal_weight_) + if(use_minimal_size() && sq_d < minimal_weight_) { sq_d = minimal_weight_; w = minimal_weight_; @@ -1436,7 +1441,7 @@ refine_balls() const Vertex_handle v = it->first; const FT new_size = it->second; // Set size of the ball to new value - if(minimal_size_ != FT() && new_size < minimal_size_) { + if(use_minimal_size() && new_size < minimal_size_) { if(!is_special(v)) { change_ball_size(v, minimal_weight_, true); // special ball @@ -1456,7 +1461,7 @@ refine_balls() dump_c3t3_edges(c3t3_, "dump-before-check_and_repopulate_edges"); #endif // Check edges - if(!forced_stop() && minimal_size_ == FT()) { + if(!forced_stop() && !use_minimal_size()) { check_and_repopulate_edges(); } } From 85b8da120dce6246320bc7565983a60cd74083e5 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 14 Dec 2023 15:36:57 +0100 Subject: [PATCH 308/329] constify more --- Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h | 6 +++--- 1 file changed, 3 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 a04664e8de6c..61e13ee4bda1 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 @@ -140,7 +140,7 @@ class Protect_edges_sizing_field const MeshDomain& domain, SizingFunction size=SizingFunction(), const FT minimal_size = FT(-1), - std::size_t maximal_number_of_vertices = 0, + const std::size_t maximal_number_of_vertices = 0, Mesh_error_code* error_code = 0 #ifndef CGAL_NO_ATOMIC , std::atomic* stop_ptr = 0 @@ -470,7 +470,7 @@ class Protect_edges_sizing_field Vertex_set unchecked_vertices_; int refine_balls_iteration_nb; bool nonlinear_growth_of_balls; - std::size_t maximal_number_of_vertices_; + const std::size_t maximal_number_of_vertices_; Mesh_error_code* const error_code_; #ifndef CGAL_NO_ATOMIC /// Pointer to the atomic Boolean that can stop the process @@ -483,7 +483,7 @@ template Protect_edges_sizing_field:: Protect_edges_sizing_field(C3T3& c3t3, const MD& domain, Sf size, const FT minimal_size, - std::size_t maximal_number_of_vertices, + const std::size_t maximal_number_of_vertices, Mesh_error_code* error_code #ifndef CGAL_NO_ATOMIC , std::atomic* stop_ptr From 7fa2db8dfc9552d18744f45ebe148a704592ff13 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Thu, 14 Dec 2023 19:01:57 +0100 Subject: [PATCH 309/329] add helper function minimal_weight() --- .../CGAL/Mesh_3/Protect_edges_sizing_field.h | 31 ++++++++++++------- 1 file changed, 19 insertions(+), 12 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 61e13ee4bda1..885c6f53160a 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 @@ -459,6 +459,13 @@ class Protect_edges_sizing_field { return minimal_size_ != FT(-1); } + Weight minimal_weight() const + { + if (use_minimal_size()) + return minimal_weight_; + else + return Weight(0); + } private: C3T3& c3t3_; @@ -822,16 +829,16 @@ smart_insert_point(const Bare_point& p, Weight w, int dim, const Index& index, const FT sq_d = tr.min_squared_distance(p, cp(c3t3_.triangulation().point(v))); - if(use_minimal_size() && sq_d < minimal_weight_) { + if(use_minimal_size() && sq_d < minimal_weight()) { insert_a_special_ball = true; #if CGAL_MESH_3_PROTECTION_DEBUG & 1 nearest_point = c3t3_.triangulation().point(v); #endif - min_sq_d = minimal_weight_; + min_sq_d = minimal_weight(); if(! is_special(v)) { *out++ = v; - ch = change_ball_size(v, minimal_weight_, true)->cell(); // special ball + ch = change_ball_size(v, minimal_weight(), true)->cell(); // special ball } } else @@ -881,10 +888,10 @@ smart_insert_point(const Bare_point& p, Weight w, int dim, const Index& index, if ( cwsr(it_wp, - sq_d) == CGAL::SMALLER ) { bool special_ball = false; - if(use_minimal_size() && sq_d < minimal_weight_) + if(use_minimal_size() && sq_d < minimal_weight()) { - sq_d = minimal_weight_; - w = minimal_weight_; + sq_d = minimal_weight(); + w = minimal_weight(); special_ball = true; insert_a_special_ball = true; } @@ -938,13 +945,13 @@ smart_insert_point(const Bare_point& p, Weight w, int dim, const Index& index, add_handle_to_unchecked = true; } - if( w < minimal_weight_) { + if( w < minimal_weight()) { #if CGAL_MESH_3_PROTECTION_DEBUG & 1 std::cerr << "smart_insert_point: weight " << w - << " was smaller than minimal weight (" << minimal_weight_ << ")\n"; + << " was smaller than minimal weight (" << minimal_weight() << ")\n"; #endif - w = minimal_weight_; + w = minimal_weight(); insert_a_special_ball = true; } Vertex_handle v = insert_point(p,w,dim,index, insert_a_special_ball); @@ -1179,7 +1186,7 @@ insert_balls(const Vertex_handle& vp, const FT d_signF = static_cast(d_sign); int n = static_cast(std::floor(FT(2)*(d-sq) / (sp+sq))+.5); - // if( minimal_weight_ != 0 && n == 0 ) return; + // if( minimal_weight() != 0 && n == 0 ) return; if(nonlinear_growth_of_balls && refine_balls_iteration_nb < 3) { @@ -1188,7 +1195,7 @@ insert_balls(const Vertex_handle& vp, // balls at corner. When the curve segment is long enough, pick a point // at the middle and choose a new size. if(n >= internal::max_nb_vertices_to_reevaluate_size && - d >= (internal::max_nb_vertices_to_reevaluate_size * minimal_weight_)) { + d >= (internal::max_nb_vertices_to_reevaluate_size * minimal_weight())) { #if CGAL_MESH_3_PROTECTION_DEBUG & 1 const Weighted_point& vq_wp = c3t3_.triangulation().point(vq); std::cerr << "Number of to-be-inserted balls is: " @@ -1443,7 +1450,7 @@ refine_balls() // Set size of the ball to new value if(use_minimal_size() && new_size < minimal_size_) { if(!is_special(v)) { - change_ball_size(v, minimal_weight_, true); // special ball + change_ball_size(v, minimal_weight(), true); // special ball // Loop will have to be run again restart = true; From 5b66d54cb827fb983c58c8b57eb38c8eb457df57 Mon Sep 17 00:00:00 2001 From: Efi Fogel Date: Fri, 15 Dec 2023 13:50:10 +0200 Subject: [PATCH 310/329] Used new conic construction interface --- .../test/Surface_sweep_2/test_sweep.cpp | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp b/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp index d44a2bbdd344..dc7851f621dc 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp +++ b/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp @@ -222,9 +222,10 @@ bool read_xcurves(std::ifstream& inp, X_monotone_curves& xcurves, #elif CGAL_ARR_TEST_TRAITS == CGAL_CONIC_TRAITS -void read_curve(std::ifstream& is, Curve_2& cv) { +void read_curve(std::ifstream& is, Curve_2& cv, const Traits& traits) { // Read a line from the input file. char one_line[128]; + auto ctr_curve_2 = traits.construct_curve_2_object(); is >> skip_comment; is.getline(one_line, 128); @@ -273,8 +274,8 @@ void read_curve(std::ifstream& is, Curve_2& cv) { if (type == 'f' || type == 'F') { // Create a full ellipse (or circle). - if (is_circle) cv = Curve_2 (circle); - else cv = Curve_2(r, s, t, u, v, w); + if (is_circle) cv = ctr_curve_2(circle); + else cv = ctr_curve_2(r, s, t, u, v, w); } else { // Read the endpointd of the arc. @@ -286,8 +287,8 @@ void read_curve(std::ifstream& is, Curve_2& cv) { Point_2 target = Point_2(Algebraic(x2), Algebraic(y2)); // Create the arc. Note that it is always clockwise oriented. - if (is_circle) cv = Curve_2(circle, CGAL::CLOCKWISE, source, target); - else cv = Curve_2(r, s, t, u, v, w, CGAL::CLOCKWISE, source, target); + if (is_circle) cv = ctr_curve_2(circle, CGAL::CLOCKWISE, source, target); + else cv = ctr_curve_2(r, s, t, u, v, w, CGAL::CLOCKWISE, source, target); } } else if (type == 's' || type == 'S') { @@ -300,7 +301,7 @@ void read_curve(std::ifstream& is, Curve_2& cv) { Rat_point_2 source = Rat_point_2 (Rational(x1), Rational(y1)); Rat_point_2 target = Rat_point_2 (Rational(x2), Rational(y2)); - cv = Curve_2(Rat_segment_2 (source, target)); + cv = ctr_curve_2(Rat_segment_2 (source, target)); } // std::cout << cv << std::endl; @@ -308,7 +309,7 @@ void read_curve(std::ifstream& is, Curve_2& cv) { /*! Read curves. */ -bool read_curves(std::ifstream& inp, Curves& curves, const Traits&) { +bool read_curves(std::ifstream& inp, Curves& curves, const Traits& traits) { // auto ctr_cv = traits.construct_curve_2_object(); int count; inp >> skip_comment >> count; @@ -316,7 +317,7 @@ bool read_curves(std::ifstream& inp, Curves& curves, const Traits&) { char dummy[256]; inp.getline(dummy, sizeof(dummy)); for (int i = 0; i < count; ++i) { - read_curve(inp, cv); + read_curve(inp, cv, traits); curves.push_back(cv); } return true; @@ -401,11 +402,11 @@ bool test_conic(std::ifstream& inp, Curves& curves, const X_monotone_curves& curves_no_overlap_out, const Points& points_with_ends_out, const Points& points_no_ends_out, - const Traits&) { - - CGAL::Bbox_2 bbox = curves.front().bbox(); + const Traits& traits) { + auto ctr_bbox_2 = traits.construct_bbox_2_object(); + CGAL::Bbox_2 bbox = ctr_bbox_2(curves.front()); for (auto it = std::next(curves.begin()); it != curves.end(); ++it) - bbox = bbox + it->bbox(); + bbox = bbox + ctr_bbox_2(*it); // generate the string for the output std::stringstream out1; From 3ef2ce91639f99b8ac277311af568fc542e03b00 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Fri, 15 Dec 2023 14:44:33 +0100 Subject: [PATCH 311/329] check_and_repopulate_edges() reactivated with minimal size disabling it may give too bad results change the arc_length computation when minimal size is used, instead, by approximating it by the segment length --- 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 885c6f53160a..c74e2ca63e00 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 @@ -1468,7 +1468,7 @@ refine_balls() dump_c3t3_edges(c3t3_, "dump-before-check_and_repopulate_edges"); #endif // Check edges - if(!forced_stop() && !use_minimal_size()) { + if(!forced_stop()) { check_and_repopulate_edges(); } } @@ -1771,7 +1771,9 @@ is_sampling_dense_enough(const Vertex_handle& v1, const Vertex_handle& v2, const Weighted_point& v1_wp = c3t3_.triangulation().point(v1); const Weighted_point& v2_wp = c3t3_.triangulation().point(v2); - FT arc_length = domain_.curve_segment_length(cp(v1_wp), + FT arc_length = use_minimal_size() + ? compute_distance(v1, v2) //curve polyline may not be consistent + : domain_.curve_segment_length(cp(v1_wp), cp(v2_wp), curve_index, orientation); From a66e78a6729a83d74c6d39d9da40ab917f26c211 Mon Sep 17 00:00:00 2001 From: Jane Tournois Date: Fri, 15 Dec 2023 15:52:02 +0100 Subject: [PATCH 312/329] when curves topology is valid, use curve_segment_length --- .../CGAL/Mesh_3/Protect_edges_sizing_field.h | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 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 c74e2ca63e00..a2e13b811237 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 @@ -1763,20 +1763,33 @@ is_sampling_dense_enough(const Vertex_handle& v1, const Vertex_handle& v2, FT size_v1 = get_radius(v1); FT size_v2 = get_radius(v2); - CGAL_assertion(get_dimension(v1) != 1 || - curve_index == domain_.curve_index(v1->index())); - CGAL_assertion(get_dimension(v2) != 1 || - curve_index == domain_.curve_index(v2->index())); + bool v1_valid_curve_index = true; + bool v2_valid_curve_index = true; + + if(use_minimal_size()) + { + v1_valid_curve_index = (get_dimension(v1) != 1 + || curve_index == domain_.curve_index(v1->index())); + v2_valid_curve_index = (get_dimension(v2) != 1 + || curve_index == domain_.curve_index(v2->index())); + } + else + { + CGAL_assertion(get_dimension(v1) != 1 || + curve_index == domain_.curve_index(v1->index())); + CGAL_assertion(get_dimension(v2) != 1 || + curve_index == domain_.curve_index(v2->index())); + } const Weighted_point& v1_wp = c3t3_.triangulation().point(v1); const Weighted_point& v2_wp = c3t3_.triangulation().point(v2); - FT arc_length = use_minimal_size() - ? compute_distance(v1, v2) //curve polyline may not be consistent - : domain_.curve_segment_length(cp(v1_wp), + FT arc_length = (v1_valid_curve_index && v2_valid_curve_index) + ? domain_.curve_segment_length(cp(v1_wp), cp(v2_wp), curve_index, - orientation); + orientation) + : compute_distance(v1, v2); //curve polyline may not be consistent // Sufficient condition so that the curve portion between v1 and v2 is // inside the union of the two balls. From 03ea4c3df538b49194b28f12dd81ebbb5be78cda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 18 Dec 2023 15:14:09 +0100 Subject: [PATCH 313/329] Revert "fix warnings" This reverts commit 8cc75d642cff010f8166d7d23c82afe7b2efe41a. --- Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp b/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp index d44a2bbdd344..cc11bbabac3f 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp +++ b/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp @@ -149,6 +149,7 @@ std::istream& skip_comment(std::istream& in) { bool read_points(std::ifstream& inp, Points& points, const Traits&) { int count; inp >> skip_comment >> count; + char ch; // std::cout << "read_points " << count << "\n"; for (int i = 0; i < count; i++) { @@ -329,7 +330,7 @@ bool read_curves(std::ifstream& inp, Curves& curves, const Traits&) { #if CGAL_ARR_TEST_TRAITS != CGAL_CONIC_TRAITS // Test subcurves w/o overlapping -bool test_curves_no_overlap(std::ifstream& inp, Curves& /* curves */, +bool test_curves_no_overlap(std::ifstream& inp, Curves& curves, const X_monotone_curves& curves_no_overlap_out, const Traits& tr) { X_monotone_curves curves_no_overlap; @@ -345,7 +346,7 @@ bool test_curves_no_overlap(std::ifstream& inp, Curves& /* curves */, } // Test subcurves w/ overlapping -bool test_curves_with_overlap(std::ifstream& inp, Curves& /* curves */, +bool test_curves_with_overlap(std::ifstream& inp, Curves& curves, const X_monotone_curves& curves_with_overlap_out, const Traits& tr) { X_monotone_curves curves_with_overlap; @@ -362,7 +363,7 @@ bool test_curves_with_overlap(std::ifstream& inp, Curves& /* curves */, } // Test intersection points (with endpoints) -bool test_points_with_ends(std::ifstream& inp, Curves& /* curves */, +bool test_points_with_ends(std::ifstream& inp, Curves& curves, const Points& points_with_ends_out, const Traits& tr) { Points points_with_ends; @@ -378,7 +379,7 @@ bool test_points_with_ends(std::ifstream& inp, Curves& /* curves */, } // Test intersection points w/o end points -bool test_points_no_ends(std::ifstream& inp, Curves& /* curves */, +bool test_points_no_ends(std::ifstream& inp, Curves& curves, const Points& points_no_ends_out, const Traits& tr) { Points points_no_ends; @@ -402,6 +403,7 @@ bool test_conic(std::ifstream& inp, Curves& curves, const Points& points_with_ends_out, const Points& points_no_ends_out, const Traits&) { + char dummy[256]; CGAL::Bbox_2 bbox = curves.front().bbox(); for (auto it = std::next(curves.begin()); it != curves.end(); ++it) From aee0c1557e156a69168aa2883d3992c991987bc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 18 Dec 2023 15:14:26 +0100 Subject: [PATCH 314/329] Revert "Ported test_sweep_conic to test_sweep and fixed the conic test cases" This reverts commit 2e99b211b0e22579f76093eec62cfbb1697e17d9. --- .../test/Surface_sweep_2/CMakeLists.txt | 2 +- .../Surface_sweep_2/data/conics/con01.txt | 1 + .../Surface_sweep_2/data/conics/con02.txt | 2 + .../Surface_sweep_2/data/conics/con03.txt | 5 + .../Surface_sweep_2/data/conics/con04.txt | 4 +- .../Surface_sweep_2/data/conics/con05.txt | 4 + .../Surface_sweep_2/data/conics/con06.txt | 1 + .../Surface_sweep_2/data/conics/con07.txt | 1 + .../Surface_sweep_2/data/conics/con08.txt | 2 + .../Surface_sweep_2/data/conics/con09.txt | 3 +- .../Surface_sweep_2/data/conics/con10.txt | 3 +- .../polylines/{test01.txt => big_overlap.txt} | 0 .../Surface_sweep_2/data/polylines/test02.txt | 51 --- .../test/Surface_sweep_2/test_sweep.cpp | 430 +++++------------- .../test/Surface_sweep_2/test_sweep_conic.cpp | 279 ++++++++++++ 15 files changed, 414 insertions(+), 374 deletions(-) rename Surface_sweep_2/test/Surface_sweep_2/data/polylines/{test01.txt => big_overlap.txt} (100%) delete mode 100644 Surface_sweep_2/test/Surface_sweep_2/data/polylines/test02.txt create mode 100644 Surface_sweep_2/test/Surface_sweep_2/test_sweep_conic.cpp diff --git a/Surface_sweep_2/test/Surface_sweep_2/CMakeLists.txt b/Surface_sweep_2/test/Surface_sweep_2/CMakeLists.txt index 9e96fa6dc1c7..ac96a58ca421 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/CMakeLists.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/CMakeLists.txt @@ -49,7 +49,7 @@ endfunction() compile_and_run_sweep(test_sweep test_sweep.cpp ${NAIVE} ${CGAL_SEGMENT_TRAITS} "data/segments_tight") -compile_and_run_sweep(test_sweep_conic test_sweep.cpp ${NAIVE} +compile_and_run_sweep(test_sweep_conic test_sweep_conic.cpp ${NAIVE} ${CGAL_CONIC_TRAITS} "data/conics") compile_and_run_sweep(test_sweep_polyline test_sweep.cpp ${NAIVE} ${CGAL_POLYLINE_TRAITS} "data/polylines") diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con01.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con01.txt index 1ff457efdb12..a3464614b95f 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con01.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con01.txt @@ -8,3 +8,4 @@ e 3 3 7 5 4 5 10 5 {1*x^2 + 1*y^2 + 0*xy + -14*x + -10*y + 65} : (4.66667,6.88562) --cw--> (10,5) 5 1 + diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con02.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con02.txt index c404b51caa16..f3ca4fd2817a 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con02.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con02.txt @@ -10,3 +10,5 @@ e 3 3 4 9 7 9 1 9 {1*x^2 + 1*y^2 + 0*xy + -8*x + -18*y + 88} : (7,9) --cw--> (5.45237,6.375) 6 2 + + diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con03.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con03.txt index 599a66f9b14e..6ed5fcbab23b 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con03.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con03.txt @@ -12,3 +12,8 @@ f 3 3 4 9 {1*x^2 + 1*y^2 + 0*xy + -8*x + -18*y + 88} : (1,9) --cw--> (7,9) 6 2 + + + + + diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con04.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con04.txt index eb6a5c187110..d9a9875cdeb0 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con04.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con04.txt @@ -12,4 +12,6 @@ f 1 1 3 2 {1*x^2 + 1*y^2 + 0*xy + -6*x + -4*y + 12} : (4,2) --cw--> (2,2) {1*x^2 + 1*y^2 + 0*xy + -6*x + -4*y + 12} : (2,2) --cw--> (4,2) 6 -1 +0 + + diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con05.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con05.txt index e68e06cb4881..224bbc2397af 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con05.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con05.txt @@ -12,3 +12,7 @@ f 3 3 4 9 {1*x^2 + 1*y^2 + 0*xy + -8*x + -18*y + 88} : (1,9) --cw--> (7,9) 6 2 + + + + diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con06.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con06.txt index f82851db1c19..59ac8c5f663a 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con06.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con06.txt @@ -14,3 +14,4 @@ f 1 1 1 1 {1*x^2 + 1*y^2 + 0*xy + -4*x + 0*y + 3} : (2,1) --cw--> (3,0) 5 3 + diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con07.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con07.txt index e884bd401544..2b2253b55948 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con07.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con07.txt @@ -10,3 +10,4 @@ f 2 2 2 2 {1*x^2 + 1*y^2 + 0*xy + -4*x + -4*y + 4} : (0,2) --cw--> (4,2) 5 1 + diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con08.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con08.txt index 630633469109..54aae8118a02 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con08.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con08.txt @@ -26,3 +26,5 @@ f 3 1 0 0 {4*x^2 + 25*y^2 + 0*xy + -16*x + 0*y + -84} : (2.75552,1.97704) --cw--> (7,0) 10 6 + + diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con09.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con09.txt index 6afc8ee809ca..543d1cff8130 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con09.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con09.txt @@ -121,4 +121,5 @@ f 1 1 -4 0 {1*x^2 + 1*y^2 + 0*xy + -8*x + 0*y + 0} : (8,0) --cw--> (4.5,-3.96863) {1*x^2 + 1*y^2 + 0*xy + -8*x + 0*y + 0} : (4.5,3.96863) --cw--> (8,0) 59 -41 +34 + diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con10.txt b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con10.txt index d5f29cc31017..51c9e3ffb2ae 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/data/conics/con10.txt +++ b/Surface_sweep_2/test/Surface_sweep_2/data/conics/con10.txt @@ -18,4 +18,5 @@ s 7 -2 3 2 {1*x^2 + 1*y^2 + 0*xy + -14*x + 2*y + 49} : (8,-1) --cw--> (7,-2) {1*x^2 + 1*y^2 + 0*xy + -14*x + 2*y + 49} : (7,0) --cw--> (8,-1) 8 -5 +7 + diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/polylines/test01.txt b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/big_overlap.txt similarity index 100% rename from Surface_sweep_2/test/Surface_sweep_2/data/polylines/test01.txt rename to Surface_sweep_2/test/Surface_sweep_2/data/polylines/big_overlap.txt diff --git a/Surface_sweep_2/test/Surface_sweep_2/data/polylines/test02.txt b/Surface_sweep_2/test/Surface_sweep_2/data/polylines/test02.txt deleted file mode 100644 index 7af88f99c7ad..000000000000 --- a/Surface_sweep_2/test/Surface_sweep_2/data/polylines/test02.txt +++ /dev/null @@ -1,51 +0,0 @@ -# No. of input polylines followed by polylines -4 -2 0 0 7 0 -2 1 0 6 0 -2 2 0 5 0 -2 3 0 4 0 -# No. of output polylines followed by polylines -7 -2 0 0 1 0 -2 1 0 2 0 -2 2 0 3 0 -2 3 0 4 0 -2 4 0 5 0 -2 5 0 6 0 -2 6 0 7 0 -# No. of output points followed by points -8 -0 0 -1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -7 0 -# No. of intersection points followed by points -6 -1 0 -2 0 -3 0 -4 0 -5 0 -6 0 -# No. of output polylines with overlaps followed by polylines -16 -2 0 0 1 0 -2 1 0 2 0 -2 1 0 2 0 -2 2 0 3 0 -2 2 0 3 0 -2 2 0 3 0 -2 3 0 4 0 -2 3 0 4 0 -2 3 0 4 0 -2 3 0 4 0 -2 4 0 5 0 -2 4 0 5 0 -2 4 0 5 0 -2 5 0 6 0 -2 5 0 6 0 -2 6 0 7 0 diff --git a/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp b/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp index cc11bbabac3f..97265afa626b 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp +++ b/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp @@ -101,8 +101,8 @@ typedef Rat_kernel::Segment_2 Rat_segment_2; typedef Rat_kernel::Circle_2 Rat_circle_2; typedef CGAL::Cartesian Alg_kernel; typedef CGAL::Arr_conic_traits_2 - Traits; -#elif CGAL_ARR_TEST_TRAITS == CGAL_POLYCONIC_TRAITS + Traits_2; +#elif CGAL_ARR_TEST_TRAITS == CGAL_POLYCURVE_TRAITS typedef CGAL::CORE_algebraic_number_traits Nt_traits; typedef Nt_traits::Rational Rational; typedef Nt_traits::Algebraic Algebraic; @@ -125,6 +125,10 @@ typedef std::list Points; typedef std::list Curves; typedef std::list X_monotone_curves; +bool read_curves(std::ifstream& inp, Curves& curves, const Traits& traits); +bool read_xcurves(std::ifstream& inp, X_monotone_curves& xcurves, + const Traits& traits); +bool read_points(std::ifstream& inp, Points& points, const Traits& traits); bool curves_identical(X_monotone_curves& list1, X_monotone_curves& list2); bool points_identical(Points& list1, Points& list2); @@ -144,32 +148,109 @@ std::istream& skip_comment(std::istream& in) { return in; } -#if CGAL_ARR_TEST_TRAITS != CGAL_CONIC_TRAITS +int main(int argc, char* argv[]) { + if (argc != 2) { + std::cout << "Specify a file name " << std::endl; + return -1; + } -bool read_points(std::ifstream& inp, Points& points, const Traits&) { - int count; - inp >> skip_comment >> count; - char ch; + std::ifstream inp(argv[1]); + if (! inp.is_open()) { + std::cerr << "Error: Cannot open file " << argv[1] << "!" << std::endl; + return -1; + } - // std::cout << "read_points " << count << "\n"; - for (int i = 0; i < count; i++) { - NT x, y; - inp >> skip_comment >> x >> y; - Point_2 p(x, y); - // std::cout << p << "\n"; - points.push_back(p); + Traits tr; + + Curves curves; + if (! read_curves(inp, curves, tr)) return -1; + + // Test subcurves w/o overlapping + X_monotone_curves curves_no_overlap_out; + CGAL::compute_subcurves(curves.begin(), curves.end(), + std::back_inserter(curves_no_overlap_out), + false, tr); + + + X_monotone_curves curves_no_overlap; + if (! read_xcurves(inp, curves_no_overlap, tr)) return -1; + + if (! compare_lists(curves_no_overlap_out, curves_no_overlap, tr)) { + std::cerr << "Curves w/o overlapping do not match!\n"; + for (const auto& xcv : curves_no_overlap_out) std::cerr << xcv << std::endl; + return -1; } - return true; -} -#endif + // Test intersection points (with endpoints) + Points points_with_ends_out; + CGAL::compute_intersection_points(curves.begin(), curves.end(), + std::back_inserter(points_with_ends_out), + true, tr); + + Points points_with_ends; + if (! read_points(inp, points_with_ends, tr)) return -1; + + if (! compare_lists(points_with_ends_out, points_with_ends, tr)) { + std::cerr << "Endpoints do not match!\n"; + for (const auto& p : points_with_ends_out) std::cerr << p << std::endl; + return -1; + } + + // Test intersection points w/o end points + Points points_without_ends_out; + CGAL::compute_intersection_points(curves.begin(), curves.end(), + std::back_inserter(points_without_ends_out), + false, tr); + + Points points_without_ends; + if (! read_points(inp, points_without_ends, tr)) return -1; + + if (! compare_lists(points_without_ends_out, points_without_ends, tr)) { + std::cerr << "Intersection points do not match!\n"; + for (const auto& p : points_without_ends_out) std::cerr << p << std::endl; + return -1; + } + + // Test subcurves w/ overlapping + X_monotone_curves curves_with_overlap_out; + CGAL::compute_subcurves(curves.begin(), curves.end(), + std::back_inserter(curves_with_overlap_out), + true, tr); + + X_monotone_curves curves_with_overlap; + if (! read_xcurves(inp, curves_with_overlap, tr)) return -1; + + if (! compare_lists(curves_with_overlap_out, curves_with_overlap, tr)) { + std::cerr << "Curves w/ overlapping do not match!\n"; + for (const auto& xcv : curves_with_overlap_out) + std::cerr << xcv << std::endl; + return -1; + } + + // Test the do_curves_intersecting method + bool do_intersect_out = + CGAL::do_curves_intersect(curves.begin(), curves.end()); + + bool do_intersect = false; + if ((points_without_ends.size() != 0) || + (curves_no_overlap_out.size() != curves_with_overlap_out.size())) + do_intersect = true; + + if (do_intersect_out != do_intersect) { + std::cerr << "Error: do_intersect()\n"; + return -1; + } + + std::cout << "Passed\n"; + return 0; +} #if CGAL_ARR_TEST_TRAITS == CGAL_SEGMENT_TRAITS bool read_curves(std::ifstream& inp, Curves& curves, const Traits&) { int count; inp >> skip_comment >> count; - // std::cout << "read_curves " << count << "\n"; + std::cout << "read_curves " << count << "\n"; for (int i = 0; i < count; ++i) { NT x0, y0, x1, y1; @@ -178,7 +259,7 @@ bool read_curves(std::ifstream& inp, Curves& curves, const Traits&) { Point_2 p2(x1, y1); Curve_2 curve(p1, p2); curves.push_back(curve); - // std::cout << curve << "\n"; + std::cout << curve << "\n"; } return true; } @@ -221,313 +302,24 @@ bool read_xcurves(std::ifstream& inp, X_monotone_curves& xcurves, return read_curves_(inp, xcurves, traits, ctr_xcv); } -#elif CGAL_ARR_TEST_TRAITS == CGAL_CONIC_TRAITS - -void read_curve(std::ifstream& is, Curve_2& cv) { - // Read a line from the input file. - char one_line[128]; - - is >> skip_comment; - is.getline(one_line, 128); - std::string stringvalues(one_line); - std::istringstream str_line(stringvalues, std::istringstream::in); - - // Get the arc type. - // Supported types are: 'f' - Full ellipse (or circle). - // 'e' - Elliptic arc (or circular arc). - // 's' - Line segment. - char type; - bool is_circle = false; // Is this a circle. - Rat_circle_2 circle; - Rational r, s, t, u, v, w; // The conic coefficients. - - str_line >> type; - - // An ellipse (full ellipse or a partial ellipse): - if (type == 'f' || type == 'F' || type == 'e' || type == 'E') { - // Read the ellipse (using the format "a b x0 y0"): - // - // x - x0 2 y - y0 2 - // ( -------- ) + ( -------- ) = 1 - // a b - // - int a, b, x0, y0; - - str_line >> a >> b >> x0 >> y0; - - Rational a_sq = Rational(a*a); - Rational b_sq = Rational(b*b); - - if (a == b) { - is_circle = true; - circle = - Rat_circle_2(Rat_point_2(Rational(x0), Rational(y0)), Rational(a*b)); - } - else { - r = b_sq; - s = a_sq; - t = 0; - u = Rational(-2*x0*b_sq); - v = Rational(-2*y0*a_sq); - w = Rational(x0*x0*b_sq + y0*y0*a_sq - a_sq*b_sq); - } - - if (type == 'f' || type == 'F') { - // Create a full ellipse (or circle). - if (is_circle) cv = Curve_2 (circle); - else cv = Curve_2(r, s, t, u, v, w); - } - else { - // Read the endpointd of the arc. - int x1, y1, x2, y2; - - str_line >> x1 >> y1 >> x2 >> y2; - - Point_2 source = Point_2(Algebraic(x1), Algebraic(y1)); - Point_2 target = Point_2(Algebraic(x2), Algebraic(y2)); - - // Create the arc. Note that it is always clockwise oriented. - if (is_circle) cv = Curve_2(circle, CGAL::CLOCKWISE, source, target); - else cv = Curve_2(r, s, t, u, v, w, CGAL::CLOCKWISE, source, target); - } - } - else if (type == 's' || type == 'S') { - // Read a segment, given by its endpoints (x1,y1) and (x2,y2); - int x1, y1, x2, y2; - - str_line >> x1 >> y1 >> x2 >> y2; - - // Create the segment. - Rat_point_2 source = Rat_point_2 (Rational(x1), Rational(y1)); - Rat_point_2 target = Rat_point_2 (Rational(x2), Rational(y2)); - - cv = Curve_2(Rat_segment_2 (source, target)); - } - - // std::cout << cv << std::endl; -} - -/*! Read curves. - */ -bool read_curves(std::ifstream& inp, Curves& curves, const Traits&) { - // auto ctr_cv = traits.construct_curve_2_object(); - int count; - inp >> skip_comment >> count; - Curve_2 cv; - char dummy[256]; - inp.getline(dummy, sizeof(dummy)); - for (int i = 0; i < count; ++i) { - read_curve(inp, cv); - curves.push_back(cv); - } - return true; -} - #else #error No traits defined for test #endif -#if CGAL_ARR_TEST_TRAITS != CGAL_CONIC_TRAITS - -// Test subcurves w/o overlapping -bool test_curves_no_overlap(std::ifstream& inp, Curves& curves, - const X_monotone_curves& curves_no_overlap_out, - const Traits& tr) { - X_monotone_curves curves_no_overlap; - if (! read_xcurves(inp, curves_no_overlap, tr)) return false; - - if (! compare_lists(curves_no_overlap_out, curves_no_overlap, tr)) { - std::cerr << "Error: Curves w/o overlapping do not match!\n"; - for (const auto& xcv : curves_no_overlap_out) std::cerr << xcv << std::endl; - return false; - } - - return true; -} - -// Test subcurves w/ overlapping -bool test_curves_with_overlap(std::ifstream& inp, Curves& curves, - const X_monotone_curves& curves_with_overlap_out, - const Traits& tr) { - X_monotone_curves curves_with_overlap; - if (! read_xcurves(inp, curves_with_overlap, tr)) return false; - - if (! compare_lists(curves_with_overlap_out, curves_with_overlap, tr)) { - std::cerr << "Error: Curves w/ overlapping do not match!\n"; - for (const auto& xcv : curves_with_overlap_out) - std::cerr << xcv << std::endl; - return false; - } - - return true; -} - -// Test intersection points (with endpoints) -bool test_points_with_ends(std::ifstream& inp, Curves& curves, - const Points& points_with_ends_out, - const Traits& tr) { - Points points_with_ends; - if (! read_points(inp, points_with_ends, tr)) return false; - - if (! compare_lists(points_with_ends_out, points_with_ends, tr)) { - std::cerr << "Error: Endpoints do not match!\n"; - for (const auto& p : points_with_ends_out) std::cerr << p << std::endl; - return false; - } - - return true; -} - -// Test intersection points w/o end points -bool test_points_no_ends(std::ifstream& inp, Curves& curves, - const Points& points_no_ends_out, - const Traits& tr) { - Points points_no_ends; - if (! read_points(inp, points_no_ends, tr)) return -1; - - if (! compare_lists(points_no_ends_out, points_no_ends, tr)) { - std::cerr << "Error: Intersection points do not match!\n"; - for (const auto& p : points_no_ends_out) std::cerr << p << std::endl; - return false; - } - - return true; -} - -#else - -/*! Test the surface sweep with conic traits. - */ -bool test_conic(std::ifstream& inp, Curves& curves, - const X_monotone_curves& curves_no_overlap_out, - const Points& points_with_ends_out, - const Points& points_no_ends_out, - const Traits&) { - char dummy[256]; - - CGAL::Bbox_2 bbox = curves.front().bbox(); - for (auto it = std::next(curves.begin()); it != curves.end(); ++it) - bbox = bbox + it->bbox(); - - // generate the string for the output - std::stringstream out1; - for (const auto& xcv : curves_no_overlap_out) out1 << xcv << "\n"; - - // read the output from the file - std::stringstream out2; - char buf[1024]; - int count = 0; - - inp >> count; - inp.getline(buf, 1024); // to get rid of the new line - for (int i = 0; i < count; ++i) { - inp.getline(buf, 1024); - out2 << buf << "\n"; - } - - // std::cout << "Result: \n" << curves_no_overlap_out.size() << "\n"; - // for (const auto& xcv : curves_no_overlap_out) - // std::cout << xcv << "\n"; - - std::string calculated = out1.str(); - std::string infile = out2.str(); - - if (infile != calculated) { - std::cerr << "Error\n"; - std::cerr << "\ncalculated:\n"; - std::cerr << calculated << std::endl; - std::cerr << "\nin file:\n"; - std::cerr << infile << std::endl; - std::cerr << "--" << std::endl; - return false; - } - - std::size_t points_with_ends_size, points_no_ends_size; - inp >> skip_comment >> points_with_ends_size >> points_no_ends_size; - - auto points_with_ends_out_size = points_with_ends_out.size(); - if (points_with_ends_size != points_with_ends_out_size ) { - std::cerr << "Error: Number of endpoints do not match (" - << points_with_ends_out_size << ", " - << points_with_ends_size << ")\n"; - return false; - } +bool read_points(std::ifstream& inp, Points& points, const Traits&) { + int count; + inp >> skip_comment >> count; + char ch; - auto points_no_ends_out_size = points_no_ends_out.size(); - if (points_no_ends_size != points_no_ends_out_size) { - std::cerr << "Error: Number of intersection points do not match (" - << points_no_ends_out_size << ", " - << points_no_ends_size << ")\n"; - return false; + // std::cout << "read_points " << count << "\n"; + for (int i = 0; i < count; i++) { + NT x, y; + inp >> skip_comment >> x >> y; + Point_2 p(x, y); + // std::cout << p << "\n"; + points.push_back(p); } - return true; } #endif - -int main(int argc, char* argv[]) { - if (argc != 2) { - std::cout << "Specify a file name " << std::endl; - return -1; - } - - std::ifstream inp(argv[1]); - if (! inp.is_open()) { - std::cerr << "Error: Cannot open file " << argv[1] << "!" << std::endl; - return -1; - } - - Traits tr; - - Curves curves; - if (! read_curves(inp, curves, tr)) return -1; - - X_monotone_curves curves_no_overlap_out; - CGAL::compute_subcurves(curves.begin(), curves.end(), - std::back_inserter(curves_no_overlap_out), - false, tr); - - X_monotone_curves curves_with_overlap_out; - CGAL::compute_subcurves(curves.begin(), curves.end(), - std::back_inserter(curves_with_overlap_out), - true, tr); - - Points points_with_ends_out; - CGAL::compute_intersection_points(curves.begin(), curves.end(), - std::back_inserter(points_with_ends_out), - true, tr); - - Points points_no_ends_out; - CGAL::compute_intersection_points(curves.begin(), curves.end(), - std::back_inserter(points_no_ends_out), - false, tr); - -#if CGAL_ARR_TEST_TRAITS == CGAL_CONIC_TRAITS - if (! test_conic(inp, curves, curves_no_overlap_out, - points_with_ends_out, points_no_ends_out, tr)) - return -1; -#else - if (! test_curves_no_overlap(inp, curves, curves_no_overlap_out, tr)) - return -1; - if (! test_points_with_ends(inp, curves, points_with_ends_out, tr)) return -1; - if (! test_points_no_ends(inp, curves, points_no_ends_out, tr)) return -1; - if (! test_curves_with_overlap(inp, curves, curves_with_overlap_out, tr)) - return -1; -#endif - - // Test the do_curves_intersecting method - bool do_intersect_out = - CGAL::do_curves_intersect(curves.begin(), curves.end()); - bool do_intersect = ! points_no_ends_out.empty() || - (curves_no_overlap_out.size() != curves_with_overlap_out.size()); - if (do_intersect_out != do_intersect) { - std::cerr << "Error: do_intersect()\n"; - return -1; - } - - std::cout << "Passed\n"; - return 0; -} - -#endif diff --git a/Surface_sweep_2/test/Surface_sweep_2/test_sweep_conic.cpp b/Surface_sweep_2/test/Surface_sweep_2/test_sweep_conic.cpp new file mode 100644 index 000000000000..45ae95448515 --- /dev/null +++ b/Surface_sweep_2/test/Surface_sweep_2/test_sweep_conic.cpp @@ -0,0 +1,279 @@ +#include + +#if !defined(CGAL_USE_CORE) +#include +int main() +{ + std::cout << "CORE is not installed. Test aborted!" << std::endl; + return 0; +} +#else + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +typedef CGAL::CORE_algebraic_number_traits Nt_traits; +typedef Nt_traits::Rational Rational; +typedef Nt_traits::Algebraic Algebraic; +typedef CGAL::Cartesian Rat_kernel; +typedef Rat_kernel::Point_2 Rat_point_2; +typedef Rat_kernel::Segment_2 Rat_segment_2; +typedef Rat_kernel::Circle_2 Rat_circle_2; +typedef CGAL::Cartesian Alg_kernel; +typedef CGAL::Arr_conic_traits_2 + Traits_2; + +typedef Traits_2::Curve_2 Curve_2; +typedef Traits_2::X_monotone_curve_2 X_monotone_curve_2; +typedef Traits_2::Point_2 Point_2; +typedef std::list CurveList; + +typedef std::list PointList; +typedef PointList::iterator PointListIter; + + +/*! Conic reader */ +template +class Conic_reader { +public: + int ReadData(const char* filename, CurveList& curves, CGAL::Bbox_2& bbox) + { + Curve_2 cv; + char dummy[256]; + + std::ifstream inp(filename); + if (!inp.is_open()) { + std::cerr << "Cannot open file " << filename << "!" << std::endl; + return -1; + } + int count; + inp >> count; + inp.getline(dummy, sizeof(dummy)); + for (int i = 0; i < count; i++) { + ReadCurve(inp, cv); + curves.push_back(cv); + CGAL::Bbox_2 curve_bbox = cv.bbox(); + if (i == 0) bbox = curve_bbox; + else bbox = bbox + curve_bbox; + } + inp.close(); + return 0; + } + + void ReadCurve(std::ifstream & is, Curve_2 & cv) + { + // Read a line from the input file. + char one_line[128]; + + skip_comments (is, one_line); + std::string stringvalues(one_line); + std::istringstream str_line (stringvalues, std::istringstream::in); + + // Get the arc type. + // Supported types are: 'f' - Full ellipse (or circle). + // 'e' - Elliptic arc (or circular arc). + // 's' - Line segment. + char type; + bool is_circle = false; // Is this a circle. + Rat_circle_2 circle; + Rational r, s, t, u, v, w; // The conic coefficients. + + str_line >> type; + + // An ellipse (full ellipse or a partial ellipse): + if (type == 'f' || type == 'F' || type == 'e' || type == 'E') + { + // Read the ellipse (using the format "a b x0 y0"): + // + // x - x0 2 y - y0 2 + // ( -------- ) + ( -------- ) = 1 + // a b + // + int a, b, x0, y0; + + str_line >> a >> b >> x0 >> y0; + + Rational a_sq = Rational(a*a); + Rational b_sq = Rational(b*b); + + if (a == b) + { + is_circle = true; + circle = Rat_circle_2 (Rat_point_2 (Rational(x0), Rational(y0)), + Rational(a*b)); + } + else + { + r = b_sq; + s = a_sq; + t = 0; + u = Rational(-2*x0*b_sq); + v = Rational(-2*y0*a_sq); + w = Rational(x0*x0*b_sq + y0*y0*a_sq - a_sq*b_sq); + } + + if (type == 'f' || type == 'F') + { + // Create a full ellipse (or circle). + if (is_circle) + cv = Curve_2 (circle); + else + cv = Curve_2 (r, s, t, u, v, w); + } + else + { + // Read the endpointd of the arc. + int x1, y1, x2, y2; + + str_line >> x1 >> y1 >> x2 >> y2; + + Point_2 source = Point_2 (Algebraic(x1), Algebraic(y1)); + Point_2 target = Point_2 (Algebraic(x2), Algebraic(y2)); + + // Create the arc. Note that it is always clockwise oriented. + if (is_circle) + cv = Curve_2 (circle, + CGAL::CLOCKWISE, + source, target); + else + cv = Curve_2 (r, s, t, u, v, w, + CGAL::CLOCKWISE, + source, target); + } + } + else if (type == 's' || type == 'S') + { + // Read a segment, given by its endpoints (x1,y1) and (x2,y2); + int x1, y1, x2, y2; + + str_line >> x1 >> y1 >> x2 >> y2; + + // Create the segment. + Rat_point_2 source = Rat_point_2 (Rational(x1), Rational(y1)); + Rat_point_2 target = Rat_point_2 (Rational(x2), Rational(y2)); + + cv = Curve_2(Rat_segment_2 (source, target)); + } + + return; + } + + void skip_comments( std::ifstream& is, char* one_line ) + { + while( !is.eof() ){ + is.getline( one_line, 128 ); + if( one_line[0] != '#' ){ + break; + } + } + } +}; + +//--------------------------------------------------------------------------- +// The main: +// +int main (int argc, char** argv) +{ + bool verbose = false; + + // Define a test objects to read the conic arcs from it. + if (argc<2) + { + std::cerr << "Usage: Conic_traits_test " << std::endl; + exit(1); + } + + CGAL::Bbox_2 bbox; + CurveList curves; + + Conic_reader reader; + reader.ReadData(argv[1], curves, bbox); + + // run the sweep + std::list mylist; + + CGAL::compute_subcurves(curves.begin(), curves.end(), + std::back_inserter(mylist), false); + + + PointList point_list_with_ends; + CGAL::compute_intersection_points(curves.begin(), curves.end(), + std::back_inserter(point_list_with_ends), true); + std::size_t point_count_with_ends_calculated = point_list_with_ends.size(); + + // generate the string for the output + std::stringstream out1; + for ( std::list::iterator iter = mylist.begin() ; + iter != mylist.end() ; ++iter ) + { + out1 << *iter << "\n"; + } + + // read the output from the file + std::stringstream out2; + char buf[1024]; + int count = 0; + + std::ifstream in_file(argv[1]); + in_file >> count; + in_file.getline(buf, 1024); // to get rid of the new line + for ( int i = 0 ; i < count ; i++ ) { + in_file.getline(buf, 1024); + } + in_file >> count; + in_file.getline(buf, 1024); // to get rid of the new line + for (int i = 0; i < count; i++) { + in_file.getline(buf, 1024); + out2 << buf << "\n"; + } + std::size_t point_count_with_ends_from_file = 0; + in_file >> point_count_with_ends_from_file; + in_file.close(); + + if ( verbose ) + { + std::cout << "Result: \n" << mylist.size() << "\n"; + for ( std::list::iterator i = mylist.begin() ; + i != mylist.end() ; ++i ) + { + std::cout << *i << "\n"; + } + } + + std::string calculated = out1.str(); + std::string infile = out2.str(); + + if ( infile == calculated ) { + if ( point_count_with_ends_from_file != + point_count_with_ends_calculated ) { + std::cout << "number of intersection points (with ends):" + << point_count_with_ends_calculated << ". Should be " + << point_count_with_ends_from_file << "\n"; + std::cout << argv[1] << " Error\n"; + return -1; + } else { + std::cout << argv[1] << " OK!\n"; + } + } else { + std::cout << argv[1] << " Error\n"; + std::cout << "\ncalculated:\n"; + std::cout << calculated << std::endl; + std::cout << "\nin file:\n"; + std::cout << infile << std::endl; + std::cout << "--" << std::endl; + return -1; + } + + return 0; +} + +#endif From 5d61c35a643dd1d17a4b471cfe6314cd9025858d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 18 Dec 2023 15:20:10 +0100 Subject: [PATCH 315/329] fix warning --- Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp b/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp index 97265afa626b..326307f84617 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp +++ b/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp @@ -309,7 +309,6 @@ bool read_xcurves(std::ifstream& inp, X_monotone_curves& xcurves, bool read_points(std::ifstream& inp, Points& points, const Traits&) { int count; inp >> skip_comment >> count; - char ch; // std::cout << "read_points " << count << "\n"; for (int i = 0; i < count; i++) { From 4fe88f8b4901b3c4429d95dbf1abb28c0d707a2f Mon Sep 17 00:00:00 2001 From: Sven Oesau Date: Mon, 18 Dec 2023 15:35:25 +0100 Subject: [PATCH 316/329] added transformation of normals --- .../Polyhedron/Plugins/PCA/Affine_transform_plugin.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Affine_transform_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PCA/Affine_transform_plugin.cpp index 1a0a9e34f35e..d651bdcd61b6 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Affine_transform_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Affine_transform_plugin.cpp @@ -614,12 +614,20 @@ endPointSet(const QMatrix4x4& transform_matrix) Point_set* new_ps = new_item->point_set(); CGAL::qglviewer::Vec c = aff_transformed_item->center(); + QMatrix3x3 normal_matrix = transform_matrix.normalMatrix(); + for(Point_set::Index idx : *new_ps) { QVector3D vec = transform_matrix.map(QVector3D(new_ps->point(idx).x() - c.x, new_ps->point(idx).y() - c.y, new_ps->point(idx).z() - c.z)); new_ps->point(idx) = Kernel::Point_3(vec.x(), vec.y(), vec.z()); + if (new_ps->has_normal_map()) { + QVector3D n(new_ps->normal(idx).x(), new_ps->normal(idx).y(), new_ps->normal(idx).z()); + new_ps->normal(idx) = Kernel::Vector_3(normal_matrix(0, 0) * n[0] + normal_matrix(0, 1) * n[1] + normal_matrix(0, 2) * n[2], + normal_matrix(1, 0) * n[0] + normal_matrix(1, 1) * n[1] + normal_matrix(1, 2) * n[2], + normal_matrix(2, 0) * n[0] + normal_matrix(2, 1) * n[1] + normal_matrix(2, 2) * n[2]); + } } new_item->setName(aff_transformed_item->name()); From c36f0ac091e0e668c1f6beff29d41355d4396f79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 19 Dec 2023 14:42:02 +0100 Subject: [PATCH 317/329] add a switch to get rid of QP_Solver dependency --- .../CGAL/Convex_hull_3/dual/halfspace_intersection_3.h | 10 +++++++++- .../dual/halfspace_intersection_with_constructions_3.h | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/Convex_hull_3/include/CGAL/Convex_hull_3/dual/halfspace_intersection_3.h b/Convex_hull_3/include/CGAL/Convex_hull_3/dual/halfspace_intersection_3.h index 2edd7244422d..e140c8a227cf 100644 --- a/Convex_hull_3/include/CGAL/Convex_hull_3/dual/halfspace_intersection_3.h +++ b/Convex_hull_3/include/CGAL/Convex_hull_3/dual/halfspace_intersection_3.h @@ -26,7 +26,9 @@ #include #include // For interior_polyhedron_3 +#ifndef CGAL_CH3_DUAL_WITHOUT_QP_SOLVER #include +#endif #include #include @@ -230,7 +232,11 @@ namespace CGAL template void halfspace_intersection_3 (PlaneIterator begin, PlaneIterator end, Polyhedron &P, - boost::optional::value_type>::Kernel::Point_3> origin = boost::none) { + boost::optional::value_type>::Kernel::Point_3> origin +#ifndef CGAL_CH3_DUAL_WITHOUT_QP_SOLVER + = boost::none +#endif + ) { // Checks whether the intersection is a polyhedron CGAL_assertion_msg(Convex_hull_3::internal::is_intersection_dim_3(begin, end), "halfspace_intersection_3: intersection not a polyhedron"); @@ -241,8 +247,10 @@ namespace CGAL // if a point inside is not provided find one using linear programming if (!origin) { +#ifndef CGAL_CH3_DUAL_WITHOUT_QP_SOLVER // find a point inside the intersection origin = halfspace_intersection_interior_point_3(begin, end); +#endif CGAL_assertion_msg(origin!=boost::none, "halfspace_intersection_3: problem when determing a point inside the intersection"); if (origin==boost::none) diff --git a/Convex_hull_3/include/CGAL/Convex_hull_3/dual/halfspace_intersection_with_constructions_3.h b/Convex_hull_3/include/CGAL/Convex_hull_3/dual/halfspace_intersection_with_constructions_3.h index 31dcb337b984..b09c632555b7 100644 --- a/Convex_hull_3/include/CGAL/Convex_hull_3/dual/halfspace_intersection_with_constructions_3.h +++ b/Convex_hull_3/include/CGAL/Convex_hull_3/dual/halfspace_intersection_with_constructions_3.h @@ -23,7 +23,9 @@ #include // For interior_polyhedron_3 +#ifndef CGAL_CH3_DUAL_WITHOUT_QP_SOLVER #include +#endif #include #include @@ -99,7 +101,9 @@ namespace CGAL // if a point inside is not provided find one using linear programming if (!origin) { // find a point inside the intersection +#ifndef CGAL_CH3_DUAL_WITHOUT_QP_SOLVER origin = halfspace_intersection_interior_point_3(pbegin, pend); +#endif CGAL_assertion_msg(origin!=boost::none, "halfspace_intersection_with_constructions_3: problem when determing a point inside the intersection"); if (origin==boost::none) @@ -134,7 +138,11 @@ namespace CGAL void halfspace_intersection_with_constructions_3 (PlaneIterator pbegin, PlaneIterator pend, Polyhedron &P, - boost::optional::value_type>::Kernel::Point_3> const& origin = boost::none) { + boost::optional::value_type>::Kernel::Point_3> const& origin +#ifndef CGAL_CH3_DUAL_WITHOUT_QP_SOLVER + = boost::none +#endif + ) { typedef typename Kernel_traits::value_type>::Kernel K; typedef typename K::Point_3 Point_3; typedef typename Convex_hull_3::internal::Default_traits_for_Chull_3::type Traits; From 0b58c21b11cbfb31c11782f7672ea62ae9e7130f Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Thu, 21 Dec 2023 15:45:39 +0100 Subject: [PATCH 318/329] improve the script [skip ci] --- .../developer_scripts/add_toc_to_github_wiki_page.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Scripts/developer_scripts/add_toc_to_github_wiki_page.py b/Scripts/developer_scripts/add_toc_to_github_wiki_page.py index 928703c502e8..f9f58e4f5b58 100644 --- a/Scripts/developer_scripts/add_toc_to_github_wiki_page.py +++ b/Scripts/developer_scripts/add_toc_to_github_wiki_page.py @@ -21,7 +21,8 @@ def get_anchor(s): s = s.replace("`", "") s = s.replace("(", "") s = s.replace(")", "") - s = s.replace(".", "") + if not args.codebase: + s = s.replace(".", "") s = s.replace("#", "") s = s.replace(":", "") s = s.replace(",", "") @@ -39,11 +40,12 @@ def get_anchor(s): s = s.lstrip(" ") s = s.rstrip("\n") s = s.rstrip(" ") - s = re.sub(r"\s+", "-", s) if not args.codebase: s = s.lower() if args.codebase: + s = s.replace("' ", "-and-39-") s = s.replace("'", "-and-39-") + s = re.sub(r"\s+", "-", s) return "#" + quote(s) @@ -106,7 +108,9 @@ def main(): sys.exit() buffer = "" - toc = "\n\n# Table of Contents\n" + toc = "\n" + toc += "\n\n" + toc += "\n# Table of Contents\n" verbatim_mode = False # to ignore verbatim mode while looking for sections toc_empty = True From bd98f389b15c22b41d4ecde183f797f5f8d8e0da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 22 Dec 2023 15:09:29 +0100 Subject: [PATCH 319/329] update for qt6 --- Scripts/developer_scripts/cgal_demo_copy_all_dlls_cygwin.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Scripts/developer_scripts/cgal_demo_copy_all_dlls_cygwin.sh b/Scripts/developer_scripts/cgal_demo_copy_all_dlls_cygwin.sh index 2af501d48c03..6699629f7c24 100644 --- a/Scripts/developer_scripts/cgal_demo_copy_all_dlls_cygwin.sh +++ b/Scripts/developer_scripts/cgal_demo_copy_all_dlls_cygwin.sh @@ -1,7 +1,7 @@ #!/bin/bash #use this script from inside the build directory of the Polyhedron demo -#Needs the Qt5_DIR env variable set to /lib/cmake/Qt5 +#Needs the Qt6_DIR env variable set to /lib/cmake/Qt6 #No config : in autotest_cgal we use NMake as generator #If using MSVC Generator, declare config="Release" @@ -43,4 +43,4 @@ for file in "${files[@]}"; do done; #check dependencies done #loop over directories mkdir -p "$target_directory/platforms" -cp "$Qt5_INSTALLATION_DIR/plugins/platforms/qwindows.dll" "$target_directory/platforms" +cp "$Qt6_INSTALLATION_DIR/plugins/platforms/qwindows.dll" "$target_directory/platforms" From 4942b8e9180ee8c3b29a15670f9de77d2214f8e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 27 Dec 2023 10:19:15 +0100 Subject: [PATCH 320/329] add QT6 version in test results --- Maintenance/test_handling/create_testresult_page | 1 + Maintenance/test_handling/to_zipped_format | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Maintenance/test_handling/create_testresult_page b/Maintenance/test_handling/create_testresult_page index 3747a4a83133..4b183402d48a 100755 --- a/Maintenance/test_handling/create_testresult_page +++ b/Maintenance/test_handling/create_testresult_page @@ -475,6 +475,7 @@ sub print_platform_descriptions() MPFR GMP QT5 +QT6 LEDA CXXFLAGS LDFLAGS diff --git a/Maintenance/test_handling/to_zipped_format b/Maintenance/test_handling/to_zipped_format index d8c7c1cd433b..e4d8e66bd566 100755 --- a/Maintenance/test_handling/to_zipped_format +++ b/Maintenance/test_handling/to_zipped_format @@ -51,7 +51,7 @@ sub reformat_results($) $_ = $line; open (PLATFORM_INFO,">${platform}.info") or return; open (PLATFORM_NEW_RESULTS,">${platform}.new_results") or return; - my ($CGAL_VERSION,$LEDA_VERSION,$COMPILER,$TESTER_NAME,$TESTER_ADDRESS,$GMP,$MPFR,$ZLIB,$OPENGL,$BOOST,$QT,$QT4,$QT5,$CMAKE) = ("-","-","-","-","-","-","-","-","-","-","-","-","-","-","-","no"); + my ($CGAL_VERSION,$LEDA_VERSION,$COMPILER,$TESTER_NAME,$TESTER_ADDRESS,$GMP,$MPFR,$ZLIB,$OPENGL,$BOOST,$QT,$QT4,$QT5,$QT6,$CMAKE) = ("-","-","-","-","-","-","-","-","-","-","-","-","-","-","-","-","no"); my ($LDFLAGS,$CXXFLAGS) = ("", ""); while (! /^------/) { if(/^\s*$/) { @@ -102,6 +102,9 @@ sub reformat_results($) if (/Qt5_VERSION = '([^']+)'/) { $QT5="$1"; } + if (/Qt6_VERSION = '([^']+)'/) { + $QT6="$1"; + } if (/BOOST_VERSION = '([^']+)'/) { $BOOST="$1"; } @@ -148,6 +151,7 @@ $BOOST $MPFR $GMP $QT5 +$QT6 $LEDA_VERSION $CXXFLAGS $LDFLAGS From e760e9795999da66038818ffe789379634e6069a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 27 Dec 2023 11:05:57 +0100 Subject: [PATCH 321/329] update indices --- Maintenance/test_handling/create_testresult_page | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Maintenance/test_handling/create_testresult_page b/Maintenance/test_handling/create_testresult_page index 4b183402d48a..8fd78fc58204 100755 --- a/Maintenance/test_handling/create_testresult_page +++ b/Maintenance/test_handling/create_testresult_page @@ -531,7 +531,7 @@ EOF print OUTPUT "$counto\n"; print OUTPUT "$countn\n"; print OUTPUT "$countr\n"; - $index = 8; + $index = 9; while ($index) { $index--; $_ = $tmp[$index]; @@ -543,7 +543,7 @@ EOF } } else { print OUTPUT ">$pf_short
"; - my $index = 12; + my $index = 13; while ($index) { print OUTPUT "?\n"; } From ee6c73b8494c24a2dd08d8e96c1155464211f3e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 27 Dec 2023 11:08:23 +0100 Subject: [PATCH 322/329] another index --- Maintenance/test_handling/create_testresult_page | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Maintenance/test_handling/create_testresult_page b/Maintenance/test_handling/create_testresult_page index 8fd78fc58204..02d4fb4a38f6 100755 --- a/Maintenance/test_handling/create_testresult_page +++ b/Maintenance/test_handling/create_testresult_page @@ -512,7 +512,7 @@ EOF my $countn = $testresults[$platform_num]->{"n"}; my $countr = $testresults[$platform_num]->{"r"}; - my $index = 8; + my $index = 9; my @tmp; while ($index) { $index--; From 37c792a764e9837a94048c5feafcc291301b393b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 27 Dec 2023 11:56:08 +0100 Subject: [PATCH 323/329] fix qt6 version --- Installation/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Installation/CMakeLists.txt b/Installation/CMakeLists.txt index 744e4fed4ab1..1e912131c120 100644 --- a/Installation/CMakeLists.txt +++ b/Installation/CMakeLists.txt @@ -1253,6 +1253,6 @@ if(RUNNING_CGAL_AUTO_TEST OR CGAL_TEST_SUITE) "USING BOOST_VERSION = '${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}'" ) if(Qt6_FOUND) - message(STATUS "USING Qt6_VERSION = '${Qt6Core_VERSION_STRING}'") + message(STATUS "USING Qt6_VERSION = '${Qt6Core_VERSION}'") endif()#Qt6_FOUND endif()#RUNNING_CGAL_AUTO_TEST OR CGAL_TEST_SUITE From ea07530d1d5ee5b17ea8dc8ffb3efee7e1d63ba7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 27 Dec 2023 12:01:55 +0100 Subject: [PATCH 324/329] add missing decrement --- Maintenance/test_handling/create_testresult_page | 1 + 1 file changed, 1 insertion(+) diff --git a/Maintenance/test_handling/create_testresult_page b/Maintenance/test_handling/create_testresult_page index 02d4fb4a38f6..37934a2fbcbb 100755 --- a/Maintenance/test_handling/create_testresult_page +++ b/Maintenance/test_handling/create_testresult_page @@ -545,6 +545,7 @@ EOF print OUTPUT ">$pf_short"; my $index = 13; while ($index) { + $index--; print OUTPUT "?\n"; } } From 3564fd185161c17f82c9b2827e9b53ba2b029b79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 27 Dec 2023 14:12:35 +0100 Subject: [PATCH 325/329] unify QT --- Maintenance/test_handling/create_testresult_page | 9 ++++----- Maintenance/test_handling/to_zipped_format | 11 +++++------ 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/Maintenance/test_handling/create_testresult_page b/Maintenance/test_handling/create_testresult_page index 37934a2fbcbb..edde28fff960 100755 --- a/Maintenance/test_handling/create_testresult_page +++ b/Maintenance/test_handling/create_testresult_page @@ -474,8 +474,7 @@ sub print_platform_descriptions() BOOST MPFR GMP -QT5 -QT6 +QT LEDA CXXFLAGS LDFLAGS @@ -512,7 +511,7 @@ EOF my $countn = $testresults[$platform_num]->{"n"}; my $countr = $testresults[$platform_num]->{"r"}; - my $index = 9; + my $index = 8; my @tmp; while ($index) { $index--; @@ -531,7 +530,7 @@ EOF print OUTPUT "$counto\n"; print OUTPUT "$countn\n"; print OUTPUT "$countr\n"; - $index = 9; + $index = 8; while ($index) { $index--; $_ = $tmp[$index]; @@ -543,7 +542,7 @@ EOF } } else { print OUTPUT ">$pf_short"; - my $index = 13; + my $index = 12; while ($index) { $index--; print OUTPUT "?\n"; diff --git a/Maintenance/test_handling/to_zipped_format b/Maintenance/test_handling/to_zipped_format index e4d8e66bd566..fdf62712b021 100755 --- a/Maintenance/test_handling/to_zipped_format +++ b/Maintenance/test_handling/to_zipped_format @@ -51,7 +51,7 @@ sub reformat_results($) $_ = $line; open (PLATFORM_INFO,">${platform}.info") or return; open (PLATFORM_NEW_RESULTS,">${platform}.new_results") or return; - my ($CGAL_VERSION,$LEDA_VERSION,$COMPILER,$TESTER_NAME,$TESTER_ADDRESS,$GMP,$MPFR,$ZLIB,$OPENGL,$BOOST,$QT,$QT4,$QT5,$QT6,$CMAKE) = ("-","-","-","-","-","-","-","-","-","-","-","-","-","-","-","-","no"); + my ($CGAL_VERSION,$LEDA_VERSION,$COMPILER,$TESTER_NAME,$TESTER_ADDRESS,$GMP,$MPFR,$ZLIB,$OPENGL,$BOOST,$QT,$CMAKE) = ("-","-","-","-","-","-","-","-","-","-","-","-","-","no"); my ($LDFLAGS,$CXXFLAGS) = ("", ""); while (! /^------/) { if(/^\s*$/) { @@ -97,13 +97,13 @@ sub reformat_results($) $QT="$1"; } if (/QT4_VERSION = '([^']+)'/) { - $QT4="$1"; + $QT="$1"; } if (/Qt5_VERSION = '([^']+)'/) { - $QT5="$1"; + $QT="$1"; } if (/Qt6_VERSION = '([^']+)'/) { - $QT6="$1"; + $QT="$1"; } if (/BOOST_VERSION = '([^']+)'/) { $BOOST="$1"; @@ -150,8 +150,7 @@ $CMAKE $BOOST $MPFR $GMP -$QT5 -$QT6 +$QT $LEDA_VERSION $CXXFLAGS $LDFLAGS From a4ba059221a3da98c4f4013a3f701f3ab77b0ae0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 2 Jan 2024 09:34:07 +0100 Subject: [PATCH 326/329] remove unused variable --- Kernel_23/test/Kernel_23/test_approximate_dihedral_angle_3.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Kernel_23/test/Kernel_23/test_approximate_dihedral_angle_3.cpp b/Kernel_23/test/Kernel_23/test_approximate_dihedral_angle_3.cpp index dc3ccdaf9899..35ddb31e0c53 100644 --- a/Kernel_23/test/Kernel_23/test_approximate_dihedral_angle_3.cpp +++ b/Kernel_23/test/Kernel_23/test_approximate_dihedral_angle_3.cpp @@ -53,7 +53,6 @@ int main() { Point_3 a = {0, 0, 0}; Point_3 b = {0, -1, 0}; // ab is oriented so that it sees the plan xz positively. - [[maybe_unused]] Point_3 c = {1, 0, 0}; // c can be any point in the half-plane xy, with x>0 const query queries[] = { From eed5e4f61f9b31c4adc9e419759fc8130ee7c086 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 2 Jan 2024 13:15:28 +0100 Subject: [PATCH 327/329] move comment --- Kernel_23/test/Kernel_23/test_approximate_dihedral_angle_3.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Kernel_23/test/Kernel_23/test_approximate_dihedral_angle_3.cpp b/Kernel_23/test/Kernel_23/test_approximate_dihedral_angle_3.cpp index 35ddb31e0c53..791ce36ac8c1 100644 --- a/Kernel_23/test/Kernel_23/test_approximate_dihedral_angle_3.cpp +++ b/Kernel_23/test/Kernel_23/test_approximate_dihedral_angle_3.cpp @@ -53,7 +53,6 @@ int main() { Point_3 a = {0, 0, 0}; Point_3 b = {0, -1, 0}; // ab is oriented so that it sees the plan xz positively. - // c can be any point in the half-plane xy, with x>0 const query queries[] = { { { 1, 0, 0}, 0.}, @@ -68,6 +67,7 @@ int main() { auto cnt = 0u; for(double yc = -10; yc < 10; yc += 0.1) { + // c can be any point in the half-plane xy, with x>0 Point_3 c{1, yc, 0}; // std::cout << "c = " << c << '\n'; for(const auto& query : queries) { From 9985f9cfa0fed1ef7dad30e1941dc58a34e57b83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 2 Jan 2024 14:04:03 +0100 Subject: [PATCH 328/329] autorefinement has its own license file --- .../Polygon_mesh_processing/autorefinement.h | 54 +++++++++++++++++++ .../interpolated_corrected_curvatures.h | 8 +-- Installation/include/CGAL/license/SMDS_3.h | 4 +- .../include/CGAL/license/gpl_package_list.txt | 1 + .../Polygon_mesh_processing/autorefinement.h | 2 +- 5 files changed, 62 insertions(+), 7 deletions(-) create mode 100644 Installation/include/CGAL/license/Polygon_mesh_processing/autorefinement.h diff --git a/Installation/include/CGAL/license/Polygon_mesh_processing/autorefinement.h b/Installation/include/CGAL/license/Polygon_mesh_processing/autorefinement.h new file mode 100644 index 000000000000..8f3c9cc5e3fe --- /dev/null +++ b/Installation/include/CGAL/license/Polygon_mesh_processing/autorefinement.h @@ -0,0 +1,54 @@ +// Copyright (c) 2016 GeometryFactory SARL (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) : Andreas Fabri +// +// Warning: this file is generated, see include/CGAL/license/README.md + +#ifndef CGAL_LICENSE_POLYGON_MESH_PROCESSING_AUTOREFINEMENT_H +#define CGAL_LICENSE_POLYGON_MESH_PROCESSING_AUTOREFINEMENT_H + +#include +#include + +#ifdef CGAL_POLYGON_MESH_PROCESSING_AUTOREFINEMENT_COMMERCIAL_LICENSE + +# if CGAL_POLYGON_MESH_PROCESSING_AUTOREFINEMENT_COMMERCIAL_LICENSE < CGAL_RELEASE_DATE + +# if defined(CGAL_LICENSE_WARNING) + + CGAL_pragma_warning("Your commercial license for CGAL does not cover " + "this release of the Polygon Mesh Processing - Autorefinement package.") +# endif + +# ifdef CGAL_LICENSE_ERROR +# error "Your commercial license for CGAL does not cover this release \ + of the Polygon Mesh Processing - Autorefinement package. \ + You get this error, as you defined CGAL_LICENSE_ERROR." +# endif // CGAL_LICENSE_ERROR + +# endif // CGAL_POLYGON_MESH_PROCESSING_AUTOREFINEMENT_COMMERCIAL_LICENSE < CGAL_RELEASE_DATE + +#else // no CGAL_POLYGON_MESH_PROCESSING_AUTOREFINEMENT_COMMERCIAL_LICENSE + +# if defined(CGAL_LICENSE_WARNING) + CGAL_pragma_warning("\nThe macro CGAL_POLYGON_MESH_PROCESSING_AUTOREFINEMENT_COMMERCIAL_LICENSE is not defined." + "\nYou use the CGAL Polygon Mesh Processing - Autorefinement package under " + "the terms of the GPLv3+.") +# endif // CGAL_LICENSE_WARNING + +# ifdef CGAL_LICENSE_ERROR +# error "The macro CGAL_POLYGON_MESH_PROCESSING_AUTOREFINEMENT_COMMERCIAL_LICENSE is not defined.\ + You use the CGAL Polygon Mesh Processing - Autorefinement package under the terms of \ + the GPLv3+. You get this error, as you defined CGAL_LICENSE_ERROR." +# endif // CGAL_LICENSE_ERROR + +#endif // no CGAL_POLYGON_MESH_PROCESSING_AUTOREFINEMENT_COMMERCIAL_LICENSE + +#endif // CGAL_LICENSE_POLYGON_MESH_PROCESSING_AUTOREFINEMENT_H diff --git a/Installation/include/CGAL/license/Polygon_mesh_processing/interpolated_corrected_curvatures.h b/Installation/include/CGAL/license/Polygon_mesh_processing/interpolated_corrected_curvatures.h index e484daaf5eae..5bf31aaa352b 100644 --- a/Installation/include/CGAL/license/Polygon_mesh_processing/interpolated_corrected_curvatures.h +++ b/Installation/include/CGAL/license/Polygon_mesh_processing/interpolated_corrected_curvatures.h @@ -9,10 +9,10 @@ // // Author(s) : Andreas Fabri // -// Warning: this file is generated, see include/CGAL/licence/README.md +// Warning: this file is generated, see include/CGAL/license/README.md -#ifndef CGAL_POLYGON_MESH_PROCESSING_INTERPOLATED_CORRECTED_CURVATURES_H -#define CGAL_POLYGON_MESH_PROCESSING_INTERPOLATED_CORRECTED_CURVATURES_H +#ifndef CGAL_LICENSE_POLYGON_MESH_PROCESSING_INTERPOLATED_CORRECTED_CURVATURES_H +#define CGAL_LICENSE_POLYGON_MESH_PROCESSING_INTERPOLATED_CORRECTED_CURVATURES_H #include #include @@ -51,4 +51,4 @@ #endif // no CGAL_POLYGON_MESH_PROCESSING_INTERPOLATED_CORRECTED_CURVATURES_COMMERCIAL_LICENSE -#endif // CGAL_POLYGON_MESH_PROCESSING_INTERPOLATED_CORRECTED_CURVATURES_H +#endif // CGAL_LICENSE_POLYGON_MESH_PROCESSING_INTERPOLATED_CORRECTED_CURVATURES_H diff --git a/Installation/include/CGAL/license/SMDS_3.h b/Installation/include/CGAL/license/SMDS_3.h index 4f349c13acf3..b4011300b50a 100644 --- a/Installation/include/CGAL/license/SMDS_3.h +++ b/Installation/include/CGAL/license/SMDS_3.h @@ -24,12 +24,12 @@ # if defined(CGAL_LICENSE_WARNING) CGAL_pragma_warning("Your commercial license for CGAL does not cover " - "this release of the 3D Mesh Data Structure package.") + "this release of the 3D Simplicial Mesh Data Structure package.") # endif # ifdef CGAL_LICENSE_ERROR # error "Your commercial license for CGAL does not cover this release \ - of the 3D Mesh Data Structure package. \ + of the 3D Simplicial Mesh Data Structure package. \ You get this error, as you defined CGAL_LICENSE_ERROR." # endif // CGAL_LICENSE_ERROR diff --git a/Installation/include/CGAL/license/gpl_package_list.txt b/Installation/include/CGAL/license/gpl_package_list.txt index 41612d5b9fca..fd4eeeb7d657 100644 --- a/Installation/include/CGAL/license/gpl_package_list.txt +++ b/Installation/include/CGAL/license/gpl_package_list.txt @@ -61,6 +61,7 @@ Polygon_mesh_processing/geometric_repair Polygon Mesh Processing - Geometric Rep Polygon_mesh_processing/miscellaneous Polygon Mesh Processing - Miscellaneous Polygon_mesh_processing/detect_features Polygon Mesh Processing - Feature Detection Polygon_mesh_processing/collision_detection Polygon Mesh Processing - Collision Detection +Polygon_mesh_processing/autorefinement Polygon Mesh Processing - Autorefinement Polyhedron 3D Polyhedral Surface Polyline_simplification_2 2D Polyline Simplification Polytope_distance_d Optimal Distances diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h index 8a61b92f7178..a3606f816a7b 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/autorefinement.h @@ -14,7 +14,7 @@ #ifndef CGAL_POLYGON_MESH_PROCESSING_AUTOREFINEMENT_H #define CGAL_POLYGON_MESH_PROCESSING_AUTOREFINEMENT_H -#include +#include #include #include From 277c1603eb8f9f355aea4849ae4a1dbbed5edd99 Mon Sep 17 00:00:00 2001 From: Sebastien Loriot Date: Tue, 2 Jan 2024 17:46:42 +0100 Subject: [PATCH 329/329] fix warning --- Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp b/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp index c0da570e916b..1171fabe6149 100644 --- a/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp +++ b/Surface_sweep_2/test/Surface_sweep_2/test_sweep.cpp @@ -385,7 +385,7 @@ bool test_points_no_ends(std::ifstream& inp, Curves& /* curves */, const Points& points_no_ends_out, const Traits& tr) { Points points_no_ends; - if (! read_points(inp, points_no_ends, tr)) return -1; + if (! read_points(inp, points_no_ends, tr)) return false; if (! compare_lists(points_no_ends_out, points_no_ends, tr)) { std::cerr << "Error: Intersection points do not match!\n";