diff --git a/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h b/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h index 05cdeb2ac54..ab8a8122bd7 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h +++ b/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h @@ -3031,6 +3031,18 @@ namespace CartesianKernelFunctors { return construct_vector(vx, vy, vz); } + + Vector_3 + operator()( Origin, const Point_3& q, const Point_3& r ) const + { + // Cross product oq * or + FT vx = q.y()*r.z() - r.y()*q.z(); + FT vy = q.z()*r.x() - r.z()*q.x(); + FT vz = q.x()*r.y() - r.x()*q.y(); + typename K::Construct_vector_3 construct_vector; + + return construct_vector(vx, vy, vz); + } }; template @@ -4307,6 +4319,15 @@ namespace CartesianKernelFunctors { w.x(), w.y(), w.z()); } + result_type + operator()( Origin, const Point_3& u, + const Point_3& v, const Point_3& w) const + { + return orientationC3(u.x(), u.y(), u.z(), + v.x(), v.y(), v.z(), + w.x(), w.y(), w.z()); + } + result_type operator()( const Tetrahedron_3& t) const { diff --git a/Filtered_kernel/include/CGAL/Epic_converter.h b/Filtered_kernel/include/CGAL/Epic_converter.h index 2db2ffa0ec2..b8dd072176d 100644 --- a/Filtered_kernel/include/CGAL/Epic_converter.h +++ b/Filtered_kernel/include/CGAL/Epic_converter.h @@ -49,7 +49,15 @@ class Epic_converter { typedef typename IK::FT IK_FT; public: + std::pair operator()(Origin o) const + { + return std::make_pair(o, true); + } + std::pair operator()(Null_vector n) const + { + return std::make_pair(n, true); + } std::pair operator()(const typename IK::FT n) const { diff --git a/Filtered_kernel/include/CGAL/Lazy.h b/Filtered_kernel/include/CGAL/Lazy.h index 07ad822d7f5..c94b77e4274 100644 --- a/Filtered_kernel/include/CGAL/Lazy.h +++ b/Filtered_kernel/include/CGAL/Lazy.h @@ -799,7 +799,7 @@ struct Approx_converter template < typename T > decltype(auto) operator()(const T&t) const - { return t.approx(); } + { return approx(t); } const Null_vector& operator()(const Null_vector& n) const @@ -824,7 +824,7 @@ struct Exact_converter template < typename T > decltype(auto) operator()(const T&t) const - { return t.exact(); } + { return exact(t); } const Null_vector& operator()(const Null_vector& n) const diff --git a/Filtered_kernel/include/CGAL/Static_filtered_predicate.h b/Filtered_kernel/include/CGAL/Static_filtered_predicate.h index 03f9da943bd..9ff3aea5d1c 100644 --- a/Filtered_kernel/include/CGAL/Static_filtered_predicate.h +++ b/Filtered_kernel/include/CGAL/Static_filtered_predicate.h @@ -7,7 +7,6 @@ // $Id$ // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // -// // Author(s) : Andreas Fabri, Laurent Rineau #ifndef CGAL_STATIC_FILTERED_PREDICATE_H @@ -29,9 +28,7 @@ public: result_type operator()(const A1& a1) const { CGAL::Epic_converter convert; - typedef typename Kernel_traits::type EK; - typedef typename Type_mapper::type T1; - std::pair aa1 = convert(a1.approx()); + auto aa1 = convert(approx(a1)); if(! aa1.second){ return fp(a1); } @@ -39,83 +36,36 @@ public: return epicp(aa1.first); } - template - result_type operator()(const A1& a1, const Null_vector& v) const - { - CGAL::Epic_converter convert; - typedef typename Kernel_traits::type EK; - typedef typename Type_mapper::type T1; - std::pair aa1 = convert(a1.approx()); - if(! aa1.second){ - return fp(a1, v); - } - - return epicp(aa1.first, v); - } template result_type operator()(const A1& a1, const A2& a2) const { CGAL::Epic_converter convert; - typedef typename Kernel_traits::type EK; - typedef typename Type_mapper::type T1; - std::pair aa1 = convert(approx(a1)); + auto aa1 = convert(approx(a1)); if(! aa1.second){ return fp(a1, a2); } - typedef typename Type_mapper::type T2; - std::pair aa2 = convert(approx(a2)); + auto aa2 = convert(approx(a2)); if(! aa2.second){ return fp(a1, a2); } return epicp(aa1.first, aa2.first); } - // We need these two specializations as in general we determine - // the kernel for the template argument A1, and this does not work for Bbox_2 and Bbox_3 - template - result_type operator()(const Bbox_2& bb, const A2& a2) const - { - CGAL::Epic_converter convert; - typedef typename Kernel_traits::type EK; - typedef typename Type_mapper::type T2; - std::pair aa2 = convert(approx(a2)); - if(! aa2.second){ - return fp(bb, a2); - } - return epicp(bb, aa2.first); - } - - template - result_type operator()(const Bbox_3& bb, const A2& a2) const - { - CGAL::Epic_converter convert; - typedef typename Kernel_traits::type EK; - typedef typename Type_mapper::type T2; - std::pair aa2 = convert(approx(a2)); - if(! aa2.second){ - return fp(bb, a2); - } - return epicp(bb, aa2.first); - } template result_type operator()(const A1& a1, const A2& a2, const A3& a3) const { CGAL::Epic_converter convert; - typedef typename Kernel_traits::type EK; - typedef typename Type_mapper::type T1; - std::pair aa1 = convert(a1.approx()); + auto aa1 = convert(approx(a1)); if(! aa1.second){ return fp(a1, a2, a3); } - typedef typename Type_mapper::type T2; - std::pair aa2 = convert(a2.approx()); + auto aa2 = convert(approx(a2)); if(! aa2.second){ return fp(a1, a2, a3); } - typedef typename Type_mapper::type T3; - std::pair aa3 = convert(a3.approx()); + auto aa3 = convert(approx(a3)); if(! aa3.second){ return fp(a1, a2, a3); } @@ -127,24 +77,22 @@ public: result_type operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) const { CGAL::Epic_converter convert; - typedef typename Kernel_traits::type EK; - typedef typename Type_mapper::type T1; - std::pair aa1 = convert(a1.approx()); + auto aa1 = convert(approx(a1)); if(! aa1.second){ return fp(a1, a2, a3, a4); } - typedef typename Type_mapper::type T2; - std::pair aa2 = convert(a2.approx()); + + auto aa2 = convert(approx(a2)); if(! aa2.second){ return fp(a1, a2, a3, a4); } - typedef typename Type_mapper::type T3; - std::pair aa3 = convert(a3.approx()); + + auto aa3 = convert(approx(a3)); if(! aa3.second){ return fp(a1, a2, a3, a4); } - typedef typename Type_mapper::type T4; - std::pair aa4 = convert(a4.approx()); + + auto aa4 = convert(approx(a4)); if(! aa4.second){ return fp(a1, a2, a3, a4); } @@ -155,29 +103,23 @@ public: result_type operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5) const { CGAL::Epic_converter convert; - typedef typename Kernel_traits::type EK; - typedef typename Type_mapper::type T1; - std::pair aa1 = convert(a1.approx()); + auto aa1 = convert(approx(a1)); if(! aa1.second){ return fp(a1, a2, a3, a4, a5); } - typedef typename Type_mapper::type T2; - std::pair aa2 = convert(a2.approx()); + auto aa2 = convert(approx(a2)); if(! aa2.second){ return fp(a1, a2, a3, a4, a5); } - typedef typename Type_mapper::type T3; - std::pair aa3 = convert(a3.approx()); + auto aa3 = convert(approx(a3)); if(! aa3.second){ return fp(a1, a2, a3, a4, a5); } - typedef typename Type_mapper::type T4; - std::pair aa4 = convert(a4.approx()); + auto aa4 = convert(approx(a4)); if(! aa4.second){ return fp(a1, a2, a3, a4, a5); } - typedef typename Type_mapper::type T5; - std::pair aa5 = convert(a5.approx()); + auto aa5 = convert(approx(a5)); if(! aa5.second){ return fp(a1, a2, a3, a4, a5); } @@ -188,34 +130,27 @@ public: result_type operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6) const { CGAL::Epic_converter convert; - typedef typename Kernel_traits::type EK; - typedef typename Type_mapper::type T1; - std::pair aa1 = convert(a1.approx()); + auto aa1 = convert(approx(a1)); if(! aa1.second){ return fp(a1, a2, a3, a4, a5, a6); } - typedef typename Type_mapper::type T2; - std::pair aa2 = convert(a2.approx()); + auto aa2 = convert(approx(a2)); if(! aa2.second){ return fp(a1, a2, a3, a4, a5, a6); } - typedef typename Type_mapper::type T3; - std::pair aa3 = convert(a3.approx()); + auto aa3 = convert(approx(a3)); if(! aa3.second){ return fp(a1, a2, a3, a4, a5, a6); } - typedef typename Type_mapper::type T4; - std::pair aa4 = convert(a4.approx()); + auto aa4 = convert(approx(a4)); if(! aa4.second){ return fp(a1, a2, a3, a4, a5, a6); } - typedef typename Type_mapper::type T5; - std::pair aa5 = convert(a5.approx()); + auto aa5 = convert(approx(a5)); if(! aa5.second){ return fp(a1, a2, a3, a4, a5, a6); } - typedef typename Type_mapper::type T6; - std::pair aa6 = convert(a6.approx()); + auto aa6 = convert(approx(a6)); if(! aa6.second){ return fp(a1, a2, a3, a4, a5, a6); } @@ -226,39 +161,31 @@ public: result_type operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A6& a7) const { CGAL::Epic_converter convert; - typedef typename Kernel_traits::type EK; - typedef typename Type_mapper::type T1; - std::pair aa1 = convert(a1.approx()); + auto aa1 = convert(approx(a1)); if(! aa1.second){ return fp(a1, a2, a3, a4, a5, a6, a7); } - typedef typename Type_mapper::type T2; - std::pair aa2 = convert(a2.approx()); + auto aa2 = convert(approx(a2)); if(! aa2.second){ return fp(a1, a2, a3, a4, a5, a6, a7); } - typedef typename Type_mapper::type T3; - std::pair aa3 = convert(a3.approx()); + auto aa3 = convert(approx(a3)); if(! aa3.second){ return fp(a1, a2, a3, a4, a5, a6, a7); } - typedef typename Type_mapper::type T4; - std::pair aa4 = convert(a4.approx()); + auto aa4 = convert(approx(a4)); if(! aa4.second){ return fp(a1, a2, a3, a4, a5, a6, a7); } - typedef typename Type_mapper::type T5; - std::pair aa5 = convert(a5.approx()); + auto aa5 = convert(approx(a5)); if(! aa5.second){ return fp(a1, a2, a3, a4, a5, a6, a7); } - typedef typename Type_mapper::type T6; - std::pair aa6 = convert(a6.approx()); + auto aa6 = convert(approx(a6)); if(! aa6.second){ return fp(a1, a2, a3, a4, a5, a6, a7); } - typedef typename Type_mapper::type T7; - std::pair aa7 = convert(a7.approx()); + auto aa7 = convert(approx(a7)); if(! aa7.second){ return fp(a1, a2, a3, a4, a5, a6, a7); } @@ -270,44 +197,35 @@ public: result_type operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8) const { CGAL::Epic_converter convert; - typedef typename Kernel_traits::type EK; - typedef typename Type_mapper::type T1; - std::pair aa1 = convert(a1.approx()); + auto aa1 = convert(approx(a1)); if(! aa1.second){ return fp(a1, a2, a3, a4, a5, a6, a7, a8); } - typedef typename Type_mapper::type T2; - std::pair aa2 = convert(a2.approx()); + auto aa2 = convert(approx(a2)); if(! aa2.second){ return fp(a1, a2, a3, a4, a5, a6, a7, a8); } - typedef typename Type_mapper::type T3; - std::pair aa3 = convert(a3.approx()); + auto aa3 = convert(approx(a3)); if(! aa3.second){ return fp(a1, a2, a3, a4, a5, a6, a7, a8); } - typedef typename Type_mapper::type T4; - std::pair aa4 = convert(a4.approx()); + auto aa4 = convert(approx(a4)); if(! aa4.second){ return fp(a1, a2, a3, a4, a5, a6, a7, a8); } - typedef typename Type_mapper::type T5; - std::pair aa5 = convert(a5.approx()); + auto aa5 = convert(approx(a5)); if(! aa5.second){ return fp(a1, a2, a3, a4, a5, a6, a7, a8); } - typedef typename Type_mapper::type T6; - std::pair aa6 = convert(a6.approx()); + auto aa6 = convert(approx(a6)); if(! aa6.second){ return fp(a1, a2, a3, a5, a5, a6, a7, a8); } - typedef typename Type_mapper::type T7; - std::pair aa7 = convert(a7.approx()); + auto aa7 = convert(approx(a7)); if(! aa7.second){ return fp(a1, a2, a3, a5, a5, a6, a7, a8); } - typedef typename Type_mapper::type T8; - std::pair aa8 = convert(a8.approx()); + auto aa8 = convert(approx(a8)); if(! aa8.second){ return fp(a1, a2, a3, a4, a5, a6, a7, a8); } diff --git a/Kernel_23/test/Kernel_23/origin_3.cpp b/Kernel_23/test/Kernel_23/origin_3.cpp new file mode 100644 index 00000000000..c1a74c68f30 --- /dev/null +++ b/Kernel_23/test/Kernel_23/origin_3.cpp @@ -0,0 +1,108 @@ +//#define CGAL_PROFILE +#include +#include +#include +#include +typedef CGAL::Exact_predicates_exact_constructions_kernel K; +typedef K::Point_3 Point_3; +typedef K::Vector_3 Vector_3; +typedef CGAL::Timer Timer; + +int main(int argc, char* argv[] ) +{ + std::ifstream ifs((argc>1)? argv[1]:CGAL::data_file_path("points_3/cube.xyz")); + + std::vector points; + Point_3 p; + + while(ifs >> p){ + points.push_back(p); + } + + std::cout << "Orientation_3" << std::endl; + Timer t; + + const int N = points.size()-3; + + const K::Orientation_3 orientation = K().orientation_3_object(); + + int positive = 0; + + t.start(); + { + std::cout << "overload with 4 points" << std::endl; + for(int k = 0; k < 100; ++k) + for(int i = 0; i < N; ++i){ + Point_3 o(CGAL::ORIGIN); + if(orientation(o, points[i], points[i+1], points[i+2]) == CGAL::POSITIVE){ + ++positive; + } + } + } + t.stop(); + + std::cout << t.time() << " sec." << std::endl; + + t.reset(); + t.start(); + { + std::cout << "overload with origin and 3 points" << std::endl; + for (int k = 0; k < 100; ++k) + for(int i = 0; i < N; ++i){ + if(orientation(CGAL::ORIGIN, points[i], points[i+1], points[i+2]) == CGAL::POSITIVE){ + --positive; + } + } + } + t.stop(); + + + if(positive != 0){ + std::cout << "Not the same results for Orientation_3"<< std::endl; + assert(false); + } + std::cout << t.time() << " sec." << std::endl; + + + std::cout << "Construct_orthogonal_vector_3" << std::endl; + + const K::Construct_orthogonal_vector_3 construct_orthogonal_vector = K().construct_orthogonal_vector_3_object(); + + double sumx1 = 0, sumx2 = 0; + + t.start(); + { + std::cout << "overload with 3 points" << std::endl; + for(int k = 0; k < 100; ++k) + for(int i = 0; i < N; ++i){ + Point_3 o(CGAL::ORIGIN); + Vector_3 v = construct_orthogonal_vector(o, points[i], points[i+1]); + sumx1 += CGAL::to_double(v.approx().x()); + } + } + t.stop(); + + std::cout << t.time() << " sec." << std::endl; + + t.reset(); + t.start(); + { + std::cout << "overload with origin and 2 points" << std::endl; + for (int k = 0; k < 100; ++k) + for(int i = 0; i < N; ++i){ + Vector_3 v = construct_orthogonal_vector(CGAL::ORIGIN, points[i], points[i+1]); + sumx2 += CGAL::to_double(v.approx().x()); + } + } + + t.stop(); + + if(sumx1 != sumx2){ + std::cout << "Not the same results for Construct_orthogonal_vector" << std::endl; + assert(false); + } + std::cout << t.time() << " sec." << std::endl; + + + return 0; +} 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 4d18b6e598b..156ce0b9cbe 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 @@ -1276,7 +1276,6 @@ bool is_planar_2( } // Here, avg_squared_distance is a little bit more tolerant than avg_distance^2. - CGAL_assertion(avg_normal != typename Traits::Vector_3()); const Plane_3 plane = Plane_3(centroid, avg_normal); FT avg_squared_distance = FT(0); for (const Point_3& p : points) @@ -1367,6 +1366,8 @@ triangulate_hole_polyline_with_cdt(const PointRange& points, const Vector_3 avg_normal = Vector_3(x, y, z); // std::cout << "avg normal: " << avg_normal << std::endl; + if (avg_normal==NULL_VECTOR) return false; + // Checking the hole planarity. if (!is_planar_2(P, avg_normal, max_squared_distance, traits)) { // std::cerr << "WARNING: planarity, cdt 2 falls back to the original solution!" << std::endl; diff --git a/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/Offset_meshing_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/Offset_meshing_plugin.cpp index 83e70119a77..4ef6a35b7a1 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/Offset_meshing_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/Offset_meshing_plugin.cpp @@ -291,9 +291,10 @@ SMesh* cgal_off_meshing(QWidget*, p::relative_error_bound = 1e-7, p::construct_surface_patch_index = [](int i, int j) { return (i * 1000 + j); }); - CGAL::Mesh_facet_topology topology = CGAL::FACET_VERTICES_ON_SAME_SURFACE_PATCH; - if(tag == 1) topology = CGAL::Mesh_facet_topology(topology | CGAL::MANIFOLD_WITH_BOUNDARY); - if(tag == 2) topology = CGAL::Mesh_facet_topology(topology | CGAL::MANIFOLD); + const CGAL::Mesh_facet_topology topology = CGAL::FACET_VERTICES_ON_SAME_SURFACE_PATCH; + auto manifold_option = p::non_manifold(); + if(tag == 1) manifold_option = p::manifold_with_boundary(); + if(tag == 2) manifold_option = p::manifold(); Mesh_criteria criteria(p::facet_angle = angle, p::facet_size = sizing, p::facet_distance = approx, @@ -314,7 +315,8 @@ SMesh* cgal_off_meshing(QWidget*, C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria, p::no_perturb(), - p::no_exude()); + p::no_exude(), + manifold_option); const Tr& tr = c3t3.triangulation();