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 de98db8e9a0..41d96180310 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 192e7d29b74..e188e01e3eb 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 00000000000..65db52fef2c --- /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 00000000000..8c34b4041d8 --- /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 5c649faa56c..7d758abc4ee 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 8c34b4041d8..fd124bce857 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 fd124bce857..4b7020b5615 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 e188e01e3eb..d2faeb70cb2 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 00000000000..fa1f5d68690 --- /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 4b7020b5615..8dd8d28fcfc 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 8dd8d28fcfc..fd5e7312c26 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 fa1f5d68690..8ca983aa31c 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 | 244 ++++++++++-------- 1 file changed, 132 insertions(+), 112 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 fd5e7312c26..01188d4d6b1 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; + 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(normal(t[0], t[1], t[2])); + 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[i1], all_segments[i2], + all_points[i1], all_points[i2]); - auto inter = intersection(t1, t2); - - if (inter != boost::none) - { - autorefine_impl::Intersection_visitor intersection_visitor(all_segments_1[it1], all_segments_2[it2], - all_points_1[it1], all_points_2[it2]); - - 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); } - CGAL_assertion( autorefine_impl::is_output_valid(tm, vpm, tid_map, is_degen, 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); + } + // 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 01188d4d6b1..d18826fc2f1 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 d18826fc2f1..3ec80745042 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 3ec80745042..0711ad71e21 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 0711ad71e21..b2786386205 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 b2786386205..881ffcc8796 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 881ffcc8796..9393e197a19 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 9393e197a19..283e139eb1c 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 | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 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 283e139eb1c..ea1c0de07eb 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; + std::vector< std::vector >& all_segments; + std::vector< std::vector >& all_points; + std::pair ids; - 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) + 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 | 125 ++++++++---------- 1 file changed, 54 insertions(+), 71 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 ea1c0de07eb..290dde25332 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)) - { - if (get(is_degen, f)) continue; //skip degenerate faces + 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)))); - int tid = get(tid_map, f); - if (tid == -1) + 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; - autorefine_soup_output(tm, soup_points, soup_triangles, np); + polygon_mesh_to_polygon_soup(tm, in_soup_points, in_soup_triangles); + + 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 8ca983aa31c..297875c9ec8 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); + std::vector output_points; + std::vector> output_triangles; + PMP::autorefine_soup_output(input_points, input_triangles, output_points, output_triangles); - PMP::autorefine(mesh); - - 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 297875c9ec8..9ade96e3be8 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 290dde25332..80b964ad859 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 80b964ad859..6d97f7521de 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 6d97f7521de..afbe0c3479d 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 false; + 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); + } +} + +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])); - //~ std::cout << "new inter " << *pt_ptr << "\n"; + 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"; + + } } - 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 afbe0c3479d..c9bb3f3ffa8 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 42867cfbb07..047c8526afc 100644 --- a/Triangulation_2/include/CGAL/Constrained_triangulation_2.h +++ b/Triangulation_2/include/CGAL/Constrained_triangulation_2.h @@ -330,11 +330,11 @@ public: #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 c9bb3f3ffa8..f412c2ea298 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 f412c2ea298..ae9858ae77d 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 | 301 +++++++++++++++--- .../Polygon_mesh_processing/autorefinement.h | 36 ++- 2 files changed, 287 insertions(+), 50 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 424e1fc9361..d4e467a0798 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 -void 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) +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) { - typedef typename std::list::iterator Iterator; + 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 +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) +{ + 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(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); - //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); - 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); + Point_on_triangle new_pt = intersection(*prev, *it, edge_id, p1, q1, p2, q2, r2, k); - // assert "not empty" - CGAL_kernel_assertion(bool(obj)); - - 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); - 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)); + 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(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 ae9858ae77d..6d0334d9366 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 | 129 +++++++++++++----- 1 file changed, 97 insertions(+), 32 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 d4e467a0798..55610e867ff 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()); + 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); - 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); + 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 6d0334d9366..b87a04c8a6a 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(t2[0]); - l_inter_pts.push_back(t2[1]); - l_inter_pts.push_back(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::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 55610e867ff..7c6ad7b95f8 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 b87a04c8a6a..c5f3ebb7890 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 7c6ad7b95f8..ac376f44350 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 c5f3ebb7890..7524c9c7f34 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 7524c9c7f34..e5a7dbbb139 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 e5a7dbbb139..3bb845854ec 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 3bb845854ec..a81b00f65a4 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 a81b00f65a4..e18cf1982b2 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 e18cf1982b2..d40fce82d2b 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 d40fce82d2b..711c3d82ce0 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"); + 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"); } - -#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; - } - - 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 711c3d82ce0..8cc1dd7ff9f 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 8cc1dd7ff9f..f6b7bac57bb 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 f6b7bac57bb..7432f1f7d35 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 7432f1f7d35..a54e4d29971 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 a54e4d29971..734a47fcf56 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 9ade96e3be8..a46fc6e711c 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 734a47fcf56..7cd083e8338 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 7cd083e8338..c90ba515271 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 ac376f44350..35aa4f8f0a5 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 c90ba515271..c7e067916d5 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 a46fc6e711c..d955734853b 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 c7e067916d5..4f56b8a0d81 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 4f56b8a0d81..e38f64ff301 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 35aa4f8f0a5..4cc5f9be560 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 8177a02d178..e8901ebd727 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 d2faeb70cb2..306e216be40 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 e38f64ff301..a46f2664803 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 d955734853b..f1230668948 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 a46f2664803..e862d683960 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 420b718d1e7..7d48df57242 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 b8f61bf90c6..b5e69de0242 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 9f96ea0d395..5c505dbd01f 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 9fc24d51667..15cc231bb28 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 953c0bdeaaf..8ea66e0df9f 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 46d7e73e4d6..187550ca704 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 cd0e00f2585..2f9455a5a35 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 c94c53eece6..b95f6e3998c 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 2aa0735bf04..10db8ae63ea 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 e9f6371753e..8e0635e3ca6 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 f0113460554..47e21732fd6 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 78140996955..e389d4a7db7 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 39d22990f45..4710b27995d 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 69f7c821d95..3fad0655447 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 6252c3b96dc..01535344d7c 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 bc9ee161137..f7b36b05432 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 d174c920fc2..3bc6a8ce547 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 32cf9a98c6c..34351b917ac 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 049c8e10a28..23c2db7d18f 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 b21e9b2a107..a6cf55f8025 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 9075a5d1fb5..2c261cad7d1 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 445b25d3b6e..ad795ac780e 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 738953c643b..e6ac95bc017 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 8c692cc93a4..633acf5e467 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 601e8cfbf8a..c1b674a8f00 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 3b52e2164d7..c679dad3f34 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 fc3cfb4fc30..2cfe803179b 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 1d25c06c8c4..09d93ba7d9b 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 ed905e724c2..d945734fca4 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 37aca71a59c..44a64a0247f 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 e6a784c9d3d..93f5204f262 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 3185f80ec7b..42f4208cf9a 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 830d83f2e59..822e3789c28 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 52b22ae49a6..6db47eaf9ed 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 9587d1b15dc..47ced43d85b 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 58b53d15991..c8a3dd025bc 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 2c4c5a96f29..03fbb7e16ea 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 bf946526e36..2c10412d83b 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 beea62f7afb..2cb778d38b7 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 3651988bd29..f9cefcc2116 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 b83c0b96d1c..4cfeb604b7f 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 a78d9c4bdea..90afe463752 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 0aff3e7b181..19a28bae19d 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 431f41756eb..24188d25fa0 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 ed0e785f55b..512151f3428 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 5861e7d3583..1624ab36537 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 8546ccf6f28..9884d9b633f 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 38fdef6d37b..937d78e447e 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 47db121f373..11d3fd8a787 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 cf9cd7243ce..0acf5053818 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 519eff3c8c9..e54693b507c 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 79d17493558..03bc28fe6ca 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 ce10a30cb75..75d46976285 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 1065362fc19..f2f078a9329 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 adc296648a4..bac5d28e69c 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 92beb4090a2..580ad875127 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 6db6035cbc7..56f8052dbd5 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 ee6c49c399e..a975379f310 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 8923f049d15..0bf64d49d7f 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 f2825be57f2..b27adefbb3b 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 e83cce072ae..d1ebcea2dc1 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 7725cef46c2..420a030dada 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 b380b5e7cbd..cdd01dcd119 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 54feabc43ba..4d739e20e78 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 cc0683ad7ad..c353837bfed 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 c6b68c4163b..cfc1576cd41 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 7ac58ab7917..726cdc2d9d4 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 c231c7b4f77..212a77a0f3c 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 0a95db80fac..5e2b5aafab2 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 4cc18dcb021..c48b428b791 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 50fe97fa383..2b7af6f80e7 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 e33576bb815..97bfc5d24fd 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 52ed98b070e..b3ec36e6744 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 194577128a5..a91fe60a739 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 dc9b76b1284..9390c7cc608 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 57300a903c3..3181a33c498 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 4c27222b415..4f7bc3a18d5 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 e4dbeb073c2..723bf69b8ff 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 67a74747e52..5ef7d44396b 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 419bf09b9eb..b7d779ff1b1 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 79d9d1bd8be..53e394fb9dc 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 bb28d85698c..85ef8c50bc4 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 2d84b028ae6..029e8e04e93 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 911adaeaab2..036b8c8b6bd 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 f18f1018db3..18f5554dde7 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 | 322 +++++++++--------- 5 files changed, 211 insertions(+), 208 deletions(-) diff --git a/Surface_sweep_2/test/Surface_sweep_2/CMakeLists.txt b/Surface_sweep_2/test/Surface_sweep_2/CMakeLists.txt index 6bc64ec7601..3471c16f715 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 ff43d9b73a4..311f26746d4 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 c6c8af71e9a..2612c02c50f 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 8c72a52e332..60483af61d6 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 23ceebf559d..7af2076d7a8 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) -int main() -{ +#elif ! defined(CGAL_USE_GMP) && \ + ((CGAL_ARR_TEST_TRAITS == CGAL_SEGMENT_TRAITS) || \ + (CGAL_ARR_TEST_TRAITS == CGAL_POLYLINE_TRAITS)) + +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 + +#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; + typedef CGAL::Arr_conic_traits_2 Traits; + +#elif CGAL_ARR_TEST_TRAITS == CGAL_POLYCURVE_TRAITS + typedef CGAL::Arr_conic_traits_2 Conic_traits; + typedef CGAL::Arr_polycurve_traits_2 Traits; + #endif -typedef Traits::Point_2 Point_2; -typedef Traits::X_monotone_curve_2 X_monotone_curve_2; +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 PointList; -typedef PointList::iterator PointListIter; +typedef std::list Points; +typedef std::list Curves; +typedef std::list X_monotone_curves; -typedef std::list CurveList; -typedef CurveList::iterator CurveListIter; +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); -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); +// 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); + 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_list_out.begin(), - curves_no_overlap_list_out.end(), + /*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); + X_monotone_curves curves_no_overlap; + if (! read_xcurves(inp, curves_no_overlap, tr)) return -1; - PointList points_with_ends_list; - ReadPointList(inp, points_with_ends_list); + Points points_with_ends; + if (! read_points(inp, points_with_ends, tr)) return -1; - PointList points_without_ends_list; - ReadPointList(inp, points_without_ends_list); + Points points_without_ends; + if (! read_points(inp, points_without_ends, tr)) return -1; - int num_faces; - inp >> num_faces; + X_monotone_curves curves_with_overlap; + if (! read_xcurves(inp, curves_with_overlap, tr)) return -1; - CurveList curves_with_overlap_list; - ReadCurveListRational(inp, curves_with_overlap_list); - - 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) -{ - int count; - inp >> count; - //std::cout << "ReadCurveList " << count << "\n"; +#if CGAL_ARR_TEST_TRAITS == CGAL_SEGMENT_TRAITS - for (int i = 0; i < count; i++) { +bool read_curves(std::ifstream& inp, Curves& curves, const Traits&) { + int count; + inp >> skip_comment >> count; + std::cout << "read_curves " << count << "\n"; + + 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"; - } -} - -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); - - inp >> a >> ch >> b; - NT x1(a,b); - inp >> a >> ch >> b; - NT y1(a,b); - Point_2 p2(x1, y1); - - X_monotone_curve_2 curve(p1, p2); - clist.push_back(curve); + Curve_2 curve(p1, p2); + curves.push_back(curve); std::cout << curve << "\n"; } + return true; } -void ReadPointList(std::ifstream &inp, PointList &plist) -{ + +bool read_xcurves(std::ifstream& inp, X_monotone_curves& xcurves, + const Traits& traits) +{ return read_curves(inp, xcurves, traits); } + +#elif CGAL_ARR_TEST_TRAITS == CGAL_POLYLINE_TRAITS + +template +bool read_curves_(std::ifstream& inp, Curves_& curves, const Traits& traits, + const Ctr& ctr) { int count; - inp >> 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); +} + +#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; - 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 311f26746d4..2727e737570 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 00000000000..60cda75d7fd --- /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 7af2076d7a8..d85bf455ccf 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); + X_monotone_curves curves_no_overlap; + if (! read_xcurves(inp, curves_no_overlap, tr)) return -1; - /*std::copy(curves_no_overlap_out.begin(), - curves_no_overlap_out.end(), - std::ostream_iterator(std::cout, "\n")); - std::cout<<"\n\n*******************\n\n"; + 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; + } - 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"; - - - // 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; - // get intersection points w/o end points + 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); - 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; + 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_no_overlap_out, curves_no_overlap, 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; + } - if (! compare_lists(curves_with_overlap_out, curves_with_overlap, tr)) - return -1; - - if (! compare_lists(points_with_ends_out, points_with_ends, tr)) - return -1; - - if (! compare_lists(points_without_ends_out, points_without_ends, tr)) - 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 00000000000..a024e6ccf8f --- /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 3471c16f715..ac96a58ca42 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 d85bf455ccf..97265afa626 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 e862d683960..ad88f3a6ace 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 f1230668948..d5ebeb78c3f 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 ad88f3a6ace..40a3ed87cbc 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 40a3ed87cbc..eb24d60804a 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 eb24d60804a..e5f96d26c3b 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 e5f96d26c3b..16c788c22ec 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 | 219 ++++++++++-------- 2 files changed, 119 insertions(+), 104 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 d5ebeb78c3f..823c50974dc 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 16c788c22ec..ae383a4af29 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 + //TODO: 100 should be fined tune and depends on #threads +#ifdef CGAL_LINKED_WITH_TBB + 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); +#endif + } + return insert_res.first->second; + }; - std::size_t offset = soup_triangles.size(); - std::string mode; - if(sequential || new_triangles.size() < 100){ - mode = "sequential"; + + 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()); + } + 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]))); - } + 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 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 | 438 +++++++++++++----- .../test/Surface_sweep_2/test_sweep_conic.cpp | 279 ----------- 15 files changed, 378 insertions(+), 418 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 ac96a58ca42..9e96fa6dc1c 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 a3464614b95..1ff457efdb1 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 f3ca4fd2817..c404b51caa1 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 6ed5fcbab23..599a66f9b14 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 d9a9875cdeb..eb6a5c18711 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 224bbc2397a..e68e06cb488 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 59ac8c5f663..f82851db1c1 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 2b2253b5594..e884bd40154 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 54aae8118a0..63063346910 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 543d1cff813..6afc8ee809c 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 51c9e3ffb2a..d5f29cc3101 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 00000000000..7af88f99c7a --- /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 97265afa626..cc11bbabac3 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; +#if CGAL_ARR_TEST_TRAITS != CGAL_CONIC_TRAITS + +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++) { + NT x, y; + inp >> skip_comment >> x >> y; + Point_2 p(x, y); + // std::cout << p << "\n"; + points.push_back(p); } - - 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()); - - 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; + 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); } -#else -#error No traits defined for test -#endif +#elif CGAL_ARR_TEST_TRAITS == CGAL_CONIC_TRAITS -bool read_points(std::ifstream& inp, Points& points, const 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; - char ch; - - // 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); + 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; + } + + 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 45ae9544851..00000000000 --- 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 ae383a4af29..18bbfa2ce40 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 4cc5f9be560..99dcd24ff45 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 0098bcd0142..f0875a55ee8 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 18bbfa2ce40..6b664ec360b 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 99dcd24ff45..68166f18c6e 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 71aa268e6d3..780c0b2d4e5 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 9c85643a977..e5a2ebf8121 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 6b664ec360b..6c8ba3f8cd2 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 6c8ba3f8cd2..90174e42753 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 90174e42753..11b15fa4ec4 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 823c50974dc..9e4999287f7 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 | 129 ++++++++++++++---- 1 file changed, 103 insertions(+), 26 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 11b15fa4ec4..9bbc67efb48 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) { - 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) { + 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; + }; - soup_points.reserve(soup_points.size() + concurrent_soup_points.size()); - soup_points.insert(soup_points.end(), concurrent_soup_points.begin(), concurrent_soup_points.end()); + //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]; + 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; + } + } + ); + + 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 e307e28ae1f..438dc0de14b 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 1360aa1bbcd..0acc0a4c690 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 9bbc67efb48..68241773f37 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 438dc0de14b..6917a06edcf 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 0acc0a4c690..a2314aef1b7 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 68241773f37..693c00676f0 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 693c00676f0..122c595b13e 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 | 174 ++++++++++++------ 3 files changed, 119 insertions(+), 68 deletions(-) diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt index b17c41399d0..95d8794cca1 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 9e4999287f7..a44d47c8b6d 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 122c595b13e..bfa65df1c73 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) - { - 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; - }; - // 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)))); + // 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? // 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 bfa65df1c73..0054a9dcdb2 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 00000000000..e3ef90e9be0 --- /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 0054a9dcdb2..166c950a983 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 166c950a983..6bbb5571e7a 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 6bbb5571e7a..0fb843c31c0 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 152d84952ae..658458acaad 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 5ecc8921433..dd4acb43427 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: << 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 @@ public: 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 @@ private: 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 e88e00fafe0..1e9674276fa 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 @@ private: 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 @@ private: 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 @@ private: 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 d7567bab205..c6591e000df 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 928cade6495..8ac2e422d87 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 e2abc6f1f12..eda64a8376a 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 5091934b62f..302494d8c30 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 1e9674276fa..1b0a6968c09 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 @@ private: 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 1b0a6968c09..a21925cdc6d 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 @@ private: 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 @@ private: // 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 a21925cdc6d..6d544be058d 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 @@ private: // 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 8974b762dcb..8309a3c97ce 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 0fb843c31c0..b3133304bb9 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 b3133304bb9..32765252a6f 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 47998400268..b361d15dec7 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 32765252a6f..884ce3477aa 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 f12ad06804b..86010b27dfc 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 @@ protected: 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 @@ public: 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 | 317 +++++++++++------- 1 file changed, 204 insertions(+), 113 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 86010b27dfc..6e8e323e85a 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,92 +648,37 @@ private: 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; + std::unordered_map vertex_to_id; -#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()); - - 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::vector points; - std::vector > faces; - std::size_t idx = 0; - - while(!to_visit.empty()) + std::array ids; + for(int pos=0; pos<3; ++pos) { - const Cell_handle cell = to_visit.front(); - CGAL_assertion(!cell->info().is_outside && !m_dt.is_infinite(cell)); + 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)); - 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->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); - } - } + ids[pos] = insertion_res.first->second; } - PMP::duplicate_non_manifold_edges_in_polygon_soup(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)); - - PMP::stitch_borders(output_mesh, CGAL::parameters::vertex_point_map(ovpm)); - CGAL_assertion(is_closed(output_mesh)); + faces.emplace_back(std::array{ids[0], ids[1], ids[2]}); } - - for(auto cit=m_dt.finite_cells_begin(), cend=m_dt.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 @@ -743,7 +688,7 @@ public: namespace PMP = Polygon_mesh_processing; #ifdef CGAL_AW3_DEBUG - std::cout << "> Extract wrap... ()" << std::endl; + std::cout << "> Extract manifold wrap... ()" << std::endl; #endif CGAL_assertion_code(for(Vertex_handle v : m_dt.finite_vertex_handles())) @@ -751,48 +696,21 @@ public: clear(output_mesh); - // boundary faces to polygon soup std::vector points; std::vector > faces; - - std::unordered_map vertex_to_id; - std::size_t nv = 0; - - for(auto fit=m_dt.finite_facets_begin(), fend=m_dt.finite_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 int s = f.second; - const Cell_handle nh = c->neighbor(s); - if(c->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; - } - - ids[pos] = insertion_res.first->second; - } - - faces.emplace_back(std::array{ids[0], ids[1], ids[2]}); - } + extract_boundary(points, faces); if(faces.empty()) + { +#ifdef CGAL_AW3_DEBUG + std::cout << "Empty wrap?..." << std::endl; +#endif return; + } if(!PMP::is_polygon_soup_a_polygon_mesh(faces)) { - CGAL_warning_msg(false, "Could NOT extract mesh..."); + CGAL_warning_msg(false, "Failed to extract a manifold boundary!"); return; } @@ -803,10 +721,183 @@ public: 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_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 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 back edge by edge by walking along the exterior + std::map facet_ids; + std::size_t 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; + + facet_ids[f] = idx / 3; + + 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}); + + idx += 3; + } + + if(polygons.empty()) + { +#ifdef CGAL_AW3_DEBUG + std::cout << "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_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)); + 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 6e8e323e85a..7c48a51ba6c 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 @@ private: // 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 8d63e34c9e3..824d27bc2c1 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 7c48a51ba6c..9a0ee2ddb61 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 @@ protected: 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 @@ public: 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 @@ public: 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 @@ private: 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 @@ private: 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 @@ private: 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 7792ad5cdb6..435075df6e2 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 2014b9baa7c..11dec5f4134 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 00000000000..600d533ee41 --- /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 9a0ee2ddb61..0579297c433 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 @@ private: 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 @@ private: #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 @@ private: return IRRELEVANT; } +private: bool push_facet(const Facet& f) { CGAL_precondition(f.first->info().is_outside); @@ -1127,19 +1146,29 @@ private: 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 @@ private: 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 @@ private: 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 @@ private: 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 @@ private: 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 @@ public: 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 @@ private: 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 @@ private: 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 5422c84b2ae..021cdc6270a 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 13568227319..3f5481d0cfe 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 c17823d72b9..5a5bc2d242d 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 42715621e4b..85ba6ccc235 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 2951b1983fe..dfa6fb89ffc 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 91313be6c5d..1aac0615585 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 @@ 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 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 @@ private: 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 75c8f25e0c9..099f44192ee 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 e4533596dd2..283b2dc66b5 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 @@ public: 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 0f2957d4714..ee072c95778 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 81eae420496..a86325de2af 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 5c8e19fa12e..ce17f3b9105 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 e726e161a6b..01104c54680 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 @@ public: 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 2d85e38d35c..eddefcec7fb 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 1e0efd6faa6..4dce0049b1a 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 861f5aea98b..f6f56cea7ef 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 aab29d9b881..b6973feb65c 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 a50266f7659..555dc554c58 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 d3d67c57a88..dbb9aa8bae6 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 911a86debc3..c6b6cb2444a 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 034b1600f93..1747f89f354 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 f08600a4603..f6d6d0559dd 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 4839184ff30..e12d38503bc 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 57890430a5b..9648697498a 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 7e3af3de705..3ab3f0d3ba5 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 @@ public: } 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 45246e4463d..3d1c030ff08 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 44e4f82b82d..ad023df618e 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 b4e2af50375..50e0a6cef08 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 db2dde5b6d3..e8517c94945 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 c02efa6dcc6..25ec0c4f25c 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 5c3a64287d2..122cfe90885 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 d62b8215cc5..edfb15ae9e9 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 a3255d25eb0..4eb0e890063 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 a1ac6faeddd..f2e6a2f3ada 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 18ac1657ee6..5693977869a 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 3f06ef3fb32..3f8a2812968 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 e91e22208a5..8c117c2fb6d 100644 --- a/Number_types/include/CGAL/Quotient.h +++ b/Number_types/include/CGAL/Quotient.h @@ -627,13 +627,13 @@ public: }; - typedef typename boost::mpl::if_c< - !std::is_same< typename Algebraic_structure_traits::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 b0913afb1b6..b1500148b59 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 @@ public: 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 6b4344348d4..5b5ddfa45c6 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 a96c2eafa36..d821ab2fe3f 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 @@ public: } 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 2780d618393..b1ee5e65065 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 @@ public: } 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 7eed15886cd..63fb9404469 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 83884277136..7dad2004ecd 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 4a15d9e59c7..68f0c9e5e6c 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 26e205ea43d..f32f9d907a9 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 ef361b17529..b99ed460a6f 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 f1b88540a60..a608179f49a 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 b3681eb43b5..ad61432cd40 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 e2529d2e349..de6bcdc447b 100644 --- a/Polynomial/include/CGAL/Polynomial/Polynomial_type.h +++ b/Polynomial/include/CGAL/Polynomial/Polynomial_type.h @@ -486,9 +486,9 @@ public: // 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 6eb4f0d6e3f..dfbf7cf3135 100644 --- a/Polynomial/include/CGAL/Polynomial_traits_d.h +++ b/Polynomial/include/CGAL/Polynomial_traits_d.h @@ -999,7 +999,7 @@ public: // 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 @@ private: 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 a7dc48b5354..bca414e19b0 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 f77f1d9c07f..ef7c6164f2d 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 24f7ef91c72..81ff5cf1bce 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 7f18ab80f57..e6a2a5dbecf 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 5f952a66e15..528bf8061d1 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 @@ public: 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 d0f1648f816..7558aae88f2 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 bd94ad33c4f..21d88e8f69c 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 6962b1ec8f2..528ea1e0e83 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 0b34898eff9..08cc1da0063 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 ff640dc639a..7a518cf68ee 100644 --- a/Spatial_searching/include/CGAL/Search_traits_adapter.h +++ b/Spatial_searching/include/CGAL/Search_traits_adapter.h @@ -224,16 +224,16 @@ public: // 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 a799eccda60..30b1e25de59 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 4ce20796d1a..02b050f790a 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 f7e4a653060..c3ab2223a0a 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 93e00b1680f..29513248384 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 aa58c124ed1..7795840a2e6 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 3a73305b380..f2c945342e8 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 7b8ef9ab6c8..fd4b530c7a8 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 021e40e2ffe..c852a4bed75 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 78b8822f598..01f08ac186c 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 e93418c19cf..20c4351bc49 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 e4f80d9149f..c1b00d9aca9 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 f2ad170c95e..8f7b1f5efc9 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 @@ public: 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 @@ public: #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 @@ private: // 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 @@ private: 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 824d27bc2c1..5e14a4d08ea 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 @@ public: 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 d3814d0f3b2..7d66cfd19f4 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 8f7b1f5efc9..3ee6061d0d8 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 @@ private: 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 6d544be058d..639c9a3f468 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 @@ private: 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 00000000000..a9aa0d1d63c --- /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 00000000000..86c57d35146 --- /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 00000000000..445b6923277 --- /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 00000000000..207b4704635 --- /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 00000000000..3b996cb5749 --- /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 00000000000..379573e9c90 --- /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 00000000000..0df5ed5e0f4 --- /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 00000000000..4565cca641a --- /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 d7567bab205..1e37919756a 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 638431e3056..189cc73fa2d 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 e2abc6f1f12..a7abdf6674e 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 470d48e40d4..e7a362fc709 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 ffcedc7f1cb..4e96d6c1116 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 3ee6061d0d8..3aaabefd94f 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 5e14a4d08ea..a9bdd7e0491 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 3aaabefd94f..14ad83cdbd3 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 @@ private: 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 @@ private: 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 7d66cfd19f4..f39a4701286 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 14ad83cdbd3..a7130c2a377 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 @@ private: 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 @@ private: 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 @@ private: 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 a7130c2a377..2174363240b 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 @@ private: } } } - 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 00000000000..f4b0f7cc649 --- /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 eb9b98cbe59..6f5d1e7c7ce 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 00000000000..36105ee3a02 --- /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 00000000000..a2098c63e3b --- /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 f4b0f7cc649..8bb6502865f 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 8742a2a2001..aeb47b80152 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 600d533ee41..59010d1212e 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 00e2e4fd9fc..369cf375a6f 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 626e3bdc3ba..6e1321c302d 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 113215b631a..682cffac339 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 1c1d6c7b3d7..9de47aefbcd 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 2174363240b..7c9509b9185 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 @@ private: 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 @@ private: 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 @@ private: } 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ private: 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 @@ private: << "\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 @@ private: << 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 @@ public: } // 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 @@ public: // @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 @@ private: 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 a9bdd7e0491..b091b2cabe2 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 @@ public: 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 a1b29fd5689..e66d6c83dd3 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 @@ public: 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 b17c41399d0..1d17b286dc5 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 c755ecf63e8..0ad5f79a261 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 a2098c63e3b..76f97bf3dc6 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 6f5d1e7c7ce..eb9b98cbe59 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 36105ee3a02..00000000000 --- 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 7e916fc7698..8a649b15ead 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 4e96d6c1116..fdba4de5f51 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 00000000000..3ce1155f4ef --- /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 aeb47b80152..a602cf5c58b 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 59010d1212e..f9b35f88b1f 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 369cf375a6f..d4953490446 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 6e1321c302d..51e04974c28 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 682cffac339..3ac28de3302 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 9de47aefbcd..9422e4d969b 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 7bad2ff313d..8ccbf049a33 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 @@ public: 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 d02a9f9faaf..08e76dc6f5d 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 @@ public: #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 c87f82ac75f..869c108693d 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 @@ public: 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 0a8f589fc2d..35966be4644 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 @@ public: 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 08e76dc6f5d..63f3532cf67 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 @@ public: 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 869c108693d..ffd8326a44f 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 @@ public: 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 35966be4644..27322a554e3 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 @@ public: 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 @@ public: 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 12fd06503fe..f1115cbf05a 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 7c9509b9185..c103a4e4c41 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 @@ private: } 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 @@ private: 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 @@ private: 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 @@ private: 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 f39a4701286..991f9e48e25 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 c103a4e4c41..9792b828a61 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 @@ private: } 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 991f9e48e25..7f5f60de701 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 8a649b15ead..7a3b2c0765e 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 8ee04d38577..ef51234bb6e 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 76f97bf3dc6..29f43453e87 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 b361d15dec7..8748eda2db0 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 884ce3477aa..5b9cad98277 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 639c9a3f468..ba4635889b4 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 @@ private: // 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 @@ private: 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 9792b828a61..08f09fcdd4c 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 @@ private: 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 @@ protected: 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 @@ private: { 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 @@ private: << " 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 @@ private: 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 @@ private: // 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 @@ private: 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 @@ private: 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 @@ private: 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 db1df61c8f6..b586d495f0d 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 @@ public: 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 @@ public: : 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 b091b2cabe2..f017f9be8cf 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 7a3b2c0765e..4e9082996e4 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 08f09fcdd4c..2764546c318 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 @@ protected: FT m_offset = FT(-1), m_sq_offset = FT(-1); Triangulation m_tr; + Alpha_PQ m_queue; public: @@ -250,24 +251,33 @@ public: 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 @@ public: 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 @@ public: #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 @@ public: 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 @@ private: 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 @@ private: 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 @@ private: 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 @@ private: 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 @@ private: 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 @@ private: // 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 @@ private: 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 @@ private: // 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 @@ private: } 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 @@ public: { 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 @@ private: 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 f017f9be8cf..9c29ac9e722 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 | 165 +++++++++++------- .../Alpha_wrap_triangulation_cell_base_3.h | 19 +- 2 files changed, 115 insertions(+), 69 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 2764546c318..f22fbfaa1f3 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 @@ public: 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 @@ private: // - 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 @@ private: 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 @@ private: { 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 @@ private: 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,38 +733,6 @@ private: } private: - void extract_boundary(std::vector& points, - std::vector >& faces) const - { - std::unordered_map vertex_to_id; - - 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()) - 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()) - continue; - - std::array ids; - for(int pos=0; pos<3; ++pos) - { - Vertex_handle vh = ch->vertex(Triangulation::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_tr.point(vh)); - - ids[pos] = insertion_res.first->second; - } - - faces.emplace_back(std::array{ids[0], ids[1], ids[2]}); - } - } - template void extract_manifold_surface(OutputMesh& output_mesh, OVPM ovpm) const @@ -760,7 +750,39 @@ private: std::vector points; std::vector > faces; - extract_boundary(points, faces); + + std::unordered_map vertex_to_id; + + 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()) + 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_outside_boundary(ch, nh)) + continue; + + std::array ids; + for(int pos=0; pos<3; ++pos) + { + Vertex_handle vh = ch->vertex(Triangulation::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_tr.point(vh)); + + ids[pos] = insertion_res.first->second; + } + + faces.emplace_back(std::array{ids[0], ids[1], ids[2]}); + } + +#ifdef CGAL_AW3_DEBUG + std::cout << "\t" << points.size() << " points" << std::endl; + std::cout << "\t" << faces.size() << " faces" << std::endl; +#endif if(faces.empty()) { @@ -787,8 +809,8 @@ private: } 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 @@ private: 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 @@ private: 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 @@ private: { 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 @@ private: 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 @@ public: 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 @@ public: // 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 @@ public: } 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 @@ private: 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 @@ private: if(m_tr.is_infinite(nh)) { - nh->is_outside() = true; + nh->label() = Cell_label::OUTSIDE; continue; } @@ -1402,7 +1432,7 @@ private: 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 @@ private: 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 @@ private: } 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 @@ private: // 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 @@ private: 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 @@ private: 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 @@ public: 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 @@ public: 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 @@ private: 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 b586d495f0d..f5636b79879 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 @@ public: 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 @@ public: }; 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 @@ public: {} 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 f22fbfaa1f3..a6244eef2ed 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 @@ private: 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 @@ private: 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 @@ private: 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 @@ public: #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 @@ public: #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 @@ public: #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 @@ private: 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 @@ private: 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 a6244eef2ed..beb2bc7708c 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ private: 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 @@ private: 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 beb2bc7708c..d61ca129ae2 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 @@ private: // 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 @@ private: 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 c851ef559bc..646ec7951e8 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 @@ public: // 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 646ec7951e8..4543277de72 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 @@ public: 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 76135fd82a7..43016f9889f 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 4543277de72..c781319c07e 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 @@ private: 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 @@ protected: 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 @@ public: 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 @@ public: 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 @@ private: // // 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 @@ private: 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 @@ private: } private: - template bool initialize(const double alpha, const double offset, - const SeedRange& seeds, const bool refining) { #ifdef CGAL_AW3_DEBUG @@ -1308,10 +1303,10 @@ private: 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 4565cca641a..f8e54c488a4 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 fdba4de5f51..90b488e0407 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 f9b35f88b1f..f8533fb9cda 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 c781319c07e..1f7a9fdcbeb 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 @@ protected: 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 @@ public: 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 638c5fb9fa1..8be78675422 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 847799522f2..af94eecd25a 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 739d131189c..35a954f17b2 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 e66d6c83dd3..0ff34cc54ec 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 0ff34cc54ec..f40130dedb1 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 @@ public: } }; -// 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 @@ public: 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 | 84 ++++++++++--------- 1 file changed, 43 insertions(+), 41 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 1f7a9fdcbeb..a3976a7ab55 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 @@ public: 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 - - 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; -#endif - make_manifold(); +#ifdef CGAL_AW3_DEBUG_DUMP_INTERMEDIATE_WRAPS + dump_triangulation_faces("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; 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 @@ public: // 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 @@ public: 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 9422e4d969b..970bb583484 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 a3976a7ab55..a1f82e6e3bd 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ private: 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 a1f82e6e3bd..8192dd063d3 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 @@ private: } 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 @@ private: 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 @@ public: 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 8192dd063d3..b4be5907d1c 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 @@ private: 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 @@ private: { 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 @@ private: 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 @@ private: 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 @@ private: 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 @@ private: } 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 @@ private: { 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 @@ public: 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 f5636b79879..efaeb82d330 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 @@ public: 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 b4be5907d1c..a986e5c6a38 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 @@ private: 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 a986e5c6a38..fc580aa561c 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 @@ private: "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 fc580aa561c..675e6e30394 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 @@ private: } 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 675e6e30394..31870dd0147 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 @@ public: 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 34674777b40..40187ca194c 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 00000000000..5663bce1684 --- /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 f40130dedb1..f9eba756bf8 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 31870dd0147..98313249efd 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 @@ public: // 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 @@ public: 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 @@ public: 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 @@ public: #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 @@ private: 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 @@ private: 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 435075df6e2..a164053aabb 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 3ce1155f4ef..581ac82bff0 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 5663bce1684..b22b21d817b 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 f8533fb9cda..301aec46e2d 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 98313249efd..45834cd6b61 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 @@ private: 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 @@ public: 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 @@ public: // 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 @@ private: // 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 @@ private: 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 @@ private: 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 @@ private: 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 @@ private: 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 @@ private: 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 @@ private: if(cell->tds_data().processed()) continue; - cell->tds_data().mark_processed(); for(int fid=0; fid<4; ++fid) @@ -1024,12 +1017,12 @@ public: << 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 @@ private: // 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 @@ private: 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 @@ private: { m_tr.clear(); - insert_bbox_corners(); if(m_seeds.empty()) @@ -1512,7 +1508,7 @@ private: 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 @@ public: 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 @@ public: 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 @@ public: // 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 @@ public: // - 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 @@ public: // '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 @@ public: 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 9c29ac9e722..f7947f246a4 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 c9445c9e9c5..6d9a9191d5f 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 9e5fead9f86..9def2bb6cc1 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 da313069594..f9938d4fc7b 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 57f58b342bd..353e5569d1f 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 4e9082996e4..8cd6dc4f6cc 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 45834cd6b61..94694034cdd 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 @@ public: // 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 8cd6dc4f6cc..f1ceb6e59d3 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 f1ceb6e59d3..293d791a47c 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 585cc9d9685..49cdb33da9c 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 49cdb33da9c..d0f605834db 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 f9eba756bf8..86a87983562 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 8ccbf049a33..37ff1495560 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 @@ public: 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 @@ public: // 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 63f3532cf67..f4d1c338b62 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 @@ public: 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 @@ public: 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 @@ public: // 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 85bd11c00b6..7f3534a484c 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 @@ public: 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 37ff1495560..ad04a43f720 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 @@ public: 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 f4d1c338b62..349cd012ef7 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 @@ public: 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 ffd8326a44f..d7f325e1428 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 @@ public: 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 27322a554e3..dadfb5d8be1 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 @@ public: 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 @@ public: 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 86a87983562..383d1103778 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 ad04a43f720..33f8a52b178 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 @@ public: 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 96511da5520..d950cfb6d82 100644 --- a/Mesh_3/include/CGAL/Mesh_criteria_3.h +++ b/Mesh_3/include/CGAL/Mesh_criteria_3.h @@ -70,22 +70,16 @@ public: // 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 7792ad5cdb6..621e551c40f 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 d950cfb6d82..12e0e422207 100644 --- a/Mesh_3/include/CGAL/Mesh_criteria_3.h +++ b/Mesh_3/include/CGAL/Mesh_criteria_3.h @@ -77,8 +77,7 @@ public: 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 621e551c40f..d656b63a006 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 12e0e422207..c2d5d3d9b13 100644 --- a/Mesh_3/include/CGAL/Mesh_criteria_3.h +++ b/Mesh_3/include/CGAL/Mesh_criteria_3.h @@ -70,15 +70,15 @@ public: // 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 5b9cad98277..d25ea95fe90 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 1aac0615585..8ba336b1e19 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 283b2dc66b5..9bcabf985d6 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 @@ public: 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 @@ public: //! 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 ee072c95778..5bc8054c525 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 30c8b38b4a0..06052a8f19d 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 @@ protected: * \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 @@ protected: * \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 @@ protected: * \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 @@ protected: * \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 f49b92f4c01..f4975fb1428 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 @@ private: // 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 4dce0049b1a..7dd7edd0887 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 @@ public: 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 1fd71599ad1..e8ab8b8bc43 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 b1500148b59..c2175bc9439 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 @@ public: // 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 e6a2a5dbecf..7f5533f92b7 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 aeb66ea052b..9f5ac5a84cb 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 02b050f790a..3cc57168971 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 b1ee5e65065..bfb4b4e8716 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 @@ public: 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 e662b13be90..3d02204b9d0 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 8ba336b1e19..94ea503e244 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; + 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::and_ LR_ide; - typedef boost::mpl::and_ BT_ide; + static inline constexpr bool lr_ide = lef_ide && rig_ide; + static inline constexpr bool bt_ide = bot_ide && top_ide; - 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_not_ide = !lef_ide && !rig_ide; - typedef boost::mpl::and_ LR_not_ide; + static inline constexpr bool bt_not_ide = !bot_ide && !top_ide; - typedef boost::mpl::and_ BT_not_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 afb6bff830e..06ff55945fe 100644 --- a/Homogeneous_kernel/include/CGAL/Homogeneous/PointH2.h +++ b/Homogeneous_kernel/include/CGAL/Homogeneous/PointH2.h @@ -53,8 +53,8 @@ public: 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 87da02cabff..f64d5b64c9a 100644 --- a/Homogeneous_kernel/include/CGAL/Homogeneous/PointH3.h +++ b/Homogeneous_kernel/include/CGAL/Homogeneous/PointH3.h @@ -52,9 +52,9 @@ public: 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 81cd3107595..92afeec7941 100644 --- a/Homogeneous_kernel/include/CGAL/Homogeneous/VectorH2.h +++ b/Homogeneous_kernel/include/CGAL/Homogeneous/VectorH2.h @@ -57,8 +57,8 @@ public: 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 5228d5251ad..aecd718d41a 100644 --- a/Homogeneous_kernel/include/CGAL/Homogeneous/VectorH3.h +++ b/Homogeneous_kernel/include/CGAL/Homogeneous/VectorH3.h @@ -67,9 +67,9 @@ public: 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 25ec0c4f25c..ef44403f9f5 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 6e6b496840e..67ea76e11fb 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 4eb0e890063..b3230858573 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 3f8a2812968..d15c11a73bd 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 4a562530c75..6b87205b501 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 @@ public: */ 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 1232e426aed..c83be87df90 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 @@ public: 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 9f5ac5a84cb..18a98dfa456 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 6630dd8ceb1..8d476da2036 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 bba12aa85a7..015c5f047c7 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 a96be0e6d76..52c14ea54b7 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 @@ public: 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 34a282b9162..617e8c23a8a 100644 --- a/Triangulation_2/include/CGAL/Delaunay_triangulation_2.h +++ b/Triangulation_2/include/CGAL/Delaunay_triangulation_2.h @@ -385,10 +385,8 @@ public: 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 c3ab2223a0a..d5d1a6c5917 100644 --- a/Triangulation_2/include/CGAL/Regular_triangulation_2.h +++ b/Triangulation_2/include/CGAL/Regular_triangulation_2.h @@ -528,10 +528,8 @@ public: 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 c79aa0128d2..14e8604640f 100644 --- a/Triangulation_2/include/CGAL/Triangulation_2.h +++ b/Triangulation_2/include/CGAL/Triangulation_2.h @@ -710,10 +710,8 @@ public: 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 8b22fddd349..63ade11b5e8 100644 --- a/Triangulation_3/include/CGAL/Delaunay_triangulation_3.h +++ b/Triangulation_3/include/CGAL/Delaunay_triangulation_3.h @@ -494,10 +494,8 @@ public: 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_ --- Arrangement_on_surface_2/include/CGAL/Arr_tags.h | 16 ++++++++-------- CGAL_ipelets/include/CGAL/CGAL_Ipelet_base_v6.h | 11 +++++------ CGAL_ipelets/include/CGAL/CGAL_Ipelet_base_v7.h | 11 +++++------ Filtered_kernel/include/CGAL/Lazy_kernel.h | 6 +++--- .../CGAL/NewKernel_d/Wrapper/Cartesian_wrap.h | 4 ++-- .../CGAL/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, 34 insertions(+), 38 deletions(-) diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_tags.h b/Arrangement_on_surface_2/include/CGAL/Arr_tags.h index 94ea503e244..384666f80fa 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 @@ private: 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; + static inline constexpr bool lef_obl_or_ope = Lef_obl::value || Lef_ope::value; + static inline constexpr bool rig_obl_or_ope = Rig_obl::value || Rig_ope::value; + static inline constexpr bool bot_obl_or_ope = Bot_obl::value || Bot_ope::value; + static inline constexpr bool top_obl_or_ope = Top_obl::value || Top_ope::value; - 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 48572f24118..9876131f47b 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 @@ public: 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 5373b0a3445..3dc51367d33 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 @@ public: 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 c6b6cb2444a..8f43a8a1af1 100644 --- a/Filtered_kernel/include/CGAL/Lazy_kernel.h +++ b/Filtered_kernel/include/CGAL/Lazy_kernel.h @@ -198,9 +198,9 @@ private: 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 9ddd7953e24..50d9a8c8b00 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 f32f9d907a9..a72d9ffaafc 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 59aae8a0307..c68386c7f76 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 015c5f047c7..7382ebabd66 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 384666f80fa..8f3c78095f4 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 @@ private: 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 f2e6a2f3ada..4296f179462 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 72198460181..4cd4d1c3af4 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 e6ff36dd0ce..a526ec5085d 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 ce61f49db7e..494878cca73 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 i in range(0,level): - res=" "+res - return res + res = "* [" + name + "](" + anchor + ")" + for _ in range(0, level): + res = " " + res + return res -#now the main -input = args.filename -f = codecs.open(input, 'r', encoding='utf-8') +# now the main +filename = args.filename + +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 | 78 ++++++++++--------- 1 file changed, 41 insertions(+), 37 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 494878cca73..928703c502e 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 @@ import sys 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() + # skip current TOC + line = f.readline() + while line and line.find("") == -1: + line = f.readline() -buffer = "" -TOC = "\n\n# Table of Contents\n" + if not line: + sys.exit() -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 = "" + 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 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 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 590305c0c8a..38d1bce078b 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 00000000000..1fc70906f7d --- /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 8641c30c6ca..02822cea9e7 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 1fc70906f7d..53d70af603f 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 a61edc699d0..d576df0e447 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 @@ private: } 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 @@ public: 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 a4144ceee65..d14f4be9666 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 @@ private: } 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 @@ public: 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 c1696428d75..30d201d1ef5 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 f13135cd873..c06f0568e68 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 @@ public: 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 6693524324a..145d5a24135 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 d576df0e447..5c3a99efef5 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 b22b21d817b..cee169048c3 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 94694034cdd..2bfae11f3b7 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 @@ public: // 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 2bfae11f3b7..8529af0b0f2 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 @@ private: 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 8529af0b0f2..d3d2beb6c6e 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 f7947f246a4..ec48b4f458b 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 @@ public: 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 c7e1fbdb21c..949fcc8dd64 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 d21d675eb2b..4418c6096d1 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 232164a1b95..d4d774d1105 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 aa7c2bd40ea..baaa0612452 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 8c7d009461b..194db942db7 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 be7b6166e4e..89825600510 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 09bc213068d..678597ad255 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 74a678ea062..ac8378781fe 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 bdcdba6b7fd..dc78152059b 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 f603925bb6b..072ec4c6360 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 93b158ce192..1a8b207cd6b 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 afbb938afb5..5cc9379992f 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 4e814c7dccd..ede5edf61e8 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 742685e7485..e043f6a9a77 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 23053a6766c..30f1ed16a14 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 e3924c3e095..381183d0c99 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 9f591e6a269..92aa3b15c6f 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 a7afc963ed7..28d770626e2 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 b731e8c0220..cf97918fd3b 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 7587d012363..9c7ef677bc0 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 9b246f7678d..84695b32e32 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 @@ public: }; -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 bd4181c3ff4..e07c803b83e 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 d3d2beb6c6e..5adf81dc443 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 @@ public: 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 d5d1a6c5917..3353b7d7603 100644 --- a/Triangulation_2/include/CGAL/Regular_triangulation_2.h +++ b/Triangulation_2/include/CGAL/Regular_triangulation_2.h @@ -528,8 +528,8 @@ public: 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 6aa1988e1cc..eba9ffdc721 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 a72d9ffaafc..a996edae648 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 ad298449b55..4fc641cc286 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 b4ff7de189c..18026962520 100644 --- a/Triangulation_3/include/CGAL/Regular_triangulation_3.h +++ b/Triangulation_3/include/CGAL/Regular_triangulation_3.h @@ -612,8 +612,8 @@ public: 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 b81befd7a56..fb74fa720e4 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 9f605978f7c..5b625f8042e 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 0ab43248e21..beddf4c0b3d 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 @@ public: 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 f09fffd0d4f..87669ceb91d 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 defc30a2079..8c3c7920ff7 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 f9546507bd4..b273ac3477b 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 00000000000..a045313f3f5 --- /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 383d1103778..ddc84bc5002 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 9b6af428e25..bb476ded1f2 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 b39ce5c01e7..dfa703b86f7 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 2042cff97b5..ad290801019 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 bb476ded1f2..ab23552b682 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 dfa703b86f7..ec352fb21dd 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 ab23552b682..73f6c672d15 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 73f6c672d15..55620fd2ed3 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 d0a77fa1a78..a2a2228f6f5 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 @@ private: 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 00000000000..08a25ad43b3 --- /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 55620fd2ed3..6bc98833dab 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 ec352fb21dd..9ad255befac 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 6bc98833dab..7848f55e94c 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 db6845db100..91390c759dd 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 293d791a47c..2c91a8ad5ef 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 eb9b98cbe59..f2e13399444 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 00000000000..9e07c831435 --- /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 9ad255befac..dc3ccdaf989 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 2c91a8ad5ef..eb52b781667 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 eb52b781667..cc0738a365b 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 fb74fa720e4..8436b51c64d 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 cc0738a365b..d86b470a260 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 5adf81dc443..727691a8021 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 @@ public: // 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 727691a8021..d6ca4fb356c 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 @@ public: // 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 b75f648be33..6056951eba9 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 a50aef4180b..c452186e1fa 100644 --- a/Polyhedron/demo/Polyhedron/CGAL_double_edit.cpp +++ b/Polyhedron/demo/Polyhedron/CGAL_double_edit.cpp @@ -9,13 +9,14 @@ public: : 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 @@ public: 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 c452186e1fa..9f6f4c9b5a2 100644 --- a/Polyhedron/demo/Polyhedron/CGAL_double_edit.cpp +++ b/Polyhedron/demo/Polyhedron/CGAL_double_edit.cpp @@ -9,18 +9,16 @@ public: : 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 a045313f3f5..0dfd38e71e1 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 | 10 +++++----- 1 file changed, 5 insertions(+), 5 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 9def2bb6cc1..afd8d6912ab 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 - continue - elif output_line == "Command terminated by signal 6": exit_code = 10 continue - elif output_line == "Command terminated by signal 8": + elif output_line == "Command terminated by signal 6": exit_code = 11 continue + elif output_line == "Command terminated by signal 8": + 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 abc82f15033..d48aef5bb1f 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 dfd31aadd84..8bc5a6c3ff6 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 032cca7e1d3..4cb187d96f2 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 e16202c69dd..51dfb109004 100644 --- a/Documentation/doc/biblio/cgal_manual.bib +++ b/Documentation/doc/biblio/cgal_manual.bib @@ -778,7 +778,7 @@ Teillaud" , 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 8b99c725a65..d656b5e75c5 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 8a8ebe925b3..133d06a3918 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 0500556f074..e7b717fd001 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 018dde26767..06b69b82469 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 b5c4c1da2ab..4448fd6bde7 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 00000000000..b5a10784e92 --- /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 d656b5e75c5..8b99c725a65 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 8b99c725a65..1c4c16c7591 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 133d06a3918..1f2cc574ca9 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 1f2cc574ca9..ae67f4ddde5 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 2e030be7f6d..8c27fa77cad 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 00000000000..ae439ee013a --- /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 e7b717fd001..f0400342db1 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 ae67f4ddde5..d0dbede067d 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 05875d4e6ca..a64a44fa331 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 f566ab1890f..09787f05dfd 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 be3dfe8f276..64e1db2ca60 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 @@ private: 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 d0dbede067d..b6688e22f09 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 b6688e22f09..d11d72973b6 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 ece342c321b..9aedf344d43 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 ece342c321b..8fc2baca0c3 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 14390abda0d..9fa7eaad0c3 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 be6ca11f069..5ac60201e26 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 5ac60201e26..0e6f9acb048 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 03171af70bc..48ca74ba265 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 48ca74ba265..33514d6f2de 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 ae439ee013a..c654a51cd6b 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 0e6f9acb048..2aa4e9b0bcb 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 2aa4e9b0bcb..2f4b6e75906 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 2f4b6e75906..6858672f19f 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 1dcb214fe39..61b0ed153b4 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 5c3a99efef5..e673ac9dfbb 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 02822cea9e7..e3c647510c9 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 192e66ddf64..04436239a40 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 9d993ee4779..c41b35ef5f8 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 e3c647510c9..b1216f3281e 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 04436239a40..a1c15f1826f 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 a1c15f1826f..f626a2881c1 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 d0f605834db..30498755698 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 f626a2881c1..2eb124c86a7 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\link PkgBGLIoFuncsVTP 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
Polygon SoupAny 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 be0f7ee02a9..7d11ad3d16a 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 c41b35ef5f8..0cacc80c631 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 30498755698..fd8f7accc45 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 2eb124c86a7..cfc647bf726 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 dd8215e67a1..1fe4a21a06f 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 @@ protected: 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 41d96180310..d720f763c57 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 d720f763c57..cd36570d27b 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 a44d47c8b6d..5baea1a3964 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 00ccfd382f6..6a658a5829f 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 146e1261ff4..c582dc76739 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 6a658a5829f..d52fd823cd4 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 e3ef90e9be0..ef2f124329b 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 09787f05dfd..9ea06ce7d4e 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 64e1db2ca60..f07a0a2d793 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 @@ private: 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 d25ea95fe90..bb81855edd5 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 8114a141aa7..a10c0e632bf 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 cfc647bf726..995c18794da 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 995c18794da..dddf1767316 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 dddf1767316..153d8ca086b 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 eebd53cd03f..886832d0508 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 5baea1a3964..a76e1254f6e 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 bb81855edd5..46f9ed9cbe7 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 353e5569d1f..3bf23fe0201 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 30d6190bdc8..928129705ae 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 46f9ed9cbe7..05d05637b16 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 2e680a744f8..8630788e787 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 5bd35941615..cff22686ae7 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 76daf4494ab..b1f3e763b07 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 72c00bd528e..ce968f49af6 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 9e60c5bfb29..b19f0ab2b38 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 f2b66d46ca0..af02d72a81b 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 da1177a7062..b729b0b4792 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 02a28d869a0..cdf89714c30 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 0bfc0891437..988c0230bae 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 0f30d0c10a5..e474020cc67 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 57c96a907d8..1f57a67524f 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 00000000000..0dce62b6a37 --- /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 8a47239c5aa..646e94e9468 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 baaa0612452..300d0182fdb 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 f2d93e83f01..21600e50bff 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 02b5e000a5e..f3c541ab65c 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 5373ac5e376..611be7e6c0b 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 c283a4652fe..270f53d3bda 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 37245edcd9d..43d7b5b291a 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 a50f2efc4da..cc73aa7493b 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 eaa971ce880..d6f68604517 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 365fc39d267..7d2f9500b5d 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 4bedf34619a..19105b1833b 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 1a6a2786c6d..6566b233e61 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 238a796eb03..5a898efb4df 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 bc2455499ad..dd62887970c 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 522ce16fb44..83f07c3d25d 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 05d05637b16..b2d8427875c 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 d9ea1a1cf37..248831b5051 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 a2ffe2c2539..8c848a2f106 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 9c908d7ec24..3af3402a5f2 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 590305c0c8a..5adc0de4597 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 00000000000..474af00a16c --- /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 6fdeda48ca4..ba917e03836 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 c654a51cd6b..8075bb003f1 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 0dce62b6a37..c2cdcbc52ee 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 474af00a16c..113845a9cb6 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 8b41ff2ecdb..b3aaf70604f 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 8075bb003f1..33c07c12ec4 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 b2d8427875c..c9751752d75 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 c9751752d75..ec3f02633c8 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 ec3f02633c8..8a61b92f717 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 cd36570d27b..88ff82a63f5 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 cc11bbabac3..d44a2bbdd34 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 00000000000..9cbff2ba95a --- /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 be3dfe8f276..8b2cbe40a6e 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 @@ public: 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 @@ public: #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 a024e6ccf8f..d2ae0552ae7 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 60cda75d7fd..93d9d322792 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 f0400342db1..a2e1c0fb136 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 06b69b82469..17d90d1f20d 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 4448fd6bde7..94981f0550b 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 113845a9cb6..fa60ae6538f 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 7ecf30255ba..08afc1a220a 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 33c07c12ec4..aa6ea4c1ba0 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 4e5d35a91d2..72d3e79168c 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 c2cdcbc52ee..b8b86d45f8f 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 d60af3c9949..84189cf7373 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 7d11ad3d16a..cc299f2540a 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 cc299f2540a..967ef41097f 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 967ef41097f..b868f7facb2 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 b868f7facb2..fb4d9fe8afa 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 928129705ae..959bc75c5c8 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 c9e6ba4f0ba..df85f0f3627 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 @@ public: 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 @@ public: \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 8630788e787..789d44921d5 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 08afc1a220a..7ecf30255ba 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 cff22686ae7..5bd35941615 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 b1f3e763b07..76daf4494ab 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 ce968f49af6..72c00bd528e 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 4cd4d1c3af4..a04664e8de6 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 @@ public: 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 @@ private: 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 a04664e8de6..61e13ee4bda 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 @@ public: 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 @@ private: 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 61e13ee4bda..885c6f53160 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 @@ private: { 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 d44a2bbdd34..dc7851f621d 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 885c6f53160..c74e2ca63e0 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 c74e2ca63e0..a2e13b81123 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 d44a2bbdd34..cc11bbabac3 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 | 434 +++++------------- .../test/Surface_sweep_2/test_sweep_conic.cpp | 279 +++++++++++ 15 files changed, 416 insertions(+), 376 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 9e96fa6dc1c..ac96a58ca42 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 1ff457efdb1..a3464614b95 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 c404b51caa1..f3ca4fd2817 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 599a66f9b14..6ed5fcbab23 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 eb6a5c18711..d9a9875cdeb 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 e68e06cb488..224bbc2397a 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 f82851db1c1..59ac8c5f663 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 e884bd40154..2b2253b5594 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 63063346910..54aae8118a0 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 6afc8ee809c..543d1cff813 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 d5f29cc3101..51c9e3ffb2a 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 7af88f99c7a..00000000000 --- 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 cc11bbabac3..97265afa626 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 - -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++) { - NT x, y; - inp >> skip_comment >> x >> y; - Point_2 p(x, y); - // std::cout << p << "\n"; - points.push_back(p); +int main(int argc, char* argv[]) { + if (argc != 2) { + std::cout << "Specify a file name " << std::endl; + return -1; } - return true; -} -#endif + 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()); + + 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 +bool read_points(std::ifstream& inp, Points& points, const Traits&) { + int count; + inp >> skip_comment >> count; + char ch; -// 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; + // 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; -} - -// 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 new file mode 100644 index 00000000000..45ae9544851 --- /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 97265afa626..326307f8461 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 1a0a9e34f35..d651bdcd61b 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 2edd7244422..e140c8a227c 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 31dcb337b98..b09c632555b 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 928703c502e..f9f58e4f5b5 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 2af501d48c0..6699629f7c2 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 3747a4a8313..4b183402d48 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 d8c7c1cd433..e4d8e66bd56 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 4b183402d48..8fd78fc5820 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 8fd78fc5820..02d4fb4a38f 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 744e4fed4ab..1e912131c12 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 02d4fb4a38f..37934a2fbcb 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 37934a2fbcb..edde28fff96 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 e4d8e66bd56..fdf62712b02 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 dc3ccdaf989..35ddb31e0c5 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 35ddb31e0c5..791ce36ac8c 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 00000000000..8f3c9cc5e3f --- /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 e484daaf5ea..5bf31aaa352 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 4f349c13acf..b4011300b50 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 41612d5b9fc..fd4eeeb7d65 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 8a61b92f717..a3606f816a7 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 c0da570e916..1171fabe614 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";