diff --git a/.github/workflows/build_doc.yml b/.github/workflows/build_doc.yml index 974d8e55f2f..8657f56e4a0 100644 --- a/.github/workflows/build_doc.yml +++ b/.github/workflows/build_doc.yml @@ -109,7 +109,7 @@ jobs: mv tmp.html index.html git add ${PR_NUMBER}/$ROUND index.html && git commit -q --amend -m "base commit" && git push -q -f -u origin master else - echo "::set-output name=DoxygenError::This round already exists. Overwrite it with /force-build" + echo "::set-output name=DoxygenError::This round already exists. Overwrite it with /force-build." exit 1 fi @@ -121,7 +121,7 @@ jobs: const tmp_round = "${{ steps.get_round.outputs.result }}"; const id = tmp_round.indexOf(":"); const round = tmp_round.substring(0,id); - const address = "The documentation is built. It will be available, after a few minutes, here : https://cgal.github.io/${{ steps.get_pr_number.outputs.result }}/"+round+"/Manual/index.html" + const address = "The documentation is built. It will be available, after a few minutes, here: https://cgal.github.io/${{ steps.get_pr_number.outputs.result }}/"+round+"/Manual/index.html" github.issues.createComment({ owner: "CGAL", repo: "cgal", diff --git a/.github/workflows/delete_doc.yml b/.github/workflows/delete_doc.yml index 38dbc242e31..0abf8bb7046 100644 --- a/.github/workflows/delete_doc.yml +++ b/.github/workflows/delete_doc.yml @@ -22,11 +22,10 @@ jobs: if [ -n "$(diff -q ./index.html ./tmp.html)" ]; then mv tmp.html index.html fi - if [ -d ${PR_NUMBER} ]; then - git rm -r ${PR_NUMBER} + if [ -d ${PR_NUMBER} ]; then + git rm -r ${PR_NUMBER} fi - #git diff exits with 1 if there is no diff - if git diff --quiet; then + # `git diff --quiet` exits with 1 if there is a diff + if ! git diff --quiet; then git commit -a --amend -m"base commit" && git push -f -u origin master fi - diff --git a/.github/workflows/filter_testsuite.yml b/.github/workflows/filter_testsuite.yml index a79a68dbff6..e1d8ebf2221 100644 --- a/.github/workflows/filter_testsuite.yml +++ b/.github/workflows/filter_testsuite.yml @@ -61,7 +61,7 @@ jobs: uses: actions/github-script@v3 with: script: | - const address = "The testsuite is lauched. results will be found, after it is done, here : https://cgal.geometryfactory.com/~cgaltest/test_suite/TESTRESULTS/index.shtml " + const address = "Testsuite launched. Results will appear on the following page: https://cgal.geometryfactory.com/~cgaltest/test_suite/TESTRESULTS/index.shtml " github.issues.createComment({ owner: "CGAL", repo: "cgal", diff --git a/AABB_tree/doc/AABB_tree/Concepts/AABBGeomTraits.h b/AABB_tree/doc/AABB_tree/Concepts/AABBGeomTraits.h index e9a664c2ff8..808f4506c5c 100644 --- a/AABB_tree/doc/AABB_tree/Concepts/AABBGeomTraits.h +++ b/AABB_tree/doc/AABB_tree/Concepts/AABBGeomTraits.h @@ -3,13 +3,19 @@ \ingroup PkgAABBTreeConcepts \cgalConcept -The concept `AABBGeomTraits` defines the requirements for the first template parameter of the class `CGAL::AABB_traits`. It provides predicates and constructors to detect and compute intersections between query objects and the primitives stored in the AABB tree. In addition, it contains predicates and constructors to compute distances between a point query and the primitives stored in the AABB tree. +The concept `AABBGeomTraits` defines the requirements for the first template parameter of the class +`CGAL::AABB_traits`. It provides predicates and constructors to detect +and compute intersections between query objects and the primitives stored in the AABB tree. +In addition, it contains predicates and constructors to compute distances between a point query +and the primitives stored in the AABB tree. \cgalRefines `SearchGeomTraits_3` -\cgalHasModel Any 3D Kernel is a model of this traits concept. +\cgalHasModel All models of the concept `Kernel` \sa `CGAL::AABB_traits` +\sa `CGAL::AABB_tree` +\sa `AABBPrimitive` */ @@ -19,118 +25,123 @@ public: /// \name Types /// @{ -/*! -A number type model of `Field`. -*/ -typedef unspecified_type FT; - -/*! -Sphere type, that should be consistent with the distance function chosen for the distance queries, namely the `Squared_distance_3` functor. -*/ -typedef unspecified_type Sphere_3; - -/*! -Point type. -*/ -typedef unspecified_type Point_3; - /*! A functor object to detect intersections between two geometric objects. -Provides the operators: -`bool operator()(const Type_1& type_1, const Type_2& type_2);` -where `Type_1` and `Type_2` are relevant types -among `Ray_3`, `Segment_3`, `Line_3`, `Triangle_3`, `Plane_3` and `Bbox_3`. Relevant herein means that a line primitive (ray, segment, line) is tested against a planar or solid primitive (plane, triangle, box), and a solid primitive is tested against another solid primitive (box against box). The operator returns `true` iff `type_1` and `type_2` have a non empty intersection. +Provides the following operators: + +`bool operator()(Query, Bbox_3)`, + +`bool operator()(Query, Primitive::Datum)`, + +`bool operator()(Sphere_3, Bbox_3)`. + +The operator returns `true` iff there exists a non-empty intersection. */ typedef unspecified_type Do_intersect_3; /*! A functor object to construct the intersection between two geometric objects. -Provides the operators: -`decltype(auto) operator()(const A& a, const B& b);` -where `A` and `B` are any relevant types among `Ray_3`, `Segment_3`, `Line_3`, -`Triangle_3`, `Plane_3` and `Bbox_3`. -Relevant herein means that a line primitive (ray, segment, line) is tested -against a planar or solid primitive (plane, triangle, box). -A model of `Kernel::Intersect_3` fulfills those requirements. +Provides the operator: + +`return_type operator()(const Query& q, const Primitive::Datum& d)`, + +which computes the intersection between `q` and `d`. The type of the returned object +must be a `boost::optional` of a `boost::variant` of the possible intersection types. */ typedef unspecified_type Intersect_3; /*! -A functor object to construct the sphere centered at one point and passing through another one. Provides the operator: -- `Sphere_3 operator()(const Point_3& p, const FT & sr)` which returns the sphere centered at `p` with `sr` as squared radius. +A functor object to construct the sphere centered at one point and passing through another one. +Provides the operator: + +`Sphere_3 operator()(const Point_3& p, const FT & sr)`, + +which returns the sphere centered at `p` with `sr` as squared radius. */ typedef unspecified_type Construct_sphere_3; /*! -A functor object to compute the point on a geometric primitive which is closest from a query. Provides the operator: -`Point_3 operator()(const Type_2& type_2, const Point_3& p);` where `Type_2` can be any of the following types : `Segment_3`, `Ray_3`, or `Triangle_3`. -The operator returns the point on `type_2` which is closest to `p`. +A functor object to compute the point on a geometric primitive which is closest from a query. +Provides the operator: + +`Point_3 operator()(const Primitive::Datum& d, const Point_3& p)`, + +which returns the point on `d` that is closest to `p`. */ typedef unspecified_type Construct_projected_point_3; /*! -A functor object to compare the distance of two points wrt a third one. -Provides the operator: -`CGAL::Comparision_result operator()(const Point_3& p1, const Point_3& p2, const Point_3& p3)`. The operator compare the distance between `p1 and `p2`, and between `p2` and `p3`. +A functor object to compare the distance of two points wrt a third one. Provides the operator: + +`CGAL::Comparision_result operator()(const Point_3& p1, const Point_3& p2, const Point_3& p3)`, + +which compares the distance between `p1 and `p2`, and between `p2` and `p3`. */ typedef unspecified_type Compare_distance_3; /*! -A functor object to detect if a point lies inside a sphere or not. +A functor object to compute the squared radius of a sphere. Provides the operator: -`bool operator()(const Sphere_3& s, const Point_3& p);` which returns `true` iff the closed volume bounded by `s` contains `p`. -*/ -typedef unspecified_type Has_on_bounded_side_3; -/*! -A functor object to compute the squared radius of a sphere. Provides the operator: -`FT operator()(const Sphere_3& s);` which returns the squared radius of `s`. +`FT operator()(const Sphere_3& s),` + +which returns the squared radius of `s`. */ typedef unspecified_type Compute_squared_radius_3; /*! A functor object to compute the squared distance between two points. Provides the operator: -`FT operator()(const Point_3& p, const Point_3& q);}` which returns the squared distance between `p` and `q`. + +`FT operator()(const Point_3& p, const Point_3& q),` + +which returns the squared distance between `p` and `q`. */ typedef unspecified_type Compute_squared_distance_3; /*! A functor object to compare the x-coordinates of two points. Provides the operator: -`bool operator()(const Point_3& p, const Point_3& q);}` which returns `true` if the x-coordinate of `p` is smaller -than the x-coordinate of `q`. + +`bool operator()(const Point_3& p, const Point_3& q)`, + + which returns `true` iff the x-coordinate of `p` is smaller than the x-coordinate of `q`. */ typedef unspecified_type Less_x_3; /*! A functor object to compare the y-coordinates of two points. Provides the operator: -`bool operator()(const Point_3& p, const Point_3& q);}` which returns `true` if the y-coordinate of `p` is smaller -than the y-coordinate of `q`. + +`bool operator()(const Point_3& p, const Point_3& q)`, + +which returns `true` iff the y-coordinate of `p` is smaller than the y-coordinate of `q`. */ typedef unspecified_type Less_y_3; /*! A functor object to compare the z-coordinates of two points. Provides the operator: -`bool operator()(const Point_3& p, const Point_3& q);}` which returns `true` if the z-coordinate of `p` is smaller -than the z-coordinate of `q`. + +`bool operator()(const Point_3& p, const Point_3& q)`, + +which returns `true` iff the z-coordinate of `p` is smaller than the z-coordinate of `q`. */ typedef unspecified_type Less_z_3; /*! A functor object to compare two points. Provides the operator: -`bool operator()(const Point_3& p, const Point_3& q);}` which returns `true` if `p` is equal to `q`. + +`bool operator()(const Point_3& p, const Point_3& q)`, + +which returns `true` iff `p` is equal to `q`. */ typedef unspecified_type Equal_3; - - /// @} /// \name Operations /// @{ /*! -returns the intersection detection functor. +returns the intersection detection predicate. */ Do_intersect_3 do_intersect_3_object(); @@ -150,15 +161,10 @@ returns the closest point constructor. Construct_projected_point_3 construct_projected_point_3_object(); /*! -returns the compare distance constructor. +returns the compare distance predicate. */ Compare_distance_3 compare_distance_3_object(); -/*! -returns the closest point constructor. -*/ -Has_on_bounded_side_3 has_on_bounded_side_3_object(); - /*! returns the squared radius functor. */ @@ -170,22 +176,22 @@ returns the squared distance functor. Compute_squared_distance_3 compute_squared_distance_3_object(); /*! -returns the `Less_x_3` functor. +returns the `Less_x_3` predicate. */ Less_x_3 less_x_3_object(); /*! -returns the `Less_y_3` functor. +returns the `Less_y_3` predicate. */ Less_y_3 less_y_3_object(); /*! -returns the `Less_z_3` functor. +returns the `Less_z_3` predicate. */ Less_z_3 less_z_3_object(); /*! -returns the equal functor. +returns the equal predicate. */ Equal_3 equal_3_object(); diff --git a/AABB_tree/doc/AABB_tree/Concepts/AABBRayIntersectionGeomTraits.h b/AABB_tree/doc/AABB_tree/Concepts/AABBRayIntersectionGeomTraits.h index 22ce34118d3..de83a001ec8 100644 --- a/AABB_tree/doc/AABB_tree/Concepts/AABBRayIntersectionGeomTraits.h +++ b/AABB_tree/doc/AABB_tree/Concepts/AABBRayIntersectionGeomTraits.h @@ -8,7 +8,8 @@ concept `AABBGeomTraits`. In addition to the types required by define the Intersection_distance functor. \cgalRefines `AABBGeomTraits` -\cgalHasModel Any 3D Kernel is a model of this concept. + +\cgalHasModel All models of the concept `Kernel` \sa `CGAL::AABB_traits` \sa `CGAL::AABB_tree` @@ -17,11 +18,6 @@ define the Intersection_distance functor. */ class AABBRayIntersectionGeomTraits { public: - /*! - Type of a 3D point. - */ - typedef unspecified_type Point_3; - /*! Type of a 3D ray. */ diff --git a/AABB_tree/doc/AABB_tree/Concepts/AABBRayIntersectionTraits.h b/AABB_tree/doc/AABB_tree/Concepts/AABBRayIntersectionTraits.h index 2633242ab96..630a569ebfb 100644 --- a/AABB_tree/doc/AABB_tree/Concepts/AABBRayIntersectionTraits.h +++ b/AABB_tree/doc/AABB_tree/Concepts/AABBRayIntersectionTraits.h @@ -9,7 +9,6 @@ distance of an intersection along a ray. \cgalHasModel `CGAL::AABB_traits` -\sa `CGAL::AABB_traits` \sa `CGAL::AABB_tree` \sa `AABBPrimitive` diff --git a/AABB_tree/doc/AABB_tree/PackageDescription.txt b/AABB_tree/doc/AABB_tree/PackageDescription.txt index 931f14adb53..d59794e62d5 100644 --- a/AABB_tree/doc/AABB_tree/PackageDescription.txt +++ b/AABB_tree/doc/AABB_tree/PackageDescription.txt @@ -25,8 +25,10 @@ \cgalCRPSection{Concepts} - `AABBPrimitive` - `AABBPrimitiveWithSharedData` -- `AABBTraits` - `AABBGeomTraits` +- `AABBTraits` +- `AABBRayIntersectionGeomTraits` +- `AABBRayIntersectionTraits` \cgalCRPSection{Classes} - `CGAL::AABB_traits` diff --git a/AABB_tree/examples/AABB_tree/AABB_ray_shooting_example.cpp b/AABB_tree/examples/AABB_tree/AABB_ray_shooting_example.cpp index f1d983eccf1..d3b2af45913 100644 --- a/AABB_tree/examples/AABB_tree/AABB_ray_shooting_example.cpp +++ b/AABB_tree/examples/AABB_tree/AABB_ray_shooting_example.cpp @@ -44,7 +44,7 @@ struct Skip int main(int argc, char* argv[]) { - const char* filename = (argc > 1) ? argv[1] : "data/tetrahedron.off"; + const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/tetrahedron.off"); Mesh mesh; if(!CGAL::IO::read_polygon_mesh(filename, mesh)) diff --git a/AABB_tree/include/CGAL/AABB_traits.h b/AABB_tree/include/CGAL/AABB_traits.h index 4afce689bc9..4e83a3ad7c1 100644 --- a/AABB_tree/include/CGAL/AABB_traits.h +++ b/AABB_tree/include/CGAL/AABB_traits.h @@ -160,7 +160,7 @@ class AABB_tree; /// \tparam BboxMap must be a model of `ReadablePropertyMap` that has as key type a primitive id, /// and as value type a `Bounding_box`. /// If the type is `Default` the `Datum` must have the -/// member function `bbox()` that returns the bounding box of the primitive. +/// member function `bbox()` that returns the bounding box of the primitive. /// /// If the argument `GeomTraits` is a model of the concept \ref /// AABBRayIntersectionGeomTraits, this class is also a model of \ref @@ -366,7 +366,7 @@ public: template boost::optional< typename Intersection_and_primitive_id::Type > operator()(const Query& query, const typename AT::Primitive& primitive) const { - auto inter_res = GeomTraits().intersect_3_object()(internal::Primitive_helper::get_datum(primitive,m_traits),query); + auto inter_res = GeomTraits().intersect_3_object()(query, internal::Primitive_helper::get_datum(primitive,m_traits)); if (!inter_res) return boost::none; return boost::make_optional( std::make_pair(*inter_res, primitive.id()) ); @@ -391,9 +391,9 @@ public: GeomTraits geom_traits; Point closest_point = geom_traits.construct_projected_point_3_object()( internal::Primitive_helper::get_datum(pr,m_traits), p); - return - geom_traits.compare_distance_3_object()(p, closest_point, bound)==LARGER ? - bound : closest_point; + + return (geom_traits.compare_distance_3_object()(p, closest_point, bound) == LARGER) ? + bound : closest_point; } }; @@ -406,15 +406,6 @@ public: typedef typename AT::FT FT; typedef typename AT::Primitive Primitive; public: - template - CGAL::Comparison_result operator()(const Point& p, const Solid& pr, const Point& bound) const - { - return GeomTraits().do_intersect_3_object() - (GeomTraits().construct_sphere_3_object() - (p, GeomTraits().compute_squared_distance_3_object()(p, bound)), pr)? - CGAL::SMALLER : CGAL::LARGER; - } - CGAL::Comparison_result operator()(const Point& p, const Bounding_box& bb, const Point& bound, Tag_true) const { return GeomTraits().do_intersect_3_object() @@ -436,6 +427,16 @@ public: return (*this)(p, bb, bound, Boolean_tag::value>()); } + // The following functions seem unused...? + template + CGAL::Comparison_result operator()(const Point& p, const Solid& pr, const Point& bound) const + { + return GeomTraits().do_intersect_3_object() + (GeomTraits().construct_sphere_3_object() + (p, GeomTraits().compute_squared_distance_3_object()(p, bound)), pr)? + CGAL::SMALLER : CGAL::LARGER; + } + template CGAL::Comparison_result operator()(const Point& p, const Solid& pr, const FT& sq_distance) const { @@ -445,7 +446,6 @@ public: CGAL::SMALLER : CGAL::LARGER; } - }; Closest_point closest_point_object() const {return Closest_point(*this);} diff --git a/AABB_tree/test/AABB_tree/aabb_correctness_triangle_test.cpp b/AABB_tree/test/AABB_tree/aabb_correctness_triangle_test.cpp index 5489c2c9c15..13eb303b771 100644 --- a/AABB_tree/test/AABB_tree/aabb_correctness_triangle_test.cpp +++ b/AABB_tree/test/AABB_tree/aabb_correctness_triangle_test.cpp @@ -38,7 +38,7 @@ int test() // load polyhedron typedef CGAL::Polyhedron_3 Polyhedron; Polyhedron polyhedron; - std::ifstream ifs("./data/tetrahedron.off"); + std::ifstream ifs(CGAL::data_file_path("meshes/tetrahedron.off")); ifs >> polyhedron; // construct tree from facets @@ -129,4 +129,3 @@ int main() /* Local Variables: */ /* tab-width: 2 */ /* End: */ - diff --git a/AABB_tree/test/AABB_tree/aabb_test_is_ray_intersection_geomtraits.cpp b/AABB_tree/test/AABB_tree/aabb_test_is_ray_intersection_geomtraits.cpp index 7552e4ab53d..c7198fe98e0 100644 --- a/AABB_tree/test/AABB_tree/aabb_test_is_ray_intersection_geomtraits.cpp +++ b/AABB_tree/test/AABB_tree/aabb_test_is_ray_intersection_geomtraits.cpp @@ -12,14 +12,12 @@ struct AABBGeomTraits { typedef nope Intersect_3; typedef nope Construct_sphere_3; typedef nope Compute_closest_point_3; - typedef nope Has_on_bounded_side_3; typedef nope Compute_squared_radius_3; typedef nope Compute_squared_distance_3; Do_intersect_3 do_intersect_3_object(); Intersect_3 intersect_3_object(); Construct_sphere_3 construct_sphere_3_object(); Compute_closest_point_3 compute_closest_point_3_object(); - Has_on_bounded_side_3 has_on_bounded_side_3_object(); Compute_squared_radius_3 compute_squared_radius_3_object(); Compute_squared_distance_3 compute_squared_distance_3_object(); }; /* end AABBGeomTraits */ diff --git a/Advancing_front_surface_reconstruction/package_info/Advancing_front_surface_reconstruction/dependencies b/Advancing_front_surface_reconstruction/package_info/Advancing_front_surface_reconstruction/dependencies index 80d674f254a..fffe4db3c74 100644 --- a/Advancing_front_surface_reconstruction/package_info/Advancing_front_surface_reconstruction/dependencies +++ b/Advancing_front_surface_reconstruction/package_info/Advancing_front_surface_reconstruction/dependencies @@ -19,7 +19,6 @@ Kernel_d Modifier Modular_arithmetic Number_types -Polygon Polyhedron Profiling_tools Property_map diff --git a/Algebraic_foundations/include/CGAL/Coercion_traits.h b/Algebraic_foundations/include/CGAL/Coercion_traits.h index 85f5f0cf950..2e97218dbe6 100644 --- a/Algebraic_foundations/include/CGAL/Coercion_traits.h +++ b/Algebraic_foundations/include/CGAL/Coercion_traits.h @@ -148,33 +148,26 @@ template struct Coercion_traits_for_level; CGAL_DEFINE_COERCION_TRAITS_FROM_TO(short,int) CGAL_DEFINE_COERCION_TRAITS_FROM_TO(short,long) -#ifdef CGAL_USE_LONG_LONG - CGAL_DEFINE_COERCION_TRAITS_FROM_TO(short,long long) -#endif +CGAL_DEFINE_COERCION_TRAITS_FROM_TO(short,long long) CGAL_DEFINE_COERCION_TRAITS_FROM_TO(short,float) CGAL_DEFINE_COERCION_TRAITS_FROM_TO(short,double) CGAL_DEFINE_COERCION_TRAITS_FROM_TO(short,long double) CGAL_DEFINE_COERCION_TRAITS_FROM_TO(int,long) -#ifdef CGAL_USE_LONG_LONG - CGAL_DEFINE_COERCION_TRAITS_FROM_TO(int,long long) -#endif +CGAL_DEFINE_COERCION_TRAITS_FROM_TO(int,long long) CGAL_DEFINE_COERCION_TRAITS_FROM_TO(int,float) CGAL_DEFINE_COERCION_TRAITS_FROM_TO(int,double) CGAL_DEFINE_COERCION_TRAITS_FROM_TO(int,long double) -#ifdef CGAL_USE_LONG_LONG - CGAL_DEFINE_COERCION_TRAITS_FROM_TO(long,long long) -#endif +CGAL_DEFINE_COERCION_TRAITS_FROM_TO(long,long long) CGAL_DEFINE_COERCION_TRAITS_FROM_TO(long,float) CGAL_DEFINE_COERCION_TRAITS_FROM_TO(long,double) CGAL_DEFINE_COERCION_TRAITS_FROM_TO(long,long double) -#ifdef CGAL_USE_LONG_LONG - CGAL_DEFINE_COERCION_TRAITS_FROM_TO(long long,float) - CGAL_DEFINE_COERCION_TRAITS_FROM_TO(long long,double) - CGAL_DEFINE_COERCION_TRAITS_FROM_TO(long long,long double) -#endif + +CGAL_DEFINE_COERCION_TRAITS_FROM_TO(long long,float) +CGAL_DEFINE_COERCION_TRAITS_FROM_TO(long long,double) +CGAL_DEFINE_COERCION_TRAITS_FROM_TO(long long,long double) CGAL_DEFINE_COERCION_TRAITS_FROM_TO(float,double) CGAL_DEFINE_COERCION_TRAITS_FROM_TO(float,long double) @@ -198,9 +191,7 @@ struct Coercion_traits{ CGAL_DEFINE_COERCION_TRAITS_FOR_SELF(short) CGAL_DEFINE_COERCION_TRAITS_FOR_SELF(int) CGAL_DEFINE_COERCION_TRAITS_FOR_SELF(long) -#ifdef CGAL_USE_LONG_LONG - CGAL_DEFINE_COERCION_TRAITS_FOR_SELF(long long) -#endif +CGAL_DEFINE_COERCION_TRAITS_FOR_SELF(long long) CGAL_DEFINE_COERCION_TRAITS_FOR_SELF(float) CGAL_DEFINE_COERCION_TRAITS_FOR_SELF(double) CGAL_DEFINE_COERCION_TRAITS_FOR_SELF(long double) diff --git a/Algebraic_foundations/include/CGAL/Needs_parens_as_product.h b/Algebraic_foundations/include/CGAL/Needs_parens_as_product.h index 1aa82b277e3..4cc9ebcd504 100644 --- a/Algebraic_foundations/include/CGAL/Needs_parens_as_product.h +++ b/Algebraic_foundations/include/CGAL/Needs_parens_as_product.h @@ -75,11 +75,9 @@ template <> struct Needs_parens_as_product{ bool operator()(const long& x){return x < long(0);} }; -#ifdef CGAL_USE_LONG_LONG template <> struct Needs_parens_as_product{ bool operator()(const long long& x){return x < (long long)(0);} }; -#endif template <> struct Needs_parens_as_product{ bool operator()(const float& x){return x < float(0);} diff --git a/Alpha_shapes_3/package_info/Alpha_shapes_3/dependencies b/Alpha_shapes_3/package_info/Alpha_shapes_3/dependencies index 6a453cfa1e9..f0dc76c90d9 100644 --- a/Alpha_shapes_3/package_info/Alpha_shapes_3/dependencies +++ b/Alpha_shapes_3/package_info/Alpha_shapes_3/dependencies @@ -11,7 +11,6 @@ Interval_support Kernel_23 Modular_arithmetic Number_types -Polygon Profiling_tools Property_map STL_Extension diff --git a/Apollonius_graph_2/package_info/Apollonius_graph_2/dependencies b/Apollonius_graph_2/package_info/Apollonius_graph_2/dependencies index 326f1dd8070..d0ac5f0a017 100644 --- a/Apollonius_graph_2/package_info/Apollonius_graph_2/dependencies +++ b/Apollonius_graph_2/package_info/Apollonius_graph_2/dependencies @@ -14,7 +14,6 @@ Interval_support Kernel_23 Modular_arithmetic Number_types -Polygon Profiling_tools Property_map STL_Extension 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 ab71867c2bc..7aa1fded18f 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 @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -885,11 +886,11 @@ public: /*! Clean all operation counters */ void clear_counters() - { memset(m_counters, 0, sizeof(m_counters)); } + { m_counters = {}; } private: /*! The operation counters */ - mutable size_t m_counters[NUMBER_OF_OPERATIONS]; + mutable std::array m_counters; }; template diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_geometry_traits/Conic_x_monotone_arc_2.h b/Arrangement_on_surface_2/include/CGAL/Arr_geometry_traits/Conic_x_monotone_arc_2.h index b6587f4e1ab..761e38b1693 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_geometry_traits/Conic_x_monotone_arc_2.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_geometry_traits/Conic_x_monotone_arc_2.h @@ -263,7 +263,7 @@ public: Comparison_result res = ker.compare_x_2_object()(this->_source, this->_target); - this->_info = (Conic_arc_2::IS_VALID | DEGREE_1); + this->_info = (static_cast(Conic_arc_2::IS_VALID) | static_cast(DEGREE_1)); if (res == EQUAL) { // Mark that the segment is vertical. this->_info = (this->_info | IS_VERTICAL_SEGMENT); diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_overlay_2.h b/Arrangement_on_surface_2/include/CGAL/Arr_overlay_2.h index 285faa4c183..9ca536c4cd9 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_overlay_2.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_overlay_2.h @@ -169,19 +169,15 @@ overlay(const Arrangement_on_surface_2& arr1 typedef typename Arr_res::Allocator Allocator; // some type assertions (not all, but better than nothing). -#if !defined(CGAL_NO_ASSERTIONS) typedef typename Agt2::Point_2 A_point; typedef typename Bgt2::Point_2 B_point; typedef typename Rgt2::Point_2 Res_point; -#endif CGAL_static_assertion((boost::is_convertible::value)); CGAL_static_assertion((boost::is_convertible::value)); -#if !defined(CGAL_NO_ASSERTIONS) typedef typename Agt2::X_monotone_curve_2 A_xcv; typedef typename Bgt2::X_monotone_curve_2 B_xcv; typedef typename Rgt2::X_monotone_curve_2 Res_xcv; -#endif CGAL_static_assertion((boost::is_convertible::value)); CGAL_static_assertion((boost::is_convertible::value)); diff --git a/Arrangement_on_surface_2/include/CGAL/IO/Fig_stream.h b/Arrangement_on_surface_2/include/CGAL/IO/Fig_stream.h index 22562cd1663..0a89ec038a3 100644 --- a/Arrangement_on_surface_2/include/CGAL/IO/Fig_stream.h +++ b/Arrangement_on_surface_2/include/CGAL/IO/Fig_stream.h @@ -20,6 +20,7 @@ #include #include +#include #include namespace CGAL { @@ -750,14 +751,17 @@ public: return; // Prepare a string desribing the color. - char color_desc [10]; - sprintf ("#%02x%02x%02x", r, g, b); + std::stringstream out; + out << "0x" << std::hex + << std::setfill('0') << std::setw(2) << r + << std::setfill('0') << std::setw(2) << g + << std::setfill('0') << std::setw(2) << b; // Write the color to the FIG file. _ofile << "0 " // Desginates a color pseudo-object. << static_cast(color) << ' ' - << color_desc << std::endl; + << out.str() << std::endl; // Mark that the color is now defined. colors[static_cast(color)] = true; @@ -1700,7 +1704,6 @@ protected: _ofile << ' ' << ix << ' ' << iy << ' '; // Write the text. - char oct[10]; int i; for (i = 0; i < len_text; i++) @@ -1712,9 +1715,11 @@ protected: } else { - // Convert the current character to an octal string and write it. - sprintf (oct, "\\%03o", text[i]); - _ofile << oct; + // Convert the current character to an octal string and write + // it. + std::stringstream out; + out << "\\" << std::setfill('0') << std::setw(3) << std::oct << text[i]; + _ofile << out.str(); } } diff --git a/BGL/include/CGAL/boost/graph/IO/PLY.h b/BGL/include/CGAL/boost/graph/IO/PLY.h index 38af496f723..f14ad0173af 100644 --- a/BGL/include/CGAL/boost/graph/IO/PLY.h +++ b/BGL/include/CGAL/boost/graph/IO/PLY.h @@ -84,7 +84,7 @@ bool read_PLY_BGL(std::istream& is, The data is expected to represent a 2-manifold (possibly with borders). - \attention When reading a binary file, the flag `std::ios::binary` flag must be set during the creation of the `ifstream`. + \attention To read a binary file, the flag `std::ios::binary` must be set during the creation of the `ifstream`. \tparam Graph a model of `MutableFaceGraph` \tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" @@ -266,7 +266,9 @@ bool read_PLY(const std::string& fname, Graph& g, \brief writes the graph in an output stream, using the \ref IOStreamPLY. - \attention When writing a binary file, the flag `std::ios::binary` flag must be set during the creation of the `ofstream`. + \attention To write to a binary file, the flag `std::ios::binary` must be set during the creation + of the `ofstream`, and the \link PkgStreamSupportEnumRef `IO::Mode` \endlink + of the stream must be set to `BINARY`. \tparam Graph a model of `FaceListGraph` \tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" diff --git a/BGL/include/CGAL/boost/graph/IO/STL.h b/BGL/include/CGAL/boost/graph/IO/STL.h index 11e9ed59ac1..1a1c05e082c 100644 --- a/BGL/include/CGAL/boost/graph/IO/STL.h +++ b/BGL/include/CGAL/boost/graph/IO/STL.h @@ -73,7 +73,7 @@ public: \attention The graph `g` is not cleared, and the data from the stream are appended. - \attention When reading a binary file, the flag `std::ios::binary` flag must be set during the creation of the `ifstream`. + \attention To read a binary file, the flag `std::ios::binary` must be set during the creation of the `ifstream`. \tparam Graph a model of `MutableFaceGraph` \tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" @@ -208,7 +208,9 @@ bool read_STL(const std::string& fname, Graph& g) { return read_STL(fname, g, pa \brief writes the graph `g` in the output stream `os`, using the \ref IOStreamSTL. - \attention When writing a binary file, the flag `std::ios::binary` flag must be set during the creation of the `ofstream`. + \attention To write to a binary file, the flag `std::ios::binary` must be set during the creation + of the `ofstream`, and the \link PkgStreamSupportEnumRef `IO::Mode` \endlink of the stream + must be set to `BINARY`. \tparam Graph a model of `FaceListGraph` and `HalfedgeListGraph` \tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" diff --git a/BGL/include/CGAL/boost/graph/Named_function_parameters.h b/BGL/include/CGAL/boost/graph/Named_function_parameters.h index c1858ac0198..0fe22798160 100644 --- a/BGL/include/CGAL/boost/graph/Named_function_parameters.h +++ b/BGL/include/CGAL/boost/graph/Named_function_parameters.h @@ -16,6 +16,7 @@ #include #include +#include #define CGAL_BGL_NP_TEMPLATE_PARAMETERS T, typename Tag, typename Base #define CGAL_BGL_NP_CLASS CGAL::Named_function_parameters @@ -38,8 +39,9 @@ enum all_default_t { all_default }; template struct Named_params_impl : Base { - T v; // copy of the parameter - Named_params_impl(T v, const Base& b) + typename std::conditional::value, + T, std::reference_wrapper >::type v; // copy of the parameter if copyable + Named_params_impl(const T& v, const Base& b) : Base(b) , v(v) {} @@ -49,8 +51,9 @@ struct Named_params_impl : Base template struct Named_params_impl { - T v; // copy of the parameter - Named_params_impl(T v) + typename std::conditional::value, + T, std::reference_wrapper >::type v; // copy of the parameter if copyable + Named_params_impl(const T& v) : v(v) {} }; @@ -63,18 +66,39 @@ template< typename T, typename Tag, typename Query_tag> struct Get_param< Named_params_impl, Query_tag > { typedef Param_not_found type; + typedef Param_not_found reference; }; template< typename T, typename Tag, typename Base> struct Get_param< Named_params_impl, Tag > { - typedef T type; + typedef typename std::conditional::value, + T, std::reference_wrapper >::type type; + typedef typename std::conditional::value, + T, const T&>::type reference; }; template< typename T, typename Tag> struct Get_param< Named_params_impl, Tag > { - typedef T type; + typedef typename std::conditional::value, + T, std::reference_wrapper >::type type; + typedef typename std::conditional::value, + T, const T&>::type reference; +}; + +template< typename T, typename Tag, typename Base> +struct Get_param< Named_params_impl, Tag, Base>, Tag > +{ + typedef std::reference_wrapper type; + typedef T& reference; +}; + +template< typename T, typename Tag> +struct Get_param< Named_params_impl, Tag, No_property>, Tag > +{ + typedef std::reference_wrapper type; + typedef T& reference; }; @@ -82,6 +106,7 @@ template< typename T, typename Tag, typename Base, typename Query_tag> struct Get_param< Named_params_impl, Query_tag> { typedef typename Get_param::type type; + typedef typename Get_param::reference reference; }; // helper to choose the default @@ -89,16 +114,24 @@ template struct Lookup_named_param_def { typedef typename internal_np::Get_param::type NP_type; + typedef typename internal_np::Get_param::reference NP_reference; typedef typename boost::mpl::if_< boost::is_same, D, NP_type>::type type; + + typedef typename boost::mpl::if_< + boost::is_same, + D&, NP_reference>::type + reference; }; // helper function to extract the value from a named parameter pack given a query tag template -T get_parameter_impl(const Named_params_impl& np, Tag) +typename std::conditional::value, + T, std::reference_wrapper >::type +get_parameter_impl(const Named_params_impl& np, Tag) { return np.v; } @@ -110,7 +143,9 @@ Param_not_found get_parameter_impl(const Named_params_impl& } template< typename T, typename Tag> -T get_parameter_impl(const Named_params_impl& np, Tag) +typename std::conditional::value, + T, std::reference_wrapper >::type +get_parameter_impl(const Named_params_impl& np, Tag) { return np.v; }; @@ -123,6 +158,67 @@ get_parameter_impl(const Named_params_impl& np, Query_tag tag) return get_parameter_impl(static_cast(np), tag); } + +// helper for getting references +template +const T& get_reference(const T& t) +{ + return t; +} + +template +T& get_reference(const std::reference_wrapper& r) +{ + return r.get(); +} + +// helper function to extract the reference from a named parameter pack given a query tag +template +typename std::conditional::value, + T, const T& >::type +get_parameter_reference_impl(const Named_params_impl& np, Tag) +{ + return get_reference(np.v); +} + +template< typename T, typename Tag, typename Query_tag> +Param_not_found +get_parameter_reference_impl(const Named_params_impl&, Query_tag) +{ + return Param_not_found(); +} + +template< typename T, typename Tag> +typename std::conditional::value, + T, const T& >::type +get_parameter_reference_impl(const Named_params_impl& np, Tag) +{ + return get_reference(np.v); +}; + +template +T& +get_parameter_reference_impl(const Named_params_impl, Tag, Base>& np, Tag) +{ + return np.v.get(); +} + +template< typename T, typename Tag> +T& +get_parameter_reference_impl(const Named_params_impl, Tag, No_property>& np, Tag) +{ + return np.v.get(); +}; + +template +typename Get_param, Query_tag>::reference +get_parameter_reference_impl(const Named_params_impl& np, Query_tag tag) +{ + CGAL_static_assertion( (!boost::is_same::value) ); + return get_parameter_reference_impl(static_cast(np), tag); +} + + } // end of internal_np namespace @@ -133,8 +229,9 @@ struct Named_function_parameters typedef internal_np::Named_params_impl base; typedef Named_function_parameters self; - Named_function_parameters(T v = T()) : base(v) {} - Named_function_parameters(T v, const Base& b) : base(v, b) {} + Named_function_parameters() : base(T()) {} + Named_function_parameters(const T& v) : base(v) {} + Named_function_parameters(const T& v, const Base& b) : base(v, b) {} Named_function_parameters all_default() const @@ -178,7 +275,7 @@ inline no_parameters(Named_function_parameters) #define CGAL_add_named_parameter(X, Y, Z) \ template \ Named_function_parameters \ - Z(K const& p) \ + Z(const K& p) \ { \ typedef Named_function_parameters Params;\ return Params(p); \ @@ -194,13 +291,40 @@ get_parameter(const Named_function_parameters& np, Query_tag tag) return internal_np::get_parameter_impl(static_cast&>(np), tag); } +template +typename internal_np::Get_param, Query_tag>::reference +get_parameter_reference(const Named_function_parameters& np, Query_tag tag) +{ + return internal_np::get_parameter_reference_impl( + static_cast&>(np), + tag); +} + // Two parameters, non-trivial default value template -D choose_parameter(const internal_np::Param_not_found&, const D& d) +D& choose_parameter(const internal_np::Param_not_found&, D& d) { return d; } +template +const D& choose_parameter(const internal_np::Param_not_found&, const D& d) +{ + return d; +} + +template +D choose_parameter(const internal_np::Param_not_found&, D&& d) +{ + return std::forward(d); +} + +template +T& choose_parameter(T& t, D&) +{ + return t; +} + template const T& choose_parameter(const T& t, const D&) { diff --git a/BGL/include/CGAL/boost/graph/iterator.h b/BGL/include/CGAL/boost/graph/iterator.h index c5df2626252..c8af78eaf8b 100644 --- a/BGL/include/CGAL/boost/graph/iterator.h +++ b/BGL/include/CGAL/boost/graph/iterator.h @@ -205,7 +205,7 @@ private: public: Halfedge_around_source_iterator() - : anchor(), pos(), g(0) + : anchor(), pos(), g(nullptr), winding(0) {} Halfedge_around_source_iterator(halfedge_descriptor hd, const Graph& g, int n=0) @@ -305,7 +305,7 @@ private: public: Halfedge_around_target_iterator() - : anchor(), pos(), g(0) + : anchor(), pos(), g(nullptr), winding(0) {} Halfedge_around_target_iterator(halfedge_descriptor hd, const Graph& g, int n=0) 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 581cf898979..679d48896f1 100644 --- a/BGL/include/CGAL/boost/graph/split_graph_into_polylines.h +++ b/BGL/include/CGAL/boost/graph/split_graph_into_polylines.h @@ -153,7 +153,7 @@ void duplicate_terminal_vertices(Graph& graph, { typename boost::graph_traits::vertex_descriptor orig_v = graph[v]; typename boost::graph_traits::degree_size_type deg = degree(v, graph); - if ((deg != 0 && is_terminal(orig_v, orig)) || deg > 2) + if (deg != 2 || is_terminal(orig_v, orig)) { out_edge_iterator b, e; boost::tie(b, e) = out_edges(v, graph); @@ -170,7 +170,6 @@ void duplicate_terminal_vertices(Graph& graph, const std::pair pair = add_edge(vc, w, graph); graph[pair.first] = orig_e; } - CGAL_assertion(degree(v, graph) == 1); } } diff --git a/BGL/test/BGL/test_cgal_bgl_named_params.cpp b/BGL/test/BGL/test_cgal_bgl_named_params.cpp index 18cb646ff35..b7322b049f2 100644 --- a/BGL/test/BGL/test_cgal_bgl_named_params.cpp +++ b/BGL/test/BGL/test_cgal_bgl_named_params.cpp @@ -4,6 +4,9 @@ #include +namespace inp = CGAL::internal_np; +namespace params = CGAL::parameters; + template struct A { @@ -11,6 +14,12 @@ struct A int v; }; +struct B +{ + B(){} + B(const B&) = delete; +}; + template void check_same_type(T) { @@ -20,416 +29,78 @@ void check_same_type(T) } template -void test(const NamedParameters& np) +void test_values_and_types(const NamedParameters& np) { - using CGAL::parameters::get_parameter; + using params::get_parameter; - // Test values + // test values + assert(get_parameter(np, inp::vertex_index).v == 0); + assert(get_parameter(np, inp::visitor).v == 1); - // Named parameters that we use in CGAL - assert(get_parameter(np, CGAL::internal_np::vertex_index).v == 0); - assert(get_parameter(np, CGAL::internal_np::visitor).v == 1); - assert(get_parameter(np, CGAL::internal_np::vertex_point).v == 2); - assert(get_parameter(np, CGAL::internal_np::halfedge_index).v == 3); - assert(get_parameter(np, CGAL::internal_np::edge_index).v == 4); - assert(get_parameter(np, CGAL::internal_np::face_index).v == 5); + // test types + check_same_type<0>(get_parameter(np, inp::vertex_index)); + check_same_type<1>(get_parameter(np, inp::visitor)); +} - assert(get_parameter(np, CGAL::internal_np::edge_is_constrained).v == 6); - assert(get_parameter(np, CGAL::internal_np::first_index).v == 7); - assert(get_parameter(np, CGAL::internal_np::number_of_iterations).v == 8); +template +void test_no_copyable(const NamedParameters& np) +{ + typedef typename inp::Get_param::type NP_type; + CGAL_static_assertion( (boost::is_same >::value) ); - assert(get_parameter(np, CGAL::internal_np::METIS_options).v == 800000001); - assert(get_parameter(np, CGAL::internal_np::vertex_partition_id).v == 800000002); - assert(get_parameter(np, CGAL::internal_np::face_partition_id).v == 800000003); + const A<4>& a = params::choose_parameter(params::get_parameter_reference(np, inp::edge_index), A<4>(4)); + assert(a.v==4); +} - assert(get_parameter(np, CGAL::internal_np::vertex_to_vertex_output_iterator).v == 800000004); - assert(get_parameter(np, CGAL::internal_np::halfedge_to_halfedge_output_iterator).v == 800000005); - assert(get_parameter(np, CGAL::internal_np::face_to_face_output_iterator).v == 800000006); +template +void test_references(const NamedParameters& np) +{ + typedef A<2> Default_type; + Default_type default_value(2); - assert(get_parameter(np, CGAL::internal_np::vertex_to_vertex_map).v == 800000007); - assert(get_parameter(np, CGAL::internal_np::halfedge_to_halfedge_map).v == 800000008); - assert(get_parameter(np, CGAL::internal_np::face_to_face_map).v == 800000009); + // std::reference_wrapper + typedef typename inp::Lookup_named_param_def::reference Visitor_reference_type; + CGAL_static_assertion( (std::is_same::value) ); + Visitor_reference_type vis_ref = params::choose_parameter(params::get_parameter_reference(np, inp::visitor), default_value); + CGAL_USE(vis_ref); - assert(get_parameter(np, CGAL::internal_np::implementation_tag).v == 800000010); - assert(get_parameter(np, CGAL::internal_np::prevent_unselection).v == 800000011); + // std::reference_wrapper of const + typedef typename inp::Lookup_named_param_def::reference FIM_reference_type; + CGAL_static_assertion( (std::is_same::value) ); + FIM_reference_type fim_ref = params::choose_parameter(params::get_parameter_reference(np, inp::face_index), default_value); + CGAL_USE(fim_ref); - assert(get_parameter(np, CGAL::internal_np::stream_precision).v == 800000012); + // non-copyable + typedef typename inp::Lookup_named_param_def::reference VPM_reference_type; + CGAL_static_assertion( (std::is_same::value) ); + VPM_reference_type vpm_ref = params::choose_parameter(params::get_parameter_reference(np, inp::vertex_point), default_value); + CGAL_USE(vpm_ref); - // Named parameters that we use in the package 'Mesh_3' - assert(get_parameter(np, CGAL::internal_np::vertex_feature_degree).v == 9); + // passed by copy + typedef typename inp::Lookup_named_param_def::reference VIM_reference_type; + CGAL_static_assertion( (std::is_same, VIM_reference_type>::value) ); + VIM_reference_type vim_ref = params::choose_parameter(params::get_parameter_reference(np, inp::vertex_index), default_value); + CGAL_USE(vim_ref); - // Named parameters used in the package 'Polygon Mesh Processing' - assert(get_parameter(np, CGAL::internal_np::geom_traits).v == 10); - assert(get_parameter(np, CGAL::internal_np::vertex_incident_patches).v == 11); - assert(get_parameter(np, CGAL::internal_np::density_control_factor).v == 12); - assert(get_parameter(np, CGAL::internal_np::use_delaunay_triangulation).v == 13); - assert(get_parameter(np, CGAL::internal_np::use_2d_constrained_delaunay_triangulation).v == 4573); - assert(get_parameter(np, CGAL::internal_np::fairing_continuity).v == 14); - assert(get_parameter(np, CGAL::internal_np::sparse_linear_solver).v == 15); - assert(get_parameter(np, CGAL::internal_np::number_of_relaxation_steps).v == 16); - assert(get_parameter(np, CGAL::internal_np::protect_constraints).v == 17); - assert(get_parameter(np, CGAL::internal_np::relax_constraints).v == 18); - assert(get_parameter(np, CGAL::internal_np::collapse_constraints).v == 43); - assert(get_parameter(np, CGAL::internal_np::vertex_is_constrained).v == 19); - assert(get_parameter(np, CGAL::internal_np::face_patch).v == 20); - assert(get_parameter(np, CGAL::internal_np::random_uniform_sampling).v == 21); - assert(get_parameter(np, CGAL::internal_np::grid_sampling).v == 22); - assert(get_parameter(np, CGAL::internal_np::monte_carlo_sampling).v == 23); - assert(get_parameter(np, CGAL::internal_np::do_sample_edges).v == 24); - assert(get_parameter(np, CGAL::internal_np::do_sample_vertices).v == 25); - assert(get_parameter(np, CGAL::internal_np::do_sample_faces).v == 26); - assert(get_parameter(np, CGAL::internal_np::number_of_points_on_faces).v == 27); - assert(get_parameter(np, CGAL::internal_np::number_of_points_per_face).v == 28); - assert(get_parameter(np, CGAL::internal_np::grid_spacing).v == 29); - assert(get_parameter(np, CGAL::internal_np::number_of_points_per_edge).v == 30); - assert(get_parameter(np, CGAL::internal_np::number_of_points_on_edges).v == 31); - assert(get_parameter(np, CGAL::internal_np::nb_points_per_area_unit).v == 32); - assert(get_parameter(np, CGAL::internal_np::nb_points_per_distance_unit).v == 33); - assert(get_parameter(np, CGAL::internal_np::throw_on_self_intersection).v == 43); - assert(get_parameter(np, CGAL::internal_np::clip_volume).v == 44); - assert(get_parameter(np, CGAL::internal_np::use_compact_clipper).v == 45); - assert(get_parameter(np, CGAL::internal_np::erase_all_duplicates).v == 48); - assert(get_parameter(np, CGAL::internal_np::require_same_orientation).v == 49); - assert(get_parameter(np, CGAL::internal_np::use_bool_op_to_clip_surface).v == 50); - assert(get_parameter(np, CGAL::internal_np::face_size_map).v == 52); - assert(get_parameter(np, CGAL::internal_np::use_angle_smoothing).v == 53); - assert(get_parameter(np, CGAL::internal_np::use_area_smoothing).v == 54); - assert(get_parameter(np, CGAL::internal_np::use_Delaunay_flips).v == 55); - assert(get_parameter(np, CGAL::internal_np::use_safety_constraints).v == 56); - assert(get_parameter(np, CGAL::internal_np::area_threshold).v == 57); - assert(get_parameter(np, CGAL::internal_np::volume_threshold).v == 58); - assert(get_parameter(np, CGAL::internal_np::snapping_tolerance).v == 59); - assert(get_parameter(np, CGAL::internal_np::dry_run).v == 60); - assert(get_parameter(np, CGAL::internal_np::do_lock_mesh).v == 61); - assert(get_parameter(np, CGAL::internal_np::halfedges_keeper).v == 62); - assert(get_parameter(np, CGAL::internal_np::do_simplify_border).v == 64); - assert(get_parameter(np, CGAL::internal_np::do_not_modify).v == 65); - assert(get_parameter(np, CGAL::internal_np::allow_self_intersections).v == 66); - assert(get_parameter(np, CGAL::internal_np::polyhedral_envelope_epsilon).v == 67); - assert(get_parameter(np, CGAL::internal_np::maximum_number_of_faces).v == 78910); - assert(get_parameter(np, CGAL::internal_np::non_manifold_feature_map).v == 60); - assert(get_parameter(np, CGAL::internal_np::filter).v == 61); - assert(get_parameter(np, CGAL::internal_np::face_epsilon_map).v == 62); - assert(get_parameter(np, CGAL::internal_np::maximum_number).v == 68); - - // Named parameters that we use in the package 'Surface Mesh Simplification' - assert(get_parameter(np, CGAL::internal_np::get_cost_policy).v == 34); - assert(get_parameter(np, CGAL::internal_np::get_placement_policy).v == 35); - - // Named parameters that we use in the package 'Optimal_bounding_box' - assert(get_parameter(np, CGAL::internal_np::use_convex_hull).v == 63); - - // To-be-documented named parameters - assert(get_parameter(np, CGAL::internal_np::face_normal).v == 36); - assert(get_parameter(np, CGAL::internal_np::random_seed).v == 37); - assert(get_parameter(np, CGAL::internal_np::do_project).v == 38); - - // Internal named parameters - assert(get_parameter(np, CGAL::internal_np::weight_calculator).v == 39); - assert(get_parameter(np, CGAL::internal_np::preserve_genus).v == 40); - assert(get_parameter(np, CGAL::internal_np::verbosity_level).v == 41); - assert(get_parameter(np, CGAL::internal_np::use_binary_mode).v == 51); - assert(get_parameter(np, CGAL::internal_np::projection_functor).v == 42); - assert(get_parameter(np, CGAL::internal_np::apply_per_connected_component).v == 46); - assert(get_parameter(np, CGAL::internal_np::output_iterator).v == 47); - - // Test types - - // Named parameters that we use in CGAL - check_same_type<0>(get_parameter(np, CGAL::internal_np::vertex_index)); - check_same_type<1>(get_parameter(np, CGAL::internal_np::visitor)); - check_same_type<2>(get_parameter(np, CGAL::internal_np::vertex_point)); - check_same_type<3>(get_parameter(np, CGAL::internal_np::halfedge_index)); - check_same_type<4>(get_parameter(np, CGAL::internal_np::edge_index)); - check_same_type<5>(get_parameter(np, CGAL::internal_np::face_index)); - - check_same_type<6>(get_parameter(np, CGAL::internal_np::edge_is_constrained)); - check_same_type<7>(get_parameter(np, CGAL::internal_np::first_index)); - check_same_type<8>(get_parameter(np, CGAL::internal_np::number_of_iterations)); - - check_same_type<800000001>(get_parameter(np, CGAL::internal_np::METIS_options)); - check_same_type<800000002>(get_parameter(np, CGAL::internal_np::vertex_partition_id)); - check_same_type<800000003>(get_parameter(np, CGAL::internal_np::face_partition_id)); - check_same_type<800000004>(get_parameter(np, CGAL::internal_np::vertex_to_vertex_output_iterator)); - check_same_type<800000005>(get_parameter(np, CGAL::internal_np::halfedge_to_halfedge_output_iterator)); - check_same_type<800000006>(get_parameter(np, CGAL::internal_np::face_to_face_output_iterator)); - check_same_type<800000007>(get_parameter(np, CGAL::internal_np::vertex_to_vertex_map)); - check_same_type<800000008>(get_parameter(np, CGAL::internal_np::halfedge_to_halfedge_map)); - check_same_type<800000009>(get_parameter(np, CGAL::internal_np::face_to_face_map)); - check_same_type<800000010>(get_parameter(np, CGAL::internal_np::implementation_tag)); - check_same_type<800000011>(get_parameter(np, CGAL::internal_np::prevent_unselection)); - check_same_type<800000012>(get_parameter(np, CGAL::internal_np::stream_precision)); - - // Named parameters that we use in the package 'Mesh_3' - check_same_type<9>(get_parameter(np, CGAL::internal_np::vertex_feature_degree)); - - // Named parameters used in the package 'Polygon Mesh Processing' - check_same_type<10>(get_parameter(np, CGAL::internal_np::geom_traits)); - check_same_type<11>(get_parameter(np, CGAL::internal_np::vertex_incident_patches)); - check_same_type<12>(get_parameter(np, CGAL::internal_np::density_control_factor)); - check_same_type<13>(get_parameter(np, CGAL::internal_np::use_delaunay_triangulation)); - check_same_type<4573>(get_parameter(np, CGAL::internal_np::use_2d_constrained_delaunay_triangulation)); - check_same_type<14>(get_parameter(np, CGAL::internal_np::fairing_continuity)); - check_same_type<15>(get_parameter(np, CGAL::internal_np::sparse_linear_solver)); - check_same_type<16>(get_parameter(np, CGAL::internal_np::number_of_relaxation_steps)); - check_same_type<17>(get_parameter(np, CGAL::internal_np::protect_constraints)); - check_same_type<18>(get_parameter(np, CGAL::internal_np::relax_constraints)); - check_same_type<43>(get_parameter(np, CGAL::internal_np::collapse_constraints)); - check_same_type<19>(get_parameter(np, CGAL::internal_np::vertex_is_constrained)); - check_same_type<20>(get_parameter(np, CGAL::internal_np::face_patch)); - check_same_type<21>(get_parameter(np, CGAL::internal_np::random_uniform_sampling)); - check_same_type<22>(get_parameter(np, CGAL::internal_np::grid_sampling)); - check_same_type<23>(get_parameter(np, CGAL::internal_np::monte_carlo_sampling)); - check_same_type<24>(get_parameter(np, CGAL::internal_np::do_sample_edges)); - check_same_type<25>(get_parameter(np, CGAL::internal_np::do_sample_vertices)); - check_same_type<26>(get_parameter(np, CGAL::internal_np::do_sample_faces)); - check_same_type<27>(get_parameter(np, CGAL::internal_np::number_of_points_on_faces)); - check_same_type<28>(get_parameter(np, CGAL::internal_np::number_of_points_per_face)); - check_same_type<29>(get_parameter(np, CGAL::internal_np::grid_spacing)); - check_same_type<30>(get_parameter(np, CGAL::internal_np::number_of_points_per_edge)); - check_same_type<31>(get_parameter(np, CGAL::internal_np::number_of_points_on_edges)); - check_same_type<32>(get_parameter(np, CGAL::internal_np::nb_points_per_area_unit)); - check_same_type<33>(get_parameter(np, CGAL::internal_np::nb_points_per_distance_unit)); - check_same_type<43>(get_parameter(np, CGAL::internal_np::throw_on_self_intersection)); - check_same_type<44>(get_parameter(np, CGAL::internal_np::clip_volume)); - check_same_type<45>(get_parameter(np, CGAL::internal_np::use_compact_clipper)); - check_same_type<48>(get_parameter(np, CGAL::internal_np::erase_all_duplicates)); - check_same_type<49>(get_parameter(np, CGAL::internal_np::require_same_orientation)); - check_same_type<50>(get_parameter(np, CGAL::internal_np::use_bool_op_to_clip_surface)); - check_same_type<52>(get_parameter(np, CGAL::internal_np::face_size_map)); - check_same_type<53>(get_parameter(np, CGAL::internal_np::use_angle_smoothing)); - check_same_type<54>(get_parameter(np, CGAL::internal_np::use_area_smoothing)); - check_same_type<55>(get_parameter(np, CGAL::internal_np::use_Delaunay_flips)); - check_same_type<56>(get_parameter(np, CGAL::internal_np::use_safety_constraints)); - check_same_type<65>(get_parameter(np, CGAL::internal_np::do_not_modify)); - check_same_type<66>(get_parameter(np, CGAL::internal_np::allow_self_intersections)); - check_same_type<67>(get_parameter(np, CGAL::internal_np::polyhedral_envelope_epsilon)); - - check_same_type<12340>(get_parameter(np, CGAL::internal_np::do_self_intersection_tests)); - check_same_type<12341>(get_parameter(np, CGAL::internal_np::do_orientation_tests)); - check_same_type<12342>(get_parameter(np, CGAL::internal_np::error_codes)); - check_same_type<12343>(get_parameter(np, CGAL::internal_np::volume_inclusions)); - check_same_type<12344>(get_parameter(np, CGAL::internal_np::face_connected_component_map)); - check_same_type<12345>(get_parameter(np, CGAL::internal_np::connected_component_id_to_volume_id)); - check_same_type<12346>(get_parameter(np, CGAL::internal_np::is_cc_outward_oriented)); - check_same_type<12347>(get_parameter(np, CGAL::internal_np::intersecting_volume_pairs_output_iterator)); - check_same_type<12348>(get_parameter(np, CGAL::internal_np::i_used_as_a_predicate)); - check_same_type<12349>(get_parameter(np, CGAL::internal_np::nesting_levels)); - check_same_type<12350>(get_parameter(np, CGAL::internal_np::i_used_for_volume_orientation)); - - check_same_type<57>(get_parameter(np, CGAL::internal_np::area_threshold)); - check_same_type<58>(get_parameter(np, CGAL::internal_np::volume_threshold)); - check_same_type<59>(get_parameter(np, CGAL::internal_np::snapping_tolerance)); - check_same_type<60>(get_parameter(np, CGAL::internal_np::dry_run)); - check_same_type<61>(get_parameter(np, CGAL::internal_np::do_lock_mesh)); - check_same_type<62>(get_parameter(np, CGAL::internal_np::halfedges_keeper)); - check_same_type<64>(get_parameter(np, CGAL::internal_np::do_simplify_border)); - check_same_type<78910>(get_parameter(np, CGAL::internal_np::maximum_number_of_faces)); - check_same_type<60>(get_parameter(np, CGAL::internal_np::non_manifold_feature_map)); - check_same_type<61>(get_parameter(np, CGAL::internal_np::filter)); - check_same_type<62>(get_parameter(np, CGAL::internal_np::face_epsilon_map)); - check_same_type<68>(get_parameter(np, CGAL::internal_np::maximum_number)); - - // Named parameters that we use in the package 'Surface Mesh Simplification' - check_same_type<34>(get_parameter(np, CGAL::internal_np::get_cost_policy)); - check_same_type<35>(get_parameter(np, CGAL::internal_np::get_placement_policy)); - - // Named parameters that we use in the package 'Optimal_bounding_box' - check_same_type<63>(get_parameter(np, CGAL::internal_np::use_convex_hull)); - - // To-be-documented named parameters - check_same_type<36>(get_parameter(np, CGAL::internal_np::face_normal)); - check_same_type<37>(get_parameter(np, CGAL::internal_np::random_seed)); - check_same_type<38>(get_parameter(np, CGAL::internal_np::do_project)); - check_same_type<456>(get_parameter(np, CGAL::internal_np::algorithm)); - - // Internal named parameters - check_same_type<39>(get_parameter(np, CGAL::internal_np::weight_calculator)); - check_same_type<40>(get_parameter(np, CGAL::internal_np::preserve_genus)); - check_same_type<41>(get_parameter(np, CGAL::internal_np::verbosity_level)); - check_same_type<51>(get_parameter(np, CGAL::internal_np::use_binary_mode)); - check_same_type<42>(get_parameter(np, CGAL::internal_np::projection_functor)); - check_same_type<46>(get_parameter(np, CGAL::internal_np::apply_per_connected_component)); - check_same_type<47>(get_parameter(np, CGAL::internal_np::output_iterator)); - - // Named parameters used in the package 'Point Set Processing' - check_same_type<9000>(get_parameter(np, CGAL::internal_np::point_map)); - check_same_type<9001>(get_parameter(np, CGAL::internal_np::query_point_map)); - check_same_type<9002>(get_parameter(np, CGAL::internal_np::normal_map)); - check_same_type<9003>(get_parameter(np, CGAL::internal_np::diagonalize_traits)); - check_same_type<9004>(get_parameter(np, CGAL::internal_np::svd_traits)); - check_same_type<9005>(get_parameter(np, CGAL::internal_np::callback)); - check_same_type<9006>(get_parameter(np, CGAL::internal_np::sharpness_angle)); - check_same_type<9007>(get_parameter(np, CGAL::internal_np::edge_sensitivity)); - check_same_type<9008>(get_parameter(np, CGAL::internal_np::neighbor_radius)); - check_same_type<9009>(get_parameter(np, CGAL::internal_np::number_of_output_points)); - check_same_type<9010>(get_parameter(np, CGAL::internal_np::size)); - check_same_type<9011>(get_parameter(np, CGAL::internal_np::maximum_variation)); - check_same_type<9012>(get_parameter(np, CGAL::internal_np::degree_fitting)); - check_same_type<9013>(get_parameter(np, CGAL::internal_np::degree_monge)); - check_same_type<9014>(get_parameter(np, CGAL::internal_np::threshold_percent)); - check_same_type<9015>(get_parameter(np, CGAL::internal_np::threshold_distance)); - check_same_type<9016>(get_parameter(np, CGAL::internal_np::attraction_factor)); - check_same_type<9017>(get_parameter(np, CGAL::internal_np::plane_map)); - check_same_type<9018>(get_parameter(np, CGAL::internal_np::plane_index_map)); - check_same_type<9019>(get_parameter(np, CGAL::internal_np::select_percentage)); - check_same_type<9020>(get_parameter(np, CGAL::internal_np::require_uniform_sampling)); - check_same_type<9021>(get_parameter(np, CGAL::internal_np::point_is_constrained)); - check_same_type<9022>(get_parameter(np, CGAL::internal_np::number_of_samples)); - check_same_type<9023>(get_parameter(np, CGAL::internal_np::accuracy)); - check_same_type<9024>(get_parameter(np, CGAL::internal_np::maximum_running_time)); - check_same_type<9025>(get_parameter(np, CGAL::internal_np::overlap)); - check_same_type<9026>(get_parameter(np, CGAL::internal_np::transformation)); - check_same_type<9027>(get_parameter(np, CGAL::internal_np::point_set_filters)); - check_same_type<9028>(get_parameter(np, CGAL::internal_np::matcher)); - check_same_type<9029>(get_parameter(np, CGAL::internal_np::outlier_filters)); - check_same_type<9030>(get_parameter(np, CGAL::internal_np::error_minimizer)); - check_same_type<9031>(get_parameter(np, CGAL::internal_np::transformation_checkers)); - check_same_type<9032>(get_parameter(np, CGAL::internal_np::inspector)); - check_same_type<9033>(get_parameter(np, CGAL::internal_np::logger)); - check_same_type<9034>(get_parameter(np, CGAL::internal_np::maximum_normal_deviation)); - check_same_type<9035>(get_parameter(np, CGAL::internal_np::scan_angle_map)); - check_same_type<9036>(get_parameter(np, CGAL::internal_np::scanline_id_map)); + // default + typedef typename inp::Lookup_named_param_def::reference EIM_reference_type; + CGAL_static_assertion(( std::is_same::value) ); + EIM_reference_type eim_ref = params::choose_parameter(params::get_parameter_reference(np, inp::edge_index), default_value); + assert(&eim_ref==&default_value); } int main() { - test(CGAL::parameters::vertex_index_map(A<0>(0)) - .visitor(A<1>(1)) - .vertex_point_map(A<2>(2)) - .halfedge_index_map(A<3>(3)) - .edge_index_map(A<4>(4)) - .face_index_map(A<5>(5)) - .edge_is_constrained_map(A<6>(6)) - .first_index(A<7>(7)) - .number_of_iterations(A<8>(8)) - .METIS_options(A<800000001>(800000001)) - .vertex_partition_id_map(A<800000002>(800000002)) - .face_partition_id_map(A<800000003>(800000003)) - .vertex_to_vertex_output_iterator(A<800000004>(800000004)) - .halfedge_to_halfedge_output_iterator(A<800000005>(800000005)) - .face_to_face_output_iterator(A<800000006>(800000006)) - .vertex_to_vertex_map(A<800000007>(800000007)) - .halfedge_to_halfedge_map(A<800000008>(800000008)) - .face_to_face_map(A<800000009>(800000009)) - .implementation_tag(A<800000010>(800000010)) - .prevent_unselection(A<800000011>(800000011)) - .stream_precision(A<800000012>(800000012)) - .vertex_feature_degree_map(A<9>(9)) - .geom_traits(A<10>(10)) - .vertex_incident_patches_map(A<11>(11)) - .density_control_factor(A<12>(12)) - .use_delaunay_triangulation(A<13>(13)) - .use_2d_constrained_delaunay_triangulation(A<4573>(4573)) - .fairing_continuity(A<14>(14)) - .sparse_linear_solver(A<15>(15)) - .number_of_relaxation_steps(A<16>(16)) - .protect_constraints(A<17>(17)) - .relax_constraints(A<18>(18)) - .collapse_constraints(A<43>(43)) - .vertex_is_constrained_map(A<19>(19)) - .face_patch_map(A<20>(20)) - .use_random_uniform_sampling(A<21>(21)) - .use_grid_sampling(A<22>(22)) - .use_monte_carlo_sampling(A<23>(23)) - .do_sample_edges(A<24>(24)) - .do_sample_vertices(A<25>(25)) - .do_sample_faces(A<26>(26)) - .number_of_points_on_faces(A<27>(27)) - .number_of_points_per_face(A<28>(28)) - .grid_spacing(A<29>(29)) - .number_of_points_per_edge(A<30>(30)) - .number_of_points_on_edges(A<31>(31)) - .number_of_points_per_area_unit(A<32>(32)) - .number_of_points_per_distance_unit(A<33>(33)) - .get_cost(A<34>(34)) - .get_placement(A<35>(35)) - .face_normal_map(A<36>(36)) - .random_seed(A<37>(37)) - .do_project(A<38>(38)) - .algorithm(A<456>(456)) - .weight_calculator(A<39>(39)) - .preserve_genus(A<40>(40)) - .verbosity_level(A<41>(41)) - .projection_functor(A<42>(42)) - .throw_on_self_intersection(A<43>(43)) - .clip_volume(A<44>(44)) - .use_compact_clipper(A<45>(45)) - .non_manifold_feature_map(A<60>(60)) - .filter(A<61>(61)) - .face_epsilon_map(A<62>(62)) - .maximum_number(A<68>(68)) - .apply_per_connected_component(A<46>(46)) - .output_iterator(A<47>(47)) - .erase_all_duplicates(A<48>(48)) - .require_same_orientation(A<49>(49)) - .use_bool_op_to_clip_surface(A<50>(50)) - .use_binary_mode(A<51>(51)) - .face_size_map(A<52>(52)) - .use_angle_smoothing(A<53>(53)) - .use_area_smoothing(A<54>(54)) - .use_Delaunay_flips(A<55>(55)) - .use_safety_constraints(A<56>(56)) - .do_self_intersection_tests(A<12340>(12340)) - .do_orientation_tests(A<12341>(12341)) - .error_codes(A<12342>(12342)) - .volume_inclusions(A<12343>(12343)) - .face_connected_component_map(A<12344>(12344)) - .connected_component_id_to_volume_id(A<12345>(12345)) - .is_cc_outward_oriented(A<12346>(12346)) - .intersecting_volume_pairs_output_iterator(A<12347>(12347)) - .i_used_as_a_predicate(A<12348>(12348)) - .nesting_levels(A<12349>(12349)) - .i_used_for_volume_orientation(A<12350>(12350)) - .area_threshold(A<57>(57)) - .volume_threshold(A<58>(58)) - .snapping_tolerance(A<59>(59)) - .dry_run(A<60>(60)) - .do_lock_mesh(A<61>(61)) - .halfedges_keeper(A<62>(62)) - .use_convex_hull(A<63>(63)) - .do_simplify_border(A<64>(64)) - .do_not_modify(A<65>(65)) - .allow_self_intersections(A<66>(66)) - .polyhedral_envelope_epsilon(A<67>(67)) - .point_map(A<9000>(9000)) - .query_point_map(A<9001>(9001)) - .normal_map(A<9002>(9002)) - .diagonalize_traits(A<9003>(9003)) - .svd_traits(A<9004>(9004)) - .callback(A<9005>(9005)) - .sharpness_angle(A<9006>(9006)) - .edge_sensitivity(A<9007>(9007)) - .neighbor_radius(A<9008>(9008)) - .number_of_output_points(A<9009>(9009)) - .size(A<9010>(9010)) - .maximum_variation(A<9011>(9011)) - .degree_fitting(A<9012>(9012)) - .degree_monge(A<9013>(9013)) - .threshold_percent(A<9014>(9014)) - .threshold_distance(A<9015>(9015)) - .attraction_factor(A<9016>(9016)) - .plane_map(A<9017>(9017)) - .plane_index_map(A<9018>(9018)) - .select_percentage(A<9019>(9019)) - .require_uniform_sampling(A<9020>(9020)) - .point_is_constrained_map(A<9021>(9021)) - .number_of_samples(A<9022>(9022)) - .accuracy(A<9023>(9023)) - .maximum_running_time(A<9024>(9024)) - .overlap(A<9025>(9025)) - .transformation(A<9026>(9026)) - .point_set_filters(A<9027>(9027)) - .matcher(A<9028>(9028)) - .outlier_filters(A<9029>(9029)) - .error_minimizer(A<9030>(9030)) - .transformation_checkers(A<9031>(9031)) - .inspector(A<9032>(9032)) - .logger(A<9033>(9033)) - .maximum_normal_deviation(A<9034>(9034)) - .scan_angle_map(A<9035>(9035)) - .scanline_id_map(A<9036>(9036)) - .maximum_number_of_faces(A<78910>(78910)) - ); + test_values_and_types(params::vertex_index_map(A<0>(0)).visitor(A<1>(1))); + + B b; + test_no_copyable(params::visitor(b)); + + test_references(params::visitor(std::ref(b)) + .vertex_point_map(b) + .vertex_index_map(A<0>(0)) + .face_index_map(std::reference_wrapper(b)) + ); + return EXIT_SUCCESS; } diff --git a/Barycentric_coordinates_2/include/CGAL/Barycentric_coordinates_2/Discrete_harmonic_2.h b/Barycentric_coordinates_2/include/CGAL/Barycentric_coordinates_2/Discrete_harmonic_2.h index b6c086dc9c8..c86dd852c03 100644 --- a/Barycentric_coordinates_2/include/CGAL/Barycentric_coordinates_2/Discrete_harmonic_2.h +++ b/Barycentric_coordinates_2/include/CGAL/Barycentric_coordinates_2/Discrete_harmonic_2.h @@ -32,6 +32,8 @@ namespace CGAL { // Barycentric coordinates namespace. namespace Barycentric_coordinates { +#if !defined(CGAL_NO_DEPRECATED_CODE) || defined(DOXYGEN_RUNNING) + // Examples: see the User Manual here - https://doc.cgal.org/latest/Manual/index.html. // [1] Reference: "M. S. Floater, K. Hormann, and G. Kos. A general construction of barycentric coordinates over convex polygons. Advances in Computational Mathematics, 24(1-4):311-331, 2006.". @@ -430,6 +432,8 @@ private: } }; +#endif // CGAL_NO_DEPRECATED_CODE + } // namespace Barycentric_coordinates } // namespace CGAL diff --git a/Barycentric_coordinates_2/include/CGAL/Barycentric_coordinates_2/Generalized_barycentric_coordinates_2.h b/Barycentric_coordinates_2/include/CGAL/Barycentric_coordinates_2/Generalized_barycentric_coordinates_2.h index 5faf72b6f98..ef4bfc7f365 100644 --- a/Barycentric_coordinates_2/include/CGAL/Barycentric_coordinates_2/Generalized_barycentric_coordinates_2.h +++ b/Barycentric_coordinates_2/include/CGAL/Barycentric_coordinates_2/Generalized_barycentric_coordinates_2.h @@ -32,6 +32,8 @@ namespace CGAL { // Barycentric coordinates namespace. namespace Barycentric_coordinates { +#if !defined(CGAL_NO_DEPRECATED_CODE) || defined(DOXYGEN_RUNNING) + // Examples: see the User Manual here - https://doc.cgal.org/latest/Manual/index.html. /*! @@ -585,6 +587,8 @@ private: } }; +#endif // CGAL_NO_DEPRECATED_CODE + } // namespace Barycentric_coordinates } // namespace CGAL diff --git a/Barycentric_coordinates_2/include/CGAL/Barycentric_coordinates_2/Mean_value_2.h b/Barycentric_coordinates_2/include/CGAL/Barycentric_coordinates_2/Mean_value_2.h index abc0a783139..406d1d6b0bf 100644 --- a/Barycentric_coordinates_2/include/CGAL/Barycentric_coordinates_2/Mean_value_2.h +++ b/Barycentric_coordinates_2/include/CGAL/Barycentric_coordinates_2/Mean_value_2.h @@ -37,6 +37,8 @@ namespace CGAL { // Barycentric coordinates namespace. namespace Barycentric_coordinates { +#if !defined(CGAL_NO_DEPRECATED_CODE) || defined(DOXYGEN_RUNNING) + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Try to find a square root object in the provided `Traits` class. If not, then use the default square root from CGAL. @@ -498,6 +500,8 @@ private: } }; +#endif // CGAL_NO_DEPRECATED_CODE + } // namespace Barycentric_coordinates } // namespace CGAL diff --git a/Barycentric_coordinates_2/include/CGAL/Barycentric_coordinates_2/Wachspress_2.h b/Barycentric_coordinates_2/include/CGAL/Barycentric_coordinates_2/Wachspress_2.h index 6fecef7ffe7..f4aaa32412c 100644 --- a/Barycentric_coordinates_2/include/CGAL/Barycentric_coordinates_2/Wachspress_2.h +++ b/Barycentric_coordinates_2/include/CGAL/Barycentric_coordinates_2/Wachspress_2.h @@ -32,6 +32,8 @@ namespace CGAL { // Barycentric coordinates namespace. namespace Barycentric_coordinates { +#if !defined(CGAL_NO_DEPRECATED_CODE) || defined(DOXYGEN_RUNNING) + // Examples: see the User Manual here - https://doc.cgal.org/latest/Manual/index.html. // [1] Reference: "M. S. Floater, K. Hormann, and G. Kos. A general construction of barycentric coordinates over convex polygons. Advances in Computational Mathematics, 24(1-4):311-331, 2006.". @@ -413,6 +415,8 @@ private: } }; +#endif // CGAL_NO_DEPRECATED_CODE + } // namespace Barycentric_coordinates } // namespace CGAL diff --git a/Barycentric_coordinates_2/include/CGAL/Barycentric_coordinates_2/barycentric_enum_2.h b/Barycentric_coordinates_2/include/CGAL/Barycentric_coordinates_2/barycentric_enum_2.h index 1a0e5480dd3..740d5716beb 100644 --- a/Barycentric_coordinates_2/include/CGAL/Barycentric_coordinates_2/barycentric_enum_2.h +++ b/Barycentric_coordinates_2/include/CGAL/Barycentric_coordinates_2/barycentric_enum_2.h @@ -73,6 +73,8 @@ enum class Computation_policy_2 { namespace CGAL { namespace Barycentric_coordinates { +#if !defined(CGAL_NO_DEPRECATED_CODE) || defined(DOXYGEN_RUNNING) + /// \name Locations of a Query Point /// @{ @@ -142,6 +144,8 @@ enum Type_of_polygon { /// \endcond +#endif // CGAL_NO_DEPRECATED_CODE + } // namespace Barycentric_coordinates } // namespace CGAL diff --git a/Barycentric_coordinates_2/include/CGAL/Barycentric_coordinates_2/segment_coordinates_2.h b/Barycentric_coordinates_2/include/CGAL/Barycentric_coordinates_2/segment_coordinates_2.h index 60514f58f51..8ef4719853c 100644 --- a/Barycentric_coordinates_2/include/CGAL/Barycentric_coordinates_2/segment_coordinates_2.h +++ b/Barycentric_coordinates_2/include/CGAL/Barycentric_coordinates_2/segment_coordinates_2.h @@ -172,6 +172,8 @@ namespace Barycentric_coordinates { namespace CGAL { namespace Barycentric_coordinates { +#if !defined(CGAL_NO_DEPRECATED_CODE) || defined(DOXYGEN_RUNNING) + /*! \ingroup PkgBarycentricCoordinates2RefDeprecated * The class `Segment_coordinates_2` implements barycentric coordinates with respect to an arbitrary non-degenerate segment along an arbitrary line in the plane. @@ -376,6 +378,8 @@ namespace Barycentric_coordinates { return CGAL::make_array(b_first, FT(1) - b_first); } +#endif // CGAL_NO_DEPRECATED_CODE + } // namespace Barycentric_coordinates } // namespace CGAL diff --git a/Barycentric_coordinates_2/include/CGAL/Barycentric_coordinates_2/triangle_coordinates_2.h b/Barycentric_coordinates_2/include/CGAL/Barycentric_coordinates_2/triangle_coordinates_2.h index ea16596a4ec..8fd076c12d7 100644 --- a/Barycentric_coordinates_2/include/CGAL/Barycentric_coordinates_2/triangle_coordinates_2.h +++ b/Barycentric_coordinates_2/include/CGAL/Barycentric_coordinates_2/triangle_coordinates_2.h @@ -182,6 +182,8 @@ namespace Barycentric_coordinates { namespace CGAL { namespace Barycentric_coordinates { +#if !defined(CGAL_NO_DEPRECATED_CODE) || defined(DOXYGEN_RUNNING) + /*! * \ingroup PkgBarycentricCoordinates2RefDeprecated * The class `Triangle_coordinates_2` implements barycentric coordinates ( [1], @@ -413,6 +415,8 @@ namespace Barycentric_coordinates { return CGAL::make_array(b_first, b_second, FT(1) - b_first - b_second); } +#endif // CGAL_NO_DEPRECATED_CODE + } // namespace Barycentric_coordinates } // namespace CGAL diff --git a/Barycentric_coordinates_2/test/Barycentric_coordinates_2/test_dh_deprecated_api.cpp b/Barycentric_coordinates_2/test/Barycentric_coordinates_2/test_dh_deprecated_api.cpp index 221f55a02b6..c19f597f43f 100644 --- a/Barycentric_coordinates_2/test/Barycentric_coordinates_2/test_dh_deprecated_api.cpp +++ b/Barycentric_coordinates_2/test/Barycentric_coordinates_2/test_dh_deprecated_api.cpp @@ -1,5 +1,3 @@ -#include -#include #include #include #include diff --git a/Barycentric_coordinates_2/test/Barycentric_coordinates_2/test_hm_const_linear_precision.cpp b/Barycentric_coordinates_2/test/Barycentric_coordinates_2/test_hm_const_linear_precision.cpp index ed349c1a5c4..e39d545d569 100644 --- a/Barycentric_coordinates_2/test/Barycentric_coordinates_2/test_hm_const_linear_precision.cpp +++ b/Barycentric_coordinates_2/test/Barycentric_coordinates_2/test_hm_const_linear_precision.cpp @@ -1,7 +1,3 @@ -// #define HMC_SparseLU -// #define HMC_SimplicialLLT -// #define HMC_SimplicialLDLT // default - #include #include #include diff --git a/Barycentric_coordinates_2/test/Barycentric_coordinates_2/test_hm_triangle.cpp b/Barycentric_coordinates_2/test/Barycentric_coordinates_2/test_hm_triangle.cpp index 5f2ff679f24..73e718ebc69 100644 --- a/Barycentric_coordinates_2/test/Barycentric_coordinates_2/test_hm_triangle.cpp +++ b/Barycentric_coordinates_2/test/Barycentric_coordinates_2/test_hm_triangle.cpp @@ -1,7 +1,3 @@ -// #define HMC_SparseLU -// #define HMC_SimplicialLLT -// #define HMC_SimplicialLDLT // default - #include #include #include diff --git a/Barycentric_coordinates_2/test/Barycentric_coordinates_2/test_hm_unit_square.cpp b/Barycentric_coordinates_2/test/Barycentric_coordinates_2/test_hm_unit_square.cpp index 8fa5a2a5e32..4dc8f6853ee 100644 --- a/Barycentric_coordinates_2/test/Barycentric_coordinates_2/test_hm_unit_square.cpp +++ b/Barycentric_coordinates_2/test/Barycentric_coordinates_2/test_hm_unit_square.cpp @@ -1,7 +1,3 @@ -// #define HMC_SparseLU -// #define HMC_SimplicialLLT -// #define HMC_SimplicialLDLT // default - #include #include #include diff --git a/Barycentric_coordinates_2/test/Barycentric_coordinates_2/test_mv_deprecated_api.cpp b/Barycentric_coordinates_2/test/Barycentric_coordinates_2/test_mv_deprecated_api.cpp index b41a9720a30..25436a0bd6e 100644 --- a/Barycentric_coordinates_2/test/Barycentric_coordinates_2/test_mv_deprecated_api.cpp +++ b/Barycentric_coordinates_2/test/Barycentric_coordinates_2/test_mv_deprecated_api.cpp @@ -1,5 +1,3 @@ -#include -#include #include #include #include diff --git a/Barycentric_coordinates_2/test/Barycentric_coordinates_2/test_sc_deprecated_api.cpp b/Barycentric_coordinates_2/test/Barycentric_coordinates_2/test_sc_deprecated_api.cpp index 152257cd72d..d0b363c7a7e 100644 --- a/Barycentric_coordinates_2/test/Barycentric_coordinates_2/test_sc_deprecated_api.cpp +++ b/Barycentric_coordinates_2/test/Barycentric_coordinates_2/test_sc_deprecated_api.cpp @@ -1,5 +1,3 @@ -#include -#include #include #include #include diff --git a/Barycentric_coordinates_2/test/Barycentric_coordinates_2/test_tc_deprecated_api.cpp b/Barycentric_coordinates_2/test/Barycentric_coordinates_2/test_tc_deprecated_api.cpp index 68db234168a..e37784a8adb 100644 --- a/Barycentric_coordinates_2/test/Barycentric_coordinates_2/test_tc_deprecated_api.cpp +++ b/Barycentric_coordinates_2/test/Barycentric_coordinates_2/test_tc_deprecated_api.cpp @@ -1,5 +1,3 @@ -#include -#include #include #include #include diff --git a/Barycentric_coordinates_2/test/Barycentric_coordinates_2/test_wp_deprecated_api.cpp b/Barycentric_coordinates_2/test/Barycentric_coordinates_2/test_wp_deprecated_api.cpp index 5dc2f114399..a44bdb5391d 100644 --- a/Barycentric_coordinates_2/test/Barycentric_coordinates_2/test_wp_deprecated_api.cpp +++ b/Barycentric_coordinates_2/test/Barycentric_coordinates_2/test_wp_deprecated_api.cpp @@ -1,5 +1,3 @@ -#include -#include #include #include #include diff --git a/CGAL_Core/include/CGAL/CORE/BigFloat_impl.h b/CGAL_Core/include/CGAL/CORE/BigFloat_impl.h index 8517011babf..3cbd077e487 100644 --- a/CGAL_Core/include/CGAL/CORE/BigFloat_impl.h +++ b/CGAL_Core/include/CGAL/CORE/BigFloat_impl.h @@ -39,6 +39,7 @@ #include +#include #include #include #include @@ -1057,8 +1058,8 @@ void BigFloatRep :: fromString(const char *str, extLong prec ) { CGAL_INLINE_FUNCTION std::istream& BigFloatRep :: operator >>(std::istream& i) { int size = 20; - char *str = new char[size]; - char *p = str; + std::string str; + str.reserve(size); char c; int d = 0, e = 0, s = 0; // d=1 means dot is found @@ -1084,7 +1085,7 @@ std::istream& BigFloatRep :: operator >>(std::istream& i) { // the current content in "c" should be the first non-whitespace char if (c == '-' || c == '+') { - *p++ = c; + str += c; i.get(c); } @@ -1096,19 +1097,8 @@ std::istream& BigFloatRep :: operator >>(std::istream& i) { // xxxx.xxxe+xxx.xxx: if (e && (c == '.')) break; - if (p - str == size) { - char *t = str; - str = new char[size*2]; - memcpy(str, t, size); - delete [] t; - p = str + size; - size *= 2; - } -#ifdef CGAL_CORE_DEBUG - CGAL_assertion((p-str) < size); -#endif - *p++ = c; + str += c; if (c == '.') d = 1; // Chen Li: fix a bug -- the sign of exponent can not happen before @@ -1120,24 +1110,8 @@ std::istream& BigFloatRep :: operator >>(std::istream& i) { e = 1; } - // chenli: make sure that the p is still in the range - if (p - str >= size) { - std::size_t len = p - str; - char *t = str; - str = new char[len + 1]; - memcpy(str, t, len); - delete [] t; - p = str + len; - } - -#ifdef CGAL_CORE_DEBUG - CGAL_assertion(p - str < size); -#endif - - *p = '\0'; i.putback(c); - fromString(str); - delete [] str; + fromString(str.c_str()); return i; }//operator >> diff --git a/CGAL_Core/include/CGAL/CORE/CoreAux_impl.h b/CGAL_Core/include/CGAL/CORE/CoreAux_impl.h index 341c83c5819..3a01758911f 100644 --- a/CGAL_Core/include/CGAL/CORE/CoreAux_impl.h +++ b/CGAL_Core/include/CGAL/CORE/CoreAux_impl.h @@ -139,27 +139,6 @@ long gcd(long m, long n) { return p; } -// char* core_itoa(int n, char* buffer, int buffer_size) -// returns a pointer to the null-terminated string in buffer -// NOTES: -// 0. Buffer size should be 17 bytes (resp., 33 bytes, 65 bytes) on 16-bit -// (resp., 32-bit, 64-bit) machines. Formula: 1+sizeof(int)*8 bytes. -// 1. itoa(...) is available on some stdlib.h, but it is -// not defined by ANSI-C and so not all compilers support it. -// 2. Our use of sprintf(...) to do the job is known to -// be inefficient, but this is hardly critical for our usage. -// 3. A more general program should take a 3rd argument (the radix of -// output number). We assume radix 10. -CGAL_INLINE_FUNCTION -char * core_itoa(int n, char* buffer, int buffer_size) { -#if defined(_MSC_VER) - sprintf_s(buffer, buffer_size, "%d", n); -#else - CGAL_USE(buffer_size); - std::sprintf(buffer, "%d", n); -#endif - return buffer; -} /// implements the "integer mantissa" function // (See CORE_PATH/progs/ieee/frexp.cpp for details) @@ -197,11 +176,8 @@ void core_error(std::string msg, std::string file, int lineno, bool err) { << msg << std::endl; outFile.close(); if (err) { - char buf[65]; - // perror((std::string("CORE ERROR") + " (file " + file + ", line " - // + core_itoa(lineno,buf, 65) +"):" + msg + "\n").c_str()); std::cerr << (std::string("CORE ERROR") + " (file " + file + ", line " - + core_itoa(lineno,buf, 65) +"):" + msg + "\n").c_str(); + + std::to_string(lineno) +"):" + msg + "\n").c_str(); std::exit(1); //Note: do not call abort() } } diff --git a/CGAL_Core/include/CGAL/CORE/Real_impl.h b/CGAL_Core/include/CGAL/CORE/Real_impl.h index ee55ed80891..c3a3041720a 100644 --- a/CGAL_Core/include/CGAL/CORE/Real_impl.h +++ b/CGAL_Core/include/CGAL/CORE/Real_impl.h @@ -33,6 +33,7 @@ #include +#include #include #include #include @@ -189,8 +190,9 @@ void Real::constructFromString(const char *str, const extLong& prec ) CGAL_INLINE_FUNCTION std::istream& operator >>(std::istream& i, Real& x) { int size = 20; - char *str = new char[size]; - char *p = str; + std::string str; + str.reserve(size); + char c; int d = 0, e = 0, s = 0; // int done = 0; @@ -211,13 +213,12 @@ std::istream& operator >>(std::istream& i, Real& x) { if (i.eof()) { i.clear(std::ios::eofbit | std::ios::failbit); - delete [] str; return i; } // the current content in "c" should be the first non-whitespace char if (c == '-' || c == '+') { - *p++ = c; + str += c; i.get(c); } @@ -230,19 +231,9 @@ std::istream& operator >>(std::istream& i, Real& x) { // xxxx.xxxe+xxx.xxx: if (e && (c == '.')) break; - if (p - str == size) { - char *t = str; - str = new char[size*2]; - std::memcpy(str, t, size); - delete [] t; - p = str + size; - size *= 2; - } -#ifdef CORE_DEBUG - CGAL_assertion((p-str) < size); -#endif - *p++ = c; + str += c; + if (c == '.') d = 1; // Chen Li: fix a bug -- the sign of exponent can not happen before @@ -255,29 +246,13 @@ std::istream& operator >>(std::istream& i, Real& x) { } if (!i && !i.eof()) { - delete [] str; return i; } - // chenli: make sure that the p is still in the range - if (p - str >= size) { - std::ptrdiff_t len = p - str; - char *t = str; - str = new char[len + 1]; - std::memcpy(str, t, len); - delete [] t; - p = str + len; - } -#ifdef CORE_DEBUG - CGAL_assertion(p - str < size); -#endif - - *p = '\0'; i.putback(c); i.clear(); // old: x = Real(str, i.precision()); // use precision of input stream. - x = Real(str); // default precision = get_static_defInputDigits() - delete [] str; + x = Real(str.c_str()); // default precision = get_static_defInputDigits() return i; }//operator >> (std::istream&, Real&) diff --git a/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h b/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h index f7cd19fdbb8..e5b2c6f9de5 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h +++ b/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h @@ -23,6 +23,8 @@ #include #include #include +#include +#include namespace CGAL { @@ -457,6 +459,103 @@ namespace CartesianKernelFunctors { } }; + namespace internal { + + template + typename K::Comparison_result + compare_distance_pssC3(const typename K::Point_3 &pt, + const typename K::Segment_3 &seg1, + const typename K::Segment_3 &seg2, + const K& k) + { + typedef typename K::Vector_3 Vector_3; + typedef typename K::RT RT; + typedef typename K::FT FT; + + typename K::Construct_vector_3 construct_vector; + + FT d1=FT(0), d2=FT(0); + RT e1 = RT(1), e2 = RT(1); + // assert that the segment is valid (non zero length). + { + Vector_3 diff = construct_vector(seg1.source(), pt); + Vector_3 segvec = construct_vector(seg1.source(), seg1.target()); + RT d = CGAL::internal::wdot(diff,segvec, k); + if (d <= (RT)0){ + d1 = (FT(diff*diff)); + }else{ + RT e = CGAL::internal::wdot(segvec,segvec, k); + if (d > e){ + d1 = CGAL::internal::squared_distance(pt, seg1.target(), k); + } else{ + Vector_3 wcr = CGAL::internal::wcross(segvec, diff, k); + d1 = FT(wcr*wcr); + e1 = e; + } + } + } + + { + Vector_3 diff = construct_vector(seg2.source(), pt); + Vector_3 segvec = construct_vector(seg2.source(), seg2.target()); + RT d = CGAL::internal::wdot(diff,segvec, k); + if (d <= (RT)0){ + d2 = (FT(diff*diff)); + }else{ + RT e = CGAL::internal::wdot(segvec,segvec, k); + if (d > e){ + d2 = CGAL::internal::squared_distance(pt, seg2.target(), k); + } else{ + Vector_3 wcr = CGAL::internal::wcross(segvec, diff, k); + d2 = FT(wcr*wcr); + e2 = e; + } + } + } + + return CGAL::compare(d1*e2, d2*e1); + } + + template + typename K::Comparison_result + compare_distance_ppsC3(const typename K::Point_3 &pt, + const typename K::Point_3 &pt2, + const typename K::Segment_3 &seg, + const K& k) + { + typedef typename K::Vector_3 Vector_3; + typedef typename K::RT RT; + typedef typename K::FT FT; + + typename K::Construct_vector_3 construct_vector; + + RT e2 = RT(1); + // assert that the segment is valid (non zero length). + FT d1 = CGAL::internal::squared_distance(pt, pt2, k); + FT d2 = FT(0); + { + Vector_3 diff = construct_vector(seg.source(), pt); + Vector_3 segvec = construct_vector(seg.source(), seg.target()); + RT d = CGAL::internal::wdot(diff,segvec, k); + if (d <= (RT)0){ + d2 = (FT(diff*diff)); + }else{ + RT e = CGAL::internal::wdot(segvec,segvec, k); + if (d > e){ + d2 = CGAL::internal::squared_distance(pt, seg.target(), k); + } else{ + Vector_3 wcr = CGAL::internal::wcross(segvec, diff, k); + d2 = FT(wcr*wcr); + e2 = e; + } + } + } + + return CGAL::compare(d1*e2, d2); + } + + } // namespace internal + template class Compare_distance_3 { @@ -476,19 +575,19 @@ namespace CartesianKernelFunctors { result_type operator()(const Point_3& p1, const Segment_3& s1, const Segment_3& s2) const { - return CGAL::internal::compare_distance_pssC3(p1,s1,s2, K()); + return internal::compare_distance_pssC3(p1,s1,s2, K()); } result_type operator()(const Point_3& p1, const Point_3& p2, const Segment_3& s2) const { - return CGAL::internal::compare_distance_ppsC3(p1,p2,s2, K()); + return internal::compare_distance_ppsC3(p1,p2,s2, K()); } result_type operator()(const Point_3& p1, const Segment_3& s2, const Point_3& p2) const { - return opposite(CGAL::internal::compare_distance_ppsC3(p1,p2,s2, K())); + return opposite(internal::compare_distance_ppsC3(p1,p2,s2, K())); } template @@ -3242,8 +3341,17 @@ namespace CartesianKernelFunctors { typedef typename K::Segment_3 Segment_3; typedef typename K::Ray_3 Ray_3; typedef typename K::FT FT; + public: - typedef Point_3 result_type; + template + struct result { + typedef const Point_3 type; + }; + + template + struct result { + typedef const Point_3& type; + }; Point_3 operator()( const Line_3& l, const Point_3& p ) const @@ -3270,15 +3378,19 @@ namespace CartesianKernelFunctors { Point_3 operator()( const Triangle_3& t, const Point_3& p ) const - { return CommonKernelFunctors::Construct_projected_point_3()(p,t,K()); } + { return CommonKernelFunctors::Construct_projected_point_3()(t,p,K()); } Point_3 operator()( const Segment_3& s, const Point_3& p ) const - { return CommonKernelFunctors::Construct_projected_point_3()(p,s,K()); } + { return CommonKernelFunctors::Construct_projected_point_3()(s,p,K()); } Point_3 operator()( const Ray_3& r, const Point_3& p ) const - { return CommonKernelFunctors::Construct_projected_point_3()(p,r,K()); } + { return CommonKernelFunctors::Construct_projected_point_3()(r,p,K()); } + + const Point_3& + operator()( const Point_3& p, const Point_3& q) const + { return CommonKernelFunctors::Construct_projected_point_3()(p,q,K()); } }; template diff --git a/Cone_spanners_2/examples/Cone_spanners_2/theta_io.cmd b/Cone_spanners_2/examples/Cone_spanners_2/theta_io.cmd deleted file mode 100644 index ddce4442855..00000000000 --- a/Cone_spanners_2/examples/Cone_spanners_2/theta_io.cmd +++ /dev/null @@ -1 +0,0 @@ -4 data/n9.cin diff --git a/Cone_spanners_2/examples/Cone_spanners_2/theta_io.cpp b/Cone_spanners_2/examples/Cone_spanners_2/theta_io.cpp index f070784e005..4096cf1c71f 100644 --- a/Cone_spanners_2/examples/Cone_spanners_2/theta_io.cpp +++ b/Cone_spanners_2/examples/Cone_spanners_2/theta_io.cpp @@ -26,26 +26,37 @@ typedef boost::adjacency_list 1 && + (!strcmp(argv[1],"-h") || !strcmp(argv[1],"--help") || !strcmp(argv[1],"-?"))) + { std::cout << "Usage: " << argv[0] << " [ ]" << std::endl; return 1; } - unsigned int k = atoi(argv[1]); - if (k<2) { - std::cout << "The number of cones should be larger than 1!" << std::endl; - return 1; + if (argc > 1) + { + k = atoi(argv[1]); + if (k<2) { + std::cout << "The number of cones should be larger than 1!" << std::endl; + return 1; + } } + if (argc > 2) + { filename=std::string(argv[2]); } + // open the file containing the vertex list - std::ifstream inf(argv[2]); + std::ifstream inf(filename); if (!inf) { - std::cout << "Cannot open file " << argv[2] << "!" << std::endl; + std::cout << "Cannot open file " << filename << "!" << std::endl; return 1; } Direction_2 initial_direction; - if (argc == 3) + if (argc == 1 || argc == 3) initial_direction = Direction_2(1, 0); // default initial_direction else if (argc == 5) initial_direction = Direction_2(atof(argv[3]), atof(argv[4])); diff --git a/Cone_spanners_2/include/CGAL/Cone_spanners_2/Plane_scan_tree_impl.h b/Cone_spanners_2/include/CGAL/Cone_spanners_2/Plane_scan_tree_impl.h index 411a671f843..b76b5a64208 100644 --- a/Cone_spanners_2/include/CGAL/Cone_spanners_2/Plane_scan_tree_impl.h +++ b/Cone_spanners_2/include/CGAL/Cone_spanners_2/Plane_scan_tree_impl.h @@ -20,7 +20,7 @@ #include - +#include #include namespace CGAL { @@ -134,9 +134,8 @@ public: _Leaf (const key_compare& less, const value_compare& vless, tree_type *const t, _leaf_type *const prev = nullptr, _leaf_type *const next = nullptr) - : _node_type (less, vless, t), prev (prev), next (next) { - std::memset (values, 0, 2*sizeof(value_type*)); - } + : _node_type (less, vless, t), values({nullptr,nullptr}), prev (prev), next (next) + {} /* Destructor. * Frees memory used for storing key-value pair, thus invalidating any @@ -242,7 +241,7 @@ protected: private: /* Key-value pairs */ - value_type* values[2]; + std::array values; /* Linked list structure of the B+ tree */ _leaf_type* prev; @@ -268,11 +267,8 @@ public: typedef typename _node_type::tree_type tree_type; _Internal (const Comp& less, const VComp& vless, tree_type *const t) - : _node_type(less, vless, t) { - std::memset (keys, 0, 2*sizeof(key_type*)); - std::memset (children, 0, 3*sizeof(_node_type*)); - std::memset (vMin, 0, 3*sizeof(mapped_type*)); - } + : _node_type(less, vless, t), keys({nullptr, nullptr}), children({nullptr, nullptr, nullptr}), vMin({nullptr, nullptr, nullptr}) + {} virtual ~_Internal() { keys[0] = nullptr; @@ -492,9 +488,9 @@ protected: } private: - const key_type* keys[2]; - _node_type* children[3]; - const mapped_type* vMin[3]; + std::array keys; + std::array< _node_type*, 3> children; + std::array vMin; }; template diff --git a/Convex_decomposition_3/include/CGAL/Convex_decomposition_3/Edge_sorter.h b/Convex_decomposition_3/include/CGAL/Convex_decomposition_3/Edge_sorter.h index 1516219ce2f..c54f3ab89f5 100644 --- a/Convex_decomposition_3/include/CGAL/Convex_decomposition_3/Edge_sorter.h +++ b/Convex_decomposition_3/include/CGAL/Convex_decomposition_3/Edge_sorter.h @@ -212,7 +212,7 @@ template SNC_point_locator* pl; public: - Edge_sorter(Container& cin) : c(cin) {} + Edge_sorter(Container& cin) : c(cin), sncp(nullptr), pl(nullptr) {} void operator()(SNC_and_PL& sncpl) { sncp = sncpl.sncp; diff --git a/Convex_decomposition_3/include/CGAL/Convex_decomposition_3/Ray_hit_generator2.h b/Convex_decomposition_3/include/CGAL/Convex_decomposition_3/Ray_hit_generator2.h index c0e8cdeb858..6fb98e4f858 100644 --- a/Convex_decomposition_3/include/CGAL/Convex_decomposition_3/Ray_hit_generator2.h +++ b/Convex_decomposition_3/include/CGAL/Convex_decomposition_3/Ray_hit_generator2.h @@ -69,7 +69,8 @@ class Ray_hit_generator2 : public Modifier_base { bool vertex_added; public: - Ray_hit_generator2(Vector_3 d, Vertex_handle v) : dir(d), vs(v) {} + Ray_hit_generator2(Vector_3 d, Vertex_handle v) + : dir(d), vs(v), sncp(nullptr), pl(nullptr), edge_splitted(false), vertex_added(false) {} Vertex_handle create_vertex_on_first_hit(const Ray_3& r) { diff --git a/Convex_decomposition_3/include/CGAL/Convex_decomposition_3/Single_wall_creator.h b/Convex_decomposition_3/include/CGAL/Convex_decomposition_3/Single_wall_creator.h index d0e8b498a59..5497f197db8 100644 --- a/Convex_decomposition_3/include/CGAL/Convex_decomposition_3/Single_wall_creator.h +++ b/Convex_decomposition_3/include/CGAL/Convex_decomposition_3/Single_wall_creator.h @@ -74,7 +74,7 @@ class Single_wall_creator : public Modifier_base { public: Single_wall_creator(SVertex_handle e, Vector_3 d) - : ein(e), dir(d) + : ein(e), dir(d), sncp(nullptr), pl(nullptr) #ifndef CGAL_NEF_NO_INDEXED_ITEMS , index1(0), index2(0) #endif diff --git a/Convex_hull_3/include/CGAL/convex_hull_3.h b/Convex_hull_3/include/CGAL/convex_hull_3.h index e6ff827f2cb..20b12772563 100644 --- a/Convex_hull_3/include/CGAL/convex_hull_3.h +++ b/Convex_hull_3/include/CGAL/convex_hull_3.h @@ -359,6 +359,8 @@ public: } } catch (Uncertain_conversion_exception&){} + Protector protector(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); if (ek_plane_ptr==nullptr) { const typename Exact_K::Point_3 ep = to_EK(p); ek_plane_ptr = new Vector_plus_point; diff --git a/Data/data/meshes/tetrahedron.off b/Data/data/meshes/tetrahedron.off new file mode 100644 index 00000000000..5c641a7849e --- /dev/null +++ b/Data/data/meshes/tetrahedron.off @@ -0,0 +1,11 @@ +OFF +4 4 0 +0.0 0.0 0.0 +1.0 0.0 0.0 +0.0 1.0 0.0 +0.0 0.0 1.0 +3 0 1 2 +3 0 3 1 +3 0 2 3 +3 1 3 2 + diff --git a/Point_set_processing_3/test/Point_set_processing_3/data/sphere_20k.xyz b/Data/data/points_3/sphere_20k.xyz similarity index 100% rename from Point_set_processing_3/test/Point_set_processing_3/data/sphere_20k.xyz rename to Data/data/points_3/sphere_20k.xyz diff --git a/Distance_2/include/CGAL/Distance_2/Line_2_Line_2.h b/Distance_2/include/CGAL/Distance_2/Line_2_Line_2.h new file mode 100644 index 00000000000..53fef5cbd53 --- /dev/null +++ b/Distance_2/include/CGAL/Distance_2/Line_2_Line_2.h @@ -0,0 +1,58 @@ +// Copyright (c) 1998-2004 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman +// Michel Hoffmann +// Andreas Fabri + +#ifndef CGAL_DISTANCE_2_LINE_2_LINE_2_H +#define CGAL_DISTANCE_2_LINE_2_LINE_2_H + +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +inline typename K::FT +squared_distance(const typename K::Line_2& line1, + const typename K::Line_2& line2, + const K& k) +{ + typedef typename K::FT FT; + + typename K::Compute_squared_distance_2 sq_dist = k.compute_squared_distance_2_object(); + + if(internal::parallel(line1, line2, k)) + return sq_dist(line1.point(), line2); + else + return FT(0); +} + +} // namespace internal + +template +inline typename K::FT +squared_distance(const Line_2& line1, + const Line_2& line2) +{ + return K().compute_squared_distance_2_object()(line1, line2); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_2_LINE_2_LINE_2_H diff --git a/Distance_2/include/CGAL/Distance_2/Line_2_Triangle_2.h b/Distance_2/include/CGAL/Distance_2/Line_2_Triangle_2.h new file mode 100644 index 00000000000..3f9fc69ac3d --- /dev/null +++ b/Distance_2/include/CGAL/Distance_2/Line_2_Triangle_2.h @@ -0,0 +1,89 @@ +// Copyright (c) 1998-2004 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman +// Michel Hoffmann +// Andreas Fabri + +#ifndef CGAL_DISTANCE_2_LINE_2_TRIANGLE_2_H +#define CGAL_DISTANCE_2_LINE_2_TRIANGLE_2_H + +#include + +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +typename K::FT +squared_distance(const typename K::Line_2& line, + const typename K::Triangle_2& triangle, + const K& k) +{ + typedef typename K::FT FT; + + typename K::Compute_squared_distance_2 sq_dist = k.compute_squared_distance_2_object(); + + const Oriented_side side0 = line.oriented_side(triangle.vertex(0)); + if(line.oriented_side(triangle.vertex(1)) != side0) + return FT(0); + + if(line.oriented_side(triangle.vertex(2)) != side0) + return FT(0); + + FT mindist = sq_dist(triangle.vertex(0), line); + for(int i=1; i<3; ++i) + { + FT dist = sq_dist(triangle.vertex(i), line); + if(dist < mindist) + mindist = dist; + } + + return mindist; +} + +template +inline typename K::FT +squared_distance(const typename K::Triangle_2& triangle, + const typename K::Line_2& line, + const K& k) +{ + return internal::squared_distance(line, triangle, k); +} + +} // namespace internal + +template +inline typename K::FT +squared_distance(const Line_2& line, + const Triangle_2& triangle) +{ + return K().compute_squared_distance_2_object()(line, triangle); +} + +template +inline typename K::FT +squared_distance(const Triangle_2& triangle, + const Line_2& line) +{ + return K().compute_squared_distance_2_object()(triangle, line); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_2_LINE_2_TRIANGLE_2_H diff --git a/Distance_2/include/CGAL/Distance_2/Point_2_Line_2.h b/Distance_2/include/CGAL/Distance_2/Point_2_Line_2.h new file mode 100644 index 00000000000..61550cb6908 --- /dev/null +++ b/Distance_2/include/CGAL/Distance_2/Point_2_Line_2.h @@ -0,0 +1,108 @@ +// Copyright (c) 1998-2004 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman +// Michel Hoffmann +// Andreas Fabri + +#ifndef CGAL_DISTANCE_2_POINT_2_LINE_2_H +#define CGAL_DISTANCE_2_POINT_2_LINE_2_H + +#include +#include +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +typename K::FT +squared_distance(const typename K::Point_2& pt, + const typename K::Line_2& line, + const K&, + const Homogeneous_tag&) +{ + typedef typename K::RT RT; + typedef typename K::FT FT; + + const RT& a = line.a(); + const RT& b = line.b(); + const RT& w = pt.hw(); + RT n = a*pt.hx() + b*pt.hy() + w*line.c(); + RT d = (CGAL_NTS square(a) + CGAL_NTS square(b)) * CGAL_NTS square(w); + + return Rational_traits().make_rational(CGAL_NTS square(n), d); +} + +template +typename K::FT +squared_distance(const typename K::Point_2& pt, + const typename K::Line_2& line, + const K&, + const Cartesian_tag&) +{ + typedef typename K::FT FT; + + const FT& a = line.a(); + const FT& b = line.b(); + FT n = a*pt.x() + b*pt.y() + line.c(); + FT d = CGAL_NTS square(a) + CGAL_NTS square(b); + + return CGAL_NTS square(n)/d; +} + +template +typename K::FT +squared_distance(const typename K::Point_2& pt, + const typename K::Line_2& line, + const K& k) +{ + typedef typename K::Kernel_tag Tag; + Tag tag; + return squared_distance(pt, line, k, tag); +} + +template +inline typename K::FT +squared_distance(const typename K::Line_2& line, + const typename K::Point_2& pt, + const K& k) +{ + return internal::squared_distance(pt, line, k); +} + +} // namespace internal + +template +inline typename K::FT +squared_distance(const Point_2& pt, + const Line_2& line) +{ + return K().compute_squared_distance_2_object()(pt, line); +} + +template +inline typename K::FT +squared_distance(const Line_2& line, + const Point_2& pt) +{ + return K().compute_squared_distance_2_object()(line, pt); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_2_POINT_2_LINE_2_H diff --git a/Distance_2/include/CGAL/Distance_2/Point_2_Point_2.h b/Distance_2/include/CGAL/Distance_2/Point_2_Point_2.h new file mode 100644 index 00000000000..b7405fddd6b --- /dev/null +++ b/Distance_2/include/CGAL/Distance_2/Point_2_Point_2.h @@ -0,0 +1,49 @@ +// Copyright (c) 1998-2004 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman +// Michel Hoffmann +// Andreas Fabri + +#ifndef CGAL_DISTANCE_2_POINT_2_POINT_2_H +#define CGAL_DISTANCE_2_POINT_2_POINT_2_H + +#include + +namespace CGAL { +namespace internal { + +template +inline typename K::FT +squared_distance(const typename K::Point_2& pt1, + const typename K::Point_2& pt2, + const K& k) +{ + typename K::Vector_2 vec = k.construct_vector_2_object()(pt2, pt1); + return k.compute_squared_length_2_object()(vec); +} + +} // namespace internal + +template +inline typename K::FT +squared_distance(const Point_2& pt1, + const Point_2& pt2) +{ + return K().compute_squared_distance_2_object()(pt1, pt2); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_2_POINT_2_POINT_2_H diff --git a/Distance_2/include/CGAL/Distance_2/Point_2_Ray_2.h b/Distance_2/include/CGAL/Distance_2/Point_2_Ray_2.h new file mode 100644 index 00000000000..c1f4543474e --- /dev/null +++ b/Distance_2/include/CGAL/Distance_2/Point_2_Ray_2.h @@ -0,0 +1,108 @@ +// Copyright (c) 1998-2004 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman +// Michel Hoffmann +// Andreas Fabri + +#ifndef CGAL_DISTANCE_2_POINT_2_RAY_2_H +#define CGAL_DISTANCE_2_POINT_2_RAY_2_H + +#include +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +void +distance_index(int &ind, + const typename K::Point_2 &pt, + const typename K::Ray_2 &ray, + const K& k) +{ + typename K::Construct_vector_2 construct_vector = k.construct_vector_2_object(); + if(!is_acute_angle(ray.direction().vector(), construct_vector(ray.source(), pt), k)) + { + ind = 0; + return; + } + + ind = -1; +} + +template +inline typename K::FT +squared_distance_indexed(const typename K::Point_2 &pt, + const typename K::Ray_2 &ray, + int ind, + const K& k) +{ + if(ind == 0) + return internal::squared_distance(pt, ray.source(), k); + + return internal::squared_distance(pt, ray.supporting_line(), k); +} + +template +typename K::FT +squared_distance(const typename K::Point_2& pt, + const typename K::Ray_2& ray, + const K& k) +{ + typedef typename K::Vector_2 Vector_2; + + typename K::Construct_vector_2 construct_vector = k.construct_vector_2_object(); + + Vector_2 diff = construct_vector(ray.source(), pt); + const Vector_2& dir = ray.direction().vector(); + if (!is_acute_angle(dir, diff, k)) + return k.compute_squared_length_2_object()(diff); + + return internal::squared_distance(pt, ray.supporting_line(), k); +} + +template +inline typename K::FT +squared_distance(const typename K::Ray_2& ray, + const typename K::Point_2& pt, + const K& k) +{ + return internal::squared_distance(pt, ray, k); +} + +} // namespace internal + +template +inline typename K::FT +squared_distance(const Point_2& pt, + const Ray_2& ray) +{ + return internal::squared_distance(pt, ray, K()); +} + +template +inline typename K::FT +squared_distance(const Ray_2& ray, + const Point_2& pt) +{ + return internal::squared_distance(pt, ray, K()); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_2_POINT_2_RAY_2_H diff --git a/Distance_2/include/CGAL/Distance_2/Point_2_Segment_2.h b/Distance_2/include/CGAL/Distance_2/Point_2_Segment_2.h new file mode 100644 index 00000000000..cc591908a2b --- /dev/null +++ b/Distance_2/include/CGAL/Distance_2/Point_2_Segment_2.h @@ -0,0 +1,126 @@ +// Copyright (c) 1998-2004 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman +// Michel Hoffmann +// Andreas Fabri + +#ifndef CGAL_DISTANCE_2_POINT_2_SEGMENT_2_H +#define CGAL_DISTANCE_2_POINT_2_SEGMENT_2_H + +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +void +distance_index(int &ind, + const typename K::Point_2 &pt, + const typename K::Segment_2 &seg, + const K& k) +{ + if(!is_acute_angle(seg.target(),seg.source(),pt, k)) + { + ind = 0; + return; + } + + if(!is_acute_angle(seg.source(),seg.target(),pt, k)) + { + ind = 1; + return; + } + ind = -1; +} + +template +inline typename K::FT +squared_distance_indexed(const typename K::Point_2 &pt, + const typename K::Segment_2 &seg, + int ind, + const K& k) +{ + typename K::Compute_squared_distance_2 sq_dist = k.compute_squared_distance_2_object(); + + if(ind == 0) + return sq_dist(pt, seg.source()); + + if(ind == 1) + return sq_dist(pt, seg.target()); + + return sq_dist(pt, seg.supporting_line()); +} + +template +typename K::FT +squared_distance(const typename K::Point_2& pt, + const typename K::Segment_2& seg, + const K& k) +{ + typedef typename K::Vector_2 Vector_2; + typedef typename K::RT RT; + + typename K::Construct_vector_2 vector = k.construct_vector_2_object(); + typename K::Compute_squared_length_2 sq_length = k.compute_squared_length_2_object(); + typename K::Compute_squared_distance_2 sq_dist = k.compute_squared_distance_2_object(); + + // assert that the segment is valid (non zero length). + const Vector_2 diff = vector(seg.source(), pt); + const Vector_2 segvec = vector(seg.source(), seg.target()); + + const RT d = wdot(diff, segvec, k); + if(d <= RT(0)) + return sq_length(diff); + + const RT e = wdot(segvec,segvec, k); + if(wmult((K*)0 ,d, segvec.hw()) > wmult((K*)0, e, diff.hw())) + return sq_dist(pt, seg.target()); + + return sq_dist(pt, seg.supporting_line()); +} + +template +inline typename K::FT +squared_distance(const typename K::Segment_2& seg, + const typename K::Point_2& pt, + const K& k) +{ + return internal::squared_distance(pt, seg, k); +} + +} // namespace internal + +template +inline typename K::FT +squared_distance(const Point_2& pt, + const Segment_2& seg) +{ + return K().compute_squared_distance_2_object()(pt, seg); +} + +template +inline typename K::FT +squared_distance(const Segment_2& seg, + const Point_2& pt) +{ + return K().compute_squared_distance_2_object()(seg, pt); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_2_POINT_2_SEGMENT_2_H diff --git a/Distance_2/include/CGAL/Distance_2/Point_2_Triangle_2.h b/Distance_2/include/CGAL/Distance_2/Point_2_Triangle_2.h new file mode 100644 index 00000000000..2448737e116 --- /dev/null +++ b/Distance_2/include/CGAL/Distance_2/Point_2_Triangle_2.h @@ -0,0 +1,266 @@ +// Copyright (c) 1998-2004 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman +// Michel Hoffmann +// Andreas Fabri + +#ifndef CGAL_DISTANCE_2_POINT_2_TRIANGLE_2_H +#define CGAL_DISTANCE_2_POINT_2_TRIANGLE_2_H + +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +void +distance_index(int &ind1, + int &ind2, + const typename K::Point_2 &pt, + const typename K::Triangle_2 &triangle, + const K& k) +{ + typedef typename K::Point_2 Point_2; + + typename K::Left_turn_2 leftturn = k.left_turn_2_object(); + + const Point_2& vt0 = triangle.vertex(0); + const Point_2& vt1 = triangle.vertex(1); + const Point_2& vt2 = triangle.vertex(2); + + if(leftturn(vt0, vt1, vt2)) { + if(leftturn(pt, vt1, vt0)) { + if(!is_acute_angle(vt0, vt1, pt, k)) { + if(leftturn(pt, vt2, vt1)) { + if(!is_acute_angle(vt1, vt2, pt, k)) { + ind1 = 2; ind2 = -1; + return; + } + if(!is_acute_angle(vt2, vt1, pt, k)) { + ind1 = 1; ind2 = -1; + return; + } + ind1 = 1; ind2 = 2; + return; + } + ind1 = 1; ind2 = -1; + return; + } + if(!is_acute_angle(vt1, vt0, pt, k)) { + if(leftturn(pt, vt0, vt2)) { + if(!is_acute_angle(vt0, vt2, pt, k)) { + ind1 = 2; ind2 = -1; + return; + } + if(!is_acute_angle(vt2, vt0, pt, k)) { + ind1 = 0; ind2 = -1; + return; + } + ind1 = 2; ind2 = 0; + return; + } + ind1 = 0; ind2 = -1; + return; + } + ind1 = 0; ind2 = 1; + return; + } else { + if(leftturn(pt, vt2, vt1)) { + if(!is_acute_angle(vt1, vt2, pt, k)) { + if(leftturn(pt, vt0, vt2)) { + if(!is_acute_angle(vt0, vt2, pt, k)) { + ind1 = 2; ind2 = -1; + return; + } + if(!is_acute_angle(vt2, vt0, pt, k)) { + ind1 = 0; ind2 = -1; + return; + } + ind1 = 2; ind2 = 0; + return; + } + ind1 = 0; ind2 = -1; + return; + } + if(!is_acute_angle(vt2, vt1, pt, k)) { + ind1 = 1; ind2 = -1; + return; + } + ind1 = 1; ind2 = 2; + return; + } else { + if(leftturn(pt, vt0, vt2)) { + if(!is_acute_angle(vt2, vt0, pt, k)) { + ind1 = 0; ind2 = -1; + return; + } + if(!is_acute_angle(vt0, vt2, pt, k)) { + ind1 = 2; ind2 = -1; + return; + } + ind1 = 2; ind2 = 0; + return; + } else { + ind1 = -1; ind2 = -1; // point inside or on boundary. + return; + } + } + } + } else { + if(leftturn(pt, vt2, vt0)) { + if(!is_acute_angle(vt0, vt2, pt, k)) { + if(leftturn(pt, vt1, vt2)) { + if(!is_acute_angle(vt2, vt1, pt, k)) { + ind1 = 1; ind2 = -1; + return; + } + if(!is_acute_angle(vt1, vt2, pt, k)) { + ind1 = 2; ind2 = -1; + return; + } + ind1 = 2; ind2 = 1; + return; + } + ind1 = 2; ind2 = -1; + return; + } + if(!is_acute_angle(vt2, vt0, pt, k)) { + if(leftturn(pt, vt0, vt1)) { + if(!is_acute_angle(vt0, vt1, pt, k)) { + ind1 = 1; ind2 = -1; + return; + } + if(!is_acute_angle(vt1, vt0, pt, k)) { + ind1 = 0; ind2 = -1; + return; + } + ind1 = 1; ind2 = 0; + return; + } + ind1 = 0; ind2 = -1; + return; + } + ind1 = 0; ind2 = 2; + return; + } else { + if(leftturn(pt, vt1, vt2)) { + if(!is_acute_angle(vt2, vt1, pt, k)) { + if(leftturn(pt, vt0, vt1)) { + if(!is_acute_angle(vt0, vt1, pt, k)) { + ind1 = 1; ind2 = -1; + return; + } + if(!is_acute_angle(vt1, vt0, pt, k)) { + ind1 = 0; ind2 = -1; + return; + } + ind1 = 1; ind2 = 0; + return; + } + ind1 = 0; ind2 = -1; + return; + } + if(!is_acute_angle(vt1, vt2, pt, k)) { + ind1 = 2; ind2 = -1; + return; + } + ind1 = 2; ind2 = 1; + return; + } else { + if(leftturn(pt, vt0, vt1)) { + if(!is_acute_angle(vt1, vt0, pt, k)) { + ind1 = 0; ind2 = -1; + return; + } + if(!is_acute_angle(vt0, vt1, pt, k)) { + ind1 = 1; ind2 = -1; + return; + } + ind1 = 1; ind2 = 0; + return; + } else { + ind1 = -1; ind2 = -1; // point inside or on boundary. + return; + } + } + } + } +} + +template +typename K::FT +squared_distance_indexed(const typename K::Point_2& pt, + const typename K::Triangle_2& triangle, + int ind1, int ind2, + const K& k) +{ + typedef typename K::FT FT; + typedef typename K::Line_2 Line_2; + + typename K::Compute_squared_distance_2 sq_dist = k.compute_squared_distance_2_object(); + + if(ind1 == -1) + return FT(0); + + if(ind2 == -1) + return sq_dist(pt, triangle.vertex(ind1)); + + return sq_dist(pt, Line_2{triangle.vertex(ind1), triangle.vertex(ind2)}); +} + +template +typename K::FT +squared_distance(const typename K::Point_2& pt, + const typename K::Triangle_2& triangle, + const K& k) +{ + int ind1, ind2; + distance_index(ind1, ind2, pt, triangle, k); + return squared_distance_indexed(pt, triangle, ind1, ind2, k); +} + +template +inline typename K::FT +squared_distance(const typename K::Triangle_2& triangle, + const typename K::Point_2& pt, + const K& k) +{ + return internal::squared_distance(pt, triangle, k); +} + +} // namespace internal + +template +inline typename K::FT +squared_distance(const Point_2& pt, + const Triangle_2& triangle) +{ + return K().compute_squared_distance_2_object()(pt, triangle); +} + +template +inline typename K::FT +squared_distance(const Triangle_2& triangle, + const Point_2& pt) +{ + return K().compute_squared_distance_2_object()(triangle, pt); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_2_POINT_2_TRIANGLE_2_H diff --git a/Distance_2/include/CGAL/Distance_2/Ray_2_Line_2.h b/Distance_2/include/CGAL/Distance_2/Ray_2_Line_2.h new file mode 100644 index 00000000000..ea3c8fb7af0 --- /dev/null +++ b/Distance_2/include/CGAL/Distance_2/Ray_2_Line_2.h @@ -0,0 +1,88 @@ +// Copyright (c) 1998-2004 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman +// Michel Hoffmann +// Andreas Fabri + +#ifndef CGAL_DISTANCE_2_RAY_2_LINE_2_H +#define CGAL_DISTANCE_2_RAY_2_LINE_2_H + +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +typename K::FT +squared_distance(const typename K::Line_2& line, + const typename K::Ray_2& ray, + const K& k) +{ + typedef typename K::FT FT; + typedef typename K::Vector_2 Vector_2; + + typename K::Construct_vector_2 construct_vector = k.construct_vector_2_object(); + + Vector_2 normalvec(line.a(), line.b()); + Vector_2 diff = construct_vector(line.point(), ray.source()); + + FT sign_dist = k.compute_scalar_product_2_object()(diff, normalvec); + if(sign_dist < FT(0)) + { + if(is_acute_angle(normalvec, ray.direction().vector(), k)) + return FT(0); + } + else + { + if(is_obtuse_angle(normalvec, ray.direction().vector(), k)) + return FT(0); + } + + return (square(sign_dist) / k.compute_squared_length_2_object()(normalvec)); +} + +template +inline typename K::FT +squared_distance(const typename K::Ray_2& ray, + const typename K::Line_2& line, + const K& k) +{ + return internal::squared_distance(line, ray, k); +} + +} // namespace internal + +template +inline typename K::FT +squared_distance(const Line_2& line, + const Ray_2& ray) +{ + return K().compute_squared_distance_2_object()(line, ray); +} + +template +inline typename K::FT +squared_distance(const Ray_2& ray, + const Line_2& line) +{ + return K().compute_squared_distance_2_object()(ray, line); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_2_RAY_2_LINE_2_H diff --git a/Distance_2/include/CGAL/Distance_2/Ray_2_Ray_2.h b/Distance_2/include/CGAL/Distance_2/Ray_2_Ray_2.h new file mode 100644 index 00000000000..f8d046f602a --- /dev/null +++ b/Distance_2/include/CGAL/Distance_2/Ray_2_Ray_2.h @@ -0,0 +1,115 @@ +// Copyright (c) 1998-2004 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman +// Michel Hoffmann +// Andreas Fabri + +#ifndef CGAL_DISTANCE_2_RAY_2_RAY_2_H +#define CGAL_DISTANCE_2_RAY_2_RAY_2_H + +#include +#include + +#include + +namespace CGAL { +namespace internal { + +template +typename K::FT +ray_ray_squared_distance_parallel(const typename K::Vector_2& ray1dir, + const typename K::Vector_2& ray2dir, + const typename K::Vector_2& from1to2, + const K& k) +{ + typedef typename K::RT RT; + typedef typename K::FT FT; + + if(!is_acute_angle(ray1dir, from1to2, k)) + { + if(!same_direction(ray1dir, ray2dir, k)) + return k.compute_squared_length_2_object()(from1to2); + } + + RT wcr = wcross(ray1dir, from1to2, k); + RT w = from1to2.hw(); + + return (square(wcr) / FT(wmult((K*)0, wdot(ray1dir, ray1dir, k), w, w))); +} + +template +typename K::FT +squared_distance(const typename K::Ray_2& ray1, + const typename K::Ray_2& ray2, + const K& k) +{ + typedef typename K::Vector_2 Vector_2; + typedef typename K::FT FT; + + typename K::Construct_vector_2 vector = k.construct_vector_2_object(); + typename K::Compute_squared_distance_2 sq_dist = k.compute_squared_distance_2_object(); + + const Vector_2 ray1dir = ray1.direction().vector(); + const Vector_2 ray2dir = ray2.direction().vector(); + const Vector_2 diffvec = vector(ray1.source(),ray2.source()); + + bool crossing1, crossing2; + switch(orientation(ray1dir, ray2dir, k)) + { + case COUNTERCLOCKWISE: + crossing1 = !clockwise(diffvec, ray2dir, k); + crossing2 = !counterclockwise(ray1dir, diffvec, k); + break; + case CLOCKWISE: + crossing1 = !counterclockwise(diffvec, ray2dir, k); + crossing2 = !clockwise(ray1dir, diffvec, k); + break; + default: + return ray_ray_squared_distance_parallel(ray1dir, ray2dir, diffvec,k); + } + + if(crossing1) + { + if(crossing2) + return FT(0); + return sq_dist(ray2.source(), ray1); + } + else + { + if(crossing2) + { + return sq_dist(ray1.source(), ray2); + } + else + { + FT min1 = sq_dist(ray1.source(), ray2); + FT min2 = sq_dist(ray2.source(), ray1); + return (min1 < min2) ? min1 : min2; + } + } +} + +} // namespace internal + +template +inline typename K::FT +squared_distance(const Ray_2 &ray1, const Ray_2 &ray2) +{ + return K().compute_squared_distance_2_object()(ray1, ray2); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_2_RAY_2_RAY_2_H diff --git a/Distance_2/include/CGAL/Distance_2/Ray_2_Triangle_2.h b/Distance_2/include/CGAL/Distance_2/Ray_2_Triangle_2.h new file mode 100644 index 00000000000..8c7bbd0be3f --- /dev/null +++ b/Distance_2/include/CGAL/Distance_2/Ray_2_Triangle_2.h @@ -0,0 +1,121 @@ +// Copyright (c) 1998-2004 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman +// Michel Hoffmann +// Andreas Fabri + +#ifndef CGAL_DISTANCE_2_RAY_2_TRIANGLE_2_H +#define CGAL_DISTANCE_2_RAY_2_TRIANGLE_2_H + +#include +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +typename K::FT +squared_distance(const typename K::Ray_2& ray, + const typename K::Triangle_2& triangle, + const K& k) +{ + typedef typename K::FT FT; + typedef typename K::Point_2 Point_2; + typedef typename K::Line_2 Line_2; + + int ind_tr1, ind_tr2, ind_ray = 0, ind1; + + distance_index(ind_tr1, ind_tr2, ray.source(), triangle, k); + FT mindist = squared_distance_indexed(ray.source(), triangle, ind_tr1, ind_tr2, k); + + for(int i=0; i<3; ++i) + { + const Point_2& pt = triangle.vertex(i); + distance_index(ind1, pt, ray, k); + FT dist = squared_distance_indexed(pt, ray, ind1, k); + if(dist < mindist) + { + ind_ray = ind1; + ind_tr1 = i; ind_tr2 = -1; + mindist = dist; + } + } + + // now check if all vertices are on the right side of the separating line. + // In case of vertex-vertex smallest distance this is the case. + if(ind_tr2 == -1 && ind_ray != -1) + return mindist; + + if(ind_tr2 != -1) + { + // Check if all the segment vertices lie at the same side of + // the triangle segment. + const Point_2& vt1 = triangle.vertex(ind_tr1); + const Point_2& vt2 = triangle.vertex(ind_tr2); + if(clockwise(ray.direction().vector(), vt2-vt1, k)) + mindist = FT(0); + } + else + { + // Check if all the triangle vertices lie + // at the same side of the segment. + const Line_2& sl = ray.supporting_line(); + Oriented_side or_s = sl.oriented_side(triangle.vertex(0)); + for(int i=1; i<3; ++i) + { + if(sl.oriented_side(triangle.vertex(i)) != or_s) + { + mindist = FT(0); + break; + } + } + } + + return mindist; +} + +template +inline typename K::FT +squared_distance(const typename K::Triangle_2& triangle, + const typename K::Ray_2& ray, + const K& k) +{ + return internal::squared_distance(ray, triangle, k); +} + +} // namespace internal + +template +inline typename K::FT +squared_distance(const Ray_2& ray, + const Triangle_2& triangle) +{ + return K().compute_squared_distance_2_object()(ray, triangle); +} + +template +inline typename K::FT +squared_distance(const Triangle_2& triangle, + const Ray_2& ray) +{ + return K().compute_squared_distance_2_object()(triangle, ray); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_2_RAY_2_TRIANGLE_2_H diff --git a/Distance_2/include/CGAL/Distance_2/Segment_2_Line_2.h b/Distance_2/include/CGAL/Distance_2/Segment_2_Line_2.h new file mode 100644 index 00000000000..a4d8537b08a --- /dev/null +++ b/Distance_2/include/CGAL/Distance_2/Segment_2_Line_2.h @@ -0,0 +1,129 @@ +// Copyright (c) 1998-2004 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman +// Michel Hoffmann +// Andreas Fabri + +#ifndef CGAL_DISTANCE_2_SEGMENT_2_LINE_2_H +#define CGAL_DISTANCE_2_SEGMENT_2_LINE_2_H + +#include +#include +#include + +#include +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +typename K::FT +_sqd_to_line(const typename K::Vector_2& diff, + const typename K::RT& wcross, + const typename K::Vector_2& dir) +{ + typedef typename K::RT RT; + typedef typename K::FT FT; + + RT numerator = CGAL_NTS square(wcross); + RT denominator = wmult((K*)0, RT(wdot(dir,dir, K())), diff.hw(), diff.hw()); + return Rational_traits().make_rational(numerator, denominator); +} + +template +typename K::FT +squared_distance(const typename K::Segment_2& seg, + const typename K::Line_2& line, + const K& k) +{ + typedef typename K::RT RT; + typedef typename K::FT FT; + typedef typename K::Vector_2 Vector_2; + typedef typename K::Point_2 Point_2; + + typename K::Construct_vector_2 vector = k.construct_vector_2_object(); + typename K::Compute_squared_distance_2 sq_dist = k.compute_squared_distance_2_object(); + + const Vector_2 linedir = line.direction().vector(); + const Point_2& linepoint = line.point(); + const Vector_2 startvec = vector(linepoint, seg.source()); + const Vector_2 endvec = vector(linepoint, seg.target()); + + if(seg.source() == seg.target()) + return sq_dist(seg.source(), line); + + bool crossing1; + const RT c1s = wcross(linedir, startvec, k); + const RT c1e = wcross(linedir, endvec, k); + if(c1s < RT(0)) + { + crossing1 = (c1e >= RT(0)); + } + else + { + if(c1e <= RT(0)) + crossing1 = true; + else + crossing1 = (c1s == RT(0)); + } + + if(crossing1) + { + return FT(0); + } + else + { + const RT dm = _distance_measure_sub(c1s, c1e, startvec, endvec); + if(dm <= RT(0)) + return _sqd_to_line(startvec, c1s, linedir); + else + return _sqd_to_line(endvec, c1e, linedir); + } +} + +template +inline typename K::FT +squared_distance(const typename K::Line_2& line, + const typename K::Segment_2& seg, + const K& k) +{ + return internal::squared_distance(seg, line, k); +} + +} // namespace internal + +template +inline typename K::FT +squared_distance(const Segment_2& seg, + const Line_2& line) +{ + return K().compute_squared_distance_2_object()(seg, line); +} + +template +inline typename K::FT +squared_distance(const Line_2& line, + const Segment_2& seg) +{ + return K().compute_squared_distance_2_object()(line, seg); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_2_SEGMENT_2_LINE_2_H diff --git a/Distance_2/include/CGAL/Distance_2/Segment_2_Ray_2.h b/Distance_2/include/CGAL/Distance_2/Segment_2_Ray_2.h new file mode 100644 index 00000000000..0c17e595c01 --- /dev/null +++ b/Distance_2/include/CGAL/Distance_2/Segment_2_Ray_2.h @@ -0,0 +1,196 @@ +// Copyright (c) 1998-2004 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman +// Michel Hoffmann +// Andreas Fabri + +#ifndef CGAL_DISTANCE_2_SEGMENT_2_RAY_2_H +#define CGAL_DISTANCE_2_SEGMENT_2_RAY_2_H + +#include + +#include +#include +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +inline typename K::RT +_distance_measure_sub(const typename K::RT& startwcross, + const typename K::RT& endwcross, + const typename K::Vector_2& start, + const typename K::Vector_2& end) +{ + return CGAL_NTS abs(wmult((K*)0, startwcross, end.hw())) - + CGAL_NTS abs(wmult((K*)0, endwcross, start.hw())); +} + +template +typename K::FT +squared_distance_parallel(const typename K::Segment_2& seg, + const typename K::Ray_2& ray, + const K& k) +{ + typedef typename K::Vector_2 Vector_2; + + typename K::Compute_squared_distance_2 sq_dist = k.compute_squared_distance_2_object(); + + const Vector_2 dir1 = seg.direction().vector(); + const Vector_2 dir2 = ray.direction().vector(); + + if(same_direction(dir1, dir2, k)) + { + if(!is_acute_angle(seg.source(), seg.target(), ray.source(), k)) + return sq_dist(seg.target(), ray.source()); + } + else + { + if(!is_acute_angle(seg.target(), seg.source(), ray.source(), k)) + return sq_dist(seg.source(), ray.source()); + } + + return sq_dist(ray.source(), seg.supporting_line()); +} + +template +typename K::FT +squared_distance(const typename K::Segment_2& seg, + const typename K::Ray_2& ray, + const K& k) +{ + typedef typename K::RT RT; + typedef typename K::FT FT; + typedef typename K::Vector_2 Vector_2; + + typename K::Construct_vector_2 vector = k.construct_vector_2_object(); + typename K::Orientation_2 orientation = k.orientation_2_object(); + typename K::Compute_squared_distance_2 sq_dist = k.compute_squared_distance_2_object(); + + const Vector_2& raydir = ray.direction().vector(); + const Vector_2 startvec = vector(ray.source(), seg.source()); + const Vector_2 endvec = vector(ray.source(), seg.target()); + + if(seg.source() == seg.target()) + return internal::squared_distance(seg.source(), ray, k); + + bool crossing1, crossing2; + const RT c1s = wcross(raydir, startvec, k); + const RT c1e = wcross(raydir, endvec, k); + if(c1s < RT(0)) + { + crossing1 = (c1e >= RT(0)); + } + else + { + if(c1e <= RT(0)) + { + if(c1s == RT(0) && c1e == RT(0)) + return internal::squared_distance_parallel(seg, ray, k); + + crossing1 = true; + } + else + { + crossing1 = (c1s == RT(0)); + } + } + + switch (orientation(seg.source(), seg.target(), ray.source())) + { + case LEFT_TURN: + crossing2 = right_turn(vector(seg.source(), seg.target()), raydir, k); + break; + case RIGHT_TURN: + crossing2 = left_turn(vector(seg.source(), seg.target()), raydir, k); + break; + default: + crossing2 = true; + break; + } + + if(crossing1) + { + if(crossing2) + return FT(0); + + return sq_dist(ray.source(), seg); + } + else + { + if(crossing2) + { + const RT dm = _distance_measure_sub(c1s, c1e, startvec, endvec); + if(dm < RT(0)) + { + return sq_dist(seg.source(), ray); + } + else + { + if(dm > RT(0)) + return sq_dist(seg.target(), ray); + else // parallel, should not happen (no crossing) + return internal::squared_distance_parallel(seg, ray, k); + } + } + else + { + const RT dm = _distance_measure_sub(c1s, c1e, startvec, endvec); + if(dm == RT(0)) + return internal::squared_distance_parallel(seg, ray, k); + + const FT min1 = (dm < RT(0)) ? sq_dist(seg.source(), ray) + : sq_dist(seg.target(), ray); + const FT min2 = sq_dist(ray.source(), seg); + + return (min1 < min2) ? min1 : min2; + } + } +} + +template +inline typename K::FT +squared_distance(const typename K::Ray_2& ray, + const typename K::Segment_2& seg, + const K& k) +{ + return internal::squared_distance(seg, ray, k); +} + +} // namespace internal + +template +inline typename K::FT +squared_distance(const Segment_2& seg, + const Ray_2& ray) +{ + return K().compute_squared_distance_2_object()(seg, ray); +} + +template +inline typename K::FT +squared_distance(const Ray_2& ray, + const Segment_2& seg) +{ + return K().compute_squared_distance_2_object()(ray, seg); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_2_SEGMENT_2_RAY_2_H diff --git a/Distance_2/include/CGAL/Distance_2/Segment_2_Segment_2.h b/Distance_2/include/CGAL/Distance_2/Segment_2_Segment_2.h new file mode 100644 index 00000000000..23e2f07c827 --- /dev/null +++ b/Distance_2/include/CGAL/Distance_2/Segment_2_Segment_2.h @@ -0,0 +1,351 @@ +// Copyright (c) 1998-2004 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman +// Michel Hoffmann +// Andreas Fabri + +#ifndef CGAL_DISTANCE_2_SEGMENT_2_SEGMENT_2_H +#define CGAL_DISTANCE_2_SEGMENT_2_SEGMENT_2_H + +#include +#include +#include +#include + +#include +#include + +#include + +namespace CGAL { +namespace internal { + +template +typename K::FT +squared_distance_parallel(const typename K::Segment_2& seg1, + const typename K::Segment_2& seg2, + const K& k) +{ + typedef typename K::Vector_2 Vector_2; + + typename K::Compute_squared_distance_2 sq_dist = k.compute_squared_distance_2_object(); + + const Vector_2 dir1 = seg1.direction().vector(); + const Vector_2 dir2 = seg2.direction().vector(); + + if(same_direction(dir1, dir2, k)) + { + if(!is_acute_angle(seg1.source(), seg1.target(), seg2.source(), k)) + return sq_dist(seg1.target(), seg2.source()); + + if(!is_acute_angle(seg1.target(), seg1.source(), seg2.target(), k)) + return sq_dist(seg1.source(), seg2.target()); + } + else + { + if(!is_acute_angle(seg1.source(), seg1.target(), seg2.target(), k)) + return sq_dist(seg1.target(), seg2.target()); + + if(!is_acute_angle(seg1.target(), seg1.source(), seg2.source(), k)) + return sq_dist(seg1.source(), seg2.source()); + } + + return sq_dist(seg2.source(), seg1.supporting_line()); +} + +template +inline typename K::RT +_distance_measure_sub(const typename K::RT& startwcross, + const typename K::RT& endwcross, + const typename K::Point_2& start, + const typename K::Point_2& end) +{ + return CGAL_NTS abs(wmult((K*)0, startwcross, end.hw())) - + CGAL_NTS abs(wmult((K*)0, endwcross, start.hw())); +} + +template +typename K::FT +squared_distance(const typename K::Segment_2& seg1, + const typename K::Segment_2& seg2, + const K& k, + const Cartesian_tag&) +{ + typedef typename K::RT RT; + typedef typename K::FT FT; + + typename K::Orientation_2 orientation = k.orientation_2_object(); + typename K::Compute_squared_distance_2 sq_dist = k.compute_squared_distance_2_object(); + + if(seg1.source() == seg1.target()) + return sq_dist(seg1.source(), seg2); + + if(seg2.source() == seg2.target()) + return sq_dist(seg2.source(), seg1); + + const Orientation o1s = orientation(seg2.source(), seg2.target(), seg1.source()); + const Orientation o1e = orientation(seg2.source(), seg2.target(), seg1.target()); + + bool crossing1, crossing2; + if(o1s == RIGHT_TURN) + { + crossing1 = (o1e != RIGHT_TURN); + } + else + { + if(o1e != LEFT_TURN) + { + if(o1s == COLLINEAR && o1e == COLLINEAR) + return internal::squared_distance_parallel(seg1, seg2, k); + + crossing1 = true; + } + else + { + crossing1 = (o1s == COLLINEAR); + } + } + + const Orientation o2s = orientation(seg1.source(), seg1.target(), seg2.source()); + const Orientation o2e = orientation(seg1.source(), seg1.target(), seg2.target()); + if(o2s == RIGHT_TURN) + { + crossing2 = (o2e != RIGHT_TURN); + } + else + { + if(o2e != LEFT_TURN) + { + if(o2s == COLLINEAR && o2e == COLLINEAR) + return internal::squared_distance_parallel(seg1, seg2, k); + + crossing2 = true; + } + else + { + crossing2 = (o2s == COLLINEAR); + } + } + + if(crossing1) + { + if(crossing2) + return (FT)0; + + const RT c2s = CGAL_NTS abs(wcross(seg1.source(), seg1.target(), seg2.source(), k)); + const RT c2e = CGAL_NTS abs(wcross(seg1.source(), seg1.target(), seg2.target(), k)); + Comparison_result dm = CGAL_NTS compare(c2s, c2e); + + if(dm == SMALLER) + { + return sq_dist(seg2.source(), seg1); + } + else + { + if(dm == LARGER) + { + return sq_dist(seg2.target(), seg1); + } + else + { + // parallel, should not happen (no crossing) + return internal::squared_distance_parallel(seg1, seg2, k); + } + } + } + else + { + const RT c1s = CGAL_NTS abs(wcross(seg2.source(), seg2.target(), seg1.source(), k)); + const RT c1e = CGAL_NTS abs(wcross(seg2.source(), seg2.target(), seg1.target(), k)); + Comparison_result dm = CGAL_NTS compare(c1s, c1e); + if(crossing2) + { + if(dm == SMALLER) + { + return sq_dist(seg1.source(), seg2); + } + else + { + if(dm == LARGER) + return sq_dist(seg1.target(), seg2); + else // parallel, should not happen (no crossing) + return internal::squared_distance_parallel(seg1, seg2, k); + } + } + else + { + if(dm == EQUAL) + return internal::squared_distance_parallel(seg1, seg2, k); + + FT min1 = (dm == SMALLER) ? sq_dist(seg1.source(), seg2): + sq_dist(seg1.target(), seg2); + + const RT c2s = CGAL_NTS abs(wcross(seg1.source(), seg1.target(), seg2.source(), k)); + const RT c2e = CGAL_NTS abs(wcross(seg1.source(), seg1.target(), seg2.target(), k)); + + dm = CGAL_NTS compare(c2s,c2e); + if(dm == EQUAL) // should not happen. + return internal::squared_distance_parallel(seg1, seg2, k); + + FT min2 = (dm == SMALLER) ? sq_dist(seg2.source(), seg1): + sq_dist(seg2.target(), seg1); + + return (min1 < min2) ? min1 : min2; + } + } +} + +template +typename K::FT +squared_distance(const typename K::Segment_2& seg1, + const typename K::Segment_2& seg2, + const K& k, + const Homogeneous_tag&) +{ + typedef typename K::RT RT; + typedef typename K::FT FT; + + typename K::Compute_squared_distance_2 sq_dist = k.compute_squared_distance_2_object(); + + if(seg1.source() == seg1.target()) + return sq_dist(seg1.source(), seg2); + + if(seg2.source() == seg2.target()) + return sq_dist(seg2.source(), seg1); + + const RT c1s = wcross(seg2.source(), seg2.target(), seg1.source(), k); + const RT c1e = wcross(seg2.source(), seg2.target(), seg1.target(), k); + const RT c2s = wcross(seg1.source(), seg1.target(), seg2.source(), k); + const RT c2e = wcross(seg1.source(), seg1.target(), seg2.target(), k); + + bool crossing1, crossing2; + + if(c1s < RT(0)) + { + crossing1 = (c1e >= RT(0)); + } + else + { + if(c1e <= RT(0)) + { + if(c1s == RT(0) && c1e == RT(0)) + return internal::squared_distance_parallel(seg1, seg2, k); + + crossing1 = true; + } + else + { + crossing1 = (c1s == RT(0)); + } + } + + if(c2s < RT(0)) + { + crossing2 = (c2e >= RT(0)); + } + else + { + if(c2e <= RT(0)) + { + if(c2s == RT(0) && c2e == RT(0)) + return internal::squared_distance_parallel(seg1, seg2, k); + + crossing2 = true; + } + else + { + crossing2 = (c2s == RT(0)); + } + } + + if(crossing1) + { + if(crossing2) + return (FT)0; + + const RT dm = _distance_measure_sub(c2s,c2e, seg2.source(), seg2.target()); + if(dm < RT(0)) + { + return sq_dist(seg2.source(), seg1); + } + else + { + if(dm > RT(0)) + return sq_dist(seg2.target(), seg1); + else // parallel, should not happen (no crossing) + return internal::squared_distance_parallel(seg1, seg2, k); + } + } + else + { + if(crossing2) + { + const RT dm = _distance_measure_sub(c1s, c1e,seg1.source(),seg1.target()); + if(dm < RT(0)) + { + return sq_dist(seg1.source(), seg2); + } + else + { + if(dm > RT(0)) + return sq_dist(seg1.target(), seg2); + else // parallel, should not happen (no crossing) + return internal::squared_distance_parallel(seg1, seg2, k); + } + } + else + { + RT dm = _distance_measure_sub(c1s, c1e, seg1.source(), seg1.target()); + if(dm == RT(0)) + return internal::squared_distance_parallel(seg1, seg2, k); + + FT min1 = (dm < RT(0)) ? sq_dist(seg1.source(), seg2): + sq_dist(seg1.target(), seg2); + + dm = _distance_measure_sub(c2s, c2e, seg2.source(), seg2.target()); + if(dm == RT(0)) // should not happen. + return internal::squared_distance_parallel(seg1, seg2, k); + + FT min2 = (dm < RT(0)) ? sq_dist(seg2.source(), seg1): + sq_dist(seg2.target(), seg1); + + return (min1 < min2) ? min1 : min2; + } + } +} + +template +inline typename K::FT +squared_distance(const Segment_2& seg1, + const Segment_2& seg2, + const K& k) +{ + typedef typename K::Kernel_tag Tag; + return squared_distance(seg1, seg2, k, Tag()); +} + +} // namespace internal + +template +inline typename K::FT +squared_distance(const Segment_2& seg1, + const Segment_2& seg2) +{ + return K().compute_squared_distance_2_object()(seg1, seg2); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_2_SEGMENT_2_SEGMENT_2_H diff --git a/Distance_2/include/CGAL/Distance_2/Segment_2_Triangle_2.h b/Distance_2/include/CGAL/Distance_2/Segment_2_Triangle_2.h new file mode 100644 index 00000000000..13424998bf8 --- /dev/null +++ b/Distance_2/include/CGAL/Distance_2/Segment_2_Triangle_2.h @@ -0,0 +1,136 @@ +// Copyright (c) 1998-2004 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman +// Michel Hoffmann +// Andreas Fabri + +#ifndef CGAL_DISTANCE_2_SEGMENT_2_TRIANGLE_2_H +#define CGAL_DISTANCE_2_SEGMENT_2_TRIANGLE_2_H + +#include +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +typename K::FT +squared_distance(const typename K::Segment_2& seg, + const typename K::Triangle_2& triangle, + const K& k) +{ + typedef typename K::FT FT; + typedef typename K::Point_2 Point_2; + + typename K::Orientation_2 orientation = k.orientation_2_object(); + + int i, ind_tr1 = 0, ind_tr2 = -1, ind_seg = 0, ind1, ind2; + FT dist; + + FT mindist = internal::squared_distance(seg.source(), triangle.vertex(0), k); + for(i=0; i<2; ++i) + { + const Point_2& pt = seg.vertex(i); + distance_index(ind1, ind2, pt, triangle, k); + dist = internal::squared_distance_indexed(pt, triangle, ind1, ind2, k); + if(dist < mindist) + { + ind_seg = i; + ind_tr1 = ind1; ind_tr2 = ind2; + mindist = dist; + } + } + + for(i=0; i<3; ++i) + { + const Point_2& pt = triangle.vertex(i); + distance_index(ind1, pt, seg, k); + dist = internal::squared_distance_indexed(pt, seg, ind1, k); + if(dist < mindist) + { + ind_seg = ind1; + ind_tr1 = i; ind_tr2 = -1; + mindist = dist; + } + } + + // now check if all vertices are on the right side of the separating line. + // In case of vertex-vertex smallest distance this is the case. + if(ind_tr2 == -1 && ind_seg != -1) + return mindist; + + if(ind_tr2 != -1) + { + // Check if all the segment vertices lie at the same side of + // the triangle segment. + const Point_2 &vt1 = triangle.vertex(ind_tr1); + const Point_2 &vt2 = triangle.vertex(ind_tr2); + const Orientation or_s = orientation(vt1, vt2, seg.source()); + if(orientation(vt1, vt2, seg.target()) != or_s) + mindist = FT(0); + } + else + { + // Check if all the triangle vertices lie + // at the same side of the segment. + const Point_2& vt1 = seg.source(); + const Point_2& vt2 = seg.target(); + const Orientation or_s = orientation(vt1, vt2, triangle.vertex(0)); + for(i=1; i<3; ++i) + { + if(orientation(vt1, vt2, triangle.vertex(i)) != or_s) + { + mindist = FT(0); + break; + } + } + } + + return mindist; +} + +template +inline typename K::FT +squared_distance(const typename K::Triangle_2 & triangle, + const typename K::Segment_2 & seg, + const K& k) +{ + return internal::squared_distance(seg, triangle, k); +} + +} // namespace internal + +template +inline typename K::FT +squared_distance(const Segment_2& seg, + const Triangle_2& triangle) +{ + return K().compute_squared_distance_2_object()(seg, triangle); +} + +template +inline typename K::FT +squared_distance(const Triangle_2& triangle, + const Segment_2& seg) +{ + return K().compute_squared_distance_2_object()(triangle, seg); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_2_SEGMENT_2_TRIANGLE_2_H diff --git a/Distance_2/include/CGAL/Distance_2/Triangle_2_Triangle_2.h b/Distance_2/include/CGAL/Distance_2/Triangle_2_Triangle_2.h new file mode 100644 index 00000000000..b308ccff35f --- /dev/null +++ b/Distance_2/include/CGAL/Distance_2/Triangle_2_Triangle_2.h @@ -0,0 +1,123 @@ +// Copyright (c) 1998-2004 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman +// Michel Hoffmann +// Andreas Fabri + +#ifndef CGAL_DISTANCE_2_TRIANGLE_2_TRIANGLE_2_H +#define CGAL_DISTANCE_2_TRIANGLE_2_TRIANGLE_2_H + +#include +#include +#include + +#include + +namespace CGAL { +namespace internal { + +template +typename K::FT +squared_distance(const typename K::Triangle_2& triangle1, + const typename K::Triangle_2& triangle2, + const K& k) +{ + typedef typename K::FT FT; + typedef typename K::Point_2 Point_2; + + typename K::Orientation_2 orientation = k.orientation_2_object(); + + int ind1_1 = 0, ind1_2 = -1, ind2_1 = 0, ind2_2 = -1, ind1, ind2; + FT dist; + + FT mindist = internal::squared_distance(triangle1.vertex(0), triangle2.vertex(0), k); + for(int i=0; i<3; ++i) + { + const Point_2& pt = triangle1.vertex(i); + distance_index(ind1, ind2, pt, triangle2, k); + dist = squared_distance_indexed(pt, triangle2, ind1, ind2, k); + if(dist < mindist) + { + ind1_1 = i; ind1_2 = -1; + ind2_1 = ind1; ind2_2 = ind2; + mindist = dist; + } + } + + for(int i=0; i<3; ++i) + { + const Point_2& pt = triangle2.vertex(i); + distance_index(ind1, ind2, pt, triangle1, k); + dist = squared_distance_indexed(pt, triangle1, ind1, ind2, k); + if(dist < mindist) + { + ind1_1 = ind1; ind1_2 = ind2; + ind2_1 = i; ind2_2 = -1; + mindist = dist; + } + } + + // now check if all vertices are on the right side of the separating line. + if(ind1_2 == -1 && ind2_2 == -1) + return mindist; + + // In case of point-segment closest distance, there is still the + // possibility of overlapping triangles. Check if all the + // vertices lie at the same side of the segment. + if(ind1_2 != -1) + { + const Point_2& vt1 = triangle1.vertex(ind1_1); + const Point_2& vt2 = triangle1.vertex(ind1_2); + const Orientation or_s = orientation(vt1, vt2, triangle2.vertex(0)); + for(int i=1; i<3; ++i) + { + if(orientation(vt1, vt2, triangle2.vertex(i)) != or_s) + { + mindist = FT(0); + break; + } + } + } + else + { + const Point_2& vt1 = triangle2.vertex(ind2_1); + const Point_2& vt2 = triangle2.vertex(ind2_2); + const Orientation or_s = orientation(vt1, vt2, triangle1.vertex(0)); + for(int i=1; i<3; ++i) + { + if(orientation(vt1, vt2, triangle1.vertex(i)) != or_s) + { + mindist = FT(0); + break; + } + } + } + + return mindist; +} + +} // namespace internal + +template +inline typename K::FT +squared_distance(const Triangle_2& triangle1, + const Triangle_2& triangle2) +{ + return K().compute_squared_distance_2_object()(triangle1, triangle2); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_2_TRIANGLE_2_TRIANGLE_2_H diff --git a/Distance_2/include/CGAL/squared_distance_utils.h b/Distance_2/include/CGAL/Distance_2/internal/squared_distance_utils_2.h similarity index 99% rename from Distance_2/include/CGAL/squared_distance_utils.h rename to Distance_2/include/CGAL/Distance_2/internal/squared_distance_utils_2.h index 7a29ee4f664..6a852577f5c 100644 --- a/Distance_2/include/CGAL/squared_distance_utils.h +++ b/Distance_2/include/CGAL/Distance_2/internal/squared_distance_utils_2.h @@ -19,6 +19,7 @@ #define CGAL_SQUARED_DISTANCE_UTILS_H #include +#include #include namespace CGAL { @@ -294,7 +295,6 @@ same_direction(const typename K::Vector_2 &u, return same_direction_tag(u,v, k, tag); } - } // namespace internal } //namespace CGAL diff --git a/Distance_2/include/CGAL/squared_distance_2.h b/Distance_2/include/CGAL/squared_distance_2.h index 035d03f703e..115d6910fb9 100644 --- a/Distance_2/include/CGAL/squared_distance_2.h +++ b/Distance_2/include/CGAL/squared_distance_2.h @@ -14,11 +14,27 @@ // // Author(s) : Geert-Jan Giezeman - #ifndef CGAL_SQUARED_DISTANCE_2_H #define CGAL_SQUARED_DISTANCE_2_H -#include -#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include #endif diff --git a/Distance_2/include/CGAL/squared_distance_2_1.h b/Distance_2/include/CGAL/squared_distance_2_1.h deleted file mode 100644 index 171b8fd1e81..00000000000 --- a/Distance_2/include/CGAL/squared_distance_2_1.h +++ /dev/null @@ -1,857 +0,0 @@ -// Copyright (c) 1998-2004 -// Utrecht University (The Netherlands), -// ETH Zurich (Switzerland), -// INRIA Sophia-Antipolis (France), -// Max-Planck-Institute Saarbruecken (Germany), -// and Tel-Aviv University (Israel). All rights reserved. -// -// This file is part of CGAL (www.cgal.org) -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial -// -// -// Author(s) : Geert-Jan Giezeman -// Michel Hoffmann -// Andreas Fabri - - -#ifndef CGAL_SQUARED_DISTANCE_2_1_H -#define CGAL_SQUARED_DISTANCE_2_1_H - -#include - - -#include -#include -#include -#include -#include - -namespace CGAL { - -namespace internal { - - template - inline typename K::FT - squared_distance(const typename K::Point_2 & pt1, - const typename K::Point_2 & pt2, - const K& k) - { - typename K::Vector_2 vec = k.construct_vector_2_object()(pt2, pt1); - return (typename K::FT)k.compute_squared_length_2_object()(vec); - } - - template - typename K::FT - squared_distance(const typename K::Point_2 &pt, - const typename K::Line_2 &line, - const K&, - const Homogeneous_tag&) - { - typedef typename K::RT RT; - typedef typename K::FT FT; - const RT & a = line.a(); - const RT & b = line.b(); - const RT & w = pt.hw(); - RT n = a*pt.hx() + b*pt.hy() + w * line.c(); - RT d = (CGAL_NTS square(a) + CGAL_NTS square(b)) * CGAL_NTS square(w); - return Rational_traits().make_rational(CGAL_NTS square(n), d); - } - - template - typename K::FT - squared_distance(const typename K::Point_2 &pt, - const typename K::Line_2 &line, - const K&, - const Cartesian_tag&) - { - typedef typename K::FT FT; - const FT & a = line.a(); - const FT & b = line.b(); - FT n = a*pt.x() + b*pt.y() + line.c(); - FT d = CGAL_NTS square(a) + CGAL_NTS square(b); - return CGAL_NTS square(n)/d; - } - - - template - typename K::FT - squared_distance(const typename K::Point_2 &pt, - const typename K::Line_2 &line, - const K& k) - { - typedef typename K::Kernel_tag Tag; - Tag tag; - return squared_distance(pt, line, k, tag); - } - - template - inline typename K::FT - squared_distance(const typename K::Line_2 &line, - const typename K::Point_2 &pt, - const K& k) - { - return internal::squared_distance(pt, line, k); - } - - template - typename K::FT - squared_distance(const typename K::Point_2 &pt, - const typename K::Ray_2 &ray, - const K& k) - { - typedef typename K::Vector_2 Vector_2; - typename K::Construct_vector_2 construct_vector; - Vector_2 diff = construct_vector(ray.source(), pt); - const Vector_2 &dir = ray.direction().vector(); - if (!is_acute_angle(dir,diff, k) ) - return (typename K::FT)k.compute_squared_length_2_object()(diff); - return internal::squared_distance(pt, ray.supporting_line(), k); - } - - template - inline typename K::FT - squared_distance(const typename K::Ray_2 &ray, - const typename K::Point_2 &pt, - const K& k) - { - return internal::squared_distance(pt, ray, k); - } - - template - typename K::FT - squared_distance(const typename K::Point_2 &pt, - const typename K::Segment_2 &seg, - const K& k) - { - typename K::Construct_vector_2 construct_vector; - typedef typename K::Vector_2 Vector_2; - typedef typename K::RT RT; - // assert that the segment is valid (non zero length). - Vector_2 diff = construct_vector(seg.source(), pt); - Vector_2 segvec = construct_vector(seg.source(), seg.target()); - RT d = wdot(diff,segvec, k); - if (d <= (RT)0) - return (typename K::FT)k.compute_squared_length_2_object()(diff); - RT e = wdot(segvec,segvec, k); - if (wmult((K*)0 ,d, segvec.hw()) > wmult((K*)0, e, diff.hw())) - return internal::squared_distance(pt, seg.target(), k); - return internal::squared_distance(pt, seg.supporting_line(), k); - } - - template - inline typename K::FT - squared_distance(const typename K::Segment_2 &seg, - const typename K::Point_2 &pt, - const K& k) - { - return internal::squared_distance(pt, seg, k); - } - - template - typename K::FT - squared_distance_parallel(const typename K::Segment_2 &seg1, - const typename K::Segment_2 &seg2, - const K& k) - { - typedef typename K::Vector_2 Vector_2; - const Vector_2 &dir1 = seg1.direction().vector(); - const Vector_2 &dir2 = seg2.direction().vector(); - if (same_direction(dir1, dir2, k)) { - if (!is_acute_angle(seg1.source(), seg1.target(), seg2.source(), k)) - return internal::squared_distance(seg1.target(), seg2.source(), k); - if (!is_acute_angle(seg1.target(), seg1.source(), seg2.target(), k)) - return internal::squared_distance(seg1.source(), seg2.target(), k); - } else { - if (!is_acute_angle(seg1.source(), seg1.target(), seg2.target(), k)) - return internal::squared_distance(seg1.target(), seg2.target(), k); - if (!is_acute_angle(seg1.target(), seg1.source(), seg2.source(), k)) - return internal::squared_distance(seg1.source(), seg2.source(), k); - } - return internal::squared_distance(seg2.source(), seg1.supporting_line(), k); - } - - template - inline typename K::RT - _distance_measure_sub(const typename K::RT &startwcross, - const typename K::RT &endwcross, - const typename K::Point_2 &start, - const typename K::Point_2 &end) - { - return CGAL_NTS abs(wmult((K*)0, startwcross, end.hw())) - - CGAL_NTS abs(wmult((K*)0, endwcross, start.hw())); - } - - template - typename K::FT - squared_distance(const typename K::Segment_2 &seg1, - const typename K::Segment_2 &seg2, - const K& k, - const Cartesian_tag&) - { - typedef typename K::RT RT; - typedef typename K::FT FT; - bool crossing1, crossing2; - RT c1s, c1e, c2s, c2e; - if (seg1.source() == seg1.target()) - return internal::squared_distance(seg1.source(), seg2, k); - if (seg2.source() == seg2.target()) - return internal::squared_distance(seg2.source(), seg1, k); - - Orientation o1s = orientation(seg2.source(), seg2.target(), seg1.source()); - Orientation o1e = orientation(seg2.source(), seg2.target(), seg1.target()); - if (o1s == RIGHT_TURN) { - crossing1 = (o1e != RIGHT_TURN); - } else { - if (o1e != LEFT_TURN) { - if (o1s == COLLINEAR && o1e == COLLINEAR) - return internal::squared_distance_parallel(seg1, seg2, k); - crossing1 = true; - } else { - crossing1 = (o1s == COLLINEAR); - } - } - - Orientation o2s = orientation(seg1.source(), seg1.target(), seg2.source()); - Orientation o2e = orientation(seg1.source(), seg1.target(), seg2.target()); - if (o2s == RIGHT_TURN) { - crossing2 = (o2e != RIGHT_TURN); - } else { - if (o2e != LEFT_TURN) { - if (o2s == COLLINEAR && o2e == COLLINEAR) - return internal::squared_distance_parallel(seg1, seg2, k); - crossing2 = true; - } else { - crossing2 = (o2s == COLLINEAR); - } - } - - if (crossing1) { - if (crossing2) - return (FT)0; - - c2s = CGAL::abs(wcross(seg1.source(), seg1.target(), seg2.source(), k)); - c2e = CGAL::abs(wcross(seg1.source(), seg1.target(), seg2.target(), k)); - Comparison_result dm = CGAL::compare(c2s,c2e); - - if (dm == SMALLER) { - return internal::squared_distance(seg2.source(), seg1, k); - } else { - if (dm == LARGER) { - return internal::squared_distance(seg2.target(), seg1, k); - } else { - // parallel, should not happen (no crossing) - return internal::squared_distance_parallel(seg1, seg2, k); - } - } - } else { - c1s = CGAL::abs(wcross(seg2.source(), seg2.target(), seg1.source(), k)); - c1e = CGAL::abs(wcross(seg2.source(), seg2.target(), seg1.target(), k)); - Comparison_result dm = CGAL::compare(c1s,c1e); - if (crossing2) { - if (dm == SMALLER) { - return internal::squared_distance(seg1.source(), seg2, k); - } else { - if (dm == LARGER) { - return internal::squared_distance(seg1.target(), seg2, k); - } else { - // parallel, should not happen (no crossing) - return internal::squared_distance_parallel(seg1, seg2, k); - } - } - } else { - FT min1, min2; - - if (dm == EQUAL) - return internal::squared_distance_parallel(seg1, seg2, k); - min1 = (dm == SMALLER) ? - internal::squared_distance(seg1.source(), seg2, k): - internal::squared_distance(seg1.target(), seg2, k); - - c2s = CGAL::abs(wcross(seg1.source(), seg1.target(), seg2.source(), k)); - c2e = CGAL::abs(wcross(seg1.source(), seg1.target(), seg2.target(), k)); - dm = CGAL::compare(c2s,c2e); - - if (dm == EQUAL) // should not happen. - return internal::squared_distance_parallel(seg1, seg2, k); - min2 = (dm == SMALLER) ? - internal::squared_distance(seg2.source(), seg1, k): - internal::squared_distance(seg2.target(), seg1, k); - return (min1 < min2) ? min1 : min2; - } - } - } - - template - typename K::FT - squared_distance(const typename K::Segment_2 &seg1, - const typename K::Segment_2 &seg2, - const K& k, - const Homogeneous_tag&) - { - typedef typename K::RT RT; - typedef typename K::FT FT; - bool crossing1, crossing2; - RT c1s, c1e, c2s, c2e; - if (seg1.source() == seg1.target()) - return internal::squared_distance(seg1.source(), seg2, k); - if (seg2.source() == seg2.target()) - return internal::squared_distance(seg2.source(), seg1, k); - c1s = wcross(seg2.source(), seg2.target(), seg1.source(), k); - c1e = wcross(seg2.source(), seg2.target(), seg1.target(), k); - c2s = wcross(seg1.source(), seg1.target(), seg2.source(), k); - c2e = wcross(seg1.source(), seg1.target(), seg2.target(), k); - if (c1s < RT(0)) { - crossing1 = (c1e >= RT(0)); - } else { - if (c1e <= RT(0)) { - if (c1s == RT(0) && c1e == RT(0)) - return internal::squared_distance_parallel(seg1, seg2, k); - crossing1 = true; - } else { - crossing1 = (c1s == RT(0)); - } - } - if (c2s < RT(0)) { - crossing2 = (c2e >= RT(0)); - } else { - if (c2e <= RT(0)) { - if (c2s == RT(0) && c2e == RT(0)) - return internal::squared_distance_parallel(seg1, seg2, k); - crossing2 = true; - } else { - crossing2 = (c2s == RT(0)); - } - } - - if (crossing1) { - if (crossing2) - return (FT)0; - RT dm; - dm = _distance_measure_sub(c2s,c2e, seg2.source(), seg2.target()); - if (dm < RT(0)) { - return internal::squared_distance(seg2.source(), seg1, k); - } else { - if (dm > RT(0)) { - return internal::squared_distance(seg2.target(), seg1, k); - } else { - // parallel, should not happen (no crossing) - return internal::squared_distance_parallel(seg1, seg2, k); - } - } - } else { - if (crossing2) { - RT dm; - dm = - _distance_measure_sub(c1s, c1e,seg1.source(),seg1.target()); - if (dm < RT(0)) { - return internal::squared_distance(seg1.source(), seg2, k); - } else { - if (dm > RT(0)) { - return internal::squared_distance(seg1.target(), seg2, k); - } else { - // parallel, should not happen (no crossing) - return internal::squared_distance_parallel(seg1, seg2, k); - } - } - } else { - - FT min1, min2; - RT dm = _distance_measure_sub( - c1s, c1e, seg1.source(), seg1.target()); - if (dm == RT(0)) - return internal::squared_distance_parallel(seg1, seg2, k); - min1 = (dm < RT(0)) ? - internal::squared_distance(seg1.source(), seg2, k): - internal::squared_distance(seg1.target(), seg2, k); - dm = _distance_measure_sub( - c2s, c2e, seg2.source(), seg2.target()); - if (dm == RT(0)) // should not happen. - return internal::squared_distance_parallel(seg1, seg2, k); - min2 = (dm < RT(0)) ? - internal::squared_distance(seg2.source(), seg1, k): - internal::squared_distance(seg2.target(), seg1, k); - return (min1 < min2) ? min1 : min2; - } - } - } - - - template - inline typename K::RT - _distance_measure_sub(const typename K::RT &startwcross, - const typename K::RT &endwcross, - const typename K::Vector_2 &start, - const typename K::Vector_2 &end) - { - return CGAL_NTS abs(wmult((K*)0, startwcross, end.hw())) - - CGAL_NTS abs(wmult((K*)0, endwcross, start.hw())); - } - - template - typename K::FT - squared_distance_parallel(const typename K::Segment_2 &seg, - const typename K::Ray_2 &ray, - const K& k) - { - typedef typename K::Vector_2 Vector_2; - const Vector_2 &dir1 = seg.direction().vector(); - const Vector_2 &dir2 = ray.direction().vector(); - - if (same_direction(dir1, dir2, k)) { - if (!is_acute_angle(seg.source(), seg.target(), ray.source(), k)) - return internal::squared_distance(seg.target(), ray.source(), k); - } else { - if (!is_acute_angle(seg.target(), seg.source(), ray.source(), k)) - return internal::squared_distance(seg.source(), ray.source(), k); - } - return internal::squared_distance(ray.source(), seg.supporting_line(), k); - } - - template - typename K::FT - squared_distance(const typename K::Segment_2 &seg, - const typename K::Ray_2 &ray, - const K& k) - { - typename K::Construct_vector_2 construct_vector; - typedef typename K::RT RT; - typedef typename K::FT FT; - typedef typename K::Vector_2 Vector_2; - const Vector_2 &raydir = ray.direction().vector(); - Vector_2 startvec(construct_vector(ray.source(), seg.source())); - Vector_2 endvec(construct_vector(ray.source(), seg.target())); - typename K::Orientation_2 orientation; - - bool crossing1, crossing2; - RT c1s, c1e; - if (seg.source() == seg.target()) - return internal::squared_distance(seg.source(), ray, k); - c1s = wcross(raydir, startvec, k); - c1e = wcross(raydir, endvec, k); - if (c1s < RT(0)) { - crossing1 = (c1e >= RT(0)); - } else { - if (c1e <= RT(0)) { - if (c1s == RT(0) && c1e == RT(0)) - return internal::squared_distance_parallel(seg, ray, k); - crossing1 = true; - } else { - crossing1 = (c1s == RT(0)); - } - } - switch (orientation(seg.source(), seg.target(), ray.source())) { - case LEFT_TURN: - crossing2 = right_turn(construct_vector(seg.source(), seg.target()), raydir, k); - break; - case RIGHT_TURN: - crossing2 = left_turn(construct_vector(seg.source(), seg.target()), raydir, k); - break; - default: - crossing2 = true; - break; - } - - if (crossing1) { - if (crossing2) - return FT(0); - return internal::squared_distance(ray.source(), seg, k); - } else { - if (crossing2) { - RT dm; - dm = _distance_measure_sub(c1s, c1e, startvec, endvec); - if (dm < RT(0)) { - return internal::squared_distance(seg.source(), ray, k); - } else { - if (dm > RT(0)) { - return internal::squared_distance(seg.target(), ray, k); - } else { - // parallel, should not happen (no crossing) - return internal::squared_distance_parallel(seg, ray, k); - } - } - } else { - FT min1, min2; - RT dm = _distance_measure_sub(c1s, c1e, startvec, endvec); - if (dm == RT(0)) - return internal::squared_distance_parallel(seg, ray, k); - min1 = (dm < RT(0)) - ? internal::squared_distance(seg.source(), ray, k) - : internal::squared_distance(seg.target(), ray, k); - min2 = internal::squared_distance(ray.source(), seg, k); - return (min1 < min2) ? min1 : min2; - } - } - } - - template - inline typename K::FT - squared_distance(const typename K::Ray_2 &ray, - const typename K::Segment_2 &seg, - const K& k) - { - return internal::squared_distance(seg, ray, k); - } - - template - typename K::FT - _sqd_to_line(const typename K::Vector_2 &diff, - const typename K::RT & wcross, - const typename K::Vector_2 &dir ) - { - typedef typename K::RT RT; - typedef typename K::FT FT; - RT numerator = CGAL_NTS square(wcross); - RT denominator = wmult((K*)0, RT(wdot(dir,dir, K())), - diff.hw(), diff.hw()); - return Rational_traits().make_rational(numerator, denominator); - } - - template - typename K::FT - squared_distance(const typename K::Segment_2 &seg, - const typename K::Line_2 &line, - const K& k) - { - typename K::Construct_vector_2 construct_vector; - typedef typename K::RT RT; - typedef typename K::FT FT; - typedef typename K::Vector_2 Vector_2; - typedef typename K::Point_2 Point_2; - const Vector_2 &linedir = line.direction().vector(); - const Point_2 &linepoint = line.point(); - Vector_2 startvec(construct_vector(linepoint, seg.source())); - Vector_2 endvec(construct_vector(linepoint, seg.target())); - - bool crossing1; - RT c1s, c1e; - if (seg.source() == seg.target()) - return internal::squared_distance(seg.source(), line, k); - c1s = wcross(linedir, startvec, k); - c1e = wcross(linedir, endvec, k); - if (c1s < RT(0)) { - crossing1 = (c1e >= RT(0)); - } else { - if (c1e <= RT(0)) { - crossing1 = true; - } else { - crossing1 = (c1s == RT(0)); - } - } - - if (crossing1) { - return (FT)0; - } else { - RT dm; - dm = _distance_measure_sub(c1s, c1e, startvec, endvec); - if (dm <= RT(0)) { - return _sqd_to_line(startvec, c1s, linedir); - } else { - return _sqd_to_line(endvec, c1e, linedir); - } - } - } - - template - inline typename K::FT - squared_distance(const typename K::Line_2 &line, - const typename K::Segment_2 &seg, - const K& k) - { - return internal::squared_distance(seg, line, k); - } - - template - typename K::FT - ray_ray_squared_distance_parallel( - const typename K::Vector_2 &ray1dir, - const typename K::Vector_2 &ray2dir, - const typename K::Vector_2 &from1to2, - const K& k) - { - typedef typename K::RT RT; - typedef typename K::FT FT; - if (!is_acute_angle(ray1dir, from1to2, k)) { - if (!same_direction(ray1dir, ray2dir, k)) - return (typename K::FT)k.compute_squared_length_2_object()(from1to2); - } - RT wcr, w; - wcr = wcross(ray1dir, from1to2, k); - w = from1to2.hw(); - return (typename K::FT)(FT(wcr*wcr) - / FT(wmult((K*)0, RT(wdot(ray1dir, ray1dir, k)), w, w))); - } - - template - typename K::FT - squared_distance(const typename K::Ray_2 &ray1, - const typename K::Ray_2 &ray2, - const K& k) - { - typename K::Construct_vector_2 construct_vector; - typedef typename K::Vector_2 Vector_2; - typedef typename K::FT FT; - const Vector_2 &ray1dir = ray1.direction().vector(); - const Vector_2 &ray2dir = ray2.direction().vector(); - Vector_2 diffvec(construct_vector(ray1.source(),ray2.source())); - - bool crossing1, crossing2; - switch (orientation(ray1dir, ray2dir, k)) { - case COUNTERCLOCKWISE: - crossing1 = !clockwise(diffvec, ray2dir, k); - crossing2 = !counterclockwise(ray1dir, diffvec, k); - break; - case CLOCKWISE: - crossing1 = !counterclockwise(diffvec, ray2dir, k); - crossing2 = !clockwise(ray1dir, diffvec, k); - break; - default: - return ray_ray_squared_distance_parallel(ray1dir,ray2dir,diffvec,k); - } - - if (crossing1) { - if (crossing2) - return (FT)0; - return internal::squared_distance(ray2.source(), ray1, k); - } else { - if (crossing2) { - return internal::squared_distance(ray1.source(), ray2, k); - } else { - - FT min1, min2; - min1 = internal::squared_distance(ray1.source(), ray2, k); - min2 = internal::squared_distance(ray2.source(), ray1, k); - return (min1 < min2) ? min1 : min2; - } - } - } - - template - typename K::FT - squared_distance(const typename K::Line_2 &line, - const typename K::Ray_2 &ray, - const K& k) - { - typename K::Construct_vector_2 construct_vector; - typedef typename K::FT FT; - typedef typename K::Vector_2 Vector_2; - Vector_2 normalvec(line.a(), line.b()); - Vector_2 diff = construct_vector(line.point(), ray.source()); - FT sign_dist = k.compute_scalar_product_2_object()(diff,normalvec); - if (sign_dist < FT(0)) { - if (is_acute_angle(normalvec, ray.direction().vector(), k) ) - return (FT)0; - } else { - if (is_obtuse_angle(normalvec, ray.direction().vector(), k) ) - return (FT)0; - } - return (typename K::FT)((sign_dist*sign_dist)/k.compute_squared_length_2_object()(normalvec)); - } - - template - inline typename K::FT - squared_distance(const typename K::Ray_2 &ray, - const typename K::Line_2 &line, - const K& k) - { - return internal::squared_distance(line, ray, k); - } - - template - inline typename K::FT - squared_distance(const typename K::Line_2 &line1, - const typename K::Line_2 &line2, - const K& k) - { - typedef typename K::FT FT; - if (internal::parallel(line1, line2, k)) - return internal::squared_distance(line1.point(), line2, k); - else - return (FT)0; - } - - template - void - distance_index(int &ind, - const typename K::Point_2 &pt, - const typename K::Ray_2 &ray, - const K& k) - { - typename K::Construct_vector_2 construct_vector; - if (!is_acute_angle(ray.direction().vector(), construct_vector(ray.source(), pt), k)) { - ind = 0; - return; - } - ind = -1; - } - - template - void - distance_index(int &ind, - const typename K::Point_2 &pt, - const typename K::Segment_2 &seg, - const K& k) - { - if (!is_acute_angle(seg.target(),seg.source(),pt, k)) { - ind = 0; - return; - } - if (!is_acute_angle(seg.source(),seg.target(),pt, k)) { - ind = 1; - return; - } - ind = -1; - } - - template - inline typename K::FT - squared_distance_indexed(const typename K::Point_2 &pt, - const typename K::Ray_2 &ray, - int ind, - const K& k) - { - if (ind == 0) - return internal::squared_distance(pt, ray.source(), k); - return internal::squared_distance(pt, ray.supporting_line(), k); - } - - template - inline typename K::FT - squared_distance_indexed(const typename K::Point_2 &pt, - const typename K::Segment_2 &seg, - int ind, - const K& k) - { - if (ind == 0) - return internal::squared_distance(pt, seg.source(), k); - if (ind == 1) - return internal::squared_distance(pt, seg.target(), k); - return internal::squared_distance(pt, seg.supporting_line(), k); - } - -} // namespace internal - -template -inline typename K::FT -squared_distance(const Point_2 & pt1, const Point_2 & pt2) -{ - return internal::squared_distance(pt1, pt2, K()); -} - - -template -inline typename K::FT -squared_distance(const Point_2 &pt, const Line_2 &line) -{ - return internal::squared_distance(pt, line, K()); -} - - -template -inline typename K::FT -squared_distance(const Line_2 & line, const Point_2 & pt) -{ - return squared_distance(pt, line); -} - - -template -inline typename K::FT -squared_distance(const Point_2 &pt, const Ray_2 &ray) -{ - return internal::squared_distance(pt, ray, K()); -} - -template -inline typename K::FT -squared_distance(const Ray_2 & ray, const Point_2 & pt) -{ - return squared_distance(pt, ray); -} - - -template -inline typename K::FT -squared_distance(const Point_2 &pt, const Segment_2 &seg) -{ - return internal::squared_distance(pt, seg, K()); -} - - -template -inline typename K::FT -squared_distance(const Segment_2 & seg, const Point_2 & pt) -{ - return internal::squared_distance(pt, seg, K()); -} - - -template -inline typename K::FT -squared_distance(const Segment_2 &seg1, const Segment_2 &seg2) -{ - typedef typename K::Kernel_tag Tag; - return internal::squared_distance(seg1, seg2, K(), Tag()); -} - -template -inline typename K::FT -squared_distance(const Segment_2 &seg, const Ray_2 &ray) -{ - return internal::squared_distance(seg, ray, K()); -} - -template -inline typename K::FT -squared_distance(const Ray_2 & ray, const Segment_2 & seg) -{ - return internal::squared_distance(seg, ray, K()); -} - -template -inline typename K::FT -squared_distance(const Segment_2 &seg, const Line_2 &line) -{ - return internal::squared_distance(seg, line, K()); -} - -template -inline typename K::FT -squared_distance(const Line_2 & line, const Segment_2 & seg) -{ - return internal::squared_distance(seg, line, K()); -} - -template -inline typename K::FT -squared_distance(const Ray_2 &ray1, const Ray_2 &ray2) -{ - return internal::squared_distance(ray1, ray2, K()); -} - -template -inline typename K::FT -squared_distance(const Line_2 &line, const Ray_2 &ray) -{ - return internal::squared_distance(line, ray, K()); -} - -template -inline typename K::FT -squared_distance(const Ray_2 & ray, const Line_2 & line) -{ - return internal::squared_distance(line, ray, K()); -} - -template -inline typename K::FT -squared_distance(const Line_2 &line1, const Line_2 &line2) -{ - return internal::squared_distance(line1, line2, K()); -} - -} //namespace CGAL - -#endif diff --git a/Distance_2/include/CGAL/squared_distance_2_2.h b/Distance_2/include/CGAL/squared_distance_2_2.h deleted file mode 100644 index f36f9ebc34c..00000000000 --- a/Distance_2/include/CGAL/squared_distance_2_2.h +++ /dev/null @@ -1,566 +0,0 @@ -// Copyright (c) 1998-2004 -// Utrecht University (The Netherlands), -// ETH Zurich (Switzerland), -// INRIA Sophia-Antipolis (France), -// Max-Planck-Institute Saarbruecken (Germany), -// and Tel-Aviv University (Israel). All rights reserved. -// -// This file is part of CGAL (www.cgal.org) -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial -// -// -// Author(s) : Geert-Jan Giezeman - - -#ifndef CGAL_SQUARED_DISTANCE_2_2_H -#define CGAL_SQUARED_DISTANCE_2_2_H - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace CGAL { - -namespace internal { - - template - void - distance_index(int &ind1, - int &ind2, - const typename K::Point_2 &pt, - const typename K::Triangle_2 &triangle, - const K& k ) - { - typename K::Left_turn_2 leftturn = k.left_turn_2_object(); - typedef typename K::Point_2 Point_2; - const Point_2 &vt0 = triangle.vertex(0); - const Point_2 &vt1 = triangle.vertex(1); - const Point_2 &vt2 = triangle.vertex(2); - if (leftturn(vt0, vt1, vt2)) { - if (leftturn(pt, vt1, vt0)) { - if (!is_acute_angle(vt0, vt1, pt, k)) { - if (leftturn(pt, vt2, vt1)) { - if (!is_acute_angle(vt1, vt2, pt, k)) { - ind1 = 2; ind2 = -1; - return; - } - if (!is_acute_angle(vt2, vt1, pt, k)) { - ind1 = 1; ind2 = -1; - return; - } - ind1 = 1; ind2 = 2; - return; - } - ind1 = 1; ind2 = -1; - return; - } - if (!is_acute_angle(vt1, vt0, pt, k)) { - if (leftturn(pt, vt0, vt2)) { - if (!is_acute_angle(vt0, vt2, pt, k)) { - ind1 = 2; ind2 = -1; - return; - } - if (!is_acute_angle(vt2, vt0, pt, k)) { - ind1 = 0; ind2 = -1; - return; - } - ind1 = 2; ind2 = 0; - return; - } - ind1 = 0; ind2 = -1; - return; - } - ind1 = 0; ind2 = 1; - return; - } else { - if (leftturn(pt, vt2, vt1)) { - if (!is_acute_angle(vt1, vt2, pt, k)) { - if (leftturn(pt, vt0, vt2)) { - if (!is_acute_angle(vt0, vt2, pt, k)) { - ind1 = 2; ind2 = -1; - return; - } - if (!is_acute_angle(vt2, vt0, pt, k)) { - ind1 = 0; ind2 = -1; - return; - } - ind1 = 2; ind2 = 0; - return; - } - ind1 = 0; ind2 = -1; - return; - } - if (!is_acute_angle(vt2, vt1, pt, k)) { - ind1 = 1; ind2 = -1; - return; - } - ind1 = 1; ind2 = 2; - return; - } else { - if (leftturn(pt, vt0, vt2)) { - if (!is_acute_angle(vt2, vt0, pt, k)) { - ind1 = 0; ind2 = -1; - return; - } - if (!is_acute_angle(vt0, vt2, pt, k)) { - ind1 = 2; ind2 = -1; - return; - } - ind1 = 2; ind2 = 0; - return; - } else { - ind1 = -1; ind2 = -1; // point inside or on boundary. - return; - } - } - } - } else { - if (leftturn(pt, vt2, vt0)) { - if (!is_acute_angle(vt0, vt2, pt, k)) { - if (leftturn(pt, vt1, vt2)) { - if (!is_acute_angle(vt2, vt1, pt, k)) { - ind1 = 1; ind2 = -1; - return; - } - if (!is_acute_angle(vt1, vt2, pt, k)) { - ind1 = 2; ind2 = -1; - return; - } - ind1 = 2; ind2 = 1; - return; - } - ind1 = 2; ind2 = -1; - return; - } - if (!is_acute_angle(vt2, vt0, pt, k)) { - if (leftturn(pt, vt0, vt1)) { - if (!is_acute_angle(vt0, vt1, pt, k)) { - ind1 = 1; ind2 = -1; - return; - } - if (!is_acute_angle(vt1, vt0, pt, k)) { - ind1 = 0; ind2 = -1; - return; - } - ind1 = 1; ind2 = 0; - return; - } - ind1 = 0; ind2 = -1; - return; - } - ind1 = 0; ind2 = 2; - return; - } else { - if (leftturn(pt, vt1, vt2)) { - if (!is_acute_angle(vt2, vt1, pt, k)) { - if (leftturn(pt, vt0, vt1)) { - if (!is_acute_angle(vt0, vt1, pt, k)) { - ind1 = 1; ind2 = -1; - return; - } - if (!is_acute_angle(vt1, vt0, pt, k)) { - ind1 = 0; ind2 = -1; - return; - } - ind1 = 1; ind2 = 0; - return; - } - ind1 = 0; ind2 = -1; - return; - } - if (!is_acute_angle(vt1, vt2, pt, k)) { - ind1 = 2; ind2 = -1; - return; - } - ind1 = 2; ind2 = 1; - return; - } else { - if (leftturn(pt, vt0, vt1)) { - if (!is_acute_angle(vt1, vt0, pt, k)) { - ind1 = 0; ind2 = -1; - return; - } - if (!is_acute_angle(vt0, vt1, pt, k)) { - ind1 = 1; ind2 = -1; - return; - } - ind1 = 1; ind2 = 0; - return; - } else { - ind1 = -1; ind2 = -1; // point inside or on boundary. - return; - } - } - } - } - } - - - - - template - typename K::FT - squared_distance_indexed(const typename K::Point_2 &pt, - const typename K::Triangle_2 &triangle, - int ind1, int ind2, - const K& k) - { - typedef typename K::FT FT; - typedef typename K::Line_2 Line_2; - if (ind1 == -1) - return FT(0); - if (ind2 == -1) - return internal::squared_distance(pt, triangle.vertex(ind1), k); - return internal::squared_distance(pt, - Line_2(triangle.vertex(ind1), triangle.vertex(ind2)), - k); - } - - - - template - typename K::FT - squared_distance(const typename K::Point_2 &pt, - const typename K::Triangle_2 &triangle, - const K& k) - { - int ind1,ind2; - distance_index(ind1, ind2, pt, triangle, k); - return squared_distance_indexed(pt, triangle, ind1, ind2, k); - } - - - template - inline typename K::FT - squared_distance(const typename K::Triangle_2 & triangle, - const typename K::Point_2 & pt, - const K& k) - { - return internal::squared_distance(pt, triangle, k); - } - - - template - typename K::FT - squared_distance(const typename K::Line_2 &line, - const typename K::Triangle_2 &triangle, - const K& k) - { - typedef typename K::FT FT; - Oriented_side side0; - side0 = line.oriented_side(triangle.vertex(0)); - if (line.oriented_side(triangle.vertex(1)) != side0) - return FT(0); - if (line.oriented_side(triangle.vertex(2)) != side0) - return FT(0); - FT mindist, dist; - int i; - mindist = internal::squared_distance(triangle.vertex(0),line,k); - for (i=1; i<3; i++) { - dist = internal::squared_distance(triangle.vertex(i),line,k); - if (dist < mindist) - mindist = dist; - } - return mindist; - } - - - template - inline typename K::FT - squared_distance(const typename K::Triangle_2 & triangle, - const typename K::Line_2 & line, - const K& k) - { - return internal::squared_distance(line, triangle, k); - } - - - template - typename K::FT - squared_distance(const typename K::Ray_2 &ray, - const typename K::Triangle_2 &triangle, - const K& k) - { - typedef typename K::FT FT; - typedef typename K::Point_2 Point_2; - typedef typename K::Line_2 Line_2; - int i, ind_tr1, ind_tr2, ind_ray = 0, ind1; - FT mindist, dist; - distance_index(ind_tr1, ind_tr2, ray.source(), triangle, k); - mindist = - squared_distance_indexed(ray.source(), triangle, ind_tr1, ind_tr2, k); - for (i=0; i<3; i++) { - const Point_2& pt = triangle.vertex(i); - distance_index(ind1, pt, ray, k); - dist = squared_distance_indexed(pt, ray, ind1, k); - if (dist < mindist) { - ind_ray = ind1; - ind_tr1 = i; ind_tr2 = -1; - mindist = dist; - } - } - // now check if all vertices are on the right side of the separating line. - // In case of vertex-vertex smallest distance this is the case. - if (ind_tr2 == -1 && ind_ray != -1) - return mindist; - if (ind_tr2 != -1) { - // Check if all the segment vertices lie at the same side of - // the triangle segment. - const Point_2 &vt1 = triangle.vertex(ind_tr1); - const Point_2 &vt2 = triangle.vertex(ind_tr2); - if (clockwise(ray.direction().vector(), vt2-vt1, k)) { - mindist = FT(0); - } - } else { - // Check if all the triangle vertices lie - // at the same side of the segment. - const Line_2 &sl = ray.supporting_line(); - Oriented_side or_s = sl.oriented_side(triangle.vertex(0)); - for (i=1; i<3; i++) { - if (sl.oriented_side(triangle.vertex(i)) != or_s) { - mindist = FT(0); - break; - } - } - } - return mindist; - } - - - template - inline typename K::FT - squared_distance(const typename K::Triangle_2 & triangle, - const typename K::Ray_2 & ray, - const K& k) - { - return internal::squared_distance(ray, triangle, k); - } - - - template - typename K::FT - squared_distance(const typename K::Segment_2 &seg, - const typename K::Triangle_2 &triangle, - const K& k) - { - typedef typename K::FT FT; - typedef typename K::Point_2 Point_2; - typename K::Orientation_2 orientation; - int i, ind_tr1 = 0, ind_tr2 = -1, ind_seg = 0, ind1, ind2; - FT mindist, dist; - mindist = internal::squared_distance(seg.source(), triangle.vertex(0), k); - for (i=0; i<2; i++) { - const Point_2 &pt = seg.vertex(i); - distance_index(ind1, ind2, pt, triangle, k); - dist = internal::squared_distance_indexed(pt, triangle, ind1, ind2, k); - if (dist < mindist) { - ind_seg = i; - ind_tr1 = ind1; ind_tr2 = ind2; - mindist = dist; - } - } - for (i=0; i<3; i++) { - const Point_2& pt = triangle.vertex(i); - distance_index(ind1, pt, seg, k); - dist = internal::squared_distance_indexed(pt, seg, ind1, k); - if (dist < mindist) { - ind_seg = ind1; - ind_tr1 = i; ind_tr2 = -1; - mindist = dist; - } - } - // now check if all vertices are on the right side of the separating line. - // In case of vertex-vertex smallest distance this is the case. - if (ind_tr2 == -1 && ind_seg != -1) - return mindist; - - if (ind_tr2 != -1) { - // Check if all the segment vertices lie at the same side of - // the triangle segment. - const Point_2 &vt1 = triangle.vertex(ind_tr1); - const Point_2 &vt2 = triangle.vertex(ind_tr2); - Orientation or_s = orientation(vt1, vt2, seg.source()); - if (orientation(vt1, vt2, seg.target()) != or_s) { - mindist = FT(0); - } - } else { - // Check if all the triangle vertices lie - // at the same side of the segment. - const Point_2 &vt1 = seg.source(); - const Point_2 &vt2 = seg.target(); - Orientation or_s = orientation(vt1, vt2, triangle.vertex(0)); - for (i=1; i<3; i++) { - if (orientation(vt1, vt2, triangle.vertex(i)) != or_s) { - mindist = FT(0); - break; - } - } - } - return mindist; - } - - - template - inline typename K::FT - squared_distance(const typename K::Triangle_2 & triangle, - const typename K::Segment_2 & seg, - const K& k) - { - return internal::squared_distance(seg, triangle, k); - } - - - - template - typename K::FT - squared_distance(const typename K::Triangle_2 &triangle1, - const typename K::Triangle_2 &triangle2, - const K& k) - { - typedef typename K::FT FT; - typedef typename K::Point_2 Point_2; - typename K::Orientation_2 orientation; - int i, ind1_1 = 0,ind1_2 = -1, ind2_1 = 0, ind2_2 = -1, ind1, ind2; - FT mindist, dist; - mindist = - internal::squared_distance(triangle1.vertex(0), triangle2.vertex(0), k); - for (i=0; i<3; i++) { - const Point_2& pt = triangle1.vertex(i); - distance_index(ind1, ind2, pt, triangle2, k); - dist = squared_distance_indexed(pt, triangle2, ind1, ind2, k); - if (dist < mindist) { - ind1_1 = i; ind1_2 = -1; - ind2_1 = ind1; ind2_2 = ind2; - mindist = dist; - } - } - for (i=0; i<3; i++) { - const Point_2& pt = triangle2.vertex(i); - distance_index(ind1, ind2, pt, triangle1, k); - dist = squared_distance_indexed(pt, triangle1, ind1, ind2, k); - if (dist < mindist) { - ind1_1 = ind1; ind1_2 = ind2; - ind2_1 = i; ind2_2 = -1; - mindist = dist; - } - } - // now check if all vertices are on the right side of the - // separating line. - if (ind1_2 == -1 && ind2_2 == -1) - return mindist; - // In case of point-segment closest distance, there is still the - // possibility of overlapping triangles. Check if all the - // vertices lie at the same side of the segment. - if (ind1_2 != -1) { - const Point_2 &vt1 = triangle1.vertex(ind1_1); - const Point_2 &vt2 = triangle1.vertex(ind1_2); - Orientation or_s = orientation(vt1, vt2, triangle2.vertex(0)); - for (i=1; i<3; i++) { - if (orientation(vt1, vt2, triangle2.vertex(i)) != or_s) { - mindist = FT(0); - break; - } - } - } else { - const Point_2 &vt1 = triangle2.vertex(ind2_1); - const Point_2 &vt2 = triangle2.vertex(ind2_2); - Orientation or_s = orientation(vt1, vt2, triangle1.vertex(0)); - for (i=1; i<3; i++) { - if (orientation(vt1, vt2, triangle1.vertex(i)) != or_s) { - mindist = FT(0); - break; - } - } - } - return mindist; - } - -} // namespace internal - -template -inline typename K::FT -squared_distance(const Point_2 &pt, - const Triangle_2 &triangle) -{ - return internal::squared_distance(pt, triangle, K()); -} - -template -inline typename K::FT -squared_distance(const Triangle_2 &triangle, - const Point_2 &pt) -{ - return internal::squared_distance(pt, triangle, K()); -} - -template -inline typename K::FT -squared_distance(const Line_2 &line, - const Triangle_2 &triangle) -{ - return internal::squared_distance(line, triangle, K()); -} - -template -inline typename K::FT -squared_distance(const Triangle_2 &triangle, - const Line_2 &line) -{ - return internal::squared_distance(line, triangle, K()); -} - -template -inline typename K::FT -squared_distance(const Ray_2 &ray, - const Triangle_2 &triangle) -{ - return internal::squared_distance(ray, triangle, K()); -} - -template -inline typename K::FT -squared_distance(const Triangle_2 &triangle, - const Ray_2 &ray) -{ - return internal::squared_distance(ray, triangle, K()); -} - -template -inline typename K::FT -squared_distance(const Segment_2 &seg, - const Triangle_2 &triangle) -{ - return internal::squared_distance(seg, triangle, K()); -} - -template -inline typename K::FT -squared_distance(const Triangle_2 &triangle, - const Segment_2 &seg) -{ - return internal::squared_distance(seg, triangle, K()); -} - -template -inline typename K::FT -squared_distance(const Triangle_2 &triangle1, - const Triangle_2 &triangle2) -{ - return internal::squared_distance(triangle1, triangle2, K()); -} - -} //namespace CGAL - -#endif diff --git a/Distance_2/test/Distance_2/test_distance_2.cpp b/Distance_2/test/Distance_2/test_distance_2.cpp index 0268e606295..2736f8fe551 100644 --- a/Distance_2/test/Distance_2/test_distance_2.cpp +++ b/Distance_2/test/Distance_2/test_distance_2.cpp @@ -1,12 +1,12 @@ -// 2D distance tests. - #ifdef NDEBUG #undef NDEBUG //this testsuite requires NDEBUG to be not defined #endif - #include #include +#include +#include +#include #include #include @@ -167,7 +167,7 @@ struct Test { check_squared_distance (R(p( 4, 0), p(-3, -1)), R(p( 1, 1), p( 2, 11)), 2); } - void R_S() + void S_R() { std::cout << "Ray - Segment\n"; check_squared_distance (R(p(2, 0), p( 0, 2)), S(p( 1, 1), p( 4, 0)), 0); @@ -216,7 +216,7 @@ struct Test { check_squared_distance (p( 1, 1), L(p( 4, 0), p( -3, -1)), 2); } - void L_S() + void S_L() { std::cout << "Line - Segment\n"; check_squared_distance (L(p( 0, 0), p( 1, 0)), S(p( 2, 2), p( 3, 3)), 4); @@ -268,29 +268,38 @@ struct Test { void run() { - std::cout << "2D Distance tests\n"; + std::cout << "-- Kernel: " << typeid(K).name() << std::endl; + P_P(); P_S(); - S_S(); P_R(); - R_R(); - R_S(); - R_L(); P_L(); - L_S(); - L_L(); P_T(); - L_T(); - R_T(); + + S_S(); S_T(); + S_R(); + S_L(); + + R_R(); + R_L(); + R_T(); + + L_L(); + L_T(); + T_T(); } - }; int main() { - Test< CGAL::Simple_cartesian >().run(); - Test< CGAL::Simple_homogeneous >().run(); - // TODO : test more kernels. + std::cout << "2D Distance tests\n"; + + Test >().run(); + Test >().run(); + + Test >().run(); + Test().run(); + Test().run(); } 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 new file mode 100644 index 00000000000..03495be04fa --- /dev/null +++ b/Distance_3/include/CGAL/Distance_3/Line_3_Line_3.h @@ -0,0 +1,61 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman, Andreas Fabri + +#ifndef CGAL_DISTANCE_3_LINE_3_LINE_3_H +#define CGAL_DISTANCE_3_LINE_3_LINE_3_H + +#include + +#include + +namespace CGAL { +namespace internal { + +template +typename K::FT +squared_distance(const typename K::Line_3& line1, + const typename K::Line_3& line2, + const K& k) +{ + typedef typename K::Vector_3 Vector_3; + + typename K::Construct_vector_3 vector = k.construct_vector_3_object(); + + const Vector_3 dir1 = line1.direction().vector(); + const Vector_3 dir2 = line2.direction().vector(); + const Vector_3 normal = wcross(dir1, dir2, k); + const Vector_3 diff = vector(line1.point(), line2.point()); + + if (is_null(normal, k)) + return squared_distance_to_line(dir2, diff, k); + + 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) +{ + return K().compute_squared_distance_3_object()(line1, line2); +} + +} // 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 new file mode 100644 index 00000000000..6bb4d125c59 --- /dev/null +++ b/Distance_3/include/CGAL/Distance_3/Line_3_Plane_3.h @@ -0,0 +1,86 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman, Andreas Fabri + +#ifndef CGAL_DISTANCE_3_LINE_3_PLANE_3_H +#define CGAL_DISTANCE_3_LINE_3_PLANE_3_H + +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +bool +contains_vector(const typename K::Plane_3& pl, + const typename K::Vector_3& vec, + const K&) +{ + typedef typename K::RT RT; + + return pl.a()*vec.hx() + pl.b()*vec.hy() + pl.c() * vec.hz() == RT(0); +} + +template +typename K::FT +squared_distance(const typename K::Line_3& l, + const typename K::Plane_3& pl, + const K& k) +{ + typedef typename K::FT FT; + + typename K::Compute_squared_distance_3 sq_dist = k.compute_squared_distance_3_object(); + + if(contains_vector(pl, l.direction().vector(), k)) + return sq_dist(pl, l.point()); + + return FT(0); +} + +template +inline typename K::FT +squared_distance(const typename K::Plane_3& pl, + const typename K::Line_3& l, + const K& k) +{ + return squared_distance(l, pl, k); +} + +} // 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 new file mode 100644 index 00000000000..d18fb366b7f --- /dev/null +++ b/Distance_3/include/CGAL/Distance_3/Plane_3_Plane_3.h @@ -0,0 +1,55 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman, Andreas Fabri + +#ifndef CGAL_DISTANCE_3_PLANE_3_PLANE_3_H +#define CGAL_DISTANCE_3_PLANE_3_PLANE_3_H + +#include + +#include + +namespace CGAL { +namespace internal { + +template +inline typename K::FT +squared_distance(const typename K::Plane_3& plane1, + const typename K::Plane_3& plane2, + const K& k) +{ + typename K::Construct_orthogonal_vector_3 ortho_vec = k.construct_orthogonal_vector_3_object(); + typename K::Compute_squared_distance_3 sq_dist = k.compute_squared_distance_3_object(); + + if(!is_null(wcross(ortho_vec(plane1), ortho_vec(plane2), k), k)) + return typename K::FT(0); + else + return sq_dist(plane1.point(), plane2); +} + +} // namespace internal + +template +inline +typename K::FT +squared_distance(const Plane_3& plane1, + const Plane_3& plane2) +{ + return K().compute_squared_distance_3_object()(plane1, plane2); +} + +} // 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 new file mode 100644 index 00000000000..0d1527c48a7 --- /dev/null +++ b/Distance_3/include/CGAL/Distance_3/Point_3_Line_3.h @@ -0,0 +1,91 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman, Andreas Fabri, Mael Rouxel-Labbé + +#ifndef CGAL_DISTANCE_3_POINT_3_LINE_3_H +#define CGAL_DISTANCE_3_POINT_3_LINE_3_H + +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +void +squared_distance_RT(const typename K::Point_3 &pt, + const typename K::Line_3 &line, + typename K::RT& num, + typename K::RT& den, + const K& k) +{ + typedef typename K::Vector_3 Vector_3; + + typename K::Construct_vector_3 vector = k.construct_vector_3_object(); + + const Vector_3& dir = line.direction().vector(); + const Vector_3 diff = vector(line.point(), pt); + + return internal::squared_distance_to_line_RT(dir, diff, num, den, k); +} + +template +typename K::FT +squared_distance(const typename K::Point_3& pt, + const typename K::Line_3& line, + const K& k) +{ + typedef typename K::RT RT; + typedef typename K::FT FT; + RT num, den; + squared_distance_RT(pt, line, num, den, k); + return Rational_traits().make_rational(num, den); +} + +template +inline +typename K::FT +squared_distance(const typename K::Line_3& line, + const typename K::Point_3& pt, + const K& k) +{ + return squared_distance(pt, line, k); +} + +} // 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 new file mode 100644 index 00000000000..7544a72d963 --- /dev/null +++ b/Distance_3/include/CGAL/Distance_3/Point_3_Plane_3.h @@ -0,0 +1,73 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman, Andreas Fabri + +#ifndef CGAL_DISTANCE_3_POINT_3_PLANE_3_H +#define CGAL_DISTANCE_3_POINT_3_PLANE_3_H + +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +inline typename K::FT +squared_distance(const typename K::Point_3& pt, + const typename K::Plane_3& plane, + const K& k) +{ + typedef typename K::Vector_3 Vector_3; + + typename K::Construct_vector_3 vector = k.construct_vector_3_object(); + + Vector_3 diff = vector(plane.point(), pt); + return squared_distance_to_plane(plane.orthogonal_vector(), diff, k); +} + +template +inline typename K::FT +squared_distance(const typename K::Plane_3& plane, + const typename K::Point_3& pt, + const K& k) +{ + return squared_distance(pt, plane, k); +} + +} // namespace internal + +template +inline +typename K::FT +squared_distance(const Point_3& pt, + const Plane_3& plane) +{ + return K().compute_squared_distance_3_object()(pt, plane); +} + +template +inline +typename K::FT +squared_distance(const Plane_3& plane, + const Point_3& pt) +{ + return K().compute_squared_distance_3_object()(plane, pt); +} + +} // namespace CGAL + +#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 new file mode 100644 index 00000000000..6b307e571c7 --- /dev/null +++ b/Distance_3/include/CGAL/Distance_3/Point_3_Point_3.h @@ -0,0 +1,48 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman, Andreas Fabri + +#ifndef CGAL_DISTANCE_3_POINT_3_POINT_3_H +#define CGAL_DISTANCE_3_POINT_3_POINT_3_H + +#include + +namespace CGAL { +namespace internal { + +template +inline +typename K::FT +squared_distance(const typename K::Point_3& pt1, + const typename K::Point_3& pt2, + const K& k) +{ + 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) +{ + return internal::squared_distance(pt1, pt2, K()); +} + +} // 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 new file mode 100644 index 00000000000..7eff899b0eb --- /dev/null +++ b/Distance_3/include/CGAL/Distance_3/Point_3_Ray_3.h @@ -0,0 +1,112 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman, Andreas Fabri, Mael Rouxel-Labbé + +#ifndef CGAL_DISTANCE_3_POINT_3_RAY_3_H +#define CGAL_DISTANCE_3_POINT_3_RAY_3_H + +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +void +squared_distance_RT(const typename K::Point_3 &pt, + const typename K::Ray_3 &ray, + typename K::RT& num, + typename K::RT& den, + const K& k) +{ + typedef typename K::Vector_3 Vector_3; + typedef typename K::RT RT; + + typename K::Construct_vector_3 vector = k.construct_vector_3_object(); + + const Vector_3 dir = ray.direction().vector(); + const Vector_3 diff = vector(ray.source(), pt); + + if(!is_acute_angle(dir, diff, k)) + { + num = wdot(diff, diff, k); + den = wmult((K*)0, RT(1), diff.hw(), diff.hw()); + return; + } + + squared_distance_to_line_RT(dir, diff, num, den, k); +} + +template +typename K::FT +squared_distance(const typename K::Point_3& pt, + const typename K::Ray_3& ray, + const K& k) +{ + // This duplicates code from the _RT functions, but it is a slowdown to do something like: + // + // RT num, den; + // squared_distance_RT(pt, ray, num, den, k); + // return Rational_traits().make_rational(num, den); + // + // See https://github.com/CGAL/cgal/pull/5680 + + typedef typename K::Vector_3 Vector_3; + + typename K::Construct_vector_3 vector = k.construct_vector_3_object(); + + const Vector_3 dir = ray.direction().vector(); + const Vector_3 diff = vector(ray.source(), pt); + + if(!is_acute_angle(dir, diff, k)) + return diff*diff; + + return squared_distance_to_line(dir, diff, k); +} + +template +typename K::FT +squared_distance(const typename K::Ray_3& ray, + const typename K::Point_3& pt, + const K& k) +{ + return squared_distance(pt, ray, k); +} + +} // 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 new file mode 100644 index 00000000000..554c0a58d2d --- /dev/null +++ b/Distance_3/include/CGAL/Distance_3/Point_3_Segment_3.h @@ -0,0 +1,133 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman, Andreas Fabri + +#ifndef CGAL_DISTANCE_3_POINT_3_SEGMENT_3_H +#define CGAL_DISTANCE_3_POINT_3_SEGMENT_3_H + +#include +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +void +squared_distance_RT(const typename K::Point_3& pt, + const typename K::Segment_3& seg, + typename K::RT& num, + typename K::RT& den, + const K& k) +{ + typedef typename K::RT RT; + typedef typename K::Vector_3 Vector_3; + + typename K::Construct_vector_3 vector = k.construct_vector_3_object(); + + // assert that the segment is valid (non zero length). + const Vector_3 diff_s = vector(seg.source(), pt); + const Vector_3 segvec = vector(seg.source(), seg.target()); + + const RT d = wdot(diff_s, segvec, k); + if(d <= RT(0)) + { + // this is squared_distance(pt, seg.source()) + num = wdot(diff_s, diff_s, k); + den = wmult((K*)0, RT(1), diff_s.hw(), diff_s.hw()); + return; + } + + const RT e = wdot(segvec, segvec, k); + if(wmult((K*)0, d, segvec.hw()) > wmult((K*)0, e, diff_s.hw())) + { + // this is squared_distance(pt, seg.target()) + const Vector_3 diff_t = vector(seg.target(), pt); + num = wdot(diff_t, diff_t, k); + den = wmult((K*)0, RT(1), diff_t.hw(), diff_t.hw()); + return; + } + + // This is an expanded call to squared_distance_to_line_RT() to avoid recomputing 'e' + const Vector_3 wcr = wcross(segvec, diff_s, k); + num = wdot(wcr, wcr, k); + den = wmult((K*)0, e, diff_s.hw(), diff_s.hw()); +} + +template +typename K::FT +squared_distance(const typename K::Point_3& pt, + const typename K::Segment_3& seg, + const K& k) +{ + typedef typename K::RT RT; + typedef typename K::FT FT; + typedef typename K::Vector_3 Vector_3; + + typename K::Construct_vector_3 vector = k.construct_vector_3_object(); + + // assert that the segment is valid (non zero length). + const Vector_3 diff = vector(seg.source(), pt); + const Vector_3 segvec = vector(seg.source(), seg.target()); + + const RT d = wdot(diff, segvec, k); + if(d <= RT(0)) + return (FT(diff*diff)); + + 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); + + // This is an expanded call to squared_distance_to_line() to avoid recomputing 'e' + const Vector_3 wcr = wcross(segvec, diff, k); + + return FT(wcr*wcr) / wmult((K*)0, e, diff.hw(), diff.hw()); +} + +template +inline +typename K::FT +squared_distance(const typename K::Segment_3& seg, + const typename K::Point_3& pt, + const K& k) +{ + return squared_distance(pt, seg, k); +} + +} // 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 new file mode 100644 index 00000000000..04d148818a3 --- /dev/null +++ b/Distance_3/include/CGAL/Distance_3/Point_3_Tetrahedron_3.h @@ -0,0 +1,148 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Andreas Fabri + +#ifndef CGAL_DISTANCE_3_POINT_3_TETRAHEDRON_3_H +#define CGAL_DISTANCE_3_POINT_3_TETRAHEDRON_3_H + +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +inline +typename K::FT +squared_distance(const typename K::Point_3& pt, + const typename K::Tetrahedron_3& tet, + const K& k) +{ + 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(); + + bool on_bounded_side = true; + 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); + + bool dmin_initialized = false; + typename K::FT dmin; + bool inside = false; + if(orientation(t0,t1,t2, pt) == NEGATIVE) + { + on_bounded_side = false; + dmin = squared_distance_to_triangle(pt, t0, t1, t2, k, inside); + dmin_initialized = true; + if(inside) + return dmin; + } + + if(orientation(t0,t3,t1, pt) == NEGATIVE) + { + on_bounded_side = false; + const typename K::FT d = squared_distance_to_triangle(pt, t0, t3, t1, k, inside); + if(inside) + return d; + + if(!dmin_initialized) + { + dmin = d; + dmin_initialized = true; + } + else + { + dmin = (std::min)(d, dmin); + } + } + + if(orientation(t1,t3,t2, pt) == NEGATIVE) + { + on_bounded_side = false; + const typename K::FT d = squared_distance_to_triangle(pt, t1, t3, t2, k, inside); + if(inside) + return d; + + if(!dmin_initialized) + { + dmin = d; + dmin_initialized = true; + } + else + { + dmin = (std::min)(d, dmin); + } + } + + if(orientation(t2,t3,t0, pt) == NEGATIVE) + { + on_bounded_side = false; + const typename K::FT d = squared_distance_to_triangle(pt, t2, t3, t0, k, inside); + if(inside) + return d; + + if(!dmin_initialized) + { + dmin = d; + dmin_initialized = true; + } + else + { + dmin = (std::min)(d, dmin); + } + } + + if(on_bounded_side) + return typename K::FT(0); + + return dmin; +} + +template +inline +typename K::FT +squared_distance(const typename K::Tetrahedron_3& tet, + const typename K::Point_3& pt, + const K& k) +{ + return squared_distance(pt, tet, k); +} + +} // 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 new file mode 100644 index 00000000000..a6f2e7c8e94 --- /dev/null +++ b/Distance_3/include/CGAL/Distance_3/Point_3_Triangle_3.h @@ -0,0 +1,242 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman, Andreas Fabri + +#ifndef CGAL_DISTANCE_3_POINT_3_TRIANGLE_3_H +#define CGAL_DISTANCE_3_POINT_3_TRIANGLE_3_H + +#include +#include + +#include +#include + +namespace CGAL { +namespace internal { + +// returns true iff pt is on the negative side of the plane defined by (ep0, ep1) and normal +template +inline bool +on_left_of_triangle_edge(const typename K::Point_3& pt, + const typename K::Vector_3& normal, + const typename K::Point_3& ep0, + const typename K::Point_3& ep1, + const K& k) +{ + typedef typename K::RT RT; + typedef typename K::Vector_3 Vector_3; + + typename K::Construct_vector_3 vector = k.construct_vector_3_object(); + + const Vector_3 edge = vector(ep0, ep1); + const Vector_3 diff = vector(ep0, pt); + + return (wdot(wcross(edge, normal, k), diff, k) <= RT(0)); +} + +template +inline void +squared_distance_to_triangle_RT(const typename K::Point_3& pt, + const typename K::Point_3& t0, + const typename K::Point_3& t1, + const typename K::Point_3& t2, + bool& inside, + typename K::RT& num, + typename K::RT& den, + const K& k) +{ + typedef typename K::Vector_3 Vector_3; + + typename K::Construct_vector_3 vector = k.construct_vector_3_object(); + typename K::Construct_segment_3 segment = k.construct_segment_3_object(); + + 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. + squared_distance_RT(pt, segment(t2, t0), num, den, k); + + typename K::RT num2, den2; + squared_distance_RT(pt, segment(t1, t2), num2, den2, k); + if(compare_quotients(num2,den2, num,den) == SMALLER) + { + num = num2; + den = den2; + } + + // Should not be needed since at most 2 edges cover the full triangle in the degenerate case, + // but leaving it for robustness + squared_distance_RT(pt, segment(t0, t1), num2, den2, k); + if(compare_quotients(num2,den2, num,den) == SMALLER) + { + num = num2; + den = den2; + } + + return; + } + + const bool b01 = on_left_of_triangle_edge(pt, normal, t0, t1, k); + if(!b01) + { + squared_distance_RT(pt, segment(t0, t1), num, den, k); + return; + } + + const bool b12 = on_left_of_triangle_edge(pt, normal, t1, t2, k); + if(!b12) + { + squared_distance_RT(pt, segment(t1, t2), num, den, k); + return; + } + + const bool b20 = on_left_of_triangle_edge(pt, normal, t2, t0, k); + if(!b20) + { + squared_distance_RT(pt, segment(t2, t0), num, den, k); + return; + } + + // The projection of pt is inside the triangle + inside = true; + squared_distance_to_plane_RT(normal, vector(t0, pt), num, den, k); +} + +template +void +squared_distance_RT(const typename K::Point_3& pt, + const typename K::Triangle_3& t, + typename K::RT& num, + typename K::RT& den, + const K& k) +{ + typename K::Construct_vertex_3 vertex; + bool inside = false; + squared_distance_to_triangle_RT(pt, + vertex(t, 0), + vertex(t, 1), + vertex(t, 2), + inside, + num, + den, + k); +} + +template +inline typename K::FT +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, + bool& inside) +{ + 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::Compute_squared_distance_3 sq_dist = k.compute_squared_distance_3_object(); + + 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, but leaving 3 for the case of + // inexact constructions as it might improve the accuracy. + typename K::FT d1 = sq_dist(pt, segment(t2, t0)); + typename K::FT d2 = sq_dist(pt, segment(t1, t2)); + typename K::FT d3 = sq_dist(pt, segment(t0, t1)); + + return (std::min)((std::min)(d1, d2), d3); + } + + const bool b01 = on_left_of_triangle_edge(pt, normal, t0, t1, k); + if(!b01) + return sq_dist(pt, segment(t0, t1)); + + const bool b12 = on_left_of_triangle_edge(pt, normal, t1, t2, k); + if(!b12) + return sq_dist(pt, segment(t1, t2)); + + const bool b20 = on_left_of_triangle_edge(pt, normal, t2, t0, k); + if(!b20) + return sq_dist(pt, segment(t2, t0)); + + // The projection of pt is inside the triangle + inside = true; + return squared_distance_to_plane(normal, vector(t0, pt), k); +} + +template +inline typename K::FT +squared_distance(const typename K::Point_3& pt, + const typename K::Triangle_3& t, + const K& k) +{ + typename K::Construct_vertex_3 vertex = k.construct_vertex_3_object(); + + bool unused_inside = false; + return squared_distance_to_triangle(pt, + vertex(t, 0), + vertex(t, 1), + vertex(t, 2), + k, + unused_inside); +} + +template +inline typename K::FT +squared_distance(const typename K::Triangle_3& t, + const typename K::Point_3& pt, + const K& k) +{ + return squared_distance(pt, t, k); +} + +} // 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/Point_3_Weighted_point_3.h b/Distance_3/include/CGAL/Distance_3/Point_3_Weighted_point_3.h new file mode 100644 index 00000000000..f5db1c3c46f --- /dev/null +++ b/Distance_3/include/CGAL/Distance_3/Point_3_Weighted_point_3.h @@ -0,0 +1,47 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman, Andreas Fabri + +#ifndef CGAL_DISTANCE_3_POINT_3_WEIGHTED_POINT_3_H +#define CGAL_DISTANCE_3_POINT_3_WEIGHTED_POINT_3_H + +#include + +#include +#include + +namespace CGAL { + +template +inline +typename K::FT +squared_distance(const Weighted_point_3& wpt, + const Point_3& pt) +{ + return K().compute_squared_distance_3_object()(wpt.point(), pt); +} + +template +inline +typename K::FT +squared_distance(const Point_3& pt, + const Weighted_point_3& wpt) +{ + return K().compute_squared_distance_3_object()(pt, wpt.point()); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_3_POINT_3_WEIGHTED_POINT_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 new file mode 100644 index 00000000000..d4b51b59cbe --- /dev/null +++ b/Distance_3/include/CGAL/Distance_3/Ray_3_Line_3.h @@ -0,0 +1,102 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman, Andreas Fabri + +#ifndef CGAL_DISTANCE_3_RAY_3_LINE_3_H +#define CGAL_DISTANCE_3_RAY_3_LINE_3_H + +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +typename K::FT +squared_distance(const typename K::Ray_3& ray, + const typename K::Line_3& line, + const K& k) +{ + typedef typename K::Vector_3 Vector_3; + typedef typename K::Point_3 Point_3; + typedef typename K::RT RT; + + typename K::Construct_vector_3 vector = k.construct_vector_3_object(); + + const Point_3& rs = ray.source(); + + const Vector_3 linedir = line.direction().vector(); + const Vector_3 raydir = ray.direction().vector(); + const Vector_3 normal = wcross(raydir, linedir, k); + + const Vector_3 rs_min_lp = vector(line.point(), rs); + if(is_null(normal, k)) + return squared_distance_to_line(linedir, rs_min_lp, k); + + bool crossing; + const Vector_3 perpend2l = wcross(linedir, normal, k); + const RT sdm_sr_l = wdot(perpend2l, rs_min_lp, k); + if(sdm_sr_l < RT(0)) + { + crossing = (wdot(perpend2l, raydir, k) >= RT(0)); + } + else + { + if(wdot(perpend2l, raydir, k) <= RT(0)) + crossing = true; + else + crossing = (sdm_sr_l == RT(0)); + } + + if(crossing) + return squared_distance_to_plane(normal, rs_min_lp, k); + else + return squared_distance_to_line(linedir, rs_min_lp, k); +} + +template +typename K::FT +squared_distance(const typename K::Line_3& line, + const typename K::Ray_3& ray, + const K& k) +{ + return squared_distance(ray, line, k); +} + +} // 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 new file mode 100644 index 00000000000..bdc9a956146 --- /dev/null +++ b/Distance_3/include/CGAL/Distance_3/Ray_3_Plane_3.h @@ -0,0 +1,97 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman, Andreas Fabri + +#ifndef CGAL_DISTANCE_3_RAY_3_PLANE_3_H +#define CGAL_DISTANCE_3_RAY_3_PLANE_3_H + +#include +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +typename K::FT +squared_distance(const typename K::Ray_3 &ray, + const typename K::Plane_3 &plane, + const K& k) +{ + typedef typename K::RT RT; + typedef typename K::FT FT; + typedef typename K::Point_3 Point_3; + typedef typename K::Vector_3 Vector_3; + + typename K::Construct_vector_3 construct_vector = k.construct_vector_3_object(); + + const Point_3& start = ray.start(); + const Point_3& planepoint = plane.point(); + const Vector_3 start_min_pp = construct_vector(planepoint, start); + const Vector_3 end_min_pp = ray.direction().vector(); + const Vector_3 normal = plane.orthogonal_vector(); + const RT sdm_rs2pp = wdot(normal, start_min_pp, k); + const RT sdm_re2pp = wdot(normal, end_min_pp, k); + + switch (CGAL_NTS sign(sdm_rs2pp)) + { + case -1: + if(sdm_re2pp > RT(0)) + return FT(0); + return squared_distance_to_plane(normal, start_min_pp, k); + case 0: + default: + return FT(0); + case 1: + if(sdm_re2pp < RT(0)) + return FT(0); + return squared_distance_to_plane(normal, start_min_pp, k); + } +} + +template +inline typename K::FT +squared_distance(const typename K::Plane_3& plane, + const typename K::Ray_3& ray, + const K& k) +{ + return squared_distance(ray, plane, k); +} + +} // 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 new file mode 100644 index 00000000000..8ca1eca308c --- /dev/null +++ b/Distance_3/include/CGAL/Distance_3/Ray_3_Ray_3.h @@ -0,0 +1,143 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman, Andreas Fabri + +#ifndef CGAL_DISTANCE_3_RAY_3_RAY_3_H +#define CGAL_DISTANCE_3_RAY_3_RAY_3_H + +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +typename K::FT +ray_ray_squared_distance_parallel(const typename K::Vector_3& ray1dir, + const typename K::Vector_3& ray2dir, + const typename K::Vector_3& s1_min_s2, + const K& k) +{ + if(!is_acute_angle(ray2dir, s1_min_s2, k)) + if(!same_direction(ray1dir, ray2dir, k)) + return typename K::FT(s1_min_s2*s1_min_s2); + + return squared_distance_to_line(ray1dir, s1_min_s2, k); +} + +template +typename K::FT +squared_distance(const typename K::Ray_3& ray1, + const typename K::Ray_3& ray2, + const K& k) +{ + typedef typename K::RT RT; + typedef typename K::FT FT; + typedef typename K::Point_3 Point_3; + typedef typename K::Vector_3 Vector_3; + + typename K::Construct_vector_3 construct_vector = k.construct_vector_3_object(); + typename K::Compute_squared_distance_3 sq_dist = k.compute_squared_distance_3_object(); + + const Point_3& s1 = ray1.source(); + const Point_3& s2 = ray2.source(); + const Vector_3 dir1 = ray1.direction().vector(); + const Vector_3 dir2 = ray2.direction().vector(); + const Vector_3 normal = wcross(dir1, dir2, k); + const Vector_3 s1_min_s2 = construct_vector(s2, s1); + + if(is_null(normal, k)) + return ray_ray_squared_distance_parallel(dir1, dir2, s1_min_s2, k); + + bool crossing1, crossing2; + + const Vector_3 perpend1 = wcross(dir1, normal, k); + const Vector_3 perpend2 = wcross(dir2, normal, k); + + const RT sdm_s1_2 = wdot(perpend2, s1_min_s2, k); + if(sdm_s1_2 < RT(0)) + { + crossing1 = (wdot(perpend2, dir1, k) >= RT(0)); + } + else + { + if(RT(wdot(perpend2, dir1, k)) <= RT(0)) + crossing1 = true; + else + crossing1 = (sdm_s1_2 == RT(0)); + } + + const RT sdm_s2_1 = - wdot(perpend1, s1_min_s2, k); + if(sdm_s2_1 < RT(0)) + { + crossing2 = (wdot(perpend1, dir2, k) >= RT(0)); + } + else + { + if(wdot(perpend1, dir2, k) <= RT(0)) + crossing2 = true; + else + crossing2 = (sdm_s2_1 == RT(0)); + } + + if(crossing1) + { + if(crossing2) + return squared_distance_to_plane(normal, s1_min_s2, k); + + return sq_dist(s2, ray1); + } + else + { + if(crossing2) + { + return sq_dist(s1, ray2); + } + else + { + FT min1, min2; + min1 = sq_dist(s1, ray2); + min2 = sq_dist(s2, ray1); + return (min1 < min2) ? min1 : min2; + } + } +} + +} // namespace internal + +template +inline +typename K::FT +ray_ray_squared_distance_parallel(const Vector_3& ray1dir, + const Vector_3& ray2dir, + const Vector_3& s1_min_s2) +{ + 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 new file mode 100644 index 00000000000..5781c5ceb74 --- /dev/null +++ b/Distance_3/include/CGAL/Distance_3/Segment_3_Line_3.h @@ -0,0 +1,116 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman, Andreas Fabri + +#ifndef CGAL_DISTANCE_3_SEGMENT_3_LINE_3_H +#define CGAL_DISTANCE_3_SEGMENT_3_LINE_3_H + +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +typename K::FT +squared_distance(const typename K::Segment_3& seg, + const typename K::Line_3& line, + const K& k) +{ + typedef typename K::RT RT; + typedef typename K::Point_3 Point_3; + 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(); + + const Point_3& linepoint = line.point(); + const Point_3& start = seg.source(); + const Point_3& end = seg.target(); + + if(start == end) + return sq_dist(start, line); + + const Vector_3 linedir = line.direction().vector(); + const Vector_3 segdir = seg.direction().vector(); + const Vector_3 normal = wcross(segdir, linedir, k); + + if(is_null(normal, k)) + return squared_distance_to_line(linedir, vector(linepoint,start), k); + + bool crossing; + + const Vector_3 perpend2line = wcross(linedir, normal, k); + const Vector_3 start_min_lp = vector(linepoint, start); + const Vector_3 end_min_lp = vector(linepoint, end); + 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)); + } + } + + 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); + } + } +} + +template +typename K::FT +squared_distance(const typename K::Line_3& line, + const typename K::Segment_3& seg, + const K& k) +{ + return squared_distance(seg, line, k); +} + +} // 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 + +#endif // CGAL_DISTANCE_3_SEGMENT_3_LINE_3_H 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 new file mode 100644 index 00000000000..1c8d6799556 --- /dev/null +++ b/Distance_3/include/CGAL/Distance_3/Segment_3_Plane_3.h @@ -0,0 +1,108 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman, Andreas Fabri + +#ifndef CGAL_DISTANCE_3_SEGMENT_3_PLANE_3_H +#define CGAL_DISTANCE_3_SEGMENT_3_PLANE_3_H + +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +typename K::FT +squared_distance(const typename K::Segment_3 &seg, + const typename K::Plane_3 &plane, + const K& k) +{ + typedef typename K::RT RT; + typedef typename K::FT FT; + typedef typename K::Vector_3 Vector_3; + typedef typename K::Point_3 Point_3; + + typename K::Construct_vector_3 vector = k.construct_vector_3_object(); + + const Point_3& start = seg.start(); + const Point_3& end = seg.end(); + + if (start == end) + return squared_distance(start, plane, k); + + const Point_3& planepoint = plane.point(); + const Vector_3 start_min_pp = vector(planepoint, start); + const Vector_3 end_min_pp = vector(planepoint, end); + const Vector_3& normal = plane.orthogonal_vector(); + + const RT sdm_ss2pp = wdot(normal, start_min_pp, k); + const RT sdm_se2pp = wdot(normal, end_min_pp, k); + + switch (CGAL_NTS sign(sdm_ss2pp)) + { + case -1: + if (sdm_se2pp >= RT(0)) + return FT(0); + if (sdm_ss2pp * end_min_pp.hw() >= sdm_se2pp * start_min_pp.hw()) + return squared_distance_to_plane(normal, start_min_pp, k); + else + return squared_distance_to_plane(normal, end_min_pp, k); + case 0: + default: + return FT(0); + case 1: + if (sdm_se2pp <= RT(0)) + return FT(0); + if (sdm_ss2pp * end_min_pp.hw() <= sdm_se2pp * start_min_pp.hw()) + return squared_distance_to_plane(normal, start_min_pp, k); + else + return squared_distance_to_plane(normal, end_min_pp, k); + } +} + +template +inline typename K::FT +squared_distance(const typename K::Plane_3& plane, + const typename K::Segment_3& seg, + const K& k) +{ + return squared_distance(seg, plane, k); +} + +} // 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 new file mode 100644 index 00000000000..5943630d76f --- /dev/null +++ b/Distance_3/include/CGAL/Distance_3/Segment_3_Ray_3.h @@ -0,0 +1,200 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman, Andreas Fabri + +#ifndef CGAL_DISTANCE_3_SEGMENT_3_RAY_3_H +#define CGAL_DISTANCE_3_SEGMENT_3_RAY_3_H + +#include + +#include +#include + +namespace CGAL { +namespace internal { + +template +typename K::FT +squared_distance_parallel(const typename K::Segment_3& seg, + const typename K::Ray_3& ray, + const K& k) +{ + typedef typename K::Vector_3 Vector_3; + + const Vector_3 dir1 = seg.direction().vector(); + const Vector_3 dir2 = ray.direction().vector(); + + bool same_direction; + if(CGAL_NTS abs(dir1.hx()) > CGAL_NTS abs(dir1.hy())) + same_direction = (CGAL_NTS sign(dir1.hx()) == CGAL_NTS sign(dir2.hx())); + else + same_direction = (CGAL_NTS sign(dir1.hy()) == CGAL_NTS sign(dir2.hy())); + + if(same_direction) + { + if(!is_acute_angle(seg.source(), seg.target(), ray.source(), k)) + return squared_distance(seg.target(), ray.source(), k); + } + else + { + if(!is_acute_angle(seg.target(), seg.source(), ray.source(), k)) + return squared_distance(seg.source(), ray.source(), k); + } + + return squared_distance(ray.source(), seg.supporting_line(), k); +} + +template +typename K::FT +squared_distance(const typename K::Segment_3& seg, + const typename K::Ray_3& ray, + const K& k) +{ + typedef typename K::RT RT; + typedef typename K::FT FT; + typedef typename K::Point_3 Point_3; + 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(); + + const Point_3& ss = seg.source(); + const Point_3& se = seg.target(); + + if(ss == se) + return sq_dist(ss, ray); + + const Vector_3 raydir = ray.direction().vector(); + const Vector_3 segdir = seg.direction().vector(); + const Vector_3 normal = wcross(segdir, raydir, k); + + if(is_null(normal, k)) + return squared_distance_parallel(seg, ray, k); + + bool crossing1, crossing2; + + const Vector_3 perpend2seg = wcross(segdir, normal, k); + const Vector_3 perpend2ray = wcross(raydir, normal, k); + const Vector_3 ss_min_rs = vector(ray.source(), ss); + const Vector_3 se_min_rs = vector(ray.source(), se); + const RT sdm_ss2r = wdot(perpend2ray, ss_min_rs, k); + const RT sdm_se2r = wdot(perpend2ray, se_min_rs, k); + + if(sdm_ss2r < RT(0)) + { + crossing1 = (sdm_se2r >= RT(0)); + } + else + { + if(sdm_se2r <= RT(0)) + crossing1 = true; + else + crossing1 = (sdm_ss2r == RT(0)); + } + + const RT sdm_rs2s = - wdot(perpend2seg, ss_min_rs, k); + const RT sdm_re2s = wdot(perpend2seg, raydir, k); + if(sdm_rs2s < RT(0)) + { + crossing2 = (sdm_re2s >= RT(0)); + } else + { + if(sdm_re2s <= RT(0)) + crossing2 = true; + else + crossing2 = (sdm_rs2s == RT(0)); + } + + if(crossing1) + { + if(crossing2) + return squared_distance_to_plane(normal, ss_min_rs, k); + + return sq_dist(ray.source(), seg); + } + else + { + if(crossing2) + { + const RT dm = distance_measure_sub(sdm_ss2r, sdm_se2r, ss_min_rs, se_min_rs, k); + if(dm < RT(0)) + { + return sq_dist(ss, ray); + } + else + { + if(dm > RT(0)) + return sq_dist(se, ray); + else + // parallel, should not happen (no crossing) + return squared_distance_parallel(seg, ray, k); + } + } + else + { + const RT dm = distance_measure_sub(sdm_ss2r, sdm_se2r, ss_min_rs, se_min_rs, k); + if(dm == RT(0)) + return squared_distance_parallel(seg, ray, k); + + const FT min1 = (dm < RT(0)) ? sq_dist(ss, ray) + : sq_dist(se, ray); + const FT min2 = sq_dist(ray.source(), seg); + + return (min1 < min2) ? min1 : min2; + } + } +} + +template +typename K::FT +squared_distance(const typename K::Ray_3& ray, + const typename K::Segment_3& seg, + const K& k) +{ + return squared_distance(seg, ray, k); +} + +} // namespace internal + +template +inline +typename K::FT +squared_distance_parallel(const Segment_3& seg, + const Ray_3& ray) +{ + 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 new file mode 100644 index 00000000000..ad933787204 --- /dev/null +++ b/Distance_3/include/CGAL/Distance_3/Segment_3_Segment_3.h @@ -0,0 +1,208 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Mael Rouxel-Labbé + +#ifndef CGAL_DISTANCE_3_SEGMENT_3_SEGMENT_3_H +#define CGAL_DISTANCE_3_SEGMENT_3_SEGMENT_3_H + +#include + +#include + +#include + +namespace CGAL { +namespace Distance_3 { +namespace internal { + +template +struct Segment_3_Segment_3_Result +{ + typename K::FT x, y; + typename K::FT squared_distance; +}; + +// Using Lumelsky, 'On Fast Computation of Distance Between Line Segments' 1984 +template +Segment_3_Segment_3_Result +squared_distance(const typename K::Segment_3& s1, + const typename K::Segment_3& s2, + const K& k) +{ + 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(); + + Segment_3_Segment_3_Result res; + + 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); + + // @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) + { + res.x = 0; + res.y = 0; + res.squared_distance = sq_dist(p1, p2); + return res; + } + + CGAL_assertion(d < 0); + + res.x = 0; + res.y = boost::algorithm::clamp(f/d, 0, 1); // (f - x*c) / d + res.squared_distance = sq_dist(p1, p2 + res.y*v2); + + return res; + } + else if(p2 == q2) + { + CGAL_assertion(a > 0); + + res.y = 0; + res.x = boost::algorithm::clamp(e/a, 0, 1); // (e + y*c) / a + res.squared_distance = sq_dist(p1 + res.x*v1, p2); + + return res; + } + + CGAL_assertion(a > 0 && d < 0); + + const FT det = a*d - b*c; + if(det == 0) + 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 + } + 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 + } + else // 0 <= y <= 1 + { + res.y = n / d; + } + } + + CGAL_postcondition(FT(0) <= res.x && res.x <= FT(1)); + CGAL_postcondition(FT(0) <= res.y && res.y <= FT(1)); + + res.squared_distance = sq_dist(p1 + res.x*v1, p2 + res.y*v2); + + CGAL_postcondition(res.squared_distance >= FT(0)); + + return res; +} + +} // namespace internal +} // namespace Distance_3 + +namespace internal { + +template +typename K::FT +squared_distance_parallel(const typename K::Segment_3& seg1, + const typename K::Segment_3& seg2, + const K& k) +{ + typedef typename K::Vector_3 Vector_3; + + typename K::Compute_squared_distance_3 sq_dist = k.compute_squared_distance_3_object(); + + const Vector_3 dir1 = seg1.direction().vector(); + const Vector_3 dir2 = seg2.direction().vector(); + + if(same_direction(dir1, dir2, k)) + { + if(!is_acute_angle(seg1.source(), seg1.target(), seg2.source(), k)) + return sq_dist(seg1.target(), seg2.source(), k); + if(!is_acute_angle(seg1.target(), seg1.source(), seg2.target(), k)) + return sq_dist(seg1.source(), seg2.target(), k); + } + else + { + if(!is_acute_angle(seg1.source(), seg1.target(), seg2.target(), k)) + return sq_dist(seg1.target(), seg2.target(), k); + if(!is_acute_angle(seg1.target(), seg1.source(), seg2.source(), k)) + return sq_dist(seg1.source(), seg2.source(), k); + } + + return sq_dist(seg2.source(), seg1.supporting_line(), k); +} + +template +typename K::FT +squared_distance(const typename K::Segment_3& seg1, + const typename K::Segment_3& seg2, + const K& k) +{ + Distance_3::internal::Segment_3_Segment_3_Result res = + Distance_3::internal::squared_distance(seg1, seg2, k); + + return res.squared_distance; +} + +} // 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 new file mode 100644 index 00000000000..73f4b0eb69c --- /dev/null +++ b/Distance_3/include/CGAL/Distance_3/Triangle_3_Triangle_3.h @@ -0,0 +1,229 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Mael Rouxel-Labbé + +#ifndef CGAL_DISTANCE_3_TRIANGLE_3_TRIANGLE_3_H +#define CGAL_DISTANCE_3_TRIANGLE_3_TRIANGLE_3_H + +#include +#include + +#include + +namespace CGAL { +namespace Distance_3 { +namespace internal { + +template +std::pair, bool> +test_edge_pair(const typename K::Point_3& p1, + const typename K::Point_3& q1, + const typename K::Point_3& r1, + const typename K::Point_3& p2, + const typename K::Point_3& q2, + const typename K::Point_3& r2, + const K& k, + typename K::FT& global_min_sqd, + bool& are_triangles_known_to_be_disjoint) +{ + typedef typename K::FT FT; + typedef typename K::Point_3 Point_3; + typedef typename K::Vector_3 Vector_3; + + typename K::Compute_scalar_product_3 scalar_product = k.compute_scalar_product_3_object(); + typename K::Construct_segment_3 segment = k.construct_segment_3_object(); + typename K::Construct_scaled_vector_3 scale_vector = k.construct_scaled_vector_3_object(); + typename K::Construct_vector_3 vector = k.construct_vector_3_object(); + typename K::Construct_translated_point_3 translate = k.construct_translated_point_3_object(); + + Distance_3::internal::Segment_3_Segment_3_Result res = + internal::squared_distance(segment(p1, q1), segment(p2, q2), k); + + if(res.squared_distance <= global_min_sqd) + global_min_sqd = res.squared_distance; + else + return std::make_pair(res, false); + + const Vector_3 v1 = vector(p1, q1), v2 = vector(p2, q2); + const Point_3 m1 = translate(p1, scale_vector(v1, res.x)); + const Point_3 m2 = translate(p2, scale_vector(v2, res.y)); + const Vector_3 vr1 = vector(m1, r1), vr2 = vector(m2, r2); + const Vector_3 n = vector(m1, m2); + + const FT sp_r1 = scalar_product(vr1, n); + const FT sp_r2 = scalar_product(vr2, n); + const bool is_r1_closer = (sp_r1 > 0); // Plane_3{m1, n}.has_on_positive_side(r1); + const bool is_r2_closer = (sp_r2 < 0); // Plane_3{m2, -n}.has_on_positive_side(r2); + const bool is_best_pair = !is_r1_closer && !is_r2_closer; + + // Even if it is not the best pair, one may be able to deduce if the triangles do not intersect + // by checking if there is a void space between the planes orthogonal to the vector realizing + // the min distance between the edges and passing through the third points. + if(!is_best_pair) + { + FT separating_distance = res.squared_distance; + if(is_r1_closer) + separating_distance -= sp_r1; + if(is_r2_closer) + separating_distance += sp_r2; + + if(separating_distance > 0) + are_triangles_known_to_be_disjoint = true; + } + + return std::make_pair(res, is_best_pair); +} + +template +std::pair +test_vertex_triangle(const typename K::Triangle_3& tr1, + const typename K::Triangle_3& tr2, + const K& k, + bool& are_triangles_known_to_be_disjoint) +{ + typedef typename K::FT FT; + typedef typename K::Point_3 Point_3; + typedef typename K::Vector_3 Vector_3; + + typename K::Compute_scalar_product_3 scalar_product = k.compute_scalar_product_3_object(); + typename K::Construct_cross_product_vector_3 cross_product = k.construct_cross_product_vector_3_object(); + typename K::Construct_vector_3 vector = k.construct_vector_3_object(); + typename K::Construct_vertex_3 vertex = k.construct_vertex_3_object(); + + const Point_3& p1 = vertex(tr1, 0); + const Point_3& q1 = vertex(tr1, 1); + const Point_3& r1 = vertex(tr1, 2); + const Point_3& p2 = vertex(tr2, 0); + const Point_3& q2 = vertex(tr2, 1); + const Point_3& r2 = vertex(tr2, 2); + + const Vector_3 p2q2 = vector(p2, q2); + const Vector_3 p2r2 = vector(p2, r2); + const Vector_3 n2 = cross_product(p2q2, p2r2); + + if(scalar_product(n2, n2) == FT(0)) + return std::make_pair(0, false); + + std::array sps = { scalar_product(vector(p2, p1), n2), + scalar_product(vector(p2, q1), n2), + scalar_product(vector(p2, r1), n2) }; + + // All the vertices of tr1 must be on the same side of tr2 + // Coplanarity is tolerated, so '1' and '0' should be allowed, but not '1' and '-1' + if(CGAL::sign(sps[0]) == - CGAL::sign(sps[1]) || CGAL::sign(sps[1]) == - CGAL::sign(sps[2])) + return std::make_pair(0, false); + + std::for_each(sps.begin(), sps.end(), [](FT& v) { v = abs(v); }); + const auto min_pos = std::min_element(sps.begin(), sps.end()); + const std::size_t min_id = static_cast(std::distance(sps.begin(), min_pos)); + + if(sps[min_id] > 0) + are_triangles_known_to_be_disjoint = true; + + const Point_3& x1 = vertex(tr1, static_cast(min_id)); + + if(CGAL::internal::on_left_of_triangle_edge(x1, n2, p2, q2, k) && + CGAL::internal::on_left_of_triangle_edge(x1, n2, q2, r2, k) && + CGAL::internal::on_left_of_triangle_edge(x1, n2, r2, p2, k)) + { + // the projection of `x1` is inside the triangle + return std::make_pair(CGAL::internal::squared_distance_to_plane(n2, vector(p2, x1), k), true); + } + + return std::make_pair(0, false); +} + +} // namespace internal +} // namespace Distance_3 + +namespace internal { + +template +typename K::FT +squared_distance(const typename K::Triangle_3& tr1, + const typename K::Triangle_3& tr2, + const K& k) +{ + typedef typename K::FT FT; + + typename K::Construct_vertex_3 vertex = k.construct_vertex_3_object(); + + // ideally just limits::infinity|max(), but it is not available for exact NTs... + FT global_min_sqd = squared_distance(vertex(tr1, 0), vertex(tr2, 0)); + + bool are_triangles_known_to_be_disjoint = false; + std::pair, bool> ss_res; + for(int i=0; i<3; ++i) + { + for(int j=0; j<3; ++j) + { + ss_res = Distance_3::internal::test_edge_pair( + vertex(tr1, i%3), vertex(tr1, (i+1)%3), vertex(tr1, (i+2)%3), + vertex(tr2, j%3), vertex(tr2, (j+1)%3), vertex(tr2, (j+2)%3), k, + global_min_sqd, are_triangles_known_to_be_disjoint); + + if(ss_res.second) + return ss_res.first.squared_distance; + } + } + + // Failed to find a minimum between segment pairs, explore vertex-triangle distances + +#if 1 + std::pair pt_res = + Distance_3::internal::test_vertex_triangle(tr1, tr2, k, are_triangles_known_to_be_disjoint); + if(pt_res.second) + return pt_res.first; + + pt_res = Distance_3::internal::test_vertex_triangle(tr2, tr1, k, are_triangles_known_to_be_disjoint); + if(pt_res.second) + return pt_res.first; + + if(are_triangles_known_to_be_disjoint) + return global_min_sqd; + else + return 0; +#else // A tiny bit less efficient, but a lot clearer! + // @todo does not handle degenerate inputs + if(!are_triangles_known_to_be_disjoint && CGAL::do_intersect(tr1, tr2)) + return 0; + + FT sqd_p1 = CGAL::squared_distance(vertex(tr1, 0), tr2); + FT sqd_q1 = CGAL::squared_distance(vertex(tr1, 1), tr2); + FT sqd_r1 = CGAL::squared_distance(vertex(tr1, 2), tr2); + FT sqd_p2 = CGAL::squared_distance(vertex(tr2, 0), tr1); + FT sqd_q2 = CGAL::squared_distance(vertex(tr2, 1), tr1); + FT sqd_r2 = CGAL::squared_distance(vertex(tr2, 2), tr1); + + const FT m = std::min({sqd_p1, sqd_q1, sqd_r1, sqd_p2, sqd_q2, sqd_r2}); + + return m; +#endif +} + +} // namespace internal + +template +inline +typename K::FT +squared_distance(const Triangle_3& tr1, + const Triangle_3& tr2) +{ + return K().compute_squared_distance_3_object()(tr1, tr2); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_3_TRIANGLE_3_TRIANGLE_3_H diff --git a/Distance_3/include/CGAL/Distance_3/Weighted_point_3_Weighted_point_3.h b/Distance_3/include/CGAL/Distance_3/Weighted_point_3_Weighted_point_3.h new file mode 100644 index 00000000000..54a41981103 --- /dev/null +++ b/Distance_3/include/CGAL/Distance_3/Weighted_point_3_Weighted_point_3.h @@ -0,0 +1,35 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman, Andreas Fabri + +#ifndef CGAL_DISTANCE_3_WEIGHTED_POINT_3_WEIGHTED_POINT_3_H +#define CGAL_DISTANCE_3_WEIGHTED_POINT_3_WEIGHTED_POINT_3_H + +#include + +namespace CGAL { + +template +inline +typename K::FT +squared_distance(const Weighted_point_3& wpt1, + const Weighted_point_3& wpt2) +{ + return K().compute_squared_distance_3_object()(wpt1.point(), wpt2.point()); +} + +} // namespace CGAL + +#endif // CGAL_DISTANCE_3_WEIGHTED_POINT_3_WEIGHTED_POINT_3_H diff --git a/Distance_3/include/CGAL/squared_distance_3_0.h b/Distance_3/include/CGAL/Distance_3/internal/squared_distance_utils_3.h similarity index 65% rename from Distance_3/include/CGAL/squared_distance_3_0.h rename to Distance_3/include/CGAL/Distance_3/internal/squared_distance_utils_3.h index 835c2b97b66..7dbf82e246e 100644 --- a/Distance_3/include/CGAL/squared_distance_3_0.h +++ b/Distance_3/include/CGAL/Distance_3/internal/squared_distance_utils_3.h @@ -12,43 +12,34 @@ // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // -// Author(s) : Geert-Jan Giezeman, Andreas Fabri +// Author(s) : Geert-Jan Giezeman +#ifndef CGAL_SQUARED_DISTANCE_UTILS_3_H +#define CGAL_SQUARED_DISTANCE_UTILS_3_H -#ifndef CGAL_DISTANCE_3_0_H -#define CGAL_DISTANCE_3_0_H - -#include +#include #include -#include - -#include -#include -#include #include #include +#include namespace CGAL { - - namespace internal { template bool is_null(const typename K::Vector_3 &v, const K&) { - typedef typename K::RT RT; - return v.hx()==RT(0) && v.hy()==RT(0) && v.hz()==RT(0); + typedef typename K::RT RT; + return v.hx() == RT(0) && v.hy() == RT(0) && v.hz() == RT(0); } - - template typename K::RT 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()); + return (u.hx()*v.hx() + u.hy()*v.hy() + u.hz()*v.hz()); } template @@ -72,12 +63,12 @@ wdot_tag(const typename K::Point_3 &p, const K&, const Homogeneous_tag&) { - return ( (p.hx() * q.hw() - q.hx() * p.hw()) - * (r.hx() * q.hw() - q.hx() * r.hw()) - + (p.hy() * q.hw() - q.hy() * p.hw()) - * (r.hy() * q.hw() - q.hy() * r.hw()) - + (p.hz() * q.hw() - q.hz() * p.hw()) - * (r.hz() * q.hw() - q.hz() * r.hw())); + return ( (p.hx() * q.hw() - q.hx() * p.hw()) + * (r.hx() * q.hw() - q.hx() * r.hw()) + + (p.hy() * q.hw() - q.hy() * p.hw()) + * (r.hy() * q.hw() - q.hy() * r.hw()) + + (p.hz() * q.hw() - q.hz() * p.hw()) + * (r.hz() * q.hw() - q.hz() * r.hw())); } template @@ -93,9 +84,6 @@ wdot(const typename K::Point_3 &p, return wdot_tag(p, q, r, k, tag); } - - - template typename K::Vector_3 wcross(const typename K::Vector_3 &u, @@ -103,13 +91,12 @@ wcross(const typename K::Vector_3 &u, const K&) { typedef typename K::Vector_3 Vector_3; - return 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()); } - template inline bool @@ -117,8 +104,8 @@ is_acute_angle(const typename K::Vector_3 &u, const typename K::Vector_3 &v, const K& k) { - typedef typename K::RT RT; - return RT(wdot(u, v, k)) > RT(0) ; + typedef typename K::RT RT; + return RT(wdot(u, v, k)) > RT(0) ; } template @@ -128,8 +115,8 @@ is_straight_angle(const typename K::Vector_3 &u, const typename K::Vector_3 &v, const K& k) { - typedef typename K::RT RT; - return RT(wdot(u, v, k)) == RT(0) ; + typedef typename K::RT RT; + return RT(wdot(u, v, k)) == RT(0) ; } template @@ -139,8 +126,8 @@ is_obtuse_angle(const typename K::Vector_3 &u, const typename K::Vector_3 &v, const K& k) { - typedef typename K::RT RT; - return RT(wdot(u, v, k)) < RT(0) ; + typedef typename K::RT RT; + return RT(wdot(u, v, k)) < RT(0) ; } template @@ -151,8 +138,8 @@ is_acute_angle(const typename K::Point_3 &p, const typename K::Point_3 &r, const K& k) { - typedef typename K::RT RT; - return RT(wdot(p, q, r, k)) > RT(0) ; + typedef typename K::RT RT; + return RT(wdot(p, q, r, k)) > RT(0) ; } template @@ -163,8 +150,8 @@ is_straight_angle(const typename K::Point_3 &p, const typename K::Point_3 &r, const K& k) { - typedef typename K::RT RT; - return RT(wdot(p, q, r, k)) == RT(0) ; + typedef typename K::RT RT; + return RT(wdot(p, q, r, k)) == RT(0) ; } template @@ -173,25 +160,15 @@ bool is_obtuse_angle(const typename K::Point_3 &p, const typename K::Point_3 &q, const typename K::Point_3 &r, - const K& k) + const K& k) { - typedef typename K::RT RT; - return RT(wdot(p, q, r, k)) < RT(0) ; + typedef typename K::RT RT; + return RT(wdot(p, q, r, k)) < RT(0) ; } -template -inline -typename K::FT -squared_distance(const typename K::Point_3 & pt1, - const typename K::Point_3 & pt2, - const K& k) -{ - return k.compute_squared_distance_3_object()(pt1, pt2); -} - template void -squared_distance_to_plane_RT(const typename K::Vector_3 & normal, - const typename K::Vector_3 & diff, +squared_distance_to_plane_RT(const typename K::Vector_3& normal, + const typename K::Vector_3& diff, typename K::RT& num, typename K::RT& den, const K& k) @@ -206,8 +183,8 @@ squared_distance_to_plane_RT(const typename K::Vector_3 & normal, template typename K::FT -squared_distance_to_plane(const typename K::Vector_3 & normal, - const typename K::Vector_3 & diff, +squared_distance_to_plane(const typename K::Vector_3& normal, + const typename K::Vector_3& diff, const K& k) { typedef typename K::RT RT; @@ -219,8 +196,8 @@ squared_distance_to_plane(const typename K::Vector_3 & normal, template void -squared_distance_to_line_RT(const typename K::Vector_3 & dir, - const typename K::Vector_3 & diff, +squared_distance_to_line_RT(const typename K::Vector_3& dir, + const typename K::Vector_3& diff, typename K::RT& num, typename K::RT& den, const K& k) @@ -233,8 +210,8 @@ squared_distance_to_line_RT(const typename K::Vector_3 & dir, template typename K::FT -squared_distance_to_line(const typename K::Vector_3 & dir, - const typename K::Vector_3 & diff, +squared_distance_to_line(const typename K::Vector_3& dir, + const typename K::Vector_3& diff, const K& k) { typedef typename K::RT RT; @@ -271,7 +248,6 @@ same_direction_tag(const typename K::Vector_3 &u, } } - template inline bool @@ -299,7 +275,6 @@ same_direction_tag(const typename K::Vector_3 &u, } } - template inline bool @@ -312,70 +287,19 @@ same_direction(const typename K::Vector_3 &u, return same_direction_tag(u, v, k, tag); } +template +inline +typename K::RT +distance_measure_sub(typename K::RT startwdist, typename K::RT endwdist, + const typename K::Vector_3 &start, + const typename K::Vector_3 &end, + const K&) +{ + return CGAL_NTS abs(wmult((K*)0, startwdist, end.hw())) - + CGAL_NTS abs(wmult((K*)0, endwdist, start.hw())); +} } // namespace internal +} // namespace CGAL -template -inline -typename K::FT -squared_distance(const Point_3 & pt1, - const Point_3 & pt2) -{ - return internal::squared_distance(pt1,pt2, K()); -} - - -template -inline -typename K::FT -squared_distance(const Weighted_point_3 & pt1, - const Weighted_point_3 & pt2) -{ - return internal::squared_distance(pt1.point(),pt2.point(), K()); -} - -template -inline -typename K::FT -squared_distance(const Weighted_point_3 & pt1, - const Point_3 & pt2) -{ - return internal::squared_distance(pt1.point(),pt2, K()); -} - -template -inline -typename K::FT -squared_distance(const Point_3 & pt1, - const Weighted_point_3 & pt2) -{ - return internal::squared_distance(pt1,pt2.point(), K()); -} - - - -template -inline -typename K::FT -squared_distance_to_plane(const Vector_3 & normal, - const Vector_3 & diff) -{ - return internal::squared_distance_to_plane(normal, diff, K()); -} - - -template -inline -typename K::FT -squared_distance_to_line(const Vector_3 & dir, - const Vector_3 & diff) -{ - return internal::squared_distance_to_line(dir, diff, K()); -} - - - -} //namespace CGAL - - -#endif +#endif // CGAL_SQUARED_DISTANCE_UTILS_3_H diff --git a/Distance_3/include/CGAL/squared_distance_3.h b/Distance_3/include/CGAL/squared_distance_3.h index b55542f5e7f..69436bbe6dc 100644 --- a/Distance_3/include/CGAL/squared_distance_3.h +++ b/Distance_3/include/CGAL/squared_distance_3.h @@ -18,9 +18,31 @@ #ifndef CGAL_DISTANCE_3_H #define CGAL_DISTANCE_3_H -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include -#endif +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include + +#include + +#endif // CGAL_DISTANCE_3_H diff --git a/Distance_3/include/CGAL/squared_distance_3_1.h b/Distance_3/include/CGAL/squared_distance_3_1.h deleted file mode 100644 index fdc02382dca..00000000000 --- a/Distance_3/include/CGAL/squared_distance_3_1.h +++ /dev/null @@ -1,1057 +0,0 @@ -// Copyright (c) 1998-2004 -// Utrecht University (The Netherlands), -// ETH Zurich (Switzerland), -// INRIA Sophia-Antipolis (France), -// Max-Planck-Institute Saarbruecken (Germany), -// and Tel-Aviv University (Israel). All rights reserved. -// -// This file is part of CGAL (www.cgal.org) -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial -// -// -// Author(s) : Geert-Jan Giezeman, Andreas Fabri - - -#ifndef CGAL_DISTANCE_3_1_H -#define CGAL_DISTANCE_3_1_H - - -#include - -#include -#include -#include - - -namespace CGAL { - -namespace internal { - -template -void -squared_distance_RT( - const typename K::Point_3 &pt, - const typename K::Line_3 &line, - typename K::RT& num, - typename K::RT& den, - const K& k) -{ - typedef typename K::Vector_3 Vector_3; - typename K::Construct_vector_3 construct_vector; - Vector_3 dir(line.direction().vector()); - Vector_3 diff = construct_vector(line.point(), pt); - return internal::squared_distance_to_line_RT(dir, diff, num, den, k); -} - -template -typename K::FT -squared_distance( - const typename K::Point_3 &pt, - const typename K::Line_3 &line, - const K& k) -{ - typedef typename K::RT RT; - typedef typename K::FT FT; - RT num, den; - squared_distance_RT(pt, line, num, den, k); - return Rational_traits().make_rational(num, den); -} - -template -inline -typename K::FT -squared_distance( - const typename K::Line_3 & line, - const typename K::Point_3 & pt, - const K& k) -{ - return squared_distance(pt, line, k); -} - - -template -void -squared_distance_RT( - const typename K::Point_3 &pt, - const typename K::Ray_3 &ray, - typename K::RT& num, - typename K::RT& den, - const K& k) -{ - typename K::Construct_vector_3 construct_vector; - typedef typename K::Vector_3 Vector_3; - typedef typename K::RT RT; - - Vector_3 diff = construct_vector(ray.source(), pt); - const Vector_3 &dir = ray.direction().vector(); - if (!is_acute_angle(dir,diff, k) ) - { - num = wdot(diff, diff, k); - den = wmult((K*)0, RT(1), diff.hw(), diff.hw()); - return; - } - - squared_distance_to_line_RT(dir, diff, num, den, k); -} - -template -typename K::FT -squared_distance( - const typename K::Point_3 &pt, - const typename K::Ray_3 &ray, - const K& k) -{ - // This duplicates code from the _RT functions, but it is a slowdown to do something like: - // - // RT num, den; - // squared_distance_RT(pt, ray, num, den, k); - // return Rational_traits().make_rational(num, den); - // - // See https://github.com/CGAL/cgal/pull/5680 - - typedef typename K::Vector_3 Vector_3; - - typename K::Construct_vector_3 construct_vector = k.construct_vector_3_object(); - - Vector_3 diff = construct_vector(ray.source(), pt); - const Vector_3 &dir = ray.direction().vector(); - if (!is_acute_angle(dir,diff, k) ) - return (typename K::FT)(diff*diff); - - return squared_distance_to_line(dir, diff, k); -} - -template -inline -typename K::FT -squared_distance( - const typename K::Ray_3 & ray, - const typename K::Point_3 & pt, - const K& k) -{ - return squared_distance(pt, ray, k); -} - -template -void -squared_distance_RT( - const typename K::Point_3 &pt, - const typename K::Segment_3 &seg, - typename K::RT& num, - typename K::RT& den, - const K& k) -{ - typedef typename K::Vector_3 Vector_3; - typedef typename K::RT RT; - - typename K::Construct_vector_3 construct_vector; - - // assert that the segment is valid (non zero length). - const Vector_3 diff_s = construct_vector(seg.source(), pt); - const Vector_3 segvec = construct_vector(seg.source(), seg.target()); - - const RT d = wdot(diff_s, segvec, k); - if (d <= RT(0)) - { - // this is squared_distance(pt, seg.source()) - num = wdot(diff_s, diff_s, k); - den = wmult((K*)0, RT(1), diff_s.hw(), diff_s.hw()); - return; - } - - const RT e = wdot(segvec, segvec, k); - if (wmult((K*)0 ,d, segvec.hw()) > wmult((K*)0, e, diff_s.hw())) - { - // this is squared_distance(pt, seg.target()) - const Vector_3 diff_t = construct_vector(seg.target(), pt); - num = wdot(diff_t, diff_t, k); - den = wmult((K*)0, RT(1), diff_t.hw(), diff_t.hw()); - return; - } - - // This is an expanded call to squared_distance_to_line_RT() to avoid recomputing 'e' - const Vector_3 wcr = wcross(segvec, diff_s, k); - num = wdot(wcr, wcr, k); - den = wmult((K*)0, e, diff_s.hw(), diff_s.hw()); -} - -template -typename K::FT -squared_distance( - const typename K::Point_3 &pt, - const typename K::Segment_3 &seg, - const K& k) -{ - typedef typename K::Vector_3 Vector_3; - typedef typename K::RT RT; - typedef typename K::FT FT; - - typename K::Construct_vector_3 construct_vector = k.construct_vector_3_object(); - - // assert that the segment is valid (non zero length). - Vector_3 diff = construct_vector(seg.source(), pt); - Vector_3 segvec = construct_vector(seg.source(), seg.target()); - RT d = wdot(diff,segvec, k); - if (d <= RT(0)) - return (FT(diff*diff)); - - 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); - - // This is an expanded call to squared_distance_to_line() to avoid recomputing 'e' - Vector_3 wcr = wcross(segvec, diff, k); - return FT(wcr*wcr) / wmult((K*)0, e, diff.hw(), diff.hw()); -} - -template -inline -typename K::FT -squared_distance( - const typename K::Segment_3 & seg, - const typename K::Point_3 & pt, - const K& k) -{ - return squared_distance(pt, seg, k); -} - -template -typename K::Comparison_result -compare_distance_pssC3( - const typename K::Point_3 &pt, - const typename K::Segment_3 &seg1, - const typename K::Segment_3 &seg2, - const K& k) -{ - typename K::Construct_vector_3 construct_vector; - typedef typename K::Vector_3 Vector_3; - typedef typename K::RT RT; - typedef typename K::FT FT; - FT d1=FT(0), d2=FT(0); - RT e1 = RT(1), e2 = RT(1); - // assert that the segment is valid (non zero length). - { - Vector_3 diff = construct_vector(seg1.source(), pt); - Vector_3 segvec = construct_vector(seg1.source(), seg1.target()); - RT d = wdot(diff,segvec, k); - if (d <= RT(0)){ - d1 = (FT(diff*diff)); - }else{ - RT e = wdot(segvec,segvec, k); - if (d > e){ - d1 = squared_distance(pt, seg1.target(), k); - } else{ - Vector_3 wcr = wcross(segvec, diff, k); - d1 = FT(wcr*wcr); - e1 = e; - } - } - } - { - Vector_3 diff = construct_vector(seg2.source(), pt); - Vector_3 segvec = construct_vector(seg2.source(), seg2.target()); - RT d = wdot(diff,segvec, k); - if (d <= RT(0)){ - d2 = (FT(diff*diff)); - }else{ - RT e = wdot(segvec,segvec, k); - if (d > e){ - d2 = squared_distance(pt, seg2.target(), k); - } else{ - Vector_3 wcr = wcross(segvec, diff, k); - d2 = FT(wcr*wcr); - e2 = e; - } - } - } - return CGAL::compare(d1*e2, d2*e1); -} - -template -typename K::Comparison_result -compare_distance_ppsC3( - const typename K::Point_3 &pt, - const typename K::Point_3 &pt2, - const typename K::Segment_3 &seg, - const K& k) -{ - typename K::Construct_vector_3 construct_vector; - typedef typename K::Vector_3 Vector_3; - typedef typename K::RT RT; - typedef typename K::FT FT; - RT e2 = RT(1); - // assert that the segment is valid (non zero length). - FT d1 = squared_distance(pt, pt2, k); - FT d2 = FT(0); - { - Vector_3 diff = construct_vector(seg.source(), pt); - Vector_3 segvec = construct_vector(seg.source(), seg.target()); - RT d = wdot(diff,segvec, k); - if (d <= RT(0)){ - d2 = (FT(diff*diff)); - }else{ - RT e = wdot(segvec,segvec, k); - if (d > e){ - d2 = squared_distance(pt, seg.target(), k); - } else{ - Vector_3 wcr = wcross(segvec, diff, k); - d2 = FT(wcr*wcr); - e2 = e; - } - } - } - return CGAL::compare(d1*e2, d2); -} - - -template -typename K::FT -squared_distance_parallel( - const typename K::Segment_3 &seg1, - const typename K::Segment_3 &seg2, - const K& k) -{ - typedef typename K::Vector_3 Vector_3; - const Vector_3 &dir1 = seg1.direction().vector(); - const Vector_3 &dir2 = seg2.direction().vector(); - - if (same_direction(dir1, dir2, k)) { - if (!is_acute_angle(seg1.source(), seg1.target(), seg2.source(), k)) - return squared_distance(seg1.target(), seg2.source(), k); - if (!is_acute_angle(seg1.target(), seg1.source(), seg2.target(), k)) - return squared_distance(seg1.source(), seg2.target(), k); - } else { - if (!is_acute_angle(seg1.source(), seg1.target(), seg2.target(), k)) - return squared_distance(seg1.target(), seg2.target(), k); - if (!is_acute_angle(seg1.target(), seg1.source(), seg2.source(), k)) - return squared_distance(seg1.source(), seg2.source(), k); - } - return squared_distance(seg2.source(), seg1.supporting_line(), k); -} - - - -template -inline -typename K::RT -_distance_measure_sub(typename K::RT startwdist, typename K::RT endwdist, - const typename K::Vector_3 &start, - const typename K::Vector_3 &end, - const K&) -{ - return CGAL_NTS abs(wmult((K*)0, startwdist, end.hw())) - - CGAL_NTS abs(wmult((K*)0, endwdist, start.hw())); -} - - -template -typename K::FT -squared_distance( - const typename K::Segment_3 &seg1, - const typename K::Segment_3 &seg2, - const K& k) -{ - typename K::Construct_vector_3 construct_vector; - typedef typename K::Vector_3 Vector_3; - typedef typename K::Point_3 Point_3; - typedef typename K::RT RT; - typedef typename K::FT FT; - const Point_3 &start1 = seg1.source(); - const Point_3 &start2 = seg2.source(); - const Point_3 &end1 = seg1.target(); - const Point_3 &end2 = seg2.target(); - - if (start1 == end1) - return squared_distance(start1, seg2, k); - if (start2 == end2) - return squared_distance(start2, seg1, k); - - Vector_3 dir1, dir2, normal; - dir1 = seg1.direction().vector(); - dir2 = seg2.direction().vector(); - normal = wcross(dir1, dir2, k); - if (is_null(normal, k)) - return squared_distance_parallel(seg1, seg2, k); - - bool crossing1, crossing2; - RT sdm_s1to2, sdm_e1to2, sdm_s2to1, sdm_e2to1; - Vector_3 perpend1, perpend2, s2mins1, e2mins1, e1mins2; - perpend1 = wcross(dir1, normal, k); - perpend2 = wcross(dir2, normal, k); - s2mins1 = construct_vector(start1, start2); - e2mins1 = construct_vector(start1, end2); - e1mins2 = construct_vector(start2, end1); - sdm_s1to2 = -RT(wdot(perpend2, s2mins1, k)); - sdm_e1to2 = wdot(perpend2, e1mins2, k); - sdm_s2to1 = wdot(perpend1, s2mins1, k); - sdm_e2to1 = wdot(perpend1, e2mins1, k); - - if (sdm_s1to2 < RT(0)) { - crossing1 = (sdm_e1to2 >= RT(0)); - } else { - if (sdm_e1to2 <= RT(0)) { - crossing1 = true; - } else { - crossing1 = (sdm_s1to2 == RT(0)); - } - } - if (sdm_s2to1 < RT(0)) { - crossing2 = (sdm_e2to1 >= RT(0)); - } else { - if (sdm_e2to1 <= RT(0)) { - crossing2 = true; - } else { - crossing2 = (sdm_s2to1 == RT(0)); - } - } - - if (crossing1) { - if (crossing2) { - return squared_distance_to_plane(normal, s2mins1, k); - } - - RT dm; - dm = _distance_measure_sub( - sdm_s2to1, sdm_e2to1, s2mins1, e2mins1, k); - if (dm < RT(0)) { - return squared_distance(start2, seg1, k); - } else { - if (dm > RT(0)) { - return squared_distance(end2, seg1, k); - } else { - // should not happen with exact arithmetic. - return squared_distance_parallel(seg1, seg2, k); - } - } - } else { - if (crossing2) { - RT dm; - dm =_distance_measure_sub( - sdm_s1to2, sdm_e1to2, s2mins1, e1mins2, k); - if (dm < RT(0)) { - return squared_distance(start1, seg2, k); - } else { - if (dm > RT(0)) { - return squared_distance(end1, seg2, k); - } else { - // should not happen with exact arithmetic. - return squared_distance_parallel(seg1, seg2, k); - } - } - } else { - FT min1, min2; - RT dm; - dm = _distance_measure_sub( - sdm_s1to2, sdm_e1to2, s2mins1, e1mins2, k); - if (dm == RT(0)) // should not happen with exact arithmetic. - return squared_distance_parallel(seg1, seg2, k); - min1 = (dm < RT(0)) ? - squared_distance(seg1.source(), seg2, k): - squared_distance(end1, seg2, k); - dm = _distance_measure_sub( - sdm_s2to1, sdm_e2to1, s2mins1, e2mins1, k); - if (dm == RT(0)) // should not happen with exact arithmetic. - return squared_distance_parallel(seg1, seg2, k); - min2 = (dm < RT(0)) ? - squared_distance(start2, seg1, k): - squared_distance(end2, seg1, k); - return (min1 < min2) ? min1 : min2; - } - } - -} - - - - - - -template -typename K::FT -squared_distance_parallel( - const typename K::Segment_3 &seg, - const typename K::Ray_3 &ray, - const K& k) -{ - - typedef typename K::Vector_3 Vector_3; - bool same_direction; - const Vector_3 &dir1 = seg.direction().vector(); - const Vector_3 &dir2 = ray.direction().vector(); - if (CGAL_NTS abs(dir1.hx()) > CGAL_NTS abs(dir1.hy())) { - same_direction = (CGAL_NTS sign(dir1.hx()) == CGAL_NTS sign(dir2.hx())); - } else { - same_direction = (CGAL_NTS sign(dir1.hy()) == CGAL_NTS sign(dir2.hy())); - } - if (same_direction) { - if (!is_acute_angle(seg.source(), seg.target(), ray.source(), k)) - return squared_distance(seg.target(), ray.source(), k); - } else { - if (!is_acute_angle(seg.target(), seg.source(), ray.source(), k)) - return squared_distance(seg.source(), ray.source(), k); - } - return squared_distance(ray.source(), seg.supporting_line(), k); -} - - -template -typename K::FT -squared_distance( - const typename K::Segment_3 &seg, - const typename K::Ray_3 &ray, - const K& k) -{ - typename K::Construct_vector_3 construct_vector; - typedef typename K::Point_3 Point_3; - typedef typename K::Vector_3 Vector_3; - typedef typename K::RT RT; - typedef typename K::FT FT; - const Point_3 & ss = seg.source(); - const Point_3 & se = seg.target(); - if (ss == se) - return squared_distance(ss, ray, k); - Vector_3 raydir, segdir, normal; - raydir = ray.direction().vector(); - segdir = seg.direction().vector(); - normal = wcross(segdir, raydir, k); - if (is_null(normal, k)) - return squared_distance_parallel(seg, ray, k); - - bool crossing1, crossing2; - RT sdm_ss2r, sdm_se2r, sdm_rs2s, sdm_re2s; - Vector_3 perpend2seg, perpend2ray, ss_min_rs, se_min_rs; - perpend2seg = wcross(segdir, normal, k); - perpend2ray = wcross(raydir, normal, k); - ss_min_rs = construct_vector(ray.source(), ss); - se_min_rs = construct_vector(ray.source(), se); - sdm_ss2r = wdot(perpend2ray, ss_min_rs, k); - sdm_se2r = wdot(perpend2ray, se_min_rs, k); - if (sdm_ss2r < RT(0)) { - crossing1 = (sdm_se2r >= RT(0)); - } else { - if (sdm_se2r <= RT(0)) { - crossing1 = true; - } else { - crossing1 = (sdm_ss2r == RT(0)); - } - } - - sdm_rs2s = -RT(wdot(perpend2seg, ss_min_rs, k)); - sdm_re2s = wdot(perpend2seg, raydir, k); - if (sdm_rs2s < RT(0)) { - crossing2 = (sdm_re2s >= RT(0)); - } else { - if (sdm_re2s <= RT(0)) { - crossing2 = true; - } else { - crossing2 = (sdm_rs2s == RT(0)); - } - } - - if (crossing1) { - if (crossing2) { - return squared_distance_to_plane(normal, ss_min_rs, k); - } - return squared_distance(ray.source(), seg, k); - } else { - if (crossing2) { - RT dm; - dm = _distance_measure_sub( - sdm_ss2r, sdm_se2r, ss_min_rs, se_min_rs, k); - if (dm < RT(0)) { - return squared_distance(ss, ray, k); - } else { - if (dm > RT(0)) { - return squared_distance(se, ray, k); - } else { - // parallel, should not happen (no crossing) - return squared_distance_parallel(seg, ray, k); - } - } - } else { - FT min1, min2; - RT dm; - dm = _distance_measure_sub( - sdm_ss2r, sdm_se2r, ss_min_rs, se_min_rs, k); - if (dm == RT(0)) - return squared_distance_parallel(seg, ray, k); - min1 = (dm < RT(0)) - ? squared_distance(ss, ray, k) - : squared_distance(se, ray, k); - min2 = squared_distance(ray.source(), seg, k); - return (min1 < min2) ? min1 : min2; - } - } -} - - - -template -inline -typename K::FT -squared_distance( - const typename K::Ray_3 & ray, - const typename K::Segment_3 & seg, - const K& k) -{ - return squared_distance(seg, ray, k); -} - - -template -typename K::FT -squared_distance( - const typename K::Segment_3 &seg, - const typename K::Line_3 &line, - const K& k) -{ - typename K::Construct_vector_3 construct_vector; - typedef typename K::Vector_3 Vector_3; - typedef typename K::Point_3 Point_3; - typedef typename K::RT RT; - const Point_3 &linepoint = line.point(); - const Point_3 &start = seg.source(); - const Point_3 &end = seg.target(); - - if (start == end) - return squared_distance(start, line, k); - Vector_3 linedir = line.direction().vector(); - Vector_3 segdir = seg.direction().vector(); - Vector_3 normal = wcross(segdir, linedir, k); - if (is_null(normal, k)) - return squared_distance_to_line(linedir, - construct_vector(linepoint,start), k); - - bool crossing; - RT sdm_ss2l, sdm_se2l; - Vector_3 perpend2line, start_min_lp, end_min_lp; - perpend2line = wcross(linedir, normal, k); - start_min_lp = construct_vector(linepoint, start); - end_min_lp = construct_vector(linepoint, end); - sdm_ss2l = wdot(perpend2line, start_min_lp, k); - 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)); - } - } - - if (crossing) { - return squared_distance_to_plane(normal, start_min_lp, k); - } else { - RT dm; - 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); - } - } -} - - -template -inline -typename K::FT -squared_distance( - const typename K::Line_3 & line, - const typename K::Segment_3 & seg, - const K& k) -{ - return squared_distance(seg, line, k); -} - - - - -template -typename K::FT -ray_ray_squared_distance_parallel( - const typename K::Vector_3 &ray1dir, - const typename K::Vector_3 &ray2dir, - const typename K::Vector_3 &s1_min_s2, - const K& k) -{ - if (!is_acute_angle(ray2dir, s1_min_s2, k)) { - if (!same_direction(ray1dir, ray2dir, k)) - return (typename K::FT)(s1_min_s2*s1_min_s2); - } - return squared_distance_to_line(ray1dir, s1_min_s2, k); -} - - -template -typename K::FT -squared_distance( - const typename K::Ray_3 &ray1, - const typename K::Ray_3 &ray2, - const K& k) -{ - typename K::Construct_vector_3 construct_vector; - typedef typename K::Vector_3 Vector_3; - typedef typename K::Point_3 Point_3; - typedef typename K::RT RT; - typedef typename K::FT FT; - const Point_3 & s1 = ray1.source(); - const Point_3 & s2 = ray2.source(); - Vector_3 dir1, dir2, normal; - dir1 = ray1.direction().vector(); - dir2 = ray2.direction().vector(); - normal = wcross(dir1, dir2, k); - Vector_3 s1_min_s2 = construct_vector(s2, s1); - if (is_null(normal, k)) - return ray_ray_squared_distance_parallel(dir1, dir2, s1_min_s2, k); - - bool crossing1, crossing2; - RT sdm_s1_2, sdm_s2_1; - Vector_3 perpend1, perpend2; - perpend1 = wcross(dir1, normal, k); - perpend2 = wcross(dir2, normal, k); - - sdm_s1_2 = wdot(perpend2, s1_min_s2, k); - if (sdm_s1_2 < RT(0)) { - crossing1 = (RT(wdot(perpend2, dir1, k)) >= RT(0)); - } else { - if (RT(wdot(perpend2, dir1, k)) <= RT(0)) { - crossing1 = true; - } else { - crossing1 = (sdm_s1_2 == RT(0)); - } - } - sdm_s2_1 = -RT(wdot(perpend1, s1_min_s2, k)); - if (sdm_s2_1 < RT(0)) { - crossing2 = (RT(wdot(perpend1, dir2, k)) >= RT(0)); - } else { - if (RT(wdot(perpend1, dir2, k)) <= RT(0)) { - crossing2 = true; - } else { - crossing2 = (sdm_s2_1 == RT(0)); - } - } - if (crossing1) { - if (crossing2) - return squared_distance_to_plane(normal, s1_min_s2, k); - return squared_distance(ray2.source(), ray1, k); - } else { - if (crossing2) { - return squared_distance(ray1.source(), ray2, k); - } else { - FT min1, min2; - min1 = squared_distance(ray1.source(), ray2, k); - min2 = squared_distance(ray2.source(), ray1, k); - return (min1 < min2) ? min1 : min2; - } - } -} - - - - - -template -typename K::FT -squared_distance( - const typename K::Line_3 &line, - const typename K::Ray_3 &ray, - const K& k) -{ - typename K::Construct_vector_3 construct_vector; - typedef typename K::Vector_3 Vector_3; - typedef typename K::Point_3 Point_3; - typedef typename K::RT RT; - const Point_3 & rs =ray.source(); - Vector_3 raydir, linedir, normal; - linedir = line.direction().vector(); - raydir = ray.direction().vector(); - normal = wcross(raydir, linedir, k); - Vector_3 rs_min_lp = construct_vector(line.point(), rs); - if (is_null(normal, k)) - return squared_distance_to_line(linedir, rs_min_lp, k); - - bool crossing; - RT sdm_sr_l; - Vector_3 perpend2l; - perpend2l = wcross(linedir, normal, k); - - sdm_sr_l = wdot(perpend2l, rs_min_lp, k); - if (sdm_sr_l < RT(0)) { - crossing = (RT(wdot(perpend2l, raydir, k)) >= RT(0)); - } else { - if (RT(wdot(perpend2l, raydir, k)) <= RT(0)) { - crossing = true; - } else { - crossing = (sdm_sr_l == RT(0)); - } - } - - if (crossing) - return squared_distance_to_plane(normal, rs_min_lp, k); - else - return squared_distance_to_line(linedir, rs_min_lp, k); -} - - -template -inline typename K::FT -squared_distance( - const typename K::Ray_3 & ray, - const typename K::Line_3 & line, - const K& k) -{ - return squared_distance(line, ray, k); -} - - - - -template -typename K::FT -squared_distance( - const typename K::Line_3 &line1, - const typename K::Line_3 &line2, - const K& k) -{ - typename K::Construct_vector_3 construct_vector; - typedef typename K::Vector_3 Vector_3; - - Vector_3 dir1, dir2, normal, diff; - dir1 = line1.direction().vector(); - dir2 = line2.direction().vector(); - normal = wcross(dir1, dir2, k); - diff = construct_vector(line1.point(), line2.point()); - if (is_null(normal, k)) - return squared_distance_to_line(dir2, diff, k); - return squared_distance_to_plane(normal, diff, k); -} - - - -} // namespace internal - - - -template -inline -typename K::FT -squared_distance(const Point_3 &pt, - const Line_3 &line) -{ - return internal::squared_distance(pt, line, K()); -} - - -template -inline -typename K::FT -squared_distance( - const Line_3 & line, - const Point_3 & pt) -{ - return internal::squared_distance(pt, line, K()); -} - - -template -inline -typename K::FT -squared_distance( - const Point_3 &pt, - const Ray_3 &ray) -{ - return internal::squared_distance(pt, ray, K()); -} - - -template -inline -typename K::FT -squared_distance( - const Ray_3 & ray, - const Point_3 & pt) -{ - return internal::squared_distance(pt, ray, K()); -} - - -template -inline -typename K::FT -squared_distance( - const Point_3 &pt, - const Segment_3 &seg) -{ - return internal::squared_distance(pt, seg, K()); -} - - -template -inline -typename K::FT -squared_distance( - const Segment_3 & seg, - const Point_3 & pt) -{ - return internal::squared_distance(pt, seg, K()); -} - - - - -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 internal::squared_distance(seg1, seg2, K()); -} - - - - - - -template -inline -typename K::FT -squared_distance_parallel( - const Segment_3 &seg, - const Ray_3 &ray) -{ - return internal::squared_distance_parallel(ray,seg, K()); -} - - -template -inline -typename K::FT -squared_distance( - const Segment_3 &seg, - const Ray_3 &ray) -{ - return internal::squared_distance(ray, seg, K()); -} - - - -template -inline -typename K::FT -squared_distance( - const Ray_3 & ray, - const Segment_3 & seg) -{ - return internal::squared_distance(seg, ray, K()); -} - - -template -inline -typename K::FT -squared_distance( - const Segment_3 &seg, - const Line_3 &line) -{ - return internal::squared_distance(seg, line, K()); -} - - -template -inline -typename K::FT -squared_distance( - const Line_3 & line, - const Segment_3 & seg) -{ - return internal::squared_distance(seg, line, K()); -} - - - - -template -inline -typename K::FT -ray_ray_squared_distance_parallel( - const Vector_3 &ray1dir, - const Vector_3 &ray2dir, - const Vector_3 &s1_min_s2) -{ - 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 internal::squared_distance(ray1, ray2, K()); -} - - - - - -template -inline -typename K::FT -squared_distance( - const Line_3 &line, - const Ray_3 &ray) -{ - return internal::squared_distance(line, ray, K()); -} - - -template -inline -typename K::FT -squared_distance( - const Ray_3 & ray, - const Line_3 & line) -{ - return internal::squared_distance(line, ray, K()); -} - - - - -template -inline -typename K::FT -squared_distance( - const Line_3 &line1, - const Line_3 &line2) -{ - return internal::squared_distance(line1, line2, K()); -} - - -} //namespace CGAL - - -#endif diff --git a/Distance_3/include/CGAL/squared_distance_3_2.h b/Distance_3/include/CGAL/squared_distance_3_2.h deleted file mode 100644 index c5cd5cf1694..00000000000 --- a/Distance_3/include/CGAL/squared_distance_3_2.h +++ /dev/null @@ -1,505 +0,0 @@ -// Copyright (c) 1998-2004 -// Utrecht University (The Netherlands), -// ETH Zurich (Switzerland), -// INRIA Sophia-Antipolis (France), -// Max-Planck-Institute Saarbruecken (Germany), -// and Tel-Aviv University (Israel). All rights reserved. -// -// This file is part of CGAL (www.cgal.org) -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial -// -// -// Author(s) : Geert-Jan Giezeman, Andreas Fabri - - -#ifndef CGAL_DISTANCE_3_2_H -#define CGAL_DISTANCE_3_2_H - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -namespace CGAL { - -namespace internal { - -template -bool -contains_vector(const typename K::Plane_3 &pl, - const typename K::Vector_3 &vec, - const K&) -{ - typedef typename K::RT RT; - return pl.a()*vec.hx() + pl.b()*vec.hy() + pl.c() * vec.hz() == RT(0); -} - - -template -inline typename K::FT -squared_distance( - const typename K::Point_3 & pt, - const typename K::Plane_3 & plane, - const K& k) -{ - typename K::Construct_vector_3 construct_vector; - typedef typename K::Vector_3 Vector_3; - Vector_3 diff = construct_vector(plane.point(), pt); - return squared_distance_to_plane(plane.orthogonal_vector(), diff, k); -} - - - -template -inline typename K::FT -squared_distance( - const typename K::Plane_3 & plane, - const typename K::Point_3 & pt, - const K& k) -{ - return squared_distance(pt, plane, k); -} - -template -typename K::FT -squared_distance( - const typename K::Line_3 &line, - const typename K::Plane_3 &plane, - const K& k) -{ - typedef typename K::FT FT; - if (contains_vector(plane, line.direction().vector(), k)) - return squared_distance(plane, line.point(), k); - return FT(0); -} - - -template -inline typename K::FT -squared_distance( - const typename K::Plane_3 & p, - const typename K::Line_3 & line, - const K& k) -{ - return squared_distance(line, p, k); -} - -template -typename K::FT -squared_distance( - const typename K::Ray_3 &ray, - const typename K::Plane_3 &plane, - const K& k) -{ - typename K::Construct_vector_3 construct_vector; - typedef typename K::Point_3 Point_3; - typedef typename K::Vector_3 Vector_3; - typedef typename K::RT RT; - typedef typename K::FT FT; - const Point_3 &start = ray.start(); - const Point_3 &planepoint = plane.point(); - Vector_3 start_min_pp = construct_vector(planepoint, start); - Vector_3 end_min_pp = ray.direction().vector(); - const Vector_3 &normal = plane.orthogonal_vector(); - RT sdm_rs2pp = wdot(normal, start_min_pp, k); - RT sdm_re2pp = wdot(normal, end_min_pp, k); - switch (CGAL_NTS sign(sdm_rs2pp)) { - case -1: - if (sdm_re2pp > RT(0)) - return FT(0); - return squared_distance_to_plane(normal, start_min_pp, k); - case 0: - default: - return FT(0); - case 1: - if (sdm_re2pp < RT(0)) - return FT(0); - return squared_distance_to_plane(normal, start_min_pp, k); - } -} - - -template -inline typename K::FT -squared_distance( - const typename K::Plane_3 & plane, - const typename K::Ray_3 & ray, - const K& k) -{ - return squared_distance(ray, plane, k); -} - -template -typename K::FT -squared_distance( - const typename K::Segment_3 &seg, - const typename K::Plane_3 &plane, - const K& k) -{ - typename K::Construct_vector_3 construct_vector; - typedef typename K::Point_3 Point_3; - typedef typename K::Vector_3 Vector_3; - typedef typename K::RT RT; - typedef typename K::FT FT; - const Point_3 &start = seg.start(); - const Point_3 &end = seg.end(); - if (start == end) - return squared_distance(start, plane, k); - const Point_3 &planepoint = plane.point(); - Vector_3 start_min_pp = construct_vector(planepoint, start); - Vector_3 end_min_pp = construct_vector(planepoint, end); - const Vector_3 &normal = plane.orthogonal_vector(); - RT sdm_ss2pp = wdot(normal, start_min_pp, k); - RT sdm_se2pp = wdot(normal, end_min_pp, k); - switch (CGAL_NTS sign(sdm_ss2pp)) { - case -1: - if (sdm_se2pp >= RT(0)) - return FT(0); - if (sdm_ss2pp * end_min_pp.hw() >= sdm_se2pp * start_min_pp.hw()) - return squared_distance_to_plane(normal, start_min_pp, k); - else - return squared_distance_to_plane(normal, end_min_pp, k); - case 0: - default: - return FT(0); - case 1: - if (sdm_se2pp <= RT(0)) - return FT(0); - if (sdm_ss2pp * end_min_pp.hw() <= sdm_se2pp * start_min_pp.hw()) - return squared_distance_to_plane(normal, start_min_pp, k); - else - return squared_distance_to_plane(normal, end_min_pp, k); - } -} - - -template -inline typename K::FT -squared_distance( - const typename K::Plane_3 & plane, - const typename K::Segment_3 & seg, - const K& k) -{ - return squared_distance(seg, plane, k); -} - - -template -inline bool -on_left_of_triangle_edge(const typename K::Point_3 & pt, - const typename K::Vector_3 & normal, - const typename K::Point_3 & ep0, - const typename K::Point_3 & ep1, - const K& k) -{ - // return true iff pt is on the negative side of the plane defined - // by (ep0, ep1) and normal - typename K::Construct_vector_3 vector; - typename K::Vector_3 edge = vector(ep0, ep1); - typename K::Vector_3 diff = vector(ep0, pt); - - typedef typename K::RT RT; - - const bool result = - RT(wdot(wcross(edge, - normal, - k), - diff, - k)) <= RT(0); - return result; -} - -template -inline void -squared_distance_to_triangle_RT( - const typename K::Point_3 & pt, - const typename K::Point_3 & t0, - const typename K::Point_3 & t1, - const typename K::Point_3 & t2, - bool & inside, - typename K::RT& num, - typename K::RT& den, - const K& k) -{ - typename K::Construct_vector_3 vector; - typedef typename K::Vector_3 Vector_3; - 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. - squared_distance_RT(pt, typename K::Segment_3(t2, t0), num, den, k); - - typename K::RT num2, den2; - squared_distance_RT(pt, typename K::Segment_3(t1, t2), num2, den2, k); - if(compare_quotients(num2,den2, num,den) == SMALLER) { - num = num2; - den = den2; - } - - // should not be needed since at most 2 edges cover the full triangle in the degenerate case - squared_distance_RT(pt, typename K::Segment_3(t0, t1), num2, den2, k); - if(compare_quotients(num2,den2, num,den) == SMALLER){ - num = num2; - den = den2; - } - - return; - } - - const bool b01 = on_left_of_triangle_edge(pt, normal, t0, t1, k); - if(!b01) { - squared_distance_RT(pt, typename K::Segment_3(t0, t1), num, den, k); - return; - } - - const bool b12 = on_left_of_triangle_edge(pt, normal, t1, t2, k); - if(!b12) { - squared_distance_RT(pt, typename K::Segment_3(t1, t2), num, den, k); - return; - } - - const bool b20 = on_left_of_triangle_edge(pt, normal, t2, t0, k); - if(!b20) { - squared_distance_RT(pt, typename K::Segment_3(t2, t0), num, den, k); - return; - } - - // The projection of pt is inside the triangle - inside = true; - squared_distance_to_plane_RT(normal, vector(t0, pt), num, den, k); -} - -template -void -squared_distance_RT( - const typename K::Point_3 & pt, - const typename K::Triangle_3 & t, - typename K::RT& num, - typename K::RT& den, - const K& k) -{ - typename K::Construct_vertex_3 vertex; - bool inside = false; - squared_distance_to_triangle_RT(pt, - vertex(t, 0), - vertex(t, 1), - vertex(t, 2), - inside, - num, - den, - k); -} - -template -inline typename K::FT -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, - bool & inside, - const K& k) -{ - typename K::Construct_vector_3 vector; - typedef typename K::Vector_3 Vector_3; - 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. - typename K::FT d1 = squared_distance(pt, typename K::Segment_3(t2, t0), k); - typename K::FT d2 = squared_distance(pt, typename K::Segment_3(t1, t2), k); - - // should not be needed since at most 2 edges cover the full triangle in the degenerate case - typename K::FT d3 = squared_distance(pt, typename K::Segment_3(t0, t1), k); - - return (std::min)( (std::min)(d1, d2), d3); - } - - const bool b01 = on_left_of_triangle_edge(pt, normal, t0, t1, k); - if(!b01) { - return internal::squared_distance(pt, typename K::Segment_3(t0, t1), k); - } - - const bool b12 = on_left_of_triangle_edge(pt, normal, t1, t2, k); - if(!b12) { - return internal::squared_distance(pt, typename K::Segment_3(t1, t2), k); - } - - const bool b20 = on_left_of_triangle_edge(pt, normal, t2, t0, k); - if(!b20) { - return internal::squared_distance(pt, typename K::Segment_3(t2, t0), k); - } - - // The projection of pt is inside the triangle - inside = true; - return squared_distance_to_plane(normal, vector(t0, pt), k); -} - -template -inline typename K::FT -squared_distance( - const typename K::Point_3 & pt, - const typename K::Triangle_3 & t, - const K& k) -{ - typename K::Construct_vertex_3 vertex = k.construct_vertex_3_object(); - bool inside = false; - return squared_distance_to_triangle(pt, - vertex(t, 0), - vertex(t, 1), - vertex(t, 2), - inside, - k); -} - -} // namespace internal - - -template -bool -contains_vector(const Plane_3 &pl, const Vector_3 &vec) -{ - return internal::contains_vector(pl,vec, K()); -} - - -template -inline -typename K::FT -squared_distance( - const Point_3 & pt, - const Plane_3 & plane) -{ - return internal::squared_distance(pt, plane, K()); -} - - - -template -inline -typename K::FT -squared_distance( - const Plane_3 & plane, - const Point_3 & pt) -{ - return internal::squared_distance(pt, plane, K()); -} - -template -inline -typename K::FT -squared_distance( - const Line_3 &line, - const Plane_3 &plane) -{ - return internal::squared_distance(line, plane, K()); -} - - -template -inline -typename K::FT -squared_distance( - const Plane_3 & p, - const Line_3 & line) -{ - return internal::squared_distance(line, p, K()); -} - -template -inline -typename K::FT -squared_distance( - const Ray_3 &ray, - const Plane_3 &plane) -{ - return internal::squared_distance(ray, plane, K()); -} - - - -template -inline -typename K::FT -squared_distance( - const Plane_3 & plane, - const Ray_3 & ray) -{ - return internal::squared_distance(ray, plane, K()); -} - -template -inline -typename K::FT -squared_distance( - const Segment_3 &seg, - const Plane_3 &plane) -{ - return internal::squared_distance(seg, plane, K()); - -} - - -template -inline -typename K::FT -squared_distance( - const Plane_3 & plane, - const Segment_3 & seg) -{ - return internal::squared_distance(seg, plane, K()); -} - -template -inline -typename K::FT -squared_distance(const Point_3 & pt, - const Triangle_3 & t) { - return internal::squared_distance(pt, t, K()); -} - - -template -inline -typename K::FT -squared_distance(const Triangle_3 & t, - const Point_3 & pt) { - return internal::squared_distance(pt, t, K()); -} - - -template -inline -typename K::FT -squared_distance(const Plane_3 & p1, - const Plane_3 & p2) { - K k; - typename K::Construct_orthogonal_vector_3 ortho_vec = - k.construct_orthogonal_vector_3_object(); - if (!internal::is_null(internal::wcross(ortho_vec(p1), ortho_vec(p2), k), k)) - return typename K::FT(0); - else - return internal::squared_distance(p1.point(), p2, k); -} - -} //namespace CGAL - - -#endif diff --git a/Distance_3/include/CGAL/squared_distance_3_3.h b/Distance_3/include/CGAL/squared_distance_3_3.h deleted file mode 100644 index 8f2987a0d5f..00000000000 --- a/Distance_3/include/CGAL/squared_distance_3_3.h +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright (c) 1998-2021 -// Utrecht University (The Netherlands), -// ETH Zurich (Switzerland), -// INRIA Sophia-Antipolis (France), -// Max-Planck-Institute Saarbruecken (Germany), -// and Tel-Aviv University (Israel). All rights reserved. -// -// This file is part of CGAL (www.cgal.org) -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial -// -// -// Author(s) : Geert-Jan Giezeman, Andreas Fabri - - -#ifndef CGAL_DISTANCE_3_3_H -#define CGAL_DISTANCE_3_3_H - -#include - -#include -#include - -namespace CGAL { - -namespace internal { - -template -inline -typename K::FT -squared_distance(const typename K::Tetrahedron_3 & t, - const typename K::Point_3 & pt, - const K& k) -{ - bool on_bounded_side = true; - const typename K::Point_3 t0 = t[0]; - const typename K::Point_3 t1 = t[1]; - const typename K::Point_3 t2 = t[2]; - const typename K::Point_3 t3 = t[3]; - - bool dmin_initialized = false; - typename K::FT dmin; - bool inside = false; - if(orientation(t0,t1,t2, pt) == NEGATIVE){ - on_bounded_side = false; - dmin = squared_distance_to_triangle(pt, t0, t1, t2, inside, k); - dmin_initialized = true; - if(inside){ - return dmin; - } - } - - if(orientation(t0,t3,t1, pt) == NEGATIVE){ - on_bounded_side = false; - const typename K::FT d = squared_distance_to_triangle(pt, t0, t3, t1, inside, k); - if(inside){ - return d; - } - if(! dmin_initialized){ - dmin = d; - dmin_initialized = true; - }else{ - dmin = (std::min)(d,dmin); - } - } - - if(orientation(t1,t3,t2, pt) == NEGATIVE){ - on_bounded_side = false; - const typename K::FT d = squared_distance_to_triangle(pt, t1, t3, t2, inside, k); - if(inside){ - return d; - } - if(! dmin_initialized){ - dmin = d; - dmin_initialized = true; - }else{ - dmin = (std::min)(d,dmin); - } - } - - if(orientation(t2,t3,t0, pt) == NEGATIVE){ - on_bounded_side = false; - const typename K::FT d = squared_distance_to_triangle(pt, t2, t3, t0, inside, k); - if(inside){ - return d; - } - if(! dmin_initialized){ - dmin = d; - dmin_initialized = true; - }else{ - dmin = (std::min)(d,dmin); - } - } - - if(on_bounded_side){ - return typename K::FT(0); - } - return dmin; -} - -} // namespace internal - - -template -typename K::FT -squared_distance(const Tetrahedron_3 & t, - const Point_3 & pt) -{ - return internal::squared_distance(t,pt,K()); -} - - -template -typename K::FT -squared_distance(const Point_3 & pt, - const Tetrahedron_3 & t) -{ - return internal::squared_distance(t,pt,K()); -} - -} //namespace CGAL - - -#endif diff --git a/Distance_3/test/Distance_3/test_distance_3.cpp b/Distance_3/test/Distance_3/test_distance_3.cpp index 0632b699765..29f66c839e1 100644 --- a/Distance_3/test/Distance_3/test_distance_3.cpp +++ b/Distance_3/test/Distance_3/test_distance_3.cpp @@ -1,22 +1,33 @@ -// 3D distance tests. - -#ifdef NDEBUG -#undef NDEBUG //this testsuite requires NDEBUG to be not defined -#endif - #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 #include +#include -const double epsilon = 0.001; - -struct randomint { +struct randomint +{ randomint() ; - int get() const { return sequence[cur]; } - int next() { cur = (cur+1)%11; return get();} + int get() const { return sequence[cur]; } + int next() { + cur = (cur + 1) % 11; + return get(); + } + private: int sequence[11]; int cur; @@ -40,43 +51,32 @@ inline randomint::randomint() randomint ri; -inline double to_nt(int d) +template +struct Test { - return double(d); -} - -template < typename K > -struct Test { - + typedef typename K::RT RT; typedef typename K::FT FT; - typedef CGAL::Point_3< K > P; - typedef CGAL::Line_3< K > L; - typedef CGAL::Segment_3< K > S; - typedef CGAL::Ray_3< K > R; - typedef CGAL::Triangle_3< K > T; - typedef CGAL::Plane_3< K > Pl; - typedef CGAL::Iso_cuboid_3< K > Cub; - typedef CGAL::Tetrahedron_3< K > Tet; + 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; - template < typename Type > - bool approx_equal_nt(const Type &t1, const Type &t2) - { - if (t1 == t2) - return true; - if (CGAL::abs(t1 - t2) / (CGAL::max)(CGAL::abs(t1), CGAL::abs(t2)) < epsilon) - return true; - std::cout << " Approximate comparison failed between : " << t1 << " and " << t2 << "\n"; - return false; - } - - template < typename O1, typename O2 > - void check_squared_distance(const O1& o1, const O2& o2, const FT& result) - { - assert(approx_equal_nt(CGAL::squared_distance(o1, o2), result)); - assert(approx_equal_nt(CGAL::squared_distance(o2, o1), result)); - } +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) { @@ -84,34 +84,119 @@ struct Test { return P(to_nt(x*w), to_nt(y*w), to_nt(z*w), to_nt(w)); } + P random_point() const + { + return P(r.get_double(m, M), r.get_double(m, M), 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; + } + + template + void check_ss_distance(const O1& o1, const O2& o2) + { + FT res = CGAL::squared_distance(o1, o2); + FT asd = compute_squared_distance_interval_between_segments(o1.source(), o1.target(), + o2.source(), o2.target(), K()); + + assert(res == asd); + + std::cout << "input: " << o1.source() << " " << o1.target() << " " << o2.source() << " " << o2.target() << std::endl; + std::cout << "result (old) = " << res << std::endl; + std::cout << "result (new) = " << asd << std::endl; + } + + 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_squared_distance(const O1& o1, const O2& o2, const FT& expected_result) + { + const FT res_o1o2 = CGAL::squared_distance(o1, o2); + const FT res_o2o1 = CGAL::squared_distance(o2, o1); + + assert(are_equal(res_o1o2, expected_result)); + assert(are_equal(res_o2o1, expected_result)); + + do_intersect_check(o1, o2); + do_intersect_check(o1, o2); + } + + template + void check_squared_distance_with_bound(const O1& o1, const O2& o2, const FT& ubound) + { + const FT res_o1o2 = CGAL::squared_distance(o1, o2); + const FT res_o2o1 = CGAL::squared_distance(o2, o1); + + do_intersect_check(o1, o2); + do_intersect_check(o1, o2); + + assert(res_o1o2 <= ubound); + assert(res_o2o1 <= ubound); + } + +private: void P_P() { - std::cout << "Point - Point\n"; - check_squared_distance (p(0, 0, 0), p(0, 0, 0), 0); - check_squared_distance (p(1, 1, 1), p(0, 0, 0), 3); + std::cout << "Point - Point" << std::endl; + check_squared_distance(p(0, 0, 0), p(0, 0, 0), 0); + check_squared_distance(p(3, 5, 7), p(0, 0, 0), 83); } void P_S() { - // Note : the values are not verified by hand - std::cout << "Point - Segment\n"; - check_squared_distance (p(0, 1, 2), S(p(-3, 0, 0), p( 2, 0, 0)), 5); - check_squared_distance (p(0, 1, 2), S(p( 3, 0, 0), p( 2, 0, 0)), 9); - check_squared_distance (p(0, 1, 2), S(p( 2, 0, 0), p( 3, 0, 0)), 9); - check_squared_distance (p(6, 1, 2), S(p( 2, 0, 0), p( 3, 0, 0)), 14); + std::cout << "Point - Segment" << std::endl; + check_squared_distance(p(0, 1, 2), S{p(-3, 0, 0), p( 2, 0, 0)}, 5); + check_squared_distance(p(0, 1, 2), S{p( 3, 0, 0), p( 2, 0, 0)}, 9); + check_squared_distance(p(0, 1, 2), S{p( 2, 0, 0), p( 3, 0, 0)}, 9); + check_squared_distance(p(6, 1, 2), S{p( 2, 0, 0), p( 3, 0, 0)}, 14); } void P_T() { - std::cout << "Point - Triangle\n"; - check_squared_distance (p(0, 1, 2), T(p(0, 0, 0), p( 2, 0, 0), p( 0, 2, 0)), 4); + std::cout << "Point - Triangle" << std::endl; + check_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_squared_distance (p(-1, -1, 0), t, 2); @@ -136,150 +221,475 @@ struct Test { void S_S() { - std::cout << "Segment - Segment\n"; - check_squared_distance (S(p( -8, -7, 0), p( 11, 6, 0)), S(p(23, -27, 2), p( -17, 16, 2)), 4); - check_squared_distance (S(p( 0, 0, 0), p( 5, 0, 0)), S(p( 1, 1, 2), p( 6, 1, 2)), 5); - check_squared_distance (S(p( 0, 0, 0), p( 5, 0, 0)), S(p( 1, 1, 2), p( 2, 1, 2)), 5); - check_squared_distance (S(p( 5, 0, 0), p( 8, 0, 0)), S(p( 1, 1, 2), p( 2, 1, 2)), 14); - check_squared_distance (S(p( 5, 0, 0), p( 0, 0, 0)), S(p( 1, 1, 2), p( 2, 1, 2)), 5); - check_squared_distance (S(p( 0, 0, 0), p( 5, 0, 0)), S(p( 6, 1, 2), p( 8, 1, 2)), 6); - check_squared_distance (S(p( 0, 0, 0), p( 0,-3, 0)), S(p( 1, 4, 2), p( 1, 7, 2)), 21); - check_squared_distance (S(p( 0, 0, 0), p( 5, 0, 0)), S(p( 8, 1, 2), p( 6, 1, 2)), 6); - check_squared_distance (S(p( 0, 0, 0), p( 0, 0, 0)), S(p( 8, 1, 2), p( 6, 1, 2)), 41); - check_squared_distance (S(p( 0, 0, 0), p( 1, 0, 0)), S(p( 2, 1, 2), p( 2, -1, 2)), 5); - check_squared_distance (S(p( 2, 0, 0), p( 0, 2, 0)), S(p( 1, 1, 4), p( 4, 0, 4)), 16); - check_squared_distance (S(p( 10, 0, 0), p( 0,10, 0)), S(p( 6, 6,20), p( 20, 0,20)), 402); - check_squared_distance (S(p(-10,-13, 0), p( 0,10, 0)), S(p(10, 5,20), p( 70,-30,20)), 524.642); - check_squared_distance (S(p( 0, 0, 0), p(30,-10, 0)), S(p(-5, 20,20), p( 40, 30,20)), 824.706); - check_squared_distance (S(p( 4, 0, 0), p(-3, -1, 0)), S(p( 1, 1, 2), p( 2, 11, 2)), 6); - check_squared_distance (S(p( 3, 4, 0), p( 7, 7, 0)), S(p( 7, 0, 2), p( 6, 5, 2)), 5); - check_squared_distance (S(p( -1, 1, 0), p( 3, 4, 0)), S(p( 7, 0, 2), p( 6, 5, 2)), 13.8462); + std::cout << "Segment - Segment" << std::endl; + + // coplanar segments (hardcoded) + double z = std::sqrt(2.); + P p0{-1, 0, z}; + P p1{ 1, 0, z}; + + // translations of (0, -1, z) -- (0, 1, z) to have all variations of x&y (<0, [0;1]; >1) 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_squared_distance(S{p0, p1}, S{p2, p3}, CGAL::squared_distance(p3, p0)); + else if(j == -2 && k == -1) + check_squared_distance(S{p0, p1}, S{p2, p3}, 1); + else if(j == -2 && k == 1) + check_squared_distance(S{p0, p1}, S{p2, p3}, CGAL::squared_distance(p2, p0)); + else if(j == 0 && k == -3) + check_squared_distance(S{p0, p1}, S{p2, p3}, 1); + else if(j == 0 && k == -1) + check_squared_distance(S{p0, p1}, S{p2, p3}, 0); + else if(j == 0 && k == 1) + check_squared_distance(S{p0, p1}, S{p2, p3}, 1); + else if(j == 2 && k == -3) + check_squared_distance(S{p0, p1}, S{p2, p3}, CGAL::squared_distance(p3, p1)); + else if(j == 2 && k == -1) + check_squared_distance(S{p0, p1}, S{p2, p3}, 1); + else if(j == 2 && k == 1) + check_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 << "3D Distance tests\n"; + std::cout << "Kernel: " << typeid(K).name() << std::endl; + P_P(); P_S(); - P_T(); - P_Tet(); - S_S(); P_R(); - R_R(); - S_R(); - R_L(); P_L(); - S_L(); - L_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() { - Test< CGAL::Simple_cartesian >().run(); - Test< CGAL::Simple_homogeneous >().run(); - // TODO : test more kernels. + 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/Documentation/doc/CMakeLists.txt b/Documentation/doc/CMakeLists.txt index 5ff79cbed2c..e069d2eb4e8 100644 --- a/Documentation/doc/CMakeLists.txt +++ b/Documentation/doc/CMakeLists.txt @@ -27,7 +27,7 @@ else() endif() find_package(Doxygen) -find_package(PythonInterp) +find_package(Python3 COMPONENTS Interpreter) if(NOT DOXYGEN_FOUND) message(WARNING "Cannot build the documentation without Doxygen!") @@ -322,9 +322,9 @@ endif() set(CGAL_DOC_VERSION ${CGAL_CREATED_VERSION_NUM}) ## generate how_to_cite files -if(PYTHONINTERP_FOUND) +if(Python3_Interpreter_FOUND) execute_process( - COMMAND ${PYTHON_EXECUTABLE} ${CGAL_DOC_SCRIPT_DIR}/generate_how_to_cite.py + COMMAND ${Python3_EXECUTABLE} ${CGAL_DOC_SCRIPT_DIR}/generate_how_to_cite.py ${CGAL_ROOT} ${CMAKE_BINARY_DIR} "${CGAL_BRANCH_BUILD}" RESULT_VARIABLE GENERATE_HOW_TO_CITE_RESULT) if(NOT GENERATE_HOW_TO_CITE_RESULT EQUAL "0") @@ -436,25 +436,25 @@ add_dependencies(Documentation_copy_doc_tags doc_pre) #total level doc dependencies add_dependencies(doc doc_post) -if(PYTHONINTERP_FOUND) +if(Python3_Interpreter_FOUND) set(CGAL_DOC_TESTSUITE_SCRIPT "${CGAL_DOC_SCRIPT_DIR}/testsuite.py") add_custom_target( doc_with_postprocessing - ${PYTHON_EXECUTABLE} ${CGAL_DOC_SCRIPT_DIR}/html_output_post_processing.py + ${Python3_EXECUTABLE} ${CGAL_DOC_SCRIPT_DIR}/html_output_post_processing.py --output ${CGAL_DOC_OUTPUT_DIR} --resources ${CGAL_DOC_RESOURCE_DIR}) add_dependencies(doc_with_postprocessing doc) if(CGAL_DOC_CREATE_LOGS) add_custom_target( Documentation_test - ${PYTHON_EXECUTABLE} ${CGAL_DOC_TESTSUITE_SCRIPT} --output-dir + ${Python3_EXECUTABLE} ${CGAL_DOC_TESTSUITE_SCRIPT} --output-dir ${CGAL_DOC_OUTPUT_DIR} --doc-log-dir ${CGAL_DOC_LOG_DIR}) add_dependencies(Documentation_test doc) add_custom_target( Documentation_test_publish - ${PYTHON_EXECUTABLE} + ${Python3_EXECUTABLE} ${CGAL_DOC_TESTSUITE_SCRIPT} --output-dir ${CGAL_DOC_OUTPUT_DIR} @@ -467,7 +467,7 @@ if(PYTHONINTERP_FOUND) add_custom_target( doc_and_publish_testsuite - ${PYTHON_EXECUTABLE} + ${Python3_EXECUTABLE} ${CGAL_DOC_TESTSUITE_SCRIPT} --output-dir ${CGAL_DOC_OUTPUT_DIR} diff --git a/Documentation/doc/Documentation/advanced/Configuration_variables.txt b/Documentation/doc/Documentation/advanced/Configuration_variables.txt index 249b6cbe0b9..2d7299bd36d 100644 --- a/Documentation/doc/Documentation/advanced/Configuration_variables.txt +++ b/Documentation/doc/Documentation/advanced/Configuration_variables.txt @@ -327,8 +327,10 @@ cmake variables is necessary. \subsection installation_tbb TBB Library -If \tbb is not automatically found, the user must set the `TBB_ROOT` -environment variable. The environment variable `TBB_ARCH_PLATFORM=/` must be set. +If \tbb is not automatically found, the user must set some variables, depending on the used version of TBB. + +\subsubsection installation_old_tbb TBB 2020 or before +The `TBB_ROOT` and `TBB_ARCH_PLATFORM=/` environment variables must be set. `` is `ia32` or `intel64`. `` describes the Linux kernel, gcc version or Visual Studio version used. It should be set to what is used in `$TBB_ROOT/lib/`. @@ -349,6 +351,14 @@ Note that the variables in the table below are being used. | `TBB_MALLOCPROXY_DEBUG_LIBRARY` | Full pathname of the compiled TBB debug malloc_proxy library (optional) | CMake | | `TBB_MALLOCPROXY_RELEASE_LIBRARY` | Full pathname of the compiled TBB release malloc_proxy library (optional) | CMake | +\subsubsection installation_new_tbb OneTBB +Since OneAPI \tbb version 2021, Intel provides CMake scripts of their own, and the user only have to set the `TBB_DIR` +CMake variable at configuration time. A typical value for `TBB_DIR` is +`/opt/intel/oneapi/tbb/latest/lib/cmake/tbb` on Unix systems, and `C:/dev/OneAPI/tbb/latest/lib/cmake/tbb` on Windows. +Alternatively, the user can instead source the `setvars` script that can be found at `/opt/intel/oneapi/setvars.sh` on Unix and +`C:/dev/OneAPI/setvars.bat` on Windows. It will setup the PATH and all Intel internal variables to be able to easily use +any library of the OneAPI. + \subsection installation_laslib LASlib library If LASLIB is not automatically found, the following variables must be set: @@ -382,9 +392,7 @@ If GLPK is not automatically found, the following variables must be set: A number of boolean flags are used to workaround compiler bugs and limitations. They all start with the prefix `CGAL_CFG`. These -flags are used to work around compiler bugs and limitations. For -example, the flag `CGAL_CFG_NO_CPP0X_LONG_LONG` denotes -that the compiler does not know the type `long long`. +flags are used to work around compiler bugs and limitations. For each installation a file is defined, with the correct diff --git a/Documentation/doc/scripts/documentation_parser.py b/Documentation/doc/scripts/documentation_parser.py index 462291efae6..ce117b098db 100644 --- a/Documentation/doc/scripts/documentation_parser.py +++ b/Documentation/doc/scripts/documentation_parser.py @@ -4,6 +4,7 @@ from pyquery import PyQuery as pq from collections import defaultdict from sys import argv import os.path as op +import codecs # if _in is part of args, return true. def check_type(_in, args): @@ -33,7 +34,8 @@ for i in range(0,len(compounds)): filepath='class'+compound+'.xml' total_path=op.join(op.sep, root_path,filepath) if(op.isfile(total_path)): - e = pq(filename=total_path, parser="xml") + file_content = codecs.open(total_path, 'rb') + e = pq(file_content.read(), parser="xml") compoundnames=[p.text() for p in list(e('includes').items())] if(len(compoundnames) > 1 and compoundnames[0].find("Concept") != -1): diff --git a/Documentation/doc/scripts/generate_how_to_cite.py b/Documentation/doc/scripts/generate_how_to_cite.py index 0f02a1a8500..e1108d6a51f 100644 --- a/Documentation/doc/scripts/generate_how_to_cite.py +++ b/Documentation/doc/scripts/generate_how_to_cite.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # coding: utf8 import re @@ -157,7 +157,7 @@ def protect_upper_case(title): return title.replace("dD","{dD}").replace("2D","{2D}").replace("3D","{3D}").replace("CGAL","{CGAL}").replace("Qt","{Qt}").replace("Boost","{Boost}") def protect_accentuated_letters(authors): - res=authors.replace(u"é",r"{\'e}").replace(u"è",r"{\`e}").replace(u"É",r"{\'E}").replace(u"ä",r"{\"a}").replace(u"ö",r"{\"o}").replace(u"ñ",r"{\~n}").replace(u"ã",r"{\~a}").replace(u"ë",r"{\"e}").replace(u"ı",r"{\i}").replace(u"Ş",r"{\c{S}}").replace(u"ş",r"{\c{s}}").replace("%","") + res=authors.replace("é",r"{\'e}").replace("è",r"{\`e}").replace("É",r"{\'E}").replace("ä",r"{\"a}").replace("ö",r"{\"o}").replace("ñ",r"{\~n}").replace("ã",r"{\~a}").replace("ë",r"{\"e}").replace("ı",r"{\i}").replace("Ş",r"{\c{S}}").replace("ş",r"{\c{s}}").replace("%","") try: res.encode('ascii') except UnicodeEncodeError: diff --git a/Documentation/doc/scripts/html_output_post_processing.py b/Documentation/doc/scripts/html_output_post_processing.py index f963ac29744..f01a02f1eef 100755 --- a/Documentation/doc/scripts/html_output_post_processing.py +++ b/Documentation/doc/scripts/html_output_post_processing.py @@ -56,13 +56,14 @@ def write_out_html(d, fn): # this is the normal doxygen doctype, which is thrown away by pyquery f.write('\n') f.write('') - f.write(d.html()) + if d.html() is not None: + f.write(d.html()) f.write('\n') f.write('\n') f.close() def package_glob(target): - return filter(lambda x: not os.path.join(os.path.join('.','Manual'),'') in x, glob.glob(target)) + return [x for x in glob.glob(target) if not os.path.join(os.path.join('.','Manual'),'') in x] # remove duplicate files def clean_doc(): @@ -127,7 +128,8 @@ def re_replace_first_in_file(pat, s_after, fname): def is_concept_file(filename): if not path.exists(filename): return False; - d = pq(filename=filename, parser='html', encoding='utf-8') + file_content = codecs.open(filename, 'r', encoding='utf-8') + d = pq(file_content.read(),parser="html") ident = d('#CGALConcept') return ident.size() == 1 @@ -190,7 +192,8 @@ def automagically_number_figures(): return - d = pq(filename="./Manual/packages.html", parser='html', encoding='utf-8') + file_content = codecs.open("./Manual/packages.html", 'r', encoding='utf-8') + d = pq(file_content.read(),parser="html") for el in d('a.elRef'): text = pq(el).attr('href') if text.find("index.html")!=-1: @@ -210,14 +213,16 @@ def automagically_number_figures(): all_pkg_files.remove(userman) for fname in [userman]+all_pkg_files: infos=figure_anchor_info(pkg_id, global_anchor_map) - d = pq(filename=fname, parser='html', encoding='utf-8') + file_content = codecs.open(fname, 'r', encoding='utf-8') + d = pq(file_content.read(), parser="html") d('a.anchor').each( lambda i: collect_figure_anchors(i,infos) ) pkg_id+=1 #Figure link dev Manual for fname in glob.glob("Manual/*.html"): infos=figure_anchor_info(0, global_anchor_map) - d = pq(filename=fname, parser='html', encoding='utf-8') + file_content = codecs.open(fname, 'r', encoding='utf-8') + d = pq(file_content.read(),parser="html") d('a.anchor').each( lambda i: collect_figure_anchors(i,infos) ) #replace each link to a figure by its unique id @@ -227,7 +232,8 @@ def automagically_number_figures(): with codecs.open(fname, encoding='utf-8') as f: if not any(re.search("fig__", line) for line in f): continue # pattern does not occur in file so we are done. - d = pq(filename=fname, parser='html', encoding='utf-8') + file_content = codecs.open(fname, 'r', encoding='utf-8') + d = pq(file_content.read(), parser="html") d('a.el').each( lambda i: update_figure_ref(i,global_anchor_map) ) d('a.elRef').each( lambda i: update_figure_ref(i,global_anchor_map) ) write_out_html(d, fname) @@ -261,7 +267,8 @@ removes some unneeded files, and performs minor repair on some glitches.''') re_replace_in_file("N", "N", fn) re_replace_in_file("C", "C", fn) dir_name=path.dirname(fn) - d = pq(filename=fn, parser='html', encoding='utf-8') + file_content = codecs.open(fn, 'r', encoding='utf-8') + d = pq(file_content.read(), parser="html") tr_tags = d('table.directory tr img') tr_tags.each(lambda i: rearrange_img(i, dir_name)) span_tags = d('table.directory tr span') @@ -270,7 +277,8 @@ removes some unneeded files, and performs minor repair on some glitches.''') class_files=list(package_glob('./*/class*.html')) class_files.extend(package_glob('./*/struct*.html')) for fn in class_files: - d = pq(filename=fn, parser='html', encoding='utf-8') + file_content = codecs.open(fn, 'r', encoding='utf-8') + d = pq(file_content.read(), parser="html") ident = d('#CGALConcept') if ident.size() == 1: conceptify(d); @@ -284,7 +292,8 @@ removes some unneeded files, and performs minor repair on some glitches.''') namespace_files=package_glob('./*/namespace*.html') for fn in namespace_files: - d = pq(filename=fn, parser='html', encoding='utf-8') + file_content = codecs.open(fn, 'r', encoding='utf-8') + d = pq(file_content.read(), parser="html") ident = d('#CGALConceptNS') if ident.size() == 1: conceptify_ns(d); @@ -294,14 +303,16 @@ removes some unneeded files, and performs minor repair on some glitches.''') # in a group we only need to change the nested-classes group_files=package_glob('./*/group*Concepts*.html') for fn in group_files: - d = pq(filename=fn, parser='html',encoding='utf-8') + file_content = codecs.open(fn, 'r', encoding='utf-8') + d = pq(file_content.read(), parser="html") conceptify_nested_classes(d) write_out_html(d, fn) # fix up Files files_files=package_glob('./*/files.html') for fn in files_files: - d = pq(filename=fn, parser='html',encoding='utf-8') + file_content = codecs.open(fn, 'r', encoding='utf-8') + d = pq(file_content.read(), parser="html") table = d("table.directory") row_id=table("td.entry").filter(lambda i: pq(this).text() == 'Concepts').parent().attr('id') if row_id != None: @@ -331,7 +342,8 @@ removes some unneeded files, and performs minor repair on some glitches.''') relationship_pages.extend(package_glob('./*/generalizes.html')) relationship_pages.extend(package_glob('./*/refines.html')) for fn in relationship_pages: - d = pq(filename=fn, parser='html',encoding='utf-8') + file_content = codecs.open(fn, 'r', encoding='utf-8') + d = pq(file_content.read(), parser="html") dts=d(".textblock .reflist dt") # no contents() on pyquery, do it the hard way # Note that in the following regular expression, the Struct did not appear in doxygen version 1.8.3 @@ -343,7 +355,8 @@ removes some unneeded files, and performs minor repair on some glitches.''') # throw out nav-sync all_pages=glob.glob('./*/*.html') for fn in all_pages: - d = pq(filename=fn, parser='html',encoding='utf-8') + file_content = codecs.open(fn, 'r', encoding='utf-8') + d = pq(file_content.read(), parser="html") d('#nav-sync').hide() # TODO count figures write_out_html(d, fn) @@ -366,7 +379,8 @@ removes some unneeded files, and performs minor repair on some glitches.''') # remove class name in Definition section if there is no default template # parameter documented for fn in class_and_struct_files: - d = pq(filename=fn, parser='html',encoding='utf-8') + file_content = codecs.open(fn, 'r', encoding='utf-8') + d = pq(file_content.read(), parser="html") for el in d('h3'): text = pq(el).text() if text[0:9]=="template<" and text.find('=')==-1: diff --git a/Documentation/doc/scripts/process_doc.sh b/Documentation/doc/scripts/process_doc.sh index a447df9cae9..a41940ee2fd 100644 --- a/Documentation/doc/scripts/process_doc.sh +++ b/Documentation/doc/scripts/process_doc.sh @@ -53,7 +53,11 @@ PATH_TO_MASTER="$PWD/doxygen_master/build/bin/doxygen" echo "done." echo "comparing versions 1.8.4 and 1.8.13" -bash -$- test_doxygen_versions.sh $PATH_TO_1_8_4 $PATH_TO_1_8_13 $PWD/doc_1_8_4 $PWD/doc_1_8_13 $PUBLISH_DIR +bash -$- test_doxygen_versions.sh $PATH_TO_1_8_4 $PATH_TO_1_8_13 $PWD/doc_1_8_4 $PWD/doc_1_8_13 $PUBLISH_DIR +if [ ! -d $PWD/doc_1_8_13/doc_log ]; then + echo "NO DOC LOGS." + exit 1 +fi mv diff.txt diff1.txt echo "comparing versions 1.8.4 and master" @@ -70,13 +74,13 @@ fi #update overview CGAL_NAME=$(cat cgal_version) if [ "$DO_COMPARE" = "TRUE" ]; then - python ${PWD}/testsuite.py --output-dir1 $PWD/doc_1_8_4/doc_output/ --output-dir2 $PWD/doc_1_8_13/doc_output/ --doc-log-dir1 $PWD/doc_1_8_4/doc_log/ \ + python3 ${PWD}/testsuite.py --output-dir1 $PWD/doc_1_8_4/doc_output/ --output-dir2 $PWD/doc_1_8_13/doc_output/ --doc-log-dir1 $PWD/doc_1_8_4/doc_log/ \ --doc-log-dir2 $PWD/doc_1_8_13/doc_log/ --doc-log-dir-master $PWD/doc_master/doc_log/ \ --publish $PUBLISH_DIR --diff1 $PWD/diff1.txt --diff2 $PWD/diff2.txt --master-dir $PWD/doc_master/doc_output/ \ --cgal-version "$CGAL_NAME" --do-copy-results --version-to-keep 10 --doxygen-version1 "$DOXYGEN_1" --doxygen-version2 "$DOXYGEN_2" --master-describe "$MASTER_DESCRIBE" else echo "NO MASTER" - python ${PWD}/testsuite.py --output-dir1 $PWD/doc_1_8_4/doc_output/ --output-dir2 $PWD/doc_1_8_13/doc_output/ --doc-log-dir1 $PWD/doc_1_8_4/doc_log/ \ + python3 ${PWD}/testsuite.py --output-dir1 $PWD/doc_1_8_4/doc_output/ --output-dir2 $PWD/doc_1_8_13/doc_output/ --doc-log-dir1 $PWD/doc_1_8_4/doc_log/ \ --doc-log-dir2 $PWD/doc_1_8_13/doc_log/ --doc-log-dir-master $PWD/doc_master/ \ --publish $PUBLISH_DIR --diff1 $PWD/diff1.txt \ --cgal-version "$CGAL_NAME" --do-copy-results --version-to-keep 10 --doxygen-version1 "$DOXYGEN_1" --doxygen-version2 "$DOXYGEN_2" diff --git a/Documentation/doc/scripts/testsuite.py b/Documentation/doc/scripts/testsuite.py index efaa0f31f0c..89819f1e591 100755 --- a/Documentation/doc/scripts/testsuite.py +++ b/Documentation/doc/scripts/testsuite.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright (c) 2012 GeometryFactory (France). All rights reserved. # All rights reserved. # @@ -88,7 +88,7 @@ body {color: black; background-color: #C0C0D0; font-family: sans-serif;} Errors ''' - + if args.publish and args.do_copy_results: suffix='' if args.doxygen_version1: @@ -97,7 +97,7 @@ body {color: black; background-color: #C0C0D0; font-family: sans-serif;} suffix = '' if args.doxygen_version2: suffix = args.doxygen_version2 - link2="\n
Documentation built with our fork of Doxygen {_suffix} (used for the official CGAL documentation)\n".format(_suffix=suffix) + link2="\n
Documentation built with our fork of Doxygen {_suffix} (used for the official CGAL documentation)\n".format(_suffix=suffix) suffix = '' if args.master_describe: suffix=args.master_describe diff --git a/Filtered_kernel/benchmark/Filtered_kernel/Orientation_3.h b/Filtered_kernel/benchmark/Filtered_kernel/Orientation_3.h index e21ea6d4981..b1ec9224787 100644 --- a/Filtered_kernel/benchmark/Filtered_kernel/Orientation_3.h +++ b/Filtered_kernel/benchmark/Filtered_kernel/Orientation_3.h @@ -12,8 +12,8 @@ #include -#include -#include +#include +#include #include namespace CGAL { namespace internal { namespace Static_filters_predicates { diff --git a/Filtered_kernel/include/CGAL/Filtered_construction.h b/Filtered_kernel/include/CGAL/Filtered_construction.h index c755d3a1eab..51910605980 100644 --- a/Filtered_kernel/include/CGAL/Filtered_construction.h +++ b/Filtered_kernel/include/CGAL/Filtered_construction.h @@ -44,54 +44,60 @@ public: result_type operator()(const A1 &a1) const { - // Protection is outside the try block as VC8 has the CGAL_CFG_FPU_ROUNDING_MODE_UNWINDING_VC_BUG - Protect_FPU_rounding P1; - try { - return From_Filtered( Filter_construction(To_Filtered(a1)) ); - } - catch (Uncertain_conversion_exception&) - { - Protect_FPU_rounding P(CGAL_FE_TONEAREST); - return From_Exact( Exact_construction(To_Exact(a1)) ); + // Protection is outside the try block as VC8 has the CGAL_CFG_FPU_ROUNDING_MODE_UNWINDING_VC_BUG + Protect_FPU_rounding P1; + try + { + return From_Filtered( Filter_construction(To_Filtered(a1)) ); + } + catch (Uncertain_conversion_exception&) + {} } + Protect_FPU_rounding P(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); + return From_Exact( Exact_construction(To_Exact(a1)) ); } template result_type operator()(const A1 &a1, const A2 &a2) const { - Protect_FPU_rounding P1; - try { - return From_Filtered( Filter_construction(To_Filtered(a1), - To_Filtered(a2)) ); - } - catch (Uncertain_conversion_exception&) - { - Protect_FPU_rounding P(CGAL_FE_TONEAREST); - return From_Exact( Exact_construction(To_Exact(a1), - To_Exact(a2)) ); + Protect_FPU_rounding P1; + try + { + return From_Filtered( Filter_construction(To_Filtered(a1), + To_Filtered(a2)) ); + } + catch (Uncertain_conversion_exception&) + {} } + Protect_FPU_rounding P(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); + return From_Exact( Exact_construction(To_Exact(a1), + To_Exact(a2)) ); } template result_type operator()(const A1 &a1, const A2 &a2, const A3 &a3) const { - Protect_FPU_rounding P1; - try { - return From_Filtered( Filter_construction(To_Filtered(a1), - To_Filtered(a2), - To_Filtered(a3)) ); - } - catch (Uncertain_conversion_exception&) - { - Protect_FPU_rounding P(CGAL_FE_TONEAREST); - return From_Exact( Exact_construction(To_Exact(a1), - To_Exact(a2), - To_Exact(a3)) ); + Protect_FPU_rounding P1; + try + { + return From_Filtered( Filter_construction(To_Filtered(a1), + To_Filtered(a2), + To_Filtered(a3)) ); + } + catch (Uncertain_conversion_exception&) + {} } + Protect_FPU_rounding P(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); + return From_Exact( Exact_construction(To_Exact(a1), + To_Exact(a2), + To_Exact(a3)) ); } }; diff --git a/Filtered_kernel/include/CGAL/Filtered_kernel.h b/Filtered_kernel/include/CGAL/Filtered_kernel.h index f412d781922..81b8bd4d07d 100644 --- a/Filtered_kernel/include/CGAL/Filtered_kernel.h +++ b/Filtered_kernel/include/CGAL/Filtered_kernel.h @@ -25,7 +25,7 @@ #include #include -#include +#include #include // This file contains the definition of a generic kernel filter. diff --git a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Angle_3.h b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Angle_3.h similarity index 96% rename from Filtered_kernel/include/CGAL/Filtered_kernel/internal/Angle_3.h rename to Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Angle_3.h index 15e69d0801a..ac57decb63e 100644 --- a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Angle_3.h +++ b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Angle_3.h @@ -16,8 +16,8 @@ #include #include -#include -#include +#include +#include #include #include diff --git a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Collinear_3.h b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Collinear_3.h similarity index 94% rename from Filtered_kernel/include/CGAL/Filtered_kernel/internal/Collinear_3.h rename to Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Collinear_3.h index 40d32e5c0f0..9279f60c3d2 100644 --- a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Collinear_3.h +++ b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Collinear_3.h @@ -14,16 +14,12 @@ #define CGAL_INTERNAL_STATIC_FILTERS_COLLINEAR_3_H #include -#include -#include +#include +#include #include namespace CGAL { namespace internal { namespace Static_filters_predicates { - -#include - - template < typename K_base > class Collinear_3 : public K_base::Collinear_3 @@ -54,6 +50,8 @@ public: fit_in_double(get_approx(r).x(), rx) && fit_in_double(get_approx(r).y(), ry) && fit_in_double(get_approx(r).z(), rz)) { + CGAL_BRANCH_PROFILER_BRANCH_1(tmp); + double dpx = (px - rx); double dqx = (qx - rx); double dpy = (py - ry); @@ -81,6 +79,7 @@ public: if (CGAL::abs(double_tmp_result) > eps ) return false; } + double dpz = (pz - rz); double dqz = (qz - rz); @@ -119,7 +118,10 @@ public: if (CGAL::abs(double_tmp_result_AvrrXBP) > eps) return false; } + + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); } + return Base::operator()(p, q, r); } diff --git a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Compare_distance_3.h b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Compare_distance_3.h similarity index 98% rename from Filtered_kernel/include/CGAL/Filtered_kernel/internal/Compare_distance_3.h rename to Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Compare_distance_3.h index 9655772b136..f3880b3f0e2 100644 --- a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Compare_distance_3.h +++ b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Compare_distance_3.h @@ -15,7 +15,7 @@ #define CGAL_INTERNAL_STATIC_FILTERS_COMPARE_DISTANCE_3_H #include -#include +#include #include #include diff --git a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Compare_squared_radius_3.h b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Compare_squared_radius_3.h similarity index 99% rename from Filtered_kernel/include/CGAL/Filtered_kernel/internal/Compare_squared_radius_3.h rename to Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Compare_squared_radius_3.h index a2e35572f9a..8e0683677aa 100644 --- a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Compare_squared_radius_3.h +++ b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Compare_squared_radius_3.h @@ -15,7 +15,7 @@ #define CGAL_INTERNAL_STATIC_FILTERS_COMPARE_SQUARED_RADIUS_3_H #include -#include +#include #include namespace CGAL { namespace internal { namespace Static_filters_predicates { diff --git a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Compare_weighted_squared_radius_3.h b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Compare_weighted_squared_radius_3.h similarity index 99% rename from Filtered_kernel/include/CGAL/Filtered_kernel/internal/Compare_weighted_squared_radius_3.h rename to Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Compare_weighted_squared_radius_3.h index b332ac9c4a5..41b9f1b9e77 100644 --- a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Compare_weighted_squared_radius_3.h +++ b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Compare_weighted_squared_radius_3.h @@ -15,8 +15,8 @@ #define CGAL_INTERNAL_STATIC_FILTERS_COMPARE_WEIGHTED_SQUARED_RADIUS_3_H #include -#include -#include +#include +#include #include diff --git a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Compare_x_2.h b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Compare_x_2.h similarity index 96% rename from Filtered_kernel/include/CGAL/Filtered_kernel/internal/Compare_x_2.h rename to Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Compare_x_2.h index 8df13f7de1b..29c6d291051 100644 --- a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Compare_x_2.h +++ b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Compare_x_2.h @@ -16,7 +16,7 @@ #include #include -#include +#include #include #include diff --git a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Compare_y_2.h b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Compare_y_2.h similarity index 96% rename from Filtered_kernel/include/CGAL/Filtered_kernel/internal/Compare_y_2.h rename to Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Compare_y_2.h index 8aa302fb504..da9b97215a8 100644 --- a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Compare_y_2.h +++ b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Compare_y_2.h @@ -16,7 +16,7 @@ #include #include -#include +#include #include #include diff --git a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Compare_y_at_x_2.h b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Compare_y_at_x_2.h similarity index 96% rename from Filtered_kernel/include/CGAL/Filtered_kernel/internal/Compare_y_at_x_2.h rename to Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Compare_y_at_x_2.h index 6c3e3e4c687..5de1af9d7b2 100644 --- a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Compare_y_at_x_2.h +++ b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Compare_y_at_x_2.h @@ -13,7 +13,7 @@ #define CGAL_INTERNAL_STATIC_FILTERS_COMPARE_Y_AT_X_2_H #include -#include +#include #include namespace CGAL { namespace internal { namespace Static_filters_predicates { diff --git a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Coplanar_3.h b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Coplanar_3.h similarity index 100% rename from Filtered_kernel/include/CGAL/Filtered_kernel/internal/Coplanar_3.h rename to Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Coplanar_3.h diff --git a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Coplanar_orientation_3.h b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Coplanar_orientation_3.h similarity index 100% rename from Filtered_kernel/include/CGAL/Filtered_kernel/internal/Coplanar_orientation_3.h rename to Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Coplanar_orientation_3.h diff --git a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Coplanar_side_of_bounded_circle_3.h b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Coplanar_side_of_bounded_circle_3.h similarity index 97% rename from Filtered_kernel/include/CGAL/Filtered_kernel/internal/Coplanar_side_of_bounded_circle_3.h rename to Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Coplanar_side_of_bounded_circle_3.h index 378f1763cc0..48c96ec886c 100644 --- a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Coplanar_side_of_bounded_circle_3.h +++ b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Coplanar_side_of_bounded_circle_3.h @@ -17,7 +17,7 @@ #include #include #include -// #include // Only used to precompute constants +// #include // Only used to precompute constants namespace CGAL { namespace internal { namespace Static_filters_predicates { diff --git a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Do_intersect_2.h b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Do_intersect_2.h similarity index 100% rename from Filtered_kernel/include/CGAL/Filtered_kernel/internal/Do_intersect_2.h rename to Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Do_intersect_2.h diff --git a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Do_intersect_3.h b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Do_intersect_3.h similarity index 98% rename from Filtered_kernel/include/CGAL/Filtered_kernel/internal/Do_intersect_3.h rename to Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Do_intersect_3.h index 8744c8bbf3c..31f71e86b58 100644 --- a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Do_intersect_3.h +++ b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Do_intersect_3.h @@ -18,8 +18,8 @@ #include #include -#include -#include +#include +#include #include // for CGAL::internal::do_intersect_bbox_segment_aux diff --git a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Equal_2.h b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Equal_2.h similarity index 97% rename from Filtered_kernel/include/CGAL/Filtered_kernel/internal/Equal_2.h rename to Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Equal_2.h index 4ac61d5d926..60b2360a939 100644 --- a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Equal_2.h +++ b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Equal_2.h @@ -16,7 +16,7 @@ #include #include -#include +#include #include #include diff --git a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Equal_3.h b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Equal_3.h similarity index 98% rename from Filtered_kernel/include/CGAL/Filtered_kernel/internal/Equal_3.h rename to Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Equal_3.h index ecea5750446..10c44051ae2 100644 --- a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Equal_3.h +++ b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Equal_3.h @@ -16,7 +16,7 @@ #include #include -#include +#include #include #include diff --git a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Is_degenerate_3.h b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Is_degenerate_3.h similarity index 100% rename from Filtered_kernel/include/CGAL/Filtered_kernel/internal/Is_degenerate_3.h rename to Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Is_degenerate_3.h diff --git a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Orientation_2.h b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Orientation_2.h similarity index 97% rename from Filtered_kernel/include/CGAL/Filtered_kernel/internal/Orientation_2.h rename to Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Orientation_2.h index 8f39ebc994f..cbb4494e7cd 100644 --- a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Orientation_2.h +++ b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Orientation_2.h @@ -15,7 +15,7 @@ #include #include -#include +#include #include diff --git a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Orientation_3.h b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Orientation_3.h similarity index 98% rename from Filtered_kernel/include/CGAL/Filtered_kernel/internal/Orientation_3.h rename to Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Orientation_3.h index 8852525eb9a..2fdffde6fda 100644 --- a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Orientation_3.h +++ b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Orientation_3.h @@ -14,7 +14,7 @@ #define CGAL_INTERNAL_STATIC_FILTERS_ORIENTATION_3_H #include -#include +#include #include namespace CGAL { namespace internal { namespace Static_filters_predicates { diff --git a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Power_side_of_oriented_power_sphere_3.h b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Power_side_of_oriented_power_sphere_3.h similarity index 99% rename from Filtered_kernel/include/CGAL/Filtered_kernel/internal/Power_side_of_oriented_power_sphere_3.h rename to Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Power_side_of_oriented_power_sphere_3.h index 5efa4b115f9..d4621b756a5 100644 --- a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Power_side_of_oriented_power_sphere_3.h +++ b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Power_side_of_oriented_power_sphere_3.h @@ -15,8 +15,8 @@ #define CGAL_INTERNAL_STATIC_FILTERS_POWER_TEST_3_H #include -#include -#include +#include +#include #include diff --git a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Side_of_oriented_circle_2.h b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Side_of_oriented_circle_2.h similarity index 98% rename from Filtered_kernel/include/CGAL/Filtered_kernel/internal/Side_of_oriented_circle_2.h rename to Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Side_of_oriented_circle_2.h index 05bdd3f30de..3b59fed08db 100644 --- a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Side_of_oriented_circle_2.h +++ b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Side_of_oriented_circle_2.h @@ -14,7 +14,7 @@ #define CGAL_INTERNAL_STATIC_FILTERS_SIDE_OF_ORIENTED_CIRCLE_2_H #include -#include +#include #include namespace CGAL { namespace internal { namespace Static_filters_predicates { diff --git a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Side_of_oriented_sphere_3.h b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Side_of_oriented_sphere_3.h similarity index 98% rename from Filtered_kernel/include/CGAL/Filtered_kernel/internal/Side_of_oriented_sphere_3.h rename to Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Side_of_oriented_sphere_3.h index af3fd6084eb..41a54d33012 100644 --- a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Side_of_oriented_sphere_3.h +++ b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Side_of_oriented_sphere_3.h @@ -14,7 +14,7 @@ #define CGAL_INTERNAL_STATIC_FILTERS_SIDE_OF_ORIENTED_SPHERE_3_H #include -#include +#include namespace CGAL { namespace internal { namespace Static_filters_predicates { diff --git a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filter_error.h b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Static_filter_error.h similarity index 100% rename from Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filter_error.h rename to Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Static_filter_error.h diff --git a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters.h b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Static_filters.h similarity index 85% rename from Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters.h rename to Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Static_filters.h index 0768f98ed30..72f4d220c09 100644 --- a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters.h +++ b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/Static_filters.h @@ -26,10 +26,10 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include // for static filters added nov./dec. 2011 #ifdef CGAL_DISABLE_STATIC_FILTERS_ADDED_2011 @@ -42,39 +42,39 @@ #endif // CGAL_DISABLE_STATIC_FILTERS_ADDED_2011 #ifndef CGAL_NO_EQUAL_3_STATIC_FILTERS -# include -# include +# include +# include #endif // NOT CGAL_NO_EQUAL_3_STATIC_FILTERS #ifndef CGAL_NO_COMPARE_X_2_STATIC_FILTERS -# include -# include +# include +# include #endif // NOT CGAL_NO_COMPARE_X_2_STATIC_FILTERS #ifndef CGAL_NO_IS_DEGENERATE_3_STATIC_FILTERS -# include +# include #endif // NOT CGAL_NO_IS_DEGENERATE_3_STATIC_FILTERS #ifndef CGAL_NO_ANGLE_3_STATIC_FILTERS -# include +# include #endif // NOT CGAL_NO_ANGLE_3_STATIC_FILTERS #ifndef CGAL_NO_DO_INTERSECT_STATIC_FILTERS -# include -# include +# include +# include #endif // NOT NOT CGAL_NO_DO_INTERSECT_STATIC_FILTERS -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include -// #include -// #include +// #include +// #include // TODO : // - add more predicates : diff --git a/Filtered_kernel/include/CGAL/Filtered_kernel/internal/tools.h b/Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/tools.h similarity index 100% rename from Filtered_kernel/include/CGAL/Filtered_kernel/internal/tools.h rename to Filtered_kernel/include/CGAL/Filtered_kernel/internal/Static_filters/tools.h diff --git a/Filtered_kernel/include/CGAL/Filtered_predicate.h b/Filtered_kernel/include/CGAL/Filtered_predicate.h index da9e4b1c4fb..2adad47f329 100644 --- a/Filtered_kernel/include/CGAL/Filtered_predicate.h +++ b/Filtered_kernel/include/CGAL/Filtered_predicate.h @@ -107,6 +107,7 @@ Filtered_predicate:: } CGAL_BRANCH_PROFILER_BRANCH(tmp); Protect_FPU_rounding p(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); return ep(c2e(args)...); } diff --git a/Filtered_kernel/include/CGAL/Filtered_predicate_with_state.h b/Filtered_kernel/include/CGAL/Filtered_predicate_with_state.h index be16571ff04..c0b2e2179ca 100644 --- a/Filtered_kernel/include/CGAL/Filtered_predicate_with_state.h +++ b/Filtered_kernel/include/CGAL/Filtered_predicate_with_state.h @@ -74,6 +74,7 @@ Filtered_predicate_with_state:: } CGAL_BRANCH_PROFILER_BRANCH(tmp); Protect_FPU_rounding p(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); if(! oep){ oep.emplace(c2e(o1)); } diff --git a/Filtered_kernel/include/CGAL/Lazy.h b/Filtered_kernel/include/CGAL/Lazy.h index 0b25b2e30f5..07ad822d7f5 100644 --- a/Filtered_kernel/include/CGAL/Lazy.h +++ b/Filtered_kernel/include/CGAL/Lazy.h @@ -1169,15 +1169,17 @@ struct Lazy_construction_bbox operator()(const L1& l1) const { CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); - // Protection is outside the try block as VC8 has the CGAL_CFG_FPU_ROUNDING_MODE_UNWINDING_VC_BUG - Protect_FPU_rounding P; - try { - return ac(CGAL::approx(l1)); - } catch (Uncertain_conversion_exception&) { - CGAL_BRANCH_PROFILER_BRANCH(tmp); - Protect_FPU_rounding P2(CGAL_FE_TONEAREST); - return ec(CGAL::exact(l1)); + { + // Protection is outside the try block as VC8 has the CGAL_CFG_FPU_ROUNDING_MODE_UNWINDING_VC_BUG + Protect_FPU_rounding P; + try { + return ac(CGAL::approx(l1)); + } catch (Uncertain_conversion_exception&) {} } + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); + return ec(CGAL::exact(l1)); } }; @@ -1199,38 +1201,36 @@ struct Lazy_construction_optional_for_polygonal_envelope template result_type operator()(const L1& l1, const L1& l2, const L1& l3) const { - Protect_FPU_rounding P; + { + Protect_FPU_rounding P; + try { + boost::optional oap = ac(CGAL::approx(l1),CGAL::approx(l2),CGAL::approx(l3)); + if(oap == boost::none){ + return boost::none; + } + // Now we have to construct a rep for a lazy point with the three lazy planes. + typedef Lazy_rep_optional_n LazyPointRep; + CGAL_STATIC_THREAD_LOCAL_VARIABLE_0(LazyPointRep, rep); - try { - boost::optional oap = ac(CGAL::approx(l1),CGAL::approx(l2),CGAL::approx(l3)); - if(oap == boost::none){ - return boost::none; - } - // Now we have to construct a rep for a lazy point with the three lazy planes. - typedef Lazy_rep_optional_n LazyPointRep; - CGAL_STATIC_THREAD_LOCAL_VARIABLE_0(LazyPointRep, rep); + const typename AK::Point_3 ap = *oap; + // rep = LazyPointRep(2,ap, ec, l1, l2, l3); + rep.~LazyPointRep(); new (&rep) LazyPointRep(2, ap, ec, l1, l2, l3); + typename LK::Point_3 lp(&rep); + return boost::make_optional(lp); - const typename AK::Point_3 ap = *oap; - // rep = LazyPointRep(2,ap, ec, l1, l2, l3); - rep.~LazyPointRep(); new (&rep) LazyPointRep(2, ap, ec, l1, l2, l3); - typename LK::Point_3 lp(&rep); - return boost::make_optional(lp); - - - } catch (Uncertain_conversion_exception&) { - Protect_FPU_rounding P2(CGAL_FE_TONEAREST); - boost::optional oep = ec(CGAL::exact(l1), CGAL::exact(l2), CGAL::exact(l3)); - if(oep == boost::none){ - return boost::none; - } - typedef Lazy_rep_0 LazyPointRep; - const typename EK::Point_3 ep = *oep; - LazyPointRep *rep = new LazyPointRep(ep); - typename LK::Point_3 lp(rep); - return boost::make_optional(lp); + } catch (Uncertain_conversion_exception&) {} } - // AF can we get here?? - return boost::none; + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); + boost::optional oep = ec(CGAL::exact(l1), CGAL::exact(l2), CGAL::exact(l3)); + if(oep == boost::none){ + return boost::none; + } + typedef Lazy_rep_0 LazyPointRep; + const typename EK::Point_3 ep = *oep; + LazyPointRep *rep = new LazyPointRep(ep); + typename LK::Point_3 lp(rep); + return boost::make_optional(lp); } // for Intersect_point_3 with Plane_3 Line_3 @@ -1238,38 +1238,36 @@ struct Lazy_construction_optional_for_polygonal_envelope result_type operator()(const L1& l1, const L2& l2) const { - Protect_FPU_rounding P; + { + Protect_FPU_rounding P; + try { + boost::optional oap = ac(CGAL::approx(l1),CGAL::approx(l2)); + if(oap == boost::none){ + return boost::none; + } + // Now we have to construct a rep for a lazy point with the line and the plane. + typedef Lazy_rep_optional_n LazyPointRep; - try { - boost::optional oap = ac(CGAL::approx(l1),CGAL::approx(l2)); - if(oap == boost::none){ - return boost::none; - } - // Now we have to construct a rep for a lazy point with the line and the plane. - typedef Lazy_rep_optional_n LazyPointRep; + CGAL_STATIC_THREAD_LOCAL_VARIABLE_0(LazyPointRep, rep); + const typename AK::Point_3 ap = *oap; + // rep = LazyPointRep(2, ap, ec, l1, l2); + rep.~LazyPointRep(); new (&rep) LazyPointRep(2, ap, ec, l1, l2); + typename LK::Point_3 lp(&rep); + return boost::make_optional(lp); - CGAL_STATIC_THREAD_LOCAL_VARIABLE_0(LazyPointRep, rep); - const typename AK::Point_3 ap = *oap; - // rep = LazyPointRep(2, ap, ec, l1, l2); - rep.~LazyPointRep(); new (&rep) LazyPointRep(2, ap, ec, l1, l2); - typename LK::Point_3 lp(&rep); - return boost::make_optional(lp); - - - } catch (Uncertain_conversion_exception&) { - Protect_FPU_rounding P2(CGAL_FE_TONEAREST); - boost::optional oep = ec(CGAL::exact(l1), CGAL::exact(l2)); - if(oep == boost::none){ - return boost::none; - } - typedef Lazy_rep_0 LazyPointRep; - const typename EK::Point_3 ep = *oep; - LazyPointRep *rep = new LazyPointRep(ep); - typename LK::Point_3 lp(rep); - return boost::make_optional(lp); + } catch (Uncertain_conversion_exception&) {} } - // AF can we get here?? - return boost::none; + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); + boost::optional oep = ec(CGAL::exact(l1), CGAL::exact(l2)); + if(oep == boost::none){ + return boost::none; + } + typedef Lazy_rep_0 LazyPointRep; + const typename EK::Point_3 ep = *oep; + LazyPointRep *rep = new LazyPointRep(ep); + typename LK::Point_3 lp(rep); + return boost::make_optional(lp); } }; @@ -1295,14 +1293,16 @@ struct Lazy_construction_nt { typedef std::remove_cv_t> ET; typedef std::remove_cv_t> AT; CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); - Protect_FPU_rounding P; - try { - return new Lazy_rep_n, false, L... >(ac, ec, l...); - } catch (Uncertain_conversion_exception&) { - CGAL_BRANCH_PROFILER_BRANCH(tmp); - Protect_FPU_rounding P2(CGAL_FE_TONEAREST); - return new Lazy_rep_0 >(ec( CGAL::exact(l)... )); + { + Protect_FPU_rounding P; + try { + return new Lazy_rep_n, false, L... >(ac, ec, l...); + } catch (Uncertain_conversion_exception&) {} } + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); + return new Lazy_rep_0 >(ec( CGAL::exact(l)... )); } }; @@ -1515,17 +1515,20 @@ public: operator()(const L1& l1, const L2& l2, R1& r1) const { CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); - Protect_FPU_rounding P; - try { - // we suppose that R1 is a Lazy - r1 = R1(new Lazy_rep_2_1(ac, ec, l1, l2)); - } catch (Uncertain_conversion_exception&) { - CGAL_BRANCH_PROFILER_BRANCH(tmp); - Protect_FPU_rounding P2(CGAL_FE_TONEAREST); - typename R1::ET et; - ec(CGAL::exact(l1), CGAL::exact(l2), et); - r1 = R1(new Lazy_rep_0(et)); + { + Protect_FPU_rounding P; + try { + // we suppose that R1 is a Lazy + r1 = R1(new Lazy_rep_2_1(ac, ec, l1, l2)); + return; + } catch (Uncertain_conversion_exception&) {} } + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); + typename R1::ET et; + ec(CGAL::exact(l1), CGAL::exact(l2), et); + r1 = R1(new Lazy_rep_0(et)); } }; @@ -1581,21 +1584,24 @@ public: typedef Lazy Handle_1; typedef Lazy Handle_2; CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); - Protect_FPU_rounding P; - try { - typedef Lazy, std::pair, E2A> Lazy_pair; - Lazy_pair lv(new Lazy_rep_2_2(ac, ec, l1, l2)); - // lv->approx() is a std::pair; - r1 = R1(Handle_1(new Lazy_rep_n >, First >, E2A, false, Lazy_pair>(First >(), First >(), lv))); - r2 = R2(Handle_2(new Lazy_rep_n >, Second >, E2A, false, Lazy_pair>(Second >(), Second >(), lv))); - } catch (Uncertain_conversion_exception&) { - CGAL_BRANCH_PROFILER_BRANCH(tmp); - Protect_FPU_rounding P2(CGAL_FE_TONEAREST); - typename R1::ET et1, et2; - ec(CGAL::exact(l1), CGAL::exact(l2), et1, et2); - r1 = R1(Handle_1(new Lazy_rep_0(et1))); - r2 = R2(Handle_2(new Lazy_rep_0(et2))); + { + Protect_FPU_rounding P; + try { + typedef Lazy, std::pair, E2A> Lazy_pair; + Lazy_pair lv(new Lazy_rep_2_2(ac, ec, l1, l2)); + // lv->approx() is a std::pair; + r1 = R1(Handle_1(new Lazy_rep_n >, First >, E2A, false, Lazy_pair>(First >(), First >(), lv))); + r2 = R2(Handle_2(new Lazy_rep_n >, Second >, E2A, false, Lazy_pair>(Second >(), Second >(), lv))); + return; + } catch (Uncertain_conversion_exception&) {} } + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); + typename R1::ET et1, et2; + ec(CGAL::exact(l1), CGAL::exact(l2), et1, et2); + r1 = R1(Handle_1(new Lazy_rep_0(et1))); + r2 = R2(Handle_2(new Lazy_rep_0(et2))); } }; @@ -1625,36 +1631,38 @@ public: operator()(const L1& l1, const L2& l2, OutputIterator it) const { CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); - Protect_FPU_rounding P; - try { - Lazy_vector lv(new Lazy_rep_with_vector_2(ac, ec, l1, l2)); - // lv.approx() is a std::vector - // that is, when we get here we have constructed all approximate results - for (unsigned int i = 0; i < lv.approx().size(); i++) { -// FIXME : I'm not sure how this work... -#define CGAL_Kernel_obj(X) if (object_cast(& (lv.approx()[i]))) { \ - *it++ = make_object(typename LK::X(new Lazy_rep_n, \ - Ith, E2A, false, Lazy_vector> \ - (Ith(i), Ith(i), lv))); \ - continue; \ + { + Protect_FPU_rounding P; + try { + Lazy_vector lv(new Lazy_rep_with_vector_2(ac, ec, l1, l2)); + // lv.approx() is a std::vector + // that is, when we get here we have constructed all approximate results + for (unsigned int i = 0; i < lv.approx().size(); i++) { + // FIXME : I'm not sure how this work... + #define CGAL_Kernel_obj(X) if (object_cast(& (lv.approx()[i]))) { \ + *it++ = make_object(typename LK::X(new Lazy_rep_n, \ + Ith, E2A, false, Lazy_vector> \ + (Ith(i), Ith(i), lv))); \ + continue; \ + } + + #include + + std::cerr << "we need more casts" << std::endl; } - -#include - - std::cerr << "we need more casts" << std::endl; - } - - } catch (Uncertain_conversion_exception&) { - CGAL_BRANCH_PROFILER_BRANCH(tmp); - // TODO: Instead of using a vector, write an iterator adapter - Protect_FPU_rounding P2(CGAL_FE_TONEAREST); - std::vector exact_objects; - ec(CGAL::exact(l1), CGAL::exact(l2), std::back_inserter(exact_objects)); - for (std::vector::const_iterator oit = exact_objects.begin(); - oit != exact_objects.end(); - ++oit){ - *it++ = make_lazy(*oit); - } + return it; + } catch (Uncertain_conversion_exception&) {} + } + CGAL_BRANCH_PROFILER_BRANCH(tmp); + // TODO: Instead of using a vector, write an iterator adapter + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); + std::vector exact_objects; + ec(CGAL::exact(l1), CGAL::exact(l2), std::back_inserter(exact_objects)); + for (std::vector::const_iterator oit = exact_objects.begin(); + oit != exact_objects.end(); + ++oit){ + *it++ = make_lazy(*oit); } return it; } @@ -1703,32 +1711,34 @@ public: operator()(const L1& l1) const { CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); - Protect_FPU_rounding P; - try { - Lazy_object lo(new Lazy_rep_n(ac, ec, l1)); + { + Protect_FPU_rounding P; + try { + Lazy_object lo(new Lazy_rep_n(ac, ec, l1)); - if(lo.approx().is_empty()) - return Object(); + if(lo.approx().is_empty()) + return Object(); #define CGAL_Kernel_obj(X) \ - if (object_cast(& (lo.approx()))) { \ - typedef Lazy_rep_n< typename AK::X, typename EK::X, Object_cast, Object_cast, E2A, false, Lazy_object> Lcr; \ - Lcr * lcr = new Lcr(Object_cast(), Object_cast(), lo); \ - return make_object(typename LK::X(lcr)); \ - } + if (object_cast(& (lo.approx()))) { \ + typedef Lazy_rep_n< typename AK::X, typename EK::X, Object_cast, Object_cast, E2A, false, Lazy_object> Lcr; \ + Lcr * lcr = new Lcr(Object_cast(), Object_cast(), lo); \ + return make_object(typename LK::X(lcr)); \ + } #include - std::cerr << "object_cast inside Lazy_construction_rep::operator() failed. It needs more else if's (#1)" << std::endl; - std::cerr << "dynamic type of the Object : " << lo.approx().type().name() << std::endl; + std::cerr << "object_cast inside Lazy_construction_rep::operator() failed. It needs more else if's (#1)" << std::endl; + std::cerr << "dynamic type of the Object : " << lo.approx().type().name() << std::endl; - } catch (Uncertain_conversion_exception&) { - CGAL_BRANCH_PROFILER_BRANCH(tmp); - Protect_FPU_rounding P2(CGAL_FE_TONEAREST); - ET eto = ec(CGAL::exact(l1)); - return make_lazy(eto); + return Object(); + } catch (Uncertain_conversion_exception&) {} } - return Object(); + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); + ET eto = ec(CGAL::exact(l1)); + return make_lazy(eto); } template @@ -1736,53 +1746,55 @@ public: operator()(const L1& l1, const L2& l2) const { CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); - Protect_FPU_rounding P; - try { - Lazy_object lo(new Lazy_rep_n(ac, ec, l1, l2)); + { + Protect_FPU_rounding P; + try { + Lazy_object lo(new Lazy_rep_n(ac, ec, l1, l2)); - if(lo.approx().is_empty()) - return Object(); + if(lo.approx().is_empty()) + return Object(); -#define CGAL_Kernel_obj(X) \ - if (object_cast(& (lo.approx()))) { \ - typedef Lazy_rep_n, Object_cast, E2A, false, Lazy_object> Lcr; \ - Lcr * lcr = new Lcr(Object_cast(), Object_cast(), lo); \ - return make_object(typename LK::X(lcr)); \ - } + #define CGAL_Kernel_obj(X) \ + if (object_cast(& (lo.approx()))) { \ + typedef Lazy_rep_n, Object_cast, E2A, false, Lazy_object> Lcr; \ + Lcr * lcr = new Lcr(Object_cast(), Object_cast(), lo); \ + return make_object(typename LK::X(lcr)); \ + } -#include + #include - // We now check vector + // We now check vector -#define CGAL_Kernel_obj(X) \ - { \ - const std::vector* v_ptr;\ - if ( (v_ptr = object_cast >(& (lo.approx()))) ) { \ - std::vector V;\ - V.resize(v_ptr->size()); \ - for (unsigned int i = 0; i < v_ptr->size(); i++) { \ - V[i] = typename LK::X(new Lazy_rep_n, \ - Ith_for_intersection, E2A, false, Lazy_object> \ - (Ith_for_intersection(i), Ith_for_intersection(i), lo)); \ - } \ - return make_object(V); \ - }\ - } + #define CGAL_Kernel_obj(X) \ + { \ + const std::vector* v_ptr;\ + if ( (v_ptr = object_cast >(& (lo.approx()))) ) { \ + std::vector V;\ + V.resize(v_ptr->size()); \ + for (unsigned int i = 0; i < v_ptr->size(); i++) { \ + V[i] = typename LK::X(new Lazy_rep_n, \ + Ith_for_intersection, E2A, false, Lazy_object> \ + (Ith_for_intersection(i), Ith_for_intersection(i), lo)); \ + } \ + return make_object(V); \ + }\ + } -CGAL_Kernel_obj(Point_2) -CGAL_Kernel_obj(Point_3) -#undef CGAL_Kernel_obj + CGAL_Kernel_obj(Point_2) + CGAL_Kernel_obj(Point_3) + #undef CGAL_Kernel_obj - std::cerr << "object_cast inside Lazy_construction_rep::operator() failed. It needs more else if's (#1)" << std::endl; - std::cerr << "dynamic type of the Object : " << lo.approx().type().name() << std::endl; + std::cerr << "object_cast inside Lazy_construction_rep::operator() failed. It needs more else if's (#1)" << std::endl; + std::cerr << "dynamic type of the Object : " << lo.approx().type().name() << std::endl; - } catch (Uncertain_conversion_exception&) { - CGAL_BRANCH_PROFILER_BRANCH(tmp); - Protect_FPU_rounding P2(CGAL_FE_TONEAREST); - ET eto = ec(CGAL::exact(l1), CGAL::exact(l2)); - return make_lazy(eto); + } catch (Uncertain_conversion_exception&) {} + return Object(); } - return Object(); + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); + ET eto = ec(CGAL::exact(l1), CGAL::exact(l2)); + return make_lazy(eto); } template @@ -1790,34 +1802,34 @@ CGAL_Kernel_obj(Point_3) operator()(const L1& l1, const L2& l2, const L3& l3) const { CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); - Protect_FPU_rounding P; - try { - Lazy_object lo(new Lazy_rep_n(ac, ec, l1, l2, l3)); + { + Protect_FPU_rounding P; + try { + Lazy_object lo(new Lazy_rep_n(ac, ec, l1, l2, l3)); - if(lo.approx().is_empty()) + if(lo.approx().is_empty()) + return Object(); + + #define CGAL_Kernel_obj(X) \ + if (object_cast(& (lo.approx()))) { \ + typedef Lazy_rep_n, Object_cast, E2A, false, Lazy_object> Lcr; \ + Lcr * lcr = new Lcr(Object_cast(), Object_cast(), lo); \ + return make_object(typename LK::X(lcr)); \ + } + + #include + + std::cerr << "object_cast inside Lazy_construction_rep::operator() failed. It needs more else if's (#1)" << std::endl; + std::cerr << "dynamic type of the Object : " << lo.approx().type().name() << std::endl; return Object(); - -#define CGAL_Kernel_obj(X) \ - if (object_cast(& (lo.approx()))) { \ - typedef Lazy_rep_n, Object_cast, E2A, false, Lazy_object> Lcr; \ - Lcr * lcr = new Lcr(Object_cast(), Object_cast(), lo); \ - return make_object(typename LK::X(lcr)); \ - } - -#include - - std::cerr << "object_cast inside Lazy_construction_rep::operator() failed. It needs more else if's (#1)" << std::endl; - std::cerr << "dynamic type of the Object : " << lo.approx().type().name() << std::endl; - - } catch (Uncertain_conversion_exception&) { - CGAL_BRANCH_PROFILER_BRANCH(tmp); - Protect_FPU_rounding P2(CGAL_FE_TONEAREST); - ET eto = ec(CGAL::exact(l1), CGAL::exact(l2), CGAL::exact(l3)); - return make_lazy(eto); + } catch (Uncertain_conversion_exception&) {} } - return Object(); + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); + ET eto = ec(CGAL::exact(l1), CGAL::exact(l2), CGAL::exact(l3)); + return make_lazy(eto); } - }; @@ -1955,6 +1967,7 @@ struct Lazy_construction_variant { template decltype(auto) operator()(const L1& l1, const L2& l2) const { + typedef typename result::type result_type; // typedef decltype(std::declval()(std::declval::type>(), @@ -1966,41 +1979,42 @@ struct Lazy_construction_variant { typedef decltype(std::declval()( CGAL::exact(l1), CGAL::exact(l2))) ET; CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); - Protect_FPU_rounding P; + { + Protect_FPU_rounding P; - try { - Lazy lazy(new Lazy_rep_n(AC(), EC(), l1, l2)); + try { + Lazy lazy(new Lazy_rep_n(AC(), EC(), l1, l2)); - // the approximate result requires the trait with types from the AK - AT approx_v = lazy.approx(); - // the result we build - result_type res; + // the approximate result requires the trait with types from the AK + AT approx_v = lazy.approx(); + // the result we build + result_type res; + + if(!approx_v) { + // empty + return res; + } + + // the static visitor fills the result_type with the correct unwrapped type + internal::Fill_lazy_variant_visitor_2< result_type, AK, LK, EK, Lazy > visitor(res, lazy); + boost::apply_visitor(visitor, *approx_v); - if(!approx_v) { - // empty return res; - } + } catch (Uncertain_conversion_exception&) {} + } + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); + ET exact_v = EC()(CGAL::exact(l1), CGAL::exact(l2)); + result_type res; - // the static visitor fills the result_type with the correct unwrapped type - internal::Fill_lazy_variant_visitor_2< result_type, AK, LK, EK, Lazy > visitor(res, lazy); - boost::apply_visitor(visitor, *approx_v); - - return res; - } catch (Uncertain_conversion_exception&) { - CGAL_BRANCH_PROFILER_BRANCH(tmp); - Protect_FPU_rounding P2(CGAL_FE_TONEAREST); - - ET exact_v = EC()(CGAL::exact(l1), CGAL::exact(l2)); - result_type res; - - if(!exact_v) { - return res; - } - - internal::Fill_lazy_variant_visitor_0 visitor(res); - boost::apply_visitor(visitor, *exact_v); + if(!exact_v) { return res; } + + internal::Fill_lazy_variant_visitor_0 visitor(res); + boost::apply_visitor(visitor, *exact_v); + return res; } template @@ -2019,41 +2033,42 @@ struct Lazy_construction_variant { typedef decltype(std::declval()( CGAL::exact(l1), CGAL::exact(l2), CGAL::exact(l3))) ET; CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); - Protect_FPU_rounding P; + { + Protect_FPU_rounding P; - try { - Lazy lazy(new Lazy_rep_n(AC(), EC(), l1, l2, l3)); + try { + Lazy lazy(new Lazy_rep_n(AC(), EC(), l1, l2, l3)); - // the approximate result requires the trait with types from the AK - AT approx_v = lazy.approx(); - // the result we build - result_type res; + // the approximate result requires the trait with types from the AK + AT approx_v = lazy.approx(); + // the result we build + result_type res; + + if(!approx_v) { + // empty + return res; + } + + // the static visitor fills the result_type with the correct unwrapped type + internal::Fill_lazy_variant_visitor_2< result_type, AK, LK, EK, Lazy > visitor(res, lazy); + boost::apply_visitor(visitor, *approx_v); - if(!approx_v) { - // empty return res; - } + } catch (Uncertain_conversion_exception&) {} + } + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); + ET exact_v = EC()(CGAL::exact(l1), CGAL::exact(l2), CGAL::exact(l3)); + result_type res; - // the static visitor fills the result_type with the correct unwrapped type - internal::Fill_lazy_variant_visitor_2< result_type, AK, LK, EK, Lazy > visitor(res, lazy); - boost::apply_visitor(visitor, *approx_v); - - return res; - } catch (Uncertain_conversion_exception&) { - CGAL_BRANCH_PROFILER_BRANCH(tmp); - Protect_FPU_rounding P2(CGAL_FE_TONEAREST); - - ET exact_v = EC()(CGAL::exact(l1), CGAL::exact(l2), CGAL::exact(l3)); - result_type res; - - if(!exact_v) { - return res; - } - - internal::Fill_lazy_variant_visitor_0< result_type, AK, LK, EK> visitor(res); - boost::apply_visitor(visitor, *exact_v); + if(!exact_v) { return res; } + + internal::Fill_lazy_variant_visitor_0< result_type, AK, LK, EK> visitor(res); + boost::apply_visitor(visitor, *exact_v); + return res; } }; @@ -2092,14 +2107,16 @@ struct Lazy_construction { operator()( BOOST_PP_ENUM(n, CGAL_LARGS, _) ) const { \ typedef Lazy< AT, ET, E2A> Handle; \ CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); \ - Protect_FPU_rounding P; \ - try { \ - return result_type( Handle(new Lazy_rep_n(ac, ec, BOOST_PP_ENUM_PARAMS(n, l)))); \ - } catch (Uncertain_conversion_exception&) { \ - CGAL_BRANCH_PROFILER_BRANCH(tmp); \ - Protect_FPU_rounding P2(CGAL_FE_TONEAREST); \ - return result_type( Handle(new Lazy_rep_0(ec( BOOST_PP_ENUM(n, CGAL_LEXACT, _) ))) ); \ + { \ + Protect_FPU_rounding P; \ + try { \ + return result_type( Handle(new Lazy_rep_n(ac, ec, BOOST_PP_ENUM_PARAMS(n, l)))); \ + } catch (Uncertain_conversion_exception&) {} \ } \ + CGAL_BRANCH_PROFILER_BRANCH(tmp); \ + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); \ + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); \ + return result_type( Handle(new Lazy_rep_0(ec( BOOST_PP_ENUM(n, CGAL_LEXACT, _) ))) ); \ } // arity 1-8 @@ -2152,14 +2169,16 @@ struct Lazy_construction typedef Lazy< AT, ET, E2A> Handle; \ typedef typename result::type result_type; \ CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); \ - Protect_FPU_rounding P; \ - try { \ - return result_type( Handle(new Lazy_rep_n(ac, ec, BOOST_PP_ENUM_PARAMS(n, l)))); \ - } catch (Uncertain_conversion_exception&) { \ - CGAL_BRANCH_PROFILER_BRANCH(tmp); \ - Protect_FPU_rounding P2(CGAL_FE_TONEAREST); \ - return result_type( Handle(new Lazy_rep_0(ec( BOOST_PP_ENUM(n, CGAL_LEXACT, _) ))) ); \ - } \ + { \ + Protect_FPU_rounding P; \ + try { \ + return result_type( Handle(new Lazy_rep_n(ac, ec, BOOST_PP_ENUM_PARAMS(n, l)))); \ + } catch (Uncertain_conversion_exception&) {} \ + } \ + CGAL_BRANCH_PROFILER_BRANCH(tmp); \ + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); \ + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); \ + return result_type( Handle(new Lazy_rep_0(ec( BOOST_PP_ENUM(n, CGAL_LEXACT, _) ))) ); \ } // arity 1-8 diff --git a/Filtered_kernel/include/CGAL/Lazy_kernel.h b/Filtered_kernel/include/CGAL/Lazy_kernel.h index e0d89075a1c..b0d0f9707b8 100644 --- a/Filtered_kernel/include/CGAL/Lazy_kernel.h +++ b/Filtered_kernel/include/CGAL/Lazy_kernel.h @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/GraphicsView/include/CGAL/Buffer_for_vao.h b/GraphicsView/include/CGAL/Buffer_for_vao.h index e1093da21a7..57c91cb7701 100644 --- a/GraphicsView/include/CGAL/Buffer_for_vao.h +++ b/GraphicsView/include/CGAL/Buffer_for_vao.h @@ -521,17 +521,15 @@ public: local_orientation=Local_kernel::Orientation_3()(V1, V2, normal) ; - if(local_orientation!=CGAL::ZERO && local_orientation!=orientation) - { return false; } - // V1 and V2 are collinear - if(local_orientation==CGAL::ZERO ) + if(local_orientation!=CGAL::ZERO) { - //TS and TU are opposite - if(CGAL::scalar_product(V1,V2) >=0) - return true; - //TS and TU have the same direction. - else - return false; + if(local_orientation!=orientation) + { return false; } + } + else + { + if(CGAL::scalar_product(V1,V2)<0) + { return false; } //TS and TU are opposite } } return true; diff --git a/GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h b/GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h index 02d557a8a44..3bf83132a3a 100644 --- a/GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h +++ b/GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h @@ -160,11 +160,11 @@ public: &arrays[SMOOTH_NORMAL_COLORED_FACES]) { // Define 'Control+Q' as the new exit shortcut (default was 'Escape') - setShortcut(qglviewer::EXIT_VIEWER, ::Qt::CTRL+::Qt::Key_Q); + setShortcut(qglviewer::EXIT_VIEWER, ::Qt::CTRL, ::Qt::Key_Q); // Add custom key description (see keyPressEvent). setKeyDescription(::Qt::Key_C, "Switch clipping plane display mode"); - setKeyDescription(::Qt::Key_C+::Qt::AltModifier, "Toggle clipping plane rendering on/off"); + setKeyDescription(::Qt::AltModifier, ::Qt::Key_C, "Toggle clipping plane rendering on/off"); setKeyDescription(::Qt::Key_E, "Toggles edges display"); setKeyDescription(::Qt::Key_M, "Toggles mono color"); setKeyDescription(::Qt::Key_N, "Inverse direction of normals"); @@ -175,8 +175,8 @@ public: setKeyDescription(::Qt::Key_W, "Toggles faces display"); setKeyDescription(::Qt::Key_Plus, "Increase size of edges"); setKeyDescription(::Qt::Key_Minus, "Decrease size of edges"); - setKeyDescription(::Qt::Key_Plus+::Qt::ControlModifier, "Increase size of vertices"); - setKeyDescription(::Qt::Key_Minus+::Qt::ControlModifier, "Decrease size of vertices"); + setKeyDescription(::Qt::ControlModifier, ::Qt::Key_Plus, "Increase size of vertices"); + setKeyDescription(::Qt::ControlModifier, ::Qt::Key_Minus, "Decrease size of vertices"); setKeyDescription(::Qt::Key_PageDown, "Increase light (all colors, use shift/alt/ctrl for one rgb component)"); setKeyDescription(::Qt::Key_PageUp, "Decrease light (all colors, use shift/alt/ctrl for one rgb component)"); setKeyDescription(::Qt::Key_O, "Toggles 2D mode only"); diff --git a/GraphicsView/include/CGAL/Qt/qglviewer.h b/GraphicsView/include/CGAL/Qt/qglviewer.h index 1c11c9e4a52..da0dbace517 100644 --- a/GraphicsView/include/CGAL/Qt/qglviewer.h +++ b/GraphicsView/include/CGAL/Qt/qglviewer.h @@ -833,8 +833,26 @@ public: public Q_SLOTS: void setShortcut(qglviewer::KeyboardAction action, unsigned int key); + void setShortcut(qglviewer::KeyboardAction action, ::Qt::Modifier modifier, ::Qt::Key key) + { + setShortcut(action, + static_cast(modifier)+ + static_cast(key)); + } void setKeyDescription(unsigned int key, QString description); + void setKeyDescription(::Qt::KeyboardModifier modifier, ::Qt::Key key, QString description) + { + setKeyDescription(static_cast(modifier) + + static_cast(key), + description); + } + void setKeyDescription(::Qt::Modifier modifier, ::Qt::Key key, QString description) + { + setKeyDescription(static_cast(modifier) + + static_cast(key), + description); + } void clearShortcuts(); // Key Frames shortcut keys diff --git a/GraphicsView/include/CGAL/Qt/qglviewer_impl.h b/GraphicsView/include/CGAL/Qt/qglviewer_impl.h index 7aa487408c3..70fdfdd9a15 100644 --- a/GraphicsView/include/CGAL/Qt/qglviewer_impl.h +++ b/GraphicsView/include/CGAL/Qt/qglviewer_impl.h @@ -657,10 +657,10 @@ void CGAL::QGLViewer::setDefaultShortcuts() { setShortcut(qglviewer::DRAW_AXIS, ::Qt::Key_A); setShortcut(qglviewer::DRAW_GRID, ::Qt::Key_G); setShortcut(qglviewer::DISPLAY_FPS, ::Qt::Key_F); - setShortcut(qglviewer::ENABLE_TEXT, ::Qt::SHIFT + ::Qt::Key_Question); + setShortcut(qglviewer::ENABLE_TEXT, ::Qt::SHIFT, ::Qt::Key_Question); setShortcut(qglviewer::EXIT_VIEWER, ::Qt::Key_Escape); setShortcut(qglviewer::CAMERA_MODE, ::Qt::Key_Space); - setShortcut(qglviewer::FULL_SCREEN, ::Qt::ALT + ::Qt::Key_Return); + setShortcut(qglviewer::FULL_SCREEN, ::Qt::ALT, ::Qt::Key_Return); setShortcut(qglviewer::ANIMATION, ::Qt::Key_Return); setShortcut(qglviewer::HELP, ::Qt::Key_H); setShortcut(qglviewer::MOVE_CAMERA_LEFT, ::Qt::Key_Left); diff --git a/Heat_method_3/doc/Heat_method_3/Concepts/HeatMethodTraits_3.h b/Heat_method_3/doc/Heat_method_3/Concepts/HeatMethodTraits_3.h index f33440e95cf..dcfe6d573e0 100644 --- a/Heat_method_3/doc/Heat_method_3/Concepts/HeatMethodTraits_3.h +++ b/Heat_method_3/doc/Heat_method_3/Concepts/HeatMethodTraits_3.h @@ -49,6 +49,8 @@ public: /// Functor with operator: `FT operator()(const Point_3& p, const Point_3& q) const` which computes the squared distance between `p` and `q`. typedef unspecified_type Compute_squared_distance_3; + /// Functor with operator: `FT operator()(const Vector_3& v) const` which computes the squared length of `v`. + typedef unspecified_type Compute_squared_length_3; /// @} 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 96f7846baa6..d8592b1346f 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 @@ -29,6 +29,7 @@ #include #endif +#include #include #include @@ -361,7 +362,6 @@ private: void compute_divergence() { - typename Traits::Construct_cross_product_vector_3 cross_product = Traits().construct_cross_product_vector_3_object(); typename Traits::Compute_scalar_product_3 scalar_product = Traits().compute_scalar_product_3_object(); typename Traits::Construct_vector_3 construct_vector = Traits().construct_vector_3_object(); Matrix indexD(dimension,1); @@ -374,36 +374,30 @@ private: Index i = get(vertex_id_map, current); Index j = get(vertex_id_map, neighbor_one); Index k = get(vertex_id_map, neighbor_two); - VertexPointMap_reference p_i = get(vpm,current); + VertexPointMap_reference p_i = get(vpm, current); VertexPointMap_reference p_j = get(vpm, neighbor_one); VertexPointMap_reference p_k = get(vpm, neighbor_two); Index face_i = get(face_id_map, f); - Vector_3 v_ij = construct_vector(p_i,p_j); - Vector_3 v_ik = construct_vector(p_i,p_k); - Vector_3 cross = cross_product(v_ij, v_ik); - double norm_cross = CGAL::sqrt(to_double(scalar_product(cross,cross))); - double dot = to_double(scalar_product(v_ij, v_ik)); - double cotan_i = dot/norm_cross; + const Vector_3 v_ij = construct_vector(p_i, p_j); + const Vector_3 v_ik = construct_vector(p_i, p_k); + const Vector_3 v_ji = construct_vector(p_j, p_i); + const Vector_3 v_jk = construct_vector(p_j, p_k); + const Vector_3 v_ki = construct_vector(p_k, p_i); + const Vector_3 v_kj = construct_vector(p_k, p_j); - Vector_3 v_ji = construct_vector(p_j, p_i); - Vector_3 v_jk = construct_vector(p_j, p_k); + const Traits traits; + const FT cotan_i = CGAL::Weights::cotangent(p_k, p_i, p_j, traits); + const FT cotan_j = CGAL::Weights::cotangent(p_k, p_j, p_i, traits); + const FT cotan_k = CGAL::Weights::cotangent(p_j, p_k, p_i, traits); - cross = cross_product(v_ji, v_jk); - dot = to_double(scalar_product(v_ji, v_jk)); - double cotan_j = dot/norm_cross; - - Vector_3 v_ki = construct_vector(p_k,p_i); - Vector_3 v_kj = construct_vector(p_k,p_j); - - cross = cross_product(v_ki, v_kj); - dot = to_double(scalar_product(v_ki,v_kj)); - double cotan_k = dot/norm_cross; - - const Vector_3& a = m_X[face_i]; - double i_entry = (to_double(scalar_product(a,v_ij)) * cotan_k) + (to_double(scalar_product(a,v_ik)) * cotan_j); - double j_entry = (to_double(scalar_product(a,v_jk)) * cotan_i) + (to_double(scalar_product(a,v_ji)) * cotan_k); - double k_entry = (to_double(scalar_product(a,v_ki)) * cotan_j) + (to_double(scalar_product(a,v_kj)) * cotan_i); + const Vector_3& a = m_X[face_i]; + const double i_entry = (CGAL::to_double(scalar_product(a, v_ij) * cotan_k)) + + (CGAL::to_double(scalar_product(a, v_ik) * cotan_j)); + const double j_entry = (CGAL::to_double(scalar_product(a, v_jk) * cotan_i)) + + (CGAL::to_double(scalar_product(a, v_ji) * cotan_k)); + const double k_entry = (CGAL::to_double(scalar_product(a, v_ki) * cotan_j)) + + (CGAL::to_double(scalar_product(a, v_kj) * cotan_i)); indexD.add_coef(i, 0, (1./2)*i_entry); indexD.add_coef(j, 0, (1./2)*j_entry); @@ -549,47 +543,40 @@ private: Index k = get(vertex_id_map, neighbor_two); Point_3 pi, pj, pk; - VertexPointMap_reference p_i = get(vpm,current); + const Traits traits; + VertexPointMap_reference p_i = get(vpm, current); VertexPointMap_reference p_j = get(vpm, neighbor_one); VertexPointMap_reference p_k = get(vpm, neighbor_two); pi = p_i; pj = p_j; pk = p_k; - Vector_3 v_ij = construct_vector(p_i,p_j); - Vector_3 v_ik = construct_vector(p_i,p_k); + const double cotan_i = CGAL::to_double( + CGAL::Weights::cotangent(pk, pi, pj, traits)); + m_cotan_matrix.add_coef(j, k, -(1./2) * cotan_i); + m_cotan_matrix.add_coef(k, j, -(1./2) * cotan_i); + m_cotan_matrix.add_coef(j, j, (1./2) * cotan_i); + m_cotan_matrix.add_coef(k, k, (1./2) * cotan_i); - Vector_3 cross = cross_product(v_ij, v_ik); - double dot = to_double(scalar_product(v_ij,v_ik)); + const double cotan_j = CGAL::to_double( + CGAL::Weights::cotangent(pk, pj, pi, traits)); + m_cotan_matrix.add_coef(i, k, -(1./2) * cotan_j); + m_cotan_matrix.add_coef(k, i, -(1./2) * cotan_j); + m_cotan_matrix.add_coef(i, i, (1./2) * cotan_j); + m_cotan_matrix.add_coef(k, k, (1./2) * cotan_j); - double norm_cross = (CGAL::sqrt(to_double(scalar_product(cross,cross)))); + const double cotan_k = CGAL::to_double( + CGAL::Weights::cotangent(pj, pk, pi, traits)); + m_cotan_matrix.add_coef(i, j, -(1./2) * cotan_k); + m_cotan_matrix.add_coef(j, i, -(1./2) * cotan_k); + m_cotan_matrix.add_coef(i, i, (1./2) * cotan_k); + m_cotan_matrix.add_coef(j, j, (1./2) * cotan_k); - double cotan_i = dot/norm_cross; - m_cotan_matrix.add_coef(j,k ,-(1./2)*cotan_i); - m_cotan_matrix.add_coef(k,j,-(1./2)* cotan_i); - m_cotan_matrix.add_coef(j,j,(1./2)*cotan_i); - m_cotan_matrix.add_coef(k,k,(1./2)* cotan_i); - - Vector_3 v_ji = construct_vector(p_j,p_i); - Vector_3 v_jk = construct_vector(p_j,p_k); - - cross = cross_product(v_ji, v_jk); - dot = to_double(scalar_product(v_ji, v_jk)); - double cotan_j = dot/norm_cross; - m_cotan_matrix.add_coef(i,k ,-(1./2)*cotan_j); - m_cotan_matrix.add_coef(k,i,-(1./2)* cotan_j); - m_cotan_matrix.add_coef(i,i,(1./2)* cotan_j); - m_cotan_matrix.add_coef(k,k,(1./2)* cotan_j); - - Vector_3 v_ki = construct_vector(p_k,p_i); - Vector_3 v_kj = construct_vector(p_k,p_j); - cross = cross_product(v_ki, v_kj); - dot = to_double(scalar_product(v_ki,v_kj)); - double cotan_k = dot/norm_cross; - m_cotan_matrix.add_coef(i,j,-(1./2)*cotan_k); - m_cotan_matrix.add_coef(j,i,-(1./2)* cotan_k); - m_cotan_matrix.add_coef(i,i,(1./2)* cotan_k); - m_cotan_matrix.add_coef(j,j,(1./2)* cotan_k); + const Vector_3 v_ij = construct_vector(p_i, p_j); + const Vector_3 v_ik = construct_vector(p_i, p_k); + const Vector_3 cross = cross_product(v_ij, v_ik); + const double norm_cross = CGAL::sqrt( + CGAL::to_double(scalar_product(cross, cross))); //double area_face = CGAL::Polygon_mesh_processing::face_area(f,tm); //cross is 2*area diff --git a/Heat_method_3/package_info/Heat_method_3/dependencies b/Heat_method_3/package_info/Heat_method_3/dependencies index 90510db1ab2..50488d5544f 100644 --- a/Heat_method_3/package_info/Heat_method_3/dependencies +++ b/Heat_method_3/package_info/Heat_method_3/dependencies @@ -18,3 +18,4 @@ Random_numbers STL_Extension Solver_interface Stream_support +Weights diff --git a/Heat_method_3/test/Heat_method_3/Heat_method_traits_3.h b/Heat_method_3/test/Heat_method_3/Heat_method_traits_3.h index b64613c641b..8b8e28c76f4 100644 --- a/Heat_method_3/test/Heat_method_3/Heat_method_traits_3.h +++ b/Heat_method_3/test/Heat_method_3/Heat_method_traits_3.h @@ -59,6 +59,11 @@ struct Heat_method_traits_3 { return 0;} }; + struct Compute_squared_length_3 { + + double operator()(const Vector_3&) const + { return 0;} + }; Construct_vector_3 construct_vector_3_object() const { @@ -79,6 +84,11 @@ struct Heat_method_traits_3 return Compute_squared_distance_3(); } + Compute_squared_length_3 compute_squared_length_3_object() const + { + return Compute_squared_length_3(); + } + Compute_scalar_product_3 compute_scalar_product_3_object() const { return Compute_scalar_product_3(); diff --git a/Homogeneous_kernel/include/CGAL/Homogeneous/SphereH3.h b/Homogeneous_kernel/include/CGAL/Homogeneous/SphereH3.h index 2515212200a..a00ec51b275 100644 --- a/Homogeneous_kernel/include/CGAL/Homogeneous/SphereH3.h +++ b/Homogeneous_kernel/include/CGAL/Homogeneous/SphereH3.h @@ -198,7 +198,7 @@ template CGAL_KERNEL_MEDIUM_INLINE Oriented_side SphereH3::oriented_side(const typename SphereH3::Point_3& p) const -{ return Oriented_side(bounded_side(p) * orientation()); } +{ return Oriented_side(static_cast(bounded_side(p)) * static_cast(orientation())); } template CGAL_KERNEL_INLINE diff --git a/Homogeneous_kernel/include/CGAL/Homogeneous/function_objects.h b/Homogeneous_kernel/include/CGAL/Homogeneous/function_objects.h index 8091a640d18..833d09e413d 100644 --- a/Homogeneous_kernel/include/CGAL/Homogeneous/function_objects.h +++ b/Homogeneous_kernel/include/CGAL/Homogeneous/function_objects.h @@ -3398,8 +3398,17 @@ namespace HomogeneousKernelFunctors { typedef typename K::Triangle_3 Triangle_3; typedef typename K::Segment_3 Segment_3; typedef typename K::Ray_3 Ray_3; + public: - typedef Point_3 result_type; + template + struct result { + typedef const Point_3 type; + }; + + template + struct result { + typedef const Point_3& type; + }; Point_3 operator()( const Line_3& l, const Point_3& p ) const @@ -3429,15 +3438,19 @@ namespace HomogeneousKernelFunctors { Point_3 operator()( const Triangle_3& t, const Point_3& p ) const - { return CommonKernelFunctors::Construct_projected_point_3()(p,t,K()); } + { return CommonKernelFunctors::Construct_projected_point_3()(t,p,K()); } Point_3 operator()( const Segment_3& s, const Point_3& p ) const - { return CommonKernelFunctors::Construct_projected_point_3()(p,s,K()); } + { return CommonKernelFunctors::Construct_projected_point_3()(s,p,K()); } Point_3 operator()( const Ray_3& r, const Point_3& p ) const - { return CommonKernelFunctors::Construct_projected_point_3()(p,r,K()); } + { return CommonKernelFunctors::Construct_projected_point_3()(r,p,K()); } + + const Point_3& + operator()( const Point_3& p, const Point_3& q) const + { return CommonKernelFunctors::Construct_projected_point_3()(p,q,K()); } }; template @@ -4675,7 +4688,7 @@ namespace HomogeneousKernelFunctors { result_type operator()( const Circle_2& c, const Point_2& p) const - { return Oriented_side(c.bounded_side(p) * c.orientation()); } + { return Oriented_side(static_cast(c.bounded_side(p)) * static_cast(c.orientation())); } result_type operator()( const Line_2& l, const Point_2& p) const diff --git a/Hyperbolic_triangulation_2/package_info/Hyperbolic_triangulation_2/dependencies b/Hyperbolic_triangulation_2/package_info/Hyperbolic_triangulation_2/dependencies index 72b10e709ef..a0d8892a1d5 100644 --- a/Hyperbolic_triangulation_2/package_info/Hyperbolic_triangulation_2/dependencies +++ b/Hyperbolic_triangulation_2/package_info/Hyperbolic_triangulation_2/dependencies @@ -19,7 +19,6 @@ Kernel_23 Kernel_d Modular_arithmetic Number_types -Polygon Profiling_tools Property_map STL_Extension diff --git a/Installation/CHANGES.md b/Installation/CHANGES.md index da44a890a15..9ca67be1cc9 100644 --- a/Installation/CHANGES.md +++ b/Installation/CHANGES.md @@ -37,7 +37,7 @@ Release date: December 2021 ### [2D and 3D Linear Geometry Kernel](https://doc.cgal.org/5.4/Manual/packages.html#PkgKernel23) - Added `construct_centroid_2_object()` and `compute_determinant_2_object()` in `Projection_traits_xy_3`, `Projection_traits_xz_3`, - and`Projection_traits_yz_3` classes. + and `Projection_traits_yz_3` classes. - Added documentation for the class `Projection_traits_3`, which enables the use of 2D algorithms on the projections of 3D data onto an arbitrary plane. @@ -54,11 +54,18 @@ Release date: December 2021 if the bounded-error Hausdorff distance between two meshes is larger than the user-specified max distance. +- Added the functions `CGAL::Polygon_mesh_processing::squared_edge_length()` + and `CGAL::Polygon_mesh_processing::squared_face_area()` which do not perform a `sqrt()` operation. + - Added more functions in the [visitor of the corefinement based methods](https://doc.cgal.org/5.4/Polygon_mesh_processing/classPMPCorefinementVisitor.html) to track all vertex creations. - Added an option to [`CGAL::Polygon_mesh_processing::self_intersections()`](https://doc.cgal.org/5.4/Polygon_mesh_processing/group__PMP__intersection__grp.html#gaf19c80ec12cbff7ebe9e69453f1d40b8) to report only a limited number of intersections (`maximum_number()`) +### [The Heat Method](https://doc.cgal.org/5.4/Manual/packages.html#PkgHeatMethod) + +- **Breaking change**: Added the functor `Compute_squared_length_3` that has an operator `operator(const Vector_3& v)`, which computes the squared length of `v`, to the `HeatMethodTraits_3` concept. + ### [Shape Regularization](https://doc.cgal.org/5.4/Manual/packages.html#PkgShapeRegularization) (new package) - This package enables to regularize a set of segments and open or closed contours in 2D diff --git a/Installation/CMakeLists.txt b/Installation/CMakeLists.txt index 16abec88e95..43d3cbadc95 100644 --- a/Installation/CMakeLists.txt +++ b/Installation/CMakeLists.txt @@ -22,8 +22,6 @@ include(GNUInstallDirs) # #-------------------------------------------------------------------------------------------------- -message("== Setting paths ==") - if(CGAL_BRANCH_BUILD) message( @@ -849,6 +847,8 @@ if(NOT RUNNING_CGAL_AUTO_TEST) endif() endif() +message("== Setting paths ==") + #-------------------------------------------------------------------------------------------------- # # -= CPack =- diff --git a/Installation/cmake/modules/CGALConfig_binary.cmake.in b/Installation/cmake/modules/CGALConfig_binary.cmake.in index 364ab5bb823..01fae62d34a 100644 --- a/Installation/cmake/modules/CGALConfig_binary.cmake.in +++ b/Installation/cmake/modules/CGALConfig_binary.cmake.in @@ -196,4 +196,15 @@ if( CGAL_DEV_MODE OR RUNNING_CGAL_AUTO_TEST ) include(CGAL_SetupFlags) endif() +#CGAL_DATA_DIR, used by `CGAL::data_file_path(filename)` from `CGAL/config.h` +set(CGAL_DATA_DIR "@CGAL_DATA_DIR@") + +if(NOT TARGET CGAL::Data) + add_library(CGAL::Data INTERFACE IMPORTED) + if ( NOT "${CGAL_DATA_DIR}" STREQUAL "" ) + set_target_properties(CGAL::Data PROPERTIES + INTERFACE_COMPILE_DEFINITIONS "CGAL_DATA_DIR=\"${CGAL_DATA_DIR}\"") + endif() +endif() + include("${CGAL_MODULES_DIR}/CGAL_enable_end_of_configuration_hook.cmake") diff --git a/Installation/cmake/modules/CGALConfig_install.cmake.in b/Installation/cmake/modules/CGALConfig_install.cmake.in index cb51524dcfa..e11acd78522 100644 --- a/Installation/cmake/modules/CGALConfig_install.cmake.in +++ b/Installation/cmake/modules/CGALConfig_install.cmake.in @@ -179,4 +179,16 @@ if( CGAL_DEV_MODE OR RUNNING_CGAL_AUTO_TEST ) # Nov. 2017). -- Laurent Rineau include(CGAL_SetupFlags) endif() + +#CGAL_DATA_DIR +set(CGAL_DATA_DIR "@CGAL_DATA_DIR@") + +if(NOT TARGET CGAL::Data) + add_library(CGAL::Data INTERFACE IMPORTED) + if ( NOT "${CGAL_DATA_DIR}" STREQUAL "" ) + set_target_properties(CGAL::Data PROPERTIES + INTERFACE_COMPILE_DEFINITIONS "CGAL_DATA_DIR=\"${CGAL_DATA_DIR}\"") + endif() +endif() + include("${CGAL_MODULES_DIR}/CGAL_enable_end_of_configuration_hook.cmake") diff --git a/Installation/cmake/modules/CGAL_CreateSingleSourceCGALProgram.cmake b/Installation/cmake/modules/CGAL_CreateSingleSourceCGALProgram.cmake index 161e59d0391..1eb308fbe1c 100644 --- a/Installation/cmake/modules/CGAL_CreateSingleSourceCGALProgram.cmake +++ b/Installation/cmake/modules/CGAL_CreateSingleSourceCGALProgram.cmake @@ -65,7 +65,7 @@ function(create_single_source_cgal_program firstfile ) add_to_cached_list( CGAL_EXECUTABLE_TARGETS ${exe_name} ) - target_link_libraries(${exe_name} PRIVATE CGAL::CGAL) + target_link_libraries(${exe_name} PRIVATE CGAL::CGAL CGAL::Data) foreach(comp ${CGAL_REQUESTED_COMPONENTS}) if(TARGET CGAL::CGAL_${comp}) target_link_libraries(${exe_name} PRIVATE CGAL::CGAL_${comp}) diff --git a/Installation/cmake/modules/CGAL_add_test.cmake b/Installation/cmake/modules/CGAL_add_test.cmake index 0864203ae20..282b161acce 100644 --- a/Installation/cmake/modules/CGAL_add_test.cmake +++ b/Installation/cmake/modules/CGAL_add_test.cmake @@ -326,6 +326,7 @@ function(cgal_add_test exe_name) endif() if(EXISTS ${cmd_file}) file(STRINGS "${cmd_file}" CMD_LINES) + string(CONFIGURE "${CMD_LINES}" CMD_LINES) set(ARGS) # message(STATUS "DEBUG test ${exe_name}") foreach(CMD_LINE ${CMD_LINES}) diff --git a/Installation/cmake/modules/CGAL_pointmatcher_support.cmake b/Installation/cmake/modules/CGAL_pointmatcher_support.cmake index 7323feae702..ab55c3b86f9 100644 --- a/Installation/cmake/modules/CGAL_pointmatcher_support.cmake +++ b/Installation/cmake/modules/CGAL_pointmatcher_support.cmake @@ -9,7 +9,7 @@ if(libpointmatcher_FOUND AND NOT TARGET CGAL::pointmatcher_support) add_library(CGAL::pointmatcher_support INTERFACE IMPORTED) target_compile_definitions(CGAL::pointmatcher_support INTERFACE "CGAL_LINKED_WITH_POINTMATCHER") target_include_directories(CGAL::pointmatcher_support INTERFACE "${libpointmatcher_INCLUDE_DIR}") - target_link_libraries(CGAL::pointmatcher_support INTERFACE "${libpointmatcher_LIBRARIES}") + target_link_libraries(CGAL::pointmatcher_support INTERFACE ${libpointmatcher_LIBRARIES}) else() message(STATUS "NOTICE : the libpointmatcher library requires the following boost components: thread filesystem system program_options date_time chrono.") endif() diff --git a/Installation/include/CGAL/atomic.h b/Installation/include/CGAL/atomic.h index da0a5c1c0a2..c9b6969b132 100644 --- a/Installation/include/CGAL/atomic.h +++ b/Installation/include/CGAL/atomic.h @@ -17,34 +17,21 @@ #ifdef CGAL_HAS_THREADS -# ifdef CGAL_CAN_USE_CXX11_ATOMIC # include -# define CGAL_ATOMIC_NS std -# else // not CGAL_CAN_USE_CXX11_ATOMIC -# if BOOST_VERSION >= 105300 -# include -# define CGAL_ATOMIC_NS boost -# else // BOOST_VERSION < 105300 -# define CGAL_NO_ATOMIC "Boost.Atomic was introduced in Boost-1.53". -# endif // BOOST_VERSION < 105300 -# endif // not CGAL_CAN_USE_CXX11_ATOMIC -# ifndef CGAL_NO_ATOMIC - namespace CGAL { - namespace cpp11 { - using CGAL_ATOMIC_NS ::atomic; +namespace CGAL { +namespace cpp11 { +using std::atomic; - using CGAL_ATOMIC_NS ::memory_order_relaxed; - using CGAL_ATOMIC_NS ::memory_order_consume; - using CGAL_ATOMIC_NS ::memory_order_acquire; - using CGAL_ATOMIC_NS ::memory_order_release; - using CGAL_ATOMIC_NS ::memory_order_acq_rel; - using CGAL_ATOMIC_NS ::memory_order_seq_cst; +using std::memory_order_relaxed; +using std::memory_order_consume; +using std::memory_order_acquire; +using std::memory_order_release; +using std::memory_order_acq_rel; +using std::memory_order_seq_cst; - using CGAL_ATOMIC_NS ::atomic_thread_fence; - } - } -# endif // CGAL_ATOMIC_NS +using std::atomic_thread_fence; +} } #else # define CGAL_NO_ATOMIC "No atomic because CGAL_NO_THREADS is defined." #endif // CGAL_HAS_THREADS diff --git a/Installation/include/CGAL/config.h b/Installation/include/CGAL/config.h index b39105005a8..33350489671 100644 --- a/Installation/include/CGAL/config.h +++ b/Installation/include/CGAL/config.h @@ -127,16 +127,6 @@ #include #include -// Hack: Boost<1.55 does not detect correctly the C++11 features of ICC. -// We declare by hand two features that we need (variadic templates and -// rvalue references). -#if defined(__INTEL_COMPILER) && defined(__GXX_EXPERIMENTAL_CXX0X__) -# undef BOOST_NO_VARIADIC_TEMPLATES -# undef BOOST_NO_CXX11_VARIADIC_TEMPLATES -# undef BOOST_NO_RVALUE_REFERENCES -# undef BOOST_NO_CXX11_RVALUE_REFERENCES -#endif - #include //----------------------------------------------------------------------// @@ -167,98 +157,6 @@ #define CGAL_USE_SSE2_FABS #endif -//----------------------------------------------------------------------// -// Detect features at compile-time. Some macros have only been -// introduced as of Boost 1.40. In that case, we simply say that the -// feature is not available, even if that is wrong. -// ----------------------------------------------------------------------// - -#if defined(BOOST_NO_0X_HDR_ARRAY) -#define CGAL_CFG_NO_CPP0X_ARRAY 1 -#endif -#if defined(BOOST_NO_0X_HDR_UNORDERED_SET) || \ - defined(BOOST_NO_0X_HDR_UNORDERED_MAP) || \ - (defined(_MSC_VER) && (_MSC_VER == 1800)) // std::unordered_set is very bad in MSVC2013 -#define CGAL_CFG_NO_CPP0X_UNORDERED 1 -#endif -#if defined( BOOST_NO_0X_HDR_THREAD) -#define CGAL_CFG_NO_STD_THREAD 1 -#endif -#if defined(BOOST_NO_DECLTYPE) -#define CGAL_CFG_NO_CPP0X_DECLTYPE 1 -#endif -#if defined(BOOST_NO_DELETED_FUNCTIONS) || \ - defined(BOOST_NO_DEFAULTED_FUNCTIONS) || \ - (defined(_MSC_VER) && _MSC_VER < 1900) // MSVC 2013 has only partial support -#define CGAL_CFG_NO_CPP0X_DELETED_AND_DEFAULT_FUNCTIONS 1 -#endif -#if defined(BOOST_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS) -#define CGAL_CFG_NO_CPP0X_DEFAULT_TEMPLATE_ARGUMENTS_FOR_FUNCTION_TEMPLATES 1 -#endif -#if defined(BOOST_NO_INITIALIZER_LISTS) -#define CGAL_CFG_NO_CPP0X_INITIALIZER_LISTS 1 -#endif -#if defined(BOOST_MSVC) -#define CGAL_CFG_NO_CPP0X_ISFINITE 1 // used in -#endif -#if defined(BOOST_NO_LONG_LONG) -#define CGAL_CFG_NO_CPP0X_LONG_LONG 1 -#endif -#if defined(BOOST_NO_LAMBDAS) -#define CGAL_CFG_NO_CPP0X_LAMBDAS 1 -#endif -#if defined(BOOST_NO_RVALUE_REFERENCES) -#define CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE 1 -#endif -#if defined(BOOST_NO_STATIC_ASSERT) -#define CGAL_CFG_NO_CPP0X_STATIC_ASSERT 1 -#endif -#if defined(BOOST_NO_0X_HDR_TUPLE) -#define CGAL_CFG_NO_CPP0X_TUPLE 1 -#endif -#if defined(BOOST_NO_VARIADIC_TEMPLATES) -#define CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES 1 -#endif -// never use TR1 -#define CGAL_CFG_NO_TR1_ARRAY 1 -// never use TR1 -#define CGAL_CFG_NO_TR1_TUPLE 1 -#if (__GNUC__ <= 0) || defined(__INTEL_COMPILER) -#define CGAL_CFG_NO_STATEMENT_EXPRESSIONS 1 -#endif -#if _MSC_VER==1800 -#define CGAL_CFG_NO_CPP0X_UNIFIED_INITIALIZATION_SYNTAX -#endif -#if __cplusplus < 201103L && !(_MSC_VER >= 1600) -#define CGAL_CFG_NO_CPP0X_COPY_N 1 -#define CGAL_CFG_NO_CPP0X_NEXT_PREV 1 -#endif -#if defined(BOOST_NO_EXPLICIT_CONVERSION_OPERATIONS) \ - || defined(BOOST_NO_EXPLICIT_CONVERSION_OPERATORS) -#define CGAL_CFG_NO_CPP0X_EXPLICIT_CONVERSION_OPERATORS 1 -#endif -#if defined(BOOST_NO_TEMPLATE_ALIASES) -#define CGAL_CFG_NO_CPP0X_TEMPLATE_ALIASES 1 -#endif - -// Some random list to let us write C++11 without thinking about -// each feature we are using. -#if ( __cplusplus >= 201103L || _MSVC_LANG >= 201103L ) && \ - !defined CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES && \ - !defined CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE && \ - !defined CGAL_CFG_NO_CPP0X_EXPLICIT_CONVERSION_OPERATORS && \ - !defined CGAL_CFG_NO_CPP0X_TUPLE && \ - !defined CGAL_CFG_NO_CPP0X_UNIFIED_INITIALIZATION_SYNTAX && \ - !defined CGAL_CFG_NO_CPP0X_STATIC_ASSERT && \ - !defined CGAL_CFG_NO_CPP0X_DECLTYPE && \ - !defined CGAL_CFG_NO_CPP0X_DELETED_AND_DEFAULT_FUNCTIONS && \ - !defined CGAL_CFG_NO_CPP0X_DEFAULT_TEMPLATE_ARGUMENTS_FOR_FUNCTION_TEMPLATES -#define CGAL_CXX11 1 -#endif -// Same for C++14. -#if __cplusplus >= 201402L || _MSVC_LANG >= 201402L -# define CGAL_CXX14 1 -#endif // Same for C++17 #if __cplusplus >= 201703L || _MSVC_LANG >= 201703L # define CGAL_CXX17 1 @@ -300,28 +198,12 @@ #define CGAL_END_NAMESPACE } #endif - -#ifndef CGAL_CFG_NO_CPP0X_LONG_LONG -# define CGAL_USE_LONG_LONG -#endif - - #ifndef CGAL_CFG_TYPENAME_BEFORE_DEFAULT_ARGUMENT_BUG # define CGAL_TYPENAME_DEFAULT_ARG typename #else # define CGAL_TYPENAME_DEFAULT_ARG #endif - -#ifdef CGAL_CFG_NO_CPP0X_DELETED_AND_DEFAULT_FUNCTIONS -# define CGAL_DELETED -# define CGAL_EXPLICITLY_DEFAULTED -#else -# define CGAL_DELETED = delete -# define CGAL_EXPLICITLY_DEFAULTED = default -#endif - - // Big endian or little endian machine. // ==================================== @@ -481,7 +363,7 @@ using std::max; #define CGAL_NORETURN [[noreturn]] // Macro to specify [[no_unique_address]] if supported -#if CGAL_CXX11 && __has_cpp_attribute(no_unique_address) +#if __has_cpp_attribute(no_unique_address) # define CGAL_NO_UNIQUE_ADDRESS [[no_unique_address]] #else # define CGAL_NO_UNIQUE_ADDRESS @@ -508,25 +390,6 @@ using std::max; # endif #endif -#if __has_feature(cxx_thread_local) || \ - ( (__GNUC__ > 0) && __cplusplus >= 201103L ) || \ - ( _MSC_VER >= 1900 ) -// see also Installation/cmake/modules/config/support/CGAL_test_cpp_version.cpp -#define CGAL_CAN_USE_CXX11_THREAD_LOCAL -#endif - -#if (__has_include() && __cplusplus >= 201103L ) | \ - ( (__GNUC__ > 0) && __cplusplus >= 201103L ) || \ - ( _MSC_VER >= 1700 ) -#define CGAL_CAN_USE_CXX11_MUTEX -#endif - -#if (__has_include() && __cplusplus >= 201103L ) || \ - ( (__GNUC__ > 0) && __cplusplus >= 201103L ) || \ - ( _MSC_VER >= 1700 ) -#define CGAL_CAN_USE_CXX11_ATOMIC -#endif - #ifndef CGAL_HAS_THREADS namespace CGAL { inline bool is_currently_single_threaded(){ return true; } } #elif __has_include() @@ -684,4 +547,63 @@ namespace cpp11{ /// @} #include +//----------------------------------------------------------------------// +// Function to define data directory +//----------------------------------------------------------------------// +#include +#include +#include +#include + +namespace CGAL { + +// Returns filename prefixed by the directory of CGAL containing data. +// This directory is either defined in the environement variable CGAL_DATA_DIR, +// otherwise it is taken from the constant CGAL_DATA_DIR (defined in CMake), +// otherwise it is empty (and thus returns filename unmodified). +inline std::string data_file_path(const std::string& filename) +{ + const char* cgal_dir=nullptr; + +#ifdef _MSC_VER + char* cgal_dir_windows=nullptr; + _dupenv_s( &cgal_dir_windows, nullptr, "CGAL_DATA_DIR"); + if (cgal_dir_windows!=nullptr) + { cgal_dir=cgal_dir_windows; } +#else + cgal_dir=getenv("CGAL_DATA_DIR"); +#endif + +#ifdef CGAL_DATA_DIR + if (cgal_dir==nullptr) + { cgal_dir=CGAL_DATA_DIR; } +#endif + + std::string cgal_dir_string; + if (cgal_dir!=nullptr) + { cgal_dir_string=std::string(cgal_dir); } + + std::string res=cgal_dir_string; + if (!res.empty() && res.back()!='/') + { res+=std::string("/"); } + res+=filename; + + // Test if the file exists, write a warning otherwise + std::ifstream f(res); + if (!f) + { + std::cerr<<"[WARNING] file "< #ifdef CGAL_HAS_THREADS -#ifdef CGAL_CAN_USE_CXX11_MUTEX #include #define CGAL_MUTEX std::mutex #define CGAL_SCOPED_LOCK(M) std::unique_lock scoped_lock(M) -#else -#include -#define CGAL_MUTEX boost::mutex -#define CGAL_SCOPED_LOCK(M) boost::mutex::scoped_lock scoped_lock(M) -#endif #endif #endif // CGAL_MUTEX_H diff --git a/Installation/lib/cmake/CGAL/CGALConfig.cmake b/Installation/lib/cmake/CGAL/CGALConfig.cmake index bb8bdcc9c93..1bcd263382c 100644 --- a/Installation/lib/cmake/CGAL/CGALConfig.cmake +++ b/Installation/lib/cmake/CGAL/CGALConfig.cmake @@ -72,6 +72,32 @@ else() endif() endif() +#set CGAL_DATA_DIR +if (NOT CGAL_DATA_DIR) + if(DEFINED ENV{CGAL_DATA_DIR}) + set(CGAL_DATA_DIR $ENV{CGAL_DATA_DIR}) + else() + if (EXISTS "${CGAL_ROOT}/data") + set(CGAL_DATA_DIR "${CGAL_ROOT}/data") + else() + if (EXISTS "${CGAL_ROOT}/Data/data") + set(CGAL_DATA_DIR "${CGAL_ROOT}/Data/data") + else() + message("CGAL_ROOT = ${CGAL_ROOT}") + message(WARNING "CGAL_DATA_DIR cannot be deduced, set the variable CGAL_DATA_DIR to set the default value of CGAL::data_file_path()") + endif() + endif() + endif() +endif() + +if(NOT TARGET CGAL::Data) + add_library(CGAL::Data INTERFACE IMPORTED) + if ( NOT "${CGAL_DATA_DIR}" STREQUAL "" ) + set_target_properties(CGAL::Data PROPERTIES + INTERFACE_COMPILE_DEFINITIONS "CGAL_DATA_DIR=\"${CGAL_DATA_DIR}\"") + endif() +endif() + include(${CGAL_MODULES_DIR}/CGAL_CreateSingleSourceCGALProgram.cmake) include(${CGAL_MODULES_DIR}/CGAL_Macros.cmake) include(${CGAL_MODULES_DIR}/CGAL_Common.cmake) diff --git a/Interpolation/include/CGAL/regular_neighbor_coordinates_2.h b/Interpolation/include/CGAL/regular_neighbor_coordinates_2.h index 7fbb978bf8c..ce5c62c0b76 100644 --- a/Interpolation/include/CGAL/regular_neighbor_coordinates_2.h +++ b/Interpolation/include/CGAL/regular_neighbor_coordinates_2.h @@ -20,6 +20,7 @@ #include #include #include +#include #include #include diff --git a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Circle_2.h b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Circle_2.h index 4b05ffa7a34..4f24b27c2de 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Circle_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Circle_2.h @@ -17,11 +17,11 @@ #ifndef CGAL_INTERSECTIONS_2_CIRCLE_2_CIRCLE_2_H #define CGAL_INTERSECTIONS_2_CIRCLE_2_CIRCLE_2_H -#include -#include - +#include #include +#include + namespace CGAL { namespace Intersections { namespace internal { diff --git a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Line_2.h b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Line_2.h index 2ff82e64475..a850baa2253 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Line_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Line_2.h @@ -18,10 +18,11 @@ #ifndef CGAL_INTERSECTIONS_2_CIRCLE_2_LINE_2_H #define CGAL_INTERSECTIONS_2_CIRCLE_2_LINE_2_H +#include +#include + #include #include -#include -#include namespace CGAL { namespace Intersections { diff --git a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Ray_2.h b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Ray_2.h index 6a4c9d8b25d..18c19fd8466 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Ray_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Ray_2.h @@ -13,10 +13,11 @@ #ifndef CGAL_INTERSECTIONS_2_CIRCLE_2_RAY_2_H #define CGAL_INTERSECTIONS_2_CIRCLE_2_RAY_2_H +#include +#include + #include #include -#include -#include namespace CGAL { namespace Intersections { diff --git a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Segment_2.h b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Segment_2.h index efed12af6e3..71384fcc4e6 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Segment_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Segment_2.h @@ -13,10 +13,11 @@ #ifndef CGAL_INTERSECTIONS_2_CIRCLE_2_SEGMENT_2_H #define CGAL_INTERSECTIONS_2_CIRCLE_2_SEGMENT_2_H +#include +#include + #include #include -#include -#include namespace CGAL { namespace Intersections { diff --git a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Triangle_2.h b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Triangle_2.h index 35cfdd3ac01..9353da936ba 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Circle_2_Triangle_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Circle_2_Triangle_2.h @@ -13,10 +13,12 @@ #ifndef CGAL_INTERSECTIONS_2_CIRCLE_2_TRIANGLE_2_H #define CGAL_INTERSECTIONS_2_CIRCLE_2_TRIANGLE_2_H +#include +#include +#include + #include #include -#include -#include namespace CGAL { namespace Intersections { diff --git a/Intersections_2/include/CGAL/Intersections_2/Iso_rectangle_2_Line_2.h b/Intersections_2/include/CGAL/Intersections_2/Iso_rectangle_2_Line_2.h index 3315328d876..a8d188a7a42 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Iso_rectangle_2_Line_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Iso_rectangle_2_Line_2.h @@ -36,11 +36,10 @@ namespace internal { template class Line_2_Iso_rectangle_2_pair { public: - enum Intersection_results {NO_INTERSECTION, POINT, SEGMENT}; + enum Intersection_results {NO_INTERSECTION, POINT, SEGMENT, UNKNOWN}; Line_2_Iso_rectangle_2_pair(typename K::Line_2 const *line, typename K::Iso_rectangle_2 const *iso) - : _known(false), - _ref_point(line->point()), + : _ref_point(line->point()), _dir(line->direction().to_vector()), _isomin((iso->min)()), _isomax((iso->max)()) {} @@ -50,8 +49,7 @@ public: typename K::Point_2 intersection_point() const; typename K::Segment_2 intersection_segment() const; protected: - mutable bool _known; - mutable Intersection_results _result; + mutable Intersection_results _result = UNKNOWN; mutable typename K::FT _min, _max; typename K::Point_2 _ref_point; typename K::Vector_2 _dir; @@ -84,10 +82,9 @@ typename Line_2_Iso_rectangle_2_pair::Intersection_results Line_2_Iso_rectangle_2_pair::intersection_type() const { //typedef typename K::Line_2 line_t; - if (_known) + if (_result!=UNKNOWN) return _result; // The non const this pointer is used to cast away const. - _known = true; typedef typename K::FT FT; typedef typename K::RT RT; bool all_values = true; @@ -156,7 +153,7 @@ intersection_point() const typename K::Construct_translated_point_2 translated_point; typename K::Construct_scaled_vector_2 construct_scaled_vector; - if (!_known) + if (_result==UNKNOWN) intersection_type(); CGAL_kernel_assertion(_result == POINT); return translated_point(_ref_point, construct_scaled_vector(_dir, _min)); @@ -170,7 +167,7 @@ intersection_segment() const typename K::Construct_segment_2 construct_segment_2; typename K::Construct_translated_point_2 translated_point; typename K::Construct_scaled_vector_2 construct_scaled_vector; - if (!_known) + if (_result==UNKNOWN) intersection_type(); CGAL_kernel_assertion(_result == SEGMENT); return construct_segment_2(translated_point(_ref_point, construct_scaled_vector(_dir,_min)), diff --git a/Intersections_2/include/CGAL/Intersections_2/Iso_rectangle_2_Ray_2.h b/Intersections_2/include/CGAL/Intersections_2/Iso_rectangle_2_Ray_2.h index 8f4136e0843..5f2b52a311a 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Iso_rectangle_2_Ray_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Iso_rectangle_2_Ray_2.h @@ -35,10 +35,10 @@ namespace internal { template class Ray_2_Iso_rectangle_2_pair { public: - enum Intersection_results {NO_INTERSECTION, POINT, SEGMENT}; + enum Intersection_results {NO_INTERSECTION, POINT, SEGMENT, UNKNOWN}; Ray_2_Iso_rectangle_2_pair(typename K::Ray_2 const *ray, typename K::Iso_rectangle_2 const *iso) - : _known(false), _ref_point(ray->source()), _dir(ray->direction().to_vector()), + : _ref_point(ray->source()), _dir(ray->direction().to_vector()), _isomin((iso->min)()), _isomax((iso->max)()), _min((typename K::FT)(0)) {} Intersection_results intersection_type() const; @@ -46,8 +46,7 @@ public: typename K::Point_2 intersection_point() const; typename K::Segment_2 intersection_segment() const; protected: - mutable bool _known; - mutable Intersection_results _result; + mutable Intersection_results _result = UNKNOWN; mutable typename K::Point_2 _ref_point; mutable typename K::Vector_2 _dir; mutable typename K::Point_2 _isomin; @@ -109,9 +108,8 @@ Ray_2_Iso_rectangle_2_pair::intersection_type() const { typedef typename K::RT RT; typedef typename K::FT FT; - if (_known) + if (_result!=UNKNOWN) return _result; - _known = true; bool to_infinity = true; typename K::Construct_cartesian_const_iterator_2 construct_cccit; @@ -175,7 +173,7 @@ Ray_2_Iso_rectangle_2_pair::intersection_segment() const typedef typename K::Segment_2 Segment_2; typename K::Construct_translated_point_2 translated_point; typename K::Construct_scaled_vector_2 construct_scaled_vector; - if (!_known) + if (_result==UNKNOWN) intersection_type(); CGAL_kernel_assertion(_result == SEGMENT); typename K::Point_2 p1(translated_point(_ref_point, construct_scaled_vector(_dir,_min))); @@ -190,7 +188,7 @@ Ray_2_Iso_rectangle_2_pair::intersection_point() const typedef typename K::Point_2 Point_2; typename K::Construct_translated_point_2 translated_point; typename K::Construct_scaled_vector_2 construct_scaled_vector; - if (!_known) + if (_result==UNKNOWN) intersection_type(); CGAL_kernel_assertion(_result == POINT); return Point_2(translated_point(_ref_point, construct_scaled_vector(_dir, _min))); diff --git a/Intersections_2/include/CGAL/Intersections_2/Iso_rectangle_2_Segment_2.h b/Intersections_2/include/CGAL/Intersections_2/Iso_rectangle_2_Segment_2.h index 3b82ffd42a3..28121109d10 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Iso_rectangle_2_Segment_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Iso_rectangle_2_Segment_2.h @@ -36,7 +36,7 @@ namespace internal { template class Segment_2_Iso_rectangle_2_pair { public: - enum Intersection_results {NO_INTERSECTION, POINT, SEGMENT}; + enum Intersection_results {NO_INTERSECTION, POINT, SEGMENT, UNKNOWN}; Segment_2_Iso_rectangle_2_pair(typename K::Segment_2 const *seg, typename K::Iso_rectangle_2 const *rect) ; @@ -45,8 +45,7 @@ public: typename K::Point_2 intersection_point() const; typename K::Segment_2 intersection_segment() const; protected: - mutable bool _known; - mutable Intersection_results _result; + mutable Intersection_results _result = UNKNOWN; mutable typename K::Point_2 _ref_point; mutable typename K::Vector_2 _dir; mutable typename K::Point_2 _isomin; @@ -108,7 +107,6 @@ Segment_2_Iso_rectangle_2_pair( typename K::Segment_2 const *seg, typename K::Iso_rectangle_2 const *iso) { - _known = false; _isomin = (iso->min)(); _isomax = (iso->max)(); _ref_point = seg->source(); @@ -130,9 +128,8 @@ Segment_2_Iso_rectangle_2_pair::intersection_type() const { typedef typename K::RT RT; typedef typename K::FT FT; - if (_known) + if (_result!=UNKNOWN) return _result; - _known = true; typename K::Construct_cartesian_const_iterator_2 construct_cccit; typename K::Cartesian_const_iterator_2 ref_point_it = construct_cccit(_ref_point); @@ -190,7 +187,7 @@ intersection_segment() const typedef typename K::Segment_2 Segment_2; typename K::Construct_translated_point_2 translated_point; typename K::Construct_scaled_vector_2 construct_scaled_vector; - if (!_known) + if (_result==UNKNOWN) intersection_type(); CGAL_kernel_assertion(_result == SEGMENT); typename K::Point_2 p1(translated_point(_ref_point, construct_scaled_vector(_dir,_min))); @@ -205,7 +202,7 @@ intersection_point() const { typename K::Construct_translated_point_2 translated_point; typename K::Construct_scaled_vector_2 construct_scaled_vector; - if (!_known) + if (_result==UNKNOWN) intersection_type(); CGAL_kernel_assertion(_result == POINT); return translated_point(_ref_point, construct_scaled_vector(_dir,_min)); diff --git a/Intersections_2/include/CGAL/Intersections_2/Line_2_Line_2.h b/Intersections_2/include/CGAL/Intersections_2/Line_2_Line_2.h index d95ddec8f2a..8d2d3e6ae0d 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Line_2_Line_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Line_2_Line_2.h @@ -36,10 +36,10 @@ namespace internal { template class Line_2_Line_2_pair { public: - enum Intersection_results {NOT_COMPUTED_YET, NO_INTERSECTION, POINT, LINE}; + enum Intersection_results {NO_INTERSECTION, POINT, LINE, UNKNOWN}; Line_2_Line_2_pair(typename K::Line_2 const *line1, typename K::Line_2 const *line2) - : _line1(line1), _line2(line2), _result(NOT_COMPUTED_YET) {} + : _line1(line1), _line2(line2) {} Intersection_results intersection_type() const; @@ -48,7 +48,7 @@ public: protected: typename K::Line_2 const* _line1; typename K::Line_2 const * _line2; - mutable Intersection_results _result; + mutable Intersection_results _result = UNKNOWN; mutable typename K::Point_2 _intersection_point; }; @@ -140,7 +140,7 @@ typename Line_2_Line_2_pair::Intersection_results Line_2_Line_2_pair::intersection_type() const { typedef typename K::RT RT; - if (_result != NOT_COMPUTED_YET) + if (_result != UNKNOWN) return _result; RT nom1, nom2, denom; // The non const this pointer is used to cast away const. @@ -178,7 +178,7 @@ template typename K::Point_2 Line_2_Line_2_pair::intersection_point() const { - if (_result == NOT_COMPUTED_YET) + if (_result == UNKNOWN) intersection_type(); CGAL_kernel_assertion(_result == POINT); return _intersection_point; @@ -188,7 +188,7 @@ template typename K::Line_2 Line_2_Line_2_pair::intersection_line() const { - if (_result == NOT_COMPUTED_YET) + if (_result == UNKNOWN) intersection_type(); CGAL_kernel_assertion(_result == LINE); return *_line1; diff --git a/Intersections_2/include/CGAL/Intersections_2/Line_2_Ray_2.h b/Intersections_2/include/CGAL/Intersections_2/Line_2_Ray_2.h index eada9a07ec2..87f59d8a45a 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Line_2_Ray_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Line_2_Ray_2.h @@ -35,11 +35,11 @@ namespace internal { template class Ray_2_Line_2_pair { public: - enum Intersection_results {NOT_COMPUTED_YET, NO_INTERSECTION, POINT, RAY}; + enum Intersection_results {NO_INTERSECTION, POINT, RAY, UNKNOWN}; typedef typename K::FT FT; Ray_2_Line_2_pair(typename K::Ray_2 const *ray, typename K::Line_2 const *line) - : _ray(ray), _line(line), _result(NOT_COMPUTED_YET), + : _ray(ray), _line(line), _intersection_point(K().construct_point_2_object()(ORIGIN)) {} @@ -50,7 +50,7 @@ public: protected: typename K::Ray_2 const * _ray; typename K::Line_2 const * _line; - mutable Intersection_results _result; + mutable Intersection_results _result = UNKNOWN; mutable typename K::Point_2 _intersection_point; }; @@ -117,7 +117,7 @@ template typename Ray_2_Line_2_pair::Intersection_results Ray_2_Line_2_pair::intersection_type() const { - if (_result != NOT_COMPUTED_YET) + if (_result != UNKNOWN) return _result; // The non const this pointer is used to cast away const. const typename K::Line_2 &l1 = _ray->supporting_line(); @@ -144,7 +144,7 @@ template typename K::Point_2 Ray_2_Line_2_pair::intersection_point() const { - if (_result == NOT_COMPUTED_YET) + if (_result == UNKNOWN) intersection_type(); CGAL_kernel_assertion(_result == POINT); return _intersection_point; @@ -154,7 +154,7 @@ template typename K::Ray_2 Ray_2_Line_2_pair::intersection_ray() const { - if (_result == NOT_COMPUTED_YET) + if (_result == UNKNOWN) intersection_type(); CGAL_kernel_assertion(_result == RAY); return *_ray; diff --git a/Intersections_2/include/CGAL/Intersections_2/Line_2_Segment_2.h b/Intersections_2/include/CGAL/Intersections_2/Line_2_Segment_2.h index 17d60e41a07..0c5d881b544 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Line_2_Segment_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Line_2_Segment_2.h @@ -34,10 +34,10 @@ namespace internal { template class Segment_2_Line_2_pair { public: - enum Intersection_results {NO_INTERSECTION, POINT, SEGMENT}; + enum Intersection_results {NO_INTERSECTION, POINT, SEGMENT, UNKNOWN}; Segment_2_Line_2_pair(typename K::Segment_2 const *seg, typename K::Line_2 const *line) - : _seg(seg), _line(line), _known(false) {} + : _seg(seg), _line(line) {} Intersection_results intersection_type() const; @@ -46,8 +46,7 @@ public: protected: typename K::Segment_2 const*_seg; typename K::Line_2 const * _line; - mutable bool _known; - mutable Intersection_results _result; + mutable Intersection_results _result = UNKNOWN; mutable typename K::Point_2 _intersection_point; }; @@ -108,10 +107,9 @@ template typename Segment_2_Line_2_pair::Intersection_results Segment_2_Line_2_pair::intersection_type() const { - if (_known) + if (_result!=UNKNOWN) return _result; // The non const this pointer is used to cast away const. - _known = true; const typename K::Line_2 &l1 = _seg->supporting_line(); Line_2_Line_2_pair linepair(&l1, _line); switch ( linepair.intersection_type()) { @@ -136,7 +134,7 @@ template typename K::Point_2 Segment_2_Line_2_pair::intersection_point() const { - if (!_known) + if (_result==UNKNOWN) intersection_type(); CGAL_kernel_assertion(_result == POINT); return _intersection_point; @@ -146,7 +144,7 @@ template typename K::Segment_2 Segment_2_Line_2_pair::intersection_segment() const { - if (!_known) + if (_result==UNKNOWN) intersection_type(); CGAL_kernel_assertion(_result == SEGMENT); return *_seg; diff --git a/Intersections_2/include/CGAL/Intersections_2/Line_2_Triangle_2.h b/Intersections_2/include/CGAL/Intersections_2/Line_2_Triangle_2.h index 7dc337bade3..9f514030f8a 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Line_2_Triangle_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Line_2_Triangle_2.h @@ -36,10 +36,10 @@ namespace internal { template class Line_2_Triangle_2_pair { public: - enum Intersection_results {NO_INTERSECTION, POINT, SEGMENT}; + enum Intersection_results {NO_INTERSECTION, POINT, SEGMENT, UNKNOWN}; Line_2_Triangle_2_pair(typename K::Line_2 const *line, typename K::Triangle_2 const *trian) - : _line(line), _trian(trian), _known(false) {} + : _line(line), _trian(trian) {} Intersection_results intersection_type() const; @@ -48,8 +48,7 @@ public: protected: typename K::Line_2 const*_line; typename K::Triangle_2 const * _trian; - mutable bool _known; - mutable Intersection_results _result; + mutable Intersection_results _result = UNKNOWN; mutable typename K::Point_2 _intersection_point; mutable typename K::Point_2 _other_point; }; @@ -81,10 +80,9 @@ typename Line_2_Triangle_2_pair::Intersection_results Line_2_Triangle_2_pair::intersection_type() const { typedef typename K::Line_2 Line_2; - if (_known) + if (_result!=UNKNOWN) return _result; // The non const this pointer is used to cast away const. - _known = true; Straight_2_ straight(*_line); Line_2 l(_trian->vertex(0), _trian->vertex(1)); if (l.oriented_side(_trian->vertex(2)) == ON_POSITIVE_SIDE) { @@ -133,7 +131,7 @@ typename K::Point_2 Line_2_Triangle_2_pair:: intersection_point() const { - if (!_known) + if (_result==UNKNOWN) intersection_type(); CGAL_kernel_assertion(_result == POINT); return _intersection_point; @@ -145,7 +143,7 @@ Line_2_Triangle_2_pair:: intersection_segment() const { typedef typename K::Segment_2 Segment_2; - if (!_known) + if (_result==UNKNOWN) intersection_type(); CGAL_kernel_assertion(_result == SEGMENT); return Segment_2(_intersection_point, _other_point); diff --git a/Intersections_2/include/CGAL/Intersections_2/Point_2_Triangle_2.h b/Intersections_2/include/CGAL/Intersections_2/Point_2_Triangle_2.h index 74f8db8c01a..ba496198cd9 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Point_2_Triangle_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Point_2_Triangle_2.h @@ -33,10 +33,10 @@ namespace internal { template class Point_2_Triangle_2_pair { public: - enum Intersection_results {NO_INTERSECTION, POINT}; + enum Intersection_results {NO_INTERSECTION, POINT, UNKNOWN}; Point_2_Triangle_2_pair(typename K::Point_2 const *pt, typename K::Triangle_2 const *trian) - : _pt(pt), _trian(trian), _known(false) {} + : _pt(pt), _trian(trian) {} Intersection_results intersection_type() const; @@ -44,8 +44,7 @@ public: protected: typename K::Point_2 const * _pt; typename K::Triangle_2 const * _trian; - mutable bool _known; - mutable Intersection_results _result; + mutable Intersection_results _result = UNKNOWN; mutable typename K::Point_2 _intersection_point; mutable typename K::Point_2 _other_point; }; @@ -73,10 +72,9 @@ template typename Point_2_Triangle_2_pair::Intersection_results Point_2_Triangle_2_pair::intersection_type() const { - if (_known) + if (_result!=UNKNOWN) return _result; // The non const this pointer is used to cast away const. - _known = true; if (_trian->has_on_unbounded_side(*_pt)) { _result = NO_INTERSECTION; } else { @@ -92,7 +90,7 @@ typename K::Point_2 Point_2_Triangle_2_pair:: intersection_point() const { - if (!_known) + if (_result==UNKNOWN) intersection_type(); CGAL_kernel_assertion(_result == POINT); return *_pt; diff --git a/Intersections_2/include/CGAL/Intersections_2/Ray_2_Ray_2.h b/Intersections_2/include/CGAL/Intersections_2/Ray_2_Ray_2.h index a59f4ba4443..2b0c166797b 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Ray_2_Ray_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Ray_2_Ray_2.h @@ -36,10 +36,10 @@ namespace internal { template class Ray_2_Ray_2_pair { public: - enum Intersection_results {NO_INTERSECTION, POINT, SEGMENT, RAY}; + enum Intersection_results {NO_INTERSECTION, POINT, SEGMENT, RAY, UNKNOWN}; Ray_2_Ray_2_pair(typename K::Ray_2 const *ray1, typename K::Ray_2 const *ray2) - : _ray1(ray1), _ray2(ray2), _known(false) {} + : _ray1(ray1), _ray2(ray2) {} Intersection_results intersection_type() const; @@ -49,8 +49,7 @@ public: protected: typename K::Ray_2 const* _ray1; typename K::Ray_2 const * _ray2; - mutable bool _known; - mutable Intersection_results _result; + mutable Intersection_results _result = UNKNOWN; mutable typename K::Point_2 _intersection_point, _other_point; }; @@ -71,10 +70,9 @@ template typename Ray_2_Ray_2_pair::Intersection_results Ray_2_Ray_2_pair::intersection_type() const { - if (_known) + if (_result!=UNKNOWN) return _result; // The non const this pointer is used to cast away const. - _known = true; // if (!do_overlap(_ray1->bbox(), _ray2->bbox())) // return NO_INTERSECTION; const typename K::Line_2 &l1 = _ray1->supporting_line(); @@ -196,7 +194,7 @@ template typename K::Point_2 Ray_2_Ray_2_pair::intersection_point() const { - if (!_known) + if (_result==UNKNOWN) intersection_type(); CGAL_kernel_assertion(_result == POINT); return _intersection_point; @@ -207,7 +205,7 @@ typename K::Segment_2 Ray_2_Ray_2_pair::intersection_segment() const { typedef typename K::Segment_2 Segment_2; - if (!_known) + if (_result==UNKNOWN) intersection_type(); CGAL_kernel_assertion(_result == SEGMENT); return Segment_2(_ray1->source(), _ray2->source()); @@ -218,7 +216,7 @@ typename K::Ray_2 Ray_2_Ray_2_pair::intersection_ray() const { typedef typename K::Ray_2 Ray_2; - if (!_known) + if (_result==UNKNOWN) intersection_type(); CGAL_kernel_assertion(_result == RAY); return Ray_2(_intersection_point, _ray1->direction()); diff --git a/Intersections_2/include/CGAL/Intersections_2/Ray_2_Segment_2.h b/Intersections_2/include/CGAL/Intersections_2/Ray_2_Segment_2.h index 579938c97fc..2cdebe84a13 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Ray_2_Segment_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Ray_2_Segment_2.h @@ -37,10 +37,10 @@ namespace internal { template class Ray_2_Segment_2_pair { public: - enum Intersection_results {NO_INTERSECTION, POINT, SEGMENT}; + enum Intersection_results {NO_INTERSECTION, POINT, SEGMENT, UNKNOWN}; Ray_2_Segment_2_pair(typename K::Ray_2 const *ray, typename K::Segment_2 const *seg) - : _ray(ray), _seg(seg), _known(false) {} + : _ray(ray), _seg(seg) {} Intersection_results intersection_type() const; @@ -49,8 +49,7 @@ public: protected: typename K::Ray_2 const * _ray; typename K::Segment_2 const * _seg; - mutable bool _known; - mutable Intersection_results _result; + mutable Intersection_results _result = UNKNOWN; mutable typename K::Point_2 _intersection_point, _other_point; }; @@ -76,10 +75,9 @@ template typename Ray_2_Segment_2_pair::Intersection_results Ray_2_Segment_2_pair::intersection_type() const { - if (_known) + if (_result!=UNKNOWN) return _result; // The non const this pointer is used to cast away const. - _known = true; // if (!do_overlap(_ray->bbox(), _seg->bbox())) // return NO_INTERSECTION; const typename K::Line_2 &l1 = _ray->supporting_line(); @@ -211,7 +209,7 @@ template typename K::Point_2 Ray_2_Segment_2_pair::intersection_point() const { - if (!_known) + if (_result==UNKNOWN) intersection_type(); CGAL_kernel_assertion(_result == POINT); return _intersection_point; @@ -222,7 +220,7 @@ typename K::Segment_2 Ray_2_Segment_2_pair::intersection_segment() const { typedef typename K::Segment_2 Segment_2; - if (!_known) + if (_result==UNKNOWN) intersection_type(); CGAL_kernel_assertion(_result == SEGMENT); return Segment_2(_intersection_point, _other_point); diff --git a/Intersections_2/include/CGAL/Intersections_2/Ray_2_Triangle_2.h b/Intersections_2/include/CGAL/Intersections_2/Ray_2_Triangle_2.h index 8384f917299..6db56586c55 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Ray_2_Triangle_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Ray_2_Triangle_2.h @@ -34,10 +34,10 @@ namespace internal { template class Ray_2_Triangle_2_pair { public: - enum Intersection_results {NO_INTERSECTION, POINT, SEGMENT}; + enum Intersection_results {NO_INTERSECTION, POINT, SEGMENT, UNKNOWN}; Ray_2_Triangle_2_pair(typename K::Ray_2 const *ray, typename K::Triangle_2 const *trian) - : _ray(ray), _trian(trian), _known(false) {} + : _ray(ray), _trian(trian) {} Intersection_results intersection_type() const; @@ -46,8 +46,7 @@ public: protected: typename K::Ray_2 const* _ray; typename K::Triangle_2 const * _trian; - mutable bool _known; - mutable Intersection_results _result; + mutable Intersection_results _result = UNKNOWN; mutable typename K::Point_2 _intersection_point; mutable typename K::Point_2 _other_point; }; @@ -59,10 +58,9 @@ typename Ray_2_Triangle_2_pair::Intersection_results Ray_2_Triangle_2_pair::intersection_type() const { typedef typename K::Line_2 Line_2; - if (_known) + if (_result!=UNKNOWN) return _result; // The non const this pointer is used to cast away const. - _known = true; Straight_2_ straight(*_ray); Line_2 l(_trian->vertex(0), _trian->vertex(1)); if (l.oriented_side(_trian->vertex(2)) == ON_POSITIVE_SIDE) { @@ -111,7 +109,7 @@ typename K::Point_2 Ray_2_Triangle_2_pair:: intersection_point() const { - if (!_known) + if (_result==UNKNOWN) intersection_type(); CGAL_kernel_assertion(_result == POINT); return _intersection_point; @@ -123,7 +121,7 @@ Ray_2_Triangle_2_pair:: intersection_segment() const { typedef typename K::Segment_2 Segment_2; - if (!_known) + if (_result==UNKNOWN) intersection_type(); CGAL_kernel_assertion(_result == SEGMENT); return Segment_2(_intersection_point, _other_point); diff --git a/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h b/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h index ba3d8b9567c..3b9e7003a40 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Segment_2_Segment_2.h @@ -274,10 +274,10 @@ do_intersect(const typename K::Segment_2 &seg1, template class Segment_2_Segment_2_pair { public: - enum Intersection_results {NO_INTERSECTION, POINT, SEGMENT}; + enum Intersection_results {NO_INTERSECTION, POINT, SEGMENT, UNKNOWN}; Segment_2_Segment_2_pair(typename K::Segment_2 const *seg1, typename K::Segment_2 const *seg2) - : _seg1(seg1), _seg2(seg2), _known(false) {} + : _seg1(seg1), _seg2(seg2) {} Intersection_results intersection_type() const; @@ -286,8 +286,7 @@ public: protected: typename K::Segment_2 const* _seg1; typename K::Segment_2 const * _seg2; - mutable bool _known; - mutable Intersection_results _result; + mutable Intersection_results _result = UNKNOWN; mutable typename K::Point_2 _intersection_point, _other_point; }; @@ -296,9 +295,8 @@ typename Segment_2_Segment_2_pair::Intersection_results Segment_2_Segment_2_pair::intersection_type() const { typename K::Construct_vector_2 construct_vector; - if (_known) + if (_result!=UNKNOWN) return _result; - _known = true; if (!internal::do_intersect(*_seg1, *_seg2, K())) { _result = NO_INTERSECTION; return _result; @@ -408,7 +406,7 @@ template typename K::Point_2 Segment_2_Segment_2_pair::intersection_point() const { - if (!_known) + if (_result==UNKNOWN) intersection_type(); CGAL_kernel_assertion(_result == POINT); return _intersection_point; @@ -419,7 +417,7 @@ typename K::Segment_2 Segment_2_Segment_2_pair::intersection_segment() const { typedef typename K::Segment_2 Segment_2; - if (!_known) + if (_result==UNKNOWN) intersection_type(); CGAL_kernel_assertion(_result == SEGMENT); return Segment_2(_intersection_point, _other_point); diff --git a/Intersections_2/include/CGAL/Intersections_2/Segment_2_Triangle_2.h b/Intersections_2/include/CGAL/Intersections_2/Segment_2_Triangle_2.h index f048c2bd35f..4d2b93c05cf 100644 --- a/Intersections_2/include/CGAL/Intersections_2/Segment_2_Triangle_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/Segment_2_Triangle_2.h @@ -34,10 +34,10 @@ namespace internal { template class Segment_2_Triangle_2_pair { public: - enum Intersection_results {NO_INTERSECTION, POINT, SEGMENT}; + enum Intersection_results {NO_INTERSECTION, POINT, SEGMENT, UNKNOWN}; Segment_2_Triangle_2_pair(typename K::Segment_2 const *seg, typename K::Triangle_2 const *trian) - : _seg(seg), _trian(trian), _known(false) {} + : _seg(seg), _trian(trian) {} Intersection_results intersection_type() const; @@ -46,8 +46,7 @@ public: protected: typename K::Segment_2 const * _seg; typename K::Triangle_2 const * _trian; - mutable bool _known; - mutable Intersection_results _result; + mutable Intersection_results _result = UNKNOWN; mutable typename K::Point_2 _intersection_point; mutable typename K::Point_2 _other_point; }; @@ -71,10 +70,9 @@ template typename Segment_2_Triangle_2_pair::Intersection_results Segment_2_Triangle_2_pair::intersection_type() const { - if (_known) + if (_result!=UNKNOWN) return _result; // The non const this pointer is used to cast away const. - _known = true; Straight_2_ straight(*_seg); typedef typename K::Line_2 Line_2; @@ -124,7 +122,7 @@ typename K::Point_2 Segment_2_Triangle_2_pair:: intersection_point() const { - if (!_known) + if (_result==UNKNOWN) intersection_type(); CGAL_kernel_assertion(_result == POINT); return _intersection_point; @@ -136,7 +134,7 @@ Segment_2_Triangle_2_pair:: intersection_segment() const { typedef typename K::Segment_2 Segment_2; - if (!_known) + if (_result==UNKNOWN) intersection_type(); CGAL_kernel_assertion(_result == SEGMENT); return Segment_2(_intersection_point, _other_point); diff --git a/Intersections_2/include/CGAL/Intersections_2/internal/Straight_2.h b/Intersections_2/include/CGAL/Intersections_2/internal/Straight_2.h index fa63e699475..36cc7e06486 100644 --- a/Intersections_2/include/CGAL/Intersections_2/internal/Straight_2.h +++ b/Intersections_2/include/CGAL/Intersections_2/internal/Straight_2.h @@ -18,8 +18,8 @@ #ifndef CGAL_INTERSECTIONS_2_INTERNAL_STRAIGHT_2_H #define CGAL_INTERSECTIONS_2_INTERNAL_STRAIGHT_2_H +#include #include -#include #include namespace CGAL { diff --git a/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h b/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h index 896c6bf5748..d752d7c87e9 100644 --- a/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h +++ b/Intersections_2/include/CGAL/Intersections_2/internal/Triangle_2_Triangle_2_intersection_impl.h @@ -22,6 +22,7 @@ #include #include #include +#include namespace CGAL { @@ -153,10 +154,10 @@ void _cut_off(Pointlist_2_ &list, template class Triangle_2_Triangle_2_pair { public: - enum Intersection_results {NO_INTERSECTION, POINT, SEGMENT, TRIANGLE, POLYGON}; + enum Intersection_results {NO_INTERSECTION, POINT, SEGMENT, TRIANGLE, POLYGON, UNKNOWN}; Triangle_2_Triangle_2_pair(typename K::Triangle_2 const *trian1, typename K::Triangle_2 const *trian2) - : _trian1(trian1), _trian2(trian2), _known(false) {} + : _trian1(trian1), _trian2(trian2) {} Intersection_results intersection_type() const; @@ -169,8 +170,7 @@ public: protected: typename K::Triangle_2 const* _trian1; typename K::Triangle_2 const * _trian2; - mutable bool _known; - mutable Intersection_results _result; + mutable Intersection_results _result = UNKNOWN; mutable Pointlist_2_ _pointlist; }; @@ -179,10 +179,9 @@ typename Triangle_2_Triangle_2_pair::Intersection_results Triangle_2_Triangle_2_pair::intersection_type() const { typedef typename K::Line_2 Line_2; - if (_known) + if (_result!=UNKNOWN) return _result; // The non const this pointer is used to cast away const. - _known = true; if (!do_overlap(_trian1->bbox(), _trian2->bbox())) { _result = NO_INTERSECTION; return _result; @@ -234,7 +233,7 @@ bool Triangle_2_Triangle_2_pair::intersection( /* Polygon_2 &result */) const { - if (!_known) + if (_result==UNKNOWN) intersection_type(); if (_result != TRIANGLE && _result != POLYGON) return false; @@ -254,7 +253,7 @@ template int Triangle_2_Triangle_2_pair::vertex_count() const { - CGAL_kernel_assertion(_known); + CGAL_kernel_assertion(_result!=UNKNOWN); return _pointlist.size; } @@ -262,7 +261,7 @@ template typename K::Point_2 Triangle_2_Triangle_2_pair::vertex(int n) const { - CGAL_kernel_assertion(_known); + CGAL_kernel_assertion(_result!=UNKNOWN); CGAL_kernel_assertion(n >= 0 && n < _pointlist.size); Pointlist_2_rec_ *cur; int k; @@ -278,7 +277,7 @@ typename K::Triangle_2 Triangle_2_Triangle_2_pair::intersection_triangle() const { typedef typename K::Triangle_2 Triangle_2; - if (!_known) + if (_result==UNKNOWN) intersection_type(); CGAL_kernel_assertion(_result == TRIANGLE); if(CGAL::left_turn(_pointlist.first->point, @@ -301,7 +300,7 @@ typename K::Segment_2 Triangle_2_Triangle_2_pair::intersection_segment() const { typedef typename K::Segment_2 Segment_2; - if (!_known) + if (_result==UNKNOWN) intersection_type(); CGAL_kernel_assertion(_result == SEGMENT); return Segment_2(_pointlist.first->point, @@ -312,7 +311,7 @@ template typename K::Point_2 Triangle_2_Triangle_2_pair::intersection_point() const { - if (!_known) + if (_result==UNKNOWN) intersection_type(); CGAL_kernel_assertion(_result == POINT); return _pointlist.first->point; diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Line_3_Sphere_3_do_intersect.h b/Intersections_3/include/CGAL/Intersections_3/internal/Line_3_Sphere_3_do_intersect.h index 17cb1c2761c..23cf7fbb4dd 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Line_3_Sphere_3_do_intersect.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Line_3_Sphere_3_do_intersect.h @@ -14,7 +14,7 @@ #define CGAL_INTERNAL_INTERSECTIONS_3_LINE_3_SPHERE_3_DO_INTERSECT_H #include -#include +#include namespace CGAL { namespace Intersections { diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Ray_3_Sphere_3_do_intersect.h b/Intersections_3/include/CGAL/Intersections_3/internal/Ray_3_Sphere_3_do_intersect.h index eea104dd7f5..974b6533c62 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Ray_3_Sphere_3_do_intersect.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Ray_3_Sphere_3_do_intersect.h @@ -14,7 +14,7 @@ #define CGAL_INTERNAL_INTERSECTIONS_RAY_3_SPHERE_3_DO_INTERSECT_H #include -#include +#include namespace CGAL { namespace Intersections { diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Segment_3_Sphere_3_do_intersect.h b/Intersections_3/include/CGAL/Intersections_3/internal/Segment_3_Sphere_3_do_intersect.h index 3be7f782408..45d3dffbbbb 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Segment_3_Sphere_3_do_intersect.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Segment_3_Sphere_3_do_intersect.h @@ -14,7 +14,7 @@ #define CGAL_INTERNAL_INTERSECTIONS_SEGMENT_3_SPHERE_3_DO_INTERSECT_H #include -#include +#include namespace CGAL { namespace Intersections { diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Sphere_3_Triangle_3_do_intersect.h b/Intersections_3/include/CGAL/Intersections_3/internal/Sphere_3_Triangle_3_do_intersect.h index f5d0e65c7a5..0ea78ba254c 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Sphere_3_Triangle_3_do_intersect.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Sphere_3_Triangle_3_do_intersect.h @@ -14,7 +14,7 @@ #define CGAL_INTERNAL_INTERSECTIONS_SPHERE_3_TRIANGLE_3_DO_INTERSECT_H #include -#include +#include namespace CGAL { namespace Intersections { diff --git a/Kernel_23/doc/Kernel_23/CGAL/squared_distance_2.h b/Kernel_23/doc/Kernel_23/CGAL/squared_distance_2.h index 5927a121da3..91e332a1bdc 100644 --- a/Kernel_23/doc/Kernel_23/CGAL/squared_distance_2.h +++ b/Kernel_23/doc/Kernel_23/CGAL/squared_distance_2.h @@ -30,8 +30,7 @@ In 2D, the types `Type1` and `Type2` can be any of the following: as well as any combination of `Kernel::Point_2` and `Kernel::Weighted_point_2` -In 3D, the types `Type1` and `Type2` can be any of the -following: +In 3D, the types `Type1` and `Type2` can be any of the following: - `Point_3` - `Line_3` @@ -39,9 +38,12 @@ following: - `Segment_3` - `Plane_3` -as well as combinations `Point_3`/`Triangle_3`, -and `Weighted_point_3`/`Triangle_3`, as well as `Point_3`/`Tetrahedron_3`, -and `Weighted_point_3`/`Tetrahedron_3` +as well as the following combinations: +- `Point_3`/`Triangle_3` +- `Point_3`/`Tetrahedron_3` +- `Weighted_point_3`/`Triangle_3` +- `Weighted_point_3`/`Tetrahedron_3` +- `Triangle_3`/`Triangle_3` \sa `compare_distance_to_point_grp` \sa `compare_signed_distance_to_line_grp` diff --git a/Kernel_23/include/CGAL/Kernel/function_objects.h b/Kernel_23/include/CGAL/Kernel/function_objects.h index 06758a7d7a3..c3a7337aefb 100644 --- a/Kernel_23/include/CGAL/Kernel/function_objects.h +++ b/Kernel_23/include/CGAL/Kernel/function_objects.h @@ -2850,8 +2850,8 @@ namespace CommonKernelFunctors { public: typename K::Point_3 - operator()(const typename K::Point_3& origin, - const typename K::Triangle_3& triangle, + operator()(const typename K::Triangle_3& triangle, + const typename K::Point_3& origin, const K& k) { typedef typename K::Point_3 Point_3; @@ -2890,18 +2890,18 @@ namespace CommonKernelFunctors { if(linf_ab > linf_ac) { if(linf_ab > linf_bc) { // ab is the maximal segment - return this->operator()(origin, seg(a, b), k); + return this->operator()(seg(a, b), origin, k); } else { // ab > ac, bc >= ab, use bc - return this->operator()(origin, seg(b, c), k); + return this->operator()(seg(b, c), origin, k); } } else { // ab <= ac if(linf_ac > linf_bc) { // ac is the maximal segment - return this->operator()(origin, seg(a, c), k); + return this->operator()(seg(a, c), origin, k); } else { // ab <= ac, ac <= bc, use bc - return this->operator()(origin, seg(b, c), k); + return this->operator()(seg(b, c), origin, k); } } } // degenerate plane @@ -2923,8 +2923,8 @@ namespace CommonKernelFunctors { } typename K::Point_3 - operator()(const typename K::Point_3& query, - const typename K::Segment_3& segment, + operator()(const typename K::Segment_3& segment, + const typename K::Point_3& query, const K& k) { @@ -2945,8 +2945,8 @@ namespace CommonKernelFunctors { } typename K::Point_3 - operator()(const typename K::Point_3& query, - const typename K::Ray_3& ray, + operator()(const typename K::Ray_3& ray, + const typename K::Point_3& query, const K& k) { if ( ray.to_vector() * (query-ray.source()) <= 0) @@ -2957,6 +2957,14 @@ namespace CommonKernelFunctors { } } + const typename K::Point_3& + operator()(const typename K::Point_3& point, + const typename K::Point_3&, + const K&) + { + return point; + } + // code for operator for plane and point is defined in // CGAL/Cartesian/function_objects.h and CGAL/Homogeneous/function_objects.h }; @@ -3005,7 +3013,6 @@ namespace CommonKernelFunctors { public: typedef typename K::Boolean result_type; - // There are 36 combinaisons, so I use a template. template result_type operator()(const T1& t1, const T2& t2) const @@ -3018,7 +3025,6 @@ namespace CommonKernelFunctors { public: typedef typename K::Boolean result_type; - // There are x combinaisons, so I use a template. template result_type operator()(const T1& t1, const T2& t2) const diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_fct_constructions_3.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_fct_constructions_3.h index e45abb683e9..1931c2ae7e2 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_fct_constructions_3.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_fct_constructions_3.h @@ -131,6 +131,8 @@ _test_fct_constructions_3(const R& r) assert( r.construct_projected_point_3_object()(ray, Point(-1,0,0)) == Point(0,0,0)); assert( r.construct_projected_point_3_object()(s, Point(-1,0,0)) == Point(0,0,0)); assert( r.construct_projected_point_3_object()(s, Point(2,0,0)) == Point(1,1,0)); + assert( r.construct_projected_point_3_object()(Point(0,0,0), Point(2,0,0)) == Point(0,0,0)); + return true; } diff --git a/Kernel_d/include/CGAL/Kernel_d/Segment_d.h b/Kernel_d/include/CGAL/Kernel_d/Segment_d.h index 5a399babf4d..bd30d04f3a7 100644 --- a/Kernel_d/include/CGAL/Kernel_d/Segment_d.h +++ b/Kernel_d/include/CGAL/Kernel_d/Segment_d.h @@ -19,7 +19,6 @@ #include #include -#include #include #include #include diff --git a/Linear_cell_complex/examples/Linear_cell_complex/voronoi_2.cpp b/Linear_cell_complex/examples/Linear_cell_complex/voronoi_2.cpp index 9ebabf6150b..0e29564d815 100644 --- a/Linear_cell_complex/examples/Linear_cell_complex/voronoi_2.cpp +++ b/Linear_cell_complex/examples/Linear_cell_complex/voronoi_2.cpp @@ -105,11 +105,10 @@ int main(int narg, char** argv) std::string filename; if ( narg==1 ) { - filename=std::string("data/points_2"); - std::cout<<"No filename given: use data/points_2 by default."< published with 4.3 -pushd Arrangement_on_surface_2_Demo_with_dlls; zip ../arrangements_2.zip *; popd +pushd Arrangement_on_surface_2_Demo_with_dlls; zip -r ../arrangements_2.zip *; popd # CGAL-4.5 -pushd Periodic_2_triangulation_2_Demo_with_dlls; zip ../Periodic_2_Delaunay_triangulation_2.zip *; +pushd Periodic_2_triangulation_2_Demo_with_dlls; zip -r ../Periodic_2_Delaunay_triangulation_2.zip *; popd # probably an error, in CGAL-4.5: rm -rf Surface_mesh_deformation_Demo @@ -54,18 +57,18 @@ rm -rf Surface_mesh_deformation_Demo rm -rf Circular_kernel_3_Demo # CGAL-4.6 -pushd Polyline_simplification_2_Demo_with_dlls; zip ../polyline_simplification_2.zip *; popd +pushd Polyline_simplification_2_Demo_with_dlls; zip -r ../polyline_simplification_2.zip *; popd # CGAL-4.7 -pushd Segment_Delaunay_graph_Linf_2_Demo_with_dlls; zip ../segment_voronoi_diagram_2.zip *; popd +pushd Segment_Delaunay_graph_Linf_2_Demo_with_dlls; zip -r ../segment_voronoi_diagram_2.zip *; popd # CGAL-4.8 -pushd Optimal_transportation_reconstruction_2_Demo_with_dlls; zip ../otr2.zip *; popd +pushd Optimal_transportation_reconstruction_2_Demo_with_dlls; zip -r ../otr2.zip *; popd #missing demos -pushd Polygon_Demo_with_dlls; zip ../polygon.zip *; popd -pushd Principal_component_analysis_Demo_with_dlls; zip ../pca.zip *; popd -pushd Hyperbolic_triangulation_2_Demo_with_dlls; zip ../Hyperbolic_Delaunay_triangulation_2.zip *; popd -pushd Periodic_4_hyperbolic_triangulation_2_Demo_with_dlls; zip ../Periodic_4_hyperbolic_Delaunay_triangulation_2.zip *; popd +pushd Polygon_Demo_with_dlls; zip -r ../polygon.zip *; popd +pushd Principal_component_analysis_Demo_with_dlls; zip -r ../pca.zip *; popd +pushd Hyperbolic_triangulation_2_Demo_with_dlls; zip -r ../Hyperbolic_Delaunay_triangulation_2.zip *; popd +pushd Periodic_4_hyperbolic_triangulation_2_Demo_with_dlls; zip -r ../Periodic_4_hyperbolic_Delaunay_triangulation_2.zip *; popd # check echo CHECK now. The following lines should be empty. diff --git a/Maintenance/test_handling/testsuite_comparison/diff_testsuites.html b/Maintenance/test_handling/testsuite_comparison/diff_testsuites.html index 6cb41ecb451..4ec2720540f 100644 --- a/Maintenance/test_handling/testsuite_comparison/diff_testsuites.html +++ b/Maintenance/test_handling/testsuite_comparison/diff_testsuites.html @@ -18,6 +18,9 @@
+

+Note that the diff should be done from left to right, as red or yellow squares in the left testsuite that become green in the right testsuite will be ignored. +

I = Master
Ic = integration

diff --git a/Maintenance/test_handling/testsuite_comparison/diff_testsuites.js b/Maintenance/test_handling/testsuite_comparison/diff_testsuites.js index 04486118b8d..567dad05351 100644 --- a/Maintenance/test_handling/testsuite_comparison/diff_testsuites.js +++ b/Maintenance/test_handling/testsuite_comparison/diff_testsuites.js @@ -30,22 +30,23 @@ function diff_testsuites(baseTest, newTest){ var init = false; for(s = 0; s < suffixes.length; s++) { var new_column = new Array(); - xhr.open('GET', URL_testsuite+baseTest+'/'+suffixes[s], false); + var suffixe=suffixes[s].replace("\r", ""); + xhr.open('GET', URL_testsuite+baseTest+'/'+suffixe, false); xhr.send(null); var base_exists = (xhr.status === 200); - var base=xhr.responseText; - xhr.open('GET', URL_testsuite+newTest+'/'+suffixes[s], false); + var base=xhr.responseText.replace("\r", ""); + xhr.open('GET', URL_testsuite+newTest+'/'+suffixe, false); xhr.send(null); var new_exists = (xhr.status === 200) if(base_exists && !new_exists) { - diffArray.push("-"+suffixes[s]); + diffArray.push("-"+suffixe); continue; } if(!base_exists && new_exists) { - diffArray.push("+"+suffixes[s]); + diffArray.push("+"+suffixe); continue; } if(!base_exists && !new_exists) @@ -53,11 +54,17 @@ function diff_testsuites(baseTest, newTest){ continue; } - var newtext=xhr.responseText; + var newtext=xhr.responseText.replace("\r", ""); var sp_base=base.split("\n"); sp_base.sort(); + for(i=0; i< sp_base.length; i++){ + sp_base[i]=sp_base[i].replace("\r", ""); + } var sp_newtext=newtext.split("\n"); sp_newtext.sort(); + for(i=0; i< sp_newtext.length; i++){ + sp_newtext[i]=sp_newtext[i].replace("\r", ""); + } addMissingLines(sp_base, sp_newtext); if(!init) { @@ -73,7 +80,7 @@ function diff_testsuites(baseTest, newTest){ myArray.push(first_column); init = true; } - var fragments = suffixes[s].split("_"); + var fragments = suffixe.split("_"); fragments.shift(); var name = fragments.join("_"); name = name.replace('.txt', ''); @@ -82,29 +89,29 @@ function diff_testsuites(baseTest, newTest){ for(i=0; i< sp_base.length; i++){ var broken = false; var res = print_diff(sp_base[i], sp_newtext[i]); - var compensator=0; - if(sp_base[i] !== ""){ - while(sp_base[i].substr(0, sp_base[i].length-2) !== first_column[i+compensator]){ - if(compensator >10){ - broken=true; - break; - } - compensator++; - } + var compensator=0; + if(sp_base[i] !== ""){ + while(sp_base[i].substr(0, sp_base[i].length-2) !== first_column[i+compensator]){ + if(compensator >10){ + broken=true; + break; + } + compensator++; } - else{ - while(sp_newtext[i].substr(0, sp_newtext[i].length-2) !== first_column[i+compensator]){ - if(compensator >10){ - broken=true; - break; - } - compensator++; - } - } - if(broken) - { - continue; + } + else{ + while(sp_newtext[i].substr(0, sp_newtext[i].length-2) !== first_column[i+compensator]){ + if(compensator >10){ + broken=true; + break; + } + compensator++; } + } + if(broken) + { + continue; + } var new_line=first_column[i+compensator]+"||"+" "+result; } else if(res[1]=== "n"){ new_line+=" background-color: rgb(100%,50%,50%)'> "+result; - } - else if(res[1]==="" && res[0]!==""){ + } else if(res[1]== "t"){ + new_line+=" background-color: rgb(75%,100%,50%)'> "+result; + } else if(res[1]==="" && res[0]!==""){ new_line+=" background-color: rgb(50%,25%,75%)'>"+result; } else{ @@ -146,3 +154,4 @@ function diff_testsuites(baseTest, newTest){ return [myArray, diffArray]; } + diff --git a/Mesh_3/benchmark/Mesh_3/StdAfx.h b/Mesh_3/benchmark/Mesh_3/StdAfx.h index 95803115a15..1eb3927c644 100644 --- a/Mesh_3/benchmark/Mesh_3/StdAfx.h +++ b/Mesh_3/benchmark/Mesh_3/StdAfx.h @@ -13,6 +13,7 @@ #include #include #include +#include // Windows #include @@ -24,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -189,11 +189,11 @@ #include #include //#include -#include -#include +#include +#include //#include -#include -#include +#include +#include //#include //#include #include diff --git a/Mesh_3/benchmark/Mesh_3/concurrency.cpp b/Mesh_3/benchmark/Mesh_3/concurrency.cpp index 4327ef35078..ea383a78832 100644 --- a/Mesh_3/benchmark/Mesh_3/concurrency.cpp +++ b/Mesh_3/benchmark/Mesh_3/concurrency.cpp @@ -105,14 +105,7 @@ const int TET_SHAPE = 3; # define CGAL_CONCURRENT_MESH_3_PROFILING //# define CGAL_DEBUG_FORCE_SEQUENTIAL_MESH_REFINEMENT - // ========================================================================== - // TBB - // ========================================================================== -# if TBB_IMPLEMENT_CPP0X -# include -# else -# include -# endif +#include // ========================================================================== // SEQUENTIAL diff --git a/Mesh_3/include/CGAL/Mesh_3/Robust_intersection_traits_3.h b/Mesh_3/include/CGAL/Mesh_3/Robust_intersection_traits_3.h index 60f1a10b4af..944916523a0 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Robust_intersection_traits_3.h +++ b/Mesh_3/include/CGAL/Mesh_3/Robust_intersection_traits_3.h @@ -25,7 +25,7 @@ #include #include #include -#include +#include namespace CGAL { diff --git a/Mesh_3/include/CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h b/Mesh_3/include/CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h index 571a4171e5d..74bb943f76e 100644 --- a/Mesh_3/include/CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h +++ b/Mesh_3/include/CGAL/Mesh_3/initialize_triangulation_from_labeled_image.h @@ -16,7 +16,7 @@ #include #include -#include +#include #include #include diff --git a/Mesh_3/include/CGAL/Mesh_3/squared_distance_Point_3_Triangle_3.h b/Mesh_3/include/CGAL/Mesh_3/squared_distance_Point_3_Triangle_3.h index 5e8595daf22..7af0376d312 100644 --- a/Mesh_3/include/CGAL/Mesh_3/squared_distance_Point_3_Triangle_3.h +++ b/Mesh_3/include/CGAL/Mesh_3/squared_distance_Point_3_Triangle_3.h @@ -16,7 +16,6 @@ #include - -#include +#include #endif // CGAL_SQUARED_DISTANCE_POINT_3_TRIANGLE_3_H diff --git a/Mesh_3/package_info/Mesh_3/dependencies b/Mesh_3/package_info/Mesh_3/dependencies index 2bfb2043f8b..e616acd30b8 100644 --- a/Mesh_3/package_info/Mesh_3/dependencies +++ b/Mesh_3/package_info/Mesh_3/dependencies @@ -24,7 +24,6 @@ Mesher_level Modifier Modular_arithmetic Number_types -Polygon Polygon_mesh_processing Polyhedron Principal_component_analysis diff --git a/Nef_2/include/CGAL/Extended_homogeneous.h b/Nef_2/include/CGAL/Extended_homogeneous.h index 83c64b7c888..704db06ca6f 100644 --- a/Nef_2/include/CGAL/Extended_homogeneous.h +++ b/Nef_2/include/CGAL/Extended_homogeneous.h @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include #undef CGAL_NEF_DEBUG diff --git a/Nef_2/include/CGAL/Filtered_extended_homogeneous.h b/Nef_2/include/CGAL/Filtered_extended_homogeneous.h index 5997110aebf..57507bc57b9 100644 --- a/Nef_2/include/CGAL/Filtered_extended_homogeneous.h +++ b/Nef_2/include/CGAL/Filtered_extended_homogeneous.h @@ -390,40 +390,64 @@ int orientation(const Extended_point& p1, const Extended_point& p3) { CGAL_NEF_TRACEN("orientation "< Protection; - res = orientation_coeff2(p1.mxD(),p1.nxD(),p1.myD(),p1.nyD(),p1.hwD(), - p2.mxD(),p2.nxD(),p2.myD(),p2.nyD(),p2.hwD(), - p3.mxD(),p3.nxD(),p3.myD(),p3.nyD(),p3.hwD()); + bool run_exact = false; + { + Protect_FPU_rounding Protection; + try { INCTOTAL(or2); + res = orientation_coeff2(p1.mxD(),p1.nxD(),p1.myD(),p1.nyD(),p1.hwD(), + p2.mxD(),p2.nxD(),p2.myD(),p2.nyD(),p2.hwD(), + p3.mxD(),p3.nxD(),p3.myD(),p3.nyD(),p3.hwD()); + } + catch (Uncertain_conversion_exception&) { + INCEXCEPTION(or2); + run_exact=true; + } } - catch (Uncertain_conversion_exception&) { INCEXCEPTION(or2); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); + if (run_exact) res = orientation_coeff2(p1.mx(),p1.nx(),p1.my(),p1.ny(),p1.hw(), p2.mx(),p2.nx(),p2.my(),p2.ny(),p2.hw(), p3.mx(),p3.nx(),p3.my(),p3.ny(),p3.hw()); - } if ( res != 0 ) return res; - try { INCTOTAL(or1); Protect_FPU_rounding Protection; - res = orientation_coeff1(p1.mxD(),p1.nxD(),p1.myD(),p1.nyD(),p1.hwD(), - p2.mxD(),p2.nxD(),p2.myD(),p2.nyD(),p2.hwD(), - p3.mxD(),p3.nxD(),p3.myD(),p3.nyD(),p3.hwD()); + run_exact = false; + { + Protect_FPU_rounding Protection; + try { INCTOTAL(or1); + res = orientation_coeff1(p1.mxD(),p1.nxD(),p1.myD(),p1.nyD(),p1.hwD(), + p2.mxD(),p2.nxD(),p2.myD(),p2.nyD(),p2.hwD(), + p3.mxD(),p3.nxD(),p3.myD(),p3.nyD(),p3.hwD()); + } + catch (Uncertain_conversion_exception&) { + INCEXCEPTION(or1); + run_exact = true; + } } - catch (Uncertain_conversion_exception&) { INCEXCEPTION(or1); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); + if (run_exact) res = orientation_coeff1(p1.mx(),p1.nx(),p1.my(),p1.ny(),p1.hw(), p2.mx(),p2.nx(),p2.my(),p2.ny(),p2.hw(), p3.mx(),p3.nx(),p3.my(),p3.ny(),p3.hw()); - } if ( res != 0 ) return res; - try { INCTOTAL(or0); Protect_FPU_rounding Protection; - res = orientation_coeff0(p1.mxD(),p1.nxD(),p1.myD(),p1.nyD(),p1.hwD(), - p2.mxD(),p2.nxD(),p2.myD(),p2.nyD(),p2.hwD(), - p3.mxD(),p3.nxD(),p3.myD(),p3.nyD(),p3.hwD()); + run_exact = false; + { + Protect_FPU_rounding Protection; + try { INCTOTAL(or0); + res = orientation_coeff0(p1.mxD(),p1.nxD(),p1.myD(),p1.nyD(),p1.hwD(), + p2.mxD(),p2.nxD(),p2.myD(),p2.nyD(),p2.hwD(), + p3.mxD(),p3.nxD(),p3.myD(),p3.nyD(),p3.hwD()); + } + catch (Uncertain_conversion_exception&) { + INCEXCEPTION(or0); + run_exact = true; + } } - catch (Uncertain_conversion_exception&) { INCEXCEPTION(or0); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); + if (run_exact) res = orientation_coeff0(p1.mx(),p1.nx(),p1.my(),p1.ny(),p1.hw(), p2.mx(),p2.nx(),p2.my(),p2.ny(),p2.hw(), p3.mx(),p3.nx(),p3.my(),p3.ny(),p3.hw()); - } return res; } @@ -441,20 +465,38 @@ int compare_x(const Extended_point& p1, const Extended_point& p2) { int res; - try { INCTOTAL(cmpx1); Protect_FPU_rounding Protection; - res = compare_expr(p1.mxD(),p1.hwD(),p2.mxD(),p2.hwD()); + bool run_exact = false; + { + Protect_FPU_rounding Protection; + try { INCTOTAL(cmpx1); + res = compare_expr(p1.mxD(),p1.hwD(),p2.mxD(),p2.hwD()); + } + catch (Uncertain_conversion_exception&) { + INCEXCEPTION(cmpx1); + run_exact = true; + } } - catch (Uncertain_conversion_exception&) { INCEXCEPTION(cmpx1); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); + if (run_exact) res = compare_expr(p1.mx(),p1.hw(),p2.mx(),p2.hw()); - } + if ( res != 0 ) return res; - try { INCTOTAL(cmpx0); Protect_FPU_rounding Protection; - res = compare_expr(p1.nxD(),p1.hwD(),p2.nxD(),p2.hwD()); + run_exact = false; + { + Protect_FPU_rounding Protection; + try { + INCTOTAL(cmpx0); + res = compare_expr(p1.nxD(),p1.hwD(),p2.nxD(),p2.hwD()); + } + catch (Uncertain_conversion_exception&) { + INCEXCEPTION(cmpx0); + run_exact = true; + } } - catch (Uncertain_conversion_exception&) { INCEXCEPTION(cmpx0); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); + if (run_exact) res = compare_expr(p1.nx(),p1.hw(),p2.nx(),p2.hw()); - } return res; } @@ -466,20 +508,36 @@ int compare_y(const Extended_point& p1, const Extended_point& p2) { int res; - try { INCTOTAL(cmpy1); Protect_FPU_rounding Protection; - res = compare_expr(p1.myD(),p1.hwD(),p2.myD(),p2.hwD()); + bool run_exact = false; + { + Protect_FPU_rounding Protection; + try { INCTOTAL(cmpy1); + res = compare_expr(p1.myD(),p1.hwD(),p2.myD(),p2.hwD()); + } + catch (Uncertain_conversion_exception&) { + INCEXCEPTION(cmpy1); + run_exact = true; + } } - catch (Uncertain_conversion_exception&) { INCEXCEPTION(cmpy1); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); + if (run_exact) res = compare_expr(p1.my(),p1.hw(),p2.my(),p2.hw()); - } if ( res != 0 ) return res; - try { INCTOTAL(cmpy0); Protect_FPU_rounding Protection; - res = compare_expr(p1.nyD(),p1.hwD(),p2.nyD(),p2.hwD()); + run_exact = false; + { + Protect_FPU_rounding Protection; + try { INCTOTAL(cmpy0); + res = compare_expr(p1.nyD(),p1.hwD(),p2.nyD(),p2.hwD()); + } + catch (Uncertain_conversion_exception&) { + INCEXCEPTION(cmpy0); + run_exact = true; + } } - catch (Uncertain_conversion_exception&) { INCEXCEPTION(cmpy0); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); + if (run_exact) res = compare_expr(p1.ny(),p1.hw(),p2.ny(),p2.hw()); - } return res; } @@ -608,46 +666,71 @@ int compare_pair_dist( const Extended_point& p3, const Extended_point& p4) { int res; - try { INCTOTAL(cmppd2); Protect_FPU_rounding Protection; - res = cmppd_coeff2(p1.mxD(),p1.nxD(),p1.myD(),p1.nyD(),p1.hwD(), - p2.mxD(),p2.nxD(),p2.myD(),p2.nyD(),p2.hwD(), - p3.mxD(),p3.nxD(),p3.myD(),p3.nyD(),p3.hwD(), - p4.mxD(),p4.nxD(),p4.myD(),p4.nyD(),p4.hwD()); + bool run_exact = false; + { + Protect_FPU_rounding Protection; + try { INCTOTAL(cmppd2); + res = cmppd_coeff2(p1.mxD(),p1.nxD(),p1.myD(),p1.nyD(),p1.hwD(), + p2.mxD(),p2.nxD(),p2.myD(),p2.nyD(),p2.hwD(), + p3.mxD(),p3.nxD(),p3.myD(),p3.nyD(),p3.hwD(), + p4.mxD(),p4.nxD(),p4.myD(),p4.nyD(),p4.hwD()); + } + catch (Uncertain_conversion_exception&) { + INCEXCEPTION(cmppd2); + run_exact = true; + } } - catch (Uncertain_conversion_exception&) { INCEXCEPTION(cmppd2); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); + if (run_exact) res = cmppd_coeff2(p1.mx(),p1.nx(),p1.my(),p1.ny(),p1.hw(), p2.mx(),p2.nx(),p2.my(),p2.ny(),p2.hw(), p3.mx(),p3.nx(),p3.my(),p3.ny(),p3.hw(), p4.mx(),p4.nx(),p4.my(),p4.ny(),p4.hw()); - } + if ( res != 0 ) return res; - try { INCTOTAL(cmppd1); Protect_FPU_rounding Protection; - res = cmppd_coeff1(p1.mxD(),p1.nxD(),p1.myD(),p1.nyD(),p1.hwD(), - p2.mxD(),p2.nxD(),p2.myD(),p2.nyD(),p2.hwD(), - p3.mxD(),p3.nxD(),p3.myD(),p3.nyD(),p3.hwD(), - p4.mxD(),p4.nxD(),p4.myD(),p4.nyD(),p4.hwD()); + run_exact = false; + { + Protect_FPU_rounding Protection; + try { INCTOTAL(cmppd1); + res = cmppd_coeff1(p1.mxD(),p1.nxD(),p1.myD(),p1.nyD(),p1.hwD(), + p2.mxD(),p2.nxD(),p2.myD(),p2.nyD(),p2.hwD(), + p3.mxD(),p3.nxD(),p3.myD(),p3.nyD(),p3.hwD(), + p4.mxD(),p4.nxD(),p4.myD(),p4.nyD(),p4.hwD()); + } + catch (Uncertain_conversion_exception&) { + INCEXCEPTION(cmppd1); + run_exact = true; + } } - catch (Uncertain_conversion_exception&) { INCEXCEPTION(cmppd1); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); + if (run_exact) res = cmppd_coeff1(p1.mx(),p1.nx(),p1.my(),p1.ny(),p1.hw(), p2.mx(),p2.nx(),p2.my(),p2.ny(),p2.hw(), p3.mx(),p3.nx(),p3.my(),p3.ny(),p3.hw(), p4.mx(),p4.nx(),p4.my(),p4.ny(),p4.hw()); - } if ( res != 0 ) return res; - try { INCTOTAL(cmppd0); Protect_FPU_rounding Protection; - res = cmppd_coeff0(p1.mxD(),p1.nxD(),p1.myD(),p1.nyD(),p1.hwD(), - p2.mxD(),p2.nxD(),p2.myD(),p2.nyD(),p2.hwD(), - p3.mxD(),p3.nxD(),p3.myD(),p3.nyD(),p3.hwD(), - p4.mxD(),p4.nxD(),p4.myD(),p4.nyD(),p4.hwD()); + run_exact = false; + { + Protect_FPU_rounding Protection; + try { INCTOTAL(cmppd0); + res = cmppd_coeff0(p1.mxD(),p1.nxD(),p1.myD(),p1.nyD(),p1.hwD(), + p2.mxD(),p2.nxD(),p2.myD(),p2.nyD(),p2.hwD(), + p3.mxD(),p3.nxD(),p3.myD(),p3.nyD(),p3.hwD(), + p4.mxD(),p4.nxD(),p4.myD(),p4.nyD(),p4.hwD()); + } + catch (Uncertain_conversion_exception&) { + INCEXCEPTION(cmppd0); + run_exact = true; + } } - catch (Uncertain_conversion_exception&) { INCEXCEPTION(cmppd0); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); + if (run_exact) res = cmppd_coeff0(p1.mx(),p1.nx(),p1.my(),p1.ny(),p1.hw(), p2.mx(),p2.nx(),p2.my(),p2.ny(),p2.hw(), p3.mx(),p3.nx(),p3.my(),p3.ny(),p3.hw(), p4.mx(),p4.nx(),p4.my(),p4.ny(),p4.hw()); - } return res; } @@ -873,42 +956,68 @@ int orientation(const Extended_direction& d1, Extended_point p1(d1.p1()), p2(d1.p2()), p3(d2.p1()), p4(d2.p2()); int res; - try { INCTOTAL(ord2); Protect_FPU_rounding Protection; - res = coeff2_dor(p1.mxD(),p1.nxD(),p1.myD(),p1.nyD(),p1.hwD(), - p2.mxD(),p2.nxD(),p2.myD(),p2.nyD(),p2.hwD(), - p3.mxD(),p3.nxD(),p3.myD(),p3.nyD(),p3.hwD(), - p4.mxD(),p4.nxD(),p4.myD(),p4.nyD(),p4.hwD()); - } catch (Uncertain_conversion_exception&) { INCEXCEPTION(ord2); + bool run_exact = true; + { + Protect_FPU_rounding Protection; + try { INCTOTAL(ord2); + res = coeff2_dor(p1.mxD(),p1.nxD(),p1.myD(),p1.nyD(),p1.hwD(), + p2.mxD(),p2.nxD(),p2.myD(),p2.nyD(),p2.hwD(), + p3.mxD(),p3.nxD(),p3.myD(),p3.nyD(),p3.hwD(), + p4.mxD(),p4.nxD(),p4.myD(),p4.nyD(),p4.hwD()); + } catch (Uncertain_conversion_exception&) { + INCEXCEPTION(ord2); + run_exact=true; + } + } + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); + if (run_exact) res = coeff2_dor(p1.mx(),p1.nx(),p1.my(),p1.ny(),p1.hw(), p2.mx(),p2.nx(),p2.my(),p2.ny(),p2.hw(), p3.mx(),p3.nx(),p3.my(),p3.ny(),p3.hw(), p4.mx(),p4.nx(),p4.my(),p4.ny(),p4.hw()); - } if ( res != 0 ) return res; - try { INCTOTAL(ord1); Protect_FPU_rounding Protection; - res = coeff1_dor(p1.mxD(),p1.nxD(),p1.myD(),p1.nyD(),p1.hwD(), - p2.mxD(),p2.nxD(),p2.myD(),p2.nyD(),p2.hwD(), - p3.mxD(),p3.nxD(),p3.myD(),p3.nyD(),p3.hwD(), - p4.mxD(),p4.nxD(),p4.myD(),p4.nyD(),p4.hwD()); - } catch (Uncertain_conversion_exception&) { INCEXCEPTION(ord1); + run_exact = false; + { + Protect_FPU_rounding Protection; + try { INCTOTAL(ord1); + res = coeff1_dor(p1.mxD(),p1.nxD(),p1.myD(),p1.nyD(),p1.hwD(), + p2.mxD(),p2.nxD(),p2.myD(),p2.nyD(),p2.hwD(), + p3.mxD(),p3.nxD(),p3.myD(),p3.nyD(),p3.hwD(), + p4.mxD(),p4.nxD(),p4.myD(),p4.nyD(),p4.hwD()); + } catch (Uncertain_conversion_exception&) { + INCEXCEPTION(ord1); + run_exact=true; + } + } + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); + if (run_exact) res = coeff1_dor(p1.mx(),p1.nx(),p1.my(),p1.ny(),p1.hw(), p2.mx(),p2.nx(),p2.my(),p2.ny(),p2.hw(), p3.mx(),p3.nx(),p3.my(),p3.ny(),p3.hw(), p4.mx(),p4.nx(),p4.my(),p4.ny(),p4.hw()); - } + if ( res != 0 ) return res; - try { INCTOTAL(ord0); Protect_FPU_rounding Protection; - res = coeff0_dor(p1.mxD(),p1.nxD(),p1.myD(),p1.nyD(),p1.hwD(), - p2.mxD(),p2.nxD(),p2.myD(),p2.nyD(),p2.hwD(), - p3.mxD(),p3.nxD(),p3.myD(),p3.nyD(),p3.hwD(), - p4.mxD(),p4.nxD(),p4.myD(),p4.nyD(),p4.hwD()); - } catch (Uncertain_conversion_exception&) { INCEXCEPTION(ord0); + + run_exact = false; + { + Protect_FPU_rounding Protection; + try { INCTOTAL(ord0); Protect_FPU_rounding Protection; + res = coeff0_dor(p1.mxD(),p1.nxD(),p1.myD(),p1.nyD(),p1.hwD(), + p2.mxD(),p2.nxD(),p2.myD(),p2.nyD(),p2.hwD(), + p3.mxD(),p3.nxD(),p3.myD(),p3.nyD(),p3.hwD(), + p4.mxD(),p4.nxD(),p4.myD(),p4.nyD(),p4.hwD()); + } catch (Uncertain_conversion_exception&) { + INCEXCEPTION(ord0); + run_exact = true; + } + } + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); + if(run_exact) res = coeff0_dor(p1.mx(),p1.nx(),p1.my(),p1.ny(),p1.hw(), p2.mx(),p2.nx(),p2.my(),p2.ny(),p2.hw(), p3.mx(),p3.nx(),p3.my(),p3.ny(),p3.hw(), p4.mx(),p4.nx(),p4.my(),p4.ny(),p4.hw()); - } return res; } diff --git a/Nef_3/include/CGAL/Nef_3/K3_tree.h b/Nef_3/include/CGAL/Nef_3/K3_tree.h index be2c8b79f5e..8329767d8eb 100644 --- a/Nef_3/include/CGAL/Nef_3/K3_tree.h +++ b/Nef_3/include/CGAL/Nef_3/K3_tree.h @@ -291,7 +291,7 @@ public: Segment_3 segment; bool initialized; public: - Objects_around_segment() : initialized(false) {} + Objects_around_segment() : root_node(nullptr), initialized(false) {} Objects_around_segment( const K3_tree& k, const Segment_3& s) : root_node(k.root), segment(s), initialized(true) { CGAL_NEF_TRACEN("Objects_around_segment: input segment: "< #include -#include +#include namespace CGAL { diff --git a/Nef_3/include/CGAL/Nef_3/OGL_helper.h b/Nef_3/include/CGAL/Nef_3/OGL_helper.h index c6aa2d82b91..e66cb433175 100644 --- a/Nef_3/include/CGAL/Nef_3/OGL_helper.h +++ b/Nef_3/include/CGAL/Nef_3/OGL_helper.h @@ -22,6 +22,7 @@ #include #include #include +#include #define CGAL_NEF3_MARKED_VERTEX_COLOR 183,232,92 #define CGAL_NEF3_MARKED_EDGE_COLOR 171,216,86 @@ -226,7 +227,7 @@ namespace OGL { inline void CGAL_GLU_TESS_CALLBACK errorCallback(GLenum errorCode) { const GLubyte *estring; estring = gluErrorString(errorCode); - fprintf(stderr, "Tessellation Error: %s\n", estring); + std::cerr << "Tessellation Error: " << estring << std::endl; std::exit (0); } diff --git a/Nef_3/include/CGAL/Nef_3/SNC_io_parser.h b/Nef_3/include/CGAL/Nef_3/SNC_io_parser.h index c0ddcc5ff22..aab28de6795 100644 --- a/Nef_3/include/CGAL/Nef_3/SNC_io_parser.h +++ b/Nef_3/include/CGAL/Nef_3/SNC_io_parser.h @@ -1088,7 +1088,10 @@ public: template SNC_io_parser::SNC_io_parser(std::istream& is, SNC_structure& W) : - Base(W), in(is), out(std::cout) { + Base(W), in(is), out(std::cout), + reduce(false), sorted(false), addInfiBox(false), + i(0), vn(0), en(0), fn(0), cn(0), sen(0), sln(0), sfn(0) +{ W.clear(); CGAL_assertion(W.is_empty()); verbose = false; @@ -1099,11 +1102,13 @@ template SNC_io_parser::SNC_io_parser(std::ostream& os, SNC_structure& W, bool sort, bool reduce_) : Base(W), in(std::cin), out(os), + addInfiBox(false), FI(W.halffacets_begin(),W.halffacets_end(),'F'), CI(W.volumes_begin(),W.volumes_end(),'C'), SEI(W.shalfedges_begin(),W.shalfedges_end(),'e'), SLI(W.shalfloops_begin(),W.shalfloops_end(),'l'), SFI(W.sfaces_begin(),W.sfaces_end(),'f'), + i(0), vn(W.number_of_vertices()), en(W.number_of_halfedges()), fn(W.number_of_halffacets()), diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_filter_NT.h b/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_filter_NT.h index 98d5c03f153..48df8678394 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_filter_NT.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_filter_NT.h @@ -48,6 +48,7 @@ struct Cartesian_filter_NT : public Base_ if(is_certain(res)) return get_certain(res); } catch (Uncertain_conversion_exception&) {} } + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); return p2(std::forward(u)...); } }; diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_static_filters.h b/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_static_filters.h index 7f1cd13d5f7..243b4e756aa 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_static_filters.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_static_filters.h @@ -13,9 +13,9 @@ #define CGAL_KD_CARTESIAN_STATIC_FILTERS_H #include #include -#include // bug, should be included by the next one -#include -#include +#include // bug, should be included by the next one +#include +#include #include namespace CGAL { diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Filtered_predicate2.h b/NewKernel_d/include/CGAL/NewKernel_d/Filtered_predicate2.h index 3f61fd5ddeb..6c7ad10e727 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Filtered_predicate2.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Filtered_predicate2.h @@ -92,6 +92,8 @@ public: catch (Uncertain_conversion_exception&) {} } CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding p(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); return ep(c2e(std::forward(args))...); } }; diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Kernel_d_interface.h b/NewKernel_d/include/CGAL/NewKernel_d/Kernel_d_interface.h index 92e291e53e7..c3abd5a7be5 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Kernel_d_interface.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Kernel_d_interface.h @@ -126,6 +126,7 @@ template struct Kernel_d_interface : public Base_ { CGAL_FUNCTOR_INIT_STORE(Construct_cartesian_const_iterator_d) typedef typename Get_functor >::type CPI; typedef typename Get_functor >::type CVI; + // @mglisse shall we update that code ? // FIXME: The following sometimes breaks compilation. The typedef below forces instantiation of this, which forces Point_d, which itself (in the wrapper) needs the derived kernel to tell it what the base kernel is, and that's a cycle. The exact circumstances are not clear, g++ and clang++ are ok in both C++03 and C++11, it is only clang in C++11 without CGAL_CXX11 that breaks. Relying on CPI::result_type is great for Epick_d but not Epeck_d. // typedef typename CGAL::decay::type>::type result_type; // typedef typename CGAL::decay::type result_type; diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Lazy_cartesian.h b/NewKernel_d/include/CGAL/NewKernel_d/Lazy_cartesian.h index 51ad838b0b8..26741caf72a 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Lazy_cartesian.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Lazy_cartesian.h @@ -178,14 +178,16 @@ struct Lazy_construction2 { template std::enable_if_t<(sizeof...(L)>0), result_type> operator()(L const&...l) const { CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); - Protect_FPU_rounding P; - try { - return new Lazy_rep_XXX(ac, ec, l...); - } catch (Uncertain_conversion_exception&) { - CGAL_BRANCH_PROFILER_BRANCH(tmp); - Protect_FPU_rounding P2(CGAL_FE_TONEAREST); - return new Lazy_rep_0(ec(CGAL::exact(l)...)); + { + Protect_FPU_rounding P; + try { + return new Lazy_rep_XXX(ac, ec, l...); + } catch (Uncertain_conversion_exception&) {} } + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); + return new Lazy_rep_0(ec(CGAL::exact(l)...)); } // FIXME: this forces us to have default constructors for all types, try to make its instantiation lazier // Actually, that may be the clearing in update_exact(). diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Wrapper/Cartesian_wrap.h b/NewKernel_d/include/CGAL/NewKernel_d/Wrapper/Cartesian_wrap.h index 1ec2d4ef977..776b59b67a6 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Wrapper/Cartesian_wrap.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Wrapper/Cartesian_wrap.h @@ -56,6 +56,7 @@ template struct Is_wrapper_iterator : { }; struct Forward_rep { +//@mglisse shall we update that code? //TODO: make a good C++0X version with perfect forwarding //#ifdef CGAL_CXX11 //template ::type>::value&&!Is_wrapper_iterator::type>::value>::type> diff --git a/Number_types/include/CGAL/CORE_BigFloat.h b/Number_types/include/CGAL/CORE_BigFloat.h index ffefaecb748..812036e3aa6 100644 --- a/Number_types/include/CGAL/CORE_BigFloat.h +++ b/Number_types/include/CGAL/CORE_BigFloat.h @@ -16,7 +16,6 @@ #include #include -#include #include #include #include @@ -513,7 +512,6 @@ template <> class Real_embeddable_traits< CORE::BigFloat > #include #include #include -#include #include namespace Eigen { diff --git a/Number_types/include/CGAL/CORE_BigInt.h b/Number_types/include/CGAL/CORE_BigInt.h index a069a4948cd..0b599543164 100644 --- a/Number_types/include/CGAL/CORE_BigInt.h +++ b/Number_types/include/CGAL/CORE_BigInt.h @@ -18,7 +18,6 @@ #include #include -#include #include #include @@ -189,7 +188,6 @@ public: //since types are included by CORE_coercion_traits.h: #include -#include #include #include #include diff --git a/Number_types/include/CGAL/CORE_BigRat.h b/Number_types/include/CGAL/CORE_BigRat.h index 0f51dac5663..caf9b73886e 100644 --- a/Number_types/include/CGAL/CORE_BigRat.h +++ b/Number_types/include/CGAL/CORE_BigRat.h @@ -18,7 +18,6 @@ #include #include -#include #include #include // used for To_interval-functor @@ -226,7 +225,6 @@ public: //since types are included by CORE_coercion_traits.h: #include #include -#include #include #include diff --git a/Number_types/include/CGAL/CORE_Expr.h b/Number_types/include/CGAL/CORE_Expr.h index 27491b01a85..4b720bc126b 100644 --- a/Number_types/include/CGAL/CORE_Expr.h +++ b/Number_types/include/CGAL/CORE_Expr.h @@ -21,7 +21,6 @@ #include #include -#include #include @@ -177,7 +176,6 @@ template <> class Real_embeddable_traits< CORE::Expr > } //namespace CGAL //since types are included by CORE_coercion_traits.h: -#include #include #include #include diff --git a/Number_types/include/CGAL/FPU.h b/Number_types/include/CGAL/FPU.h index 429e8fe29f0..d5a123608c4 100644 --- a/Number_types/include/CGAL/FPU.h +++ b/Number_types/include/CGAL/FPU.h @@ -248,6 +248,8 @@ inline __m128d IA_opacify128(__m128d x) # ifdef _MSC_VER // With VS, __m128d is a union, where volatile doesn't disappear automatically // However, this version generates wrong code with clang, check before enabling it for more compilers. + // The usage here is safe as we write from a __m128d to a __m128d + // and we know that this type has 16 bytes std::memcpy(&x, (void*)&e, 16); return x; # else diff --git a/Number_types/include/CGAL/Gmpq.h b/Number_types/include/CGAL/Gmpq.h index 87d240ecef6..9816d719b19 100644 --- a/Number_types/include/CGAL/Gmpq.h +++ b/Number_types/include/CGAL/Gmpq.h @@ -209,7 +209,6 @@ namespace Eigen { //since types are included by Gmp_coercion_traits.h: #include -#include #include #include diff --git a/Number_types/include/CGAL/Gmpz.h b/Number_types/include/CGAL/Gmpz.h index c67035a1e03..63be45e78fd 100644 --- a/Number_types/include/CGAL/Gmpz.h +++ b/Number_types/include/CGAL/Gmpz.h @@ -241,7 +241,6 @@ namespace Eigen { //since types are included by Gmp_coercion_traits.h: -#include #include #include #include diff --git a/Number_types/include/CGAL/Gmpzf.h b/Number_types/include/CGAL/Gmpzf.h index 5b6a0448eb6..128d0f94d36 100644 --- a/Number_types/include/CGAL/Gmpzf.h +++ b/Number_types/include/CGAL/Gmpzf.h @@ -171,7 +171,6 @@ public: //since types are included by Gmp_coercion_traits.h: #include #include -#include #endif // CGAL_GMPZF_H diff --git a/Number_types/include/CGAL/Mpzf.h b/Number_types/include/CGAL/Mpzf.h index 60034bb3896..b1b023a1058 100644 --- a/Number_types/include/CGAL/Mpzf.h +++ b/Number_types/include/CGAL/Mpzf.h @@ -112,16 +112,9 @@ #if !defined(CGAL_HAS_THREADS) #define CGAL_MPZF_THREAD_LOCAL #define CGAL_MPZF_TLS -#elif defined(CGAL_CAN_USE_CXX11_THREAD_LOCAL) +#else #define CGAL_MPZF_THREAD_LOCAL thread_local #define CGAL_MPZF_TLS thread_local -#elif defined(_MSC_VER) -#define CGAL_MPZF_THREAD_LOCAL __declspec(thread) -#define CGAL_MPZF_TLS -#else -#define CGAL_MPZF_THREAD_LOCAL __thread -#define CGAL_MPZF_TLS -// Too bad for the others #endif namespace CGAL { namespace Mpzf_impl { @@ -162,7 +155,6 @@ template struct pool2 { static T& ptr(T t) { t -= extra+1; return *reinterpret_cast(t); } }; -#if defined(CGAL_CAN_USE_CXX11_THREAD_LOCAL) template struct pool3 { static T pop() { T ret = data(); data() = ptr(data()); return ret; } static void push(T t) { ptr(t) = data(); data() = t; } @@ -185,7 +177,6 @@ template struct pool3 { } static T& ptr(T t) { t -= extra+1; return *reinterpret_cast(t); } }; -#endif // No caching template struct no_pool { diff --git a/Number_types/include/CGAL/Quotient.h b/Number_types/include/CGAL/Quotient.h index e4099e4b1fd..de1e6adbebe 100644 --- a/Number_types/include/CGAL/Quotient.h +++ b/Number_types/include/CGAL/Quotient.h @@ -565,7 +565,7 @@ namespace INTERN_QUOTIENT { public: NT operator()( const NT& x ) const { CGAL_precondition(x > 0); - return NT(CGAL_NTS sqrt(x.numerator()*x.denominator()), + return NT(CGAL_NTS sqrt(typename NT::NT(x.numerator()*x.denominator())), x.denominator()); } }; diff --git a/Number_types/include/CGAL/number_type_basic.h b/Number_types/include/CGAL/number_type_basic.h index 8e0cb00f85a..918e3bd521c 100644 --- a/Number_types/include/CGAL/number_type_basic.h +++ b/Number_types/include/CGAL/number_type_basic.h @@ -54,11 +54,7 @@ #include // needed by To_interval(long double), To_interval(long), To_interval(long long) #include -#ifdef CGAL_USE_LONG_LONG #include -#endif - - #ifdef CGAL_USE_GMP #ifdef CGAL_USE_GMPXX diff --git a/Number_types/test/Number_types/Lazy_exact_nt_new.cpp b/Number_types/test/Number_types/Lazy_exact_nt_new.cpp index 0f4d11d73d5..d7ec7182923 100644 --- a/Number_types/test/Number_types/Lazy_exact_nt_new.cpp +++ b/Number_types/test/Number_types/Lazy_exact_nt_new.cpp @@ -96,10 +96,9 @@ void test_lazy_exact_nt() { { // see also Coercion_traits_test.C #ifdef CGAL_USE_LEDA #ifdef CGAL_USE_CORE - CGAL_assertion_code(typedef CGAL::Lazy_exact_nt T1;) - CGAL_assertion_code(typedef CGAL::Lazy_exact_nt T2;) + typedef CGAL::Lazy_exact_nt T1; + typedef CGAL::Lazy_exact_nt T2; typedef CGAL::Coercion_traits CT; - CGAL_USE_TYPE(CT); CGAL_static_assertion((boost::is_same< typename CT::Are_implicit_interoperable,CGAL::Tag_false>::value)); CGAL_static_assertion((boost::is_same< typename CT::Are_explicit_interoperable,CGAL::Tag_false>::value)); #endif diff --git a/Number_types/test/Number_types/ioformat.cpp b/Number_types/test/Number_types/ioformat.cpp index e2d0bf7cda9..4d9a6656321 100644 --- a/Number_types/test/Number_types/ioformat.cpp +++ b/Number_types/test/Number_types/ioformat.cpp @@ -30,9 +30,7 @@ #include #endif // CGAL_USE_LEDA -#ifdef CGAL_USE_LONG_LONG -# include -#endif +#include #include #include @@ -77,10 +75,8 @@ int main() // test_it("unsigned int"); // test_it("unsigned long int"); // test_it("unsigned short int"); -#ifdef CGAL_USE_LONG_LONG test_it("long long"); // test_it("unsigned long long"); -#endif test_it("float"); test_it("double"); test_it("long double"); diff --git a/Number_types/test/Number_types/unsigned.cpp b/Number_types/test/Number_types/unsigned.cpp index b82e961cfaa..5ca8430169e 100644 --- a/Number_types/test/Number_types/unsigned.cpp +++ b/Number_types/test/Number_types/unsigned.cpp @@ -16,8 +16,6 @@ int main(){ (void)CGAL::compare(a,a); unsigned long b = 42; (void)CGAL::compare(b,b); -#ifdef CGAL_USE_LONG_LONG unsigned long long c = 42; (void)CGAL::compare(c,c); -#endif } diff --git a/Number_types/test/Number_types/utilities.cpp b/Number_types/test/Number_types/utilities.cpp index f8028bf59d6..48400c97520 100644 --- a/Number_types/test/Number_types/utilities.cpp +++ b/Number_types/test/Number_types/utilities.cpp @@ -32,9 +32,7 @@ #include #endif // CGAL_USE_LEDA -#ifdef CGAL_USE_LONG_LONG -# include -#endif +#include #include @@ -63,10 +61,8 @@ int main() // TESTIT(unsigned int, "unsigned int") // TESTIT(unsigned long int, "unsigned long int") // TESTIT(unsigned short int, "unsigned short int") -#ifdef CGAL_USE_LONG_LONG TESTIT(long long, "long long") // TESTIT(unsigned long long, "unsigned long long") -#endif TESTIT(float, "float") TESTIT(double, "double") TESTIT(long double, "long double") diff --git a/Optimal_transportation_reconstruction_2/package_info/Optimal_transportation_reconstruction_2/dependencies b/Optimal_transportation_reconstruction_2/package_info/Optimal_transportation_reconstruction_2/dependencies index 7fb921a03fa..1f25a1c4d47 100644 --- a/Optimal_transportation_reconstruction_2/package_info/Optimal_transportation_reconstruction_2/dependencies +++ b/Optimal_transportation_reconstruction_2/package_info/Optimal_transportation_reconstruction_2/dependencies @@ -12,7 +12,6 @@ Kernel_23 Modular_arithmetic Number_types Optimal_transportation_reconstruction_2 -Polygon Profiling_tools Property_map Random_numbers diff --git a/Periodic_2_triangulation_2/include/CGAL/Periodic_2_triangulation_2/internal/Periodic_2_Delaunay_triangulation_statically_filtered_traits_2.h b/Periodic_2_triangulation_2/include/CGAL/Periodic_2_triangulation_2/internal/Periodic_2_Delaunay_triangulation_statically_filtered_traits_2.h index 9f7ed54424b..180d39e207c 100644 --- a/Periodic_2_triangulation_2/include/CGAL/Periodic_2_triangulation_2/internal/Periodic_2_Delaunay_triangulation_statically_filtered_traits_2.h +++ b/Periodic_2_triangulation_2/include/CGAL/Periodic_2_triangulation_2/internal/Periodic_2_Delaunay_triangulation_statically_filtered_traits_2.h @@ -14,7 +14,7 @@ #include -#include +#include #include namespace CGAL { diff --git a/Periodic_2_triangulation_2/include/CGAL/Periodic_2_triangulation_2/internal/Periodic_2_triangulation_statically_filtered_traits_2.h b/Periodic_2_triangulation_2/include/CGAL/Periodic_2_triangulation_2/internal/Periodic_2_triangulation_statically_filtered_traits_2.h index 9994f09807d..500df4e46b5 100644 --- a/Periodic_2_triangulation_2/include/CGAL/Periodic_2_triangulation_2/internal/Periodic_2_triangulation_statically_filtered_traits_2.h +++ b/Periodic_2_triangulation_2/include/CGAL/Periodic_2_triangulation_2/internal/Periodic_2_triangulation_statically_filtered_traits_2.h @@ -24,7 +24,7 @@ #include #include -#include +#include namespace CGAL { diff --git a/Periodic_2_triangulation_2/include/CGAL/Periodic_2_triangulation_2/internal/Periodic_2_orientation_2.h b/Periodic_2_triangulation_2/include/CGAL/Periodic_2_triangulation_2/internal/Static_filters/Periodic_2_orientation_2.h similarity index 98% rename from Periodic_2_triangulation_2/include/CGAL/Periodic_2_triangulation_2/internal/Periodic_2_orientation_2.h rename to Periodic_2_triangulation_2/include/CGAL/Periodic_2_triangulation_2/internal/Static_filters/Periodic_2_orientation_2.h index d55918e6930..255f72b4e63 100644 --- a/Periodic_2_triangulation_2/include/CGAL/Periodic_2_triangulation_2/internal/Periodic_2_orientation_2.h +++ b/Periodic_2_triangulation_2/include/CGAL/Periodic_2_triangulation_2/internal/Static_filters/Periodic_2_orientation_2.h @@ -15,8 +15,8 @@ #include #include -#include -#include +#include +#include #include diff --git a/Periodic_2_triangulation_2/include/CGAL/Periodic_2_triangulation_2/internal/Periodic_2_side_of_oriented_circle_2.h b/Periodic_2_triangulation_2/include/CGAL/Periodic_2_triangulation_2/internal/Static_filters/Periodic_2_side_of_oriented_circle_2.h similarity index 97% rename from Periodic_2_triangulation_2/include/CGAL/Periodic_2_triangulation_2/internal/Periodic_2_side_of_oriented_circle_2.h rename to Periodic_2_triangulation_2/include/CGAL/Periodic_2_triangulation_2/internal/Static_filters/Periodic_2_side_of_oriented_circle_2.h index d5b7dcd99df..996db9f975a 100644 --- a/Periodic_2_triangulation_2/include/CGAL/Periodic_2_triangulation_2/internal/Periodic_2_side_of_oriented_circle_2.h +++ b/Periodic_2_triangulation_2/include/CGAL/Periodic_2_triangulation_2/internal/Static_filters/Periodic_2_side_of_oriented_circle_2.h @@ -16,10 +16,10 @@ #include -#include +#include #include -#include -#include +#include +#include #include diff --git a/Periodic_2_triangulation_2/package_info/Periodic_2_triangulation_2/dependencies b/Periodic_2_triangulation_2/package_info/Periodic_2_triangulation_2/dependencies index a78447643d8..22f0ba917df 100644 --- a/Periodic_2_triangulation_2/package_info/Periodic_2_triangulation_2/dependencies +++ b/Periodic_2_triangulation_2/package_info/Periodic_2_triangulation_2/dependencies @@ -14,7 +14,6 @@ Kernel_23 Modular_arithmetic Number_types Periodic_2_triangulation_2 -Polygon Profiling_tools Property_map STL_Extension 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 5e60842dd3d..5be36b550e6 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 @@ -2113,8 +2113,10 @@ insert_balls(const Vertex_handle& vp, curve_index, d_sign) << ")\n"; #endif + const FT sgn = (d_sign == CGAL::POSITIVE) ? 1. + : (d_sign == CGAL::NEGATIVE ? -1. : 0.); const Bare_point new_point = - domain_.construct_point_on_curve(vpp, curve_index, d_sign * d / 2); + domain_.construct_point_on_curve(vpp, curve_index, sgn * d / 2); const int dim = 1; // new_point is on edge const Index index = domain_.index_from_curve_index(curve_index); const FT point_weight = CGAL::square(size_(new_point, dim, index)); diff --git a/Periodic_3_mesh_3/package_info/Periodic_3_mesh_3/dependencies b/Periodic_3_mesh_3/package_info/Periodic_3_mesh_3/dependencies index c07e2af9cd5..7fb9ae91209 100644 --- a/Periodic_3_mesh_3/package_info/Periodic_3_mesh_3/dependencies +++ b/Periodic_3_mesh_3/package_info/Periodic_3_mesh_3/dependencies @@ -22,7 +22,6 @@ Modular_arithmetic Number_types Periodic_3_mesh_3 Periodic_3_triangulation_3 -Polygon Principal_component_analysis Principal_component_analysis_LGPL Profiling_tools 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 97cf5cd0363..a80c3995d5c 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 @@ -38,7 +38,7 @@ #include #ifndef CGAL_NO_STRUCTURAL_FILTERING -#include +#include #include #include #endif // no CGAL_NO_STRUCTURAL_FILTERING diff --git a/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3/internal/Periodic_3_Delaunay_triangulation_statically_filtered_traits_3.h b/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3/internal/Periodic_3_Delaunay_triangulation_statically_filtered_traits_3.h index 2ae5c6e3dc5..b2a2a8b7e39 100644 --- a/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3/internal/Periodic_3_Delaunay_triangulation_statically_filtered_traits_3.h +++ b/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3/internal/Periodic_3_Delaunay_triangulation_statically_filtered_traits_3.h @@ -16,7 +16,7 @@ #include -#include +#include #include namespace CGAL { diff --git a/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3/internal/Periodic_3_regular_triangulation_statically_filtered_traits_3.h b/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3/internal/Periodic_3_regular_triangulation_statically_filtered_traits_3.h index bc3eb8b6cb2..1dccfa50e5c 100644 --- a/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3/internal/Periodic_3_regular_triangulation_statically_filtered_traits_3.h +++ b/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3/internal/Periodic_3_regular_triangulation_statically_filtered_traits_3.h @@ -15,7 +15,7 @@ #include -#include +#include #include namespace CGAL { diff --git a/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3/internal/Periodic_3_triangulation_statically_filtered_traits_3.h b/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3/internal/Periodic_3_triangulation_statically_filtered_traits_3.h index b21a612935a..34865a17af2 100644 --- a/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3/internal/Periodic_3_triangulation_statically_filtered_traits_3.h +++ b/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3/internal/Periodic_3_triangulation_statically_filtered_traits_3.h @@ -15,7 +15,7 @@ #include -#include +#include #include namespace CGAL { diff --git a/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3/internal/Periodic_3_orientation_3.h b/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3/internal/Static_filters/Periodic_3_orientation_3.h similarity index 98% rename from Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3/internal/Periodic_3_orientation_3.h rename to Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3/internal/Static_filters/Periodic_3_orientation_3.h index 172b69628a0..9b19c03f511 100644 --- a/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3/internal/Periodic_3_orientation_3.h +++ b/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3/internal/Static_filters/Periodic_3_orientation_3.h @@ -17,8 +17,8 @@ #include #include -#include -#include +#include +#include #include diff --git a/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3/internal/Periodic_3_power_side_of_oriented_power_sphere_3.h b/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3/internal/Static_filters/Periodic_3_power_side_of_oriented_power_sphere_3.h similarity index 88% rename from Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3/internal/Periodic_3_power_side_of_oriented_power_sphere_3.h rename to Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3/internal/Static_filters/Periodic_3_power_side_of_oriented_power_sphere_3.h index e680a7976de..fa8288872a1 100644 --- a/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3/internal/Periodic_3_power_side_of_oriented_power_sphere_3.h +++ b/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3/internal/Static_filters/Periodic_3_power_side_of_oriented_power_sphere_3.h @@ -13,8 +13,8 @@ #define CGAL_INTERNAL_STATIC_FILTERS_PERIODIC_3_POWER_TEST_3_H #include -#include -#include +#include +#include #include diff --git a/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3/internal/Periodic_3_side_of_oriented_sphere_3.h b/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3/internal/Static_filters/Periodic_3_side_of_oriented_sphere_3.h similarity index 98% rename from Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3/internal/Periodic_3_side_of_oriented_sphere_3.h rename to Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3/internal/Static_filters/Periodic_3_side_of_oriented_sphere_3.h index 5271e1eaa25..992e60d1ee0 100644 --- a/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3/internal/Periodic_3_side_of_oriented_sphere_3.h +++ b/Periodic_3_triangulation_3/include/CGAL/Periodic_3_triangulation_3/internal/Static_filters/Periodic_3_side_of_oriented_sphere_3.h @@ -17,8 +17,8 @@ #include #include -#include -#include +#include +#include #include diff --git a/Periodic_3_triangulation_3/package_info/Periodic_3_triangulation_3/dependencies b/Periodic_3_triangulation_3/package_info/Periodic_3_triangulation_3/dependencies index ccf19df4283..b31b936ff04 100644 --- a/Periodic_3_triangulation_3/package_info/Periodic_3_triangulation_3/dependencies +++ b/Periodic_3_triangulation_3/package_info/Periodic_3_triangulation_3/dependencies @@ -16,7 +16,6 @@ Kernel_d Modular_arithmetic Number_types Periodic_3_triangulation_3 -Polygon Profiling_tools Property_map STL_Extension diff --git a/Periodic_3_triangulation_3/test/Periodic_3_triangulation_3/include/CGAL/_test_cls_periodic_3_regular_triangulation_traits_3.h b/Periodic_3_triangulation_3/test/Periodic_3_triangulation_3/include/CGAL/_test_cls_periodic_3_regular_triangulation_traits_3.h index c59d2d48472..d9d43f5e28b 100644 --- a/Periodic_3_triangulation_3/test/Periodic_3_triangulation_3/include/CGAL/_test_cls_periodic_3_regular_triangulation_traits_3.h +++ b/Periodic_3_triangulation_3/test/Periodic_3_triangulation_3/include/CGAL/_test_cls_periodic_3_regular_triangulation_traits_3.h @@ -10,10 +10,6 @@ // Author(s) : Aymeric PELLE // Mael Rouxel-Labbé -#if (__GNUC__>4) || (__GNUC__ == 4 && __GNUC_MINOR__ >=6) -# pragma GCC diagnostic ignored "-Wunused-but-set-variable" -#endif - #include #include diff --git a/Periodic_3_triangulation_3/test/Periodic_3_triangulation_3/include/CGAL/_test_cls_periodic_3_triangulation_traits_3.h b/Periodic_3_triangulation_3/test/Periodic_3_triangulation_3/include/CGAL/_test_cls_periodic_3_triangulation_traits_3.h index 37ebb32353b..6c248ce0210 100644 --- a/Periodic_3_triangulation_3/test/Periodic_3_triangulation_3/include/CGAL/_test_cls_periodic_3_triangulation_traits_3.h +++ b/Periodic_3_triangulation_3/test/Periodic_3_triangulation_3/include/CGAL/_test_cls_periodic_3_triangulation_traits_3.h @@ -11,10 +11,6 @@ // Author(s) : Mariette Yvinec // Manuel Caroli -#if (__GNUC__>4) || (__GNUC__ == 4 && __GNUC_MINOR__ >=6) -# pragma GCC diagnostic ignored "-Wunused-but-set-variable" -#endif - #include template diff --git a/Periodic_4_hyperbolic_triangulation_2/package_info/Periodic_4_hyperbolic_triangulation_2/dependencies b/Periodic_4_hyperbolic_triangulation_2/package_info/Periodic_4_hyperbolic_triangulation_2/dependencies index 3c6be77faf7..d4694a4551a 100644 --- a/Periodic_4_hyperbolic_triangulation_2/package_info/Periodic_4_hyperbolic_triangulation_2/dependencies +++ b/Periodic_4_hyperbolic_triangulation_2/package_info/Periodic_4_hyperbolic_triangulation_2/dependencies @@ -16,7 +16,6 @@ Kernel_23 Modular_arithmetic Number_types Periodic_4_hyperbolic_triangulation_2 -Polygon Profiling_tools Property_map STL_Extension diff --git a/Point_set_2/include/CGAL/Point_set_2.h b/Point_set_2/include/CGAL/Point_set_2.h index 25e3845d922..c9ac5efe759 100644 --- a/Point_set_2/include/CGAL/Point_set_2.h +++ b/Point_set_2/include/CGAL/Point_set_2.h @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include diff --git a/Point_set_2/include/CGAL/nearest_neighbor_delaunay_2.h b/Point_set_2/include/CGAL/nearest_neighbor_delaunay_2.h index 365a9364dff..002b18d819b 100644 --- a/Point_set_2/include/CGAL/nearest_neighbor_delaunay_2.h +++ b/Point_set_2/include/CGAL/nearest_neighbor_delaunay_2.h @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include diff --git a/Point_set_2/package_info/Point_set_2/dependencies b/Point_set_2/package_info/Point_set_2/dependencies index 8978ceba4bf..72d35397d68 100644 --- a/Point_set_2/package_info/Point_set_2/dependencies +++ b/Point_set_2/package_info/Point_set_2/dependencies @@ -1,6 +1,5 @@ Algebraic_foundations Circulator -Distance_2 Filtered_kernel Hash_map Installation @@ -9,7 +8,6 @@ Kernel_23 Modular_arithmetic Number_types Point_set_2 -Polygon Profiling_tools Property_map STL_Extension diff --git a/Point_set_3/include/CGAL/Point_set_3/IO.h b/Point_set_3/include/CGAL/Point_set_3/IO.h index 5baf100079a..6d5e5b1f9a3 100644 --- a/Point_set_3/include/CGAL/Point_set_3/IO.h +++ b/Point_set_3/include/CGAL/Point_set_3/IO.h @@ -53,7 +53,7 @@ class Point_set_3; normal vectors, the normal map is added to the point set. For PLY input, all point properties found in the header are added. - \attention When reading a binary file, the flag `std::ios::binary` flag must be set during the creation of the `ifstream`. + \attention To read a binary file, the flag `std::ios::binary` must be set during the creation of the `ifstream`. \param is input stream \param ps point set @@ -167,7 +167,9 @@ bool read_point_set(const std::string& fname, CGAL::Point_set_3& All properties are inserted in their instantiation order. - \attention When writing a binary file, the flag `std::ios::binary` flag must be set during the creation of the `ofstream`. + \attention To write to a binary file, the flag `std::ios::binary` must be set during the creation + of the `ofstream`, and the \link PkgStreamSupportEnumRef `IO::Mode` \endlink + of the stream must be set to `BINARY`. \param os the output stream \param ps the point set 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 b68091e5fbb..7ecf30255ba 100644 --- a/Point_set_3/include/CGAL/Point_set_3/IO/LAS.h +++ b/Point_set_3/include/CGAL/Point_set_3/IO/LAS.h @@ -54,7 +54,7 @@ void check_if_property_is_used(PointSet& point_set, \brief reads the content of an intput stream in the \ref IOStreamLAS into a point set. - \attention When reading a binary file, the flag `std::ios::binary` flag must be set during the creation of the `ifstream`. + \attention To read a binary file, the flag `std::ios::binary` must be set during the creation of the `ifstream`. \param is the input stream \param point_set the point set @@ -194,7 +194,7 @@ namespace IO { \brief writes the content of a point set into an output stream in the \ref IOStreamLAS. - \attention When writing a binary file, the flag `std::ios::binary` flag must be set during the creation of the `ofstream`. + \attention To write to a binary file, the flag `std::ios::binary` must be set during the creation of the `ofstream`. \tparam Point the point type of the `Point_set_3` \tparam Vector the vector type of the `Point_set_3` 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 dd96c762556..aaab12817f4 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 @@ -234,7 +234,7 @@ public: header. Each line starting by "comment " in the header is appended to the `comments` string (without the "comment " word). - \attention When reading a binary file, the flag `std::ios::binary` flag must be set during the creation of the `ifstream`. + \attention To read a binary file, the flag `std::ios::binary` must be set during the creation of the `ifstream`. \param is the input stream \param point_set the point set @@ -443,7 +443,9 @@ namespace IO { the header of the PLY stream (each line will be precedeed by "comment "). - \attention When writing a binary file, the flag `std::ios::binary` flag must be set during the creation of the `ofstream`. + \attention To write to a binary file, the flag `std::ios::binary` must be set during the creation + of the `ofstream`, and the \link PkgStreamSupportEnumRef `IO::Mode` \endlink + of the stream must be set to `BINARY`. \tparam Point the point type of the `Point_set_3` \tparam Vector the vector type of the `Point_set_3` diff --git a/Point_set_processing_3/include/CGAL/IO/read_las_points.h b/Point_set_processing_3/include/CGAL/IO/read_las_points.h index 5e9e127d0f8..45c9a02e1d3 100644 --- a/Point_set_processing_3/include/CGAL/IO/read_las_points.h +++ b/Point_set_processing_3/include/CGAL/IO/read_las_points.h @@ -365,7 +365,7 @@ void process_properties (const LASpoint& reader, OutputValueType& new_element, - `LAS_property::B` with type `unsigned short` - `LAS_property::I` with type `unsigned short` - \attention When reading a binary file, the flag `std::ios::binary` flag must be set during the creation of the `ifstream`. + \attention To read a binary file, the flag `std::ios::binary` must be set during the creation of the `ifstream`. \tparam OutputIteratorValueType type of objects that can be put in `PointOutputIterator`. It must be a model of `DefaultConstructible` and defaults to `value_type_traits::%type`. @@ -430,7 +430,7 @@ bool read_LAS_with_properties(std::istream& is, Potential additional properties are ignored. - \attention When reading a binary file, the flag `std::ios::binary` flag must be set during the creation of the `ifstream`. + \attention To read a binary file, the flag `std::ios::binary` must be set during the creation of the `ifstream`. \tparam OutputIteratorValueType type of objects that can be put in `PointOutputIterator`. It must be a model of `DefaultConstructible` and defaults to `value_type_traits::%type`. diff --git a/Point_set_processing_3/include/CGAL/IO/read_off_points.h b/Point_set_processing_3/include/CGAL/IO/read_off_points.h index 8fee80ba6bf..1a459a48a56 100644 --- a/Point_set_processing_3/include/CGAL/IO/read_off_points.h +++ b/Point_set_processing_3/include/CGAL/IO/read_off_points.h @@ -190,12 +190,15 @@ bool read_OFF(std::istream& is, put(normal_map, pwn, normal); // normal_map[&pwn] = normal *output++ = pwn; pointsRead++; + } // ...or skip comment line } // Skip remaining lines } - + if(is.eof()) { + is.clear(is.rdstate() & ~std::ios_base::failbit); // set by getline + } return true; } diff --git a/Point_set_processing_3/include/CGAL/IO/read_ply_points.h b/Point_set_processing_3/include/CGAL/IO/read_ply_points.h index 55c79e8a989..7ef8d18806e 100644 --- a/Point_set_processing_3/include/CGAL/IO/read_ply_points.h +++ b/Point_set_processing_3/include/CGAL/IO/read_ply_points.h @@ -124,7 +124,7 @@ make_ply_normal_reader(VectorMap normal_map); second element of the tuple should be a functor that constructs the value type of `PropertyMap` from N objects of types `T`. - \attention When reading a binary file, the flag `std::ios::binary` flag must be set during the creation of the `ifstream`. + \attention To read a binary file, the flag `std::ios::binary` must be set during the creation of the `ifstream`. \tparam OutputIteratorValueType type of objects that can be put in `PointOutputIterator`. It must be a model of `DefaultConstructible` and defaults to `value_type_traits::%type`. @@ -207,7 +207,7 @@ bool read_PLY_with_properties(std::istream& is, Potential additional point properties and faces are ignored. - \attention When reading a binary file, the flag `std::ios::binary` flag must be set during the creation of the `ifstream`. + \attention To read a binary file, the flag `std::ios::binary` must be set during the creation of the `ifstream`. \tparam OutputIteratorValueType type of objects that can be put in `PointOutputIterator`. It must be a model of `DefaultConstructible` and defaults to `value_type_traits::%type`. diff --git a/Point_set_processing_3/include/CGAL/IO/read_xyz_points.h b/Point_set_processing_3/include/CGAL/IO/read_xyz_points.h index a414ddb839a..0de735fadf8 100644 --- a/Point_set_processing_3/include/CGAL/IO/read_xyz_points.h +++ b/Point_set_processing_3/include/CGAL/IO/read_xyz_points.h @@ -179,6 +179,9 @@ bool read_XYZ(std::istream& is, return false; } } + if(is.eof()) { + is.clear(is.rdstate() & ~std::ios_base::failbit); // set by getline + } return true; } diff --git a/Point_set_processing_3/include/CGAL/IO/write_las_points.h b/Point_set_processing_3/include/CGAL/IO/write_las_points.h index 14679ca570a..2fbb8d09af7 100644 --- a/Point_set_processing_3/include/CGAL/IO/write_las_points.h +++ b/Point_set_processing_3/include/CGAL/IO/write_las_points.h @@ -176,10 +176,10 @@ namespace LAS { See documentation of `read_LAS_with_properties()` for the list of available `LAS_property::Tag` classes. - \attention When writing a binary file, the flag `std::ios::binary` flag must be set during the creation of the `ofstream`. + \attention To write to a binary file, the flag `std::ios::binary` must be set during the creation of the `ofstream`. \tparam PointRange is a model of `ConstRange`. The value type of - its iterator is the key type of the named parameter `point_map`. + its iterator is the key type of the named parameter `point_map`. \tparam PointMap is a model of `ReadablePropertyMap` with a value_type = `CGAL::Point_3`. \tparam PropertyHandler handlers to recover properties. @@ -254,10 +254,10 @@ bool write_LAS_with_properties(std::ostream& os, ///< output stream. \brief writes the range of `points` (positions only), using the \ref IOStreamLAS. - \attention When writing a binary file, the flag `std::ios::binary` flag must be set during the creation of the `ofstream`. + \attention To write to a binary file, the flag `std::ios::binary` must be set during the creation of the `ofstream`. \tparam PointRange is a model of `ConstRange`. The value type of - its iterator is the key type of the named parameter `point_map`. + its iterator is the key type of the named parameter `point_map`. \tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" \param os output stream diff --git a/Point_set_processing_3/include/CGAL/IO/write_ply_points.h b/Point_set_processing_3/include/CGAL/IO/write_ply_points.h index 41281a1360f..27dfe372ba9 100644 --- a/Point_set_processing_3/include/CGAL/IO/write_ply_points.h +++ b/Point_set_processing_3/include/CGAL/IO/write_ply_points.h @@ -96,11 +96,13 @@ namespace IO { be provided for `PropertyMap::value_type` that handles both ASCII and binary output (see `CGAL::IO::get_mode()`). - \attention When writing to a binary file, the flag `std::ios::binary` flag must be set during the creation of the `ofstream`. + \attention To write to a binary file, the flag `std::ios::binary` must be set during the creation + of the `ofstream`, and the \link PkgStreamSupportEnumRef `IO::Mode` \endlink + of the stream must be set to `BINARY`. \tparam PointRange is a model of `ConstRange`. The value type of - its iterator is the key type of the `PropertyMap` objects provided - within the `PropertyHandler` parameter. + its iterator is the key type of the `PropertyMap` objects provided + within the `PropertyHandler` parameter. \tparam PropertyHandler handlers to recover properties. \returns `true` if writing was successful, `false` otherwise. @@ -145,10 +147,12 @@ template = 2 || neighbor_radius > FT(0)); - std::size_t memory = CGAL::Memory_sizer().virtual_size(); CGAL_TRACE(" %ld Mb allocated\n", memory>>20); - CGAL_TRACE(" Creates KD-tree\n"); + std::size_t memory = CGAL::Memory_sizer().virtual_size(); + CGAL_TRACE_STREAM << (memory >> 20) << " Mb allocated\n"; + CGAL_TRACE_STREAM << " Creates KD-tree\n"; Neighbor_query neighbor_query (points, point_map); - memory = CGAL::Memory_sizer().virtual_size(); CGAL_TRACE(" %ld Mb allocated\n", memory>>20); - CGAL_TRACE(" Computes normals\n"); + memory = CGAL::Memory_sizer().virtual_size(); + CGAL_TRACE_STREAM << (memory >> 20) << " Mb allocated\n"; + CGAL_TRACE_STREAM << " Computes normals\n"; std::size_t nb_points = points.size(); @@ -251,8 +253,9 @@ jet_estimate_normals( callback_wrapper.join(); - memory = CGAL::Memory_sizer().virtual_size(); CGAL_TRACE(" %ld Mb allocated\n", memory>>20); - CGAL_TRACE("End of jet_estimate_normals()\n"); + memory = CGAL::Memory_sizer().virtual_size(); + CGAL_TRACE_STREAM << (memory >> 20) << " Mb allocated\n"; + CGAL_TRACE_STREAM << "End of jet_estimate_normals()\n"; } 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 544614a7fbc..cdc316fc7ad 100644 --- a/Point_set_processing_3/include/CGAL/mst_orient_normals.h +++ b/Point_set_processing_3/include/CGAL/mst_orient_normals.h @@ -245,7 +245,7 @@ mst_find_source( NormalMap normal_map, ///< property map: value_type of ForwardIterator -> Vector_3 const Kernel& /*kernel*/) ///< geometric traits. { - CGAL_TRACE(" mst_find_source()\n"); + CGAL_TRACE_STREAM << " mst_find_source()\n"; // Input points types typedef typename boost::property_traits::value_type Vector; @@ -270,8 +270,8 @@ mst_find_source( Vector_ref normal = get(normal_map,*top_point); const Vector Z(0, 0, 1); if (Z * normal < 0) { - CGAL_TRACE(" Flip top point normal\n"); - put(normal_map,*top_point, -normal); + CGAL_TRACE_STREAM << " Flip top point normal\n"; + put(normal_map,*top_point, -normal); } return top_point; @@ -329,13 +329,15 @@ create_riemannian_graph( // Number of input points const std::size_t num_input_points = points.size(); - std::size_t memory = CGAL::Memory_sizer().virtual_size(); CGAL_TRACE(" %ld Mb allocated\n", memory>>20); - CGAL_TRACE(" Creates KD-tree\n"); + std::size_t memory = CGAL::Memory_sizer().virtual_size(); + CGAL_TRACE_STREAM << (memory >> 20) << " Mb allocated\n"; + CGAL_TRACE_STREAM << " Creates KD-tree\n"; Neighbor_query neighbor_query (points, point_map); - memory = CGAL::Memory_sizer().virtual_size(); CGAL_TRACE(" %ld Mb allocated\n", memory>>20); - CGAL_TRACE(" Creates Riemannian Graph\n"); + memory = CGAL::Memory_sizer().virtual_size(); + CGAL_TRACE_STREAM << (memory >> 20) << " Mb allocated\n"; + CGAL_TRACE_STREAM << " Creates Riemannian Graph\n"; // Iterates over input points and creates Riemannian Graph: // - vertices are numbered like the input points index. @@ -465,8 +467,9 @@ create_mst_graph( // Number of input points const std::size_t num_input_points = num_vertices(riemannian_graph) - 1; - std::size_t memory = CGAL::Memory_sizer().virtual_size(); CGAL_TRACE(" %ld Mb allocated\n", memory>>20); - CGAL_TRACE(" Calls boost::prim_minimum_spanning_tree()\n"); + std::size_t memory = CGAL::Memory_sizer().virtual_size(); + CGAL_TRACE_STREAM << (memory >> 20) << " Mb allocated\n"; + CGAL_TRACE_STREAM << " Calls boost::prim_minimum_spanning_tree()\n"; // Computes Minimum Spanning Tree. std::size_t source_point_index = num_input_points; @@ -478,8 +481,9 @@ create_mst_graph( weight_map( riemannian_graph_weight_map ) .root_vertex( vertex(source_point_index, riemannian_graph) )); - memory = CGAL::Memory_sizer().virtual_size(); CGAL_TRACE(" %ld Mb allocated\n", memory>>20); - CGAL_TRACE(" Creates MST Graph\n"); + memory = CGAL::Memory_sizer().virtual_size(); + CGAL_TRACE_STREAM << (memory >> 20) << " Mb allocated\n"; + CGAL_TRACE_STREAM << " Creates MST Graph\n"; // Converts predecessor map to a MST graph: // - vertices are numbered like the input points index. @@ -605,7 +609,7 @@ mst_orient_normals( using parameters::choose_parameter; using parameters::get_parameter; - CGAL_TRACE("Calls mst_orient_normals()\n"); + CGAL_TRACE_STREAM << "Calls mst_orient_normals()\n"; typedef typename CGAL::GetPointMap::type PointMap; typedef typename Point_set_processing_3::GetNormalMap::type NormalMap; @@ -643,8 +647,9 @@ mst_orient_normals( // Precondition: at least 2 nearest neighbors CGAL_point_set_processing_precondition(k >= 2); - std::size_t memory = CGAL::Memory_sizer().virtual_size(); CGAL_TRACE(" %ld Mb allocated\n", memory>>20); - CGAL_TRACE(" Create Index_property_map\n"); + std::size_t memory = CGAL::Memory_sizer().virtual_size(); + CGAL_TRACE_STREAM << (memory >> 20) << " Mb allocated\n"; + CGAL_TRACE_STREAM << " Create Index_property_map\n"; // Create a property map Iterator -> index. // - if typename PointRange::iterator is a random access iterator (typically vector and deque), @@ -686,8 +691,9 @@ mst_orient_normals( kernel, riemannian_graph); - memory = CGAL::Memory_sizer().virtual_size(); CGAL_TRACE(" %ld Mb allocated\n", memory>>20); - CGAL_TRACE(" Calls boost::breadth_first_search()\n"); + memory = CGAL::Memory_sizer().virtual_size(); + CGAL_TRACE_STREAM << (memory >> 20) << " Mb allocated\n"; + CGAL_TRACE_STREAM << " Calls boost::breadth_first_search()\n"; const std::size_t num_input_points = distance(points.begin(), points.end()); std::size_t source_point_index = num_input_points; @@ -717,10 +723,11 @@ mst_orient_normals( std::copy(unoriented_points.begin(), unoriented_points.end(), first_unoriented_point); // At this stage, we have typically 0 unoriented normals if k is large enough - CGAL_TRACE(" => %u normals are unoriented\n", unoriented_points.size()); + CGAL_TRACE_STREAM << " => " << unoriented_points.size() << " normals are unoriented\n"; - memory = CGAL::Memory_sizer().virtual_size(); CGAL_TRACE(" %ld Mb allocated\n", memory>>20); - CGAL_TRACE("End of mst_orient_normals()\n"); + memory = CGAL::Memory_sizer().virtual_size(); + CGAL_TRACE_STREAM << (memory >> 20) << " Mb allocated\n"; + CGAL_TRACE_STREAM << "End of mst_orient_normals()\n"; return first_unoriented_point; } diff --git a/Point_set_processing_3/include/CGAL/pca_estimate_normals.h b/Point_set_processing_3/include/CGAL/pca_estimate_normals.h index 8f20104b64d..5979f11086e 100644 --- a/Point_set_processing_3/include/CGAL/pca_estimate_normals.h +++ b/Point_set_processing_3/include/CGAL/pca_estimate_normals.h @@ -159,7 +159,7 @@ pca_estimate_normals( using parameters::choose_parameter; using parameters::get_parameter; - CGAL_TRACE("Calls pca_estimate_normals()\n"); + CGAL_TRACE_STREAM << "Calls pca_estimate_normals()\n"; // basic geometric types typedef typename CGAL::GetPointMap::type PointMap; @@ -192,13 +192,15 @@ pca_estimate_normals( // precondition: at least 2 nearest neighbors CGAL_point_set_processing_precondition(k >= 2); - std::size_t memory = CGAL::Memory_sizer().virtual_size(); CGAL_TRACE(" %ld Mb allocated\n", memory>>20); - CGAL_TRACE(" Creates KD-tree\n"); + std::size_t memory = CGAL::Memory_sizer().virtual_size(); + CGAL_TRACE_STREAM << (memory >> 20) << " Mb allocated\n"; + CGAL_TRACE_STREAM << " Creates KD-tree\n"; Neighbor_query neighbor_query (points, point_map); - memory = CGAL::Memory_sizer().virtual_size(); CGAL_TRACE(" %ld Mb allocated\n", memory>>20); - CGAL_TRACE(" Computes normals\n"); + memory = CGAL::Memory_sizer().virtual_size(); + CGAL_TRACE_STREAM << (memory >> 20) << " Mb allocated\n"; + CGAL_TRACE_STREAM << " Computes normals\n"; std::size_t nb_points = points.size(); @@ -223,8 +225,9 @@ pca_estimate_normals( callback_wrapper.join(); - memory = CGAL::Memory_sizer().virtual_size(); CGAL_TRACE(" %ld Mb allocated\n", memory>>20); - CGAL_TRACE("End of pca_estimate_normals()\n"); + memory = CGAL::Memory_sizer().virtual_size(); + CGAL_TRACE_STREAM << (memory >> 20) << " Mb allocated\n"; + CGAL_TRACE_STREAM << "End of pca_estimate_normals()\n"; } /// \cond SKIP_IN_MANUAL diff --git a/Point_set_processing_3/package_info/Point_set_processing_3/dependencies b/Point_set_processing_3/package_info/Point_set_processing_3/dependencies index 34b36f0b394..dcdadf3e8dc 100644 --- a/Point_set_processing_3/package_info/Point_set_processing_3/dependencies +++ b/Point_set_processing_3/package_info/Point_set_processing_3/dependencies @@ -22,7 +22,6 @@ Modular_arithmetic Number_types Point_set_2 Point_set_processing_3 -Polygon Principal_component_analysis Principal_component_analysis_LGPL Profiling_tools diff --git a/Point_set_processing_3/test/Point_set_processing_3/test_deprecated_io_point_set.cpp b/Point_set_processing_3/test/Point_set_processing_3/test_deprecated_io_point_set.cpp index 701692d16f3..218f4f42b63 100644 --- a/Point_set_processing_3/test/Point_set_processing_3/test_deprecated_io_point_set.cpp +++ b/Point_set_processing_3/test/Point_set_processing_3/test_deprecated_io_point_set.cpp @@ -77,116 +77,150 @@ points[1] = std::make_pair(Point_3(0,1,0), Color{0,255,0,255}); points[2] = std::make_pair(Point_3(0,0,1), Color{0,0,255,255}); -std::ofstream os; -std::ifstream is; bool ok; std::vector ps; ps.push_back(Point_3(1,0,0)); ps.push_back(Point_3(0,1,0)); ps.push_back(Point_3(0,0,1)); + + //LAS #ifdef CGAL_LINKED_WITH_LASLIB -os.open("tmp.las", std::ios::binary); -ok = CGAL::write_las_points_with_properties(os, points, - CGAL::make_las_point_writer(CGAL::First_of_pair_property_map()), - std::make_pair(GetRedMap(),CGAL::LAS_property::R()), - std::make_pair(GetGreenMap(), CGAL::LAS_property::G()), - std::make_pair(GetBlueMap(), CGAL::LAS_property::B()), - std::make_pair(GetAlphaMap(), CGAL::LAS_property::I()) - ); -os.close(); -assert(ok); -points.clear(); -is.open("tmp.las", std::ios::binary); -ok = CGAL::read_las_points_with_properties(is, std::back_inserter (points), - CGAL::make_las_point_reader(CGAL::First_of_pair_property_map()), - std::make_tuple(CGAL::Second_of_pair_property_map(), - CGAL::Construct_array(), - CGAL::LAS_property::R(), - CGAL::LAS_property::G(), - CGAL::LAS_property::B(), - CGAL::LAS_property::I())); -is.close(); -assert(ok); -assert(points.size() == 3); -assert(points[1].second[1] == 255); -os.open("tmp.las", std::ios_base::binary); -CGAL::write_las_points(os, ps, CGAL::parameters::all_default()); -os.close(); -assert(ok); -ps.clear(); -is.open("tmp.las", std::ios::binary); -ok = CGAL::read_las_points(is, std::back_inserter (ps),CGAL::parameters::all_default()); -is.close(); -assert(ok); -assert(ps.size() == 3); + { + std::ofstream os("tmp1.las", std::ios::binary); + ok = CGAL::write_las_points_with_properties(os, points, + CGAL::make_las_point_writer(CGAL::First_of_pair_property_map()), + std::make_pair(GetRedMap(),CGAL::LAS_property::R()), + std::make_pair(GetGreenMap(), CGAL::LAS_property::G()), + std::make_pair(GetBlueMap(), CGAL::LAS_property::B()), + std::make_pair(GetAlphaMap(), CGAL::LAS_property::I()) + ); + assert(ok); + + } + + { + points.clear(); + std::ifstream is("tmp1.las", std::ios::binary); + ok = CGAL::read_las_points_with_properties(is, std::back_inserter (points), + CGAL::make_las_point_reader(CGAL::First_of_pair_property_map()), + std::make_tuple(CGAL::Second_of_pair_property_map(), + CGAL::Construct_array(), + CGAL::LAS_property::R(), + CGAL::LAS_property::G(), + CGAL::LAS_property::B(), + CGAL::LAS_property::I())); + assert(ok); + assert(points.size() == 3); + assert(points[1].second[1] == 255); + } + + { + std::ofstream os("tmp2.las", std::ios_base::binary); + CGAL::write_las_points(os, ps, CGAL::parameters::all_default()); + assert(ok); + } + + { + ps.clear(); + std::ifstream is("tmp2.las", std::ios::binary); + ok = CGAL::read_las_points(is, std::back_inserter (ps),CGAL::parameters::all_default()); + assert(ok); + assert(ps.size() == 3); + } #endif + + //PLY -os.open("tmp.ply"); -ok = CGAL::write_ply_points_with_properties(os, points, - CGAL::make_ply_point_writer (CGAL::First_of_pair_property_map()), - std::make_pair(GetRedMap(),CGAL::PLY_property("red")), - std::make_pair(GetGreenMap(), CGAL::PLY_property("green")), - std::make_pair(GetBlueMap(), CGAL::PLY_property("blue")), - std::make_pair(GetAlphaMap(), CGAL::PLY_property("alpha")) - ); -os.close(); -assert(ok); + { + std::ofstream os("tmp1.ply"); + assert(os.good()); + ok = CGAL::write_ply_points_with_properties(os, points, + CGAL::make_ply_point_writer (CGAL::First_of_pair_property_map()), + std::make_pair(GetRedMap(),CGAL::PLY_property("red")), + std::make_pair(GetGreenMap(), CGAL::PLY_property("green")), + std::make_pair(GetBlueMap(), CGAL::PLY_property("blue")), + std::make_pair(GetAlphaMap(), CGAL::PLY_property("alpha")) + ); + assert(! os.fail()); + assert(ok); + } -is.open("tmp.ply"); -points.clear(); -ok = CGAL::read_ply_points_with_properties(is, std::back_inserter (points), - CGAL::make_ply_point_reader(CGAL::First_of_pair_property_map()), - std::make_tuple(CGAL::Second_of_pair_property_map(), - CGAL::Construct_array(), - CGAL::PLY_property("red"), - CGAL::PLY_property("green"), - CGAL::PLY_property("blue"), - CGAL::PLY_property("alpha"))); -is.close(); -assert(ok); -assert(points.size() == 3); -assert(points[1].second[1] == 255); + { + std::ifstream is("tmp1.ply"); + assert(is.good()); + points.clear(); + ok = CGAL::read_ply_points_with_properties(is, std::back_inserter (points), + CGAL::make_ply_point_reader(CGAL::First_of_pair_property_map()), + std::make_tuple(CGAL::Second_of_pair_property_map(), + CGAL::Construct_array(), + CGAL::PLY_property("red"), + CGAL::PLY_property("green"), + CGAL::PLY_property("blue"), + CGAL::PLY_property("alpha"))); + assert(! is.fail()); + assert(ok); + assert(points.size() == 3); + assert(points[1].second[1] == 255); + } -os.open("tmp.ply"); -ok = CGAL::write_ply_points(os, ps, CGAL::parameters::all_default()); -os.close(); -assert(ok); + { + std::ofstream os("tmp2.ply"); + assert(os.good()); + ok = CGAL::write_ply_points(os, ps, CGAL::parameters::all_default()); + assert(! os.fail()); + assert(ok); + } -is.open("tmp.ply"); -ps.clear(); -ok = CGAL::read_ply_points(is, std::back_inserter (ps), - CGAL::parameters::all_default()); -is.close(); -assert(ok); -assert(ps.size() == 3); + { + std::ifstream is("tmp2.ply"); + assert(is.good()); + ps.clear(); + ok = CGAL::read_ply_points(is, std::back_inserter (ps), + CGAL::parameters::all_default()); + assert(! is.fail()); + assert(ok); + assert(ps.size() == 3); + } //OFF -os.open("tmp.off"); -ok = CGAL::write_off_points(os, ps, CGAL::parameters::all_default()); -os.close(); -assert(ok); + { + std::ofstream os("tmp.off"); + assert(os.good()); + ok = CGAL::write_off_points(os, ps, CGAL::parameters::all_default()); + assert(! os.fail()); + assert(ok); + } -is.open("tmp.off"); -ps.clear(); -ok = CGAL::read_off_points(is, std::back_inserter (ps), - CGAL::parameters::all_default()); -is.close(); -assert(ok); -assert(ps.size() == 3); + { + std::ifstream is("tmp.off"); + assert(is.good()); + ps.clear(); + ok = CGAL::read_off_points(is, std::back_inserter (ps), + CGAL::parameters::all_default()); + assert(! is.fail()); + assert(ok); + assert(ps.size() == 3); + } //XYZ -os.open("tmp.xyz"); -ok = CGAL::write_xyz_points(os, ps, CGAL::parameters::all_default()); -os.close(); -assert(ok); + { + std::ofstream os("tmp.xyz"); + assert(os.good()); + ok = CGAL::write_xyz_points(os, ps, CGAL::parameters::all_default()); + assert(! os.fail()); + assert(ok); + } -is.open("tmp.xyz"); -ps.clear(); -ok = CGAL::read_xyz_points(is, std::back_inserter (ps), - CGAL::parameters::all_default()); -is.close(); -assert(ok); -assert(ps.size() == 3); + { + std::ifstream is("tmp.xyz"); + assert(is.good()); + ps.clear(); + ok = CGAL::read_xyz_points(is, std::back_inserter (ps), + CGAL::parameters::all_default()); + assert(! is.fail()); + assert(ok); + assert(ps.size() == 3); + } } diff --git a/Point_set_processing_3/test/Point_set_processing_3/wlop_simplify_and_regularize_test.cmd b/Point_set_processing_3/test/Point_set_processing_3/wlop_simplify_and_regularize_test.cmd index ee93d623f58..7c335728af0 100644 --- a/Point_set_processing_3/test/Point_set_processing_3/wlop_simplify_and_regularize_test.cmd +++ b/Point_set_processing_3/test/Point_set_processing_3/wlop_simplify_and_regularize_test.cmd @@ -1 +1 @@ -data/sphere_20k.xyz +${CGAL_DATA_DIR}/points_3/sphere_20k.xyz 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 e526d4ac91f..2c4cc8d1f7a 100644 --- a/Poisson_surface_reconstruction_3/include/CGAL/Poisson_reconstruction_function.h +++ b/Poisson_surface_reconstruction_3/include/CGAL/Poisson_reconstruction_function.h @@ -770,7 +770,7 @@ private: SparseLinearAlgebraTraits_d solver, ///< sparse linear solver double lambda) { - CGAL_TRACE("Calls solve_poisson()\n"); + CGAL_TRACE_STREAM << "Calls solve_poisson()\n"; double time_init = clock(); @@ -786,7 +786,7 @@ private: m_tr->index_unconstrained_vertices(); unsigned int nb_variables = static_cast(m_tr->number_of_vertices()-1); - CGAL_TRACE(" Number of variables: %ld\n", (long)(nb_variables)); + CGAL_TRACE_STREAM << " Number of variables: " << nb_variables << std::endl; // Assemble linear system A*X=B typename SparseLinearAlgebraTraits_d::Matrix A(nb_variables); // matrix is symmetric definite positive @@ -815,9 +815,9 @@ private: clear_duals(); clear_normals(); duration_assembly = (clock() - time_init)/CLOCKS_PER_SEC; - CGAL_TRACE(" Creates matrix: done (%.2lf s)\n", duration_assembly); + CGAL_TRACE_STREAM << " Creates matrix: done (" << duration_assembly << "sec.)\n"; - CGAL_TRACE(" Solve sparse linear system...\n"); + CGAL_TRACE_STREAM << " Solve sparse linear system...\n"; // Solve "A*X = B". On success, solution is (1/D) * X. time_init = clock(); @@ -827,7 +827,7 @@ private: CGAL_surface_reconstruction_points_assertion(D == 1.0); duration_solve = (clock() - time_init)/CLOCKS_PER_SEC; - CGAL_TRACE(" Solve sparse linear system: done (%.2lf s)\n", duration_solve); + CGAL_TRACE_STREAM << " Solve sparse linear system: done (" << duration_solve << "sec.)\n"; // copy function's values to vertices unsigned int index = 0; @@ -835,7 +835,7 @@ private: if(!m_tr->is_constrained(v)) v->f() = X[index++]; - CGAL_TRACE("End of solve_poisson()\n"); + CGAL_TRACE_STREAM << "End of solve_poisson()\n"; return true; } diff --git a/Poisson_surface_reconstruction_3/package_info/Poisson_surface_reconstruction_3/dependencies b/Poisson_surface_reconstruction_3/package_info/Poisson_surface_reconstruction_3/dependencies index 81a3dea3b55..5c532a3d624 100644 --- a/Poisson_surface_reconstruction_3/package_info/Poisson_surface_reconstruction_3/dependencies +++ b/Poisson_surface_reconstruction_3/package_info/Poisson_surface_reconstruction_3/dependencies @@ -20,7 +20,6 @@ Modular_arithmetic Number_types Point_set_processing_3 Poisson_surface_reconstruction_3 -Polygon Principal_component_analysis_LGPL Profiling_tools Property_map diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt index e678bf1627f..5d2addbde92 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt @@ -193,9 +193,11 @@ The page \ref bgl_namedparameters "Named Parameters" describes their usage. \cgalCRPSection{Geometric Measure Functions} - \link measure_grp `CGAL::Polygon_mesh_processing::face_area()` \endlink +- \link measure_grp `CGAL::Polygon_mesh_processing::squared_face_area()` \endlink - \link measure_grp `CGAL::Polygon_mesh_processing::area()` \endlink - \link measure_grp `CGAL::Polygon_mesh_processing::volume()` \endlink - \link measure_grp `CGAL::Polygon_mesh_processing::edge_length()` \endlink +- \link measure_grp `CGAL::Polygon_mesh_processing::squared_edge_length()` \endlink - \link measure_grp `CGAL::Polygon_mesh_processing::face_border_length()` \endlink - \link measure_grp `CGAL::Polygon_mesh_processing::centroid()` \endlink - \link measure_grp `CGAL::Polygon_mesh_processing::match_faces()` \endlink diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/Weights.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/Weights.h deleted file mode 100644 index 22c308757e1..00000000000 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/Weights.h +++ /dev/null @@ -1,917 +0,0 @@ -// Copyright (c) 2015 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) : Yin Xu, Andreas Fabri and Ilker O. Yaz - -#ifndef CGAL_PMP_WEIGHTS_H -#define CGAL_PMP_WEIGHTS_H - -#include - -/// @cond CGAL_DOCUMENT_INTERNAL - -#include -#include -#include - -namespace CGAL { -namespace internal { - -// Returns the cotangent value of half angle v0 v1 v2 -// using formula in -[Meyer02] Discrete Differential-Geometry Operators for- page 19 -// The potential problem with previous one (Cotangent_value) is that it does not produce symmetric results -// (i.e. for v0, v1, v2 and v2, v1, v0 returned cot weights can be slightly different) -// This one provides stable results. -template -struct Cotangent_value_Meyer_impl -{ - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - - template - double operator()(vertex_descriptor v0, vertex_descriptor v1, vertex_descriptor v2, const VertexPointMap& ppmap) - { - typedef typename Kernel_traits< - typename boost::property_traits::value_type >::Kernel::Vector_3 Vector; - - Vector a = get(ppmap, v0) - get(ppmap, v1); - Vector b = get(ppmap, v2) - get(ppmap, v1); - - double dot_ab = to_double(a*b); - // rewritten for safer fp arithmetic - //double dot_aa = a.squared_length(); - //double dot_bb = b.squared_length(); - //double divider = CGAL::sqrt( dot_aa * dot_bb - dot_ab * dot_ab ); - - Vector cross_ab = CGAL::cross_product(a, b); - double divider = to_double(CGAL::approximate_sqrt(cross_ab*cross_ab)); - - if(divider == 0 /*|| divider != divider*/) - { - CGAL::collinear(get(ppmap, v0), get(ppmap, v1), get(ppmap, v2)) ? - CGAL_warning_msg(false, "Infinite Cotangent value with degenerate triangle!") : - CGAL_warning_msg(false, "Infinite Cotangent value due to floating point arithmetic!"); - - - return dot_ab > 0 ? (std::numeric_limits::max)() : - -(std::numeric_limits::max)(); - } - - return dot_ab / divider; - } -}; - -// Same as above but with a different API -template::type> -class Cotangent_value_Meyer -{ -protected: - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - typedef VertexPointMap Point_property_map; - typedef typename boost::property_traits::value_type Point; - typedef typename Kernel_traits::Kernel::Vector_3 Vector; - - PolygonMesh& pmesh_; - Point_property_map ppmap_; - -public: - - Cotangent_value_Meyer(PolygonMesh& pmesh_, VertexPointMap vpmap_) - : pmesh_(pmesh_) - , ppmap_(vpmap_) - {} - - PolygonMesh& pmesh() - { - return pmesh_; - } - - Point_property_map& ppmap() - { - return ppmap_; - } - - double operator()(vertex_descriptor v0, vertex_descriptor v1, vertex_descriptor v2) - { - return Cotangent_value_Meyer_impl()(v0, v1, v2, ppmap()); - } -}; - - -// imported from skeletonization -template::type> -class Cotangent_value_Meyer_secure -{ - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - typedef VertexPointMap Point_property_map; - typedef typename boost::property_traits::value_type Point; - typedef typename Kernel_traits::Kernel::Vector_3 Vector; - - PolygonMesh& pmesh_; - Point_property_map ppmap_; - -public: - - Cotangent_value_Meyer_secure(PolygonMesh& pmesh_, VertexPointMap vpmap_) - : pmesh_(pmesh_) - , ppmap_(vpmap_) - {} - - PolygonMesh& pmesh() - { - return pmesh_; - } - - Point_property_map& ppmap() - { - return ppmap_; - } - - double operator()(vertex_descriptor v0, vertex_descriptor v1, vertex_descriptor v2) - { - Vector a = get(ppmap(), v0) - get(ppmap(), v1); - Vector b = get(ppmap(), v2) - get(ppmap(), v1); - - double dot_ab = CGAL::to_double(a * b); - double dot_aa = CGAL::to_double(a.squared_length()); - double dot_bb = CGAL::to_double(b.squared_length()); - double lb = -0.999, ub = 0.999; - double cosine = dot_ab / CGAL::sqrt(dot_aa) / CGAL::sqrt(dot_bb); - cosine = (cosine < lb) ? lb : cosine; - cosine = (cosine > ub) ? ub : cosine; - double sine = std::sqrt(1.0 - cosine * cosine); - return cosine / sine; - } -}; - -// Returns the cotangent value of half angle v0 v1 v2 by clamping between [1, 89] degrees -// as suggested by -[Friedel] Unconstrained Spherical Parameterization- -template::type - , class CotangentValue = Cotangent_value_Meyer > -class Cotangent_value_clamped : CotangentValue -{ - Cotangent_value_clamped() - {} -public: - - Cotangent_value_clamped(PolygonMesh& pmesh_, VertexPointMap vpmap_) - : CotangentValue(pmesh_, vpmap_) - {} - - PolygonMesh& pmesh() - { - return CotangentValue::pmesh(); - } - - VertexPointMap& ppmap() - { - return CotangentValue::ppmap(); - } - - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - - double operator()(vertex_descriptor v0, vertex_descriptor v1, vertex_descriptor v2) - { - const double cot_1 = 57.289962; - const double cot_89 = 0.017455; - double value = CotangentValue::operator()(v0, v1, v2); - return (std::max)(cot_89, (std::min)(value, cot_1)); - } -}; - -template::type - , class CotangentValue = Cotangent_value_Meyer > -class Cotangent_value_clamped_2 : CotangentValue -{ - Cotangent_value_clamped_2() - {} - -public: - - Cotangent_value_clamped_2(PolygonMesh& pmesh_, VertexPointMap vpmap_) - : CotangentValue(pmesh_, vpmap_) - {} - - PolygonMesh& pmesh() - { - return CotangentValue::pmesh(); - } - - VertexPointMap& ppmap() - { - return CotangentValue::ppmap(); - } - - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - - double operator()(vertex_descriptor v0, vertex_descriptor v1, vertex_descriptor v2) - { - const double cot_5 = 5.671282; - const double cot_175 = -cot_5; - double value = CotangentValue::operator()(v0, v1, v2); - return (std::max)(cot_175, (std::min)(value, cot_5)); - } -}; - -template::type - , class CotangentValue = Cotangent_value_Meyer > -class Cotangent_value_minimum_zero : CotangentValue -{ - Cotangent_value_minimum_zero() - {} -public: - Cotangent_value_minimum_zero(PolygonMesh& pmesh_, VertexPointMap vpmap_) - : CotangentValue(pmesh_, vpmap_) - {} - - PolygonMesh& pmesh() - { - return CotangentValue::pmesh(); - } - - VertexPointMap& ppmap() - { - return CotangentValue::ppmap(); - } - - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - - double operator()(vertex_descriptor v0, vertex_descriptor v1, vertex_descriptor v2) - { - double value = CotangentValue::operator()(v0, v1, v2); - return (std::max)(0.0, value); - } -}; - -template > -struct Cotangent_value_minimum_zero_impl : CotangentValue -{ - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - - template - double operator()(vertex_descriptor v0, vertex_descriptor v1, vertex_descriptor v2, const VertexPointMap ppmap) - { - double value = CotangentValue::operator()(v0, v1, v2, ppmap); - return (std::max)(0.0, value); - } -}; - -template::type - , class CotangentValue - = Cotangent_value_Meyer > -class Voronoi_area : CotangentValue -{ -public: - Voronoi_area(PolygonMesh& pmesh_, VertexPointMap vpmap_) - : CotangentValue(pmesh_, vpmap_) - {} - - PolygonMesh& pmesh() - { - return CotangentValue::pmesh(); - } - - VertexPointMap& ppmap() - { - return CotangentValue::ppmap(); - } - - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - typedef typename boost::graph_traits::in_edge_iterator in_edge_iterator; - typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - - typedef VertexPointMap Point_property_map; - typedef typename boost::property_traits::value_type Point; - typedef typename Kernel_traits::Kernel::Vector_3 Vector; - - double operator()(vertex_descriptor v0) { - - //return 1.0; - double voronoi_area = 0.0; - for(halfedge_descriptor he : - halfedges_around_target( halfedge(v0,pmesh()), pmesh()) ) - { - if( is_border(he,pmesh()) ) { continue; } - - CGAL_expensive_assertion(CGAL::is_valid_polygon_mesh(pmesh())); - CGAL_expensive_assertion(CGAL::is_triangle_mesh(pmesh())); - CGAL_assertion( v0 == target(he, pmesh()) ); - vertex_descriptor v1 = source(he, pmesh()); - vertex_descriptor v_op = target(next(he, pmesh()), pmesh()); - - const Point& v0_p = get(ppmap(), v0); - const Point& v1_p = get(ppmap(), v1); - const Point& v_op_p = get(ppmap(), v_op); - - // (?) check if there is a better way to predicate triangle is obtuse or not - CGAL::Angle angle0 = CGAL::angle(v1_p, v0_p, v_op_p); - CGAL::Angle angle1 = CGAL::angle(v_op_p, v1_p, v0_p); - CGAL::Angle angle_op = CGAL::angle(v0_p, v_op_p, v1_p); - - bool obtuse = (angle0 == CGAL::OBTUSE) || (angle1 == CGAL::OBTUSE) || (angle_op == CGAL::OBTUSE); - - if(!obtuse) { - double cot_v1 = CotangentValue::operator()(v_op, v1, v0); - double cot_v_op = CotangentValue::operator()(v0, v_op, v1); - - double term1 = cot_v1 * to_double((v_op_p - v0_p).squared_length()); - double term2 = cot_v_op * to_double((v1_p - v0_p).squared_length()); - voronoi_area += (1.0 / 8.0) * (term1 + term2); - } - else { - double area_t = to_double(CGAL::approximate_sqrt(squared_area(v0_p, v1_p, v_op_p))); - if(angle0 == CGAL::OBTUSE) { - voronoi_area += area_t / 2.0; - } - else { - voronoi_area += area_t / 4.0; - } - } - } - CGAL_warning_msg(voronoi_area != 0, "Zero voronoi area!"); - return voronoi_area; - } -}; -// Returns the cotangent value of half angle v0 v1 v2 by dividing the triangle area -// as suggested by -[Mullen08] Spectral Conformal Parameterization- -template::type - , class CotangentValue = Cotangent_value_Meyer > -class Cotangent_value_area_weighted : CotangentValue -{ - Cotangent_value_area_weighted() - {} - -public: - - Cotangent_value_area_weighted(PolygonMesh& pmesh_, VertexPointMap vpmap_) - : CotangentValue(pmesh_, vpmap_) - {} - - PolygonMesh& pmesh() - { - return CotangentValue::pmesh(); - } - - VertexPointMap& ppmap() - { - return CotangentValue::ppmap(); - } - - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - - double operator()(vertex_descriptor v0, vertex_descriptor v1, vertex_descriptor v2) - { - return CotangentValue::operator()(v0, v1, v2) / - CGAL::sqrt(squared_area(get(this->ppmap(), v0), - get(this->ppmap(), v1), - get(this->ppmap(), v2))); - } -}; -///////////////////////////////////////////////////////////////////////////////////////// - -///////////////////////////// Edge Weight Calculators /////////////////////////////////// -// Cotangent weight calculator -// Cotangent_value: as suggested by -[Sorkine07] ARAP Surface Modeling- -// Cotangent_value_area_weighted: as suggested by -[Mullen08] Spectral Conformal Parameterization- -template< class PolygonMesh, - class CotangentValue = Cotangent_value_minimum_zero_impl > -struct Cotangent_weight_impl : CotangentValue -{ - typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - - // Returns the cotangent weight of specified halfedge_descriptor - // Edge orientation is trivial - template - double operator()(halfedge_descriptor he, PolygonMesh& pmesh, const VertexPointMap& ppmap) - { - vertex_descriptor v0 = target(he, pmesh); - vertex_descriptor v1 = source(he, pmesh); - // Only one triangle for border edges - if (is_border_edge(he, pmesh)) - { - - halfedge_descriptor he_cw = opposite( next(he, pmesh) , pmesh ); - vertex_descriptor v2 = source(he_cw, pmesh); - if (is_border_edge(he_cw, pmesh) ) - { - halfedge_descriptor he_ccw = prev( opposite(he, pmesh) , pmesh ); - v2 = source(he_ccw, pmesh); - } - return ( CotangentValue::operator()(v0, v2, v1, ppmap)/2.0 ); - } - else - { - halfedge_descriptor he_cw = opposite( next(he, pmesh) , pmesh ); - vertex_descriptor v2 = source(he_cw, pmesh); - halfedge_descriptor he_ccw = prev( opposite(he, pmesh) , pmesh ); - vertex_descriptor v3 = source(he_ccw, pmesh); - - return ( CotangentValue::operator()(v0, v2, v1, ppmap)/2.0 + - CotangentValue::operator()(v0, v3, v1, ppmap)/2.0 ); - } - } -}; - -template::type - , class CotangentValue - = Cotangent_value_minimum_zero > -class Cotangent_weight : CotangentValue -{ - Cotangent_weight() - {} - -public: - Cotangent_weight(PolygonMesh& pmesh_, VertexPointMap vpmap_) - : CotangentValue(pmesh_, vpmap_) - {} - - Cotangent_weight(PolygonMesh& pmesh_) - : CotangentValue(pmesh_, get(CGAL::vertex_point, pmesh_)) - {} - - PolygonMesh& pmesh() - { - return CotangentValue::pmesh(); - } - - VertexPointMap& ppmap() - { - return CotangentValue::ppmap(); - } - - typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - - typedef typename boost::property_map::type Point_property_map; - typedef typename boost::property_traits::value_type Point; - typedef typename Kernel_traits::Kernel::Vector_3 Vector; - - // Returns the cotangent weight of specified halfedge_descriptor - // Edge orientation is trivial - double operator()(halfedge_descriptor he) - { - vertex_descriptor v0 = target(he, pmesh()); - vertex_descriptor v1 = source(he, pmesh()); - // Only one triangle for border edges - if (is_border_edge(he, pmesh())) - { - - halfedge_descriptor he_cw = opposite( next(he, pmesh()) , pmesh() ); - vertex_descriptor v2 = source(he_cw, pmesh()); - if (is_border_edge(he_cw, pmesh()) ) - { - halfedge_descriptor he_ccw = prev( opposite(he, pmesh()) , pmesh() ); - v2 = source(he_ccw, pmesh()); - } - return ( CotangentValue::operator()(v0, v2, v1)/2.0 ); - } - else - { - halfedge_descriptor he_cw = opposite( next(he, pmesh()) , pmesh() ); - vertex_descriptor v2 = source(he_cw, pmesh()); - halfedge_descriptor he_ccw = prev( opposite(he, pmesh()) , pmesh() ); - vertex_descriptor v3 = source(he_ccw, pmesh()); - - return ( CotangentValue::operator()(v0, v2, v1)/2.0 + CotangentValue::operator()(v0, v3, v1)/2.0 ); - } - } -}; - -// Single cotangent from -[Chao10] Simple Geometric Model for Elastic Deformation -template > -struct Single_cotangent_weight_impl : CotangentValue -{ - typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - - // Returns the cotangent of the opposite angle of the edge - // 0 for border edges (which does not have an opposite angle) - template - double operator()(halfedge_descriptor he, PolygonMesh& pmesh, const VertexPointMap& ppmap) - { - if(is_border(he, pmesh)) { return 0.0;} - - vertex_descriptor v0 = target(he, pmesh); - vertex_descriptor v1 = source(he, pmesh); - - vertex_descriptor v_op = target(next(he, pmesh), pmesh); - return CotangentValue::operator()(v0, v_op, v1, ppmap); - } -}; - -template::type - , class CotangentValue = Cotangent_value_Meyer > -class Single_cotangent_weight : CotangentValue -{ - Single_cotangent_weight() - {} -public: - Single_cotangent_weight(PolygonMesh& pmesh_, VertexPointMap vpmap_) - : CotangentValue(pmesh_, vpmap_) - {} - - PolygonMesh& pmesh() - { - return CotangentValue::pmesh(); - } - - VertexPointMap& ppmap() - { - return CotangentValue::ppmap(); - } - - typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - - typedef typename boost::property_map::type Point_property_map; - typedef typename boost::property_traits::value_type Point; - typedef typename Kernel_traits::Kernel::Vector_3 Vector; - - // Returns the cotangent of the opposite angle of the edge - // 0 for border edges (which does not have an opposite angle) - double operator()(halfedge_descriptor he) - { - if(is_border(he, pmesh())) { return 0.0;} - - vertex_descriptor v0 = target(he, pmesh()); - vertex_descriptor v1 = source(he, pmesh()); - - vertex_descriptor v_op = target(next(he, pmesh()), pmesh()); - return CotangentValue::operator()(v0, v_op, v1); - } -}; - - -template::type - , class CotangentValue = Cotangent_value_Meyer -> -class Cotangent_weight_with_triangle_area : CotangentValue -{ - typedef PolygonMesh PM; - typedef VertexPointMap VPMap; - typedef typename boost::property_traits::value_type Point; - - typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - - Cotangent_weight_with_triangle_area() - {} -public: - Cotangent_weight_with_triangle_area(PolygonMesh& pmesh_, VertexPointMap vpmap_) - : CotangentValue(pmesh_, vpmap_) - {} - - PolygonMesh& pmesh() - { - return CotangentValue::pmesh(); - } - - VertexPointMap& ppmap() - { - return CotangentValue::ppmap(); - } - - double operator()(halfedge_descriptor he) - { - vertex_descriptor v0 = target(he, pmesh()); - vertex_descriptor v1 = source(he, pmesh()); - - // Only one triangle for border edges - if (is_border_edge(he, pmesh())) - { - halfedge_descriptor he_cw = opposite( next(he, pmesh()) , pmesh() ); - vertex_descriptor v2 = source(he_cw, pmesh()); - if (is_border_edge(he_cw, pmesh()) ) - { - halfedge_descriptor he_ccw = prev( opposite(he, pmesh()) , pmesh() ); - v2 = source(he_ccw, pmesh()); - } - - const Point& v0_p = get(ppmap(), v0); - const Point& v1_p = get(ppmap(), v1); - const Point& v2_p = get(ppmap(), v2); - double area_t = to_double(CGAL::sqrt(squared_area(v0_p, v1_p, v2_p))); - - return ( CotangentValue::operator()(v0, v2, v1) / area_t ); - } - else - { - halfedge_descriptor he_cw = opposite( next(he, pmesh()) , pmesh() ); - vertex_descriptor v2 = source(he_cw, pmesh()); - halfedge_descriptor he_ccw = prev( opposite(he, pmesh()) , pmesh() ); - vertex_descriptor v3 = source(he_ccw, pmesh()); - - const Point& v0_p = get(ppmap(), v0); - const Point& v1_p = get(ppmap(), v1); - const Point& v2_p = get(ppmap(), v2); - const Point& v3_p = get(ppmap(), v3); - double area_t1 = to_double(CGAL::sqrt(squared_area(v0_p, v1_p, v2_p))); - double area_t2 = to_double(CGAL::sqrt(squared_area(v0_p, v1_p, v3_p))); - - return ( CotangentValue::operator()(v0, v2, v1) / area_t1 - + CotangentValue::operator()(v0, v3, v1) / area_t2); - } - - return 0.; - } -}; - -// Mean value calculator described in -[Floater04] Mean Value Coordinates- -template::type> -class Mean_value_weight -{ - //Mean_value_weight() - //{} - - PolygonMesh& pmesh_; - VertexPointMap vpmap_; - -public: - Mean_value_weight(PolygonMesh& pmesh_, VertexPointMap vpmap) - : pmesh_(pmesh_), vpmap_(vpmap) - {} - - PolygonMesh& pmesh() - { - return pmesh_; - } - - typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - - typedef VertexPointMap Point_property_map; - typedef typename boost::property_traits::value_type Point; - typedef typename Kernel_traits::Kernel::Vector_3 Vector; - - // Returns the mean-value coordinate of specified halfedge_descriptor - // Returns different value for different edge orientation (which is a normal behaivour according to formula) - double operator()(halfedge_descriptor he) - { - vertex_descriptor v0 = target(he, pmesh()); - vertex_descriptor v1 = source(he, pmesh()); - Vector vec = get(vpmap_, v0) - get(vpmap_, v1); - double norm = CGAL::sqrt( vec.squared_length() ); - - // Only one triangle for border edges - if ( is_border_edge(he, pmesh()) ) - { - halfedge_descriptor he_cw = opposite( next(he, pmesh()) , pmesh() ); - vertex_descriptor v2 = source(he_cw, pmesh()); - if ( is_border_edge(he_cw, pmesh()) ) - { - halfedge_descriptor he_ccw = prev( opposite(he, pmesh()) , pmesh() ); - v2 = source(he_ccw, pmesh()); - } - - return ( half_tan_value_2(v1, v0, v2)/norm); - } - else - { - halfedge_descriptor he_cw = opposite( next(he, pmesh()) , pmesh() ); - vertex_descriptor v2 = source(he_cw, pmesh()); - halfedge_descriptor he_ccw = prev( opposite(he, pmesh()) , pmesh() ); - vertex_descriptor v3 = source(he_ccw, pmesh()); - - return ( half_tan_value_2(v1, v0, v2)/norm + half_tan_value_2(v1, v0, v3)/norm); - } - } - -private: - // Returns the tangent value of half angle v0_v1_v2/2 - double half_tan_value(vertex_descriptor v0, vertex_descriptor v1, vertex_descriptor v2) - { - Vector vec0 = get(vpmap_, v1) - get(vpmap_, v2); - Vector vec1 = get(vpmap_, v2) - get(vpmap_, v0); - Vector vec2 = get(vpmap_, v0) - get(vpmap_, v1); - double e0_square = vec0.squared_length(); - double e1_square = vec1.squared_length(); - double e2_square = vec2.squared_length(); - double e0 = CGAL::sqrt(e0_square); - double e2 = CGAL::sqrt(e2_square); - double cos_angle = ( e0_square + e2_square - e1_square ) / 2.0 / e0 / e2; - cos_angle = (std::max)(-1.0, (std::min)(1.0, cos_angle)); // clamp into [-1, 1] - double angle = acos(cos_angle); - - return ( tan(angle/2.0) ); - } - - // My deviation built on Meyer_02 - double half_tan_value_2(vertex_descriptor v0, vertex_descriptor v1, vertex_descriptor v2) - { - Vector a = get(vpmap_, v0) - get(vpmap_, v1); - Vector b = get(vpmap_, v2) - get(vpmap_, v1); - double dot_ab = a[0]*b[0] + a[1]*b[1] + a[2]*b[2]; - double dot_aa = a.squared_length(); - double dot_bb = b.squared_length(); - double dot_aa_bb = dot_aa * dot_bb; - - double cos_rep = dot_ab; - double sin_rep = CGAL::sqrt(dot_aa_bb - dot_ab * dot_ab); - double normalizer = CGAL::sqrt(dot_aa_bb); // |a|*|b| - - return (normalizer - cos_rep) / sin_rep; // formula from [Floater04] page 4 - // tan(Q/2) = (1 - cos(Q)) / sin(Q) - } -}; - -template< class PolygonMesh, - class PrimaryWeight = Cotangent_weight, - class SecondaryWeight = Mean_value_weight > -class Hybrid_weight : public PrimaryWeight, SecondaryWeight -{ - PrimaryWeight primary; - SecondaryWeight secondary; - - Hybrid_weight() - {} - -public: - Hybrid_weight(PolygonMesh& pmesh_) - : primary(pmesh_), secondary(pmesh_) - {} - - PolygonMesh& pmesh() - { - return primary.pmesh(); - } - - typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - - double operator()(halfedge_descriptor he) - { - double weight = primary(he); - //if(weight < 0) { std::cout << "Negative weight" << std::endl; } - return (weight >= 0) ? weight : secondary(he); - } -}; - -// Trivial uniform weights (created for test purposes) -template -class Uniform_weight -{ -public: - typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - - double operator()(halfedge_descriptor /*e*/) - { return 1.0; } -}; - -//////////////////////////////////////////////////////////////////////////// -// FAIRING // -template -class Scale_dependent_weight_fairing -{ - PolygonMesh& pmesh_; -public: - Scale_dependent_weight_fairing(PolygonMesh& pmesh_) - : pmesh_(pmesh_) - {} - - PolygonMesh& pmesh() - { - return pmesh_; - } - - typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - - typedef typename boost::property_map::type Point_property_map; - typedef typename boost::property_traits::value_type Point; - typedef typename Kernel_traits::Kernel::Vector_3 Vector; - - double w_i(vertex_descriptor /*v_i*/) { return 1.0; } - - double w_ij(halfedge_descriptor he) - { - Vector v = target(he, pmesh())->point() - source(he, pmesh())->point(); - double divider = CGAL::sqrt(v.squared_length()); - if(divider == 0.0) { - CGAL_warning_msg(false, "Scale dependent weight - zero length edge."); - return (std::numeric_limits::max)(); - } - return 1.0 / divider; - } -}; - -template::type -> -class Cotangent_weight_with_voronoi_area_fairing -{ - typedef PolygonMesh PM; - typedef VertexPointMap VPMap; - Voronoi_area voronoi_functor; - Cotangent_weight > cotangent_functor; - -public: - Cotangent_weight_with_voronoi_area_fairing(PM& pmesh_) - : voronoi_functor(pmesh_, get(CGAL::vertex_point, pmesh_)) - , cotangent_functor(pmesh_, get(CGAL::vertex_point, pmesh_)) - {} - - Cotangent_weight_with_voronoi_area_fairing(PM& pmesh_, VPMap vpmap_) - : voronoi_functor(pmesh_, vpmap_) - , cotangent_functor(pmesh_, vpmap_) - {} - - PM& pmesh() - { - return voronoi_functor.pmesh(); - } - - typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - - double w_i(vertex_descriptor v_i) - { - return 0.5 / voronoi_functor(v_i); - } - - double w_ij(halfedge_descriptor he) { - - return cotangent_functor(he) * 2.0; - } -}; - -// Cotangent_value_Meyer has been changed to the version: -// Cotangent_value_Meyer_secure to avoid imprecisions from -// the issue #4706 - https://github.com/CGAL/cgal/issues/4706. -template< -class PolygonMesh, class VertexPointMap = typename boost::property_map::type> -class Cotangent_weight_with_voronoi_area_fairing_secure { - - typedef PolygonMesh PM; - typedef VertexPointMap VPMap; - Voronoi_area voronoi_functor; - Cotangent_weight > cotangent_functor; - -public: - Cotangent_weight_with_voronoi_area_fairing_secure(PM& pmesh_) : - voronoi_functor(pmesh_, get(CGAL::vertex_point, pmesh_)), - cotangent_functor(pmesh_, get(CGAL::vertex_point, pmesh_)) - { } - - Cotangent_weight_with_voronoi_area_fairing_secure(PM& pmesh_, VPMap vpmap_) : - voronoi_functor(pmesh_, vpmap_), - cotangent_functor(pmesh_, vpmap_) - { } - - PM& pmesh() { - return voronoi_functor.pmesh(); - } - - typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - - double w_i(vertex_descriptor v_i) { - return 0.5 / voronoi_functor(v_i); - } - - double w_ij(halfedge_descriptor he) { - return cotangent_functor(he) * 2.0; - } -}; - -template -class Uniform_weight_fairing -{ -public: - typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - - Uniform_weight_fairing(PolygonMesh&) - {} - - double w_ij(halfedge_descriptor /*e*/) { return 1.0; } - - double w_i(vertex_descriptor /*v_i*/) { return 1.0; } -}; -//////////////////////////////////////////////////////////////////////////// - -}//namespace internal - - -}//namespace CGAL -/// @endcond -#endif //CGAL_PMP_WEIGHTS_H diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/border.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/border.h index 609352d5fac..6f8c0cb9081 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/border.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/border.h @@ -13,7 +13,7 @@ #ifndef CGAL_POLYGON_MESH_PROCESSING_GET_BORDER_H #define CGAL_POLYGON_MESH_PROCESSING_GET_BORDER_H -#include +#include #include #include diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/detect_features.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/detect_features.h index d4a32b81183..e3109944ec1 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/detect_features.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/detect_features.h @@ -16,15 +16,13 @@ #include -#include - #include #include #include #include #include -#include +#include namespace CGAL { namespace Polygon_mesh_processing { @@ -45,29 +43,44 @@ generate_patch_id(std::pair, int i) return std::pair(i, 0); } -template +template bool -is_sharp(PolygonMesh& polygonMesh, - const typename boost::graph_traits::halfedge_descriptor& he, - const typename GT::FT& cos_angle) +is_sharp(const typename boost::graph_traits::halfedge_descriptor h, + const PolygonMesh& pmesh, + const VPM vpm, + const GT gt, + const typename GT::Sign cos_sign, + const typename GT::FT sq_cos_angle) { - typedef typename boost::graph_traits::face_descriptor face_descriptor; - if(is_border(edge(he,polygonMesh),polygonMesh)){ + typedef typename GT::FT FT; + typedef typename GT::Vector_3 Vector_3; + + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + + if(is_border_edge(h, pmesh)) return false; - } - face_descriptor f1 = face(he,polygonMesh); - face_descriptor f2 = face(opposite(he,polygonMesh),polygonMesh); - const typename GT::Vector_3& n1 = Polygon_mesh_processing::compute_face_normal(f1,polygonMesh); - const typename GT::Vector_3& n2 = Polygon_mesh_processing::compute_face_normal(f2,polygonMesh); + typename GT::Construct_vector_3 vector = gt.construct_vector_3_object(); + typename GT::Construct_cross_product_vector_3 cross = gt.construct_cross_product_vector_3_object(); + typename GT::Compute_squared_length_3 sq_length = gt.compute_squared_length_3_object(); - if ( n1 * n2 <= cos_angle ) - return true; + halfedge_descriptor opp_h = opposite(h, pmesh); + + const Vector_3 vc = vector(get(vpm, source(h, pmesh)), get(vpm, target(h, pmesh))); + const Vector_3 v1 = vector(get(vpm, source(h, pmesh)), get(vpm, target(next(h, pmesh), pmesh))); + const Vector_3 v2 = vector(get(vpm, target(next(opp_h, pmesh), pmesh)), get(vpm, target(opp_h, pmesh))); + + const Vector_3 n1 = cross(vc, v1); + const Vector_3 n2 = cross(vc, v2); + const FT sp = n1 * n2; + + // n1.n2 <= cos() without computing the norms of the vectors + if(cos_sign == NEGATIVE) + return (is_negative(sp) && (square(sp) >= sq_cos_angle * sq_length(n1) * sq_length(n2))); else - return false; + return (is_negative(sp) || (square(sp) <= sq_cos_angle * sq_length(n1) * sq_length(n2))); } - //wrapper for patchid map. template::value_type> @@ -133,7 +146,7 @@ void put(PatchIdMapWrapper >& map, Handle_type h template typename boost::graph_traits::faces_size_type -detect_surface_patches(PolygonMesh& p, +detect_surface_patches(const PolygonMesh& p, PatchIdMap patch_id_map, EdgeIsFeatureMap eif, const NamedParameters& np) @@ -152,7 +165,7 @@ detect_surface_patches(PolygonMesh& p, template typename boost::graph_traits::faces_size_type -detect_surface_patches(PolygonMesh& p, +detect_surface_patches(const PolygonMesh& p, PatchIdMap patch_id_map, EdgeIsFeatureMap eif) { @@ -160,69 +173,64 @@ detect_surface_patches(PolygonMesh& p, } -template - void sharp_call(PolygonMesh& pmesh, - FT angle_in_deg, - EIFMap edge_is_feature_map, - VNFEMap vnfe) +template +void sharp_call(const FT angle_in_deg, + const PolygonMesh& pmesh, + const VPM vpm, + const GT gt, + EIFMap edge_is_feature_map, + VNFEMap vnfe) { // Initialize vertices - for(typename boost::graph_traits::vertex_descriptor vd : - vertices(pmesh)) - { + for(typename boost::graph_traits::vertex_descriptor vd : vertices(pmesh)) put(vnfe, vd, 0); - } - FT cos_angle ( std::cos(CGAL::to_double(angle_in_deg) * CGAL_PI / 180.) ); + + const FT cos_angle = std::cos(CGAL::to_double(angle_in_deg) * CGAL_PI / 180.); + const FT sq_cos_angle = square(cos_angle); // Detect sharp edges for(typename boost::graph_traits::edge_descriptor ed : edges(pmesh)) { - typename boost::graph_traits::halfedge_descriptor he = halfedge(ed,pmesh); - if(is_border_edge(he,pmesh) - || angle_in_deg == FT() - || (angle_in_deg != FT(180) && internal::is_sharp(pmesh,he,cos_angle)) - ) + typename boost::graph_traits::halfedge_descriptor he = halfedge(ed, pmesh); + if(is_border_edge(he, pmesh) || + angle_in_deg == FT() || + (angle_in_deg != FT(180) && internal::is_sharp(he, pmesh, vpm, gt, CGAL::sign(cos_angle), sq_cos_angle))) { put(edge_is_feature_map, edge(he, pmesh), true); - put(vnfe, target(he,pmesh), get(vnfe, target(he,pmesh))+1); - put(vnfe, source(he,pmesh), get(vnfe, source(he,pmesh))+1); + put(vnfe, target(he, pmesh), get(vnfe, target(he, pmesh))+1); + put(vnfe, source(he, pmesh), get(vnfe, source(he, pmesh))+1); } } } - -template - void sharp_call(PolygonMesh& pmesh, - FT& angle_in_deg, - EIFMap edge_is_feature_map, - const internal_np::Param_not_found&) +template +void sharp_call(const FT angle_in_deg, + const PolygonMesh& pmesh, + const VPM vpm, + const GT gt, + EIFMap edge_is_feature_map, + const internal_np::Param_not_found&) { typedef typename boost::graph_traits::edge_descriptor edge_descriptor; typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - FT cos_angle ( std::cos(CGAL::to_double(angle_in_deg) * CGAL_PI / 180.) ); + const FT cos_angle = std::cos(CGAL::to_double(angle_in_deg) * CGAL_PI / 180.); + const FT sq_cos_angle = square(cos_angle); // Detect sharp edges for(edge_descriptor ed : edges(pmesh)) { - halfedge_descriptor he = halfedge(ed,pmesh); - if(is_border_edge(he,pmesh) - || angle_in_deg == FT() - || (angle_in_deg != FT(180) && internal::is_sharp(pmesh,he,cos_angle)) - ) + halfedge_descriptor he = halfedge(ed, pmesh); + if(is_border_edge(he, pmesh) || + angle_in_deg == FT() || + (angle_in_deg != FT(180) && internal::is_sharp(he, pmesh, vpm, gt, CGAL::sign(cos_angle), sq_cos_angle))) { put(edge_is_feature_map, edge(he, pmesh), true); } } } -} //end internal + +} // namespace internal /*! * \ingroup PMP_detect_features_grp @@ -270,24 +278,30 @@ template #endif -void detect_sharp_edges(PolygonMesh& pmesh, +void detect_sharp_edges(const PolygonMesh& pmesh, #ifdef DOXYGEN_RUNNING - FT angle_in_deg, + FT angle_in_deg, #else - typename GetGeomTraits::type::FT angle_in_deg, + typename GetGeomTraits::type::FT angle_in_deg, #endif - EdgeIsFeatureMap edge_is_feature_map, - const NamedParameters& np) + EdgeIsFeatureMap edge_is_feature_map, + const NamedParameters& np) { - //extract types from NPs + using parameters::choose_parameter; + using parameters::get_parameter; + + // extract types from NPs typedef typename GetGeomTraits::type GT; - typedef typename GT::FT FT; + GT gt = choose_parameter(get_parameter(np, internal_np::geom_traits)); - internal::sharp_call(pmesh, angle_in_deg, edge_is_feature_map, - parameters::get_parameter(np, internal_np::vertex_feature_degree)); + typedef typename GetVertexPointMap::const_type VPM; + VPM vpm = choose_parameter(get_parameter(np, internal_np::vertex_point), + get_const_property_map(boost::vertex_point, pmesh)); + + internal::sharp_call(angle_in_deg, pmesh, vpm, gt, edge_is_feature_map, + get_parameter(np, internal_np::vertex_feature_degree)); } - /*! * \ingroup PMP_detect_features_grp * @@ -315,7 +329,7 @@ void detect_sharp_edges(PolygonMesh& pmesh, template -void detect_vertex_incident_patches(PolygonMesh& pmesh, +void detect_vertex_incident_patches(const PolygonMesh& pmesh, const PatchIdMap patch_id_map, VertexIncidentPatchesMap vertex_incident_patches_map, const EdgeIsFeatureMap edge_is_feature_map) @@ -326,19 +340,18 @@ void detect_vertex_incident_patches(PolygonMesh& pmesh, for(vertex_descriptor vit :vertices(pmesh)) { // Look only at feature vertices - if( ! get(edge_is_feature_map, edge(halfedge(vit, pmesh), pmesh) )) - { continue; } + if(!get(edge_is_feature_map, edge(halfedge(vit, pmesh), pmesh))) + continue; // Loop on incident facets of vit - typename VertexIncidentPatchesMap::value_type& - id_set = vertex_incident_patches_map[vit]; - for(halfedge_descriptor he : halfedges_around_target(vit,pmesh)) + typename VertexIncidentPatchesMap::value_type& id_set = vertex_incident_patches_map[vit]; + for(halfedge_descriptor he : halfedges_around_target(vit, pmesh)) { - if( ! is_border(he,pmesh) ) + if(!is_border(he, pmesh)) { id_set.insert(get(patch_id_map, face(he, pmesh))); } - else if( ! is_border(opposite(he,pmesh),pmesh) ) + else if(!is_border(opposite(he, pmesh), pmesh)) { id_set.insert(get(patch_id_map, face(opposite(he, pmesh), pmesh))); } @@ -346,26 +359,22 @@ void detect_vertex_incident_patches(PolygonMesh& pmesh, } } +namespace internal { -namespace internal +template +void vip_call(const PolygonMesh& mesh, PIDMap pid, VIPMap vip, EIFMap eif) { - template - void vip_call(PolygonMesh& mesh, PIDMap pid, VIPMap vip, EIFMap eif ) - { - CGAL::Polygon_mesh_processing::detect_vertex_incident_patches(mesh, pid, vip, eif); - } + CGAL::Polygon_mesh_processing::detect_vertex_incident_patches(mesh, pid, vip, eif); +} + +template +void vip_call(const PolygonMesh&, PIDMap, const internal_np::Param_not_found&, EIFMap) +{ + //do nothing when the parameter is not given +} + +} // namespace internal - template - void vip_call(PolygonMesh&, PIDMap, const internal_np::Param_not_found&, EIFMap) - { - //do nothing when the parameter is not given - } -}//end internal /*! * \ingroup PMP_detect_features_grp * @@ -446,30 +455,30 @@ template #endif typename boost::graph_traits::faces_size_type -sharp_edges_segmentation(PolygonMesh& pmesh, +sharp_edges_segmentation(const PolygonMesh& pmesh, #ifdef DOXYGEN_RUNNING - FT angle_in_deg, + FT angle_in_deg, #else - typename GetGeomTraits::type::FT angle_in_deg, + typename GetGeomTraits::type::FT angle_in_deg, #endif - EdgeIsFeatureMap edge_is_feature_map, - PatchIdMap patch_id_map, - const NamedParameters& np) + EdgeIsFeatureMap edge_is_feature_map, + PatchIdMap patch_id_map, + const NamedParameters& np) { - detect_sharp_edges(pmesh, angle_in_deg, edge_is_feature_map, np); + detect_sharp_edges(pmesh, angle_in_deg, edge_is_feature_map, np); - typename boost::graph_traits::faces_size_type result = - internal::detect_surface_patches(pmesh, patch_id_map, edge_is_feature_map, np); + typename boost::graph_traits::faces_size_type result = + internal::detect_surface_patches(pmesh, patch_id_map, edge_is_feature_map, np); - internal::vip_call(pmesh, patch_id_map, - parameters::get_parameter(np, internal_np::vertex_incident_patches), edge_is_feature_map); + internal::vip_call(pmesh, patch_id_map, + parameters::get_parameter(np, internal_np::vertex_incident_patches), edge_is_feature_map); - return result; + return result; } //Convenient overrides template -void detect_sharp_edges(PolygonMesh& p, +void detect_sharp_edges(const PolygonMesh& p, FT angle_in_deg, EdgeIsFeatureMap edge_is_feature_map) { @@ -480,18 +489,16 @@ void detect_sharp_edges(PolygonMesh& p, template typename boost::graph_traits::faces_size_type -sharp_edges_segmentation(PolygonMesh& p, +sharp_edges_segmentation(const PolygonMesh& p, FT angle_in_deg, EdgeIsFeatureMap edge_is_feature_map, PatchIdMap patch_id_map) { return sharp_edges_segmentation(p, angle_in_deg, edge_is_feature_map, patch_id_map, - parameters::all_default()); + parameters::all_default()); } } // end namespace PMP } // end namespace CGAL -#include - #endif // CGAL_POLYGON_MESH_PROCESSING_DETECT_FEATURES_IN_POLYGON_MESH_H diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/fair.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/fair.h index 727e007995a..b6e9d00b9d0 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/fair.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/fair.h @@ -20,6 +20,7 @@ #include #include #include +#include #if defined(CGAL_EIGEN3_ENABLED) #include // for sparse linear system solver @@ -162,15 +163,14 @@ namespace internal { // Cotangent_weight_with_voronoi_area_fairing has been changed to the version: // Cotangent_weight_with_voronoi_area_fairing_secure to avoid imprecisions from // the issue #4706 - https://github.com/CGAL/cgal/issues/4706. - typedef CGAL::internal::Cotangent_weight_with_voronoi_area_fairing_secure - Default_Weight_calculator; + typedef CGAL::Weights::Secure_cotangent_weight_with_voronoi_area Default_weight_calculator; VPMap vpmap_ = choose_parameter(get_parameter(np, internal_np::vertex_point), get_property_map(vertex_point, tmesh)); return internal::fair(tmesh, vertices, choose_parameter(get_parameter(np, internal_np::sparse_linear_solver)), - choose_parameter(get_parameter(np, internal_np::weight_calculator), Default_Weight_calculator(tmesh, vpmap_)), + choose_parameter(get_parameter(np, internal_np::weight_calculator), Default_weight_calculator(tmesh, vpmap_)), choose_parameter(get_parameter(np, internal_np::fairing_continuity), 1), vpmap_); } diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Hole_filling/Triangulate_hole_polyline.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Hole_filling/Triangulate_hole_polyline.h index a28b3e2c826..5eab37058cd 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Hole_filling/Triangulate_hole_polyline.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Hole_filling/Triangulate_hole_polyline.h @@ -30,6 +30,7 @@ #include #include #include +#include #endif #include diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/remesh_impl.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/remesh_impl.h index f3098e2422a..fa70904f325 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/remesh_impl.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/remesh_impl.h @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include #include @@ -1492,6 +1492,8 @@ private: || GeomTraits().collinear_3_object()(t, p, q)) continue; + typename GeomTraits::Construct_cross_product_vector_3 cross_product + = GeomTraits().construct_cross_product_vector_3_object(); #ifdef CGAL_PMP_REMESHING_DEBUG typename GeomTraits::Construct_normal_3 normal = GeomTraits().construct_normal_3_object(); @@ -1499,13 +1501,13 @@ private: Vector_3 normal_after_collapse = normal(t, p, q); CGAL::Sign s1 = CGAL::sign(normal_before_collapse * normal_after_collapse); - CGAL::Sign s2 = CGAL::sign(CGAL::cross_product(Vector_3(s, p), Vector_3(s, q)) - * CGAL::cross_product(Vector_3(t, p), Vector_3(t, q))); + CGAL::Sign s2 = CGAL::sign(cross_product(Vector_3(s, p), Vector_3(s, q)) + * cross_product(Vector_3(t, p), Vector_3(t, q))); CGAL_assertion(s1 == s2); #endif - if(CGAL::sign(CGAL::cross_product(Vector_3(s, p), Vector_3(s, q)) - * CGAL::cross_product(Vector_3(t, p), Vector_3(t, q))) + if(CGAL::sign(cross_product(Vector_3(s, p), Vector_3(s, q)) + * cross_product(Vector_3(t, p), Vector_3(t, q))) != CGAL::POSITIVE) return true; } diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Smoothing/curvature_flow_impl.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Smoothing/curvature_flow_impl.h index 0c9e2d9fa0e..fa600557af3 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Smoothing/curvature_flow_impl.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Smoothing/curvature_flow_impl.h @@ -17,10 +17,9 @@ #include #include -#include #include #include - +#include #include #include @@ -41,45 +40,6 @@ namespace CGAL { namespace Polygon_mesh_processing { namespace internal { -// Empirically, _Meyer seems to produce the best results from the various weights available in Weights.h -template > -struct Edge_cotangent_weight - : public CotangentValue -{ - typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - - Edge_cotangent_weight(TriangleMesh& pmesh_, VertexPointMap vpmap_) : CotangentValue(pmesh_, vpmap_) {} - - TriangleMesh& pmesh() { return CotangentValue::pmesh(); } - - double operator()(halfedge_descriptor he) - { - if(is_border_edge(he, pmesh())) - { - halfedge_descriptor h1 = next(he, pmesh()); - vertex_descriptor vs = source(he, pmesh()); - vertex_descriptor vt = target(he, pmesh()); - vertex_descriptor v1 = target(h1, pmesh()); - - return CotangentValue::operator()(vs, v1, vt); - } - else - { - halfedge_descriptor h1 = next(he, pmesh()); - halfedge_descriptor h2 = prev(opposite(he, pmesh()), pmesh()); - vertex_descriptor vs = source(he, pmesh()); - vertex_descriptor vt = target(he, pmesh()); - vertex_descriptor v1 = target(h1, pmesh()); - vertex_descriptor v2 = source(h2, pmesh()); - - return CotangentValue::operator()(vs, v1, vt) + CotangentValue::operator()(vs, v2, vt); - } - } -}; - template constrained_flags_; const GeomTraits& traits_; - Edge_cotangent_weight weight_calculator_; + const CGAL::Weights::Edge_cotangent_weight weight_calculator_; }; } // internal 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 5352ca1a8dd..0c3fc465392 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 @@ -37,7 +37,8 @@ void vertices_as_halfedges(const VertexRange& vertex_range, *out++ = halfedge(v, pmesh); } -// Assigns at each vertex the 'tolerance' value as tolerance, but bounded by a percentage of the length of its shortest incident edge +// Assigns at each vertex the 'tolerance' value as tolerance, +// but bounded by a percentage of the length of its shortest incident edge template = sq_va_l * sq_vb_l * sq_cos); } +template +struct Snapping_default_visitor +{ + bool m_stop = false; + + bool stop() { return m_stop; } + + // ------------------------------- Preprocessing ------------------------------ + + // Called when starting preprocessing phase of the mesh. + void start_mesh_preprocessing() { } + + // Called at the end of the preprocessing phase of the mesh. + void end_mesh_preprocessing() { } + + // ------------------------------- Vertex - Vertex ------------------------------- + + // Called when starting snapping a range of vertices of `A` and a range of vertices of `B`. + void start_vertex_vertex_phase() { } + + // Called when finished snapping a range of vertices of `A` and a range of vertices of `B`. + void end_vertex_vertex_phase() { } + + // Called when trying to find `v`-`v_other` pair (with `v` in `A` and `v_other` in `B`) + // + // Available only if vertex-vertex pair detection is based on the kd-tree. + // Must be threadsafe if parallelism is used. + template + void on_vertex_vertex_inquiry(const Vertex /*v*/, const Mesh&) { } + + // Called when a match between two ranges of vertices is found. + // All vertices in `va` have the same position (and same for `vb`). + // + // Must be threadsafe if parallelism is used. + template + void on_vertex_vertex_match(const VertexContainer& /*va*/, const Mesh&, + const VertexContainer& /*vb*/, const Mesh&) { } + + // Called before proceeding with actual vertex-vertex snapping. + void start_vertex_vertex_snapping() { } + + // Called after proceeding with actual vertex-vertex snapping. + void end_vertex_vertex_snapping() { } + + // Called before two ranges of vertices are snapped together. + // All vertices in `va` have the same position (and same for `vb`). + template + void before_vertex_vertex_snap(const VertexContainer& /*va*/, const Mesh&, + const VertexContainer& /*vb*/, const Mesh&) { } + + // Called after two ranges of vertices have been snapped. + template + void after_vertex_vertex_snap(const VertexContainer& /*va*/, const Mesh&, + const VertexContainer& /*vb*/, const Mesh&) { } + + // ------------------------------- Vertex - Edge ------------------------------- + + // Called when starting snapping a range of vertices of A onto edges of B + void start_first_vertex_edge_phase() { } + + // Called when finished snapping a range of vertices of A onto edges of B + void end_first_vertex_edge_phase() { } + + // Called when starting snapping a range of vertices of B onto edges of A. + // Not called if A and B are the same mesh. + void start_second_vertex_edge_phase() { } + + // Called when starting snapping a range of vertices of B onto edges of A. + // Not called if A and B are the same mesh. + void end_second_vertex_edge_phase() { } + + // Called when trying to find `v`-`edge` pair + // + // Available only if vertex-vertex pair detection is based on the kd-tree. + // Must be threadsafe if parallelism is used. + template + void on_vertex_edge_inquiry(const Vertex /*v*/, const Mesh& /*tm*/) { } + + // Called when a match between a vertex and an edge is found. + // + // Must be threadsafe if parallelism is used. + template + void on_vertex_edge_match(const Vertex, const Mesh&, const Edge, const Mesh&, const Point&) { } + + // Called before proceeding with actual snapping. + void start_vertex_edge_snapping() { } + + // Called after proceeding with actual snapping. + void end_vertex_edge_snapping() { } + + // Called before a new vertex is created. + template + void before_vertex_edge_snap(const Edge, const Mesh&, const Point&) { } + + // Called after a new vertex has been created, splitting an edge. + template + void after_vertex_edge_snap(const Vertex /*new_vertex*/, const Mesh&) { } + + // ------------------------------- Two passes (segmentation or not) ------------------------------ + + // Called at the start of the snapping pass that is restricted to compatible patch (first pass). + void start_patch_snapping() { } + + // Called at the end of the snapping pass that is restricted to compatible patch (first pass). + void end_patch_snapping() { } + + // Called at the start of the second snapping pass, all elements are potentially compatible (second pass). + void start_global_snapping() { } + + // Called at the end of the second snapping pass, all elements are potentially compatible (second pass). + void end_global_snapping() { } +}; + } // namespace internal } // namespace Polygon_mesh_processing } // namespace CGAL diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Snapping/snap.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Snapping/snap.h index 3571ae48b52..490cc457b13 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Snapping/snap.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Snapping/snap.h @@ -92,6 +92,7 @@ void simplify_range(HalfedgeRange& halfedge_range, typedef typename GT::FT FT; typedef typename GetVertexPointMap::type VPM; + typedef typename boost::property_traits::value_type Point; typedef typename boost::property_traits::reference Point_ref; using parameters::get_parameter; @@ -125,10 +126,10 @@ void simplify_range(HalfedgeRange& halfedge_range, // @fixme what if the source vertex is not to be snapped? Tolerance cannot be obtained... // and where should the post-collapse vertex be since we can't move the source vertex... // --> simply don't collapse? - const FT min_tol = (std::min)(get(tolerance_map, vs), get(tolerance_map, vt)); - const FT max_tol = (std::max)(get(tolerance_map, vs), get(tolerance_map, vt)); + const FT tol_s = get(tolerance_map, vs), tol_t = get(tolerance_map, vt); + const FT max_tol = (std::max)(tol_s, tol_t); - if(gt.compare_squared_distance_3_object()(ps,pt,CGAL::square(max_tol))==SMALLER) + if(gt.compare_squared_distance_3_object()(ps,pt,CGAL::square(max_tol)) == SMALLER) { const halfedge_descriptor prev_h = prev(h, tm); const halfedge_descriptor next_h = next(h, tm); @@ -136,11 +137,23 @@ void simplify_range(HalfedgeRange& halfedge_range, // check that the border has at least 4 edges not to create degenerate volumes if(border_size(h, tm) >= 4) { - const FT h_sq_length = gt.compute_squared_distance_3_object()(ps, pt); - vertex_descriptor v = Euler::collapse_edge(edge(h, tm), tm); + const FT lambda = tol_s / (tol_s + tol_t); + const Point new_p = ps + lambda * (pt - ps); - put(vpm, v, gt.construct_midpoint_3_object()(ps, pt)); - put(tolerance_map, v, min_tol + 0.5 * CGAL::approximate_sqrt(h_sq_length)); + // If we're collapsing onto a vertex that is not allowed to move, keep it fixed + const FT min_tol = (std::min)(tol_s, tol_t); + FT new_tolerance = min_tol; + if(!is_zero(min_tol)) + { + if(tol_t > tol_s) // the new point is closer to ps than to pt + new_tolerance += CGAL::approximate_sqrt(CGAL::squared_distance(new_p, ps)); + else + new_tolerance += CGAL::approximate_sqrt(CGAL::squared_distance(new_p, pt)); + } + + vertex_descriptor v = Euler::collapse_edge(edge(h, tm), tm); + put(vpm, v, new_p); + put(tolerance_map, v, new_tolerance); if(get(range_halfedges, prev_h)) edges_to_test.insert(prev_h); @@ -453,7 +466,8 @@ template + typename VPMS, typename VPMT, typename GT, + typename Visitor> void find_splittable_edge(const VertexWithTolerance& vertex_with_tolerance, EdgeToSplitMap& edges_to_split, const AABBTree* aabb_tree_ptr, @@ -463,7 +477,8 @@ void find_splittable_edge(const VertexWithTolerance& vertex_with_tolerance, const TriangleMesh& tm_T, FacePatchMap_T face_patch_map_T, VPMT vpm_T, - const GT& gt) + const GT& gt, + Visitor& visitor) { typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; @@ -477,6 +492,9 @@ void find_splittable_edge(const VertexWithTolerance& vertex_with_tolerance, typedef internal::Projection_traits Projection_traits; + if(visitor.stop()) + throw CGAL::internal::Throw_at_output_exception(); + // by construction the whole range has the same position const halfedge_descriptor h = vertex_with_tolerance.first; const vertex_descriptor v = target(h, tm_S); @@ -488,6 +506,8 @@ void find_splittable_edge(const VertexWithTolerance& vertex_with_tolerance, std::cout << "--------------------------- Query: " << v << " (" << query << ")" << std::endl; #endif + visitor.on_vertex_edge_inquiry(v, tm_S); + Projection_traits traversal_traits(h, patch_id, sq_tolerance, tm_S, vpm_S, tm_T, face_patch_map_T, vpm_T, aabb_tree_ptr->traits()); aabb_tree_ptr->traversal(query, traversal_traits); @@ -522,7 +542,6 @@ void find_splittable_edge(const VertexWithTolerance& vertex_with_tolerance, if(!is_close_enough) return; - CGAL_assertion(get(vpm_T, source(closest_e, tm_T)) != query && get(vpm_T, target(closest_e, tm_T)) != query); @@ -534,43 +553,17 @@ void find_splittable_edge(const VertexWithTolerance& vertex_with_tolerance, // Using a map because we need to know if the same halfedge is split multiple times Edges_to_split_map_inserter()(edges_to_split, closest_h, vertex_with_tolerance.first, closest_p); + + visitor.on_vertex_edge_match(v, tm_S, closest_h, tm_T, closest_p); } #ifdef CGAL_LINKED_WITH_TBB template -struct Find_splittable_edge_for_parallel_for + typename VPMS, typename VPMT, typename GT, typename Visitor> +struct Parallel_find_splittable_edge { - Find_splittable_edge_for_parallel_for(const PointWithToleranceContainer& points_with_tolerance, - EdgeToSplitMap& edges_to_split, - const AABBTree* aabb_tree_ptr, - const TriangleMesh& tm_S, - const VertexPatchMap_S vertex_patch_map_S, - const VPMS vpm_S, - const TriangleMesh& tm_T, - const FacePatchMap_T face_patch_map_T, - const VPMT vpm_T, - const GT& gt) - : - m_points_with_tolerance(points_with_tolerance), - m_edges_to_split(edges_to_split), m_aabb_tree_ptr(aabb_tree_ptr), - m_tm_S(tm_S), m_vertex_patch_map_S(vertex_patch_map_S), m_vpm_S(vpm_S), - m_tm_T(tm_T), m_face_patch_map_T(face_patch_map_T), m_vpm_T(vpm_T), - m_gt(gt) - { } - - void operator()(const tbb::blocked_range& r) const - { - for(std::size_t i=r.begin(); i!=r.end(); ++i) - { - find_splittable_edge(m_points_with_tolerance[i], m_edges_to_split, m_aabb_tree_ptr, - m_tm_S, m_vertex_patch_map_S, m_vpm_S, - m_tm_T, m_face_patch_map_T, m_vpm_T, m_gt); - } - } - private: const PointWithToleranceContainer& m_points_with_tolerance; EdgeToSplitMap& m_edges_to_split; @@ -582,18 +575,51 @@ private: const FacePatchMap_T m_face_patch_map_T; const VPMT m_vpm_T; const GT& m_gt; + Visitor& m_visitor; + +public: + Parallel_find_splittable_edge(const PointWithToleranceContainer& points_with_tolerance, + EdgeToSplitMap& edges_to_split, + const AABBTree* aabb_tree_ptr, + const TriangleMesh& tm_S, + const VertexPatchMap_S vertex_patch_map_S, + const VPMS vpm_S, + const TriangleMesh& tm_T, + const FacePatchMap_T face_patch_map_T, + const VPMT vpm_T, + const GT& gt, + Visitor& visitor) + : + m_points_with_tolerance(points_with_tolerance), + m_edges_to_split(edges_to_split), m_aabb_tree_ptr(aabb_tree_ptr), + m_tm_S(tm_S), m_vertex_patch_map_S(vertex_patch_map_S), m_vpm_S(vpm_S), + m_tm_T(tm_T), m_face_patch_map_T(face_patch_map_T), m_vpm_T(vpm_T), + m_gt(gt), m_visitor(visitor) + { } + + void operator()(const tbb::blocked_range& r) const + { + for(std::size_t i=r.begin(); i!=r.end(); ++i) + { + find_splittable_edge(m_points_with_tolerance[i], m_edges_to_split, m_aabb_tree_ptr, + m_tm_S, m_vertex_patch_map_S, m_vpm_S, + m_tm_T, m_face_patch_map_T, m_vpm_T, m_gt, m_visitor); + } + } }; #endif template + typename TriangleMesh, + typename VPMS, typename VPMT, typename GeomTraits, + typename Visitor> std::size_t split_edges(EdgesToSplitContainer& edges_to_split, TriangleMesh& tm_S, VPMS vpm_S, TriangleMesh& tm_T, VPMT vpm_T, const GeomTraits& gt, + Visitor& visitor, const bool is_source_mesh_fixed) // when snapping is B --> A and the mesh B is fixed { #ifdef CGAL_PMP_SNAP_DEBUG @@ -611,10 +637,14 @@ std::size_t split_edges(EdgesToSplitContainer& edges_to_split, typedef std::vector Vertices_with_new_position; typedef std::pair Edge_and_splitters; - std::size_t snapped_n = 0; - +#ifdef CGAL_PMP_SNAPPING_PRINT_RUNTIME CGAL::Real_timer timer; timer.start(); +#endif + + visitor.start_vertex_edge_snapping(); + + std::size_t snapped_n = 0; for(Edge_and_splitters& es : edges_to_split) { @@ -642,6 +672,9 @@ std::size_t split_edges(EdgesToSplitContainer& edges_to_split, Point previous_split_position = get(vpm_S, *(vertices(tm_S).begin())); // dummy value to avoid "used uninitialized" warning for(const Vertex_with_new_position& vnp : splitters) { + if(visitor.stop()) + return snapped_n; + const halfedge_descriptor splitter_h = vnp.first; const vertex_descriptor splitter_v = target(splitter_h, tm_S); const Point new_position = is_source_mesh_fixed ? get(vpm_S, splitter_v) : vnp.second; @@ -668,9 +701,13 @@ std::size_t split_edges(EdgesToSplitContainer& edges_to_split, vertex_descriptor new_v = boost::graph_traits::null_vertex(); if(do_split) { + visitor.before_vertex_edge_snap(h_to_split, tm_T, vnp.second); + CGAL::Euler::split_edge(h_to_split, tm_T); new_v = source(h_to_split, tm_T); put(vpm_T, new_v, new_position); // position of the new point on the target mesh + + visitor.after_vertex_edge_snap(new_v, tm_T); } if(!is_source_mesh_fixed) @@ -740,6 +777,13 @@ std::size_t split_edges(EdgesToSplitContainer& edges_to_split, } } + visitor.end_vertex_edge_snapping(); + +#ifdef CGAL_PMP_SNAPPING_PRINT_RUNTIME + timer.stop(); + std::cout << "time for actual snapping (vertex-edge) " << timer.time() << " s." << std::endl; +#endif + return snapped_n; } @@ -757,6 +801,7 @@ template std::size_t snap_non_conformal_one_way(const HalfedgeRange& halfedge_range_S, TriangleMesh& tm_S, @@ -768,6 +813,7 @@ std::size_t snap_non_conformal_one_way(const HalfedgeRange& halfedge_range_S, FacePatchMap_T face_patch_map_T, LockedHalfedgeMap locked_halfedges_T, const bool is_source_mesh_fixed, + Visitor& visitor, const SourceNamedParameters& snp, const TargetNamedParameters& tnp) { @@ -839,7 +885,7 @@ std::size_t snap_non_conformal_one_way(const HalfedgeRange& halfedge_range_S, for(auto& p : vertices_to_snap) p.second = point_tolerance_map[get(vpm_S, target(p.first, tm_S))]; - // Since we're inserting primitives one by one, we can't pass this shared data in the constructor of the tree + // Since primitives are inserted one by one, the shared data cannot be in the constructor of the tree AABB_Traits aabb_traits; aabb_traits.set_shared_data(tm_T, vpm_T); AABB_tree aabb_tree(aabb_traits); @@ -863,10 +909,15 @@ std::size_t snap_non_conformal_one_way(const HalfedgeRange& halfedge_range_S, std::cout << "Collect edges to split with " << vertices_to_snap.size() << " vertices" << std::endl; #endif +#ifdef CGAL_PMP_SNAPPING_PRINT_RUNTIME + CGAL::Real_timer timer; + timer.start(); +#endif + #ifndef CGAL_LINKED_WITH_TBB CGAL_static_assertion_msg (!(std::is_convertible::value), "Parallel_tag is enabled but TBB is unavailable."); -#else +#else // CGAL_LINKED_WITH_TBB if(std::is_convertible::value) { #ifdef CGAL_PMP_SNAP_DEBUG @@ -875,22 +926,45 @@ std::size_t snap_non_conformal_one_way(const HalfedgeRange& halfedge_range_S, typedef tbb::concurrent_hash_map Concurrent_edge_to_split_container; - typedef internal::Find_splittable_edge_for_parallel_for< + typedef internal::Parallel_find_splittable_edge< Vertices_with_tolerance, TriangleMesh, Concurrent_edge_to_split_container, AABB_tree, - VertexPatchMap_S, FacePatchMap_T, VPMS, VPMT, GT> Functor; - - CGAL::Real_timer timer; - timer.start(); + VertexPatchMap_S, FacePatchMap_T, VPMS, VPMT, GT, Visitor> Functor; Concurrent_edge_to_split_container edges_to_split; Functor f(vertices_to_snap, edges_to_split, &aabb_tree, - tm_S, vertex_patch_map_S, vpm_S, tm_T, face_patch_map_T, vpm_T, gt); - tbb::parallel_for(tbb::blocked_range(0, vertices_to_snap.size()), f); + tm_S, vertex_patch_map_S, vpm_S, tm_T, face_patch_map_T, vpm_T, + gt, visitor); - std::cout << "Time to gather edges: " << timer.time() << std::endl; + try + { + tbb::parallel_for(tbb::blocked_range(0, vertices_to_snap.size()), f); + } + catch(const CGAL::internal::Throw_at_output_exception&) + { + return 0; + } +#if TBB_USE_CAPTURED_EXCEPTION + catch(const tbb::captured_exception& e) + { + const std::string tn1(e.name()); + const std::string tn2(typeid(const CGAL::internal::Throw_at_output_exception&).name()); + if(tn1 != tn2) + { + std::cerr << "Unexpected throw: " << tn1 << std::endl; + throw; + } - return split_edges(edges_to_split, tm_S, vpm_S, tm_T, vpm_T, gt, is_source_mesh_fixed); + return 0; + } +#endif + +#ifdef CGAL_PMP_SNAPPING_PRINT_RUNTIME + timer.stop(); + std::cout << "time for find split edges (parallel): " << timer.time() << std::endl; +#endif + + return split_edges(edges_to_split, tm_S, vpm_S, tm_T, vpm_T, gt, visitor, is_source_mesh_fixed); } else #endif // CGAL_LINKED_WITH_TBB @@ -900,14 +974,28 @@ std::size_t snap_non_conformal_one_way(const HalfedgeRange& halfedge_range_S, #endif std::map edges_to_split; - for(const Vertex_with_tolerance& vt : vertices_to_snap) + + try { - internal::find_splittable_edge(vt, edges_to_split, &aabb_tree, - tm_S, vertex_patch_map_S, vpm_S, - tm_T, face_patch_map_T, vpm_T, gt); + for(const Vertex_with_tolerance& vt : vertices_to_snap) + { + internal::find_splittable_edge(vt, edges_to_split, &aabb_tree, + tm_S, vertex_patch_map_S, vpm_S, + tm_T, face_patch_map_T, vpm_T, + gt, visitor); + } + } + catch(const CGAL::internal::Throw_at_output_exception&) + { + return 0; } - return split_edges(edges_to_split, tm_S, vpm_S, tm_T, vpm_T, gt, is_source_mesh_fixed); +#ifdef CGAL_PMP_SNAPPING_PRINT_RUNTIME + timer.stop(); + std::cout << "time for find split edges (sequential): " << timer.time() << std::endl; +#endif + + return split_edges(edges_to_split, tm_S, vpm_S, tm_T, vpm_T, gt, visitor, is_source_mesh_fixed); } } @@ -999,15 +1087,28 @@ std::size_t snap_non_conformal(HalfedgeRange& halfedge_range_A, internal_np::face_patch_t, NamedParameters_B, Constant_property_map /*default*/ >::type Face_patch_map_B; + typedef typename internal_np::Lookup_named_param_def < + internal_np::visitor_t, + NamedParameters_A, + internal::Snapping_default_visitor // default + >::reference Visitor; + using CGAL::parameters::choose_parameter; using CGAL::parameters::is_default_parameter; using CGAL::parameters::get_parameter; + using CGAL::parameters::get_parameter_reference; const bool is_same_mesh = (&tm_A == &tm_B); const bool simplify_first_mesh = choose_parameter(get_parameter(np_A, internal_np::do_simplify_border), false); const bool simplify_second_mesh = choose_parameter(get_parameter(np_B, internal_np::do_simplify_border), false); const bool is_second_mesh_fixed = choose_parameter(get_parameter(np_B, internal_np::do_lock_mesh), false); + internal::Snapping_default_visitor default_visitor; + Visitor& visitor = choose_parameter(get_parameter_reference(np_A, internal_np::visitor), default_visitor); + + if(visitor.stop()) + return 0; + // vertex-vertex and vertex-edge snapping is only considered within compatible patches Face_patch_map_A face_patch_map_A = choose_parameter(get_parameter(np_A, internal_np::face_patch), Constant_property_map(-1)); @@ -1053,6 +1154,9 @@ std::size_t snap_non_conformal(HalfedgeRange& halfedge_range_A, /// #1 and #1bis (Simplification of borders) ////////////////////////////////////////////////////////////////////////////////////////////////// + if(visitor.stop()) + return 0; + #ifdef CGAL_PMP_SNAP_DEBUG std::cout << "Simplify ranges (" << simplify_first_mesh << " " << simplify_second_mesh << ")..." << std::endl; #endif @@ -1079,6 +1183,8 @@ std::size_t snap_non_conformal(HalfedgeRange& halfedge_range_A, /// #2 (Two-way vertex-vertex snapping) ////////////////////////////////////////////////////////////////////////////////////////////////// + std::size_t snapped_n = 0; + // We keep in memory pairs of source/target edges that are stitchable after vertex-vertex snapping // --> these halfedges should not be considered as targets in non-conformal snapping // Similarly, matching vertices whose incident edges have matching directions are also locked @@ -1087,8 +1193,6 @@ std::size_t snap_non_conformal(HalfedgeRange& halfedge_range_A, Locked_halfedges locked_halfedges_A = get(Halfedge_bool_tag(), tm_A); Locked_halfedges locked_halfedges_B = get(Halfedge_bool_tag(), tm_B); - std::size_t snapped_n = 0; - std::vector > locked_vertices; std::vector locked_halfedges_A_vector, locked_halfedges_B_vector; @@ -1130,17 +1234,24 @@ std::size_t snap_non_conformal(HalfedgeRange& halfedge_range_A, #endif ////////////////////////////////////////////////////////////////////////////////////////////////// - /// #3 (Two one-way vertex-edge snapping) + /// #3 (Two one-way vertex-edge snappings) ////////////////////////////////////////////////////////////////////////////////////////////////// + if(visitor.stop()) + return snapped_n; + #ifdef CGAL_PMP_SNAP_DEBUG std::cout << " ///////////// Two one-way vertex-edge snapping (A --> B) " << std::endl; #endif + visitor.start_first_vertex_edge_phase(); + snapped_n += internal::snap_non_conformal_one_way( halfedge_range_A, tm_A, tolerance_map_A, vertex_patch_map_A, locked_vertices_A, halfedge_range_B, tm_B, face_patch_map_B, locked_halfedges_B, - false /*source is never fixed*/, np_A, np_B); + false /*source is never fixed*/, visitor, np_A, np_B); + + visitor.end_first_vertex_edge_phase(); #ifdef CGAL_PMP_SNAP_DEBUG_OUTPUT std::ofstream("results/vertex_edge_A.off") << std::setprecision(17) << tm_A; @@ -1149,14 +1260,21 @@ std::size_t snap_non_conformal(HalfedgeRange& halfedge_range_A, if(!is_self_snapping) { + if(visitor.stop()) + return snapped_n; + #ifdef CGAL_PMP_SNAP_DEBUG - std::cout << " ///////////// Two one-way vertex-edge snapping (B --> A) " << std::endl; + std::cout << " ///////////// Two one-way vertex-edge snapping (B --> A) " << std::endl; #endif + visitor.start_second_vertex_edge_phase(); + snapped_n += internal::snap_non_conformal_one_way( halfedge_range_B, tm_B, tolerance_map_B, vertex_patch_map_B, locked_vertices_B, halfedge_range_A, tm_A, face_patch_map_A, locked_halfedges_A, - is_second_mesh_fixed, np_B, np_A); + is_second_mesh_fixed, visitor, np_B, np_A); + + visitor.end_second_vertex_edge_phase(); } return snapped_n; diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Snapping/snap_vertices.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Snapping/snap_vertices.h index 90df8a56406..98aa23f2862 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Snapping/snap_vertices.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Snapping/snap_vertices.h @@ -34,12 +34,18 @@ #include #include #include +#include +#include +#include #include +#include #include #include -#include #include +#include +#include #include +#include #include #include @@ -47,7 +53,9 @@ #include #ifdef CGAL_LINKED_WITH_TBB +#define TBB_PREVIEW_CONCURRENT_ORDERED_CONTAINERS 1 # include +# include # include # include #endif @@ -88,26 +96,41 @@ struct Snapping_pair FT sq_dist; }; -// Functor that just forwards the pair of the two intersecting boxes -template -struct Intersecting_boxes_pairs_report +#ifdef CGAL_LINKED_WITH_TBB +// Functor that forwards the pair of the two intersecting boxes +// Note that Box_intersection_d does a lot of copies of the callback functor, but we are passing it +// with std::ref, so is always refering to the same reporter object (and importantly, the same counter) +template +struct Intersecting_boxes_pairs_parallel_report { - Intersecting_boxes_pairs_report(OutputIterator it) : m_iterator(it) { } + mutable OutputIterator m_iterator; + Visitor& m_visitor; + + Intersecting_boxes_pairs_parallel_report(OutputIterator it, Visitor& visitor) + : m_iterator(it), + m_visitor(visitor) + { } + + Intersecting_boxes_pairs_parallel_report(const Intersecting_boxes_pairs_parallel_report& other) = delete; + Intersecting_boxes_pairs_parallel_report& operator=(const Intersecting_boxes_pairs_parallel_report&) = delete; template - void operator()(const Box* b, const Box* c) const { - *m_iterator++ = std::make_pair(b->info(), c->info()); - } + void operator()(const Box* b, const Box* c) const + { + *m_iterator++ = std::make_pair(b->info(), c->info()); // writing into a concurrent vector - mutable OutputIterator m_iterator; + if(m_visitor.stop()) + throw CGAL::internal::Throw_at_output_exception(); + } }; +#endif template Unique_vertex_pair; +private: + const PolygonMesh& m_tm_A; + ToleranceMap_A m_tolerance_map_A; + VertexPatchMap_A m_vertex_patch_map_A; + VPM_A m_vpm_A; + const PolygonMesh& m_tm_B; + ToleranceMap_B m_tolerance_map_B; + VertexPatchMap_B m_vertex_patch_map_B; + VPM_B m_vpm_B; + const GeomTraits& m_gt; + + Visitor& m_visitor; + SnappingPairContainer& m_snapping_pairs; // will only be filled here in the sequential setting + +#ifdef CGAL_LINKED_WITH_TBB + const UniqueVertexPairContainer* m_uv_pairs; + ToKeepContainer* m_to_keep; +#endif + +public: Vertex_proximity_report(SnappingPairContainer& snapping_pairs, const PolygonMesh& tm_A, ToleranceMap_A tolerance_map_A, @@ -135,7 +178,8 @@ struct Vertex_proximity_report ToleranceMap_B tolerance_map_B, VertexPatchMap_B vertex_patch_map_B, const VPM_B& vpm_B, - const GeomTraits& gt + const GeomTraits& gt, + Visitor& visitor #ifdef CGAL_LINKED_WITH_TBB , const UniqueVertexPairContainer* uv_pairs = nullptr , ToKeepContainer* to_keep = nullptr @@ -151,6 +195,7 @@ struct Vertex_proximity_report m_vertex_patch_map_B(vertex_patch_map_B), m_vpm_B(vpm_B), m_gt(gt), + m_visitor(visitor), m_snapping_pairs(snapping_pairs) #ifdef CGAL_LINKED_WITH_TBB , m_uv_pairs(uv_pairs) @@ -158,7 +203,7 @@ struct Vertex_proximity_report #endif { } - bool are_equal_vertices(Unique_vertex_ptr uv_a, Unique_vertex_ptr uv_b) const + bool are_equal_vertices(const Unique_vertex_ptr uv_a, const Unique_vertex_ptr uv_b) const { if(&m_tm_A != &m_tm_B) // must be the same mesh return false; @@ -171,10 +216,13 @@ struct Vertex_proximity_report return (std::find(uv_b->first.begin(), uv_b->first.end(), ha) != uv_b->first.end()); } - std::pair do_keep(Unique_vertex_ptr uv_a, Unique_vertex_ptr uv_b) const + std::pair do_keep(const Unique_vertex_ptr uv_a, const Unique_vertex_ptr uv_b) const { + CGAL_precondition(uv_a != nullptr && uv_b != nullptr); + const Vertex_container& vs_a = uv_a->first; const Vertex_container& vs_b = uv_b->first; + const vertex_descriptor va = target(vs_a.front(), m_tm_A); const vertex_descriptor vb = target(vs_b.front(), m_tm_B); @@ -204,7 +252,9 @@ struct Vertex_proximity_report #endif if(res == CGAL::LARGER) + { return std::make_pair(-1, false); // ignore + } else { const FT sq_dist = (min)(m_gt.compute_squared_distance_3_object()(get(m_vpm_A, va), get(m_vpm_B, vb)), @@ -213,17 +263,29 @@ struct Vertex_proximity_report } } - // that's the sequential version - void operator()(const Box* a, const Box* b) + // sequential version (kd_tree) + void operator()(const Unique_vertex_ptr uv_a, const Unique_vertex_ptr uv_b) { - Unique_vertex_ptr uv_a = a->info(), uv_b = b->info(); + if(m_visitor.stop()) + throw CGAL::internal::Throw_at_output_exception(); + const std::pair res = do_keep(uv_a, uv_b); if(res.second) - m_snapping_pairs.insert(Snapping_pair(uv_a, uv_b, res.first)); + { + m_snapping_pairs.emplace(uv_a, uv_b, res.first); + m_visitor.on_vertex_vertex_match(uv_a->first, m_tm_A, uv_b->first, m_tm_B); + } } + // sequential version (box_d) + template + void operator()(const BoxPtr a, const BoxPtr b) + { + return this->operator()(a->info(), b->info()); + } + + // parallel version #ifdef CGAL_LINKED_WITH_TBB - // that's the parallel version void operator()(const tbb::blocked_range& r) const { CGAL_assertion(m_uv_pairs != nullptr); @@ -236,26 +298,384 @@ struct Vertex_proximity_report } } #endif - -private: - const PolygonMesh& m_tm_A; - ToleranceMap_A m_tolerance_map_A; - VertexPatchMap_A m_vertex_patch_map_A; - VPM_A m_vpm_A; - const PolygonMesh& m_tm_B; - ToleranceMap_B m_tolerance_map_B; - VertexPatchMap_B m_vertex_patch_map_B; - VPM_B m_vpm_B; - const GeomTraits& m_gt; - - SnappingPairContainer& m_snapping_pairs; // will only be filled here in the sequential setting - -#ifdef CGAL_LINKED_WITH_TBB - const UniqueVertexPairContainer* m_uv_pairs; - ToKeepContainer* m_to_keep; -#endif }; +template +struct Unique_point_position_accessor +{ + typedef Key key_type; + typedef ValueType value_type; + typedef const value_type& reference; + typedef boost::lvalue_property_map_tag category; + + friend reference get(const Unique_point_position_accessor&, const key_type& k) + { + return k->first.first; + } +}; + +template +void find_vertex_vertex_matches_with_kd_tree(Unique_positions& unique_positions_A, // not const because it complicates parallel loops + const Unique_positions& unique_positions_B, + const PolygonMesh& tm_A, + VPM_A vpm_A, + ToleranceMap_A tolerance_map_A, + VertexPatchMap_A vertex_patch_map_A, + const PolygonMesh& tm_B, + VPM_B vpm_B, + ToleranceMap_B tolerance_map_B, + VertexPatchMap_B vertex_patch_map_B, + const GT& gt, + Visitor& visitor, + Snapping_pair_container& snapping_pairs) +{ + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + + typedef typename GT::FT FT; + typedef typename boost::property_traits::value_type Point; + + typedef std::vector Vertex_container; + typedef std::pair Unique_vertex; + typedef const Unique_vertex* Unique_vertex_ptr; + typedef std::pair Patch_point; + + // Put iterators into the tree: + // - to be lighter + // - because kd_tree.search() returns copies + typedef typename Unique_positions::const_iterator Key; + + typedef CGAL::Search_traits_3 Base_search_traits; + typedef CGAL::Search_traits_adapter, Base_search_traits> Search_traits; + typedef CGAL::Kd_tree Kd_tree; + typedef CGAL::Fuzzy_sphere Fuzzy_sphere; + + typedef std::vector Unique_positions_vector; + +#ifdef CGAL_PMP_SNAPPING_PRINT_RUNTIME + CGAL::Real_timer timer; + timer.start(); +#endif + + Unique_positions_vector unique_positions_Bv; + unique_positions_Bv.reserve(unique_positions_B.size()); + for(auto it=unique_positions_B.cbegin(); it!=unique_positions_B.cend(); ++it) + unique_positions_Bv.push_back(it); + + Kd_tree tree; + tree.insert(unique_positions_Bv.begin(), unique_positions_Bv.end()); + +#if !defined(CGAL_LINKED_WITH_TBB) + CGAL_static_assertion_msg (!(std::is_convertible::value), + "Parallel_tag is enabled but TBB is unavailable."); +#else + // parallel + if(std::is_convertible::value) + { + typedef std::pair Unique_vertex_pair; + typedef tbb::concurrent_vector Unique_vertex_pairs; + + Unique_vertex_pairs uv_pairs; + + // Functor for the parallel_for over the conccurrent map + auto vertex_inquiry = [&](const typename Unique_positions::range_type &r) + { + for(const auto& e : r) + { + if(visitor.stop()) + return; + + const Patch_point& pp = e.first; + const Point& q = pp.first; + const Unique_vertex& uv = e.second; + const FT tolerance = uv.second; + + visitor.on_vertex_vertex_inquiry(uv, tm_A); + + // @fixme this assumes constant and equal tolerances, because querying the kd tree is one way + // and we don't know the tolerance at the potential match since we don't know the potential match... + Fuzzy_sphere fq(q, 2 * tolerance); + + std::vector res; + tree.search(std::back_inserter(res), fq); + + for(const auto rit : res) + { + uv_pairs.emplace_back(&uv, &(rit->second)); + CGAL_assertion(!rit->second.first.empty()); + } + } + }; + + tbb::parallel_for(unique_positions_A.range(), vertex_inquiry); + + // Filter the range of possible matches (also in parallel) + typedef std::vector > Filters; + typedef Vertex_proximity_report Reporter; + + Filters to_keep(uv_pairs.size()); + Reporter proximity_filterer(snapping_pairs, + tm_A, tolerance_map_A, vertex_patch_map_A, vpm_A, + tm_B, tolerance_map_B, vertex_patch_map_B, vpm_B, + gt, visitor, &uv_pairs, &to_keep); + + tbb::parallel_for(tbb::blocked_range(0, uv_pairs.size()), proximity_filterer); + + // Now fill the multi-index, sequentially + for(std::size_t i=0, uvps = uv_pairs.size(); ifirst, tm_A, uv_pairs[i].second->first, tm_B); + snapping_pairs.emplace(uv_pairs[i].first, uv_pairs[i].second, to_keep[i].first); + } + } + +#ifdef CGAL_PMP_SNAPPING_PRINT_RUNTIME + timer.stop(); + std::cout << "time for KD Tree (parallel): " << timer.time() << std::endl; +#endif + } + else +#endif // CGAL_LINKED_WITH_TBB + // sequential + { + typedef std::pair Unique_vertex_pair; + typedef std::vector Unique_vertex_pairs; + + Unique_vertex_pairs uv_pairs; + + for(const auto& e : unique_positions_A) + { + if(visitor.stop()) + return; + + const Patch_point& pp = e.first; + const Point& q = pp.first; + const Unique_vertex& uv = e.second; + const FT tolerance = uv.second; + + visitor.on_vertex_vertex_inquiry(uv, tm_A); + + // @fixme this assumes constant and equal tolerances, because querying the kd tree is one way + // and we don't know the tolerance at the potential match since we don't know the potential match... + Fuzzy_sphere fq(q, 2 * tolerance); + + std::vector res; + tree.search(std::back_inserter(res), fq); + + for(const auto rit : res) + { + uv_pairs.emplace_back(&uv, &(rit->second)); + CGAL_assertion(!rit->second.first.empty()); + } + } + + typedef Vertex_proximity_report Reporter; + + Reporter proximity_filterer(snapping_pairs, + tm_A, tolerance_map_A, vertex_patch_map_A, vpm_A, + tm_B, tolerance_map_B, vertex_patch_map_B, vpm_B, + gt, visitor); + + for(const auto& p : uv_pairs) + proximity_filterer(p.first, p.second); + +#ifdef CGAL_PMP_SNAPPING_PRINT_RUNTIME + timer.stop(); + std::cout << "time for KD Tree (sequential): " << timer.time() << std::endl; +#endif + } +} + +template +void find_vertex_vertex_matches_with_box_d(const Unique_positions& unique_positions_A, + const Unique_positions& unique_positions_B, + const PolygonMesh& tm_A, + VPM_A vpm_A, + ToleranceMap_A tolerance_map_A, + VertexPatchMap_A vertex_patch_map_A, + const PolygonMesh& tm_B, + VPM_B vpm_B, + ToleranceMap_B tolerance_map_B, + VertexPatchMap_B vertex_patch_map_B, + const GT& gt, + Visitor& visitor, + Snapping_pair_container& snapping_pairs) +{ + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + + typedef typename GT::FT FT; + + typedef std::vector Vertex_container; + typedef std::pair Unique_vertex; + typedef const Unique_vertex* Unique_vertex_ptr; + + typedef Box_intersection_d::ID_FROM_BOX_ADDRESS Box_policy; + typedef CGAL::Box_intersection_d::Box_with_info_d Box; + +#ifdef CGAL_PMP_SNAPPING_PRINT_RUNTIME + CGAL::Real_timer timer; + timer.start(); +#endif + + std::vector boxes_A; + boxes_A.reserve(unique_positions_A.size()); + std::vector boxes_B; + boxes_B.reserve(unique_positions_B.size()); + + // Actually build the boxes now + for(const auto& p : unique_positions_A) + { +#ifdef CGAL_PMP_SNAP_DEBUG_PP + std::cout << "Unique_vertex (A), pos: " << p.first.first << " vertices:"; + for(const halfedge_descriptor h : p.second.first) + std::cout << " " << target(h, tm_A); + std::cout << std::endl; +#endif + + const Unique_vertex& ev = p.second; + CGAL_assertion(!ev.first.empty()); + + // this only makes the box a little larger to ease intersection computations, + // the final tolerance is not changed + const double eps = 1.01 * CGAL::to_double(ev.second); + const Bbox_3 pb = gt.construct_bbox_3_object()(p.first.first); + const Bbox_3 b(pb.xmin() - eps, pb.ymin() - eps, pb.zmin() - eps, + pb.xmax() + eps, pb.ymax() + eps, pb.zmax() + eps); + boxes_A.emplace_back(b, &ev); + } + + for(const auto& p : unique_positions_B) + { +#ifdef CGAL_PMP_SNAP_DEBUG_PP + std::cout << "Unique_vertex (B), pos: " << p.first.first << " vertices:"; + for(const halfedge_descriptor h : p.second.first) + std::cout << " " << target(h, tm_B); + std::cout << std::endl; +#endif + + const Unique_vertex& ev = p.second; + CGAL_assertion(!ev.first.empty()); + + const double eps = 1.01 * CGAL::to_double(ev.second); + const Bbox_3 pb = gt.construct_bbox_3_object()(p.first.first); + const Bbox_3 b(pb.xmin() - eps, pb.ymin() - eps, pb.zmin() - eps, + pb.xmax() + eps, pb.ymax() + eps, pb.zmax() + eps); + boxes_B.emplace_back(b, &ev); + } + + // @fixme bench and don't use ptrs if not useful + std::vector boxes_A_ptr; + boxes_A_ptr.reserve(boxes_A.size()); + for(const Box& b : boxes_A) + boxes_A_ptr.push_back(&b); + + std::vector boxes_B_ptr; + boxes_B_ptr.reserve(boxes_B.size()); + for(const Box& b : boxes_B) + boxes_B_ptr.push_back(&b); + +#if !defined(CGAL_LINKED_WITH_TBB) + CGAL_static_assertion_msg (!(std::is_convertible::value), + "Parallel_tag is enabled but TBB is unavailable."); +#else // CGAL_LINKED_WITH_TBB + if(std::is_convertible::value) + { + typedef std::pair Unique_vertex_pair; + typedef tbb::concurrent_vector Unique_vertex_pairs; + typedef std::back_insert_iterator UVP_output_iterator; + + Unique_vertex_pairs uv_pairs; + Intersecting_boxes_pairs_parallel_report box_callback(std::back_inserter(uv_pairs), visitor); + + // Shenanigans to pass a reference as callback (which is copied by value by 'box_intersection_d') + std::function callback(std::ref(box_callback)); + + // Grab the boxes that are interesecting but don't do any extra filtering (in parallel) + CGAL::box_intersection_d(boxes_A_ptr.begin(), boxes_A_ptr.end(), + boxes_B_ptr.begin(), boxes_B_ptr.end(), + callback); + + // Actually filter the range of intersecting boxes now (also in parallel) + typedef std::vector > Filters; + typedef Vertex_proximity_report Reporter; + + Filters to_keep(uv_pairs.size()); + Reporter proximity_filterer(snapping_pairs, + tm_A, tolerance_map_A, vertex_patch_map_A, vpm_A, + tm_B, tolerance_map_B, vertex_patch_map_B, vpm_B, + gt, visitor, &uv_pairs, &to_keep); + + tbb::parallel_for(tbb::blocked_range(0, uv_pairs.size()), proximity_filterer); + + // Now fill the multi-index, sequentially + for(std::size_t i=0, uvps = uv_pairs.size(); ifirst, uv_pairs[i].second->first); + snapping_pairs.emplace(uv_pairs[i].first, uv_pairs[i].second, to_keep[i].first); + } + } + +#ifdef CGAL_PMP_SNAPPING_PRINT_RUNTIME + timer.stop(); + std::cout << "time for box_d (parallel): " << timer.time() << std::endl; +#endif + } + else +#endif // CGAL_LINKED_WITH_TBB + // Sequential code + { + typedef Vertex_proximity_report Reporter; + + Reporter proximity_filterer(snapping_pairs, + tm_A, tolerance_map_A, vertex_patch_map_A, vpm_A, + tm_B, tolerance_map_B, vertex_patch_map_B, vpm_B, gt, + visitor); + + // Shenanigans to pass a reference as callback (which is copied by value by 'box_intersection_d') + std::function callback(std::ref(proximity_filterer)); + + CGAL::box_intersection_d(boxes_A_ptr.begin(), boxes_A_ptr.end(), + boxes_B_ptr.begin(), boxes_B_ptr.end(), + callback); + +#ifdef CGAL_PMP_SNAPPING_PRINT_RUNTIME + timer.stop(); + std::cout << "time for box_d (sequential): " << timer.time() << std::endl; +#endif + } +} + template ::vertex_descriptor vertex_descriptor; - typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - typedef typename GetVertexPointMap::type VPM_A; - typedef typename GetVertexPointMap::type VPM_B; + typedef typename GetVertexPointMap::type VPM_A; + typedef typename GetVertexPointMap::type VPM_B; - typedef typename GetGeomTraits::type GT; - typedef typename GT::FT FT; - typedef typename boost::property_traits::value_type Point; + typedef typename GetGeomTraits::type GT; + typedef typename GT::FT FT; + typedef typename boost::property_traits::value_type Point; - typedef std::vector Vertex_container; - typedef std::pair Unique_vertex; - typedef const Unique_vertex* Unique_vertex_ptr; - typedef std::map, Unique_vertex> Unique_positions; + typedef std::vector Vertex_container; + typedef std::pair Unique_vertex; + typedef const Unique_vertex* Unique_vertex_ptr; + typedef std::pair Patch_point; - typedef Box_intersection_d::ID_FROM_BOX_ADDRESS Box_policy; - typedef CGAL::Box_intersection_d::Box_with_info_d Box; + // @todo in theory could be unordered maps, but this requires defining the hashes & stuff +#ifdef CGAL_LINKED_WITH_TBB + typedef tbb::concurrent_map Unique_positions; +#else + typedef std::map Unique_positions; +#endif + + typedef typename internal_np::Lookup_named_param_def < + internal_np::visitor_t, + NamedParameters_A, + internal::Snapping_default_visitor // default + >::reference Visitor; - using parameters::get_parameter; using parameters::choose_parameter; + using parameters::get_parameter; + using parameters::get_parameter_reference; CGAL_static_assertion((std::is_same::value)); @@ -306,6 +737,13 @@ std::size_t snap_vertices_two_way(const HalfedgeRange_A& halfedge_range_A, VPM_B vpm_B = choose_parameter(get_parameter(np_B, internal_np::vertex_point), get_property_map(vertex_point, tm_B)); + internal::Snapping_default_visitor default_visitor; + Visitor& visitor = choose_parameter(get_parameter_reference(np_A, internal_np::visitor), default_visitor); + + visitor.start_vertex_vertex_phase(); + if(visitor.stop()) + return 0; + #ifdef CGAL_PMP_SNAP_DEBUG std::cout << "Finding snappables vertices. Range sizes: " << std::distance(halfedge_range_A.begin(), halfedge_range_A.end()) << " and " @@ -316,15 +754,10 @@ std::size_t snap_vertices_two_way(const HalfedgeRange_A& halfedge_range_A, is_empty_range(halfedge_range_B.begin(), halfedge_range_B.end())) return 0; - // Vertex-Vertex snapping is performed as follows: - // - Identify points which are already equal and group them together so that they are moved together - // - Create a single box for these points - - std::vector boxes_A; - boxes_A.reserve(halfedge_range_A.size()); - std::vector boxes_B; - boxes_B.reserve(halfedge_range_B.size()); + // Vertex-Vertex snapping is performed by identify points which are already equal + // and grouping them together so that they are moved together + // @todo all range building could be parallel (worth it?) Unique_positions unique_positions_A; for(halfedge_descriptor h : halfedge_range_A) { @@ -336,10 +769,9 @@ std::size_t snap_vertices_two_way(const HalfedgeRange_A& halfedge_range_A, #endif Vertex_container nvc {{ h }}; - std::pair is_insert_successful = - unique_positions_A.insert(std::make_pair( - std::make_pair(get(vpm_A, v), get(vertex_patch_map_A, v)), // point and patch id - std::make_pair(nvc, tolerance))); + auto is_insert_successful = unique_positions_A.emplace(std::make_pair(get(vpm_A, v), + get(vertex_patch_map_A, v)), + std::make_pair(nvc, tolerance)); if(!is_insert_successful.second) // point was already met { @@ -351,7 +783,7 @@ std::size_t snap_vertices_two_way(const HalfedgeRange_A& halfedge_range_A, } } - // same for tm_B (@todo avoid all that for self snapping + use self_intersection_d) + // same for tm_B (@todo when doing boxes, avoid all that for self snapping + use self_intersection_d) Unique_positions unique_positions_B; for(halfedge_descriptor h : halfedge_range_B) { @@ -364,9 +796,8 @@ std::size_t snap_vertices_two_way(const HalfedgeRange_A& halfedge_range_A, Vertex_container nvc {{ h }}; std::pair is_insert_successful = - unique_positions_B.insert(std::make_pair( - std::make_pair(get(vpm_B, v), get(vertex_patch_map_B, v)), // point and patch id - std::make_pair(nvc, tolerance))); + unique_positions_B.emplace(std::make_pair(get(vpm_B, v), get(vertex_patch_map_B, v)), // point and patch id + std::make_pair(nvc, tolerance)); if(!is_insert_successful.second) // point was already met { @@ -378,62 +809,10 @@ std::size_t snap_vertices_two_way(const HalfedgeRange_A& halfedge_range_A, } } - // Actually build the boxes now - for(const auto& p : unique_positions_A) - { -#ifdef CGAL_PMP_SNAP_DEBUG_PP - std::cout << "Unique_vertex (A), pos: " << p.first.first << " vertices:"; - for(const halfedge_descriptor h : p.second.first) - std::cout << " " << target(h, tm_A); - std::cout << std::endl; -#endif - - const Unique_vertex& ev = p.second; - CGAL_assertion(!ev.first.empty()); - - // this only makes the box a little larger to ease intersection computations, - // the final tolerance is not changed - const double eps = 1.01 * CGAL::to_double(ev.second); - const Bbox_3 pb = gt.construct_bbox_3_object()(p.first.first); - const Bbox_3 b(pb.xmin() - eps, pb.ymin() - eps, pb.zmin() - eps, - pb.xmax() + eps, pb.ymax() + eps, pb.zmax() + eps); - boxes_A.push_back(Box(b, &ev)); - } - - for(const auto& p : unique_positions_B) - { -#ifdef CGAL_PMP_SNAP_DEBUG_PP - std::cout << "Unique_vertex (B), pos: " << p.first.first << " vertices:"; - for(const halfedge_descriptor h : p.second.first) - std::cout << " " << target(h, tm_B); - std::cout << std::endl; -#endif - - const Unique_vertex& ev = p.second; - CGAL_assertion(!ev.first.empty()); - - const double eps = 1.01 * CGAL::to_double(ev.second); - const Bbox_3 pb = gt.construct_bbox_3_object()(p.first.first); - const Bbox_3 b(pb.xmin() - eps, pb.ymin() - eps, pb.zmin() - eps, - pb.xmax() + eps, pb.ymax() + eps, pb.zmax() + eps); - boxes_B.push_back(Box(b, &ev)); - } - - // @fixme bench and don't use ptrs if not useful - std::vector boxes_A_ptr; - boxes_A_ptr.reserve(boxes_A.size()); - for(const Box& b : boxes_A) - boxes_A_ptr.push_back(&b); - - std::vector boxes_B_ptr; - boxes_B_ptr.reserve(boxes_B.size()); - for(const Box& b : boxes_B) - boxes_B_ptr.push_back(&b); - // Use a multi index to sort easily by sources, targets, AND distance. // Then, look up the distances in increasing order, and snap whenever the source and the target // have both not been snapped yet. - typedef internal::Snapping_pair Snapping_pair; + typedef internal::Snapping_pair Snapping_pair; typedef boost::multi_index::multi_index_container< Snapping_pair, boost::multi_index::indexed_by< @@ -444,77 +823,55 @@ std::size_t snap_vertices_two_way(const HalfedgeRange_A& halfedge_range_A, boost::multi_index::ordered_non_unique< BOOST_MULTI_INDEX_MEMBER(Snapping_pair, FT, sq_dist)> > - > Snapping_pair_container; + > Snapping_pair_container; Snapping_pair_container snapping_pairs; - -#if !defined(CGAL_LINKED_WITH_TBB) - CGAL_static_assertion_msg (!(std::is_convertible::value), - "Parallel_tag is enabled but TBB is unavailable."); -#else - if(std::is_convertible::value) + try { - typedef std::pair Unique_vertex_pair; - typedef tbb::concurrent_vector Unique_vertex_pairs; - typedef std::back_insert_iterator UVP_output_iterator; - - Unique_vertex_pairs uv_pairs; - Intersecting_boxes_pairs_report callback(std::back_inserter(uv_pairs)); - - CGAL::Real_timer timer; - timer.start(); - - // Grab the boxes that are interesecting but don't do any extra filtering (in parallel) - CGAL::box_intersection_d(boxes_A_ptr.begin(), boxes_A_ptr.end(), - boxes_B_ptr.begin(), boxes_B_ptr.end(), - callback); - - std::cout << "time for box_d: " << timer.time() << std::endl; - - // Actually filter the range of intersecting boxes now (in parallel) - typedef std::vector > Filters; - typedef Vertex_proximity_report Reporter; - - Filters to_keep(uv_pairs.size()); - Reporter proximity_filterer(snapping_pairs, tm_A, tolerance_map_A, vertex_patch_map_A, vpm_A, - tm_B, tolerance_map_B, vertex_patch_map_B, vpm_B, - gt, &uv_pairs, &to_keep); - tbb::parallel_for(tbb::blocked_range(0, uv_pairs.size()), proximity_filterer); - - // Now fill the multi index, sequentially - for(std::size_t i=0, uvps = uv_pairs.size(); i(unique_positions_A, unique_positions_B, + tm_A, vpm_A, tolerance_map_A, vertex_patch_map_A, + tm_B, vpm_B, tolerance_map_B, vertex_patch_map_B, gt, + visitor, snapping_pairs); +#else // CGAL_PMP_SNAP_VERTICES_USE_KD_TREE + find_vertex_vertex_matches_with_box_d(unique_positions_A, unique_positions_B, + tm_A, vpm_A, tolerance_map_A, vertex_patch_map_A, + tm_B, vpm_B, tolerance_map_B, vertex_patch_map_B, gt, + visitor, snapping_pairs); +#endif // CGAL_PMP_SNAP_VERTICES_USE_KD_TREE } - else -#endif + catch(const CGAL::internal::Throw_at_output_exception&) { - typedef Vertex_proximity_report Reporter; - - Reporter vpr(snapping_pairs, tm_A, tolerance_map_A, vertex_patch_map_A, vpm_A, - tm_B, tolerance_map_B, vertex_patch_map_B, vpm_B, gt); - - // Shenanigans to pass a reference as callback (which is copied by value by 'box_intersection_d') - std::function callback(std::ref(vpr)); - - CGAL::box_intersection_d(boxes_A_ptr.begin(), boxes_A_ptr.end(), - boxes_B_ptr.begin(), boxes_B_ptr.end(), - callback); + return 0; } +#if TBB_USE_CAPTURED_EXCEPTION + catch(const tbb::captured_exception& e) + { + const std::string tn1(e.name()); + const std::string tn2(typeid(const CGAL::internal::Throw_at_output_exception&).name()); + if(tn1 != tn2) + { + std::cerr << "Unexpected throw: " << tn1 << std::endl; + throw; + } + + return 0; + } +#endif // TBB_USE_CAPTURED_EXCEPTION ////////////////////////////////////////////////////////////////////////////////////////////////// /// Done collecting; start matching ////////////////////////////////////////////////////////////////////////////////////////////////// - if(snapping_pairs.empty()) + if(snapping_pairs.empty() || visitor.stop()) return 0; +#ifdef CGAL_PMP_SNAPPING_PRINT_RUNTIME + CGAL::Real_timer timer; + timer.start(); +#endif + typedef std::pair Unique_vertex_pair; std::vector snappable_vertices_pairs; @@ -566,15 +923,21 @@ std::size_t snap_vertices_two_way(const HalfedgeRange_A& halfedge_range_A, /// Done matching; start snapping ////////////////////////////////////////////////////////////////////////////////////////////////// - std::size_t counter = 0; + visitor.start_vertex_vertex_snapping(); + if(snappable_vertices_pairs.empty() || visitor.stop()) + return 0; #ifdef CGAL_PMP_SNAP_DEBUG_OUTPUT std::ofstream out_edges("results/snappable.polylines.txt"); out_edges.precision(17); #endif + std::size_t counter = 0; for(const Unique_vertex_pair& uvp : snappable_vertices_pairs) { + if(visitor.stop()) + return counter; + Unique_vertex_ptr uv_a = uvp.first; Unique_vertex_ptr uv_b = uvp.second; const Vertex_container& vs_a = uv_a->first; @@ -582,6 +945,8 @@ std::size_t snap_vertices_two_way(const HalfedgeRange_A& halfedge_range_A, const vertex_descriptor va = target(vs_a.front(), tm_A); const vertex_descriptor vb = target(vs_b.front(), tm_B); + visitor.before_vertex_vertex_snap(vs_a, tm_A, vs_b, tm_B); + #ifdef CGAL_PMP_SNAP_DEBUG_OUTPUT out_edges << "2 " << tm_A.point(va) << " " << tm_B.point(vb) << std::endl; #endif @@ -600,7 +965,7 @@ std::size_t snap_vertices_two_way(const HalfedgeRange_A& halfedge_range_A, const FT tol_t = uv_b->second; CGAL_assertion(tol_s != FT(0) || tol_t != FT(0)); - const FT lambda = tol_t / (tol_s + tol_t); + const FT lambda = tol_s / (tol_s + tol_t); const Point new_p = get(vpm_A, va) + lambda * (get(vpm_B, vb) - get(vpm_A, va)); #ifdef CGAL_PMP_SNAP_DEBUG_PP std::cout << "new position of " << va << " " << vb << " --> " << new_p << std::endl; @@ -615,12 +980,16 @@ std::size_t snap_vertices_two_way(const HalfedgeRange_A& halfedge_range_A, ++counter; } + + visitor.after_vertex_vertex_snap(vs_a, tm_A, vs_b, tm_B); } #ifdef CGAL_PMP_SNAP_DEBUG_OUTPUT out_edges.close(); #endif + visitor.end_vertex_vertex_snapping(); + #ifdef CGAL_PMP_SNAP_DEBUG std::cout << "Snapped " << counter << " pair(s)!" << std::endl; #endif @@ -629,7 +998,7 @@ std::size_t snap_vertices_two_way(const HalfedgeRange_A& halfedge_range_A, /// Done snapping; start analyzing ////////////////////////////////////////////////////////////////////////////////////////////////// - // Below is used in non-conformal snapping + // Below is performed to improve non-conformal snapping // @todo could avoid doing it if not required // // Now that vertex-vertex snapping has been performed, look around to see if we can already @@ -640,8 +1009,7 @@ std::size_t snap_vertices_two_way(const HalfedgeRange_A& halfedge_range_A, // #2 : If pairs on either side of the two matching vertices are compatible (not necessary fully matching), // then the two vertices should be locked as no better match can be obtained // #3 : If a pair of incident edges are not fully matching, but still have compatible directions - // (i.e. collinear and opposite directions), then we don't want to project onto the shorter - // of the two + // (i.e. collinear and opposite directions), then we don't want to project onto the shorter of the two for(const Unique_vertex_pair& uvp : snappable_vertices_pairs) { Unique_vertex_ptr uv_a = uvp.first; @@ -724,6 +1092,13 @@ std::size_t snap_vertices_two_way(const HalfedgeRange_A& halfedge_range_A, } } + visitor.end_vertex_vertex_phase(); + +#ifdef CGAL_PMP_SNAPPING_PRINT_RUNTIME + timer.stop(); + std::cout << "time for the actual snapping (vertex-vertex): " << timer.time() << std::endl; +#endif + return counter; } @@ -750,15 +1125,15 @@ std::size_t snap_vertices_two_way(const HalfedgeRange_A& halfedge_range_A, using CGAL::parameters::choose_parameter; using CGAL::parameters::get_parameter; - return snap_vertices_two_way(halfedge_range_A, tm_A, tolerance_map_A, - choose_parameter(get_parameter(np_A, internal_np::vertex_incident_patches), - Constant_property_map(-1)), - halfedge_range_B, tm_B, tolerance_map_B, - choose_parameter(get_parameter(np_B, internal_np::vertex_incident_patches), - Constant_property_map(-1)), - lockable_vps_out, lockable_ha_out, lockable_hb_out, - choose_parameter(get_parameter(np_B, internal_np::do_lock_mesh), false), - np_A, np_B); + return snap_vertices_two_way(halfedge_range_A, tm_A, tolerance_map_A, + choose_parameter(get_parameter(np_A, internal_np::vertex_incident_patches), + Constant_property_map(-1)), + halfedge_range_B, tm_B, tolerance_map_B, + choose_parameter(get_parameter(np_B, internal_np::vertex_incident_patches), + Constant_property_map(-1)), + lockable_vps_out, lockable_ha_out, lockable_hb_out, + choose_parameter(get_parameter(np_B, internal_np::do_lock_mesh), false), + np_A, np_B); } } // namespace internal @@ -818,7 +1193,8 @@ namespace experimental { // // \return the number of snapped vertex pairs // -template std::size_t snap_vertices(const HalfedgeRange_A& halfedge_range_A, @@ -832,13 +1208,14 @@ std::size_t snap_vertices(const HalfedgeRange_A& halfedge_range_A, { CGAL::Emptyset_iterator unused_output_iterator; - return internal::snap_vertices_two_way(halfedge_range_A, tm_A, tolerance_map_A, - halfedge_range_B, tm_B, tolerance_map_B, - unused_output_iterator, unused_output_iterator, - unused_output_iterator, np_A, np_B); + return internal::snap_vertices_two_way(halfedge_range_A, tm_A, tolerance_map_A, + halfedge_range_B, tm_B, tolerance_map_B, + unused_output_iterator, unused_output_iterator, + unused_output_iterator, np_A, np_B); } -template std::size_t snap_vertices(const HalfedgeRange_A& halfedge_range_A, PolygonMesh& tm_A, @@ -847,11 +1224,13 @@ std::size_t snap_vertices(const HalfedgeRange_A& halfedge_range_A, PolygonMesh& tm_B, ToleranceMap_B tolerance_map_B) { - return snap_vertices(halfedge_range_A, tm_A, tolerance_map_A, halfedge_range_B, tm_B, tolerance_map_B, - CGAL::parameters::all_default(), CGAL::parameters::all_default()); + return snap_vertices(halfedge_range_A, tm_A, tolerance_map_A, + halfedge_range_B, tm_B, tolerance_map_B, + CGAL::parameters::all_default(), CGAL::parameters::all_default()); } -template std::size_t snap_vertices(const HalfedgeRange_A& halfedge_range_A, @@ -877,21 +1256,23 @@ std::size_t snap_vertices(const HalfedgeRange_A& halfedge_range_A, return snap_vertices(halfedge_range_A, tm_A, tolerance_map_A, halfedge_range_B, tm_B, tolerance_map_B, np_A, np_B); } -template +template std::size_t snap_vertices(const HalfedgeRange_A& halfedge_range_A, PolygonMesh& tm_A, const HalfedgeRange_B& halfedge_range_B, PolygonMesh& tm_B) { - return snap_vertices(halfedge_range_A, tm_A, halfedge_range_B, tm_B, - parameters::all_default(), parameters::all_default()); + return snap_vertices(halfedge_range_A, tm_A, halfedge_range_B, tm_B, + parameters::all_default(), parameters::all_default()); } /////////////////////////////////////////////////////////////////////////////////////////////////// /// Border convenience overloads /////////////////////////////////////////////////////////////////////////////////////////////////// -template +template std::size_t snap_border_vertices(PolygonMesh& tm_A, ToleranceMap_A tolerance_map_A, PolygonMesh& tm_B, @@ -904,11 +1285,12 @@ std::size_t snap_border_vertices(PolygonMesh& tm_A, std::vector border_B; border_halfedges(tm_B, std::back_inserter(border_B)); - return snap_vertices(border_A, tm_A, tolerance_map_A, - border_B, tm_B, tolerance_map_B); + return snap_vertices(border_A, tm_A, tolerance_map_A, + border_B, tm_B, tolerance_map_B); } -template +template std::size_t snap_border_vertices(PolygonMesh& tm_A, PolygonMesh& tm_B) { @@ -920,25 +1302,28 @@ std::size_t snap_border_vertices(PolygonMesh& tm_A, std::vector border_vertices_B; border_halfedges(tm_B, std::back_inserter(border_vertices_B)); - return snap_vertices(border_vertices_A, tm_A, border_vertices_B, tm_B); + return snap_vertices(border_vertices_A, tm_A, border_vertices_B, tm_B); } -template +template std::size_t snap_border_vertices(PolygonMesh& tm, ToleranceMap tolerance_map) { - return snap_border_vertices(tm, tolerance_map, tm, tolerance_map); + return snap_border_vertices(tm, tolerance_map, tm, tolerance_map); } -template +template std::size_t snap_border_vertices(PolygonMesh& tm) { - return snap_border_vertices(tm, tm); + return snap_border_vertices(tm, tm); } /////////////////////////////////////////////////////////////////////////////////////////////////// /// Other convenience overloads /////////////////////////////////////////////////////////////////////////////////////////////////// -template +template std::size_t snap_all_vertices(PolygonMesh& tm, ToleranceMap tolerance_map) { typedef boost::graph_traits GT; @@ -952,10 +1337,9 @@ std::size_t snap_all_vertices(PolygonMesh& tm, ToleranceMap tolerance_map) boost::make_transform_iterator(vertices(tm).begin(), get_halfedge), boost::make_transform_iterator(vertices(tm).end(), get_halfedge) ); - return snap_vertices(hedges, tm, tolerance_map, hedges, tm, tolerance_map); + return snap_vertices(hedges, tm, tolerance_map, hedges, tm, tolerance_map); } - } // namespace experimental } // namespace Polygon_mesh_processing } // namespace CGAL diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/fair_impl.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/fair_impl.h index a45ff4b55e9..62e1ce5e5e8 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/fair_impl.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/fair_impl.h @@ -19,7 +19,7 @@ #include #include #include -#include +#include #ifdef CGAL_PMP_FAIR_DEBUG #include #endif @@ -65,7 +65,7 @@ private: double weight = 0; Halfedge_around_vertex_circulator circ(halfedge(v,pmesh),pmesh), done(circ); do { - weight += weight_calculator.w_ij(*circ); + weight += CGAL::to_double(weight_calculator.w_ij(*circ)); } while(++circ != done); return weight; } @@ -95,11 +95,11 @@ private: } } else { - double w_i = weight_calculator.w_i(v); + double w_i = CGAL::to_double(weight_calculator.w_i(v)); Halfedge_around_vertex_circulator circ(halfedge(v,pmesh),pmesh), done(circ); do { - double w_i_w_ij = w_i * weight_calculator.w_ij(*circ) ; + double w_i_w_ij = w_i * CGAL::to_double(weight_calculator.w_ij(*circ)) ; vertex_descriptor nv = target(opposite(*circ,pmesh),pmesh); compute_row(nv, row_id, matrix, x, y, z, -w_i_w_ij*multiplier, vertex_id_map, depth-1); diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/measure.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/measure.h index f65caaaa87a..6d9533b2226 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/measure.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/measure.h @@ -23,8 +23,7 @@ #include #include #include -#include -#include + #include // needed for CGAL::exact(FT)/CGAL::exact(Lazy_exact_nt) @@ -61,6 +60,7 @@ inline void rearrange_face_ids(boost::container::small_vector& i std::rotate(ids.begin(), min_elem, ids.end()); } }//namespace internal + /** * \ingroup measure_grp * computes the length of an edge of a given polygon mesh. @@ -69,7 +69,7 @@ inline void rearrange_face_ids(boost::container::small_vector& i * @tparam PolygonMesh a model of `HalfedgeGraph` * @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" * - * @param h one halfedge of the edge to compute the length + * @param h one halfedge of the edge whose length is computed * @param pmesh the polygon mesh to which `h` belongs * @param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below * @@ -98,6 +98,7 @@ inline void rearrange_face_ids(boost::container::small_vector& i * If `FT` does not have a `sqrt()` operation, the square root computation * will be done approximately. * + * @sa `squared_edge_length()` * @sa `face_border_length()` */ template::halfedge_descriptor h, const PolygonMesh& pmesh, const NamedParameters& np) { + typedef typename GetGeomTraits::type Geom_traits; + using parameters::choose_parameter; using parameters::get_parameter; + CGAL_precondition(boost::graph_traits::null_halfedge() != h); + typename GetVertexPointMap::const_type vpm = choose_parameter(get_parameter(np, internal_np::vertex_point), get_const_property_map(CGAL::vertex_point, pmesh)); - return CGAL::approximate_sqrt(CGAL::squared_distance(get(vpm, source(h, pmesh)), - get(vpm, target(h, pmesh)))); + Geom_traits gt = choose_parameter(get_parameter(np, internal_np::geom_traits)); + + return CGAL::approximate_sqrt(gt.compute_squared_distance_3_object()(get(vpm, source(h, pmesh)), + get(vpm, target(h, pmesh)))); } template @@ -150,6 +157,99 @@ edge_length(typename boost::graph_traits::edge_descriptor e, return edge_length(halfedge(e, pmesh), pmesh); } +/** + * \ingroup measure_grp + * computes the squared length of an edge of a given polygon mesh. + * The edge is given by one of its halfedges, or the edge itself. + * + * @tparam PolygonMesh a model of `HalfedgeGraph` + * @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" + * + * @param h one halfedge of the edge whose squared length is computed + * @param pmesh the polygon mesh to which `h` 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{a class model of `Kernel`} + * \cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`} + * \cgalParamExtra{The geometric traits class must be compatible with the vertex point type.} + * \cgalParamNEnd + * \cgalNamedParamsEnd + * + * @return the squared length of `h`. The return type `FT` is a number type. It is + * 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`. + * + * @sa `edge_length()` + * @sa `face_border_length()` + */ +template +#ifdef DOXYGEN_RUNNING +FT +#else +typename GetGeomTraits::type::FT +#endif +squared_edge_length(typename boost::graph_traits::halfedge_descriptor h, + const PolygonMesh& pmesh, + const NamedParameters& np) +{ + typedef typename GetGeomTraits::type Geom_traits; + + using parameters::choose_parameter; + using parameters::get_parameter; + + CGAL_precondition(boost::graph_traits::null_halfedge() != h); + + 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)); + + return gt.compute_squared_distance_3_object()(get(vpm, source(h, pmesh)), + get(vpm, target(h, pmesh))); +} + +template +typename CGAL::Kernel_traits::type>::Kernel::FT +squared_edge_length(typename boost::graph_traits::halfedge_descriptor h, + const PolygonMesh& pmesh) +{ + return squared_edge_length(h, pmesh, CGAL::Polygon_mesh_processing::parameters::all_default()); +} +// edge overloads +template +typename GetGeomTraits::type::FT +squared_edge_length(typename boost::graph_traits::edge_descriptor e, + const PolygonMesh& pmesh, + const NamedParameters& np) +{ + return squared_edge_length(halfedge(e, pmesh), pmesh, np); +} + +template +typename CGAL::Kernel_traits::type>::Kernel::FT +squared_edge_length(typename boost::graph_traits::edge_descriptor e, + const PolygonMesh& pmesh) +{ + return squared_edge_length(halfedge(e, pmesh), pmesh); +} + + /** * \ingroup measure_grp * computes the length of the border polyline @@ -158,7 +258,7 @@ edge_length(typename boost::graph_traits::edge_descriptor e, * @tparam PolygonMesh a model of `HalfedgeGraph` * @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" * - * @param h a halfedge of the border polyline of which the length is computed + * @param h a halfedge of the border polyline whose length is computed * @param pmesh the polygon mesh to which `h` belongs * @param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below * @@ -315,10 +415,10 @@ longest_border(const PolygonMesh& pmesh) * computes the area of a face of a given * triangulated surface mesh. * - * @tparam TriangleMesh a model of `HalfedgeGraph` + * @tparam TriangleMesh a model of `FaceGraph` * @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" * - * @param f the face of which the area is computed + * @param f the face whose area is computed * @param tmesh the triangulated surface mesh to which `f` belongs * @param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below * @@ -346,6 +446,11 @@ longest_border(const PolygonMesh& pmesh) * or the geometric traits class deduced from the point property map * of `tmesh`. * + * \warning This function involves a square root computation. + * If `Kernel::FT` does not have a `sqrt()` operation, the square root computation + * will be done approximately. + * + * @sa `squared_face_area()` * @sa `area()` */ template::face_descriptor f, return face_area(f, tmesh, CGAL::Polygon_mesh_processing::parameters::all_default()); } +/** + * \ingroup measure_grp + * computes the squared area of a face of a given + * triangulated surface mesh. + * + * @tparam TriangleMesh a model of `FaceGraph` + * @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" + * + * @param f the face whose squared area is computed + * @param tmesh the triangulated surface mesh to which `f` 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{a class model of `Kernel`} + * \cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`} + * \cgalParamExtra{The geometric traits class must be compatible with the vertex point type.} + * \cgalParamNEnd + * \cgalNamedParamsEnd + * + * @pre `f != boost::graph_traits::%null_face()` + * + * @return the squared area of `f`. + * The return type `FT` is a number type. It is + * 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`. + * + * @sa `face_area()` + */ +template +#ifdef DOXYGEN_RUNNING +FT +#else +typename GetGeomTraits::type::FT +#endif +squared_face_area(typename boost::graph_traits::face_descriptor f, + const TriangleMesh& tmesh, + const CGAL_PMP_NP_CLASS& np) +{ + using parameters::choose_parameter; + using parameters::get_parameter; + + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + + CGAL_precondition(boost::graph_traits::null_face() != f); + + typename GetVertexPointMap::const_type + vpm = choose_parameter(get_parameter(np, internal_np::vertex_point), + get_const_property_map(CGAL::vertex_point, tmesh)); + + halfedge_descriptor hd = halfedge(f, tmesh); + halfedge_descriptor nhd = next(hd, tmesh); + + typedef typename GetGeomTraits::type GT; + GT traits = choose_parameter(get_parameter(np, internal_np::geom_traits)); + + return traits.compute_squared_area_3_object()(get(vpm, source(hd, tmesh)), + get(vpm, target(hd, tmesh)), + get(vpm, target(nhd, tmesh))); +} + +template +typename CGAL::Kernel_traits::type>::Kernel::FT +squared_face_area(typename boost::graph_traits::face_descriptor f, + const TriangleMesh& tmesh) +{ + return squared_face_area(f, tmesh, CGAL::Polygon_mesh_processing::parameters::all_default()); +} + + /** * \ingroup measure_grp * computes the area of a range of faces of a given @@ -398,10 +584,10 @@ face_area(typename boost::graph_traits::face_descriptor f, * @tparam FaceRange range of `boost::graph_traits::%face_descriptor`, model of `Range`. Its iterator type is `InputIterator`. - * @tparam TriangleMesh a model of `HalfedgeGraph` + * @tparam TriangleMesh a model of `FaceGraph` * @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" * - * @param face_range the range of faces of which the area is computed + * @param face_range the range of faces of whose area is computed * @param tmesh the triangulated surface mesh to which the faces of `face_range` belong * @param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below * @@ -468,7 +654,7 @@ area(FaceRange face_range, const TriangleMesh& tmesh) * \ingroup measure_grp * computes the surface area of a triangulated surface mesh. * - * @tparam TriangleMesh a model of `HalfedgeGraph` + * @tparam TriangleMesh a model of `FaceGraph` * @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" * * @param tmesh the triangulated surface mesh @@ -611,7 +797,7 @@ volume(const TriangleMesh& tmesh) * @tparam TriangleMesh a model of `HalfedgeGraph` * @tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" * - * @param f the face of which the aspect ratio is computed + * @param f the face whose aspect ratio is computed * @param tmesh the triangulated surface mesh to which `f` belongs * @param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below * diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_degeneracies.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_degeneracies.h index cb4a1ce9e08..ccad1bf4d50 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_degeneracies.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_degeneracies.h @@ -42,6 +42,7 @@ #include #include #include +#include // First part of the file: remove_ALMOST_degenerate_faces (needles/caps) // Second part of the file: remove_degenerate_edges/faces @@ -338,6 +339,191 @@ bool should_flip(typename boost::graph_traits::edge_descriptor e, return p0p2 <= p1p3; } +template +struct Filter_wrapper_for_cap_needle_removal +{ + Filter_wrapper_for_cap_needle_removal(TriangleMesh& tm, const VPM& vpm, const Functor& functor) + : m_tm(tm) + , m_vpm(vpm) + , m_functor(functor) + {} + + typedef boost::graph_traits Graph_traits; + typedef typename Graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename Graph_traits::edge_descriptor edge_descriptor; + typedef typename Graph_traits::vertex_descriptor vertex_descriptor; + typedef typename Traits::Point_3 Point_3; + + bool flip(halfedge_descriptor h) + { + CGAL_assertion(!is_border(h, m_tm)); + + const Point_3& o1 = get(m_vpm, target(next(h, m_tm), m_tm)); + const Point_3& o2 = get(m_vpm, target(next(opposite(h, m_tm), m_tm), m_tm)); + const Point_3& src = get(m_vpm, source(h,m_tm)); + const Point_3& tgt = get(m_vpm, target(h,m_tm)); + + if (!m_functor(o1, o2, src)) + return false; + + if (!m_functor(o1, o2, tgt)) + return false; + + return true; + } + + bool collapse(edge_descriptor e) + { + halfedge_descriptor h = halfedge(e, m_tm), + oh = opposite(h, m_tm); + vertex_descriptor vkept = target(h, m_tm); + const Point_3& p = get(m_vpm, vkept); + + // look at all the triangles that will be created after the collapse of the edge + // and call the functor using them. If we get a negative answer for one of them + // return false. Code copy/pasted/adapted from SMS package + halfedge_descriptor endleft = next(oh, m_tm); + halfedge_descriptor endright = next(h, m_tm); + + // counterclockwise around src + halfedge_descriptor e02 = opposite(prev(h, m_tm), m_tm); + vertex_descriptor v = target(e02, m_tm), v2 = v; + + while(e02 != endleft) + { + bool is_b = is_border(e02, m_tm); + e02 = opposite(prev(e02, m_tm), m_tm); + v = target(e02, m_tm); + if(!is_b) + if (!m_functor(get(m_vpm,v), p, get(m_vpm,v2))) + return false; + v2 = v; + } + + e02 = opposite(prev(oh, m_tm), m_tm); + + // counterclockwise around tgt + v2 = target(e02, m_tm); + v = v2; + while(e02 != endright) + { + bool is_b = is_border(e02, m_tm); + e02 = opposite(prev(e02, m_tm), m_tm); + v = target(e02, m_tm); + + if(!is_b) + if (!m_functor(get(m_vpm,v),p,get(m_vpm,v2))) + return false; + v2 = v; + } + return true; + } + + TriangleMesh& m_tm; + const VPM& m_vpm; + const Functor& m_functor; +}; + +template +struct Filter_wrapper_for_cap_needle_removal > + : public Filter_wrapper_for_cap_needle_removal +{ + typedef Filter_wrapper_for_cap_needle_removal Base; + + Filter_wrapper_for_cap_needle_removal(TriangleMesh& tm, const VPM& vpm, const std::reference_wrapper& functor_ref) + : Base(tm, vpm, functor_ref.get()) + {} +}; + +template +struct Filter_wrapper_for_cap_needle_removal::face_descriptor>&)> > +{ + typedef boost::graph_traits Graph_traits; + typedef typename Graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename Graph_traits::edge_descriptor edge_descriptor; + typedef typename Graph_traits::face_descriptor face_descriptor; + + typedef Filter_wrapper_for_cap_needle_removal Base; + typedef std::function&)> Make_env; + + Filter_wrapper_for_cap_needle_removal(TriangleMesh& tm, const VPM& vpm, const Make_env& make_envelope) + : m_tm(tm) + , m_vpm(vpm) + , m_make_envelope(make_envelope) + {} + + void collect_link_faces(edge_descriptor e, std::vector& link_faces) + { + halfedge_descriptor h = halfedge(e, m_tm); + halfedge_descriptor h_opp = opposite(h, m_tm); + + halfedge_descriptor endleft = next(h_opp, m_tm); + halfedge_descriptor endright = next(h, m_tm); + + face_descriptor f = face(h, m_tm); + if(f!=boost::graph_traits::null_face()) + link_faces.push_back(f); + f = face(h_opp, m_tm); + if(f!=boost::graph_traits::null_face()) + link_faces.push_back(f); + + // counterclockwise around src + halfedge_descriptor hl = opposite(prev(h, m_tm), m_tm); + + while(hl != endleft) + { + if (!is_border(hl, m_tm)) + link_faces.push_back(face(hl, m_tm)); + hl = opposite(prev(hl, m_tm), m_tm); + } + + // counterclockwise around tgt + hl = opposite(prev(h_opp, m_tm), m_tm); + + while(hl != endright) + { + if (!is_border(hl, m_tm)) + link_faces.push_back(face(hl, m_tm)); + hl = opposite(prev(hl, m_tm), m_tm); + } + } + + bool flip(halfedge_descriptor h) + { + std::vector link_faces; + collect_link_faces(edge(h, m_tm), link_faces); + Functor f = m_make_envelope(link_faces); + Base base(m_tm, m_vpm, f); + return base.flip(h); + } + + bool collapse(edge_descriptor e) + { + std::vector link_faces; + collect_link_faces(e, link_faces); + Functor f = std::move(m_make_envelope(link_faces)); + Base base(m_tm, m_vpm, f); + return base.collapse(e); + } + + TriangleMesh& m_tm; + const VPM& m_vpm; + const Make_env& m_make_envelope; +}; + +template +struct Filter_wrapper_for_cap_needle_removal > +{ + Filter_wrapper_for_cap_needle_removal(TriangleMesh&, const VPM&, Identity) {} + + typedef boost::graph_traits Graph_traits; + typedef typename Graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename Graph_traits::edge_descriptor edge_descriptor; + + bool flip(halfedge_descriptor){ return true; } + bool collapse(edge_descriptor){ return true; } +}; + } // namespace internal namespace experimental { @@ -378,6 +564,16 @@ bool remove_almost_degenerate_faces(const FaceRange& face_range, typedef typename GetGeomTraits::type Traits; Traits gt = choose_parameter(get_parameter(np, internal_np::geom_traits), Traits()); + typedef typename internal_np::Lookup_named_param_def< + internal_np::filter_t, + NamedParameters, + Identity + > ::type User_filter; + User_filter user_filter = choose_parameter>(get_parameter(np, internal_np::filter)); + + typedef internal::Filter_wrapper_for_cap_needle_removal Accept_change_functor; + Accept_change_functor accept_change(tmesh, vpm, user_filter); + // Vertex property map that combines the VCM and the fact that extremities of a constrained edge should be constrained typedef CGAL::dynamic_vertex_property_t Vertex_property_tag; typedef typename boost::property_map::type DVCM; @@ -495,6 +691,15 @@ bool remove_almost_degenerate_faces(const FaceRange& face_range, continue; } + if (!accept_change.collapse(edge(best_h, tmesh))) + { +#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES_EXTRA + std::cout << "\t edge collapse prevented by the user functor" << std::endl; +#endif + next_edges_to_collapse.insert(h); + continue; + } + // Proceeding with the collapse, purge the sets from halfedges being removed for(int i=0; i<2; ++i) { @@ -642,6 +847,14 @@ bool remove_almost_degenerate_faces(const FaceRange& face_range, continue; } + if (!accept_change.flip(h)) + { +#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES_EXTRA + std::cout << "\t Flipping prevented: rejected by user functor" << std::endl; +#endif + continue; + } + #ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES_EXTRA std::cout << "\t step " << kk << " -- Flipping" << std::endl; #endif diff --git a/Polygon_mesh_processing/include/CGAL/Rigid_triangle_mesh_collision_detection.h b/Polygon_mesh_processing/include/CGAL/Rigid_triangle_mesh_collision_detection.h index c93f3338999..927fed1fe89 100644 --- a/Polygon_mesh_processing/include/CGAL/Rigid_triangle_mesh_collision_detection.h +++ b/Polygon_mesh_processing/include/CGAL/Rigid_triangle_mesh_collision_detection.h @@ -246,11 +246,7 @@ public: { // handle vpm typedef typename CGAL::GetVertexPointMap::const_type Local_vpm; - CGAL_USE_TYPE(Local_vpm); - - CGAL_assertion_code( - static const bool same_vpm = (boost::is_same::value); ) - CGAL_static_assertion(same_vpm); + CGAL_static_assertion( (boost::is_same::value) ); Vpm vpm = parameters::choose_parameter(parameters::get_parameter(np, internal_np::vertex_point), @@ -562,11 +558,7 @@ public: parameters::get_parameter(np, internal_np::apply_per_connected_component), true); typedef typename CGAL::GetVertexPointMap::const_type Local_vpm; - CGAL_USE_TYPE(Local_vpm); - - CGAL_assertion_code( - static const bool same_vpm = (boost::is_same::value); ) - CGAL_static_assertion(same_vpm); + CGAL_static_assertion((boost::is_same::value)); Vpm vpm = parameters::choose_parameter(parameters::get_parameter(np, internal_np::vertex_point), diff --git a/Polygon_mesh_processing/package_info/Polygon_mesh_processing/dependencies b/Polygon_mesh_processing/package_info/Polygon_mesh_processing/dependencies index e0691224967..6d471658093 100644 --- a/Polygon_mesh_processing/package_info/Polygon_mesh_processing/dependencies +++ b/Polygon_mesh_processing/package_info/Polygon_mesh_processing/dependencies @@ -35,3 +35,4 @@ TDS_3 Triangulation_2 Triangulation_3 Union_find +Weights diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/measures_test.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/measures_test.cpp index b8db4721474..ffb8824f406 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/measures_test.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/measures_test.cpp @@ -55,6 +55,13 @@ void test_pmesh(const Mesh& pmesh) continue; else { + FT edge_length = PMP::edge_length(h, pmesh); + FT squared_edge_length = PMP::squared_edge_length(h, pmesh); + std::cout << "squared edge length = " << squared_edge_length << std::endl; + std::cout << "edge length = " << edge_length << std::endl; + + FT squared_face_area = PMP::squared_face_area(face(h, pmesh), pmesh); + std::cout << "squared face area = " << squared_face_area << std::endl; FT face_area = PMP::face_area(face(h, pmesh), pmesh); std::cout << "face area = " << face_area << std::endl; assert(face_area > 0); diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_detect_features.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_detect_features.cpp index 1e0994c78b0..62dc602d5e4 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_detect_features.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_detect_features.cpp @@ -2,92 +2,130 @@ #include #include +#include #include -typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef CGAL::Surface_mesh Mesh; -typedef boost::graph_traits::face_descriptor face_descriptor; -typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef CGAL::Surface_mesh Mesh; + +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::face_descriptor face_descriptor; namespace PMP = CGAL::Polygon_mesh_processing; -int main(int argc, char* argv[]) +void test_cube() { - const char* filename = (argc > 1) ? argv[1] : "data/cube_quad.off"; - std::ifstream input(filename); + std::cout << "Test cube..." << std::endl; - Mesh mesh; - if (!input || !(input >> mesh)) - { - std::cerr << "Not a valid input file." << std::endl; - return 1; - } + std::ifstream input("data/cube_quad.off"); + Mesh mesh; + if(!input || !(input >> mesh)) + { + std::cerr << "Failed to read cube_quad.off input." << std::endl; + assert(false); + return; + } - typedef boost::property_map >::type PatchID; - typedef boost::property_map >::type VIP; - typedef boost::property_map::type EIF_map; + typedef boost::property_map >::type PatchID; + typedef boost::property_map >::type VIP; + typedef boost::property_map::type EIF_map; - PatchID pid = get(CGAL::face_patch_id_t(), mesh); - VIP vip = get(CGAL::vertex_incident_patches_t(), mesh); - EIF_map eif = get(CGAL::edge_is_feature, mesh); - std::size_t number_of_patches - = PMP::sharp_edges_segmentation(mesh, 90, eif, pid); + PatchID pid = get(CGAL::face_patch_id_t(), mesh); + VIP vip = get(CGAL::vertex_incident_patches_t(), mesh); + EIF_map eif = get(CGAL::edge_is_feature, mesh); + std::size_t number_of_patches = PMP::sharp_edges_segmentation(mesh, 90, eif, pid); - std::size_t nb_sharp_edges = 0; - for(boost::graph_traits::edge_descriptor e : edges(mesh)) - { - if(get(eif, e)) - ++nb_sharp_edges; - } + std::size_t nb_sharp_edges = 0; + for(boost::graph_traits::edge_descriptor e : edges(mesh)) + { + if(get(eif, e)) + ++nb_sharp_edges; + } - CGAL_assertion(nb_sharp_edges == 12); - CGAL_assertion(number_of_patches == 6); - CGAL_USE(number_of_patches); + assert(nb_sharp_edges == 12); + assert(number_of_patches == 6); + CGAL_USE(number_of_patches); - number_of_patches - = PMP::sharp_edges_segmentation(mesh, 90, eif, pid, - PMP::parameters::first_index(1) - .vertex_incident_patches_map(vip)); + number_of_patches = PMP::sharp_edges_segmentation(mesh, 90, eif, pid, + PMP::parameters::first_index(1) + .vertex_incident_patches_map(vip)); - CGAL_assertion(number_of_patches == 6); - - PMP::detect_sharp_edges(mesh, 90, eif); - number_of_patches = PMP::internal::detect_surface_patches(mesh, pid, eif); - PMP::detect_vertex_incident_patches(mesh, pid, vip, eif); - - nb_sharp_edges = 0; - for(boost::graph_traits::edge_descriptor e : edges(mesh)) - { - if(get(eif, e)) - ++nb_sharp_edges; - } + assert(number_of_patches == 6); - CGAL_assertion(nb_sharp_edges == 12); - CGAL_assertion(number_of_patches == 6); + number_of_patches = PMP::internal::detect_surface_patches(mesh, pid, eif); + PMP::detect_vertex_incident_patches(mesh, pid, vip, eif); - Mesh::Property_map > patch_id_map - = mesh.add_property_map >("f:pid",std::pair()).first; - Mesh::Property_map > > vertex_incident_patch_map - = mesh.add_property_map > >("f:vip",std::set >()).first; - PMP::detect_sharp_edges(mesh, 90, eif); - number_of_patches - = PMP::internal::detect_surface_patches(mesh, patch_id_map, eif, - PMP::parameters::first_index(1)); - PMP::detect_vertex_incident_patches(mesh, patch_id_map, vertex_incident_patch_map, eif); + nb_sharp_edges = 0; + for(boost::graph_traits::edge_descriptor e : edges(mesh)) + { + if(get(eif, e)) + ++nb_sharp_edges; + } - nb_sharp_edges =0; - for(boost::graph_traits::edge_descriptor e : edges(mesh)) - { - if(get(eif, e)) - ++nb_sharp_edges; - } + assert(nb_sharp_edges == 12); + assert(number_of_patches == 6); - CGAL_assertion(nb_sharp_edges == 12); - CGAL_assertion(number_of_patches == 6); + Mesh::Property_map > patch_id_map + = mesh.add_property_map >("f:pid",std::pair()).first; + Mesh::Property_map > > vertex_incident_patch_map + = mesh.add_property_map > >("f:vip",std::set >()).first; + PMP::detect_sharp_edges(mesh, 90, eif); + number_of_patches = PMP::internal::detect_surface_patches(mesh, patch_id_map, eif, + PMP::parameters::first_index(1)); + PMP::detect_vertex_incident_patches(mesh, patch_id_map, vertex_incident_patch_map, eif); - return 0; + nb_sharp_edges =0; + for(boost::graph_traits::edge_descriptor e : edges(mesh)) + { + if(get(eif, e)) + ++nb_sharp_edges; + } + + assert(nb_sharp_edges == 12); + assert(number_of_patches == 6); } +void test_blobby() +{ + std::cout << "Test blobby..." << std::endl; + std::ifstream input("data/blobby.off"); + Mesh mesh; + if(!input || !(input >> mesh)) + { + std::cerr << "Failed to read blobby.off input." << std::endl; + assert(false); + return; + } + + typedef CGAL::dynamic_edge_property_t EIF_tag; + typedef boost::property_map::type EIF; + + EIF eif = get(EIF_tag(), mesh); + + CGAL::Real_timer timer; + timer.start(); + + PMP::detect_sharp_edges(mesh, 5, eif); + + timer.stop(); + std::cout << "Elapsed: " << timer.time() << std::endl; + + unsigned int nb_sharp_edges = 0; + for(auto e : edges(mesh)) + if(get(eif, e)) + ++nb_sharp_edges; + + std::cout << "Found " << nb_sharp_edges << " sharp edges" << std::endl; + assert(nb_sharp_edges == 2565); +} + +int main(int, char**) +{ + test_cube(); + test_blobby(); + + return EXIT_SUCCESS; +} 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 91d4754c4da..cf1c5baa60a 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 @@ -620,7 +620,7 @@ struct Locate_with_AABB_tree_Tester // 3D typedef CGAL::AABB_face_graph_triangle_primitive AABB_face_graph_primitive; typedef CGAL::AABB_traits AABB_face_graph_traits; - CGAL_assertion_code(typedef typename K::Point_3 Point_3;) + typedef typename K::Point_3 Point_3; CGAL_static_assertion((std::is_same::value)); CGAL::AABB_tree tree_a; diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_remove_caps_needles.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_remove_caps_needles.cpp index cc9733d4c34..04da8e6a05d 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_remove_caps_needles.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_remove_caps_needles.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -17,20 +18,22 @@ typedef boost::graph_traits::face_descriptor face_descriptor; namespace PMP = CGAL::Polygon_mesh_processing; -int main(int argc, char** argv) +typedef CGAL::Polyhedral_envelope Envelope; + +void general_test(std::string filename) { - const char* filename = (argc > 1) ? argv[1] : "data/pig.off"; + std::cout << "Removing caps/needles no extra parameters\n"; std::ifstream input(filename); Mesh mesh; if (!input || !(input >> mesh) || !CGAL::is_triangle_mesh(mesh)) { std::cerr << "Not a valid input file." << std::endl; - return 1; + exit(EXIT_FAILURE); } - std::cout << "Input mesh has " << edges(mesh).size() << " edges\n"; + std::cout << " Input mesh has " << edges(mesh).size() << " edges\n"; if (PMP::does_self_intersect(mesh)) - std::cout << "Input mesh has self-intersections\n"; + std::cout << " Input mesh has self-intersections\n"; PMP::experimental::remove_almost_degenerate_faces(mesh, std::cos(160. / 180 * CGAL_PI), @@ -40,9 +43,91 @@ int main(int argc, char** argv) CGAL::IO::write_polygon_mesh("cleaned_mesh.off", mesh, CGAL::parameters::stream_precision(17)); - std::cout << "Output mesh has " << edges(mesh).size() << " edges\n"; + std::cout << " Output mesh has " << edges(mesh).size() << " edges\n"; if (PMP::does_self_intersect(mesh)) - std::cout << "Output mesh has self-intersections\n"; + std::cout << " Output mesh has self-intersections\n"; +} + +void test_with_envelope(std::string filename, double eps) +{ + std::cout << "Removing caps/needles with envelope, epsilon = " << eps << "\n"; + std::ifstream input(filename); + + Mesh mesh, bk; + if (!input || !(input >> mesh) || !CGAL::is_triangle_mesh(mesh)) { + std::cerr << "Not a valid input file." << std::endl; + exit(EXIT_FAILURE); + } + + if (PMP::does_self_intersect(mesh)) + std::cout << " Input mesh has self-intersections\n"; + + // first a test where nothing should be done + struct No_modification_allowed + { + bool operator()(K::Point_3, K::Point_3, K::Point_3) const { return false; } + }; + No_modification_allowed no_modif; + const std::size_t nbv = vertices(mesh).size(); + PMP::experimental::remove_almost_degenerate_faces(mesh, + std::cos(160. / 180 * CGAL_PI), + 4, + 0.14, + CGAL::parameters::filter(no_modif)); + assert(nbv == vertices(mesh).size()); + + // now the real test with a fixed envelope + std::cout << "Using fixed envelope\n"; + std::cout << " Input mesh has " << edges(mesh).size() << " edges\n"; + bk=mesh; + Envelope envelope(mesh, eps); + PMP::experimental::remove_almost_degenerate_faces(mesh, + std::cos(160. / 180 * CGAL_PI), + 4, + 0.14, + CGAL::parameters::filter(std::ref(envelope))); + + CGAL::IO::write_polygon_mesh("cleaned_mesh_with_envelope.off", mesh, CGAL::parameters::stream_precision(17)); + + std::cout << " Output mesh has " << edges(mesh).size() << " edges\n"; + if (PMP::does_self_intersect(mesh)) + std::cout << " Output mesh has self-intersections\n"; + + + // now the real test with an iterative envelope + mesh=bk; + std::cout << "Using iteratively created fixed envelope\n"; + std::cout << " Input mesh has " << edges(mesh).size() << " edges\n"; + auto create_envelope = [&](const std::vector& frange) -> Envelope + { + return Envelope(frange, mesh, eps); + }; + std::function&)> filter(create_envelope); + PMP::experimental::remove_almost_degenerate_faces(mesh, + std::cos(160. / 180 * CGAL_PI), + 4, + 0.14, + CGAL::parameters::filter(filter)); + + CGAL::IO::write_polygon_mesh("cleaned_mesh_with_iterative_envelope.off", mesh, CGAL::parameters::stream_precision(17)); + + std::cout << " Output mesh has " << edges(mesh).size() << " edges\n"; + if (PMP::does_self_intersect(mesh)) + std::cout << " Output mesh has self-intersections\n"; +} + + + +int main(int argc, char** argv) +{ + const char* filename = (argc > 1) ? argv[1] : "data/pig.off"; + + general_test(filename); + if (argc==2) + test_with_envelope(filename, 0.01); + else + if (argc==3) + test_with_envelope(filename, atof(argv[2])); return 0; } diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/triangulate_hole_Polyhedron_3_no_delaunay_test.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/triangulate_hole_Polyhedron_3_no_delaunay_test.cpp index 3dc4125306c..5e071d05055 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/triangulate_hole_Polyhedron_3_no_delaunay_test.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/triangulate_hole_Polyhedron_3_no_delaunay_test.cpp @@ -16,6 +16,8 @@ #include +#include + #include #include #include @@ -336,16 +338,16 @@ void test_triangulate_refine_and_fair_hole_compile() { read_poly_with_borders("elephant_quad_hole.off", poly, border_reps); CGAL::Polygon_mesh_processing::triangulate_refine_and_fair_hole (poly, border_reps[0], back_inserter(patch_facets), back_inserter(patch_vertices), - CGAL::Polygon_mesh_processing::parameters::weight_calculator( - CGAL::internal::Uniform_weight_fairing(poly)). + CGAL::Polygon_mesh_processing::parameters:: + weight_calculator(CGAL::Weights::Uniform_weight()). sparse_linear_solver(Default_solver())); // default solver read_poly_with_borders("elephant_quad_hole.off", poly, border_reps); CGAL::Polygon_mesh_processing::triangulate_refine_and_fair_hole (poly, border_reps[0], back_inserter(patch_facets), back_inserter(patch_vertices), - CGAL::Polygon_mesh_processing::parameters::weight_calculator( - CGAL::internal::Uniform_weight_fairing(poly))); + CGAL::Polygon_mesh_processing::parameters:: + weight_calculator(CGAL::Weights::Uniform_weight())); // default solver and weight read_poly_with_borders("elephant_quad_hole.off", poly, border_reps); diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/triangulate_hole_Polyhedron_3_test.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/triangulate_hole_Polyhedron_3_test.cpp index fd8e8448a7b..a83038f56d3 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/triangulate_hole_Polyhedron_3_test.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/triangulate_hole_Polyhedron_3_test.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -326,16 +327,17 @@ void test_triangulate_refine_and_fair_hole_compile() { read_poly_with_borders("elephant_quad_hole.off", poly, border_reps); CGAL::Polygon_mesh_processing::triangulate_refine_and_fair_hole (poly, border_reps[0], back_inserter(patch_facets), back_inserter(patch_vertices), - CGAL::Polygon_mesh_processing::parameters::weight_calculator( - CGAL::internal::Uniform_weight_fairing(poly)). - sparse_linear_solver(Default_solver()).use_2d_constrained_delaunay_triangulation(false)); + CGAL::Polygon_mesh_processing::parameters:: + weight_calculator(CGAL::Weights::Uniform_weight()). + sparse_linear_solver(Default_solver()). + use_2d_constrained_delaunay_triangulation(false)); // default solver read_poly_with_borders("elephant_quad_hole.off", poly, border_reps); CGAL::Polygon_mesh_processing::triangulate_refine_and_fair_hole (poly, border_reps[0], back_inserter(patch_facets), back_inserter(patch_vertices), - CGAL::Polygon_mesh_processing::parameters::weight_calculator( - CGAL::internal::Uniform_weight_fairing(poly))); + CGAL::Polygon_mesh_processing::parameters:: + weight_calculator(CGAL::Weights::Uniform_weight())); // default solver and weight read_poly_with_borders("elephant_quad_hole.off", poly, border_reps); diff --git a/Polygonal_surface_reconstruction/include/CGAL/Polygonal_surface_reconstruction/internal/compute_confidences.h b/Polygonal_surface_reconstruction/include/CGAL/Polygonal_surface_reconstruction/internal/compute_confidences.h index 9c1deeae355..416b4abd0c7 100644 --- a/Polygonal_surface_reconstruction/include/CGAL/Polygonal_surface_reconstruction/internal/compute_confidences.h +++ b/Polygonal_surface_reconstruction/include/CGAL/Polygonal_surface_reconstruction/internal/compute_confidences.h @@ -141,8 +141,10 @@ namespace internal { // The last point in the polygon if (!plg.is_empty()) { const Point2& r = plg[plg.size() - 1]; - if (CGAL::squared_distance(q, r) < CGAL::snap_squared_distance_threshold()) + if (CGAL::squared_distance(q, r) < CGAL::snap_squared_distance_threshold()) { + ++cir; continue; + } } plg.push_back(q); diff --git a/Polyhedron/demo/Polyhedron/CMakeLists.txt b/Polyhedron/demo/Polyhedron/CMakeLists.txt index cf3d94bc7fa..ade09e4d836 100644 --- a/Polyhedron/demo/Polyhedron/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/CMakeLists.txt @@ -249,17 +249,25 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND) add_to_cached_list(CGAL_EXECUTABLE_TARGETS ${item_name}) endmacro(add_item) + add_item(scene_triangulation_3_item Scene_triangulation_3_item.cpp) + target_link_libraries(scene_triangulation_3_item PUBLIC scene_basic_objects) + add_item(scene_c3t3_item Scene_c3t3_item.cpp) target_link_libraries( - scene_c3t3_item PUBLIC scene_surface_mesh_item scene_polygon_soup_item - scene_basic_objects ${TBB_LIBRARIES}) + scene_c3t3_item PUBLIC scene_triangulation_3_item + scene_surface_mesh_item scene_polygon_soup_item + scene_basic_objects ${TBB_LIBRARIES}) + if(TARGET CGAL::TBB_support) target_link_libraries(scene_c3t3_item PUBLIC CGAL::TBB_support) + target_link_libraries(scene_triangulation_3_item PUBLIC CGAL::TBB_support) endif() if(COMMAND target_precompile_headers) # Support for precompiled headers, for Mesh_3 (since CMake 3.16) target_precompile_headers(scene_c3t3_item PUBLIC [["C3t3_type.h"]]) endif() + add_item(scene_tetrahedra_item Scene_tetrahedra_item.cpp) + target_link_libraries(scene_tetrahedra_item PUBLIC scene_c3t3_item) add_item(scene_transform_item Plugins/PCA/Scene_facegraph_transform_item.cpp) add_item(scene_edit_box_item Plugins/PCA/Scene_edit_box_item.cpp) add_item(scene_image_item Scene_image_item.cpp) diff --git a/Polyhedron/demo/Polyhedron/Edge_container.cpp b/Polyhedron/demo/Polyhedron/Edge_container.cpp index 50584f8e94f..76a7ed7b463 100644 --- a/Polyhedron/demo/Polyhedron/Edge_container.cpp +++ b/Polyhedron/demo/Polyhedron/Edge_container.cpp @@ -110,6 +110,15 @@ void Edge_container::initGL(Viewer_interface *viewer) if(!getTexture()) setTexture(new Texture()); } + if(viewer->getShaderProgram(getProgram())->property("hasSubdomainIndicesValues").toBool()) + { + if(!getVbo(Subdomain_indices)) + setVbo(Subdomain_indices, + new Vbo("subdomain_in", + Vbo::GEOMETRY, + QOpenGLBuffer::VertexBuffer, GL_FLOAT, 0, 2)); + getVao(viewer)->addVbo(getVbo(Subdomain_indices)); + } } } setGLInit(viewer, true); diff --git a/Polyhedron/demo/Polyhedron/MainWindow.cpp b/Polyhedron/demo/Polyhedron/MainWindow.cpp index 284f118bbd0..b595087b242 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.cpp +++ b/Polyhedron/demo/Polyhedron/MainWindow.cpp @@ -185,7 +185,7 @@ MainWindow::MainWindow(const QStringList &keywords, bool verbose, QWidget* paren CGAL::Three::Three::s_scene = scene; CGAL::Three::Three::s_connectable_scene = scene; { - QShortcut* shortcut = new QShortcut(QKeySequence(Qt::ALT+Qt::Key_Q), this); + QShortcut* shortcut = new QShortcut(QKeySequence(Qt::ALT,Qt::Key_Q), this); connect(shortcut, SIGNAL(activated()), this, SLOT(setFocusToQuickSearch())); shortcut = new QShortcut(QKeySequence(Qt::Key_F5), this); @@ -194,10 +194,10 @@ MainWindow::MainWindow(const QStringList &keywords, bool verbose, QWidget* paren shortcut = new QShortcut(QKeySequence(Qt::Key_F11), this); connect(shortcut, SIGNAL(activated()), this, SLOT(toggleFullScreen())); - shortcut = new QShortcut(QKeySequence(Qt::CTRL+Qt::Key_R), this); + shortcut = new QShortcut(QKeySequence(Qt::CTRL,Qt::Key_R), this); connect(shortcut, &QShortcut::activated, this, &MainWindow::recenterScene); - shortcut = new QShortcut(QKeySequence(Qt::CTRL+Qt::Key_T), this); + shortcut = new QShortcut(QKeySequence(Qt::CTRL,Qt::Key_T), this); connect(shortcut, &QShortcut::activated, this, [](){ diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt index 2fe2eafed6d..f11a57e817e 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt @@ -50,6 +50,9 @@ set_package_properties( DESCRIPTION "A library for image processing." PURPOSE "Can be used for I/O (DICOM, VTU, VTP.") +polyhedron_demo_plugin(triangulation_3_io_plugin triangulation_3_io_plugin KEYWORDS IO) +target_link_libraries(triangulation_3_io_plugin PUBLIC scene_triangulation_3_item) + if(VTK_FOUND) if(VTK_USE_FILE) include(${VTK_USE_FILE}) diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/triangulation_3_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/triangulation_3_io_plugin.cpp new file mode 100644 index 00000000000..37bf23b7494 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/triangulation_3_io_plugin.cpp @@ -0,0 +1,94 @@ +#include +#include +#include "T3_type.h" +#include +#include +#include "Scene_triangulation_3_item.h" + +class Triangulation_3_io_plugin : + public QObject, + public CGAL::Three::Polyhedron_demo_io_plugin_interface +{ + Q_OBJECT + Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface) + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90" FILE "triangulation_3_io_plugin.json") + +public: + + QString name() const override{ return "triangulation_3_io_plugin"; } + + QString nameFilters() const override{ return "T3 files(*.ascii.cgal);;T3 binary files (*.binary.cgal)"; } + + + bool canLoad(QFileInfo) const override{ return true; } + + QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true) override{ + + // Open file + std::ifstream ifs(fileinfo.filePath().toUtf8()); + if(!ifs) { + std::cerr << "Error! Cannot open file " << (const char*)fileinfo.filePath().toUtf8() << std::endl; + ok = false; + return QList(); + } + T3 tr;; + + if(fileinfo.absoluteFilePath().endsWith(".binary.cgal")) + CGAL::set_binary_mode(ifs); + ifs >> tr; + if(ifs.fail() || !tr.is_valid(false)) { + std::cerr << "Error! Cannot open file " << (const char*)fileinfo.filePath().toUtf8() << std::endl; + ok = false; + return QList(); + } + Scene_triangulation_3_item* new_item = new Scene_triangulation_3_item(tr); + new_item->setName(fileinfo.fileName()); + new_item->invalidateOpenGLBuffers(); + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(new_item); + ok = true; + return QList()<(item); + } + + bool save(QFileInfo fileinfo, QList &items)override{ + for(int id : CGAL::Three::Three::scene()->selectionIndices()) + { + Scene_item* item = CGAL::Three::Three::scene()->item(id); + const Scene_triangulation_3_item* t3_item = qobject_cast(item); + if (!t3_item) + { + continue; + } + + QString path = fileinfo.absoluteFilePath(); + + std::ofstream out(fileinfo.filePath().toUtf8()); + if(path.endsWith(".binary.cgal")) + { + CGAL::set_binary_mode(out); + } + else + { + CGAL::set_ascii_mode(out); + } + out << t3_item->triangulation(); + if( out.fail()) + return false; + else + { + items.pop_front(); + return true; + } + } + return false; + } + +}; + +#include "triangulation_3_io_plugin.moc" diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/C3t3_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/C3t3_io_plugin.cpp index ed29a004b31..755e5e8730e 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/C3t3_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/C3t3_io_plugin.cpp @@ -90,17 +90,19 @@ Polyhedron_demo_c3t3_binary_io_plugin::load( if(item->load_binary(in)) { - if(add_to_scene) + if(add_to_scene){ + item->resetCutPlane(); CGAL::Three::Three::scene()->addItem(item); + } return QList() << item; } item->c3t3().clear(); in.seekg(0); if(try_load_other_binary_format(in, item->c3t3())) { + item->resetCutPlane(); item->c3t3_changed(); item->changed(); - item->resetCutPlane(); if(add_to_scene) CGAL::Three::Three::scene()->addItem(item); return QList()<< item; @@ -109,9 +111,9 @@ Polyhedron_demo_c3t3_binary_io_plugin::load( item->c3t3().clear(); in.seekg(0); if(try_load_a_cdt_3(in, item->c3t3())) { + item->resetCutPlane(); item->c3t3_changed(); item->changed(); - item->resetCutPlane(); if(add_to_scene) CGAL::Three::Three::scene()->addItem(item); return QList()<c3t3_changed(); item->resetCutPlane(); + item->c3t3_changed(); if(add_to_scene) CGAL::Three::Three::scene()->addItem(item); return QList()< + + TetraFilterWidget + + + + 0 + 0 + 561 + 579 + + + + Only the tetrahedra with the values associated with the criterion that are inside the interval will be displayed. + + + Tetrahedra Properties + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + Min Dihedral Angle + + + + + Max Dihedral Angle + + + + + Radius - Radius Ratio + + + + + Volume + + + + + Subdomain + + + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Reset Item + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1000 + + + 1 + + + 0 + + + Qt::Horizontal + + + QSlider::NoTicks + + + 1 + + + + + + + + + + + + + + + + + + + + + + + + + 1000 + + + 1000 + + + Qt::Horizontal + + + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + QFrame::NoFrame + + + Filtering Interval: [ + + + + + + + + + + + + + + + + + ; + + + + + + + + + + ] + + + + + + + + + + + + + + + + DoubleEdit + QLineEdit +
CGAL_double_edit.h
+
+
+ + +
diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Tetrahedra_filtering_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Tetrahedra_filtering_plugin.cpp new file mode 100644 index 00000000000..ce75e3eafd3 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Tetrahedra_filtering_plugin.cpp @@ -0,0 +1,205 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "Scene_c3t3_item.h" +#include "Scene_tetrahedra_item.h" +#include "Messages_interface.h" +#include "CGAL_double_edit.h" +#include "ui_Tetrahedra_filter_widget.h" +using namespace CGAL::Three; + +class DockWidget : + public QDockWidget, + public Ui::TetraFilterWidget +{ +public: + DockWidget(QString name, QWidget *parent) + :QDockWidget(name,parent) + { + setupUi(this); + } +}; + + +class Q_DECL_EXPORT Tetrahedra_filtering_plugin: + public QObject, + public Polyhedron_demo_plugin_helper +{ + Q_OBJECT + Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "tetrahedra_filtering_plugin.json") +public : + + void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, Messages_interface*)Q_DECL_OVERRIDE { + this->scene = scene_interface; + this->mw = mainWindow; + this->tet_item = nullptr; + + + QAction* actionFilterTets = new QAction("Tetrahedra Filtering", mw); + if(actionFilterTets) { + connect(actionFilterTets, &QAction::triggered, + this, &Tetrahedra_filtering_plugin::on_actionFilterTets_triggered); + _actions << actionFilterTets; + } + + dock_widget = new DockWidget("", mw); + dock_widget->setVisible(false); // do not show at the beginning + dock_widget->domainBox->hide(); + addDockWidget(dock_widget); + + connect(dock_widget->resetButton, &QPushButton::clicked, [this](){ + filter(); + }); + } + bool applicable(QAction*) const Q_DECL_OVERRIDE + { + return qobject_cast( scene->item( scene->mainSelectionIndex() ) ); + } + QList actions() const Q_DECL_OVERRIDE { + return _actions; + } + virtual void closure() override + { + dock_widget->hide(); + } + +public Q_SLOTS: + void onFilterIndexChanged(int i) + { + if(i != 4) + { + tet_item->setVisible(true); + tet_item->c3t3_item()->setVisible(false); + tet_item->setFilter(i); + dock_widget->domainBox->hide(); + dock_widget->intervalBox->show(); + } + else + { + tet_item->setVisible(false); + tet_item->c3t3_item()->setVisible(true); + dock_widget->intervalBox->hide(); + dock_widget->domainBox->show(); + filter(); + } + + } + void on_actionFilterTets_triggered() + { + const Scene_interface::Item_id index = scene->mainSelectionIndex(); + Scene_c3t3_item* c3t3_item = qobject_cast(scene->item(index)); + + if (!c3t3_item ) //shouldn't happen thanks to applicable() + { + return; + } + if(tet_item) + { + scene->erase(this->scene->item_id(tet_item)); + } + tet_item = new Scene_tetrahedra_item(c3t3_item); + connect(c3t3_item, &Scene_c3t3_item::aboutToBeDestroyed, this, [this](){ + this->scene->erase(this->scene->item_id(this->tet_item)); + this->tet_item = nullptr; + }); + connect(tet_item, &Scene_tetrahedra_item::aboutToBeDestroyed, dock_widget, &DockWidget::hide); + tet_item->setMinMinLabelPointer(dock_widget->minMinLabel); + tet_item->setMinMaxLabelPointer(dock_widget->minMaxLabel); + tet_item->setMaxMinLabelPointer(dock_widget->maxMinLabel); + tet_item->setMaxMaxLabelPointer(dock_widget->maxMaxLabel); + tet_item->setMinEditPointer(dock_widget->minEdit); + tet_item->setMaxEditPointer(dock_widget->maxEdit); + tet_item->invalidateOpenGLBuffers(); + tet_item->setName(QString("%1 filter").arg(c3t3_item->name())); + c3t3_item->setVisible(false); + scene->addItem(tet_item); + connect(dock_widget->minSlider, &QSlider::valueChanged, tet_item, QOverload::of(&Scene_tetrahedra_item::setMinThreshold)); + connect(dock_widget->maxSlider, &QSlider::valueChanged, tet_item, QOverload::of(&Scene_tetrahedra_item::setMaxThreshold)); + connect(dock_widget->filterBox, QOverload::of(&QComboBox::currentIndexChanged), this, &Tetrahedra_filtering_plugin::onFilterIndexChanged); + connect(dock_widget->minEdit, &DoubleEdit::editingFinished, tet_item, QOverload<>::of(&Scene_tetrahedra_item::setMinThreshold)); + connect(dock_widget->maxEdit, &DoubleEdit::editingFinished, tet_item, QOverload<>::of(&Scene_tetrahedra_item::setMaxThreshold)); + + dock_widget->show(); + } + + void cleanup() + { + while(!buttons.empty()) + { + auto button = buttons.back(); + buttons.pop_back(); + dock_widget->gridLayout->removeWidget(button); + buttons.removeAll(button); + delete button; + } + dock_widget->hide(); + } + + void filter() + { + if(!tet_item) + return; + Scene_c3t3_item* c3t3_item = tet_item->c3t3_item(); + if(c3t3_item->subdomain_indices().size() > 96) + { + QMessageBox::warning(nullptr, "Warning", tr("The filtering is only available for items with less than 96 subdomains, and this one has %1").arg(c3t3_item->subdomain_indices().size())); + return; + } + int counter = 0; + int limit = static_cast(std::ceil(CGAL::approximate_sqrt(EPICK::FT(c3t3_item->subdomain_indices().size())))); + QGridLayout *layout = dock_widget->gridLayout; + for (std::set::iterator it = c3t3_item->subdomain_indices().begin(), + end = c3t3_item->subdomain_indices().end(); it != end; ++it) + { + int index = *it; + QPushButton* button = new QPushButton(tr("%1").arg(index)); + buttons.push_back(button); + button->setCheckable(true); + button->setChecked(true); + QColor color = c3t3_item->getSubdomainIndexColor(index); + QString s("QPushButton { font-weight: bold; background: #" + + QString::number(90,16) + + QString::number(90,16) + + QString::number(90,16) + + "; color: red;} QPushButton:checked{ font-weight: bold; background: #" + + QString::number(color.red(),16) + + QString::number(color.green(),16) + + QString::number(color.blue(),16) + + "; color: black;}" + ); + + button->setStyleSheet(s); + connect(button, &QPushButton::toggled, [index, c3t3_item](bool){ + c3t3_item->switchVisibleSubdomain(index); + c3t3_item->computeIntersection(); + c3t3_item->redraw(); + + }); + layout->addWidget(button,counter/limit, counter%limit); + ++counter; + + } + + + connect(c3t3_item, &Scene_c3t3_item::aboutToBeDestroyed, this, &Tetrahedra_filtering_plugin::cleanup); + } + +private: + DockWidget* dock_widget; + QList _actions; + Scene_tetrahedra_item* tet_item; + QVector buttons; + + +}; //end of class Tetrahedra_filtering_plugin +#include "Tetrahedra_filtering_plugin.moc" diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Fairing_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Fairing_plugin.cpp index 93c130d4854..d20d302e43f 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Fairing_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Fairing_plugin.cpp @@ -13,6 +13,7 @@ typedef Scene_surface_mesh_item Scene_facegraph_item; #include #include #include +#include #include #include @@ -98,7 +99,8 @@ public Q_SLOTS: if(weight_index == 1) CGAL::Polygon_mesh_processing::fair(*selection_item->polyhedron(), selection_item->selected_vertices, - CGAL::Polygon_mesh_processing::parameters::weight_calculator(CGAL::internal::Uniform_weight_fairing(*selection_item->polyhedron())). + CGAL::Polygon_mesh_processing::parameters:: + weight_calculator(CGAL::Weights::Uniform_weight()). fairing_continuity(continuity)); if(weight_index == 0) CGAL::Polygon_mesh_processing::fair(*selection_item->polyhedron(), diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_plugin.cpp index d746af5fbad..c4a6207c968 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_plugin.cpp @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include #include @@ -716,16 +718,18 @@ bool Polyhedron_demo_hole_filling_plugin::fill if(weight_index == 0) { success = std::get<0>(CGAL::Polygon_mesh_processing::triangulate_refine_and_fair_hole(poly, it, std::back_inserter(patch), CGAL::Emptyset_iterator(), - CGAL::Polygon_mesh_processing::parameters::weight_calculator - (CGAL::internal::Uniform_weight_fairing(poly)). + CGAL::Polygon_mesh_processing::parameters:: + weight_calculator(CGAL::Weights::Uniform_weight()). density_control_factor(alpha). fairing_continuity(continuity). use_delaunay_triangulation(use_DT))); } else { + auto pmap = get_property_map(CGAL::vertex_point, poly); success = std::get<0>(CGAL::Polygon_mesh_processing::triangulate_refine_and_fair_hole(poly, it, std::back_inserter(patch), CGAL::Emptyset_iterator(), - CGAL::Polygon_mesh_processing::parameters::weight_calculator(CGAL::internal::Cotangent_weight_with_voronoi_area_fairing(poly)). + CGAL::Polygon_mesh_processing::parameters:: + weight_calculator(CGAL::Weights::Secure_cotangent_weight_with_voronoi_area(poly, pmap)). density_control_factor(alpha). fairing_continuity(continuity). use_delaunay_triangulation(use_DT))); diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_3.qrc b/Polyhedron/demo/Polyhedron/Polyhedron_3.qrc index 9a10f5c14a8..dc9a43a0d81 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_3.qrc +++ b/Polyhedron/demo/Polyhedron/Polyhedron_3.qrc @@ -105,6 +105,8 @@ resources/heat_intensity_shader.vert resources/compatibility_shaders/heat_intensity_shader.frag resources/compatibility_shaders/heat_intensity_shader.vert + resources/shader_tet_filter.frag + resources/shader_tet_filter.vert resources/rotate_around_cursor.png diff --git a/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp b/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp index d536c022959..a18f10211bf 100644 --- a/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp @@ -1,5 +1,4 @@ #include "config.h" -#include "Scene_spheres_item.h" #include "Scene_c3t3_item.h" #include "Scene_surface_mesh_item.h" @@ -50,371 +49,38 @@ typedef Edge_container Ec; typedef Point_container Pc; typedef Viewer_interface Vi; -QVector4D cgal_plane_to_vector4d(EPICK::Plane_3 plane) { - return { - static_cast(-plane.a()), - static_cast(-plane.b()), - static_cast(-plane.c()), - static_cast(-plane.d()) }; -} - -// The special Scene_item only for triangles -class Scene_intersection_item : public CGAL::Three::Scene_item_rendering_helper -{ - Q_OBJECT -public : - Scene_intersection_item(Scene_c3t3_item* parent) - :is_fast(false) - { - setParent(parent); - alphaSlider = NULL; - m_alpha = 1.0f; - setTriangleContainer(0, new Tc(Vi::PROGRAM_C3T3, false)); - setEdgeContainer(0, new Ec(Vi::PROGRAM_NO_SELECTION, false)); - } - bool isFinite() const Q_DECL_OVERRIDE{ return false; } - ~Scene_intersection_item() - { - if(alphaSlider) - delete alphaSlider; - } - void compute_bbox() const Q_DECL_OVERRIDE{} - - void gl_initialization(Vi* viewer) - { - if(!isInit(viewer)) - initGL(viewer); - computeElements(); - initializeBuffers(viewer); - } - void init_vectors( - std::vector *p_vertices, - std::vector *p_normals, - std::vector *p_edges, - std::vector *p_colors, - std::vector *p_bary) - { - vertices = p_vertices; - normals = p_normals; - edges = p_edges; - colors = p_colors; - barycenters = p_bary; - } - void setColor(QColor c) Q_DECL_OVERRIDE - { - Scene_c3t3_item* p_item = qobject_cast(this->parent()); - if(p_item->number_of_patches() > 1) - p_item->setColor(c); - Scene_item::setColor(c); - if(p_item->number_of_patches() <= 1) - p_item->changed(); - } - // Indicates if rendering mode is supported - bool supportsRenderingMode(RenderingMode m) const Q_DECL_OVERRIDE{ - return (m != Gouraud && m != PointsPlusNormals && m != Points && m != ShadedPoints); - } - void computeElements() const Q_DECL_OVERRIDE - { - getTriangleContainer(0)->reset_vbos(ALL); - getEdgeContainer(0)->reset_vbos(ALL); - - getTriangleContainer(0)->allocate(Tc::Flat_vertices, - vertices->data(), static_cast(vertices->size()*sizeof(float))); - getTriangleContainer(0)->allocate(Tc::Flat_normals, normals->data(), - static_cast(normals->size()*sizeof(float))); - getTriangleContainer(0)->allocate(Tc::FColors, colors->data(), - static_cast(colors->size()*sizeof(float))); - getTriangleContainer(0)->allocate(Tc::Facet_centers, barycenters->data(), - static_cast(barycenters->size()*sizeof(float))); - getEdgeContainer(0)->allocate(Ec::Vertices, edges->data(), - static_cast(edges->size()*sizeof(float))); - setBuffersFilled(true); - } - void initializeBuffers(CGAL::Three::Viewer_interface *viewer)const Q_DECL_OVERRIDE - { - //vao containing the data for the facets - { - getTriangleContainer(0)->initializeBuffers(viewer); - getTriangleContainer(0)->setFlatDataSize(vertices->size()); - } - //vao containing the data for the lines - { - getEdgeContainer(0)->initializeBuffers(viewer); - getEdgeContainer(0)->setFlatDataSize(edges->size()); - } - } - - //Displays the item - void draw(CGAL::Three::Viewer_interface* viewer) const Q_DECL_OVERRIDE - { - if(is_fast) - return; - - if(!alphaSlider) - { - alphaSlider = new QSlider(::Qt::Horizontal); - alphaSlider->setMinimum(0); - alphaSlider->setMaximum(255); - alphaSlider->setValue(255); - } - //viewer->makeCurrent(); - const EPICK::Plane_3& plane = qobject_cast(this->parent())->plane(); - float shrink_factor = qobject_cast(this->parent())->getShrinkFactor(); - QVector4D cp = cgal_plane_to_vector4d(plane); - getTriangleContainer(0)->setPlane(-cp); - getTriangleContainer(0)->setShrinkFactor(shrink_factor); - // positions_poly is also used for the faces in the cut plane - // and changes when the cut plane is moved - getTriangleContainer(0)->setAlpha(alpha()); - getTriangleContainer(0)->draw(viewer, false); - } - void drawEdges(CGAL::Three::Viewer_interface* viewer) const Q_DECL_OVERRIDE - { - if(is_fast) - return; - const EPICK::Plane_3& plane = qobject_cast(this->parent())->plane(); - QVector4D cp = cgal_plane_to_vector4d(plane); - getEdgeContainer(0)->setPlane(cp); - getEdgeContainer(0)->setColor(QColor(Qt::black)); - getEdgeContainer(0)->draw(viewer, true); - - } - - void setFast(bool b) - { - is_fast = b; - } - - void addTriangle(const Tr::Bare_point& pa, const Tr::Bare_point& pb, - const Tr::Bare_point& pc, const CGAL::IO::Color color) - { - const CGAL::qglviewer::Vec offset = Three::mainViewer()->offset(); - Geom_traits::Vector_3 n = cross_product(pb - pa, pc - pa); - n = n / CGAL::sqrt(n*n); - - auto push_normal = [this](auto n) { - normals->push_back(static_cast(n.x())); - normals->push_back(static_cast(n.y())); - normals->push_back(static_cast(n.z())); - }; - - auto push_vertex = [this, &offset](const auto& p) { - this->vertices->push_back(static_cast(p.x()+offset.x)); - this->vertices->push_back(static_cast(p.y()+offset.y)); - this->vertices->push_back(static_cast(p.z()+offset.z)); - }; - - auto push_edge = [this, &offset](const auto& pa, const auto& pb) { - this->edges->push_back(static_cast(pa.x()+offset.x)); - this->edges->push_back(static_cast(pa.y()+offset.y)); - this->edges->push_back(static_cast(pa.z()+offset.z)); - this->edges->push_back(static_cast(pb.x()+offset.x)); - this->edges->push_back(static_cast(pb.y()+offset.y)); - this->edges->push_back(static_cast(pb.z()+offset.z)); - }; - - for (int i = 0; i<3; i++) - { - push_normal(n); - } - push_vertex(pa); - push_vertex(pb); - push_vertex(pc); - - push_edge(pa, pb); - push_edge(pb, pc); - push_edge(pc, pa); - - for(int i=0; i<3; i++) - { - colors->push_back((float)color.red()/255); - colors->push_back((float)color.green()/255); - colors->push_back((float)color.blue()/255); - - barycenters->push_back(static_cast((pa[0]+pb[0]+pc[0])/3.0 + offset.x)); - barycenters->push_back(static_cast((pa[1]+pb[1]+pc[1])/3.0 + offset.y)); - barycenters->push_back(static_cast((pa[2]+pb[2]+pc[2])/3.0 + offset.z)); - } - } - - Scene_item* clone() const Q_DECL_OVERRIDE{return 0;} - QString toolTip() const Q_DECL_OVERRIDE{return QString();} - QMenu* contextMenu() Q_DECL_OVERRIDE - { - QMenu* menu = Scene_item::contextMenu(); - - const char* prop_name = "Menu modified by Scene_surface_mesh_item."; - bool menuChanged = menu->property(prop_name).toBool(); - - if(!menuChanged) { - menu->addSeparator(); - QMenu *container = new QMenu(tr("Alpha value")); - container->menuAction()->setProperty("is_groupable", true); - QWidgetAction *sliderAction = new QWidgetAction(0); - sliderAction->setDefaultWidget(alphaSlider); - connect(alphaSlider, &QSlider::valueChanged, - [this](){ - setAlpha(alphaSlider->value()); - redraw(); - }); - - container->addAction(sliderAction); - menu->addMenu(container); - setProperty("menu_changed", true); - menu->setProperty(prop_name, true); - } - return menu; - } - float alpha() const Q_DECL_OVERRIDE - { - return m_alpha ; - } - - void setAlpha(int a) Q_DECL_OVERRIDE - { - m_alpha = a / 255.0f; - redraw(); - } -private: - - //contains the data - mutable std::vector *vertices; - mutable std::vector *normals; - mutable std::vector *edges; - mutable std::vector *colors; - mutable std::vector *barycenters; - mutable bool is_fast; - mutable QSlider* alphaSlider; - mutable float m_alpha ; -}; //end of class Scene_triangle_item - struct Scene_c3t3_item_priv { - typedef CGAL::qglviewer::ManipulatedFrame ManipulatedFrame; - Scene_c3t3_item_priv(Scene_c3t3_item* item) - : item(item), c3t3() - , frame(new ManipulatedFrame()) - , data_item_(NULL) - , histogram_() - , surface_patch_indices_() - , subdomain_indices_() - , is_valid(true) - { - init_default_values(); - tet_Slider = new QSlider(Qt::Horizontal); - tet_Slider->setMinimum(0); - tet_Slider->setMaximum(100); - tet_Slider->setValue(100); - invalidate_stats(); - } - Scene_c3t3_item_priv(const C3t3& c3t3_, Scene_c3t3_item* item) - : item(item), c3t3(c3t3_) - , frame(new ManipulatedFrame()) - , data_item_(NULL) - , histogram_() - , surface_patch_indices_() - , subdomain_indices_() - , is_valid(true) - { - init_default_values(); - tet_Slider = new QSlider(Qt::Horizontal); - tet_Slider->setMinimum(0); - tet_Slider->setMaximum(100); - tet_Slider->setValue(100); - invalidate_stats(); - } - ~Scene_c3t3_item_priv() - { - if(alphaSlider) - delete alphaSlider; - c3t3.clear(); - tree.clear(); - if(frame) - { - delete frame; - frame = NULL; - delete tet_Slider; - } - } void init_default_values() { - positions_lines.resize(0); - positions_poly.resize(0); - normals.resize(0); - s_vertex.resize(0); - s_normals.resize(0); - ws_vertex.resize(0); - need_changed = false; - spheres = NULL; - intersection = NULL; - spheres_are_shown = false; - cnc_are_shown = false; - is_aabb_tree_built = false; - alphaSlider = NULL; sharp_edges_angle = -1; detect_borders = false; } - void computeIntersection(const Primitive& facet); - void fill_aabb_tree() { - if(item->isEmpty()) return; - QGuiApplication::setOverrideCursor(Qt::WaitCursor); - CGAL::Real_timer timer; - timer.start(); - tree.clear(); - for (Tr::Finite_cells_iterator - cit = c3t3.triangulation().finite_cells_begin(), - end = c3t3.triangulation().finite_cells_end(); - cit != end; ++cit) - { - Tr::Cell_handle ch = cit; - if(!c3t3.is_in_complex(ch)) continue; - - tree.insert(Primitive(cit)); - } - tree.build(); - std::cerr << "C3t3 cells AABB tree built in " << timer.time() - << " wall-clock seconds\n"; - - is_aabb_tree_built = true; - QGuiApplication::restoreOverrideCursor(); + Scene_c3t3_item_priv(Scene_c3t3_item* item) + : item(item), c3t3(), is_valid(true), computed_stats(false){ } - void reset_cut_plane(); - void draw_triangle(const Tr::Bare_point& pa, - const Tr::Bare_point& pb, - const Tr::Bare_point& pc) const; - void draw_triangle_edges(const Tr::Bare_point& pa, - const Tr::Bare_point& pb, - const Tr::Bare_point& pc) const; + + Scene_c3t3_item_priv(const C3t3& c3t3_, Scene_c3t3_item* item) + : item(item), c3t3(c3t3_), is_valid(true), computed_stats(false){ + } + + ~Scene_c3t3_item_priv() + { + c3t3.clear(); + } + void draw_triangle_edges_cnc(const Tr::Bare_point& pa, const Tr::Bare_point& pb, const Tr::Bare_point& pc) const; - double complex_diag() const; - void compute_color_map(const QColor& c); - void initializeBuffers(CGAL::Three::Viewer_interface *viewer); - void initialize_intersection_buffers(CGAL::Three::Viewer_interface *viewer); - void computeSpheres(); - void computeElements(); - void computeIntersections(CGAL::Three::Viewer_interface* viewer); - - void invalidate_stats() - { - min_edges_length = (std::numeric_limits::max)(); - max_edges_length = 0; - mean_edges_length = 0; - min_dihedral_angle = (std::numeric_limits::max)(); - max_dihedral_angle = 0; - mean_dihedral_angle = 0; - nb_subdomains = 0; - nb_spheres = 0; - nb_cnc = 0; - nb_vertices = 0; - nb_tets = 0; - smallest_radius_radius = (std::numeric_limits::max)(); - smallest_edge_radius = (std::numeric_limits::max)(); - biggest_v_sma_cube = 0; - computed_stats = false; - } + Scene_c3t3_item* item; + C3t3 c3t3; + bool is_surface; + //only for optimizers + double sharp_edges_angle; + bool detect_borders; + bool is_valid; + bool cnc_are_shown; enum STATS { MIN_EDGES_LENGTH = 0, @@ -424,99 +90,20 @@ struct Scene_c3t3_item_priv { MAX_DIHEDRAL_ANGLE, MEAN_DIHEDRAL_ANGLE, NB_SPHERES, - NB_CNC, NB_VERTICES, NB_TETS, SMALLEST_RAD_RAD, SMALLEST_EDGE_RAD, BIGGEST_VL3_CUBE, - NB_SUBDOMAINS + NB_SUBDOMAINS, + NB_CNC }; - Scene_c3t3_item* item; - C3t3 c3t3; - bool is_grid_shown; - CGAL::qglviewer::ManipulatedFrame* frame; - bool need_changed; - mutable std::map are_intersection_buffers_filled; - bool areInterBufFilled(CGAL::Three::Viewer_interface* viewer) - { - if(are_intersection_buffers_filled.find(viewer) != are_intersection_buffers_filled.end()) - return are_intersection_buffers_filled[viewer]; - return false; - } - Scene_spheres_item *spheres; - std::vector tr_vertices; - Scene_intersection_item *intersection; - bool spheres_are_shown; - const Scene_item* data_item_; - QPixmap histogram_; - typedef std::set Indices; - Indices surface_patch_indices_; - Indices subdomain_indices_; - QSlider* tet_Slider; - //!Allows OpenGL 2.0 context to get access to glDrawArraysInstanced. - typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDARBPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); - //!Allows OpenGL 2.0 context to get access to glVertexAttribDivisor. - typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORARBPROC) (GLuint index, GLuint divisor); - //!Allows OpenGL 2.0 context to get access to gkFrameBufferTexture2D. - PFNGLDRAWARRAYSINSTANCEDARBPROC glDrawArraysInstanced; - //!Allows OpenGL 2.0 context to get access to glVertexAttribDivisor. - PFNGLVERTEXATTRIBDIVISORARBPROC glVertexAttribDivisor; - - mutable std::size_t positions_poly_size; - mutable std::size_t positions_lines_size; - mutable std::size_t positions_lines_not_in_complex_size; - mutable std::vector positions_lines; mutable std::vector positions_lines_not_in_complex; - mutable std::vector positions_grid; - mutable std::vector positions_poly; - mutable std::vector positions_barycenter; - - mutable std::vector normals; - mutable std::vector f_colors; - mutable std::vector s_normals; - mutable std::vector s_colors; - mutable std::vector s_vertex; - mutable std::vector ws_vertex; - mutable std::vector s_radius; - mutable std::vector s_center; - mutable bool computed_stats; - mutable float max_edges_length; - mutable float min_edges_length; - mutable float mean_edges_length; - mutable float min_dihedral_angle; - mutable float max_dihedral_angle; - mutable float mean_dihedral_angle; - mutable std::size_t nb_spheres; + mutable std::size_t positions_lines_not_in_complex_size; mutable std::size_t nb_cnc; - mutable std::size_t nb_subdomains; - mutable std::size_t nb_vertices; - mutable std::size_t nb_tets; - mutable float smallest_radius_radius; - mutable float smallest_edge_radius; - mutable float biggest_v_sma_cube; - QSlider* alphaSlider; + mutable bool computed_stats; - Tree tree; - QVector colors; - QVector colors_subdomains; - bool show_tetrahedra; - bool is_aabb_tree_built; - bool cnc_are_shown; - bool is_valid; - bool is_surface; - bool last_intersection; - //only for optimizers - double sharp_edges_angle; - bool detect_borders; - - void push_normal(std::vector& normals, const EPICK::Vector_3& n) const - { - normals.push_back(static_cast(n.x())); - normals.push_back(static_cast(n.y())); - normals.push_back(static_cast(n.z())); - } void push_point(std::vector& points, const EPICK::Point_3& p, const CGAL::qglviewer::Vec& offset) const { @@ -524,6 +111,7 @@ struct Scene_c3t3_item_priv { points.push_back(static_cast(p.y()+offset.y)); points.push_back(static_cast(p.z()+offset.z)); } + void push_edge(std::vector& edges, const EPICK::Point_3& pa, const EPICK::Point_3& pb, @@ -534,88 +122,42 @@ struct Scene_c3t3_item_priv { } }; -struct Set_show_tetrahedra { - Scene_c3t3_item_priv* priv; - Set_show_tetrahedra(Scene_c3t3_item_priv* priv) : priv(priv) {} - void operator()(bool b) { - priv->show_tetrahedra = b; - priv->item->show_intersection(b); - } -}; +void Scene_c3t3_item_priv::draw_triangle_edges_cnc(const Tr::Bare_point& pa, + const Tr::Bare_point& pb, + const Tr::Bare_point& pc) const +{ + const CGAL::qglviewer::Vec offset = Three::mainViewer()->offset(); + push_edge(positions_lines_not_in_complex, pa, pb, offset); + push_edge(positions_lines_not_in_complex, pb, pc, offset); + push_edge(positions_lines_not_in_complex, pc, pa, offset); +} + void Scene_c3t3_item::common_constructor(bool is_surface) { - compute_bbox(); - connect(d->frame, SIGNAL(modified()), this, SLOT(changed())); - c3t3_changed(); - setRenderingMode(FlatPlusEdges); - create_flat_and_wire_sphere(1.0f,d->s_vertex,d->s_normals, d->ws_vertex); - d->is_surface = is_surface; - d->is_grid_shown = !is_surface; - d->show_tetrahedra = !is_surface; - d->last_intersection = !d->show_tetrahedra; - - setTriangleContainer(C3t3_faces, new Tc(Vi::PROGRAM_C3T3, false)); - + d->cnc_are_shown = false; setEdgeContainer(CNC, new Ec(Vi::PROGRAM_NO_SELECTION, false)); - setEdgeContainer(Grid_edges, new Ec(Vi::PROGRAM_NO_SELECTION, false)); - setEdgeContainer(C3t3_edges, new Ec(Vi::PROGRAM_C3T3_EDGES, false)); - setPointContainer(C3t3_points, new Pc(Vi::PROGRAM_C3T3_EDGES, false)); - for(auto v : CGAL::QGLViewer::QGLViewerPool()) - { - v->installEventFilter(this); - } } + Scene_c3t3_item::Scene_c3t3_item(bool is_surface) - : Scene_group_item("unnamed") - , d(new Scene_c3t3_item_priv(this)) + : Scene_triangulation_3_item(!is_surface) { + d = new Scene_c3t3_item_priv(this); common_constructor(is_surface); + } Scene_c3t3_item::Scene_c3t3_item(const C3t3& c3t3, bool is_surface) - : Scene_group_item("unnamed") - , d(new Scene_c3t3_item_priv(c3t3, this)) + : Scene_triangulation_3_item(c3t3.triangulation(), !is_surface) { + d = new Scene_c3t3_item_priv(c3t3, this); common_constructor(is_surface); - d->reset_cut_plane(); - c3t3_changed(); - changed(); } Scene_c3t3_item::~Scene_c3t3_item() { - if(d) - { - delete d; - d = NULL; - } -} - - - -const Scene_item* -Scene_c3t3_item::data_item() const -{ - return d->data_item_; -} - -void -Scene_c3t3_item::set_data_item(const Scene_item* data_item) -{ - d->data_item_ = data_item; - if (NULL != data_item) - { - connect(d->data_item_, SIGNAL(aboutToBeDestroyed()), - this, SLOT(data_item_destroyed())); - } -} - -void -Scene_c3t3_item::data_item_destroyed() -{ - set_data_item(NULL); + delete d; } const C3t3& @@ -629,558 +171,51 @@ Scene_c3t3_item::c3t3() return d->c3t3; } -void -Scene_c3t3_item::changed() -{ - if(!d) - return; - d->need_changed = true; - QTimer::singleShot(0,this, SLOT(updateCutPlane())); -} - -void Scene_c3t3_item::updateCutPlane() -{ // just handle deformation - paint like selection is handled in eventFilter() - if(!d) - return; - if(d->need_changed) { - for(auto v : CGAL::QGLViewer::QGLViewerPool()) - { - CGAL::Three::Viewer_interface* viewer = static_cast(v); - d->are_intersection_buffers_filled[viewer] = false; - } - d->need_changed = false; - } -} - void Scene_c3t3_item::c3t3_changed() { - // Update colors - // Fill indices map and get max subdomain value - d->surface_patch_indices_.clear(); - d->subdomain_indices_.clear(); - - int max = 0; - for (C3t3::Cells_in_complex_iterator cit = this->c3t3().cells_in_complex_begin(), - end = this->c3t3().cells_in_complex_end(); cit != end; ++cit) - { - max = (std::max)(max, cit->subdomain_index()); - d->subdomain_indices_.insert(cit->subdomain_index()); - } - const int max_subdomain_index = max; - for (C3t3::Facets_in_complex_iterator fit = this->c3t3().facets_in_complex_begin(), - end = this->c3t3().facets_in_complex_end(); fit != end; ++fit) - { - max = (std::max)(max, fit->first->surface_patch_index(fit->second)); - d->surface_patch_indices_.insert(fit->first->surface_patch_index(fit->second)); - } - - d->colors.resize(max + 1); - d->colors_subdomains.resize(max_subdomain_index + 1); - d->compute_color_map(color_); - - // Rebuild histogram - build_histogram(); - - d->tree.clear(); - d->is_aabb_tree_built = false; + triangulation_changed(); } -QPixmap -Scene_c3t3_item::graphicalToolTip() const +const T3& +Scene_c3t3_item::triangulation() const { + return d->c3t3.triangulation(); +} + +T3& +Scene_c3t3_item::triangulation() { - if (!d->histogram_.isNull()) - { - return d->histogram_; - } - const_cast(*this).build_histogram(); - return d->histogram_; + return d->c3t3.triangulation(); } -std::vector -create_histogram(const C3t3& c3t3, double& min_value, double& max_value) +bool Scene_c3t3_item::do_take_cell(const T3::Cell_handle& c) const { - Geom_traits::Compute_approximate_dihedral_angle_3 approx_dihedral_angle - = c3t3.triangulation().geom_traits().compute_approximate_dihedral_angle_3_object(); - Geom_traits::Construct_point_3 wp2p - = c3t3.triangulation().geom_traits().construct_point_3_object(); - - std::vector histo(181, 0); - - min_value = 180.; - max_value = 0.; - - for (C3t3::Cells_in_complex_iterator cit = c3t3.cells_in_complex_begin(); - cit != c3t3.cells_in_complex_end(); - ++cit) - { - if (!c3t3.is_in_complex(cit)) - continue; - -#ifdef CGAL_MESH_3_DEMO_DONT_COUNT_TETS_ADJACENT_TO_SHARP_FEATURES_FOR_HISTOGRAM - if (c3t3.in_dimension(cit->vertex(0)) <= 1 - || c3t3.in_dimension(cit->vertex(1)) <= 1 - || c3t3.in_dimension(cit->vertex(2)) <= 1 - || c3t3.in_dimension(cit->vertex(3)) <= 1) - continue; -#endif //CGAL_MESH_3_DEMO_DONT_COUNT_TETS_ADJACENT_TO_SHARP_FEATURES_FOR_HISTOGRAM - - const Tr::Bare_point& p0 = wp2p(cit->vertex(0)->point()); - const Tr::Bare_point& p1 = wp2p(cit->vertex(1)->point()); - const Tr::Bare_point& p2 = wp2p(cit->vertex(2)->point()); - const Tr::Bare_point& p3 = wp2p(cit->vertex(3)->point()); - - double a = CGAL::to_double(CGAL::abs(approx_dihedral_angle(p0, p1, p2, p3))); - histo[static_cast(std::floor(a))] += 1; - min_value = (std::min)(min_value, a); - max_value = (std::max)(max_value, a); - - a = CGAL::to_double(CGAL::abs(approx_dihedral_angle(p0, p2, p1, p3))); - histo[static_cast(std::floor(a))] += 1; - min_value = (std::min)(min_value, a); - max_value = (std::max)(max_value, a); - - a = CGAL::to_double(CGAL::abs(approx_dihedral_angle(p0, p3, p1, p2))); - histo[static_cast(std::floor(a))] += 1; - min_value = (std::min)(min_value, a); - max_value = (std::max)(max_value, a); - - a = CGAL::to_double(CGAL::abs(approx_dihedral_angle(p1, p2, p0, p3))); - histo[static_cast(std::floor(a))] += 1; - min_value = (std::min)(min_value, a); - max_value = (std::max)(max_value, a); - - a = CGAL::to_double(CGAL::abs(approx_dihedral_angle(p1, p3, p0, p2))); - histo[static_cast(std::floor(a))] += 1; - min_value = (std::min)(min_value, a); - max_value = (std::max)(max_value, a); - - a = CGAL::to_double(CGAL::abs(approx_dihedral_angle(p2, p3, p0, p1))); - histo[static_cast(std::floor(a))] += 1; - min_value = (std::min)(min_value, a); - max_value = (std::max)(max_value, a); - - } - - return histo; + return d->c3t3.is_in_complex(c); } -void -Scene_c3t3_item::build_histogram() +bool Scene_c3t3_item::do_take_facet(const T3::Facet& f)const { -#ifdef CGAL_MESH_3_DEMO_BIGGER_HISTOGRAM_WITH_WHITE_BACKGROUNG - // Create an histogram_ and display it - const int height = 280; - const int top_margin = 5; - const int left_margin = 20; - const int drawing_height = height - top_margin * 2; - const int width = 804; - const int cell_width = 4; - const int text_margin = 3; - const int text_height = 34; - - d->histogram_ = QPixmap(width, height + text_height); - d->histogram_.fill(QColor(255, 255, 255)); -#else - // Create an histogram_ and display it - const int height = 140; - const int top_margin = 5; - const int left_margin = 20; - const int drawing_height = height - top_margin * 2; - const int width = 402; - const int cell_width = 2; - const int text_margin = 3; - const int text_height = 20; - - d->histogram_ = QPixmap(width, height + text_height); - d->histogram_.fill(QColor(192, 192, 192)); -#endif - - QPainter painter(&d->histogram_); - painter.setPen(Qt::black); - painter.setBrush(QColor(128, 128, 128)); - //painter.setFont(QFont("Arial", 30)); - - // Build histogram_ data - double min_value, max_value; - std::vector histo_data = create_histogram(c3t3(), min_value, max_value); - - // Get maximum value (to normalize) - int max_size = 0; - for (std::vector::iterator it = histo_data.begin(), end = histo_data.end(); - it != end; ++it) - { - max_size = (std::max)(max_size, *it); - } - - // colored histogram - int j = 0; - - // draw - int i = left_margin; - for (std::vector::iterator it = histo_data.begin(), end = histo_data.end(); - it != end; ++it, i += cell_width) - { - int line_height = static_cast(std::ceil(static_cast(drawing_height)* - static_cast(*it) / static_cast(max_size)) + .5); - - painter.fillRect(i, - drawing_height + top_margin - line_height, - cell_width, - line_height, - get_histogram_color(j++)); - } - - // draw bottom horizontal line - painter.setPen(Qt::blue); - - painter.drawLine(QPoint(left_margin, drawing_height + top_margin), - QPoint(left_margin + static_cast(histo_data.size())*cell_width, - drawing_height + top_margin)); - - - // draw min value and max value - const int min_tr_width = - static_cast(2 * (std::floor(min_value)*cell_width + left_margin)); - const int max_tr_width = - static_cast(2 * ((double(histo_data.size()) - - std::floor(max_value))*cell_width + left_margin)); - const int tr_y = drawing_height + top_margin + text_margin; - - painter.setPen(get_histogram_color(min_value)); - QRect min_text_rect(0, tr_y, min_tr_width, text_height); - painter.drawText(min_text_rect, Qt::AlignCenter, tr("%1").arg(min_value, 0, 'f', 1)); - - painter.setPen(get_histogram_color(max_value)); - QRect max_text_rect(width - max_tr_width, tr_y, max_tr_width, text_height); - painter.drawText(max_text_rect, Qt::AlignCenter, tr("%1").arg(max_value, 0, 'f', 1)); + return (d->c3t3.is_in_complex(f)); } -QColor -Scene_c3t3_item::get_histogram_color(const double v) const +bool Scene_c3t3_item::do_take_vertex(const T3::Vertex_handle& v)const { - if (v < 5) { return Qt::red; } - else if (v < 10) { return QColor(215, 108, 0); } - else if (v < 15) { return QColor(138, 139, 0); } - else if (v < 165) { return QColor(60, 136, 64); } - else if (v < 170) { return QColor(138, 139, 1); } - else if (v < 175) { return QColor(215, 108, 0); } - else /* 175c3t3.is_in_complex(v); } -void -Scene_c3t3_item::update_histogram() +bool Scene_c3t3_item::is_facet_oriented(const T3::Facet& f)const { - build_histogram(); -} - -void -Scene_c3t3_item_priv::compute_color_map(const QColor& c) -{ - typedef Indices::size_type size_type; - - const size_type nb_domains = subdomain_indices_.size(); - double i = 0; - for (Indices::iterator it = subdomain_indices_.begin(), - end = subdomain_indices_.end(); it != end; ++it, i += 1.) - { - double hue = c.hueF() + 1. / double(nb_domains) * i; - if (hue > 1) { hue -= 1.; } - colors_subdomains[*it] = QColor::fromHsvF(hue, c.saturationF(), c.valueF()); - } - const size_type nb_patch_indices = surface_patch_indices_.size(); - i = 0; - for (Indices::iterator it = surface_patch_indices_.begin(), - end = surface_patch_indices_.end(); it != end; ++it, i += 1.) - { - double hue = c.hueF() + 1. / double(nb_patch_indices) * i; - if (hue > 1) { hue -= 1.; } - colors[*it] = QColor::fromHsvF(hue, c.saturationF(), c.valueF()); - } -} - -Geom_traits::Plane_3 Scene_c3t3_item::plane(CGAL::qglviewer::Vec offset) const -{ - const CGAL::qglviewer::Vec& pos = d->frame->position() - offset; - const CGAL::qglviewer::Vec& n = - d->frame->inverseTransformOf(CGAL::qglviewer::Vec(0.f, 0.f, 1.f)); - return Geom_traits::Plane_3(n[0], n[1], n[2], -n * pos); -} - -void Scene_c3t3_item::compute_bbox() const { - if (isEmpty()) - _bbox = Bbox(); - else { - bool bbox_init = false; - CGAL::Bbox_3 result; - for (Tr::Finite_vertices_iterator - vit = c3t3().triangulation().finite_vertices_begin(), - end = c3t3().triangulation().finite_vertices_end(); - vit != end; ++vit) - { - if(vit->in_dimension() == -1) continue; - if (bbox_init) - result = result + vit->point().bbox(); - else - { - result = vit->point().bbox(); - bbox_init = true; - } - } - _bbox = Bbox(result.xmin(), result.ymin(), result.zmin(), - result.xmax(), result.ymax(), result.zmax()); - } -} - -QString Scene_c3t3_item::toolTip() const { - return tr("

3D complex in a 3D triangulation

" - "

Number of vertices: %1
" - "Number of surface facets: %2
" - "Number of volume tetrahedra: %3

%4") - .arg(c3t3().triangulation().number_of_vertices()) - .arg(c3t3().number_of_facets_in_complex()) - .arg(c3t3().number_of_cells_in_complex()) - .arg(property("toolTip").toString()); -} - -void Scene_c3t3_item::draw(CGAL::Three::Viewer_interface* viewer) const { - if(!visible()) - return; - Scene_c3t3_item* ncthis = const_cast(this); - if(!isInit(viewer)) - initGL(viewer); - //viewer->makeCurrent(); - if ( getBuffersFilled() && - ! getBuffersInit(viewer)) - { - initializeBuffers(viewer); - setBuffersInit(viewer, true); - } - if(!getBuffersFilled()) - { - computeElements(); - initializeBuffers(viewer); - } - if(renderingMode() == Flat || - renderingMode() == FlatPlusEdges) - { - QVector4D cp = cgal_plane_to_vector4d(this->plane()); - getTriangleContainer(C3t3_faces)->setPlane(cp); - float shrink_factor = getShrinkFactor(); - getTriangleContainer(C3t3_faces)->setShrinkFactor(shrink_factor); - // positions_poly_size is the number of total facets in the C3T3 - // it is only computed once and positions_poly is emptied at the end - getTriangleContainer(C3t3_faces)->setAlpha(alpha()); - getTriangleContainer(C3t3_faces)->setIsSurface(d->is_surface); - getTriangleContainer(C3t3_faces)->draw(viewer, false); - if(d->show_tetrahedra){ - ncthis->show_intersection(true); - if(!d->frame->isManipulated()) - d->intersection->setFast(false); - else - d->intersection->setFast(true); - - if(!d->frame->isManipulated() && !d->areInterBufFilled(viewer)) - { - //initGL - ncthis->d->computeIntersections(viewer); - d->are_intersection_buffers_filled[viewer] = true; - ncthis->show_intersection(true); - } - } - if(d->spheres_are_shown) - { - d->spheres->setPlane(this->plane()); - } - } - if(d->is_grid_shown) - { - //viewer->makeCurrent(); //messes with the depthPeeling - getEdgeContainer(Grid_edges)->setColor(QColor(Qt::black)); - QMatrix4x4 f_mat; - for (int i = 0; i<16; i++) - f_mat.data()[i] = static_cast(d->frame->matrix()[i]); - getEdgeContainer(Grid_edges)->setFrameMatrix(f_mat); - getEdgeContainer(Grid_edges)->draw(viewer, true); - } -} - -void Scene_c3t3_item::drawEdges(CGAL::Three::Viewer_interface* viewer) const { - if(!visible()) - return; - if(renderingMode() == Wireframe || - renderingMode() == FlatPlusEdges ) - { - if(renderingMode() == FlatPlusEdges) - { - GLint renderMode; - viewer->glGetIntegerv(GL_RENDER_MODE, &renderMode); - if(renderMode == GL_SELECT) return; - } - Scene_c3t3_item* ncthis = const_cast(this); - if(!isInit(viewer)) - initGL(viewer); - if ( getBuffersFilled() && - ! getBuffersInit(viewer)) - { - initializeBuffers(viewer); - setBuffersInit(viewer, true); - } - if(!getBuffersFilled()) - { - computeElements(); - initializeBuffers(viewer); - } - if(renderingMode() == Wireframe && d->is_grid_shown) - { - getEdgeContainer(Grid_edges)->setColor(QColor(Qt::black)); - QMatrix4x4 f_mat; - for (int i = 0; i<16; i++) - f_mat.data()[i] = static_cast(d->frame->matrix()[i]); - getEdgeContainer(Grid_edges)->setFrameMatrix(f_mat); - getEdgeContainer(Grid_edges)->draw(viewer, true); - } - - QVector4D cp = cgal_plane_to_vector4d(this->plane()); - getEdgeContainer(C3t3_edges)->setPlane(cp); - getEdgeContainer(C3t3_edges)->setIsSurface(d->is_surface); - getEdgeContainer(C3t3_edges)->setColor(QColor(Qt::black)); - getEdgeContainer(C3t3_edges)->draw(viewer, true); - - if(d->show_tetrahedra){ - ncthis->show_intersection(true); - if(!d->frame->isManipulated()) - d->intersection->setFast(false); - else - d->intersection->setFast(true); - if(!d->frame->isManipulated() && !d->areInterBufFilled(viewer)) - { - ncthis->d->computeIntersections(viewer); - d->are_intersection_buffers_filled[viewer]=true; - } - } - if(d->spheres_are_shown) - { - d->spheres->setPlane(this->plane()); - } - } - if(d->cnc_are_shown) - { - getEdgeContainer(CNC)->setColor(QColor(Qt::black)); - getEdgeContainer(CNC)->draw(viewer, true); - } -} - -void Scene_c3t3_item::drawPoints(CGAL::Three::Viewer_interface * viewer) const -{ - if(!visible()) - return; - if(renderingMode() == Points) - { - if(!isInit(viewer)) - initGL(viewer); - if ( getBuffersFilled() && - ! getBuffersInit(viewer)) - { - initializeBuffers(viewer); - setBuffersInit(viewer, true); - } - if(!getBuffersFilled()) - { - computeElements(); - initializeBuffers(viewer); - } - - - QVector4D cp = cgal_plane_to_vector4d(this->plane()); - getPointContainer(C3t3_points)->setPlane(cp); - getPointContainer(C3t3_points)->setIsSurface(d->is_surface); - getPointContainer(C3t3_points)->setColor(this->color()); - getPointContainer(C3t3_points)->draw(viewer, true); - - if(d->is_grid_shown) - { - getEdgeContainer(Grid_edges)->setColor(QColor(Qt::black)); - QMatrix4x4 f_mat; - for (int i = 0; i<16; i++) - f_mat.data()[i] = static_cast(d->frame->matrix()[i]); - getEdgeContainer(Grid_edges)->setFrameMatrix(f_mat); - getEdgeContainer(Grid_edges)->draw(viewer, true); - } - if(d->spheres_are_shown) - { - d->spheres->setPlane(this->plane()); - } - } -} - -void Scene_c3t3_item_priv::draw_triangle(const Tr::Bare_point& pa, - const Tr::Bare_point& pb, - const Tr::Bare_point& pc) const -{ - Geom_traits::Vector_3 n = cross_product(pb - pa, pc - pa); - n = n / CGAL::sqrt(n*n); - const CGAL::qglviewer::Vec offset = Three::mainViewer()->offset(); - - for (int i = 0; i<3; i++) - { - push_normal(normals, n); - } - push_point(positions_poly, pa, offset); - push_point(positions_poly, pb, offset); - push_point(positions_poly, pc, offset); - - for(int i=0; i<3; ++i) - { - push_point(positions_barycenter, CGAL::centroid(pa, pb, pc), offset); - } -} - -void Scene_c3t3_item_priv::draw_triangle_edges(const Tr::Bare_point& pa, - const Tr::Bare_point& pb, - const Tr::Bare_point& pc) const -{ - const CGAL::qglviewer::Vec offset = Three::mainViewer()->offset(); - push_edge(positions_lines, pa, pb, offset); - push_edge(positions_lines, pb, pc, offset); - push_edge(positions_lines, pc, pa, offset); -} -void Scene_c3t3_item_priv::draw_triangle_edges_cnc(const Tr::Bare_point& pa, - const Tr::Bare_point& pb, - const Tr::Bare_point& pc) const -{ - const CGAL::qglviewer::Vec offset = Three::mainViewer()->offset(); - push_edge(positions_lines_not_in_complex, pa, pb, offset); - push_edge(positions_lines_not_in_complex, pb, pc, offset); - push_edge(positions_lines_not_in_complex, pc, pa, offset); -} - -double Scene_c3t3_item_priv::complex_diag() const { - const CGAL::Three::Scene_item::Bbox& bbox = item->bbox(); - const double& xdelta = bbox.xmax() - bbox.xmin(); - const double& ydelta = bbox.ymax() - bbox.ymin(); - const double& zdelta = bbox.zmax() - bbox.zmin(); - const double diag = std::sqrt(xdelta*xdelta + - ydelta*ydelta + - zdelta*zdelta); - return diag * 0.7; -} - -void Scene_c3t3_item::export_facets_in_complex() -{ - SMesh outmesh; - CGAL::facets_in_complex_3_to_triangle_mesh(c3t3(), outmesh); - Scene_surface_mesh_item* item = new Scene_surface_mesh_item(std::move(outmesh)); - item->setName(QString("%1_%2").arg(this->name()).arg("facets")); - scene->addItem(item); - this->setVisible(false); + const Tr::Cell_handle& cell = f.first; + const int& index = f.second; + return (index % 2 == 1) == d->c3t3.is_in_complex(cell); } QMenu* Scene_c3t3_item::contextMenu() { + const char* prop_name = "Menu modified by Scene_c3t3_item."; - QMenu* menu = Scene_item::contextMenu(); + QMenu* menu = Scene_triangulation_3_item::contextMenu(); // Use dynamic properties: // https://doc.qt.io/qt-5/qobject.html#property @@ -1188,43 +223,8 @@ QMenu* Scene_c3t3_item::contextMenu() if (!menuChanged) { - QMenu *container = new QMenu(tr("Alpha value")); - container->menuAction()->setProperty("is_groupable", true); - QWidgetAction *sliderAction = new QWidgetAction(0); - sliderAction->setDefaultWidget(alphaSlider()); - connect(d->alphaSlider, &QSlider::valueChanged, - [this]() - { - if(d->intersection) - d->intersection->setAlpha(d->alphaSlider->value()); - redraw(); - } - ); - container->addAction(sliderAction); - menu->addMenu(container); - - container = new QMenu(tr("Tetrahedra's Shrink Factor")); - sliderAction = new QWidgetAction(0); - connect(d->tet_Slider, &QSlider::valueChanged, this, &Scene_c3t3_item::itemChanged); - sliderAction->setDefaultWidget(d->tet_Slider); - container->addAction(sliderAction); - menu->addMenu(container); - QAction* actionExportFacetsInComplex = - menu->addAction(tr("Export facets in complex")); - actionExportFacetsInComplex->setObjectName("actionExportFacetsInComplex"); - connect(actionExportFacetsInComplex, - SIGNAL(triggered()), this, - SLOT(export_facets_in_complex())); - if(is_valid()) { - QAction* actionShowSpheres = - menu->addAction(tr("Show protecting &spheres")); - actionShowSpheres->setCheckable(true); - actionShowSpheres->setObjectName("actionShowSpheres"); - connect(actionShowSpheres, SIGNAL(toggled(bool)), - this, SLOT(show_spheres(bool))); - QAction* actionShowCNC = menu->addAction(tr("Show cells not in complex")); actionShowCNC->setCheckable(true); @@ -1232,427 +232,27 @@ QMenu* Scene_c3t3_item::contextMenu() connect(actionShowCNC, SIGNAL(toggled(bool)), this, SLOT(show_cnc(bool))); } - QAction* actionShowTets = - menu->addAction(tr("Show &tetrahedra")); - actionShowTets->setCheckable(true); - actionShowTets->setObjectName("actionShowTets"); - connect(actionShowTets, &QAction::toggled, Set_show_tetrahedra(this->d)); - - QAction* actionShowGrid= - menu->addAction(tr("Show &grid")); - actionShowGrid->setCheckable(true); - actionShowGrid->setChecked(true); - actionShowGrid->setObjectName("actionShowGrid"); - connect(actionShowGrid, SIGNAL(toggled(bool)), - this, SLOT(show_grid(bool))); + QAction* actionExportFacetsInComplex = + menu->addAction(tr("Export facets in complex")); + actionExportFacetsInComplex->setObjectName("actionExportFacetsInComplex"); + connect(actionExportFacetsInComplex, + SIGNAL(triggered()), this, + SLOT(export_facets_in_complex())); menu->setProperty(prop_name, true); } return menu; } - -void Scene_c3t3_item_priv::initializeBuffers(CGAL::Three::Viewer_interface *viewer) +bool Scene_c3t3_item::is_valid() const { - //vao containing the data for the facets - { - item->getTriangleContainer(Scene_c3t3_item::C3t3_faces)->initializeBuffers(viewer); - item->getTriangleContainer(Scene_c3t3_item::C3t3_faces)->setFlatDataSize( - positions_poly_size); - - - positions_poly.clear(); - positions_poly.shrink_to_fit(); - normals.clear(); - normals.shrink_to_fit(); - f_colors.clear(); - f_colors.shrink_to_fit(); - positions_barycenter.clear(); - positions_barycenter.shrink_to_fit(); - } - - //vao containing the data for the lines - { - item->getEdgeContainer(Scene_c3t3_item::C3t3_edges)->initializeBuffers(viewer); - item->getEdgeContainer(Scene_c3t3_item::C3t3_edges)->setFlatDataSize( - positions_lines_size); - } - //vao containing the data for the points - { - item->getPointContainer(Scene_c3t3_item::C3t3_points)->initializeBuffers(viewer); - item->getPointContainer(Scene_c3t3_item::C3t3_points)->setFlatDataSize( - positions_lines_size); - - positions_lines.clear(); - positions_lines.shrink_to_fit(); - } - // vao containing the data for the cnc - { - item->getEdgeContainer(Scene_c3t3_item::CNC)->initializeBuffers(viewer); - item->getEdgeContainer(Scene_c3t3_item::CNC)->setFlatDataSize( - positions_lines_not_in_complex_size); - positions_lines_not_in_complex.clear(); - positions_lines_not_in_complex.shrink_to_fit(); - } - - //vao containing the data for the grid - { - item->getEdgeContainer(Scene_c3t3_item::Grid_edges)->initializeBuffers(viewer); - item->getEdgeContainer(Scene_c3t3_item::Grid_edges)->setFlatDataSize( - positions_grid.size()); - } + return d->is_valid; } - - -void Scene_c3t3_item_priv::computeIntersection(const Primitive& cell) +void Scene_c3t3_item::set_valid(bool b) { - Geom_traits::Construct_point_3 wp2p - = c3t3.triangulation().geom_traits().construct_point_3_object(); - - typedef unsigned char UC; - Tr::Cell_handle ch = cell.id(); - QColor c; - if(surface_patch_indices_.size()>1) - c = this->colors_subdomains[ch->subdomain_index()].lighter(50); - else - c = intersection->color(); - - const Tr::Bare_point& pa = wp2p(ch->vertex(0)->point()); - const Tr::Bare_point& pb = wp2p(ch->vertex(1)->point()); - const Tr::Bare_point& pc = wp2p(ch->vertex(2)->point()); - const Tr::Bare_point& pd = wp2p(ch->vertex(3)->point()); - - CGAL::IO::Color color(UC(c.red()), UC(c.green()), UC(c.blue())); - - intersection->addTriangle(pb, pa, pc, color); - intersection->addTriangle(pa, pb, pd, color); - intersection->addTriangle(pa, pd, pc, color); - intersection->addTriangle(pb, pc, pd, color); -} - -struct ComputeIntersection { - Scene_c3t3_item_priv& item_priv; - - ComputeIntersection(Scene_c3t3_item_priv& item_priv) - : item_priv(item_priv) - {} - - void operator()(const Primitive& facet) const - { - item_priv.computeIntersection(facet); - } -}; - -void Scene_c3t3_item_priv::computeIntersections(CGAL::Three::Viewer_interface* viewer) -{ - const CGAL::qglviewer::Vec offset = Three::mainViewer()->offset(); - if(!is_aabb_tree_built) fill_aabb_tree(); - - positions_poly.clear(); - normals.clear(); - f_colors.clear(); - positions_lines.clear(); - positions_barycenter.clear(); - const Geom_traits::Plane_3& plane = item->plane(offset); - tree.all_intersected_primitives(plane, - boost::make_function_output_iterator(ComputeIntersection(*this))); - intersection->gl_initialization(viewer); -} - -void Scene_c3t3_item_priv::computeSpheres() -{ - Geom_traits::Construct_point_3 wp2p - = c3t3.triangulation().geom_traits().construct_point_3_object(); - - if(!spheres) - return; - int s_id = 0; - for(Tr::Finite_vertices_iterator - vit = c3t3.triangulation().finite_vertices_begin(), - end = c3t3.triangulation().finite_vertices_end(); - vit != end; ++vit) - { - if(vit->point().weight()==0) continue; - - typedef Tr::Vertex_handle Vertex_handle; - std::vector incident_vertices; - c3t3.triangulation().incident_vertices(vit, std::back_inserter(incident_vertices)); - bool red = vit->is_special(); - for(std::vector::const_iterator - vvit = incident_vertices.begin(), end = incident_vertices.end(); - vvit != end; ++vvit) - { - if(c3t3.triangulation().is_infinite(*vvit)) continue; - if(Geom_traits::Sphere_3(wp2p(vit->point()), - vit->point().weight()).bounded_side(wp2p((*vvit)->point())) - == CGAL::ON_BOUNDED_SIDE) - red = true; - } - - QColor c; - if(red) - c = QColor(Qt::red); - else - c = spheres->color(); - - switch(vit->in_dimension()) - { - case 0: - c = QColor::fromHsv((c.hue()+120)%360, c.saturation(),c.lightness(), c.alpha()); - break; - case 1: - break; - default: - c.setRgb(50,50,50,255); - } - - const CGAL::qglviewer::Vec offset = Three::mainViewer()->offset(); - Tr::Bare_point center(wp2p(vit->point()).x() + offset.x, - wp2p(vit->point()).y() + offset.y, - wp2p(vit->point()).z() + offset.z); - double radius = vit->point().weight() ; - typedef unsigned char UC; - tr_vertices.push_back(*vit); - spheres->add_sphere(Geom_traits::Sphere_3(center, radius),s_id++, - CGAL::IO::Color(UC(c.red()), UC(c.green()), UC(c.blue()))); - - } - spheres->invalidateOpenGLBuffers(); -} - -void Scene_c3t3_item_priv::computeElements() -{ - if(!alphaSlider) - { - alphaSlider = new QSlider(::Qt::Horizontal); - alphaSlider->setMinimum(0); - alphaSlider->setMaximum(255); - alphaSlider->setValue(255); - } - - positions_poly.clear(); - positions_grid.clear(); - normals.clear(); - f_colors.clear(); - positions_lines.clear(); - positions_lines_not_in_complex.clear(); - s_colors.resize(0); - s_center.resize(0); - s_radius.resize(0); - - //The grid - { - positions_grid.resize(0); - - float x = (2 * (float)complex_diag()) / 10.0f; - float y = (2 * (float)complex_diag()) / 10.0f; - for (float u = 0; u < 11; u += 1.f) - { - - positions_grid.push_back(-(float)complex_diag() + x* u); - positions_grid.push_back(-(float)complex_diag()); - positions_grid.push_back(0.0f); - - positions_grid.push_back(-(float)complex_diag() + x* u); - positions_grid.push_back((float)complex_diag()); - positions_grid.push_back(0.0f); - } - for (float v = 0; v<11; v += 1.f) - { - - positions_grid.push_back(-(float)complex_diag()); - positions_grid.push_back(-(float)complex_diag() + v * y); - positions_grid.push_back(0.0f); - - positions_grid.push_back((float)complex_diag()); - positions_grid.push_back(-(float)complex_diag() + v * y); - positions_grid.push_back(0.0f); - } - } - - //The facets - { - Geom_traits::Construct_point_3 wp2p - = c3t3.triangulation().geom_traits().construct_point_3_object(); - - for (C3t3::Facet_iterator - fit = c3t3.facets_begin(), - end = c3t3.facets_end(); - fit != end; ++fit) - { - const Tr::Cell_handle& cell = fit->first; - const int& index = fit->second; - const Tr::Bare_point& pa = wp2p(cell->vertex((index + 1) & 3)->point()); - const Tr::Bare_point& pb = wp2p(cell->vertex((index + 2) & 3)->point()); - const Tr::Bare_point& pc = wp2p(cell->vertex((index + 3) & 3)->point()); - - QColor color = colors[cell->surface_patch_index(index)]; - f_colors.push_back((float)color.redF());f_colors.push_back((float)color.greenF());f_colors.push_back((float)color.blueF()); - f_colors.push_back((float)color.redF());f_colors.push_back((float)color.greenF());f_colors.push_back((float)color.blueF()); - f_colors.push_back((float)color.redF());f_colors.push_back((float)color.greenF());f_colors.push_back((float)color.blueF()); - if ((index % 2 == 1) == c3t3.is_in_complex(cell)) - draw_triangle(pb, pa, pc); - else draw_triangle(pa, pb, pc); - draw_triangle_edges(pa, pb, pc); - } - //the cells not in the complex - for(C3t3::Triangulation::Cell_iterator - cit = c3t3.triangulation().finite_cells_begin(), - end = c3t3.triangulation().finite_cells_end(); - cit != end; ++cit) - { - if(!c3t3.is_in_complex(cit)) - { - - bool has_far_point = false; - for(int i=0; i<4; i++) - if(c3t3.in_dimension(cit->vertex(i)) == -1) - { - has_far_point = true; - break; - } - if(!has_far_point) - { - const Tr::Bare_point& p1 = wp2p(cit->vertex(0)->point()); - const Tr::Bare_point& p2 = wp2p(cit->vertex(1)->point()); - const Tr::Bare_point& p3 = wp2p(cit->vertex(2)->point()); - const Tr::Bare_point& p4 = wp2p(cit->vertex(3)->point()); - draw_triangle_edges_cnc(p1, p2, p4); - draw_triangle_edges_cnc(p1, p3, p4); - draw_triangle_edges_cnc(p2, p3, p4); - draw_triangle_edges_cnc(p1, p2, p3); - } - } - } - } -} - -bool Scene_c3t3_item::load_binary(std::istream& is) -{ - if(!CGAL::IO::load_binary_file(is, c3t3())) return false; - if(is && d->frame == 0) { - d->frame = new CGAL::qglviewer::ManipulatedFrame(); - } - d->reset_cut_plane(); - if(is.good()) { - c3t3_changed(); - changed(); - return true; - } - else - return false; -} - -void -Scene_c3t3_item_priv::reset_cut_plane() { - const CGAL::Three::Scene_item::Bbox& bbox = item->bbox(); - const float xcenter = static_cast((bbox.xmax()+bbox.xmin())/2.); - const float ycenter = static_cast((bbox.ymax()+bbox.ymin())/2.); - const float zcenter = static_cast((bbox.zmax()+bbox.zmin())/2.); - const CGAL::qglviewer::Vec offset = Three::mainViewer()->offset(); - CGAL::qglviewer::Vec center(xcenter+offset.x, ycenter+offset.y, zcenter+offset.z); - frame->setPosition(center); -} - -void -Scene_c3t3_item::setColor(QColor c) -{ - color_ = c; - d->compute_color_map(c); - invalidateOpenGLBuffers(); - d->invalidate_stats(); - for(auto v : CGAL::QGLViewer::QGLViewerPool()) - { - CGAL::Three::Viewer_interface* viewer = static_cast(v); - d->are_intersection_buffers_filled[viewer] = false; - } -} - -void Scene_c3t3_item::show_grid(bool b) -{ - d->is_grid_shown = b; - contextMenu()->findChild("actionShowGrid")->setChecked(b); - itemChanged(); -} -void Scene_c3t3_item::show_spheres(bool b) -{ - if(is_valid()) - { - d->spheres_are_shown = b; - contextMenu()->findChild("actionShowSpheres")->setChecked(b); - if(b && !d->spheres) - { - d->spheres = new Scene_spheres_item(this, d->c3t3.number_of_vertices_in_complex(), true); - connect(d->spheres, &Scene_spheres_item::picked, - this, [this](std::size_t id) - { - if(id == (std::size_t)(-1)) - return; - QString msg = QString("Vertex's index : %1; Vertex's in dimension: %2.").arg(d->tr_vertices[id].index()).arg(d->tr_vertices[id].in_dimension()); - CGAL::Three::Three::information(msg); - CGAL::Three::Three::mainViewer()->displayMessage(msg, 5000); - - }); - d->spheres->setName("Protecting spheres"); - d->spheres->setRenderingMode(Gouraud); - connect(d->spheres, SIGNAL(destroyed()), this, SLOT(reset_spheres())); - connect(d->spheres, SIGNAL(on_color_changed()), this, SLOT(on_spheres_color_changed())); - d->computeSpheres(); - lockChild(d->spheres); - scene->addItem(d->spheres); - scene->changeGroup(d->spheres, this); - } - else if (!b && d->spheres!=NULL) - { - unlockChild(d->spheres); - scene->erase(scene->item_id(d->spheres)); - } - Q_EMIT redraw(); - } -} -void Scene_c3t3_item::show_intersection(bool b) -{ - contextMenu()->findChild("actionShowTets")->setChecked(b); - if(b && !d->intersection) - { - d->intersection = new Scene_intersection_item(this); - d->intersection->init_vectors(&d->positions_poly, - &d->normals, - &d->positions_lines, - &d->f_colors, - &d->positions_barycenter); - d->intersection->setName("Intersection tetrahedra"); - d->intersection->setRenderingMode(renderingMode()); - connect(d->intersection, SIGNAL(destroyed()), this, SLOT(reset_intersection_item())); - - for(auto v : CGAL::QGLViewer::QGLViewerPool()) - { - CGAL::Three::Viewer_interface* viewer = static_cast(v); - d->are_intersection_buffers_filled[viewer] = false; - if(!d->areInterBufFilled(viewer)) - { - //initGL - Scene_c3t3_item* ncthis = const_cast(this); - ncthis->d->computeIntersections(viewer); - d->are_intersection_buffers_filled[viewer] = true; - } - } - scene->addItem(d->intersection); - scene->changeGroup(d->intersection, this); - lockChild(d->intersection); - } - else if (!b && d->intersection!=NULL) - { - unlockChild(d->intersection); - scene->erase(scene->item_id(d->intersection)); - } - if(d->last_intersection != b) - { - d->last_intersection = b; - Q_EMIT redraw(); - } + d->is_valid = b; } void Scene_c3t3_item::show_cnc(bool b) @@ -1665,139 +265,103 @@ void Scene_c3t3_item::show_cnc(bool b) } } -void Scene_c3t3_item::reset_intersection_item() +bool Scene_c3t3_item::load_binary(std::istream& is) { - d->intersection = NULL; -} - -void Scene_c3t3_item::reset_spheres() -{ - d->spheres = NULL; -} -CGAL::Three::Scene_item::ManipulatedFrame* Scene_c3t3_item::manipulatedFrame() { - if(d) - return d->frame; - else - return NULL; -} - -void Scene_c3t3_item::setPosition(float x, float y, float z) { - const CGAL::qglviewer::Vec offset = Three::mainViewer()->offset(); - d->frame->setPosition(x+offset.x, y+offset.y, z+offset.z); -} - -bool Scene_c3t3_item::has_spheres()const { return d->spheres_are_shown;} - -bool Scene_c3t3_item::has_grid()const { return d->is_grid_shown;} - -bool Scene_c3t3_item::has_cnc()const { return d->cnc_are_shown;} - -bool Scene_c3t3_item::has_tets()const { return d->intersection; } - -void Scene_c3t3_item::setNormal(float x, float y, float z) { - d->frame->setOrientation(x, y, z, 0.f); -} - -void Scene_c3t3_item::copyProperties(Scene_item *item) -{ - Scene_c3t3_item* c3t3_item = qobject_cast(item); - if(!c3t3_item) - return; - const CGAL::qglviewer::Vec offset = Three::mainViewer()->offset(); - d->frame->setPositionAndOrientation(c3t3_item->manipulatedFrame()->position() - offset, - c3t3_item->manipulatedFrame()->orientation()); - - show_intersection(c3t3_item->has_tets()); - - show_spheres(c3t3_item->has_spheres()); - - show_cnc(c3t3_item->has_cnc()); - - show_grid(c3t3_item->has_grid()); - int value = c3t3_item->alphaSlider()->value(); - alphaSlider()->setValue(value); -} - -bool Scene_c3t3_item::is_valid() const -{ - return d->is_valid; -} -void Scene_c3t3_item::set_valid(bool b) -{ - d->is_valid = b; -} -float Scene_c3t3_item::getShrinkFactor() const -{ - return float(d->tet_Slider->value())/100.0f; -} - -bool Scene_c3t3_item::eventFilter(QObject *, QEvent *event) -{ - if(event->type() == QEvent::MouseButtonRelease) - { - redraw(); + if(!CGAL::Mesh_3::load_binary_file(is, c3t3())) return false; + resetCutPlane(); + if(is.good()) { + c3t3_changed(); + changed(); + return true; } - return false; + else + return false; } -bool Scene_c3t3_item::keyPressEvent(QKeyEvent *event) +void Scene_c3t3_item::export_facets_in_complex() { - if(event->key() == Qt::Key_Plus) - { - d->tet_Slider->setValue(d->tet_Slider->value() + 5); - itemChanged(); - } - else if(event->key() == Qt::Key_Minus) - { - d->tet_Slider->setValue(d->tet_Slider->value() -5); - itemChanged(); - } - return false; + SMesh outmesh; + CGAL::facets_in_complex_3_to_triangle_mesh(c3t3(), outmesh); + Scene_surface_mesh_item* item = new Scene_surface_mesh_item(std::move(outmesh)); + item->setName(QString("%1_%2").arg(this->name()).arg("facets")); + scene->addItem(item); + this->setVisible(false); +} + +void Scene_c3t3_item::drawEdges(Viewer_interface *viewer) const +{ + Scene_triangulation_3_item::drawEdges(viewer); +//add cnc + if(d->cnc_are_shown) + { + getEdgeContainer(CNC)->setColor(QColor(Qt::black)); + getEdgeContainer(CNC)->draw(viewer, true); + } +} + +void Scene_c3t3_item::initializeBuffers(CGAL::Three::Viewer_interface *viewer)const +{ + Scene_triangulation_3_item::initializeBuffers(viewer); + // add cnc + { + getEdgeContainer(Scene_c3t3_item::CNC)->initializeBuffers(viewer); + getEdgeContainer(Scene_c3t3_item::CNC)->setFlatDataSize( + d->positions_lines_not_in_complex_size); + d->positions_lines_not_in_complex.clear(); + d->positions_lines_not_in_complex.shrink_to_fit(); + } +} +void Scene_c3t3_item::computeElements()const +{ + Scene_triangulation_3_item::computeElements(); + QApplication::setOverrideCursor(Qt::WaitCursor); + //add cnc + //the cells not in the complex + Geom_traits::Construct_point_3 wp2p + = c3t3().triangulation().geom_traits().construct_point_3_object(); + for(C3t3::Triangulation::Cell_iterator + cit = c3t3().triangulation().finite_cells_begin(), + end = c3t3().triangulation().finite_cells_end(); + cit != end; ++cit) + { + if(!c3t3().is_in_complex(cit)) + { + + bool has_far_point = false; + for(int i=0; i<4; i++) + if(c3t3().in_dimension(cit->vertex(i)) == -1) + { + has_far_point = true; + break; + } + if(!has_far_point) + { + const Tr::Bare_point& p1 = wp2p(cit->vertex(0)->point()); + const Tr::Bare_point& p2 = wp2p(cit->vertex(1)->point()); + const Tr::Bare_point& p3 = wp2p(cit->vertex(2)->point()); + const Tr::Bare_point& p4 = wp2p(cit->vertex(3)->point()); + d->draw_triangle_edges_cnc(p1, p2, p4); + d->draw_triangle_edges_cnc(p1, p3, p4); + d->draw_triangle_edges_cnc(p2, p3, p4); + d->draw_triangle_edges_cnc(p1, p2, p3); + } + } + } + getEdgeContainer(CNC)->allocate( + Ec::Vertices, + d->positions_lines_not_in_complex.data(), + static_cast(d->positions_lines_not_in_complex.size()*sizeof(float))); + d->positions_lines_not_in_complex_size = d->positions_lines_not_in_complex.size(); + QApplication::restoreOverrideCursor(); } QString Scene_c3t3_item::computeStats(int type) { - Geom_traits::Construct_point_3 wp2p - = d->c3t3.triangulation().geom_traits().construct_point_3_object(); - + if(type != Scene_c3t3_item_priv::NB_CNC) + return Scene_triangulation_3_item::computeStats(type); if(!d->computed_stats) { - double nb_edges = 0; - double total_edges = 0; - double nb_angle = 0; - double total_angle = 0; - - for (C3t3::Facet_iterator - fit = d->c3t3.facets_begin(), - end = d->c3t3.facets_end(); - fit != end; ++fit) - { - const Tr::Cell_handle& cell = fit->first; - const int& index = fit->second; - const Tr::Bare_point& pa = wp2p(cell->vertex((index + 1) & 3)->point()); - const Tr::Bare_point& pb = wp2p(cell->vertex((index + 2) & 3)->point()); - const Tr::Bare_point& pc = wp2p(cell->vertex((index + 3) & 3)->point()); - double edges[3]; - edges[0]=(std::sqrt(CGAL::squared_distance(pa, pb))); - edges[1]=(std::sqrt(CGAL::squared_distance(pa, pc))); - edges[2]=(std::sqrt(CGAL::squared_distance(pb, pc))); - for(int i=0; i<3; ++i) - { - if(edges[i] < d->min_edges_length){ d->min_edges_length = static_cast(edges[i]); } - if(edges[i] > d->max_edges_length){ d->max_edges_length = static_cast(edges[i]); } - total_edges+=edges[i]; - ++nb_edges; - } - } - d->mean_edges_length = static_cast(total_edges/nb_edges); - for(Tr::Finite_vertices_iterator - vit = d->c3t3.triangulation().finite_vertices_begin(), - end = d->c3t3.triangulation().finite_vertices_end(); - vit != end; ++vit) - { - if(vit->point().weight()==0) continue; - ++d->nb_spheres; - } + d->nb_cnc = 0; for(C3t3::Triangulation::Cell_iterator cit = d->c3t3.triangulation().finite_cells_begin(), end = d->c3t3.triangulation().finite_cells_end(); @@ -1817,307 +381,24 @@ QString Scene_c3t3_item::computeStats(int type) ++d->nb_cnc; } } - - Geom_traits::Compute_approximate_dihedral_angle_3 approx_dihedral_angle - = d->c3t3.triangulation().geom_traits().compute_approximate_dihedral_angle_3_object(); - - QVector sub_ids; - for (C3t3::Cells_in_complex_iterator cit = d->c3t3.cells_in_complex_begin(); - cit != d->c3t3.cells_in_complex_end(); - ++cit) - { - if (!d->c3t3.is_in_complex(cit)) - continue; - if(!sub_ids.contains(cit->subdomain_index())) - { - sub_ids.push_back(cit->subdomain_index()); - } - - const Tr::Bare_point& p0 = wp2p(cit->vertex(0)->point()); - const Tr::Bare_point& p1 = wp2p(cit->vertex(1)->point()); - const Tr::Bare_point& p2 = wp2p(cit->vertex(2)->point()); - const Tr::Bare_point& p3 = wp2p(cit->vertex(3)->point()); - double v = std::abs(CGAL::volume(p0, p1, p2, p3)); - double circumradius = std::sqrt(CGAL::squared_radius(p0, p1, p2, p3)); - //find smallest edge - double edges[6]; - edges[0] = std::sqrt(CGAL::squared_distance(p0, p1)); - edges[1] = std::sqrt(CGAL::squared_distance(p0, p2)); - edges[2] = std::sqrt(CGAL::squared_distance(p0, p3)); - edges[3] = std::sqrt(CGAL::squared_distance(p2, p1)); - edges[4] = std::sqrt(CGAL::squared_distance(p2, p3)); - edges[5] = std::sqrt(CGAL::squared_distance(p1, p3)); - - double min_edge = edges[0]; - for(int i=1; i<6; ++i) - { - if(edges[i]smallest_edge_radius) - d->smallest_edge_radius = static_cast(smallest_edge_radius); - - if(smallest_radius_radius < d->smallest_radius_radius) - d->smallest_radius_radius = static_cast(smallest_radius_radius); - - if(biggest_v_sma_cube > d->biggest_v_sma_cube) - d->biggest_v_sma_cube = static_cast(biggest_v_sma_cube); - - auto update_min_max_dihedral_angle = [this](double a) { - if(a < this->d->min_dihedral_angle) { this->d->min_dihedral_angle = static_cast(a); } - if(a > this->d->max_dihedral_angle) { this->d->max_dihedral_angle = static_cast(a); } - }; - - double a = CGAL::to_double(CGAL::abs(approx_dihedral_angle(p0, p1, p2, p3))); - update_min_max_dihedral_angle(a); - total_angle+=a; - ++nb_angle; - a = CGAL::to_double(CGAL::abs(approx_dihedral_angle(p0, p2, p1, p3))); - update_min_max_dihedral_angle(a); - total_angle+=a; - ++nb_angle; - a = CGAL::to_double(CGAL::abs(approx_dihedral_angle(p0, p3, p1, p2))); - update_min_max_dihedral_angle(a); - total_angle+=a; - ++nb_angle; - a = CGAL::to_double(CGAL::abs(approx_dihedral_angle(p1, p2, p0, p3))); - update_min_max_dihedral_angle(a); - total_angle+=a; - ++nb_angle; - a = CGAL::to_double(CGAL::abs(approx_dihedral_angle(p1, p3, p0, p2))); - update_min_max_dihedral_angle(a); - total_angle+=a; - ++nb_angle; - a = CGAL::to_double(CGAL::abs(approx_dihedral_angle(p2, p3, p0, p1))); - update_min_max_dihedral_angle(a); - total_angle+=a; - ++nb_angle; - } - d->mean_dihedral_angle = static_cast(total_angle/nb_angle); - d->nb_subdomains = sub_ids.size(); - d->nb_vertices = d->c3t3.number_of_vertices_in_complex(); - d->nb_tets = d->c3t3.number_of_cells(); d->computed_stats = true; } - - switch (type) - { - case Scene_c3t3_item_priv::MIN_EDGES_LENGTH: - return QString::number(d->min_edges_length); - case Scene_c3t3_item_priv::MAX_EDGES_LENGTH: - return QString::number(d->max_edges_length); - case Scene_c3t3_item_priv::MEAN_EDGES_LENGTH: - return QString::number(d->mean_edges_length); - case Scene_c3t3_item_priv::MIN_DIHEDRAL_ANGLE: - return QString::number(d->min_dihedral_angle); - case Scene_c3t3_item_priv::MAX_DIHEDRAL_ANGLE: - return QString::number(d->max_dihedral_angle); - case Scene_c3t3_item_priv::MEAN_DIHEDRAL_ANGLE: - return QString::number(d->mean_dihedral_angle); - case Scene_c3t3_item_priv::NB_SPHERES: - return QString::number(d->nb_spheres); - case Scene_c3t3_item_priv::NB_CNC: - return QString::number(d->nb_cnc); - case Scene_c3t3_item_priv::NB_VERTICES: - return QString::number(d->nb_vertices); - case Scene_c3t3_item_priv::NB_TETS: - return QString::number(d->nb_tets); - case Scene_c3t3_item_priv::SMALLEST_RAD_RAD: - return QString::number(d->smallest_radius_radius); - case Scene_c3t3_item_priv::SMALLEST_EDGE_RAD: - return QString::number(d->smallest_edge_radius); - case Scene_c3t3_item_priv::BIGGEST_VL3_CUBE: - return QString::number(d->biggest_v_sma_cube); - case Scene_c3t3_item_priv::NB_SUBDOMAINS: - return QString::number(d->nb_subdomains); - - default: - return QString(); - } + return QString::number(d->nb_cnc); } + CGAL::Three::Scene_item::Header_data Scene_c3t3_item::header() const { - CGAL::Three::Scene_item::Header_data data; - //categories - data.categories.append(std::pair(QString("Properties"),14)); - - - //titles - data.titles.append(QString("Min Edges Length")); - data.titles.append(QString("Max Edges Length")); - data.titles.append(QString("Mean Edges Length")); - data.titles.append(QString("Min Dihedral Angle")); - data.titles.append(QString("Max Dihedral Angle")); - data.titles.append(QString("Mean Dihedral Angle")); - data.titles.append(QString("#Protecting Spheres")); + CGAL::Three::Scene_item::Header_data data = Scene_triangulation_3_item::header(); + data.categories[0] = std::pair(QString("Properties"),14); data.titles.append(QString("#Cells not in Complex")); - data.titles.append(QString("#Vertices in Complex")); - data.titles.append(QString("#Cells")); - data.titles.append(QString("Smallest Radius-Radius Ratio")); - data.titles.append(QString("Smallest Edge-Radius Ratio")); - data.titles.append(QString("Biggest Vl^3")); - data.titles.append(QString("#Subdomains")); return data; } -void Scene_c3t3_item::invalidateOpenGLBuffers() +bool Scene_c3t3_item::has_cnc()const { return d->cnc_are_shown;} + +bool Scene_c3t3_item::is_surface() const { - setBuffersFilled(false); - getTriangleContainer(C3t3_faces)->reset_vbos(ALL); - getEdgeContainer(C3t3_edges)->reset_vbos(ALL); - getEdgeContainer(CNC)->reset_vbos(ALL); - getEdgeContainer(Grid_edges)->reset_vbos(ALL); - getPointContainer(C3t3_points)->reset_vbos(ALL); - - Q_FOREACH(CGAL::QGLViewer* v, CGAL::QGLViewer::QGLViewerPool()) - { - CGAL::Three::Viewer_interface* viewer = static_cast(v); - if(viewer == NULL) - continue; - setBuffersInit(viewer, false); - } - resetCutPlane(); - compute_bbox(); - d->invalidate_stats(); -} -void Scene_c3t3_item::resetCutPlane() -{ - if(!d) - return; - d->reset_cut_plane(); -} - -void Scene_c3t3_item::itemAboutToBeDestroyed(Scene_item *item) -{ - Scene_item::itemAboutToBeDestroyed(item); - - if(d && item == this) - { - d->c3t3.clear(); - d->tree.clear(); - if(d->frame) - { - Three::mainViewer()->setManipulatedFrame(0); - delete d->frame; - d->frame = NULL; - delete d->tet_Slider; - } - delete d; - d=0; - } - -} -void Scene_c3t3_item::on_spheres_color_changed() -{ - if(!d->spheres) - return; - d->spheres->clear_spheres(); - d->computeSpheres(); -} - -float Scene_c3t3_item::alpha() const -{ - if(!d->alphaSlider) - return 1.0f; - return (float)d->alphaSlider->value() / 255.0f; -} - -void Scene_c3t3_item::setAlpha(int alpha) -{ - if(!d->alphaSlider) - d->computeElements(); - d->alphaSlider->setValue(alpha); - if(d->intersection) - d->intersection->setAlpha(alpha); - redraw(); -} - -QSlider* Scene_c3t3_item::alphaSlider() { - if(!d->alphaSlider) - d->computeElements(); - return d->alphaSlider; -} - -void Scene_c3t3_item::initializeBuffers(Viewer_interface *v) const -{ - const_cast(this)->d->initializeBuffers(v); -} - -void Scene_c3t3_item::computeElements()const -{ - QApplication::setOverrideCursor(Qt::WaitCursor); - const_cast(this)->d->computeElements(); - - getTriangleContainer(C3t3_faces)->allocate( - Tc::Flat_vertices, d->positions_poly.data(), - static_cast(d->positions_poly.size()*sizeof(float))); - - getTriangleContainer(C3t3_faces)->allocate( - Tc::Flat_normals, - d->normals.data(), - static_cast(d->normals.size()*sizeof(float))); - - - getTriangleContainer(C3t3_faces)->allocate( - Tc::FColors, - d->f_colors.data(), - static_cast(d->f_colors.size()*sizeof(float))); - - getTriangleContainer(C3t3_faces)->allocate( - Tc::Facet_centers, - d->positions_barycenter.data(), - static_cast(d->positions_barycenter.size()*sizeof(float))); - - d->positions_poly_size = d->positions_poly.size(); - - getEdgeContainer(C3t3_edges)->allocate( - Ec::Vertices, - d->positions_lines.data(), - static_cast(d->positions_lines.size()*sizeof(float))); - d->positions_lines_size = d->positions_lines.size(); - - getEdgeContainer(CNC)->allocate( - Ec::Vertices, - d->positions_lines_not_in_complex.data(), - static_cast(d->positions_lines_not_in_complex.size()*sizeof(float))); - - d->positions_lines_not_in_complex_size = d->positions_lines_not_in_complex.size(); - - getEdgeContainer(Grid_edges)->allocate( - Ec::Vertices, - d->positions_grid.data(), - static_cast(d->positions_grid.size()*sizeof(float))); - - getPointContainer(C3t3_points)->allocate( - Pc::Vertices, - d->positions_lines.data(), - static_cast(d->positions_lines.size()*sizeof(float))); - - setBuffersFilled(true); - QApplication::restoreOverrideCursor(); -} - -void Scene_c3t3_item::newViewer(Viewer_interface *viewer) -{ - viewer->installEventFilter(this); - Scene_item_rendering_helper::newViewer(viewer); - if(d->intersection) - { - d->intersection->newViewer(viewer); - d->computeIntersections(viewer); - } -} - -Scene_c3t3_item* Scene_c3t3_item::clone() const -{ - return new Scene_c3t3_item(d->c3t3, d->is_surface); + return d->is_surface; } void Scene_c3t3_item::set_sharp_edges_angle(double a) { d->sharp_edges_angle = a; } @@ -2126,9 +407,20 @@ double Scene_c3t3_item::get_sharp_edges_angle() { return d->sharp_edges_angle; } void Scene_c3t3_item::set_detect_borders(bool b) { d->detect_borders = b;} bool Scene_c3t3_item::get_detect_borders() { return d->detect_borders; } -std::size_t Scene_c3t3_item::number_of_patches() const +Scene_c3t3_item* Scene_c3t3_item::clone() const { - return d->surface_patch_indices_.size(); + return new Scene_c3t3_item(d->c3t3, d->is_surface); } + +void Scene_c3t3_item::copyProperties(Scene_item *item) +{ + Scene_triangulation_3_item::copyProperties(item); + Scene_c3t3_item* c3t3_item = qobject_cast(item); + if(!c3t3_item) + return; + show_cnc(c3t3_item->has_cnc()); + +} + #include "Scene_c3t3_item.moc" diff --git a/Polyhedron/demo/Polyhedron/Scene_c3t3_item.h b/Polyhedron/demo/Polyhedron/Scene_c3t3_item.h index c34951335b6..ea3a5572e10 100644 --- a/Polyhedron/demo/Polyhedron/Scene_c3t3_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_c3t3_item.h @@ -21,168 +21,81 @@ #include #include #include -#include +#include "Scene_triangulation_3_item.h" struct Scene_c3t3_item_priv; -class Scene_spheres_item; -class Scene_intersection_item; using namespace CGAL::Three; class SCENE_C3T3_ITEM_EXPORT Scene_c3t3_item - : public Scene_group_item, public Scene_item_with_properties -{ - Q_OBJECT -public: - typedef CGAL::qglviewer::ManipulatedFrame ManipulatedFrame; + : public Scene_triangulation_3_item + { + Q_OBJECT + public: + typedef CGAL::qglviewer::ManipulatedFrame ManipulatedFrame; - Scene_c3t3_item(bool is_surface = false); - Scene_c3t3_item(const C3t3& c3t3, bool is_surface = false); - ~Scene_c3t3_item(); + Scene_c3t3_item(bool is_surface = false); + Scene_c3t3_item(const C3t3& c3t3, bool is_surface = false); + ~Scene_c3t3_item(); - void common_constructor(bool is_surface); - bool has_stats()const Q_DECL_OVERRIDE {return true;} - QString computeStats(int type) Q_DECL_OVERRIDE; - CGAL::Three::Scene_item::Header_data header() const Q_DECL_OVERRIDE; + Scene_c3t3_item* clone() const override; + const C3t3& c3t3() const; + C3t3& c3t3(); + + void c3t3_changed(); + + const T3& triangulation() const override; + T3& triangulation() override; - void setColor(QColor c) Q_DECL_OVERRIDE; bool save_binary(std::ostream& os) const { return CGAL::IO::save_binary_file(os, c3t3()); } + bool save_ascii(std::ostream& os) const { os << "ascii CGAL c3t3 " << CGAL::Get_io_signature()() << "\n"; CGAL::IO::set_ascii_mode(os); return !!(os << c3t3()); - } + } + bool load_binary(std::istream& is) override; - void invalidateOpenGLBuffers() Q_DECL_OVERRIDE; + bool is_valid() const;//true if the c3t3 is correct, false if it was made from a .mesh, for example + void set_valid(bool); + QMenu* contextMenu() override; - void c3t3_changed(); + void drawEdges(Viewer_interface *viewer) const override; - void resetCutPlane(); + //stats + QString computeStats(int type) override; - void set_valid(bool); + void copyProperties(Scene_item *) override; - const C3t3& c3t3() const; - C3t3& c3t3(); - - bool manipulatable() const Q_DECL_OVERRIDE{ - return true; - } - - bool has_spheres() const; - bool has_grid() const; - bool has_cnc() const; - bool has_tets() const; - bool is_valid() const;//true if the c3t3 is correct, false if it was made from a .mesh, for example - float alpha() const Q_DECL_OVERRIDE; - void setAlpha(int alpha) Q_DECL_OVERRIDE; - QSlider* alphaSlider(); - ManipulatedFrame* manipulatedFrame() Q_DECL_OVERRIDE; - - void setPosition(float x, float y, float z) ; - - void setNormal(float x, float y, float z) ; - - Geom_traits::Plane_3 plane(CGAL::qglviewer::Vec offset = CGAL::qglviewer::Vec(0,0,0)) const; - - bool isFinite() const Q_DECL_OVERRIDE { return true; } - bool isEmpty() const Q_DECL_OVERRIDE { - return c3t3().triangulation().number_of_vertices() == 0 - || ( c3t3().number_of_vertices_in_complex() == 0 - && c3t3().number_of_facets_in_complex() == 0 - && c3t3().number_of_cells_in_complex() == 0 ); - } - - - void compute_bbox() const Q_DECL_OVERRIDE; - Scene_item::Bbox bbox() const Q_DECL_OVERRIDE - { - return Scene_item::bbox(); - } - - Scene_c3t3_item* clone() const Q_DECL_OVERRIDE; - - bool load_binary(std::istream& is); - - // data item - const Scene_item* data_item() const; - void set_data_item(const Scene_item* data_item); - - QString toolTip() const Q_DECL_OVERRIDE; - - // Indicate if rendering mode is supported - bool supportsRenderingMode(RenderingMode m) const Q_DECL_OVERRIDE{ - return (m != Gouraud && m != PointsPlusNormals && m != Points && m != ShadedPoints); - } - - void draw(CGAL::Three::Viewer_interface* viewer) const Q_DECL_OVERRIDE; - void drawEdges(CGAL::Three::Viewer_interface* viewer) const Q_DECL_OVERRIDE; - void drawPoints(CGAL::Three::Viewer_interface * viewer) const Q_DECL_OVERRIDE; - //When selecting a c3t3 item, we don't want to select its children, so we can still apply Operations to it - QList getChildrenForSelection() const Q_DECL_OVERRIDE { return QList(); } - public: - QMenu* contextMenu() Q_DECL_OVERRIDE; - void copyProperties(Scene_item *) Q_DECL_OVERRIDE; - float getShrinkFactor() const; - bool keyPressEvent(QKeyEvent *) Q_DECL_OVERRIDE; - bool eventFilter(QObject *, QEvent *) Q_DECL_OVERRIDE; - std::size_t number_of_patches() const; + CGAL::Three::Scene_item::Header_data header() const override; + bool has_cnc() const; public Q_SLOTS: + void show_cnc(bool); + void export_facets_in_complex(); + void initializeBuffers(Viewer_interface *) const override; + void computeElements() const override; + void set_sharp_edges_angle(double d); + double get_sharp_edges_angle(); - void on_spheres_color_changed(); - void export_facets_in_complex(); - - void data_item_destroyed(); - - void reset_spheres(); - - void reset_intersection_item(); - void show_spheres(bool b); - void show_intersection(bool b); - void show_grid(bool b); - void show_cnc(bool b); - - virtual QPixmap graphicalToolTip() const Q_DECL_OVERRIDE; - - void update_histogram(); - - void changed(); - - void updateCutPlane(); - - void build_histogram(); - - QColor get_histogram_color(const double v) const; - - void set_sharp_edges_angle(double d); - double get_sharp_edges_angle(); - - void set_detect_borders(bool b); - bool get_detect_borders(); - - void itemAboutToBeDestroyed(Scene_item *) Q_DECL_OVERRIDE; - - void initializeBuffers(Viewer_interface *) const Q_DECL_OVERRIDE; - void computeElements() const Q_DECL_OVERRIDE; - void newViewer(Viewer_interface *viewer) Q_DECL_OVERRIDE; + void set_detect_borders(bool b); + bool get_detect_borders(); protected: friend struct Scene_c3t3_item_priv; - Scene_c3t3_item_priv* d; - enum Face_Containers{ - C3t3_faces = 0 - }; - enum Edge_Containers{ - C3t3_edges = 0, - Grid_edges, - CNC - }; - enum Point_Container{ - C3t3_points = 0 - }; + mutable Scene_c3t3_item_priv* d; -}; + enum Edge_Containers{ + CNC = 2 + }; + bool do_take_cell(const T3::Cell_handle&) const override; + bool do_take_facet(const T3::Facet&)const override; + bool do_take_vertex(const T3::Vertex_handle &)const override; + bool is_facet_oriented(const T3::Facet&)const override; + bool is_surface()const override; + void common_constructor(bool is_surface); + }; #endif // SCENE_C3T3_ITEM_H diff --git a/Polyhedron/demo/Polyhedron/Scene_tetrahedra_item.cpp b/Polyhedron/demo/Polyhedron/Scene_tetrahedra_item.cpp new file mode 100644 index 00000000000..56d7278ade4 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Scene_tetrahedra_item.cpp @@ -0,0 +1,390 @@ +#include +#include +#include +#include +#include +#include "Scene_tetrahedra_item.h" +#include "C3t3_type.h" +#include "CGAL_double_edit.h" + +using namespace CGAL::Three; +typedef Viewer_interface Vi; +typedef Triangle_container Tri; + +struct tet_item_priv{ + mutable Scene_c3t3_item* c3t3_item; + mutable std::vector positions; + mutable std::vector filter_values[4]; + mutable std::size_t positions_size; + mutable std::vector normals; + mutable std::vector colors; + mutable CGAL::qglviewer::Vec offset; + float min_threshold; + float max_threshold; + float threshold_1; + float threshold_2; + int filter_index; + double extrema[4][2]; + QLabel* minMinLabel; + QLabel* minMaxLabel; + QLabel* maxMinLabel; + QLabel* maxMaxLabel; + + DoubleEdit* minEdit; + DoubleEdit* maxEdit; + + void draw_triangle(const Tr::Bare_point& a, + const Tr::Bare_point& b, + const Tr::Bare_point& c, + const QColor& color) + { + const CGAL::qglviewer::Vec offset = Three::mainViewer()->offset(); + Geom_traits::Vector_3 n = cross_product(b - a, c - a); + n = n / CGAL::sqrt(n*n); + + auto push_normal = [this](auto n) { + normals.push_back(static_cast(n.x())); + normals.push_back(static_cast(n.y())); + normals.push_back(static_cast(n.z())); + }; + auto push_color = [this](auto c) { + colors.push_back(static_cast(c.redF())); + colors.push_back(static_cast(c.greenF())); + colors.push_back(static_cast(c.blueF())); + }; + + positions.push_back(static_cast(a.x()+offset.x)); + positions.push_back(static_cast(a.y()+offset.y)); + positions.push_back(static_cast(a.z()+offset.z)); + + positions.push_back(static_cast(b.x()+offset.x)); + positions.push_back(static_cast(b.y()+offset.y)); + positions.push_back(static_cast(b.z()+offset.z)); + + positions.push_back(static_cast(c.x()+offset.x)); + positions.push_back(static_cast(c.y()+offset.y)); + positions.push_back(static_cast(c.z()+offset.z)); + + for (int i = 0; i<3; i++) + { + push_normal(n); + push_color(color); + } + } + + +}; +Scene_tetrahedra_item::Scene_tetrahedra_item(Scene_c3t3_item* c3t3_item) + : Scene_item_rendering_helper(), + d(new tet_item_priv) +{ + d->c3t3_item = c3t3_item; + d->positions_size = 0; + d->min_threshold = 0.0f; + d->max_threshold = 1.0f; + d->threshold_1 = 0.0f; + d->threshold_2 = 1.0f; + d->filter_index = 0; + d->extrema[0][0] = 360.0; + d->extrema[0][1] = 360; + d->extrema[1][0] = 0; + d->extrema[1][1] = 0; + d->extrema[2][0] = 1.0; + d->extrema[2][1] = 0; + d->extrema[3][0] = (std::numeric_limits::max)(); + d->extrema[3][1] = 0.0; + d->minMinLabel = nullptr; + d->minMaxLabel = nullptr; + d->maxMinLabel = nullptr; + d->maxMaxLabel = nullptr; + + d->minEdit = nullptr; + d->maxEdit = nullptr; + setFlatMode(); + setTriangleContainer(0, + new Tri(Vi::PROGRAM_TETRA_FILTERING, false)); + +} + +void Scene_tetrahedra_item::draw(CGAL::Three::Viewer_interface* viewer) const +{ + if(!isInit(viewer)) + { + initGL(viewer); + } + if ( getBuffersFilled() && + ! getBuffersInit(viewer)) + { + initializeBuffers(viewer); + setBuffersInit(viewer, true); + } + if(!getBuffersFilled()) + { + computeElements(); + initializeBuffers(viewer); + } + getTriangleContainer(0)->setColor(this->color()); + getTriangleContainer(0)->getVao(viewer)->bind(); + getTriangleContainer(0)->getVao(viewer)->program->setUniformValue("min_threshold", d->min_threshold); + getTriangleContainer(0)->getVao(viewer)->program->setUniformValue("max_threshold", d->max_threshold); + getTriangleContainer(0)->getVao(viewer)->release(); + getTriangleContainer(0)->draw(viewer, true); + +} + + +void Scene_tetrahedra_item::invalidateOpenGLBuffers() +{ + setBuffersFilled(false); + getTriangleContainer(0)->reset_vbos(ALL); + compute_bbox(); + +} + +void Scene_tetrahedra_item::computeElements()const +{ + CGAL::Three::Three::CursorScopeGuard guard{QCursor(Qt::WaitCursor)}; + for(int i=0; i<4; ++i) + { + d->filter_values[i].clear(); + d->filter_values[i].shrink_to_fit(); + } + d->offset = CGAL::Three::Three::mainViewer()->offset(); + const C3t3& c3t3 = d->c3t3_item->c3t3(); + Geom_traits::Construct_point_3 wp2p + = c3t3.triangulation().geom_traits().construct_point_3_object(); + Geom_traits::Compute_approximate_dihedral_angle_3 approx_dihedral_angle + = c3t3.triangulation().geom_traits().compute_approximate_dihedral_angle_3_object(); + d->extrema[0][0] = 360.0; + d->extrema[0][1] = 0; + d->extrema[1][0] = 360; + d->extrema[1][1] = 0; + d->extrema[2][0] = 9999999999; + d->extrema[2][1] = 0; + d->extrema[3][0] = 1.0; + d->extrema[3][1] = 0.0; + std::vector tmp_min, tmp_max, tmp_rrr, tmp_v; + tmp_min.reserve(c3t3.number_of_cells_in_complex()); + tmp_max.reserve(c3t3.number_of_cells_in_complex()); + tmp_rrr.reserve(c3t3.number_of_cells_in_complex()); + tmp_v.reserve(c3t3.number_of_cells_in_complex()); + + + for(C3t3::Triangulation::Cell_iterator + cit = c3t3.triangulation().finite_cells_begin(), + end = c3t3.triangulation().finite_cells_end(); + cit != end; ++cit) + { + if(!c3t3.is_in_complex(cit)) + { + continue; + } + const Tr::Bare_point& pa = wp2p(cit->vertex(0)->point()); + const Tr::Bare_point& pb = wp2p(cit->vertex(1)->point()); + const Tr::Bare_point& pc = wp2p(cit->vertex(2)->point()); + const Tr::Bare_point& pd = wp2p(cit->vertex(3)->point()); + const QColor color = d->c3t3_item->getSubdomainIndexColor(cit->subdomain_index()); + //0 - 1 : dihedral angle + double min_dihedral_angle = 360.0; + double max_dihedral_angle = -360.0; + double a = CGAL::to_double(CGAL::abs(approx_dihedral_angle(pa, pb, pc, pd))); + if(a < min_dihedral_angle) { min_dihedral_angle = static_cast(a); } + if(a > max_dihedral_angle) { max_dihedral_angle = static_cast(a); } + a = CGAL::to_double(CGAL::abs(approx_dihedral_angle(pa, pc, pb, pd))); + if(a < min_dihedral_angle) { min_dihedral_angle = static_cast(a); } + if(a > max_dihedral_angle) { max_dihedral_angle = static_cast(a); } + a = CGAL::to_double(CGAL::abs(approx_dihedral_angle(pa, pd, pb, pc))); + if(a < min_dihedral_angle) { min_dihedral_angle = static_cast(a); } + if(a > max_dihedral_angle) { max_dihedral_angle = static_cast(a); } + a = CGAL::to_double(CGAL::abs(approx_dihedral_angle(pb, pc, pa, pd))); + if(a < min_dihedral_angle) { min_dihedral_angle = static_cast(a); } + if(a > max_dihedral_angle) { max_dihedral_angle = static_cast(a); } + a = CGAL::to_double(CGAL::abs(approx_dihedral_angle(pb, pd, pa, pc))); + if(a < min_dihedral_angle) { min_dihedral_angle = static_cast(a); } + if(a > max_dihedral_angle) { max_dihedral_angle = static_cast(a); } + a = CGAL::to_double(CGAL::abs(approx_dihedral_angle(pc, pd, pa, pb))); + if(a < min_dihedral_angle) { min_dihedral_angle = static_cast(a); } + if(a > max_dihedral_angle) { max_dihedral_angle = static_cast(a); } + tmp_min.push_back(min_dihedral_angle); + tmp_max.push_back(max_dihedral_angle); + if(min_dihedral_angle < d->extrema[0][0]) { d->extrema[0][0]=min_dihedral_angle; } + if(min_dihedral_angle > d->extrema[0][1]) { d->extrema[0][1]=min_dihedral_angle; } + if(max_dihedral_angle < d->extrema[1][0]) { d->extrema[1][0]=max_dihedral_angle; } + if(max_dihedral_angle > d->extrema[1][1]) { d->extrema[1][1]=max_dihedral_angle; } + //3 : volume + double v = std::abs(CGAL::volume(pa, pb, pc, pd)); + tmp_v.push_back(v); + if(v < d->extrema[3][0]) { d->extrema[3][0] = static_cast(v); } + if(v > d->extrema[3][1]) { d->extrema[3][1] = static_cast(v); } + //2 : Radius-radius ratio + double sumar = std::sqrt(CGAL::squared_area(pa,pb,pc))+std::sqrt(CGAL::squared_area(pb,pc,pd))+ + std::sqrt(CGAL::squared_area(pc,pd,pa)) + std::sqrt(CGAL::squared_area(pd,pb,pa)); + double inradius = 3*v/sumar; + double circumradius = std::sqrt(CGAL::squared_radius(pa, pb, pc, pd)); + double rrr = inradius/circumradius*3; //*3 so that the perfect tet ratio is 1 instead of 1/3 + if(rrr < d->extrema[2][0]) { d->extrema[2][0] = static_cast(rrr); } + if(rrr > d->extrema[2][1]) { d->extrema[2][1] = static_cast(rrr); } + tmp_rrr.push_back(rrr); + d->draw_triangle(pb, pa, pc, color); + d->draw_triangle(pa, pb, pd, color); + d->draw_triangle(pa, pd, pc, color); + d->draw_triangle(pb, pc, pd, color); + } + d->positions_size = d->positions.size(); + for(std::size_t i = 0; i< tmp_min.size(); ++i) + { + float min = tmp_min[i]/(d->extrema[0][1]-d->extrema[0][0]) - d->extrema[0][0]/(d->extrema[0][1]-d->extrema[0][0]); + float max = tmp_max[i]/(d->extrema[1][1]-d->extrema[1][0]) - d->extrema[1][0]/(d->extrema[1][1]-d->extrema[1][0]); + float rrr = tmp_rrr[i]/(d->extrema[2][1]-d->extrema[2][0]) - d->extrema[2][0]/(d->extrema[2][1]-d->extrema[2][0]); + float v = static_cast(tmp_v[i]/(d->extrema[3][1]-d->extrema[3][0]) - d->extrema[3][0]/(d->extrema[3][1] - d->extrema[3][0])); + for(int j = 0; j< 12; ++j) + { + d->filter_values[0].push_back(min); + d->filter_values[1].push_back(max); + d->filter_values[2].push_back(rrr); + d->filter_values[3].push_back(v); + } + } + + getTriangleContainer(0)->allocate( + Tri::Flat_vertices, d->positions.data(), + static_cast(d->positions.size()*sizeof(float))); + getTriangleContainer(0)->allocate( + Tri::Flat_normals, d->normals.data(), + static_cast(d->normals.size()*sizeof(float))); + getTriangleContainer(0)->allocate( + Tri::FColors, d->colors.data(), + static_cast(d->colors.size()*sizeof(float))); + //Use the Distances vbo for the float filter values for convenience. They are probably not a distance, but the mechanism is already here so let's use it. + setBuffersFilled(true); + updateFilter(); +} + +Scene_item* Scene_tetrahedra_item::clone() const +{ + return new Scene_tetrahedra_item(d->c3t3_item); +} +void Scene_tetrahedra_item::compute_bbox() const +{ + if (isEmpty()) + setBbox(Bbox()); + else { + bool bbox_init = false; + CGAL::Bbox_3 result; + const C3t3& c3t3 = d->c3t3_item->c3t3(); + for (Tr::Finite_vertices_iterator + vit = c3t3.triangulation().finite_vertices_begin(), + end = c3t3.triangulation().finite_vertices_end(); + vit != end; ++vit) + { + if(vit->in_dimension() == -1) continue; + if (bbox_init) + result = result + vit->point().bbox(); + else + { + result = vit->point().bbox(); + bbox_init = true; + } + } + setBbox(Bbox(result.xmin(), result.ymin(), result.zmin(), + result.xmax(), result.ymax(), result.zmax())); + } + +} + + +void Scene_tetrahedra_item::initializeBuffers(CGAL::Three::Viewer_interface *viewer) const +{ + getTriangleContainer(0)->initializeBuffers(viewer); + getTriangleContainer(0)->setFlatDataSize(d->positions_size); + + d->positions.clear(); + d->positions.shrink_to_fit(); + d->normals.clear(); + d->normals.shrink_to_fit(); + d->colors.clear(); + d->colors.shrink_to_fit(); +} + +void Scene_tetrahedra_item::setMinThreshold(int i) +{ + d->threshold_1 = 0.001*i; + updateThresholds(); +} + +void Scene_tetrahedra_item::setMaxThreshold(int i) +{ + d->threshold_2 = 0.001*i; + updateThresholds(); +} + +void Scene_tetrahedra_item::setMinThreshold(void) +{ + double i = d->minEdit->text().toDouble(); + d->threshold_1 = 0.001*i; + updateThresholds(false); +} + +void Scene_tetrahedra_item::setMaxThreshold(void) +{ + double i = d->maxEdit->text().toDouble(); + d->threshold_2 = 0.001*i; + updateThresholds(false); +} + +void Scene_tetrahedra_item::setFilter(int i) +{ + d->filter_index = i; + updateFilter(); + redraw(); +} + +void Scene_tetrahedra_item::updateFilter() const +{ + CGAL::Three::Vbo* vbo = getTriangleContainer(0)->getVbo(Tri::Distances); + vbo->allocated = false; + vbo->dataSize=0; + getTriangleContainer(0)->allocate(Tri::Distances, d->filter_values[d->filter_index].data(), + static_cast(d->filter_values[d->filter_index].size()*sizeof(float))); + d->minMinLabel->setText(QString("%1").arg(d->extrema[d->filter_index][0])); + d->minMaxLabel->setText(QString("%1").arg(d->extrema[d->filter_index][1])); + + d->maxMinLabel->setText(QString("%1").arg(d->extrema[d->filter_index][0])); + d->maxMaxLabel->setText(QString("%1").arg(d->extrema[d->filter_index][1])); + + double a = 1/(d->extrema[d->filter_index][1] - d->extrema[d->filter_index][0]); + double b = - d->extrema[d->filter_index][0]/(d->extrema[d->filter_index][1] - d->extrema[d->filter_index][0]); + + d->minEdit->setValue((d->min_threshold - b)/a); + d->maxEdit->setValue((d->max_threshold - b)/a); + for(CGAL::QGLViewer* v : CGAL::QGLViewer::QGLViewerPool()) + { + setBuffersInit(static_cast(v), false); + } +} + +void Scene_tetrahedra_item::setMinMinLabelPointer(QLabel* ptr){ d->minMinLabel = ptr; } +void Scene_tetrahedra_item::setMinMaxLabelPointer(QLabel* ptr){ d->minMaxLabel = ptr; } +void Scene_tetrahedra_item::setMaxMinLabelPointer(QLabel* ptr){ d->maxMinLabel = ptr; } +void Scene_tetrahedra_item::setMaxMaxLabelPointer(QLabel* ptr){ d->maxMaxLabel = ptr; } +void Scene_tetrahedra_item::setMinEditPointer(DoubleEdit* ptr){ d->minEdit= ptr; } +void Scene_tetrahedra_item::setMaxEditPointer(DoubleEdit* ptr){ d->maxEdit = ptr; } + +void Scene_tetrahedra_item::updateThresholds(bool update) +{ + d->max_threshold = (std::max)(d->threshold_1, d->threshold_2); + d->min_threshold = (std::min)(d->threshold_1, d->threshold_2); + if(update) + { + double a = 1/(d->extrema[d->filter_index][1] - d->extrema[d->filter_index][0]); + double b = - d->extrema[d->filter_index][0]/(d->extrema[d->filter_index][1] - d->extrema[d->filter_index][0]); + d->minEdit->setValue((d->min_threshold - b)/a); + d->maxEdit->setValue((d->max_threshold - b)/a); + } + redraw(); +} + +Scene_c3t3_item* Scene_tetrahedra_item::c3t3_item() +{ + return d->c3t3_item; +} diff --git a/Polyhedron/demo/Polyhedron/Scene_tetrahedra_item.h b/Polyhedron/demo/Polyhedron/Scene_tetrahedra_item.h new file mode 100644 index 00000000000..fdf609481d5 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Scene_tetrahedra_item.h @@ -0,0 +1,66 @@ +#ifndef SCENE_TETRAHEDRA_ITEM_H +#define SCENE_TETRAHEDRA_ITEM_H + +#ifndef SCENE_TETRAHEDRA_ITEM_CONFIG_H +#define SCENE_TETRAHEDRA_ITEM_CONFIG_H + +#ifdef scene_tetrahedra_item_EXPORTS +# define mesh_3_demo_scene_tetrahedra_item_EXPORTS 1 +#endif + +#ifdef mesh_3_demo_scene_tetrahedra_item_EXPORTS +# define SCENE_TETRAHEDRA_ITEM_EXPORT Q_DECL_EXPORT +#else +# define SCENE_TETRAHEDRA_ITEM_EXPORT Q_DECL_IMPORT +#endif + +#endif // SCENE_TETRAHEDRA_ITEM_CONFIG_H + + +#include +#include +#include "Scene_c3t3_item.h" + +struct tet_item_priv; +class QLabel; +class DoubleEdit; + +class SCENE_TETRAHEDRA_ITEM_EXPORT Scene_tetrahedra_item : public CGAL::Three::Scene_item_rendering_helper +{ + Q_OBJECT +public : + Scene_tetrahedra_item(Scene_c3t3_item*); + bool supportsRenderingMode(RenderingMode m) const Q_DECL_OVERRIDE { + return (m == Flat); + } + void draw(CGAL::Three::Viewer_interface* viewer) const Q_DECL_OVERRIDE; + void invalidateOpenGLBuffers()Q_DECL_OVERRIDE; + void computeElements() const Q_DECL_OVERRIDE; + Scene_item* clone() const Q_DECL_OVERRIDE; + QString toolTip() const Q_DECL_OVERRIDE{return QString();} + bool isEmpty() const Q_DECL_OVERRIDE{ return false;} + bool isFinite() const Q_DECL_OVERRIDE{ return true;} + void initializeBuffers(CGAL::Three::Viewer_interface *) const Q_DECL_OVERRIDE; + void compute_bbox() const Q_DECL_OVERRIDE; + void setMinMinLabelPointer(QLabel*); + void setMinMaxLabelPointer(QLabel*); + void setMaxMinLabelPointer(QLabel*); + void setMaxMaxLabelPointer(QLabel*); + void setMinEditPointer(DoubleEdit* ); + void setMaxEditPointer(DoubleEdit* ); + Scene_c3t3_item* c3t3_item(); + public Q_SLOTS: + void setMinThreshold(int); + void setMinThreshold(void); + void setMaxThreshold(int); + void setMaxThreshold(void); + void setFilter(int); + +private: + friend struct tet_item_priv; + tet_item_priv* d; + void updateFilter() const; + void updateThresholds(bool update = true); +}; //end of class Scene_tetrahedra_item + +#endif // SCENE_TETRAHEDRA_ITEM_H diff --git a/Polyhedron/demo/Polyhedron/Scene_triangulation_3_item.cpp b/Polyhedron/demo/Polyhedron/Scene_triangulation_3_item.cpp new file mode 100644 index 00000000000..5f95145b69f --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Scene_triangulation_3_item.cpp @@ -0,0 +1,2059 @@ +#include "config.h" +#include "Scene_triangulation_3_item.h" +#include "Scene_surface_mesh_item.h" +#include "Scene_spheres_item.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include "Scene_polygon_soup_item.h" + + +typedef CGAL::AABB_triangulation_3_cell_primitive Primitive; +typedef CGAL::AABB_traits Traits; +typedef CGAL::AABB_tree Tree; +typedef Tree::Point_and_primitive_id Point_and_primitive_id; +using namespace CGAL::Three; +typedef Triangle_container Tc; +typedef Edge_container Ec; +typedef Point_container Pc; +typedef Viewer_interface Vi; + +QVector4D cgal_plane_to_vector4d(EPICK::Plane_3 plane) { + return { + static_cast(-plane.a()), + static_cast(-plane.b()), + static_cast(-plane.c()), + static_cast(-plane.d()) }; +} + + +class Scene_intersection_item : public CGAL::Three::Scene_item_rendering_helper +{ + Q_OBJECT +public : + Scene_intersection_item(Scene_triangulation_3_item* parent) + :is_fast(false) + { + setParent(parent); + alphaSlider = NULL; + m_alpha = 1.0f; + setTriangleContainer(0, new Tc(Vi::PROGRAM_C3T3, false)); + setEdgeContainer(0, new Ec(Vi::PROGRAM_NO_SELECTION, false)); + } + bool isFinite() const Q_DECL_OVERRIDE{ return false; } + ~Scene_intersection_item() + { + if(alphaSlider) + delete alphaSlider; + } + void compute_bbox() const Q_DECL_OVERRIDE{} + + void gl_initialization(Vi* viewer) + { + if(!isInit(viewer)) + initGL(viewer); + computeElements(); + initializeBuffers(viewer); + } + void init_vectors( + std::vector *p_vertices, + std::vector *p_normals, + std::vector *p_edges, + std::vector *p_colors, + std::vector *p_bary, + std::vector *p_subdomain_ids) + { + vertices = p_vertices; + normals = p_normals; + edges = p_edges; + colors = p_colors; + barycenters = p_bary; + subdomain_ids = p_subdomain_ids; + } + void setColor(QColor c) Q_DECL_OVERRIDE + { + qobject_cast(this->parent())->setColor(c); + Scene_item::setColor(c); + } + // Indicates if rendering mode is supported + bool supportsRenderingMode(RenderingMode m) const Q_DECL_OVERRIDE{ + return (m != Gouraud && m != PointsPlusNormals && m != Points && m != ShadedPoints); + } + void computeElements() const Q_DECL_OVERRIDE + { + getTriangleContainer(0)->reset_vbos(ALL); + getEdgeContainer(0)->reset_vbos(ALL); + + getTriangleContainer(0)->allocate(Tc::Flat_vertices, + vertices->data(), static_cast(vertices->size()*sizeof(float))); + getTriangleContainer(0)->allocate(Tc::Flat_normals, normals->data(), + static_cast(normals->size()*sizeof(float))); + getTriangleContainer(0)->allocate(Tc::FColors, colors->data(), + static_cast(colors->size()*sizeof(float))); + getTriangleContainer(0)->allocate(Tc::Facet_centers, barycenters->data(), + static_cast(barycenters->size()*sizeof(float))); + getTriangleContainer(0)->allocate(Tc::Subdomain_indices, subdomain_ids->data(), + static_cast(subdomain_ids->size()*sizeof(float))); + getEdgeContainer(0)->allocate(Ec::Vertices, edges->data(), + static_cast(edges->size()*sizeof(float))); + setBuffersFilled(true); + } + void initializeBuffers(CGAL::Three::Viewer_interface *viewer)const Q_DECL_OVERRIDE + { + //vao containing the data for the facets + { + getTriangleContainer(0)->initializeBuffers(viewer); + getTriangleContainer(0)->setFlatDataSize(vertices->size()); + } + //vao containing the data for the lines + { + getEdgeContainer(0)->initializeBuffers(viewer); + getEdgeContainer(0)->setFlatDataSize(edges->size()); + } + } + + //Displays the item + void draw(CGAL::Three::Viewer_interface* viewer) const Q_DECL_OVERRIDE + { + if(is_fast) + return; + + if(!alphaSlider) + { + alphaSlider = new QSlider(::Qt::Horizontal); + alphaSlider->setMinimum(0); + alphaSlider->setMaximum(255); + alphaSlider->setValue(255); + } + const EPICK::Plane_3& plane = qobject_cast(this->parent())->plane(); + float shrink_factor = qobject_cast(this->parent())->getShrinkFactor(); + QVector4D cp = cgal_plane_to_vector4d(plane); + getTriangleContainer(0)->setPlane(-cp); + getTriangleContainer(0)->setShrinkFactor(shrink_factor); + // positions_poly is also used for the faces in the cut plane + // and changes when the cut plane is moved + getTriangleContainer(0)->setAlpha(alpha()); + getTriangleContainer(0)->draw(viewer, false); + } + void drawEdges(CGAL::Three::Viewer_interface* viewer) const Q_DECL_OVERRIDE + { + if(is_fast) + return; + const EPICK::Plane_3& plane = qobject_cast(this->parent())->plane(); + QVector4D cp = cgal_plane_to_vector4d(plane); + getEdgeContainer(0)->setPlane(cp); + getEdgeContainer(0)->setColor(QColor(Qt::black)); + getEdgeContainer(0)->draw(viewer, true); + + } + + void setFast(bool b) + { + is_fast = b; + } + + void addTriangle(const Tr::Bare_point& pa, const Tr::Bare_point& pb, + const Tr::Bare_point& pc, const CGAL::Color color) + { + const CGAL::qglviewer::Vec offset = Three::mainViewer()->offset(); + Geom_traits::Vector_3 n = cross_product(pb - pa, pc - pa); + n = n / CGAL::sqrt(n*n); + + auto push_normal = [this](auto n) { + normals->push_back(static_cast(n.x())); + normals->push_back(static_cast(n.y())); + normals->push_back(static_cast(n.z())); + }; + + auto push_vertex = [this, &offset](const auto& p) { + this->vertices->push_back(static_cast(p.x()+offset.x)); + this->vertices->push_back(static_cast(p.y()+offset.y)); + this->vertices->push_back(static_cast(p.z()+offset.z)); + }; + + auto push_edge = [this, &offset](const auto& pa, const auto& pb) { + this->edges->push_back(static_cast(pa.x()+offset.x)); + this->edges->push_back(static_cast(pa.y()+offset.y)); + this->edges->push_back(static_cast(pa.z()+offset.z)); + this->edges->push_back(static_cast(pb.x()+offset.x)); + this->edges->push_back(static_cast(pb.y()+offset.y)); + this->edges->push_back(static_cast(pb.z()+offset.z)); + }; + + for (int i = 0; i<3; i++) + { + push_normal(n); + } + push_vertex(pa); + push_vertex(pb); + push_vertex(pc); + + push_edge(pa, pb); + push_edge(pb, pc); + push_edge(pc, pa); + + for(int i=0; i<3; i++) + { + colors->push_back((float)color.red()/255); + colors->push_back((float)color.green()/255); + colors->push_back((float)color.blue()/255); + + barycenters->push_back(static_cast((pa[0]+pb[0]+pc[0])/3.0 + offset.x)); + barycenters->push_back(static_cast((pa[1]+pb[1]+pc[1])/3.0 + offset.y)); + barycenters->push_back(static_cast((pa[2]+pb[2]+pc[2])/3.0 + offset.z)); + } + } + + Scene_item* clone() const Q_DECL_OVERRIDE{return 0;} + QString toolTip() const Q_DECL_OVERRIDE{return QString();} + QMenu* contextMenu() Q_DECL_OVERRIDE + { + QMenu* menu = Scene_item::contextMenu(); + + const char* prop_name = "Menu modified by Scene_surface_mesh_item."; + bool menuChanged = menu->property(prop_name).toBool(); + + if(!menuChanged) { + menu->addSeparator(); + QMenu *container = new QMenu(tr("Alpha value")); + container->menuAction()->setProperty("is_groupable", true); + QWidgetAction *sliderAction = new QWidgetAction(0); + sliderAction->setDefaultWidget(alphaSlider); + connect(alphaSlider, &QSlider::valueChanged, + [this](){ + setAlpha(alphaSlider->value()); + redraw(); + }); + container->addAction(sliderAction); + menu->addMenu(container); + setProperty("menu_changed", true); + menu->setProperty(prop_name, true); + + } + return menu; + } + float alpha() const Q_DECL_OVERRIDE + { + return m_alpha ; + } + + void setAlpha(int a) Q_DECL_OVERRIDE + { + m_alpha = a / 255.0f; + redraw(); + } +private: + + //contains the data + mutable std::vector *vertices; + mutable std::vector *normals; + mutable std::vector *edges; + mutable std::vector *colors; + mutable std::vector *barycenters; + mutable std::vector *subdomain_ids; + mutable bool is_fast; + mutable QSlider* alphaSlider; + mutable float m_alpha ; +}; //end of class Scene_triangle_item + + +struct Scene_triangulation_3_item_priv { + typedef CGAL::qglviewer::ManipulatedFrame ManipulatedFrame; + Scene_triangulation_3_item_priv(Scene_triangulation_3_item* item) + : item(item), triangulation() + , frame(new ManipulatedFrame()) + , data_item_(NULL) + , histogram_() + , surface_patch_indices_() + , subdomain_indices_() + { + init_default_values(); + tet_Slider = new QSlider(Qt::Horizontal); + tet_Slider->setMinimum(0); + tet_Slider->setMaximum(100); + tet_Slider->setValue(100); + invalidate_stats(); + } + Scene_triangulation_3_item_priv(const T3& triangulation_, Scene_triangulation_3_item* item) + : item(item), triangulation(triangulation_) + , frame(new ManipulatedFrame()) + , data_item_(NULL) + , histogram_() + , surface_patch_indices_() + , subdomain_indices_() + { + init_default_values(); + tet_Slider = new QSlider(Qt::Horizontal); + tet_Slider->setMinimum(0); + tet_Slider->setMaximum(100); + tet_Slider->setValue(100); + invalidate_stats(); + } + ~Scene_triangulation_3_item_priv() + { + if(alphaSlider) + delete alphaSlider; + item->triangulation().clear(); + tree.clear(); + if(frame) + { + delete frame; + frame = NULL; + delete tet_Slider; + } + } + + void init_default_values() { + positions_lines.resize(0); + positions_poly.resize(0); + normals.resize(0); + s_vertex.resize(0); + s_normals.resize(0); + ws_vertex.resize(0); + need_changed = false; + spheres = NULL; + intersection = NULL; + spheres_are_shown = false; + is_aabb_tree_built = false; + alphaSlider = NULL; + is_filterable = true; + } + void computeIntersection(const Primitive& facet); + void fill_aabb_tree() { + if(item->isEmpty()) return; + QGuiApplication::setOverrideCursor(Qt::WaitCursor); + CGAL::Real_timer timer; + timer.start(); + tree.clear(); + for (Tr::Finite_cells_iterator + cit = item->triangulation().finite_cells_begin(), + end = item->triangulation().finite_cells_end(); + cit != end; ++cit) + { + if(!item->do_take_cell(cit)) continue; + tree.insert(Primitive(cit)); + } + tree.build(); + is_aabb_tree_built = true; + QGuiApplication::restoreOverrideCursor(); + } + void reset_cut_plane(); + void draw_triangle(const Tr::Bare_point& pa, + const Tr::Bare_point& pb, + const Tr::Bare_point& pc) const; + void draw_triangle_edges(const Tr::Bare_point& pa, + const Tr::Bare_point& pb, + const Tr::Bare_point& pc) const; + double complex_diag() const; + void compute_color_map(const QColor& c); + void initializeBuffers(CGAL::Three::Viewer_interface *viewer); + void initialize_intersection_buffers(CGAL::Three::Viewer_interface *viewer); + void computeSpheres(); + void computeElements(); + void computeIntersections(CGAL::Three::Viewer_interface* viewer); + void invalidate_stats() + { + min_edges_length = (std::numeric_limits::max)(); + max_edges_length = 0; + mean_edges_length = 0; + min_dihedral_angle = (std::numeric_limits::max)(); + max_dihedral_angle = 0; + mean_dihedral_angle = 0; + nb_subdomains = 0; + nb_spheres = 0; + nb_vertices = 0; + nb_tets = 0; + spheres_are_shown = false; + smallest_radius_radius = (std::numeric_limits::max)(); + smallest_edge_radius = (std::numeric_limits::max)(); + biggest_v_sma_cube = 0; + computed_stats = false; + } + + enum STATS { + MIN_EDGES_LENGTH = 0, + MAX_EDGES_LENGTH, + MEAN_EDGES_LENGTH, + MIN_DIHEDRAL_ANGLE, + MAX_DIHEDRAL_ANGLE, + MEAN_DIHEDRAL_ANGLE, + NB_SPHERES, + NB_VERTICES, + NB_TETS, + SMALLEST_RAD_RAD, + SMALLEST_EDGE_RAD, + BIGGEST_VL3_CUBE, + NB_SUBDOMAINS + }; + Scene_triangulation_3_item* item; + T3 triangulation; + bool is_grid_shown; + CGAL::qglviewer::ManipulatedFrame* frame; + bool need_changed; + mutable std::map are_intersection_buffers_filled; + bool areInterBufFilled(CGAL::Three::Viewer_interface* viewer) + { + if(are_intersection_buffers_filled.find(viewer) != are_intersection_buffers_filled.end()) + return are_intersection_buffers_filled[viewer]; + return false; + } + Scene_spheres_item *spheres; + std::vector tr_vertices; + Scene_intersection_item *intersection; + bool spheres_are_shown; + const Scene_item* data_item_; + QPixmap histogram_; + typedef std::set Indices; + Indices surface_patch_indices_; + Indices subdomain_indices_; + std::unordered_map id_to_compact; + QSlider* tet_Slider; + bool is_filterable; + + //!Allows OpenGL 2.0 context to get access to glDrawArraysInstanced. + typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDARBPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); + //!Allows OpenGL 2.0 context to get access to glVertexAttribDivisor. + typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORARBPROC) (GLuint index, GLuint divisor); + //!Allows OpenGL 2.0 context to get access to gkFrameBufferTexture2D. + PFNGLDRAWARRAYSINSTANCEDARBPROC glDrawArraysInstanced; + //!Allows OpenGL 2.0 context to get access to glVertexAttribDivisor. + PFNGLVERTEXATTRIBDIVISORARBPROC glVertexAttribDivisor; + + mutable std::size_t positions_poly_size; + mutable std::size_t positions_lines_size; + mutable std::vector positions_lines; + mutable std::vector positions_grid; + mutable std::vector positions_poly; + mutable std::vector positions_barycenter; + mutable std::vector inter_subdomain_ids; + + mutable std::vector normals; + mutable std::vector f_colors; + mutable std::vector s_normals; + mutable std::vector s_colors; + mutable std::vector s_vertex; + mutable std::vector ws_vertex; + mutable std::vector s_radius; + mutable std::vector s_center; + mutable std::vector subdomain_ids; + mutable bool computed_stats; + mutable float max_edges_length; + mutable float min_edges_length; + mutable float mean_edges_length; + mutable float min_dihedral_angle; + mutable float max_dihedral_angle; + mutable float mean_dihedral_angle; + mutable std::size_t nb_spheres; + mutable std::size_t nb_subdomains; + mutable std::size_t nb_vertices; + mutable std::size_t nb_tets; + mutable float smallest_radius_radius; + mutable float smallest_edge_radius; + mutable float biggest_v_sma_cube; + QSlider* alphaSlider; + + Tree tree; + QVector colors; + QVector colors_subdomains; + boost::dynamic_bitset<> visible_subdomain; + std::bitset<24> bs[4] = {16777215, 16777215, 16777215, 16777215}; + bool show_tetrahedra; + bool is_aabb_tree_built; + bool last_intersection; + + void push_normal(std::vector& normals, const EPICK::Vector_3& n) const + { + normals.push_back(static_cast(n.x())); + normals.push_back(static_cast(n.y())); + normals.push_back(static_cast(n.z())); + } + void push_point(std::vector& points, const EPICK::Point_3& p, + const CGAL::qglviewer::Vec& offset) const + { + points.push_back(static_cast(p.x()+offset.x)); + points.push_back(static_cast(p.y()+offset.y)); + points.push_back(static_cast(p.z()+offset.z)); + } + void push_edge(std::vector& edges, + const EPICK::Point_3& pa, + const EPICK::Point_3& pb, + const CGAL::qglviewer::Vec& offset) const + { + push_point(edges, pa, offset); + push_point(edges, pb, offset); + } +}; + +struct Set_show_tetrahedra { + Scene_triangulation_3_item_priv* priv; + Set_show_tetrahedra(Scene_triangulation_3_item_priv* priv) : priv(priv) {} + void operator()(bool b) { + priv->show_tetrahedra = b; + priv->item->show_intersection(b); + } +}; + +void Scene_triangulation_3_item::common_constructor(bool display_elements) +{ + d->frame = new CGAL::qglviewer::ManipulatedFrame(); + connect(d->frame, SIGNAL(modified()), this, SLOT(changed())); + triangulation_changed(); + setRenderingMode(FlatPlusEdges); + create_flat_and_wire_sphere(1.0f,d->s_vertex,d->s_normals, d->ws_vertex); + + d->is_grid_shown = display_elements; + d->show_tetrahedra = display_elements; + d->last_intersection = !d->show_tetrahedra; + + setTriangleContainer(T3_faces, new Tc(Vi::PROGRAM_C3T3, false)); + + setEdgeContainer(Grid_edges, new Ec(Vi::PROGRAM_NO_SELECTION, false)); + setEdgeContainer(T3_edges, new Ec(Vi::PROGRAM_C3T3_EDGES, false)); + for(auto v : CGAL::QGLViewer::QGLViewerPool()) + { + v->installEventFilter(this); + } +} +Scene_triangulation_3_item::Scene_triangulation_3_item(bool display_elements) + : Scene_group_item("unnamed") + , d(new Scene_triangulation_3_item_priv(this)) +{ + common_constructor(display_elements); +} + +Scene_triangulation_3_item::Scene_triangulation_3_item(const T3 triangulation, bool display_elements) + : Scene_group_item("unnamed") + , d(new Scene_triangulation_3_item_priv(triangulation, this)) +{ + common_constructor(display_elements); + d->reset_cut_plane(); + triangulation_changed(); + changed(); +} + +Scene_triangulation_3_item::~Scene_triangulation_3_item() +{ + if(d) + { + delete d; + d = NULL; + } +} + + + +const Scene_item* +Scene_triangulation_3_item::data_item() const +{ + return d->data_item_; +} + +void +Scene_triangulation_3_item::set_data_item(const Scene_item* data_item) +{ + d->data_item_ = data_item; + if (NULL != data_item) + { + connect(d->data_item_, SIGNAL(aboutToBeDestroyed()), + this, SLOT(data_item_destroyed())); + } +} + +void +Scene_triangulation_3_item::data_item_destroyed() +{ + set_data_item(NULL); +} + +const T3& +Scene_triangulation_3_item::triangulation() const { + return d->triangulation; +} + +T3& +Scene_triangulation_3_item::triangulation() +{ + return d->triangulation; +} + +void +Scene_triangulation_3_item::changed() +{ + if(!d) + return; + d->need_changed = true; + QTimer::singleShot(0,this, SLOT(updateCutPlane())); +} + +void Scene_triangulation_3_item::updateCutPlane() +{ + // just handle deformation - paint like selection is handled in eventFilter() + if(!d) + return; + if(d->need_changed) { + for(auto v : CGAL::QGLViewer::QGLViewerPool()) + { + CGAL::Three::Viewer_interface* viewer = static_cast(v); + d->are_intersection_buffers_filled[viewer] = false; + } + d->need_changed = false; + } +} + +void +Scene_triangulation_3_item::triangulation_changed() +{ + // Update colors + // Fill indices map and get max subdomain value + d->surface_patch_indices_.clear(); + d->subdomain_indices_.clear(); + d->visible_subdomain.clear(); + d->id_to_compact.clear(); + + int max = 0; + int compact = 0; + for (Tr::Finite_cells_iterator cit = triangulation().finite_cells_begin(), + end = triangulation().finite_cells_end(); cit != end; ++cit) + { + max = (std::max)(max, cit->subdomain_index()); + if(d->subdomain_indices_.insert(cit->subdomain_index()).second) + { + d->id_to_compact[cit->subdomain_index()] = compact++; + } + } + const int max_subdomain_index = max; + d->visible_subdomain.resize(max_subdomain_index+1, true); + d->is_filterable &=( d->subdomain_ids.size() < 96); + for (Tr::Finite_facets_iterator fit = triangulation().finite_facets_begin(), + end = triangulation().finite_facets_end(); fit != end; ++fit) + { + max = (std::max)(max, fit->first->surface_patch_index(fit->second)); + d->surface_patch_indices_.insert(fit->first->surface_patch_index(fit->second)); + } + + d->colors.resize(max + 1); + d->colors_subdomains.resize(max_subdomain_index + 1); + d->compute_color_map(color_); + // Rebuild histogram + build_histogram(); + + d->tree.clear(); + d->is_aabb_tree_built = false; +} + +QPixmap +Scene_triangulation_3_item::graphicalToolTip() const +{ + if (!d->histogram_.isNull()) + { + return d->histogram_; + } + const_cast(*this).build_histogram(); + return d->histogram_; +} + +std::vector +create_histogram(const T3& triangulation, double& min_value, double& max_value) +{ + + Geom_traits::Compute_approximate_dihedral_angle_3 approx_dihedral_angle + = triangulation.geom_traits().compute_approximate_dihedral_angle_3_object(); + Geom_traits::Construct_point_3 wp2p + = triangulation.geom_traits().construct_point_3_object(); + + std::vector histo(181, 0); + + min_value = 180.; + max_value = 0.; + for (T3::Finite_cells_iterator cit = triangulation.finite_cells_begin(); + cit != triangulation.finite_cells_end(); + ++cit) + { +#ifdef CGAL_MESH_3_DEMO_DONT_COUNT_TETS_ADJACENT_TO_SHARP_FEATURES_FOR_HISTOGRAM + if (triangulation.in_dimension(cit->vertex(0)) <= 1 + || triangulation.in_dimension(cit->vertex(1)) <= 1 + || triangulation.in_dimension(cit->vertex(2)) <= 1 + || triangulation.in_dimension(cit->vertex(3)) <= 1) + continue; +#endif //CGAL_MESH_3_DEMO_DONT_COUNT_TETS_ADJACENT_TO_SHARP_FEATURES_FOR_HISTOGRAM + + const Tr::Bare_point& p0 = wp2p(cit->vertex(0)->point()); + const Tr::Bare_point& p1 = wp2p(cit->vertex(1)->point()); + const Tr::Bare_point& p2 = wp2p(cit->vertex(2)->point()); + const Tr::Bare_point& p3 = wp2p(cit->vertex(3)->point()); + + double a = CGAL::to_double(CGAL::abs(approx_dihedral_angle(p0, p1, p2, p3))); + histo[static_cast(std::floor(a))] += 1; + min_value = (std::min)(min_value, a); + max_value = (std::max)(max_value, a); + + a = CGAL::to_double(CGAL::abs(approx_dihedral_angle(p0, p2, p1, p3))); + histo[static_cast(std::floor(a))] += 1; + min_value = (std::min)(min_value, a); + max_value = (std::max)(max_value, a); + + a = CGAL::to_double(CGAL::abs(approx_dihedral_angle(p0, p3, p1, p2))); + histo[static_cast(std::floor(a))] += 1; + min_value = (std::min)(min_value, a); + max_value = (std::max)(max_value, a); + + a = CGAL::to_double(CGAL::abs(approx_dihedral_angle(p1, p2, p0, p3))); + histo[static_cast(std::floor(a))] += 1; + min_value = (std::min)(min_value, a); + max_value = (std::max)(max_value, a); + + a = CGAL::to_double(CGAL::abs(approx_dihedral_angle(p1, p3, p0, p2))); + histo[static_cast(std::floor(a))] += 1; + min_value = (std::min)(min_value, a); + max_value = (std::max)(max_value, a); + + a = CGAL::to_double(CGAL::abs(approx_dihedral_angle(p2, p3, p0, p1))); + histo[static_cast(std::floor(a))] += 1; + min_value = (std::min)(min_value, a); + max_value = (std::max)(max_value, a); + + } + return histo; +} + +void +Scene_triangulation_3_item::build_histogram() +{ +#ifdef CGAL_MESH_3_DEMO_BIGGER_HISTOGRAM_WITH_WHITE_BACKGROUNG + // Create an histogram_ and display it + const int height = 280; + const int top_margin = 5; + const int left_margin = 20; + const int drawing_height = height - top_margin * 2; + const int width = 804; + const int cell_width = 4; + const int text_margin = 3; + const int text_height = 34; + + d->histogram_ = QPixmap(width, height + text_height); + d->histogram_.fill(QColor(255, 255, 255)); +#else + // Create an histogram_ and display it + const int height = 140; + const int top_margin = 5; + const int left_margin = 20; + const int drawing_height = height - top_margin * 2; + const int width = 402; + const int cell_width = 2; + const int text_margin = 3; + const int text_height = 20; + + d->histogram_ = QPixmap(width, height + text_height); + d->histogram_.fill(QColor(192, 192, 192)); +#endif + + QPainter painter(&d->histogram_); + painter.setPen(Qt::black); + painter.setBrush(QColor(128, 128, 128)); + //painter.setFont(QFont("Arial", 30)); + + // Build histogram_ data + double min_value, max_value; + std::vector histo_data = create_histogram(triangulation(), min_value, max_value); + + // Get maximum value (to normalize) + int max_size = 0; + for (std::vector::iterator it = histo_data.begin(), end = histo_data.end(); + it != end; ++it) + { + max_size = (std::max)(max_size, *it); + } + + // colored histogram + int j = 0; + + // draw + int i = left_margin; + for (std::vector::iterator it = histo_data.begin(), end = histo_data.end(); + it != end; ++it, i += cell_width) + { + int line_height = static_cast(std::ceil(static_cast(drawing_height)* + static_cast(*it) / static_cast(max_size)) + .5); + + painter.fillRect(i, + drawing_height + top_margin - line_height, + cell_width, + line_height, + get_histogram_color(j++)); + } + + // draw bottom horizontal line + painter.setPen(Qt::blue); + + painter.drawLine(QPoint(left_margin, drawing_height + top_margin), + QPoint(left_margin + static_cast(histo_data.size())*cell_width, + drawing_height + top_margin)); + + + // draw min value and max value + const int min_tr_width = + static_cast(2 * (std::floor(min_value)*cell_width + left_margin)); + const int max_tr_width = + static_cast(2 * ((double(histo_data.size()) - + std::floor(max_value))*cell_width + left_margin)); + const int tr_y = drawing_height + top_margin + text_margin; + + painter.setPen(get_histogram_color(min_value)); + QRect min_text_rect(0, tr_y, min_tr_width, text_height); + painter.drawText(min_text_rect, Qt::AlignCenter, tr("%1").arg(min_value, 0, 'f', 1)); + + painter.setPen(get_histogram_color(max_value)); + QRect max_text_rect(width - max_tr_width, tr_y, max_tr_width, text_height); + painter.drawText(max_text_rect, Qt::AlignCenter, tr("%1").arg(max_value, 0, 'f', 1)); +} + +QColor +Scene_triangulation_3_item::get_histogram_color(const double v) const +{ + if (v < 5) { return Qt::red; } + else if (v < 10) { return QColor(215, 108, 0); } + else if (v < 15) { return QColor(138, 139, 0); } + else if (v < 165) { return QColor(60, 136, 64); } + else if (v < 170) { return QColor(138, 139, 1); } + else if (v < 175) { return QColor(215, 108, 0); } + else /* 175 1) { hue -= 1.; } + colors_subdomains[*it] = QColor::fromHsvF(hue, c.saturationF(), c.valueF()); + } + const size_type nb_patch_indices = surface_patch_indices_.size(); + i = 0; + for (Indices::iterator it = surface_patch_indices_.begin(), + end = surface_patch_indices_.end(); it != end; ++it, i += 1.) + { + double hue = c.hueF() + 1. / double(nb_patch_indices) * i; + if (hue > 1) { hue -= 1.; } + colors[*it] = QColor::fromHsvF(hue, c.saturationF(), c.valueF()); + } +} + +Geom_traits::Plane_3 Scene_triangulation_3_item::plane(CGAL::qglviewer::Vec offset) const +{ + const CGAL::qglviewer::Vec& pos = d->frame->position() - offset; + const CGAL::qglviewer::Vec& n = + d->frame->inverseTransformOf(CGAL::qglviewer::Vec(0.f, 0.f, 1.f)); + return Geom_traits::Plane_3(n[0], n[1], n[2], -n * pos); +} + +void Scene_triangulation_3_item::compute_bbox() const { + if (isEmpty()) + _bbox = Bbox(); + else { + bool bbox_init = false; + CGAL::Bbox_3 result; + for (Tr::Finite_vertices_iterator + vit = triangulation().finite_vertices_begin(), + end = triangulation().finite_vertices_end(); + vit != end; ++vit) + { + //if(!do_take_vertex(vit)) continue; + if (bbox_init) + result = result + vit->point().bbox(); + else + { + result = vit->point().bbox(); + bbox_init = true; + } + } + _bbox = Bbox(result.xmin(), result.ymin(), result.zmin(), + result.xmax(), result.ymax(), result.zmax()); + } +} + +QString Scene_triangulation_3_item::toolTip() const { + return tr("

3D triangulation

" + "

Number of vertices: %1
" + "Number of finite facets: %2
" + "Number of finite cells: %3

%4") + .arg(triangulation().number_of_vertices()) + .arg(triangulation().number_of_finite_facets()) + .arg(triangulation().number_of_finite_cells()) + .arg(property("toolTip").toString()); +} + +void Scene_triangulation_3_item::draw(CGAL::Three::Viewer_interface* viewer) const { + if(!viewer->isOpenGL_4_3()) + { + d->is_filterable = false; + } + if(!visible()) + return; + Scene_triangulation_3_item* ncthis = const_cast(this); + if(!isInit(viewer)) + initGL(viewer); + + if ( getBuffersFilled() && + ! getBuffersInit(viewer)) + { + initializeBuffers(viewer); + setBuffersInit(viewer, true); + } + if(!getBuffersFilled()) + { + computeElements(); + initializeBuffers(viewer); + } + if(renderingMode() == Flat || + renderingMode() == FlatPlusEdges) + { + QVector4D cp = cgal_plane_to_vector4d(this->plane()); + getTriangleContainer(T3_faces)->setPlane(cp); + float shrink_factor = getShrinkFactor(); + getTriangleContainer(T3_faces)->setShrinkFactor(shrink_factor); + // positions_poly_size is the number of total facets in the C3T3 + // it is only computed once and positions_poly is emptied at the end + getTriangleContainer(T3_faces)->setAlpha(alpha()); + getTriangleContainer(T3_faces)->setIsSurface(is_surface()); + QOpenGLShaderProgram* program = viewer->getShaderProgram(getTriangleContainer(T3_faces)->getProgram()); + program->bind(); + if(d->is_filterable) + { + QVector4D visible_bitset(d->bs[0].to_ulong(),d->bs[1].to_ulong(),d->bs[2].to_ulong(),d->bs[3].to_ulong()); + program->setUniformValue("is_visible_bitset", visible_bitset); + } + program->setUniformValue("is_filterable", d->is_filterable); + program->release(); + getTriangleContainer(T3_faces)->draw(viewer, false); + if(d->show_tetrahedra){ + ncthis->show_intersection(true); + if(!d->frame->isManipulated()) + d->intersection->setFast(false); + else + d->intersection->setFast(true); + + if(!d->frame->isManipulated() && !d->areInterBufFilled(viewer)) + { + //initGL + ncthis->d->computeIntersections(viewer); + d->are_intersection_buffers_filled[viewer] = true; + ncthis->show_intersection(true); + } + } + if(d->spheres_are_shown) + { + d->spheres->setPlane(this->plane()); + } + } + if(d->is_grid_shown) + { + + getEdgeContainer(Grid_edges)->setColor(QColor(Qt::black)); + QMatrix4x4 f_mat; + for (int i = 0; i<16; i++) + f_mat.data()[i] = static_cast(d->frame->matrix()[i]); + getEdgeContainer(Grid_edges)->setFrameMatrix(f_mat); + getEdgeContainer(Grid_edges)->draw(viewer, true); + } +} + +void Scene_triangulation_3_item::drawEdges(CGAL::Three::Viewer_interface* viewer) const { + if(!visible()) + return; + if(renderingMode() == Wireframe || + renderingMode() == FlatPlusEdges ) + { + if(renderingMode() == FlatPlusEdges) + { + GLint renderMode; + viewer->glGetIntegerv(GL_RENDER_MODE, &renderMode); + if(renderMode == GL_SELECT) return; + } + Scene_triangulation_3_item* ncthis = const_cast(this); + if(!isInit(viewer)) + initGL(viewer); + if ( getBuffersFilled() && + ! getBuffersInit(viewer)) + { + initializeBuffers(viewer); + setBuffersInit(viewer, true); + } + if(!getBuffersFilled()) + { + computeElements(); + initializeBuffers(viewer); + } + if(renderingMode() == Wireframe && d->is_grid_shown) + { + getEdgeContainer(Grid_edges)->setColor(QColor(Qt::black)); + QMatrix4x4 f_mat; + for (int i = 0; i<16; i++) + f_mat.data()[i] = static_cast(d->frame->matrix()[i]); + getEdgeContainer(Grid_edges)->setFrameMatrix(f_mat); + getEdgeContainer(Grid_edges)->draw(viewer, true); + } + + QVector4D cp = cgal_plane_to_vector4d(this->plane()); + QOpenGLShaderProgram* program = viewer->getShaderProgram(getEdgeContainer(T3_edges)->getProgram()); + program->bind(); + if(d->is_filterable) + { + QVector4D visible_bitset(d->bs[0].to_ulong(),d->bs[1].to_ulong(),d->bs[2].to_ulong(),d->bs[3].to_ulong()); + program->setUniformValue("is_visible_bitset", visible_bitset); + } + program->setUniformValue("is_filterable", d->is_filterable); + program->release(); + getEdgeContainer(T3_edges)->setPlane(cp); + getEdgeContainer(T3_edges)->setIsSurface(is_surface()); + getEdgeContainer(T3_edges)->setColor(QColor(Qt::black)); + getEdgeContainer(T3_edges)->draw(viewer, true); + + if(d->show_tetrahedra){ + if(!d->frame->isManipulated()) + d->intersection->setFast(false); + else + d->intersection->setFast(true); + if(!d->frame->isManipulated() && !d->areInterBufFilled(viewer)) + { + ncthis->d->computeIntersections(viewer); + d->are_intersection_buffers_filled[viewer]=true; + } + } + if(d->spheres_are_shown) + { + d->spheres->setPlane(this->plane()); + } + } +} + +void Scene_triangulation_3_item::drawPoints(CGAL::Three::Viewer_interface *) const +{ + +} + +void Scene_triangulation_3_item_priv::draw_triangle(const Tr::Bare_point& pa, + const Tr::Bare_point& pb, + const Tr::Bare_point& pc) const +{ + Geom_traits::Vector_3 n = cross_product(pb - pa, pc - pa); + n = n / CGAL::sqrt(n*n); + const CGAL::qglviewer::Vec offset = Three::mainViewer()->offset(); + + for (int i = 0; i<3; i++) + { + push_normal(normals, n); + } + push_point(positions_poly, pa, offset); + push_point(positions_poly, pb, offset); + push_point(positions_poly, pc, offset); + + for(int i=0; i<3; ++i) + { + push_point(positions_barycenter, CGAL::centroid(pa, pb, pc), offset); + } +} + +void Scene_triangulation_3_item_priv::draw_triangle_edges(const Tr::Bare_point& pa, + const Tr::Bare_point& pb, + const Tr::Bare_point& pc) const +{ + const CGAL::qglviewer::Vec offset = Three::mainViewer()->offset(); + push_edge(positions_lines, pa, pb, offset); + push_edge(positions_lines, pb, pc, offset); + push_edge(positions_lines, pc, pa, offset); +} + +double Scene_triangulation_3_item_priv::complex_diag() const { + const CGAL::Three::Scene_item::Bbox& bbox = item->bbox(); + const double& xdelta = bbox.xmax() - bbox.xmin(); + const double& ydelta = bbox.ymax() - bbox.ymin(); + const double& zdelta = bbox.zmax() - bbox.zmin(); + const double diag = std::sqrt(xdelta*xdelta + + ydelta*ydelta + + zdelta*zdelta); + return diag * 0.7; +} + +QMenu* Scene_triangulation_3_item::contextMenu() +{ + const char* prop_name = "Menu modified by Scene_triangulation_3_item."; + + QMenu* menu = Scene_item::contextMenu(); + + // Use dynamic properties: + // https://doc.qt.io/qt-5/qobject.html#property + bool menuChanged = menu->property(prop_name).toBool(); + + if (!menuChanged) { + + QMenu *container = new QMenu(tr("Alpha value")); + container->menuAction()->setProperty("is_groupable", true); + QWidgetAction *sliderAction = new QWidgetAction(0); + sliderAction->setDefaultWidget(alphaSlider()); + connect(d->alphaSlider, &QSlider::valueChanged, + [this]() + { + if(d->intersection) + d->intersection->setAlpha(d->alphaSlider->value()); + redraw(); + } + ); + container->addAction(sliderAction); + menu->addMenu(container); + + container = new QMenu(tr("Tetrahedra's Shrink Factor")); + sliderAction = new QWidgetAction(0); + connect(d->tet_Slider, &QSlider::valueChanged, this, &Scene_triangulation_3_item::itemChanged); + sliderAction->setDefaultWidget(d->tet_Slider); + container->addAction(sliderAction); + menu->addMenu(container); + + QAction* actionShowTets = + menu->addAction(tr("Show &tetrahedra")); + actionShowTets->setCheckable(true); + actionShowTets->setObjectName("actionShowTets"); + connect(actionShowTets, &QAction::toggled, Set_show_tetrahedra(this->d)); + + QAction* actionShowGrid= + menu->addAction(tr("Show &grid")); + actionShowGrid->setCheckable(true); + actionShowGrid->setChecked(true); + actionShowGrid->setObjectName("actionShowGrid"); + connect(actionShowGrid, SIGNAL(toggled(bool)), + this, SLOT(show_grid(bool))); + + bool should_show_spheres = false; + for(Tr::Finite_vertices_iterator + vit = triangulation().finite_vertices_begin(), + end = triangulation().finite_vertices_end(); + vit != end; ++vit) + { + if(vit->point().weight()!=0) + { + should_show_spheres = true; + break; + } + } + if(should_show_spheres) + { + QAction* actionShowSpheres = + menu->addAction(tr("Show protecting &spheres")); + actionShowSpheres->setCheckable(true); + actionShowSpheres->setObjectName("actionShowSpheres"); + connect(actionShowSpheres, SIGNAL(toggled(bool)), + this, SLOT(show_spheres(bool))); + } + + menu->setProperty(prop_name, true); + } + return menu; +} + + +void Scene_triangulation_3_item_priv::initializeBuffers(CGAL::Three::Viewer_interface *viewer) +{ + //vao containing the data for the facets + { + item->getTriangleContainer(Scene_triangulation_3_item::T3_faces)->initializeBuffers(viewer); + item->getTriangleContainer(Scene_triangulation_3_item::T3_faces)->setFlatDataSize( + positions_poly_size); + + + positions_poly.clear(); + positions_poly.shrink_to_fit(); + normals.clear(); + normals.shrink_to_fit(); + f_colors.clear(); + f_colors.shrink_to_fit(); + positions_barycenter.clear(); + positions_barycenter.shrink_to_fit(); + } + + //vao containing the data for the lines + { + item->getEdgeContainer(Scene_triangulation_3_item::T3_edges)->initializeBuffers(viewer); + item->getEdgeContainer(Scene_triangulation_3_item::T3_edges)->setFlatDataSize( + positions_lines_size); + positions_lines.clear(); + positions_lines.shrink_to_fit(); + } + + //vao containing the data for the grid + { + item->getEdgeContainer(Scene_triangulation_3_item::Grid_edges)->initializeBuffers(viewer); + item->getEdgeContainer(Scene_triangulation_3_item::Grid_edges)->setFlatDataSize( + positions_grid.size()); + } +} + + + +void Scene_triangulation_3_item_priv::computeIntersection(const Primitive& cell) +{ + Geom_traits::Construct_point_3 wp2p + = item->triangulation().geom_traits().construct_point_3_object(); + + typedef unsigned char UC; + Tr::Cell_handle ch = cell.id(); + if(!visible_subdomain[ch->subdomain_index()]) + { + return; + } + QColor c = this->colors_subdomains[ch->subdomain_index()].lighter(50); + + const Tr::Bare_point& pa = wp2p(ch->vertex(0)->point()); + const Tr::Bare_point& pb = wp2p(ch->vertex(1)->point()); + const Tr::Bare_point& pc = wp2p(ch->vertex(2)->point()); + const Tr::Bare_point& pd = wp2p(ch->vertex(3)->point()); + + CGAL::Color color(UC(c.red()), UC(c.green()), UC(c.blue())); + + if(is_filterable) + { + float id = static_cast(id_to_compact[ch->subdomain_index()]); + for(int i=0; i< 48; ++i) + { + inter_subdomain_ids.push_back(id); + } + } + + intersection->addTriangle(pb, pa, pc, color); + intersection->addTriangle(pa, pb, pd, color); + intersection->addTriangle(pa, pd, pc, color); + intersection->addTriangle(pb, pc, pd, color); +} + +struct ComputeIntersection { + Scene_triangulation_3_item_priv& item_priv; + + ComputeIntersection(Scene_triangulation_3_item_priv& item_priv) + : item_priv(item_priv) + {} + + void operator()(const Primitive& facet) const + { + item_priv.computeIntersection(facet); + } +}; + +void Scene_triangulation_3_item_priv::computeIntersections(CGAL::Three::Viewer_interface* viewer) +{ + const CGAL::qglviewer::Vec offset = Three::mainViewer()->offset(); + if(!is_aabb_tree_built) fill_aabb_tree(); + + positions_poly.clear(); + normals.clear(); + f_colors.clear(); + positions_lines.clear(); + positions_barycenter.clear(); + inter_subdomain_ids.clear(); + const Geom_traits::Plane_3& plane = item->plane(offset); + tree.all_intersected_primitives(plane, + boost::make_function_output_iterator(ComputeIntersection(*this))); + intersection->gl_initialization(viewer); +} + +void Scene_triangulation_3_item_priv::computeSpheres() +{ + Geom_traits::Construct_point_3 wp2p + = item->triangulation().geom_traits().construct_point_3_object(); + + if(!spheres) + return; + int s_id = 0; + for(Tr::Finite_vertices_iterator + vit = item->triangulation().finite_vertices_begin(), + end = item->triangulation().finite_vertices_end(); + vit != end; ++vit) + { + if(vit->point().weight()==0) continue; + + typedef Tr::Vertex_handle Vertex_handle; + std::vector incident_vertices; + item->triangulation().incident_vertices(vit, std::back_inserter(incident_vertices)); + bool red = vit->is_special(); + for(std::vector::const_iterator + vvit = incident_vertices.begin(), end = incident_vertices.end(); + vvit != end; ++vvit) + { + if(item->triangulation().is_infinite(*vvit)) continue; + if(Geom_traits::Sphere_3(wp2p(vit->point()), + vit->point().weight()).bounded_side(wp2p((*vvit)->point())) + == CGAL::ON_BOUNDED_SIDE) + red = true; + } + + QColor c; + if(red) + c = QColor(Qt::red); + else + c = spheres->color(); + + switch(vit->in_dimension()) + { + case 0: + c = QColor::fromHsv((c.hue()+120)%360, c.saturation(),c.lightness(), c.alpha()); + break; + case 1: + break; + default: + c.setRgb(50,50,50,255); + } + + const CGAL::qglviewer::Vec offset = Three::mainViewer()->offset(); + Tr::Bare_point center(wp2p(vit->point()).x() + offset.x, + wp2p(vit->point()).y() + offset.y, + wp2p(vit->point()).z() + offset.z); + double radius = vit->point().weight() ; + typedef unsigned char UC; + tr_vertices.push_back(*vit); + spheres->add_sphere(Geom_traits::Sphere_3(center, radius),s_id++, + CGAL::Color(UC(c.red()), UC(c.green()), UC(c.blue()))); + + } + spheres->invalidateOpenGLBuffers(); +} + +void Scene_triangulation_3_item_priv::computeElements() +{ + if(!alphaSlider) + { + alphaSlider = new QSlider(::Qt::Horizontal); + alphaSlider->setMinimum(0); + alphaSlider->setMaximum(255); + alphaSlider->setValue(255); + } + + positions_poly.clear(); + positions_grid.clear(); + normals.clear(); + f_colors.clear(); + positions_lines.clear(); + s_colors.resize(0); + s_center.resize(0); + s_radius.resize(0); + subdomain_ids.resize(0); + + //The grid + { + positions_grid.resize(0); + + float x = (2 * (float)complex_diag()) / 10.0f; + float y = (2 * (float)complex_diag()) / 10.0f; + for (float u = 0; u < 11; u += 1.f) + { + + positions_grid.push_back(-(float)complex_diag() + x* u); + positions_grid.push_back(-(float)complex_diag()); + positions_grid.push_back(0.0f); + + positions_grid.push_back(-(float)complex_diag() + x* u); + positions_grid.push_back((float)complex_diag()); + positions_grid.push_back(0.0f); + } + for (float v = 0; v<11; v += 1.f) + { + + positions_grid.push_back(-(float)complex_diag()); + positions_grid.push_back(-(float)complex_diag() + v * y); + positions_grid.push_back(0.0f); + + positions_grid.push_back((float)complex_diag()); + positions_grid.push_back(-(float)complex_diag() + v * y); + positions_grid.push_back(0.0f); + } + } + + //the facets + { + Geom_traits::Construct_point_3 wp2p + = item->triangulation().geom_traits().construct_point_3_object(); + + for (Tr::Finite_facets_iterator + fit = item->triangulation().finite_facets_begin(), + end = item->triangulation().finite_facets_end(); + fit != end; ++fit) + { + if(!item->do_take_facet(*fit)) continue; + const Tr::Cell_handle& cell = fit->first; + const Tr::Cell_handle& cell2 = cell->neighbor(fit->second); + const int& index = fit->second; + const Tr::Bare_point& pa = wp2p(cell->vertex((index + 1) & 3)->point()); + const Tr::Bare_point& pb = wp2p(cell->vertex((index + 2) & 3)->point()); + const Tr::Bare_point& pc = wp2p(cell->vertex((index + 3) & 3)->point()); + + QColor color = colors[cell->surface_patch_index(index)]; + f_colors.push_back((float)color.redF());f_colors.push_back((float)color.greenF());f_colors.push_back((float)color.blueF()); + f_colors.push_back((float)color.redF());f_colors.push_back((float)color.greenF());f_colors.push_back((float)color.blueF()); + f_colors.push_back((float)color.redF());f_colors.push_back((float)color.greenF());f_colors.push_back((float)color.blueF()); + //As a facet belongs to 2 cells, we need both to decide if it should be hidden or not. + //Also 0 is a forbidden value, that is reserved for the "outside of the domain", so it won't be in the bs table. + if(is_filterable) + { + float dom1 = (cell->subdomain_index() != 0) ? static_cast(id_to_compact[cell->subdomain_index()]) + : static_cast(id_to_compact[cell2->subdomain_index()]); + + float dom2 = (cell2->subdomain_index() != 0) ? static_cast(id_to_compact[cell2->subdomain_index()]) + : static_cast(id_to_compact[cell->subdomain_index()]); + for(int i=0; i<6; ++i) + { + subdomain_ids.push_back(dom1); + subdomain_ids.push_back(dom2); + } + } + if(item->is_facet_oriented(*fit)) + draw_triangle(pb, pa, pc); + else + draw_triangle(pa, pb, pc); + draw_triangle_edges(pa, pb, pc); + } + } +} + +bool Scene_triangulation_3_item::load_binary(std::istream& is) +{ + is >> triangulation(); + if(!is) + return false; + d->reset_cut_plane(); + if(is.good()) { + triangulation_changed(); + changed(); + return true; + } + else + return false; +} + +void +Scene_triangulation_3_item_priv::reset_cut_plane() +{ + if(frame == 0) + frame = new CGAL::qglviewer::ManipulatedFrame(); + const CGAL::Three::Scene_item::Bbox& bbox = item->bbox(); + const float xcenter = static_cast((bbox.xmax()+bbox.xmin())/2.); + const float ycenter = static_cast((bbox.ymax()+bbox.ymin())/2.); + const float zcenter = static_cast((bbox.zmax()+bbox.zmin())/2.); + const CGAL::qglviewer::Vec offset = Three::mainViewer()->offset(); + CGAL::qglviewer::Vec center(xcenter+offset.x, ycenter+offset.y, zcenter+offset.z); + frame->setPosition(center); +} + +void +Scene_triangulation_3_item::setColor(QColor c) +{ + color_ = c; + d->compute_color_map(c); + invalidateOpenGLBuffers(); + d->invalidate_stats(); + for(auto v : CGAL::QGLViewer::QGLViewerPool()) + { + CGAL::Three::Viewer_interface* viewer = static_cast(v); + d->are_intersection_buffers_filled[viewer] = false; + } +} + +void Scene_triangulation_3_item::show_grid(bool b) +{ + d->is_grid_shown = b; + contextMenu()->findChild("actionShowGrid")->setChecked(b); + itemChanged(); +} + +void Scene_triangulation_3_item::show_intersection(bool b) +{ + contextMenu()->findChild("actionShowTets")->setChecked(b); + if(b && !d->intersection) + { + d->intersection = new Scene_intersection_item(this); + d->intersection->init_vectors(&d->positions_poly, + &d->normals, + &d->positions_lines, + &d->f_colors, + &d->positions_barycenter, + &d->inter_subdomain_ids); + d->intersection->setName("Intersection tetrahedra"); + d->intersection->setRenderingMode(renderingMode()); + connect(d->intersection, SIGNAL(destroyed()), this, SLOT(reset_intersection_item())); + + for(auto v : CGAL::QGLViewer::QGLViewerPool()) + { + CGAL::Three::Viewer_interface* viewer = static_cast(v); + d->are_intersection_buffers_filled[viewer] = false; + if(!d->areInterBufFilled(viewer)) + { + //initGL + Scene_triangulation_3_item* ncthis = const_cast(this); + ncthis->d->computeIntersections(viewer); + d->are_intersection_buffers_filled[viewer] = true; + } + } + scene->addItem(d->intersection); + scene->changeGroup(d->intersection, this); + lockChild(d->intersection); + } + else if (!b && d->intersection!=NULL) + { + unlockChild(d->intersection); + scene->erase(scene->item_id(d->intersection)); + } + if(d->last_intersection != b) + { + d->last_intersection = b; + Q_EMIT redraw(); + } +} + +void Scene_triangulation_3_item::reset_intersection_item() +{ + d->intersection = NULL; +} + +void Scene_triangulation_3_item::reset_spheres() +{ + d->spheres = NULL; +} + +CGAL::Three::Scene_item::ManipulatedFrame* Scene_triangulation_3_item::manipulatedFrame() { + if(d) + return d->frame; + else + return NULL; +} + +void Scene_triangulation_3_item::setPosition(float x, float y, float z) { + const CGAL::qglviewer::Vec offset = Three::mainViewer()->offset(); + d->frame->setPosition(x+offset.x, y+offset.y, z+offset.z); +} + +bool Scene_triangulation_3_item::has_spheres()const { + return d->spheres_are_shown; +} + +bool Scene_triangulation_3_item::has_grid()const { return d->is_grid_shown;} + +bool Scene_triangulation_3_item::has_tets()const { return d->intersection; } + +void Scene_triangulation_3_item::setNormal(float x, float y, float z) { + d->frame->setOrientation(x, y, z, 0.f); +} + +void Scene_triangulation_3_item::copyProperties(Scene_item *item) +{ + Scene_triangulation_3_item* t3_item = qobject_cast(item); + if(!t3_item) + return; + const CGAL::qglviewer::Vec offset = Three::mainViewer()->offset(); + d->frame->setPositionAndOrientation(t3_item->manipulatedFrame()->position() - offset, + t3_item->manipulatedFrame()->orientation()); + + show_intersection(t3_item->has_tets()); + show_spheres(t3_item->has_spheres()); + + show_grid(t3_item->has_grid()); + int value = t3_item->alphaSlider()->value(); + alphaSlider()->setValue(value); +} + +float Scene_triangulation_3_item::getShrinkFactor() const +{ + return float(d->tet_Slider->value())/100.0f; +} + +bool Scene_triangulation_3_item::eventFilter(QObject *, QEvent *event) +{ + if(event->type() == QEvent::MouseButtonRelease) + { + redraw(); + } + return false; +} + +bool Scene_triangulation_3_item::keyPressEvent(QKeyEvent *event) +{ + if(event->key() == Qt::Key_Plus) + { + d->tet_Slider->setValue(d->tet_Slider->value() + 5); + itemChanged(); + } + else if(event->key() == Qt::Key_Minus) + { + d->tet_Slider->setValue(d->tet_Slider->value() -5); + itemChanged(); + } + return false; +} + +QString Scene_triangulation_3_item::computeStats(int type) +{ + Geom_traits::Construct_point_3 wp2p + = triangulation().geom_traits().construct_point_3_object(); + + if(!d->computed_stats) + { + d->nb_tets = 0; + double nb_edges = 0; + double total_edges = 0; + double nb_angle = 0; + double total_angle = 0; + + for (T3::Finite_facets_iterator + fit = triangulation().finite_facets_begin(), + end = triangulation().finite_facets_end(); + fit != end; ++fit) + { + if(!do_take_facet(*fit)) continue; + + const Tr::Cell_handle& cell = fit->first; + const int& index = fit->second; + const Tr::Bare_point& pa = wp2p(cell->vertex((index + 1) & 3)->point()); + const Tr::Bare_point& pb = wp2p(cell->vertex((index + 2) & 3)->point()); + const Tr::Bare_point& pc = wp2p(cell->vertex((index + 3) & 3)->point()); + double edges[3]; + edges[0]=(std::sqrt(CGAL::squared_distance(pa, pb))); + edges[1]=(std::sqrt(CGAL::squared_distance(pa, pc))); + edges[2]=(std::sqrt(CGAL::squared_distance(pb, pc))); + for(int i=0; i<3; ++i) + { + if(edges[i] < d->min_edges_length){ d->min_edges_length = static_cast(edges[i]); } + if(edges[i] > d->max_edges_length){ d->max_edges_length = static_cast(edges[i]); } + total_edges+=edges[i]; + ++nb_edges; + } + } + d->mean_edges_length = static_cast(total_edges/nb_edges); + for(Tr::Finite_vertices_iterator + vit = triangulation().finite_vertices_begin(), + end = triangulation().finite_vertices_end(); + vit != end; ++vit) + { + if(vit->point().weight()==0) continue; + ++d->nb_spheres; + } + + Geom_traits::Compute_approximate_dihedral_angle_3 approx_dihedral_angle + = triangulation().geom_traits().compute_approximate_dihedral_angle_3_object(); + + QVector sub_ids; + for (T3::Finite_cells_iterator cit = triangulation().finite_cells_begin(); + cit != triangulation().finite_cells_end(); + ++cit) + { + if(!do_take_cell(cit)) + continue; + if(!sub_ids.contains(cit->subdomain_index())) + { + sub_ids.push_back(cit->subdomain_index()); + } + + const Tr::Bare_point& p0 = wp2p(cit->vertex(0)->point()); + const Tr::Bare_point& p1 = wp2p(cit->vertex(1)->point()); + const Tr::Bare_point& p2 = wp2p(cit->vertex(2)->point()); + const Tr::Bare_point& p3 = wp2p(cit->vertex(3)->point()); + double v = std::abs(CGAL::volume(p0, p1, p2, p3)); + double circumradius = std::sqrt(CGAL::squared_radius(p0, p1, p2, p3)); + //find smallest edge + double edges[6]; + edges[0] = std::sqrt(CGAL::squared_distance(p0, p1)); + edges[1] = std::sqrt(CGAL::squared_distance(p0, p2)); + edges[2] = std::sqrt(CGAL::squared_distance(p0, p3)); + edges[3] = std::sqrt(CGAL::squared_distance(p2, p1)); + edges[4] = std::sqrt(CGAL::squared_distance(p2, p3)); + edges[5] = std::sqrt(CGAL::squared_distance(p1, p3)); + + double min_edge = edges[0]; + for(int i=1; i<6; ++i) + { + if(edges[i]smallest_edge_radius) + d->smallest_edge_radius = static_cast(smallest_edge_radius); + + if(smallest_radius_radius < d->smallest_radius_radius) + d->smallest_radius_radius = static_cast(smallest_radius_radius); + + if(biggest_v_sma_cube > d->biggest_v_sma_cube) + d->biggest_v_sma_cube = static_cast(biggest_v_sma_cube); + + auto update_min_max_dihedral_angle = [this](double a) { + if(a < this->d->min_dihedral_angle) { this->d->min_dihedral_angle = static_cast(a); } + if(a > this->d->max_dihedral_angle) { this->d->max_dihedral_angle = static_cast(a); } + }; + + double a = CGAL::to_double(CGAL::abs(approx_dihedral_angle(p0, p1, p2, p3))); + update_min_max_dihedral_angle(a); + total_angle+=a; + ++nb_angle; + a = CGAL::to_double(CGAL::abs(approx_dihedral_angle(p0, p2, p1, p3))); + update_min_max_dihedral_angle(a); + total_angle+=a; + ++nb_angle; + a = CGAL::to_double(CGAL::abs(approx_dihedral_angle(p0, p3, p1, p2))); + update_min_max_dihedral_angle(a); + total_angle+=a; + ++nb_angle; + a = CGAL::to_double(CGAL::abs(approx_dihedral_angle(p1, p2, p0, p3))); + update_min_max_dihedral_angle(a); + total_angle+=a; + ++nb_angle; + a = CGAL::to_double(CGAL::abs(approx_dihedral_angle(p1, p3, p0, p2))); + update_min_max_dihedral_angle(a); + total_angle+=a; + ++nb_angle; + a = CGAL::to_double(CGAL::abs(approx_dihedral_angle(p2, p3, p0, p1))); + update_min_max_dihedral_angle(a); + total_angle+=a; + ++nb_angle; + ++d->nb_tets; + } + d->nb_vertices = 0; + for(T3::Finite_vertices_iterator vit = triangulation().finite_vertices_begin(); + vit != triangulation().finite_vertices_end(); + ++vit) + { + if(!do_take_vertex(vit)) + continue; + ++d->nb_vertices; + } + d->mean_dihedral_angle = static_cast(total_angle/nb_angle); + d->nb_subdomains = sub_ids.size(); + d->computed_stats = true; + } + + switch (type) + { + case Scene_triangulation_3_item_priv::MIN_EDGES_LENGTH: + return QString::number(d->min_edges_length); + case Scene_triangulation_3_item_priv::MAX_EDGES_LENGTH: + return QString::number(d->max_edges_length); + case Scene_triangulation_3_item_priv::MEAN_EDGES_LENGTH: + return QString::number(d->mean_edges_length); + case Scene_triangulation_3_item_priv::MIN_DIHEDRAL_ANGLE: + return QString::number(d->min_dihedral_angle); + case Scene_triangulation_3_item_priv::MAX_DIHEDRAL_ANGLE: + return QString::number(d->max_dihedral_angle); + case Scene_triangulation_3_item_priv::MEAN_DIHEDRAL_ANGLE: + return QString::number(d->mean_dihedral_angle); + case Scene_triangulation_3_item_priv::NB_SPHERES: + return QString::number(d->nb_spheres); + case Scene_triangulation_3_item_priv::NB_VERTICES: + return QString::number(d->nb_vertices); + case Scene_triangulation_3_item_priv::NB_TETS: + return QString::number(d->nb_tets); + case Scene_triangulation_3_item_priv::SMALLEST_RAD_RAD: + return QString::number(d->smallest_radius_radius); + case Scene_triangulation_3_item_priv::SMALLEST_EDGE_RAD: + return QString::number(d->smallest_edge_radius); + case Scene_triangulation_3_item_priv::BIGGEST_VL3_CUBE: + return QString::number(d->biggest_v_sma_cube); + case Scene_triangulation_3_item_priv::NB_SUBDOMAINS: + return QString::number(d->nb_subdomains); + + default: + return QString(); + } +} +CGAL::Three::Scene_item::Header_data Scene_triangulation_3_item::header() const +{ + CGAL::Three::Scene_item::Header_data data; + //categories + data.categories.append(std::pair(QString("Properties"),13)); + + + //titles + data.titles.append(QString("Min Edges Length")); + data.titles.append(QString("Max Edges Length")); + data.titles.append(QString("Mean Edges Length")); + data.titles.append(QString("Min Dihedral Angle")); + data.titles.append(QString("Max Dihedral Angle")); + data.titles.append(QString("Mean Dihedral Angle")); + data.titles.append(QString("#Protecting Spheres")); + data.titles.append(QString("#Vertices in Complex")); + data.titles.append(QString("#Cells")); + data.titles.append(QString("Smallest Radius-Radius Ratio")); + data.titles.append(QString("Smallest Edge-Radius Ratio")); + data.titles.append(QString("Biggest Vl^3")); + data.titles.append(QString("#Subdomains")); + return data; +} + +void Scene_triangulation_3_item::invalidateOpenGLBuffers() +{ + setBuffersFilled(false); + getTriangleContainer(T3_faces)->reset_vbos(ALL); + getEdgeContainer(T3_edges)->reset_vbos(ALL); + getEdgeContainer(Grid_edges)->reset_vbos(ALL); + + Q_FOREACH(CGAL::QGLViewer* v, CGAL::QGLViewer::QGLViewerPool()) + { + CGAL::Three::Viewer_interface* viewer = static_cast(v); + if(viewer == NULL) + continue; + setBuffersInit(viewer, false); + } + d->invalidate_stats(); +} +void Scene_triangulation_3_item::resetCutPlane() +{ + if(!d) + return; + d->reset_cut_plane(); +} + +void Scene_triangulation_3_item::itemAboutToBeDestroyed(Scene_item *item) +{ + Scene_item::itemAboutToBeDestroyed(item); + + if(d && item == this) + { + triangulation().clear(); + d->tree.clear(); + if(d->frame) + { + Three::mainViewer()->setManipulatedFrame(0); + delete d->frame; + d->frame = NULL; + delete d->tet_Slider; + } + delete d; + d=0; + } + +} + +void Scene_triangulation_3_item::on_spheres_color_changed() +{ + if(!d->spheres) + return; + d->spheres->clear_spheres(); + d->computeSpheres(); +} + +float Scene_triangulation_3_item::alpha() const +{ + if(!d->alphaSlider) + return 1.0f; + return (float)d->alphaSlider->value() / 255.0f; +} + +void Scene_triangulation_3_item::setAlpha(int alpha) +{ + if(!d->alphaSlider) + d->computeElements(); + d->alphaSlider->setValue(alpha); + if(d->intersection) + d->intersection->setAlpha(alpha); + redraw(); +} + +QSlider* Scene_triangulation_3_item::alphaSlider() { + if(!d->alphaSlider) + d->computeElements(); + return d->alphaSlider; +} + +void Scene_triangulation_3_item::initializeBuffers(Viewer_interface *v) const +{ + const_cast(this)->d->initializeBuffers(v); +} + +void Scene_triangulation_3_item::computeElements()const +{ + QApplication::setOverrideCursor(Qt::WaitCursor); + compute_bbox(); + + const_cast(this)->d->computeElements(); + + getTriangleContainer(T3_faces)->allocate( + Tc::Flat_vertices, d->positions_poly.data(), + static_cast(d->positions_poly.size()*sizeof(float))); + + getTriangleContainer(T3_faces)->allocate( + Tc::Flat_normals, + d->normals.data(), + static_cast(d->normals.size()*sizeof(float))); + + + getTriangleContainer(T3_faces)->allocate( + Tc::FColors, + d->f_colors.data(), + static_cast(d->f_colors.size()*sizeof(float))); + + getTriangleContainer(T3_faces)->allocate( + Tc::Facet_centers, + d->positions_barycenter.data(), + static_cast(d->positions_barycenter.size()*sizeof(float))); + + getTriangleContainer(T3_faces)->allocate( + Tc::Subdomain_indices, d->subdomain_ids.data(), + static_cast(d->subdomain_ids.size()*sizeof(float))); + + d->positions_poly_size = d->positions_poly.size(); + + getEdgeContainer(T3_edges)->allocate( + Ec::Vertices, + d->positions_lines.data(), + static_cast(d->positions_lines.size()*sizeof(float))); + getEdgeContainer(T3_edges)->allocate( + Ec::Subdomain_indices, d->subdomain_ids.data(), + static_cast(d->subdomain_ids.size()*sizeof(float))); + + d->positions_lines_size = d->positions_lines.size(); + + getEdgeContainer(Grid_edges)->allocate( + Ec::Vertices, + d->positions_grid.data(), + static_cast(d->positions_grid.size()*sizeof(float))); + + setBuffersFilled(true); + d->reset_cut_plane(); + QApplication::restoreOverrideCursor(); +} + +void Scene_triangulation_3_item::newViewer(Viewer_interface *viewer) +{ + viewer->installEventFilter(this); + Scene_item_rendering_helper::newViewer(viewer); + if(d->intersection) + { + d->intersection->newViewer(viewer); + d->computeIntersections(viewer); + } +} + +Scene_triangulation_3_item* Scene_triangulation_3_item::clone() const +{ + return new Scene_triangulation_3_item(d->triangulation); +} + +void Scene_triangulation_3_item::show_spheres(bool b) +{ + d->spheres_are_shown = b; + QAction* action_show_spheres = contextMenu()->findChild("actionShowSpheres"); + if(action_show_spheres) + { + action_show_spheres->setChecked(b); + if(b && !d->spheres) + { + d->spheres = new Scene_spheres_item(this, triangulation().number_of_vertices(), true); + connect(d->spheres, &Scene_spheres_item::picked, + this, [this](std::size_t id) + { + if(id == (std::size_t)(-1)) + return; + QString msg = QString("Vertex's index : %1; Vertex's in dimension: %2.").arg(d->tr_vertices[id].index()).arg(d->tr_vertices[id].in_dimension()); + CGAL::Three::Three::information(msg); + CGAL::Three::Three::mainViewer()->displayMessage(msg, 5000); + + }); + d->spheres->setName("Protecting spheres"); + d->spheres->setRenderingMode(Gouraud); + connect(d->spheres, SIGNAL(destroyed()), this, SLOT(reset_spheres())); + connect(d->spheres, SIGNAL(on_color_changed()), this, SLOT(on_spheres_color_changed())); + d->computeSpheres(); + lockChild(d->spheres); + scene->addItem(d->spheres); + scene->changeGroup(d->spheres, this); + } + else if (!b && d->spheres!=NULL) + { + unlockChild(d->spheres); + scene->erase(scene->item_id(d->spheres)); + } + } + Q_EMIT redraw(); +} + +Scene_item::Bbox Scene_triangulation_3_item::bbox() const +{ + if(!is_bbox_computed) + compute_bbox(); + is_bbox_computed = true; + return _bbox; +} + +const std::set& Scene_triangulation_3_item::subdomain_indices() const +{ + return d->subdomain_indices_; +} + +QColor Scene_triangulation_3_item::getSubdomainIndexColor(int i) const +{ + return d->colors_subdomains[i]; +} + +void Scene_triangulation_3_item::switchVisibleSubdomain(int id) +{ + d->visible_subdomain[id] = !d->visible_subdomain[id]; + int compact_id = d->id_to_compact[id]; + int i = compact_id/32; + int j = compact_id%32; + + d->bs[i][j] = d->visible_subdomain[id]; +} + +void Scene_triangulation_3_item::computeIntersection() +{ + for(auto v : CGAL::QGLViewer::QGLViewerPool()) + { + d->computeIntersections(static_cast(v)); + } +} + +#include "Scene_triangulation_3_item.moc" + diff --git a/Polyhedron/demo/Polyhedron/Scene_triangulation_3_item.h b/Polyhedron/demo/Polyhedron/Scene_triangulation_3_item.h new file mode 100644 index 00000000000..8cd2b81bd12 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Scene_triangulation_3_item.h @@ -0,0 +1,170 @@ +#ifndef SCENE_TRIANGULATION_3_ITEM_H +#define SCENE_TRIANGULATION_3_ITEM_H + +#include "Scene_triangulation_3_item_config.h" +#include "T3_type.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +struct Scene_triangulation_3_item_priv; +using namespace CGAL::Three; + class SCENE_TRIANGULATION_3_ITEM_EXPORT Scene_triangulation_3_item + : public Scene_group_item, public Scene_item_with_properties +{ + Q_OBJECT +public: + typedef CGAL::qglviewer::ManipulatedFrame ManipulatedFrame; + + Scene_triangulation_3_item(bool display_elements = true); + Scene_triangulation_3_item(const T3 t3, bool display_elements = true); + ~Scene_triangulation_3_item(); + + void common_constructor(bool); + bool has_stats()const Q_DECL_OVERRIDE {return true;} + QString computeStats(int type) Q_DECL_OVERRIDE; + CGAL::Three::Scene_item::Header_data header() const Q_DECL_OVERRIDE; + + + void setColor(QColor c) Q_DECL_OVERRIDE; + + void invalidateOpenGLBuffers() Q_DECL_OVERRIDE; + + void triangulation_changed(); + + void resetCutPlane(); + + void set_valid(bool); + + virtual const T3& triangulation() const; + virtual T3& triangulation(); + + bool manipulatable() const Q_DECL_OVERRIDE{ + return true; + } + + Scene_item::Bbox bbox() const Q_DECL_OVERRIDE; + + bool has_spheres() const; + bool has_grid() const; + bool has_tets() const; + + float alpha() const Q_DECL_OVERRIDE; + void setAlpha(int alpha) Q_DECL_OVERRIDE; + QSlider* alphaSlider(); + ManipulatedFrame* manipulatedFrame() Q_DECL_OVERRIDE; + + void setPosition(float x, float y, float z) ; + + void setNormal(float x, float y, float z) ; + + Geom_traits::Plane_3 plane(CGAL::qglviewer::Vec offset = CGAL::qglviewer::Vec(0,0,0)) const; + + bool isFinite() const Q_DECL_OVERRIDE { return true; } + bool isEmpty() const Q_DECL_OVERRIDE { + return triangulation().number_of_vertices() == 0 + || ( triangulation().number_of_finite_facets() == 0 + && triangulation().number_of_finite_cells() == 0 ); + return false; + } + + + void compute_bbox() const Q_DECL_OVERRIDE; + + Scene_triangulation_3_item* clone() const Q_DECL_OVERRIDE; + + virtual bool load_binary(std::istream& is); + + // data item + const Scene_item* data_item() const; + void set_data_item(const Scene_item* data_item); + + QString toolTip() const Q_DECL_OVERRIDE; + + // Indicate if rendering mode is supported + bool supportsRenderingMode(RenderingMode m) const Q_DECL_OVERRIDE{ + return (m != Gouraud && m != PointsPlusNormals && m != Points && m != ShadedPoints); + } + + void draw(CGAL::Three::Viewer_interface* viewer) const Q_DECL_OVERRIDE; + void drawEdges(CGAL::Three::Viewer_interface* viewer) const Q_DECL_OVERRIDE; + void drawPoints(CGAL::Three::Viewer_interface * viewer) const Q_DECL_OVERRIDE; + //When selecting a t3 item, we don't want to select its children, so we can still apply Operations to it + QList getChildrenForSelection() const Q_DECL_OVERRIDE { return QList(); } + public: + QMenu* contextMenu() Q_DECL_OVERRIDE; + void copyProperties(Scene_item *) Q_DECL_OVERRIDE; + float getShrinkFactor() const; + bool keyPressEvent(QKeyEvent *) Q_DECL_OVERRIDE; + bool eventFilter(QObject *, QEvent *) Q_DECL_OVERRIDE; + const std::set &subdomain_indices() const; + QColor getSubdomainIndexColor(int i) const; + public Q_SLOTS: + + void on_spheres_color_changed(); + + void data_item_destroyed(); + + void reset_spheres(); + + void reset_intersection_item(); + void show_intersection(bool b); + void show_grid(bool b); + void show_spheres(bool b); + void computeIntersection(); + + virtual QPixmap graphicalToolTip() const Q_DECL_OVERRIDE; + + void update_histogram(); + + void changed(); + + void updateCutPlane(); + + void build_histogram(); + + QColor get_histogram_color(const double v) const; + + void switchVisibleSubdomain(int); + + void itemAboutToBeDestroyed(Scene_item *) Q_DECL_OVERRIDE; + + void initializeBuffers(Viewer_interface *) const Q_DECL_OVERRIDE; + void computeElements() const Q_DECL_OVERRIDE; + void newViewer(Viewer_interface *viewer) Q_DECL_OVERRIDE; + + protected: + friend struct Scene_triangulation_3_item_priv; + mutable Scene_triangulation_3_item_priv* d; + enum Face_Containers{ + T3_faces = 0 + }; + enum Edge_Containers{ + T3_edges = 0, + Grid_edges + }; + + virtual bool do_take_cell(const T3::Cell_handle&) const { return true; } + virtual bool do_take_facet(const T3::Facet&)const { return true; } + virtual bool do_take_vertex(const T3::Vertex_handle&)const { return true; } + virtual bool is_facet_oriented(const T3::Facet&)const { return true; } + virtual bool is_surface() const { return false; } +}; + +#endif // SCENE_TRIANGULATION_3_ITEM_H diff --git a/Polyhedron/demo/Polyhedron/Scene_triangulation_3_item_config.h b/Polyhedron/demo/Polyhedron/Scene_triangulation_3_item_config.h new file mode 100644 index 00000000000..b7c10668c44 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Scene_triangulation_3_item_config.h @@ -0,0 +1,15 @@ +#ifndef SCENE_TRIANGULATION_3_ITEM_CONFIG_H +#define SCENE_TRIANGULATION_3_ITEM_CONFIG_H + +#ifdef scene_triangulation_3_item_EXPORTS +# define mesh_3_demo_scene_triangulation_3_item_EXPORTS 1 +#endif + +#ifdef mesh_3_demo_scene_triangulation_3_item_EXPORTS +# define SCENE_TRIANGULATION_3_ITEM_EXPORT Q_DECL_EXPORT +#else +# define SCENE_TRIANGULATION_3_ITEM_EXPORT Q_DECL_IMPORT +#endif + + +#endif // SCENE_TRIANGULATION_3_ITEM_CONFIG_H diff --git a/Polyhedron/demo/Polyhedron/T3_type.h b/Polyhedron/demo/Polyhedron/T3_type.h new file mode 100644 index 00000000000..59daacdccd7 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/T3_type.h @@ -0,0 +1,7 @@ +#ifndef CGAL_DEMO_T3_TYPE_H +#define CGAL_DEMO_T3_TYPE_H +#include "C3t3_type.h" +#include + +typedef CGAL::Triangulation_3 T3; +#endif // CGAL_DEMO_T3_TYPE_H diff --git a/Polyhedron/demo/Polyhedron/Triangle_container.cpp b/Polyhedron/demo/Polyhedron/Triangle_container.cpp index 3442f948e3a..335b032d788 100644 --- a/Polyhedron/demo/Polyhedron/Triangle_container.cpp +++ b/Polyhedron/demo/Polyhedron/Triangle_container.cpp @@ -79,6 +79,7 @@ void Triangle_container::initGL( Viewer_interface* viewer) QOpenGLBuffer::VertexBuffer, GL_FLOAT, 0, 1)); getVao(viewer)->addVbo(getVbo(Distances)); } + } else { @@ -137,6 +138,27 @@ void Triangle_container::initGL( Viewer_interface* viewer) if(!getTexture()) setTexture(new Texture()); } + // This is passed as float because to pass an integer type to glsl the function is glVertexAttribIPointer(), + // but the qt system only calls glVertexAttribPointer(), whatever type is given. It is far less efforts to + // convert floats that to reimplement the whole system without Qt for this attribute. + if(viewer->getShaderProgram(getProgram())->property("hasSubdomainIndicesValues").toBool()) + { + if(!getVbo(Subdomain_indices)) + setVbo(Subdomain_indices, + new Vbo("subdomain_in", + Vbo::GEOMETRY, + QOpenGLBuffer::VertexBuffer, GL_FLOAT, 0, 2, 4*sizeof(float))); + getVao(viewer)->addVbo(getVbo(Subdomain_indices)); + } + if(viewer->getShaderProgram(getProgram())->property("hasDistanceValues").toBool()) + { + if(!getVbo(Distances)) + setVbo(Distances, + new Vbo("distance", + Vbo::COLORS, + QOpenGLBuffer::VertexBuffer, GL_FLOAT, 0, 1)); + getVao(viewer)->addVbo(getVbo(Distances)); + } } } setGLInit(viewer, true); diff --git a/Polyhedron/demo/Polyhedron/Viewer.cpp b/Polyhedron/demo/Polyhedron/Viewer.cpp index 1d9cbbc2c0c..4b58030049f 100644 --- a/Polyhedron/demo/Polyhedron/Viewer.cpp +++ b/Polyhedron/demo/Polyhedron/Viewer.cpp @@ -309,7 +309,7 @@ void Viewer::doBindings() setKeyDescription(Qt::Key_M, tr("Toggle macro mode: useful to view details very near from the camera, " "but decrease the z-buffer precision")); - setKeyDescription(Qt::Key_I + Qt::CTRL, + setKeyDescription(Qt::CTRL, Qt::Key_I, tr("Toggle the primitive IDs visibility of the selected Item, for the types selected in the context menu of the said item.")); setKeyDescription(Qt::Key_D, tr("Disable the distance between two points visibility.")); @@ -1022,6 +1022,7 @@ void Viewer::attribBuffers(int program_name) const { case PROGRAM_FLAT: case PROGRAM_NO_INTERPOLATION: case PROGRAM_HEAT_INTENSITY: + case PROGRAM_TETRA_FILTERING: program->setUniformValue("light_pos", light_pos); program->setUniformValue("light_diff",d->diffuse); program->setUniformValue("light_spec", d->specular); @@ -1045,6 +1046,7 @@ void Viewer::attribBuffers(int program_name) const { case PROGRAM_FLAT: case PROGRAM_NO_INTERPOLATION: case PROGRAM_HEAT_INTENSITY: + case PROGRAM_TETRA_FILTERING: program->setUniformValue("mv_matrix", mv_mat); program->setUniformValue("norm_matrix", norm_mat); break; @@ -1240,6 +1242,7 @@ QOpenGLShaderProgram* Viewer::getShaderProgram(int name) const program->setProperty("hasTransparency", true); program->setProperty("hasCenter", true); program->setProperty("hasSurfaceMode", true); + program->setProperty("hasSubdomainIndicesValues", true); return program; } case PROGRAM_C3T3_EDGES: @@ -1250,6 +1253,7 @@ QOpenGLShaderProgram* Viewer::getShaderProgram(int name) const ":/cgal/Polyhedron_3/resources/compatibility_shaders/shader_c3t3_edges.frag"); program->setProperty("hasCutPlane", true); program->setProperty("hasSurfaceMode", true); + program->setProperty("hasSubdomainIndicesValues", true); return program; } case PROGRAM_WITH_LIGHT: @@ -1446,6 +1450,19 @@ QOpenGLShaderProgram* Viewer::getShaderProgram(int name) const program->setProperty("drawLinesAdjacency", true); return program; } + case PROGRAM_TETRA_FILTERING: + { + if(!isOpenGL_4_3()) + { + std::cerr<<"An OpenGL context of version 4.3 is required for the program ("<setProperty("hasLight", true); + program->setProperty("hasNormals", true); + program->setProperty("hasDistanceValues", true); + return program; + } default: std::cerr<<"ERROR : Program not found."< +#include +#include #include #include diff --git a/Polyhedron/demo/Polyhedron/resources/shader_c3t3.frag b/Polyhedron/demo/Polyhedron/resources/shader_c3t3.frag index 9893fcc80a5..27b255c5e1c 100644 --- a/Polyhedron/demo/Polyhedron/resources/shader_c3t3.frag +++ b/Polyhedron/demo/Polyhedron/resources/shader_c3t3.frag @@ -2,6 +2,7 @@ in vec4 color; in vec4 fP; in vec3 fN; +flat in vec2 subdomain_out; uniform vec4 light_pos; uniform vec4 light_diff; uniform vec4 light_spec; @@ -18,6 +19,8 @@ uniform bool writing; uniform sampler2D sampler; uniform float alpha; uniform bool is_surface; +uniform vec4 is_visible_bitset; +uniform bool is_filterable; out vec4 out_color; float depth(float z) @@ -26,17 +29,29 @@ float depth(float z) } void main(void) { + if(is_filterable) + { + uint domain1 = uint(subdomain_out.x); + uint domain2 = uint(subdomain_out.y); + uint i1 = domain1/25u; + uint i2 = domain2/25u; + uint visible1 = uint(is_visible_bitset[i1]); + uint visible2 = uint(is_visible_bitset[i2]); + if((visible1>>(domain1%25u))%2u == 0u && (visible2>>(domain2%25u))%2u == 0u) + { + discard; + } + } float d = depth(gl_FragCoord.z); float test = texture(sampler, vec2(gl_FragCoord.x/width, gl_FragCoord.y/height)).r; if(comparing && d <= test) - discard; + discard; if(writing) out_color = vec4(d,d,d,1.0); else { if(color.w<0 || is_surface) { - vec4 my_color = vec4(color.xyz, 1.); vec3 L = light_pos.xyz - fP.xyz; vec3 V = -fP.xyz; diff --git a/Polyhedron/demo/Polyhedron/resources/shader_c3t3.vert b/Polyhedron/demo/Polyhedron/resources/shader_c3t3.vert index c9570f479e4..2298a14b15c 100644 --- a/Polyhedron/demo/Polyhedron/resources/shader_c3t3.vert +++ b/Polyhedron/demo/Polyhedron/resources/shader_c3t3.vert @@ -3,6 +3,7 @@ in vec4 vertex; in vec3 normals; in vec3 colors; in vec3 center; +in vec2 subdomain_in; uniform mat4 mvp_matrix; uniform mat4 mv_matrix; uniform mat4 norm_matrix; @@ -11,9 +12,11 @@ uniform float shrink_factor; out vec4 fP; out vec3 fN; out vec4 color; +flat out vec2 subdomain_out; uniform float point_size; void main(void) { + subdomain_out = subdomain_in; gl_PointSize = point_size; color = vec4(colors, vertex.x * cutplane.x + vertex.y * cutplane.y + vertex.z * cutplane.z + cutplane.w); fP = mv_matrix * vertex; diff --git a/Polyhedron/demo/Polyhedron/resources/shader_c3t3_edges.frag b/Polyhedron/demo/Polyhedron/resources/shader_c3t3_edges.frag index 81366aefa9f..c3fbb6bba00 100644 --- a/Polyhedron/demo/Polyhedron/resources/shader_c3t3_edges.frag +++ b/Polyhedron/demo/Polyhedron/resources/shader_c3t3_edges.frag @@ -1,9 +1,26 @@ #version 150 in vec4 color; +flat in vec2 subdomain_out; uniform bool is_surface; +uniform vec4 is_visible_bitset; +uniform bool is_filterable; out vec4 out_color; void main(void) { + if(is_filterable) + { + uint domain1 = uint(subdomain_out.x); + uint domain2 = uint(subdomain_out.y); + uint i1 = domain1/32u; + uint i2 = domain2/32u; + uint visible1 = uint(is_visible_bitset[i1]); + uint visible2 = uint(is_visible_bitset[i2]); + if((visible1>>(domain1%32u))%2u == 0u && (visible2>>(domain2%32u))%2u == 0u) + { + discard; + } + } + if(color.w<0 || is_surface) out_color = vec4(0,0,0,1.0); else diff --git a/Polyhedron/demo/Polyhedron/resources/shader_c3t3_edges.vert b/Polyhedron/demo/Polyhedron/resources/shader_c3t3_edges.vert index e84bcbc1d48..9d00649a829 100644 --- a/Polyhedron/demo/Polyhedron/resources/shader_c3t3_edges.vert +++ b/Polyhedron/demo/Polyhedron/resources/shader_c3t3_edges.vert @@ -1,12 +1,15 @@ #version 150 in vec4 vertex; in vec3 colors; +in vec2 subdomain_in; uniform mat4 mvp_matrix; uniform vec4 cutplane; out vec4 color; uniform float point_size; +flat out vec2 subdomain_out; void main(void) { + subdomain_out = subdomain_in; gl_PointSize = point_size; color = vec4(colors, vertex.x * cutplane.x + vertex.y * cutplane.y + vertex.z * cutplane.z + cutplane.w); gl_Position = mvp_matrix * vertex; diff --git a/Polyhedron/demo/Polyhedron/resources/shader_tet_filter.frag b/Polyhedron/demo/Polyhedron/resources/shader_tet_filter.frag new file mode 100644 index 00000000000..b5eb06160de --- /dev/null +++ b/Polyhedron/demo/Polyhedron/resources/shader_tet_filter.frag @@ -0,0 +1,57 @@ +#version 150 + +in VS_OUT +{ + vec4 fP; + vec4 out_color; + float dist[6]; + vec4 vertex; + vec3 normal; + flat float stat_value; +}fs_in; + +uniform bool is_two_side; +uniform vec4 light_pos; +uniform vec4 light_diff; +uniform vec4 light_spec; +uniform vec4 light_amb; +uniform float spec_power ; +uniform bool is_clipbox_on; +uniform float min_threshold; +uniform float max_threshold; + +out vec4 out_color; + +void main(void) +{ + if(fs_in.stat_value < min_threshold + || fs_in.stat_value > max_threshold) + discard; + if(is_clipbox_on) + if(fs_in.dist[0]>0.0 || + fs_in.dist[1]>0.0 || + fs_in.dist[2]>0.0 || + fs_in.dist[3]>0.0 || + fs_in.dist[4]>0.0 || + fs_in.dist[5]>0.0) + discard; + vec3 L = light_pos.xyz - fs_in.fP.xyz; + vec3 V = -fs_in.fP.xyz; + + vec3 N; + if(fs_in.normal == vec3(0.0,0.0,0.0)) + N = vec3(0.0,0.0,0.0); + else + N = fs_in.normal; + L = normalize(L); + V = normalize(V); + + vec3 R = reflect(-L, N); + vec4 diffuse; + if(!is_two_side) + diffuse = max(dot(N,L),0) * light_diff*fs_in.out_color; + else + diffuse = max(abs(dot(N,L)),0) * light_diff*fs_in.out_color; + vec4 specular = pow(max(dot(R,V), 0.0), spec_power) * light_spec; + out_color = vec4((fs_in.out_color*light_amb).xyz + diffuse.xyz + specular.xyz,1.0); +} diff --git a/Polyhedron/demo/Polyhedron/resources/shader_tet_filter.vert b/Polyhedron/demo/Polyhedron/resources/shader_tet_filter.vert new file mode 100644 index 00000000000..95787fc3416 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/resources/shader_tet_filter.vert @@ -0,0 +1,57 @@ +#version 150 + +in vec4 vertex; +in vec3 normals; +in vec4 colors; +in float distance; +out VS_OUT +{ + vec4 fP; + vec4 out_color; + float dist[6]; + vec4 vertex; + vec3 normal; + flat float stat_value; +}vs_out; + +uniform mat4 mvp_matrix; +uniform mat4 mv_matrix; +uniform mat4 norm_matrix; +uniform bool is_clipbox_on; +uniform highp mat4 clipbox1; +uniform highp mat4 clipbox2; + +void compute_distances(void) +{ + for(int i=0; i<3; ++i) + { + vs_out.dist[i]= + clipbox1[i][0]*vertex.x+ + clipbox1[i][1]*vertex.y+ + clipbox1[i][2]*vertex.z + + clipbox1[i][3]; + vs_out.dist[i+3]= + clipbox2[i][0]*vertex.x+ + clipbox2[i][1]*vertex.y+ + clipbox2[i][2]*vertex.z + + clipbox2[i][3]; + } +} + +void main(void) +{ + if(is_clipbox_on) + compute_distances(); + vs_out.out_color=colors; + vs_out.fP = mv_matrix * vertex; + vs_out.vertex = vertex; + vs_out.stat_value= distance; + + mat3 norm_matrix_3; + norm_matrix_3[0] = norm_matrix[0].xyz; + norm_matrix_3[1] = norm_matrix[1].xyz; + norm_matrix_3[2] = norm_matrix[2].xyz; + vs_out.normal = norm_matrix_3* normals; + + gl_Position = mvp_matrix * vertex; +} diff --git a/Polyhedron/include/CGAL/boost/graph/properties_Polyhedron_3.h b/Polyhedron/include/CGAL/boost/graph/properties_Polyhedron_3.h index 939093a7db5..65c8df16fd1 100644 --- a/Polyhedron/include/CGAL/boost/graph/properties_Polyhedron_3.h +++ b/Polyhedron/include/CGAL/boost/graph/properties_Polyhedron_3.h @@ -15,10 +15,10 @@ #include #include #include -#include #include #include #include +#include #define CGAL_HDS_PARAM_ template < class Traits, class Items, class Alloc> class HDS diff --git a/Polynomial/include/CGAL/Test/_test_polynomial_traits_d.h b/Polynomial/include/CGAL/Test/_test_polynomial_traits_d.h index de76f759311..dbb37d309b9 100644 --- a/Polynomial/include/CGAL/Test/_test_polynomial_traits_d.h +++ b/Polynomial/include/CGAL/Test/_test_polynomial_traits_d.h @@ -1800,28 +1800,25 @@ void test_rebind(const PT& /*traits*/){ typedef typename PT::Innermost_coefficient_type IC; { - CGAL_assertion_code( const int dimension = 1; ); typedef typename PT:: template Rebind::Other PT_IC_1; CGAL_USE_TYPE(PT_IC_1); CGAL_static_assertion((boost::is_same< typename PT_IC_1::Innermost_coefficient_type, IC>::value)); - CGAL_static_assertion((PT_IC_1::d==dimension)); + CGAL_static_assertion((PT_IC_1::d==1)); } { - CGAL_assertion_code( const int dimension = 2; ); typedef typename PT:: template Rebind::Other PT_IC_2; CGAL_USE_TYPE(PT_IC_2); CGAL_static_assertion((boost::is_same< typename PT_IC_2::Innermost_coefficient_type, IC>::value)); - CGAL_static_assertion((PT_IC_2::d==dimension)); + CGAL_static_assertion((PT_IC_2::d==2)); } { - CGAL_assertion_code( const int dimension = 3; ) typedef typename PT:: template Rebind::Other PT_IC_3; CGAL_USE_TYPE(PT_IC_3); CGAL_static_assertion((boost::is_same< typename PT_IC_3::Innermost_coefficient_type, IC>::value)); - CGAL_static_assertion((PT_IC_3::d==dimension)); + CGAL_static_assertion((PT_IC_3::d==3)); } { typedef typename PT:: template Rebind::Other PT_IC_1; @@ -1831,8 +1828,8 @@ void test_rebind(const PT& /*traits*/){ CGAL_USE_TYPE(PT_IC_1); CGAL_USE_TYPE(PT_IC_2); CGAL_USE_TYPE(PT_IC_3); - CGAL_assertion_code(typedef typename PT_IC_1::Polynomial_d Poly1;) - CGAL_assertion_code(typedef typename PT_IC_2::Polynomial_d Poly2;) + typedef typename PT_IC_1::Polynomial_d Poly1; + typedef typename PT_IC_2::Polynomial_d Poly2; CGAL_static_assertion((boost::is_same< typename PT_IC_1::Coefficient_type, IC>::value)); @@ -1866,7 +1863,6 @@ void test_rebind(const PT& /*traits*/){ typedef CGAL::CORE_arithmetic_kernel AT; typedef typename AT::Integer Integer; typedef typename AT::Rational Rational; - CGAL_assertion_code( const int dimension = 4; ) typedef typename PT:: template Rebind::Other PT_Integer_4; typedef typename PT:: template Rebind::Other PT_Rational_4; CGAL_USE_TYPE(PT_Integer_4); @@ -1875,12 +1871,11 @@ void test_rebind(const PT& /*traits*/){ Integer>::value)); CGAL_static_assertion((boost::is_same< typename PT_Rational_4::Innermost_coefficient_type, Rational>::value)); - CGAL_static_assertion((PT_Integer_4::d==dimension)); - CGAL_static_assertion((PT_Rational_4::d==dimension)); + CGAL_static_assertion((PT_Integer_4::d==4)); + CGAL_static_assertion((PT_Rational_4::d==4)); } #endif { - CGAL_assertion_code( const int dimension = 4; ) typedef typename PT:: template Rebind::Other PT_Integer_4; typedef typename PT:: template Rebind::Other PT_Rational_4; CGAL_USE_TYPE(PT_Integer_4); @@ -1889,8 +1884,8 @@ void test_rebind(const PT& /*traits*/){ int>::value)); CGAL_static_assertion((boost::is_same< typename PT_Rational_4::Innermost_coefficient_type, double>::value)); - CGAL_static_assertion((PT_Integer_4::d==dimension)); - CGAL_static_assertion((PT_Rational_4::d==dimension)); + CGAL_static_assertion((PT_Integer_4::d==4)); + CGAL_static_assertion((PT_Rational_4::d==4)); } } diff --git a/Polynomial/test/Polynomial/Polynomial_type_generator.cpp b/Polynomial/test/Polynomial/Polynomial_type_generator.cpp index e0510591c5d..41997959c8a 100644 --- a/Polynomial/test/Polynomial/Polynomial_type_generator.cpp +++ b/Polynomial/test/Polynomial/Polynomial_type_generator.cpp @@ -6,23 +6,20 @@ #include int main(){ - CGAL_assertion_code(typedef CGAL::Polynomial Poly_int_1;) - CGAL_assertion_code(typedef CGAL::Polynomial Poly_int_2;) - CGAL_assertion_code(typedef CGAL::Polynomial Poly_int_3;) + typedef CGAL::Polynomial Poly_int_1; + typedef CGAL::Polynomial Poly_int_2; + typedef CGAL::Polynomial Poly_int_3; { typedef CGAL::Polynomial_type_generator::Type Polynomial; - CGAL_USE_TYPE(Polynomial); CGAL_static_assertion((::boost::is_same::value)); } { typedef CGAL::Polynomial_type_generator::Type Polynomial; - CGAL_USE_TYPE(Polynomial); CGAL_static_assertion((::boost::is_same::value)); } { typedef CGAL::Polynomial_type_generator::Type Polynomial; - CGAL_USE_TYPE(Polynomial); CGAL_static_assertion((::boost::is_same::value)); } } diff --git a/Polynomial/test/Polynomial/test_polynomial.h b/Polynomial/test/Polynomial/test_polynomial.h index 646057c636b..a8a07ba92d0 100644 --- a/Polynomial/test/Polynomial/test_polynomial.h +++ b/Polynomial/test/Polynomial/test_polynomial.h @@ -33,7 +33,7 @@ template inline void convert_to(const NT& x, RT& r){ typedef CGAL::Coercion_traits CT; - CGAL_assertion_code(typedef typename CT::Coercion_type RET;) + typedef typename CT::Coercion_type RET; CGAL_static_assertion((::boost::is_same::value)); r = typename CT::Cast()(x); } @@ -878,7 +878,7 @@ void test_scalar_factor_traits(){ typedef CGAL::Polynomial Polynomial; typedef CGAL::Scalar_factor_traits SFT; typedef typename AT::Integer Scalar; - CGAL_assertion_code(typedef typename SFT::Scalar Scalar_;) + typedef typename SFT::Scalar Scalar_; CGAL_static_assertion((::boost::is_same::value)); typename SFT::Scalar_factor sfac; @@ -903,8 +903,8 @@ void test_scalar_factor_traits(){ typedef CGAL::Polynomial Poly_1_ext_1; typedef CGAL::Polynomial Poly_2_ext_1; typedef CGAL::Scalar_factor_traits SFT; - CGAL_assertion_code(typedef typename AT::Integer Scalar;) - CGAL_assertion_code(typedef typename SFT::Scalar Scalar_;) + typedef typename AT::Integer Scalar; + typedef typename SFT::Scalar Scalar_; CGAL_static_assertion((::boost::is_same::value)); typename SFT::Scalar_factor sfac; diff --git a/Polynomial/test/Polynomial/test_polynomial_Get_arithmetic_kernel.cpp b/Polynomial/test/Polynomial/test_polynomial_Get_arithmetic_kernel.cpp index cddfbfb99b2..dc47580cc91 100644 --- a/Polynomial/test/Polynomial/test_polynomial_Get_arithmetic_kernel.cpp +++ b/Polynomial/test/Polynomial/test_polynomial_Get_arithmetic_kernel.cpp @@ -3,14 +3,14 @@ template void test_get_arithmetic_kernel(){ - CGAL_assertion_code(typedef typename AK::Integer Integer); + typedef typename AK::Integer Integer; { - CGAL_assertion_code(typedef CGAL::Polynomial POLY;) - CGAL_assertion_code(typedef typename CGAL::Get_arithmetic_kernel::Arithmetic_kernel AK_;) + typedef CGAL::Polynomial POLY; + typedef typename CGAL::Get_arithmetic_kernel::Arithmetic_kernel AK_; CGAL_static_assertion((boost::is_same::value)); }{ - CGAL_assertion_code(typedef CGAL::Polynomial > POLY;) - CGAL_assertion_code(typedef typename CGAL::Get_arithmetic_kernel::Arithmetic_kernel AK_;) + typedef CGAL::Polynomial > POLY; + typedef typename CGAL::Get_arithmetic_kernel::Arithmetic_kernel AK_; CGAL_static_assertion((boost::is_same::value)); } } diff --git a/Profiling_tools/include/CGAL/Profile_counter.h b/Profiling_tools/include/CGAL/Profile_counter.h index 537d7640bee..518ccbc43eb 100644 --- a/Profiling_tools/include/CGAL/Profile_counter.h +++ b/Profiling_tools/include/CGAL/Profile_counter.h @@ -121,9 +121,9 @@ struct Profile_histogram_counter { private: #ifdef CGAL_CONCURRENT_PROFILE - typedef tbb::concurrent_hash_map Counters; + typedef tbb::concurrent_hash_map CounterMap; #else - typedef std::map Counters; + typedef std::map CounterMap; #endif public: @@ -133,7 +133,7 @@ public: void operator()(unsigned i) { #ifdef CGAL_CONCURRENT_PROFILE - Counters::accessor a; + CounterMap::accessor a; counters.insert(a, i); ++a->second; #else @@ -144,7 +144,7 @@ public: ~Profile_histogram_counter() { unsigned total=0; - for (Counters::const_iterator it=counters.begin(), end=counters.end(); + for (CounterMap::const_iterator it=counters.begin(), end=counters.end(); it != end; ++it) { std::cerr << "[CGAL::Profile_histogram_counter] " << s; std::cerr << " [ " << std::setw(10) << internal::dot_it(it->first) << " : " @@ -158,7 +158,7 @@ public: } private: - Counters counters; + CounterMap counters; const std::string s; }; diff --git a/STL_Extension/benchmark/copy_n_benchmark/copy_n_benchmark.cpp b/STL_Extension/benchmark/copy_n_benchmark/copy_n_benchmark.cpp index e3a8abf0128..8c9c25999d4 100644 --- a/STL_Extension/benchmark/copy_n_benchmark/copy_n_benchmark.cpp +++ b/STL_Extension/benchmark/copy_n_benchmark/copy_n_benchmark.cpp @@ -77,11 +77,9 @@ int main(int argc, char* argv[]) { "|- \n"; float item_sec; -#ifndef CGAL_CFG_NO_CPP0X_COPY_N item_sec = test(v.begin(), n, copy_m, repeats, std_tag()); format_output("stdlib", "vector", "int*", n, item_sec); std::cout << "|- \n"; -#endif item_sec = test(v.begin(), n, copy_m, repeats, cgal_tag()); format_output("CGAL", "vector", "int*", n, item_sec); @@ -93,11 +91,9 @@ int main(int argc, char* argv[]) { list l(n); -#ifndef CGAL_CFG_NO_CPP0X_COPY_N item_sec = test(l.begin(), n, copy_m, repeats, std_tag()); format_output("stdlib", "list", "int*", n, item_sec); std::cout << "|- \n"; -#endif item_sec = test(l.begin(), n, copy_m, repeats, cgal_tag()); format_output("CGAL", "list", "int*", n, item_sec); @@ -108,11 +104,9 @@ int main(int argc, char* argv[]) { vector2 v2(n); copy_mem2 copy_m2 = new non_trivial_cctor[n]; -#ifndef CGAL_CFG_NO_CPP0X_COPY_N item_sec = test(v2.begin(), n, copy_m2, repeats, std_tag()); format_output("stdlib", "vector", "non_trivial_cctor*", n, item_sec); std::cout << "|- \n"; -#endif item_sec = test(v2.begin(), n, copy_m2, repeats, cgal_tag()); format_output("CGAL", "vector", "non_trivial_cctor*", n, item_sec); diff --git a/STL_Extension/include/CGAL/Compact_container.h b/STL_Extension/include/CGAL/Compact_container.h index 470918b5f80..15081283ede 100644 --- a/STL_Extension/include/CGAL/Compact_container.h +++ b/STL_Extension/include/CGAL/Compact_container.h @@ -425,9 +425,7 @@ public: CGAL_precondition(type(&*x) == USED); EraseCounterStrategy::increment_erase_counter(*x); std::allocator_traits::destroy(alloc, &*x); -/*#ifndef CGAL_NO_ASSERTIONS - std::memset(&*x, 0, sizeof(T)); -#endif*/ + put_on_free_list(&*x); --size_; } diff --git a/STL_Extension/include/CGAL/Concurrent_compact_container.h b/STL_Extension/include/CGAL/Concurrent_compact_container.h index d1f1a4e840f..d3f60bbd381 100644 --- a/STL_Extension/include/CGAL/Concurrent_compact_container.h +++ b/STL_Extension/include/CGAL/Concurrent_compact_container.h @@ -394,10 +394,6 @@ private: std::allocator_traits::destroy(m_alloc, &*x); -/* WE DON'T DO THAT BECAUSE OF THE ERASE COUNTER -#ifndef CGAL_NO_ASSERTIONS - std::memset(&*x, 0, sizeof(T)); -#endif*/ put_on_free_list(&*x, fl); } public: diff --git a/STL_Extension/include/CGAL/Iterator_range.h b/STL_Extension/include/CGAL/Iterator_range.h index e998fcf8cdc..e1d41818d5a 100644 --- a/STL_Extension/include/CGAL/Iterator_range.h +++ b/STL_Extension/include/CGAL/Iterator_range.h @@ -68,7 +68,6 @@ namespace CGAL { { return begin()==end(); } -#ifndef CGAL_CFG_NO_CPP0X_TUPLE operator std::tuple() { @@ -79,8 +78,6 @@ namespace CGAL { { return std::tuple{this->first, this->second}; } -#endif - }; template diff --git a/STL_Extension/include/CGAL/STL_Extension/internal/boost/array_binary_tree.hpp b/STL_Extension/include/CGAL/STL_Extension/internal/boost/array_binary_tree.hpp index dba4dc93fb8..3e1fa963176 100644 --- a/STL_Extension/include/CGAL/STL_Extension/internal/boost/array_binary_tree.hpp +++ b/STL_Extension/include/CGAL/STL_Extension/internal/boost/array_binary_tree.hpp @@ -21,10 +21,9 @@ #define CGAL_INTERNAL_ARRAY_BINARY_TREE_HPP #include - #include -#include +#include #include namespace CGAL { namespace internal { diff --git a/STL_Extension/include/CGAL/Spatial_lock_grid_3.h b/STL_Extension/include/CGAL/Spatial_lock_grid_3.h index f5d2b6df798..b50211b0199 100644 --- a/STL_Extension/include/CGAL/Spatial_lock_grid_3.h +++ b/STL_Extension/include/CGAL/Spatial_lock_grid_3.h @@ -17,11 +17,7 @@ #include #include -#if TBB_IMPLEMENT_CPP0X -# include -#else -# include -#endif +#include #include #include diff --git a/STL_Extension/include/CGAL/Uncertain.h b/STL_Extension/include/CGAL/Uncertain.h index 1a7539b2b24..00a7eaaa82f 100644 --- a/STL_Extension/include/CGAL/Uncertain.h +++ b/STL_Extension/include/CGAL/Uncertain.h @@ -325,32 +325,6 @@ Uncertain operator&(Uncertain a, bool b) return Uncertain(a.inf() & b, a.sup() & b); } -// operator&& and operator|| are not provided because, unless their bool counterpart, -// they lack the "short-circuiting" property. -// We provide macros CGAL_AND and CGAL_OR, which attempt to emulate their behavior. -// Key things : do not evaluate expressions twice, and evaluate the right hand side -// expression only when needed. -// TODO : C++0x lambdas should be able to help here. -#ifdef CGAL_CFG_NO_STATEMENT_EXPRESSIONS -# define CGAL_AND(X, Y) ((X) && (Y)) -# define CGAL_OR(X, Y) ((X) || (Y)) -#else -# define CGAL_AND(X, Y) \ - __extension__ \ - ({ CGAL::Uncertain CGAL_TMP = (X); \ - CGAL::certainly_not(CGAL_TMP) ? CGAL::make_uncertain(false) \ - : CGAL_TMP & CGAL::make_uncertain((Y)); }) -# define CGAL_OR(X, Y) \ - __extension__ \ - ({ CGAL::Uncertain CGAL_TMP = (X); \ - CGAL::certainly(CGAL_TMP) ? CGAL::make_uncertain(true) \ - : CGAL_TMP | CGAL::make_uncertain((Y)); }) -#endif - -#define CGAL_AND_3(X, Y, Z) CGAL_AND(X, CGAL_AND(Y, Z)) -#define CGAL_AND_6(A, B, C, D, E, F) CGAL_AND(CGAL_AND_3(A, B, C), CGAL_AND_3(D, E,F)) -#define CGAL_OR_3(X, Y, Z) CGAL_OR(X, CGAL_OR(Y, Z)) - // Equality operators @@ -520,6 +494,38 @@ Uncertain make_uncertain(Uncertain t) return t; } +// operator&& and operator|| are not provided because, unless their bool counterpart, +// they lack the "short-circuiting" property. +// We provide macros CGAL_AND and CGAL_OR, which attempt to emulate their behavior. +// Key things : do not evaluate expressions twice, and evaluate the right hand side +// expression only when needed. This is done by using the second value of the macro +// only when required thanks to a lambda that will consume the second expression on demand. + +namespace internal{ + template + inline Uncertain cgal_and_impl(const Uncertain& a, F_B&& f_b) + { + return certainly_not(a) ? make_uncertain(false) + : a & make_uncertain(f_b()); + } + + template + inline Uncertain cgal_or_impl(const Uncertain& a, F_B&& f_b) + { + return certainly(a) ? make_uncertain(true) + : a | make_uncertain(f_b()); + } +} + +# define CGAL_AND(X, Y) \ + ::CGAL::internal::cgal_and_impl((X), [&]() { return (Y); }) + +# define CGAL_OR(X, Y) \ + ::CGAL::internal::cgal_or_impl((X), [&]() { return (Y); }) + +#define CGAL_AND_3(X, Y, Z) CGAL_AND(X, CGAL_AND(Y, Z)) +#define CGAL_AND_6(A, B, C, D, E, F) CGAL_AND(CGAL_AND_3(A, B, C), CGAL_AND_3(D, E,F)) +#define CGAL_OR_3(X, Y, Z) CGAL_OR(X, CGAL_OR(Y, Z)) // make_certain() : Forcing a cast to certain (possibly throwing). // This is meant to be used only in cases where we cannot easily propagate the diff --git a/STL_Extension/include/CGAL/assertions.h b/STL_Extension/include/CGAL/assertions.h index f3de2c1e8b2..90ea7557ed6 100644 --- a/STL_Extension/include/CGAL/assertions.h +++ b/STL_Extension/include/CGAL/assertions.h @@ -44,10 +44,6 @@ # define CGAL_NO_WARNINGS #endif -#ifdef CGAL_CFG_NO_CPP0X_STATIC_ASSERT -#include -#endif - namespace CGAL { // function declarations @@ -110,48 +106,12 @@ inline bool possibly(Uncertain c); # define CGAL_assume_code(CODE) CGAL_assertion_code(CODE) #endif // no CGAL_NO_ASSERTIONS -#ifndef CGAL_CFG_NO_CPP0X_STATIC_ASSERT - -# if defined(CGAL_NO_ASSERTIONS) - -# define CGAL_static_assertion(EX) \ - static_assert(true, "") - -# define CGAL_static_assertion_msg(EX,MSG) \ - static_assert(true, "") - -# else // no CGAL_NO_ASSERTIONS - -# define CGAL_static_assertion(EX) \ +# define CGAL_static_assertion(EX) \ static_assert(EX, #EX) -# define CGAL_static_assertion_msg(EX,MSG) \ +# define CGAL_static_assertion_msg(EX,MSG) \ static_assert(EX, MSG) -# endif // no CGAL_NO_ASSERTIONS - -#else // if CGAL_CFG_NO_CPP0X_STATIC_ASSERT is true - -# if defined(CGAL_NO_ASSERTIONS) - -# define CGAL_static_assertion(EX) \ - BOOST_STATIC_ASSERT(true) CGAL_UNUSED - -# define CGAL_static_assertion_msg(EX,MSG) \ - BOOST_STATIC_ASSERT(true) CGAL_UNUSED - -# else // no CGAL_NO_ASSERTIONS - -# define CGAL_static_assertion(EX) \ - BOOST_STATIC_ASSERT(EX) CGAL_UNUSED - -# define CGAL_static_assertion_msg(EX,MSG) \ - BOOST_STATIC_ASSERT(EX) CGAL_UNUSED - -# endif // no CGAL_NO_ASSERTIONS - -#endif // if CGAL_CFG_NO_CPP0X_STATIC_ASSERT is true - #if defined(CGAL_NO_ASSERTIONS) || !defined(CGAL_CHECK_EXACTNESS) # define CGAL_exactness_assertion(EX) (static_cast(0)) # define CGAL_exactness_assertion_msg(EX,MSG) (static_cast(0)) diff --git a/STL_Extension/include/CGAL/thread.h b/STL_Extension/include/CGAL/thread.h index 7d163964cf7..7ae53e976be 100644 --- a/STL_Extension/include/CGAL/thread.h +++ b/STL_Extension/include/CGAL/thread.h @@ -22,55 +22,16 @@ - CGAL::cpp11::thread - CGAL::cpp11::atomic - CGAL::cpp11::sleep_for - - It uses either TBB or STD depending on what's available: as TBB can - quite often override `std::thread`, it is possible that TBB will be - used instead of STD even if the real CXX11 `std::thread` is - available. - - As the conflicting API between TBB and STD can be quite complicated, - we offer a more generic `sleep_for()` function that takes - double-typed seconds as argument and deals with it. */ -#if defined(CGAL_LINKED_WITH_TBB) -# include -# if TBB_IMPLEMENT_CPP0X -# include -# include -# include -# define CGAL_USE_TBB_THREADS 1 -# else -# define CGAL_USE_TBB_THREADS 0 -# endif -#else -# define CGAL_USE_TBB_THREADS 0 -#endif - -#if !CGAL_USE_TBB_THREADS -# include -# include -#endif - +#include +#include #include // for CGAL::cpp11::atomic namespace CGAL { namespace cpp11 { -#if CGAL_USE_TBB_THREADS - - using std::thread; // std::thread is declared by TBB if TBB_IMPLEMENT_CPP0X == 1 - - inline void sleep_for (double seconds) - { - // std::this_thread::sleep_for is declared by TBB if TBB_IMPLEMENT_CPP0X == 1 - // It takes interval_t types as argument (!= from the std norm) - std::this_thread::sleep_for(tbb::tick_count::interval_t(seconds)); - } - -#else // C++11 implementation - using std::thread; inline void sleep_for (double seconds) @@ -81,20 +42,8 @@ namespace cpp11 { nanoseconds ns (nanoseconds::rep (1000000000.0 * seconds)); std::this_thread::sleep_for(ns); } - -#endif - -#if defined(CGAL_NO_ATOMIC) && defined(CGAL_LINKED_WITH_TBB) - // If did not defined CGAL::cpp11::atomic, then use - // std::atomic as a fallback. - using std::atomic; -#endif - } // cpp11 - } //namespace CGAL -#undef CGAL_USE_TBB_THREADS - #endif // CGAL_THREAD_H diff --git a/Scale_space_reconstruction_3/package_info/Scale_space_reconstruction_3/dependencies b/Scale_space_reconstruction_3/package_info/Scale_space_reconstruction_3/dependencies index 3a5c0a7b9e2..114d4ba5acd 100644 --- a/Scale_space_reconstruction_3/package_info/Scale_space_reconstruction_3/dependencies +++ b/Scale_space_reconstruction_3/package_info/Scale_space_reconstruction_3/dependencies @@ -22,7 +22,6 @@ Modifier Modular_arithmetic Number_types Point_set_processing_3 -Polygon Polyhedron Profiling_tools Property_map diff --git a/Scripts/developer_scripts/cgal_create_release_with_cmake.cmake b/Scripts/developer_scripts/cgal_create_release_with_cmake.cmake index 77ba8c846f1..03fea9b297f 100644 --- a/Scripts/developer_scripts/cgal_create_release_with_cmake.cmake +++ b/Scripts/developer_scripts/cgal_create_release_with_cmake.cmake @@ -161,6 +161,9 @@ endif() file(COPY ${GIT_REPO}/GraphicsView/demo/resources ${GIT_REPO}/GraphicsView/demo/icons DESTINATION "${release_dir}/cmake/modules/demo") +#copy data +file(COPY ${GIT_REPO}/Data/data DESTINATION "${release_dir}/") + #create VERSION file(WRITE ${release_dir}/VERSION "${CGAL_VERSION}") @@ -296,6 +299,7 @@ file(REMOVE ${release_dir}/include/CGAL/license/package_list.txt) if(PUBLIC AND NOT TESTSUITE) # we are not creating an internal release. # Taken from create_new_release. file(REMOVE_RECURSE ${release_dir}/test) + file(REMOVE_RECURSE ${release_dir}/data/test) file(REMOVE_RECURSE ${release_dir}/package_info) file(REMOVE_RECURSE ${release_dir}/developer_scripts) file(REMOVE_RECURSE ${release_dir}/doc) @@ -322,7 +326,7 @@ if (GENERATE_TARBALLS) #create examples+demos execute_process( - COMMAND tar cJf ${DESTINATION}/CGAL-${CGAL_VERSION}-examples.tar.xz -C ${DESTINATION} CGAL-${CGAL_VERSION}/examples CGAL-${CGAL_VERSION}/demo + COMMAND tar cJf ${DESTINATION}/CGAL-${CGAL_VERSION}-examples.tar.xz -C ${DESTINATION} CGAL-${CGAL_VERSION}/data CGAL-${CGAL_VERSION}/examples CGAL-${CGAL_VERSION}/demo RESULT_VARIABLE RESULT_VAR OUTPUT_VARIABLE OUT_VAR ) @@ -336,6 +340,7 @@ if (GENERATE_TARBALLS) file(REMOVE_RECURSE ${release_dir}/include/CGAL/Test) file(REMOVE_RECURSE ${release_dir}/include/CGAL/Testsuite/) endif() + file(REMOVE_RECURSE ${release_dir}/data) file(REMOVE_RECURSE ${release_dir}/demo) file(REMOVE_RECURSE ${release_dir}/examples) file(REMOVE_RECURSE ${release_dir}/scripts) diff --git a/Scripts/developer_scripts/create_cgal_test b/Scripts/developer_scripts/create_cgal_test index 48296e17658..635051c3b92 100755 --- a/Scripts/developer_scripts/create_cgal_test +++ b/Scripts/developer_scripts/create_cgal_test @@ -34,7 +34,7 @@ while [ $1 ]; do DO_RUN="" shift; continue ;; - *) + *) echo "Unknown option: $1" usage ;; @@ -97,6 +97,21 @@ cat << EOF compile_and_run() { + if [ -z "\${CGAL_DATA_DIR}" ]; then + if [ -d \${CGAL_DIR}/data ]; then + export CGAL_DATA_DIR=\${CGAL_DIR}/data + else + if [ -d \${CGAL_DIR}/Data/data ]; then + export CGAL_DATA_DIR=\${CGAL_DIR}/Data/data + else + echo "ERROR: Cannot run test script, please set the variable CGAL_DATA_DIR" + exit 1 + fi + fi + fi + + echo "Runs will be using CGAL_DATA_DIR = \${CGAL_DATA_DIR}" + echo "Compiling \$1 ... " SUCCESS="y" @@ -113,7 +128,7 @@ compile_and_run() rm -f \$OUTPUTFILE COMMAND="./\$1" if [ -f \$1.cmd ] ; then - COMMAND="\$COMMAND \`cat \$1.cmd\`" + COMMAND="\$COMMAND \`eval echo \$(cat \$1.cmd)\`" fi if [ -f \$1.cin ] ; then COMMAND="cat \$1.cin | \$COMMAND" diff --git a/Scripts/developer_scripts/run_doxygen_testsuite b/Scripts/developer_scripts/run_doxygen_testsuite index 62e1a5d2eeb..a796d4dfde5 100755 --- a/Scripts/developer_scripts/run_doxygen_testsuite +++ b/Scripts/developer_scripts/run_doxygen_testsuite @@ -58,8 +58,6 @@ if [ ! -d "${CGAL_DOC_BUILD}/${CGAL_RELEASE_ID}" ]; then fi cd "${CGAL_RELEASE_ID}" -PYTHONPATH=/home/cgal-testsuite/.local/lib/python2.6/site-packages -export PYTHONPATH PATH=/home/cgal-testsuite/local/bin:$PATH export PATH cd "$PWD/doc/scripts" diff --git a/Segment_Delaunay_graph_2/package_info/Segment_Delaunay_graph_2/dependencies b/Segment_Delaunay_graph_2/package_info/Segment_Delaunay_graph_2/dependencies index 36deee2c524..c3083729fef 100644 --- a/Segment_Delaunay_graph_2/package_info/Segment_Delaunay_graph_2/dependencies +++ b/Segment_Delaunay_graph_2/package_info/Segment_Delaunay_graph_2/dependencies @@ -16,7 +16,6 @@ Kernel_23 Kernel_d Modular_arithmetic Number_types -Polygon Profiling_tools Property_map STL_Extension diff --git a/Skin_surface_3/include/CGAL/Skin_surface_base_3.h b/Skin_surface_3/include/CGAL/Skin_surface_base_3.h index b04b7942881..00f97708e78 100644 --- a/Skin_surface_3/include/CGAL/Skin_surface_base_3.h +++ b/Skin_surface_3/include/CGAL/Skin_surface_base_3.h @@ -313,7 +313,7 @@ sign(TMC_Vertex_handle vit) const } CGAL_BRANCH_PROFILER_BRANCH(tmp); Protect_FPU_rounding P(CGAL_FE_TONEAREST); - + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); typedef Exact_predicates_exact_constructions_kernel EK; typedef Skin_surface_traits_3 Exact_skin_surface_traits; typedef Skin_surface_base_3 Exact_skin_surface_base; @@ -355,6 +355,7 @@ sign(const Bare_point &p, const Cell_info &info) const } CGAL_BRANCH_PROFILER_BRANCH(tmp); Protect_FPU_rounding P(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); return construct_surface(info.first, Exact_predicates_exact_constructions_kernel()).sign(p); } @@ -630,7 +631,7 @@ compare(Cell_info &info1, const Bare_point &p1, } CGAL_BRANCH_PROFILER_BRANCH(tmp); Protect_FPU_rounding P(CGAL_FE_TONEAREST); - + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); return CGAL_NTS sign( construct_surface(info1.first, Exact_predicates_exact_constructions_kernel()).value(p1) - @@ -689,33 +690,37 @@ locate_in_tmc(const Bare_point &p0, TMC_Cell_handle start) const // We temporarily put p at i's place in pts. const TMC_Point* backup = pts[i]; pts[i] = &p_inexact; + bool run_exact=false; { Protect_FPU_rounding P; try { o = TMC_Geom_traits().orientation_3_object()(*pts[0], *pts[1], *pts[2], *pts[3]); - } catch (Uncertain_conversion_exception&) { - Protect_FPU_rounding P(CGAL_FE_TONEAREST); - typedef Exact_predicates_exact_constructions_kernel EK; - Cartesian_converter converter_ek; + } catch (Uncertain_conversion_exception&) { run_exact=true; } + } + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); + if (run_exact) + { + Protect_FPU_rounding P(CGAL_FE_TONEAREST); + typedef Exact_predicates_exact_constructions_kernel EK; + Cartesian_converter converter_ek; - Skin_surface_traits_3 exact_traits(shrink_factor()); + Skin_surface_traits_3 exact_traits(shrink_factor()); - typename EK::Point_3 e_pts[4]; + typename EK::Point_3 e_pts[4]; - // We know that the 4 vertices of c are positively oriented. - // So, in order to test if p is seen outside from one of c's facets, - // we just replace the corresponding point by p in the orientation - // test. We do this using the array below. - for (int k=0; k<4; k++) { - if (k != i) { - e_pts[k] = get_anchor_point(c->vertex(k)->info(), exact_traits); - } else { - e_pts[k] = converter_ek(p0); - } + // We know that the 4 vertices of c are positively oriented. + // So, in order to test if p is seen outside from one of c's facets, + // we just replace the corresponding point by p in the orientation + // test. We do this using the array below. + for (int k=0; k<4; k++) { + if (k != i) { + e_pts[k] = get_anchor_point(c->vertex(k)->info(), exact_traits); + } else { + e_pts[k] = converter_ek(p0); } - o = orientation(e_pts[0], e_pts[1], e_pts[2], e_pts[3]); } + o = orientation(e_pts[0], e_pts[1], e_pts[2], e_pts[3]); } if ( o != NEGATIVE ) { diff --git a/Skin_surface_3/include/CGAL/make_union_of_balls_3.h b/Skin_surface_3/include/CGAL/make_union_of_balls_3.h index 6f0e242e2c1..e40ecd76707 100644 --- a/Skin_surface_3/include/CGAL/make_union_of_balls_3.h +++ b/Skin_surface_3/include/CGAL/make_union_of_balls_3.h @@ -20,8 +20,6 @@ #include #include -#include - namespace CGAL { template diff --git a/Skin_surface_3/include/CGAL/triangulate_mixed_complex_3.h b/Skin_surface_3/include/CGAL/triangulate_mixed_complex_3.h index 0a6451424fc..92bfb84c326 100644 --- a/Skin_surface_3/include/CGAL/triangulate_mixed_complex_3.h +++ b/Skin_surface_3/include/CGAL/triangulate_mixed_complex_3.h @@ -1197,39 +1197,39 @@ Mixed_complex_triangulator_3:: orientation(Tmc_Cell_handle ch) { - Orientation o; - // Protection is outside the try block as VC8 has the CGAL_CFG_FPU_ROUNDING_MODE_UNWINDING_VC_BUG - Protect_FPU_rounding P; - try { - Tmc_Point pts[4]; - for (int i=0; i<4; i++) - pts[i] = ch->vertex(i)->point(); + { + // Protection is outside the try block as VC8 has the CGAL_CFG_FPU_ROUNDING_MODE_UNWINDING_VC_BUG + Protect_FPU_rounding P; + try { + Tmc_Point pts[4]; + for (int i=0; i<4; i++) + pts[i] = ch->vertex(i)->point(); - // filtered kernel - o = _tmc.geom_traits().orientation_3_object()(pts[0], pts[1], pts[2], pts[3]); - } catch (Uncertain_conversion_exception&) { - Protect_FPU_rounding P(CGAL_FE_TONEAREST); - typedef Exact_predicates_exact_constructions_kernel EK; - typedef Cartesian_converter Exact_converter; - typedef Skin_surface_traits_3 Exact_traits; - typedef Skin_surface_base_3 Exact_skin_surface; - - Exact_converter converter; - Exact_traits exact_traits(shrink); - typename Exact_skin_surface::Bare_point e_pts[4]; - - for (int k=0; k<4; k++) { - e_pts[k] = - Triangulated_mixed_complex_observer::Skin_surface:: - get_anchor_point(ch->vertex(k)->info(), exact_traits); - - // Store the more precise point - ch->vertex(k)->point() = converter(e_pts[k]); - } - o = exact_traits.orientation_3_object()(e_pts[0], e_pts[1], - e_pts[2], e_pts[3]); + // filtered kernel + return _tmc.geom_traits().orientation_3_object()(pts[0], pts[1], pts[2], pts[3]); + } catch (Uncertain_conversion_exception&) {} } - return o; + Protect_FPU_rounding P(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); + typedef Exact_predicates_exact_constructions_kernel EK; + typedef Cartesian_converter Exact_converter; + typedef Skin_surface_traits_3 Exact_traits; + typedef Skin_surface_base_3 Exact_skin_surface; + + Exact_converter converter; + Exact_traits exact_traits(shrink); + typename Exact_skin_surface::Bare_point e_pts[4]; + + for (int k=0; k<4; k++) { + e_pts[k] = + Triangulated_mixed_complex_observer::Skin_surface:: + get_anchor_point(ch->vertex(k)->info(), exact_traits); + + // Store the more precise point + ch->vertex(k)->point() = converter(e_pts[k]); + } + return exact_traits.orientation_3_object()(e_pts[0], e_pts[1], + e_pts[2], e_pts[3]); } template ` -\cgalHasModel `Simple_cartesian` +\cgalHasModel All models of the concept `Kernel` */ diff --git a/Spatial_sorting/include/CGAL/Hilbert_sort_middle_2.h b/Spatial_sorting/include/CGAL/Hilbert_sort_middle_2.h index 766e4fac4c6..32cf03cc435 100644 --- a/Spatial_sorting/include/CGAL/Hilbert_sort_middle_2.h +++ b/Spatial_sorting/include/CGAL/Hilbert_sort_middle_2.h @@ -16,7 +16,7 @@ #include #include #include -#include +#include namespace CGAL { diff --git a/Spatial_sorting/include/CGAL/hilbert_sort.h b/Spatial_sorting/include/CGAL/hilbert_sort.h index 97973dd4058..fc6d7bddb8b 100644 --- a/Spatial_sorting/include/CGAL/hilbert_sort.h +++ b/Spatial_sorting/include/CGAL/hilbert_sort.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include diff --git a/Spatial_sorting/package_info/Spatial_sorting/dependencies b/Spatial_sorting/package_info/Spatial_sorting/dependencies index ca434381fc1..7fb348192a7 100644 --- a/Spatial_sorting/package_info/Spatial_sorting/dependencies +++ b/Spatial_sorting/package_info/Spatial_sorting/dependencies @@ -2,7 +2,6 @@ Algebraic_foundations Installation Kernel_23 Number_types -Polygon Profiling_tools Property_map STL_Extension diff --git a/Straight_skeleton_2/include/CGAL/Straight_skeleton_2/Straight_skeleton_builder_traits_2_aux.h b/Straight_skeleton_2/include/CGAL/Straight_skeleton_2/Straight_skeleton_builder_traits_2_aux.h index 4b11a217440..6939ad21b72 100644 --- a/Straight_skeleton_2/include/CGAL/Straight_skeleton_2/Straight_skeleton_builder_traits_2_aux.h +++ b/Straight_skeleton_2/include/CGAL/Straight_skeleton_2/Straight_skeleton_builder_traits_2_aux.h @@ -136,20 +136,23 @@ public: result_type operator()(A&& ... a) const { - try { Protect_FPU_rounding P; - FC_result_type fr = Filter_construction(To_Filtered(std::forward(a))...); + try + { + FC_result_type fr = Filter_construction(To_Filtered(std::forward(a))...); - const double precision = - Lazy_exact_nt::get_relative_precision_of_to_double(); + const double precision = + Lazy_exact_nt::get_relative_precision_of_to_double(); - if ( fr && has_enough_precision(*fr, precision) ) - return From_Filtered(fr); + if ( fr && has_enough_precision(*fr, precision) ) + return From_Filtered(fr); + } + catch (Uncertain_conversion_exception&) {} } - catch (Uncertain_conversion_exception&) {} Protect_FPU_rounding P(CGAL_FE_TONEAREST); + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_TONEAREST); EC_result_type er = Exact_construction(To_Exact(std::forward(a))...) ; return From_Exact(er); } diff --git a/Stream_support/doc/Stream_support/IOstream.txt b/Stream_support/doc/Stream_support/IOstream.txt index 085fe65127d..cb098fc45e7 100644 --- a/Stream_support/doc/Stream_support/IOstream.txt +++ b/Stream_support/doc/Stream_support/IOstream.txt @@ -176,7 +176,8 @@ int main() \subsubsection IOstreamUsingOutputFormatting Using Output Formatting -To ensure that non-\cgal types are formatted correctly (i.e., respecting `IO::Mode`), `oformat()` can be used. +To ensure that non-\cgal types are formatted correctly (i.e., respecting \link PkgStreamSupportEnumRef `IO::Mode` \endlink), +`oformat()` can be used. For types with a `Output_rep` specialization, the respective output routine of `Output_rep` will be called by `oformat()`. Otherwise, the stream output operator will be called. @@ -197,7 +198,8 @@ refer to the documentation of the respective type. In some situations, you want to control the output formatting for a type `T`. For external types (third party libraries etc.), there might be problems if their stream output operator does not -respect `IO::Mode`. The purpose of `Output_rep` is to provide a way to +respect \link PkgStreamSupportEnumRef `IO::Mode` \endlink. +The purpose of `Output_rep` is to provide a way to control output formatting that works independently of the object's stream output operator. diff --git a/Stream_support/doc/Stream_support/PackageDescription.txt b/Stream_support/doc/Stream_support/PackageDescription.txt index 9efed4d7e45..9d993ee4779 100644 --- a/Stream_support/doc/Stream_support/PackageDescription.txt +++ b/Stream_support/doc/Stream_support/PackageDescription.txt @@ -58,7 +58,7 @@ All classes in the \cgal kernel provide input and output operators for I/O streams. \cgal provides three different printing mode, defined in the enum -`IO::Mode`, as well as different functions to set and get +\link PkgStreamSupportEnumRef `IO::Mode` \endlink, as well as different functions to set and get the printing mode. \cgalClassifedRefPages diff --git a/Stream_support/include/CGAL/IO/PLY.h b/Stream_support/include/CGAL/IO/PLY.h index 86745f0e6a6..dc11c16e873 100644 --- a/Stream_support/include/CGAL/IO/PLY.h +++ b/Stream_support/include/CGAL/IO/PLY.h @@ -276,7 +276,7 @@ bool read_PLY(std::istream& is, * * \attention The polygon soup is not cleared, and the data from the stream are appended. * - * \attention When reading a binary file, the flag `std::ios::binary` flag must be set during the creation of the `ifstream`. + * \attention To read a binary file, the flag `std::ios::binary` must be set during the creation of the `ifstream`. * * \tparam PointRange a model of the concepts `RandomAccessContainer` and `BackInsertionSequence` * whose value type is the point type @@ -426,7 +426,9 @@ bool read_PLY(const std::string& fname, PointRange& points, PolygonRange& polygo * * \brief writes the content of `points` and `polygons` in `out`, using the \ref IOStreamPLY. * - * \attention When writing a binary file, the flag `std::ios::binary` flag must be set during the creation of the `ofstream`. + * \attention To write to a binary file, the flag `std::ios::binary` must be set during the creation + * of the `ofstream`, and the \link PkgStreamSupportEnumRef `IO::Mode` \endlink + * of the stream must be set to `BINARY`. * * \tparam PointRange a model of the concept `RandomAccessContainer` whose value type is the point type * \tparam PolygonRange a model of the concept `SequenceContainer` diff --git a/Stream_support/include/CGAL/IO/STL.h b/Stream_support/include/CGAL/IO/STL.h index 88a3c3d7933..797376e8285 100644 --- a/Stream_support/include/CGAL/IO/STL.h +++ b/Stream_support/include/CGAL/IO/STL.h @@ -49,7 +49,7 @@ namespace IO { * * \attention The polygon soup is not cleared, and the data from the stream are appended. * - * \attention When reading a binary file, the flag `std::ios::binary` flag must be set during the creation of the `ifstream`. + * \attention To read a binary file, the flag `std::ios::binary` must be set during the creation of the `ifstream`. * * \tparam PointRange a model of the concepts `RandomAccessContainer` and `BackInsertionSequence` * whose value type is the point type @@ -89,7 +89,7 @@ bool read_STL(std::istream& is, if(!is.good()) { if(verbose) - std::cerr<<"File doesn't exist."< diff --git a/Stream_support/include/CGAL/IO/trace.h b/Stream_support/include/CGAL/IO/trace.h index 6a3f9f7096e..42ef6317665 100644 --- a/Stream_support/include/CGAL/IO/trace.h +++ b/Stream_support/include/CGAL/IO/trace.h @@ -11,32 +11,13 @@ #ifndef CGAL_IO_TRACE_H #define CGAL_IO_TRACE_H -#include -#include #include -#include /// \cond SKIP_IN_MANUAL // Trace utilities // --------------- -// print_stderr() = printf-like function to print to stderr -inline void CGAL_print_stderr(const char *fmt, ...) -{ - va_list argp; - va_start(argp, fmt); - vfprintf(stderr, fmt, argp); - va_end(argp); -} - -// CGAL_TRACE() = printf-like function to print to stderr -// if DEBUG_TRACE is defined (ignored otherwise) -#ifdef DEBUG_TRACE -#define CGAL_TRACE CGAL_print_stderr -#else - #define CGAL_TRACE if (false) CGAL_print_stderr -#endif // CGAL_TRACE_STREAM = C++ stream that prints to std::cerr // if DEBUG_TRACE is defined (ignored otherwise) diff --git a/Surface_mesh/include/CGAL/Surface_mesh/IO/PLY.h b/Surface_mesh/include/CGAL/Surface_mesh/IO/PLY.h index 26fc352c391..d0edd60afcc 100644 --- a/Surface_mesh/include/CGAL/Surface_mesh/IO/PLY.h +++ b/Surface_mesh/include/CGAL/Surface_mesh/IO/PLY.h @@ -21,8 +21,6 @@ #include #include -#if !defined(CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE) && !defined(CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES) - #include #ifdef DOXYGEN_RUNNING @@ -717,7 +715,7 @@ void fill_header(std::ostream& os, const Surface_mesh& sm, /// \ingroup PkgSurfaceMeshIOFuncPLY /// -/// \attention When reading a binary file, the flag `std::ios::binary` flag must be set during the creation of the `ifstream`. +/// \attention To read a binary file, the flag `std::ios::binary` flag must be set during the creation of the `ifstream`. /// /// \brief extracts the surface mesh from an input stream in the \ref IOStreamPLY /// and appends it to the surface mesh `sm`. @@ -890,7 +888,9 @@ namespace IO { /// simple types are inserted in the stream. The halfedges follow /// the same behavior. /// -/// \attention When writing a binary file, the flag `std::ios::binary` flag must be set during the creation of the `ofstream`. +/// \attention To write to a binary file, the flag `std::ios::binary` must be set during the creation +/// of the `ofstream`, and the \link PkgStreamSupportEnumRef `IO::Mode` \endlink +/// of the stream must be set to `BINARY`. /// /// \tparam Point The type of the \em point property of a vertex. There is no requirement on `P`, /// besides being default constructible and assignable. @@ -1158,6 +1158,4 @@ CGAL_DEPRECATED bool write_ply(std::ostream& os, const Surface_mesh

& sm) } // namespace CGAL -#endif // !defined(CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE) && !defined(CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES) - #endif // CGAL_SURFACE_MESH_IO_PLY_H diff --git a/Surface_mesh_deformation/include/CGAL/Surface_mesh_deformation.h b/Surface_mesh_deformation/include/CGAL/Surface_mesh_deformation.h index 06a8151e9b7..95956028eb4 100644 --- a/Surface_mesh_deformation/include/CGAL/Surface_mesh_deformation.h +++ b/Surface_mesh_deformation/include/CGAL/Surface_mesh_deformation.h @@ -21,8 +21,8 @@ #include #include #include -#include #include +#include #include #include @@ -54,12 +54,15 @@ enum Deformation_algorithm_tag /// @cond CGAL_DOCUMENT_INTERNAL namespace internal { + template struct Types_selectors; template struct Types_selectors { - typedef internal::Single_cotangent_weight_impl Weight_calculator; + + // Get weight from the weight interface. + typedef CGAL::Weights::Single_cotangent_weight Weight_calculator; struct ARAP_visitor{ template @@ -80,7 +83,9 @@ struct Types_selectors { template struct Types_selectors { - typedef internal::Cotangent_weight_impl Weight_calculator; + + // Get weight from the weight interface. + typedef CGAL::Weights::Cotangent_weight Weight_calculator; typedef typename Types_selectors ::ARAP_visitor ARAP_visitor; @@ -88,7 +93,9 @@ struct Types_selectors { template struct Types_selectors { - typedef internal::Cotangent_weight_impl Weight_calculator; + + // Get weight from the weight interface. + typedef CGAL::Weights::Cotangent_weight Weight_calculator; class ARAP_visitor{ double m_nb_edges_incident; diff --git a/Surface_mesh_deformation/package_info/Surface_mesh_deformation/dependencies b/Surface_mesh_deformation/package_info/Surface_mesh_deformation/dependencies index 974b4a8f5f5..e4abdd72dbd 100644 --- a/Surface_mesh_deformation/package_info/Surface_mesh_deformation/dependencies +++ b/Surface_mesh_deformation/package_info/Surface_mesh_deformation/dependencies @@ -11,7 +11,6 @@ Interval_support Kernel_23 Modular_arithmetic Number_types -Polygon_mesh_processing Profiling_tools Property_map Random_numbers @@ -19,3 +18,4 @@ STL_Extension Solver_interface Stream_support Surface_mesh_deformation +Weights diff --git a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/ARAP_parameterizer_3.h b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/ARAP_parameterizer_3.h index 3fb7edade43..33fef26c674 100644 --- a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/ARAP_parameterizer_3.h +++ b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/ARAP_parameterizer_3.h @@ -26,8 +26,8 @@ #include #include #include - #include +#include #include @@ -449,7 +449,7 @@ private: const Point_3& position_vj = get(ppmap, vj); const Point_3& position_vk = get(ppmap, vk); - NT cot = internal::cotangent(position_vi, position_vj, position_vk); + const NT cot = CGAL::Weights::cotangent(position_vi, position_vj, position_vk); put(ctmap, hd, cot); } @@ -489,13 +489,13 @@ private: // coefficient corresponding to the angle at vk if vk is the vertex before vj // while circulating around vi - NT c_k = get(ctmap, opposite(hd, mesh)); + const NT c_k = get(ctmap, opposite(hd, mesh)); // coefficient corresponding to the angle at vl if vl is the vertex after vj // while circulating around vi - NT c_l = get(ctmap, hd); + const NT c_l = get(ctmap, hd); - NT weight = c_k + c_l; + const NT weight = c_k + c_l; return weight; } diff --git a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Barycentric_mapping_parameterizer_3.h b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Barycentric_mapping_parameterizer_3.h index c53c4c56d20..f311cb9396a 100644 --- a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Barycentric_mapping_parameterizer_3.h +++ b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Barycentric_mapping_parameterizer_3.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -180,7 +181,7 @@ protected: Vertex_around_target_circulator /* neighbor_vertex_v_j */ ) const { /// In the Tutte Barycentric Mapping algorithm, we have `w_ij = 1`, for `j` neighbor vertex of `i`. - return 1.; + return NT(1); } }; diff --git a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Discrete_authalic_parameterizer_3.h b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Discrete_authalic_parameterizer_3.h index 61ca95aab95..aeb891cff92 100644 --- a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Discrete_authalic_parameterizer_3.h +++ b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Discrete_authalic_parameterizer_3.h @@ -16,11 +16,10 @@ #include -#include #include #include - #include +#include #include @@ -177,34 +176,18 @@ protected: Vertex_around_target_circulator neighbor_vertex_v_j) const { const PPM ppmap = get(vertex_point, mesh); - const Point_3& position_v_i = get(ppmap, main_vertex_v_i); const Point_3& position_v_j = get(ppmap, *neighbor_vertex_v_j); - // Compute the square norm of v_j -> v_i vector - Vector_3 edge = position_v_i - position_v_j; - double square_len = edge*edge; - - // Compute cotangent of (v_k,v_j,v_i) corner (i.e. cotan of v_j corner) - // if v_k is the vertex before v_j when circulating around v_i vertex_around_target_circulator previous_vertex_v_k = neighbor_vertex_v_j; - previous_vertex_v_k--; + --previous_vertex_v_k; const Point_3& position_v_k = get(ppmap, *previous_vertex_v_k); - NT cotg_psi_ij = internal::cotangent(position_v_k, position_v_j, position_v_i); - // Compute cotangent of (v_i,v_j,v_l) corner (i.e. cotan of v_j corner) - // if v_l is the vertex after v_j when circulating around v_i vertex_around_target_circulator next_vertex_v_l = neighbor_vertex_v_j; - next_vertex_v_l++; - const Point_3& position_v_l = get(ppmap,*next_vertex_v_l); - NT cotg_theta_ij = internal::cotangent(position_v_i, position_v_j, position_v_l); + ++next_vertex_v_l; + const Point_3& position_v_l = get(ppmap, *next_vertex_v_l); - NT weight = 0.0; - CGAL_assertion(square_len != 0.0); // two points are identical! - if(square_len != 0.0) - weight = (cotg_psi_ij + cotg_theta_ij) / square_len; - - return weight; + return CGAL::Weights::authalic_weight(position_v_k, position_v_j, position_v_l, position_v_i) / NT(2); } }; diff --git a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Discrete_conformal_map_parameterizer_3.h b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Discrete_conformal_map_parameterizer_3.h index 62bf4f29b3c..3d09fad861c 100644 --- a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Discrete_conformal_map_parameterizer_3.h +++ b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Discrete_conformal_map_parameterizer_3.h @@ -16,11 +16,10 @@ #include -#include #include #include - #include +#include #if defined(CGAL_EIGEN3_ENABLED) #include @@ -173,26 +172,18 @@ protected: Vertex_around_target_circulator neighbor_vertex_v_j) const // its target is main_vertex_v_i { const PPM ppmap = get(vertex_point, mesh); - const Point_3& position_v_i = get(ppmap, main_vertex_v_i); const Point_3& position_v_j = get(ppmap, *neighbor_vertex_v_j); - // Compute cotangent of (v_i,v_k,v_j) corner (i.e. cotan of v_k corner) - // if v_k is the vertex before v_j when circulating around v_i vertex_around_target_circulator previous_vertex_v_k = neighbor_vertex_v_j; - previous_vertex_v_k--; + --previous_vertex_v_k; const Point_3& position_v_k = get(ppmap, *previous_vertex_v_k); - NT cotg_beta_ij = internal::cotangent(position_v_i, position_v_k, position_v_j); - // Compute cotangent of (v_j,v_l,v_i) corner (i.e. cotan of v_l corner) - // if v_l is the vertex after v_j when circulating around v_i vertex_around_target_circulator next_vertex_v_l = neighbor_vertex_v_j; - next_vertex_v_l++; + ++next_vertex_v_l; const Point_3& position_v_l = get(ppmap, *next_vertex_v_l); - NT cotg_alpha_ij = internal::cotangent(position_v_j, position_v_l, position_v_i); - NT weight = cotg_beta_ij + cotg_alpha_ij; - return weight; + return CGAL::Weights::cotangent_weight(position_v_k, position_v_j, position_v_l, position_v_i) / NT(2); } }; diff --git a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Fixed_border_parameterizer_3.h b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Fixed_border_parameterizer_3.h index c3b9d8de956..4222d5f2244 100644 --- a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Fixed_border_parameterizer_3.h +++ b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Fixed_border_parameterizer_3.h @@ -16,10 +16,8 @@ #include -#include #include #include - #include #include diff --git a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Iterative_authalic_parameterizer_3.h b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Iterative_authalic_parameterizer_3.h index 38093049023..2e475b11db8 100644 --- a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Iterative_authalic_parameterizer_3.h +++ b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Iterative_authalic_parameterizer_3.h @@ -21,7 +21,6 @@ #include -#include #include #include #include @@ -34,7 +33,9 @@ #include #include #include -#include +// #include +#include +#include #include #if defined(CGAL_EIGEN3_ENABLED) @@ -629,7 +630,7 @@ private: /// computes `w_ij`, coefficient of matrix `A` for `j` neighbor vertex of `i`. /// - /// \param mesh a triangulated surface. + /// \param tmesh a triangulated surface. /// \param main_vertex_v_i the vertex of `mesh` with index `i` /// \param neighbor_vertex_v_j the vertex of `mesh` with index `j` NT compute_w_ij(const Triangle_mesh& tmesh, @@ -637,36 +638,28 @@ private: Vertex_around_target_circulator neighbor_vertex_v_j) const { const PPM ppmap = get(vertex_point, tmesh); - const PPM_ref position_v_i = get(ppmap, main_vertex_v_i); const PPM_ref position_v_j = get(ppmap, *neighbor_vertex_v_j); - // Compute the square norm of v_j -> v_i vector - Vector_3 edge = position_v_i - position_v_j; - NT square_len = edge*edge; + const Vector_3 edge = position_v_i - position_v_j; + const NT squared_length = edge * edge; - // Compute cotangent of (v_k,v_j,v_i) corner (i.e. cotan of v_j corner) - // if v_k is the vertex before v_j when circulating around v_i vertex_around_target_circulator previous_vertex_v_k = neighbor_vertex_v_j; --previous_vertex_v_k; const PPM_ref position_v_k = get(ppmap, *previous_vertex_v_k); -// NT cotg_psi_ij = internal::cotangent(position_v_k, position_v_j, position_v_i); - NT cotg_beta_ij = internal::cotangent(position_v_i, position_v_k, position_v_j); - // Compute cotangent of (v_i,v_j,v_l) corner (i.e. cotan of v_j corner) - // if v_l is the vertex after v_j when circulating around v_i vertex_around_target_circulator next_vertex_v_l = neighbor_vertex_v_j; ++next_vertex_v_l; + const PPM_ref position_v_l = get(ppmap, *next_vertex_v_l); - const Point_3 position_v_l = get(ppmap, *next_vertex_v_l); -// NT cotg_theta_ij = internal::cotangent(position_v_i, position_v_j, position_v_l); - NT cotg_alpha_ij = internal::cotangent(position_v_j, position_v_l, position_v_i); - - NT weight = 0; - CGAL_assertion(square_len > NT(0)); // two points are identical! - if(square_len != NT(0)) - weight = cotg_beta_ij + cotg_alpha_ij; - + NT weight = NT(0); + CGAL_assertion(squared_length > NT(0)); // two points are identical! + if(squared_length != NT(0)) { + // This version was commented out to be an alternative weight + // in the original code by authors. + // weight = CGAL::Weights::authalic_weight(position_v_k, position_v_j, position_v_l, position_v_i) / NT(2); + weight = CGAL::Weights::cotangent_weight(position_v_k, position_v_j, position_v_l, position_v_i) / NT(2); + } return weight; } @@ -730,7 +723,7 @@ private: VertexIndexMap& vimap) const { auto vpm = get_const_property_map(CGAL::vertex_point, tmesh); - CGAL::internal::Mean_value_weight compute_mvc(tmesh, vpm); + const CGAL::Weights::Edge_tangent_weight compute_mvc(tmesh, vpm); const int i = get(vimap, v); diff --git a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/MVC_post_processor_3.h b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/MVC_post_processor_3.h index 7803a1980a4..a8053c2a9bd 100644 --- a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/MVC_post_processor_3.h +++ b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/MVC_post_processor_3.h @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -354,22 +355,6 @@ private: return OK; } - // -> -> - // Return angle (in radians) of of (P,Q,R) corner (i.e. QP,QR angle). - double compute_angle_rad(const Point_2& P, - const Point_2& Q, - const Point_2& R) const - { - Vector_2 u = P - Q; - Vector_2 v = R - Q; - - double angle = std::atan2(v.y(), v.x()) - std::atan2(u.y(), u.x()); - if(angle < 0) - angle += 2 * CGAL_PI; - - return angle; - } - // Fix vertices that are on the convex hull. template @@ -385,23 +370,6 @@ private: } while (++vc != vend); } - NT compute_w_ij_mvc(const Point_2& pi, const Point_2& pj, const Point_2& pk) const - { - // -> -> - // Compute the angle (pj, pi, pk), the angle between the vectors ij and ik - NT angle = compute_angle_rad(pj, pi, pk); - - // For flipped triangles, the connectivity is inversed and thus the angle - // computed by the previous function is not the one we need. Instead, - // we need the explementary angle. - if(angle > CGAL_PI) { // flipped triangle - angle = 2 * CGAL_PI - angle; - } - NT weight = std::tan(0.5 * angle); - - return weight; - } - void fill_linear_system_matrix_mvc_from_points(const Point_2& pi, int i, const Point_2& pj, int j, const Point_2& pk, int k, @@ -418,27 +386,25 @@ private: // The other parts of A(i,j) and A(i,k) will be added when this function // is called from the neighboring faces of F_ijk that share the vertex i - // Compute: - tan(alpha / 2) - NT w_i_base = -1.0 * compute_w_ij_mvc(pi, pj, pk); - // @fixme unefficient: lengths are computed (and inversed!) twice per edge + // Set w_i_base: - tan(alpha / 2) + // Match order of the input points to the new weight implementation. + const Point_2& p = pk; + const Point_2& q = pi; + const Point_2& r = pj; + const CGAL::Weights::Tangent_weight tangent_weight(p, q, r); + // Set w_ij in matrix - Vector_2 edge_ij = pi - pj; - double len_ij = std::sqrt(edge_ij * edge_ij); - CGAL_assertion(len_ij != 0.0); // two points are identical! - NT w_ij = w_i_base / len_ij; + const NT w_ij = tangent_weight.get_w_r(); A.add_coef(i, j, w_ij); // Set w_ik in matrix - Vector_2 edge_ik = pi - pk; - double len_ik = std::sqrt(edge_ik * edge_ik); - CGAL_assertion(len_ik != 0.0); // two points are identical! - NT w_ik = w_i_base / len_ik; + const NT w_ik = tangent_weight.get_w_p(); A.add_coef(i, k, w_ik); // Add to w_ii (w_ii = - sum w_ij) - NT w_ii = - w_ij - w_ik; + const NT w_ii = - w_ij - w_ik; A.add_coef(i, i, w_ii); } diff --git a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Mean_value_coordinates_parameterizer_3.h b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Mean_value_coordinates_parameterizer_3.h index 796504c93f2..95593adf95e 100644 --- a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Mean_value_coordinates_parameterizer_3.h +++ b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/Mean_value_coordinates_parameterizer_3.h @@ -17,9 +17,9 @@ #include #include - #include #include +#include #ifdef CGAL_EIGEN3_ENABLED #include @@ -195,35 +195,18 @@ protected: Vertex_around_target_circulator neighbor_vertex_v_j) const { const PPM ppmap = get(vertex_point, mesh); - const Point_3& position_v_i = get(ppmap, main_vertex_v_i); const Point_3& position_v_j = get(ppmap, *neighbor_vertex_v_j); - // Compute the norm of v_j -> v_i vector - Vector_3 edge = position_v_i - position_v_j; - NT len = std::sqrt(edge * edge); - - // Compute angle of (v_j,v_i,v_k) corner (i.e. angle of v_i corner) - // if v_k is the vertex before v_j when circulating around v_i vertex_around_target_circulator previous_vertex_v_k = neighbor_vertex_v_j; - previous_vertex_v_k--; + --previous_vertex_v_k; const Point_3& position_v_k = get(ppmap, *previous_vertex_v_k); - NT gamma_ij = internal::compute_angle_rad(position_v_j, position_v_i, position_v_k); - // Compute angle of (v_l,v_i,v_j) corner (i.e. angle of v_i corner) - // if v_l is the vertex after v_j when circulating around v_i vertex_around_target_circulator next_vertex_v_l = neighbor_vertex_v_j; - next_vertex_v_l++; + ++next_vertex_v_l; const Point_3& position_v_l = get(ppmap, *next_vertex_v_l); - NT delta_ij = internal::compute_angle_rad(position_v_l, position_v_i, position_v_j); - NT weight = 0.0; - CGAL_assertion(len != 0.0); // two points are identical! - if(len != 0.0) - weight = (std::tan(0.5*gamma_ij) + std::tan(0.5*delta_ij)) / len; - CGAL_assertion(weight > 0); - - return weight; + return CGAL::Weights::tangent_weight(position_v_k, position_v_j, position_v_l, position_v_i) / NT(2); } }; 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 5d5cc9e6a54..3f8337d0660 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 @@ -16,17 +16,15 @@ #include -#include #include #include #include - #include #include #include - +#include +#include #include -#include #include #include @@ -702,17 +700,6 @@ private: CGAL_postcondition(current_line_id_in_M - initial_line_id == number_of_linear_constraints(mesh)); } - // MVC computations - NT compute_w_ij_mvc(const Point_3& pi, const Point_3& pj, const Point_3& pk) const - { - // -> -> - // Compute the angle (pj, pi, pk), the angle between the vectors ij and ik - const NT angle = internal::compute_angle_rad(pj, pi, pk); - const NT weight = std::tan(0.5 * angle); - - return weight; - } - // Computes the coefficients of the mean value Laplacian matrix for the edge. // `ij` in the face `ijk` void fill_mvc_matrix(const Point_3& pi, int i, @@ -730,29 +717,27 @@ private: // The other parts of M(i,j) and M(i,k) will be added when this function // is called from the neighboring faces of F_ijk that share the vertex i - // Compute: - tan(alpha / 2) - const NT w_i_base = 1.0 * compute_w_ij_mvc(pi, pj, pk); - // @fixme unefficient: lengths are computed (and inversed!) twice per edge + // Set w_i_base: - tan(alpha / 2) + const Point_3& p = pk; + const Point_3& q = pi; + const Point_3& r = pj; + const CGAL::Weights::Tangent_weight tangent_weight(p, q, r); + // Set w_ij in matrix - const Vector_3 edge_ij = pi - pj; - const NT len_ij = CGAL::sqrt(edge_ij * edge_ij); - CGAL_assertion(len_ij != 0.0); // two points are identical! - const NT w_ij = w_i_base / len_ij; + const NT w_ij = tangent_weight.get_w_r(); M.add_coef(2*i, 2*j, w_ij); - M.add_coef(2*i +1, 2*j + 1, w_ij); + M.add_coef(2*i + 1, 2*j + 1, w_ij); // Set w_ik in matrix - Vector_3 edge_ik = pi - pk; - const NT len_ik = CGAL::sqrt(edge_ik * edge_ik); - CGAL_assertion(len_ik != 0.0); // two points are identical! - const NT w_ik = w_i_base / len_ik; + const NT w_ik = tangent_weight.get_w_p(); M.add_coef(2*i, 2*k, w_ik); M.add_coef(2*i + 1, 2*k + 1, w_ik); // Add to w_ii (w_ii = - sum w_ij) const NT w_ii = - w_ij - w_ik; + M.add_coef(2*i, 2*i, w_ii); M.add_coef(2*i + 1, 2*i + 1, w_ii); } @@ -790,35 +775,25 @@ private: VertexIndexMap vimap, Matrix& M) const { - const PPM ppmap = get(vertex_point, mesh); + const PPM pmap = get(vertex_point, mesh); + for (const halfedge_descriptor hd : halfedges(mesh)) { - // not exactly sure which cotan weights should be used: - // 0.5 (cot a + cot b) ? 1/T1 cot a + 1/T2 cot b ? 1/Vor(i) (cot a + cot b?) - // Comparing to the matlab code, the basic Cotangent_weight gives the same results. - typedef CGAL::internal::Cotangent_weight Cotan_weights; -// typedef CGAL::internal::Cotangent_weight_with_triangle_area Cotan_weights; - - Cotan_weights cotan_weight_calculator(mesh, ppmap); - - for(halfedge_descriptor hd : halfedges(mesh)) { const vertex_descriptor vi = source(hd, mesh); const vertex_descriptor vj = target(hd, mesh); const int i = get(vimap, vi); const int j = get(vimap, vj); - if(i > j) - continue; - - // times 2 because Cotangent_weight returns 1/2 (cot alpha + cot beta)... - const NT w_ij = 2 * cotan_weight_calculator(hd); + if (i > j) continue; + const CGAL::Weights::Cotangent_weight cotangent_weight; + const NT w_ij = NT(2) * cotangent_weight(hd, mesh, pmap); // ij M.set_coef(2*i, 2*j, w_ij, true /* new coef */); - M.set_coef(2*i +1, 2*j + 1, w_ij, true /* new coef */); + M.set_coef(2*i + 1, 2*j + 1, w_ij, true /* new coef */); // ji M.set_coef(2*j, 2*i, w_ij, true /* new coef */); - M.set_coef(2*j +1, 2*i + 1, w_ij, true /* new coef */); + M.set_coef(2*j + 1, 2*i + 1, w_ij, true /* new coef */); // ii M.add_coef(2*i, 2*i, - w_ij); diff --git a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/internal/angles.h b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/internal/angles.h deleted file mode 100644 index abd987d33f9..00000000000 --- a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/internal/angles.h +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (c) 2016 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) : Mael Rouxel-Labbé - -#ifndef CGAL_SURFACE_MESH_PARAMETERIZATION_ANGLES_H -#define CGAL_SURFACE_MESH_PARAMETERIZATION_ANGLES_H - -#include - -#include -#include - -#include - -namespace CGAL { - -namespace Surface_mesh_parameterization { - -namespace internal { - -// -> -> -// Returns the cotangent of the corner (P,Q,R) (i.e. the cotan of the angle (QP, QR) ). -template -typename K::FT cotangent(const typename K::Point_3& P, - const typename K::Point_3& Q, - const typename K::Point_3& R) -{ - typedef typename K::FT NT; - typedef typename K::Vector_3 Vector_3; - - Vector_3 u = P - Q; - Vector_3 v = R - Q; - NT dot = (u * v); - Vector_3 cross_vector = CGAL::cross_product(u, v); - NT cross_norm = CGAL::sqrt(cross_vector * cross_vector); - if(cross_norm != NT(0)) - return (dot / cross_norm); - else - return 0; // undefined -} - -// -> -> -// Returns the tangent of the corner (P,Q,R) (i.e. the tangent of angle (QP, QR) ). -template -typename K::FT tangent(const typename K::Point_3& P, - const typename K::Point_3& Q, - const typename K::Point_3& R) -{ - typedef typename K::FT NT; - typedef typename K::Vector_3 Vector_3; - - Vector_3 u = P - Q; - Vector_3 v = R - Q; - NT dot = (u * v); - Vector_3 cross_vector = CGAL::cross_product(u, v); - NT cross_norm = CGAL::sqrt(cross_vector * cross_vector); - if(dot != NT(0)) - return (cross_norm / dot); - else - return 0; // undefined -} - -// Fixes the sine to be within [-1;1]. -template -typename K::FT fix_sine(typename K::FT sine) -{ - if(sine >= 1) - return 1; - else if(sine <= -1) - return -1; - else - return sine; -} - -// -> -> -// Returns the angle (in radians) of the corner (P,Q,R) (i.e. the angle (QP, QR) ). -template -typename K::FT compute_angle_rad(const typename K::Point_3& P, - const typename K::Point_3& Q, - const typename K::Point_3& R) -{ - typedef typename K::FT NT; - typedef typename K::Vector_3 Vector_3; - - Vector_3 u = P - Q; - Vector_3 v = R - Q; - - NT product = CGAL::sqrt(u * u) * CGAL::sqrt(v * v); - if(product == NT(0)) - return 0; - - // cosine - NT dot = (u * v); - NT cosine = dot / product; - - // sine - Vector_3 w = CGAL::cross_product(u, v); - NT abs_sine = CGAL::sqrt(w * w) / product; - - if(cosine >= NT(0)) - return std::asin(fix_sine(abs_sine)); - else - return CGAL_PI - std::asin(fix_sine(abs_sine)); -} - -} // namespace internal - -} // namespace Surface_mesh_parameterization - -} // namespace CGAL - -#endif // CGAL_SURFACE_MESH_PARAMETERIZATION_ANGLES_H diff --git a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/orbifold_shortest_path.h b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/orbifold_shortest_path.h index 4243374f9d3..4b1e4ab2cc0 100644 --- a/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/orbifold_shortest_path.h +++ b/Surface_mesh_parameterization/include/CGAL/Surface_mesh_parameterization/orbifold_shortest_path.h @@ -190,8 +190,8 @@ void compute_shortest_paths_between_cones(const TriangleMesh& mesh, compute_shortest_paths_between_two_cones(mesh, *first, *next, std::back_inserter(seams)); } - std::ofstream out("shortest_path.selection.txt"); #ifdef CGAL_SMP_ORBIFOLD_DEBUG + std::ofstream out("shortest_path.selection.txt"); internal::output_shortest_paths_to_selection_file(mesh, seams, out); #endif } diff --git a/Surface_mesh_parameterization/package_info/Surface_mesh_parameterization/dependencies b/Surface_mesh_parameterization/package_info/Surface_mesh_parameterization/dependencies index d66c39f593f..0d5931b478b 100644 --- a/Surface_mesh_parameterization/package_info/Surface_mesh_parameterization/dependencies +++ b/Surface_mesh_parameterization/package_info/Surface_mesh_parameterization/dependencies @@ -15,7 +15,6 @@ Kernel_23 Modular_arithmetic Number_types OpenNL -Polygon Polygon_mesh_processing Profiling_tools Property_map @@ -27,3 +26,4 @@ Stream_support Surface_mesh_parameterization TDS_2 Triangulation_2 +Weights diff --git a/Surface_mesh_segmentation/include/CGAL/Surface_mesh_segmentation/internal/graph.h b/Surface_mesh_segmentation/include/CGAL/Surface_mesh_segmentation/internal/auxiliary/graph.h similarity index 99% rename from Surface_mesh_segmentation/include/CGAL/Surface_mesh_segmentation/internal/graph.h rename to Surface_mesh_segmentation/include/CGAL/Surface_mesh_segmentation/internal/auxiliary/graph.h index 5698e0c59a0..e13471ce036 100644 --- a/Surface_mesh_segmentation/include/CGAL/Surface_mesh_segmentation/internal/graph.h +++ b/Surface_mesh_segmentation/include/CGAL/Surface_mesh_segmentation/internal/auxiliary/graph.h @@ -109,7 +109,7 @@ a minimum cut on the following graph: /////////////////////////////////////////////////// -#include +#include #include "graph.h" void main() @@ -125,16 +125,16 @@ void main() Graph::flowtype flow = g -> maxflow(); - printf("Flow = %d\n", flow); + std::cout << "Flow = " << flow << std::endl; printf("Minimum cut:\n"); if (g->what_segment(nodes[0]) == Graph::SOURCE) - printf("node0 is in the SOURCE set\n"); + std::cout << "node0 is in the SOURCE set\n"; else - printf("node0 is in the SINK set\n"); + std::cout << "node0 is in the SINK set\n"; if (g->what_segment(nodes[1]) == Graph::SOURCE) - printf("node1 is in the SOURCE set\n"); + std::cout << "node1 is in the SOURCE set\n"; else - printf("node1 is in the SINK set\n"); + std::cout << "node1 is in the SINK set\n"; delete g; } diff --git a/Surface_mesh_segmentation/include/CGAL/boost/graph/Alpha_expansion_MaxFlow_tag.h b/Surface_mesh_segmentation/include/CGAL/boost/graph/Alpha_expansion_MaxFlow_tag.h index beab78dfce9..3b311b70191 100644 --- a/Surface_mesh_segmentation/include/CGAL/boost/graph/Alpha_expansion_MaxFlow_tag.h +++ b/Surface_mesh_segmentation/include/CGAL/boost/graph/Alpha_expansion_MaxFlow_tag.h @@ -20,7 +20,7 @@ namespace MaxFlow { -#include +#include } 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 ca29638a015..7c641c5eb69 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 @@ -306,12 +306,12 @@ public : virtual void OnCollected(const Profile& aProfile, const boost::optional& aCost) const { - TEST_TRACE(str (format("Collecting %1% : cost=%2%") % edge2str(aProfile.v0_v1()) % optfloat2str(aCost))); + TEST_TRACE(str (boost::format("Collecting %1% : cost=%2%") % edge2str(aProfile.v0_v1()) % optfloat2str(aCost))); } virtual void OnCollapsing(const Profile& aProfile, const boost::optional& aP) const { - TEST_TRACE(str (format("S %1% - Collapsing %2% : placement=%3%") % mStep % edge2str(aProfile.v0_v1()) % optpoint2str(aP))); + TEST_TRACE(str (boost::format("S %1% - Collapsing %2% : placement=%3%") % mStep % edge2str(aProfile.v0_v1()) % optpoint2str(aP))); //mBefore = create_edge_link(aProfile); } @@ -323,10 +323,10 @@ public : { SurfaceSP lAfter = create_vertex_link(aProfile, aV); - write(mBefore, str(format("%1%.step-%2%-before.off") % mTestCase % mStep)); - write(lAfter , str(format("%1%.step-%2%-after.off") % mTestCase % mStep)); + write(mBefore, str(boost::format("%1%.step-%2%-before.off") % mTestCase % mStep)); + write(lAfter , str(boost::format("%1%.step-%2%-after.off") % mTestCase % mStep)); - REPORT_ERROR(str(format("Resulting surface self-intersects after step %1% (%2% edges left)") % mStep % (aProfile.surface().size_of_halfedges() / 2))); + REPORT_ERROR(str(boost::format("Resulting surface self-intersects after step %1% (%2% edges left)") % mStep % (aProfile.surface().size_of_halfedges() / 2))); } ++mStep; 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 81bacc0d8a8..3882180786a 100644 --- a/Surface_mesh_skeletonization/include/CGAL/Mean_curvature_flow_skeletonization.h +++ b/Surface_mesh_skeletonization/include/CGAL/Mean_curvature_flow_skeletonization.h @@ -35,7 +35,7 @@ #include // Compute cotangent Laplacian -#include +#include // Compute the vertex normal #include @@ -222,12 +222,8 @@ public: typedef typename boost::graph_traits::edge_descriptor edge_descriptor; typedef typename boost::graph_traits::edge_iterator edge_iterator; - // Cotangent weight calculator - typedef internal::Cotangent_weight::type, - internal::Cotangent_value_minimum_zero::type, - internal::Cotangent_value_Meyer_secure > > Weight_calculator; + // Get weight from the weight interface. + typedef CGAL::Weights::Cotangent_weight Weight_calculator; typedef internal::Curve_skeleton:: No_intersection_surface_sweep_2(Visitor* visitor) : m_traits(new Traits_adaptor_2()), m_traitsOwner(true), + m_currentEvent(nullptr), m_statusLineCurveLess(m_traits, &m_currentEvent), m_queueEventLess(m_traits), m_queue(new Event_queue(m_queueEventLess)), @@ -54,6 +55,7 @@ No_intersection_surface_sweep_2:: No_intersection_surface_sweep_2(const Gt2* traits, Visitor* visitor) : m_traits(static_cast(traits)), m_traitsOwner(false), + m_currentEvent(nullptr), m_statusLineCurveLess(m_traits, &m_currentEvent), m_queueEventLess(m_traits), m_queue(new Event_queue(m_queueEventLess)), diff --git a/TDS_3/include/CGAL/TDS_3/internal/Triangulation_ds_iterators_3.h b/TDS_3/include/CGAL/TDS_3/internal/Triangulation_ds_iterators_3.h index d0bcd4a0a86..885172184d0 100644 --- a/TDS_3/include/CGAL/TDS_3/internal/Triangulation_ds_iterators_3.h +++ b/TDS_3/include/CGAL/TDS_3/internal/Triangulation_ds_iterators_3.h @@ -40,6 +40,7 @@ public: typedef typename Tds::Cell_iterator Cell_iterator; Triangulation_ds_facet_iterator_3() + : _tds(nullptr) {} Triangulation_ds_facet_iterator_3(const Tds * tds) diff --git a/Testsuite/include/CGAL/Testsuite/vc_debug_hook.h b/Testsuite/include/CGAL/Testsuite/vc_debug_hook.h index 7bb642de70c..cb4d1dce665 100644 --- a/Testsuite/include/CGAL/Testsuite/vc_debug_hook.h +++ b/Testsuite/include/CGAL/Testsuite/vc_debug_hook.h @@ -19,6 +19,7 @@ #include #include #include +#include namespace @@ -27,7 +28,7 @@ namespace { if ( type == _CRT_ASSERT ) { - std::fprintf(stderr,msg); + std::cerr << msg << std::endl; *retval = 0 ; std::exit(255); } @@ -38,11 +39,11 @@ namespace { switch(n) { - case SIGSEGV: std::fprintf(stderr,"In CGAL_handle_signal, Program received signal SIGSEGV: Segmentation Fault."); break ; - case SIGFPE : std::fprintf(stderr,"In CGAL_handle_signal, Program received signal SIGFPE: Floating Point Execption."); break ; - case SIGILL : std::fprintf(stderr,"In CGAL_handle_signal, Program received signal SIGILL: Illegal Instruction."); break ; + case SIGSEGV: std::cerr << "In CGAL_handle_signal, Program received signal SIGSEGV: Segmentation Fault." << std::endl; break ; + case SIGFPE : std::cerr << "In CGAL_handle_signal, Program received signal SIGFPE: Floating Point Execption." << std::endl; break ; + case SIGILL : std::cerr << "In CGAL_handle_signal, Program received signal SIGILL: Illegal Instruction." << std::endl; break ; default: - std::fprintf(stderr,"In CGAL_handle_signal, Program received signal %d", n); break ; + std::cerr << "In CGAL_handle_signal, Program received signal " << n << std::endl; break ; } std::exit(128+n); diff --git a/Tetrahedral_remeshing/package_info/Tetrahedral_remeshing/dependencies b/Tetrahedral_remeshing/package_info/Tetrahedral_remeshing/dependencies index 2311653695c..57bd26ce97b 100644 --- a/Tetrahedral_remeshing/package_info/Tetrahedral_remeshing/dependencies +++ b/Tetrahedral_remeshing/package_info/Tetrahedral_remeshing/dependencies @@ -17,7 +17,6 @@ Kernel_d Mesh_3 Modular_arithmetic Number_types -Polygon Polygon_mesh_processing Profiling_tools Property_map diff --git a/Three/include/CGAL/Three/Edge_container.h b/Three/include/CGAL/Three/Edge_container.h index a32b2f6dee5..1db3c7ebaef 100644 --- a/Three/include/CGAL/Three/Edge_container.h +++ b/Three/include/CGAL/Three/Edge_container.h @@ -48,6 +48,7 @@ struct DEMO_FRAMEWORK_EXPORT Edge_container :public Primitive_container Radius, //!< Designates the buffer that contains the radius of wire spheres. Centers, //!< Designates the buffer that contains the center of c3t3 facets or the center of wire spheres, for example. Texture_map, //!< Designates the buffer that contains the UV map for the texture. + Subdomain_indices, //!< Designates the buffer that contains the subdomains of both cells defining a c3t3 facet. NbOfVbos //!< Designates the size of the VBOs vector for `Edge_container`s }; diff --git a/Three/include/CGAL/Three/Triangle_container.h b/Three/include/CGAL/Three/Triangle_container.h index cb16f3fe4cd..bf8d4224e62 100644 --- a/Three/include/CGAL/Three/Triangle_container.h +++ b/Three/include/CGAL/Three/Triangle_container.h @@ -50,6 +50,7 @@ struct DEMO_FRAMEWORK_EXPORT Triangle_container :public Primitive_container FColors, //!< Designates the buffer that contains the colors of the flat vertices. Texture_map, //!< Designates the buffer that contains the UV map for the texture. Distances, + Subdomain_indices, //!< Designates the buffer that contains the subdomains of both cells defining a c3t3 facet. NbOfVbos //!< Designates the size of the VBOs vector for `Triangle_container`s }; diff --git a/Three/include/CGAL/Three/Viewer_interface.h b/Three/include/CGAL/Three/Viewer_interface.h index 75bab97e145..a66f4afbf4b 100644 --- a/Three/include/CGAL/Three/Viewer_interface.h +++ b/Three/include/CGAL/Three/Viewer_interface.h @@ -71,6 +71,7 @@ public: PROGRAM_SOLID_WIREFRAME, //! Used to render edges with width superior to 1. PROGRAM_NO_INTERPOLATION, //! Used to render faces without interpolating their color. PROGRAM_HEAT_INTENSITY, //! Used to render special item in Display_property_plugin + PROGRAM_TETRA_FILTERING, //! Used in Scene_tetrahedra_item with Tetrahedra_filtering_plugin NB_OF_PROGRAMS //! Holds the number of different programs in this enum. }; diff --git a/Triangulation/package_info/Triangulation/dependencies b/Triangulation/package_info/Triangulation/dependencies index f26faea33f6..c7893bd09b0 100644 --- a/Triangulation/package_info/Triangulation/dependencies +++ b/Triangulation/package_info/Triangulation/dependencies @@ -5,7 +5,6 @@ Interval_support Kernel_23 Modular_arithmetic Number_types -Polygon Profiling_tools Random_numbers STL_Extension diff --git a/Triangulation_2/include/CGAL/Triangulation_2.h b/Triangulation_2/include/CGAL/Triangulation_2.h index c4a9db15ce0..75ebfb45a09 100644 --- a/Triangulation_2/include/CGAL/Triangulation_2.h +++ b/Triangulation_2/include/CGAL/Triangulation_2.h @@ -51,7 +51,7 @@ #endif #ifndef CGAL_NO_STRUCTURAL_FILTERING -#include +#include #include #include #endif // no CGAL_NO_STRUCTURAL_FILTERING diff --git a/Triangulation_3/demo/Triangulation_3/PreferenceDlg.cpp b/Triangulation_3/demo/Triangulation_3/PreferenceDlg.cpp index c922abd6fd4..122c291d048 100644 --- a/Triangulation_3/demo/Triangulation_3/PreferenceDlg.cpp +++ b/Triangulation_3/demo/Triangulation_3/PreferenceDlg.cpp @@ -12,7 +12,7 @@ PreferenceDlg::PreferenceDlg(QWidget *parent) : QDialog(parent) QPushButton *btnVertex = new QPushButton( tr("Set Color") ); // create color label m_labelVertex = new QLabel; - m_labelVertex->setFrameStyle(QFrame::Sunken | QFrame::Panel); + m_labelVertex->setFrameStyle(static_cast(QFrame::Sunken) | static_cast(QFrame::Panel)); // create size label QLabel *labelSizeV = new QLabel( tr("Set Size") ); // create lineedit @@ -38,7 +38,7 @@ PreferenceDlg::PreferenceDlg(QWidget *parent) : QDialog(parent) QPushButton *btnDEdge = new QPushButton( tr("Set Color") ); // create color label m_labelDEdge = new QLabel; - m_labelDEdge->setFrameStyle(QFrame::Sunken | QFrame::Panel); + m_labelDEdge->setFrameStyle(static_cast(QFrame::Sunken) | static_cast(QFrame::Panel)); // create size label QLabel *labelSizeDE = new QLabel( tr("Set Size") ); // create lineedit @@ -64,7 +64,7 @@ PreferenceDlg::PreferenceDlg(QWidget *parent) : QDialog(parent) QPushButton *btnVEdge = new QPushButton( tr("Set Color") ); // create color label m_labelVEdge = new QLabel; - m_labelVEdge->setFrameStyle(QFrame::Sunken | QFrame::Panel); + m_labelVEdge->setFrameStyle(static_cast(QFrame::Sunken) | static_cast(QFrame::Panel)); // create size label QLabel *labelSizeVE = new QLabel( tr("Set Size") ); // create lineedit @@ -90,7 +90,7 @@ PreferenceDlg::PreferenceDlg(QWidget *parent) : QDialog(parent) QPushButton *btnFacet = new QPushButton( tr("Set Color") ); // create color label m_labelFacet = new QLabel; - m_labelFacet->setFrameStyle(QFrame::Sunken | QFrame::Panel); + m_labelFacet->setFrameStyle(static_cast(QFrame::Sunken) | static_cast(QFrame::Panel)); // create label and spinbox QLabel *labelFacetA = new QLabel( tr("Transparency") ); m_spinAlphaF = new QSpinBox; @@ -116,7 +116,7 @@ PreferenceDlg::PreferenceDlg(QWidget *parent) : QDialog(parent) QPushButton *btnBall = new QPushButton( tr("Set Color") ); // create color label m_labelBall = new QLabel; - m_labelBall->setFrameStyle(QFrame::Sunken | QFrame::Panel); + m_labelBall->setFrameStyle(static_cast(QFrame::Sunken) | static_cast(QFrame::Panel)); // create label and spinbox QLabel *labelBallA = new QLabel( tr("Transparency") ); m_spinAlphaB = new QSpinBox; @@ -147,7 +147,7 @@ PreferenceDlg::PreferenceDlg(QWidget *parent) : QDialog(parent) QGroupBox *groupS = new QGroupBox( tr("Empty Sphere") ); // create color label m_labelSphere = new QLabel; - m_labelSphere->setFrameStyle(QFrame::Sunken | QFrame::Panel); + m_labelSphere->setFrameStyle(static_cast(QFrame::Sunken) | static_cast(QFrame::Panel)); // create button QPushButton *btnSphere = new QPushButton( tr("Set Color") ); // create label and spinbox diff --git a/Triangulation_3/demo/Triangulation_3/Viewer.cpp b/Triangulation_3/demo/Triangulation_3/Viewer.cpp index 90af7a440db..62937f5a5bc 100644 --- a/Triangulation_3/demo/Triangulation_3/Viewer.cpp +++ b/Triangulation_3/demo/Triangulation_3/Viewer.cpp @@ -69,12 +69,12 @@ void Viewer::init() glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); /* Add mouse and key description */ - setKeyDescription( Qt::CTRL + Qt::Key_G, tr("Generate points") ); - setKeyDescription( Qt::CTRL + Qt::Key_O, tr("Load points") ); - setKeyDescription( Qt::CTRL + Qt::Key_S, tr("Save points") ); - setKeyDescription( Qt::CTRL + Qt::Key_Comma, tr("Preference") ); - setKeyDescription( Qt::CTRL + Qt::Key_H, tr("Hide Kernel Demo") ); - setKeyDescription( Qt::CTRL + Qt::Key_Q, tr("Quit Kernel Demo") ); + setKeyDescription( Qt::CTRL, Qt::Key_G, tr("Generate points") ); + setKeyDescription( Qt::CTRL, Qt::Key_O, tr("Load points") ); + setKeyDescription( Qt::CTRL, Qt::Key_S, tr("Save points") ); + setKeyDescription( Qt::CTRL, Qt::Key_Comma, tr("Preference") ); + setKeyDescription( Qt::CTRL, Qt::Key_H, tr("Hide Kernel Demo") ); + setKeyDescription( Qt::CTRL, Qt::Key_Q, tr("Quit Kernel Demo") ); setKeyDescription( Qt::Key_Return, tr("Insert new point to triangulation in Input-Point mode") ); setKeyDescription( Qt::Key_Escape, diff --git a/Triangulation_3/include/CGAL/Triangulation_3.h b/Triangulation_3/include/CGAL/Triangulation_3.h index 4ff224448c5..07518932ccc 100644 --- a/Triangulation_3/include/CGAL/Triangulation_3.h +++ b/Triangulation_3/include/CGAL/Triangulation_3.h @@ -68,7 +68,7 @@ #endif #ifndef CGAL_NO_STRUCTURAL_FILTERING -#include +#include #include #include #endif // no CGAL_NO_STRUCTURAL_FILTERING @@ -446,7 +446,8 @@ private: const Self *t; public: - Infinite_tester() {} + Infinite_tester() + : t(nullptr) {} Infinite_tester(const Self *tr) : t(tr) {} @@ -574,7 +575,7 @@ protected: public: template // Point or Point_3 - typename boost::result_of::type + typename boost::result_of::type construct_point(const P& p) const { return geom_traits().construct_point_3_object()(p); diff --git a/Triangulation_3/package_info/Triangulation_3/dependencies b/Triangulation_3/package_info/Triangulation_3/dependencies index 53da26a4122..a68982ddaa5 100644 --- a/Triangulation_3/package_info/Triangulation_3/dependencies +++ b/Triangulation_3/package_info/Triangulation_3/dependencies @@ -17,7 +17,6 @@ Kernel_23 Kernel_d Modular_arithmetic Number_types -Polygon Profiling_tools Property_map Random_numbers diff --git a/Triangulation_on_sphere_2/package_info/Triangulation_on_sphere_2/dependencies b/Triangulation_on_sphere_2/package_info/Triangulation_on_sphere_2/dependencies index d0187657dfe..5b77a741e4d 100644 --- a/Triangulation_on_sphere_2/package_info/Triangulation_on_sphere_2/dependencies +++ b/Triangulation_on_sphere_2/package_info/Triangulation_on_sphere_2/dependencies @@ -16,7 +16,6 @@ Interval_support Kernel_23 Modular_arithmetic Number_types -Polygon Profiling_tools Property_map STL_Extension diff --git a/Visibility_2/package_info/Visibility_2/dependencies b/Visibility_2/package_info/Visibility_2/dependencies index bdaf92f883b..7acbd250303 100644 --- a/Visibility_2/package_info/Visibility_2/dependencies +++ b/Visibility_2/package_info/Visibility_2/dependencies @@ -13,7 +13,6 @@ Interval_support Kernel_23 Modular_arithmetic Number_types -Polygon Principal_component_analysis_LGPL Profiling_tools Property_map diff --git a/Voronoi_diagram_2/include/CGAL/Voronoi_diagram_2/Handle_adaptor.h b/Voronoi_diagram_2/include/CGAL/Voronoi_diagram_2/Handle_adaptor.h index 91b5be76f09..8ed30759595 100644 --- a/Voronoi_diagram_2/include/CGAL/Voronoi_diagram_2/Handle_adaptor.h +++ b/Voronoi_diagram_2/include/CGAL/Voronoi_diagram_2/Handle_adaptor.h @@ -33,6 +33,8 @@ class Handle_adaptor typedef T& reference; typedef const T* const_pointer; typedef const T& const_reference; + typedef void iterator_category; + typedef std::ptrdiff_t difference_type; public: Handle_adaptor() : t() {} diff --git a/Weights/doc/Weights/PackageDescription.txt b/Weights/doc/Weights/PackageDescription.txt index 1fc97c0ee1f..f6e5cfaf1e1 100644 --- a/Weights/doc/Weights/PackageDescription.txt +++ b/Weights/doc/Weights/PackageDescription.txt @@ -510,7 +510,7 @@ a model of `AnalyticWeightTraits_3` for 3D points \cgalPkgDescriptionBegin{Weight Interface, PkgWeightsRef} -\cgalPkgPicture{logo_120x120.png} +\cgalPkgPicture{weights_logo_120x120.png} \cgalPkgSummaryBegin \cgalPkgAuthors{Dmitry Anisimov} diff --git a/Weights/doc/Weights/fig/logo.svg b/Weights/doc/Weights/fig/weights_logo.svg similarity index 100% rename from Weights/doc/Weights/fig/logo.svg rename to Weights/doc/Weights/fig/weights_logo.svg diff --git a/Weights/doc/Weights/fig/logo_120x120.png b/Weights/doc/Weights/fig/weights_logo_120x120.png similarity index 100% rename from Weights/doc/Weights/fig/logo_120x120.png rename to Weights/doc/Weights/fig/weights_logo_120x120.png diff --git a/Weights/include/CGAL/Weights/internal/utils.h b/Weights/include/CGAL/Weights/internal/utils.h index 0786d605ff7..cfefee02d4b 100644 --- a/Weights/include/CGAL/Weights/internal/utils.h +++ b/Weights/include/CGAL/Weights/internal/utils.h @@ -187,7 +187,7 @@ namespace internal { const FT cross = cross_product_2(v1, v2); const FT length = CGAL::abs(cross); - CGAL_assertion(length != FT(0)); + // CGAL_assertion(length != FT(0)); not really necessary if (length != FT(0)) { return dot / length; } else { @@ -218,7 +218,7 @@ namespace internal { const FT cross = cross_product_2(v1, v2); const FT length = CGAL::abs(cross); - CGAL_assertion(dot != FT(0)); + // CGAL_assertion(dot != FT(0)); not really necessary if (dot != FT(0)) { return length / dot; } else { @@ -293,7 +293,11 @@ namespace internal { const auto cross = cross_product_3(v1, v2); const FT length = length_3(traits, cross); - CGAL_assertion(length != FT(0)); + // TODO: + // Not really necessary: since we handle case length = 0. Does this case happen? + // Yes, e.g. in Surface Parameterization tests. Does it affect the results? + // In current applications, not really. + // CGAL_assertion(length != FT(0)); if (length != FT(0)) { return dot / length; } else { @@ -324,7 +328,7 @@ namespace internal { const auto cross = cross_product_3(v1, v2); const FT length = length_3(traits, cross); - CGAL_assertion(dot != FT(0)); + // CGAL_assertion(dot != FT(0)); not really necessary if (dot != FT(0)) { return length / dot; } else { diff --git a/Weights/include/CGAL/Weights/mean_value_weights.h b/Weights/include/CGAL/Weights/mean_value_weights.h index d66d9bf3487..2fc9117247d 100644 --- a/Weights/include/CGAL/Weights/mean_value_weights.h +++ b/Weights/include/CGAL/Weights/mean_value_weights.h @@ -188,99 +188,6 @@ namespace Weights { } // namespace internal - // Undocumented mean value weight class. - // Its constructor takes a polygon mesh and a vertex to point map - // and its operator() is defined based on the halfedge_descriptor only. - // This version is currently used in: - // Surface_mesh_parameterizer -> Iterative_authalic_parameterizer_3.h - template< - typename PolygonMesh, - typename VertexPointMap = typename boost::property_map::type> - class Mean_value_weight { - - using GeomTraits = typename CGAL::Kernel_traits< - typename boost::property_traits::value_type>::type; - using FT = typename GeomTraits::FT; - - const PolygonMesh& m_pmesh; - const VertexPointMap m_pmap; - const GeomTraits m_traits; - - public: - using vertex_descriptor = typename boost::graph_traits::vertex_descriptor; - using halfedge_descriptor = typename boost::graph_traits::halfedge_descriptor; - - Mean_value_weight(const PolygonMesh& pmesh, const VertexPointMap pmap) : - m_pmesh(pmesh), m_pmap(pmap), m_traits() { } - - // Returns the mean-value coordinate of the specified halfedge_descriptor. - // Returns different values for different edge orientations (which is normal - // behavior according to the formula). - FT operator()(const halfedge_descriptor he) const { - - const vertex_descriptor v0 = target(he, m_pmesh); - const vertex_descriptor v1 = source(he, m_pmesh); - const auto& p0 = get(m_pmap, v0); - const auto& p1 = get(m_pmap, v1); - const FT norm = internal::distance_3(m_traits, p0, p1); - - // Only one triangle for border edges. - if (is_border_edge(he, m_pmesh)) { - const halfedge_descriptor he_cw = opposite(next(he, m_pmesh), m_pmesh); - vertex_descriptor v2 = source(he_cw, m_pmesh); - if (is_border_edge(he_cw, m_pmesh)) { - const halfedge_descriptor he_ccw = prev(opposite(he, m_pmesh), m_pmesh); - v2 = source(he_ccw, m_pmesh); - } - return half_tan_value_2(v1, v0, v2) / norm; - } else { - const halfedge_descriptor he_cw = opposite(next(he, m_pmesh), m_pmesh); - const vertex_descriptor v2 = source(he_cw, m_pmesh); - const halfedge_descriptor he_ccw = prev(opposite(he, m_pmesh), m_pmesh); - const vertex_descriptor v3 = source(he_ccw, m_pmesh); - return ( - half_tan_value_2(v1, v0, v2) / norm + - half_tan_value_2(v1, v0, v3) / norm ); - } - } - - private: - // The authors deviation built on Meyer_02. - FT half_tan_value_2( - const vertex_descriptor v0, - const vertex_descriptor v1, - const vertex_descriptor v2) const { - - using Get_sqrt = internal::Get_sqrt; - const auto sqrt = Get_sqrt::sqrt_object(m_traits); - - const auto squared_length_3 = - m_traits.compute_squared_length_3_object(); - const auto construct_vector_3 = - m_traits.construct_vector_3_object(); - - const auto& p0 = get(m_pmap, v0); - const auto& p1 = get(m_pmap, v1); - const auto& p2 = get(m_pmap, v2); - - const auto a = construct_vector_3(p1, p0); - const auto b = construct_vector_3(p1, p2); - - const FT dot_ab = a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; - const FT dot_aa = squared_length_3(a); - const FT dot_bb = squared_length_3(b); - const FT dot_aa_bb = dot_aa * dot_bb; - - const FT cos_rep = dot_ab; - const FT sin_rep = sqrt(dot_aa_bb - dot_ab * dot_ab); - const FT normalizer = sqrt(dot_aa_bb); // |a| * |b| - - // The formula from [Floater04] page 4: - // tan(Q / 2) = (1 - cos(Q)) / sin(Q). - return (normalizer - cos_rep) / sin_rep; - } - }; - /// \endcond /*! diff --git a/Weights/include/CGAL/Weights/tangent_weights.h b/Weights/include/CGAL/Weights/tangent_weights.h index a7e93109a02..47a7539ae8a 100644 --- a/Weights/include/CGAL/Weights/tangent_weights.h +++ b/Weights/include/CGAL/Weights/tangent_weights.h @@ -372,6 +372,67 @@ namespace Weights { return tangent_weight(t, r, p, q, traits); } + // Undocumented tangent weight class. + // Its constructor takes a polygon mesh and a vertex to point map + // and its operator() is defined based on the halfedge_descriptor only. + // This version is currently used in: + // Surface_mesh_parameterizer -> Iterative_authalic_parameterizer_3.h + template< + typename PolygonMesh, + typename VertexPointMap = typename boost::property_map::type> + class Edge_tangent_weight { + + using GeomTraits = typename CGAL::Kernel_traits< + typename boost::property_traits::value_type>::type; + using FT = typename GeomTraits::FT; + + const PolygonMesh& m_pmesh; + const VertexPointMap m_pmap; + const GeomTraits m_traits; + + public: + using vertex_descriptor = typename boost::graph_traits::vertex_descriptor; + using halfedge_descriptor = typename boost::graph_traits::halfedge_descriptor; + + Edge_tangent_weight(const PolygonMesh& pmesh, const VertexPointMap pmap) : + m_pmesh(pmesh), m_pmap(pmap), m_traits() { } + + FT operator()(const halfedge_descriptor he) const { + + FT weight = FT(0); + if (is_border_edge(he, m_pmesh)) { + const auto h1 = next(he, m_pmesh); + + const auto v0 = target(he, m_pmesh); + const auto v1 = source(he, m_pmesh); + const auto v2 = target(h1, m_pmesh); + + const auto& p0 = get(m_pmap, v0); + const auto& p1 = get(m_pmap, v1); + const auto& p2 = get(m_pmap, v2); + + weight = internal::tangent_3(m_traits, p0, p2, p1); + + } else { + const auto h1 = next(he, m_pmesh); + const auto h2 = prev(opposite(he, m_pmesh), m_pmesh); + + const auto v0 = target(he, m_pmesh); + const auto v1 = source(he, m_pmesh); + const auto v2 = target(h1, m_pmesh); + const auto v3 = source(h2, m_pmesh); + + const auto& p0 = get(m_pmap, v0); + const auto& p1 = get(m_pmap, v1); + const auto& p2 = get(m_pmap, v2); + const auto& p3 = get(m_pmap, v3); + + weight = tangent_weight(p2, p1, p3, p0) / FT(2); + } + return weight; + } + }; + // Undocumented tangent weight class. // Its constructor takes three points either in 2D or 3D. // This version is currently used in: diff --git a/Weights/include/CGAL/Weights/utils.h b/Weights/include/CGAL/Weights/utils.h index 919b2fc2bf2..4f68b34e1ef 100644 --- a/Weights/include/CGAL/Weights/utils.h +++ b/Weights/include/CGAL/Weights/utils.h @@ -18,7 +18,6 @@ // Internal includes. #include -#include namespace CGAL { namespace Weights {