diff --git a/Algebraic_foundations/doc/Algebraic_foundations/PackageDescription.txt b/Algebraic_foundations/doc/Algebraic_foundations/PackageDescription.txt index caa1060d544..9e12449ab5b 100644 --- a/Algebraic_foundations/doc/Algebraic_foundations/PackageDescription.txt +++ b/Algebraic_foundations/doc/Algebraic_foundations/PackageDescription.txt @@ -5,7 +5,6 @@ /*! \addtogroup PkgAlgebraicFoundationsRef -\todo check generated documentation \cgalPkgDescriptionBegin{Algebraic Foundations,PkgAlgebraicFoundations} \cgalPkgPicture{Algebraic_foundations2.png} diff --git a/Algebraic_foundations/include/CGAL/number_utils.h b/Algebraic_foundations/include/CGAL/number_utils.h index 5a5bc2d242d..48d8fc48725 100644 --- a/Algebraic_foundations/include/CGAL/number_utils.h +++ b/Algebraic_foundations/include/CGAL/number_utils.h @@ -21,6 +21,7 @@ #include #include #include +#include namespace CGAL { CGAL_NTS_BEGIN_NAMESPACE diff --git a/Algebraic_kernel_d/doc/Algebraic_kernel_d/PackageDescription.txt b/Algebraic_kernel_d/doc/Algebraic_kernel_d/PackageDescription.txt index 4907d2a4192..b8107073f4a 100644 --- a/Algebraic_kernel_d/doc/Algebraic_kernel_d/PackageDescription.txt +++ b/Algebraic_kernel_d/doc/Algebraic_kernel_d/PackageDescription.txt @@ -16,7 +16,6 @@ /*! \addtogroup PkgAlgebraicKernelDRef -\todo check generated documentation \cgalPkgDescriptionBegin{Algebraic Kernel,PkgAlgebraicKernelD} \cgalPkgPicture{Algebraic_kernel_d.png} \cgalPkgSummaryBegin diff --git a/Alpha_shapes_2/include/CGAL/Alpha_shape_2.h b/Alpha_shapes_2/include/CGAL/Alpha_shape_2.h index 43be2407022..6df4b45c7b9 100644 --- a/Alpha_shapes_2/include/CGAL/Alpha_shape_2.h +++ b/Alpha_shapes_2/include/CGAL/Alpha_shape_2.h @@ -1442,7 +1442,7 @@ Alpha_shape_2::find_alpha_solid() const // takes O(#alpha_shape) time Type_of_alpha alpha_solid = 0; - if (number_of_vertices()<3) return alpha_solid; + if (dimension()!=2) return alpha_solid; Finite_vertices_iterator vertex_it; // only finite vertices 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 efaeb82d330..bcca1bd0143 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 @@ -97,7 +97,7 @@ template class Cell_base_with_timestamp : public Cb { - std::size_t time_stamp_; + std::size_t time_stamp_ = std::size_t(-2); public: using Has_timestamp = CGAL::Tag_true; @@ -112,7 +112,7 @@ public: public: template Cell_base_with_timestamp(const Args&... args) - : Cb(args...), time_stamp_(-1) + : Cb(args...) { } Cell_base_with_timestamp(const Cell_base_with_timestamp& other) diff --git a/Apollonius_graph_2/doc/Apollonius_graph_2/PackageDescription.txt b/Apollonius_graph_2/doc/Apollonius_graph_2/PackageDescription.txt index f82d98db1ed..102f019f68c 100644 --- a/Apollonius_graph_2/doc/Apollonius_graph_2/PackageDescription.txt +++ b/Apollonius_graph_2/doc/Apollonius_graph_2/PackageDescription.txt @@ -3,7 +3,6 @@ /// \ingroup PkgApolloniusGraph2Ref /*! \addtogroup PkgApolloniusGraph2Ref -\todo check generated documentation \cgalPkgDescriptionBegin{2D Apollonius Graphs (Delaunay Graphs of Disks),PkgApolloniusGraph2} \cgalPkgPicture{CircleVoronoi.png} \cgalPkgSummaryBegin diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2_earth/CMakeLists.txt b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2_earth/CMakeLists.txt index 332c3deada6..faf3db032af 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2_earth/CMakeLists.txt +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2_earth/CMakeLists.txt @@ -16,27 +16,24 @@ find_package(Qt6 QUIET COMPONENTS Core Gui OpenGL OpenGLWidgets Widgets Xml) find_package(CGAL COMPONENTS Qt6) find_package(nlohmann_json QUIET 3.9) -if (NOT CGAL_FOUND OR NOT CGAL_Qt6_FOUND OR NOT Qt6_FOUND OR NOT Boost_FOUND OR NOT nlohmann_json_FOUND) - if (NOT CGAL_FOUND) - set(MISSING_DEPS "the CGAL library, ${MISSING_DEPS}") - endif() - if (NOT CGAL_Qt6_FOUND) - set(MISSING_DEPS "the CGAL Qt6 component, ${MISSING_DEPS}") - endif() - if (NOT Qt6_FOUND) - set(MISSING_DEPS "the Qt6 library, ${MISSING_DEPS}") - endif() - if (NOT Boost_FOUND) - set(MISSING_DEPS "the Boost library, ${MISSING_DEPS}") - endif() - if (NOT nlohmann_json_FOUND) - set(MISSING_DEPS "JSON for Modern C++ 3.9+ (know as nlohmann_json), ${MISSING_DEPS}") - endif() - - message(STATUS "NOTICE: This project requires ${MISSING_DEPS} and will not be compiled.") - return() +set(MISSING_DEPS "") +if (NOT CGAL_FOUND) + set(MISSING_DEPS "the CGAL library, ${MISSING_DEPS}") +endif() +if (NOT CGAL_Qt6_FOUND) + set(MISSING_DEPS "the CGAL Qt6 component, ${MISSING_DEPS}") +endif() +if (NOT Qt6_FOUND) + set(MISSING_DEPS "the Qt6 library, ${MISSING_DEPS}") +endif() +if (NOT nlohmann_json_FOUND) + set(MISSING_DEPS "JSON for Modern C++ 3.9+ (know as nlohmann_json), ${MISSING_DEPS}") endif() +if (MISSING_DEPS) + message(STATUS "NOTICE: This project requires ${MISSING_DEPS}and will not be compiled.") + return() +endif() add_compile_definitions(QT_NO_VERSION_TAGGING) diff --git a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arrangement_on_surface_2.h b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arrangement_on_surface_2.h index d4c30698e16..a900bd3f6e7 100644 --- a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arrangement_on_surface_2.h +++ b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arrangement_on_surface_2.h @@ -973,6 +973,7 @@ public: * u_1\f$ to \f$ u_2\f$. * \pre `e1` and `e2` share a common end-vertex, such that the two other * end-vertices of the two edges are associated with `c`'s endpoints. + * \pre `e1` and `e2` have the same direction. */ Halfedge_handle merge_edge(Halfedge_handle e1, Halfedge_handle e2, diff --git a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/PackageDescription.txt b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/PackageDescription.txt index 300970a336e..62d1384f312 100644 --- a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/PackageDescription.txt +++ b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/PackageDescription.txt @@ -66,7 +66,6 @@ namespace ArrTraits {} /*! \addtogroup PkgArrangementOnSurface2Ref -\todo check generated documentation \cgalPkgDescriptionBegin{2D Arrangements,PkgArrangementOnSurface2} \cgalPkgPicture{Arrangement_2.png} \cgalPkgSummaryBegin diff --git a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/algebraic_curves.cpp b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/algebraic_curves.cpp index f8bc222897b..bb113edd04d 100644 --- a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/algebraic_curves.cpp +++ b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/algebraic_curves.cpp @@ -14,7 +14,6 @@ int main () #else -#include #include #include diff --git a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/algebraic_segments.cpp b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/algebraic_segments.cpp index aba48b9f222..1665af18e8f 100644 --- a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/algebraic_segments.cpp +++ b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/algebraic_segments.cpp @@ -14,7 +14,6 @@ int main () } #else -#include #include #include diff --git a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/batched_point_location.cpp b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/batched_point_location.cpp index a88e118f38c..1e4ff25b9af 100644 --- a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/batched_point_location.cpp +++ b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/batched_point_location.cpp @@ -4,7 +4,6 @@ #include #include -#include #include #include "arr_inexact_construction_segments.h" diff --git a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/bounded_vertical_decomposition.cpp b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/bounded_vertical_decomposition.cpp index 77137ced487..c7b0621eace 100644 --- a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/bounded_vertical_decomposition.cpp +++ b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/bounded_vertical_decomposition.cpp @@ -3,7 +3,6 @@ #include -#include #include #include "arr_exact_construction_segments.h" diff --git a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/conic_multiplicities.cpp b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/conic_multiplicities.cpp index 5eaccf5db9e..fdb8852661d 100644 --- a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/conic_multiplicities.cpp +++ b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/conic_multiplicities.cpp @@ -5,7 +5,6 @@ #ifdef CGAL_USE_CORE -#include #include #include "arr_conics.h" diff --git a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/consolidated_curve_data.cpp b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/consolidated_curve_data.cpp index 55ea5aada14..86a07143360 100644 --- a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/consolidated_curve_data.cpp +++ b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/consolidated_curve_data.cpp @@ -2,7 +2,6 @@ // Associating a color attribute with segments using the consolidated // curve-data traits. -#include #include #include "arr_exact_construction_segments.h" diff --git a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/curve_history.cpp b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/curve_history.cpp index 4a7b7a57bdb..06c2b6b3f8b 100644 --- a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/curve_history.cpp +++ b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/curve_history.cpp @@ -1,7 +1,6 @@ //! \file examples/Arrangement_on_surface_2/curve_history.cpp // Constructing an arrangement with curve history. -#include #include #include diff --git a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/dcel_extension.cpp b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/dcel_extension.cpp index 88140318fd2..63fec621829 100644 --- a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/dcel_extension.cpp +++ b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/dcel_extension.cpp @@ -1,7 +1,6 @@ //! \file examples/Arrangement_on_surface_2/dcel_extension.cpp // Extending all DCEL records (vertices, edges and faces). -#include #include #include "arr_exact_construction_segments.h" diff --git a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/dcel_extension_io.cpp b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/dcel_extension_io.cpp index 441e4f7b6ca..5dab64d1041 100644 --- a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/dcel_extension_io.cpp +++ b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/dcel_extension_io.cpp @@ -3,7 +3,6 @@ #include -#include #include #include #include diff --git a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/dual_with_data.cpp b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/dual_with_data.cpp index 8ffb6688971..996728bd717 100644 --- a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/dual_with_data.cpp +++ b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/dual_with_data.cpp @@ -4,7 +4,6 @@ #include -#include #include #include "arr_linear.h" diff --git a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/edge_manipulation_curve_history.cpp b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/edge_manipulation_curve_history.cpp index bf1d504d4f6..92f8d96c893 100644 --- a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/edge_manipulation_curve_history.cpp +++ b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/edge_manipulation_curve_history.cpp @@ -1,7 +1,6 @@ //! \file examples/Arrangement_on_surface_2/edge_manipulation_curve_history.cpp // Removing curves and manipulating edges in an arrangement with history. -#include #include #include diff --git a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/ellipses.cpp b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/ellipses.cpp index bc2403f2aeb..480b0eefe31 100644 --- a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/ellipses.cpp +++ b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/ellipses.cpp @@ -5,7 +5,6 @@ #ifdef CGAL_USE_CORE -#include #include #include "arr_conics.h" diff --git a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/face_extension.cpp b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/face_extension.cpp index d1bdaa8bb38..9850df520c4 100644 --- a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/face_extension.cpp +++ b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/face_extension.cpp @@ -1,7 +1,6 @@ //! \file examples/Arrangement_on_surface_2/face_extension.cpp // Extending the arrangement-face records. -#include #include #include diff --git a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/face_extension_overlay.cpp b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/face_extension_overlay.cpp index 27459e6ff9e..255e4473822 100644 --- a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/face_extension_overlay.cpp +++ b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/face_extension_overlay.cpp @@ -3,7 +3,6 @@ #include -#include #include #include diff --git a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/generic_curve_data.cpp b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/generic_curve_data.cpp index 72710580dee..55ac76ffb59 100644 --- a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/generic_curve_data.cpp +++ b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/generic_curve_data.cpp @@ -2,7 +2,6 @@ // Associating a name attribute with segments using the generic curve-data // traits. -#include #include #include "arr_polylines.h" diff --git a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/hyperbolas.cpp b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/hyperbolas.cpp index aa68c6c247f..8c165cac9f6 100644 --- a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/hyperbolas.cpp +++ b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/hyperbolas.cpp @@ -5,7 +5,6 @@ #ifdef CGAL_USE_CORE -#include #include #include "arr_conics.h" diff --git a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/incremental_insertion.cpp b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/incremental_insertion.cpp index 857a5ecdf01..a2d4c8e7f43 100644 --- a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/incremental_insertion.cpp +++ b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/incremental_insertion.cpp @@ -1,7 +1,6 @@ //! \file examples/Arrangement_on_surface_2/incremental_insertion.cpp // Using the global incremental insertion functions. -#include #include #include "arr_exact_construction_segments.h" diff --git a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/io.cpp b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/io.cpp index 4e38086f3ab..05f95776038 100644 --- a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/io.cpp +++ b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/io.cpp @@ -3,7 +3,6 @@ #include -#include #include #include "arr_inexact_construction_segments.h" diff --git a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/io_curve_history.cpp b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/io_curve_history.cpp index b62c6a93ff9..6a37fd24094 100644 --- a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/io_curve_history.cpp +++ b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/io_curve_history.cpp @@ -3,7 +3,6 @@ #include -#include #include #include diff --git a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/io_unbounded.cpp b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/io_unbounded.cpp index 5cf95522f18..1cb4d2161a8 100644 --- a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/io_unbounded.cpp +++ b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/io_unbounded.cpp @@ -4,7 +4,6 @@ #include #include -#include #include #include "arr_linear.h" diff --git a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/linear_conics.cpp b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/linear_conics.cpp index b0f990e0ee9..071c118052e 100644 --- a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/linear_conics.cpp +++ b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/linear_conics.cpp @@ -5,7 +5,6 @@ #ifdef CGAL_USE_CORE -#include #include #include "arr_conics.h" diff --git a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/observer.cpp b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/observer.cpp index d4261d64dd2..88bbd31b83a 100644 --- a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/observer.cpp +++ b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/observer.cpp @@ -1,7 +1,6 @@ //! \file examples/Arrangement_on_surface_2/observer.cpp // Using a simple arrangement observer. -#include #include #include "arr_exact_construction_segments.h" diff --git a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/overlay.cpp b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/overlay.cpp index 4f2fa8a38dd..30b0fd90a23 100644 --- a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/overlay.cpp +++ b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/overlay.cpp @@ -1,7 +1,6 @@ //! \file examples/Arrangement_on_surface_2/overlay.cpp // A simple overlay of two arrangements. -#include #include #include "arr_exact_construction_segments.h" diff --git a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/overlay_color.cpp b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/overlay_color.cpp index 42c7f69aaff..1009abe7d95 100644 --- a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/overlay_color.cpp +++ b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/overlay_color.cpp @@ -3,7 +3,6 @@ #include -#include #include #include #include diff --git a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/overlay_unbounded.cpp b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/overlay_unbounded.cpp index 40d06f4f712..fd49d0fa95a 100644 --- a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/overlay_unbounded.cpp +++ b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/overlay_unbounded.cpp @@ -3,7 +3,6 @@ #include -#include #include #include #include diff --git a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/parabolas.cpp b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/parabolas.cpp index 2f3bf04bf61..7213b06f095 100644 --- a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/parabolas.cpp +++ b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/parabolas.cpp @@ -5,7 +5,6 @@ #ifdef CGAL_USE_CORE -#include #include #include "arr_conics.h" diff --git a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/point_location.cpp b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/point_location.cpp index 8f9c0458d55..10fbb71ab83 100644 --- a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/point_location.cpp +++ b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/point_location.cpp @@ -1,7 +1,6 @@ //! \file examples/Arrangement_on_surface_2/point_location.cpp // Answering point-location queries. -#include #include #include diff --git a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/polycurve_bezier.cpp b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/polycurve_bezier.cpp index 309a849e64b..25c74a71836 100644 --- a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/polycurve_bezier.cpp +++ b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/polycurve_bezier.cpp @@ -13,7 +13,6 @@ int main() { #else -#include #include #include "arr_Bezier.h" diff --git a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/polycurve_circular_arc.cpp b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/polycurve_circular_arc.cpp index 742473a79bf..46432532c00 100644 --- a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/polycurve_circular_arc.cpp +++ b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/polycurve_circular_arc.cpp @@ -15,7 +15,6 @@ int main() { #include -#include #include #include diff --git a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/polycurve_conic.cpp b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/polycurve_conic.cpp index bdaafb9ebb0..7910a723c46 100644 --- a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/polycurve_conic.cpp +++ b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/polycurve_conic.cpp @@ -15,7 +15,6 @@ int main() { #include -#include #include #include "arr_conics.h" diff --git a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/predefined_kernel.cpp b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/predefined_kernel.cpp index f0ed969d845..d238706a0df 100644 --- a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/predefined_kernel.cpp +++ b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/predefined_kernel.cpp @@ -5,8 +5,6 @@ #include #include -#include - #include "arr_exact_construction_segments.h" #include "arr_print.h" #include "read_objects.h" diff --git a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/spherical_overlay.cpp b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/spherical_overlay.cpp index ba27599b22d..e43b1df9ab8 100644 --- a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/spherical_overlay.cpp +++ b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/spherical_overlay.cpp @@ -1,7 +1,6 @@ //! \file examples/Arrangement_on_surface_2/spherical_overlay.cpp // Overlay of two arrangements embedded on the sphere. -#include #include #include diff --git a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/tracing_counting.cpp b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/tracing_counting.cpp index df5715628f7..1f2a4407b16 100644 --- a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/tracing_counting.cpp +++ b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/tracing_counting.cpp @@ -3,7 +3,6 @@ #include -#include #include #include diff --git a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/unb_planar_vertical_decomposition.cpp b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/unb_planar_vertical_decomposition.cpp index e870a714ccc..50ac2b19f3e 100644 --- a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/unb_planar_vertical_decomposition.cpp +++ b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/unb_planar_vertical_decomposition.cpp @@ -3,7 +3,6 @@ #include -#include #include #include "arr_linear.h" diff --git a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/vertical_ray_shooting.cpp b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/vertical_ray_shooting.cpp index e4e415bd825..c1e80f97c82 100644 --- a/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/vertical_ray_shooting.cpp +++ b/Arrangement_on_surface_2/examples/Arrangement_on_surface_2/vertical_ray_shooting.cpp @@ -1,7 +1,6 @@ //! \file examples/Arrangement_on_surface_2/ex_vertical_ray_shooting.cpp // Answering vertical ray-shooting queries. -#include #include #include diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_counting_traits_2.h b/Arrangement_on_surface_2/include/CGAL/Arr_counting_traits_2.h index 51949d4546e..1e622f83d34 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_counting_traits_2.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_counting_traits_2.h @@ -411,7 +411,7 @@ public: m_object(base.construct_opposite_2_object()), m_counter(counter) {} /*! operates */ - X_monotone_curve_2 operator()(const X_monotone_curve_2& xc) + X_monotone_curve_2 operator()(const X_monotone_curve_2& xc) const { ++m_counter; return m_object(xc); } }; @@ -429,7 +429,7 @@ public: m_object(base.compare_endpoints_xy_2_object()), m_counter(counter) {} /*! operates */ - Comparison_result operator()(const X_monotone_curve_2& xc) + Comparison_result operator()(const X_monotone_curve_2& xc) const { ++m_counter; return m_object(xc); } }; diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_dcel_base.h b/Arrangement_on_surface_2/include/CGAL/Arr_dcel_base.h index f38156da2af..0e986fc78bb 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_dcel_base.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_dcel_base.h @@ -40,24 +40,24 @@ namespace CGAL { inline void* _clean_pointer(const void* p) { - static_assert(sizeof(void*) == sizeof(size_t)); - const size_t mask = ~1; - const size_t val = (reinterpret_cast(p) & mask); + static_assert(sizeof(void*) == sizeof(std::size_t)); + const std::size_t mask = ~1; + const std::size_t val = (reinterpret_cast(p) & mask); return (reinterpret_cast(val)); } inline void* _set_lsb(const void* p) { - const size_t mask = 1; - const size_t val = (reinterpret_cast(p) | mask); + const std::size_t mask = 1; + const std::size_t val = (reinterpret_cast(p) | mask); return (reinterpret_cast( val)); } inline bool _is_lsb_set(const void* p) { - const size_t mask = 1; - const size_t val = reinterpret_cast(p); + const std::size_t mask = 1; + const std::size_t val = reinterpret_cast(p); return ((val & mask) != 0); } @@ -565,7 +565,7 @@ public: Outer_ccb_const_iterator; /*! obtains the number of outer CCBs the face has. */ - size_t number_of_outer_ccbs() const { return (this->outer_ccbs.size()); } + std::size_t number_of_outer_ccbs() const { return (this->outer_ccbs.size()); } /*! obtains an iterator for the first outer CCB of the face. */ Outer_ccb_iterator outer_ccbs_begin() { return (this->outer_ccbs.begin()); } @@ -601,7 +601,7 @@ public: typedef Inner_ccb_const_iterator Hole_const_iterator; /*! obtains the number of inner CCBs the face has. */ - size_t number_of_inner_ccbs() const { return (this->inner_ccbs.size()); } + std::size_t number_of_inner_ccbs() const { return (this->inner_ccbs.size()); } /*! obtains an iterator for the first inner CCB of the face. */ Inner_ccb_iterator inner_ccbs_begin() { return (this->inner_ccbs.begin()); } @@ -646,7 +646,7 @@ public: } // Backward compatibility: - size_t number_of_holes() const { return number_of_inner_ccbs(); } + std::size_t number_of_holes() const { return number_of_inner_ccbs(); } Hole_iterator holes_begin() { return inner_ccbs_begin(); } Hole_iterator holes_end() { return inner_ccbs_end(); } Hole_const_iterator holes_begin() const { return inner_ccbs_begin(); } @@ -669,7 +669,7 @@ public: Isolated_vertex_const_iterator; /*! obtains the number of isloated vertices inside the face. */ - size_t number_of_isolated_vertices() const + std::size_t number_of_isolated_vertices() const { return (this->iso_verts.size()); } /*! obtains an iterator for the first isloated vertex inside the face. */ @@ -986,13 +986,13 @@ protected: typedef In_place_list Inner_ccb_list; typedef In_place_list Iso_vert_list; - typedef std::allocator_traits Allocator_traits; - typedef typename Allocator_traits::template rebind_alloc Vertex_allocator; - typedef typename Allocator_traits::template rebind_alloc Halfedge_allocator; - typedef typename Allocator_traits::template rebind_alloc Face_allocator; - typedef typename Allocator_traits::template rebind_alloc Outer_ccb_allocator; - typedef typename Allocator_traits::template rebind_alloc Inner_ccb_allocator; - typedef typename Allocator_traits::template rebind_alloc Iso_vert_allocator; + typedef std::allocator_traits Allocator_traits; + typedef typename Allocator_traits::template rebind_alloc Vertex_allocator; + typedef typename Allocator_traits::template rebind_alloc Halfedge_allocator; + typedef typename Allocator_traits::template rebind_alloc Face_allocator; + typedef typename Allocator_traits::template rebind_alloc Outer_ccb_allocator; + typedef typename Allocator_traits::template rebind_alloc Inner_ccb_allocator; + typedef typename Allocator_traits::template rebind_alloc Iso_vert_allocator; public: typedef typename Halfedge_list::size_type Size; @@ -1002,7 +1002,6 @@ public: typedef std::bidirectional_iterator_tag iterator_category; protected: - Vertex_list vertices; // The vertices container. Halfedge_list halfedges; // The halfedges container. Face_list faces; // The faces container. diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_extended_dcel.h b/Arrangement_on_surface_2/include/CGAL/Arr_extended_dcel.h index da68eb331be..0f9b28f3cdd 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_extended_dcel.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_extended_dcel.h @@ -61,8 +61,10 @@ public: template struct rebind { - using Point_2 = Point_; - using other = typename Vertex_base::template rebind; + using Pnt = Point_; + using Rebind_vertex_base = typename Vertex_base::template rebind; + using Other_vertex_base = typename Rebind_vertex_base::other; + using other = Arr_extended_vertex; }; }; @@ -101,8 +103,10 @@ public: template struct rebind { - using X_monotonote_curve_2 = XMonotoneCurve; - using other = typename Halfedge_base::template rebind; + using Xcv = XMonotoneCurve; + using Rebind_halfedge_base = typename Halfedge_base::template rebind; + using Other_halfedge_base = typename Rebind_halfedge_base::other; + using other = Arr_extended_halfedge; }; }; diff --git a/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_basic_insertion_traits_2.h b/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_basic_insertion_traits_2.h index e1accd10731..b6090350941 100644 --- a/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_basic_insertion_traits_2.h +++ b/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_basic_insertion_traits_2.h @@ -251,7 +251,7 @@ public: // vertex to the extended point. if (! vh->is_at_open_boundary() && m_base_equal(base_p, vh->point())) return (Point_2(base_p, vh)); - else return (Point_2(base_p)); + return (Point_2(base_p)); } }; @@ -308,7 +308,7 @@ public: // vertex to the extended point. if (! vh->is_at_open_boundary() && m_base_equal(base_p, vh->point())) return (Point_2(base_p, vh)); - else return (Point_2(base_p)); + return (Point_2(base_p)); } }; diff --git a/BGL/doc/BGL/BGL.txt b/BGL/doc/BGL/BGL.txt index 96be1186c66..c4db7311c6d 100644 --- a/BGL/doc/BGL/BGL.txt +++ b/BGL/doc/BGL/BGL.txt @@ -88,7 +88,7 @@ boost::graph_traits::edge_iterator ei; Algorithms obtain incidence information in graphs with the help of global functions such as: - `std::pair vertices(const Graph& g);` to obtain an iterator range providing access to all the vertices, or -- `int num_vertices(const Graph&);` to obtain the number of vertices of a graph, or +- `vertices_size_type num_vertices(const Graph&);` to obtain the number of vertices of a graph, or - `vertex_descriptor source(edge_descriptor, const Graph&);` to obtain the source vertex of an edge. Note, that the way we have written the types is a simplification; in reality, diff --git a/BGL/doc/BGL/Concepts/FaceListGraph.h b/BGL/doc/BGL/Concepts/FaceListGraph.h index 40339f34e8f..0010e2c78e2 100644 --- a/BGL/doc/BGL/Concepts/FaceListGraph.h +++ b/BGL/doc/BGL/Concepts/FaceListGraph.h @@ -40,6 +40,6 @@ faces(const FaceListGraph& g); This is the case for implementations only marking faces deleted in the face container. */ template -boost::graph_traits::face_size_type +boost::graph_traits::faces_size_type num_faces(const FaceListGraph& g); diff --git a/BGL/doc/BGL/Concepts/HalfedgeListGraph.h b/BGL/doc/BGL/Concepts/HalfedgeListGraph.h index a709aadaa8b..d66abfdaaed 100644 --- a/BGL/doc/BGL/Concepts/HalfedgeListGraph.h +++ b/BGL/doc/BGL/Concepts/HalfedgeListGraph.h @@ -40,6 +40,6 @@ halfedges(const HalfedgeListGraph& g); This is the case for implementations only marking halfedges deleted in the halfedge container. */ template -boost::graph_traits::halfedge_size_type +boost::graph_traits::halfedges_size_type num_halfedges(const HalfedgeListGraph& g); diff --git a/BGL/doc/BGL/PackageDescription.txt b/BGL/doc/BGL/PackageDescription.txt index e058589c3bf..39d72cd330d 100644 --- a/BGL/doc/BGL/PackageDescription.txt +++ b/BGL/doc/BGL/PackageDescription.txt @@ -741,6 +741,7 @@ user might encounter. - `CGAL::Euler::join_vertex()` - `CGAL::Euler::make_hole()` - `CGAL::Euler::remove_center_vertex()` +- `CGAL::Euler::remove_degree_2_vertex()` - `CGAL::Euler::remove_face()` - `CGAL::Euler::split_edge()` - `CGAL::Euler::split_face()` diff --git a/BGL/examples/BGL_LCC/distance_lcc.cpp b/BGL/examples/BGL_LCC/distance_lcc.cpp index b19f0ab2b38..7baf0883ff4 100644 --- a/BGL/examples/BGL_LCC/distance_lcc.cpp +++ b/BGL/examples/BGL_LCC/distance_lcc.cpp @@ -28,7 +28,7 @@ int main(int argc, char** argv) // Here we start at an arbitrary vertex // Any other vertex could be the starting point vertex_iterator vb, ve; - boost::tie(vb,ve)=vertices(lcc); + std::tie(vb,ve)=vertices(lcc); vertex_descriptor vd = *vb; std::cout << "We compute distances to " << vd->point() << std::endl; @@ -45,7 +45,7 @@ int main(int argc, char** argv) boost::on_tree_edge())))); // Traverse all vertices and show at what distance they are - for(boost::tie(vb,ve)=vertices(lcc); vb!=ve; ++vb) + for(std::tie(vb,ve)=vertices(lcc); vb!=ve; ++vb) { vd = *vb; std::cout<point()<<" is "<id()]<<" hops away."<point() << "\n"; } diff --git a/BGL/examples/BGL_LCC/normals_lcc.cpp b/BGL/examples/BGL_LCC/normals_lcc.cpp index b729b0b4792..b91f302563b 100644 --- a/BGL/examples/BGL_LCC/normals_lcc.cpp +++ b/BGL/examples/BGL_LCC/normals_lcc.cpp @@ -31,7 +31,7 @@ void calculate_face_normals(const HalfedgeGraph& g, typedef typename boost::property_traits::value_type normal; face_iterator fb, fe; - for(boost::tie(fb, fe) = faces(g); fb != fe; ++fb) + for(std::tie(fb, fe) = faces(g); fb != fe; ++fb) { halfedge_descriptor edg = halfedge(*fb, g); halfedge_descriptor edgb = edg; diff --git a/BGL/examples/BGL_LCC/range_lcc.cpp b/BGL/examples/BGL_LCC/range_lcc.cpp index cdf89714c30..e6aca96a397 100644 --- a/BGL/examples/BGL_LCC/range_lcc.cpp +++ b/BGL/examples/BGL_LCC/range_lcc.cpp @@ -42,10 +42,10 @@ void fct(const LCC& lcc) std::cout << vd->point() << std::endl; } - std::cout << "boost::tie + std::for_each" << std::endl; + std::cout << "std::tie + std::for_each" << std::endl; vertex_iterator vb, ve; - boost::tie(vb,ve) = vertices_range(lcc); + std::tie(vb,ve) = vertices_range(lcc); std::for_each(vb,ve, Fct()); } diff --git a/BGL/examples/BGL_LCC/transform_iterator_lcc.cpp b/BGL/examples/BGL_LCC/transform_iterator_lcc.cpp index 988c0230bae..06153ecf2ce 100644 --- a/BGL/examples/BGL_LCC/transform_iterator_lcc.cpp +++ b/BGL/examples/BGL_LCC/transform_iterator_lcc.cpp @@ -49,7 +49,7 @@ int main(int argc, char** argv) typedef boost::transform_iterator,halfedge_around_target_iterator> adjacent_vertex_iterator; halfedge_around_target_iterator hb,he; - boost::tie(hb,he) = halfedges_around_target(halfedge(vd,lcc),lcc); + std::tie(hb,he) = halfedges_around_target(halfedge(vd,lcc),lcc); adjacent_vertex_iterator avib, avie; avib = boost::make_transform_iterator(hb, Source(lcc)); avie = boost::make_transform_iterator(he, Source(lcc)); diff --git a/BGL/examples/BGL_polyhedron_3/distance.cpp b/BGL/examples/BGL_polyhedron_3/distance.cpp index 4a289af9760..9547d9b6606 100644 --- a/BGL/examples/BGL_polyhedron_3/distance.cpp +++ b/BGL/examples/BGL_polyhedron_3/distance.cpp @@ -24,9 +24,9 @@ int main(int argc, char** argv) { vertex_iterator vb, ve; int index = 0; - // boost::tie assigns the first and second element of the std::pair + // std::tie assigns the first and second element of the std::pair // returned by boost::vertices to the variables vit and ve - for(boost::tie(vb,ve)=vertices(P); vb!=ve; ++vb ){ + for(std::tie(vb,ve)=vertices(P); vb!=ve; ++vb ){ vertex_descriptor vd = *vb; vd->id() = index++; } @@ -37,7 +37,7 @@ int main(int argc, char** argv) { // Here we start at an arbitrary vertex // Any other vertex could be the starting point - boost::tie(vb,ve)=vertices(P); + std::tie(vb,ve)=vertices(P); vertex_descriptor vd = *vb; std::cout << "We compute distances to " << vd->point() << std::endl; @@ -54,7 +54,7 @@ int main(int argc, char** argv) { // Traverse all vertices and show at what distance they are - for(boost::tie(vb,ve)=vertices(P); vb!=ve; ++vb ){ + for(std::tie(vb,ve)=vertices(P); vb!=ve; ++vb ){ vd = *vb; std::cout << vd->point() << " is " << distance[vd->id()] << " hops away" << std::endl; } diff --git a/BGL/examples/BGL_polyhedron_3/incident_vertices.cpp b/BGL/examples/BGL_polyhedron_3/incident_vertices.cpp index b951c472d14..464bd9ecbb5 100644 --- a/BGL/examples/BGL_polyhedron_3/incident_vertices.cpp +++ b/BGL/examples/BGL_polyhedron_3/incident_vertices.cpp @@ -36,7 +36,7 @@ adjacent_vertices_V2(const Polyhedron& g, { halfedge_around_target_iterator hi, he; - for(boost::tie(hi, he) = halfedges_around_target(halfedge(vd,g),g); hi != he; ++hi) + for(std::tie(hi, he) = halfedges_around_target(halfedge(vd,g),g); hi != he; ++hi) { *out++ = source(*hi,g); } diff --git a/BGL/examples/BGL_polyhedron_3/kruskal.cpp b/BGL/examples/BGL_polyhedron_3/kruskal.cpp index 64371997377..36b3c625605 100644 --- a/BGL/examples/BGL_polyhedron_3/kruskal.cpp +++ b/BGL/examples/BGL_polyhedron_3/kruskal.cpp @@ -33,9 +33,9 @@ kruskal(const Polyhedron& P) vertex_iterator vb, ve; int index = 0; - // boost::tie assigns the first and second element of the std::pair + // std::tie assigns the first and second element of the std::pair // returned by boost::vertices to the variables vb and ve - for(boost::tie(vb, ve)=vertices(P); vb!=ve; ++vb){ + for(std::tie(vb, ve)=vertices(P); vb!=ve; ++vb){ vertex_index_pmap[*vb]= index++; } @@ -59,7 +59,7 @@ kruskal(const Polyhedron& P) " coord Coordinate {\n" " point [ \n"; - for(boost::tie(vb, ve) = vertices(P); vb!=ve; ++vb){ + for(std::tie(vb, ve) = vertices(P); vb!=ve; ++vb){ std::cout << " " << (*vb)->point() << "\n"; } diff --git a/BGL/examples/BGL_polyhedron_3/kruskal_with_stored_id.cpp b/BGL/examples/BGL_polyhedron_3/kruskal_with_stored_id.cpp index a1280a1b479..1b8d467255c 100644 --- a/BGL/examples/BGL_polyhedron_3/kruskal_with_stored_id.cpp +++ b/BGL/examples/BGL_polyhedron_3/kruskal_with_stored_id.cpp @@ -41,7 +41,7 @@ kruskal( const Polyhedron& P) "point [ \n"; vertex_iterator vb, ve; - for(boost::tie(vb,ve) = vertices(P); vb!=ve; ++vb){ + for(std::tie(vb,ve) = vertices(P); vb!=ve; ++vb){ std::cout << (*vb)->point() << "\n"; } @@ -75,9 +75,9 @@ int main() { vertex_iterator vb, ve; int index = 0; - // boost::tie assigns the first and second element of the std::pair + // std::tie assigns the first and second element of the std::pair // returned by boost::vertices to the variables vit and ve - for(boost::tie(vb,ve)=vertices(P); vb!=ve; ++vb ){ + for(std::tie(vb,ve)=vertices(P); vb!=ve; ++vb ){ vertex_descriptor vd = *vb; vd->id() = index++; } diff --git a/BGL/examples/BGL_polyhedron_3/normals.cpp b/BGL/examples/BGL_polyhedron_3/normals.cpp index 711800cb8ab..d6ed605de84 100644 --- a/BGL/examples/BGL_polyhedron_3/normals.cpp +++ b/BGL/examples/BGL_polyhedron_3/normals.cpp @@ -26,7 +26,7 @@ void calculate_face_normals(const HalfedgeGraph& g, typedef typename boost::property_traits::value_type normal; face_iterator fb, fe; - for(boost::tie(fb, fe) = faces(g); fb != fe; ++fb) + for(std::tie(fb, fe) = faces(g); fb != fe; ++fb) { halfedge_descriptor edg = halfedge(*fb, g); halfedge_descriptor edgb = edg; diff --git a/BGL/examples/BGL_polyhedron_3/range.cpp b/BGL/examples/BGL_polyhedron_3/range.cpp index bf54640120f..fcf325cba3b 100644 --- a/BGL/examples/BGL_polyhedron_3/range.cpp +++ b/BGL/examples/BGL_polyhedron_3/range.cpp @@ -40,10 +40,10 @@ void fct(const Polyhedron& p) std::cout << vd->point() << std::endl; } - std::cout << "boost::tie + std::for_each" << std::endl; + std::cout << "std::tie + std::for_each" << std::endl; vertex_iterator vb, ve; - boost::tie(vb,ve) = vertices_range(p); + std::tie(vb,ve) = vertices_range(p); std::for_each(vb,ve, Fct()); } diff --git a/BGL/examples/BGL_polyhedron_3/transform_iterator.cpp b/BGL/examples/BGL_polyhedron_3/transform_iterator.cpp index 5642ab08d6a..3ff09778fe1 100644 --- a/BGL/examples/BGL_polyhedron_3/transform_iterator.cpp +++ b/BGL/examples/BGL_polyhedron_3/transform_iterator.cpp @@ -47,7 +47,7 @@ int main(int argc, char** argv) typedef boost::transform_iterator,halfedge_around_target_iterator> adjacent_vertex_iterator; halfedge_around_target_iterator hb,he; - boost::tie(hb,he) = halfedges_around_target(halfedge(vd,P),P); + std::tie(hb,he) = halfedges_around_target(halfedge(vd,P),P); adjacent_vertex_iterator avib, avie; avib = boost::make_transform_iterator(hb, Source(P)); avie = boost::make_transform_iterator(he, Source(P)); diff --git a/BGL/examples/BGL_surface_mesh/surface_mesh_partition.cpp b/BGL/examples/BGL_surface_mesh/surface_mesh_partition.cpp index 1f57a67524f..58704355d62 100644 --- a/BGL/examples/BGL_surface_mesh/surface_mesh_partition.cpp +++ b/BGL/examples/BGL_surface_mesh/surface_mesh_partition.cpp @@ -51,7 +51,7 @@ int main(int argc, char** argv) std::ofstream outxyz("out.xyz"); outxyz.precision(17); boost::graph_traits::vertex_iterator vit, ve; - boost::tie(vit, ve) = vertices(sm); + std::tie(vit, ve) = vertices(sm); for(; vit!=ve; ++vit) { if(get(vertex_pid_map, *vit) == 0) diff --git a/BGL/include/CGAL/boost/graph/Dual.h b/BGL/include/CGAL/boost/graph/Dual.h index 4ca45b9bcec..59156f7232d 100644 --- a/BGL/include/CGAL/boost/graph/Dual.h +++ b/BGL/include/CGAL/boost/graph/Dual.h @@ -306,7 +306,7 @@ edge(typename boost::graph_traits >::vertex_descriptor u, const Dual

& dual) { typename boost::graph_traits >::out_edge_iterator e, e_end; - for(boost::tie(e, e_end) = out_edges(u, dual); e != e_end; ++e) { + for(std::tie(e, e_end) = out_edges(u, dual); e != e_end; ++e) { if(target(*e, dual) == v) return std::make_pair(*e, true); } @@ -391,7 +391,7 @@ halfedge(typename boost::graph_traits >::vertex_descriptor u, const Dual

& dual) { typename boost::graph_traits >::out_edge_iterator e, e_end; - for(boost::tie(e, e_end) = out_edges(u, dual); e != e_end; ++e) { + for(std::tie(e, e_end) = out_edges(u, dual); e != e_end; ++e) { if(target(*e, dual) == v) return std::make_pair(halfedge(*e, dual), true); } diff --git a/BGL/include/CGAL/boost/graph/Euler_operations.h b/BGL/include/CGAL/boost/graph/Euler_operations.h index f8c79165bc5..ece862d5dc7 100644 --- a/BGL/include/CGAL/boost/graph/Euler_operations.h +++ b/BGL/include/CGAL/boost/graph/Euler_operations.h @@ -12,10 +12,6 @@ #ifndef CGAL_EULER_OPERATIONS_H #define CGAL_EULER_OPERATIONS_H -#include -#include -#include - #include #include @@ -27,6 +23,10 @@ #include +#include +#include +#include + namespace CGAL { /// \cond SKIP_IN_MANUAL @@ -136,7 +136,7 @@ join_vertex(typename boost::graph_traits::halfedge_descriptor h, CGAL_assertion( halfedge(v_to_remove, v, g).first == h ); halfedge_around_vertex_iterator ieb, iee; - for(boost::tie(ieb, iee) = halfedges_around_target(hop, g); ieb != iee; ++ieb) { + for(std::tie(ieb, iee) = halfedges_around_target(hop, g); ieb != iee; ++ieb) { CGAL_assertion( target(*ieb,g) == v_to_remove); set_target(*ieb ,v , g); } @@ -615,7 +615,7 @@ bool can_add_face(const VertexRange& vrange, const PMesh& sm) for(std::size_t i=0; i < N; ++i){ halfedge_descriptor hd; bool found; - boost::tie(hd,found) = halfedge(face[i],face[i+1],sm); + std::tie(hd,found) = halfedge(face[i],face[i+1],sm); if(found && (! is_border(hd,sm))){ return false; } @@ -1149,7 +1149,7 @@ void make_hole(typename boost::graph_traits::halfedge_descriptor h, face_descriptor fd = face(h, g); halfedge_around_face_iterator hafib, hafie; - for(boost::tie(hafib, hafie) = halfedges_around_face(h, g); + for(std::tie(hafib, hafie) = halfedges_around_face(h, g); hafib != hafie; ++hafib){ CGAL_assertion(! is_border(opposite(*hafib,g),g)); @@ -1361,7 +1361,7 @@ add_vertex_and_face_to_border(typename boost::graph_traits::halfedge_desc internal::set_border(he2,g); CGAL::Halfedge_around_face_iterator hafib,hafie; - for(boost::tie(hafib, hafie) = halfedges_around_face(ohe1, g); + for(std::tie(hafib, hafie) = halfedges_around_face(ohe1, g); hafib != hafie; ++hafib){ set_face(*hafib, f, g); @@ -1421,7 +1421,7 @@ add_face_to_border(typename boost::graph_traits::halfedge_descriptor h1, internal::set_border(newhop, g); CGAL::Halfedge_around_face_iterator hafib,hafie; - for(boost::tie(hafib, hafie) = halfedges_around_face(newh, g); + for(std::tie(hafib, hafie) = halfedges_around_face(newh, g); hafib != hafie; ++hafib){ set_face(*hafib, f, g); @@ -1458,7 +1458,7 @@ does_satisfy_link_condition(typename boost::graph_traits::edge_descriptor // The following loop checks the link condition for v0_v1. // Specifically, that for every vertex 'k' adjacent to both 'p and 'q', 'pkq' is a face of the mesh. // - for ( boost::tie(eb1,ee1) = halfedges_around_source(v0,g) ; eb1 != ee1 ; ++ eb1 ) + for ( std::tie(eb1,ee1) = halfedges_around_source(v0,g) ; eb1 != ee1 ; ++ eb1 ) { halfedge_descriptor v0_k = *eb1; @@ -1466,7 +1466,7 @@ does_satisfy_link_condition(typename boost::graph_traits::edge_descriptor { vertex_descriptor k = target(v0_k,g); - for ( boost::tie(eb2,ee2) = halfedges_around_source(k,g) ; eb2 != ee2 ; ++ eb2 ) + for ( std::tie(eb2,ee2) = halfedges_around_source(k,g) ; eb2 != ee2 ; ++ eb2 ) { halfedge_descriptor k_v1 = *eb2; @@ -1866,10 +1866,95 @@ bool satisfies_link_condition(typename boost::graph_traits::edge_descript } /// \endcond #endif + +/** + * removes the target vertex of `h`, merging its incident edges into a single edge linking + * the two vertices adjacent to the vertex being removed. + * + * \tparam Graph must be a model of `MutableFaceGraph` + * + * \param h halfedge descriptor + * \param g the graph + * + * \returns an halfedge linking the two vertices adjacent to the vertex being removed. + * + * \pre `degree(target(h, g), g) == 2`. + * + * \sa `remove_center_vertex()` + */ + +template +typename boost::graph_traits::halfedge_descriptor +remove_degree_2_vertex(const typename boost::graph_traits::halfedge_descriptor h, + Graph& g) +{ + typedef boost::graph_traits Traits; + typedef typename Traits::vertex_descriptor vertex_descriptor; + typedef typename Traits::halfedge_descriptor halfedge_descriptor; + typedef typename Traits::face_descriptor face_descriptor; + + CGAL_precondition(degree(target(h, g), g) == 2); + + vertex_descriptor v = target(h, g); + halfedge_descriptor h1 = h; + halfedge_descriptor h2 = opposite(next(h1, g), g); + + if(is_border(h1, g)) + std::swap(h1, h2); + + vertex_descriptor v1 = source(h1, g); + vertex_descriptor v2 = source(h2, g); + + bool exists; + halfedge_descriptor huv; + std::tie(huv, exists) = halfedge(v1, v2, g); + + if(is_border(h2, g)) + { + CGAL_assertion(!is_border(h1, g)); + + if(exists) + { + Euler::remove_face(h1, g); + return huv; + } + else + { + halfedge_descriptor oh1 = opposite(h1, g); + halfedge_descriptor nnh1 = next(next(h1, g), g); + halfedge_descriptor ph2 = prev(h2, g); + face_descriptor f1 = face(h1, g); + + set_target(h1, v2, g); + set_halfedge(v2, ph2, g); + set_next(h1, nnh1, g); + set_next(ph2, oh1, g); + set_halfedge(f1, h1, g); // in case it was nh1 + + remove_edge(edge(h2, g), g); + remove_vertex(v, g); + + return h1; + } + } + else + { + CGAL_assertion(!is_border(h1, g) && !is_border(h2, g)); + + halfedge_descriptor ph1 = prev(h1, g); + halfedge_descriptor ph2 = prev(h2, g); + Euler::remove_center_vertex(h, g); + + if(exists) + return huv; + else + return Euler::split_face(ph1, ph2, g); + } +} + /// @} } // namespace Euler - } // namespace CGAL #endif /* CGAL_EULER_OPERATIONS_H */ diff --git a/BGL/include/CGAL/boost/graph/Face_filtered_graph.h b/BGL/include/CGAL/boost/graph/Face_filtered_graph.h index 362f6b241b1..00097ff1574 100644 --- a/BGL/include/CGAL/boost/graph/Face_filtered_graph.h +++ b/BGL/include/CGAL/boost/graph/Face_filtered_graph.h @@ -895,7 +895,7 @@ vertices(const Face_filtered_graph & w) typename Face_filtered_graph ::Is_simplex_valid predicate(&w); g_vertex_iterator b,e; - boost::tie(b,e) = vertices(w.graph()); + std::tie(b,e) = vertices(w.graph()); return make_range(vertex_iterator(predicate, b, e), vertex_iterator(predicate, e, e)); } @@ -912,7 +912,7 @@ edges(const Face_filtered_graph & w) typename Face_filtered_graph ::Is_simplex_valid predicate(&w); g_edge_iterator b,e; - boost::tie(b,e) = edges(w.graph()); + std::tie(b,e) = edges(w.graph()); return make_range(edge_iterator(predicate, b, e), edge_iterator(predicate, e, e)); } @@ -931,7 +931,7 @@ out_edges(typename boost::graph_traits ::Is_simplex_valid predicate(&w); g_out_edge_iterator b,e; - boost::tie(b,e) = out_edges(v, w.graph()); + std::tie(b,e) = out_edges(v, w.graph()); return make_range(out_edge_iterator(predicate, b, e), out_edge_iterator(predicate, e, e)); } @@ -950,7 +950,7 @@ in_edges(typename boost::graph_traits ::Is_simplex_valid predicate(&w); g_in_edge_iterator b,e; - boost::tie(b,e) = in_edges(v, w.graph()); + std::tie(b,e) = in_edges(v, w.graph()); return make_range(in_edge_iterator(predicate, b, e), in_edge_iterator(predicate, e, e)); } diff --git a/BGL/include/CGAL/boost/graph/Graph_with_descriptor_with_graph.h b/BGL/include/CGAL/boost/graph/Graph_with_descriptor_with_graph.h index 368c5fca524..ad107978828 100644 --- a/BGL/include/CGAL/boost/graph/Graph_with_descriptor_with_graph.h +++ b/BGL/include/CGAL/boost/graph/Graph_with_descriptor_with_graph.h @@ -310,7 +310,7 @@ edge(typename boost::graph_traits >::ver CGAL_assertion(in_same_graph(v,w)); bool b; g_edge_descriptor ed; - boost::tie(ed,b) = edge(u.descriptor, v.descriptor, *w.graph); + std::tie(ed,b) = edge(u.descriptor, v.descriptor, *w.graph); return std::make_pair(edge_descriptor(ed,*w.graph),b); } @@ -320,7 +320,7 @@ CGAL::Iterator_range & w) { typename boost::graph_traits::vertex_iterator b,e; - boost::tie(b,e) = vertices(*w.graph); + std::tie(b,e) = vertices(*w.graph); return std::make_pair(boost::make_transform_iterator(b,typename boost::graph_traits >::V2V(*w.graph)), boost::make_transform_iterator(e,typename boost::graph_traits >::V2V(*w.graph))); } @@ -330,7 +330,7 @@ CGAL::Iterator_range & w) { typename boost::graph_traits::edge_iterator b,e; - boost::tie(b,e) = edges(*w.graph); + std::tie(b,e) = edges(*w.graph); return std::make_pair(boost::make_transform_iterator(b,typename boost::graph_traits >::E2E(*w.graph)), boost::make_transform_iterator(e,typename boost::graph_traits >::E2E(*w.graph))); } @@ -342,7 +342,7 @@ out_edges(typename boost::graph_traits > { CGAL_assertion(in_same_graph(v,w)); typename boost::graph_traits::out_edge_iterator b,e; - boost::tie(b,e) = out_edges(v.descriptor, *w.graph); + std::tie(b,e) = out_edges(v.descriptor, *w.graph); return std::make_pair(boost::make_transform_iterator(b,typename boost::graph_traits >::E2E(*w.graph)), boost::make_transform_iterator(e,typename boost::graph_traits >::E2E(*w.graph))); } @@ -354,7 +354,7 @@ in_edges(typename boost::graph_traits >: { CGAL_assertion(in_same_graph(v,w)); typename boost::graph_traits::in_edge_iterator b,e; - boost::tie(b,e) = in_edges(v.descriptor, *w.graph); + std::tie(b,e) = in_edges(v.descriptor, *w.graph); return std::make_pair(boost::make_transform_iterator(b,typename boost::graph_traits >::E2E(*w.graph)), boost::make_transform_iterator(e,typename boost::graph_traits >::E2E(*w.graph))); } @@ -557,7 +557,7 @@ halfedge(typename boost::graph_traits< Graph_with_descriptor_with_graph > bool b; CGAL_assertion(in_same_graph(u,w)); CGAL_assertion(in_same_graph(v,w)); - boost::tie(hd,b) = halfedge(u.descriptor, v.descriptor, *w.graph); + std::tie(hd,b) = halfedge(u.descriptor, v.descriptor, *w.graph); return std::make_pair(halfedge_descriptor(hd,*w.graph),b); } @@ -621,7 +621,7 @@ CGAL::Iterator_range & w) { typename boost::graph_traits::halfedge_iterator b,e; - boost::tie(b,e) = halfedges(*w.graph); + std::tie(b,e) = halfedges(*w.graph); return std::make_pair(boost::make_transform_iterator(b, typename boost::graph_traits >::H2H(*w.graph)), boost::make_transform_iterator(e, typename boost::graph_traits >::H2H(*w.graph))); } @@ -661,7 +661,7 @@ CGAL::Iterator_range & w) { typename boost::graph_traits::face_iterator b,e; - boost::tie(b,e) = faces(*w.graph); + std::tie(b,e) = faces(*w.graph); return std::make_pair(boost::make_transform_iterator(b,typename boost::graph_traits >::F2F(*w.graph)), boost::make_transform_iterator(e,typename boost::graph_traits >::F2F(*w.graph))); } diff --git a/BGL/include/CGAL/boost/graph/METIS/partition_dual_graph.h b/BGL/include/CGAL/boost/graph/METIS/partition_dual_graph.h index 9a217389d82..32a2cb66294 100644 --- a/BGL/include/CGAL/boost/graph/METIS/partition_dual_graph.h +++ b/BGL/include/CGAL/boost/graph/METIS/partition_dual_graph.h @@ -61,7 +61,7 @@ void partition_dual_graph(const TriangleMesh& tm, // fill the adjacency info face_iterator fit, fe; - boost::tie(fit, fe) = faces(tm); + std::tie(fit, fe) = faces(tm); for(int i=0, j=0; fit!=fe; ++fit, ++i) { eptr[i] = j; diff --git a/BGL/include/CGAL/boost/graph/METIS/partition_graph.h b/BGL/include/CGAL/boost/graph/METIS/partition_graph.h index 42f8c240f01..362d8a1502b 100644 --- a/BGL/include/CGAL/boost/graph/METIS/partition_graph.h +++ b/BGL/include/CGAL/boost/graph/METIS/partition_graph.h @@ -47,7 +47,7 @@ struct Output_vertex_partition_ids VertexPartitionIDPmap vertex_partition_id_map) { typename boost::graph_traits::vertex_iterator vit, ve; - boost::tie(vit, ve) = vertices(tm); + std::tie(vit, ve) = vertices(tm); for(; vit!=ve; ++vit) put(vertex_partition_id_map, *vit, npart[get(indices, *vit)]); } @@ -64,7 +64,7 @@ struct Output_face_partition_ids FacePartitionIDPmap face_partition_id_map) { typename boost::graph_traits::face_iterator fit, fe; - boost::tie(fit, fe) = faces(tm); + std::tie(fit, fe) = faces(tm); for(int i=0; fit!=fe; ++fit, ++i) put(face_partition_id_map, *fit, epart[i]); } @@ -98,7 +98,7 @@ void partition_graph(const TriangleMesh& tm, // fill the adjacency info face_iterator fit, fe; - boost::tie(fit, fe) = faces(tm); + std::tie(fit, fe) = faces(tm); for(int i=0, j=0; fit!=fe; ++fit, ++i) { eptr[i] = j; diff --git a/BGL/include/CGAL/boost/graph/alpha_expansion_graphcut.h b/BGL/include/CGAL/boost/graph/alpha_expansion_graphcut.h index b2d6e1cc840..75014bd9371 100644 --- a/BGL/include/CGAL/boost/graph/alpha_expansion_graphcut.h +++ b/BGL/include/CGAL/boost/graph/alpha_expansion_graphcut.h @@ -238,7 +238,7 @@ public: // initialize vertex indices, it is necessary since we are using VertexList = listS Vertex_iterator v_begin, v_end; Traits::vertices_size_type index = 0; - for(boost::tie(v_begin, v_end) = vertices(graph); v_begin != v_end; ++v_begin) { + for(std::tie(v_begin, v_end) = vertices(graph); v_begin != v_end; ++v_begin) { boost::put(boost::vertex_index, graph, *v_begin, index++); } } @@ -269,8 +269,8 @@ public: Edge_descriptor v1_v2, v2_v1; bool v1_v2_added, v2_v1_added; - boost::tie(v1_v2, v1_v2_added) = boost::add_edge(v1, v2, graph); - boost::tie(v2_v1, v2_v1_added) = boost::add_edge(v2, v1, graph); + std::tie(v1_v2, v1_v2_added) = boost::add_edge(v1, v2, graph); + std::tie(v2_v1, v2_v1_added) = boost::add_edge(v2, v1, graph); CGAL_assertion(v1_v2_added && v2_v1_added); //put edge capacities @@ -360,7 +360,7 @@ public: // however from our edge_map, we know that each (2i, 2i + 1) is reverse pairs, how to facilitate that ? // will look it back Graph::edge_iterator ei, ee; - for(boost::tie(ei, ee) = boost::edges(graph); ei != ee; ++ei) { + for(std::tie(ei, ee) = boost::edges(graph); ei != ee; ++ei) { Graph::vertex_descriptor v1 = boost::source(*ei, graph); Graph::vertex_descriptor v2 = boost::target(*ei, graph); std::pair opp_edge = boost::edge(v2, v1, graph); diff --git a/BGL/include/CGAL/boost/graph/helpers.h b/BGL/include/CGAL/boost/graph/helpers.h index 75673493e0d..26b358b3561 100644 --- a/BGL/include/CGAL/boost/graph/helpers.h +++ b/BGL/include/CGAL/boost/graph/helpers.h @@ -65,7 +65,7 @@ is_border(typename boost::graph_traits::vertex_descriptor vd, const FaceGraph& g) { CGAL::Halfedge_around_target_iterator havib, havie; - for(boost::tie(havib, havie) = halfedges_around_target(halfedge(vd, g), g); havib != havie; ++havib) { + for(std::tie(havib, havie) = halfedges_around_target(halfedge(vd, g), g); havib != havie; ++havib) { if(is_border(*havib,g)) { typename boost::graph_traits::halfedge_descriptor h = *havib; return h; diff --git a/BGL/include/CGAL/boost/graph/split_graph_into_polylines.h b/BGL/include/CGAL/boost/graph/split_graph_into_polylines.h index 679d48896f1..194bd6b95b1 100644 --- a/BGL/include/CGAL/boost/graph/split_graph_into_polylines.h +++ b/BGL/include/CGAL/boost/graph/split_graph_into_polylines.h @@ -147,7 +147,7 @@ void duplicate_terminal_vertices(Graph& graph, typedef typename boost::graph_traits::out_edge_iterator out_edge_iterator; vertex_iterator b,e; - boost::tie(b,e) = vertices(graph); + std::tie(b,e) = vertices(graph); std::vector V(b,e); for(vertex_descriptor v : V) { @@ -156,7 +156,7 @@ void duplicate_terminal_vertices(Graph& graph, if (deg != 2 || is_terminal(orig_v, orig)) { out_edge_iterator b, e; - boost::tie(b, e) = out_edges(v, graph); + std::tie(b, e) = out_edges(v, graph); std::vector out_edges_of_v(b, e); for (unsigned int i = 1; i < out_edges_of_v.size(); ++i) { diff --git a/BGL/test/BGL/data/degree_2_collection.off b/BGL/test/BGL/data/degree_2_collection.off new file mode 100644 index 00000000000..629a920c99d --- /dev/null +++ b/BGL/test/BGL/data/degree_2_collection.off @@ -0,0 +1,52 @@ +OFF +29 19 0 + +0 0 0 +0.20000000000000001 0 0 +0.40000000000000002 0 0 +0.59999999999999998 0 0 +0.80000000000000004 0 0 +1 0 0 +0 0.20000000000000001 0 +0.20000000000000001 0.20000000000000001 0 +0 1 0 +0.59999999999999998 0.20000000000000001 0 +0.80000000000000004 0.20000000000000001 0 +1 0.20000000000000001 0 +0 0.40000000000000002 0 +0.20000000000000001 1 0 +0.40000000000000002 0.40000000000000002 0 +0.59999999999999998 0.40000000000000002 0 +1 1 0 +1 0.40000000000000002 0 +0 0.59999999999999998 0 +1 0.80000000000000004 0 +0.59999999999999998 1 0 +0.59999999999999998 0.59999999999999998 0 +0.80000000000000004 1 0 +1 0.59999999999999998 0 +0 0.80000000000000004 0 +0.20000000000000001 0.80000000000000004 0 +0.40000000000000002 1 0 +0.59999999999999998 0.80000000000000004 0 +0.80000000000000004 0.80000000000000004 0 +4 1 7 6 0 +3 28 19 22 +3 6 7 12 +3 4 10 9 +3 3 4 9 +3 27 20 26 +3 9 15 14 +3 5 11 10 +3 24 25 8 +3 25 13 8 +3 1 2 7 +8 17 23 28 27 21 15 10 11 +3 9 10 15 +3 19 16 22 +12 25 24 18 12 7 2 3 9 14 15 21 27 +3 4 5 10 +3 28 22 20 +3 27 28 20 +3 23 19 28 + diff --git a/BGL/test/BGL/test_Euler_operations.cpp b/BGL/test/BGL/test_Euler_operations.cpp index 615a4fd756d..758825d0943 100644 --- a/BGL/test/BGL/test_Euler_operations.cpp +++ b/BGL/test/BGL/test_Euler_operations.cpp @@ -1,12 +1,15 @@ #include "test_Prefix.h" -#include + #include #include +#include +#include +#include #include -#include -#include + +#include template void @@ -97,7 +100,7 @@ join_face_test() bool found; halfedge_descriptor e; - boost::tie(e, found) = halfedge(f.w, f.v, f.m); + std::tie(e, found) = halfedge(f.w, f.v, f.m); assert(found); // manually set the halfedge of f.f1 to the edge that is to be // removed to provoke a special case @@ -108,7 +111,7 @@ join_face_test() assert(CGAL::internal::exact_num_edges(f.m) == 6); CGAL::Halfedge_around_face_iterator begin, end; - boost::tie(begin, end) = CGAL::halfedges_around_face(halfedge(f.f1, f.m), f.m); + std::tie(begin, end) = CGAL::halfedges_around_face(halfedge(f.f1, f.m), f.m); assert(std::distance(begin, end) == 4); for(; begin != end; ++begin) { @@ -119,7 +122,7 @@ join_face_test() } face_iterator fit, fend; - for(boost::tie(fit, fend) = faces(f.m); fit != fend; ++fit) { + for(std::tie(fit, fend) = faces(f.m); fit != fend; ++fit) { assert(*fit == f.f1 || *fit == f.f3); } @@ -141,7 +144,7 @@ remove_face_test_1() // find the edge between x and y bool found; halfedge_descriptor e; - boost::tie(e, found) = halfedge(f.x, f.y, f.m); + std::tie(e, found) = halfedge(f.x, f.y, f.m); assert(found); assert(face(e, f.m) == f.f3); @@ -156,7 +159,7 @@ remove_face_test_1() assert_EQUAL(CGAL::internal::exact_num_vertices(f.m) == 4); halfedge_iterator eb, ee; int count = 0; - for(boost::tie(eb, ee) = halfedges(f.m); eb != ee; ++eb) { + for(std::tie(eb, ee) = halfedges(f.m); eb != ee; ++eb) { if(face(*eb,f.m) == boost::graph_traits::null_face()) ++count; } @@ -177,9 +180,9 @@ remove_face_test_2() bool found; halfedge_descriptor e; - boost::tie(e, found) = halfedge(f.x, f.w, f.m); + std::tie(e, found) = halfedge(f.x, f.w, f.m); assert(found); - boost::tie(e, found) = halfedge(f.x, f.v, f.m); + std::tie(e, found) = halfedge(f.x, f.v, f.m); assert(found); assert(face(e, f.m) == f.f1); CGAL::Euler::remove_face(e,f.m); @@ -189,7 +192,7 @@ remove_face_test_2() assert(CGAL::internal::exact_num_edges(f.m) == 7); assert(CGAL::internal::exact_num_vertices(f.m) == 5); - boost::tie(e, found) = halfedge(f.x, f.w, f.m); + std::tie(e, found) = halfedge(f.x, f.w, f.m); assert(found); assert(face(e,f.m) == boost::graph_traits::null_face()); @@ -266,7 +269,7 @@ join_vertex_interior_test() halfedge_descriptor e; bool found; - boost::tie(e, found) = halfedge(f.w, f.x, f.m); + std::tie(e, found) = halfedge(f.w, f.x, f.m); assert(found); CGAL::Euler::join_vertex(e,f.m); assert(CGAL::internal::exact_num_faces(f.m) == 2); @@ -289,7 +292,7 @@ join_vertex_exterior_test() Surface_fixture_3 f; halfedge_descriptor e; bool found; - boost::tie(e, found) = halfedge(f.w, f.y, f.m); + std::tie(e, found) = halfedge(f.w, f.y, f.m); assert(source(e,f.m) == f.w); assert(target(e,f.m) == f.y); assert(found); @@ -307,7 +310,7 @@ join_vertex_exterior_test() Surface_fixture_3 f; halfedge_descriptor e; bool found; - boost::tie(e, found) = halfedge(f.y, f.w, f.m); + std::tie(e, found) = halfedge(f.y, f.w, f.m); assert(source(e,f.m) == f.y); assert(target(e,f.m) == f.w); @@ -335,9 +338,9 @@ split_vertex() Surface_fixture_3 f; halfedge_descriptor h1, h2; bool found; - boost::tie(h1, found) = halfedge(f.w, f.y, f.m); + std::tie(h1, found) = halfedge(f.w, f.y, f.m); assert(found); - boost::tie(h2, found) = halfedge(f.z, f.y, f.m); + std::tie(h2, found) = halfedge(f.z, f.y, f.m); assert(found); assert(face(h2, f.m) == Traits::null_face()); @@ -358,13 +361,13 @@ split_join_vertex_inverse() Surface_fixture_3 f; halfedge_descriptor h, h1, h2; bool found; - boost::tie(h, found) = halfedge(f.w, f.x, f.m); + std::tie(h, found) = halfedge(f.w, f.x, f.m); assert(found); CGAL::Euler::join_vertex(h,f.m); assert(CGAL::is_valid_polygon_mesh(f.m)); - boost::tie(h1, found) = halfedge(f.z, f.x, f.m); + std::tie(h1, found) = halfedge(f.z, f.x, f.m); assert(found); - boost::tie(h2, found) = halfedge(f.v, f.x, f.m); + std::tie(h2, found) = halfedge(f.v, f.x, f.m); assert(found); CGAL::Euler::join_vertex(CGAL::Euler::split_vertex(h1, h2,f.m),f.m); assert(CGAL::is_valid_polygon_mesh(f.m)); @@ -448,6 +451,67 @@ remove_center_vertex_test() assert(CGAL::internal::exact_num_halfedges(f.m) == nh-(2*deg)); } +template +void +remove_degree_2_vertex_test() +{ + CGAL_GRAPH_TRAITS_MEMBERS(T); + + // vertex at .first should be removable, and after removal, + // there should .second[0] nv, .second[1] ne, and .second[2] nf + // anything not in the map should not be removable + std::map > removable; + removable[0] = CGAL::make_array(28, 92, 19); + removable[13] = CGAL::make_array(28, 90, 18); + removable[14] = CGAL::make_array(28, 90, 18); + removable[16] = CGAL::make_array(28, 90, 18); + removable[17] = CGAL::make_array(28, 92, 19); + removable[18] = CGAL::make_array(28, 92, 19); + removable[21] = CGAL::make_array(28, 92, 19); + removable[26] = CGAL::make_array(28, 90, 18); + + auto test = [&removable](const std::size_t hi) // intentional copy of 'm' + { + T m; + const bool ok = CGAL::IO::read_polygon_mesh("data/degree_2_collection.off", m); + assert(ok); + assert(CGAL::is_valid_polygon_mesh(m)); + + auto vim = CGAL::get_initialized_vertex_index_map(m); + + const halfedge_descriptor h = *(std::next(halfedges(m).begin(), hi)); + const vertex_descriptor v = target(h, m); + auto vid = get(vim, v); + if(degree(v, m) != 2) + { + assert(removable.count(vid) == 0); + return; + } + + const halfedge_descriptor res = CGAL::Euler::remove_degree_2_vertex(h, m); + assert(res != boost::graph_traits::null_halfedge()); + + const std::array& ns = removable.at(vid); + + assert(ns[0] == vertices(m).size()); + assert(ns[1] == halfedges(m).size()); + assert(ns[2] == faces(m).size()); + }; + + T m; + const bool ok = CGAL::IO::read_polygon_mesh("data/degree_2_collection.off", m); + assert(ok); + assert(CGAL::is_valid_polygon_mesh(m)); + + std::size_t nv = num_vertices(m); + std::size_t nh = num_halfedges(m); + std::size_t nf = num_faces(m); + assert(nv == 29 && nh == 94 && nf == 19); + + for(std::size_t hi=0; hi void join_split_inverse() @@ -670,6 +734,8 @@ template void test_Euler_operations() { + std::cout << "== Test with Graph: " << typeid(Graph).name() << std::endl; + test_copy_face_graph_nm_umbrella(); test_copy_face_graph_isolated_vertices(); join_face_test(); @@ -684,6 +750,7 @@ test_Euler_operations() split_face_test(); make_hole_test(); remove_center_vertex_test(); + remove_degree_2_vertex_test(); join_split_inverse(); does_satisfy_link_condition(); test_swap_edges(); diff --git a/BGL/test/BGL/test_Face_filtered_graph.cpp b/BGL/test/BGL/test_Face_filtered_graph.cpp index 84e1bbbf69f..e6cfc53be6e 100644 --- a/BGL/test/BGL/test_Face_filtered_graph.cpp +++ b/BGL/test/BGL/test_Face_filtered_graph.cpp @@ -29,9 +29,9 @@ void test_halfedge_around_vertex_iterator(const Graph& g) Adapter fg(g, 0, boost::make_assoc_property_map(map)); typename boost::graph_traits::vertex_iterator vit, vend; - for(boost::tie(vit, vend) = vertices(fg); vit != vend; ++vit) { + for(std::tie(vit, vend) = vertices(fg); vit != vend; ++vit) { halfedge_around_target_iterator havit, havend; - for(boost::tie(havit, havend) = CGAL::halfedges_around_target(halfedge(*vit, fg), fg); + for(std::tie(havit, havend) = CGAL::halfedges_around_target(halfedge(*vit, fg), fg); havit != havend; ++havit) { assert(target(*havit, fg) == *vit); @@ -56,11 +56,11 @@ void test_halfedge_around_face_iterator(const Graph& g) Adapter fg(g, 0, boost::make_assoc_property_map(map)); face_iterator fit, fend; - for(boost::tie(fit, fend) = faces(fg); fit != fend; ++fit) { + for(std::tie(fit, fend) = faces(fg); fit != fend; ++fit) { halfedge_around_face_iterator hafit, hafend; - boost::tie(hafit, hafend) = CGAL::halfedges_around_face(halfedge(*fit, fg), fg); + std::tie(hafit, hafend) = CGAL::halfedges_around_face(halfedge(*fit, fg), fg); assert(std::distance(hafit, hafend) != 0); - for(boost::tie(hafit, hafend) = CGAL::halfedges_around_face(halfedge(*fit, fg), fg); hafit != hafend; ++hafit) { + for(std::tie(hafit, hafend) = CGAL::halfedges_around_face(halfedge(*fit, fg), fg); hafit != hafend; ++hafit) { assert(face(*hafit, fg) == *fit); } } @@ -78,11 +78,11 @@ void test_edge_iterators(const Graph& g) // do we iterate as many as that? edge_iterator eb, ee; - boost::tie(eb, ee) = edges(fg); + std::tie(eb, ee) = edges(fg); assert(static_cast(std::distance(eb, ee)) == num_edges(g)); id_map ids; unsigned int count = 0; - for(boost::tie(eb, ee) = edges(fg); eb != ee; ++eb) { + for(std::tie(eb, ee) = edges(fg); eb != ee; ++eb) { edge_descriptor e = *eb; std::pair r = ids.insert(get(boost::edge_index, g, e)); // unique? @@ -103,7 +103,7 @@ void test_vertex_iterators(Graph& g) Adapter fg(g, 0, boost::make_assoc_property_map(map)); vertex_iterator vb, ve; std::size_t count = 0; - for(boost::tie(vb, ve) = vertices(fg); vb != ve; ++vb){ + for(std::tie(vb, ve) = vertices(fg); vb != ve; ++vb){ ++count; } @@ -113,7 +113,7 @@ void test_vertex_iterators(Graph& g) id_map ids; count = 0; - for(boost::tie(vb, ve) = vertices(fg); vb != ve; ++vb) { + for(std::tie(vb, ve) = vertices(fg); vb != ve; ++vb) { std::pair r = ids.insert(get(boost::vertex_index, g, *vb)); assert(r.second); ++count; @@ -133,12 +133,12 @@ void test_out_edges(const Graph& g) Adapter fg(g, 0, boost::make_assoc_property_map(map)); vertex_iterator vb, ve; - for(boost::tie(vb, ve) = vertices(fg); vb != ve; ++vb) { + for(std::tie(vb, ve) = vertices(fg); vb != ve; ++vb) { id_map v_ids; vertex_descriptor around = *vb; out_edge_iterator oeb, oee; - for(boost::tie(oeb, oee) = out_edges(*vb, fg); oeb != oee; ++oeb) { + for(std::tie(oeb, oee) = out_edges(*vb, fg); oeb != oee; ++oeb) { vertex_descriptor t = target(*oeb, fg); vertex_descriptor s = source(*oeb, fg); assert(s != t); @@ -162,11 +162,11 @@ void test_in_edges(const Graph& g) Adapter fg(g, 0, boost::make_assoc_property_map(map)); vertex_iterator vb, ve; - for(boost::tie(vb, ve) = vertices(fg); vb != ve; ++vb) { + for(std::tie(vb, ve) = vertices(fg); vb != ve; ++vb) { id_map v_ids; vertex_descriptor around = *vb; in_edge_iterator ieb, iee; - for(boost::tie(ieb, iee) = in_edges(*vb, fg); ieb != iee; ++ieb) { + for(std::tie(ieb, iee) = in_edges(*vb, fg); ieb != iee; ++ieb) { vertex_descriptor t = target(*ieb, fg); vertex_descriptor s = source(*ieb, fg); assert(t == around); @@ -190,18 +190,18 @@ void test_in_out_edges(const Graph& g) // check that the sets of in out edges are the same vertex_iterator vb, ve; - for(boost::tie(vb, ve) = vertices(fg); vb != ve; ++vb) { + for(std::tie(vb, ve) = vertices(fg); vb != ve; ++vb) { id_map v_ids; std::vector in, out; in_edge_iterator ieb, iee; - for(boost::tie(ieb, iee) = in_edges(*vb, fg); ieb != iee; ++ieb) { + for(std::tie(ieb, iee) = in_edges(*vb, fg); ieb != iee; ++ieb) { std::pair r = v_ids.insert(get(boost::vertex_index, g, source(*ieb, fg))); assert(r.second); in.push_back(source(*ieb, fg)); } out_edge_iterator oeb, oee; - for(boost::tie(oeb, oee) = out_edges(*vb, fg); oeb != oee; ++oeb) { + for(std::tie(oeb, oee) = out_edges(*vb, fg); oeb != oee; ++oeb) { std::pair r = v_ids.insert(get(boost::vertex_index, g, target(*oeb, fg))); // insertion must fail @@ -232,7 +232,7 @@ void test_edge_find(const Graph& g) typedef std::pair ret; edge_iterator eb, ee; - for(boost::tie(eb, ee) = edges(fg); eb != ee; ++eb) { + for(std::tie(eb, ee) = edges(fg); eb != ee; ++eb) { vertex_descriptor s = source(*eb, fg); vertex_descriptor t = target(*eb, fg); ret found = edge(s, t, fg); @@ -256,14 +256,14 @@ void test_faces(const Graph& g) unsigned int count = 0; face_iterator fb, fe; - for(boost::tie(fb, fe) = faces(fg); fb != fe; ++fb) { + for(std::tie(fb, fe) = faces(fg); fb != fe; ++fb) { ++count; // reverse look-up halfedge_descriptor assoc = halfedge(*fb, fg); assert(face(assoc, fg) == *fb); // check the enclosure halfedge_around_face_iterator encb, ence; - for(boost::tie(encb, ence) = CGAL::halfedges_around_face(halfedge(*fb, fg), fg); encb != ence; ++encb) { + for(std::tie(encb, ence) = CGAL::halfedges_around_face(halfedge(*fb, fg), fg); encb != ence; ++encb) { assert(face(*encb, fg) == *fb); } } diff --git a/BGL/test/BGL/test_Prefix.h b/BGL/test/BGL/test_Prefix.h index ca92ed230f2..fe866af6842 100644 --- a/BGL/test/BGL/test_Prefix.h +++ b/BGL/test/BGL/test_Prefix.h @@ -238,7 +238,7 @@ struct Surface_fixture_1 { pm = get(CGAL::vertex_point, const_cast(m)); typename boost::graph_traits::vertex_iterator vb, ve; - for(boost::tie(vb, ve) = vertices(m); vb != ve; ++vb) { + for(std::tie(vb, ve) = vertices(m); vb != ve; ++vb) { if (get(pm, *vb) == Point_3(0, 0, 0)) u = *vb; else if(get(pm, *vb) == Point_3(1, 0, 0)) @@ -259,13 +259,13 @@ struct Surface_fixture_1 { f1 = CGAL::is_border(halfedge(u, m),m) ? face(opposite(halfedge(u, m), m), m) : face(halfedge(u, m), m); assert(f1 != boost::graph_traits::null_face()); CGAL::Halfedge_around_face_iterator hafib, hafie; - for(boost::tie(hafib, hafie) = CGAL::halfedges_around_face(halfedge(f1, m), m); hafib != hafie; ++hafib) + for(std::tie(hafib, hafie) = CGAL::halfedges_around_face(halfedge(f1, m), m); hafib != hafie; ++hafib) { if(! CGAL::is_border(opposite(*hafib, m), m)) f2 = face(opposite(*hafib, m), m); } typename boost::graph_traits::face_iterator fb, fe; - for(boost::tie(fb, fe) = faces(m); fb != fe; ++fb) { + for(std::tie(fb, fe) = faces(m); fb != fe; ++fb) { if(*fb != f1 && *fb != f2) f3 = *fb; } @@ -289,7 +289,7 @@ struct Surface_fixture_2 { pm = get(CGAL::vertex_point, const_cast(m)); typename boost::graph_traits::vertex_iterator vb, ve; - for(boost::tie(vb, ve) = vertices(m); vb != ve; ++vb) { + for(std::tie(vb, ve) = vertices(m); vb != ve; ++vb) { if (get(pm, *vb) == Point_3(0, 2, 0)) u = *vb; else if(get(pm, *vb) == Point_3(2, 2, 0)) @@ -308,25 +308,25 @@ struct Surface_fixture_2 { assert(y != boost::graph_traits::null_vertex()); typename boost::graph_traits::halfedge_descriptor h; bool found; - boost::tie(h, found) = halfedge(x, v, m); + std::tie(h, found) = halfedge(x, v, m); assert(found); assert(! CGAL::is_border(h,m)); f1 = face(h, m); assert(f1 != boost::graph_traits::null_face()); - boost::tie(h, found) = halfedge(v, u, m); + std::tie(h, found) = halfedge(v, u, m); assert(found); assert(!CGAL::is_border(h,m)); f2 = face(h, m); assert(f2 != boost::graph_traits::null_face()); - boost::tie(h, found) = halfedge(u, w, m); + std::tie(h, found) = halfedge(u, w, m); assert(found); assert(!CGAL::is_border(h,m)); f3 = face(h, m); assert(f3 != boost::graph_traits::null_face()); - boost::tie(h, found) = halfedge(w, x, m); + std::tie(h, found) = halfedge(w, x, m); assert(found); assert(!CGAL::is_border(h,m)); f4 = face(h, m); @@ -351,7 +351,7 @@ struct Surface_fixture_3 { pm = get(CGAL::vertex_point, const_cast(m)); typename boost::graph_traits::vertex_iterator vb, ve; - for(boost::tie(vb, ve) = vertices(m); vb != ve; ++vb) { + for(std::tie(vb, ve) = vertices(m); vb != ve; ++vb) { if (get(pm, *vb) == Point_3(0, 1, 0)) u = *vb; else if(get(pm, *vb) == Point_3(0, 0, 0)) @@ -399,7 +399,7 @@ struct Surface_fixture_4 { int found = 0; typename boost::graph_traits::halfedge_iterator hb, he; - for(boost::tie(hb, he) = halfedges(m); hb != he; ++hb) { + for(std::tie(hb, he) = halfedges(m); hb != he; ++hb) { if(CGAL::is_border(*hb,m)){ if(get(pm, target(*hb,m)) == Point_3(0,0,0)){ if(found == 0){ @@ -435,7 +435,7 @@ struct Surface_fixture_5 { int found = 0; typename boost::graph_traits::halfedge_iterator hb, he; - for(boost::tie(hb, he) = halfedges(m); hb != he; ++hb) { + for(std::tie(hb, he) = halfedges(m); hb != he; ++hb) { if(CGAL::is_border(*hb,m)){ if(get(pm, target(*hb,m)) == Point_3(2,1,0)){ h1 = *hb; @@ -500,7 +500,7 @@ struct Surface_fixture_8 { int found = 0; typename boost::graph_traits::halfedge_iterator hb, he; - for(boost::tie(hb, he) = halfedges(m); hb != he; ++hb) { + for(std::tie(hb, he) = halfedges(m); hb != he; ++hb) { if(get(pm, source(*hb,m)) == Point_3(0,0,0) && get(pm, target(*hb,m)) == Point_3(1,0,0)){ h1 = *hb; @@ -521,8 +521,6 @@ struct Surface_fixture_8 { Graph m; typename boost::graph_traits::halfedge_descriptor h1, h2, h3; - }; - #endif /* CGAL_TEST_PREFIX_H */ diff --git a/BGL/test/BGL/test_bgl_dual.cpp b/BGL/test/BGL/test_bgl_dual.cpp index 9a79832fcb9..e6a6330a256 100644 --- a/BGL/test/BGL/test_bgl_dual.cpp +++ b/BGL/test/BGL/test_bgl_dual.cpp @@ -42,13 +42,13 @@ int main() { out_edge_iterator b,e; - boost::tie(b,e) = out_edges(vd,dual); + std::tie(b,e) = out_edges(vd,dual); std::cerr << vd << " " << source(*b,dual) << std::endl; } { in_edge_iterator b,e; - boost::tie(b,e) = in_edges(vd,dual); + std::tie(b,e) = in_edges(vd,dual); std::cerr << vd << " " << source(*b,dual) << std::endl; } std::cerr << "done"<< std::endl; diff --git a/BGL/test/BGL/test_circulator.cpp b/BGL/test/BGL/test_circulator.cpp index 1c862324bb6..cd0a18cbbe4 100644 --- a/BGL/test/BGL/test_circulator.cpp +++ b/BGL/test/BGL/test_circulator.cpp @@ -102,7 +102,7 @@ int main(int argc, char* argv[]) { halfedge_around_target_iterator vit, end; vertex_descriptor vd = target(hd,P); - boost::tie(vit,end) = halfedges_around_target(hd,P); + std::tie(vit,end) = halfedges_around_target(hd,P); while(vit!= end) { halfedge_descriptor hd = *vit; assert(target(hd,P) == vd); @@ -113,7 +113,7 @@ int main(int argc, char* argv[]) { halfedge_around_face_iterator vit, end; - boost::tie(vit,end) = halfedges_around_face(hd,P); + std::tie(vit,end) = halfedges_around_face(hd,P); while(vit!= end) { halfedge_descriptor hd = *vit; @@ -125,7 +125,7 @@ int main(int argc, char* argv[]) { out_edge_iterator ohi, end; - for(boost::tie(ohi,end) = out_edges(target(hd,P),P); ohi != end; ++ohi){ + for(std::tie(ohi,end) = out_edges(target(hd,P),P); ohi != end; ++ohi){ edge_descriptor ed = *ohi; halfedge_descriptor hd2 = halfedge(ed,P); std::cout << get(CGAL::vertex_point, P, target(hd2,P)) << std::endl; diff --git a/BGL/test/BGL/test_graph_traits.cpp b/BGL/test/BGL/test_graph_traits.cpp index 082469a58a9..19e03408f21 100644 --- a/BGL/test/BGL/test_graph_traits.cpp +++ b/BGL/test/BGL/test_graph_traits.cpp @@ -26,9 +26,9 @@ void test_halfedge_around_vertex_iterator(const Graph& g) { CGAL_GRAPH_TRAITS_MEMBERS(Graph); vertex_iterator vit, vend; - for(boost::tie(vit, vend) = vertices(g); vit != vend; ++vit) { + for(std::tie(vit, vend) = vertices(g); vit != vend; ++vit) { halfedge_around_target_iterator havit, havend; - for(boost::tie(havit, havend) = CGAL::halfedges_around_target(halfedge(*vit, g), g); + for(std::tie(havit, havend) = CGAL::halfedges_around_target(halfedge(*vit, g), g); havit != havend; ++havit) { assert(target(*havit, g) == *vit); @@ -47,11 +47,11 @@ void test_halfedge_around_face_iterator(const Graph& g) { CGAL_GRAPH_TRAITS_MEMBERS(Graph); face_iterator fit, fend; - for(boost::tie(fit, fend) = faces(g); fit != fend; ++fit) { + for(std::tie(fit, fend) = faces(g); fit != fend; ++fit) { halfedge_around_face_iterator hafit, hafend; - boost::tie(hafit, hafend) = CGAL::halfedges_around_face(halfedge(*fit, g), g); + std::tie(hafit, hafend) = CGAL::halfedges_around_face(halfedge(*fit, g), g); assert(std::distance(hafit, hafend) != 0); - for(boost::tie(hafit, hafend) = CGAL::halfedges_around_face(halfedge(*fit, g), g); hafit != hafend; ++hafit) { + for(std::tie(hafit, hafend) = CGAL::halfedges_around_face(halfedge(*fit, g), g); hafit != hafend; ++hafit) { assert(face(*hafit, g) == *fit); } } @@ -66,12 +66,12 @@ void test_halfedge_iterators(const G& g) // do we iterate as many as that? halfedge_iterator hb, he; - boost::tie(hb, he) = halfedges(g); + std::tie(hb, he) = halfedges(g); assert(static_cast(std::distance(hb, he)) == num_halfedges(g)); id_map ids; unsigned int count = 0; - for(boost::tie(hb, he) = halfedges(g); hb != he; ++hb) { + for(std::tie(hb, he) = halfedges(g); hb != he; ++hb) { std::pair r = ids.insert(get(boost::halfedge_index, g, *hb)); // unique? assert(r.second); @@ -92,12 +92,12 @@ void test_edge_iterators(const G& g) // do we iterate as many as that? edge_iterator eb, ee; - boost::tie(eb, ee) = edges(g); + std::tie(eb, ee) = edges(g); assert(static_cast(std::distance(eb, ee)) == num_edges(g)); id_map ids; unsigned int count = 0; - for(boost::tie(eb, ee) = edges(g); eb != ee; ++eb) { + for(std::tie(eb, ee) = edges(g); eb != ee; ++eb) { edge_descriptor e = *eb; std::pair r = ids.insert(get(boost::edge_index, g, e)); // unique? @@ -115,7 +115,7 @@ void test_vertex_iterators(const G& g) vertex_iterator vb, ve; std::size_t count = 0; - for(boost::tie(vb, ve) = vertices(g); vb != ve; ++vb){ + for(std::tie(vb, ve) = vertices(g); vb != ve; ++vb){ ++count; } @@ -125,7 +125,7 @@ void test_vertex_iterators(const G& g) id_map ids; count = 0; - for(boost::tie(vb, ve) = vertices(g); vb != ve; ++vb) { + for(std::tie(vb, ve) = vertices(g); vb != ve; ++vb) { std::pair r = ids.insert(get(boost::vertex_index, g, *vb)); assert(r.second); ++count; @@ -142,12 +142,12 @@ void test_out_edges(const G& g) typedef typename Traits::vertex_descriptor vertex_descriptor; vertex_iterator vb, ve; - for(boost::tie(vb, ve) = vertices(g); vb != ve; ++vb) { + for(std::tie(vb, ve) = vertices(g); vb != ve; ++vb) { id_map v_ids; vertex_descriptor around = *vb; out_edge_iterator oeb, oee; - for(boost::tie(oeb, oee) = out_edges(*vb, g); oeb != oee; ++oeb) { + for(std::tie(oeb, oee) = out_edges(*vb, g); oeb != oee; ++oeb) { vertex_descriptor t = target(*oeb, g); vertex_descriptor s = source(*oeb, g); assert(s != t); @@ -169,11 +169,11 @@ void test_in_edges(const G& g) typedef typename Traits::vertex_descriptor vertex_descriptor; vertex_iterator vb, ve; - for(boost::tie(vb, ve) = vertices(g); vb != ve; ++vb) { + for(std::tie(vb, ve) = vertices(g); vb != ve; ++vb) { id_map v_ids; vertex_descriptor around = *vb; in_edge_iterator ieb, iee; - for(boost::tie(ieb, iee) = in_edges(*vb, g); ieb != iee; ++ieb) { + for(std::tie(ieb, iee) = in_edges(*vb, g); ieb != iee; ++ieb) { vertex_descriptor t = target(*ieb, g); vertex_descriptor s = source(*ieb, g); assert(t == around); @@ -196,18 +196,18 @@ void test_in_out_edges(const G& g) // check that the sets of in out edges are the same vertex_iterator vb, ve; - for(boost::tie(vb, ve) = vertices(g); vb != ve; ++vb) { + for(std::tie(vb, ve) = vertices(g); vb != ve; ++vb) { id_map v_ids; std::vector in, out; in_edge_iterator ieb, iee; - for(boost::tie(ieb, iee) = in_edges(*vb, g); ieb != iee; ++ieb) { + for(std::tie(ieb, iee) = in_edges(*vb, g); ieb != iee; ++ieb) { std::pair r = v_ids.insert(get(boost::vertex_index, g, source(*ieb, g))); assert(r.second); in.push_back(source(*ieb, g)); } out_edge_iterator oeb, oee; - for(boost::tie(oeb, oee) = out_edges(*vb, g); oeb != oee; ++oeb) { + for(std::tie(oeb, oee) = out_edges(*vb, g); oeb != oee; ++oeb) { std::pair r = v_ids.insert(get(boost::vertex_index, g, target(*oeb, g))); // insertion must fail @@ -239,13 +239,13 @@ void test_adjacent_vertices(const G& g) vertex_descriptor v = *(vertices(g).begin()); adjacency_iterator vb, ve; - boost::tie(vb, ve) = adjacent_vertices(v, g); + std::tie(vb, ve) = adjacent_vertices(v, g); in_edge_iterator ieb, iee; - boost::tie(ieb, iee) = in_edges(v, g); + std::tie(ieb, iee) = in_edges(v, g); out_edge_iterator oeb, oee; - boost::tie(oeb, oee) = out_edges(v, g); + std::tie(oeb, oee) = out_edges(v, g); assert(std::distance(vb, ve) == std::distance(ieb, iee)); assert(std::distance(vb, ve) == std::distance(oeb, oee)); @@ -271,7 +271,7 @@ void test_edge_find(const G& g) typedef std::pair ret; edge_iterator eb, ee; - for(boost::tie(eb, ee) = edges(g); eb != ee; ++eb) { + for(std::tie(eb, ee) = edges(g); eb != ee; ++eb) { vertex_descriptor s = source(*eb, g); vertex_descriptor t = target(*eb, g); ret found = edge(s, t, g); @@ -293,14 +293,14 @@ void test_faces(const G& g) unsigned int count = 0; face_iterator fb, fe; - for(boost::tie(fb, fe) = faces(g); fb != fe; ++fb) { + for(std::tie(fb, fe) = faces(g); fb != fe; ++fb) { ++count; // reverse look-up halfedge_descriptor assoc = halfedge(*fb, g); assert(face(assoc, g) == *fb); // check the enclosure halfedge_around_face_iterator encb, ence; - for(boost::tie(encb, ence) = CGAL::halfedges_around_face(halfedge(*fb, g), g); encb != ence; ++encb) { + for(std::tie(encb, ence) = CGAL::halfedges_around_face(halfedge(*fb, g), g); encb != ence; ++encb) { assert(face(*encb, g) == *fb); } } diff --git a/Basic_viewer/examples/Basic_viewer/draw_surface_mesh_small_faces.cpp b/Basic_viewer/examples/Basic_viewer/draw_surface_mesh_small_faces.cpp index 5c98556e0cf..f7f677e9660 100644 --- a/Basic_viewer/examples/Basic_viewer/draw_surface_mesh_small_faces.cpp +++ b/Basic_viewer/examples/Basic_viewer/draw_surface_mesh_small_faces.cpp @@ -92,7 +92,7 @@ int main(int argc, char* argv[]) Mesh::Property_map faces_size; bool created; - boost::tie(faces_size, created)=sm.add_property_map("f:size",0.); + std::tie(faces_size, created)=sm.add_property_map("f:size",0.); assert(created); for(face_descriptor fd : sm.faces()) diff --git a/Boolean_set_operations_2/doc/Boolean_set_operations_2/PackageDescription.txt b/Boolean_set_operations_2/doc/Boolean_set_operations_2/PackageDescription.txt index a562dd4e48a..c36bb0cdd61 100644 --- a/Boolean_set_operations_2/doc/Boolean_set_operations_2/PackageDescription.txt +++ b/Boolean_set_operations_2/doc/Boolean_set_operations_2/PackageDescription.txt @@ -14,7 +14,6 @@ namespace ArrDirectionalTraits {} /*! \addtogroup PkgBooleanSetOperations2Ref -\todo check generated documentation \cgalPkgDescriptionBegin{2D Regularized Boolean Set-Operations,PkgBooleanSetOperations2} \cgalPkgPicture{Boolean_set_operations_2.png} \cgalPkgSummaryBegin diff --git a/Bounding_volumes/doc/Bounding_volumes/PackageDescription.txt b/Bounding_volumes/doc/Bounding_volumes/PackageDescription.txt index 7ec2b717b7b..6777f112a5b 100644 --- a/Bounding_volumes/doc/Bounding_volumes/PackageDescription.txt +++ b/Bounding_volumes/doc/Bounding_volumes/PackageDescription.txt @@ -3,7 +3,6 @@ /// \ingroup PkgBoundingVolumesRef /*! \addtogroup PkgBoundingVolumesRef -\todo check generated documentation \cgalPkgDescriptionBegin{Bounding Volumes,PkgBoundingVolumes} \cgalPkgPicture{minCircle.png} \cgalPkgSummaryBegin diff --git a/CGAL_ipelets/demo/CGAL_ipelets/alpha_shapes.cpp b/CGAL_ipelets/demo/CGAL_ipelets/alpha_shapes.cpp index f5423b0ab19..0aa825dcd77 100644 --- a/CGAL_ipelets/demo/CGAL_ipelets/alpha_shapes.cpp +++ b/CGAL_ipelets/demo/CGAL_ipelets/alpha_shapes.cpp @@ -85,7 +85,7 @@ void ASphapeIpelet::protected_run(int fn) Alpha_shape_2 A(LWP.begin(),LWP.end()); int alpha=-1; int nb_ret; - boost::tie(nb_ret,alpha)=request_value_from_user((boost::format("# Spectral critical value (0-%d)") % A.number_of_alphas()).str() ); + std::tie(nb_ret,alpha)=request_value_from_user((boost::format("# Spectral critical value (0-%d)") % A.number_of_alphas()).str() ); if (nb_ret == -1) return; if(alpha<0 || (std::size_t) alpha>A.number_of_alphas()){ diff --git a/CGAL_ipelets/demo/CGAL_ipelets/cone_spanners.cpp b/CGAL_ipelets/demo/CGAL_ipelets/cone_spanners.cpp index 97aad8daa24..826ef549364 100644 --- a/CGAL_ipelets/demo/CGAL_ipelets/cone_spanners.cpp +++ b/CGAL_ipelets/demo/CGAL_ipelets/cone_spanners.cpp @@ -86,7 +86,7 @@ void Cone_spanners_ipelet::protected_run(int fn) } int ret_val; - boost::tie(ret_val,number_of_cones)=request_value_from_user("Enter the number of cones"); + std::tie(ret_val,number_of_cones)=request_value_from_user("Enter the number of cones"); if (ret_val < 0) { print_error_message("Incorrect value"); return; @@ -129,7 +129,7 @@ void Cone_spanners_ipelet::protected_run(int fn) } } boost::graph_traits::edge_iterator ei, ei_end; - for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) { + for (std::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) { boost::graph_traits::edge_descriptor e = *ei; boost::graph_traits::vertex_descriptor u = source(e, g); boost::graph_traits::vertex_descriptor v = target(e, g); diff --git a/CGAL_ipelets/demo/CGAL_ipelets/generator.cpp b/CGAL_ipelets/demo/CGAL_ipelets/generator.cpp index 92104a15cff..0c35beae131 100644 --- a/CGAL_ipelets/demo/CGAL_ipelets/generator.cpp +++ b/CGAL_ipelets/demo/CGAL_ipelets/generator.cpp @@ -83,7 +83,7 @@ void generator::protected_run(int fn) origin= Kernel::Vector_2((bbox.xmin()+bbox.xmax())/2,(bbox.ymin()+bbox.ymax())/2); if (size<1){ size=200; - //boost::tie(ret_val,size)=request_value_from_user((boost::format("Size (default : %1%)") % size).str()); + //std::tie(ret_val,size)=request_value_from_user((boost::format("Size (default : %1%)") % size).str()); //if (ret_val == -1) return; //if (ret_val == 0) size=200; origin = Kernel::Vector_2(200,200); @@ -92,7 +92,7 @@ void generator::protected_run(int fn) int nbelements=30; - boost::tie(ret_val,nbelements)=request_value_from_user((boost::format("Number of elements (default : %1%)") % nbelements).str() ); + std::tie(ret_val,nbelements)=request_value_from_user((boost::format("Number of elements (default : %1%)") % nbelements).str() ); if (ret_val == -1) return; if (ret_val == 0) nbelements=30; diff --git a/CGAL_ipelets/demo/CGAL_ipelets/mesh_2.cpp b/CGAL_ipelets/demo/CGAL_ipelets/mesh_2.cpp index 8b4a70e49fe..f737113bbd6 100644 --- a/CGAL_ipelets/demo/CGAL_ipelets/mesh_2.cpp +++ b/CGAL_ipelets/demo/CGAL_ipelets/mesh_2.cpp @@ -94,7 +94,7 @@ void IpeletMesh2::protected_run(int fn) int y=static_cast( floor((bbox.max)().y()-(bbox.min)().y()) ); int ret_val; - boost::tie(ret_val,alpha)=request_value_from_user((boost::format("Max edge length (BBox %1%x%2%)") % x % y).str() ); + std::tie(ret_val,alpha)=request_value_from_user((boost::format("Max edge length (BBox %1%x%2%)") % x % y).str() ); if (ret_val == -1) return; if(alpha<0){ diff --git a/CGAL_ipelets/demo/CGAL_ipelets/mst.cpp b/CGAL_ipelets/demo/CGAL_ipelets/mst.cpp index 2d3f050d6cd..add1a29eb06 100644 --- a/CGAL_ipelets/demo/CGAL_ipelets/mst.cpp +++ b/CGAL_ipelets/demo/CGAL_ipelets/mst.cpp @@ -82,9 +82,9 @@ void mstIpelet::protected_run(int /*fn*/) vertex_iterator vit, ve; // Associate indices to the vertices int index = 0; - // boost::tie assigns the first and second element of the std::pair + // std::tie assigns the first and second element of the std::pair // returned by boost::vertices to the variables vit and ve - for(boost::tie(vit,ve)=boost::vertices(ft); vit!=ve; ++vit ){ + for(std::tie(vit,ve)=boost::vertices(ft); vit!=ve; ++vit ){ vertex_descriptor vd = *vit; vertex_id_map[vd] = index++; } diff --git a/CGAL_ipelets/demo/CGAL_ipelets/multi_delaunay.cpp b/CGAL_ipelets/demo/CGAL_ipelets/multi_delaunay.cpp index 9361353d575..56244ed708f 100644 --- a/CGAL_ipelets/demo/CGAL_ipelets/multi_delaunay.cpp +++ b/CGAL_ipelets/demo/CGAL_ipelets/multi_delaunay.cpp @@ -172,7 +172,7 @@ void MdelaunayIpelet::protected_run(int fn) if(fn==4 ||fn==9){ int order; int ret_val; - boost::tie(ret_val,order)=request_value_from_user("Enter order"); + std::tie(ret_val,order)=request_value_from_user("Enter order"); if (ret_val < 0){ print_error_message("Incorrect value"); return; diff --git a/CGAL_ipelets/demo/CGAL_ipelets/multi_regular.cpp b/CGAL_ipelets/demo/CGAL_ipelets/multi_regular.cpp index 3727c487040..731f8a1181f 100644 --- a/CGAL_ipelets/demo/CGAL_ipelets/multi_regular.cpp +++ b/CGAL_ipelets/demo/CGAL_ipelets/multi_regular.cpp @@ -80,7 +80,7 @@ void MregularIpelet::protected_run(int fn) if(fn==4 || fn==9){ int ret_val; - boost::tie(ret_val,order)=request_value_from_user("Enter order"); + std::tie(ret_val,order)=request_value_from_user("Enter order"); if (ret_val < 0){ print_error_message("Incorrect value"); return; diff --git a/CGAL_ipelets/demo/CGAL_ipelets/nearest_neighbor_graph.cpp b/CGAL_ipelets/demo/CGAL_ipelets/nearest_neighbor_graph.cpp index bf1954cf307..73f99255cb8 100644 --- a/CGAL_ipelets/demo/CGAL_ipelets/nearest_neighbor_graph.cpp +++ b/CGAL_ipelets/demo/CGAL_ipelets/nearest_neighbor_graph.cpp @@ -56,7 +56,7 @@ void nngIpelet::protected_run(int fn) int ret_val; int kNeighbors=1; - boost::tie(ret_val,kNeighbors)=request_value_from_user((boost::format("Number of nearest neighbors (default : k=%1%)") % kNeighbors).str() ); + std::tie(ret_val,kNeighbors)=request_value_from_user((boost::format("Number of nearest neighbors (default : k=%1%)") % kNeighbors).str() ); if (ret_val == -1) return; if (ret_val == 0) kNeighbors=1; diff --git a/CGAL_ipelets/demo/CGAL_ipelets/skeleton.cpp b/CGAL_ipelets/demo/CGAL_ipelets/skeleton.cpp index 71557e65968..6ba3994a584 100644 --- a/CGAL_ipelets/demo/CGAL_ipelets/skeleton.cpp +++ b/CGAL_ipelets/demo/CGAL_ipelets/skeleton.cpp @@ -124,7 +124,7 @@ void SkeletonIpelet::protected_run(int fn) if (fn==0 || fn==1) draw_straight_skeleton(*ss,max_edge); else{ - boost::tie(ret_val,dist)= + std::tie(ret_val,dist)= request_value_from_user( (boost::format("Offset value (BBox %1%x%2%)") % (bbox.xmax()-bbox.xmin()) % (bbox.ymax()-bbox.ymin())).str() ); diff --git a/Circular_kernel_2/doc/Circular_kernel_2/PackageDescription.txt b/Circular_kernel_2/doc/Circular_kernel_2/PackageDescription.txt index f596f9b0a1b..3092d4092ba 100644 --- a/Circular_kernel_2/doc/Circular_kernel_2/PackageDescription.txt +++ b/Circular_kernel_2/doc/Circular_kernel_2/PackageDescription.txt @@ -22,7 +22,6 @@ /*! \addtogroup PkgCircularKernel2Ref -\todo check generated documentation \cgalPkgDescriptionBegin{2D Circular Geometry Kernel,PkgCircularKernel2} \cgalPkgPicture{Boolean_operation_detail.png} \cgalPkgSummaryBegin diff --git a/Classification/include/CGAL/Classification/Feature/Vertical_dispersion.h b/Classification/include/CGAL/Classification/Feature/Vertical_dispersion.h index 2a5c8e6e9c7..53ef4ff89e5 100644 --- a/Classification/include/CGAL/Classification/Feature/Vertical_dispersion.h +++ b/Classification/include/CGAL/Classification/Feature/Vertical_dispersion.h @@ -127,7 +127,7 @@ public: continue; std::vector::iterator min_it, max_it; - boost::tie(min_it, max_it) + std::tie(min_it, max_it) = boost::minmax_element (hori.begin(), hori.end()); std::vector occupy (1 + (std::size_t)((*max_it - *min_it) / grid.resolution()), false); diff --git a/Classification/include/CGAL/Classification/Point_set_neighborhood.h b/Classification/include/CGAL/Classification/Point_set_neighborhood.h index c27c874f0c2..5a051426088 100644 --- a/Classification/include/CGAL/Classification/Point_set_neighborhood.h +++ b/Classification/include/CGAL/Classification/Point_set_neighborhood.h @@ -317,9 +317,8 @@ private: Point ref (std::floor(p.x() / voxel_size), std::floor(p.y() / voxel_size), std::floor(p.z() / voxel_size)); - typename std::map >::iterator it; - boost::tie (it, boost::tuples::ignore) - = grid.insert (std::make_pair (ref, std::vector())); + typename std::map >::iterator it + = grid.insert (std::make_pair (ref, std::vector())).first; it->second.push_back (i); } diff --git a/Classification/test/Classification/test_classification_point_set.cpp b/Classification/test/Classification/test_classification_point_set.cpp index 0a1dc9cee79..bb0cce75796 100644 --- a/Classification/test/Classification/test_classification_point_set.cpp +++ b/Classification/test/Classification/test_classification_point_set.cpp @@ -53,9 +53,9 @@ int main (int, char**) map_added = pts.add_normal_map().second; assert (map_added); normal_map = pts.normal_map(); - boost::tie (echo_map, map_added) = pts.add_property_map ("echo"); + std::tie (echo_map, map_added) = pts.add_property_map ("echo"); assert (map_added); - boost::tie (color_map, map_added) = pts.add_property_map ("color"); + std::tie (color_map, map_added) = pts.add_property_map ("color"); assert (map_added); for (std::size_t i = 0; i < 1000; ++ i) diff --git a/Combinatorial_map/include/CGAL/Cell_iterators.h b/Combinatorial_map/include/CGAL/Cell_iterators.h index 93104ba01e2..9f73b23f232 100644 --- a/Combinatorial_map/include/CGAL/Cell_iterators.h +++ b/Combinatorial_map/include/CGAL/Cell_iterators.h @@ -86,7 +86,8 @@ namespace CGAL { Tag_true>::value); CGAL_assertion(amap.is_whole_map_unmarked(mcell_mark_number)); - mark_cell(amap, adart, mcell_mark_number); + if(this->cont()) + { mark_cell(amap, adart, mcell_mark_number); } } /// Destructor. @@ -126,7 +127,8 @@ namespace CGAL { { unmark_treated_darts(); Ite::rewind(); - mark_cell(*this->mmap, (*this), mcell_mark_number); + if(this->cont()) + { mark_cell(*this->mmap, (*this), mcell_mark_number); } } /// Prefix ++ operator. @@ -199,7 +201,8 @@ namespace CGAL { static_assert(std::is_same::value); CGAL_assertion(amap.is_whole_map_unmarked(mmark_number)); - mark_cell(amap, adart, mmark_number); + if(this->cont()) + { mark_cell(amap, adart, mmark_number); } } /// Destructor. @@ -234,7 +237,8 @@ namespace CGAL { { unmark_treated_darts(); Ite::rewind(); - mark_cell(*this->mmap, (*this), mmark_number); + if(this->cont()) + { mark_cell(*this->mmap, (*this), mmark_number); } } /// Postfix ++ operator. @@ -253,7 +257,7 @@ namespace CGAL { this->mmap->is_marked((*this), mmark_number)); if (this->cont()) - mark_cell(*this->mmap, (*this), mmark_number); + { mark_cell(*this->mmap, (*this), mmark_number); } return *this; } @@ -306,7 +310,8 @@ namespace CGAL { static_assert(std::is_same::value); CGAL_assertion(amap.is_whole_map_unmarked(mmark_number)); - mark_cell(amap, (*this), mmark_number); + if(this->cont()) + { mark_cell(amap, (*this), mmark_number); } } /// Constructor with a dart in parameter (for end iterator). @@ -314,8 +319,8 @@ namespace CGAL { Base(amap, adart), mmark_number(amap.get_new_mark()) { - if (adart!=this->mmap->null_descriptor) - mark_cell(amap, (*this), mmark_number); + if (this->cont()) + { mark_cell(amap, (*this), mmark_number); } } /// Destructor. @@ -350,7 +355,8 @@ namespace CGAL { { unmark_treated_darts(); Base::rewind(); - mark_cell(*this->mmap, (*this), mmark_number); + if(this->cont()) + { mark_cell(*this->mmap, (*this), mmark_number); } } /// Postfix ++ operator. @@ -369,7 +375,7 @@ namespace CGAL { this->mmap->is_marked((*this), mmark_number)); if (this->cont()) - mark_cell(*this->mmap, (*this), mmark_number); + { mark_cell(*this->mmap, (*this), mmark_number); } return *this; } diff --git a/Combinatorial_map/include/CGAL/Compact_container_with_index.h b/Combinatorial_map/include/CGAL/Compact_container_with_index.h index b14fe21083a..7395743edb0 100644 --- a/Combinatorial_map/include/CGAL/Compact_container_with_index.h +++ b/Combinatorial_map/include/CGAL/Compact_container_with_index.h @@ -610,16 +610,16 @@ public: } iterator begin() { return empty()?end():iterator(this, 0, 0); } - iterator end() { return iterator(this, upper_bound()); } + iterator end() { return iterator(this, null_descriptor); } const_iterator begin() const { return empty()?end():const_iterator(this, 0, 0); } - const_iterator end() const { return const_iterator(this, upper_bound()); } + const_iterator end() const { return const_iterator(this, null_descriptor); } - reverse_iterator rbegin() { return reverse_iterator(end()); } + reverse_iterator rbegin() { return reverse_iterator(iterator(this, upper_bound())); } reverse_iterator rend() { return reverse_iterator(begin()); } const_reverse_iterator - rbegin() const { return const_reverse_iterator(end()); } + rbegin() const { return const_reverse_iterator(iterator(this, upper_bound())); } const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } @@ -878,7 +878,8 @@ namespace internal { CC_iterator_with_index(const iterator &it): m_ptr_to_cc(it.m_ptr_to_cc), m_index(it.m_index) { - CGAL_assertion(m_index<=m_ptr_to_cc->upper_bound()); + CGAL_assertion(m_index<=m_ptr_to_cc->upper_bound() || + m_index==DSC::null_descriptor); } // Same for assignment operator @@ -928,14 +929,16 @@ namespace internal { // It's either pointing to end(), or valid. CGAL_assertion_msg(m_ptr_to_cc!=nullptr, "Incrementing a singular iterator or an empty container iterator ?"); - CGAL_assertion_msg(m_indexupper_bound(), - "Incrementing end() ?"); + CGAL_assertion_msg(m_indexupper_bound() && + m_index!=DSC::null_descriptor, + "Incrementing end() ?"); // If it's not end(), then it's valid, we can do ++. do { ++m_index; } while(m_indexupper_bound() && (!m_ptr_to_cc->is_used(m_index))); + if(m_index==m_ptr_to_cc->upper_bound()) { m_index=DSC::null_descriptor; } } void decrement() @@ -969,7 +972,7 @@ namespace internal { pointer operator->() const { return &((*m_ptr_to_cc)[m_index]); } - bool is_end() const { return m_index>=m_ptr_to_cc->upper_bound(); } + bool is_end() const { return m_index==DSC::null_descriptor; } // Can itself be used for bit-squatting. size_type for_compact_container() const diff --git a/Combinatorial_map/test/Combinatorial_map/CMakeLists.txt b/Combinatorial_map/test/Combinatorial_map/CMakeLists.txt index 271451857f9..028f26c9d93 100644 --- a/Combinatorial_map/test/Combinatorial_map/CMakeLists.txt +++ b/Combinatorial_map/test/Combinatorial_map/CMakeLists.txt @@ -12,6 +12,8 @@ set(hfiles Combinatorial_map_2_test.h Combinatorial_map_3_test.h # create a target per cppfile create_single_source_cgal_program(Combinatorial_map_test.cpp ${hfiles}) create_single_source_cgal_program(Combinatorial_map_copy_test.cpp ${hfiles}) +create_single_source_cgal_program(cmap_test_split_attribute.cpp) +create_single_source_cgal_program(Combinatorial_map_empty_it_test.cpp) # Same targets, defining USE_COMPACT_CONTAINER_WITH_INDEX to test index version add_executable(Combinatorial_map_test_index Combinatorial_map_test.cpp ${hfiles}) @@ -24,7 +26,10 @@ target_compile_definitions(Combinatorial_map_copy_test_index PRIVATE USE_COMPACT target_link_libraries(Combinatorial_map_copy_test_index PRIVATE CGAL::CGAL CGAL::Data) cgal_add_compilation_test(Combinatorial_map_copy_test_index) -create_single_source_cgal_program(cmap_test_split_attribute.cpp) +add_executable(Combinatorial_map_empty_it_test_index Combinatorial_map_empty_it_test.cpp) +target_compile_definitions(Combinatorial_map_empty_it_test_index PRIVATE USE_COMPACT_CONTAINER_WITH_INDEX) +target_link_libraries(Combinatorial_map_empty_it_test_index PRIVATE CGAL::CGAL CGAL::Data) +cgal_add_compilation_test(Combinatorial_map_empty_it_test_index) # Link with OpenMesh if possible find_package(OpenMesh QUIET) diff --git a/Combinatorial_map/test/Combinatorial_map/Combinatorial_map_empty_it_test.cpp b/Combinatorial_map/test/Combinatorial_map/Combinatorial_map_empty_it_test.cpp new file mode 100644 index 00000000000..a7364439192 --- /dev/null +++ b/Combinatorial_map/test/Combinatorial_map/Combinatorial_map_empty_it_test.cpp @@ -0,0 +1,53 @@ +#include + +struct Map_3_dart_items_3: public CGAL::Generic_map_min_items +{ +#ifdef USE_COMPACT_CONTAINER_WITH_INDEX + typedef CGAL::Tag_true Use_index; +#endif +}; + +using Map3=CGAL::Combinatorial_map<3, Map_3_dart_items_3>; +Map3 m; + +template +bool test_empty_it(const Range& r, const std::string& txt) +{ + bool res=true; + if(r.size()!=0) + { + std::cout<<"[ERROR "<(m.darts(), "Dart_range"); + res=res && test_empty_it + (const_cast(m).darts(), "Dart_const_range"); + + res=res && test_empty_it> + (m.one_dart_per_cell<3>(), "One_dart_per_cell_range<0>"); + + res=res && test_empty_it> + (const_cast(m).one_dart_per_cell<3>(), + "One_dart_per_cell_const_range<0>"); + + if(!res) + { return(EXIT_FAILURE); } + + std::cout<<"ALL SUCCESS."<::edge_iterator ei, ei_end; - for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) { + for (std::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) { boost::graph_traits::edge_descriptor e = *ei; boost::graph_traits::vertex_descriptor u = source(e, g); boost::graph_traits::vertex_descriptor v = target(e, g); diff --git a/Cone_spanners_2/include/CGAL/Construct_theta_graph_2.h b/Cone_spanners_2/include/CGAL/Construct_theta_graph_2.h index 3d1ebc15efb..5a6a73299fb 100644 --- a/Cone_spanners_2/include/CGAL/Construct_theta_graph_2.h +++ b/Cone_spanners_2/include/CGAL/Construct_theta_graph_2.h @@ -193,7 +193,7 @@ protected: const Less_by_direction orderMid(g, cw90(bisector_direction)); typename Graph_::vertex_iterator vit, ve; - boost::tie(vit, ve) = boost::vertices(g); + std::tie(vit, ve) = boost::vertices(g); // Step 1: Sort S according to order induced by D1 std::vector S(vit, ve); @@ -218,7 +218,7 @@ protected: typename Graph_::edge_descriptor existing_e; bool existing; // check whether the edge already exists - boost::tie(existing_e, existing)=boost::edge(*it, *ri, g); + std::tie(existing_e, existing)=boost::edge(*it, *ri, g); if (!existing) boost::add_edge(*it, *ri, g); } diff --git a/Cone_spanners_2/include/CGAL/Construct_yao_graph_2.h b/Cone_spanners_2/include/CGAL/Construct_yao_graph_2.h index 7f6fdb16a17..58090bdd506 100644 --- a/Cone_spanners_2/include/CGAL/Construct_yao_graph_2.h +++ b/Cone_spanners_2/include/CGAL/Construct_yao_graph_2.h @@ -179,7 +179,7 @@ protected: const Less_by_direction orderD2 (g, cwBound); typename Graph_::vertex_iterator vit, ve; - boost::tie(vit, ve) = boost::vertices(g); + std::tie(vit, ve) = boost::vertices(g); // Step 1: Sort S according to order induced by D1 std::vector S(vit, ve); @@ -205,7 +205,7 @@ protected: typename Graph_::edge_descriptor existing_e; bool existing; // check whether the edge already exists - boost::tie(existing_e, existing)=boost::edge(*it, *min, g); + std::tie(existing_e, existing)=boost::edge(*it, *min, g); if (!existing) boost::add_edge(*it, *min, g); } diff --git a/Cone_spanners_2/include/CGAL/gnuplot_output_2.h b/Cone_spanners_2/include/CGAL/gnuplot_output_2.h index d2cb402e37a..ac3fcebb911 100644 --- a/Cone_spanners_2/include/CGAL/gnuplot_output_2.h +++ b/Cone_spanners_2/include/CGAL/gnuplot_output_2.h @@ -109,7 +109,7 @@ std::string gnuplot_edge_list (const Graph& g) ss << std::fixed; // Use fixed floating-point notation typename Graph::edge_iterator eit, ee; - for (boost::tie(eit, ee) = boost::edges(g); eit != ee; ++eit) { + for (std::tie(eit, ee) = boost::edges(g); eit != ee; ++eit) { typename Graph::vertex_descriptor src = boost::source(*eit, g); typename Graph::vertex_descriptor end = boost::target(*eit, g); ss << "set arrow from "; @@ -129,7 +129,7 @@ std::string gnuplot_vertex_list(const Graph& g) { ss << std::fixed; typename Graph::vertex_iterator vit, ve; - for (boost::tie(vit, ve) = boost::vertices(g); vit != ve; ++vit) { + for (std::tie(vit, ve) = boost::vertices(g); vit != ve; ++vit) { ss << to_double(g[*vit].x()) << " " << to_double(g[*vit].y()) << std::endl; } return ss.str(); diff --git a/Convex_hull_3/include/CGAL/convex_hull_3.h b/Convex_hull_3/include/CGAL/convex_hull_3.h index eac14144073..b2089fdc53c 100644 --- a/Convex_hull_3/include/CGAL/convex_hull_3.h +++ b/Convex_hull_3/include/CGAL/convex_hull_3.h @@ -963,7 +963,7 @@ convex_hull_3(InputIterator first, InputIterator beyond, } CGAL_assertion(num_vertices(P)>=3); typename boost::graph_traits::vertex_iterator b,e; - boost::tie(b,e) = vertices(P); + std::tie(b,e) = vertices(P); if (num_vertices(P) == 3){ typename boost::property_map::type vpmap = get(CGAL::vertex_point, P); typedef typename Traits::Triangle_3 Triangle_3; diff --git a/Convex_hull_3/include/CGAL/convexity_check_3.h b/Convex_hull_3/include/CGAL/convexity_check_3.h index cd18bf1d394..b895641d98c 100644 --- a/Convex_hull_3/include/CGAL/convexity_check_3.h +++ b/Convex_hull_3/include/CGAL/convexity_check_3.h @@ -83,7 +83,7 @@ bool is_strongly_convex_3(const Polyhedron& P, const Traits& traits) typename boost::property_map::const_type vpmap = get(CGAL::vertex_point, P); vertex_iterator v_it, v_it_e; - boost::tie(v_it, v_it_e) = vertices(P); + std::tie(v_it, v_it_e) = vertices(P); if (v_it == v_it_e) return false; @@ -97,7 +97,7 @@ bool is_strongly_convex_3(const Polyhedron& P, const Traits& traits) typename Traits::Coplanar_3 coplanar = traits.coplanar_3_object(); face_iterator f_it, f_it_e; - boost::tie(f_it, f_it_e) = faces(P); + std::tie(f_it, f_it_e) = faces(P); Point_3 p; Point_3 q; Point_3 r; diff --git a/Convex_hull_d/doc/Convex_hull_d/PackageDescription.txt b/Convex_hull_d/doc/Convex_hull_d/PackageDescription.txt index a1a4b8a3de1..bf45d7bfeb3 100644 --- a/Convex_hull_d/doc/Convex_hull_d/PackageDescription.txt +++ b/Convex_hull_d/doc/Convex_hull_d/PackageDescription.txt @@ -3,7 +3,6 @@ /// \ingroup PkgConvexHullDRef /*! \addtogroup PkgConvexHullDRef -\todo check generated documentation \cgalPkgDescriptionBegin{dD Convex Hulls and Delaunay Triangulations,PkgConvexHullD} \cgalPkgPicture{convex_hull_d-teaser.png} \cgalPkgSummaryBegin diff --git a/Distance_3/benchmark/Distance_3/CMakeLists.txt b/Distance_3/benchmark/Distance_3/CMakeLists.txt new file mode 100644 index 00000000000..3cc6ca18f7d --- /dev/null +++ b/Distance_3/benchmark/Distance_3/CMakeLists.txt @@ -0,0 +1,23 @@ +# Created by the script cgal_create_cmake_script +# This is the CMake script for compiling a CGAL application. + +cmake_minimum_required(VERSION 3.12...3.31) +project(Distance_3_Benchs) + +find_package(CGAL REQUIRED) + +if(MSVC) + # Turn off a VC++ warning on a potential division by zero + # in Cartesian_kernel/include/CGAL/constructions/kernel_ftC3.h + # where CGAL_assume() does not help + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4723") +endif() + +# create a target per cppfile +file( + GLOB cppfiles + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) +foreach(cppfile ${cppfiles}) + create_single_source_cgal_program("${cppfile}") +endforeach() diff --git a/Distance_3/benchmark/Distance_3/bench_compare_distance_3.cpp b/Distance_3/benchmark/Distance_3/bench_compare_distance_3.cpp new file mode 100644 index 00000000000..d7005a594ab --- /dev/null +++ b/Distance_3/benchmark/Distance_3/bench_compare_distance_3.cpp @@ -0,0 +1,297 @@ +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include + +// #define CGAL_USE_GTE_AS_SANITY_CHECK +#ifdef CGAL_USE_GTE_AS_SANITY_CHECK +#include +#include +#endif + +#include +#include + +struct randomint +{ + randomint() ; + int get() const { return sequence[cur]; } + int next() { + cur = (cur + 1) % 11; + return get(); + } + +private: + int sequence[11]; + int cur; +}; + +inline randomint::randomint() +{ + cur = 0; + sequence[0] = 19; + sequence[1] = 5; + sequence[2] = 17; + sequence[3] = 13; + sequence[4] = 29; + sequence[5] = 2; + sequence[6] = 23; + sequence[7] = 31; + sequence[8] = 3; + sequence[9] = 37; + sequence[10] = 11; +} + +randomint ri; + +template +struct Test +{ + typedef typename K::RT RT; + typedef typename K::FT FT; + typedef typename K::Comparison_result Comparison_result; + typedef typename K::Point_3 P; + typedef typename K::Segment_3 S; + typedef typename K::Vector_3 V; + typedef typename K::Ray_3 R; + typedef typename K::Line_3 L; + typedef typename K::Triangle_3 T; + typedef typename K::Plane_3 Pl; + typedef typename K::Tetrahedron_3 Tet; + typedef typename K::Iso_cuboid_3 Cub; + +private: + CGAL::Random& r; + double m = 0, M = 1; + +public: + Test(CGAL::Random& r) : r(r) { } + +private: + inline RT to_nt(int d) const { return RT(d); } + + P p(int x, int y, int z) + { + int w = ri.next(); + return P(to_nt(x*w), to_nt(y*w), to_nt(z*w), to_nt(w)); + } + + P random_point() const + { + return P(FT(r.get_double(m, M)), FT(r.get_double(m, M)), FT(r.get_double(m, M))); + } + + Pl pl(int a, int b, int c, int d) + { + int w = ri.next(); + return Pl(to_nt(a*w), to_nt(b*w), to_nt(c*w), to_nt(d*w)); + } + + +private: + void P_P(int N, FT d2) + { + std::cout << "Point - Point" << std::endl; + CGAL::Real_timer t; + t.start(); + for(int i=0; i(F& f){ + + }; + P_P(10000000, FT(0.1)); + P_S(1000000, FT(0.1)); + + std::cout << std::endl; + P_T(500000, FT(10)); + P_T(500000, FT(0.1)); + P_T(500000, FT(0.001)); + std::cout << std::endl; + + P_Tet(200000, FT(0.1)); + + std::cout << std::endl; + S_S(500000, FT(10)); + S_S(500000, FT(0.1)); + S_S(500000, FT(0.001)); + std::cout << std::endl; + S_L(500000, FT(0.1)); + + std::cout << std::endl; + T_T(500000, FT(10)); + T_T(500000, FT(0.1)); + T_T(500000, FT(0.001)); + std::cout << std::endl; + std::cout << std::endl; + } +}; + +int main(int argc, char** argv) +{ + std::cout.precision(17); + std::cerr.precision(17); + + std::cout << "3D Distance tests" << std::endl; + + CGAL::Random rp; + CGAL::Random r(argc==1?rp.get_seed():std::stoi(argv[1])); + std::cout << "random seed = " << r.get_seed() << std::endl; + + Test >(r).run(); + Test >(r).run(); +// Test > >(r).run(); + + // Test >(r).run(); + + Test(r).run(); + + Test(r).run(); + + std::cout << "Done!" << std::endl; + + return EXIT_SUCCESS; +} diff --git a/Distance_3/benchmark/Distance_3/bench_distance_3.cpp b/Distance_3/benchmark/Distance_3/bench_distance_3.cpp new file mode 100644 index 00000000000..641bd01f0ae --- /dev/null +++ b/Distance_3/benchmark/Distance_3/bench_distance_3.cpp @@ -0,0 +1,280 @@ +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include + +// #define CGAL_USE_GTE_AS_SANITY_CHECK +#ifdef CGAL_USE_GTE_AS_SANITY_CHECK +#include +#include +#endif + +#include +#include + +struct randomint +{ + randomint() ; + int get() const { return sequence[cur]; } + int next() { + cur = (cur + 1) % 11; + return get(); + } + +private: + int sequence[11]; + int cur; +}; + +inline randomint::randomint() +{ + cur = 0; + sequence[0] = 19; + sequence[1] = 5; + sequence[2] = 17; + sequence[3] = 13; + sequence[4] = 29; + sequence[5] = 2; + sequence[6] = 23; + sequence[7] = 31; + sequence[8] = 3; + sequence[9] = 37; + sequence[10] = 11; +} + +randomint ri; + +template +struct Test +{ + typedef typename K::RT RT; + typedef typename K::FT FT; + typedef typename K::Comparison_result Comparison_result; + typedef typename K::Point_3 P; + typedef typename K::Segment_3 S; + typedef typename K::Vector_3 V; + typedef typename K::Ray_3 R; + typedef typename K::Line_3 L; + typedef typename K::Triangle_3 T; + typedef typename K::Plane_3 Pl; + typedef typename K::Tetrahedron_3 Tet; + typedef typename K::Iso_cuboid_3 Cub; + +private: + CGAL::Random& r; + double m = 0, M = 1; + +public: + Test(CGAL::Random& r) : r(r) { } + +private: + inline RT to_nt(int d) const { return RT(d); } + + P p(int x, int y, int z) + { + int w = ri.next(); + return P(to_nt(x*w), to_nt(y*w), to_nt(z*w), to_nt(w)); + } + + P random_point() const + { + return P(FT(r.get_double(m, M)), FT(r.get_double(m, M)), FT(r.get_double(m, M))); + } + + Pl pl(int a, int b, int c, int d) + { + int w = ri.next(); + return Pl(to_nt(a*w), to_nt(b*w), to_nt(c*w), to_nt(d*w)); + } + + +private: + void P_P(int N) + { + std::cout << "Point - Point" << std::endl; + CGAL::Real_timer t; + t.start(); + for(int i=0; i +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include + +#include +#include + +template +class Old_compare_squared_distance_3 +{ + typedef typename K::FT FT; +public: + typedef typename K::Comparison_result result_type; + + template + CGAL::Needs_FT + operator()(const T1& p, const T2& q, const FT& d2) const + { + return CGAL::compare(CGAL::internal::squared_distance(p, q, K()), d2); + } +}; + +template +struct Test +{ + typedef typename K::RT RT; + typedef typename K::FT FT; + typedef typename K::Comparison_result Comparison_result; + typedef typename K::Point_3 P; + typedef typename K::Segment_3 S; + typedef typename K::Vector_3 V; + typedef typename K::Ray_3 R; + typedef typename K::Line_3 L; + typedef typename K::Triangle_3 T; + typedef typename K::Plane_3 Pl; + typedef typename K::Tetrahedron_3 Tet; + typedef typename K::Iso_cuboid_3 Cub; + + typedef std::vector >::iterator Iterator; + typedef CGAL::Box_intersection_d::Box_with_handle_d CBox; + + size_t nb_closed_pairs; + size_t nb_tested_pairs; + +public: + Test() : nb_closed_pairs(0), nb_tested_pairs(0){ } + + void close_triangles(std::vector

&points, std::vector >& triangles, FT d2){ + std::vector< CBox > boxes; + auto extend_bbox3=[&](const Iterator it, FT& d2){ + CGAL::Bbox_3 bb = points[(*it)[0]].bbox()+points[(*it)[1]].bbox()+points[(*it)[2]].bbox(); + return CGAL::Bbox_3(bb.xmin(),bb.ymin(),bb.zmin(),bb.xmax()+CGAL::to_double(d2),bb.ymax()+CGAL::to_double(d2),bb.zmax()+CGAL::to_double(d2)); + }; + + auto callback=[&](const CBox &ba, const CBox &bb){ + boost::container::small_vector &a = *(ba.handle()); + boost::container::small_vector &b = *(bb.handle()); + + std::sort(a.begin(), a.end()); + std::sort(b.begin(), b.end()); + std::vector v; + std::set_intersection(a.begin(), a.end(), b.begin(), b.end(),std::back_inserter(v)); + + if(v.size()!=0) //they have common vertices + return; + + nb_tested_pairs++; + if(nb_tested_pairs>1000000) + return; + + T tr1(points[a[0]], points[a[1]], points[a[2]]); + T tr2(points[b[0]], points[b[1]], points[b[2]]); + bool comp = K().compare_squared_distance_3_object()(tr1, tr2, d2)!=CGAL::LARGER; + if(comp) + { + nb_closed_pairs++; + } + }; + + for(Iterator it=triangles.begin(); it!=triangles.end(); ++it) + boxes.emplace_back(extend_bbox3(it, d2), it); + + CGAL::box_self_intersection_d(boxes.begin(), boxes.end(), callback); + } + + void run(std::string filename, FT d2) + { + nb_closed_pairs=0; + std::vector

input_points; + std::vector> input_triangles; + + if (!CGAL::IO::read_polygon_soup(filename, input_points, input_triangles)) + { + std::cerr << "Cannot read " << filename << "\n"; + return; + } + CGAL::Real_timer t; + t.start(); + close_triangles(input_points, input_triangles, d2); + t.stop(); + std::cout << "#points = " << input_points.size() << " and #triangles = " << input_triangles.size() << " has " << nb_closed_pairs << " pairs at squared distance " << d2 << " in " << t.time() << " sec." << std::endl; + } +}; + +int main(int argc, char** argv) +{ + const std::string filename = argc == 1 ? CGAL::data_file_path("meshes/elephant.off") + : std::string(argv[1]); + + // const std::string out_file = argc <= 2 ? "rounded_soup.off" + // : std::string(argv[2]); + + std::cout.precision(17); + std::cerr.precision(17); + + std::cout << "3D Distance bench" << std::endl; + + std::vector::Point_3> input_points; + std::vector> input_triangles; + + if (!CGAL::IO::read_polygon_soup(filename, input_points, input_triangles)) + { + std::cerr << "Cannot read " << filename << "\n"; + return 1; + } + CGAL::Bbox_3 bb = CGAL::bbox_3(input_points.begin(), input_points.end()); + double max= (std::max)((std::max)(bb.xmax()-bb.xmin(),bb.ymax()-bb.ymin()),bb.zmax()-bb.zmin()); + +// Test >().run(filename); +// Test >().run(filename); +// Test > >(r).run(); + + // Test >(r).run(); + + // Test().run(filename, max*max); + // Test().run(filename, 10*max*max/input_points.size()); + + double average_length=0; + double min_sq_length=CGAL::squared_distance(input_points[input_triangles[0][0]],input_points[input_triangles[0][1]]); + for(auto &tr: input_triangles){ + for(int i=0; i<3; ++i){ + double l=CGAL::squared_distance(input_points[tr[i]], input_points[tr[(i+1)%3]]); + min_sq_length=(std::min)(min_sq_length, l); + average_length+=std::sqrt(l); + } + } + average_length/=(3*input_triangles.size()); + + std::cout << "Simple_Cartesian" << std::endl; + Test >().run(filename, average_length*average_length/256); + Test >().run(filename, min_sq_length*4); + + // Equivalent to EPECK since there are only predicates + // Test().run(filename, 100*max/input_points.size()); + // std::cout << "EPICK" << std::endl; + // Test().run(filename, average_length*average_length/256); + // Test().run(filename, min_sq_length*4); + + std::cout << "EPECK" << std::endl; + Test().run(filename, average_length*average_length/256); + Test().run(filename, min_sq_length*4); + + std::cout << "Done!" << std::endl; + + return EXIT_SUCCESS; +} diff --git a/Distance_3/include/CGAL/Distance_3/Line_3_Line_3.h b/Distance_3/include/CGAL/Distance_3/Line_3_Line_3.h index 03495be04fa..a27c6b7aaa6 100644 --- a/Distance_3/include/CGAL/Distance_3/Line_3_Line_3.h +++ b/Distance_3/include/CGAL/Distance_3/Line_3_Line_3.h @@ -45,17 +45,18 @@ squared_distance(const typename K::Line_3& line1, return squared_distance_to_plane(normal, diff, k); } -} // namespace internal - template -inline -typename K::FT -squared_distance(const Line_3& line1, - const Line_3& line2) +typename K::Comparison_result +compare_squared_distance(const typename K::Line_3& line1, + const typename K::Line_3& line2, + const K& k, + const typename K::FT& d2) { - return K().compute_squared_distance_3_object()(line1, line2); + return compare(squared_distance(line1,line2,k),d2); } +} // namespace internal + } // namespace CGAL #endif // CGAL_DISTANCE_3_LINE_3_LINE_3_H diff --git a/Distance_3/include/CGAL/Distance_3/Line_3_Plane_3.h b/Distance_3/include/CGAL/Distance_3/Line_3_Plane_3.h index 6bb4d125c59..df4a14ef8ed 100644 --- a/Distance_3/include/CGAL/Distance_3/Line_3_Plane_3.h +++ b/Distance_3/include/CGAL/Distance_3/Line_3_Plane_3.h @@ -61,26 +61,28 @@ squared_distance(const typename K::Plane_3& pl, return squared_distance(l, pl, k); } +template +inline typename K::Comparison_result +compare_squared_distance(const typename K::Line_3& l, + const typename K::Plane_3& pl, + const K& k, + const typename K::FT& d2) +{ + return compare(squared_distance(l, pl, k), d2); +} + +template +inline typename K::Comparison_result +compare_squared_distance(const typename K::Plane_3& pl, + const typename K::Line_3& l, + const K& k, + const typename K::FT& d2) +{ + return compare_squared_distance(l, pl, k, d2); +} + } // namespace internal -template -inline -typename K::FT -squared_distance(const Line_3& line, - const Plane_3& plane) -{ - return K().compute_squared_distance_3_object()(line, plane); -} - -template -inline -typename K::FT -squared_distance(const Plane_3& plane, - const Line_3& line) -{ - return K().compute_squared_distance_3_object()(plane, line); -} - } // namespace CGAL #endif // CGAL_DISTANCE_3_LINE_3_PLANE_3_H diff --git a/Distance_3/include/CGAL/Distance_3/Plane_3_Plane_3.h b/Distance_3/include/CGAL/Distance_3/Plane_3_Plane_3.h index d18fb366b7f..6331d938d82 100644 --- a/Distance_3/include/CGAL/Distance_3/Plane_3_Plane_3.h +++ b/Distance_3/include/CGAL/Distance_3/Plane_3_Plane_3.h @@ -39,17 +39,18 @@ squared_distance(const typename K::Plane_3& plane1, return sq_dist(plane1.point(), plane2); } -} // namespace internal - template -inline -typename K::FT -squared_distance(const Plane_3& plane1, - const Plane_3& plane2) +inline typename K::Comparison_result +compare_squared_distance(const typename K::Plane_3& plane1, + const typename K::Plane_3& plane2, + const K& k, + const typename K::FT& d2) { - return K().compute_squared_distance_3_object()(plane1, plane2); + return compare(squared_distance(plane1,plane2,k), d2); } +} // namespace internal + } // namespace CGAL #endif // CGAL_DISTANCE_3_PLANE_3_PLANE_3_H diff --git a/Distance_3/include/CGAL/Distance_3/Point_3_Line_3.h b/Distance_3/include/CGAL/Distance_3/Point_3_Line_3.h index 0d1527c48a7..b265894c910 100644 --- a/Distance_3/include/CGAL/Distance_3/Point_3_Line_3.h +++ b/Distance_3/include/CGAL/Distance_3/Point_3_Line_3.h @@ -66,26 +66,30 @@ squared_distance(const typename K::Line_3& line, return squared_distance(pt, line, k); } +template +inline +typename K::Comparison_result +compare_squared_distance(const typename K::Point_3& pt, + const typename K::Line_3& line, + const K& k, + const typename K::FT& d2) +{ + return compare(squared_distance(pt, line, k), d2); +} + +template +inline +typename K::Comparison_result +compare_squared_distance(const typename K::Line_3& line, + const typename K::Point_3& pt, + const K& k, + const typename K::FT& d2) +{ + return compare_squared_distance(pt, line, k, d2); +} + } // namespace internal -template -inline -typename K::FT -squared_distance(const Point_3& pt, - const Line_3& line) -{ - return K().compute_squared_distance_3_object()(pt, line); -} - -template -inline -typename K::FT -squared_distance(const Line_3& line, - const Point_3& pt) -{ - return K().compute_squared_distance_3_object()(line, pt); -} - } // namespace CGAL #endif // CGAL_DISTANCE_3_POINT_3_LINE_3_H diff --git a/Distance_3/include/CGAL/Distance_3/Point_3_Plane_3.h b/Distance_3/include/CGAL/Distance_3/Point_3_Plane_3.h index 7544a72d963..921b13a446f 100644 --- a/Distance_3/include/CGAL/Distance_3/Point_3_Plane_3.h +++ b/Distance_3/include/CGAL/Distance_3/Point_3_Plane_3.h @@ -48,26 +48,26 @@ squared_distance(const typename K::Plane_3& plane, return squared_distance(pt, plane, k); } -} // namespace internal - template -inline -typename K::FT -squared_distance(const Point_3& pt, - const Plane_3& plane) +inline typename K::Comparison_result +compare_squared_distance(const typename K::Point_3& pt, + const typename K::Plane_3& plane, + const K& k, + const typename K::FT& d2) { - return K().compute_squared_distance_3_object()(pt, plane); + return compare(squared_distance(pt, plane, k), d2); } template -inline -typename K::FT -squared_distance(const Plane_3& plane, - const Point_3& pt) +inline typename K::Comparison_result +compare_squared_distance(const typename K::Plane_3& plane, + const typename K::Point_3& pt, + const K& k, + const typename K::FT& d2) { - return K().compute_squared_distance_3_object()(plane, pt); + return compare_squared_distance(pt, plane, k, d2); } -} // namespace CGAL +} } // namespace CGAL::internal #endif // CGAL_DISTANCE_3_POINT_3_PLANE_3_H diff --git a/Distance_3/include/CGAL/Distance_3/Point_3_Point_3.h b/Distance_3/include/CGAL/Distance_3/Point_3_Point_3.h index 6b307e571c7..4d7de336e31 100644 --- a/Distance_3/include/CGAL/Distance_3/Point_3_Point_3.h +++ b/Distance_3/include/CGAL/Distance_3/Point_3_Point_3.h @@ -32,17 +32,19 @@ squared_distance(const typename K::Point_3& pt1, return k.compute_squared_distance_3_object()(pt1, pt2); } -} // namespace internal - template inline -typename K::FT -squared_distance(const Point_3& pt1, - const Point_3& pt2) +typename K::Comparison_result +compare_squared_distance(const typename K::Point_3& pt1, + const typename K::Point_3& pt2, + const K& k, + const typename K::FT& d2) { - return internal::squared_distance(pt1, pt2, K()); + return compare(k.compute_squared_distance_3_object()(pt1, pt2), d2); } +} // namespace internal + } // namespace CGAL #endif // CGAL_DISTANCE_3_POINT_3_POINT_3_H diff --git a/Distance_3/include/CGAL/Distance_3/Point_3_Ray_3.h b/Distance_3/include/CGAL/Distance_3/Point_3_Ray_3.h index 7eff899b0eb..bb4195cbb75 100644 --- a/Distance_3/include/CGAL/Distance_3/Point_3_Ray_3.h +++ b/Distance_3/include/CGAL/Distance_3/Point_3_Ray_3.h @@ -87,26 +87,28 @@ squared_distance(const typename K::Ray_3& ray, return squared_distance(pt, ray, k); } +template +typename K::Comparison_result +compare_squared_distance(const typename K::Point_3& pt, + const typename K::Ray_3& ray, + const K& k, + const typename K::FT &d2) +{ + return compare(squared_distance(pt, ray, k), d2); +} + +template +typename K::Comparison_result +compare_squared_distance(const typename K::Ray_3& ray, + const typename K::Point_3& pt, + const K& k, + const typename K::FT &d2) +{ + return compare_squared_distance(pt, ray, k, d2); +} + } // namespace internal -template -inline -typename K::FT -squared_distance(const Point_3& pt, - const Ray_3& ray) -{ - return K().compute_squared_distance_3_object()(pt, ray); -} - -template -inline -typename K::FT -squared_distance(const Ray_3& ray, - const Point_3& pt) -{ - return K().compute_squared_distance_3_object()(ray, pt); -} - } // namespace CGAL #endif // CGAL_DISTANCE_3_POINT_3_RAY_3_H diff --git a/Distance_3/include/CGAL/Distance_3/Point_3_Segment_3.h b/Distance_3/include/CGAL/Distance_3/Point_3_Segment_3.h index 554c0a58d2d..07f79bfd912 100644 --- a/Distance_3/include/CGAL/Distance_3/Point_3_Segment_3.h +++ b/Distance_3/include/CGAL/Distance_3/Point_3_Segment_3.h @@ -79,6 +79,7 @@ squared_distance(const typename K::Point_3& pt, typedef typename K::Vector_3 Vector_3; typename K::Construct_vector_3 vector = k.construct_vector_3_object(); + typename K::Compute_squared_distance_3 sq_dist = k.compute_squared_distance_3_object(); // assert that the segment is valid (non zero length). const Vector_3 diff = vector(seg.source(), pt); @@ -90,7 +91,7 @@ squared_distance(const typename K::Point_3& pt, const RT e = wdot(segvec, segvec, k); if(wmult((K*)0, d, segvec.hw()) > wmult((K*)0, e, diff.hw())) - return squared_distance(pt, seg.target(), k); + return sq_dist(pt, seg.target()); // This is an expanded call to squared_distance_to_line() to avoid recomputing 'e' const Vector_3 wcr = wcross(segvec, diff, k); @@ -108,26 +109,30 @@ squared_distance(const typename K::Segment_3& seg, return squared_distance(pt, seg, k); } +template +typename K::Comparison_result +compare_squared_distance(const typename K::Point_3& pt, + const typename K::Segment_3& seg, + const K& k, + const typename K::FT& d2) +{ + //Doing an early exit was slower. + return compare(squared_distance(pt, seg, k), d2); +} + +template +inline +typename K::Comparison_result +compare_squared_distance(const typename K::Segment_3& seg, + const typename K::Point_3& pt, + const K& k, + const typename K::FT &d2) +{ + return compare_squared_distance(pt, seg, k, d2); +} + } // namespace internal -template -inline -typename K::FT -squared_distance(const Point_3& pt, - const Segment_3& seg) -{ - return K().compute_squared_distance_3_object()(pt, seg); -} - -template -inline -typename K::FT -squared_distance(const Segment_3& seg, - const Point_3& pt) -{ - return K().compute_squared_distance_3_object()(seg, pt); -} - } // namespace CGAL #endif // CGAL_DISTANCE_3_POINT_3_SEGMENT_3_H diff --git a/Distance_3/include/CGAL/Distance_3/Point_3_Tetrahedron_3.h b/Distance_3/include/CGAL/Distance_3/Point_3_Tetrahedron_3.h index 04d148818a3..031a60a6650 100644 --- a/Distance_3/include/CGAL/Distance_3/Point_3_Tetrahedron_3.h +++ b/Distance_3/include/CGAL/Distance_3/Point_3_Tetrahedron_3.h @@ -43,10 +43,28 @@ squared_distance(const typename K::Point_3& pt, const Point_3& t2 = vertex(tet, 2); const Point_3& t3 = vertex(tet, 3); - bool dmin_initialized = false; + Orientation ori_tet = orientation(t0,t1,t2,t3); + + if(ori_tet==COPLANAR){ + //Degen Tetrahedron + //Get the minimum of three triangles (no need to test the fourth) + bool inside = false; + typename K::FT dmin = squared_distance_to_triangle(pt, t0, t1, t2, k, inside); + if(inside) + return dmin; + typename K::FT d = squared_distance_to_triangle(pt, t0, t1, t3, k, inside); + if(inside) + return d; + dmin=(std::min)(d,dmin); + d = squared_distance_to_triangle(pt, t0, t2, t3, k, inside); + return (std::min)(d,dmin); + } + + bool dmin_initialized = false; //dmin_initialized and !on_bounded_side have always the samed value typename K::FT dmin; bool inside = false; - if(orientation(t0,t1,t2, pt) == NEGATIVE) + + if(orientation(pt, t0,t1,t2) == ori_tet) { on_bounded_side = false; dmin = squared_distance_to_triangle(pt, t0, t1, t2, k, inside); @@ -55,7 +73,7 @@ squared_distance(const typename K::Point_3& pt, return dmin; } - if(orientation(t0,t3,t1, pt) == NEGATIVE) + if(orientation(pt, t0,t3,t1) == ori_tet) { on_bounded_side = false; const typename K::FT d = squared_distance_to_triangle(pt, t0, t3, t1, k, inside); @@ -73,7 +91,7 @@ squared_distance(const typename K::Point_3& pt, } } - if(orientation(t1,t3,t2, pt) == NEGATIVE) + if(orientation(pt, t1,t3,t2) == ori_tet) { on_bounded_side = false; const typename K::FT d = squared_distance_to_triangle(pt, t1, t3, t2, k, inside); @@ -91,7 +109,7 @@ squared_distance(const typename K::Point_3& pt, } } - if(orientation(t2,t3,t0, pt) == NEGATIVE) + if(orientation(pt, t2,t3,t0) == ori_tet) { on_bounded_side = false; const typename K::FT d = squared_distance_to_triangle(pt, t2, t3, t0, k, inside); @@ -125,24 +143,100 @@ squared_distance(const typename K::Tetrahedron_3& tet, return squared_distance(pt, tet, k); } +template +typename K::Comparison_result +compare_squared_distance(const typename K::Point_3& pt, + const typename K::Tetrahedron_3& tet, + const K& k, + const typename K::FT& d2) +{ + typedef typename K::Point_3 Point_3; + + typename K::Construct_vertex_3 vertex = k.construct_vertex_3_object(); + typename K::Orientation_3 orientation = k.orientation_3_object(); + + /* The content of this function is very similar with the one above, the difference is we can exit earlier if + we found a triangle closer than d or plane farther than d since we do not need the exact distance. + (there are also early exits in calling functions) */ + + bool on_bounded_side = true; + bool inside_or_far_to_the_plane = false; + const Point_3& t0 = vertex(tet, 0); + const Point_3& t1 = vertex(tet, 1); + const Point_3& t2 = vertex(tet, 2); + const Point_3& t3 = vertex(tet, 3); + + Orientation ori_tet = orientation(t0,t1,t2,t3); + + if(ori_tet==COPLANAR){ + //Degen Tetrahedron + //Get the minimum of three triangles (no need to test the fourth) + typename K::Comparison_result res = compare_squared_distance_to_triangle(pt, t0, t1, t2, k, d2, inside_or_far_to_the_plane); + if(inside_or_far_to_the_plane) + return res; + typename K::Comparison_result temp_res = compare_squared_distance_to_triangle(pt, t0, t1, t3, k, d2, inside_or_far_to_the_plane); + if(inside_or_far_to_the_plane) + return temp_res; + res=smaller_of(res,temp_res); + temp_res = compare_squared_distance_to_triangle(pt, t0, t2, t3, k, d2, inside_or_far_to_the_plane); + return smaller_of(res,temp_res); + } + + typename K::Comparison_result res=LARGER; + if(orientation(pt, t0,t1,t2) == ori_tet) + { + on_bounded_side = false; + res = compare_squared_distance_to_triangle(pt, t0, t1, t2, k, d2, inside_or_far_to_the_plane); + if(inside_or_far_to_the_plane || res==SMALLER) + return res; + } + + if(orientation(pt, t0,t3,t1) == ori_tet) + { + on_bounded_side = false; + const typename K::Comparison_result temp_res = compare_squared_distance_to_triangle(pt, t0, t3, t1, k, d2, inside_or_far_to_the_plane); + if(inside_or_far_to_the_plane || temp_res==SMALLER) + return temp_res; + res = smaller_of(res, temp_res); + } + + if(orientation(pt, t1,t3,t2) == ori_tet) + { + on_bounded_side = false; + const typename K::Comparison_result temp_res = compare_squared_distance_to_triangle(pt, t1, t3, t2, k, d2, inside_or_far_to_the_plane); + if(inside_or_far_to_the_plane || temp_res==SMALLER) + return temp_res; + res = smaller_of(res, temp_res); + } + + if(orientation(pt, t2,t3,t0) == ori_tet) + { + on_bounded_side = false; + const typename K::Comparison_result temp_res = compare_squared_distance_to_triangle(pt, t2, t3, t0, k, d2, inside_or_far_to_the_plane); + if(inside_or_far_to_the_plane || temp_res==SMALLER) + return temp_res; + res = smaller_of(res, temp_res); + } + + if(on_bounded_side) + return compare(typename K::FT(0),d2); + + return res; +} + +template +inline +typename K::Comparison_result +compare_squared_distance(const typename K::Tetrahedron_3& tet, + const typename K::Point_3& pt, + const K& k, + const typename K::FT& d2) +{ + return compare_squared_distance(pt, tet, k, d2); +} + } // namespace internal -template -typename K::FT -squared_distance(const Tetrahedron_3& tet, - const Point_3& pt) -{ - return K().compute_squared_distance_3_object()(tet, pt); -} - -template -typename K::FT -squared_distance(const Point_3& pt, - const Tetrahedron_3& tet) -{ - return K().compute_squared_distance_3_object()(pt, tet); -} - } // namespace CGAL #endif // CGAL_DISTANCE_3_POINT_3_TETRAHEDRON_3_H diff --git a/Distance_3/include/CGAL/Distance_3/Point_3_Triangle_3.h b/Distance_3/include/CGAL/Distance_3/Point_3_Triangle_3.h index 8b58e9a81a6..f9545323e4a 100644 --- a/Distance_3/include/CGAL/Distance_3/Point_3_Triangle_3.h +++ b/Distance_3/include/CGAL/Distance_3/Point_3_Triangle_3.h @@ -292,26 +292,140 @@ squared_distance(const typename K::Triangle_3& t, return squared_distance(pt, t, k); } +template +typename K::Comparison_result +compare_squared_distance_to_triangle(const typename K::Point_3& pt, + const typename K::Point_3& t0, + const typename K::Point_3& t1, + const typename K::Point_3& t2, + const K& k, + const typename K::FT &d2, + bool& inside_or_far_to_the_plane) +{ + typedef typename K::Vector_3 Vector_3; + + typename K::Construct_segment_3 segment = k.construct_segment_3_object(); + typename K::Construct_vector_3 vector = k.construct_vector_3_object(); + typename K::Compare_squared_distance_3 csq_dist = k.compare_squared_distance_3_object(); + + /* The content of this function is very similar with the one above, the difference is we can exit earlier if + we found a segment closer than d or if the point is farther than d to the plane since we do not need the exact distance */ + + const Vector_3 e1 = vector(t0, t1); + const Vector_3 oe3 = vector(t0, t2); + const Vector_3 normal = wcross(e1, oe3, k); + + if(normal == NULL_VECTOR) + { + // The case normal == NULL_VECTOR covers the case when the triangle + // is colinear, or even more degenerate. In that case, we can + // simply take also the distance to the three segments. + // + // Note that in the degenerate case, at most 2 edges cover the full triangle, + // and only two distances could be used + typename K::Comparison_result res1 = csq_dist(pt, segment(t2, t0), d2); + if(certainly(res1 == SMALLER)) + return SMALLER; + typename K::Comparison_result res2 = csq_dist(pt, segment(t1, t2), d2); + return smaller_of(res1,res2); + } + + // Compare first the distance to the plane, if larger we can exit early + typename K::Comparison_result res_p_pl = compare(squared_distance_to_plane(normal, vector(t0, pt), k), d2); + if(certainly(res_p_pl==LARGER)) + { + inside_or_far_to_the_plane=true; + return LARGER; + } + + //If we are smaller when compare to a segment, we can exit early + if(!on_left_of_triangle_edge(pt, normal, t0, t1, k)) + { + typename K::Comparison_result res_p_s1 = csq_dist(pt, segment(t0, t1), d2); + if(certainly(res_p_s1==SMALLER)) + return SMALLER; + if(!on_left_of_triangle_edge(pt, normal, t1, t2, k)) + { + // can't be to the right of all three segments + typename K::Comparison_result res_p_s2 = csq_dist(pt, segment(t1, t2), d2); + return smaller_of(res_p_s1, res_p_s2); + } + else // on_left_of_triangle_edge(pt, normal, t1, t2, k) + { + if(!on_left_of_triangle_edge(pt, normal, t2, t0, k)) + { + typename K::Comparison_result res_p_s3 = csq_dist(pt, segment(t2, t0), d2); + return smaller_of(res_p_s1, res_p_s3); + } + else // on_left_of_triangle_edge(pt, normal, t2, t0, k) + { + return res_p_s1; + } + } + } + else // on_left_of_triangle_edge(pt, normal, t0, t1, k) + { + if(!on_left_of_triangle_edge(pt, normal, t1, t2, k)) + { + typename K::Comparison_result res_p_s2 = csq_dist(pt, segment(t1, t2), d2); + if(certainly(res_p_s2 == SMALLER)) + return SMALLER; + if(!on_left_of_triangle_edge(pt, normal, t2, t0, k)) + { + typename K::Comparison_result res_p_s3 = csq_dist(pt, segment(t2, t0), d2); + return smaller_of(res_p_s2, res_p_s3); + } + else // on_left_of_triangle_edge(pt, normal, t2, t0, k) + { + return res_p_s2; + } + } + else // on_left_of_triangle_edge(pt, normal, t1, t2, k) + { + if(!on_left_of_triangle_edge(pt, normal, t2, t0, k)) + { + return csq_dist(pt, segment(t2, t0), d2); + } + else // on_left_of_triangle_edge(pt, normal, t2, t0, k) + { + inside_or_far_to_the_plane = true; + return res_p_pl; + } + } + } +} + +template +typename K::Comparison_result +compare_squared_distance(const typename K::Point_3& pt, + const typename K::Triangle_3& t, + const K& k, + const typename K::FT& d2) +{ + typename K::Construct_vertex_3 vertex = k.construct_vertex_3_object(); + + bool unused_inside_or_far_to_the_plane = false; + return compare_squared_distance_to_triangle(pt, + vertex(t, 0), + vertex(t, 1), + vertex(t, 2), + k, + d2, + unused_inside_or_far_to_the_plane); +} + +template +typename K::Comparison_result +compare_squared_distance(const typename K::Triangle_3& t, + const typename K::Point_3& pt, + const K& k, + const typename K::FT& d2) +{ + return compare_squared_distance(pt, t, k, d2); +} + } // namespace internal -template -inline -typename K::FT -squared_distance(const Point_3& pt, - const Triangle_3& t) -{ - return K().compute_squared_distance_3_object()(pt, t); -} - -template -inline -typename K::FT -squared_distance(const Triangle_3& t, - const Point_3& pt) -{ - return K().compute_squared_distance_3_object()(t, pt); -} - } // namespace CGAL #endif // CGAL_DISTANCE_3_POINT_3_TRIANGLE_3_H diff --git a/Distance_3/include/CGAL/Distance_3/Ray_3_Line_3.h b/Distance_3/include/CGAL/Distance_3/Ray_3_Line_3.h index d4b51b59cbe..ed431f63128 100644 --- a/Distance_3/include/CGAL/Distance_3/Ray_3_Line_3.h +++ b/Distance_3/include/CGAL/Distance_3/Ray_3_Line_3.h @@ -77,26 +77,28 @@ squared_distance(const typename K::Line_3& line, return squared_distance(ray, line, k); } +template +typename K::Comparison_result +compare_squared_distance(const typename K::Ray_3& ray, + const typename K::Line_3& line, + const K& k, + const typename K::FT& d2) +{ + return compare(squared_distance(ray, line, k), d2); +} + +template +typename K::Comparison_result +compare_squared_distance(const typename K::Line_3& line, + const typename K::Ray_3& ray, + const K& k, + const typename K::FT& d2) +{ + return compare_squared_distance(ray, line, k, d2); +} + } // namespace internal -template -inline -typename K::FT -squared_distance(const Line_3& line, - const Ray_3& ray) -{ - return K().compute_squared_distance_3_object()(line, ray); -} - -template -inline -typename K::FT -squared_distance(const Ray_3& ray, - const Line_3& line) -{ - return K().compute_squared_distance_3_object()(ray, line); -} - } // namespace CGAL #endif // CGAL_DISTANCE_3_RAY_3_LINE_3_H diff --git a/Distance_3/include/CGAL/Distance_3/Ray_3_Plane_3.h b/Distance_3/include/CGAL/Distance_3/Ray_3_Plane_3.h index bdc9a956146..eb2a4810a32 100644 --- a/Distance_3/include/CGAL/Distance_3/Ray_3_Plane_3.h +++ b/Distance_3/include/CGAL/Distance_3/Ray_3_Plane_3.h @@ -72,26 +72,28 @@ squared_distance(const typename K::Plane_3& plane, return squared_distance(ray, plane, k); } +template +typename K::Comparison_result +compare_squared_distance(const typename K::Ray_3& ray, + const typename K::Plane_3& plane, + const K& k, + const typename K::FT& d2) +{ + return compare(squared_distance(ray, plane, k), d2); +} + +template +typename K::Comparison_result +compare_squared_distance(const typename K::Plane_3& plane, + const typename K::Ray_3& ray, + const K& k, + const typename K::FT& d2) +{ + return compare_squared_distance(ray, plane, k, d2); +} + } // namespace internal -template -inline -typename K::FT -squared_distance(const Ray_3& ray, - const Plane_3& plane) -{ - return K().compute_squared_distance_3_object()(ray, plane); -} - -template -inline -typename K::FT -squared_distance(const Plane_3& plane, - const Ray_3& ray) -{ - return K().compute_squared_distance_3_object()(plane, ray); -} - } // namespace CGAL #endif // CGAL_DISTANCE_3_RAY_3_PLANE_3_H diff --git a/Distance_3/include/CGAL/Distance_3/Ray_3_Ray_3.h b/Distance_3/include/CGAL/Distance_3/Ray_3_Ray_3.h index 8ca1eca308c..9367e095e92 100644 --- a/Distance_3/include/CGAL/Distance_3/Ray_3_Ray_3.h +++ b/Distance_3/include/CGAL/Distance_3/Ray_3_Ray_3.h @@ -117,6 +117,16 @@ squared_distance(const typename K::Ray_3& ray1, } } +template +typename K::Comparison_result +compare_squared_distance(const typename K::Ray_3& ray1, + const typename K::Ray_3& ray2, + const K& k, + const typename K::FT& d2) +{ + return compare(squared_distance(ray1, ray2, k), d2); +} + } // namespace internal template @@ -129,15 +139,6 @@ ray_ray_squared_distance_parallel(const Vector_3& ray1dir, return internal::ray_ray_squared_distance_parallel(ray1dir, ray2dir, s1_min_s2, K()); } -template -inline -typename K::FT -squared_distance(const Ray_3& ray1, - const Ray_3& ray2) -{ - return K().compute_squared_distance_3_object()(ray1, ray2); -} - } // namespace CGAL #endif // CGAL_DISTANCE_3_RAY_3_RAY_3_H diff --git a/Distance_3/include/CGAL/Distance_3/Segment_3_Line_3.h b/Distance_3/include/CGAL/Distance_3/Segment_3_Line_3.h index 5781c5ceb74..f5d3336b5d6 100644 --- a/Distance_3/include/CGAL/Distance_3/Segment_3_Line_3.h +++ b/Distance_3/include/CGAL/Distance_3/Segment_3_Line_3.h @@ -38,6 +38,8 @@ squared_distance(const typename K::Segment_3& seg, typename K::Construct_vector_3 vector = k.construct_vector_3_object(); typename K::Compute_squared_distance_3 sq_dist = k.compute_squared_distance_3_object(); + //Probably writable with less if than currently + const Point_3& linepoint = line.point(); const Point_3& start = seg.source(); const Point_3& end = seg.target(); @@ -60,26 +62,12 @@ squared_distance(const typename K::Segment_3& seg, const RT sdm_ss2l = wdot(perpend2line, start_min_lp, k); const RT sdm_se2l = wdot(perpend2line, end_min_lp, k); - if(sdm_ss2l < RT(0)) { - crossing = (sdm_se2l >= RT(0)); - } else { - if(sdm_se2l <= RT(0)) { - crossing = true; - } else { - crossing = (sdm_ss2l == RT(0)); - } - } + crossing = (sdm_ss2l*sdm_se2l) <= RT(0); - if(crossing) { + if(crossing) return squared_distance_to_plane(normal, start_min_lp, k); - } else { - const RT dm = distance_measure_sub(sdm_ss2l, sdm_se2l, start_min_lp, end_min_lp, k); - if(dm <= RT(0)) { - return squared_distance_to_line(linedir, start_min_lp, k); - } else { - return squared_distance_to_line(linedir, end_min_lp, k); - } - } + else + return min(squared_distance_to_line(linedir, start_min_lp, k), squared_distance_to_line(linedir, end_min_lp, k)); } template @@ -91,25 +79,29 @@ squared_distance(const typename K::Line_3& line, return squared_distance(seg, line, k); } +template +typename K::Comparison_result +compare_squared_distance(const typename K::Segment_3& seg, + const typename K::Line_3& line, + const K& k, + const typename K::FT& d2) +{ + // Perform an early exit was slower + return compare(squared_distance(seg, line, k), d2); +} + +template +typename K::Comparison_result +compare_squared_distance(const typename K::Line_3& line, + const typename K::Segment_3& seg, + const K& k, + const typename K::FT& d2) +{ + return compare_squared_distance(seg, line, k, d2); +} + } // namespace internal -template -inline -typename K::FT -squared_distance(const Segment_3& seg, - const Line_3& line) -{ - return K().compute_squared_distance_3_object()(seg, line); -} - -template -inline -typename K::FT -squared_distance(const Line_3& line, - const Segment_3& seg) -{ - return K().compute_squared_distance_3_object()(line, seg); -} } // namespace CGAL diff --git a/Distance_3/include/CGAL/Distance_3/Segment_3_Plane_3.h b/Distance_3/include/CGAL/Distance_3/Segment_3_Plane_3.h index 1c8d6799556..4b46049940c 100644 --- a/Distance_3/include/CGAL/Distance_3/Segment_3_Plane_3.h +++ b/Distance_3/include/CGAL/Distance_3/Segment_3_Plane_3.h @@ -37,12 +37,13 @@ squared_distance(const typename K::Segment_3 &seg, typedef typename K::Point_3 Point_3; typename K::Construct_vector_3 vector = k.construct_vector_3_object(); + typename K::Compute_squared_distance_3 sq_dist = k.compute_squared_distance_3_object(); const Point_3& start = seg.start(); const Point_3& end = seg.end(); if (start == end) - return squared_distance(start, plane, k); + return sq_dist(start, plane); const Point_3& planepoint = plane.point(); const Vector_3 start_min_pp = vector(planepoint, start); @@ -83,26 +84,28 @@ squared_distance(const typename K::Plane_3& plane, return squared_distance(seg, plane, k); } +template +typename K::Comparison_result +compare_squared_distance(const typename K::Segment_3 &seg, + const typename K::Plane_3 &plane, + const K& k, + const typename K::FT& d2) +{ + return compare(squared_distance(seg, plane, k), d2); +} + +template +inline typename K::Comparison_result +compare_squared_distance(const typename K::Plane_3& plane, + const typename K::Segment_3& seg, + const K& k, + const typename K::FT& d2) +{ + return compare_squared_distance(seg, plane, k, d2); +} + } // namespace internal -template -inline -typename K::FT -squared_distance(const Segment_3& seg, - const Plane_3& plane) -{ - return K().compute_squared_distance_3_object()(seg, plane); -} - -template -inline -typename K::FT -squared_distance(const Plane_3& plane, - const Segment_3& seg) -{ - return K().compute_squared_distance_3_object()(plane, seg); -} - } // namespace CGAL #endif // CGAL_DISTANCE_3_SEGMENT_3_PLANE_3_H diff --git a/Distance_3/include/CGAL/Distance_3/Segment_3_Ray_3.h b/Distance_3/include/CGAL/Distance_3/Segment_3_Ray_3.h index 5943630d76f..d35fda6d08b 100644 --- a/Distance_3/include/CGAL/Distance_3/Segment_3_Ray_3.h +++ b/Distance_3/include/CGAL/Distance_3/Segment_3_Ray_3.h @@ -73,6 +73,8 @@ squared_distance(const typename K::Segment_3& seg, const Point_3& ss = seg.source(); const Point_3& se = seg.target(); + //TODO This seems complicated compared to Segment_3_Segment_3.h. Consider improving by adapting Lumelsky's method for segment-segment intersection. + if(ss == se) return sq_dist(ss, ray); @@ -166,6 +168,26 @@ squared_distance(const typename K::Ray_3& ray, return squared_distance(seg, ray, k); } +template +typename K::Comparison_result +compare_squared_distance(const typename K::Ray_3& ray, + const typename K::Segment_3& seg, + const K& k, + const typename K::FT& d2) +{ + return compare(squared_distance(ray, seg, k), d2); +} + +template +typename K::Comparison_result +compare_squared_distance(const typename K::Segment_3& seg, + const typename K::Ray_3& ray, + const K& k, + const typename K::FT& d2) +{ + return compare_squared_distance(ray, seg, k, d2); +} + } // namespace internal template @@ -177,24 +199,6 @@ squared_distance_parallel(const Segment_3& seg, return internal::squared_distance_parallel(ray, seg, K()); } -template -inline -typename K::FT -squared_distance(const Segment_3& seg, - const Ray_3& ray) -{ - return K().compute_squared_distance_3_object()(seg, ray); -} - -template -inline -typename K::FT -squared_distance(const Ray_3& ray, - const Segment_3& seg) -{ - return K().compute_squared_distance_3_object()(ray, seg); -} - } // namespace CGAL #endif // CGAL_DISTANCE_3_SEGMENT_3_RAY_3_H diff --git a/Distance_3/include/CGAL/Distance_3/Segment_3_Segment_3.h b/Distance_3/include/CGAL/Distance_3/Segment_3_Segment_3.h index ad933787204..8967e982a79 100644 --- a/Distance_3/include/CGAL/Distance_3/Segment_3_Segment_3.h +++ b/Distance_3/include/CGAL/Distance_3/Segment_3_Segment_3.h @@ -59,14 +59,6 @@ squared_distance(const typename K::Segment_3& s1, const Vector_3 v1 = cv(p1, q1), v2 = cv(p2, q2); const Vector_3 p1p2 = cv(p1, p2); - // @todo compute these only when needed? - const FT a = sp(v1, v1); - const FT b = - sp(v1, v2); - const FT c = - b; - const FT d = - sp(v2, v2); - const FT e = sp(v1, p1p2); - const FT f = sp(v2, p1p2); - if(p1 == q1) { if(p2 == q2) @@ -77,6 +69,9 @@ squared_distance(const typename K::Segment_3& s1, return res; } + const FT d = - sp(v2, v2); + const FT f = sp(v2, p1p2); + CGAL_assertion(d < 0); res.x = 0; @@ -87,6 +82,9 @@ squared_distance(const typename K::Segment_3& s1, } else if(p2 == q2) { + const FT a = sp(v1, v1); + const FT e = sp(v1, p1p2); + CGAL_assertion(a > 0); res.y = 0; @@ -96,10 +94,17 @@ squared_distance(const typename K::Segment_3& s1, return res; } + const FT a = sp(v1, v1); + const FT b = - sp(v1, v2); + const FT c = - b; + const FT d = - sp(v2, v2); + const FT e = sp(v1, p1p2); + const FT f = sp(v2, p1p2); + CGAL_assertion(a > 0 && d < 0); const FT det = a*d - b*c; - if(det == 0) + if(is_zero(det)) res.x = 0; else res.x = boost::algorithm::clamp((e*d - b*f) / det, 0, 1); @@ -183,26 +188,102 @@ squared_distance(const typename K::Segment_3& seg1, return res.squared_distance; } +template +typename K::Comparison_result +compare_squared_distance(const typename K::Segment_3& s1, + const typename K::Segment_3& s2, + const K& k, + const typename K::FT& d2) +{ + typedef typename K::FT FT; + typedef typename K::Point_3 Point_3; + typedef typename K::Vector_3 Vector_3; + + typename K::Construct_vertex_3 vertex = k.construct_vertex_3_object(); + typename K::Construct_vector_3 cv = k.construct_vector_3_object(); + typename K::Compute_scalar_product_3 sp = k.compute_scalar_product_3_object(); + typename K::Compute_squared_distance_3 sq_dist = k.compute_squared_distance_3_object(); + typename K::Compare_squared_distance_3 csq_dist = k.compare_squared_distance_3_object(); + + /* The content of this function is very similar with the one above, the difference is we can exit earlier if + the supporting line are farther than d since we do not need the exact distance. */ + +#if 1 + const Point_3& p1 = vertex(s1, 0); + const Point_3& q1 = vertex(s1, 1); + const Point_3& p2 = vertex(s2, 0); + const Point_3& q2 = vertex(s2, 1); + const Vector_3 v1 = cv(p1, q1), v2 = cv(p2, q2); + const Vector_3 p1p2 = cv(p1, p2); + + // If degenerate segment, compare the distance between the point and the other segment + if(p1 == q1) + if(p2 == q2) + return csq_dist(p1,p2,d2); + else + return csq_dist(p1,s2,d2); + else if(p2 == q2) + return csq_dist(s1,p2,d2); + + // Compare first the distance between the lines, if larger we can exit early + typename K::Comparison_result res_ll=csq_dist(s1.supporting_line(), s2.supporting_line(), d2); + if(certainly(res_ll==LARGER)) + return LARGER; + + // Compute the distance between the segments + // TODO some factorization with above function? only the last case is different + + const FT a = sp(v1, v1); + const FT b = - sp(v1, v2); + const FT c = - b; + const FT d = - sp(v2, v2); + const FT e = sp(v1, p1p2); + const FT f = sp(v2, p1p2); + + CGAL_assertion(a > 0 && d < 0); + const FT det = a*d - b*c; + FT res_x; + if(is_zero(det)) + res_x = 0; + else + res_x = boost::algorithm::clamp((e*d - b*f) / det, 0, 1); + + FT xc = res_x*c; + // res.y = (f - xc) / d, by definition, but building it up more efficiently + if(f > xc) // y < 0 <=> f - xc / d < 0 <=> f - xc > 0 (since d is -||v2||) + { + // res_y = 0; + res_x = boost::algorithm::clamp(e/a, 0, 1); // (e + y*c) / a + return compare(sq_dist(p1+res_x*v1,p2), d2); + } + else // y >= 0 + { + FT n = f - xc; // delay the division by d + if(n < d) // y > 1 <=> n / d > 1 <=> n < d (once again, important to note that d is negative!) + { + // res_y = 1; + res_x = boost::algorithm::clamp((e + c) / a, 0, 1); // (e + y*c) / a + return compare(sq_dist(p1+res_x*v1,p2+v2), d2); + } + else if(res_x==0 || res_x==1) // 0 <= y <= 1 + { + FT res_y = n / d; + return compare(sq_dist(p1 + res_x*v1, p2 + res_y*v2), d2); + } + else + { + //Already computed by distance line line + return res_ll; + } + } +#else + // Faster with Simple_cartesian, a bit slower with EPICK or EPECK specifically if d2 is small + return compare(squared_distance(s1, s2 ,k), d2); +#endif +} + } // namespace internal -template -inline -typename K::FT -squared_distance_parallel(const Segment_3& seg1, - const Segment_3& seg2) -{ - return internal::squared_distance_parallel(seg1, seg2, K()); -} - -template -inline -typename K::FT -squared_distance(const Segment_3& seg1, - const Segment_3& seg2) -{ - return K().compute_squared_distance_3_object()(seg1, seg2); -} - } // namespace CGAL #endif // CGAL_DISTANCE_3_SEGMENT_3_SEGMENT_3_H diff --git a/Distance_3/include/CGAL/Distance_3/Triangle_3_Triangle_3.h b/Distance_3/include/CGAL/Distance_3/Triangle_3_Triangle_3.h index f6bf77fd39b..9bf27fb6c2a 100644 --- a/Distance_3/include/CGAL/Distance_3/Triangle_3_Triangle_3.h +++ b/Distance_3/include/CGAL/Distance_3/Triangle_3_Triangle_3.h @@ -213,17 +213,65 @@ squared_distance(const typename K::Triangle_3& tr1, #endif } -} // namespace internal - -template -inline -typename K::FT -squared_distance(const Triangle_3& tr1, - const Triangle_3& tr2) +template +typename K::Comparison_result +compare_squared_distance_disjoint(const typename K::Triangle_3& tr1, + const typename K::Triangle_3& tr2, + const K& k, + const typename K::FT& d2) { - return K().compute_squared_distance_3_object()(tr1, tr2); + typedef typename K::Segment_3 Segment_3; + + typename K::Construct_vertex_3 vertex = k.construct_vertex_3_object(); + typename K::Compare_squared_distance_3 csq_dist = k.compare_squared_distance_3_object(); + + typename K::Comparison_result res(LARGER); + + // The tiangle are supposed to be disjoint + assert(!do_intersect(tr1, tr2)); + + for(int i=0; i<3; ++i) + { + //Compare the distance between edges + for(int j=0; j<3; ++j) + { + typename K::Comparison_result temp_res_ss=csq_dist(Segment_3(vertex(tr1, i%3), vertex(tr1, (i+1)%3)),Segment_3(vertex(tr2, j%3), vertex(tr2, (j+1)%3)),d2); + if(certainly(temp_res_ss==SMALLER)) + return SMALLER; + res=smaller_of(res, temp_res_ss); + } + + //Compare the distance between vertices and triangles + typename K::Comparison_result temp_res_v_pl= csq_dist(vertex(tr1, i), tr2,d2); + if(certainly(temp_res_v_pl==SMALLER)) + return SMALLER; + res=smaller_of(res, temp_res_v_pl); + + temp_res_v_pl= csq_dist(vertex(tr2, i), tr1,d2); + if(certainly(temp_res_v_pl==SMALLER)) + return SMALLER; + res=smaller_of(res, temp_res_v_pl); + } + return res; + } +template +typename K::Comparison_result +compare_squared_distance(const typename K::Triangle_3& tr1, + const typename K::Triangle_3& tr2, + const K& k, + const typename K::FT& d2){ + //TODO did something more intelligent (sq_dist and csq_dist does not exist for Segment-Triangle) + if(tr1.is_degenerate() || tr2.is_degenerate()) + return compare(squared_distance(tr1,tr2, k), d2); + if(do_intersect(tr1, tr2)) + return compare(typename K::FT(0), d2); + return compare_squared_distance_disjoint(tr1, tr2, k, d2); +} + +} // namespace internal + } // namespace CGAL #endif // CGAL_DISTANCE_3_TRIANGLE_3_TRIANGLE_3_H diff --git a/Distance_3/include/CGAL/Distance_3/internal/squared_distance_utils_3.h b/Distance_3/include/CGAL/Distance_3/internal/squared_distance_utils_3.h index 7dbf82e246e..260301cf8b1 100644 --- a/Distance_3/include/CGAL/Distance_3/internal/squared_distance_utils_3.h +++ b/Distance_3/include/CGAL/Distance_3/internal/squared_distance_utils_3.h @@ -23,9 +23,35 @@ #include #include +#include + namespace CGAL { namespace internal { +inline +Comparison_result smaller_of(const Comparison_result& a, const Comparison_result& b) +{ + return (std::min)(a,b); +} + +inline +Uncertain smaller_of(const Uncertain& a, const Uncertain& b) +{ + return Uncertain((std::min)(a.inf(),b.inf()), (std::min)(a.sup(),b.sup())); +} + +inline +Uncertain smaller_of(const Uncertain& a, const Comparison_result& b) +{ + return smaller_of(a,make_uncertain(b)); +} + +inline +Uncertain smaller_of(const Comparison_result& a, const Uncertain& b) +{ + return smaller_of(make_uncertain(a),b); +} + template bool is_null(const typename K::Vector_3 &v, const K&) { @@ -39,7 +65,10 @@ wdot(const typename K::Vector_3 &u, const typename K::Vector_3 &v, const K&) { - return (u.hx()*v.hx() + u.hy()*v.hy() + u.hz()*v.hz()); + if constexpr(std::is_same_v) + return std::fma(u.hx(), v.hx(), std::fma(u.hy(), v.hy(), u.hz()*v.hz())); + else + return (u.hx()*v.hx() + u.hy()*v.hy() + u.hz()*v.hz()); } template @@ -84,6 +113,26 @@ wdot(const typename K::Point_3 &p, return wdot_tag(p, q, r, k, tag); } +inline +double diff_of_products(const double a, const double b, const double c, const double d) +{ +// Kahan method, less numerical error +#if 1 + double w = d * c; + double e = std::fma(c, -d, w); + double f = std::fma(a, b, -w); + return f + e; +#else + return std::fma(a, b, -c*d); +#endif +} + +template +OFT diff_of_products(const OFT& a, const OFT& b, const OFT& c, const OFT& d, std::enable_if_t>* = 0) +{ + return a*b - c*d; +} + template typename K::Vector_3 wcross(const typename K::Vector_3 &u, @@ -92,9 +141,9 @@ wcross(const typename K::Vector_3 &u, { typedef typename K::Vector_3 Vector_3; return Vector_3( - u.hy()*v.hz() - u.hz()*v.hy(), - u.hz()*v.hx() - u.hx()*v.hz(), - u.hx()*v.hy() - u.hy()*v.hx()); + diff_of_products(u.hy(),v.hz(),u.hz(),v.hy()), + diff_of_products(u.hz(),v.hx(),u.hx(),v.hz()), + diff_of_products(u.hx(),v.hy(),u.hy(),v.hx())); } template @@ -221,6 +270,16 @@ squared_distance_to_line(const typename K::Vector_3& dir, return Rational_traits().make_rational(num, den); } +template +typename K::Comparison_result +compare_squared_distance_to_line(const typename K::Vector_3& dir, + const typename K::Vector_3& diff, + const K& k, + const typename K::FT &d2) +{ + return compare(squared_distance_to_line(dir,diff,k),d2); +} + template inline bool diff --git a/Distance_3/include/CGAL/global_functions_distance_3.h b/Distance_3/include/CGAL/global_functions_distance_3.h new file mode 100644 index 00000000000..388867ae697 --- /dev/null +++ b/Distance_3/include/CGAL/global_functions_distance_3.h @@ -0,0 +1,109 @@ +// Copyright (c) 2025 +// GeometryFactory (France), +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Léo Valque + +#ifndef CGAL_KERNEL_GLOBAL_FUNCTIONS_DISTANCE_3_H +#define CGAL_KERNEL_GLOBAL_FUNCTIONS_DISTANCE_3_H + +// Distance functions calling the kernel functor. + +#define CGAL_SQUARED_DISTANCE_FUNCTION(A, B) \ +template \ +inline \ +typename K::FT \ +squared_distance(const A& a, const B& b) \ +{ \ + return K().compute_squared_distance_3_object()(a, b); \ +} \ +template \ +inline \ +typename K::FT \ +squared_distance(const B& a, const A& b) \ +{ \ + return K().compute_squared_distance_3_object()(b, a); \ +} + +#define CGAL_SQUARED_DISTANCE_FUNCTION_SELF(A) \ +template \ +inline \ +typename K::FT \ +squared_distance(const A& a, const A& b) \ +{ \ + return K().compute_squared_distance_3_object()(a, b); \ +} + +#define CGAL_COMPARE_SQUARED_DISTANCE_FUNCTION(A, B) \ +template \ +inline \ +typename K::Comparison_result \ +compare_squared_distance(const A& a, \ + const B& b, \ + const typename K::FT& d2) \ +{ \ + return K().compare_squared_distance_3_object()(a, b, d2); \ +} \ +template \ +inline \ +typename K::Comparison_result \ +compare_squared_distance(const B& b, \ + const A& a, \ + const typename K::FT& d2) \ +{ \ + return K().compare_squared_distance_3_object()(b, a, d2); \ +} + +#define CGAL_COMPARE_SQUARED_DISTANCE_FUNCTION_SELF(A) \ +template \ +inline \ +typename K::Comparison_result \ +compare_squared_distance(const A& a, \ + const A& b, \ + const typename K::FT& d2) \ +{ \ + return K().compare_squared_distance_3_object()(a, b, d2); \ +} + +#define CGAL_COMPUTE_AND_COMPARE_SQUARED_DISTANCE_FUNCTION_SELF(A) \ +CGAL_SQUARED_DISTANCE_FUNCTION_SELF(A) \ +CGAL_COMPARE_SQUARED_DISTANCE_FUNCTION_SELF(A) + +#define CGAL_COMPUTE_AND_COMPARE_SQUARED_DISTANCE_FUNCTION(A, B) \ +CGAL_SQUARED_DISTANCE_FUNCTION(A, B) \ +CGAL_COMPARE_SQUARED_DISTANCE_FUNCTION(A, B) + +namespace CGAL { + +CGAL_COMPUTE_AND_COMPARE_SQUARED_DISTANCE_FUNCTION_SELF(Point_3) +CGAL_COMPUTE_AND_COMPARE_SQUARED_DISTANCE_FUNCTION_SELF(Line_3) +CGAL_COMPUTE_AND_COMPARE_SQUARED_DISTANCE_FUNCTION_SELF(Ray_3) +CGAL_COMPUTE_AND_COMPARE_SQUARED_DISTANCE_FUNCTION_SELF(Segment_3) +CGAL_COMPUTE_AND_COMPARE_SQUARED_DISTANCE_FUNCTION_SELF(Triangle_3) +CGAL_COMPUTE_AND_COMPARE_SQUARED_DISTANCE_FUNCTION_SELF(Plane_3) + +CGAL_COMPUTE_AND_COMPARE_SQUARED_DISTANCE_FUNCTION(Point_3, Line_3) +CGAL_COMPUTE_AND_COMPARE_SQUARED_DISTANCE_FUNCTION(Point_3, Ray_3) +CGAL_COMPUTE_AND_COMPARE_SQUARED_DISTANCE_FUNCTION(Point_3, Segment_3) +CGAL_COMPUTE_AND_COMPARE_SQUARED_DISTANCE_FUNCTION(Point_3, Plane_3) +CGAL_COMPUTE_AND_COMPARE_SQUARED_DISTANCE_FUNCTION(Point_3, Triangle_3) +CGAL_COMPUTE_AND_COMPARE_SQUARED_DISTANCE_FUNCTION(Point_3, Tetrahedron_3) + +CGAL_COMPUTE_AND_COMPARE_SQUARED_DISTANCE_FUNCTION(Line_3, Plane_3) + +CGAL_COMPUTE_AND_COMPARE_SQUARED_DISTANCE_FUNCTION(Ray_3, Line_3) +CGAL_COMPUTE_AND_COMPARE_SQUARED_DISTANCE_FUNCTION(Ray_3, Plane_3) + +CGAL_COMPUTE_AND_COMPARE_SQUARED_DISTANCE_FUNCTION(Segment_3, Line_3) +CGAL_COMPUTE_AND_COMPARE_SQUARED_DISTANCE_FUNCTION(Segment_3, Ray_3) +CGAL_COMPUTE_AND_COMPARE_SQUARED_DISTANCE_FUNCTION(Segment_3, Plane_3) + +} //namespace CGAL + +#endif // CGAL_KERNEL_GLOBAL_FUNCTIONS_DISTANCE_3_H diff --git a/Distance_3/include/CGAL/squared_distance_3.h b/Distance_3/include/CGAL/squared_distance_3.h index 69436bbe6dc..f2e51c4b51f 100644 --- a/Distance_3/include/CGAL/squared_distance_3.h +++ b/Distance_3/include/CGAL/squared_distance_3.h @@ -20,9 +20,9 @@ #include #include +#include #include #include -#include #include #include #include @@ -45,4 +45,6 @@ #include +#include + #endif // CGAL_DISTANCE_3_H diff --git a/Distance_3/test/Distance_3/test_compare_distance_3.cpp b/Distance_3/test/Distance_3/test_compare_distance_3.cpp new file mode 100644 index 00000000000..633cdd50771 --- /dev/null +++ b/Distance_3/test/Distance_3/test_compare_distance_3.cpp @@ -0,0 +1,785 @@ +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include + +// #define CGAL_USE_GTE_AS_SANITY_CHECK +#ifdef CGAL_USE_GTE_AS_SANITY_CHECK +#include +#include +#endif + +#include +#include + +struct randomint +{ + randomint() ; + int get() const { return sequence[cur]; } + int next() { + cur = (cur + 1) % 11; + return get(); + } + +private: + int sequence[11]; + int cur; +}; + +inline randomint::randomint() +{ + cur = 0; + sequence[0] = 19; + sequence[1] = 5; + sequence[2] = 17; + sequence[3] = 13; + sequence[4] = 29; + sequence[5] = 2; + sequence[6] = 23; + sequence[7] = 31; + sequence[8] = 3; + sequence[9] = 37; + sequence[10] = 11; +} + +randomint ri; + +template +struct Test +{ + typedef typename K::RT RT; + typedef typename K::FT FT; + typedef typename K::Comparison_result Comparison_result; + typedef typename K::Point_3 P; + typedef typename K::Segment_3 S; + typedef typename K::Vector_3 V; + typedef typename K::Ray_3 R; + typedef typename K::Line_3 L; + typedef typename K::Triangle_3 T; + typedef typename K::Plane_3 Pl; + typedef typename K::Tetrahedron_3 Tet; + typedef typename K::Iso_cuboid_3 Cub; + +private: + CGAL::Random& r; + const double epsilon = 1e-14; + int N = 10; + double m = 0, M = 1; + +public: + Test(CGAL::Random& r, const double epsilon) : r(r), epsilon(epsilon) { } + +private: + inline RT to_nt(int d) const { return RT(d); } + + P p(int x, int y, int z) + { + int w = ri.next(); + return P(to_nt(x*w), to_nt(y*w), to_nt(z*w), to_nt(w)); + } + + P random_point() const + { + return P(FT(r.get_double(m, M)), FT(r.get_double(m, M)), FT(r.get_double(m, M))); + } + + Pl pl(int a, int b, int c, int d) + { + int w = ri.next(); + return Pl(to_nt(a*w), to_nt(b*w), to_nt(c*w), to_nt(d*w)); + } + +private: + template + bool are_equal(const Type& t1, const Type& t2, const bool verbose = true) + { + const FT diff = CGAL::abs(t1 - t2); + if(diff > std::numeric_limits::epsilon() && + diff > epsilon * (CGAL::abs(t1) + CGAL::abs(t2))) + { + if(verbose) + { + std::cerr << "Approximate comparison failed (t1|t2): got " << t1 << " but expected " << t2 << std::endl; + std::cerr << "Diff: " << CGAL::abs(t1 - t2) << " vs eps: " << epsilon * (CGAL::abs(t1) + CGAL::abs(t2)) << std::endl; + } + return false; + } + + return true; + } + + void do_intersect_check(const P&, const P&) { } + + template + void do_intersect_check(const P& p, const O2& o2) + { + if(!o2.is_degenerate() && CGAL::do_intersect(p, o2)) + { + assert(are_equal(CGAL::squared_distance(p, o2), FT(0))); + assert(are_equal(CGAL::squared_distance(o2, p), FT(0))); + } + } + + template + void do_intersect_check(const O1& o1, const O2& o2) + { + if(!o1.is_degenerate() && !o2.is_degenerate() && CGAL::do_intersect(o1, o2)) + { + assert(are_equal(CGAL::squared_distance(o1, o2), FT(0))); + assert(are_equal(CGAL::squared_distance(o2, o1), FT(0))); + } + } + + template + void check_compare_squared_distance(const O1& o1, const O2& o2, const FT& expected_result) + { + // const FT res_o1o2 = K().compare_squared_distance_3_object()(o1, o2, expected_result); + // const FT res_o2o1 = K().compare_squared_distance_3_object()(o2, o1, expected_result); + + // std::cout << std::endl << "Test" << std::endl; + + // std::cout << o1 << std::endl << o2 << std::endl; + // std::cout << CGAL::squared_distance(o1, o2) << " " << expected_result << std::endl; + // std::cout << CGAL::SMALLER << CGAL::EQUAL << CGAL::LARGER << std::endl; + // std::cout << CGAL::compare_squared_distance(o1, o2, expected_result) << std::endl; + + const bool res_e_o1o2 = (CGAL::compare_squared_distance(o1, o2, expected_result) == CGAL::EQUAL); + const bool res_e_o2o1 = (CGAL::compare_squared_distance(o2, o1, expected_result) == CGAL::EQUAL); + const bool res_s_o1o2 = (CGAL::compare_squared_distance(o1, o2, expected_result*(1+epsilon)+1) == CGAL::SMALLER); + const bool res_s_o2o1 = (CGAL::compare_squared_distance(o2, o1, expected_result*(1+epsilon)+1) == CGAL::SMALLER); + const bool res_l_o1o2 = (CGAL::compare_squared_distance(o1, o2, expected_result*(1-epsilon)-1) == CGAL::LARGER); + const bool res_l_o2o1 = (CGAL::compare_squared_distance(o2, o1, expected_result*(1-epsilon)-1) == CGAL::LARGER); + + // The equal result is guaranted only on exact construction kernel + if(epsilon==0) + { + assert(res_e_o1o2); + assert(res_e_o2o1); + } + assert(res_s_o1o2); + assert(res_s_o2o1); + assert(res_l_o1o2); + assert(res_l_o2o1); + } + + template + void check_compare_squared_distance_with_bound(const O1& o1, const O2& o2, const FT& upper_bound) + { + // const FT res_o1o2 = K().compare_squared_distance_3_object()(o1, o2, expected_result); + // const FT res_o2o1 = K().compare_squared_distance_3_object()(o2, o1, expected_result); + + const FT up = upper_bound * (1 + epsilon) + std::numeric_limits::epsilon(); + + const bool res_o1o2 = (CGAL::compare_squared_distance(o1, o2, up) != CGAL::LARGER); + const bool res_o2o1 = (CGAL::compare_squared_distance(o2, o1, up) != CGAL::LARGER); + + assert(res_o1o2); + assert(res_o2o1); + } + +private: + void P_P() + { + std::cout << "Point - Point" << std::endl; + check_compare_squared_distance(p(0, 0, 0), p(0, 0, 0), 0); + check_compare_squared_distance(p(3, 5, 7), p(0, 0, 0), 83); + } + + void P_S() + { + std::cout << "Point - Segment" << std::endl; + check_compare_squared_distance(p(0, 1, 2), S{p(-3, 0, 0), p( 2, 0, 0)}, 5); + check_compare_squared_distance(p(0, 1, 2), S{p( 3, 0, 0), p( 2, 0, 0)}, 9); + check_compare_squared_distance(p(0, 1, 2), S{p( 2, 0, 0), p( 3, 0, 0)}, 9); + check_compare_squared_distance(p(6, 1, 2), S{p( 2, 0, 0), p( 3, 0, 0)}, 14); + } + + void P_T() + { + std::cout << "Point - Triangle" << std::endl; + check_compare_squared_distance(p(0, 1, 2), T{p(0, 0, 0), p(2, 0, 0), p(0, 2, 0)}, 4); + + T t(p(0,0,0), p(3,0,0), p(3,3,0)); + check_compare_squared_distance (p(-1, -1, 0), t, 2); + check_compare_squared_distance (p(-1, 0, 0), t, 1); + check_compare_squared_distance (p(0, 0, 0), t, 0); + check_compare_squared_distance (p(1, 0, 0), t, 0); + check_compare_squared_distance (p(4, 0, 0), t, 1); + check_compare_squared_distance (p(1, -1, 0), t, 1); + check_compare_squared_distance (p(1, 1, 1), t, 1); + check_compare_squared_distance (p(1, 0, 1), t, 1); + check_compare_squared_distance (p(0, 0, 1), t, 1); + + // // Degenerate + check_compare_squared_distance (p(1, 2, 3), T(p(4,3,2), p(4,3,2), p(4,3,2)), squared_distance(p(1, 2, 3), p(4,3,2))); + check_compare_squared_distance (p(1, 2, 3), T(p(4,3,2), p(10,12,3), p(4,3,2)), squared_distance(p(1, 2, 3), p(4,3,2))); + check_compare_squared_distance (p(0, 0, 0), T(p(4,3,2), p(4,-3,-2), p(4,3,2)), squared_distance(p(0, 0, 0), p(4,0,0))); + + // On the triangle + check_compare_squared_distance (p(7, 1, -5), T(p(2,9,8), p(-4,-3,-5), p(7, 1, -5)), 0); // vertex + check_compare_squared_distance (p(7, 1, -5), T(p(14,2,-10), p(-7,-1,5), p(8, 3, -1)), 0); // edge + check_compare_squared_distance (p(1, 4, -3), T(p(0,-8,-3), p(-5,14,-3), p(10, 1, -3)), 0); // face + + // General + check_compare_squared_distance (p(-15, 1, 0), T(p(-10, 1, 0), p(0,0,0), p(10,0,0)), 25); + check_compare_squared_distance (p(-5, 0, 0), T(p(-10, 1, 0), p(0,0,0), p(10,0,0)), squared_distance(p(-5, 0, 0), S(p(-10, 1, 0), p(0,0,0)))); + check_compare_squared_distance (p(0, -3, 0), T(p(-10, 1, 0), p(0,0,0), p(10,0,0)), 9); + check_compare_squared_distance (p(3, -3, 0), T(p(-10, 1, 0), p(0,0,0), p(10,0,0)), squared_distance(p(3, -3, 0), S(p(0,0,0), p(10,0,0)))); + check_compare_squared_distance (p(16, 1, 1), T(p(-10, 1, 0), p(0,0,0), p(10,0,0)), 38); + check_compare_squared_distance (p(5, 5, 2), T(p(-10, 1, 0), p(0,0,0), p(10,0,0)), squared_distance(p(5, 5, 2), S(p(10,0,0), p(-10,1,0)))); + + for(int i=0; i1) in the code + for(int j=-2;j<4; j+=2) + { + for(int k=-3;k<3; k+=2) + { + P p2{j, k, z}; + P p3{j, k+2, z}; + + // to explicit the expected distances + if(j == -2 && k == -3) + check_compare_squared_distance(S{p0, p1}, S{p2, p3}, CGAL::squared_distance(p3, p0)); + else if(j == -2 && k == -1) + check_compare_squared_distance(S{p0, p1}, S{p2, p3}, 1); + else if(j == -2 && k == 1) + check_compare_squared_distance(S{p0, p1}, S{p2, p3}, CGAL::squared_distance(p2, p0)); + else if(j == 0 && k == -3) + check_compare_squared_distance(S{p0, p1}, S{p2, p3}, 1); + else if(j == 0 && k == -1) + check_compare_squared_distance(S{p0, p1}, S{p2, p3}, 0); + else if(j == 0 && k == 1) + check_compare_squared_distance(S{p0, p1}, S{p2, p3}, 1); + else if(j == 2 && k == -3) + check_compare_squared_distance(S{p0, p1}, S{p2, p3}, CGAL::squared_distance(p3, p1)); + else if(j == 2 && k == -1) + check_compare_squared_distance(S{p0, p1}, S{p2, p3}, 1); + else if(j == 2 && k == 1) + check_compare_squared_distance(S{p0, p1}, S{p2, p3}, CGAL::squared_distance(p2, p1)); + } + } + + for(int i=0; i, gte::Segment<3, FT> > GTE_SS_checker; + gte::Segment<3, FT> gte_s1{{p8.x(), p8.y(), p8.z()}, {p9.x(), p9.y(), p9.z()}}; + gte::Segment<3, FT> gte_s2{{p3.x(), p3.y(), p3.z()}, {p2.x(), p2.y(), p2.z()}}; + auto gte_res = GTE_SS_checker(gte_s1, gte_s2); + std::cout << "-------" << std::endl; + std::cout << "old: " << CGAL::internal::squared_distance_old(s89, s32, K()) << std::endl; + std::cout << "dist (GTE) : " << gte_res.sqrDistance << std::endl; +#endif + + // Because do_intersect() with constructions is likely to return 'false' even for overlaps + assert(are_equal(CGAL::squared_distance(s89, s32), result, false /*verbose*/) || + are_equal(CGAL::squared_distance(s32, s89), FT(0))); + } + + // completely generic + S s1{p0, p1}, s2{p2, p3}; + do_intersect_check(s1, s2); + +#ifdef CGAL_USE_GTE_AS_SANITY_CHECK + gte::DCPQuery, gte::Segment<3, FT> > GTE_SS_checker; + gte::Segment<3, FT> gte_s1{{p0.x(), p0.y(), p0.z()}, {p1.x(), p1.y(), p1.z()}}; + gte::Segment<3, FT> gte_s2{{p2.x(), p2.y(), p2.z()}, {p3.x(), p3.y(), p3.z()}}; + auto gte_res = GTE_SS_checker(gte_s1, gte_s2); + + std::cout << "dist (CGAL) : " << CGAL::squared_distance(s1, s2) << std::endl; + std::cout << "dist (GTE) : " << gte_res.sqrDistance << std::endl; + assert(are_equal(CGAL::squared_distance(s1, s2), gte_res.sqrDistance)); +#endif + } + + // a few brute force checks: sample a segments and use squared_distance(P3, S3) + for(int i=0; i<10; ++i) + { + P p0 = random_point(); + P p1 = random_point(); + P p2 = random_point(); + P p3 = random_point(); + + S s01{p0, p1}; + S s23{p2, p3}; + + FT upper_bound = CGAL::squared_distance(p0, p2); + + V p01 = V{p0, p1} / FT(N); + for(int l=0; l, gte::Triangle3 > GTE_TT_checker; + gte::Triangle3 gte_tr1{{p0.x(), p0.y(), p0.z()}, {p1.x(), p1.y(), p1.z()}, {p2.x(), p2.y(), p2.z()}}; + gte::Triangle3 gte_tr2{{p3.x(), p3.y(), p3.z()}, {p4.x(), p4.y(), p4.z()}, {p5.x(), p5.y(), p5.z()}}; + auto gte_res = GTE_TT_checker(gte_tr1, gte_tr2); + + std::cout << "dist (CGAL) : " << CGAL::squared_distance(tr1, tr2) << std::endl; + std::cout << "dist (GTE) : " << gte_res.sqrDistance << std::endl; + std::cout << "diff CGAL GTE : " << (gte_res.sqrDistance - CGAL::squared_distance(tr1, tr2)) << std::endl; + + // don't assert on purpose, GTE has slightly (10^-30 different results, even with an exact NT) + are_equal(CGAL::squared_distance(tr1, tr2), gte_res.sqrDistance); +#endif + } + } + +public: + void run() + { + std::cout << "Kernel: " << typeid(K).name() << std::endl; + + P_P(); + P_S(); + P_R(); + P_L(); + P_T(); + P_Pl(); + P_Tet(); + + S_S(); + S_R(); + S_L(); + S_Pl(); + + R_R(); + R_L(); + R_Pl(); + + L_L(); + L_Pl(); + + T_T(); + + Pl_Pl(); + } +}; + +int main() +{ + std::cout.precision(17); + std::cerr.precision(17); + + std::cout << "3D Distance tests" << std::endl; + + CGAL::Random r; + std::cout << "random seed = " << r.get_seed() << std::endl; + + // @todo Some tests are too difficult for these kernels +// Test >(r, 1e-5).run(); +// Test >(r, 1e-5).run(); +// Test > >(r, 1e-5).run(); + + // Test >(r, 0).run(); + + const double epick_eps = 10 * std::numeric_limits::epsilon(); + Test(r, epick_eps).run(); + + Test(r, 0).run(); + + std::cout << "Done!" << std::endl; + + return EXIT_SUCCESS; +} diff --git a/Distance_3/test/Distance_3/test_distance_3.cpp b/Distance_3/test/Distance_3/test_distance_3.cpp index f297e93016b..db899ac309f 100644 --- a/Distance_3/test/Distance_3/test_distance_3.cpp +++ b/Distance_3/test/Distance_3/test_distance_3.cpp @@ -241,10 +241,36 @@ private: void P_Tet() { std::cout << "Point - Tetrahedron\n"; + //Degenerate Tetrahedron + check_squared_distance (p(2, 2, 2), Tet(p(0, 0, 0), p( 6, 0, 0), p( 0, 6, 0), p( 6, 6, 0)), 4); + check_squared_distance (p(3, 3, 0), Tet(p(0, 0, 0), p( 6, 0, 0), p( 0, 6, 0), p( 6, 6, 0)), 0); + check_squared_distance (p(8, 8, 0), Tet(p(0, 0, 0), p( 6, 0, 0), p( 0, 6, 0), p( 6, 6, 0)), 8); + + //Inside Tetrahedron + check_squared_distance (p(1, 1, 1), Tet(p(0, 0, 0), p( 3, 0, 0), p( 0, 3, 0), p( 0, 0, 3)), 0); + check_squared_distance (p(1, 1, 1), Tet(p(0, 0, 0), p( 3, 0, 0), p( 0, 0, 3), p( 0, 3, 0)), 0); check_squared_distance (p(0, 0, 0), Tet(p(0, 0, 0), p( 1, 0, 0), p( 0, 1, 0), p( 0, 0, 1)), 0); + + //General check_squared_distance (p(0, 0, 2), Tet(p(0, 0, 0), p( 1, 0, 0), p( 0, 1, 0), p( 0, 0, 1)), 1); check_squared_distance (p(0, 0, -1), Tet(p(0, 0, 0), p( 1, 0, 0), p( 0, 1, 0), p( 0, 0, 1)), 1); check_squared_distance (p(5, 0, 0), Tet(p(0, 0, 0), p( 1, 0, 0), p( 0, 1, 0), p( 4, 0, 1)), 2); + check_squared_distance (p(1, 1, -1), Tet(p(0, 0, 1), p( 0, 0, 0), p( 4, 0, 0), p( 0, 4, 0)), 1); + check_squared_distance (p(1, 1, -1), Tet(p(0, 0, 1), p( 0, 0, 0), p( 0, 4, 0), p( 4, 0, 0)), 1); + + for(int i=0; i::value); CGAL_assertion(amap.is_whole_map_unmarked(mmark_number)); - mark_cell(amap, (*this), mmark_number); + if(this->cont()) + { mark_cell(amap, (*this), mmark_number); } } /// Constructor with a dart in parameter (for end iterator). @@ -81,8 +82,8 @@ namespace CGAL { Base(amap, adart), mmark_number(amap.get_new_mark()) { - if (adart!=this->mmap->null_descriptor) - mark_cell(amap, (*this), mmark_number); + if (this->cont()) + { mark_cell(amap, (*this), mmark_number); } } /// Destructor. @@ -136,7 +137,7 @@ namespace CGAL { this->mmap->is_marked((*this), mmark_number)); if (this->cont()) - mark_cell(*this->mmap, (*this), mmark_number); + { mark_cell(*this->mmap, (*this), mmark_number); } return *this; } @@ -249,7 +250,7 @@ namespace CGAL { this->mmap->is_marked((*this), mmark_number)); if (this->cont()) - mark_cell(*this->mmap, (*this), mmark_number); + { mark_cell(*this->mmap, (*this), mmark_number); } return *this; } diff --git a/GraphicsView/include/CGAL/Qt/GraphicsViewPolygonWithHolesInput.h b/GraphicsView/include/CGAL/Qt/GraphicsViewPolygonWithHolesInput.h index e97c999ee10..24c60dcdcf6 100644 --- a/GraphicsView/include/CGAL/Qt/GraphicsViewPolygonWithHolesInput.h +++ b/GraphicsView/include/CGAL/Qt/GraphicsViewPolygonWithHolesInput.h @@ -90,7 +90,7 @@ private: template GraphicsViewPolygonWithHolesInput::GraphicsViewPolygonWithHolesInput(QObject *parent, QGraphicsScene* s) - : GraphicsViewInput(parent), scene_(s), polygon_input(false) + : GraphicsViewInput(parent), polygon_input(false), scene_(s) { pwhItem = new CGAL::Qt::PolygonWithHolesGraphicsItem(&pwh); pwhItem->setBrush(::Qt::yellow); @@ -151,7 +151,7 @@ GraphicsViewPolygonWithHolesInput::processInput(CGAL::Object o) template void -GraphicsViewPolygonWithHolesInput::keyPressEvent ( QKeyEvent * event ) +GraphicsViewPolygonWithHolesInput::keyPressEvent ( QKeyEvent * /* event */ ) { } diff --git a/HalfedgeDS/doc/HalfedgeDS/PackageDescription.txt b/HalfedgeDS/doc/HalfedgeDS/PackageDescription.txt index 48650817c57..ea6800cd6b1 100644 --- a/HalfedgeDS/doc/HalfedgeDS/PackageDescription.txt +++ b/HalfedgeDS/doc/HalfedgeDS/PackageDescription.txt @@ -19,7 +19,6 @@ /*! \addtogroup PkgHalfedgeDSRef -\todo check generated documentation \cgalPkgDescriptionBegin{Halfedge Data Structures,PkgHalfedgeDS} \cgalPkgPicture{HalfedgeDS/fig/HalfedgeDS-teaser-small.png} \cgalPkgSummaryBegin diff --git a/HalfedgeDS/include/CGAL/boost/graph/properties_HalfedgeDS_base.h b/HalfedgeDS/include/CGAL/boost/graph/properties_HalfedgeDS_base.h index a39cfd90715..fcb7e3a9175 100644 --- a/HalfedgeDS/include/CGAL/boost/graph/properties_HalfedgeDS_base.h +++ b/HalfedgeDS/include/CGAL/boost/graph/properties_HalfedgeDS_base.h @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include namespace CGAL { @@ -70,7 +70,7 @@ public: { unsigned int data = 0; typename boost::graph_traits::edge_iterator it, end; - for(boost::tie(it, end) = edges(p); it != end; ++it, ++data) + for(std::tie(it, end) = edges(p); it != end; ++it, ++data) (*map_)[*it] = data; } diff --git a/HalfedgeDS/package_info/HalfedgeDS/dependencies b/HalfedgeDS/package_info/HalfedgeDS/dependencies index ffbfcd5b201..1015a2da048 100644 --- a/HalfedgeDS/package_info/HalfedgeDS/dependencies +++ b/HalfedgeDS/package_info/HalfedgeDS/dependencies @@ -1,6 +1,7 @@ Algebraic_foundations BGL Circulator +Distance_2 Distance_3 HalfedgeDS Hash_map diff --git a/Hash_map/benchmark/Hash_map/hm.cpp b/Hash_map/benchmark/Hash_map/hm.cpp index 891ca23ef10..070b7c7cd4d 100644 --- a/Hash_map/benchmark/Hash_map/hm.cpp +++ b/Hash_map/benchmark/Hash_map/hm.cpp @@ -157,11 +157,11 @@ run(const G& g) #if 0 - std::cerr << "boost::tie(vb,ve) = vertices(g);\n"; + std::cerr << "std::tie(vb,ve) = vertices(g);\n"; t.reset(); t.start(); for(int i=0; i<100; i++){ typename boost::graph_traits::vertex_iterator vb, ve; - boost::tie(vb,ve) = vertices(g); + std::tie(vb,ve) = vertices(g); for(; vb != ve; ++vb) { vertex_descriptor vd = *vb; #ifdef NOHASH diff --git a/Heat_method_3/include/CGAL/Heat_method_3/Surface_mesh_geodesic_distances_3.h b/Heat_method_3/include/CGAL/Heat_method_3/Surface_mesh_geodesic_distances_3.h index a4510dd552c..16078898df6 100644 --- a/Heat_method_3/include/CGAL/Heat_method_3/Surface_mesh_geodesic_distances_3.h +++ b/Heat_method_3/include/CGAL/Heat_method_3/Surface_mesh_geodesic_distances_3.h @@ -297,7 +297,7 @@ private: } CGAL::Vertex_around_face_iterator vbegin, vend, vmiddle; for(face_descriptor f : faces(tm)) { - boost::tie(vbegin, vend) = vertices_around_face(halfedge(f,tm),tm); + std::tie(vbegin, vend) = vertices_around_face(halfedge(f,tm),tm); vertex_descriptor current = *(vbegin); vertex_descriptor neighbor_one = *(++vbegin); vertex_descriptor neighbor_two = *(++vbegin); @@ -350,7 +350,7 @@ private: Matrix indexD(dimension,1); CGAL::Vertex_around_face_iterator vbegin, vend, vmiddle; for(face_descriptor f : faces(tm)) { - boost::tie(vbegin, vend) = vertices_around_face(halfedge(f,tm),tm); + std::tie(vbegin, vend) = vertices_around_face(halfedge(f,tm),tm); vertex_descriptor current = *(vbegin); vertex_descriptor neighbor_one = *(++vbegin); vertex_descriptor neighbor_two = *(++vbegin); @@ -514,7 +514,7 @@ private: CGAL::Vertex_around_face_iterator vbegin, vend, vmiddle; for(face_descriptor f : faces(tm)) { - boost::tie(vbegin, vend) = vertices_around_face(halfedge(f,tm),tm); + std::tie(vbegin, vend) = vertices_around_face(halfedge(f,tm),tm); vertex_descriptor current = *(vbegin); vertex_descriptor neighbor_one = *(++vbegin); vertex_descriptor neighbor_two = *(++vbegin); diff --git a/Heat_method_3/include/CGAL/Heat_method_3/internal/Intrinsic_Delaunay_triangulation_3.h b/Heat_method_3/include/CGAL/Heat_method_3/internal/Intrinsic_Delaunay_triangulation_3.h index 77a399704ec..64a61c993ba 100644 --- a/Heat_method_3/include/CGAL/Heat_method_3/internal/Intrinsic_Delaunay_triangulation_3.h +++ b/Heat_method_3/include/CGAL/Heat_method_3/internal/Intrinsic_Delaunay_triangulation_3.h @@ -446,7 +446,7 @@ private: for(face_descriptor f : faces(m_intrinsic_tm)) { CGAL::Vertex_around_face_iterator vbegin, vend, vmiddle; - boost::tie(vbegin, vend) = vertices_around_face(halfedge(f,m_intrinsic_tm),m_intrinsic_tm); + std::tie(vbegin, vend) = vertices_around_face(halfedge(f,m_intrinsic_tm),m_intrinsic_tm); halfedge_descriptor hd = halfedge(f,m_intrinsic_tm); if(face(hd,m_intrinsic_tm) != f) { hd = opposite(hd,m_intrinsic_tm); diff --git a/Hyperbolic_triangulation_2/doc/Hyperbolic_triangulation_2/CGAL/Hyperbolic_Delaunay_triangulation_2.h b/Hyperbolic_triangulation_2/doc/Hyperbolic_triangulation_2/CGAL/Hyperbolic_Delaunay_triangulation_2.h index ef2d984340b..b89c95f5656 100644 --- a/Hyperbolic_triangulation_2/doc/Hyperbolic_triangulation_2/CGAL/Hyperbolic_Delaunay_triangulation_2.h +++ b/Hyperbolic_triangulation_2/doc/Hyperbolic_triangulation_2/CGAL/Hyperbolic_Delaunay_triangulation_2.h @@ -200,7 +200,19 @@ public: /*! Returns the hyperbolic segment formed by the vertices of edge `e`. */ - Hyperbolic_segment hyperbolic_segment (const Edge& e) const; + Hyperbolic_segment hyperbolic_segment(const Edge& e) const; + + /*! + Returns the hyperbolic point given by the finite vertex `vh`. + */ + Point point(const Vertex_handle vh) const; + + /*! + Returns the point given by vertex `i` of face `fh`. + \pre `t.dimension()` \f$ \geq0\f$ and \f$ i \in\{0,1,2\}\f$ in dimension 2, \f$ i \in\{0,1\}\f$ in dimension 1, \f$ i = 0\f$ in dimension 0, and the vertex is finite. + */ + Point point(const Face_handle fh, const int i) const; + ///@} diff --git a/Hyperbolic_triangulation_2/include/CGAL/Hyperbolic_Delaunay_triangulation_2.h b/Hyperbolic_triangulation_2/include/CGAL/Hyperbolic_Delaunay_triangulation_2.h index d95bfe27fba..0b79c1af1b3 100644 --- a/Hyperbolic_triangulation_2/include/CGAL/Hyperbolic_Delaunay_triangulation_2.h +++ b/Hyperbolic_triangulation_2/include/CGAL/Hyperbolic_Delaunay_triangulation_2.h @@ -740,6 +740,32 @@ public: Hyperbolic_segment segment(const Edge& e) const { return hyperbolic_segment(e); } Hyperbolic_segment segment(const Edge_circulator& e) const { return hyperbolic_segment(e); } + const Point& point(const Vertex_handle vh) const + { + CGAL_precondition(!is_infinite(vh)); + return vh->point(); + } + + const Point& point(const Face_handle fh, const int i) const + { + CGAL_precondition(!is_infinite(fh->vertex(i))); + CGAL_precondition(0 <= i && i <= 2); + return fh->vertex(i)->point(); + } + + Point& point(const Vertex_handle vh) + { + CGAL_precondition(!is_infinite(vh)); + return vh->point(); + } + + Point& point(const Face_handle fh, const int i) + { + CGAL_precondition(!is_infinite(fh->vertex(i))); + CGAL_precondition(0 <= i && i <= 2); + return fh->vertex(i)->point(); + } + size_type number_of_vertices() const { return Base::number_of_vertices(); } Vertex_circulator adjacent_vertices(Vertex_handle v) const { return Vertex_circulator(v, *this); } @@ -825,32 +851,6 @@ public: } public: - const Point& point(const Vertex_handle vh) const - { - CGAL_precondition(!is_infinite(vh)); - return vh->point(); - } - - const Point& point(const Face_handle fh, const int i) const - { - CGAL_precondition(!is_infinite(fh->vertex(i))); - CGAL_precondition(0 <= i && i <= 2); - return fh->vertex(i)->point(); - } - - Point& point(const Vertex_handle vh) - { - CGAL_precondition(!is_infinite(vh)); - return vh->point(); - } - - Point& point(const Face_handle fh, const int i) - { - CGAL_precondition(!is_infinite(fh->vertex(i))); - CGAL_precondition(0 <= i && i <= 2); - return fh->vertex(i)->point(); - } - bool is_valid() { if (!Base::is_valid()) diff --git a/Inscribed_areas/doc/Inscribed_areas/PackageDescription.txt b/Inscribed_areas/doc/Inscribed_areas/PackageDescription.txt index a15bb4b041c..aa77a9b9cc9 100644 --- a/Inscribed_areas/doc/Inscribed_areas/PackageDescription.txt +++ b/Inscribed_areas/doc/Inscribed_areas/PackageDescription.txt @@ -5,7 +5,6 @@ /*! \addtogroup PkgInscribedAreasRef -\todo check generated documentation \cgalPkgDescriptionBegin{Inscribed Areas,PkgInscribedAreas} \cgalPkgPicture{ler-detail.png} \cgalPkgSummaryBegin diff --git a/Installation/CHANGES.md b/Installation/CHANGES.md index e5d5ee5be91..c52ea9139f0 100644 --- a/Installation/CHANGES.md +++ b/Installation/CHANGES.md @@ -6,14 +6,23 @@ ### General Changes - The minimal supported version of Boost is now 1.74.0. +### [Polygon Mesh Processing](https://doc.cgal.org/6.1/Manual/packages.html#PkgPolygonMeshProcessing) +- Added the function `CGAL::Polygon_mesh_processing::discrete_mean_curvature` and `CGAL::Polygon_mesh_processing::discrete_Guassian_curvature` to evaluate the discrete curvature at a vertex of a mesh. +- Added the function `CGAL::Polygon_mesh_processing::angle_sum` to compute the sum of the angles around a vertex. + + ### [Algebraic Kernel](https://doc.cgal.org/6.1/Manual/packages.html#PkgAlgebraicKernelD) - **Breaking change**: Classes based on the RS Library are no longer provided. +### [BGL](https://doc.cgal.org/6.1/Manual/packages.html#PkgBGL) +- Added the function `CGAL::Euler::remove_degree_2_vertex()`, which enables users to remove vertices which have exactly two incident edges. + ### [2D Arrangements](https://doc.cgal.org/6.1/Manual/packages.html#PkgArrangementOnSurface2) - Introduces two traits decorators, namely `Arr_tracing_traits_2` and `Arr_counting_traits_2`, which can be used to extract debugging and informative metadata about the traits in use while a program is being executed. - Fixed the Landmark point-location strategy so that it can be applied to arrangements on a sphere. +- Fixed a bug in the extensions of vertex and halfedge types of the DCEL when used to instantiate Arrangement_with_history_2 or similar arrangement classes that derive from Arrangement_2. ### [3D Mesh Generation](https://doc.cgal.org/6.1/Manual/packages.html#PkgMesh3) @@ -28,6 +37,13 @@ by `subconstraints()` has changed from `const std::pair*>` to `Subconstraint`. The old range type is now returned by a new function named `subconstraints_and_contexts()`. +### [Polygon Repair](https://doc.cgal.org/6.1/Manual/packages.html#PkgPolygonRepair) + +- Add a the non-zero rule, as well as functions to compute the conservative inner and outer hull of similar polygons. + +### Triangulations +- All triangulations now offer the functions `point(Vertex_handle)` and `point(Simplex, int)`, which enables users to access the geometric position of a vertex and of the i-th vertex of a simplex of a triangulation. + ## [Release 6.0.1](https://github.com/CGAL/cgal/releases/tag/v6.0.1) ### [Poisson Surface Reconstruction](https://doc.cgal.org/6.0.1/Manual/packages.html#PkgPoissonSurfaceReconstruction3) diff --git a/Installation/cmake/modules/display-third-party-libs-versions.cmake b/Installation/cmake/modules/display-third-party-libs-versions.cmake index 96ef4e14992..7f7d8695797 100644 --- a/Installation/cmake/modules/display-third-party-libs-versions.cmake +++ b/Installation/cmake/modules/display-third-party-libs-versions.cmake @@ -1,9 +1,27 @@ set(LIBRARIES_TO_CHECK - Eigen3 Qt6 TBB OpenMesh Boost - GMP Threads SuiteSparse MPFI METIS - VTK SCIP OSQP LASLIB GLPK - ITT Ceres MPFR libpointmatcher ITK - OpenGR OpenCV ZLIB + Boost + Ceres + Eigen3 + GLPK + GMP + ITK + ITT + LASLIB + libpointmatcher + METIS + MPFI + MPFR + OpenCV + OpenGR + OpenMesh + OSQP + Qt6 + SCIP + SuiteSparse + TBB + Threads + VTK + ZLIB ) include(${CMAKE_CURRENT_LIST_DIR}/CGAL_TweakFindBoost.cmake) diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h index 4aba04c9e1a..9693b6ce436 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/tetrahedron_lines_intersections_3.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include diff --git a/Jet_fitting_3/doc/Jet_fitting_3/PackageDescription.txt b/Jet_fitting_3/doc/Jet_fitting_3/PackageDescription.txt index cc0ea70929d..90af6ff6785 100644 --- a/Jet_fitting_3/doc/Jet_fitting_3/PackageDescription.txt +++ b/Jet_fitting_3/doc/Jet_fitting_3/PackageDescription.txt @@ -3,7 +3,6 @@ /// \ingroup PkgJetFitting3Ref /*! \addtogroup PkgJetFitting3Ref -\todo check generated documentation \cgalPkgDescriptionBegin{Estimation of Local Differential Properties of Point-Sampled Surfaces,PkgJetFitting3} \cgalPkgPicture{DavidDetail.png} \cgalPkgSummaryBegin diff --git a/Kernel_23/examples/Kernel_23/MyKernel.cpp b/Kernel_23/examples/Kernel_23/MyKernel.cpp index 834a22629b8..0894706db7b 100644 --- a/Kernel_23/examples/Kernel_23/MyKernel.cpp +++ b/Kernel_23/examples/Kernel_23/MyKernel.cpp @@ -1,4 +1,3 @@ -#include #include #include #include diff --git a/Kernel_23/include/CGAL/Kernel/function_objects.h b/Kernel_23/include/CGAL/Kernel/function_objects.h index 5a7b0774e6d..c932ea5acfe 100644 --- a/Kernel_23/include/CGAL/Kernel/function_objects.h +++ b/Kernel_23/include/CGAL/Kernel/function_objects.h @@ -937,15 +937,14 @@ namespace CommonKernelFunctors { Needs_FT operator()(const T1& p, const T2& q, const FT& d2) const { - return CGAL::compare(internal::squared_distance(p, q, K()), d2); + return internal::compare_squared_distance(p, q, K(), d2); } template Needs_FT operator()(const T1& p, const T2& q, const T3& r, const T4& s) const { - return CGAL::compare(internal::squared_distance(p, q, K()), - internal::squared_distance(r, s, K())); + return internal::compare_squared_distance(p, q, K(), internal::squared_distance(r, s, K())); } }; @@ -965,22 +964,14 @@ namespace CommonKernelFunctors { typename K::Compute_scalar_product_3 scalar_product = k.compute_scalar_product_3_object(); - double product = CGAL::sqrt(to_double(scalar_product(u,u)) * to_double(scalar_product(v,v))); + double product = to_double(approximate_sqrt(scalar_product(u,u) * scalar_product(v,v))); if(product == 0) return 0; // cosine double dot = to_double(scalar_product(u,v)); - double cosine = dot / product; - - if(cosine > 1.){ - cosine = 1.; - } - if(cosine < -1.){ - cosine = -1.; - } - + double cosine = std::clamp(dot / product, -1., 1.); return std::acos(cosine) * 180./CGAL_PI; } diff --git a/Kernel_23/include/CGAL/Kernel/global_functions_3.h b/Kernel_23/include/CGAL/Kernel/global_functions_3.h index 6fb9b975647..b660dd84f05 100644 --- a/Kernel_23/include/CGAL/Kernel/global_functions_3.h +++ b/Kernel_23/include/CGAL/Kernel/global_functions_3.h @@ -412,16 +412,6 @@ compare_slope(const Point_3 &p, return internal::compare_slope(p, q, r, s, K()); } -template < class K > -inline -typename K::Comparison_result -compare_squared_distance(const Point_3 &p, - const Point_3 &q, - const typename K::FT &d2) -{ - return internal::compare_squared_distance(p, q, d2, K()); -} - template < class K > inline typename K::Comparison_result diff --git a/Kernel_d/doc/Kernel_d/CGAL/Kernel_d/Aff_transformation_d.h b/Kernel_d/doc/Kernel_d/CGAL/Kernel_d/Aff_transformation_d.h index aa572c2df9a..f2edc867e1d 100644 --- a/Kernel_d/doc/Kernel_d/CGAL/Kernel_d/Aff_transformation_d.h +++ b/Kernel_d/doc/Kernel_d/CGAL/Kernel_d/Aff_transformation_d.h @@ -98,7 +98,7 @@ in the plane spanned by the base vectors \f$ b_{e1}\f$ and \f$ b_{e2}\f$ in \f$ d\f$-space. Thus the default use delivers a planar rotation in the \f$ x\f$-\f$ y\f$ plane. -\pre \f$ sin_num^2 + cos_num^2 = den^2\f$ and \f$ 0 \leq e_1 < e_2 < d\f$. +\pre \f$ sin\_num^2 + cos\_num^2 = den^2\f$ and \f$ 0 \leq e_1 < e_2 < d\f$. \pre `den != 0`. */ diff --git a/Kernel_d/doc/Kernel_d/PackageDescription.txt b/Kernel_d/doc/Kernel_d/PackageDescription.txt index f8c024183a2..783f291db01 100644 --- a/Kernel_d/doc/Kernel_d/PackageDescription.txt +++ b/Kernel_d/doc/Kernel_d/PackageDescription.txt @@ -21,7 +21,6 @@ /*! \addtogroup PkgKernelDRef -\todo check generated documentation \cgalPkgDescriptionBegin{dD Geometry Kernel,PkgKernelD} \cgalPkgPicture{hypercube.png} \cgalPkgSummaryBegin diff --git a/Kinetic_space_partition/include/CGAL/KSP/debug.h b/Kinetic_space_partition/include/CGAL/KSP/debug.h index eae47856078..6615721be51 100644 --- a/Kinetic_space_partition/include/CGAL/KSP/debug.h +++ b/Kinetic_space_partition/include/CGAL/KSP/debug.h @@ -929,14 +929,6 @@ void dump_polygon(const std::vector& pts, const std::string saver.export_polygon_soup_3(pts2, filename); } -void dump_polygon(const std::vector& pts, const std::string& filename) { - Saver saver; - std::vector > pts2; - pts2.push_back(pts); - - saver.export_polygon_soup_3(pts2, filename); -} - void dump_polygona(const std::vector& pts, const std::string& filename) { Saver saver; std::vector > pts2; diff --git a/Kinetic_space_partition/include/CGAL/KSP_3/Data_structure.h b/Kinetic_space_partition/include/CGAL/KSP_3/Data_structure.h index 85c93daeb05..8514cff93d8 100644 --- a/Kinetic_space_partition/include/CGAL/KSP_3/Data_structure.h +++ b/Kinetic_space_partition/include/CGAL/KSP_3/Data_structure.h @@ -159,7 +159,6 @@ public: } }; - // ToDo:: check all kind of iterators/circulators using PEdge_around_pvertex_iterator = boost::transform_iterator >; using PEdges_around_pvertex = CGAL::Iterator_range; @@ -1390,16 +1389,19 @@ public: return support_plane(support_plane_idx).to_2d(segment_3); } -/* - IkSegment_2 to_2d(const std::size_t support_plane_idx, const IkSegment_3& segment_3) const { + template + auto to_2d(const std::size_t support_plane_idx, const IkSegment_3& segment_3) const + -> std::enable_if_t, IkSegment_2> { return support_plane(support_plane_idx).to_2d(segment_3); - }*/ + } Point_2 to_2d(const std::size_t support_plane_idx, const Point_3& point_3) const { return support_plane(support_plane_idx).to_2d(point_3); } - IkPoint_2 to_2d(const std::size_t support_plane_idx, const IkPoint_3& point_3) const { + template + auto to_2d(const std::size_t support_plane_idx, const IkPoint_3& point_3) const + -> std::enable_if_t, IkPoint_2> { return support_plane(support_plane_idx).to_2d(point_3); } diff --git a/Kinetic_space_partition/include/CGAL/KSP_3/Initializer.h b/Kinetic_space_partition/include/CGAL/KSP_3/Initializer.h index f3e5550a4d9..9942d696dcc 100644 --- a/Kinetic_space_partition/include/CGAL/KSP_3/Initializer.h +++ b/Kinetic_space_partition/include/CGAL/KSP_3/Initializer.h @@ -493,7 +493,7 @@ private: typename Intersection_graph::Kinetic_interval& kinetic_interval = m_data.igraph().kinetic_interval(e, sp_idx); crossing_iedges.push_back(e); - if (emin > s || std::isinf(min_speed)) { + if (emin > s || std::isinf(CGAL::to_double(min_speed))) { typename Intersection_kernel::FT bary_edge_exact = (emin - s) / (t - s); FT bary_edge = from_exact((emin - s) / (t - s)); CGAL_assertion(bary_edge_exact >= 0); @@ -505,7 +505,7 @@ private: kinetic_interval.push_back(std::pair(0, 0)); } - if (t > emax || std::isinf(max_speed)) { + if (t > emax || std::isinf(CGAL::to_double(max_speed))) { typename Intersection_kernel::FT bary_edge_exact = (emax - s) / (t - s); FT bary_edge = from_exact((emax - s) / (t - s)); CGAL_assertion(0 <= bary_edge_exact && bary_edge_exact <= 1); diff --git a/Kinetic_space_partition/include/CGAL/KSP_3/Support_plane.h b/Kinetic_space_partition/include/CGAL/KSP_3/Support_plane.h index b85e37ea14d..c4f0e0c5ed9 100644 --- a/Kinetic_space_partition/include/CGAL/KSP_3/Support_plane.h +++ b/Kinetic_space_partition/include/CGAL/KSP_3/Support_plane.h @@ -377,7 +377,7 @@ public: for (const auto& pair : points) { const auto& point = pair.first; directions.push_back(typename Intersection_kernel::Vector_2(to_exact(m_data->centroid), point)); - const FT length = CGAL::sqrt(CGAL::abs(from_exact(directions.back() * directions.back()))); + const FT length = CGAL::approximate_sqrt(CGAL::abs(from_exact(directions.back() * directions.back()))); sum_length += length; num += 1; } @@ -676,8 +676,9 @@ public: m_data->plane.to_2d(Point_3(0, 0, 0) + vec)); } - template::type > - const typename Intersection_kernel::Point_2 to_2d(const typename Intersection_kernel::Point_3& point) const { + template + auto to_2d(const typename Intersection_kernel::Point_3& point) const + ->std::enable_if_t, const typename Intersection_kernel::Point_2> { return m_data->exact_plane.to_2d(point); } @@ -687,8 +688,9 @@ public: m_data->plane.to_2d(line.point() + line.to_vector())); } - template::type > - const typename Intersection_kernel::Line_2 to_2d(const typename Intersection_kernel::Line_3& line) const { + template + auto to_2d(const typename Intersection_kernel::Line_3& line) const + -> std::enable_if_t, const typename Intersection_kernel::Line_2> { return typename Intersection_kernel::Line_2( m_data->exact_plane.to_2d(line.point()), m_data->exact_plane.to_2d(line.point() + line.to_vector())); @@ -700,25 +702,21 @@ public: m_data->plane.to_2d(segment.target())); } - template::type > - const typename Intersection_kernel::Segment_2 to_2d(const typename Intersection_kernel::Segment_3& segment) const { + template + auto to_2d(const typename Intersection_kernel::Segment_3& segment) const + -> std::enable_if_t, const typename Intersection_kernel::Segment_2> { return typename Intersection_kernel::Segment_2( m_data->exact_plane.to_2d(segment.source()), m_data->exact_plane.to_2d(segment.target())); } - const Vector_3 to_3d(const Vector_2& vec) const { - return Vector_3( - m_data->plane.to_3d(Point_2(FT(0), FT(0))), - m_data->plane.to_3d(Point_2(FT(0), FT(0)) + vec)); - } - const Point_3 to_3d(const Point_2& point) const { return m_data->plane.to_3d(point); } - template::type > - const typename Intersection_kernel::Point_3 to_3d(const typename Intersection_kernel::Point_2& point) const { + template + auto to_3d(const typename Intersection_kernel::Point_2& point) const + ->std::enable_if_t, const typename Intersection_kernel::Point_3> { return m_data->exact_plane.to_3d(point); } diff --git a/Kinetic_space_partition/include/CGAL/Kinetic_space_partition_3.h b/Kinetic_space_partition/include/CGAL/Kinetic_space_partition_3.h index a11a1f9dc71..23a43b8f646 100644 --- a/Kinetic_space_partition/include/CGAL/Kinetic_space_partition_3.h +++ b/Kinetic_space_partition/include/CGAL/Kinetic_space_partition_3.h @@ -398,6 +398,8 @@ public: using NP_helper = Point_set_processing_3_np_helper; using PointMap = typename NP_helper::Point_map; + static_assert(std::is_same_v); + PointMap point_map = NP_helper::get_point_map(np); To_exact to_exact; diff --git a/Kinetic_space_partition/test/Kinetic_space_partition/CMakeLists.txt b/Kinetic_space_partition/test/Kinetic_space_partition/CMakeLists.txt index 81789f3965f..edae7092c3f 100644 --- a/Kinetic_space_partition/test/Kinetic_space_partition/CMakeLists.txt +++ b/Kinetic_space_partition/test/Kinetic_space_partition/CMakeLists.txt @@ -10,30 +10,24 @@ set(CMAKE_CXX_STANDARD 17) find_package(CGAL QUIET COMPONENTS Core) include(CGAL_CreateSingleSourceCGALProgram) -find_package(Boost REQUIRED) -if(Boost_FOUND) - message(STATUS "Found Boost") - - find_package(Eigen3 3.1.0 REQUIRED) - if(Eigen3_FOUND) - message(STATUS "Found Eigen") - include(CGAL_Eigen3_support) - - set(targets kinetic_3d_test_all issue_8624) - - set(project_linked_libraries) - set(project_compilation_definitions) - - foreach(target ${targets}) - create_single_source_cgal_program("${target}.cpp") - if(TARGET ${target}) - target_link_libraries(${target} PRIVATE ${project_linked_libraries} CGAL::Eigen3_support) - target_compile_definitions(${target} PRIVATE ${project_compilation_definitions}) - endif() - endforeach() - else() - message(ERROR "This program requires the Eigen library, and will not be compiled.") - endif() -else() - message(ERROR "This program requires the Boost library, and will not be compiled.") +find_package(Eigen3 3.1.0 REQUIRED) +if(NOT Eigen3_FOUND) + message(ERROR "This project requires the Eigen library, and will not be compiled.") + return() endif() + +message(STATUS "Found Eigen") +include(CGAL_Eigen3_support) + +set(targets kinetic_3d_test_all issue_8624) + +set(project_linked_libraries) +set(project_compilation_definitions) + +foreach(target ${targets}) + create_single_source_cgal_program("${target}.cpp") + if(TARGET ${target}) + target_link_libraries(${target} PRIVATE ${project_linked_libraries} CGAL::Eigen3_support) + target_compile_definitions(${target} PRIVATE ${project_compilation_definitions}) + endif() +endforeach() diff --git a/Kinetic_surface_reconstruction/include/CGAL/Kinetic_surface_reconstruction_3.h b/Kinetic_surface_reconstruction/include/CGAL/Kinetic_surface_reconstruction_3.h index 9ff59a0202a..b2325f285d9 100644 --- a/Kinetic_surface_reconstruction/include/CGAL/Kinetic_surface_reconstruction_3.h +++ b/Kinetic_surface_reconstruction/include/CGAL/Kinetic_surface_reconstruction_3.h @@ -1546,7 +1546,7 @@ private: n = m_lcc.beta(n, 1); } while (n != dh); - KSP_3::internal::dump_polygon(face, fn); + KSP_3::internal::dump_polygon(face, fn); } void write_edge(typename LCC::Dart_descriptor dh, const std::string& fn) { @@ -1707,7 +1707,7 @@ private: m_face_area_lcc.resize(m_faces_lcc.size(), 0); for (std::size_t i = 0; i < m_faces_lcc.size(); i++) - m_face_area_lcc[i] = m_face_area_lcc[i] * 2.0 * m_total_inliers / total_area; + m_face_area_lcc[i] = m_face_area_lcc[i] * FT(2.0) * FT(m_total_inliers) / total_area; } FT area(typename LCC::Dart_descriptor face_dart, Plane_3 &pl, std::vector *tris = nullptr) { diff --git a/Lab/demo/Lab/CGAL_Lab.cpp b/Lab/demo/Lab/CGAL_Lab.cpp index 85880fb8add..ff4d0d3c598 100644 --- a/Lab/demo/Lab/CGAL_Lab.cpp +++ b/Lab/demo/Lab/CGAL_Lab.cpp @@ -83,7 +83,7 @@ CGAL_Lab::CGAL_Lab(int& argc, char **argv, tr("Ignore the autostart.js file, if any.")); parser.addOption(no_autostart); QCommandLineOption verbose("verbose", - tr("Print the paths explored byt the application searching for plugins.")); + tr("Print the paths explored by the application searching for plugins.")); parser.addOption(verbose); QCommandLineOption old("old", tr("Force OpenGL 2.1 context.")); diff --git a/Lab/demo/Lab/CGALlab.h b/Lab/demo/Lab/CGALlab.h index 47b5d6289a2..b1142724524 100644 --- a/Lab/demo/Lab/CGALlab.h +++ b/Lab/demo/Lab/CGALlab.h @@ -20,7 +20,7 @@ public: * Constructor : calls the constructor of QApplication */ CGAL_Lab(int& argc, char **argv, - QString application_name = "Polyhedron_3 demo", + QString application_name = "CGAL Lab", QString main_window_title = "CGAL Lab", QStringList input_keywords = QStringList()); diff --git a/Lab/demo/Lab/CGALlab_macros.cmake b/Lab/demo/Lab/CGALlab_macros.cmake index c0d73bd4cec..5b7e51e07c1 100644 --- a/Lab/demo/Lab/CGALlab_macros.cmake +++ b/Lab/demo/Lab/CGALlab_macros.cmake @@ -63,30 +63,20 @@ add_dependencies(CGALlab_compile_all_plugins CGALlab_all_plugins) STRING(TOLOWER "${plugin_implementation_base_name}.json" base_name) SET(filename "${CMAKE_CURRENT_BINARY_DIR}/${base_name}") LIST(LENGTH ARG_KEYWORDS size) + SET(keywords "") if(${size} GREATER 0) - SET(keywords ) - FILE(WRITE ${filename} "{ \"Keywords\" : [") foreach(keyword ${ARG_KEYWORDS}) - LIST(APPEND keywords "\"${keyword}\", ") + SET(keywords "${keywords}\"${keyword}\", ") if(NOT TARGET ${keyword}) add_custom_target(${keyword}) endif() add_dependencies( ${keyword} ${plugin_name}) endforeach() - LIST(LENGTH keywords size) - math(EXPR size "${size} - 1") - LIST(GET keywords -1 last_element) - LIST(REMOVE_AT keywords ${size}) - STRING(LENGTH ${last_element} size) - math(EXPR size "${size} - 2") - STRING(SUBSTRING ${last_element} 0 ${size} last_element) - LIST(APPEND keywords ${last_element}) - foreach(keyword ${keywords}) - file(APPEND ${filename} ${keyword}) - endforeach() - file(APPEND ${filename} "], \n") - string(TIMESTAMP VERSION "%Y-%m-%d %H:%M") - file(APPEND ${filename} "\"ConfigDate\" : \"${VERSION}\" }") + # Remove the last comma and space + string(REGEX REPLACE ", $" "" keywords "${keywords}") endif() + file(WRITE ${filename} "{\n \"Keywords\" : [ ${keywords} ],\n") + string(TIMESTAMP VERSION "%Y-%m-%d %H:%M") + file(APPEND ${filename} " \"ConfigDate\" : \"${VERSION}\"\n}\n") CGAL_install_hooks() endmacro(cgal_lab_plugin) diff --git a/Lab/demo/Lab/Color_map.h b/Lab/demo/Lab/Color_map.h index a7a608112eb..909fc2f6a93 100644 --- a/Lab/demo/Lab/Color_map.h +++ b/Lab/demo/Lab/Color_map.h @@ -23,9 +23,9 @@ compute_color_map(QColor base_color, std::size_t nb_of_colors, Output_color_iterator out) { - qreal hue = base_color.hueF(); - const qreal step = (static_cast(1)) / nb_of_colors; + const qreal step = (static_cast(0.85)) / nb_of_colors; + qreal hue = base_color.hueF(); qreal h = (hue == -1) ? 0 : hue; for(std::size_t i=0; ipoint_set()->add_property_map("training", -1); + std::tie (m_training, training_found) = m_points->point_set()->add_property_map("training", -1); bool classif_found = false; - boost::tie (m_classif, classif_found) = m_points->point_set()->add_property_map("label", -1); + std::tie (m_classif, classif_found) = m_points->point_set()->add_property_map("label", -1); training_found = !training_found; // add_property_map returns false if classif_found = !classif_found; // property was already there diff --git a/Lab/demo/Lab/Plugins/Classification/Point_set_item_classification.cpp b/Lab/demo/Lab/Plugins/Classification/Point_set_item_classification.cpp index 11ef26725a6..a5169477661 100644 --- a/Lab/demo/Lab/Plugins/Classification/Point_set_item_classification.cpp +++ b/Lab/demo/Lab/Plugins/Classification/Point_set_item_classification.cpp @@ -41,9 +41,9 @@ Point_set_item_classification::Point_set_item_classification(Scene_points_with_n backup_existing_colors_and_add_new(); bool training_found = false; - boost::tie (m_training, training_found) = m_points->point_set()->add_property_map("training", -1); + std::tie (m_training, training_found) = m_points->point_set()->add_property_map("training", -1); bool classif_found = false; - boost::tie (m_classif, classif_found) = m_points->point_set()->add_property_map("label", -1); + std::tie (m_classif, classif_found) = m_points->point_set()->add_property_map("label", -1); training_found = !training_found; // add_property_map returns false if classif_found = !classif_found; // property was already there diff --git a/Lab/demo/Lab/Plugins/Display/Display_property_plugin.cpp b/Lab/demo/Lab/Plugins/Display/Display_property_plugin.cpp index f0eb9086215..ae298d99940 100644 --- a/Lab/demo/Lab/Plugins/Display/Display_property_plugin.cpp +++ b/Lab/demo/Lab/Plugins/Display/Display_property_plugin.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -350,11 +351,11 @@ private: template void displayMapLegend(const std::vector& values) { - const std::size_t size = (std::min)(color_map.size(), std::size_t(1024)); + const std::size_t size = (std::min)(color_map.size(), std::size_t(4096)); const int text_height = 20; const int height = text_height * static_cast(size) + text_height; - const int width = 140; + const int width = 200; const int cell_width = width / 3; const int top_margin = 15; const int left_margin = 5; @@ -381,13 +382,13 @@ private: tick_height, color); - QRect text_rect(left_margin + cell_width + 10, drawing_height - top_margin - j, 50, text_height); - painter.drawText(text_rect, Qt::AlignCenter, QObject::tr("%1").arg(values[i], 0, 'f', 3, QLatin1Char(' '))); + QRect text_rect(left_margin + cell_width + 10, drawing_height - top_margin - j, 100, text_height); + painter.drawText(text_rect, Qt::AlignCenter, QObject::tr("%1").arg(values[i], 0, 'f', 6, QLatin1Char(' '))); } if(color_map.size() > size) { - QRect text_rect(left_margin + cell_width + 10, 0, 50, text_height); + QRect text_rect(left_margin + cell_width + 10, 0, 100, text_height); painter.drawText(text_rect, Qt::AlignCenter, QObject::tr("[...]")); } @@ -463,6 +464,8 @@ private: "Largest Angle Per Face", "Scaled Jacobian", "Face Area", + "Discrete Mean Curvature", + "Discrete Gaussian Curvature", "Interpolated Corrected Mean Curvature", "Interpolated Corrected Gaussian Curvature"}); property_simplex_types = { Property_simplex_type::FACE, @@ -470,6 +473,8 @@ private: Property_simplex_type::FACE, Property_simplex_type::FACE, Property_simplex_type::VERTEX, + Property_simplex_type::VERTEX, + Property_simplex_type::VERTEX, Property_simplex_type::VERTEX }; detectSMScalarProperties(*(sm_item->face_graph())); } @@ -516,12 +521,12 @@ private Q_SLOTS: // Curvature property-specific slider const std::string& property_name = dock_widget->propertyBox->currentText().toStdString(); - const bool is_curvature_property = (property_name == "Interpolated Corrected Mean Curvature" || - property_name == "Interpolated Corrected Gaussian Curvature"); - dock_widget->expandingRadiusLabel->setVisible(is_curvature_property); - dock_widget->expandingRadiusSlider->setVisible(is_curvature_property); - dock_widget->expandingRadiusLabel->setEnabled(is_curvature_property); - dock_widget->expandingRadiusSlider->setEnabled(is_curvature_property); + const bool is_interpolated_curvature_property = (property_name == "Interpolated Corrected Mean Curvature" || + property_name == "Interpolated Corrected Gaussian Curvature"); + dock_widget->expandingRadiusLabel->setVisible(is_interpolated_curvature_property); + dock_widget->expandingRadiusSlider->setVisible(is_interpolated_curvature_property); + dock_widget->expandingRadiusLabel->setEnabled(is_interpolated_curvature_property); + dock_widget->expandingRadiusSlider->setEnabled(is_interpolated_curvature_property); } else // no or broken property { @@ -570,6 +575,16 @@ private: { displayArea(sm_item); } + else if(property_name == "Discrete Mean Curvature") + { + displayDiscreteCurvatureMeasure(sm_item, MEAN_CURVATURE); + sm_item->setRenderingMode(Gouraud); + } + else if(property_name == "Discrete Gaussian Curvature") + { + displayDiscreteCurvatureMeasure(sm_item, GAUSSIAN_CURVATURE); + sm_item->setRenderingMode(Gouraud); + } else if(property_name == "Interpolated Corrected Mean Curvature") { displayInterpolatedCurvatureMeasure(sm_item, MEAN_CURVATURE); @@ -682,6 +697,8 @@ private: removeDisplayPluginProperty(item, "f:display_plugin_largest_angle"); removeDisplayPluginProperty(item, "f:display_plugin_scaled_jacobian"); removeDisplayPluginProperty(item, "f:display_plugin_area"); + removeDisplayPluginProperty(item, "v:display_plugin_discrete_mean_curvature"); + removeDisplayPluginProperty(item, "v:display_plugin_discrete_Gaussian_curvature"); removeDisplayPluginProperty(item, "v:display_plugin_interpolated_corrected_mean_curvature"); removeDisplayPluginProperty(item, "v:display_plugin_interpolated_corrected_Gaussian_curvature"); } @@ -864,6 +881,35 @@ private: displaySMProperty("f:display_plugin_area", *sm); } +private: + void displayDiscreteCurvatureMeasure(Scene_surface_mesh_item* sm_item, + CurvatureType mu_index) + { + SMesh* sm = sm_item->face_graph(); + if(sm == nullptr) + return; + + if(mu_index != MEAN_CURVATURE && mu_index != GAUSSIAN_CURVATURE) + return; + + std::string vdc_name = (mu_index == MEAN_CURVATURE) ? "v:display_plugin_discrete_mean_curvature" + : "v:display_plugin_discrete_Gaussian_curvature"; + + bool not_initialized; + SMesh::Property_map vdc; + std::tie(vdc, not_initialized) = sm->add_property_map(vdc_name, 0); + + if(not_initialized) + { + if(mu_index == MEAN_CURVATURE) + PMP::discrete_mean_curvatures(*sm, vdc); + else + PMP::discrete_Gaussian_curvatures(*sm, vdc); + } + + displaySMProperty(vdc_name, *sm); + } + private Q_SLOTS: void setExpandingRadius() { @@ -1131,6 +1177,10 @@ private: zoomToSimplexWithPropertyExtremum(faces(mesh), mesh, "f:display_plugin_scaled_jacobian", extremum); else if(property_name == "Face Area") zoomToSimplexWithPropertyExtremum(faces(mesh), mesh, "f:display_plugin_area", extremum); + else if(property_name == "Discrete Mean Curvature") + zoomToSimplexWithPropertyExtremum(vertices(mesh), mesh, "v:display_plugin_discrete_mean_curvature", extremum); + else if(property_name == "Discrete Gaussian Curvature") + zoomToSimplexWithPropertyExtremum(vertices(mesh), mesh, "v:display_plugin_discrete_Gaussian_curvature", extremum); else if(property_name == "Interpolated Corrected Mean Curvature") zoomToSimplexWithPropertyExtremum(vertices(mesh), mesh, "v:display_plugin_interpolated_corrected_mean_curvature", extremum); else if(property_name == "Interpolated Corrected Gaussian Curvature") @@ -1470,6 +1520,8 @@ isSMPropertyScalar(const std::string& name, name == "f:display_plugin_largest_angle" || name == "f:display_plugin_scaled_jacobian" || name == "f:display_plugin_area" || + name == "v:display_plugin_discrete_mean_curvature" || + name == "v:display_plugin_discrete_Gaussian_curvature" || name == "v:display_plugin_interpolated_corrected_mean_curvature" || name == "v:display_plugin_interpolated_corrected_Gaussian_curvature") return false; diff --git a/Lab/demo/Lab/Plugins/IO/VTK_io_plugin.cpp b/Lab/demo/Lab/Plugins/IO/VTK_io_plugin.cpp index 58512209f23..9fcea780b98 100644 --- a/Lab/demo/Lab/Plugins/IO/VTK_io_plugin.cpp +++ b/Lab/demo/Lab/Plugins/IO/VTK_io_plugin.cpp @@ -250,7 +250,7 @@ public: if(!c3t3_item || extension != "vtu") return false; - std::ofstream os(output_filename.data()); + std::ofstream os(output_filename.data(), std::ios::binary); os << std::setprecision(16); const C3t3& c3t3 = c3t3_item->c3t3(); @@ -447,8 +447,8 @@ public: cit != c3t3_item->c3t3().triangulation().finite_cells_end(); ++cit) { - CGAL_assertion(cit->info() >= 0); - c3t3_item->c3t3().add_to_complex(cit, cit->info()); + if(cit->info() != 0) + c3t3_item->c3t3().add_to_complex(cit, cit->info()); for(int i=0; i < 4; ++i) { if(cit->surface_patch_index(i)>0) diff --git a/Lab/demo/Lab/Plugins/Mesh_2/Mesh_2_plugin.cpp b/Lab/demo/Lab/Plugins/Mesh_2/Mesh_2_plugin.cpp index e55c30779bb..515ad8a999c 100644 --- a/Lab/demo/Lab/Plugins/Mesh_2/Mesh_2_plugin.cpp +++ b/Lab/demo/Lab/Plugins/Mesh_2/Mesh_2_plugin.cpp @@ -124,7 +124,7 @@ void cdt2_to_face_graph(const CDT& cdt, TriangleMesh& tm, int constant_coordinat { typename Map::iterator it; bool insert_ok; - boost::tie(it,insert_ok) = + std::tie(it,insert_ok) = descriptors.insert(std::make_pair(fit->vertex(i),vertex_descriptor())); if (insert_ok){ const Kernel::Point_3& pt=fit->vertex(i)->point(); diff --git a/Lab/demo/Lab/Plugins/Mesh_3/CMakeLists.txt b/Lab/demo/Lab/Plugins/Mesh_3/CMakeLists.txt index 6edbaf4da55..b63737188ff 100644 --- a/Lab/demo/Lab/Plugins/Mesh_3/CMakeLists.txt +++ b/Lab/demo/Lab/Plugins/Mesh_3/CMakeLists.txt @@ -2,6 +2,8 @@ include(CGALlab_macros) remove_definitions(-DQT_STATICPLUGIN) +set(CMAKE_AUTOMOC ON) + qt6_wrap_cpp(VOLUME_MOC_OUTFILES ${CMAKE_CURRENT_SOURCE_DIR}/Volume_plane_thread.h) qt6_wrap_cpp(VOLUME_MOC_OUTFILES diff --git a/Lab/demo/Lab/Plugins/Mesh_3/Offset_meshing_plugin.cpp b/Lab/demo/Lab/Plugins/Mesh_3/Offset_meshing_plugin.cpp index df2f5ca5287..a21cdbbf655 100644 --- a/Lab/demo/Lab/Plugins/Mesh_3/Offset_meshing_plugin.cpp +++ b/Lab/demo/Lab/Plugins/Mesh_3/Offset_meshing_plugin.cpp @@ -1,7 +1,5 @@ #include "config.h" -#ifdef CGAL_LAB_DEMO_USE_SURFACE_MESHER - #include #include "ui_Offset_meshing_dialog.h" @@ -761,5 +759,3 @@ inflate_mesh() } #include "Offset_meshing_plugin.moc" - -#endif // CGAL_LAB_DEMO_USE_SURFACE_MESHER diff --git a/Lab/demo/Lab/Plugins/PCA/Basic_generator_plugin.cpp b/Lab/demo/Lab/Plugins/PCA/Basic_generator_plugin.cpp index 15883fa976a..46539303a43 100644 --- a/Lab/demo/Lab/Plugins/PCA/Basic_generator_plugin.cpp +++ b/Lab/demo/Lab/Plugins/PCA/Basic_generator_plugin.cpp @@ -375,7 +375,7 @@ void Basic_generator_plugin::generateCube() if (list.size()!=3){ QMessageBox *msgBox = new QMessageBox; msgBox->setWindowTitle("Error"); - msgBox->setText("ERROR : Input should consists of 3 doubles."); + msgBox->setText("ERROR : Input should consist of 3 doubles."); msgBox->exec(); return; } @@ -416,7 +416,7 @@ void Basic_generator_plugin::generateCube() if (list.size()!=6){ QMessageBox *msgBox = new QMessageBox; msgBox->setWindowTitle("Error"); - msgBox->setText("ERROR : Input should consists of 6 doubles."); + msgBox->setText("ERROR : Input should consist of 6 doubles."); msgBox->exec(); return; } @@ -467,7 +467,7 @@ void Basic_generator_plugin::generatePrism() if (list.size()!=3){ QMessageBox *msgBox = new QMessageBox; msgBox->setWindowTitle("Error"); - msgBox->setText("ERROR : Input should consists of 3 doubles."); + msgBox->setText("ERROR : Input should consist of 3 doubles."); msgBox->exec(); return; } @@ -514,7 +514,7 @@ void Basic_generator_plugin::generatePyramid() if (list.size()!=3){ QMessageBox *msgBox = new QMessageBox; msgBox->setWindowTitle("Error"); - msgBox->setText("ERROR : Input should consists of 3 doubles."); + msgBox->setText("ERROR : Input should consist of 3 doubles."); msgBox->exec(); return; } @@ -557,7 +557,7 @@ void Basic_generator_plugin::generateSphere() if (list.size()!=4){ QMessageBox *msgBox = new QMessageBox; msgBox->setWindowTitle("Error"); - msgBox->setText("ERROR : Input should consists of four doubles."); + msgBox->setText("ERROR : Input should consist of four doubles."); msgBox->exec(); return; } @@ -607,7 +607,7 @@ void Basic_generator_plugin::generateTetrahedron() if (list.size() != 3) { QMessageBox* msgBox = new QMessageBox; msgBox->setWindowTitle("Error"); - msgBox->setText("ERROR : Input should consists of 3 doubles."); + msgBox->setText("ERROR : Input should consist of 3 doubles."); msgBox->exec(); return; } @@ -641,7 +641,7 @@ void Basic_generator_plugin::generateTetrahedron() if (list.size() != 12) { QMessageBox* msgBox = new QMessageBox; msgBox->setWindowTitle("Error"); - msgBox->setText("ERROR : Input should consists of 12 doubles."); + msgBox->setText("ERROR : Input should consist of 12 doubles."); msgBox->exec(); return; } @@ -685,7 +685,7 @@ void Basic_generator_plugin::generatePoints() if (list.size()%3!=0){ QMessageBox *msgBox = new QMessageBox; msgBox->setWindowTitle("Error"); - msgBox->setText("ERROR : Input should consists of triplets."); + msgBox->setText("ERROR : Input should consist of triplets."); msgBox->exec(); return; } @@ -742,14 +742,14 @@ void Basic_generator_plugin::generateLines() if(!is_2d && list.size()%3!=0){ QMessageBox *msgBox = new QMessageBox; msgBox->setWindowTitle("Error"); - msgBox->setText("ERROR : Input should consists of triplets."); + msgBox->setText("ERROR : Input should consist of triplets."); msgBox->exec(); return false; } else if(is_2d && list.size()%2!=0){ QMessageBox *msgBox = new QMessageBox; msgBox->setWindowTitle("Error"); - msgBox->setText("ERROR : Input should consists of pairs."); + msgBox->setText("ERROR : Input should consist of pairs."); msgBox->exec(); return false; } @@ -912,7 +912,7 @@ void Basic_generator_plugin::generateGrid() if (list.size()!=6){ QMessageBox *msgBox = new QMessageBox; msgBox->setWindowTitle("Error"); - msgBox->setText("ERROR : Input should consists of 6 doubles."); + msgBox->setText("ERROR : Input should consist of 6 doubles."); msgBox->exec(); return; } diff --git a/Lab/demo/Lab/Plugins/PCA/Basic_generator_widget.ui b/Lab/demo/Lab/Plugins/PCA/Basic_generator_widget.ui index eed6885a04c..f749ca97ab7 100644 --- a/Lab/demo/Lab/Plugins/PCA/Basic_generator_widget.ui +++ b/Lab/demo/Lab/Plugins/PCA/Basic_generator_widget.ui @@ -18,7 +18,7 @@ - 4 + 6 @@ -43,7 +43,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -180,7 +180,7 @@ QGroupBox::title { - Qt::RightToLeft + Qt::LayoutDirection::RightToLeft @@ -198,7 +198,7 @@ QGroupBox::title { - Qt::Vertical + Qt::Orientation::Vertical @@ -232,7 +232,7 @@ QGroupBox::title { - Qt::Vertical + Qt::Orientation::Vertical @@ -315,7 +315,7 @@ QGroupBox::title { - Qt::Vertical + Qt::Orientation::Vertical @@ -349,7 +349,7 @@ QGroupBox::title { - Qt::Vertical + Qt::Orientation::Vertical @@ -495,7 +495,7 @@ QGroupBox::title { - Qt::RightToLeft + Qt::LayoutDirection::RightToLeft @@ -513,7 +513,7 @@ QGroupBox::title { - Qt::Vertical + Qt::Orientation::Vertical @@ -880,7 +880,7 @@ p, li { white-space: pre-wrap; } hr { height: 1px; border-width: 0; } li.unchecked::marker { content: "\2610"; } li.checked::marker { content: "\2612"; } -</style></head><body style=" font-family:'Segoe UI'; font-size:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'Cantarell'; font-size:11pt; font-weight:400; font-style:normal;"> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:10pt;"><br /></p></body></html> @@ -919,7 +919,7 @@ li.checked::marker { content: "\2612"; } - Qt::Vertical + Qt::Orientation::Vertical @@ -1045,7 +1045,7 @@ QGroupBox::title { - Qt::Vertical + Qt::Orientation::Vertical @@ -1081,7 +1081,7 @@ p, li { white-space: pre-wrap; } hr { height: 1px; border-width: 0; } li.unchecked::marker { content: "\2610"; } li.checked::marker { content: "\2612"; } -</style></head><body style=" font-family:'Segoe UI'; font-size:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'Cantarell'; font-size:11pt; font-weight:400; font-style:normal;"> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:10pt;"><br /></p></body></html> @@ -1149,7 +1149,7 @@ p, li { white-space: pre-wrap; } hr { height: 1px; border-width: 0; } li.unchecked::marker { content: "\2610"; } li.checked::marker { content: "\2612"; } -</style></head><body style=" font-family:'Segoe UI'; font-size:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'Cantarell'; font-size:11pt; font-weight:400; font-style:normal;"> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:10pt;"><br /></p></body></html> @@ -1167,7 +1167,7 @@ li.checked::marker { content: "\2612"; } - Qt::Vertical + Qt::Orientation::Vertical @@ -1206,7 +1206,7 @@ li.checked::marker { content: "\2612"; } - Qt::Horizontal + Qt::Orientation::Horizontal diff --git a/Lab/demo/Lab/Plugins/PMP/Engrave_text_plugin.cpp b/Lab/demo/Lab/Plugins/PMP/Engrave_text_plugin.cpp index 1adc2ae81ea..b0a7ca79f35 100644 --- a/Lab/demo/Lab/Plugins/PMP/Engrave_text_plugin.cpp +++ b/Lab/demo/Lab/Plugins/PMP/Engrave_text_plugin.cpp @@ -897,7 +897,7 @@ private: { typename Map::iterator it; bool insert_ok; - boost::tie(it,insert_ok) = + std::tie(it,insert_ok) = descriptors.insert(std::make_pair(fit->vertex(i),vertex_descriptor())); if (insert_ok){ const EPICK::Point_2& pt=fit->vertex(i)->point(); diff --git a/Lab/demo/Lab/Plugins/PMP/Interpolated_corrected_principal_curvatures_plugin.cpp b/Lab/demo/Lab/Plugins/PMP/Interpolated_corrected_principal_curvatures_plugin.cpp index 489b5baca5f..9ffa83fe5ba 100644 --- a/Lab/demo/Lab/Plugins/PMP/Interpolated_corrected_principal_curvatures_plugin.cpp +++ b/Lab/demo/Lab/Plugins/PMP/Interpolated_corrected_principal_curvatures_plugin.cpp @@ -67,7 +67,7 @@ void compute(SMesh* sMesh, bool created = false; SMesh::Property_map> principal_curvatures_and_directions_map; - boost::tie(principal_curvatures_and_directions_map, created) = sMesh->add_property_map> + std::tie(principal_curvatures_and_directions_map, created) = sMesh->add_property_map> ("v:principal_curvatures_and_directions_map", { 0, 0, Vector(0,0,0), Vector(0,0,0) }); diff --git a/Lab/demo/Lab/Plugins/PMP/Mean_curvature_flow_skeleton_plugin.cpp b/Lab/demo/Lab/Plugins/PMP/Mean_curvature_flow_skeleton_plugin.cpp index 7c333459555..884f0bb04f8 100644 --- a/Lab/demo/Lab/Plugins/PMP/Mean_curvature_flow_skeleton_plugin.cpp +++ b/Lab/demo/Lab/Plugins/PMP/Mean_curvature_flow_skeleton_plugin.cpp @@ -692,7 +692,7 @@ if(!contracted_item) item->mcs->poles(pole_points); vertex_iterator vb, ve; int id = 0; - for (boost::tie(vb, ve) = vertices(*pMesh); vb != ve; ++vb) + for (std::tie(vb, ve) = vertices(*pMesh); vb != ve; ++vb) { std::vector line; line.clear(); diff --git a/Lab/demo/Lab/Plugins/PMP/Orient_soup_plugin.cpp b/Lab/demo/Lab/Plugins/PMP/Orient_soup_plugin.cpp index 12e6a6ead33..f668a2ffa37 100644 --- a/Lab/demo/Lab/Plugins/PMP/Orient_soup_plugin.cpp +++ b/Lab/demo/Lab/Plugins/PMP/Orient_soup_plugin.cpp @@ -109,28 +109,28 @@ QList CGAL_Lab_orient_soup_plugin::actions() const { << actionClean; } -void set_vcolors(SMesh* smesh, std::vector colors) +void set_vcolors(SMesh* smesh, const std::vector& colors) { typedef SMesh SMesh; typedef boost::graph_traits::vertex_descriptor vertex_descriptor; - SMesh::Property_map vcolors = - smesh->property_map("v:color").value(); + + SMesh::Property_map vcolors; bool created; - boost::tie(vcolors, created) = smesh->add_property_map("v:color",CGAL::IO::Color(0,0,0)); + std::tie(vcolors, created) = smesh->add_property_map("v:color",CGAL::IO::Color(0,0,0)); assert(colors.size()==smesh->number_of_vertices()); int color_id = 0; for(vertex_descriptor vd : vertices(*smesh)) vcolors[vd] = colors[color_id++]; } -void set_fcolors(SMesh* smesh, std::vector colors) +void set_fcolors(SMesh* smesh, const std::vector& colors) { typedef SMesh SMesh; typedef boost::graph_traits::face_descriptor face_descriptor; - SMesh::Property_map fcolors = - smesh->property_map("f:color").value(); + + SMesh::Property_map fcolors; bool created; - boost::tie(fcolors, created) = smesh->add_property_map("f:color",CGAL::IO::Color(0,0,0)); + std::tie(fcolors, created) = smesh->add_property_map("f:color",CGAL::IO::Color(0,0,0)); assert(colors.size()==smesh->number_of_faces()); int color_id = 0; for(face_descriptor fd : faces(*smesh)) diff --git a/Lab/demo/Lab/Plugins/PMP/Selection_plugin.cpp b/Lab/demo/Lab/Plugins/PMP/Selection_plugin.cpp index eaf633c7cf5..6daad328b43 100644 --- a/Lab/demo/Lab/Plugins/PMP/Selection_plugin.cpp +++ b/Lab/demo/Lab/Plugins/PMP/Selection_plugin.cpp @@ -210,6 +210,7 @@ public: connect(ui_widget.Select_sharp_edges_button, SIGNAL(clicked()), this, SLOT(on_Select_sharp_edges_button_clicked())); connect(ui_widget.selectionOrEuler, SIGNAL(currentChanged(int)), this, SLOT(on_SelectionOrEuler_changed(int))); connect(ui_widget.editionBox, SIGNAL(currentIndexChanged(int)), this, SLOT(on_editionBox_changed(int))); + connect(ui_widget.movePoint_pushButton, SIGNAL(clicked()), this, SLOT(on_movePoint_pushButton_clicked())); ui_widget.Sharp_edges_label->hide(); ui_widget.Sharp_angle_spinbox->hide(); @@ -701,7 +702,7 @@ public Q_SLOTS: begin != selection_item->selected_edges.end(); ++begin) { fg_vertex_descriptor source = target(opposite(halfedge(*begin,*poly),*poly),*poly); - boost::tie(it_find, insert_OK) + std::tie(it_find, insert_OK) = p2vd.insert(std::make_pair(source, Edge_graph::vertex_descriptor())); if (insert_OK) { @@ -711,7 +712,7 @@ public Q_SLOTS: Edge_graph::vertex_descriptor src=it_find->second; fg_vertex_descriptor targ = target(halfedge(*begin,*poly),*poly); - boost::tie(it_find, insert_OK) + std::tie(it_find, insert_OK) = p2vd.insert(std::make_pair(targ, Edge_graph::vertex_descriptor())); if (insert_OK) { @@ -987,6 +988,10 @@ public Q_SLOTS: { Q_EMIT set_operation_mode(mode); } + + ui_widget.movePointCoordinates_textEdit->setVisible(false); + ui_widget.movePoint_pushButton->setVisible(false); + switch(mode) { //Join vertex @@ -1025,24 +1030,97 @@ public Q_SLOTS: } //Add vertex and face to border case 9: + { + QPixmap pm(":/cgal/Lab/resources/euler_deg2.png"); + ui_widget.docImage_Label->setPixmap(pm); + break; + } + case 10: { QPixmap pm(":/cgal/Lab/resources/add_facet1.png"); ui_widget.docImage_Label->setPixmap(pm); break; } //add facet to border - case 10: + case 11: { QPixmap pm(":/cgal/Lab/resources/add_facet2.png"); ui_widget.docImage_Label->setPixmap(pm); break; } + // Move point + case 12: + { + ui_widget.docImage_Label->clear(); + ui_widget.movePointCoordinates_textEdit->setVisible(true); + ui_widget.movePoint_pushButton->setVisible(true); + ui_widget.movePoint_pushButton->setEnabled(true); + break; + } default: ui_widget.docImage_Label->clear(); break; } on_LassoCheckBox_changed(ui_widget.lassoCheckBox->isChecked()); } + + void on_movePoint_pushButton_clicked() + { + QString text = ui_widget.movePointCoordinates_textEdit->toPlainText(); + Scene_points_with_normal_item* item = new Scene_points_with_normal_item(); + QStringList list = text.split(QRegularExpression("\\s+"), CGAL_QT_SKIP_EMPTY_PARTS); + int counter = 0; + double coord[3]; + bool ok = true; + if (list.isEmpty()) return; + if (list.size() != 3){ + QMessageBox *msgBox = new QMessageBox; + msgBox->setWindowTitle("Error"); + msgBox->setText("ERROR : Input should consist of a triplet."); + msgBox->exec(); + return; + } + + for(QString s : list) + { + if(!s.isEmpty()) + { + double res = s.toDouble(&ok); + if(!ok) + { + QMessageBox *msgBox = new QMessageBox; + msgBox->setWindowTitle("Error"); + msgBox->setText("ERROR : Coordinates are invalid."); + msgBox->exec(); + break; + } + else + { + coord[counter++] = res; + } + } + } + + if(counter == 3) + { + const Kernel::Point_3 p(coord[0], coord[1], coord[2]); + item->point_set()->insert(p); + counter = 0; + + ui_widget.movePointCoordinates_textEdit->clear(); + + Scene_polyhedron_selection_item* selection_item = getSelectedItem(); + if(!selection_item) + selection_item = onTheFlyItem(); + if (!selection_item) { + print_message("Error: there is no selected polyhedron selection item!"); + return; + } + + selection_item->moveVertex(p); + } + } + void on_Select_sharp_edges_button_clicked() { Scene_polyhedron_selection_item* selection_item = getSelectedItem(); if(!selection_item) diff --git a/Lab/demo/Lab/Plugins/PMP/Selection_widget.ui b/Lab/demo/Lab/Plugins/PMP/Selection_widget.ui index d7b76c83d06..5a9dce0a662 100644 --- a/Lab/demo/Lab/Plugins/PMP/Selection_widget.ui +++ b/Lab/demo/Lab/Plugins/PMP/Selection_widget.ui @@ -7,7 +7,7 @@ 0 0 630 - 532 + 579 @@ -46,7 +46,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -61,7 +61,7 @@ - 0 + 1 @@ -176,7 +176,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -200,7 +200,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -218,7 +218,7 @@ Sharp edges angle: - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter @@ -274,7 +274,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -294,7 +294,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -367,7 +367,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -386,7 +386,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -479,7 +479,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -572,20 +572,7 @@ - - - Qt::Vertical - - - - 20 - 40 - - - - - - + @@ -633,6 +620,11 @@ Remove center vertex + + + Remove degree 2 vertex + + Add vertex and face to border (Advanced) @@ -659,6 +651,29 @@ + + + + true + + + + 0 + 0 + + + + New Coordinates: X Y Z + + + + + + + Apply move + + + @@ -666,15 +681,28 @@ - - - - Ctrl+Z to cancel the temporary selection. Ctrl+U to undo last operation (if applicable). - - - + + + + Ctrl+Z to cancel the temporary selection. Ctrl+U to undo last operation (if applicable). + + + + + + + Qt::Orientation::Vertical + + + + 20 + 40 + + + + @@ -685,7 +713,7 @@ - Qt::Vertical + Qt::Orientation::Vertical diff --git a/Lab/demo/Lab/Plugins/Point_set/Point_set_shape_detection_plugin.cpp b/Lab/demo/Lab/Plugins/Point_set/Point_set_shape_detection_plugin.cpp index 1baaa63af33..5a0c76720ea 100644 --- a/Lab/demo/Lab/Plugins/Point_set/Point_set_shape_detection_plugin.cpp +++ b/Lab/demo/Lab/Plugins/Point_set/Point_set_shape_detection_plugin.cpp @@ -277,7 +277,7 @@ private: Point_set::Property_map shape_id; if (dialog.add_property()) { bool added = false; - boost::tie(shape_id, added) = points->template add_property_map ("shape", -1); + std::tie(shape_id, added) = points->template add_property_map ("shape", -1); if (!added) { for (auto it = points->begin(); it != points->end(); ++ it) shape_id[*it] = -1; @@ -563,7 +563,7 @@ private: if (dialog.add_property()) { bool added = false; - boost::tie (shape_id, added) = points->template add_property_map ("shape", -1); + std::tie (shape_id, added) = points->template add_property_map ("shape", -1); if (!added) { for (Point_set::iterator it = points->begin(); it != points->end(); ++ it) diff --git a/Lab/demo/Lab/Plugins/Point_set/Point_set_to_mesh_distance_plugin.cpp b/Lab/demo/Lab/Plugins/Point_set/Point_set_to_mesh_distance_plugin.cpp index ea75b2286ca..95cff942339 100644 --- a/Lab/demo/Lab/Plugins/Point_set/Point_set_to_mesh_distance_plugin.cpp +++ b/Lab/demo/Lab/Plugins/Point_set/Point_set_to_mesh_distance_plugin.cpp @@ -223,10 +223,10 @@ private Q_SLOTS: bool d, r, g, b; new_item->point_set()->remove_colors(); //bind pmaps - boost::tie(distance_map , d) = new_item->point_set()->add_property_map("distance",0); - boost::tie(fred_map , r) = new_item->point_set()->add_property_map("red",0); - boost::tie(fgreen_map, g) = new_item->point_set()->add_property_map("green",0); - boost::tie(fblue_map , b) = new_item->point_set()->add_property_map("blue",0); + std::tie(distance_map , d) = new_item->point_set()->add_property_map("distance",0); + std::tie(fred_map , r) = new_item->point_set()->add_property_map("red",0); + std::tie(fgreen_map, g) = new_item->point_set()->add_property_map("green",0); + std::tie(fblue_map , b) = new_item->point_set()->add_property_map("blue",0); new_item->point_set()->check_colors(); Point_set* points = new_item->point_set(); diff --git a/Lab/demo/Lab/Plugins/Surface_mesh/Offset_meshing_plugin.cpp b/Lab/demo/Lab/Plugins/Surface_mesh/Offset_meshing_plugin.cpp deleted file mode 100644 index 217e5888724..00000000000 --- a/Lab/demo/Lab/Plugins/Surface_mesh/Offset_meshing_plugin.cpp +++ /dev/null @@ -1,691 +0,0 @@ -#include "config.h" -#ifdef CGAL_LAB_DEMO_USE_SURFACE_MESHER -#include -#include "ui_Remeshing_dialog.h" - -#include -#include -#include -#include -#include -#include -#include -#include "Scene_surface_mesh_item.h" -#include "Scene_polygon_soup_item.h" -#include "Scene_polylines_item.h" -#include -#include -#include -#include - -#include "C3t3_type.h" - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include // std::shared_ptr - -namespace CGAL{ - -template -class Offset_function -{ - typedef AABB_face_graph_triangle_primitive Primitive; - typedef AABB_traits_3 Traits; - typedef AABB_tree Tree; - typedef Side_of_triangle_mesh Side_of; - -public: - - Offset_function(TriangleMesh& tm, double offset_distance) - : m_tree_ptr(new Tree(std::begin(faces(tm)), - std::end(faces(tm)), - tm) ) - , m_side_of_ptr( new Side_of(*m_tree_ptr) ) - , m_offset_distance(offset_distance) - , m_is_closed( is_closed(tm) ) - { - CGAL_assertion(!m_tree_ptr->empty()); - } - - double operator()(const typename GeomTraits::Point_3& p) const - { - using CGAL::sqrt; - - Bounded_side side = m_is_closed?m_side_of_ptr->operator()(p):ON_UNBOUNDED_SIDE; - if (side==ON_BOUNDARY) return m_offset_distance; - - typename GeomTraits::Point_3 closest_point = m_tree_ptr->closest_point(p); - double distance = sqrt(squared_distance(p, closest_point)); - - return (side == ON_UNBOUNDED_SIDE ? -distance : distance) + m_offset_distance; - } - -private: - std::shared_ptr m_tree_ptr; - std::shared_ptr m_side_of_ptr; - double m_offset_distance; - bool m_is_closed; - -}; - -class Polygon_soup_offset_function { - typedef Scene_polygon_soup_item::Points Points; - typedef Scene_polygon_soup_item::Polygons Polygons; - - typedef Polygons::const_iterator Polygon_iterator; - - - class Polygon_soup_point_property_map { - const Points* points_vector_ptr; - public: - typedef Polygon_iterator key_type; - typedef EPICK::Point_3 value_type; - typedef const value_type& reference; - typedef boost::readable_property_map_tag category; - - Polygon_soup_point_property_map() = default; - Polygon_soup_point_property_map(const Points* ptr) - : points_vector_ptr(ptr) - {} - - friend reference get(Polygon_soup_point_property_map map, - key_type polygon_it) - { - return (*map.points_vector_ptr)[*polygon_it->begin()]; - } - }; - - - class Polygon_soup_triangle_property_map { - const Points* points_vector_ptr; - public: - typedef Polygon_iterator key_type; - typedef EPICK::Triangle_3 value_type; - typedef value_type reference; - typedef boost::readable_property_map_tag category; - - Polygon_soup_triangle_property_map() = default; - Polygon_soup_triangle_property_map(const Points* ptr) - : points_vector_ptr(ptr) - {} - - friend value_type get(Polygon_soup_triangle_property_map map, - key_type polygon_it) - { - auto it = polygon_it->begin(); - CGAL_assertion(it != polygon_it->end()); - const auto id0 = *it++; - CGAL_assertion(it != polygon_it->end()); - const auto id1 = *it++; - CGAL_assertion(it != polygon_it->end()); - const auto id2 = *it++; - CGAL_assertion(it == polygon_it->end()); - - return value_type( (*map.points_vector_ptr)[id0], - (*map.points_vector_ptr)[id1], - (*map.points_vector_ptr)[id2] ); - } - }; - - struct AABB_primitive : - public CGAL::AABB_primitive - { - typedef CGAL::AABB_primitive Base; - - typedef Polygon_iterator Id; - - template - AABB_primitive(Id id, ObjectPmap&& opmap, PointPmap&& ppmap) - : Base(id, std::forward(opmap), std::forward(ppmap)) - {} - - template - AABB_primitive(Iterator it, ObjectPmap&& opmap, PointPmap&& ppmap) - : Base(*it, std::forward(opmap), std::forward(ppmap)) - {} - }; // end struct template AABB_primitive - - - typedef CGAL::AABB_traits_3 AABB_traits; - typedef CGAL::AABB_tree AABB_tree; - - std::shared_ptr m_tree_ptr; - double m_offset_distance; - - typedef Polygon_soup_triangle_property_map ObjectPmap; - typedef Polygon_soup_point_property_map PointPmap; -public: - Polygon_soup_offset_function(const Scene_polygon_soup_item* soup, - const double offset_distance) - : m_tree_ptr - (std::make_shared(begin(soup->polygons()), - end(soup->polygons()), - ObjectPmap(&soup->points()), - PointPmap(&soup->points())) - ) - , m_offset_distance(offset_distance) - { - CGAL_assertion(! m_tree_ptr->empty() ); - } - - double operator()(const EPICK::Point_3& p) const - { - using CGAL::sqrt; - - EPICK::Point_3 closest_point = m_tree_ptr->closest_point(p); - double distance = sqrt(squared_distance(p, closest_point)); - - return m_offset_distance - distance; - } - -}; // end class Polygon_soup_offset_function - -} //end of CGAL namespace - -Scene_surface_mesh_item* make_item(SMesh* sm) -{ - return new Scene_surface_mesh_item(sm); -} - -CGAL::Offset_function -offset_function(SMesh* surface_mesh_ptr, double offset_value) { - return { *surface_mesh_ptr, offset_value }; -} - -CGAL::Polygon_soup_offset_function -offset_function(Scene_polygon_soup_item* item, double offset_value) { - return { item, offset_value }; -} - -template -struct Result_type { - typedef T type; -}; - -template <> -struct Result_type { - typedef SMesh type; -}; - -template -CGAL::Bbox_3 bbox(Mesh* mesh_ptr) { - return CGAL::Polygon_mesh_processing::bbox(*mesh_ptr); -} - -CGAL::Bbox_3 bbox(Scene_polygon_soup_item* item) { - return item->bbox(); -} -class MeshGuard{ - SMesh* mesh; - bool done; -public: - MeshGuard(SMesh* mesh):mesh(mesh), done(false){} - void setDone(){done = true;} - ~MeshGuard(){ - if(!done) - delete mesh; - } -}; -// declare the CGAL function -template -SMesh* cgal_off_meshing(QWidget*, - Mesh* tm_ptr, - Scene_polylines_item* polylines_item, - const double offset_value, - const double angle, - const double sizing, - const double approx, - const double edge_size, - int tag) -{ - typedef EPICK GT; - typedef CGAL::Labeled_mesh_domain_3 Mesh_domain_base; - typedef CGAL::Mesh_domain_with_polyline_features_3 Mesh_domain; - typedef C3t3::Triangulation Tr; - typedef CGAL::Mesh_criteria_3 Mesh_criteria; - typedef GT::Sphere_3 Sphere_3; - - CGAL::Bbox_3 bbox = ::bbox(tm_ptr); - - GT::Point_3 center((bbox.xmax()+bbox.xmin())/2, - (bbox.ymax()+bbox.ymin())/2, - (bbox.zmax()+bbox.zmin())/2); - double sqrad = 0.6 * std::sqrt( CGAL::square(bbox.xmax()-bbox.xmin())+ - CGAL::square(bbox.ymax()-bbox.ymin())+ - CGAL::square(bbox.zmax()-bbox.zmin()) ) - + offset_value; - sqrad=CGAL::square(sqrad); - - CGAL::Timer timer; - timer.start(); - - namespace p = CGAL::parameters; - - Mesh_domain domain = - Mesh_domain::create_implicit_mesh_domain - (p::function = offset_function(tm_ptr, offset_value), - p::bounding_object = Sphere_3(center, sqrad), - p::relative_error_bound = 1e-7, - p::construct_surface_patch_index = [](int i, int j) { return (i * 1000 + j); }); - - const CGAL::Mesh_facet_topology topology = CGAL::FACET_VERTICES_ON_SAME_SURFACE_PATCH; - auto manifold_option = p::non_manifold(); - if(tag == 1) manifold_option = p::manifold_with_boundary(); - if(tag == 2) manifold_option = p::manifold(); - Mesh_criteria criteria(p::facet_angle = angle, - p::facet_size = sizing, - p::facet_distance = approx, - p::facet_topology = topology, - p::edge_size = edge_size); - - if (polylines_item!=nullptr) - { - typedef std::vector Surface_patch_ids; - std::vector surface_patch_ids; - - domain.add_features_and_incidences(polylines_item->polylines.begin(), - polylines_item->polylines.end(), - CGAL::Identity_property_map(), - CGAL::Constant_property_map( - surface_patch_ids)); - } - - C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria, - p::no_perturb(), - p::no_exude(), - manifold_option); - - const Tr& tr = c3t3.triangulation(); - - timer.stop(); - std::cerr << "done (" << timer.time() << " ms, " << tr.number_of_vertices() << " vertices)" << std::endl; - - if(tr.number_of_vertices() > 0) - { - typedef typename Result_type::type Result_mesh; - // add remesh as new polyhedron - Result_mesh *pRemesh = new Result_mesh; - //if the thread is interrupted before the mesh is returned, delete it. - MeshGuard guard(pRemesh); - CGAL::facets_in_complex_3_to_triangle_mesh(c3t3, *pRemesh); - guard.setDone(); - if(CGAL::is_closed(*pRemesh) - && ! CGAL::Polygon_mesh_processing::is_outward_oriented(*pRemesh)) - { - CGAL::Polygon_mesh_processing::reverse_face_orientations(*pRemesh); - } - - return pRemesh; - } - else - return nullptr; -} - -struct Mesher_thread:public QThread{ - Q_OBJECT - -private: - SMesh* sMesh; - Scene_polygon_soup_item* soup_item; - Scene_polylines_item* polylines_item; - const double offset_value; - const double angle; - const double sizing; - const double approx; - const double edge_size; - int tag_index; -public: - Mesher_thread( SMesh* tm_ptr, - Scene_polygon_soup_item* soup_item, - Scene_polylines_item* polylines_item, - const double offset_value, - const double angle, - const double sizing, - const double approx, - const double edge_size, - int tag) - :sMesh(tm_ptr), soup_item(soup_item), polylines_item(polylines_item), - offset_value(offset_value), angle(angle), - sizing(sizing), approx(approx), edge_size(edge_size), tag_index(tag){ - } - void run() override { - SMesh* new_mesh= nullptr; - if(soup_item) - new_mesh = cgal_off_meshing(CGAL::Three::Three::mainWindow(), - soup_item, - polylines_item, - offset_value, - angle, - sizing, - approx, - edge_size, - tag_index); - else - new_mesh = cgal_off_meshing(CGAL::Three::Three::mainWindow(), - sMesh, - polylines_item, - offset_value, - angle, - sizing, - approx, - edge_size, - tag_index); - CGAL::Three::Three::getMutex()->lock(); - CGAL::Three::Three::getWaitCondition()->wakeAll(); - CGAL::Three::Three::getMutex()->unlock(); - Q_EMIT resultReady(new_mesh); - } -Q_SIGNALS: - void resultReady(SMesh *new_mesh); -}; - -using namespace CGAL::Three; -class CGAL_Lab_offset_meshing_plugin : - public QObject, - protected CGAL_Lab_plugin_interface -{ - Q_OBJECT - Q_INTERFACES(CGAL::Three::CGAL_Lab_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.CGALLab.PluginInterface/1.0") - -public: - void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, Messages_interface*) { - this->scene = scene_interface; - this->mw = mainWindow; - actionOffsetMeshing = new QAction(tr("Offset Meshing"), mw); - actionOffsetMeshing->setProperty("subMenuName", "3D Surface Mesh Generation"); - if(actionOffsetMeshing) { - connect(actionOffsetMeshing, SIGNAL(triggered()), - this, SLOT(offset_meshing())); - } - - actionInflateMesh= new QAction(tr("Inflate Mesh"), mw); - actionInflateMesh->setProperty("subMenuName", "Operations on Polyhedra"); - if(actionInflateMesh) { - connect(actionInflateMesh, SIGNAL(triggered()), - this, SLOT(inflate_mesh())); - } - } - - bool applicable(QAction*) const { - if ( scene->selectionIndices().size() != 1 && - scene->selectionIndices().size() != 2 ) - { - return false; - } - - for(CGAL::Three::Scene_interface::Item_id index : scene->selectionIndices()) - { - if ( qobject_cast(scene->item(index)) || - qobject_cast(scene->item(index)) ) - return true; - } - return false; - } - - QList actions() const { - return QList() << actionOffsetMeshing - << actionInflateMesh; - } -public Q_SLOTS: - void offset_meshing(); - void inflate_mesh(); - -private: - QAction* actionOffsetMeshing; - QAction* actionInflateMesh; - Scene_interface *scene; - QMainWindow *mw; -}; // end class CGAL_Lab_offset_meshing_plugin - -void CGAL_Lab_offset_meshing_plugin::inflate_mesh() -{ - const CGAL::Three::Scene_interface::Item_id index = scene->mainSelectionIndex(); - Scene_item* item = scene->item(index); - if(item == nullptr){ - return; - } - - Scene_surface_mesh_item* sm_item = - qobject_cast(item); - - if(sm_item == nullptr){ - return; - } - - SMesh* sMesh = sm_item->face_graph(); - - if(sMesh == nullptr){ - return; - } - - double diag = sm_item->diagonalBbox(); - double offset_value = QInputDialog::getDouble(mw, - QString("Choose Inflate Distance"), - QString("Inflate Distance (use negative number for deflate)"), - 0.1*diag, - -(std::numeric_limits::max)(), - (std::numeric_limits::max)(), 10); - - auto vpm = get(CGAL::vertex_point,*sMesh); - auto vnm = - sMesh->property_map("v:normal").value(); - - for(const auto& v : vertices(*sMesh)) - { - Point_3 p = get(vpm, v); - EPICK::Vector_3 n = get(vnm, v); - n/=(CGAL::sqrt(n.squared_length())); - put(vpm, v, p + offset_value*n); - } - sm_item->invalidateOpenGLBuffers(); -} - -void CGAL_Lab_offset_meshing_plugin::offset_meshing() -{ - Scene_surface_mesh_item* sm_item = nullptr; - Scene_polygon_soup_item* soup_item = nullptr; - Scene_polylines_item* polylines_item = nullptr; - Scene_item* item = nullptr; - - bool mesh_or_soup_item_found = false; - - for(CGAL::Three::Scene_interface::Item_id index : scene->selectionIndices()) - { - if (!mesh_or_soup_item_found) - { - sm_item = qobject_cast(scene->item(index)); - if (sm_item == nullptr) - { - soup_item = qobject_cast(item); - if (soup_item != nullptr) - { - item=scene->item(index); - mesh_or_soup_item_found = true; - continue; - } - } - else - { - item=scene->item(index); - mesh_or_soup_item_found = true; - continue; - } - } - polylines_item = qobject_cast(scene->item(index)); - } - - SMesh* sMesh = nullptr; - double diag = 0; - Scene_item::Bbox box; - if(sm_item) - { - sMesh = sm_item->face_graph(); - if(!sMesh) - return; - box = bbox(sMesh); - } - else if(soup_item != nullptr) - { - box = bbox(soup_item); - } - else if(soup_item == nullptr) - return; - double X=(box.max)(0)-(box.min)(0), - Y = (box.max)(1)-(box.min)(1), - Z = (box.max)(2)-(box.min)(2); - diag = CGAL::sqrt(X*X+Y*Y+Z*Z); - double offset_value = QInputDialog::getDouble(mw, - QString("Choose Offset Value"), - QString("Offset Value (use negative number for inset)"), - 0.1*diag, - -(std::numeric_limits::max)(), - (std::numeric_limits::max)(), 10); - - QDialog dialog(mw); - Ui::Remeshing_dialog ui; - ui.setupUi(&dialog); - ui.angle->setRange(1.0, 30.0); - connect(ui.buttonBox, SIGNAL(accepted()), - &dialog, SLOT(accept())); - connect(ui.buttonBox, SIGNAL(rejected()), - &dialog, SLOT(reject())); - - ui.sizing->setRange(diag * 10e-6, // min - diag); // max - ui.sizing->setValue(diag * 0.05); // default value - - ui.approx->setRange(diag * 10e-7, // min - diag); // max - ui.approx->setValue(diag * 0.005); - - if (polylines_item!=nullptr) - { - ui.edge_sizing->setRange(diag * 10e-6, // min - diag); // max - ui.edge_sizing->setValue(diag * 0.05); // default value - } - else - ui.edge_sizing->setEnabled(false); - - int i = dialog.exec(); - if(i == QDialog::Rejected) - return; - - const double angle = ui.angle->value(); - const double approx = ui.approx->value(); - const double sizing = ui.sizing->value(); - const double edge_size=polylines_item!=nullptr?ui.edge_sizing->value():0; - const int tag_index = ui.tags->currentIndex(); - - if(tag_index < 0) return; - - QApplication::setOverrideCursor(Qt::WaitCursor); - - std::cerr << "mesh with:" - << "\n angle=" << angle - << "\n sizing=" << sizing - << "\n approx=" << approx - << "\n tag=" << tag_index - << std::boolalpha - << std::endl; - Mesher_thread* worker = nullptr; - if(soup_item) - worker = new Mesher_thread(nullptr, - soup_item, - polylines_item, - offset_value, - angle, - sizing, - approx, - edge_size, - tag_index); - else - worker = new Mesher_thread(sMesh, - nullptr, - polylines_item, - offset_value, - angle, - sizing, - approx, - edge_size, - tag_index); - connect(worker, &QThread::finished, worker, &QObject::deleteLater); - connect(worker, &Mesher_thread::resultReady, this, - [item, angle, sizing, approx, offset_value/* , index */] - (SMesh *new_mesh){ - QApplication::restoreOverrideCursor(); - if(!new_mesh){ - CGAL::Three::Three::getMutex()->lock(); - CGAL::Three::Three::isLocked() = false; - CGAL::Three::Three::getMutex()->unlock(); - return; - } - Scene_surface_mesh_item* new_item = new Scene_surface_mesh_item(new_mesh); - new_item->setName(tr("%1 offset %5 (%2 %3 %4)") - .arg(item->name()) - .arg(angle) - .arg(sizing) - .arg(approx) - .arg(offset_value)); - new_item->setColor(Qt::magenta); - new_item->setWireframeMode(); - CGAL::Three::Three::scene()->addItem(new_item); -// CGAL::Three::Three::scene()->itemChanged(index); - QApplication::restoreOverrideCursor(); - CGAL::Three::Three::getMutex()->lock(); - CGAL::Three::Three::isLocked() = false; - CGAL::Three::Three::getMutex()->unlock(); - }); - QMessageBox* message_box = new QMessageBox(QMessageBox::NoIcon, - "Meshing", - "Offset meshing in progress...", - QMessageBox::Cancel, - mw); - message_box->setDefaultButton(QMessageBox::Cancel); - QAbstractButton* cancelButton = message_box->button(QMessageBox::Cancel); - cancelButton->setText(tr("Stop")); - - connect(cancelButton, &QAbstractButton::clicked, - this, [worker](){ - worker->terminate(); - QApplication::restoreOverrideCursor();//waitcursor - QApplication::restoreOverrideCursor();//busycursor - }); - connect(worker, &Mesher_thread::finished, - message_box, &QMessageBox::close); - message_box->open(); - - QApplication::setOverrideCursor(Qt::BusyCursor); - CGAL::Three::Three::getMutex()->lock(); - CGAL::Three::Three::isLocked() = true; - CGAL::Three::Three::getMutex()->unlock(); - worker->start(); -} - -#include "Offset_meshing_plugin.moc" - -#endif // CGAL_LAB_DEMO_USE_SURFACE_MESHER diff --git a/Lab/demo/Lab/Plugins/Surface_mesh/Scene_polyhedron_shortest_path_item.cpp b/Lab/demo/Lab/Plugins/Surface_mesh/Scene_polyhedron_shortest_path_item.cpp index 90477043da7..5ed52540c41 100644 --- a/Lab/demo/Lab/Plugins/Surface_mesh/Scene_polyhedron_shortest_path_item.cpp +++ b/Lab/demo/Lab/Plugins/Surface_mesh/Scene_polyhedron_shortest_path_item.cpp @@ -562,7 +562,7 @@ bool Scene_polyhedron_shortest_path_item::deferred_load( std::vector listOfFaces; listOfFaces.reserve(CGAL::num_faces(*polyhedron())); face_iterator current, end; - for (boost::tie(current, end) = CGAL::faces(*polyhedron()); current != end; ++current) + for (std::tie(current, end) = CGAL::faces(*polyhedron()); current != end; ++current) { listOfFaces.push_back(*current); } diff --git a/Lab/demo/Lab/Plugins/Surface_mesh_deformation/Scene_edit_polyhedron_item.cpp b/Lab/demo/Lab/Plugins/Surface_mesh_deformation/Scene_edit_polyhedron_item.cpp index 786727bc145..9be866438e9 100644 --- a/Lab/demo/Lab/Plugins/Surface_mesh_deformation/Scene_edit_polyhedron_item.cpp +++ b/Lab/demo/Lab/Plugins/Surface_mesh_deformation/Scene_edit_polyhedron_item.cpp @@ -1572,7 +1572,7 @@ void Scene_edit_polyhedron_item_priv::read_roi(const char* file_name, Mesh* mesh std::vector all_vertices; all_vertices.reserve(num_vertices(fs.get_deform_mesh(mesh)->halfedge_graph())); mesh_vi vb, ve; - for(boost::tie(vb, ve) = vertices(fs.get_deform_mesh(mesh)->halfedge_graph()); vb != ve; ++vb) { + for(std::tie(vb, ve) = vertices(fs.get_deform_mesh(mesh)->halfedge_graph()); vb != ve; ++vb) { all_vertices.push_back(*vb); } // read roi @@ -1731,7 +1731,7 @@ void Scene_edit_polyhedron_item::update_normals() { void Scene_edit_polyhedron_item::set_all_vertices_as_roi() { boost::graph_traits::vertex_iterator vb, ve; - for(boost::tie(vb, ve) = vertices(*surface_mesh()); vb != ve; ++vb) + for(std::tie(vb, ve) = vertices(*surface_mesh()); vb != ve; ++vb) { insert_roi_vertex(*vb, surface_mesh()); } diff --git a/Lab/demo/Lab/Scene_polyhedron_selection_item.cpp b/Lab/demo/Lab/Scene_polyhedron_selection_item.cpp index 7df511b6169..a00454c375b 100644 --- a/Lab/demo/Lab/Scene_polyhedron_selection_item.cpp +++ b/Lab/demo/Lab/Scene_polyhedron_selection_item.cpp @@ -779,19 +779,26 @@ void Scene_polyhedron_selection_item::set_operation_mode(int mode) //set the selection type to vertex set_active_handle_type(static_cast(0)); break; - //Add vertex and face to border + //Remove degree 2 vertex case 9: - Q_EMIT updateInstructions("Select a border edge. (1/2)"); - //set the selection type to Edge - set_active_handle_type(static_cast(2)); + Q_EMIT updateInstructions("Select the vertex you want to remove." + "Warning: This will clear the undo stack."); + //set the selection type to vertex + set_active_handle_type(static_cast(0)); break; - //Add face to border + //Add vertex and face to border case 10: Q_EMIT updateInstructions("Select a border edge. (1/2)"); //set the selection type to Edge set_active_handle_type(static_cast(2)); break; + //Add face to border case 11: + Q_EMIT updateInstructions("Select a border edge. (1/2)"); + //set the selection type to Edge + set_active_handle_type(static_cast(2)); + break; + case 12: Q_EMIT updateInstructions("Select a vertex. (1/2)"); //set the selection type to Edge set_active_handle_type(static_cast(0)); @@ -1011,7 +1018,24 @@ bool Scene_polyhedron_selection_item::treat_selection(const std::setinvalidateOpenGLBuffers(); + } + else + { + d->tempInstructions("Vertex not selected: The vertex must have degree 2 (and not be incident to a triangle)", + "Select the vertex you want to remove." + "Warning: This will clear the undo stack."); + } + break; + } + //Move point + case 12: CGAL::QGLViewer* viewer = Three::mainViewer(); const CGAL::qglviewer::Vec offset = viewer->offset(); if(viewer->manipulatedFrame() != d->manipulated_frame) @@ -1032,7 +1056,7 @@ bool Scene_polyhedron_selection_item::treat_selection(const std::set= degree -/* -std::size_t facet_degree(fg_halfedge_descriptor h, const Face_graph& polyhedron) -{ - return degree(h,polyhedron); -} -*/ bool Scene_polyhedron_selection_item:: treat_selection(const std::set& selection) { VPmap vpm = get(CGAL::vertex_point, *polyhedron()); @@ -1203,7 +1220,7 @@ bool Scene_polyhedron_selection_item:: treat_selection(const std::setfirst_selected) @@ -1255,7 +1272,7 @@ bool Scene_polyhedron_selection_item:: treat_selection(const std::setfirst_selected) @@ -1963,6 +1980,23 @@ void Scene_polyhedron_selection_item::moveVertex() } } +void Scene_polyhedron_selection_item::moveVertex(const Point_3& new_position) +{ + const CGAL::qglviewer::Vec offset = Three::mainViewer()->offset(); + fg_vertex_descriptor vh = *temp_selected_vertices.begin(); + + VPmap vpm = get(CGAL::vertex_point,*polyhedron()); + put(vpm, vh, Point_3(new_position.x() - offset.x, + new_position.y() - offset.y, + new_position.z() - offset.z)); + const Point_3& p = get(vpm,vh); + d->manipulated_frame->setPosition(p.x()+offset.x, p.y()+offset.y, p.z()+offset.z); + setProperty("need_invalidate_aabb_tree", true); + invalidateOpenGLBuffers(); + poly_item->updateVertex(vh); + // poly_item->invalidateOpenGLBuffers(); +} + void Scene_polyhedron_selection_item::validateMoveVertex() { temp_selected_vertices.clear(); diff --git a/Lab/demo/Lab/Scene_polyhedron_selection_item.h b/Lab/demo/Lab/Scene_polyhedron_selection_item.h index 7a2cc2f16bd..23af5a1cfee 100644 --- a/Lab/demo/Lab/Scene_polyhedron_selection_item.h +++ b/Lab/demo/Lab/Scene_polyhedron_selection_item.h @@ -415,7 +415,7 @@ public: fg_vertex_descriptor t = all_vertices[id2]; fg_halfedge_descriptor hd; bool exists; - boost::tie(hd,exists) = halfedge(s,t,*polyhedron()); + std::tie(hd,exists) = halfedge(s,t,*polyhedron()); if(! exists) { return false; } selected_edges.insert(edge(hd,*polyhedron())); } @@ -917,6 +917,7 @@ public Q_SLOTS: void updateTick(); void moveVertex(); + void moveVertex(const Point_3&); protected: bool eventFilter(QObject* /*target*/, QEvent * gen_event) { diff --git a/Lab/demo/Lab/Scene_surface_mesh_item.cpp b/Lab/demo/Lab/Scene_surface_mesh_item.cpp index 30e0d59ab83..cf8ed877f77 100644 --- a/Lab/demo/Lab/Scene_surface_mesh_item.cpp +++ b/Lab/demo/Lab/Scene_surface_mesh_item.cpp @@ -545,7 +545,7 @@ void Scene_surface_mesh_item_priv::compute_elements(Scene_item_rendering_helper: } if(name.testFlag(Scene_item_rendering_helper::NORMALS)) { - EPICK::Vector_3 n = fnormals[fd]; + const EPICK::Vector_3& n = fnormals[fd]; CPF::add_normal_in_buffer(n, flat_normals); } if(name.testFlag(Scene_item_rendering_helper::COLORS)) @@ -553,7 +553,7 @@ void Scene_surface_mesh_item_priv::compute_elements(Scene_item_rendering_helper: if(has_fpatch_id) { //The sharp features detection produces patch ids >=1, this - //is meant to insure the wanted id is in the range [min,max] + //is meant to ensure the wanted id is in the range [min,max] QColor c = item->color_vector()[fpatch_id_map[fd] - min_patch_id]; CGAL::IO::Color color(c.red(),c.green(),c.blue()); CPF::add_color_in_buffer(color, f_colors); diff --git a/Lab/demo/Lab/Viewer.cpp b/Lab/demo/Lab/Viewer.cpp index b93cb2cb7b1..00e98fa2b88 100644 --- a/Lab/demo/Lab/Viewer.cpp +++ b/Lab/demo/Lab/Viewer.cpp @@ -1838,7 +1838,7 @@ void Viewer::setLighting() if (list.size()!=3){ QMessageBox *msgBox = new QMessageBox; msgBox->setWindowTitle("Error"); - msgBox->setText("ERROR : Input should consists of 3 floats."); + msgBox->setText("ERROR : Input should consist of 3 floats."); msgBox->exec(); return; } diff --git a/Lab/demo/Lab/include/Point_set_3.h b/Lab/demo/Lab/include/Point_set_3.h index fcfb3805c9e..a0444c9b744 100644 --- a/Lab/demo/Lab/include/Point_set_3.h +++ b/Lab/demo/Lab/include/Point_set_3.h @@ -135,7 +135,7 @@ public: bool add_radius() { bool out = false; - boost::tie (m_radius, out) = this->template add_property_map ("radius", 0.); + std::tie (m_radius, out) = this->template add_property_map ("radius", 0.); return out; } double& radius (const Index& index) { return m_radius[index]; } @@ -409,21 +409,15 @@ public: { if (other.template has_property_map("red")) { - boost::tie (m_red, boost::tuples::ignore) - = this->template add_property_map("red", 0); - boost::tie (m_green, boost::tuples::ignore) - = this->template add_property_map("green", 0); - boost::tie (m_blue, boost::tuples::ignore) - = this->template add_property_map("blue", 0); + m_red = this->template add_property_map("red", 0).first; + m_green = this->template add_property_map("green", 0).first; + m_blue = this->template add_property_map("blue", 0).first; } else { - boost::tie (m_red, boost::tuples::ignore) - = this->template add_property_map("r", 0); - boost::tie (m_green, boost::tuples::ignore) - = this->template add_property_map("g", 0); - boost::tie (m_blue, boost::tuples::ignore) - = this->template add_property_map("b", 0); + m_red = this->template add_property_map("r", 0).first; + m_green = this->template add_property_map("g", 0).first; + m_blue = this->template add_property_map("b", 0).first; } } diff --git a/Matrix_search/doc/Matrix_search/PackageDescription.txt b/Matrix_search/doc/Matrix_search/PackageDescription.txt index 202989f2da3..1dabc40e68c 100644 --- a/Matrix_search/doc/Matrix_search/PackageDescription.txt +++ b/Matrix_search/doc/Matrix_search/PackageDescription.txt @@ -5,7 +5,6 @@ /*! \addtogroup PkgMatrixSearchRef -\todo check generated documentation \cgalPkgDescriptionBegin{Monotone and Sorted Matrix Search,PkgMatrixSearch} \cgalPkgPicture{matrix.png} \cgalPkgSummaryBegin diff --git a/Mesh_2/doc/Mesh_2/CGAL/IO/write_VTU.h b/Mesh_2/doc/Mesh_2/CGAL/IO/write_VTU.h index 35b4dda2756..5513693788b 100644 --- a/Mesh_2/doc/Mesh_2/CGAL/IO/write_VTU.h +++ b/Mesh_2/doc/Mesh_2/CGAL/IO/write_VTU.h @@ -6,6 +6,8 @@ namespace IO { //! //! The faces output are those for which `DelaunayMeshFaceBase_2::is_in_domain()` returns `true`, //! the edges are those for which `ConstrainedTriangulationFaceBase_2::is_constrained()` returns `true`. +//!\attention To read a binary file, the flag `std::ios::binary` must be set during the creation of `os`. +//! //! \tparam CDT a `Constrained_Delaunay_triangulation_2` with face type model of `DelaunayMeshFaceBase_2`. //! //! \param os the stream used for writing. @@ -23,9 +25,12 @@ void write_VTU(std::ostream& os, //! \brief writes the faces of a domain and its constrained edges embedded in //! a 2D constrained Delaunay triangulation using the `PolyData` XML //! format. - //! The faces output are those for which `get(ipm, f)` returns - //! `true` where `f` is a `CDT::Face_handle`, +//! The faces output are those for which `get(ipm, f)` returns +//! `true` where `f` is a `CDT::Face_handle`, //! the edges are those for which `ConstrainedTriangulationFaceBase_2::is_constrained()` returns `true`. +//! +//!\attention To read a binary file, the flag `std::ios::binary` must be set during the creation of `os`. +//! //! \tparam CDT a `Constrained_Delaunay_triangulation_2` with face //! type model of `DelaunayMeshFaceBase_2`. //! \tparam InDomainPmap a class model of `ReadWritePropertyMap` with diff --git a/Mesh_2/include/CGAL/Delaunay_mesh_face_base_2.h b/Mesh_2/include/CGAL/Delaunay_mesh_face_base_2.h index a3e54124402..5601684ed22 100644 --- a/Mesh_2/include/CGAL/Delaunay_mesh_face_base_2.h +++ b/Mesh_2/include/CGAL/Delaunay_mesh_face_base_2.h @@ -78,7 +78,7 @@ public: void set_time_stamp(const std::size_t& ts) { time_stamp_ = ts; } - std::size_t time_stamp_; + std::size_t time_stamp_ = std::size_t(-2); }; } // namespace CGAL diff --git a/Mesh_2/include/CGAL/Delaunay_mesh_vertex_base_2.h b/Mesh_2/include/CGAL/Delaunay_mesh_vertex_base_2.h index 3093f3b49a9..0c62a20fb5c 100644 --- a/Mesh_2/include/CGAL/Delaunay_mesh_vertex_base_2.h +++ b/Mesh_2/include/CGAL/Delaunay_mesh_vertex_base_2.h @@ -67,7 +67,7 @@ public: void set_time_stamp(const std::size_t& ts) { time_stamp_ = ts; } - std::size_t time_stamp_; + std::size_t time_stamp_ = std::size_t(-2); #endif // CGAL_MESH_2_DEBUG_REFINEMENT_POINTS }; diff --git a/Mesh_3/include/CGAL/Compact_mesh_cell_base_3.h b/Mesh_3/include/CGAL/Compact_mesh_cell_base_3.h index 82380d7865b..e47d899faec 100644 --- a/Mesh_3/include/CGAL/Compact_mesh_cell_base_3.h +++ b/Mesh_3/include/CGAL/Compact_mesh_cell_base_3.h @@ -644,7 +644,7 @@ private: #ifdef CGAL_INTRUSIVE_LIST Cell_handle next_intrusive_ = {}, previous_intrusive_ = {}; #endif - std::size_t time_stamp_; + std::size_t time_stamp_ = std::size_t(-2); std::array surface_center_index_table_ = {}; /// Stores visited facets (4 first bits) diff --git a/Mesh_3/include/CGAL/Mesh_3/Mesher_3.h b/Mesh_3/include/CGAL/Mesh_3/Mesher_3.h index 036094d60b0..982681d4ac2 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Mesher_3.h +++ b/Mesh_3/include/CGAL/Mesh_3/Mesher_3.h @@ -687,14 +687,16 @@ initialize() bbox.xmin() + 0.5*xdelta, bbox.ymin() + 0.5*ydelta, bbox.zmin() + 0.5*zdelta); -# ifdef CGAL_CONCURRENT_MESH_3_VERBOSE - std::cerr << "Adding points on a far sphere (radius = " << radius <<")..."; -# endif CGAL::Random rnd(0); Random_points_on_sphere_3 random_point(radius, rnd); const int NUM_PSEUDO_INFINITE_VERTICES = static_cast( float(std::thread::hardware_concurrency()) * Concurrent_mesher_config::get().num_pseudo_infinite_vertices_per_core); +#ifdef CGAL_MESH_3_VERBOSE + std::cerr << "Adding " << NUM_PSEUDO_INFINITE_VERTICES + << " points on a far sphere (radius = " << radius << ")..."; +#endif + for (int i = 0 ; i < NUM_PSEUDO_INFINITE_VERTICES ; ++i, ++random_point) r_c3t3_.add_far_point(r_c3t3_.triangulation().geom_traits().construct_weighted_point_3_object() (r_c3t3_.triangulation().geom_traits().construct_translated_point_3_object()(*random_point, center))); @@ -745,11 +747,12 @@ initialize() bbox.xmin() + 0.5*xdelta, bbox.ymin() + 0.5*ydelta, bbox.zmin() + 0.5*zdelta); -# ifdef CGAL_MESH_3_VERBOSE - std::cerr << "Adding points on a far sphere (radius = " << radius << ")..."; -# endif Random_points_on_sphere_3 random_point(radius); const int NUM_PSEUDO_INFINITE_VERTICES = 12*2; +# ifdef CGAL_MESH_3_VERBOSE + std::cerr << "Adding " << NUM_PSEUDO_INFINITE_VERTICES + << " points on a far sphere (radius = " << radius << ")..."; +#endif for (int i = 0 ; i < NUM_PSEUDO_INFINITE_VERTICES ; ++i, ++random_point) r_c3t3_.add_far_point(r_c3t3_.triangulation().geom_traits().construct_weighted_point_3_object() (r_c3t3_.triangulation().geom_traits().construct_translated_point_3_object()(*random_point, center))); 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 dfe2fb0a4ed..2e936424d62 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 @@ -234,6 +234,7 @@ private: Weight w, int dim, const Index& index, + Vertex_handle prev, ErasedVeOutIt out); /// Inserts balls between the points identified by the handles `vp` and `vq` @@ -549,7 +550,7 @@ Protect_edges_sizing_field:: operator()(const bool refine) { // This class is only meant to be used with non-periodic triangulations - CGAL_assertion(!(std::is_same::value)); + CGAL_assertion(!(std::is_same_v)); #ifdef CGAL_MESH_3_VERBOSE std::cerr << "Inserting protection balls..." << std::endl @@ -630,7 +631,7 @@ insert_corners() // Get weight (the ball radius is given by the 'query_size' function) const FT query_weight = CGAL::square(query_size(p, 0, p_index)); FT w = use_minimal_size() - ? (std::min)(minimal_weight_, query_weight) + ? (std::max)(minimal_weight(), query_weight) : query_weight; #if CGAL_MESH_3_PROTECTION_DEBUG & 1 @@ -639,7 +640,8 @@ insert_corners() // The following lines ensure that the weight w is small enough so that // corners balls do not intersect - if(dt.number_of_vertices() >= 2) + if( dt.number_of_vertices() >= 2 + && (!use_minimal_size() || w != minimal_weight())) { typename Dt::Vertex_handle vh; CGAL_assertion_code( bool p_found = ) @@ -656,10 +658,13 @@ insert_corners() dt, vh, finite_incident_cells); w = (std::min)(w, nearest_sq_dist / FT(9)); + + if(use_minimal_size()) + w = (std::max)(w, minimal_weight_); } // Insert corner with ball (dim is zero because p is a corner) - Vertex_handle v = smart_insert_point(p, w, 0, p_index, + Vertex_handle v = smart_insert_point(p, w, 0, p_index, Vertex_handle(), CGAL::Emptyset_iterator()).first; CGAL_assertion(v != Vertex_handle()); @@ -760,7 +765,7 @@ template std::pair::Vertex_handle, ErasedVeOutIt> Protect_edges_sizing_field:: -smart_insert_point(const Bare_point& p, Weight w, int dim, const Index& index, +smart_insert_point(const Bare_point& p, Weight w, int dim, const Index& index, Vertex_handle prev, ErasedVeOutIt out) { #if CGAL_MESH_3_PROTECTION_DEBUG & 1 @@ -791,7 +796,7 @@ smart_insert_point(const Bare_point& p, Weight w, int dim, const Index& index, // Check that new point will not be inside a power sphere typename Tr::Locate_type lt; int li, lj; - Cell_handle ch = tr.locate(wp0, lt, li, lj); + Cell_handle ch = tr.locate(wp0, lt, li, lj, prev); Vertex_handle nearest_vh = tr.nearest_power_vertex(p, ch); FT sq_d = sq_distance(p, cp(tr.point(nearest_vh))); @@ -1059,6 +1064,7 @@ insert_balls_on_edges() CGAL::square(p_size), 1 /*dim*/, p_index, + Vertex_handle(), CGAL::Emptyset_iterator()).first; } // No 'else' because in that case 'is_vertex(..)' already filled @@ -1248,6 +1254,7 @@ insert_balls(const Vertex_handle& vp, point_weight, dim, index, + Vertex_handle(), out); if(forced_stop()) return out; const Vertex_handle new_vertex = pair.first; @@ -1338,7 +1345,7 @@ insert_balls(const Vertex_handle& vp, // Insert point into c3t3 std::pair pair = - smart_insert_point(new_point, point_weight, dim, index, out); + smart_insert_point(new_point, point_weight, dim, index, prev, out); Vertex_handle new_vertex = pair.first; out = pair.second; diff --git a/Mesh_3/include/CGAL/Mesh_3/internal/Graph_manipulations.h b/Mesh_3/include/CGAL/Mesh_3/internal/Graph_manipulations.h index 31218f7c60d..db92293abf4 100644 --- a/Mesh_3/include/CGAL/Mesh_3/internal/Graph_manipulations.h +++ b/Mesh_3/include/CGAL/Mesh_3/internal/Graph_manipulations.h @@ -100,7 +100,7 @@ struct Graph_manipulations edge_descriptor edge; bool b; // test if the edge is already here, using add_edge - boost::tie(edge, b) = add_edge(va, vb, g); + std::tie(edge, b) = add_edge(va, vb, g); remove_edge(edge, g); if(!b) { // The edge was already here. @@ -129,7 +129,7 @@ struct Graph_manipulations if(v1 != v2) { edge_descriptor edge; bool b; - boost::tie(edge, b) = add_edge(v1, v2, g); + std::tie(edge, b) = add_edge(v1, v2, g); return b; } else return false; diff --git a/Mesh_3/include/CGAL/Mesh_3/internal/helpers.h b/Mesh_3/include/CGAL/Mesh_3/internal/helpers.h index f51af8cd0b3..8debd8dfdfc 100644 --- a/Mesh_3/include/CGAL/Mesh_3/internal/helpers.h +++ b/Mesh_3/include/CGAL/Mesh_3/internal/helpers.h @@ -72,7 +72,7 @@ struct Angle_tester else { out_edge_iterator out_edge_it, out_edges_end; - boost::tie(out_edge_it, out_edges_end) = out_edges(v, g); + std::tie(out_edge_it, out_edges_end) = out_edges(v, g); vertex_descriptor v1 = target(*out_edge_it++, g); vertex_descriptor v2 = target(*out_edge_it++, g); diff --git a/Mesh_3/include/CGAL/Mesh_3/polylines_to_protect.h b/Mesh_3/include/CGAL/Mesh_3/polylines_to_protect.h index 7b3dde34edc..67bcedd1a6b 100644 --- a/Mesh_3/include/CGAL/Mesh_3/polylines_to_protect.h +++ b/Mesh_3/include/CGAL/Mesh_3/polylines_to_protect.h @@ -325,7 +325,7 @@ struct Angle_tester else { out_edge_iterator out_edge_it, out_edges_end; - boost::tie(out_edge_it, out_edges_end) = out_edges(v, g); + std::tie(out_edge_it, out_edges_end) = out_edges(v, g); vertex_descriptor v1 = target(*out_edge_it++, g); vertex_descriptor v2 = target(*out_edge_it++, g); diff --git a/Mesh_3/include/CGAL/Mesh_cell_base_3.h b/Mesh_3/include/CGAL/Mesh_cell_base_3.h index d2f09a0606a..ac5535f7090 100644 --- a/Mesh_3/include/CGAL/Mesh_cell_base_3.h +++ b/Mesh_3/include/CGAL/Mesh_cell_base_3.h @@ -273,7 +273,7 @@ private: #ifdef CGAL_INTRUSIVE_LIST Cell_handle next_intrusive_, previous_intrusive_; #endif - std::size_t time_stamp_; + std::size_t time_stamp_ = std::size_t(-2); }; // end class Mesh_cell_base_3 diff --git a/Mesh_3/include/CGAL/Mesh_polyhedron_3.h b/Mesh_3/include/CGAL/Mesh_polyhedron_3.h index 454c0c94aff..04b6d247da1 100644 --- a/Mesh_3/include/CGAL/Mesh_polyhedron_3.h +++ b/Mesh_3/include/CGAL/Mesh_polyhedron_3.h @@ -41,10 +41,9 @@ private: typedef CGAL::HalfedgeDS_vertex_base Pdv_base; Set_of_indices indices; - std::size_t time_stamp_; - + std::size_t time_stamp_ = std::size_t(-2); public: - int nb_of_feature_edges; + int nb_of_feature_edges = 0; bool is_corner() const { return nb_of_feature_edges > 2; @@ -85,8 +84,8 @@ public: return indices; } - Mesh_polyhedron_vertex() : Pdv_base(), time_stamp_(-1), nb_of_feature_edges(0) {} - Mesh_polyhedron_vertex(const Point& p) : Pdv_base(p), time_stamp_(-1), nb_of_feature_edges(0) {} + Mesh_polyhedron_vertex() = default; + Mesh_polyhedron_vertex(const Point& p) : Pdv_base(p) {} }; template @@ -95,7 +94,7 @@ public CGAL::HalfedgeDS_halfedge_base { private: bool feature_edge; - std::size_t time_stamp_; + std::size_t time_stamp_ = std::size_t(-2); public: @@ -143,7 +142,7 @@ public CGAL::HalfedgeDS_face_base { private: Patch_id_ patch_id_; - std::size_t time_stamp_; + std::size_t time_stamp_ = std::size_t(-2); public: diff --git a/Mesh_3/include/CGAL/Mesh_vertex_base_3.h b/Mesh_3/include/CGAL/Mesh_vertex_base_3.h index 46b09094e95..db43424ec4f 100644 --- a/Mesh_3/include/CGAL/Mesh_vertex_base_3.h +++ b/Mesh_3/include/CGAL/Mesh_vertex_base_3.h @@ -250,7 +250,7 @@ private: Vertex_handle next_intrusive_; Vertex_handle previous_intrusive_; #endif - std::size_t time_stamp_; + std::size_t time_stamp_ = std::size_t(-2); public: friend std::istream& operator>>(std::istream &is, Mesh_vertex_3& v) diff --git a/Mesh_3/test/Mesh_3/CMakeLists.txt b/Mesh_3/test/Mesh_3/CMakeLists.txt index 9939a2710e7..de33e3d2024 100644 --- a/Mesh_3/test/Mesh_3/CMakeLists.txt +++ b/Mesh_3/test/Mesh_3/CMakeLists.txt @@ -49,6 +49,7 @@ create_single_source_cgal_program( "test_meshing_with_default_edge_size.cpp" ) create_single_source_cgal_program( "test_meshing_determinism.cpp" ) create_single_source_cgal_program( "test_meshing_without_features_determinism.cpp" ) create_single_source_cgal_program( "test_mesh_3_issue_1554.cpp" ) +create_single_source_cgal_program( "test_mesh_3_issue_8773.cpp" ) create_single_source_cgal_program( "test_mesh_polyhedral_domain_with_features_deprecated.cpp" ) create_single_source_cgal_program( "test_meshing_with_one_step.cpp" ) create_single_source_cgal_program( "test_meshing_with_one_step_with_features.cpp" ) @@ -79,6 +80,7 @@ foreach(target test_meshing_determinism test_meshing_without_features_determinism test_mesh_3_issue_1554 + test_mesh_3_issue_8773 test_mesh_polyhedral_domain_with_features_deprecated test_mesh_cell_base_3 test_meshing_with_one_step @@ -108,6 +110,7 @@ if(TARGET CGAL::TBB_support) test_meshing_determinism test_meshing_without_features_determinism test_mesh_3_issue_1554 + test_mesh_3_issue_8773 test_mesh_polyhedral_domain_with_features_deprecated test_mesh_cell_base_3 test_min_edge_length @@ -129,6 +132,7 @@ if(TARGET CGAL::TBB_support) "execution of test_meshing_polyhedral_complex" "execution of test_mesh_capsule_var_distance_bound" "execution of test_mesh_3_issue_1554" + "execution of test_mesh_3_issue_8773" "execution of test_mesh_polyhedral_domain_with_features_deprecated" "execution of test_mesh_cell_base_3" PROPERTY RUN_SERIAL 1) diff --git a/Mesh_3/test/Mesh_3/test_mesh_3_issue_8773.cpp b/Mesh_3/test/Mesh_3/test_mesh_3_issue_8773.cpp new file mode 100644 index 00000000000..bc348b25676 --- /dev/null +++ b/Mesh_3/test/Mesh_3/test_mesh_3_issue_8773.cpp @@ -0,0 +1,130 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Domain +using K = CGAL::Exact_predicates_inexact_constructions_kernel; +using Polyhedron = CGAL::Surface_mesh; +using Mesh_domain = CGAL::Polyhedral_mesh_domain_with_features_3; + +// Triangulation +using Tr = CGAL::Mesh_triangulation_3::type; +using C3t3 = CGAL::Mesh_complex_3_in_triangulation_3; + +// Criteria +using Mesh_criteria = CGAL::Mesh_criteria_3; + +namespace params = CGAL::parameters; + +void check_stream(const std::ios& stream, + const std::string& filename, + const std::string& operation, + bool ok = true) { + if(!stream || !ok) { + std::cerr << "Stream error after " << operation << " file: " << filename << std::endl; + std::cerr << "Stream state: "; + if(stream.rdstate() == std::ios::goodbit) { + std::cerr << "no error"; + } else { + if(stream.rdstate() & std::ios::eofbit) { + std::cerr << "eofbit "; + } + if(stream.rdstate() & std::ios::failbit) { + std::cerr << "failbit "; + } + if(stream.rdstate() & std::ios::badbit) { + std::cerr << "badbit "; + } + } + std::cerr << std::endl; + std::exit(EXIT_FAILURE); + } +} + +int main(int argc, char* argv[]) { + const std::string fname = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/cube.off"); + + // Create input polyhedron + Polyhedron polyhedron; + std::ifstream input(fname); + check_stream(input, fname, "opening"); + input >> polyhedron; + check_stream(input, fname, "reading polyhedron from"); + + // Create domain + Mesh_domain domain(polyhedron); + domain.detect_features(); + + // Mesh criteria (no cell_size set) + Mesh_criteria criteria(params::facet_angle(25).facet_size(0.15).facet_distance(0.05).cell_radius_edge_ratio(3)); + + // Mesh generation + const C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria, params::no_perturb().no_exude()); + + const auto nb_vertices = c3t3.triangulation().number_of_vertices(); + const auto nb_far_vertices = c3t3.number_of_far_points(); + const auto nb_cells = c3t3.number_of_cells(); + + std::cout << "Created a c3t3 with " << c3t3.triangulation().number_of_vertices() << " vertices, and " + << c3t3.number_of_cells() << " cells" << std::endl; + + // Output + { + const std::string filename = "ascii.vtu"; + std::ofstream out(filename); + check_stream(out, filename, "opening"); + CGAL::IO::output_to_vtu(out, c3t3, CGAL::IO::ASCII); + check_stream(out, filename, "writing (ASCII)"); + } + + { + const std::string filename = "binary.vtu"; + std::ofstream out(filename, std::ios::binary); + check_stream(out, filename, "opening"); + CGAL::IO::output_to_vtu(out, c3t3, CGAL::IO::BINARY); + check_stream(out, filename, "writing (BINARY)"); + } + + const std::string filename = "mesh.binary.cgal"; + { + std::ofstream out(filename, std::ios::binary); + check_stream(out, filename, "opening"); + bool ok = CGAL::IO::save_binary_file(out, c3t3); + check_stream(out, filename, "writing (binary)", ok); + } + + // Input + C3t3 bis; + { + std::ifstream in(filename, std::ios::binary); + check_stream(in, filename, "opening (binary)"); + bool ok = CGAL::IO::load_binary_file(in, bis); + check_stream(in, filename, "reading binary file", ok); + } + + { + const std::string bis_filename = "bis.vtu"; + std::ofstream bis_os(bis_filename); + check_stream(bis_os, bis_filename, "opening (bis.vtu)"); + CGAL::IO::output_to_vtu(bis_os, bis, CGAL::IO::ASCII); + check_stream(bis_os, bis_filename, "writing (ASCII)"); + } + + assert(bis.number_of_cells() == nb_cells); + assert(bis.triangulation().number_of_vertices() == nb_vertices); + assert(bis.number_of_far_points() == nb_far_vertices); + + std::cout << "Mesh generation and output completed successfully." << std::endl; + + return EXIT_SUCCESS; +} diff --git a/Minkowski_sum_3/doc/Minkowski_sum_3/PackageDescription.txt b/Minkowski_sum_3/doc/Minkowski_sum_3/PackageDescription.txt index 55255f3db34..5f467e1e05f 100644 --- a/Minkowski_sum_3/doc/Minkowski_sum_3/PackageDescription.txt +++ b/Minkowski_sum_3/doc/Minkowski_sum_3/PackageDescription.txt @@ -2,7 +2,6 @@ /*! \addtogroup PkgMinkowskiSum3Ref -\todo check generated documentation \cgalPkgDescriptionBegin{3D Minkowski Sum of Polyhedra,PkgMinkowskiSum3} \cgalPkgPicture{Minkowski_sum_3/fig/Minkowski_sum_3_teaser.png} \cgalPkgSummaryBegin diff --git a/Nef_3/doc/Nef_3/PackageDescription.txt b/Nef_3/doc/Nef_3/PackageDescription.txt index de1e15c2f1c..6f591bcfb6c 100644 --- a/Nef_3/doc/Nef_3/PackageDescription.txt +++ b/Nef_3/doc/Nef_3/PackageDescription.txt @@ -11,7 +11,6 @@ /*! \addtogroup PkgNef3Ref -\todo check generated documentation \cgalPkgDescriptionBegin{3D Boolean Operations on Nef Polyhedra,PkgNef3} \cgalPkgPicture{Nef_3-teaser.png} \cgalPkgSummaryBegin diff --git a/Number_types/doc/Number_types/CGAL/double.h b/Number_types/doc/Number_types/CGAL/double.h index 5c48d4332c8..a0520d46957 100644 --- a/Number_types/doc/Number_types/CGAL/double.h +++ b/Number_types/doc/Number_types/CGAL/double.h @@ -4,10 +4,10 @@ This header provides all necessary functions so the fundamental type `double` is a model of the concepts `RealEmbeddable` and -`Field`. Due to rounding errors and overflow `double` is considered as +`FieldWithKthRoot`. Due to rounding errors and overflow `double` is considered as not exact. -\cgalModels{FieldWithSqrt,RealEmbeddable} +\cgalModels{FieldWithKthRoot,RealEmbeddable} */ diff --git a/Number_types/doc/Number_types/CGAL/float.h b/Number_types/doc/Number_types/CGAL/float.h index 84f782c4d82..ee5aab1d406 100644 --- a/Number_types/doc/Number_types/CGAL/float.h +++ b/Number_types/doc/Number_types/CGAL/float.h @@ -6,10 +6,10 @@ This header provides all necessary functions so the fundamental type `float` is a model of the concepts `RealEmbeddable` and -`FieldWithSqrt`. Due to rounding errors and overflow `float` is +`FieldWithKthRoot`. Due to rounding errors and overflow `float` is considered as not exact. -\cgalModels{FieldWithSqrt,RealEmbeddable} +\cgalModels{FieldWithKthRoot,RealEmbeddable} */ diff --git a/Number_types/doc/Number_types/CGAL/int.h b/Number_types/doc/Number_types/CGAL/int.h index 8f43eac76b7..6db0d8c9e5c 100644 --- a/Number_types/doc/Number_types/CGAL/int.h +++ b/Number_types/doc/Number_types/CGAL/int.h @@ -3,12 +3,10 @@ \ingroup nt_builtin This header provides all necessary functions so the fundamental types -`int`, `long int`, and `short int` become models of their respective algebraic concepts. - -- `int` is a model of `RealEmbeddable` and `EuclideanRing`, -- `long int` is a model of `RealEmbeddable` and `EuclideanRing` -- `short int` is a model of `RealEmbeddable` and `EuclideanRing` +`int`, `long int`, and `short int` are models of the concepts `RealEmbeddable` and +`EuclideanRing`. Due to overflow neither of those types is considered as exact. +\cgalModels{RealEmbeddable, EuclideanRing} */ diff --git a/Number_types/doc/Number_types/CGAL/long_double.h b/Number_types/doc/Number_types/CGAL/long_double.h index 74275b716d1..283a9458b16 100644 --- a/Number_types/doc/Number_types/CGAL/long_double.h +++ b/Number_types/doc/Number_types/CGAL/long_double.h @@ -5,8 +5,10 @@ This header provides all necessary functions so the fundamental type `long double` is a model of the concepts `RealEmbeddable` and -`FieldWithSqrt`. Due to rounding errors and overflow `long double` is +`FieldWithKthRoot`. Due to rounding errors and overflow `long double` is considered as not exact. + +\cgalModels{FieldWithKthRoot,RealEmbeddable} */ namespace CGAL { diff --git a/Number_types/doc/Number_types/CGAL/long_long.h b/Number_types/doc/Number_types/CGAL/long_long.h index 83e6e23a058..26885845e4c 100644 --- a/Number_types/doc/Number_types/CGAL/long_long.h +++ b/Number_types/doc/Number_types/CGAL/long_long.h @@ -1,8 +1,10 @@ -/// \file long_long.h -/// \ingroup nt_builtin -/// -/// This header provides all necessary functions so the fundamental -/// type `long long int` is an `RealEmbeddable` `EuclideanRing`. Due -/// to overflow `long long int` is considered as not exact. -/// -/// \cgalModels{EuclideanRing,RealEmbeddable} +/*! +\file long_long.h +\ingroup nt_builtin + +This header provides all necessary functions so the fundamental +type `long long int` is a model of the concepts `RealEmbeddable` and `EuclideanRing`. Due +to overflow `long long int` is considered as not exact. + +\cgalModels{RealEmbeddable, EuclideanRing} +*/ \ No newline at end of file diff --git a/Number_types/doc/Number_types/PackageDescription.txt b/Number_types/doc/Number_types/PackageDescription.txt index 84bfd6debbd..ba551f7c153 100644 --- a/Number_types/doc/Number_types/PackageDescription.txt +++ b/Number_types/doc/Number_types/PackageDescription.txt @@ -30,7 +30,6 @@ /*! \addtogroup PkgNumberTypesRef -\todo check generated documentation \cgalPkgDescriptionBegin{Number Types,PkgNumberTypes} \cgalPkgPicture{illustration.png} \cgalPkgSummaryBegin diff --git a/Partition_2/doc/Partition_2/PackageDescription.txt b/Partition_2/doc/Partition_2/PackageDescription.txt index ec875293336..2d33fd123ce 100644 --- a/Partition_2/doc/Partition_2/PackageDescription.txt +++ b/Partition_2/doc/Partition_2/PackageDescription.txt @@ -7,7 +7,6 @@ /// \ingroup PkgPartition2Ref /*! \addtogroup PkgPartition2Ref -\todo check generated documentation \cgalPkgDescriptionBegin{2D Polygon Partitioning,PkgPartition2} \cgalPkgPicture{Partition_2/fig/Partition_2-teaser-small.png} \cgalPkgSummaryBegin diff --git a/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/CGAL/Periodic_2_triangulation_2.h b/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/CGAL/Periodic_2_triangulation_2.h index 05f9da516bc..1124eeab784 100644 --- a/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/CGAL/Periodic_2_triangulation_2.h +++ b/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/CGAL/Periodic_2_triangulation_2.h @@ -579,7 +579,7 @@ public: /*! Converts the `Periodic_point` `pp` (point-offset pair) to the - corresponding `Point` in \f$ \mathbb R^3\f$. + corresponding `Point` in \f$ \mathbb R^2\f$. */ Point point(const Periodic_point & pp ) const; @@ -593,6 +593,18 @@ public: */ Triangle triangle(const Periodic_triangle & t) const; + /*! + Equivalent to + the call `t.point(t.periodic_point(fh,i));` + */ + Point point(Face_handle fh, int i) const; + + /*! + Equivalent to + the call `t.point(t.periodic_point(v));` + */ + Point point(Vertex_handle v) const; + /*! Equivalent to the call `t.segment(t.periodic_segment(f,i));` diff --git a/Periodic_3_mesh_3/include/CGAL/Periodic_3_mesh_3/Protect_edges_sizing_field.h b/Periodic_3_mesh_3/include/CGAL/Periodic_3_mesh_3/Protect_edges_sizing_field.h index 33420371bfc..fd1e0b9e104 100644 --- a/Periodic_3_mesh_3/include/CGAL/Periodic_3_mesh_3/Protect_edges_sizing_field.h +++ b/Periodic_3_mesh_3/include/CGAL/Periodic_3_mesh_3/Protect_edges_sizing_field.h @@ -52,8 +52,7 @@ #ifndef CGAL_NO_ASSERTIONS # include // for float_prior #endif -#include -#include + #include #include @@ -62,10 +61,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include @@ -393,7 +394,7 @@ private: const Curve_index& curve_index, const CGAL::Orientation orientation) const { Bare_point pa, pb; - boost::tie(pa, pb) = get_positions(va, vb, curve_index, orientation); + std::tie(pa, pb) = get_positions(va, vb, curve_index, orientation); return compute_distance(pa, pb); } @@ -511,11 +512,11 @@ private: const Vertex_handle v2, const Curve_index& curve_index) const; - boost::tuple get_positions(const Vertex_handle v1, - const Vertex_handle v2, - const Vertex_handle v3, - const Curve_index& curve_index, - const CGAL::Orientation orientation) const; + std::tuple get_positions(const Vertex_handle v1, + const Vertex_handle v2, + const Vertex_handle v3, + const Curve_index& curve_index, + const CGAL::Orientation orientation) const; private: C3T3& c3t3_; @@ -953,9 +954,9 @@ get_positions_with_unknown_orientation(const Vertex_handle v1, template -boost::tuple::Bare_point, - typename Protect_edges_sizing_field::Bare_point, - typename Protect_edges_sizing_field::Bare_point> +std::tuple::Bare_point, + typename Protect_edges_sizing_field::Bare_point, + typename Protect_edges_sizing_field::Bare_point> Protect_edges_sizing_field:: get_positions(const Vertex_handle v1, const Vertex_handle v2, @@ -965,11 +966,11 @@ get_positions(const Vertex_handle v1, { Bare_point p1, p2_check, p2, p3; - boost::tie(p1, p2) = get_positions(v1, v2, curve_index, orientation); - boost::tie(p2_check, p3) = get_positions(v2, v3, curve_index, orientation); + std::tie(p1, p2) = get_positions(v1, v2, curve_index, orientation); + std::tie(p2_check, p3) = get_positions(v2, v3, curve_index, orientation); CGAL_assertion(p2_check == p2); - return boost::make_tuple(p1, p2, p3); + return std::make_tuple(p1, p2, p3); } @@ -1674,7 +1675,7 @@ smart_insert_point(const Bare_point& p, Weight w, int dim, const Index& index, Vertex_handle nearest_vh; FT sq_d; - boost::tie(nearest_vh, sq_d) = tr.nearest_power_vertex_with_sq_distance(p, ch); + std::tie(nearest_vh, sq_d) = tr.nearest_power_vertex_with_sq_distance(p, ch); CGAL_assertion(nearest_vh != Vertex_handle()); CGAL_assertion(tr.point(nearest_vh) != cwp(tr.canonicalize_point(p))); @@ -1710,7 +1711,7 @@ smart_insert_point(const Bare_point& p, Weight w, int dim, const Index& index, // Iterate ch = tr.locate(wp0, lt, li, lj, nearest_vh); - boost::tie(nearest_vh, sq_d) = tr.nearest_power_vertex_with_sq_distance(p, ch); + std::tie(nearest_vh, sq_d) = tr.nearest_power_vertex_with_sq_distance(p, ch); CGAL_assertion(nearest_vh != Vertex_handle()); } @@ -2000,7 +2001,7 @@ insert_balls(const Vertex_handle& vp, { // Get size of p & q Bare_point vpp, vqp; - boost::tie(vpp, vqp) = get_positions(vp, vq, curve_index, orientation); + std::tie(vpp, vqp) = get_positions(vp, vq, curve_index, orientation); const FT sp = get_radius(vp); const FT sq = get_radius(vq); @@ -2049,7 +2050,7 @@ insert_balls(const Vertex_handle& vp, CGAL_precondition(sp <= sq); Bare_point vpp, vqp; - boost::tie(vpp, vqp) = get_positions(vp, vq, curve_index, d_sign); + std::tie(vpp, vqp) = get_positions(vp, vq, curve_index, d_sign); #if ! defined(CGAL_NO_PRECONDITIONS) if(sp <= 0) @@ -2749,7 +2750,7 @@ is_sampling_dense_enough(const Vertex_handle& v1, const Vertex_handle& v2, curve_index == domain_.curve_index(v2->index())); Bare_point v1p, v2p; - boost::tie(v1p, v2p) = get_positions(v1, v2, curve_index, orientation); + std::tie(v1p, v2p) = get_positions(v1, v2, curve_index, orientation); FT arc_length = domain_.curve_segment_length(v1p, v2p, @@ -2816,7 +2817,7 @@ orientation_of_walk(const Vertex_handle& start, #endif Bare_point start_p, next_p; - boost::tie(start_p, next_p) = get_positions_with_unknown_orientation(start, next, curve_index); + std::tie(start_p, next_p) = get_positions_with_unknown_orientation(start, next, curve_index); #if CGAL_MESH_3_PROTECTION_DEBUG & 4 std::cerr << "positions to determine orientation: " << start_p << " " << next_p << std::endl; #endif @@ -3091,7 +3092,7 @@ is_sizing_field_correct(const Vertex_handle& v1, FT s3 = get_radius(v3); Bare_point p1, p2, p3; - boost::tie(p1, p2, p3) = get_positions(v1, v2, v3, curve_index, orientation); + std::tie(p1, p2, p3) = get_positions(v1, v2, v3, curve_index, orientation); FT D = domain_.curve_segment_length(p1, p3, curve_index, orientation); FT d = domain_.curve_segment_length(p1, p2, curve_index, orientation); diff --git a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_triangulation_3.h b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_triangulation_3.h index 254a7a26b11..8a4de97b43a 100644 --- a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_triangulation_3.h +++ b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_triangulation_3.h @@ -551,6 +551,24 @@ size_type number_of_stored_facets() const; /// `Periodic_triangle`, and `Periodic_tetrahedron`, which have inner type `Point`. /// @{ +/*! +Converts the `Periodic_point` `pp` (point-offset pair) to the +corresponding `Point` in \f$ \mathbb R^3\f$. +*/ +Point point(const Periodic_point& pp) const; + +/*! +Equivalent to +the call `t.point(t.periodic_point(v));` +*/ +Point point(Vertex_handle v) const; + +/*! +Equivalent to +the call `t.point(t.periodic_point(c,idx));` +*/ +Point point(Cell_handle c, int idx) const; + /*! Returns the periodic point given by vertex `v`. If `t` is represented in the 1-sheeted covering space, the offset is always diff --git a/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3.h b/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3.h index 5848af0a527..516c3e7434d 100644 --- a/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3.h +++ b/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3.h @@ -4414,7 +4414,7 @@ test_next(const Periodic_3_triangulation_3& t1, queue.push_back(std::make_pair(c1,c2)); while(! queue.empty()) { - boost::tie(c1,c2) = queue.back(); + std::tie(c1,c2) = queue.back(); queue.pop_back(); // Precondition: c1, c2 have been registered as well as their 4 vertices. diff --git a/Point_set_2/doc/Point_set_2/PackageDescription.txt b/Point_set_2/doc/Point_set_2/PackageDescription.txt index a191f6ff181..bf3a90fd689 100644 --- a/Point_set_2/doc/Point_set_2/PackageDescription.txt +++ b/Point_set_2/doc/Point_set_2/PackageDescription.txt @@ -10,7 +10,6 @@ /*! \addtogroup PkgPointSet2Ref -\todo check generated documentation \cgalPkgDescriptionBegin{2D Range and Neighbor Search,PkgPointSet2} \cgalPkgPicture{Point_set_2/fig/point_set.png} \cgalPkgSummaryBegin diff --git a/Point_set_3/examples/Point_set_3/point_set_property.cpp b/Point_set_3/examples/Point_set_3/point_set_property.cpp index 98a32e10fce..b34f01737d0 100644 --- a/Point_set_3/examples/Point_set_3/point_set_property.cpp +++ b/Point_set_3/examples/Point_set_3/point_set_property.cpp @@ -40,11 +40,11 @@ int main (int, char**) bool success = false; Color_map color; - boost::tie (color, success) = point_set.add_property_map ("color", black); + std::tie (color, success) = point_set.add_property_map ("color", black); assert (success); FT_map intensity; - boost::tie (intensity, success) = point_set.add_property_map ("intensity", 0.); + std::tie (intensity, success) = point_set.add_property_map ("intensity", 0.); assert (success); point_set.reserve (10); // For memory optimization 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 6fcffaee3d0..aa2de169bf2 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 @@ -219,86 +219,86 @@ bool write_LAS(std::ostream& os, Ushort_map intensity; bool remove_intensity; - boost::tie(intensity, remove_intensity) + std::tie(intensity, remove_intensity) = point_set.template add_property_map("intensity", 0); Uchar_map return_number; bool remove_return_number; - boost::tie(return_number, remove_return_number) + std::tie(return_number, remove_return_number) = point_set.template add_property_map("return_number", 0); Uchar_map number_of_returns; bool remove_number_of_returns; - boost::tie(number_of_returns, remove_number_of_returns) + std::tie(number_of_returns, remove_number_of_returns) = point_set.template add_property_map("number_of_returns", 0); Uchar_map scan_direction_flag; bool remove_scan_direction_flag; - boost::tie(scan_direction_flag, remove_scan_direction_flag) + std::tie(scan_direction_flag, remove_scan_direction_flag) = point_set.template add_property_map("scan_direction_flag", 0); Uchar_map edge_of_flight_line; bool remove_edge_of_flight_line; - boost::tie(edge_of_flight_line, remove_edge_of_flight_line) + std::tie(edge_of_flight_line, remove_edge_of_flight_line) = point_set.template add_property_map("edge_of_flight_line", 0); Uchar_map classification; bool remove_classification; - boost::tie(classification, remove_classification) + std::tie(classification, remove_classification) = point_set.template add_property_map("classification", 0); Uchar_map synthetic_flag; bool remove_synthetic_flag; - boost::tie(synthetic_flag, remove_synthetic_flag) + std::tie(synthetic_flag, remove_synthetic_flag) = point_set.template add_property_map("synthetic_flag", 0); Uchar_map keypoint_flag; bool remove_keypoint_flag; - boost::tie(keypoint_flag, remove_keypoint_flag) + std::tie(keypoint_flag, remove_keypoint_flag) = point_set.template add_property_map("keypoint_flag", 0); Uchar_map withheld_flag; bool remove_withheld_flag; - boost::tie(withheld_flag, remove_withheld_flag) + std::tie(withheld_flag, remove_withheld_flag) = point_set.template add_property_map("withheld_flag", 0); Float_map scan_angle; bool remove_scan_angle; - boost::tie(scan_angle, remove_scan_angle) + std::tie(scan_angle, remove_scan_angle) = point_set.template add_property_map("scan_angle", 0.); Uchar_map user_data; bool remove_user_data; - boost::tie(user_data, remove_user_data) + std::tie(user_data, remove_user_data) = point_set.template add_property_map("user_data", 0); Ushort_map point_source_ID; bool remove_point_source_ID; - boost::tie(point_source_ID, remove_point_source_ID) + std::tie(point_source_ID, remove_point_source_ID) = point_set.template add_property_map("point_source_ID", 0); Uint_map deleted_flag; bool remove_deleted_flag; - boost::tie(deleted_flag, remove_deleted_flag) + std::tie(deleted_flag, remove_deleted_flag) = point_set.template add_property_map("deleted_flag", 0); Double_map gps_time; bool remove_gps_time; - boost::tie(gps_time, remove_gps_time) + std::tie(gps_time, remove_gps_time) = point_set.template add_property_map("gps_time", 0); Ushort_map R; bool remove_R; - boost::tie(R, remove_R) = point_set.template add_property_map("R", 0); + std::tie(R, remove_R) = point_set.template add_property_map("R", 0); Ushort_map G; bool remove_G; - boost::tie(G, remove_G) = point_set.template add_property_map("G", 0); + std::tie(G, remove_G) = point_set.template add_property_map("G", 0); Ushort_map B; bool remove_B; - boost::tie(B, remove_B) = point_set.template add_property_map("B", 0); + std::tie(B, remove_B) = point_set.template add_property_map("B", 0); Ushort_map I; bool remove_I; - boost::tie(I, remove_I) = point_set.template add_property_map("I", 0); + std::tie(I, remove_I) = point_set.template add_property_map("I", 0); if(remove_R) { 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 f4658b4926b..5cad538b3ea 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 @@ -57,7 +57,7 @@ private: PLY_property_to_point_set_property(Point_set& ps, const std::string& name) : m_name(name) { - boost::tie(m_map, boost::tuples::ignore) = ps.add_property_map(name, Type()); + m_map = ps.add_property_map(name, Type()).first; m_pmap = ps.push_property_map(m_map); } diff --git a/Point_set_3/test/Point_set_3/point_set_test.cpp b/Point_set_3/test/Point_set_3/point_set_test.cpp index 086feabface..72563b63c54 100644 --- a/Point_set_3/test/Point_set_3/point_set_test.cpp +++ b/Point_set_3/test/Point_set_3/point_set_test.cpp @@ -103,7 +103,7 @@ int main (int, char**) test (!(point_set.has_property_map ("color")), "point set shouldn't have colors."); Point_set::Property_map color_prop; bool garbage; - boost::tie (color_prop, garbage) = point_set.add_property_map ("color", Color()); + std::tie (color_prop, garbage) = point_set.add_property_map ("color", Color()); test (point_set.has_property_map ("color"), "point set should have colors."); for (Point_set::iterator it = point_set.begin(); it != point_set.end(); ++ it) diff --git a/Point_set_3/test/Point_set_3/point_set_test_join.cpp b/Point_set_3/test/Point_set_3/point_set_test_join.cpp index 986f1748cf1..bcd39c531bb 100644 --- a/Point_set_3/test/Point_set_3/point_set_test_join.cpp +++ b/Point_set_3/test/Point_set_3/point_set_test_join.cpp @@ -72,7 +72,7 @@ int main (int, char**) Point_set::Property_map intensity; bool okay; - boost::tie (intensity, okay) = ps3.add_property_map("intensity", 0); + std::tie (intensity, okay) = ps3.add_property_map("intensity", 0); assert (okay); Point_set::iterator it = ps3.insert (Point (double(0), double(1), double(2)), diff --git a/Point_set_processing_3/include/CGAL/mst_orient_normals.h b/Point_set_processing_3/include/CGAL/mst_orient_normals.h index f9ce5352b26..5c5cd75063c 100644 --- a/Point_set_processing_3/include/CGAL/mst_orient_normals.h +++ b/Point_set_processing_3/include/CGAL/mst_orient_normals.h @@ -388,7 +388,7 @@ create_riemannian_graph( // Add edge typename boost::graph_traits::edge_descriptor e; bool inserted; - boost::tie(e, inserted) = add_edge(vertex(it_index, riemannian_graph), + std::tie(e, inserted) = add_edge(vertex(it_index, riemannian_graph), vertex(neighbor_index, riemannian_graph), riemannian_graph); CGAL_assertion(inserted); @@ -410,7 +410,7 @@ create_riemannian_graph( { typename boost::graph_traits::edge_descriptor e; bool inserted; - boost::tie(e, inserted) = add_edge(vertex(it_index, riemannian_graph), + std::tie(e, inserted) = add_edge(vertex(it_index, riemannian_graph), vertex(source_point_index, riemannian_graph), riemannian_graph); CGAL_assertion(inserted); diff --git a/Poisson_surface_reconstruction_3/include/CGAL/Poisson_reconstruction_function.h b/Poisson_surface_reconstruction_3/include/CGAL/Poisson_reconstruction_function.h index abe83515408..488e15b0b3a 100644 --- a/Poisson_surface_reconstruction_3/include/CGAL/Poisson_reconstruction_function.h +++ b/Poisson_surface_reconstruction_3/include/CGAL/Poisson_reconstruction_function.h @@ -598,24 +598,24 @@ public: } #endif - boost::tuple special_func(const Point& p) const + std::tuple special_func(const Point& p) const { Cell_handle& hint = get_hint(); hint = m_tr->locate(p, hint); if(m_tr->is_infinite(hint)) { int i = hint->index(m_tr->infinite_vertex()); - return boost::make_tuple(hint->vertex((i+1)&3)->f(), - hint, true); + return std::make_tuple(hint->vertex((i+1)&3)->f(), + hint, true); } FT a,b,c,d; barycentric_coordinates(p,hint,a,b,c,d); - return boost::make_tuple(a * hint->vertex(0)->f() + - b * hint->vertex(1)->f() + - c * hint->vertex(2)->f() + - d * hint->vertex(3)->f(), - hint, false); + return std::make_tuple(a * hint->vertex(0)->f() + + b * hint->vertex(1)->f() + + c * hint->vertex(2)->f() + + d * hint->vertex(3)->f(), + hint, false); } /// \endcond diff --git a/Poisson_surface_reconstruction_3/include/CGAL/Poisson_surface_reconstruction_3/internal/Poisson_sphere_oracle_3.h b/Poisson_surface_reconstruction_3/include/CGAL/Poisson_surface_reconstruction_3/internal/Poisson_sphere_oracle_3.h index fb0655be01c..36e56fe4d89 100644 --- a/Poisson_surface_reconstruction_3/include/CGAL/Poisson_surface_reconstruction_3/internal/Poisson_sphere_oracle_3.h +++ b/Poisson_surface_reconstruction_3/include/CGAL/Poisson_surface_reconstruction_3/internal/Poisson_sphere_oracle_3.h @@ -24,7 +24,7 @@ #include #include -#include +#include namespace CGAL { @@ -102,7 +102,7 @@ namespace CGAL { { const Self& oracle; - boost::tuple + std::tuple intersection_line_sphere_lambda(const Surface_3& sphere, const Point& a, const Point& b) const @@ -154,18 +154,18 @@ namespace CGAL { switch( CGAL::sign(deltaprime) ) { case ZERO: - return boost::make_tuple(1, ab_ac / ab2, 0); + return std::make_tuple(1, ab_ac / ab2, 0); case POSITIVE: { const FT sqrt_deltaprime = CGAL::sqrt(deltaprime); - return boost::make_tuple(2, - (ab_ac - sqrt_deltaprime) / ab2, - (ab_ac + sqrt_deltaprime) / ab2); + return std::make_tuple(2, + (ab_ac - sqrt_deltaprime) / ab2, + (ab_ac + sqrt_deltaprime) / ab2); } case NEGATIVE: break; } - return boost::make_tuple(0, 0, 0); + return std::make_tuple(0, 0, 0); } //end intersection_line_sphere_lambda template @@ -185,7 +185,7 @@ namespace CGAL { int number_of_roots; FT root_1, root_2; - boost::tie(number_of_roots, root_1, root_2) = + std::tie(number_of_roots, root_1, root_2) = intersection_line_sphere_lambda(sphere, a, b); const Vector ab = vector(a, b); @@ -291,7 +291,7 @@ namespace CGAL { int number_of_roots; FT root_1, root_2; - boost::tie(number_of_roots, root_1, root_2) = + std::tie(number_of_roots, root_1, root_2) = intersection_line_sphere_lambda(sphere, a, b); #ifdef CGAL_SURFACE_MESHER_DEBUG_IMPLICIT_ORACLE @@ -353,7 +353,7 @@ namespace CGAL { int number_of_roots; FT root_1, root_2; - boost::tie(number_of_roots, root_1, root_2) = + std::tie(number_of_roots, root_1, root_2) = intersection_line_sphere_lambda(sphere, a, b); if( number_of_roots == 2 && root_2 > FT(0) ) @@ -392,7 +392,7 @@ namespace CGAL { int number_of_roots; FT root_1, root_2; - boost::tie(number_of_roots, root_1, root_2) = + std::tie(number_of_roots, root_1, root_2) = intersection_line_sphere_lambda(sphere, a, b); if( number_of_roots == 2 ) diff --git a/Poisson_surface_reconstruction_3/include/CGAL/Surface_mesher/Poisson_implicit_surface_oracle_3.h b/Poisson_surface_reconstruction_3/include/CGAL/Surface_mesher/Poisson_implicit_surface_oracle_3.h index 7ebcbbe814e..0be13053ada 100644 --- a/Poisson_surface_reconstruction_3/include/CGAL/Surface_mesher/Poisson_implicit_surface_oracle_3.h +++ b/Poisson_surface_reconstruction_3/include/CGAL/Surface_mesher/Poisson_implicit_surface_oracle_3.h @@ -286,8 +286,8 @@ namespace CGAL { Cell_handle c1, c2; bool c1_is_inf, c2_is_inf; - boost::tie(value_at_p1, c1, c1_is_inf) = surface.function().special_func(p1); - boost::tie(value_at_p2, c2, c2_is_inf) = surface.function().special_func(p2); + std::tie(value_at_p1, c1, c1_is_inf) = surface.function().special_func(p1); + std::tie(value_at_p2, c2, c2_is_inf) = surface.function().special_func(p2); // If both extremities are in the same volume component, returns // no intersection. @@ -320,7 +320,7 @@ namespace CGAL { Cell_handle c_at_mid; FT value_at_mid; bool c_is_inf; - boost::tie(value_at_mid, c_at_mid, c_is_inf) = surface.function().special_func(mid); + std::tie(value_at_mid, c_at_mid, c_is_inf) = surface.function().special_func(mid); if ( squared_distance(p1, p2) < squared_distance_bound ) // If the two points are close, then we must decide diff --git a/Polygon/include/CGAL/Multipolygon_with_holes_2.h b/Polygon/include/CGAL/Multipolygon_with_holes_2.h index bdfd3cb47bc..9228850edf5 100644 --- a/Polygon/include/CGAL/Multipolygon_with_holes_2.h +++ b/Polygon/include/CGAL/Multipolygon_with_holes_2.h @@ -24,14 +24,14 @@ namespace CGAL { /*! \ingroup PkgPolygon2Ref * * The class `Multipolygon_with_holes_2` models the concept `MultipolygonWithHoles_2`. - * It is parameterized with two types (`Kernel` and `Container`) that are used to instantiate - * the types `Polygon_2` and `Polygon_with_holes_2`. + * It is parameterized with two types (`Kernel` and `Container_`) that are used to instantiate + * the types `Polygon_2` and `Polygon_with_holes_2`. * The latter is used to represent each polygon with holes. The former is converted to the latter. * * \cgalModels{MultipolygonWithHoles_2} */ template > + class Container_ = std::vector> class Multipolygon_with_holes_2 { public: /// \name Definition @@ -39,14 +39,15 @@ public: /// @{ /// polygon type - using Polygon_2 = CGAL::Polygon_2; + using Polygon_2 = CGAL::Polygon_2; /// polygon with holes type - using Polygon_with_holes_2 = CGAL::Polygon_with_holes_2; + using Polygon_with_holes_2 = CGAL::Polygon_with_holes_2; /// @} using Traits = Kernel; + using Container = Container_; using value_type = Polygon_with_holes_2; using Polygon_with_holes_container = std::deque; @@ -183,10 +184,10 @@ order. \relates Multipolygon_with_holes_2 */ -template +template std::ostream& operator<<(std::ostream& os, - const Multipolygon_with_holes_2& mp) { - typename Multipolygon_with_holes_2::Polygon_with_holes_const_iterator i; + const Multipolygon_with_holes_2& mp) { + typename Multipolygon_with_holes_2::Polygon_with_holes_const_iterator i; switch(IO::get_mode(os)) { case IO::ASCII : @@ -214,11 +215,11 @@ std::ostream& operator<<(std::ostream& os, } } -template -Multipolygon_with_holes_2 transform(const Transformation& t, - const Multipolygon_with_holes_2& mp) +template +Multipolygon_with_holes_2 transform(const Transformation& t, + const Multipolygon_with_holes_2& mp) { - Multipolygon_with_holes_2 result; + Multipolygon_with_holes_2 result; for(const auto& pwh : mp.polygons_with_holes()){ result.add_polygon_with_holes(transform(t, pwh)); } diff --git a/Polygon/include/CGAL/Polygon_2.h b/Polygon/include/CGAL/Polygon_2.h index c3300d939fa..cfe9b4f3472 100644 --- a/Polygon/include/CGAL/Polygon_2.h +++ b/Polygon/include/CGAL/Polygon_2.h @@ -60,8 +60,8 @@ namespace CGAL { /// algorithms were used and what complexity they have. /// -template > +template > class Polygon_2 { public: @@ -70,33 +70,33 @@ class Polygon_2 { /// @{ /// The traits type. - typedef Traits_P Traits; + typedef Traits_ Traits; /// The container type. - typedef Container_P Container; + typedef Container_ Container; /// The number type of the coordinates of the points of the polygon. - typedef typename Traits_P::FT FT; + typedef typename Traits_::FT FT; /// The point type of the polygon. - typedef typename Traits_P::Point_2 Point_2; + typedef typename Traits_::Point_2 Point_2; /// The type of a segment between two points of the polygon. - typedef typename Traits_P::Segment_2 Segment_2; + typedef typename Traits_::Segment_2 Segment_2; /// @} - typedef typename Container_P::difference_type difference_type; - typedef typename Container_P::value_type value_type; - typedef typename Container_P::pointer pointer; - typedef typename Container_P::reference reference; - typedef typename Container_P::const_reference const_reference; + typedef typename Container_::difference_type difference_type; + typedef typename Container_::value_type value_type; + typedef typename Container_::pointer pointer; + typedef typename Container_::reference reference; + typedef typename Container_::const_reference const_reference; //-------------------------------------------------------// // this intermediary step is required by Sun C++ 4.1 - typedef typename Container_P::iterator iterator; - typedef typename Container_P::const_iterator const_iterator; + typedef typename Container_::iterator iterator; + typedef typename Container_::const_iterator const_iterator; //-------------------------------------------------------// typedef typename Container::iterator Vertex_const_iterator; - typedef Polygon_circulator Vertex_const_circulator; + typedef Polygon_circulator Vertex_const_circulator; /// \name Iterators /// @@ -141,11 +141,11 @@ class Polygon_2 { // #else typedef Vertex_const_circulator Vertex_circulator; - typedef Polygon_2_edge_iterator Edge_const_iterator; - typedef Polygon_2_const_edge_circulator Edge_const_circulator; + typedef Polygon_2_edge_iterator Edge_const_iterator; + typedef Polygon_2_const_edge_circulator Edge_const_circulator; - typedef Polygon_2_edge_iterator Vertex_pair_iterator; typedef Iterator_range Edges; @@ -162,7 +162,7 @@ class Polygon_2 { Polygon_2(const Traits & p_traits) : traits(p_traits) {} // Move constructor - // Polygon_2(Polygon_2&& polygon) = default; + // Polygon_2(Polygon_2&& polygon) = default; /// Creates a polygon with vertices from the sequence /// defined by the range \c [first,last). @@ -260,7 +260,7 @@ class Polygon_2 { { if (size() <= 1) return; - typename Container_P::iterator i = d_container.begin(); + typename Container_::iterator i = d_container.begin(); std::reverse(++i, d_container.end()); } @@ -500,32 +500,32 @@ class Polygon_2 { { return d_container.empty(); } /// Returns a const reference to the sequence of vertices of the polygon. - const Container_P& container() const + const Container_& container() const { return d_container; } /// Returns a reference to the sequence of vertices of the polygon. - Container_P& container() + Container_& container() { return d_container; } /// Returns an iterator to the first vertex of the polygon. - typename Container_P::iterator begin() + typename Container_::iterator begin() { return container().begin(); } /// Returns an iterator to the element after the last vertex of the polygon. - typename Container_P::iterator end() + typename Container_::iterator end() { return container().end(); } /// Returns a const iterator to the first vertex of the polygon. - const typename Container_P::const_iterator begin() const + const typename Container_::const_iterator begin() const { return container().begin(); } /// Returns a const iterator to the element after the last vertex of the polygon. - const typename Container_P::const_iterator end() const + const typename Container_::const_iterator end() const { return container().end(); } @@ -544,14 +544,14 @@ class Polygon_2 { /// @} - bool identical(const Polygon_2 &q) const + bool identical(const Polygon_2 &q) const { return this == &q; } - Traits_P const &traits_member() const { return traits;} + Traits_ const &traits_member() const { return traits;} private: - Container_P d_container; - Traits_P traits; + Container_ d_container; + Traits_ traits; }; @@ -563,23 +563,23 @@ class Polygon_2 { /// equal to the vertices of `p1`. Note that the template argument /// `%Container` of `p1` and `p2` may be different. /// \memberof Polygon_2 -template -bool operator==( const Polygon_2 &p1, - const Polygon_2 &p2 ); +template +bool operator==( const Polygon_2 &p1, + const Polygon_2 &p2 ); /// Test for inequality. /// \memberof Polygon_2 -template +template inline bool -operator!=(const Polygon_2 &p1, - const Polygon_2 &p2); +operator!=(const Polygon_2 &p1, + const Polygon_2 &p2); /// Returns the image of the polygon \c p under the transformation \c t. /// \relates Polygon_2 -template -Polygon_2 -transform(const Transformation& t, const Polygon_2& p); +template +Polygon_2 +transform(const Transformation& t, const Polygon_2& p); /// @} // global operators @@ -591,14 +591,14 @@ transform(const Transformation& t, const Polygon_2& p); /// Reads a polygon from stream `is` and assigns it to `p`. /// \pre The extract operator must be defined for `Point_2`. /// \relates Polygon_2 -template -std::istream &operator>>(std::istream &is, Polygon_2& p); +template +std::istream &operator>>(std::istream &is, Polygon_2& p); /// Inserts the polygon `p` into the stream `os`. /// \pre The insert operator must be defined for `Point_2`. /// \relates Polygon_2 -template -std::ostream &operator<<(std::ostream &os, const Polygon_2& p); +template +std::ostream &operator<<(std::ostream &os, const Polygon_2& p); /// @} // IO @@ -612,11 +612,11 @@ std::ostream &operator<<(std::ostream &os, const Polygon_2 namespace CGAL { -template +template inline bool -operator!=(const Polygon_2 &x, - const Polygon_2 &y) +operator!=(const Polygon_2 &x, + const Polygon_2 &y) { return !(x==y); } diff --git a/Polygon/include/CGAL/Polygon_with_holes_2.h b/Polygon/include/CGAL/Polygon_with_holes_2.h index 032b2c52084..7d581a28150 100644 --- a/Polygon/include/CGAL/Polygon_with_holes_2.h +++ b/Polygon/include/CGAL/Polygon_with_holes_2.h @@ -29,21 +29,22 @@ namespace CGAL { The class `Polygon_with_holes_2` models the concept `GeneralPolygonWithHoles_2`. It represents a linear polygon with holes. It is parameterized with two -types (`Kernel` and `Container`) that are used to instantiate -the type `Polygon_2`. This poygon type is used to +types (`Kernel` and `Container_`) that are used to instantiate +the type `Polygon_2`. This polygon type is used to represent the outer boundary and the boundary of the holes (if any exist). \cgalModels{GeneralPolygonWithHoles_2} */ template > + class Container_ = std::vector > class Polygon_with_holes_2 : - public General_polygon_with_holes_2 > + public General_polygon_with_holes_2 > { public: - - typedef CGAL::Polygon_2 Polygon_2; + typedef Kernel Traits; + typedef Container_ Container; + typedef CGAL::Polygon_2 Polygon_2; typedef General_polygon_with_holes_2 Base; typedef typename Base::Hole_const_iterator Hole_const_iterator; typedef typename Base::Size Size; @@ -90,11 +91,11 @@ public: }; - template - Polygon_with_holes_2 transform(const Transformation& t, - const Polygon_with_holes_2& pwh) + template + Polygon_with_holes_2 transform(const Transformation& t, + const Polygon_with_holes_2& pwh) { - Polygon_with_holes_2 result(transform(t, pwh.outer_boundary())); + Polygon_with_holes_2 result(transform(t, pwh.outer_boundary())); for(const auto& hole : pwh.holes()){ result.add_hole(transform(t, hole)); } diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt index 6b74ce9696a..50f198e8317 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt @@ -25,7 +25,7 @@ /// \ingroup PkgPolygonMeshProcessingRef /// \defgroup PMP_measure_grp Geometric Measure Functions -/// Functions to compute lengths of edges and borders, areas of faces and patches, as well as volumes of closed meshes. +/// Functions to compute discrete curvatures, lengths of edges and borders, areas of faces and patches, volumes of closed meshes. /// \ingroup PkgPolygonMeshProcessingRef /// \defgroup PMP_orientation_grp Orientation Functions @@ -239,6 +239,11 @@ The page \ref bgl_namedparameters "Named Parameters" describes their usage. - `CGAL::Polygon_mesh_processing::sample_triangle_mesh()` \cgalCRPSection{Geometric Measure Functions} +- \link PMP_measure_grp `CGAL::Polygon_mesh_processing::angle_sum()` \endlink +- \link PMP_measure_grp `CGAL::Polygon_mesh_processing::discrete_Gaussian_curvatures()` \endlink +- \link PMP_measure_grp `CGAL::Polygon_mesh_processing::discrete_Gaussian_curvature()` \endlink +- \link PMP_measure_grp `CGAL::Polygon_mesh_processing::discrete_mean_curvature()` \endlink +- \link PMP_measure_grp `CGAL::Polygon_mesh_processing::discrete_mean_curvatures()` \endlink - \link PMP_measure_grp `CGAL::Polygon_mesh_processing::edge_length()` \endlink - \link PMP_measure_grp `CGAL::Polygon_mesh_processing::squared_edge_length()` \endlink - \link PMP_measure_grp `CGAL::Polygon_mesh_processing::face_area()` \endlink @@ -248,7 +253,6 @@ The page \ref bgl_namedparameters "Named Parameters" describes their usage. - \link PMP_measure_grp `CGAL::Polygon_mesh_processing::face_border_length()` \endlink - \link PMP_measure_grp `CGAL::Polygon_mesh_processing::longest_border()` \endlink - \link PMP_measure_grp `CGAL::Polygon_mesh_processing::centroid()` \endlink -- \link PMP_measure_grp `CGAL::Polygon_mesh_processing::match_faces()` \endlink \cgalCRPSection{Feature Detection Functions} - `CGAL::Polygon_mesh_processing::sharp_edges_segmentation()` 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 08d8d798f41..c4bf5a424fc 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 @@ -1225,6 +1225,17 @@ compute the curvatures on a specific vertex. \cgalExample{Polygon_mesh_processing/interpolated_corrected_curvatures_vertex.cpp} +\subsection DCurvartures Discrete Curvatures + +The package also provides methods to compute the standard, non-interpolated discrete mean and Gaussian +curvatures on triangle meshes, based on the work of Meyer et al. \cgalCite{cgal:mdsb-ddgot-02}. +These curvatures are computed at each vertex of the mesh, and are based on the angles of the incident +triangles. The functions are: +- `CGAL::Polygon_mesh_processing::discrete_mean_curvature()` +- `CGAL::Polygon_mesh_processing::discrete_mean_curvatures()` +- `CGAL::Polygon_mesh_processing::discrete_Gaussian_curvature()` +- `CGAL::Polygon_mesh_processing::discrete_Gaussian_curvatures()` + **************************************** \section PMPSlicer Slicer 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 ac8378781fe..e549dad832d 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 @@ -32,11 +32,11 @@ int main(int argc, char* argv[]) Mesh::Property_map mean_curvature_map, Gaussian_curvature_map; - boost::tie(mean_curvature_map, created) = + std::tie(mean_curvature_map, created) = smesh.add_property_map("v:mean_curvature_map", 0); assert(created); - boost::tie(Gaussian_curvature_map, created) = + std::tie(Gaussian_curvature_map, created) = smesh.add_property_map("v:Gaussian_curvature_map", 0); assert(created); @@ -44,7 +44,7 @@ int main(int argc, char* argv[]) Mesh::Property_map> principal_curvatures_and_directions_map; - boost::tie(principal_curvatures_and_directions_map, created) = + std::tie(principal_curvatures_and_directions_map, created) = smesh.add_property_map> ("v:principal_curvatures_and_directions_map", { 0, 0, Epic_kernel::Vector_3(0,0,0), diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/curvature.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/curvature.h new file mode 100644 index 00000000000..f612535dfc5 --- /dev/null +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/curvature.h @@ -0,0 +1,475 @@ +// 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) : Andreas Fabri, +// Mael Rouxel-Labbé + +#ifndef CGAL_PMP_CURVATURE_H +#define CGAL_PMP_CURVATURE_H + +#include + +#include +#include +#include +#include + +#include +#include + +namespace CGAL { +namespace Polygon_mesh_processing { + +/** + * \ingroup PMP_measure_grp + * + * computes the sum of the angles around a vertex. + * + * The angle sum is given in degrees. + * + * @tparam PolygonMesh a model of `FaceGraph` + * @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" + * + * @param v the vertex whose sum of angles is computed + * @param pmesh the polygon mesh to which `v` belongs + * @param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below + * + * \cgalNamedParamsBegin + * \cgalParamNBegin{vertex_point_map} + * \cgalParamDescription{a property map associating points to the vertices of `pmesh`} + * \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, pmesh)`} + * \cgalParamNEnd + * + * \cgalParamNBegin{geom_traits} + * \cgalParamDescription{an instance of a geometric traits class} + * \cgalParamType{The traits class must provide the nested functor `Compute_approximate_angle_3`, + * model of `Kernel::ComputeApproximateAngle_3`.} + * \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 + * \cgalNamedParamsEnd + * + * @return the sum of angles around `v`. The return type `FT` is a number type either deduced + * from the `geom_traits` \ref bgl_namedparameters "Named Parameters" if provided, + * or the geometric traits class deduced from the point property map of `pmesh`. + * + * \warning This function involves trigonometry. + */ +template +#ifdef DOXYGEN_RUNNING +FT +#else +typename GetGeomTraits::type::FT +#endif +angle_sum(typename boost::graph_traits::vertex_descriptor v, + const PolygonMesh& pmesh, + const CGAL_NP_CLASS& np = parameters::default_values()) +{ + using parameters::choose_parameter; + using parameters::get_parameter; + + using Geom_traits = typename GetGeomTraits::type; + using FT = typename Geom_traits::FT; + + typename GetVertexPointMap::const_type + vpm = choose_parameter(get_parameter(np, internal_np::vertex_point), + get_const_property_map(CGAL::vertex_point, pmesh)); + + Geom_traits gt = choose_parameter(get_parameter(np, internal_np::geom_traits)); + + CGAL_precondition(is_valid_vertex_descriptor(v, pmesh)); + + typename Geom_traits::Compute_approximate_angle_3 approx_angle = gt.compute_approximate_angle_3_object(); + + FT angle_sum = 0; + for(auto h : halfedges_around_source(v, pmesh)) + { + if(is_border(h, pmesh)) + continue; + + angle_sum += approx_angle(get(vpm, target(h, pmesh)), + get(vpm, source(h, pmesh)), + get(vpm, source(prev(h,pmesh), pmesh))); + } + + return angle_sum; +} + +// Discrete Gaussian Curvature + +/** + * \ingroup PMP_measure_grp + * + * computes the discrete Gaussian curvature at a vertex. + * + * We refer to Meyer et al. \cgalCite{cgal:mdsb-ddgot-02} for the definition of discrete Gaussian curvature. + * + * @tparam TriangleMesh a model of `FaceGraph` + * @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" + * + * @param v the vertex whose discrete Gaussian curvature is being computed + * @param tmesh the triangle mesh to which `v` belongs + * @param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below + * + * \cgalNamedParamsBegin + * \cgalParamNBegin{vertex_point_map} + * \cgalParamDescription{a property map associating points to the vertices of `tmesh`} + * \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, tmesh)`} + * \cgalParamNEnd + * + * \cgalParamNBegin{geom_traits} + * \cgalParamDescription{an instance of a geometric traits class} + * \cgalParamType{The traits class must be a 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 vertex point type.} + * \cgalParamNEnd + * \cgalNamedParamsEnd + * + * @return the discrete Gaussian curvature at `v`. The return type `FT` is a number type either deduced + * from the `geom_traits` \ref bgl_namedparameters "Named Parameters" if provided, + * or the geometric traits class deduced from the point property map of `tmesh`. + * + * \warning This function involves trigonometry. + * \warning The current formulation is not well defined for border vertices. + * + * \pre `tmesh` is a triangle mesh + */ +template +#ifdef DOXYGEN_RUNNING +FT +#else +typename GetGeomTraits::type::FT +#endif +discrete_Gaussian_curvature(typename boost::graph_traits::vertex_descriptor v, + const TriangleMesh& tmesh, + const CGAL_NP_CLASS& np = parameters::default_values()) +{ + using parameters::choose_parameter; + using parameters::get_parameter; + + using GeomTraits = typename GetGeomTraits::type; + using FT = typename GeomTraits::FT; + using Vector_3 = typename GeomTraits::Vector_3; + + using VertexPointMap = typename GetVertexPointMap::const_type; + using halfedge_descriptor = typename boost::graph_traits::halfedge_descriptor; + + GeomTraits gt = choose_parameter(get_parameter(np, internal_np::geom_traits)); + VertexPointMap vpm = choose_parameter(get_parameter(np, internal_np::vertex_point), + get_const_property_map(vertex_point, tmesh)); + + typename GeomTraits::Construct_vector_3 vector = + gt.construct_vector_3_object(); + typename GeomTraits::Construct_cross_product_vector_3 cross_product = + gt.construct_cross_product_vector_3_object(); + typename GeomTraits::Compute_scalar_product_3 scalar_product = + gt.compute_scalar_product_3_object(); + typename GeomTraits::Compute_squared_length_3 squared_length = + gt.compute_squared_length_3_object(); + + FT angle_sum = 0; + + for(halfedge_descriptor h : CGAL::halfedges_around_target(v, tmesh)) + { + if(is_border(h, tmesh)) + continue; + + const Vector_3 v0 = vector(get(vpm, v), get(vpm, target(next(h, tmesh), tmesh))); // p1p2 + const Vector_3 v1 = vector(get(vpm, v), get(vpm, source(h, tmesh))); // p1p0 + + const FT dot = scalar_product(v0, v1); + const Vector_3 cross = cross_product(v0, v1); + const FT sqcn = squared_length(cross); + if(is_zero(dot)) + { + angle_sum += CGAL_PI/FT(2); + } + else + { + if(is_zero(sqcn)) // collinear + { + if(dot < 0) + angle_sum += CGAL_PI; + // else + // angle_sum += 0; + } + else + { + angle_sum += std::atan2(CGAL::approximate_sqrt(sqcn), dot); + } + } + } + + Weights::Secure_cotangent_weight_with_voronoi_area wc(tmesh, vpm, gt); + + const FT gaussian_curvature = (2 * CGAL_PI - angle_sum) / wc.voronoi(v); + + return gaussian_curvature; +} + +/** + * \ingroup PMP_measure_grp + * + * computes the discrete Gaussian curvatures at the vertices of a mesh. + * + * We refer to Meyer et al. \cgalCite{cgal:mdsb-ddgot-02} for the definition of discrete Gaussian curvature. + * + * @tparam TriangleMesh a model of `FaceGraph` + * @tparam VertexCurvatureMap must be a model of `WritablePropertyMap` with key type + * `boost::graph_traits::%vertex_descriptor` and value type `FT`, + * which is either `geom_traits::FT` if this named parameter is provided, + * or `kernel::FT` with the kernel deduced from from the point property map of `tmesh`. + * @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" + * + * @param tmesh the triangle mesh to which `v` belongs + * @param vcm the property map that contains the computed discrete curvatures + * @param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below + * + * \cgalNamedParamsBegin + * \cgalParamNBegin{vertex_point_map} + * \cgalParamDescription{a property map associating points to the vertices of `tmesh`} + * \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, tmesh)`} + * \cgalParamNEnd + * + * \cgalParamNBegin{geom_traits} + * \cgalParamDescription{an instance of a geometric traits class} + * \cgalParamType{The traits class must be a 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 vertex point type.} + * \cgalParamNEnd + * \cgalNamedParamsEnd + * + * \warning This function involves trigonometry. + * \warning The current formulation is not well defined for border vertices. + * + * \pre `tmesh` is a triangle mesh + */ +template +void discrete_Gaussian_curvatures(const TriangleMesh& tmesh, + VertexCurvatureMap vcm, + const CGAL_NP_CLASS& np = parameters::default_values()) +{ + using vertex_descriptor = typename boost::graph_traits::vertex_descriptor; + + for(vertex_descriptor v : vertices(tmesh)) + { + put(vcm, v, discrete_Gaussian_curvature(v, tmesh, np)); + // std::cout << "curvature: " << get(vcm, v) << std::endl; + } +} + +// Discrete Mean Curvature + +/** + * \ingroup PMP_measure_grp + * + * computes the discrete mean curvature at a vertex. + * + * We refer to Meyer et al. \cgalCite{cgal:mdsb-ddgot-02} for the definition of discrete mean curvature. + * + * @tparam TriangleMesh a model of `FaceGraph` + * @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" + * + * @param v the vertex whose discrete mean curvature is being computed + * @param tmesh the triangle mesh to which `v` belongs + * @param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below + * + * \cgalNamedParamsBegin + * \cgalParamNBegin{vertex_point_map} + * \cgalParamDescription{a property map associating points to the vertices of `tmesh`} + * \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, tmesh)`} + * \cgalParamNEnd + * + * \cgalParamNBegin{geom_traits} + * \cgalParamDescription{an instance of a geometric traits class} + * \cgalParamType{The traits class must be a 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 vertex point type.} + * \cgalParamNEnd + * \cgalNamedParamsEnd + * + * @return the discrete mean curvature at `v`. The return type `FT` is a number type either deduced + * from the `geom_traits` \ref bgl_namedparameters "Named Parameters" if provided, + * or the geometric traits class deduced from the point property map of `tmesh`. + * + * \warning The current formulation is not well defined for border vertices. + * + * \pre `tmesh` is a triangle mesh + */ +template +#ifdef DOXYGEN_RUNNING +FT +#else +typename GetGeomTraits::type::FT +#endif +discrete_mean_curvature(typename boost::graph_traits::vertex_descriptor v, + const TriangleMesh& tmesh, + const CGAL_NP_CLASS& np = parameters::default_values()) +{ + using parameters::choose_parameter; + using parameters::get_parameter; + + using GeomTraits = typename GetGeomTraits::type; + using FT = typename GeomTraits::FT; + using Vector_3 = typename GeomTraits::Vector_3; + + using VertexPointMap = typename GetVertexPointMap::const_type; + using Point_ref = typename boost::property_traits::reference; + + using vertex_descriptor = typename boost::graph_traits::vertex_descriptor; + using halfedge_descriptor = typename boost::graph_traits::halfedge_descriptor; + + GeomTraits gt = choose_parameter(get_parameter(np, internal_np::geom_traits)); + VertexPointMap vpm = choose_parameter(get_parameter(np, internal_np::vertex_point), + get_const_property_map(vertex_point, tmesh)); + +#if 0 + typename GeomTraits::Compute_squared_distance_3 squared_distance = + gt.compute_squared_distance_3_object(); + typename GeomTraits::Compute_approximate_dihedral_angle_3 dihedral_angle = + gt.compute_approximate_dihedral_angle_3_object(); + + const FT two_pi = 2 * CGAL_PI; + + FT hi = 0; + for(halfedge_descriptor h : CGAL::halfedges_around_target(v, tmesh)) + { + const Point_3& p = get(vpm, source(h, tmesh)); + const Point_3& q = get(vpm, target(h, tmesh)); + const Point_3& r = get(vpm, target(next(h, tmesh), tmesh)); + const Point_3& s = get(vpm, target(next(opposite(h, tmesh), tmesh), tmesh)); + const FT l = squared_distance(p,q); + + FT phi = CGAL_PI * dihedral_angle(p, q, r, s) / FT(180); + + if(phi < 0) + phi += two_pi; + if(phi > two_pi) + phi = two_pi; + + hi += FT(0.5) * l * (CGAL_PI - phi); + } + + return FT(0.5) * hi; +#else + typename GeomTraits::Construct_vector_3 vector = + gt.construct_vector_3_object(); + typename GeomTraits::Construct_sum_of_vectors_3 vector_sum = + gt.construct_sum_of_vectors_3_object(); + typename GeomTraits::Construct_scaled_vector_3 scaled_vector = + gt.construct_scaled_vector_3_object(); + typename GeomTraits::Compute_squared_length_3 squared_length = + gt.compute_squared_length_3_object(); + + Weights::Secure_cotangent_weight_with_voronoi_area wc(tmesh, vpm, gt); + + Vector_3 kh = vector(CGAL::NULL_VECTOR); + for(halfedge_descriptor h : CGAL::halfedges_around_target(v, tmesh)) + { + const vertex_descriptor v1 = source(h, tmesh); + + const Point_ref p0 = get(vpm, v); + const Point_ref p1 = get(vpm, v1); + + FT local_c = 0; + if(!is_border(h, tmesh)) + { + const vertex_descriptor v2 = target(next(h, tmesh), tmesh); + const Point_ref p2 = get(vpm, v2); + local_c += Weights::cotangent_3_clamped(p0, p2, p1, gt); + } + + if(!is_border(opposite(h, tmesh), tmesh)) + { + const vertex_descriptor v3 = target(next(opposite(h, tmesh), tmesh), tmesh); + const Point_ref p3 = get(vpm, v3); + local_c += Weights::cotangent_3_clamped(p1, p3, p0, gt); + } + + kh = vector_sum(kh, scaled_vector(vector(p0, p1), local_c)); + } + + const FT khn = CGAL::approximate_sqrt(squared_length(kh)); + const FT va = wc.voronoi(v); + CGAL_assertion(!is_zero(va)); + + const FT mean_curvature = khn / (FT(4) * va); + return mean_curvature; +#endif +} + +/** + * \ingroup PMP_measure_grp + * + * computes the discrete mean curvatures at the vertices of a mesh. + * + * We refer to Meyer et al. \cgalCite{cgal:mdsb-ddgot-02} for the definition of discrete mean curvature. + * + * @tparam TriangleMesh a model of `FaceGraph` + * @tparam VertexCurvatureMap must be a model of `WritablePropertyMap` with key type + * `boost::graph_traits::%vertex_descriptor` and value type `FT`, + * which is either `geom_traits::FT` if this named parameter is provided, + * or `kernel::FT` with the kernel deduced from from the point property map of `tmesh`. + * @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" + * + * @param tmesh the triangle mesh to which `v` belongs + * @param vcm the property map that contains the computed discrete curvatures + * @param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below + * + * \cgalNamedParamsBegin + * \cgalParamNBegin{vertex_point_map} + * \cgalParamDescription{a property map associating points to the vertices of `tmesh`} + * \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, tmesh)`} + * \cgalParamNEnd + * + * \cgalParamNBegin{geom_traits} + * \cgalParamDescription{an instance of a geometric traits class} + * \cgalParamType{The traits class must be a 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 vertex point type.} + * \cgalParamNEnd + * \cgalNamedParamsEnd + * + * \warning The current formulation is not well defined for border vertices. + * + * \pre `tmesh` is a triangle mesh + */ +template +void discrete_mean_curvatures(const TriangleMesh& tmesh, + VertexCurvatureMap vcm, + const CGAL_NP_CLASS& np = parameters::default_values()) +{ + using vertex_descriptor = typename boost::graph_traits::vertex_descriptor; + + for(vertex_descriptor v : vertices(tmesh)) + put(vcm, v, discrete_mean_curvature(v, tmesh, np)); +} + +} // namespace Polygon_mesh_processing +} // namespace CGAL + +#endif //CGAL_PMP_CURVATURE_H diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h index 925303c6f32..60e20772372 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h @@ -2515,7 +2515,7 @@ public: typedef std::pair Hedge_pair; std::vector< Hedge_pair> hedges_to_link; typename CGAL::Halfedge_around_target_iterator hit, end; - boost::tie(hit,end) = halfedges_around_target(vd, tm1); + std::tie(hit,end) = halfedges_around_target(vd, tm1); for(; hit!=end; ++hit) { // look for a border halfedge incident to the non-manifold vertex that will not be diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Snapping/helper.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Snapping/helper.h index 20e95e59610..38053bee8fe 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Snapping/helper.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Snapping/helper.h @@ -67,7 +67,7 @@ void assign_tolerance_with_local_edge_length_bound(const HalfedgeRange& halfedge { const vertex_descriptor vd = target(hd, mesh); CGAL::Halfedge_around_target_iterator hit, hend; - boost::tie(hit, hend) = CGAL::halfedges_around_target(vd, mesh); + std::tie(hit, hend) = CGAL::halfedges_around_target(vd, mesh); CGAL_assertion(hit != hend); FT sq_length = gt.compute_squared_distance_3_object()(get(vpm, source(*hit, mesh)), 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 c8653c0196d..e21e0a4a0ed 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/locate.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -1450,7 +1451,7 @@ void build_AABB_tree(const TriangleMesh& tm, >::value>* = 0) { typename boost::graph_traits::face_iterator ffirst, fbeyond; - boost::tie(ffirst, fbeyond) = faces(tm); + std::tie(ffirst, fbeyond) = faces(tm); outTree.rebuild(ffirst, fbeyond, tm, wrapped_vpm); outTree.build(); } diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt b/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt index 12cb26ca381..1e442ae768f 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt @@ -28,6 +28,7 @@ create_single_source_cgal_program("test_stitching.cpp") create_single_source_cgal_program("remeshing_test.cpp") create_single_source_cgal_program("remeshing_with_isolated_constraints_test.cpp" ) create_single_source_cgal_program("measures_test.cpp") +create_single_source_cgal_program("test_discrete_curvatures.cpp") create_single_source_cgal_program("triangulate_faces_test.cpp") create_single_source_cgal_program("triangulate_faces_hole_filling_dt3_test.cpp") create_single_source_cgal_program("triangulate_faces_hole_filling_all_search_test.cpp") diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_discrete_curvatures.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_discrete_curvatures.cpp new file mode 100644 index 00000000000..d37bf7471ad --- /dev/null +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_discrete_curvatures.cpp @@ -0,0 +1,146 @@ +#include +#include +#include + +#include + +#include + +#include +#include + +#define ABS_ERROR 1e-6 + +namespace PMP = CGAL::Polygon_mesh_processing; + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef K::FT FT; +typedef CGAL::Surface_mesh SMesh; +typedef CGAL::Polyhedron_3 Polyhedron; + +struct Average_test_info +{ + FT mean_curvature_avg; + FT gaussian_curvature_avg; + FT tolerance = 0.9; + + Average_test_info(FT mean_curvature_avg, + FT gaussian_curvature_avg) + : mean_curvature_avg(mean_curvature_avg), + gaussian_curvature_avg(gaussian_curvature_avg) + { } +}; + +bool passes_comparison(FT result, FT expected, FT tolerance) +{ + std::cout << "result: " << result << std::endl; + std::cout << "expected: " << expected << std::endl; + + if(abs(expected) < ABS_ERROR && abs(result) < ABS_ERROR) + return true; // expected 0, got 0 + else if (abs(expected) < ABS_ERROR) + return false; // expected 0, got non-0 + + return (std::min)(result, expected) / (std::max)(result, expected) > tolerance; +} + +template +void test_curvatures(std::string mesh_path, + Average_test_info test_info) +{ + std::cout << "test discrete curvatures of " << mesh_path << std::endl; + std::cout << "mesh type: " << typeid(mesh_path).name() << std::endl; + + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + + TriangleMesh tmesh; + const std::string filename = CGAL::data_file_path(mesh_path); + + if(!CGAL::IO::read_polygon_mesh(filename, tmesh) || faces(tmesh).size() == 0) + { + std::cerr << "Invalid input file." << std::endl; + std::exit(1); + } + + typename boost::property_map>::type + mean_curvature_map = get(CGAL::dynamic_vertex_property_t(), tmesh), + gaussian_curvature_map = get(CGAL::dynamic_vertex_property_t(), tmesh); + + PMP::discrete_mean_curvatures(tmesh, mean_curvature_map); + PMP::discrete_Gaussian_curvatures(tmesh, gaussian_curvature_map); + + FT mean_curvature_avg = 0, gaussian_curvature_avg = 0; + for(vertex_descriptor v : vertices(tmesh)) + { + mean_curvature_avg += get(mean_curvature_map, v); + gaussian_curvature_avg += get(gaussian_curvature_map, v); + } + + mean_curvature_avg /= vertices(tmesh).size(); + gaussian_curvature_avg /= vertices(tmesh).size(); + + std::cout << "checking mean curvature..." << std::endl; + assert(passes_comparison(mean_curvature_avg, test_info.mean_curvature_avg, test_info.tolerance)); + + std::cout << "checking Gaussian curvature..." << std::endl; + assert(passes_comparison(gaussian_curvature_avg, test_info.gaussian_curvature_avg, test_info.tolerance)); +} + +template +void test_angle_sums(const std::string mesh_path, + const std::vector& expected_values) +{ + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + + PolygonMesh pmesh; + const std::string filename = CGAL::data_file_path(mesh_path); + + if(!CGAL::IO::read_polygon_mesh(filename, pmesh) || faces(pmesh).size() == 0) + { + std::cerr << "Invalid input file." << std::endl; + std::exit(1); + } + + std::size_t pos = 0; + for(vertex_descriptor v : vertices(pmesh)) + { + FT angle_sum = PMP::angle_sum(v, pmesh, + CGAL::parameters::geom_traits(K()) + .vertex_point_map(get(CGAL::vertex_point, pmesh))); + assert(passes_comparison(angle_sum, expected_values[pos++], 0.9)); + } +} + +int main(int, char**) +{ + // testing on a simple sphere(r = 0.5), on both Polyhedron & SurfaceMesh: + // Expected: Mean Curvature = 2, Gaussian Curvature = 4 + test_curvatures("meshes/sphere.off", Average_test_info(2, 4)); + test_curvatures("meshes/sphere.off", Average_test_info(2, 4)); + + // testing on a simple sphere(r = 10), on both Polyhedron & SurfaceMesh: + // Expected: Mean Curvature = 0.1, Gaussian Curvature = 0.01 + test_curvatures("meshes/sphere966.off", Average_test_info(0.1, 0.01)); + test_curvatures("meshes/sphere966.off", Average_test_info(0.1, 0.01)); + + // testing on a simple half cylinder(r = 1), on both Polyhedron & SurfaceMesh: + // Expected: Mean Curvature = 0.5, Gaussian Curvature = 0 + // To be tested once the discrete curvatures are well defined for boundary vertices + // test_curvatures("meshes/cylinder.off", Average_test_info(0.5, 0)); + // test_curvatures("meshes/cylinder.off", Average_test_info(0.5, 0)); + + test_angle_sums("meshes/quad.off", std::vector(4, 90)); + test_angle_sums("meshes/quad.off", std::vector(4, 90)); + + test_angle_sums("meshes/regular_tetrahedron.off", std::vector(4, 180)); + test_angle_sums("meshes/regular_tetrahedron.off", std::vector(4, 180)); + + test_angle_sums("meshes/cube_quad.off", std::vector(8, 270)); + test_angle_sums("meshes/cube_quad.off", std::vector(8, 270)); + + test_angle_sums("meshes/cube_poly.off", std::vector(8, 270)); + test_angle_sums("meshes/cube_poly.off", std::vector(8, 270)); + + std::cout << "Done." << std::endl; + return EXIT_SUCCESS; +} diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_interpolated_corrected_curvatures.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_interpolated_corrected_curvatures.cpp index 412443a42c7..a15258b0fc9 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_interpolated_corrected_curvatures.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_interpolated_corrected_curvatures.cpp @@ -9,8 +9,9 @@ #include +#include #include -#include +#include #define ABS_ERROR 1e-6 @@ -181,7 +182,7 @@ void test_average_curvatures(std::string mesh_path, int main() { // testing on a simple sphere(r = 0.5), on both Polyhedron & SurfaceMesh: - // For this mesh, ina addition to the whole mesh functions, we also compare against the single vertex + // For this mesh, in addition to the whole mesh functions, we also compare against the single vertex // curvature functions to make sure the produce the same results // Expected: Mean Curvature = 2, Gaussian Curvature = 4, Principal Curvatures = 2 & 2 so 2 on avg. test_average_curvatures("meshes/sphere.off", Average_test_info(2, 4, 2), true); diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp index b2250c03641..e33c34e45cb 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_locate.cpp @@ -378,7 +378,7 @@ void test_predicates(const G& g, CGAL::Random& rnd) // --------------------------------------------------------------------------- int max = 1000, counter = 0; typename boost::graph_traits::halfedge_iterator hit, hend; - boost::tie(hit, hend) = halfedges(g); + std::tie(hit, hend) = halfedges(g); for(; hit!=hend; ++hit) { const halfedge_descriptor h = *hit; diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_shape_predicates.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_shape_predicates.cpp index 17228d4603f..716a5a81654 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_shape_predicates.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_shape_predicates.cpp @@ -78,7 +78,7 @@ void test_needles_and_caps(const std::string fname) const FT eps = std::numeric_limits::epsilon(); face_iterator fit, fend; - boost::tie(fit, fend) = faces(mesh); + std::tie(fit, fend) = faces(mesh); // (0 0 0) -- (1 0 0) -- (1 1 0) (90° cap angle) face_descriptor f = *fit; diff --git a/Polygon_repair/doc/Polygon_repair/PackageDescription.txt b/Polygon_repair/doc/Polygon_repair/PackageDescription.txt index 0bd41658ad4..3a311dd0cd1 100644 --- a/Polygon_repair/doc/Polygon_repair/PackageDescription.txt +++ b/Polygon_repair/doc/Polygon_repair/PackageDescription.txt @@ -1,10 +1,11 @@ -// PRETTY PACKAGE NAME should equal the project title in Doxyfile.in - /// \defgroup PkgPolygonRepairRef 2D Polygon Repair Reference /// \defgroup PkgPolygonRepairFunctions Functions /// \ingroup PkgPolygonRepairRef +/// \defgroup PkgPolygonRepairRules Repair Rules +/// \ingroup PkgPolygonRepairRef + /*! \addtogroup PkgPolygonRepairRef @@ -15,7 +16,8 @@ \cgalPkgAuthors{Ken Arroyo Ohori} \cgalPkgDesc{This package provides algorithms to repair 2D polygons, polygons with holes, and multipolygons with holes, by selecting faces of the arrangement of the input based on a selection rule. -Currently, only the even-odd rule is provided. } +The even-odd rule and the non-zero rule are provided for dealing with self intersections. +The %union and the %intersection rule enable to combine similar polygons. } \cgalPkgManuals{Chapter_2D_Polygon_repair,PkgPolygonRepairRef} \cgalPkgSummaryEnd @@ -32,7 +34,12 @@ Currently, only the even-odd rule is provided. } \cgalCRPSection{Functions} - `CGAL::Polygon_repair::repair()` +- `CGAL::Polygon_repair::join()` +- `CGAL::Polygon_repair::intersect()` -\cgalCRPSection{Simplification Rules} +\cgalCRPSection{Repair Rules} - `CGAL::Polygon_repair::Even_odd_rule` +- `CGAL::Polygon_repair::Non_zero_rule` +- `CGAL::Polygon_repair::Union_rule` +- `CGAL::Polygon_repair::Intersection_rule` */ diff --git a/Polygon_repair/doc/Polygon_repair/Polygon_repair.txt b/Polygon_repair/doc/Polygon_repair/Polygon_repair.txt index 26b6f6d62c7..f837f18e9eb 100644 --- a/Polygon_repair/doc/Polygon_repair/Polygon_repair.txt +++ b/Polygon_repair/doc/Polygon_repair/Polygon_repair.txt @@ -9,20 +9,25 @@ namespace CGAL { \section SectionPolygonRepair_Introduction Introduction -This package implements a polygon repair method. Starting from possibly +This package implements polygon repair methods. Starting from possibly invalid input in the form of a polygon, polygon with holes or multipolygon with holes, the method computes an arrangement of the input edges, labels each face according to what it represents (exterior, polygon interior or hole), and reconstructs the polygon(s) represented by the arrangement. The method returns valid output stored in a multipolygon with holes. -Different arrangement and labelling heuristics are possible, but -currently only the even-odd rule is implemented in this package. -This rule results in areas that are alternately assigned as polygon +Different labeling heuristics are possible. This package offers +the even-odd rule, the non-zero rule, the union rule, +as well as the intersection rule. +The even-odd rule results in areas that are alternately assigned as polygon interiors and exterior/holes each time that an input edge is passed. It does not distinguish between edges that are part of outer boundaries -from those of inner boundaries. In a next version we will add the -winding number rule. +from those of inner boundaries. +The non-zero rule results in areas with a non-zero winding number. +The union and intersection rules are useful when given +two or more similar valid polygons with holes. +The union rule results in areas that are contained in at least one of the input polygons with holes. +Similarly, the intersection rule results in areas that are contained in all input polygons with holes. \section SectionPolygonRepair_Definitions Definitions @@ -63,7 +68,51 @@ Invalid: (a) self-intersecting polygon self-intersection, (b) self-touching poly with overlapping polygons, and (h) multipolygon with polygons that touch at an edge. \cgalFigureEnd -\subsection SubsectionPolygonRepair_Output Stricter Conditions for Output + +\section SectionPolygonRepair_EvenOdd Even-Odd and Non-Zero Rule + +While the even-odd rule switches between inside/outside at each edge only taking +into account multiplicity, the non-zero rule takes also into account +the orientation of the edge. + +For some configurations this leads to different results, as can be seen in the figure below. + +\cgalFigureBegin{WindingNonZeroDifferent, WindingNonZeroDifferent.svg} +Input (left), non-zero (middle) even-odd (right). +\cgalFigureEnd + +And there are other configurations where the two rules lead to the same result. + +\cgalFigureBegin{WindingNonZero, WindingNonZero.svg} +Input (left), non-zero and even-odd (right). +\cgalFigureEnd + +A valid polygon with holes, obviously has the same result with both rules applied +as it is just the identity. However an invalid multipolygon with one polygon +enclosing the other one results in the union of the two, that is the enclosing one +for the non-zero rule, while it results in a polygon with hole for the even-odd rule. + +\cgalFigureBegin{MultipolygonHole, MultipolygonHole.svg} +Input (left), non-zero (middle) even-odd (right). +\cgalFigureEnd + +\section SectionPolygonRepair_UnionIntersection Union and Intersection Rule + +Given several valid polygons these rules apply a %Boolean operation: +In the arrangement of two valid multipolygons with holes, the faces that are in any and both multipolygons +with holes are in the resulting multipolygon with holes for a union and intersection, respectively. + +While this %Boolean operation works for any two valid multipolygons, in the scope of repairing +it serves to obtain an approximation from outside and inside when applying union and intersection, respectively, +when the input is similar. + +\cgalFigureBegin{UnionIntersection, UnionIntersection.svg} +Union (top) and Intersection (bottom). +\cgalFigureEnd + + + +\section SubsectionPolygonRepair_Output Notes on the Output The conditions listed above are sufficient to define valid polygons, polygons with holes and multipolygons with holes for most applications. However, in @@ -81,64 +130,10 @@ order - The polygons with holes of a multipolygon with holes are also stored in lexicographic order -\section SectionPolygonRepair_Algorithm Algorithm - -Broadly, the algorithm consists of three steps: - --# Arrangement: the edges in the polygon, polygon with -holes or multipolygon with holes are added as edges in the arrangement. --# Labeling of the faces: the resulting faces are labeled with ids -according to what they represent (exterior, polygon interior or hole). --# Reconstruction of the multipolygon: each boundary is reconstructed, -then these are assembled into individual polygons with holes and put into a -single multipolygon with holes. - -\cgalFigureBegin{inout, inout.svg} -Examples of polygons with holes (a-d) and multipolygons with holes -(e-h) before (left) and after (right) being repaired. -\cgalFigureEnd - -\subsection SubsectionPolygonRepair_Arrangement Arrangement - -For the purposes of the repair operation, the input polygon, polygon with holes -or multipolygon is merely used as a container of input line segments. These line -segments are added to the arrangement as edges. Internally, this is done using -a constrained triangulation where they are added as constraints. - -With the even-odd rule, only the edges that are present an odd number of -times in the input will be edges in the final arrangement. -When these edges are only partially overlapping, only the parts that overlap -an odd number of times will be edges in the final arrangement. - -This procedure is done in two steps: 1. preprocessing to eliminate identical -edges that are present an even number of times, and 2. adding edges incrementally -while applying an even-odd counting mechanism, which erases existing (parts of) -edges when new overlapping ones are added. - -\subsection SubsectionPolygonRepair_Labeling Labeling - -First, the polygon exterior is labeled. For this, all of the faces that can be -accessed from the exterior without passing through an edge are labeled as exterior -faces. - -Then, all other faces are labeled. For the even-odd rule, the label applied -alternates between polygon interior and hole every time that an edge is passed. - -\subsection SubsectionPolygonRepair_Reconstruction Reconstruction of the Multipolygon - -The algorithm reconstructs the multipolygon boundary by boundary, obtaining -counter-clockwise cycles for outer boundaries and clockwise cycles for inner -boundaries. Once all boundaries have been reconstructed, the boundaries are assembled -into multipolygons using the face labels to know which polygon with holes inner/outer -boundaries belong to, and using the orientation to distinguish between the outer and -inner boundaries of each polygon with holes. - -\subsection SubsectionPolygonRepair_Notes Notes on the Output If the input is already valid, the method will return a valid output representing the same area. However, the output might be different in order to conform to the -stricter conditions to generate deterministic output (see -\ref SubsectionPolygonRepair_Output). +stricter conditions to generate deterministic output. Also, it is worth noting that even the repair of a single polygon without holes but with self-intersections can result in a multipolygon with holes. This is why @@ -146,9 +141,11 @@ the repair function will always return a multipolygon with holes. The user can then check whether it consists of a single polygon with holes, and if a polygon with holes has zero holes and extract these if needed. + + \section SectionPolygonRepair_Examples Examples -\subsection SubsectionPolygonRepair_Repair Repairing a (Multi)polygon +\subsection SubsectionPolygonRepair_Repair Repairing a (Multi)polygon with the Even-Odd Rule It is possible to repair a polygon, polygon with holes or multipolygon with holes using the even-odd rule by calling the `Polygon_repair::repair()` function @@ -183,6 +180,8 @@ to edges, which enables correct counting even on partially overlapping edges. Ken Arroyo Ohori developed this package during the Google Summer of Code 2023 mentored by Sébastien Loriot and Andreas Fabri. +The GSoC project was limited to the even-odd rule. Further rules were added +with CGAL 6.1 by Andreas Fabri. */ } /* namespace CGAL */ diff --git a/Polygon_repair/doc/Polygon_repair/dependencies b/Polygon_repair/doc/Polygon_repair/dependencies index 6df3ace8d07..f5c7866adae 100644 --- a/Polygon_repair/doc/Polygon_repair/dependencies +++ b/Polygon_repair/doc/Polygon_repair/dependencies @@ -4,4 +4,5 @@ STL_Extension Algebraic_foundations Circulator Stream_support -Polygon \ No newline at end of file +Polygon +Triangulation_2 diff --git a/Polygon_repair/doc/Polygon_repair/examples.txt b/Polygon_repair/doc/Polygon_repair/examples.txt index e7d63a06e20..3ae4d468ea4 100644 --- a/Polygon_repair/doc/Polygon_repair/examples.txt +++ b/Polygon_repair/doc/Polygon_repair/examples.txt @@ -1,4 +1,6 @@ /*! \example Polygon_repair/repair_polygon_2.cpp +\example Polygon_repair/repair_non_zero_polygon_2.cpp \example Polygon_repair/repair_multipolygon_2.cpp +\example Polygon_repair/repair_union_intersect_2.cpp */ diff --git a/Polygon_repair/doc/Polygon_repair/fig/MultipolygonHole.ipe b/Polygon_repair/doc/Polygon_repair/fig/MultipolygonHole.ipe new file mode 100644 index 00000000000..6da403058d4 --- /dev/null +++ b/Polygon_repair/doc/Polygon_repair/fig/MultipolygonHole.ipe @@ -0,0 +1,564 @@ + + + + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-0.8 0 l +-1 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-0.8 0 l +-1 -0.333 l +h + + + + +0.6 0 0 0.6 0 0 e +0.4 0 0 0.4 0 0 e + + + + +0.6 0 0 0.6 0 0 e + + + + + +0.5 0 0 0.5 0 0 e + + +0.6 0 0 0.6 0 0 e +0.4 0 0 0.4 0 0 e + + + + + +-0.6 -0.6 m +0.6 -0.6 l +0.6 0.6 l +-0.6 0.6 l +h +-0.4 -0.4 m +0.4 -0.4 l +0.4 0.4 l +-0.4 0.4 l +h + + + + +-0.6 -0.6 m +0.6 -0.6 l +0.6 0.6 l +-0.6 0.6 l +h + + + + + +-0.5 -0.5 m +0.5 -0.5 l +0.5 0.5 l +-0.5 0.5 l +h + + +-0.6 -0.6 m +0.6 -0.6 l +0.6 0.6 l +-0.6 0.6 l +h +-0.4 -0.4 m +0.4 -0.4 l +0.4 0.4 l +-0.4 0.4 l +h + + + + + + +-0.43 -0.57 m +0.57 0.43 l +0.43 0.57 l +-0.57 -0.43 l +h + + +-0.43 0.57 m +0.57 -0.43 l +0.43 -0.57 l +-0.57 0.43 l +h + + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-0.8 0 l +-1 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-0.8 0 l +-1 -0.333 l +h + + + + +-1 0.333 m +0 0 l +-1 -0.333 l + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h +-1 0 m +-2 0.333 l +-2 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h +-1 0 m +-2 0.333 l +-2 -0.333 l +h + + + + +0.5 0 m +-0.5 0.333 l +-0.5 -0.333 l +h + + + + +0.5 0 m +-0.5 0.333 l +-0.5 -0.333 l +h + + + + +0.5 0 m +-0.5 0.333 l +-0.3 0 l +-0.5 -0.333 l +h + + + + +0.5 0 m +-0.5 0.333 l +-0.3 0 l +-0.5 -0.333 l +h + + + + +1 0 m +0 0.333 l +0 -0.333 l +h +0 0 m +-1 0.333 l +-1 -0.333 l +h + + + + +1 0 m +0 0.333 l +0 -0.333 l +h +0 0 m +-1 0.333 l +-1 -0.333 l +h + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +64 528 m +64 464 l +192 464 l +192 528 l +h +96 512 m +96 480 l +160 480 l +160 512 l +h + + +64 528 m +64 464 l +192 464 l +192 528 l +h + + +96 512 m +96 480 l +160 480 l +160 512 l +h + + +64 464 m +192 464 l + + +192 464 m +192 528 l + + +192 528 m +64 528 l + + +64 528 m +64 464 l + + +96 480 m +160 480 l + + +160 480 m +160 512 l + + +160 512 m +96 512 l + + +96 512 m +96 480 l + + +64 528 m +64 464 l +192 464 l +192 528 l +h + + +192 464 m +192 528 l + + +192 528 m +64 528 l + + +64 528 m +64 464 l + + +64 464 m +192 464 l + + +192 464 m +192 528 l + + +192 528 m +64 528 l + + +480 512 m +544 512 l + + +544 512 m +544 480 l + + +544 480 m +480 480 l + + +448 528 m +448 464 l + + +480 480 m +480 512 l + + +256 464 m +384 464 l + + +64 528 m +64 464 l +192 464 l +192 528 l +h + + +96 512 m +96 480 l +160 480 l +160 512 l +h + + +64 464 m +192 464 l + + +192 464 m +192 528 l + + +192 528 m +64 528 l + + +64 528 m +64 464 l + + +96 656 m +96 688 l + + +96 688 m +160 688 l + + +160 688 m +160 656 l + + +160 656 m +96 656 l + + +64 528 m +64 464 l +192 464 l +192 528 l +h +96 512 m +96 480 l +160 480 l +160 512 l +h + + +64 464 m +192 464 l + + +192 464 m +192 528 l + + +192 528 m +64 528 l + + +480 512 m +544 512 l + + +544 512 m +544 480 l + + +544 480 m +480 480 l + + +448 528 m +448 464 l + + +480 480 m +480 512 l + + +64 528 m +64 464 l +192 464 l +192 528 l +h +96 512 m +96 480 l +160 480 l +160 512 l +h + + +64 464 m +192 464 l + + +192 464 m +192 528 l + + +192 528 m +64 528 l + + +480 512 m +544 512 l + + +544 512 m +544 480 l + + +544 480 m +480 480 l + + +448 528 m +448 464 l + + +480 480 m +480 512 l + + + diff --git a/Polygon_repair/doc/Polygon_repair/fig/MultipolygonHole.svg b/Polygon_repair/doc/Polygon_repair/fig/MultipolygonHole.svg new file mode 100644 index 00000000000..fb0747ad459 --- /dev/null +++ b/Polygon_repair/doc/Polygon_repair/fig/MultipolygonHole.svg @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Polygon_repair/doc/Polygon_repair/fig/UnionIntersection.ipe b/Polygon_repair/doc/Polygon_repair/fig/UnionIntersection.ipe new file mode 100644 index 00000000000..5d9ad8bfc53 --- /dev/null +++ b/Polygon_repair/doc/Polygon_repair/fig/UnionIntersection.ipe @@ -0,0 +1,446 @@ + + + + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-0.8 0 l +-1 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-0.8 0 l +-1 -0.333 l +h + + + + +0.6 0 0 0.6 0 0 e +0.4 0 0 0.4 0 0 e + + + + +0.6 0 0 0.6 0 0 e + + + + + +0.5 0 0 0.5 0 0 e + + +0.6 0 0 0.6 0 0 e +0.4 0 0 0.4 0 0 e + + + + + +-0.6 -0.6 m +0.6 -0.6 l +0.6 0.6 l +-0.6 0.6 l +h +-0.4 -0.4 m +0.4 -0.4 l +0.4 0.4 l +-0.4 0.4 l +h + + + + +-0.6 -0.6 m +0.6 -0.6 l +0.6 0.6 l +-0.6 0.6 l +h + + + + + +-0.5 -0.5 m +0.5 -0.5 l +0.5 0.5 l +-0.5 0.5 l +h + + +-0.6 -0.6 m +0.6 -0.6 l +0.6 0.6 l +-0.6 0.6 l +h +-0.4 -0.4 m +0.4 -0.4 l +0.4 0.4 l +-0.4 0.4 l +h + + + + + + +-0.43 -0.57 m +0.57 0.43 l +0.43 0.57 l +-0.57 -0.43 l +h + + +-0.43 0.57 m +0.57 -0.43 l +0.43 -0.57 l +-0.57 0.43 l +h + + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-0.8 0 l +-1 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-0.8 0 l +-1 -0.333 l +h + + + + +-1 0.333 m +0 0 l +-1 -0.333 l + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h +-1 0 m +-2 0.333 l +-2 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h +-1 0 m +-2 0.333 l +-2 -0.333 l +h + + + + +0.5 0 m +-0.5 0.333 l +-0.5 -0.333 l +h + + + + +0.5 0 m +-0.5 0.333 l +-0.5 -0.333 l +h + + + + +0.5 0 m +-0.5 0.333 l +-0.3 0 l +-0.5 -0.333 l +h + + + + +0.5 0 m +-0.5 0.333 l +-0.3 0 l +-0.5 -0.333 l +h + + + + +1 0 m +0 0.333 l +0 -0.333 l +h +0 0 m +-1 0.333 l +-1 -0.333 l +h + + + + +1 0 m +0 0.333 l +0 -0.333 l +h +0 0 m +-1 0.333 l +-1 -0.333 l +h + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +138.353 615.529 m +201.6 633.6 l +229.895 638.316 l +261.333 629.333 l +304 608 l +317.333 613.333 l +336 608 l +432 640 l +480 640 l +501.333 645.333 l +544 624 l +544 592 l +496 592 l +464 576 l +448 576 l +408 560 l +368 560 l +276.364 546.909 l +256 552 l +256 560 l +208 560 l +200 552 l +176 544 l +130.286 562.286 l +112 576 l +138.353 615.529 l + + +96 720 m +130.286 706.286 l +176 672 l +200 696 l +224 704 l +256 696 l +256 688 l +276.364 690.909 l +288 688 l +368 688 l +408 704 l +432 704 l +464 720 l +512 720 l +544 736 l +560 736 l +544 800 l +501.333 789.333 l +480 800 l +432 784 l +384 784 l +317.333 757.333 l +261.333 773.333 l +240 784 l +229.895 782.316 l +224 784 l +201.6 777.6 l +144 768 l +138.353 759.529 l +112 752 l +96 720 l + + +112 720 m +176 672 l +208 704 l +256 704 l +256 688 l +368 704 l +432 704 l +496 736 l +560 736 l +544 800 l +480 784 l +384 784 l +304 752 l +240 784 l +144 768 l +112 720 l + + +96 720 m +176 688 l +224 704 l +288 688 l +368 688 l +448 720 l +512 720 l +544 736 l +544 768 l +480 800 l +336 752 l +224 784 l +112 752 l +96 720 l + + +112 720 m +176 672 l +208 704 l +256 704 l +256 688 l +368 704 l +432 704 l +496 736 l +560 736 l +544 800 l +480 784 l +384 784 l +304 752 l +240 784 l +144 768 l +112 720 l + + +96 720 m +176 688 l +224 704 l +288 688 l +368 688 l +448 720 l +512 720 l +544 736 l +544 768 l +480 800 l +336 752 l +224 784 l +112 752 l +96 720 l + + + diff --git a/Polygon_repair/doc/Polygon_repair/fig/UnionIntersection.svg b/Polygon_repair/doc/Polygon_repair/fig/UnionIntersection.svg new file mode 100644 index 00000000000..5374b62ecce --- /dev/null +++ b/Polygon_repair/doc/Polygon_repair/fig/UnionIntersection.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/Polygon_repair/doc/Polygon_repair/fig/WindingNonZero.ipe b/Polygon_repair/doc/Polygon_repair/fig/WindingNonZero.ipe new file mode 100644 index 00000000000..131a5919dcc --- /dev/null +++ b/Polygon_repair/doc/Polygon_repair/fig/WindingNonZero.ipe @@ -0,0 +1,515 @@ + + + + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-0.8 0 l +-1 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-0.8 0 l +-1 -0.333 l +h + + + + +0.6 0 0 0.6 0 0 e +0.4 0 0 0.4 0 0 e + + + + +0.6 0 0 0.6 0 0 e + + + + + +0.5 0 0 0.5 0 0 e + + +0.6 0 0 0.6 0 0 e +0.4 0 0 0.4 0 0 e + + + + + +-0.6 -0.6 m +0.6 -0.6 l +0.6 0.6 l +-0.6 0.6 l +h +-0.4 -0.4 m +0.4 -0.4 l +0.4 0.4 l +-0.4 0.4 l +h + + + + +-0.6 -0.6 m +0.6 -0.6 l +0.6 0.6 l +-0.6 0.6 l +h + + + + + +-0.5 -0.5 m +0.5 -0.5 l +0.5 0.5 l +-0.5 0.5 l +h + + +-0.6 -0.6 m +0.6 -0.6 l +0.6 0.6 l +-0.6 0.6 l +h +-0.4 -0.4 m +0.4 -0.4 l +0.4 0.4 l +-0.4 0.4 l +h + + + + + + +-0.43 -0.57 m +0.57 0.43 l +0.43 0.57 l +-0.57 -0.43 l +h + + +-0.43 0.57 m +0.57 -0.43 l +0.43 -0.57 l +-0.57 0.43 l +h + + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-0.8 0 l +-1 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-0.8 0 l +-1 -0.333 l +h + + + + +-1 0.333 m +0 0 l +-1 -0.333 l + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h +-1 0 m +-2 0.333 l +-2 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h +-1 0 m +-2 0.333 l +-2 -0.333 l +h + + + + +0.5 0 m +-0.5 0.333 l +-0.5 -0.333 l +h + + + + +0.5 0 m +-0.5 0.333 l +-0.5 -0.333 l +h + + + + +0.5 0 m +-0.5 0.333 l +-0.3 0 l +-0.5 -0.333 l +h + + + + +0.5 0 m +-0.5 0.333 l +-0.3 0 l +-0.5 -0.333 l +h + + + + +1 0 m +0 0.333 l +0 -0.333 l +h +0 0 m +-1 0.333 l +-1 -0.333 l +h + + + + +1 0 m +0 0.333 l +0 -0.333 l +h +0 0 m +-1 0.333 l +-1 -0.333 l +h + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +64 704 m +192 704 l +192 768 l +64 768 l +h +32 752 m +128 752 l +128 720 l +32 720 l +h + + +64 704 m +192 704 l + + +192 704 m +192 768 l + + +192 768 m +64 768 l + + +64 768 m +64 704 l + + +128 720 m +32 720 l + + +32 720 m +32 752 l + + +32 752 m +128 752 l + + +128 752 m +128 720 l + + +384 640 m +256 640 l +256 592 l +320 592 l +320 576 l +304 576 l +304 608 l +384 608 l +h + + +384 528 m +256 528 l + + +256 528 m +256 480 l + + +256 480 m +320 480 l + + +320 480 m +320 464 l + + +320 464 m +304 464 l + + +304 464 m +304 496 l + + +304 496 m +384 496 l + + +384 496 m +384 528 l + + +384 640 m +256 640 l +256 592 l +320 592 l +320 576 l +304 576 l +304 608 l +384 608 l +h + + +384 528 m +256 528 l + + +256 528 m +256 480 l + + +304 496 m +384 496 l + + +384 496 m +384 528 l + + +64 704 m +192 704 l +192 768 l +64 768 l +h +32 752 m +128 752 l +128 720 l +32 720 l +h + + +64 704 m +192 704 l + + +192 704 m +192 768 l + + +192 768 m +64 768 l + + +256 592 m +304 592 l + + +304 592 m +304 608 l + + +304 576 m +320 576 l + + +320 576 m +320 592 l + + +320 592 m +304 592 l + + +304 592 m +304 576 l + + +256 768 m +256 752 l + + +256 752 m +320 752 l + + +320 752 m +320 720 l + + +320 720 m +256 720 l + + +256 720 m +256 704 l + + +224 720 m +256 720 l + + +256 720 m +256 752 l + + +256 752 m +224 752 l + + +224 752 m +224 720 l + + + diff --git a/Polygon_repair/doc/Polygon_repair/fig/WindingNonZero.svg b/Polygon_repair/doc/Polygon_repair/fig/WindingNonZero.svg new file mode 100644 index 00000000000..75d37586db8 --- /dev/null +++ b/Polygon_repair/doc/Polygon_repair/fig/WindingNonZero.svg @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Polygon_repair/doc/Polygon_repair/fig/WindingNonZeroDifferent.ipe b/Polygon_repair/doc/Polygon_repair/fig/WindingNonZeroDifferent.ipe new file mode 100644 index 00000000000..47617b1dcc9 --- /dev/null +++ b/Polygon_repair/doc/Polygon_repair/fig/WindingNonZeroDifferent.ipe @@ -0,0 +1,650 @@ + + + + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-0.8 0 l +-1 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-0.8 0 l +-1 -0.333 l +h + + + + +0.6 0 0 0.6 0 0 e +0.4 0 0 0.4 0 0 e + + + + +0.6 0 0 0.6 0 0 e + + + + + +0.5 0 0 0.5 0 0 e + + +0.6 0 0 0.6 0 0 e +0.4 0 0 0.4 0 0 e + + + + + +-0.6 -0.6 m +0.6 -0.6 l +0.6 0.6 l +-0.6 0.6 l +h +-0.4 -0.4 m +0.4 -0.4 l +0.4 0.4 l +-0.4 0.4 l +h + + + + +-0.6 -0.6 m +0.6 -0.6 l +0.6 0.6 l +-0.6 0.6 l +h + + + + + +-0.5 -0.5 m +0.5 -0.5 l +0.5 0.5 l +-0.5 0.5 l +h + + +-0.6 -0.6 m +0.6 -0.6 l +0.6 0.6 l +-0.6 0.6 l +h +-0.4 -0.4 m +0.4 -0.4 l +0.4 0.4 l +-0.4 0.4 l +h + + + + + + +-0.43 -0.57 m +0.57 0.43 l +0.43 0.57 l +-0.57 -0.43 l +h + + +-0.43 0.57 m +0.57 -0.43 l +0.43 -0.57 l +-0.57 0.43 l +h + + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-0.8 0 l +-1 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-0.8 0 l +-1 -0.333 l +h + + + + +-1 0.333 m +0 0 l +-1 -0.333 l + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h +-1 0 m +-2 0.333 l +-2 -0.333 l +h + + + + +0 0 m +-1 0.333 l +-1 -0.333 l +h +-1 0 m +-2 0.333 l +-2 -0.333 l +h + + + + +0.5 0 m +-0.5 0.333 l +-0.5 -0.333 l +h + + + + +0.5 0 m +-0.5 0.333 l +-0.5 -0.333 l +h + + + + +0.5 0 m +-0.5 0.333 l +-0.3 0 l +-0.5 -0.333 l +h + + + + +0.5 0 m +-0.5 0.333 l +-0.3 0 l +-0.5 -0.333 l +h + + + + +1 0 m +0 0.333 l +0 -0.333 l +h +0 0 m +-1 0.333 l +-1 -0.333 l +h + + + + +1 0 m +0 0.333 l +0 -0.333 l +h +0 0 m +-1 0.333 l +-1 -0.333 l +h + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +304 576 m +384 576 l +384 640 l +256 640 l +256 592 l +304 592 l +h + + +256 688 m +384 688 l +384 768 l +304 768 l +304 752 l +256 752 l +h +272 736 m +304 736 l +304 720 l +368 720 l +368 704 l +272 704 l +h + + +256 688 m +384 688 l + + +384 688 m +384 768 l + + +368 720 m +368 704 l + + +368 704 m +272 704 l + + +272 704 m +272 736 l + + +256 752 m +256 688 l + + +336 752 m +256 752 l +256 688 l +384 688 l +384 768 l +304 768 l +304 720 l +368 720 l +368 704 l +272 704 l +272 736 l +336 736 l +h + + +256 688 m +384 688 l + + +384 688 m +384 768 l + + +384 768 m +304 768 l + + +304 768 m +304 720 l + + +304 720 m +368 720 l + + +368 720 m +368 704 l + + +368 704 m +272 704 l + + +272 704 m +272 736 l + + +256 752 m +256 688 l + + +384 640 m +256 640 l + + +256 640 m +256 592 l + + +304 576 m +384 576 l + + +384 576 m +384 640 l + + +192 640 m +64 640 l +64 592 l +128 592 l +128 608 l +112 608 l +112 576 l +192 576 l +h + + +384 640 m +256 640 l + + +256 640 m +256 592 l + + +304 608 m +304 576 l + + +304 576 m +384 576 l + + +384 576 m +384 640 l + + +336 752 m +256 752 l +256 688 l +384 688 l +384 768 l +304 768 l +304 720 l +368 720 l +368 704 l +272 704 l +272 736 l +336 736 l +h + + +256 688 m +384 688 l + + +384 688 m +384 768 l + + +384 768 m +304 768 l + + +304 768 m +304 720 l + + +304 720 m +368 720 l + + +368 720 m +368 704 l + + +368 704 m +272 704 l + + +272 704 m +272 736 l + + +272 736 m +336 736 l + + +336 736 m +336 752 l + + +336 752 m +256 752 l + + +256 752 m +256 688 l + + +384 768 m +304 768 l + + +272 736 m +304 736 l + + +304 736 m +304 720 l + + +304 720 m +368 720 l + + +304 768 m +304 752 l + + +304 752 m +256 752 l + + +496 768 m +496 752 l + + +496 752 m +528 752 l + + +528 752 m +528 736 l + + +528 736 m +496 736 l + + +464 736 m +496 736 l + + +496 736 m +496 752 l + + +496 752 m +448 752 l + + +192 640 m +64 640 l +64 592 l +128 592 l +128 608 l +112 608 l +112 576 l +192 576 l +h + + +384 640 m +256 640 l + + +256 640 m +256 592 l + + +256 592 m +320 592 l + + +320 592 m +320 608 l + + +320 608 m +304 608 l + + +304 608 m +304 576 l + + +304 576 m +384 576 l + + +384 576 m +384 640 l + + +512 592 m +496 592 l + + +496 592 m +496 608 l + + +496 608 m +512 608 l + + +512 608 m +512 592 l + + +448 592 m +496 592 l + + +256 592 m +304 592 l + + +304 592 m +304 576 l + + + diff --git a/Polygon_repair/doc/Polygon_repair/fig/WindingNonZeroDifferent.svg b/Polygon_repair/doc/Polygon_repair/fig/WindingNonZeroDifferent.svg new file mode 100644 index 00000000000..537b74fa694 --- /dev/null +++ b/Polygon_repair/doc/Polygon_repair/fig/WindingNonZeroDifferent.svg @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Polygon_repair/examples/Polygon_repair/CMakeLists.txt b/Polygon_repair/examples/Polygon_repair/CMakeLists.txt index 1053fbe2725..3453a093f10 100644 --- a/Polygon_repair/examples/Polygon_repair/CMakeLists.txt +++ b/Polygon_repair/examples/Polygon_repair/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.12...3.31) project(Polygon_repair_Examples) -find_package(CGAL REQUIRED) +find_package(CGAL REQUIRED OPTIONAL_COMPONENTS Qt6) # create a target per cppfile file( @@ -13,4 +13,11 @@ file( ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) foreach(cppfile ${cppfiles}) create_single_source_cgal_program("${cppfile}") -endforeach() \ No newline at end of file +endforeach() + + + +if(CGAL_Qt6_FOUND) + target_link_libraries(repair_non_zero_polygon_2 PUBLIC CGAL::CGAL_Basic_viewer) + target_link_libraries(repair_union_intersect_2 PUBLIC CGAL::CGAL_Basic_viewer) +endif() diff --git a/Polygon_repair/examples/Polygon_repair/data/winding.wkt b/Polygon_repair/examples/Polygon_repair/data/winding.wkt new file mode 100644 index 00000000000..6fd39f4923c --- /dev/null +++ b/Polygon_repair/examples/Polygon_repair/data/winding.wkt @@ -0,0 +1 @@ +POLYGON((0 0, 10 0, 10 6, 6 6, 6 4 , 10 4, 10 10, 0 10)) \ No newline at end of file diff --git a/Polygon_repair/examples/Polygon_repair/repair_non_zero_polygon_2.cpp b/Polygon_repair/examples/Polygon_repair/repair_non_zero_polygon_2.cpp new file mode 100644 index 00000000000..3ce04501ab0 --- /dev/null +++ b/Polygon_repair/examples/Polygon_repair/repair_non_zero_polygon_2.cpp @@ -0,0 +1,37 @@ +#include +#include +#include + +#include +#include +#include +#ifdef CGAL_USE_BASIC_VIEWER +#include +#endif + +using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel; +using Point_2 = Kernel::Point_2; +using Polygon_2 = CGAL::Polygon_2; +using Polygon_with_holes_2 = CGAL::Polygon_with_holes_2; +using Multipolygon_with_holes_2 = CGAL::Multipolygon_with_holes_2; + +int main(int argc, char* argv[]) { + + const char* filename = (argc > 1) ? argv[1] : "data/winding.wkt"; + + std::ifstream in(filename); + Polygon_with_holes_2 pin; + CGAL::IO::read_polygon_WKT(in, pin); + + Multipolygon_with_holes_2 mp = CGAL::Polygon_repair::repair(pin, CGAL::Polygon_repair::Non_zero_rule()); +#ifdef CGAL_USE_BASIC_VIEWER + CGAL::draw(mp); +#endif + + if (mp.number_of_polygons_with_holes() > 1) { + CGAL::IO::write_multi_polygon_WKT(std::cout, mp); + } else { + CGAL::IO::write_polygon_WKT(std::cout, mp.polygons_with_holes()[0]); + } + return 0; +} diff --git a/Polygon_repair/examples/Polygon_repair/repair_union_intersect_2.cpp b/Polygon_repair/examples/Polygon_repair/repair_union_intersect_2.cpp new file mode 100644 index 00000000000..bec35767d1c --- /dev/null +++ b/Polygon_repair/examples/Polygon_repair/repair_union_intersect_2.cpp @@ -0,0 +1,72 @@ +#include + +#include +#include + +#ifdef CGAL_USE_BASIC_VIEWER +#include +#endif + +#include + +#include + + +#include +#include + +using K = CGAL::Exact_predicates_inexact_constructions_kernel; + +using Point_2 = K::Point_2; +using Polygon_2 = CGAL::Polygon_2; +using Polygon_with_holes_2 = CGAL::Polygon_with_holes_2; +using Multipolygon_with_holes_2 = CGAL::Multipolygon_with_holes_2; + +int +main(int argc, char* argv[]) +{ + Multipolygon_with_holes_2 pA; + if (argc == 2) { + { + std::ifstream in(argv[1]); + CGAL::IO::read_multi_polygon_WKT(in, pA); + } + } else { + std::istringstream is("MULTIPOLYGON( ((0 0, 20 0, 20 20, 0 20), (1 1, 1 19, 19 19, 19 1) ) , (( 10 -2, 12 -2, 12 22, 10 22)) )"); + //std::istringstream is("MULTIPOLYGON( ((0 0, 2 0, 2 3, 0 3) ) )"); // (0.1 0.1, 0.1 0.4, 0.4 0.1) + CGAL::IO::read_multi_polygon_WKT(is, pA); + } + + Multipolygon_with_holes_2 mpwh = CGAL::Polygon_repair::repair(pA, CGAL::Polygon_repair::Union_rule()); + { + std::ofstream out("union.wkt"); + CGAL::IO::write_multi_polygon_WKT(out, mpwh); +#ifdef CGAL_USE_BASIC_VIEWER + CGAL::draw(mpwh); +#endif + } + mpwh = CGAL::Polygon_repair::repair(pA, CGAL::Polygon_repair::Intersection_rule()); + { + std::ofstream out("intersection.wkt"); + CGAL::IO::write_multi_polygon_WKT(out, mpwh); +#ifdef CGAL_USE_BASIC_VIEWER + CGAL::draw(mpwh); +#endif + } + + { + Polygon_2 pB; + pB.push_back(Point_2(-1,-1)); + pB.push_back(Point_2(1,-1)); + pB.push_back(Point_2(1,1)); + pB.push_back(Point_2(-1,1)); + mpwh = CGAL::Polygon_repair::join(mpwh, pB); + + std::ofstream out("joinn.wkt"); + CGAL::IO::write_multi_polygon_WKT(out, mpwh); +#ifdef CGAL_USE_BASIC_VIEWER + CGAL::draw(mpwh); +#endif + } + return 0; +} diff --git a/Polygon_repair/include/CGAL/Polygon_repair/Boolean.h b/Polygon_repair/include/CGAL/Polygon_repair/Boolean.h new file mode 100644 index 00000000000..a726139d70d --- /dev/null +++ b/Polygon_repair/include/CGAL/Polygon_repair/Boolean.h @@ -0,0 +1,396 @@ +// Copyright (c) 2024 GeometryFactory SARL (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) : Andreas Fabri + +#ifndef CGAL_POLYGON_REPAIR_BOOLEAN_H +#define CGAL_POLYGON_REPAIR_BOOLEAN_H + +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include + +namespace CGAL { +namespace Polygon_repair { + +/*! +\ingroup PkgTriangulation2Miscellaneous + +\tparam Kernel must be +*/ + +template +class Boolean { + +private: + struct FaceInfo { + + FaceInfo() + {} + + int label; + int layers; + bool processed; + + template + bool + in_domain(const Fct& fct) const + { + return fct(layers); + } + + }; + + using K = Kernel; + using Container = Container_; + using Point_2 = typename K::Point_2; + using Polygon_2 = CGAL::Polygon_2; + using Polygon_with_holes_2 = CGAL::Polygon_with_holes_2; + using Multipolygon_with_holes_2 = CGAL::Multipolygon_with_holes_2; + + using Itag = std::conditional_t, Exact_predicates_tag, Exact_intersections_tag>; + using Vb = CGAL::Triangulation_vertex_base_2; + using Fbb = CGAL::Triangulation_face_base_with_info_2; + using Fb = CGAL::Constrained_triangulation_face_base_2; + using Tds = CGAL::Triangulation_data_structure_2; + using CDT = CGAL::Constrained_Delaunay_triangulation_2; + using CDTplus = CGAL::Constrained_triangulation_plus_2; + using Face_handle = typename CDTplus::Face_handle; + using Face_circulator = typename CDTplus::Face_circulator; + using Vertex_handle = typename CDTplus::Vertex_handle; + using Constraint_id = typename CDTplus::Constraint_id; + using Edge = typename CDTplus::Edge; + using Context = typename CDTplus::Context; + + + // @todo taken from Polygon_repair should be factorized + struct Polygon_less { + + bool + operator()(const Polygon_2& pa, const Polygon_2& pb) const + { + typename Polygon_2::Vertex_iterator va = pa.vertices_begin(); + typename Polygon_2::Vertex_iterator vb = pb.vertices_begin(); + while (va != pa.vertices_end() && vb != pb.vertices_end()) { + if (*va != *vb) return *va < *vb; + ++va; + ++vb; + } + if (vb == pb.vertices_end()) return false; + return true; + } + + }; + + + // @todo taken from Polygon_repair should be factorized + struct Polygon_with_holes_less { + Polygon_less pl; + + bool + operator()(const Polygon_with_holes_2& pa, const Polygon_with_holes_2& pb) const + { + if (pl(pa.outer_boundary(), pb.outer_boundary())) return true; + if (pl(pb.outer_boundary(), pa.outer_boundary())) return false; + typename Polygon_with_holes_2::Hole_const_iterator ha = pa.holes_begin(); + typename Polygon_with_holes_2::Hole_const_iterator hb = pb.holes_begin(); + while (ha != pa.holes_end() && hb != pb.holes_end()) { + if (pl(*ha, *hb)) return true; + if (pl(*hb, *ha)) return false; + } + if (hb == pb.holes_end()) return false; + return true; + } + + }; + + + CDTplus cdt; + +public: + +/*! +default constructor. +*/ + Boolean() = default; + + +/*! +sets the polygons as input of the %Boolean operation. +*/ + void + insert(const Polygon_2& pA) + { + cdt.insert_constraint(pA.vertices_begin(), pA.vertices_end(), true); + } + + + void + insert(const Polygon_with_holes_2& pwh) + { + cdt.insert_constraint(pwh.outer_boundary().vertices_begin(), pwh.outer_boundary().vertices_end(), true); + for(auto const& hole : pwh.holes()){ + cdt.insert_constraint(hole.vertices_begin(), hole.vertices_end(), true); + } + } + + void + insert(const Multipolygon_with_holes_2& pA) + { + for(const auto& pwh : pA.polygons_with_holes()){ + cdt.insert_constraint(pwh.outer_boundary().vertices_begin(), pwh.outer_boundary().vertices_end(), true); + for(auto const& hole : pwh.holes()){ + cdt.insert_constraint(hole.vertices_begin(), hole.vertices_end(), true); + } + } + } +private: + + void + mark_domains(Face_handle start, + int index, + std::list& border) + { + if(start->info().layers != -1){ + return; + } + std::list queue; + queue.push_back(start); + + while(! queue.empty()){ + Face_handle fh = queue.front(); + queue.pop_front(); + if(fh->info().layers == -1){ + fh->info().layers = index; + for(int i = 0; i < 3; i++){ + Edge e(fh,i); + Face_handle n = fh->neighbor(i); + if(n->info().layers == -1){ + if(cdt.is_constrained(e)){ + border.push_back(e); + }else{ + queue.push_back(n); + } + } + } + } + } + } + + public: + // this marks how many multipolygon interiors overlap a cell of the arrangement of mutipolygons + void + mark_domains() + { + for(Face_handle f : cdt.all_face_handles()){ + f->info().layers = -1; + } + + int overlays = 0; + std::list border; + mark_domains(cdt.infinite_face(), overlays, border); + + while(! border.empty()){ + Edge e = border.front(); + border.pop_front(); + Face_handle fh = e.first; + int fi = e.second; + Face_handle n = fh->neighbor(fi); + if(n->info().layers == -1){ + Vertex_handle u = fh->vertex(cdt.cw(fi)), v = fh->vertex(cdt.ccw(fi)); + int delta = 0; + for(Context c : cdt.contexts(u,v)){ + if(*c.current() ==u && *std::next(c.current()) == v){ + ++delta; + }else if(*c.current() ==v && *std::next(c.current()) == u){ + --delta; + }else{ + CGAL_assertion(false); + } + } + mark_domains(n, fh->info().layers+delta, border); + } + } + } + +private: + template + void + label_domain(Face_handle start, int label, const Fct& fct) + { + std::list queue; + start->info().label = label; + queue.push_back(start); + + while(! queue.empty()){ + Face_handle fh = queue.front(); + queue.pop_front(); + + for(int i = 0; i < 3; i++){ + Face_handle n = fh->neighbor(i); + if(n->info().in_domain(fct)){ + if(n->info().label == 0){ + n->info().label = label; + queue.push_back(n); + } + } + } + } + } + + // this marks the domain for the Boolean operation applied on the two multipolygons + template + int + label_domains(const Fct& fct) + { + for (auto const face: cdt.all_face_handles()) { + face->info().processed = false; + face->info().label = 0; + } + int label = 1; + for (auto const face: cdt.all_face_handles()) { + if(face->info().in_domain(fct) && face->info().label == 0){ + label_domain(face, label, fct); + ++label; + } + } + return label; + } + + + + // @todo taken from Polygon_repair and adapted; might be factorized + // Reconstruct ring boundary starting from an edge (face + opposite vertex) that is part of it + template + void + reconstruct_ring(std::list& ring, + Face_handle face_adjacent_to_boundary, + int opposite_vertex, + const Fct& CGAL_assertion_code(fct)) + { + // Create ring + Face_handle current_face = face_adjacent_to_boundary; + int current_opposite_vertex = opposite_vertex; + CGAL_assertion(face_adjacent_to_boundary->info().in_domain(fct)); + do { + CGAL_assertion(current_face->info().in_domain(fct) == face_adjacent_to_boundary->info().in_domain(fct)); + current_face->info().processed = true; + Vertex_handle pivot_vertex = current_face->vertex(current_face->cw(current_opposite_vertex)); + // std::cout << "\tAdding point " << pivot_vertex->point() << std::endl; + ring.push_back(pivot_vertex->point()); + Face_circulator fc = cdt.incident_faces(pivot_vertex, current_face); + do { + ++fc; + } while (fc->info().label != current_face->info().label); + current_face = fc; + current_opposite_vertex = fc->cw(fc->index(pivot_vertex)); + } while (current_face != face_adjacent_to_boundary || + current_opposite_vertex != opposite_vertex); + + // Start at lexicographically smallest vertex + typename std::list::iterator smallest_vertex = ring.begin(); + for (typename std::list::iterator current_vertex = ring.begin(); + current_vertex != ring.end(); ++current_vertex) { + if (*current_vertex < *smallest_vertex) smallest_vertex = current_vertex; + } + if (ring.front() != *smallest_vertex) { + ring.splice(ring.begin(), ring, smallest_vertex, ring.end()); + } + } + + +public: + + // @todo taken from Polygon_repair and adapted; might be factorized + +/*! +performs the Boolean operation applying `fct` and returns the result as a multipolygon with holes. + +\tparam Fct must have the operator `bool operator()(bool, bool)`. +*/ + template + Multipolygon_with_holes_2 + operator()(const Fct& fct) + { + int number_of_polygons = label_domains(fct) - 1; + Multipolygon_with_holes_2 mp; + std::vector polygons; // outer boundaries + std::vector> holes; // holes are ordered (per polygon) + polygons.resize(number_of_polygons); + holes.resize(number_of_polygons); + + for (auto const face: cdt.all_face_handles()) { + face->info().processed = false; + } + + for (auto const &face: cdt.finite_face_handles()) { + if (! face->info().in_domain(fct)) continue; // exterior triangle + if (face->info().processed) continue; // already reconstructed + for (int opposite_vertex = 0; opposite_vertex < 3; ++opposite_vertex) { + if (face->info().in_domain(fct) == face->neighbor(opposite_vertex)->info().in_domain(fct)) continue; // not adjacent to boundary + + // Reconstruct ring + std::list ring; + reconstruct_ring(ring, face, opposite_vertex, fct); + + // Put ring in polygons + Polygon_2 polygon; + polygon.reserve(ring.size()); + polygon.insert(polygon.vertices_end(), ring.begin(), ring.end()); + if (polygon.orientation() == CGAL::COUNTERCLOCKWISE) { + polygons[face->info().label-1] = std::move(polygon); + } else { + holes[face->info().label-1].insert(std::move(polygon)); + } break; + } + } + + // Create polygons with holes and put in multipolygon + std::set ordered_polygons; + for (std::size_t i = 0; i < polygons.size(); ++i) { + ordered_polygons.insert(Polygon_with_holes_2(std::move(polygons[i]), + std::make_move_iterator(holes[i].begin()), + std::make_move_iterator(holes[i].end()))); + } + for (auto const& polygon: ordered_polygons) { + mp.add_polygon_with_holes(std::move(polygon)); + } + return mp; + } + + +/*! +access to the underlying constrained triangulation. +*/ + const CDTplus& + triangulation() const + { + return cdt; + } + +}; + + + +} // namespace Polygon_repair +} //namespace CGAL + +#endif // CGAL_POLYGON_REPAIR_BOOLEAN_H diff --git a/Polygon_repair/include/CGAL/Polygon_repair/Even_odd_rule.h b/Polygon_repair/include/CGAL/Polygon_repair/Even_odd_rule.h index b2dc51bfe36..372fb2479ee 100644 --- a/Polygon_repair/include/CGAL/Polygon_repair/Even_odd_rule.h +++ b/Polygon_repair/include/CGAL/Polygon_repair/Even_odd_rule.h @@ -18,11 +18,15 @@ namespace CGAL { namespace Polygon_repair { -/// \addtogroup PkgPolygonRepairRef +/// \addtogroup PkgPolygonRepairRules /// @{ /*! Tag class to select the even odd rule when calling `CGAL::Polygon_repair::repair()`. + The even-odd rule results in areas that are alternately assigned as polygon +interiors and exterior/holes each time that an input edge is passed. +It does not distinguish between edges that are part of outer boundaries +from those of inner boundaries. */ struct Even_odd_rule {}; diff --git a/Polygon_repair/include/CGAL/Polygon_repair/Intersection_rule.h b/Polygon_repair/include/CGAL/Polygon_repair/Intersection_rule.h new file mode 100644 index 00000000000..7c2984b3c2d --- /dev/null +++ b/Polygon_repair/include/CGAL/Polygon_repair/Intersection_rule.h @@ -0,0 +1,38 @@ +// Copyright (c) 2024 GeometryFactory. +// 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) : Andreas Fabri + +#ifndef CGAL_POLYGON_REPAIR_INTERSECTION_RULE_H +#define CGAL_POLYGON_REPAIR_INTERSECTION_RULE_H + +#include + +namespace CGAL { + +namespace Polygon_repair { + +/// \addtogroup PkgPolygonRepairRules +/// @{ + +/*! + Tag class to select the %intersection rule when calling `CGAL::Polygon_repair::repair()`. + The intersection rule are useful when given +two or more similar valid polygons with holes. +The intersection rule results in areas that are contained in all input polygons with holes. + */ + struct Intersection_rule {}; + +///@} + +} // namespace Polygon_repair + +} // namespace CGAL + +#endif // CGAL_POLYGON_REPAIR_INTERSECTION_RULE_H diff --git a/Polygon_repair/include/CGAL/Polygon_repair/Non_zero_rule.h b/Polygon_repair/include/CGAL/Polygon_repair/Non_zero_rule.h new file mode 100644 index 00000000000..8df2f32ad61 --- /dev/null +++ b/Polygon_repair/include/CGAL/Polygon_repair/Non_zero_rule.h @@ -0,0 +1,36 @@ +// Copyright (c) 2024 GeometryFactory. +// 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) : Andreas Fabri + +#ifndef CGAL_POLYGON_REPAIR_NON_ZERO_RULE_H +#define CGAL_POLYGON_REPAIR_NON_ZERO_RULE_H + +#include + +namespace CGAL { + +namespace Polygon_repair { + +/// \addtogroup PkgPolygonRepairRules +/// @{ + +/*! + Tag class to select the non zero rule when calling `CGAL::Polygon_repair::repair()`. + The non-zero rule results in areas with a non-zero winding number. + */ + struct Non_zero_rule {}; + +///@} + +} // namespace Polygon_repair + +} // namespace CGAL + +#endif // CGAL_POLYGON_REPAIR_NON_ZERO_RULE_H diff --git a/Polygon_repair/include/CGAL/Polygon_repair/Union_rule.h b/Polygon_repair/include/CGAL/Polygon_repair/Union_rule.h new file mode 100644 index 00000000000..fbba8d1cbed --- /dev/null +++ b/Polygon_repair/include/CGAL/Polygon_repair/Union_rule.h @@ -0,0 +1,37 @@ +// Copyright (c) 2024 GeometryFactory. +// 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) : Andreas Fabri + +#ifndef CGAL_POLYGON_REPAIR_UNION_RULE_H +#define CGAL_POLYGON_REPAIR_UNION_RULE_H + +#include + +namespace CGAL { + +namespace Polygon_repair { + +/// \addtogroup PkgPolygonRepairRules +/// @{ + +/*! + Tag class to select the %union rule when calling `CGAL::Polygon_repair::repair()`. + The union rules are useful when given two or more similar valid polygons with holes. +The union rule results in areas that are contained in at least one of the input polygons with holes. + */ + struct Union_rule {}; + +///@} + +} // namespace Polygon_repair + +} // namespace CGAL + +#endif // CGAL_POLYGON_REPAIR_UNION_RULE_H diff --git a/Polygon_repair/include/CGAL/Polygon_repair/Winding.h b/Polygon_repair/include/CGAL/Polygon_repair/Winding.h new file mode 100644 index 00000000000..c40865c67e7 --- /dev/null +++ b/Polygon_repair/include/CGAL/Polygon_repair/Winding.h @@ -0,0 +1,354 @@ +// Copyright (c) 2024 GeometryFactory SARL (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) : Andreas Fabri + +#ifndef CGAL_POLYGON_REPAIR_WINDING_H +#define CGAL_POLYGON_REPAIR_WINDING_H + +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include + +namespace CGAL { +namespace Polygon_repair { + +#ifndef DOXYGEN_RUNNING +/* +\ingroup PkgPolygonRepairFunctions + +\tparam Kernel must be +*/ + +template +class Winding { + +private: + struct FaceInfo { + + FaceInfo() + {} + + int wind; + int label; + int nesting_level[2]; + bool processed; + + bool + in_domain(int i) const + { + return nesting_level[i] % 2 == 1; + } + + template + bool + in_domain(const Fct& fct) const + { + return fct(in_domain(0), in_domain(1)); + } + + }; + + using K = Kernel; + using Point_2 = typename K::Point_2; + using Polygon_2 = CGAL::Polygon_2; + using Polygon_with_holes_2 = CGAL::Polygon_with_holes_2; + using Multipolygon_with_holes_2 = CGAL::Multipolygon_with_holes_2; + + using Itag = std::conditional_t, Exact_predicates_tag, Exact_intersections_tag>; + using Vb = CGAL::Triangulation_vertex_base_2; + using Fbb = CGAL::Triangulation_face_base_with_info_2; + using Fb = CGAL::Constrained_triangulation_face_base_2; + using Tds = CGAL::Triangulation_data_structure_2; + using CDT = CGAL::Constrained_Delaunay_triangulation_2; + using CDTplus = CGAL::Constrained_triangulation_plus_2; + using Face_handle = typename CDTplus::Face_handle; + using Face_circulator = typename CDTplus::Face_circulator; + using Vertex_handle = typename CDTplus::Vertex_handle; + using Constraint_id = typename CDTplus::Constraint_id; + using Edge = typename CDTplus::Edge; + using Context = typename CDTplus::Context; + + CDTplus cdt; + constexpr static int uninitialized = std::numeric_limits::lowest(); + + + struct Polygon_less { + bool operator()(const Polygon_2& pa, const Polygon_2& pb) const { + typename Polygon_2::Vertex_iterator va = pa.vertices_begin(); + typename Polygon_2::Vertex_iterator vb = pb.vertices_begin(); + while (va != pa.vertices_end() && vb != pb.vertices_end()) { + if (*va != *vb) return *va < *vb; + ++va; + ++vb; + } + if (vb == pb.vertices_end()) return false; + return true; + } + }; + + struct Polygon_with_holes_less { + Polygon_less pl; + bool operator()(const Polygon_with_holes_2& pa, const Polygon_with_holes_2& pb) const { + if (pl(pa.outer_boundary(), pb.outer_boundary())) return true; + if (pl(pb.outer_boundary(), pa.outer_boundary())) return false; + typename Polygon_with_holes_2::Hole_const_iterator ha = pa.holes_begin(); + typename Polygon_with_holes_2::Hole_const_iterator hb = pb.holes_begin(); + while (ha != pa.holes_end() && hb != pb.holes_end()) { + if (pl(*ha, *hb)) return true; + if (pl(*hb, *ha)) return false; + } + if (hb == pb.holes_end()) return false; + return true; + } + }; + +public: + +/*! +default constructor. +*/ + Winding() = default; + + +/*! +sets the polygon as input of the winding number computation. +*/ + void + insert(const Polygon_2& p) + { + Constraint_id cidA = cdt.insert_constraint(p.vertices_begin(), p.vertices_end(), true); + } + +/*! +sets the polygon as input of the winding number computation. +*/ + void + insert(const Polygon_with_holes_2& pwh) + { + Constraint_id cidA = cdt.insert_constraint(pwh.outer_boundary().vertices_begin(), pwh.outer_boundary().vertices_end(), true); + for(auto const& hole : pwh.holes()){ + cidA = cdt.insert_constraint(hole.vertices_begin(), hole.vertices_end(), true); + } + } + +/*! +sets the polygon as input of the winding number computation. +*/ + void + insert(const Multipolygon_with_holes_2& mpwh) + { + for(const auto& pwh : mpwh.polygons_with_holes()){ + Constraint_id cidA = cdt.insert_constraint(pwh.outer_boundary().vertices_begin(), pwh.outer_boundary().vertices_end(), true); + for(auto const& hole : pwh.holes()){ + cidA = cdt.insert_constraint(hole.vertices_begin(), hole.vertices_end(), true); + } + } + } + + void label(Face_handle f, int index, std::list>& border) + { + std::list queue; + queue.push_back(f); + while(! queue.empty()){ + Face_handle fh = queue.front(); + queue.pop_front(); + fh->info().wind = index; + for(int i = 0; i < 3; i++){ + Edge e(fh,i); + Face_handle n = fh->neighbor(i); + if(! cdt.is_constrained(e)){ + if(n->info().wind != index){ + queue.push_back(n); + } + }else{ + if(n->info().wind == uninitialized){ + Vertex_handle u = e.first->vertex(cdt.cw(e.second)); + Vertex_handle v = e.first->vertex(cdt.ccw(e.second)); + int delta = 0; + for(Context c : cdt.contexts(u,v)){ + if(*c.current() ==u && *std::next(c.current()) == v){ + ++delta; + }else if(*c.current() ==v && *std::next(c.current()) == u){ + --delta; + }else{ + CGAL_assertion(false); + } + } + border.push_back(std::make_pair(Edge(n,n->index(fh)),index+delta)); + } + } + } + } + } + + void label() + { + std::list> border; + for(Face_handle f : cdt.all_face_handles()){ + f->info().wind = uninitialized; + } + int index = 0; + label(cdt.infinite_face(),index++, border); + while(! border.empty()){ + Edge e; + int wind; + std::tie(e,wind) = border.front(); + border.pop_front(); + if(e.first->info().wind == uninitialized){ + label(e.first, wind,border); + }else{ + CGAL_assertion(e.first->info().wind == wind); + } + } + } + + void + label_domain(Face_handle start, int label) + { + std::list queue; + queue.push_back(start); + + while(! queue.empty()){ + Face_handle fh = queue.front(); + queue.pop_front(); + fh->info().label = label; + + for(int i = 0; i < 3; i++){ + Face_handle n = fh->neighbor(i); + if(n->info().wind != 0 && n->info().label == 0){ + queue.push_back(n); + } + } + } + } + + int + label_domains() + { + for (auto const face: cdt.all_face_handles()) { + face->info().processed = false; + face->info().label = 0; + } + int label = 1; + for (auto const face: cdt.all_face_handles()) { + if(face->info().wind != 0 && face->info().label == 0){ + label_domain(face, label); + ++label; + } + } + return label; + } + + void + reconstruct_ring(std::list& ring, + Face_handle face_adjacent_to_boundary, + int opposite_vertex) + { + // Create ring + Face_handle current_face = face_adjacent_to_boundary; + int current_opposite_vertex = opposite_vertex; + CGAL_assertion(face_adjacent_to_boundary->info().wind != 0); + do { + current_face->info().processed = true; + Vertex_handle pivot_vertex = current_face->vertex(current_face->cw(current_opposite_vertex)); + // std::cout << "\tAdding point " << pivot_vertex->point() << std::endl; + ring.push_back(pivot_vertex->point()); + Face_circulator fc = cdt.incident_faces(pivot_vertex, current_face); + do { + ++fc; + } while (fc->info().label != current_face->info().label); + current_face = fc; + current_opposite_vertex = fc->cw(fc->index(pivot_vertex)); + } while (current_face != face_adjacent_to_boundary || + current_opposite_vertex != opposite_vertex); + + // Start at lexicographically smallest vertex + typename std::list::iterator smallest_vertex = ring.begin(); + for (typename std::list::iterator current_vertex = ring.begin(); + current_vertex != ring.end(); ++current_vertex) { + if (*current_vertex < *smallest_vertex) smallest_vertex = current_vertex; + } + if (ring.front() != *smallest_vertex) { + ring.splice(ring.begin(), ring, smallest_vertex, ring.end()); + } + } + + Multipolygon_with_holes_2 + operator()() + { + int number_of_polygons = label_domains() - 1; + + Multipolygon_with_holes_2 mp; + std::vector polygons; // outer boundaries + std::vector> holes; // holes are ordered (per polygon) + polygons.resize(number_of_polygons); + holes.resize(number_of_polygons); + + for (auto const face: cdt.all_face_handles()) { + face->info().processed = false; + } + + for (auto const &face: cdt.finite_face_handles()) { + if (face->info().wind==0) continue; // exterior triangle + if (face->info().processed) continue; // already reconstructed + for (int opposite_vertex = 0; opposite_vertex < 3; ++opposite_vertex) { + + if ((face->info().wind != 0) == (face->neighbor(opposite_vertex)->info().wind != 0)) continue; // not adjacent to boundary + + // Reconstruct ring + std::list ring; + reconstruct_ring(ring, face, opposite_vertex); + + // Put ring in polygons + Polygon_2 polygon; + polygon.reserve(ring.size()); + polygon.insert(polygon.vertices_end(), ring.begin(), ring.end()); + if (polygon.orientation() == CGAL::COUNTERCLOCKWISE) { + polygons[face->info().label-1] = std::move(polygon); + } else { + holes[face->info().label-1].insert(std::move(polygon)); + } break; + } + } + + // Create polygons with holes and put in multipolygon + std::set ordered_polygons; + for (std::size_t i = 0; i < polygons.size(); ++i) { + ordered_polygons.insert(Polygon_with_holes_2(std::move(polygons[i]), + std::make_move_iterator(holes[i].begin()), + std::make_move_iterator(holes[i].end()))); + } + for (auto const& polygon: ordered_polygons) { + mp.add_polygon_with_holes(std::move(polygon)); + } + return mp; + } + +}; + +#endif + +} // namespace Polygon_repair + +} // namespace CGAL + +#endif // CGAL_POLYGON_REPAIR_WINDING_H diff --git a/Polygon_repair/include/CGAL/Polygon_repair/internal/Triangulation_with_even_odd_constraints_2.h b/Polygon_repair/include/CGAL/Polygon_repair/internal/Triangulation_with_even_odd_constraints_2.h index e75be739e61..1203d1882a2 100644 --- a/Polygon_repair/include/CGAL/Polygon_repair/internal/Triangulation_with_even_odd_constraints_2.h +++ b/Polygon_repair/include/CGAL/Polygon_repair/internal/Triangulation_with_even_odd_constraints_2.h @@ -9,8 +9,8 @@ // // Author(s) : Ken Arroyo Ohori -#ifndef CGAL_TRIANGULATION_WITH_EVEN_ODD_CONSTRAINTS_2_H -#define CGAL_TRIANGULATION_WITH_EVEN_ODD_CONSTRAINTS_2_H +#ifndef CGAL_POLYGON_REPAIR_TRIANGULATION_WITH_EVEN_ODD_CONSTRAINTS_2_H +#define CGAL_POLYGON_REPAIR_TRIANGULATION_WITH_EVEN_ODD_CONSTRAINTS_2_H #include #include @@ -124,4 +124,4 @@ public: } // namespace Polygon_repair } // namespace CGAL -#endif // CGAL_TRIANGULATION_WITH_EVEN_ODD_CONSTRAINTS_2_H +#endif // CGAL_POLYGON_REPAIR_TRIANGULATION_WITH_EVEN_ODD_CONSTRAINTS_2_H diff --git a/Polygon_repair/include/CGAL/Polygon_repair/repair.h b/Polygon_repair/include/CGAL/Polygon_repair/repair.h index f6f2e84cfee..03961636059 100644 --- a/Polygon_repair/include/CGAL/Polygon_repair/repair.h +++ b/Polygon_repair/include/CGAL/Polygon_repair/repair.h @@ -24,9 +24,14 @@ #include #include #include +#include +#include +#include #include #include +#include +#include namespace CGAL { @@ -39,9 +44,9 @@ class Polygon_repair; /// \ingroup PkgPolygonRepairFunctions /// repairs polygon `p` using the given rule -/// \tparam Kernel parameter of the input and output polygons +/// \tparam Kernel parameter of the input and output polygons. Must be model of `ConstrainedDelaunayTriangulationTraits_2 ` /// \tparam Container parameter of the input and output polygons -/// \tparam Rule must be `Even_odd_rule` +/// \tparam Rule must be `Even_odd_rule` or `Non_zero_rule` template Multipolygon_with_holes_2 repair(const Polygon_2& p , Rule = Rule()) { @@ -56,9 +61,9 @@ Multipolygon_with_holes_2 repair(const Polygon_2 Multipolygon_with_holes_2 repair(const Polygon_with_holes_2& p, Rule = Rule()) { @@ -71,11 +76,24 @@ Multipolygon_with_holes_2 repair(const Polygon_with_holes_2 +Multipolygon_with_holes_2 repair(const Polygon_with_holes_2& p, Non_zero_rule) +{ + Winding winding; + winding.insert(p); + winding.label(); + winding.label_domains(); + return winding(); +} + + /// \ingroup PkgPolygonRepairFunctions /// repairs multipolygon with holes `p` using the given rule -/// \tparam Kernel parameter of the input and output polygons +/// \tparam Kernel parameter of the input and output polygons. Must be model of `ConstrainedDelaunayTriangulationTraits_2 ` /// \tparam Container parameter of the input and output polygons -/// \tparam Rule must be `Even_odd_rule` +/// \tparam Rule may be any \ref PkgPolygonRepairRules +/// \pre If the rule is the `Union_rule` or `Non_zero_rule`, each polygon with hole must be free of self-intersections template Multipolygon_with_holes_2 repair(const Multipolygon_with_holes_2& p, Rule = Rule()) { @@ -88,6 +106,61 @@ Multipolygon_with_holes_2 repair(const Multipolygon_with_hole } return pr.multipolygon(); } + +template +Multipolygon_with_holes_2 repair(const Multipolygon_with_holes_2& p, Union_rule) +{ + struct Larger_than_zero { + bool operator()(int i) const + { + return i > 0; + } + }; + + CGAL::Polygon_repair::Boolean bops; + bops.insert(p); + bops.mark_domains(); + Larger_than_zero ltz; + return bops(ltz); +} + + +template +Multipolygon_with_holes_2 repair(const Multipolygon_with_holes_2& p, Intersection_rule) +{ + struct Equal { + int val; + Equal(int val) + : val(val) + {} + + bool operator()(int i) const + { + return i == val; + } + }; + + CGAL::Polygon_repair::Boolean bops; + bops.insert(p); + bops.mark_domains(); + Equal equal(p.number_of_polygons_with_holes()); + return bops(equal); +} + +/* +template +Multipolygon_with_holes_2 repair(const Multipolygon_with_holes_2& p, Non_zero_rule rule) +{ + static_assert(std::is_same_v); + CGAL::Polygon_repair::Polygon_repair pr; + pr.add_to_triangulation_even_odd(p); + if (pr.triangulation().number_of_faces() > 0) { + pr.label_triangulation_even_odd(); + pr.reconstruct_multipolygon(); + } return pr.multipolygon(); +} +*/ + template bool is_valid(const Polygon_2& polygon) { if (polygon.vertices().size() < 3) { @@ -514,7 +587,7 @@ public: static void label_region(T& tt, Face_handle face, int label, std::list& to_check, std::list& to_check_added_by) { - // std::cout << "Labelling region with " << label << std::endl; + // std::cout << "Labeling region with " << label << std::endl; std::list to_check_in_region; face->label() = label; to_check_in_region.push_back(face); @@ -712,6 +785,127 @@ protected: #endif // DOXYGEN_RUNNING + + +/// \ingroup PkgPolygonRepairFunctions +/// computes the union of all polygons with holes in `p` +/// \tparam Kernel parameter of the input and output polygons. Must be model of `ConstrainedDelaunayTriangulationTraits_2 ` +/// \tparam Container parameter of the input and output polygons +/// \pre Each polygon with hole must be free of self-intersections +template +Multipolygon_with_holes_2 +join(const Multipolygon_with_holes_2& pa) +{ + struct Larger_than_zero { + bool operator()(int i) const + { + return i > 0; + } + }; + + CGAL::Polygon_repair::Boolean bops; + bops.insert(pa); + bops.mark_domains(); + Larger_than_zero ltz; + return bops(ltz); +} + +/// \ingroup PkgPolygonRepairFunctions +/// computes the union of two polygonal domains +/// \tparam Kernel parameter of the output polygons. Must be model of `ConstrainedDelaunayTriangulationTraits_2 ` +/// \tparam Container parameter of the input and output polygons +/// \tparam PA must be `Polygon_2`, or `Polygon_with_holes_2`, or `Multipolygon_with_holes_2` +/// \tparam PB must be `Polygon_2`, or `Polygon_with_holes_2`, or `Multipolygon_with_holes_2` +/// \pre The polygons `pa` and `pb` must be free of self-intersections +template +#ifdef DOXYGEN_RUNNING +Multipolygon_with_holes_2 +#else +decltype(auto) +#endif +join(const PA& pa, const PB& pb, const Kernel& = Default(), const Container& = Default()) +{ + typedef typename Default::Get::type Traits; + typedef typename Default::Get::type Container_; + + struct Larger_than_zero { + bool operator()(int i) const + { + return i > 0; + } + }; + + CGAL::Polygon_repair::Boolean bops; + bops.insert(pa); + bops.insert(pb); + bops.mark_domains(); + Larger_than_zero ltz; + return bops(ltz); +} + + +/// \ingroup PkgPolygonRepairFunctions +/// computes the intersection of all polygons with holes in `p` +/// \tparam Kernel parameter of the input and output polygons. Must be model of `ConstrainedDelaunayTriangulationTraits_2 ` +/// \tparam Container parameter of the input and output polygons +/// \pre Each polygon with hole must be free of self-intersections +template +Multipolygon_with_holes_2 +intersect(const Multipolygon_with_holes_2& p) +{ + struct Equal { + int val; + Equal(int val) + : val(val) + {} + + bool operator()(int i) const + { + return i == val; + } + }; + + CGAL::Polygon_repair::Boolean bops; + bops.insert(p); + bops.mark_domains(); + Equal equal(p.number_of_polygons_with_holes()); + return bops(equal); +} + + +/// \ingroup PkgPolygonRepairFunctions +/// computes the intersection of two polygonal domains +/// \tparam Kernel parameter of the output polygon. Must be model of `ConstrainedDelaunayTriangulationTraits_2 ` +/// \tparam Container parameter of the input and output polygons +/// \tparam PA must be `Polygon_2`, or `Polygon_with_holes_2`, or `Multipolygon_with_holes_2` +/// \tparam PB must be `Polygon_2`, or `Polygon_with_holes_2`, or `Multipolygon_with_holes_2` +/// \pre The polygons `pa` and `pb` must be free of self-intersections +template +#ifdef DOXYGEN_RUNNING +Multipolygon_with_holes_2 +#else +decltype(auto) +#endif +intersect(const PA& pa, const PB& pb, const Kernel& = Default(), const Container& = Default()) +{ + typedef typename Default::Get::type Traits; + typedef typename Default::Get::type Container_; + + struct Equal { + bool operator()(int i) const + { + return i == 2; + } + }; + + CGAL::Polygon_repair::Boolean bops; + bops.insert(pa); + bops.insert(pb); + bops.mark_domains(); + Equal equal; + return bops(equal); +} + } // namespace Polygon_repair } // namespace CGAL diff --git a/Polygon_repair/package_info/Polygon_repair/dependencies b/Polygon_repair/package_info/Polygon_repair/dependencies index 8231db1007e..517729e1d03 100644 --- a/Polygon_repair/package_info/Polygon_repair/dependencies +++ b/Polygon_repair/package_info/Polygon_repair/dependencies @@ -20,3 +20,4 @@ Spatial_sorting Stream_support TDS_2 Triangulation_2 +BGL diff --git a/Polyhedron/doc/Polyhedron/PackageDescription.txt b/Polyhedron/doc/Polyhedron/PackageDescription.txt index 7369093e05d..f0033c7efd7 100644 --- a/Polyhedron/doc/Polyhedron/PackageDescription.txt +++ b/Polyhedron/doc/Polyhedron/PackageDescription.txt @@ -13,7 +13,6 @@ /*! \addtogroup PkgPolyhedronRef -\todo check generated documentation \cgalPkgDescriptionBegin{3D Polyhedral Surface,PkgPolyhedron} \cgalPkgPicture{Polyhedron-teaser-small.png} \cgalPkgSummaryBegin diff --git a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/simplify.h b/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/simplify.h index 198928e2145..9e7fe636d01 100644 --- a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/simplify.h +++ b/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/simplify.h @@ -154,8 +154,11 @@ public: (*it)->set_removable(false); ++it; for(; it != ite; ++it){ - if((std::next(it) != ite) && (std::prev(it)== std::next(it))){ - (*it)->set_removable(false); + if(std::next(it) != ite){ + Vertex_handle vp = *std::prev(it), vn = *std::next(it); + if(vp == vn){ + (*it)->set_removable(false); + } } } it = std::prev(it); diff --git a/Polyline_simplification_2/test/Polyline_simplification_2/CMakeLists.txt b/Polyline_simplification_2/test/Polyline_simplification_2/CMakeLists.txt index be79ae27506..3ef613d9a83 100644 --- a/Polyline_simplification_2/test/Polyline_simplification_2/CMakeLists.txt +++ b/Polyline_simplification_2/test/Polyline_simplification_2/CMakeLists.txt @@ -8,5 +8,6 @@ project(Polyline_simplification_2_Tests) find_package(CGAL REQUIRED) create_single_source_cgal_program( "issue-5774.cpp" ) +create_single_source_cgal_program( "issue-8735.cpp" ) create_single_source_cgal_program( "simplify_polygon_test.cpp" ) create_single_source_cgal_program( "simplify_polyline_with_duplicate_points.cpp" ) diff --git a/Polyline_simplification_2/test/Polyline_simplification_2/issue-8735.cpp b/Polyline_simplification_2/test/Polyline_simplification_2/issue-8735.cpp new file mode 100644 index 00000000000..11f2cb75643 --- /dev/null +++ b/Polyline_simplification_2/test/Polyline_simplification_2/issue-8735.cpp @@ -0,0 +1,34 @@ +#include +#include +#include +#include + +namespace PS = CGAL::Polyline_simplification_2; +typedef CGAL::Exact_predicates_exact_constructions_kernel K; +typedef PS::Vertex_base_2 Vb; +typedef CGAL::Constrained_triangulation_face_base_2 Fb; +typedef CGAL::Triangulation_data_structure_2 TDS; +typedef CGAL::Constrained_Delaunay_triangulation_2 CDT; +typedef CGAL::Constrained_triangulation_plus_2 CT; +typedef CT::Point Point; +typedef PS::Stop_above_cost_threshold Stop; +typedef PS::Squared_distance_cost Cost; + +int main() +{ + double tolerance = 100; + CT ct; + std::vector pts; + + pts.push_back(CT::Point(0, 0)); + pts.push_back(CT::Point(2, 0)); + pts.push_back(CT::Point(1, 0)); + pts.push_back(CT::Point(3, 0)); + pts.push_back(CT::Point(4, 1)); + tolerance = 100; + ct.insert_constraint(pts.begin(), pts.end(), false); + + PS::simplify(ct, Cost(), Stop(tolerance * tolerance), false); + + return 0; +} diff --git a/Polynomial/doc/Polynomial/PackageDescription.txt b/Polynomial/doc/Polynomial/PackageDescription.txt index 0f1de49b78b..96273a5ada8 100644 --- a/Polynomial/doc/Polynomial/PackageDescription.txt +++ b/Polynomial/doc/Polynomial/PackageDescription.txt @@ -9,7 +9,6 @@ /// \ingroup PkgPolynomialRef /*! \addtogroup PkgPolynomialRef -\todo check generated documentation \cgalPkgDescriptionBegin{Polynomial,PkgPolynomial} \cgalPkgPicture{Polynomial.png} \cgalPkgSummaryBegin diff --git a/Polytope_distance_d/doc/Polytope_distance_d/PackageDescription.txt b/Polytope_distance_d/doc/Polytope_distance_d/PackageDescription.txt index aaecb2b37da..b49377cf9ed 100644 --- a/Polytope_distance_d/doc/Polytope_distance_d/PackageDescription.txt +++ b/Polytope_distance_d/doc/Polytope_distance_d/PackageDescription.txt @@ -4,7 +4,6 @@ /*! \addtogroup PkgPolytopeDistanceDRef -\todo check generated documentation \cgalPkgDescriptionBegin{Optimal Distances,PkgPolytopeDistanceD} \cgalPkgPicture{dist.png} \cgalPkgSummaryBegin diff --git a/Principal_component_analysis/doc/Principal_component_analysis/PackageDescription.txt b/Principal_component_analysis/doc/Principal_component_analysis/PackageDescription.txt index c1640a1188d..03acad4f33b 100644 --- a/Principal_component_analysis/doc/Principal_component_analysis/PackageDescription.txt +++ b/Principal_component_analysis/doc/Principal_component_analysis/PackageDescription.txt @@ -17,7 +17,6 @@ /*! \addtogroup PkgPrincipalComponentAnalysisDRef -\todo check generated documentation \cgalPkgDescriptionBegin{Principal Component Analysis,PkgPrincipalComponentAnalysisD} \cgalPkgPicture{teaserLeastSquaresFitting.png} \cgalPkgSummaryBegin diff --git a/QP_solver/doc/QP_solver/PackageDescription.txt b/QP_solver/doc/QP_solver/PackageDescription.txt index e63fc8a3310..0da82f7f3b6 100644 --- a/QP_solver/doc/QP_solver/PackageDescription.txt +++ b/QP_solver/doc/QP_solver/PackageDescription.txt @@ -72,7 +72,6 @@ Programs can be written to an output stream in MPSFormat, using one of the follo /*! \addtogroup PkgQPSolverRef -\todo check generated documentation \cgalPkgDescriptionBegin{Linear and Quadratic Programming Solver,PkgQPSolver} \cgalPkgPicture{qp.png} \cgalPkgSummaryBegin diff --git a/Ridges_3/doc/Ridges_3/PackageDescription.txt b/Ridges_3/doc/Ridges_3/PackageDescription.txt index d34109ac8e3..5c06986a879 100644 --- a/Ridges_3/doc/Ridges_3/PackageDescription.txt +++ b/Ridges_3/doc/Ridges_3/PackageDescription.txt @@ -5,7 +5,6 @@ /*! \addtogroup PkgRidges3Ref -\todo check generated documentation \cgalPkgDescriptionBegin{Approximation of Ridges and Umbilics on Triangulated Surface Meshes,PkgRidges3} \cgalPkgPicture{RidgesMechPartDetail.png} \cgalPkgSummaryBegin diff --git a/Ridges_3/examples/Ridges_3/PolyhedralSurf_rings.h b/Ridges_3/examples/Ridges_3/PolyhedralSurf_rings.h index c3e5aefec98..72f9add2cb7 100644 --- a/Ridges_3/examples/Ridges_3/PolyhedralSurf_rings.h +++ b/Ridges_3/examples/Ridges_3/PolyhedralSurf_rings.h @@ -64,7 +64,7 @@ T_PolyhedralSurf_rings(const TPoly& P) { //init the ring_index_map Vertex_const_iterator itb, ite; - boost::tie(itb,ite) = vertices(P); + std::tie(itb,ite) = vertices(P); for(;itb!=ite;itb++) ring_index_map[*itb] = -1; } diff --git a/Ridges_3/include/CGAL/PolyhedralSurf_neighbors.h b/Ridges_3/include/CGAL/PolyhedralSurf_neighbors.h index 775fec7d89d..5d4c57f7b43 100644 --- a/Ridges_3/include/CGAL/PolyhedralSurf_neighbors.h +++ b/Ridges_3/include/CGAL/PolyhedralSurf_neighbors.h @@ -158,7 +158,7 @@ T_PolyhedralSurf_neighbors(const TriangleMesh& P) { //init the is_visited_map Vertex_const_iterator itb, ite; - boost::tie(itb,ite) = vertices(P); + std::tie(itb,ite) = vertices(P); for(;itb!=ite;itb++) is_visited_map[*itb] = false; } diff --git a/Ridges_3/include/CGAL/Ridges.h b/Ridges_3/include/CGAL/Ridges.h index d4052642864..c52aef7081b 100644 --- a/Ridges_3/include/CGAL/Ridges.h +++ b/Ridges_3/include/CGAL/Ridges.h @@ -336,7 +336,7 @@ Ridge_approximation(const TriangleMesh &p, { //init the is_visited_map and check that the mesh is a triangular one. face_iterator itb,ite; - boost::tie(itb,ite) = faces(P); + std::tie(itb,ite) = faces(P); for(;itb!=ite;itb++) { is_visited_map[*itb] = false; } @@ -411,10 +411,10 @@ compute_ridges(Ridge_interrogation_type r_type, OutputIterator ridge_lines_it, R //reinit the is_visited_map face_iterator itb,ite; - boost::tie(itb,ite) = faces(P); + std::tie(itb,ite) = faces(P); for(;itb!=ite;itb++) is_visited_map[*itb] = false; - boost::tie(itb,ite) = faces(P); + std::tie(itb,ite) = faces(P); for(;itb!=ite;itb++) { face_descriptor f = *itb; diff --git a/Ridges_3/include/CGAL/Umbilics.h b/Ridges_3/include/CGAL/Umbilics.h index f815b9c18ca..e56e0f000b8 100644 --- a/Ridges_3/include/CGAL/Umbilics.h +++ b/Ridges_3/include/CGAL/Umbilics.h @@ -184,7 +184,7 @@ compute(OutputIterator umbilics_it, FT size) //MAIN loop on P vertices Vertex_const_iterator itb, ite; - boost::tie(itb,ite) = vertices(P); + std::tie(itb,ite) = vertices(P); for (;itb != ite; itb++) { vertex_descriptor vh = *itb; umbilicEstimatorVertex = cgal_abs(get(k1,vh)-get(k2,vh)); diff --git a/Ridges_3/test/Ridges_3/PolyhedralSurf_rings.h b/Ridges_3/test/Ridges_3/PolyhedralSurf_rings.h index c3e5aefec98..72f9add2cb7 100644 --- a/Ridges_3/test/Ridges_3/PolyhedralSurf_rings.h +++ b/Ridges_3/test/Ridges_3/PolyhedralSurf_rings.h @@ -64,7 +64,7 @@ T_PolyhedralSurf_rings(const TPoly& P) { //init the ring_index_map Vertex_const_iterator itb, ite; - boost::tie(itb,ite) = vertices(P); + std::tie(itb,ite) = vertices(P); for(;itb!=ite;itb++) ring_index_map[*itb] = -1; } diff --git a/SMDS_3/include/CGAL/Compact_simplicial_mesh_cell_base_3.h b/SMDS_3/include/CGAL/Compact_simplicial_mesh_cell_base_3.h index 92272897094..9f26f6f3b29 100644 --- a/SMDS_3/include/CGAL/Compact_simplicial_mesh_cell_base_3.h +++ b/SMDS_3/include/CGAL/Compact_simplicial_mesh_cell_base_3.h @@ -47,20 +47,7 @@ public: public: // Constructors - Compact_simplicial_mesh_cell_3() - : time_stamp_(std::size_t(-1)) - {} - - Compact_simplicial_mesh_cell_3(const Compact_simplicial_mesh_cell_3& rhs) - : N(rhs.N) - , V(rhs.V) - , time_stamp_(rhs.time_stamp_) - , subdomain_index_(rhs.subdomain_index_) - { - for(int i=0; i <4; i++){ - surface_index_table_[i] = rhs.surface_index_table_[i]; - } - } + Compact_simplicial_mesh_cell_3() = default; Compact_simplicial_mesh_cell_3(Vertex_handle v0, Vertex_handle v1, @@ -279,7 +266,7 @@ private: std::array N; std::array V; - std::size_t time_stamp_; + std::size_t time_stamp_ = std::size_t(-2); // The index of the cell of the input complex that contains me Subdomain_index subdomain_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 19fd269cc32..6255bb26104 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 @@ -2034,6 +2034,7 @@ Mesh_complex_3_in_triangulation_3:: rescan_after_load_of_triangulation() { corners_.clear(); + far_vertices_.clear(); for(typename Tr::Finite_vertices_iterator vit = this->triangulation().finite_vertices_begin(), end = this->triangulation().finite_vertices_end(); @@ -2041,6 +2042,8 @@ rescan_after_load_of_triangulation() { if ( vit->in_dimension() == 0 ) { add_to_complex(vit, Corner_index(1)); + } else if(vit->in_dimension() == -1) { + far_vertices_.push_back(vit); } } diff --git a/SMDS_3/include/CGAL/Simplicial_mesh_cell_base_3.h b/SMDS_3/include/CGAL/Simplicial_mesh_cell_base_3.h index 8ed8d332f59..a9a98b155ba 100644 --- a/SMDS_3/include/CGAL/Simplicial_mesh_cell_base_3.h +++ b/SMDS_3/include/CGAL/Simplicial_mesh_cell_base_3.h @@ -96,9 +96,7 @@ public: }; public: - Simplicial_mesh_cell_base_3() - : time_stamp_(std::size_t(-1)) - {} + Simplicial_mesh_cell_base_3() = default; Simplicial_mesh_cell_base_3(const Simplicial_mesh_cell_base_3& rhs) : Cb(static_cast(rhs)), @@ -191,7 +189,7 @@ private: /// Stores surface_index for each facet of the cell std::array surface_index_table_ = {}; - std::size_t time_stamp_; + std::size_t time_stamp_ = std::size_t(-2); // The index of the cell of the input complex that contains me Subdomain_index subdomain_index_ = {}; diff --git a/SMDS_3/include/CGAL/Simplicial_mesh_vertex_base_3.h b/SMDS_3/include/CGAL/Simplicial_mesh_vertex_base_3.h index 96a2377355c..1a15aaf09d7 100644 --- a/SMDS_3/include/CGAL/Simplicial_mesh_vertex_base_3.h +++ b/SMDS_3/include/CGAL/Simplicial_mesh_vertex_base_3.h @@ -130,7 +130,6 @@ public: , index_() , dimension_(-1) , cache_validity(false) - , time_stamp_(std::size_t(-1)) {} // Default copy constructor and assignment operator are ok @@ -218,7 +217,7 @@ private: // that contains me. Negative values are a marker for special vertices. short dimension_; bool cache_validity; - std::size_t time_stamp_; + std::size_t time_stamp_ = std::size_t(-2); public: friend std::istream& operator>>(std::istream& is, diff --git a/STL_Extension/doc/STL_Extension/CGAL/Iterator_range.h b/STL_Extension/doc/STL_Extension/CGAL/Iterator_range.h index 1c28472d34d..5331aaca8ab 100644 --- a/STL_Extension/doc/STL_Extension/CGAL/Iterator_range.h +++ b/STL_Extension/doc/STL_Extension/CGAL/Iterator_range.h @@ -21,7 +21,7 @@ namespace CGAL { \ingroup PkgSTLExtensionRef `CGAL::Iterator_range` encapsulates two iterators so they fulfill the `ForwardRange` concept. The class is essentially a clone of `boost::iterator_range`, - and it additionally is derived from `std::pair`, so that one can apply `boost::tie`. + and it additionally is derived from `std::pair`, so that one can apply `std::tie`. */ template class Iterator_range diff --git a/STL_Extension/include/CGAL/Compact_container.h b/STL_Extension/include/CGAL/Compact_container.h index 073300c8a82..9b6cb202e93 100644 --- a/STL_Extension/include/CGAL/Compact_container.h +++ b/STL_Extension/include/CGAL/Compact_container.h @@ -220,6 +220,10 @@ class Compact_container CGAL_INCREMENT_COMPACT_CONTAINER_BLOCK_SIZE> >::type Increment_policy; typedef TimeStamper_ Ts; + + template using EraseCounterStrategy = + internal::Erase_counter_strategy::value>; + typedef Compact_container Self; typedef Compact_container_traits Traits; public: @@ -354,7 +358,7 @@ public: return all_items[block_number].first[index_in_block]; } - friend void swap(Compact_container& a, Compact_container b) { + friend void swap(Compact_container& a, Compact_container b) noexcept { a.swap(b); } @@ -390,22 +394,16 @@ public: // (just forward the arguments to the constructor, to optimize a copy). template < typename... Args > iterator - emplace(const Args&... args) + emplace(Args&&... args) { if (free_list == nullptr) allocate_new_block(); pointer ret = free_list; free_list = clean_pointee(ret); - std::size_t ts; - CGAL_USE(ts); - if constexpr (Time_stamper::has_timestamp) { - ts = ret->time_stamp(); - } - new (ret) value_type(args...); - if constexpr (Time_stamper::has_timestamp) { - ret->set_time_stamp(ts); - } + const auto ts = Time_stamper::time_stamp(ret); + new (ret) value_type(std::forward(args)...); + Time_stamper::restore_timestamp(ret, ts); Time_stamper::set_time_stamp(ret, time_stamp); CGAL_assertion(type(ret) == USED); ++size_; @@ -414,24 +412,7 @@ public: iterator insert(const T &t) { - if (free_list == nullptr) - allocate_new_block(); - - pointer ret = free_list; - free_list = clean_pointee(ret); - std::size_t ts; - CGAL_USE(ts); - if constexpr (Time_stamper::has_timestamp) { - ts = ret->time_stamp(); - } - std::allocator_traits::construct(alloc, ret, t); - if constexpr (Time_stamper::has_timestamp) { - ret->set_time_stamp(ts); - } - Time_stamper::set_time_stamp(ret, time_stamp); - CGAL_assertion(type(ret) == USED); - ++size_; - return iterator(ret, 0); + return emplace(t); } template < class InputIterator > @@ -450,22 +431,14 @@ public: void erase(iterator x) { - typedef internal::Erase_counter_strategy< - internal::has_increment_erase_counter::value> EraseCounterStrategy; + auto ptr = &*x; + CGAL_precondition(type(ptr) == USED); + EraseCounterStrategy::increment_erase_counter(*x); + const auto ts = Time_stamper::time_stamp(ptr); + std::allocator_traits::destroy(alloc, ptr); + Time_stamper::restore_timestamp(ptr, ts); - CGAL_precondition(type(&*x) == USED); - EraseCounterStrategy::increment_erase_counter(*x); - std::size_t ts; - CGAL_USE(ts); - if constexpr (Time_stamper::has_timestamp) { - ts = x->time_stamp(); - } - std::allocator_traits::destroy(alloc, &*x); - if constexpr (Time_stamper::has_timestamp) { - x->set_time_stamp(ts); - } - - put_on_free_list(&*x); + put_on_free_list(ptr); --size_; } @@ -598,25 +571,7 @@ public: while ( capacity_= 1; --i) - put_on_free_list(new_block + i); + auto [new_block, block_size] = all_items[curblock]; + put_block_on_free_list(new_block, block_size - 2); } while ( curblock>lastblock ); } private: - void allocate_new_block(); +std::pair push_back_new_block(); +void put_block_on_free_list(pointer new_block, size_type block_size); + +void allocate_new_block(); void put_on_free_list(pointer x) { @@ -697,7 +654,7 @@ public: static bool is_begin_or_end(const_pointer ptr) { return type(ptr)==START_END; } - void swap(Self &c) + void swap(Self &c) noexcept { std::swap(alloc, c.alloc); std::swap(capacity_, c.capacity_); @@ -803,23 +760,13 @@ void Compact_container::clear() } template < class T, class Allocator, class Increment_policy, class TimeStamper > -void Compact_container::allocate_new_block() +auto Compact_container::push_back_new_block() + -> std::pair { - typedef internal::Erase_counter_strategy< - internal::has_increment_erase_counter::value> EraseCounterStrategy; - pointer new_block = alloc.allocate(block_size + 2); + std::pair result{new_block, block_size}; all_items.push_back(std::make_pair(new_block, block_size + 2)); capacity_ += block_size; - // We don't touch the first and the last one. - // We mark them free in reverse order, so that the insertion order - // will correspond to the iterator order... - for (size_type i = block_size; i >= 1; --i) - { - EraseCounterStrategy::set_erase_counter(*(new_block + i), 0); - Time_stamper::initialize_time_stamp(new_block + i); - put_on_free_list(new_block + i); - } // We insert this new block at the end. if (last_item == nullptr) // First time { @@ -836,8 +783,33 @@ void Compact_container::allocate_ne set_type(last_item, nullptr, START_END); // Increase the block_size for the next time. Increment_policy::increase_size(*this); + return result; } +template < class T, class Allocator, class Increment_policy, class TimeStamper > +void Compact_container:: +put_block_on_free_list(pointer new_block, size_type block_size) +{ + // The block actually has a size==block_size+2. + // We don't touch the first and the last one. + // We mark them free in reverse order, so that the insertion order + // will correspond to the iterator order... + for (size_type i = block_size; i >= 1; --i) + { + EraseCounterStrategy::set_erase_counter(*(new_block + i), 0); + Time_stamper::initialize_time_stamp(new_block + i); + put_on_free_list(new_block + i); + } +} + +template < class T, class Allocator, class Increment_policy, class TimeStamper > +void Compact_container::allocate_new_block() +{ + auto [new_block, block_size] = push_back_new_block(); + put_block_on_free_list(new_block, block_size); +} + + template < class T, class Allocator, class Increment_policy, class TimeStamper > inline bool operator==(const Compact_container &lhs, diff --git a/STL_Extension/include/CGAL/Concurrent_compact_container.h b/STL_Extension/include/CGAL/Concurrent_compact_container.h index 7f5533f92b7..653ea056e74 100644 --- a/STL_Extension/include/CGAL/Concurrent_compact_container.h +++ b/STL_Extension/include/CGAL/Concurrent_compact_container.h @@ -202,6 +202,9 @@ class Concurrent_compact_container typedef Concurrent_compact_container Self; typedef Concurrent_compact_container_traits Traits; + template using EraseCounterStrategy = + internal::Erase_counter_strategy::value>; + public: typedef CGAL::Time_stamper_impl Time_stamper; typedef Time_stamper Time_stamper_impl; // backward compatibility @@ -344,28 +347,21 @@ public: // (just forward the arguments to the constructor, to optimize a copy). template < typename... Args > iterator - emplace(const Args&... args) + emplace(Args&&... args) { - typedef CCC_internal::Erase_counter_strategy< - CCC_internal::has_increment_erase_counter::value> EraseCounterStrategy; FreeList * fl = get_free_list(); pointer ret = init_insert(fl); - auto erase_counter = EraseCounterStrategy::erase_counter(*ret);; - new (ret) value_type(args...); - EraseCounterStrategy::set_erase_counter(*ret, erase_counter); + auto erase_counter = EraseCounterStrategy::erase_counter(*ret); + const auto ts = Time_stamper::time_stamp(ret); + new (ret) value_type(std::forward(args)...); + Time_stamper::restore_timestamp(ret, ts); + EraseCounterStrategy::set_erase_counter(*ret, erase_counter); return finalize_insert(ret, fl); } iterator insert(const T &t) { - typedef CCC_internal::Erase_counter_strategy< - CCC_internal::has_increment_erase_counter::value> EraseCounterStrategy; - FreeList * fl = get_free_list(); - pointer ret = init_insert(fl); - auto erase_counter = EraseCounterStrategy::erase_counter(*ret);; - std::allocator_traits::construct(m_alloc, ret, t); - EraseCounterStrategy::set_erase_counter(*ret, erase_counter); - return finalize_insert(ret, fl); + return emplace(t); } template < class InputIterator > @@ -385,13 +381,13 @@ public: private: void erase(iterator x, FreeList * fl) { - typedef CCC_internal::Erase_counter_strategy< - CCC_internal::has_increment_erase_counter::value> EraseCounterStrategy; - CGAL_precondition(type(x) == USED); - EraseCounterStrategy::increment_erase_counter(*x); + EraseCounterStrategy::increment_erase_counter(*x); + auto ptr = &*x; + const auto ts = Time_stamper::time_stamp(ptr); std::allocator_traits::destroy(m_alloc, &*x); + Time_stamper::restore_timestamp(ptr, ts); put_on_free_list(&*x, fl); } @@ -778,9 +774,6 @@ template < class T, class Allocator > void Concurrent_compact_container:: allocate_new_block(FreeList * fl) { - typedef CCC_internal::Erase_counter_strategy< - CCC_internal::has_increment_erase_counter::value> EraseCounterStrategy; - size_type old_block_size; pointer new_block; @@ -818,7 +811,7 @@ void Concurrent_compact_container:: // will correspond to the iterator order... for (size_type i = old_block_size; i >= 1; --i) { - EraseCounterStrategy::set_erase_counter(*(new_block + i), 0); + EraseCounterStrategy::set_erase_counter(*(new_block + i), 0); Time_stamper::initialize_time_stamp(new_block + i); put_on_free_list(new_block + i, fl); } diff --git a/STL_Extension/include/CGAL/Skiplist.h b/STL_Extension/include/CGAL/Skiplist.h index 3be7908c90c..e7d7b60b422 100644 --- a/STL_Extension/include/CGAL/Skiplist.h +++ b/STL_Extension/include/CGAL/Skiplist.h @@ -75,7 +75,7 @@ public: all_iterator , typename all_list::iterator , T - > + , std::bidirectional_iterator_tag> { public: all_iterator() {} @@ -91,7 +91,7 @@ public: skip_iterator , typename skip_list::iterator , T - > + , std::bidirectional_iterator_tag> { public: skip_iterator() {} diff --git a/STL_Extension/include/CGAL/Time_stamper.h b/STL_Extension/include/CGAL/Time_stamper.h index 081c003b69b..01187a33085 100644 --- a/STL_Extension/include/CGAL/Time_stamper.h +++ b/STL_Extension/include/CGAL/Time_stamper.h @@ -30,13 +30,17 @@ struct Time_stamper { static constexpr bool has_timestamp = true; + static bool is_valid(const T* pt) { + return pt != nullptr && pt->time_stamp() != std::size_t(-2); + } + static void initialize_time_stamp(T* pt) { pt->set_time_stamp(std::size_t(-1)); } template static void set_time_stamp(T* pt, time_stamp_t& time_stamp_) { - CGAL_assertion(pt->time_stamp() != std::size_t(-2)); + CGAL_assertion(is_valid(pt)); if(pt->time_stamp() == std::size_t(-1)) { const std::size_t new_ts = time_stamp_++; pt->set_time_stamp(new_ts); @@ -64,13 +68,18 @@ struct Time_stamper static std::size_t time_stamp(const T* pt) { - CGAL_assertion(pt == nullptr || pt->time_stamp() != std::size_t(-2)); + CGAL_assertion(is_valid(pt)); if(pt == nullptr){ return std::size_t(-1); } return pt->time_stamp(); } + static void restore_timestamp(T* pt, std::size_t ts) + { + pt->set_time_stamp(ts); + } + static auto display_id(const T* pt, int offset = 0) { if(pt == nullptr) @@ -80,7 +89,7 @@ struct Time_stamper } static std::size_t hash_value(const T* p) { - CGAL_assertion(p == nullptr || p->time_stamp() != std::size_t(-2)); + CGAL_assertion(nullptr== p || is_valid(p)); if(nullptr == p) return std::size_t(-1); else @@ -116,6 +125,10 @@ public: return 0; } + static void restore_timestamp(T*, std::size_t) + { + } + static auto display_id(const T* pt, int) { return static_cast(pt); diff --git a/STL_Extension/test/STL_Extension/test_Compact_container.cpp b/STL_Extension/test/STL_Extension/test_Compact_container.cpp index bf6b0d83948..8cb5d9726ec 100644 --- a/STL_Extension/test/STL_Extension/test_Compact_container.cpp +++ b/STL_Extension/test/STL_Extension/test_Compact_container.cpp @@ -18,7 +18,6 @@ template struct Node_1 : public CGAL::Compact_container_base { - Node_1() {} // // it is important `time_stamp_` is not initialized bool operator==(const Node_1 &) const { return true; } bool operator!=(const Node_1 &) const { return false; } bool operator< (const Node_1 &) const { return false; } @@ -49,7 +48,7 @@ struct Node_1 } ///@} int m_erase_counter; - std::size_t time_stamp_; + std::size_t time_stamp_ = std::size_t(-2); }; class Node_2 diff --git a/STL_Extension/test/STL_Extension/test_Concurrent_compact_container.cpp b/STL_Extension/test/STL_Extension/test_Concurrent_compact_container.cpp index a42676f8f7f..e919369cabf 100644 --- a/STL_Extension/test/STL_Extension/test_Concurrent_compact_container.cpp +++ b/STL_Extension/test/STL_Extension/test_Concurrent_compact_container.cpp @@ -32,7 +32,6 @@ int main() struct Node_1 : public CGAL::Compact_container_base { - Node_1() {} bool operator==(const Node_1 &) const { return true; } bool operator!=(const Node_1 &) const { return false; } bool operator< (const Node_1 &) const { return false; } @@ -45,7 +44,7 @@ struct Node_1 void set_time_stamp(const std::size_t& ts) { time_stamp_ = ts; } - std::size_t time_stamp_; + std::size_t time_stamp_ = std::size_t(-2); }; class Node_2 diff --git a/STL_Extension/test/STL_Extension/test_namespaces.cpp b/STL_Extension/test/STL_Extension/test_namespaces.cpp index 63a9971c576..f7293e8a7c4 100644 --- a/STL_Extension/test/STL_Extension/test_namespaces.cpp +++ b/STL_Extension/test/STL_Extension/test_namespaces.cpp @@ -13,7 +13,7 @@ int main() { - CGAL::cpp0x::array arr; + CGAL::cpp0x::array arr{1, 2, 3}; std::array arr2; CGAL::cpp0x::tuple tuple; diff --git a/Scale_space_reconstruction_3/examples/Scale_space_reconstruction_3/scale_space_sm.cpp b/Scale_space_reconstruction_3/examples/Scale_space_reconstruction_3/scale_space_sm.cpp index a562362bfcf..398e35353b9 100644 --- a/Scale_space_reconstruction_3/examples/Scale_space_reconstruction_3/scale_space_sm.cpp +++ b/Scale_space_reconstruction_3/examples/Scale_space_reconstruction_3/scale_space_sm.cpp @@ -58,7 +58,7 @@ int main(int argc, char* argv[]) { // Also store the input points as vertex property Surface_mesh::Property_map original; bool created; - boost::tie(original, created) = mesh.add_property_map("v:original"); + std::tie(original, created) = mesh.add_property_map("v:original"); assert(created); int i = 0; diff --git a/SearchStructures/doc/SearchStructures/PackageDescription.txt b/SearchStructures/doc/SearchStructures/PackageDescription.txt index a2f35335bfc..3fdc12fd5b8 100644 --- a/SearchStructures/doc/SearchStructures/PackageDescription.txt +++ b/SearchStructures/doc/SearchStructures/PackageDescription.txt @@ -10,7 +10,6 @@ /*! \addtogroup PkgSearchStructuresRef -\todo check generated documentation \cgalPkgDescriptionBegin{dD Range and Segment Trees,PkgSearchStructures} \cgalPkgPicture{segment_tree.png} \cgalPkgSummaryBegin diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/PackageDescription.txt b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/PackageDescription.txt index 947f7034f0d..8db5cfb3b9b 100644 --- a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/PackageDescription.txt +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/PackageDescription.txt @@ -3,7 +3,6 @@ /// \ingroup PkgSegmentDelaunayGraph2Ref /*! \addtogroup PkgSegmentDelaunayGraph2Ref -\todo check generated documentation \cgalPkgDescriptionBegin{2D Segment Delaunay Graphs,PkgSegmentDelaunayGraph2} \cgalPkgPicture{svd.png} \cgalPkgSummaryBegin diff --git a/Segment_Delaunay_graph_2/test/Segment_Delaunay_graph_2/test_sdg_traits_2.cpp b/Segment_Delaunay_graph_2/test/Segment_Delaunay_graph_2/test_sdg_traits_2.cpp index aabc32a7b35..57ed0cc3fd4 100644 --- a/Segment_Delaunay_graph_2/test/Segment_Delaunay_graph_2/test_sdg_traits_2.cpp +++ b/Segment_Delaunay_graph_2/test/Segment_Delaunay_graph_2/test_sdg_traits_2.cpp @@ -1,14 +1,11 @@ -#include -#include -#include -#include -#include -#include -#include + #include #include +#include +#include + #if defined(CGAL_USE_CORE) || defined(CGAL_USE_LEDA) #include #endif @@ -16,6 +13,10 @@ #include #include +#include +#include +#include +#include typedef CGAL::Simple_cartesian Double_Kernel; typedef CGAL::Simple_cartesian > IT_Kernel; diff --git a/Segment_Delaunay_graph_Linf_2/doc/Segment_Delaunay_graph_Linf_2/PackageDescription.txt b/Segment_Delaunay_graph_Linf_2/doc/Segment_Delaunay_graph_Linf_2/PackageDescription.txt index 3b8dcdecfb0..42096623238 100644 --- a/Segment_Delaunay_graph_Linf_2/doc/Segment_Delaunay_graph_Linf_2/PackageDescription.txt +++ b/Segment_Delaunay_graph_Linf_2/doc/Segment_Delaunay_graph_Linf_2/PackageDescription.txt @@ -4,7 +4,6 @@ /*! \addtogroup PkgSegmentDelaunayGraphLinf2Ref -\todo check generated documentation \cgalPkgDescriptionBegin{L Infinity Segment Delaunay Graphs,PkgSegmentDelaunayGraphLinf2} \cgalPkgPicture{sdglinf-small.png} diff --git a/Segment_Delaunay_graph_Linf_2/test/Segment_Delaunay_graph_Linf_2/test_sdg_linf_traits_2.cpp b/Segment_Delaunay_graph_Linf_2/test/Segment_Delaunay_graph_Linf_2/test_sdg_linf_traits_2.cpp index 570eb727a6f..0e96c246782 100644 --- a/Segment_Delaunay_graph_Linf_2/test/Segment_Delaunay_graph_Linf_2/test_sdg_linf_traits_2.cpp +++ b/Segment_Delaunay_graph_Linf_2/test/Segment_Delaunay_graph_Linf_2/test_sdg_linf_traits_2.cpp @@ -5,20 +5,20 @@ #define CGAL_SDG_DEBUG(a) { a } #endif +#include +#include + #include #include #include #include -#include #include #include #include #include #include -#include -#include diff --git a/Snap_rounding_2/doc/Snap_rounding_2/PackageDescription.txt b/Snap_rounding_2/doc/Snap_rounding_2/PackageDescription.txt index 39d8c15bcd7..58e533bedcf 100644 --- a/Snap_rounding_2/doc/Snap_rounding_2/PackageDescription.txt +++ b/Snap_rounding_2/doc/Snap_rounding_2/PackageDescription.txt @@ -3,7 +3,6 @@ /// \ingroup PkgSnapRounding2Ref /*! \addtogroup PkgSnapRounding2Ref -\todo check generated documentation \cgalPkgDescriptionBegin{2D Snap Rounding,PkgSnapRounding2} \cgalPkgPicture{snap-detail.png} \cgalPkgSummaryBegin diff --git a/Stream_support/include/CGAL/IO/VTK/VTK_writer.h b/Stream_support/include/CGAL/IO/VTK/VTK_writer.h index 9be80302861..2769b3ab0f0 100644 --- a/Stream_support/include/CGAL/IO/VTK/VTK_writer.h +++ b/Stream_support/include/CGAL/IO/VTK/VTK_writer.h @@ -25,6 +25,8 @@ template void write_vector(std::ostream& os, const std::vector& vect) { + if(vect.empty()) + return; const char* buffer = reinterpret_cast(&(vect[0])); std::size_t size = vect.size()*sizeof(FT); diff --git a/Surface_mesh/examples/Surface_mesh/sm_circulators.cpp b/Surface_mesh/examples/Surface_mesh/sm_circulators.cpp index 05a166dc567..ca8593988b3 100644 --- a/Surface_mesh/examples/Surface_mesh/sm_circulators.cpp +++ b/Surface_mesh/examples/Surface_mesh/sm_circulators.cpp @@ -42,7 +42,7 @@ int main() { std::cout << "vertices around face " << f << std::endl; CGAL::Vertex_around_face_iterator vbegin, vend; - for(boost::tie(vbegin, vend) = vertices_around_face(m.halfedge(f), m); + for(std::tie(vbegin, vend) = vertices_around_face(m.halfedge(f), m); vbegin != vend; ++vbegin){ std::cout << *vbegin << std::endl; diff --git a/Surface_mesh/examples/Surface_mesh/sm_iterators.cpp b/Surface_mesh/examples/Surface_mesh/sm_iterators.cpp index 6fe9d48402e..0e16a7f0b38 100644 --- a/Surface_mesh/examples/Surface_mesh/sm_iterators.cpp +++ b/Surface_mesh/examples/Surface_mesh/sm_iterators.cpp @@ -44,8 +44,8 @@ int main() vb = std::begin(r); ve = std::end(r); - // or with boost::tie, as the CGAL range derives from std::pair - for(boost::tie(vb, ve) = m.vertices(); vb != ve; ++vb){ + // or with std::tie, as the CGAL range derives from std::pair + for(std::tie(vb, ve) = m.vertices(); vb != ve; ++vb){ // Print vertex index and vertex coordinates std::cout << *vb << " " << m.point(*vb) << std::endl; } diff --git a/Surface_mesh/examples/Surface_mesh/sm_join.cpp b/Surface_mesh/examples/Surface_mesh/sm_join.cpp index df0526992fe..d692035479a 100644 --- a/Surface_mesh/examples/Surface_mesh/sm_join.cpp +++ b/Surface_mesh/examples/Surface_mesh/sm_join.cpp @@ -25,8 +25,8 @@ int main(int argc, char* argv[]) Mesh::Property_map name1, name2; bool created; sm1.add_property_map("v:weight",7812); - boost::tie(name1, created) = sm1.add_property_map("v:name","hello"); - boost::tie(name2, created) = sm2.add_property_map("v:name","world"); + std::tie(name1, created) = sm1.add_property_map("v:name","hello"); + std::tie(name2, created) = sm2.add_property_map("v:name","world"); sm1 += sm2; diff --git a/Surface_mesh/examples/Surface_mesh/sm_kruskal.cpp b/Surface_mesh/examples/Surface_mesh/sm_kruskal.cpp index 986b9e9d4e3..61f1f73745f 100644 --- a/Surface_mesh/examples/Surface_mesh/sm_kruskal.cpp +++ b/Surface_mesh/examples/Surface_mesh/sm_kruskal.cpp @@ -34,7 +34,7 @@ void kruskal(const Mesh& sm) " point [ \n"; vertex_iterator vb,ve; - for(boost::tie(vb, ve) = vertices(sm); vb!=ve; ++vb){ + for(std::tie(vb, ve) = vertices(sm); vb!=ve; ++vb){ std::cout << " " << sm.point(*vb) << "\n"; } diff --git a/Surface_mesh/examples/Surface_mesh/sm_properties.cpp b/Surface_mesh/examples/Surface_mesh/sm_properties.cpp index 5fa15d74058..9d591e8019c 100644 --- a/Surface_mesh/examples/Surface_mesh/sm_properties.cpp +++ b/Surface_mesh/examples/Surface_mesh/sm_properties.cpp @@ -26,7 +26,7 @@ int main() // give each vertex a name, the default is empty Mesh::Property_map name; bool created; - boost::tie(name, created) = m.add_property_map("v:name","m1"); + std::tie(name, created) = m.add_property_map("v:name","m1"); assert(created); // add some names to the vertices name[v0] = "hello"; @@ -36,7 +36,7 @@ int main() // You get an existing property, and created will be false Mesh::Property_map name; bool created; - boost::tie(name, created) = m.add_property_map("v:name", ""); + std::tie(name, created) = m.add_property_map("v:name", ""); assert(! created); } diff --git a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h index 83ca6a3b4b7..86a3b498b6f 100644 --- a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h +++ b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h @@ -598,7 +598,7 @@ public: /// \name Range Types /// /// Each range `R` in this section has a nested type `R::iterator`, - /// is convertible to `std::pair`, so that one can use `boost::tie()`, + /// is convertible to `std::pair`, so that one can use `std::tie()`, /// and can be used with `BOOST_FOREACH()`, as well as with the C++11 range based for-loop. ///@{ diff --git a/Surface_mesh/test/Surface_mesh/sm_circulator_test.cpp b/Surface_mesh/test/Surface_mesh/sm_circulator_test.cpp index 5e932869a44..999d54de50d 100644 --- a/Surface_mesh/test/Surface_mesh/sm_circulator_test.cpp +++ b/Surface_mesh/test/Surface_mesh/sm_circulator_test.cpp @@ -75,7 +75,7 @@ struct test_emptiness : public Surface_fixture m.remove_vertex(iv); assert(m.is_removed(iv)); Sm::Vertex_iterator vb, ve; - for(boost::tie(vb, ve) = m.vertices(); vb != ve; ++vb) { + for(std::tie(vb, ve) = m.vertices(); vb != ve; ++vb) { Sm::Vertex_around_target_range vr = m.vertices_around_target(m.halfedge(*vb)); assert(!is_empty_range(std::begin(vr), std::end(vr))); } diff --git a/Surface_mesh/test/Surface_mesh/surface_mesh_test.cpp b/Surface_mesh/test/Surface_mesh/surface_mesh_test.cpp index 16fb699982c..d4e47e53b98 100644 --- a/Surface_mesh/test/Surface_mesh/surface_mesh_test.cpp +++ b/Surface_mesh/test/Surface_mesh/surface_mesh_test.cpp @@ -28,19 +28,19 @@ void standard_iterators() Surface_fixture f; Sm::Vertex_iterator vb, ve; - boost::tie(vb, ve) = f.m.vertices(); + std::tie(vb, ve) = f.m.vertices(); test_iterator(vb, ve, 5); Sm::Halfedge_iterator hb, he; - boost::tie(hb, he) = f.m.halfedges(); + std::tie(hb, he) = f.m.halfedges(); test_iterator(hb, he, 14); Sm::Edge_iterator eb, ee; - boost::tie(eb, ee) = f.m.edges(); + std::tie(eb, ee) = f.m.edges(); test_iterator(eb, ee, 7); Sm::Face_iterator fb, fe; - boost::tie(fb, fe) = f.m.faces(); + std::tie(fb, fe) = f.m.faces(); test_iterator(fb, fe, 3); } @@ -97,7 +97,7 @@ void memory_reuse_test() Faces faces; Sm::Face_iterator fb, fe; - for(boost::tie(fb, fe) = f.m.faces(); fb != fe; ++fb) { + for(std::tie(fb, fe) = f.m.faces(); fb != fe; ++fb) { faces.push_back(VecFace()); Sm::Vertex_around_face_circulator vafb(f.m.halfedge(*fb), f.m), vafe(vafb); if(vafb) @@ -108,7 +108,7 @@ void memory_reuse_test() } Sm::Vertex_iterator vb, ve; - for(boost::tie(vb, ve) = f.m.vertices(); vb != ve; ++vb) { + for(std::tie(vb, ve) = f.m.vertices(); vb != ve; ++vb) { f.m.set_halfedge(*vb, Sm::Halfedge_index()); } @@ -223,10 +223,10 @@ void properties () { Sm::Property_map prop; bool created = false; - boost::tie(prop,created) = f.m.add_property_map("illuminatiproperty", 23); + std::tie(prop,created) = f.m.add_property_map("illuminatiproperty", 23); assert(created == true); - boost::tie(prop, created)= f.m.add_property_map("illuminatiproperty"); + std::tie(prop, created)= f.m.add_property_map("illuminatiproperty"); assert(created == false); } diff --git a/Surface_mesh_deformation/demo/Surface_mesh_deformation/deform_mesh_for_botsch08_format.cpp b/Surface_mesh_deformation/demo/Surface_mesh_deformation/deform_mesh_for_botsch08_format.cpp index 9f5036cc3c0..6b5c101ceb6 100644 --- a/Surface_mesh_deformation/demo/Surface_mesh_deformation/deform_mesh_for_botsch08_format.cpp +++ b/Surface_mesh_deformation/demo/Surface_mesh_deformation/deform_mesh_for_botsch08_format.cpp @@ -41,7 +41,7 @@ int main(int argc,char** argv) // Definition of the region of interest (use the whole mesh) vertex_iterator vb,ve; - boost::tie(vb, ve) = vertices(mesh); + std::tie(vb, ve) = vertices(mesh); //the selection is set by a file input.open(argv[2]); diff --git a/Surface_mesh_deformation/examples/Surface_mesh_deformation/all_roi_assign_example.cpp b/Surface_mesh_deformation/examples/Surface_mesh_deformation/all_roi_assign_example.cpp index 5f429231d84..ed83fd3fb13 100644 --- a/Surface_mesh_deformation/examples/Surface_mesh_deformation/all_roi_assign_example.cpp +++ b/Surface_mesh_deformation/examples/Surface_mesh_deformation/all_roi_assign_example.cpp @@ -33,7 +33,7 @@ int main() // Definition of the region of interest (use the whole mesh) vertex_iterator vb,ve; - boost::tie(vb, ve) = vertices(mesh); + std::tie(vb, ve) = vertices(mesh); deform_mesh.insert_roi_vertices(vb, ve); // Select two control vertices ... diff --git a/Surface_mesh_deformation/examples/Surface_mesh_deformation/all_roi_assign_example_Surface_mesh.cpp b/Surface_mesh_deformation/examples/Surface_mesh_deformation/all_roi_assign_example_Surface_mesh.cpp index fe91ed58baf..4242008b653 100644 --- a/Surface_mesh_deformation/examples/Surface_mesh_deformation/all_roi_assign_example_Surface_mesh.cpp +++ b/Surface_mesh_deformation/examples/Surface_mesh_deformation/all_roi_assign_example_Surface_mesh.cpp @@ -29,7 +29,7 @@ int main(int argc, char** argv) // Definition of the region of interest (use the whole mesh) vertex_iterator vb,ve; - boost::tie(vb, ve) = vertices(mesh); + std::tie(vb, ve) = vertices(mesh); deform_mesh.insert_roi_vertices(vb, ve); // Select two control vertices ... diff --git a/Surface_mesh_deformation/examples/Surface_mesh_deformation/all_roi_assign_example_custom_polyhedron.cpp b/Surface_mesh_deformation/examples/Surface_mesh_deformation/all_roi_assign_example_custom_polyhedron.cpp index 74590db427b..d1927088526 100644 --- a/Surface_mesh_deformation/examples/Surface_mesh_deformation/all_roi_assign_example_custom_polyhedron.cpp +++ b/Surface_mesh_deformation/examples/Surface_mesh_deformation/all_roi_assign_example_custom_polyhedron.cpp @@ -81,7 +81,7 @@ int main() Vertex_index_map vertex_index_map(internal_vertex_index_map); vertex_iterator vb, ve; std::size_t counter = 0; - for(boost::tie(vb, ve) = vertices(mesh); vb != ve; ++vb, ++counter) { + for(std::tie(vb, ve) = vertices(mesh); vb != ve; ++vb, ++counter) { put(vertex_index_map, *vb, counter); } @@ -89,14 +89,14 @@ int main() Hedge_index_map hedge_index_map(internal_hedge_index_map); counter = 0; halfedge_iterator eb, ee; - for(boost::tie(eb, ee) = halfedges(mesh); eb != ee; ++eb, ++counter) { + for(std::tie(eb, ee) = halfedges(mesh); eb != ee; ++eb, ++counter) { put(hedge_index_map, *eb, counter); } Surface_mesh_deformation deform_mesh(mesh, vertex_index_map, hedge_index_map); // Insert the whole mesh as region of interest - boost::tie(vb, ve) = vertices(mesh); + std::tie(vb, ve) = vertices(mesh); deform_mesh.insert_roi_vertices(vb, ve); // Insert two control vertices diff --git a/Surface_mesh_deformation/examples/Surface_mesh_deformation/all_roi_assign_example_with_OpenMesh.cpp b/Surface_mesh_deformation/examples/Surface_mesh_deformation/all_roi_assign_example_with_OpenMesh.cpp index 88ad5c127df..f0acef64d8e 100644 --- a/Surface_mesh_deformation/examples/Surface_mesh_deformation/all_roi_assign_example_with_OpenMesh.cpp +++ b/Surface_mesh_deformation/examples/Surface_mesh_deformation/all_roi_assign_example_with_OpenMesh.cpp @@ -24,7 +24,7 @@ int main() // Definition of the region of interest (use the whole mesh) vertex_iterator vb,ve; - boost::tie(vb, ve) = vertices(mesh); + std::tie(vb, ve) = vertices(mesh); deform_mesh.insert_roi_vertices(vb, ve); // Select two control vertices ... diff --git a/Surface_mesh_deformation/examples/Surface_mesh_deformation/deform_mesh_for_botsch08_format_sre_arap.cpp b/Surface_mesh_deformation/examples/Surface_mesh_deformation/deform_mesh_for_botsch08_format_sre_arap.cpp index 112fdfb8467..afccc9903c7 100644 --- a/Surface_mesh_deformation/examples/Surface_mesh_deformation/deform_mesh_for_botsch08_format_sre_arap.cpp +++ b/Surface_mesh_deformation/examples/Surface_mesh_deformation/deform_mesh_for_botsch08_format_sre_arap.cpp @@ -51,7 +51,7 @@ int main(int argc,char** argv) // Definition of the region of interest (use the whole mesh) vertex_iterator vb,ve; - boost::tie(vb, ve) = vertices(mesh); + std::tie(vb, ve) = vertices(mesh); //the selection is set by a file input.open(sel_name); diff --git a/Surface_mesh_deformation/examples/Surface_mesh_deformation/k_ring_roi_translate_rotate_Surface_mesh.cpp b/Surface_mesh_deformation/examples/Surface_mesh_deformation/k_ring_roi_translate_rotate_Surface_mesh.cpp index 61740ac320f..2adbedc0235 100644 --- a/Surface_mesh_deformation/examples/Surface_mesh_deformation/k_ring_roi_translate_rotate_Surface_mesh.cpp +++ b/Surface_mesh_deformation/examples/Surface_mesh_deformation/k_ring_roi_translate_rotate_Surface_mesh.cpp @@ -60,7 +60,7 @@ int main(int argc, char** argv) // Select and insert the vertices of the region of interest vertex_iterator vb, ve; - boost::tie(vb,ve) = vertices(mesh); + std::tie(vb,ve) = vertices(mesh); std::vector roi = extract_k_ring(mesh, *std::next(vb, 47), 9); deform_mesh.insert_roi_vertices(roi.begin(), roi.end()); diff --git a/Surface_mesh_deformation/examples/Surface_mesh_deformation/k_ring_roi_translate_rotate_example.cpp b/Surface_mesh_deformation/examples/Surface_mesh_deformation/k_ring_roi_translate_rotate_example.cpp index 79a82bc238b..08d82307bec 100644 --- a/Surface_mesh_deformation/examples/Surface_mesh_deformation/k_ring_roi_translate_rotate_example.cpp +++ b/Surface_mesh_deformation/examples/Surface_mesh_deformation/k_ring_roi_translate_rotate_example.cpp @@ -65,7 +65,7 @@ int main() // Select and insert the vertices of the region of interest vertex_iterator vb, ve; - boost::tie(vb,ve) = vertices(mesh); + std::tie(vb,ve) = vertices(mesh); std::vector roi = extract_k_ring(mesh, *std::next(vb, 47), 9); deform_mesh.insert_roi_vertices(roi.begin(), roi.end()); diff --git a/Surface_mesh_deformation/test/Surface_mesh_deformation/Surface_mesh_deformation_test_commons.h b/Surface_mesh_deformation/test/Surface_mesh_deformation/Surface_mesh_deformation_test_commons.h index bdc14cee74e..508cd98f3a6 100644 --- a/Surface_mesh_deformation/test/Surface_mesh_deformation/Surface_mesh_deformation_test_commons.h +++ b/Surface_mesh_deformation/test/Surface_mesh_deformation/Surface_mesh_deformation_test_commons.h @@ -27,13 +27,13 @@ void init_indices(Polyhedron& poly) { vertex_iterator vb, ve; std::size_t counter = 0; - for(boost::tie(vb, ve) = vertices(poly); vb != ve; ++vb, ++counter) { + for(std::tie(vb, ve) = vertices(poly); vb != ve; ++vb, ++counter) { (*vb)->id() = counter; } counter = 0; halfedge_iterator heb, hee; - for(boost::tie(heb, hee) = halfedges(poly); heb != hee; ++heb, ++counter) { + for(std::tie(heb, hee) = halfedges(poly); heb != hee; ++heb, ++counter) { (*heb)->id() = counter; } } @@ -59,7 +59,7 @@ read_rois(DeformMesh& deform_mesh, std::vector vvertices; vvertices.reserve(num_vertices(polyhedron)); vertex_iterator vb, ve; - for(boost::tie(vb, ve) = vertices(polyhedron); vb != ve; ++vb) { + for(std::tie(vb, ve) = vertices(polyhedron); vb != ve; ++vb) { vvertices.push_back(*vb); } // load handles and roi from txt diff --git a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Orbifold_Tutte_parameterizer_3.h b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Orbifold_Tutte_parameterizer_3.h index 151165423f9..6ca9c4c8fe3 100644 --- a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Orbifold_Tutte_parameterizer_3.h +++ b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Orbifold_Tutte_parameterizer_3.h @@ -121,7 +121,7 @@ Error_code read_cones(const TriangleMesh& tm, std::ifstream& in, VertexIndexMap // Since the cones are unique, we only need to loop all the vertices once TM_vertex_iterator vit, end; - boost::tie(vit, end) = vertices(tm); + std::tie(vit, end) = vertices(tm); for(; vit!=end; ++vit) { for(std::size_t i=0; i::max)(); - for(boost::tie(b,e) = halfedges_around_face(bhd, mesh); b!=e; ++b, ++id) { + for(std::tie(b,e) = halfedges_around_face(bhd, mesh); b!=e; ++b, ++id) { double d = CGAL::abs(offset[id] - value); if(d < min) { best = b; @@ -160,7 +160,7 @@ private: double total_len = compute_border_length(mesh, bhd); halfedge_around_face_iterator b, e; - boost::tie(b,e) = halfedges_around_face(bhd, mesh); + std::tie(b,e) = halfedges_around_face(bhd, mesh); for(halfedge_around_face_iterator it = b; it!= e; ++it) { vertex_descriptor vs = source(*it, mesh); vertex_descriptor vt = target(*it, mesh); diff --git a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/internal/Containers_filler.h b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/internal/Containers_filler.h index d9da2714623..6a8a74a4ebe 100644 --- a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/internal/Containers_filler.h +++ b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/internal/Containers_filler.h @@ -86,7 +86,7 @@ struct Index_map_filler { typename Map::iterator it; bool new_element; - boost::tie(it,new_element) = map->insert(std::make_pair(vd,1)); + std::tie(it,new_element) = map->insert(std::make_pair(vd,1)); if(new_element) { it->second = index++; } diff --git a/Surface_mesh_segmentation/include/CGAL/Surface_mesh_segmentation/internal/Filters.h b/Surface_mesh_segmentation/include/CGAL/Surface_mesh_segmentation/internal/Filters.h index 7afb29eecf2..7ad3cec0a83 100644 --- a/Surface_mesh_segmentation/include/CGAL/Surface_mesh_segmentation/internal/Filters.h +++ b/Surface_mesh_segmentation/include/CGAL/Surface_mesh_segmentation/internal/Filters.h @@ -80,7 +80,7 @@ public: smoothed_values.reserve(num_faces(mesh)); face_iterator facet_it, fend; - for(boost::tie(facet_it,fend) = faces(mesh); + for(std::tie(facet_it,fend) = faces(mesh); facet_it != fend; ++facet_it) { std::map neighbors; NeighborSelector()(mesh,*facet_it, window_size, @@ -126,7 +126,7 @@ public: } // put smoothed values back again to values pmap. std::vector::iterator smoothed_value_it = smoothed_values.begin(); - for(boost::tie(facet_it,fend) = faces(mesh); + for(std::tie(facet_it,fend) = faces(mesh); facet_it != fend; ++facet_it, ++smoothed_value_it) { put(values, *facet_it, *smoothed_value_it); @@ -162,7 +162,7 @@ public: std::vector smoothed_values; smoothed_values.reserve(num_faces(mesh)); face_iterator facet_it, fend; - for(boost::tie(facet_it,fend) = faces(mesh); + for(std::tie(facet_it,fend) = faces(mesh); facet_it != fend; ++facet_it) { std::map neighbors; NeighborSelector()(mesh, *facet_it, window_size, @@ -188,7 +188,7 @@ public: } // put smoothed values back again to values pmap. std::vector::iterator smoothed_value_it = smoothed_values.begin(); - for(boost::tie(facet_it,fend) = faces(mesh); + for(std::tie(facet_it,fend) = faces(mesh); facet_it != fend; ++facet_it) { values[*facet_it] = *smoothed_value_it; } diff --git a/Surface_mesh_segmentation/include/CGAL/Surface_mesh_segmentation/internal/SDF_calculation.h b/Surface_mesh_segmentation/include/CGAL/Surface_mesh_segmentation/internal/SDF_calculation.h index 5709694f491..1baaa2b8c91 100644 --- a/Surface_mesh_segmentation/include/CGAL/Surface_mesh_segmentation/internal/SDF_calculation.h +++ b/Surface_mesh_segmentation/include/CGAL/Surface_mesh_segmentation/internal/SDF_calculation.h @@ -25,7 +25,7 @@ #include #include -#include +#include #include #define CGAL_NUMBER_OF_MAD 1.5 @@ -90,11 +90,11 @@ private: typedef typename Tree::Primitive_id Primitive_id; // Sampled points from disk, t1 = coordinate-x, t2 = coordinate-y, t3 = weight. - typedef boost::tuple Disk_sample; + typedef std::tuple Disk_sample; typedef std::vector Disk_samples_list; // DiskSampling class responsible for the sampling points in a disk. It is used for generating rays in the cones. For different example see Disk_samplers.h - typedef Vogel_disk_sampling > + typedef Vogel_disk_sampling > Default_sampler; // member variables @@ -303,8 +303,8 @@ public: Primitive_id closest_id; Vector disk_vector = sum_functor( - scale_functor(v1, FT(disk_multiplier * sample_it->get<0>())), - scale_functor(v2, FT(disk_multiplier * sample_it->get<1>())) ); + scale_functor(v1, FT(disk_multiplier * std::get<0>(*sample_it))), + scale_functor(v2, FT(disk_multiplier * std::get<1>(*sample_it))) ); Vector ray_direction = sum_functor(scaled_normal, disk_vector); if(use_diagonal) { @@ -322,7 +322,7 @@ public: "A degenerate segment is constructed. Most probable reason is using CGAL_PI as cone_angle parameter and also picking center of disk as a sample."); } - boost::tie(is_intersected, intersection_is_acute, min_distance, closest_id) + std::tie(is_intersected, intersection_is_acute, min_distance, closest_id) = cast_and_return_minimum(segment, skip, accept_if_acute); } else { Ray ray(center, ray_direction); @@ -332,7 +332,7 @@ public: "A degenerate ray is constructed. Most probable reason is using CGAL_PI as cone_angle parameter and also picking center of disk as a sample."); } - boost::tie(is_intersected, intersection_is_acute, min_distance, closest_id) + std::tie(is_intersected, intersection_is_acute, min_distance, closest_id) = ray_casting(ray, skip, accept_if_acute); } @@ -342,7 +342,7 @@ public: visitor(closest_id, min_distance); - ray_distances.push_back(std::make_pair(min_distance, sample_it->get<2>())); + ray_distances.push_back(std::make_pair(min_distance, std::get<2>(*sample_it))); } if(ray_distances.empty()) { @@ -407,9 +407,9 @@ private: * - get<3> Primitive_id : closest intersected primitive if get<0> is true, else Primitive_id() */ template - boost::tuple cast_and_return_minimum( + std::tuple cast_and_return_minimum( const Query& query, SkipPrimitiveFunctor skip, bool accept_if_acute) const { - boost::tuple + std::tuple min_distance(false, false, 0.0, Primitive_id()); typedef typename Tree:: template Intersection_and_primitive_id::Type Intersection_and_primitive_id; @@ -440,16 +440,16 @@ private: Vector i_ray(*i_point, query.source()); double new_distance = to_double( i_ray.squared_length() ); - if(!min_distance.template get<0>() - || new_distance < min_distance.template get<2>()) { - min_distance.template get<3>() = id; - min_distance.template get<2>() = new_distance; - min_distance.template get<0>() = true; + if(!std::get<0>(min_distance) + || new_distance < std::get<2>(min_distance)) { + std::get<3>(min_distance) = id; + std::get<2>(min_distance) = new_distance; + std::get<0>(min_distance) = true; min_id = id; min_i_ray = i_ray; } } - if(!min_distance.template get<0>()) { + if(!std::get<0>(min_distance)) { return min_distance; } @@ -467,32 +467,32 @@ private: } } - min_distance.template get<1>() = true; // founded intersection is acceptable. - min_distance.template get<2>() = std::sqrt(min_distance.template get<2>()); + std::get<1>(min_distance) = true; // founded intersection is acceptable. + std::get<2>(min_distance) = std::sqrt(std::get<2>(min_distance)); return min_distance; } // function similar to `cast_and_return_minimum()` but using the function // first_intersection with a Ray to get the closest intersected primitive template - boost::tuple ray_casting( + std::tuple ray_casting( const Ray& query, SkipFunctor s, bool accept_if_acute) const { const std::optional< typename Tree::template Intersection_and_primitive_id::Type > min_intersection = tree.first_intersection(query, s); if(!min_intersection) - return boost::make_tuple(false, false, 0.0, Primitive_id()); + return std::make_tuple(false, false, 0.0, Primitive_id()); const Point* i_point = std::get_if( &min_intersection->first ); if (!i_point) //segment case ignored - return boost::make_tuple(false, false, 0.0, Primitive_id()); + return std::make_tuple(false, false, 0.0, Primitive_id()); Vector min_i_ray(*i_point, query.source()); - boost::tuple + std::tuple min_distance(true, false, to_double(min_i_ray.squared_length()), min_intersection->second); - const Primitive_id& min_id = min_distance.template get<3>(); + const Primitive_id& min_id = std::get<3>(min_distance); if(accept_if_acute) { // check whether the ray makes acute angle with intersected facet @@ -508,8 +508,8 @@ private: } } - min_distance.template get<1>() = true; // founded intersection is acceptable. - min_distance.template get<2>() = std::sqrt(min_distance.template get<2>()); + std::get<1>(min_distance) = true; // founded intersection is acceptable. + std::get<2>(min_distance) = std::sqrt(std::get<2>(min_distance)); return min_distance; } 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 a2a2228f6f5..eb78e5ed48d 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 @@ -84,7 +84,7 @@ public: double min_sdf = (std::numeric_limits::max)(); // If there is any facet which has no sdf value, assign average sdf value of its neighbors face_iterator facet_it, fend; - for(boost::tie(facet_it,fend) = faces(mesh); + for(std::tie(facet_it,fend) = faces(mesh); facet_it != fend; ++facet_it) { double sdf_value = get(sdf_values, *facet_it); CGAL_assertion(sdf_value == -1 || sdf_value >= 0); // validity check @@ -130,7 +130,7 @@ public: double min_sdf = (std::numeric_limits::max)(); double max_sdf = -min_sdf; face_iterator facet_it, fend; - for(boost::tie(facet_it,fend) = faces(mesh); + for(std::tie(facet_it,fend) = faces(mesh); facet_it != fend; ++facet_it) { double sdf_value = get(sdf_values, *facet_it); max_sdf = (std::max)(sdf_value, max_sdf); @@ -147,7 +147,7 @@ public: std::pair linear_normalize_sdf_values(const Polyhedron& mesh, SDFPropertyMap sdf_values) { double min_sdf, max_sdf; - boost::tie(min_sdf, max_sdf) = min_max_value(mesh, sdf_values); + std::tie(min_sdf, max_sdf) = min_max_value(mesh, sdf_values); if(min_sdf == max_sdf) { CGAL_warning_msg(min_sdf == max_sdf, "Linear normalization is not applicable!"); @@ -156,7 +156,7 @@ public: const double max_min_dif = max_sdf - min_sdf; face_iterator facet_it, fend; - for(boost::tie(facet_it,fend) = faces(mesh); + for(std::tie(facet_it,fend) = faces(mesh); facet_it != fend; ++facet_it) { put(sdf_values, *facet_it, (get(sdf_values, *facet_it) - min_sdf) / max_min_dif); } @@ -297,7 +297,7 @@ public: AlphaExpansionImplementationTag()); std::vector::iterator label_it = labels.begin(); face_iterator facet_it, fend; - for(boost::tie(facet_it,fend) = faces(mesh); + for(std::tie(facet_it,fend) = faces(mesh); facet_it != fend; ++facet_it, ++label_it) { put(segment_pmap, *facet_it, *label_it); // fill with cluster-ids @@ -354,7 +354,7 @@ private: std::vector& normalized_sdf_values) { normalized_sdf_values.reserve(num_faces(mesh)); face_iterator facet_it, fend; - for(boost::tie(facet_it,fend) = faces(mesh); + for(std::tie(facet_it,fend) = faces(mesh); facet_it != fend; ++facet_it) { double log_normalized = log(get(sdf_values, *facet_it) * CGAL_NORMALIZATION_ALPHA + 1) / log(CGAL_NORMALIZATION_ALPHA + 1); @@ -398,7 +398,7 @@ private: std::map facet_index_map; std::size_t facet_index = 0; face_iterator facet_it, fend; - for(boost::tie(facet_it,fend) = faces(mesh); + for(std::tie(facet_it,fend) = faces(mesh); facet_it != fend; ++facet_it, ++facet_index) { facet_index_map[*facet_it] = facet_index; @@ -407,7 +407,7 @@ private: const double epsilon = 5e-6; // edges and their weights. pair stores facet-id pairs (see above) (may be using boost::tuple can be more suitable) edge_iterator edge_it, eend; - for(boost::tie(edge_it,eend) = edges(mesh); + for(std::tie(edge_it,eend) = edges(mesh); edge_it != eend; ++edge_it) { halfedge_descriptor hd = halfedge(*edge_it,mesh); halfedge_descriptor ohd = opposite(hd,mesh); @@ -461,7 +461,7 @@ private: std::size_t segment_id = number_of_clusters; std::vector > segments_with_average_sdf_values; face_iterator facet_it, fend; - for(boost::tie(facet_it,fend) = faces(mesh); + for(std::tie(facet_it,fend) = faces(mesh); facet_it != fend; ++facet_it) { if(get(segments, *facet_it) < number_of_clusters) { // not visited by depth_first_traversal @@ -488,7 +488,7 @@ private: } // make one-pass on facets. First make segment-id zero based by subtracting number_of_clusters // . Then place its sorted index to pmap - for(boost::tie(facet_it,fend) = faces(mesh); + for(std::tie(facet_it,fend) = faces(mesh); facet_it != fend; ++facet_it) { std::size_t segment_id = get(segments, *facet_it) - number_of_clusters; put(segments, *facet_it, segment_id_to_sorted_id_map[segment_id]); diff --git a/Surface_mesh_shortest_path/benchmark/Surface_mesh_shortest_path/benchmark_shortest_paths.cpp b/Surface_mesh_shortest_path/benchmark/Surface_mesh_shortest_path/benchmark_shortest_paths.cpp index 412d7ed844f..811ab9345df 100644 --- a/Surface_mesh_shortest_path/benchmark/Surface_mesh_shortest_path/benchmark_shortest_paths.cpp +++ b/Surface_mesh_shortest_path/benchmark/Surface_mesh_shortest_path/benchmark_shortest_paths.cpp @@ -192,7 +192,7 @@ void run_benchmarks(CGAL::Random& rand, size_t numTrials, size_t numSources, siz outData.numFaces = num_faces(polyhedron); face_iterator startFace, endFace; - boost::tie(startFace, endFace) = faces(polyhedron); + std::tie(startFace, endFace) = faces(polyhedron); std::vector allFaces; diff --git a/Surface_mesh_shortest_path/examples/Surface_mesh_shortest_path/shortest_paths.cpp b/Surface_mesh_shortest_path/examples/Surface_mesh_shortest_path/shortest_paths.cpp index a3b7268b77d..fdf2afc0969 100644 --- a/Surface_mesh_shortest_path/examples/Surface_mesh_shortest_path/shortest_paths.cpp +++ b/Surface_mesh_shortest_path/examples/Surface_mesh_shortest_path/shortest_paths.cpp @@ -48,7 +48,7 @@ int main(int argc, char** argv) // into a file readable using CGAL Lab std::ofstream output("shortest_paths_with_id.polylines.txt"); vertex_iterator vit, vit_end; - for ( boost::tie(vit, vit_end) = vertices(tmesh); + for ( std::tie(vit, vit_end) = vertices(tmesh); vit != vit_end; ++vit) { std::vector points; diff --git a/Surface_mesh_shortest_path/examples/Surface_mesh_shortest_path/shortest_paths_OpenMesh.cpp b/Surface_mesh_shortest_path/examples/Surface_mesh_shortest_path/shortest_paths_OpenMesh.cpp index 34b337d95f4..4192f5e70b8 100644 --- a/Surface_mesh_shortest_path/examples/Surface_mesh_shortest_path/shortest_paths_OpenMesh.cpp +++ b/Surface_mesh_shortest_path/examples/Surface_mesh_shortest_path/shortest_paths_OpenMesh.cpp @@ -60,7 +60,7 @@ int main(int argc, char** argv) // into a file readable using the CGAL Tmesh demo std::ofstream output("shortest_paths_OpenMesh.polylines.txt"); vertex_iterator vit, vit_end; - for ( boost::tie(vit, vit_end) = vertices(tmesh); + for ( std::tie(vit, vit_end) = vertices(tmesh); vit != vit_end; ++vit) { std::vector points; diff --git a/Surface_mesh_shortest_path/examples/Surface_mesh_shortest_path/shortest_paths_multiple_sources.cpp b/Surface_mesh_shortest_path/examples/Surface_mesh_shortest_path/shortest_paths_multiple_sources.cpp index a0a05111c91..eab88444695 100644 --- a/Surface_mesh_shortest_path/examples/Surface_mesh_shortest_path/shortest_paths_multiple_sources.cpp +++ b/Surface_mesh_shortest_path/examples/Surface_mesh_shortest_path/shortest_paths_multiple_sources.cpp @@ -39,7 +39,7 @@ int main(int argc, char** argv) // by copying the faces in a vector to get a direct access to faces std::size_t nb_faces=num_faces(tmesh); face_iterator fit, fit_end; - boost::tie(fit, fit_end) = faces(tmesh); + std::tie(fit, fit_end) = faces(tmesh); std::vector face_vector(fit, fit_end); // and creating a vector of Face_location objects const std::size_t nb_source_points = 30; @@ -59,7 +59,7 @@ int main(int argc, char** argv) // into a file readable using the CGAL Tmesh demo std::ofstream output("shortest_paths_multiple_sources.polylines.txt"); vertex_iterator vit, vit_end; - for ( boost::tie(vit, vit_end) = vertices(tmesh); + for ( std::tie(vit, vit_end) = vertices(tmesh); vit != vit_end; ++vit) { std::vector points; diff --git a/Surface_mesh_shortest_path/examples/Surface_mesh_shortest_path/shortest_paths_no_id.cpp b/Surface_mesh_shortest_path/examples/Surface_mesh_shortest_path/shortest_paths_no_id.cpp index 8b51ee23d2b..678183446cf 100644 --- a/Surface_mesh_shortest_path/examples/Surface_mesh_shortest_path/shortest_paths_no_id.cpp +++ b/Surface_mesh_shortest_path/examples/Surface_mesh_shortest_path/shortest_paths_no_id.cpp @@ -60,7 +60,7 @@ int main(int argc, char** argv) // into a file readable using CGAL Lab std::ofstream output("shortest_paths_no_id.polylines.txt"); vertex_iterator vit, vit_end; - for ( boost::tie(vit, vit_end) = vertices(tmesh); + for ( std::tie(vit, vit_end) = vertices(tmesh); vit != vit_end; ++vit) { std::vector points; diff --git a/Surface_mesh_shortest_path/examples/Surface_mesh_shortest_path/shortest_paths_with_id.cpp b/Surface_mesh_shortest_path/examples/Surface_mesh_shortest_path/shortest_paths_with_id.cpp index 697146cc16b..ea434a51188 100644 --- a/Surface_mesh_shortest_path/examples/Surface_mesh_shortest_path/shortest_paths_with_id.cpp +++ b/Surface_mesh_shortest_path/examples/Surface_mesh_shortest_path/shortest_paths_with_id.cpp @@ -48,7 +48,7 @@ int main(int argc, char** argv) // into a file readable using CGAL Lab std::ofstream output("shortest_paths_with_id.polylines.txt"); vertex_iterator vit, vit_end; - for ( boost::tie(vit, vit_end) = vertices(tmesh); + for ( std::tie(vit, vit_end) = vertices(tmesh); vit != vit_end; ++vit) { std::vector points; diff --git a/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_1.cpp b/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_1.cpp index 22b1869274a..e39457cf08f 100644 --- a/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_1.cpp +++ b/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_1.cpp @@ -50,7 +50,7 @@ void shortest_path_regular_tetrahedron() face_iterator startFace; face_iterator endFace; - boost::tie(startFace,endFace) = CGAL::faces(P); + std::tie(startFace,endFace) = CGAL::faces(P); face_descriptor firstFace = *startFace; @@ -66,7 +66,7 @@ void shortest_path_regular_tetrahedron() Kernel::FT halfSideLength = sideLength / Kernel::FT(2.0); Kernel::FT triangleHeight = CGAL::sqrt((sideLength*sideLength) - (halfSideLength*halfSideLength)); - for (boost::tie(currentVertex, endVertex) = CGAL::vertices(P); currentVertex != endVertex; ++currentVertex) + for (std::tie(currentVertex, endVertex) = CGAL::vertices(P); currentVertex != endVertex; ++currentVertex) { if ((*currentVertex)->point().y()==-1) { @@ -118,7 +118,7 @@ void test_simple_saddle_vertex_mesh() vertex_iterator startVertex; vertex_iterator endVertex; - boost::tie(startVertex, endVertex) = CGAL::vertices(P); + std::tie(startVertex, endVertex) = CGAL::vertices(P); vertex_iterator currentVertex = startVertex; @@ -368,7 +368,7 @@ void test_boundary_mesh() face_iterator startFace; face_iterator endFace; - boost::tie(startFace, endFace) = CGAL::faces(P); + std::tie(startFace, endFace) = CGAL::faces(P); vertex_iterator currentVertex; vertex_iterator endVertex; @@ -380,7 +380,7 @@ void test_boundary_mesh() Point_3 vertexLocations[10]; size_t currentVertexIndex = 0; - for (boost::tie(currentVertex, endVertex) = CGAL::vertices(P); currentVertex != endVertex; ++currentVertex) + for (std::tie(currentVertex, endVertex) = CGAL::vertices(P); currentVertex != endVertex; ++currentVertex) { vertexHandles[currentVertexIndex] = *currentVertex; vertexLocations[currentVertexIndex] = vpm[*currentVertex]; diff --git a/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_2.cpp b/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_2.cpp index 19bda236706..ceb07b5e178 100644 --- a/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_2.cpp +++ b/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_2.cpp @@ -73,7 +73,7 @@ int main(int argc, char* argv[]) std::vector vertices; - boost::tie(verticesStart, verticesEnd) = CGAL::vertices(polyhedron); + std::tie(verticesStart, verticesEnd) = CGAL::vertices(polyhedron); for (vertex_iterator it = verticesStart; it != verticesEnd; ++it) { @@ -85,7 +85,7 @@ int main(int argc, char* argv[]) std::vector faces; - boost::tie(facesStart, facesEnd) = CGAL::faces(polyhedron); + std::tie(facesStart, facesEnd) = CGAL::faces(polyhedron); for (face_iterator it = facesStart; it != facesEnd; ++it) { diff --git a/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_3.cpp b/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_3.cpp index 26da5f2d915..608a79b29c6 100644 --- a/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_3.cpp +++ b/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_3.cpp @@ -70,7 +70,7 @@ int main(int argc, char* argv[]) Surface_mesh_shortest_path shortestPaths(polyhedron, traits); face_iterator facesBegin, facesEnd; - boost::tie(facesBegin, facesEnd) = faces(polyhedron); + std::tie(facesBegin, facesEnd) = faces(polyhedron); std::vector facesList; diff --git a/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_4.cpp b/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_4.cpp index 1774d928a24..b0070bd17d0 100644 --- a/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_4.cpp +++ b/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_4.cpp @@ -73,7 +73,7 @@ int main(int argc, char* argv[]) Surface_mesh_shortest_path shortestPaths(polyhedron, traits); face_iterator facesBegin, facesEnd; - boost::tie(facesBegin, facesEnd) = faces(polyhedron); + std::tie(facesBegin, facesEnd) = faces(polyhedron); std::vector facesList; @@ -112,7 +112,7 @@ int main(int argc, char* argv[]) } vertex_iterator startVertexIt, endVertexIt; - boost::tie(startVertexIt, endVertexIt) = vertices(polyhedron); + std::tie(startVertexIt, endVertexIt) = vertices(polyhedron); bool first = true; diff --git a/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_5.cpp b/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_5.cpp index 54e3c49e4dd..cc7ed1d29b8 100644 --- a/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_5.cpp +++ b/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_5.cpp @@ -72,7 +72,7 @@ int main(int argc, char* argv[]) std::vector faces; - boost::tie(facesStart, facesEnd) = CGAL::faces(polyhedron); + std::tie(facesStart, facesEnd) = CGAL::faces(polyhedron); for (face_iterator it = facesStart; it != facesEnd; ++it) { diff --git a/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_traits_test.cpp b/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_traits_test.cpp index 784be8d0abd..e02ac923237 100644 --- a/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_traits_test.cpp +++ b/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_traits_test.cpp @@ -64,7 +64,7 @@ void test_simple_2D_barycentric_coordinatess() size_t outVertex0; CGAL::Surface_mesh_shortest_paths_3::Barycentric_coordinates_type b0Type; - boost::tie(b0Type, outVertex0) = classify_barycentric_coordinates(b0); + std::tie(b0Type, outVertex0) = classify_barycentric_coordinates(b0); CHECK_EQUAL(b0Type, CGAL::Surface_mesh_shortest_paths_3::BARYCENTRIC_COORDINATES_ON_VERTEX); CHECK_EQUAL(outVertex0, 0u); @@ -77,7 +77,7 @@ void test_simple_2D_barycentric_coordinatess() size_t outVertex1; CGAL::Surface_mesh_shortest_paths_3::Barycentric_coordinates_type b1Type; - boost::tie(b1Type, outVertex1) = classify_barycentric_coordinates(b1); + std::tie(b1Type, outVertex1) = classify_barycentric_coordinates(b1); CHECK_EQUAL(b1Type, CGAL::Surface_mesh_shortest_paths_3::BARYCENTRIC_COORDINATES_ON_VERTEX); CHECK_EQUAL(outVertex1, 1u); @@ -90,7 +90,7 @@ void test_simple_2D_barycentric_coordinatess() size_t outVertex2; CGAL::Surface_mesh_shortest_paths_3::Barycentric_coordinates_type b2Type; - boost::tie(b2Type, outVertex2) = classify_barycentric_coordinates(b2); + std::tie(b2Type, outVertex2) = classify_barycentric_coordinates(b2); CHECK_EQUAL(b2Type, CGAL::Surface_mesh_shortest_paths_3::BARYCENTRIC_COORDINATES_ON_VERTEX); CHECK_EQUAL(outVertex2, 2u); @@ -100,7 +100,7 @@ void test_simple_2D_barycentric_coordinatess() size_t dummyOut; CGAL::Surface_mesh_shortest_paths_3::Barycentric_coordinates_type bLocationType; - boost::tie(bLocationType, dummyOut) = classify_barycentric_coordinates(bLocation); + std::tie(bLocationType, dummyOut) = classify_barycentric_coordinates(bLocation); CHECK_EQUAL(bLocationType, CGAL::Surface_mesh_shortest_paths_3::BARYCENTRIC_COORDINATES_ON_BOUNDED_SIDE); @@ -282,7 +282,7 @@ void detect_is_saddle_vertex() vertex_iterator currentVertex; vertex_iterator endVertex; - for (boost::tie(currentVertex, endVertex) = vertices(P); currentVertex != endVertex; ++currentVertex) + for (std::tie(currentVertex, endVertex) = vertices(P); currentVertex != endVertex; ++currentVertex) { if (currentVertexIndex <= 3 || currentVertexIndex == 7) { diff --git a/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/TestMesh.cpp b/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/TestMesh.cpp index aaf41537b8b..35d2c0cab86 100644 --- a/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/TestMesh.cpp +++ b/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/TestMesh.cpp @@ -168,7 +168,7 @@ struct TestMeshProgramInstance std::vector vertices; - boost::tie(verticesStart, verticesEnd) = CGAL::vertices(polyhedron); + std::tie(verticesStart, verticesEnd) = CGAL::vertices(polyhedron); for (vertex_iterator it = verticesStart; it != verticesEnd; ++it) { @@ -180,7 +180,7 @@ struct TestMeshProgramInstance std::vector faces; - boost::tie(facesStart, facesEnd) = CGAL::faces(polyhedron); + std::tie(facesStart, facesEnd) = CGAL::faces(polyhedron); for (face_iterator it = facesStart; it != facesEnd; ++it) { diff --git a/Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/internal/Edge_collapse.h b/Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/internal/Edge_collapse.h index 5c23e83e94f..d53b3458d15 100644 --- a/Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/internal/Edge_collapse.h +++ b/Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/internal/Edge_collapse.h @@ -754,7 +754,7 @@ is_collapse_topologically_valid(const Profile& profile) // The following loop checks the link condition for v0_v1. // Specifically, that for every vertex 'k' adjacent to both 'p and 'q', 'pkq' is a face of the mesh. // - for(boost::tie(eb1,ee1) = halfedges_around_source(profile.v0(), m_tm); res && eb1 != ee1; ++eb1) + for(std::tie(eb1,ee1) = halfedges_around_source(profile.v0(), m_tm); res && eb1 != ee1; ++eb1) { halfedge_descriptor v0_k = *eb1; @@ -762,7 +762,7 @@ is_collapse_topologically_valid(const Profile& profile) { vertex_descriptor k = target(v0_k, m_tm); - for(boost::tie(eb2,ee2) = halfedges_around_source(k, m_tm); res && eb2 != ee2; ++eb2) + for(std::tie(eb2,ee2) = halfedges_around_source(k, m_tm); res && eb2 != ee2; ++eb2) { halfedge_descriptor k_v1 = *eb2; diff --git a/Surface_mesh_simplification/test/Surface_mesh_simplification/test_edge_collapse_Polyhedron_3.cpp b/Surface_mesh_simplification/test/Surface_mesh_simplification/test_edge_collapse_Polyhedron_3.cpp index 00e6cf68501..45eba38aa7a 100644 --- a/Surface_mesh_simplification/test/Surface_mesh_simplification/test_edge_collapse_Polyhedron_3.cpp +++ b/Surface_mesh_simplification/test/Surface_mesh_simplification/test_edge_collapse_Polyhedron_3.cpp @@ -136,7 +136,7 @@ public: Profile::Triangle_vector triangles; out_edge_iterator eb, ee; - for(boost::tie(eb,ee) = halfedges_around_source(opposite(halfedge(mV,tm()),tm()),tm()); eb != ee; ++ eb) + for(std::tie(eb,ee) = halfedges_around_source(opposite(halfedge(mV,tm()),tm()),tm()); eb != ee; ++ eb) { halfedge_descriptor out_edge1 = *eb; halfedge_descriptor out_edge2 = out_edge1->opposite()->next(); diff --git a/Surface_mesh_skeletonization/include/CGAL/Mean_curvature_flow_skeletonization.h b/Surface_mesh_skeletonization/include/CGAL/Mean_curvature_flow_skeletonization.h index 39b928852ea..b69e59d8e0c 100644 --- a/Surface_mesh_skeletonization/include/CGAL/Mean_curvature_flow_skeletonization.h +++ b/Surface_mesh_skeletonization/include/CGAL/Mean_curvature_flow_skeletonization.h @@ -344,7 +344,7 @@ double diagonal_length(const Bbox_3& bbox) double init_min_edge_length() { vertex_iterator vb, ve; - boost::tie(vb, ve) = vertices(m_tmesh); + std::tie(vb, ve) = vertices(m_tmesh); Vertex_to_point v_to_p(m_tmesh_point_pmap); Bbox_3 bbox = CGAL::bbox_3(boost::make_transform_iterator(vb, v_to_p), boost::make_transform_iterator(ve, v_to_p)); diff --git a/Surface_mesh_skeletonization/include/CGAL/Surface_mesh_skeletonization/internal/Curve_skeleton.h b/Surface_mesh_skeletonization/include/CGAL/Surface_mesh_skeletonization/internal/Curve_skeleton.h index f8a1f3eeb20..c1905924ba8 100644 --- a/Surface_mesh_skeletonization/include/CGAL/Surface_mesh_skeletonization/internal/Curve_skeleton.h +++ b/Surface_mesh_skeletonization/include/CGAL/Surface_mesh_skeletonization/internal/Curve_skeleton.h @@ -177,7 +177,7 @@ public: bool exist; edge_desc edge; - boost::tie(edge, exist) = boost::edge(p1_vd, p2_vd, curve); + std::tie(edge, exist) = boost::edge(p1_vd, p2_vd, curve); if (!exist) { boost::add_edge(p1_vd, p2_vd, curve); @@ -353,7 +353,7 @@ private: // look for ei from p2's incident edges bool found; int ind; - boost::tie(found, ind) = find_edge(vertex_to_edge[p2], ei); + std::tie(found, ind) = find_edge(vertex_to_edge[p2], ei); if (!found) { continue; diff --git a/Surface_mesher/doc/Surface_mesher/PackageDescription.txt b/Surface_mesher/doc/Surface_mesher/PackageDescription.txt index 39b9d967d97..091d2399df4 100644 --- a/Surface_mesher/doc/Surface_mesher/PackageDescription.txt +++ b/Surface_mesher/doc/Surface_mesher/PackageDescription.txt @@ -21,7 +21,6 @@ /*! \addtogroup PkgSurfaceMesher3Ref -\todo check generated documentation \cgalPkgDescriptionBegin{3D Surface Mesh Generation,PkgSurfaceMesher3} \cgalPkgPicture{segmented_head-small.png} \cgalPkgSummaryBegin diff --git a/Surface_mesher/include/CGAL/Surface_mesher/Sphere_oracle_3.h b/Surface_mesher/include/CGAL/Surface_mesher/Sphere_oracle_3.h index 2e8cf47f695..92c9b08a56b 100644 --- a/Surface_mesher/include/CGAL/Surface_mesher/Sphere_oracle_3.h +++ b/Surface_mesher/include/CGAL/Surface_mesher/Sphere_oracle_3.h @@ -27,7 +27,7 @@ #include #include -#include +#include namespace CGAL { @@ -96,7 +96,7 @@ namespace CGAL { { const Self& oracle; - boost::tuple + std::tuple intersection_line_sphere_lambda(const Surface_3& sphere, const Point& a, const Point& b) const @@ -148,18 +148,18 @@ namespace CGAL { switch( CGAL::sign(deltaprime) ) { case ZERO: - return boost::make_tuple(1, ab_ac / ab2, 0); + return std::make_tuple(1, ab_ac / ab2, 0); case POSITIVE: { const FT sqrt_deltaprime = CGAL::sqrt(deltaprime); - return boost::make_tuple(2, - (ab_ac - sqrt_deltaprime) / ab2, - (ab_ac + sqrt_deltaprime) / ab2); + return std::make_tuple(2, + (ab_ac - sqrt_deltaprime) / ab2, + (ab_ac + sqrt_deltaprime) / ab2); } case NEGATIVE: break; } - return boost::make_tuple(0, 0, 0); + return std::make_tuple(0, 0, 0); } //end intersection_line_sphere_lambda template @@ -179,7 +179,7 @@ namespace CGAL { int number_of_roots; FT root_1, root_2; - boost::tie(number_of_roots, root_1, root_2) = + std::tie(number_of_roots, root_1, root_2) = intersection_line_sphere_lambda(sphere, a, b); const Vector ab = vector(a, b); @@ -285,7 +285,7 @@ namespace CGAL { int number_of_roots; FT root_1, root_2; - boost::tie(number_of_roots, root_1, root_2) = + std::tie(number_of_roots, root_1, root_2) = intersection_line_sphere_lambda(sphere, a, b); #ifdef CGAL_SURFACE_MESHER_DEBUG_IMPLICIT_ORACLE @@ -347,7 +347,7 @@ namespace CGAL { int number_of_roots; FT root_1, root_2; - boost::tie(number_of_roots, root_1, root_2) = + std::tie(number_of_roots, root_1, root_2) = intersection_line_sphere_lambda(sphere, a, b); if( number_of_roots == 2 && root_2 > FT(0) ) @@ -386,7 +386,7 @@ namespace CGAL { int number_of_roots; FT root_1, root_2; - boost::tie(number_of_roots, root_1, root_2) = + std::tie(number_of_roots, root_1, root_2) = intersection_line_sphere_lambda(sphere, a, b); if( number_of_roots == 2 ) diff --git a/Surface_sweep_2/doc/Surface_sweep_2/PackageDescription.txt b/Surface_sweep_2/doc/Surface_sweep_2/PackageDescription.txt index d6d239ae476..8f4d6fcc4d6 100644 --- a/Surface_sweep_2/doc/Surface_sweep_2/PackageDescription.txt +++ b/Surface_sweep_2/doc/Surface_sweep_2/PackageDescription.txt @@ -1,7 +1,6 @@ /// \defgroup PkgSurfaceSweep2Ref 2D Intersection of Curves Reference /*! \addtogroup PkgSurfaceSweep2Ref -\todo check generated documentation \cgalPkgDescriptionBegin{2D Intersection of Curves,PkgSurfaceSweep2} \cgalPkgPicture{Curve_intersections_2.png} \cgalPkgSummaryBegin diff --git a/TDS_2/doc/TDS_2/PackageDescription.txt b/TDS_2/doc/TDS_2/PackageDescription.txt index d4dc2c2645e..95af343936f 100644 --- a/TDS_2/doc/TDS_2/PackageDescription.txt +++ b/TDS_2/doc/TDS_2/PackageDescription.txt @@ -3,7 +3,6 @@ /// \ingroup PkgTDS2Ref /*! \addtogroup PkgTDS2Ref -\todo check generated documentation \cgalPkgDescriptionBegin{2D Triangulation Data Structure,PkgTDS2} \cgalPkgPicture{tds_small.png} \cgalPkgSummaryBegin diff --git a/TDS_3/doc/TDS_3/PackageDescription.txt b/TDS_3/doc/TDS_3/PackageDescription.txt index 06523934036..9f2efbc741f 100644 --- a/TDS_3/doc/TDS_3/PackageDescription.txt +++ b/TDS_3/doc/TDS_3/PackageDescription.txt @@ -10,7 +10,6 @@ /// \ingroup PkgTDS3Ref /*! \addtogroup PkgTDS3Ref -\todo check generated documentation \cgalPkgDescriptionBegin{3D Triangulation Data Structure,PkgTDS3} \cgalPkgPicture{tds3_small.png} \cgalPkgSummaryBegin diff --git a/Triangulation_2/doc/Triangulation_2/CGAL/Triangulation_2.h b/Triangulation_2/doc/Triangulation_2/CGAL/Triangulation_2.h index 14dff71d41f..ffc29f933bb 100644 --- a/Triangulation_2/doc/Triangulation_2/CGAL/Triangulation_2.h +++ b/Triangulation_2/doc/Triangulation_2/CGAL/Triangulation_2.h @@ -1192,6 +1192,18 @@ Returns the line segment corresponding to edge `*ei`. Segment segment(const Edge_iterator& ei) const; +/*! +Returns the point given by vertex `i` of face `f`. +\pre `t.dimension()` \f$ \geq0\f$ and \f$ i \in\{0,1,2\}\f$ in dimension 2, \f$ i \in\{0,1\}\f$ in dimension 1, \f$ i = 0\f$ in dimension 0, and the vertex is finite. +*/ +const Point& point(Face_handle f, int i) const; + +/*! +Same as the previous method for vertex `v`. +\pre `t.dimension()` \f$ \geq0\f$ and the vertex is finite. +*/ +const Point& point(Vertex_handle v) const; + /*! Compute the circumcenter of the face pointed to by f. This function is available only if the corresponding function is provided in the diff --git a/Triangulation_2/doc/Triangulation_2/PackageDescription.txt b/Triangulation_2/doc/Triangulation_2/PackageDescription.txt index f84ffe376ba..815186bb141 100644 --- a/Triangulation_2/doc/Triangulation_2/PackageDescription.txt +++ b/Triangulation_2/doc/Triangulation_2/PackageDescription.txt @@ -27,7 +27,6 @@ /*! \addtogroup PkgTriangulation2Ref -\todo check generated documentation \cgalPkgDescriptionBegin{2D Triangulations,PkgTriangulation2} \cgalPkgPicture{cdt2d-small.png} \cgalPkgSummaryBegin diff --git a/Triangulation_2/include/CGAL/Constrained_triangulation_2.h b/Triangulation_2/include/CGAL/Constrained_triangulation_2.h index bebc96c3c0e..eb71d1223d6 100644 --- a/Triangulation_2/include/CGAL/Constrained_triangulation_2.h +++ b/Triangulation_2/include/CGAL/Constrained_triangulation_2.h @@ -738,7 +738,7 @@ insert(const Point& a, Locate_type lt, Face_handle loc, int li) int i; if(this->is_edge(vp.first, vp.second, fh,i)){ fh->set_constraint(i,true); - boost::tie(fh,i) = mirror_edge(Edge(fh,i)); + std::tie(fh,i) = mirror_edge(Edge(fh,i)); fh->set_constraint(i,true); } } @@ -815,7 +815,7 @@ insert_constraint(Vertex_handle vaa, Vertex_handle vbb) internal::Indentation_level::Exit_guard exit_guard = CGAL::internal::cdt_2_indent_level.open_new_scope(); #endif // CGAL_CDT_2_DEBUG_INTERSECTIONS while(! stack.empty()){ - boost::tie(vaa,vbb) = stack.top(); + std::tie(vaa,vbb) = stack.top(); stack.pop(); CGAL_precondition( vaa != vbb); #ifdef CGAL_CDT_2_DEBUG_INTERSECTIONS diff --git a/Triangulation_2/include/CGAL/Constrained_triangulation_plus_2.h b/Triangulation_2/include/CGAL/Constrained_triangulation_plus_2.h index 4690ef410ad..b34ff60a36e 100644 --- a/Triangulation_2/include/CGAL/Constrained_triangulation_plus_2.h +++ b/Triangulation_2/include/CGAL/Constrained_triangulation_plus_2.h @@ -428,7 +428,7 @@ public: // cid is [B, P, C] // head is null or [A...B] // tail is null or [C...D] - // Let create insert [C,D] and conditionnaly concatenate head and tail, + // Let create insert [C,D] and conditionally concatenate head and tail, // and return the iterator to C Vertex_handle b = *std::prev(pos); @@ -740,9 +740,9 @@ public: for(auto it = vertices.begin(), succ = it; ++succ != vertices.end(); ++it){ if(! is_subconstraint(*it, *succ)){ // this checks whether other constraints pass Face_handle fh; - int i; - bool b = Triangulation::is_edge(*it, *succ, fh, i); - CGAL_assume(b); + int i = -1; + Triangulation::is_edge(*it, *succ, fh, i); + CGAL_assertion(i != -1); Triangulation::remove_constrained_edge(fh,i, out); // this does also flipping if necessary. } } diff --git a/Triangulation_2/include/CGAL/Triangulation_2/internal/Polyline_constraint_hierarchy_2.h b/Triangulation_2/include/CGAL/Triangulation_2/internal/Polyline_constraint_hierarchy_2.h index 88adda09d48..4bcc4bebfe0 100644 --- a/Triangulation_2/include/CGAL/Triangulation_2/internal/Polyline_constraint_hierarchy_2.h +++ b/Triangulation_2/include/CGAL/Triangulation_2/internal/Polyline_constraint_hierarchy_2.h @@ -365,7 +365,7 @@ public: // - The end value is when `constraint_it` is the end iterator of `constraints_set`. // In that case `vertex_it` must be singular. // - // - Otherwise all members must be valid pointers or dereferencable iterators. + // - Otherwise all members must be valid pointers or dereferenceable iterators. bool is_singular() const { return hierarchy == nullptr; diff --git a/Triangulation_3/benchmark/Triangulation_3/CMakeLists.txt b/Triangulation_3/benchmark/Triangulation_3/CMakeLists.txt index 544a5c02d2a..419938ed36e 100644 --- a/Triangulation_3/benchmark/Triangulation_3/CMakeLists.txt +++ b/Triangulation_3/benchmark/Triangulation_3/CMakeLists.txt @@ -8,22 +8,6 @@ project(Triangulation_3) # CGAL and its components find_package(CGAL REQUIRED) -# Boost and its components -find_package(Boost REQUIRED) - -if(NOT Boost_FOUND) - - message( - STATUS "This project requires the Boost library, and will not be compiled.") - - return() - -endif() - -# include for local directory - -# include for local package - # Creating entries for all C++ files with "main" routine # ########################################################## diff --git a/Triangulation_on_sphere_2/demo/Triangulation_on_sphere_2/main.cpp b/Triangulation_on_sphere_2/demo/Triangulation_on_sphere_2/main.cpp index 71cae05953d..1579f45389a 100644 --- a/Triangulation_on_sphere_2/demo/Triangulation_on_sphere_2/main.cpp +++ b/Triangulation_on_sphere_2/demo/Triangulation_on_sphere_2/main.cpp @@ -69,7 +69,7 @@ public slots: if (list.size()!=4){ QMessageBox *msgBox = new QMessageBox; msgBox->setWindowTitle("Error"); - msgBox->setText("ERROR : Input should consists of 4 doubles: The radius first, then the coordinates of the center."); + msgBox->setText("ERROR : Input should consist of 4 doubles: The radius first, then the coordinates of the center."); msgBox->exec(); return; } diff --git a/Voronoi_diagram_2/doc/Voronoi_diagram_2/PackageDescription.txt b/Voronoi_diagram_2/doc/Voronoi_diagram_2/PackageDescription.txt index 58edde2ec5a..898f2932d71 100644 --- a/Voronoi_diagram_2/doc/Voronoi_diagram_2/PackageDescription.txt +++ b/Voronoi_diagram_2/doc/Voronoi_diagram_2/PackageDescription.txt @@ -20,7 +20,6 @@ /*! \addtogroup PkgVoronoiDiagram2Ref -\todo check generated documentation \cgalPkgDescriptionBegin{2D Voronoi Diagram Adaptor,PkgVoronoiDiagram2} \cgalPkgPicture{voronoi.png} \cgalPkgSummaryBegin diff --git a/Weights/include/CGAL/Weights/cotangent_weights.h b/Weights/include/CGAL/Weights/cotangent_weights.h index 4f389e3b06b..34a6d79f178 100644 --- a/Weights/include/CGAL/Weights/cotangent_weights.h +++ b/Weights/include/CGAL/Weights/cotangent_weights.h @@ -344,7 +344,6 @@ public: return cotangent_weight_calculator(he); } -private: FT voronoi(const vertex_descriptor v0) const { auto squared_length_3 = m_traits.compute_squared_length_3_object(); @@ -354,11 +353,12 @@ private: for (const halfedge_descriptor he : halfedges_around_target(halfedge(v0, m_pmesh), m_pmesh)) { CGAL_assertion(v0 == target(he, m_pmesh)); - CGAL_assertion(CGAL::is_triangle(he, m_pmesh)); if (is_border(he, m_pmesh)) continue; + CGAL_assertion(CGAL::is_triangle(he, m_pmesh)); + const vertex_descriptor v1 = source(he, m_pmesh); const vertex_descriptor v2 = target(next(he, m_pmesh), m_pmesh); diff --git a/Weights/include/CGAL/Weights/internal/utils.h b/Weights/include/CGAL/Weights/internal/utils.h index 850fccff1e8..80822b68c84 100644 --- a/Weights/include/CGAL/Weights/internal/utils.h +++ b/Weights/include/CGAL/Weights/internal/utils.h @@ -44,7 +44,7 @@ private: public: FT operator()(const FT value) const { - return static_cast(CGAL::sqrt(CGAL::to_double(CGAL::abs(value)))); + return CGAL::approximate_sqrt(CGAL::abs(value)); } };