30 #ifndef __CGAL_EXACT_ARITHMETIC_H 31 #define __CGAL_EXACT_ARITHMETIC_H 33 #ifndef DOLFIN_ENABLE_GEOMETRY_DEBUGGING 36 #define CHECK_CGAL(RESULT_DOLFIN, RESULT_CGAL) RESULT_DOLFIN 38 #define CGAL_INTERSECTION_CHECK(RESULT_DOLFIN, RESULT_CGAL) RESULT_DOLFIN 42 #define CGAL_CHECK_TOLERANCE 1e-10 45 #include "predicates.h" 46 #include <dolfin/log/log.h> 47 #include <dolfin/log/LogStream.h> 48 #include <dolfin/math/basic.h> 61 check_cgal(
bool result_dolfin,
63 const std::string&
function)
65 if (result_dolfin != result_cgal)
68 std::stringstream s_dolfin;
69 std::stringstream s_cgal;
70 s_dolfin << result_dolfin;
71 s_cgal << result_cgal;
75 "verify geometric predicate with exact types",
76 "Error in predicate %s\n DOLFIN: %s\n CGAL: %s",
77 function.c_str(), s_dolfin.str().c_str(), s_cgal.str().c_str());
85 cgal_intersection_check(
const std::vector<Point>& dolfin_result,
86 const std::vector<Point>& cgal_result,
87 const std::string&
function)
89 if (dolfin_result.size() != cgal_result.size())
92 "verify intersection",
93 "Intersection function %s and CGAL give different size of point sets (%d vs %d)",
94 function.c_str(), dolfin_result.size(), cgal_result.size());
97 for (
const Point& p1 : dolfin_result)
100 for (
const Point& p2 : cgal_result)
102 if ( (p1-p2).norm() < 1e-15 )
111 "verify intersection construction result",
112 "Error in intersection function %s\nPoint (%f, %f, %f) in dolfin result not found",
113 function.c_str(), p1[0], p1[1], p1[2]);
115 return dolfin_result;
120 #define CHECK_CGAL(RESULT_DOLFIN, RESULT_CGAL) \ 121 check_cgal(RESULT_DOLFIN, RESULT_CGAL, __FUNCTION__) 123 #define CGAL_INTERSECTION_CHECK(RESULT_DOLFIN, RESULT_CGAL) \ 124 cgal_intersection_check(RESULT_DOLFIN, RESULT_CGAL, __FUNCTION__) 127 #define CGAL_HEADER_ONLY 128 #include <CGAL/Cartesian.h> 129 #include <CGAL/Quotient.h> 130 #include <CGAL/MP_Float.h> 131 #include <CGAL/Point_2.h> 132 #include <CGAL/Triangle_2.h> 133 #include <CGAL/Segment_2.h> 134 #include <CGAL/Point_3.h> 135 #include <CGAL/Triangle_3.h> 136 #include <CGAL/Segment_3.h> 137 #include <CGAL/Tetrahedron_3.h> 138 #include <CGAL/Polyhedron_3.h> 139 #include <CGAL/convex_hull_3.h> 140 #include <CGAL/intersections.h> 141 #include <CGAL/intersection_of_Polyhedra_3.h> 142 #include <CGAL/Exact_predicates_exact_constructions_kernel.h> 143 #include <CGAL/Triangulation_2.h> 144 #include <CGAL/Nef_polyhedron_3.h> 151 typedef CGAL::Exact_predicates_exact_constructions_kernel ExactKernel;
152 typedef ExactKernel::FT ExactNumber;
154 typedef ExactKernel::Point_2 Point_2;
155 typedef ExactKernel::Triangle_2 Triangle_2;
156 typedef ExactKernel::Segment_2 Segment_2;
157 typedef ExactKernel::Intersect_2 Intersect_2;
158 typedef ExactKernel::Point_3 Point_3;
159 typedef ExactKernel::Vector_3 Vector_3;
160 typedef ExactKernel::Triangle_3 Triangle_3;
161 typedef ExactKernel::Segment_3 Segment_3;
162 typedef ExactKernel::Tetrahedron_3 Tetrahedron_3;
163 typedef ExactKernel::Intersect_3 Intersect_3;
164 typedef CGAL::Nef_polyhedron_3<ExactKernel> Nef_polyhedron_3;
165 typedef CGAL::Polyhedron_3<ExactKernel> Polyhedron_3;
166 typedef CGAL::Triangulation_2<ExactKernel> Triangulation_2;
171 inline Point_2 convert_to_cgal_2d(
double a,
double b)
173 return Point_2(a, b);
176 inline Point_3 convert_to_cgal_3d(
double a,
double b,
double c)
178 return Point_3(a, b, c);
183 return Point_2(p[0], p[1]);
188 return Point_3(p[0], p[1], p[2]);
194 return Segment_2(convert_to_cgal_2d(a), convert_to_cgal_2d(b));
200 return Segment_3(convert_to_cgal_3d(a), convert_to_cgal_3d(b));
207 return Triangle_2(convert_to_cgal_2d(a),
208 convert_to_cgal_2d(b),
209 convert_to_cgal_2d(c));
216 return Triangle_3(convert_to_cgal_3d(a),
217 convert_to_cgal_3d(b),
218 convert_to_cgal_3d(c));
221 inline Tetrahedron_3 convert_to_cgal_3d(
const dolfin::Point& a,
226 return Tetrahedron_3(convert_to_cgal_3d(a),
227 convert_to_cgal_3d(b),
228 convert_to_cgal_3d(c),
229 convert_to_cgal_3d(d));
235 const Segment_2 s(convert_to_cgal_2d(a), convert_to_cgal_2d(b));
236 return s.is_degenerate();
242 const Segment_3 s(convert_to_cgal_3d(a), convert_to_cgal_3d(b));
243 return s.is_degenerate();
250 const Triangle_2 t(convert_to_cgal_2d(a),
251 convert_to_cgal_2d(b),
252 convert_to_cgal_2d(c));
253 return t.is_degenerate();
260 const Triangle_3 t(convert_to_cgal_3d(a),
261 convert_to_cgal_3d(b),
262 convert_to_cgal_3d(c));
263 return t.is_degenerate();
271 const Tetrahedron_3 t(convert_to_cgal_3d(a),
272 convert_to_cgal_3d(b),
273 convert_to_cgal_3d(c),
274 convert_to_cgal_3d(d));
275 return t.is_degenerate();
280 return dolfin::Point(CGAL::to_double(p.x()),CGAL::to_double(p.y()));
286 CGAL::to_double(p.y()),
287 CGAL::to_double(p.z()));
290 inline std::vector<dolfin::Point> convert_from_cgal(
const Segment_2& s)
292 const std::vector<dolfin::Point> triangulation =
294 CGAL::to_double(s.vertex(0)[1])),
296 CGAL::to_double(s.vertex(1)[1]))
298 return triangulation;
301 inline std::vector<dolfin::Point> convert_from_cgal(
const Segment_3& s)
303 const std::vector<dolfin::Point> triangulation =
305 CGAL::to_double(s.vertex(0)[1]),
306 CGAL::to_double(s.vertex(0)[2])),
308 CGAL::to_double(s.vertex(1)[1]),
309 CGAL::to_double(s.vertex(1)[2]))
311 return triangulation;
314 inline std::vector<dolfin::Point> convert_from_cgal(
const Triangle_2& t)
316 const std::vector<dolfin::Point> triangulation =
318 CGAL::to_double(t.vertex(0)[1])),
320 CGAL::to_double(t.vertex(2)[1])),
322 CGAL::to_double(t.vertex(1)[1]))
324 return triangulation;
327 inline std::vector<dolfin::Point> convert_from_cgal(
const Triangle_3& t)
329 const std::vector<dolfin::Point> triangulation =
331 CGAL::to_double(t.vertex(0)[1]),
332 CGAL::to_double(t.vertex(0)[2])),
334 CGAL::to_double(t.vertex(2)[1]),
335 CGAL::to_double(t.vertex(2)[2])),
337 CGAL::to_double(t.vertex(1)[1]),
338 CGAL::to_double(t.vertex(1)[2]))
340 return triangulation;
344 std::vector<std::vector<dolfin::Point>>
345 triangulate_polygon_2d(
const std::vector<dolfin::Point>& points)
348 std::vector<Point_2> pcgal(points.size());
349 for (std::size_t i = 0; i < points.size(); ++i)
350 pcgal[i] = convert_to_cgal_2d(points[i]);
353 Triangulation_2 tcgal;
354 tcgal.insert(pcgal.begin(), pcgal.end());
357 std::vector<std::vector<dolfin::Point>> t;
358 for (Triangulation_2::Finite_faces_iterator fit = tcgal.finite_faces_begin();
359 fit != tcgal.finite_faces_end(); ++fit)
361 t.push_back({{ convert_from_cgal(tcgal.triangle(fit)[0]),
362 convert_from_cgal(tcgal.triangle(fit)[1]),
363 convert_from_cgal(tcgal.triangle(fit)[2]) }});
370 std::vector<std::vector<dolfin::Point>>
371 triangulate_polygon_3d(
const std::vector<dolfin::Point>& points)
375 "triangulate_polygon_3d",
377 return std::vector<std::vector<dolfin::Point>>();
388 inline bool cgal_collides_segment_point_2d(
const Point& q0,
391 bool only_interior=
false)
393 const Point_2 q0_ = convert_to_cgal_2d(q0);
394 const Point_2 q1_ = convert_to_cgal_2d(q1);
395 const Point_2 p_ = convert_to_cgal_2d(p);
397 const bool intersects = CGAL::do_intersect(Segment_2(q0_, q1_), p_);
398 return only_interior ? intersects && p_ != q0_ && p_ != q1_ : intersects;
401 inline bool cgal_collides_segment_point_3d(
const Point& q0,
404 bool only_interior=
false)
406 const Point_3 q0_ = convert_to_cgal_3d(q0);
407 const Point_3 q1_ = convert_to_cgal_3d(q1);
408 const Point_3 p_ = convert_to_cgal_3d(p);
410 const Segment_3 segment(q0_, q1_);
411 const bool intersects = segment.has_on(p_);
412 return only_interior ? intersects && p_ != q0_ && p_ != q1_ : intersects;
415 inline bool cgal_collides_segment_segment_2d(
const Point& p0,
420 return CGAL::do_intersect(convert_to_cgal_2d(p0, p1),
421 convert_to_cgal_2d(q0, q1));
424 inline bool cgal_collides_segment_segment_3d(
const Point& p0,
429 return CGAL::do_intersect(convert_to_cgal_3d(p0, p1),
430 convert_to_cgal_3d(q0, q1));
433 inline bool cgal_collides_triangle_point_2d(
const Point& p0,
438 return CGAL::do_intersect(convert_to_cgal_2d(p0, p1, p2),
439 convert_to_cgal_2d(point));
442 inline bool cgal_collides_triangle_point_3d(
const Point& p0,
447 const Triangle_3 tri = convert_to_cgal_3d(p0, p1, p2);
448 return tri.has_on(convert_to_cgal_3d(point));
451 inline bool cgal_collides_triangle_segment_2d(
const Point& p0,
457 return CGAL::do_intersect(convert_to_cgal_2d(p0, p1, p2),
458 convert_to_cgal_2d(q0, q1));
461 inline bool cgal_collides_triangle_segment_3d(
const Point& p0,
467 return CGAL::do_intersect(convert_to_cgal_3d(p0, p1, p2),
468 convert_to_cgal_3d(q0, q1));
471 inline bool cgal_collides_triangle_triangle_2d(
const Point& p0,
478 return CGAL::do_intersect(convert_to_cgal_2d(p0, p1, p2),
479 convert_to_cgal_2d(q0, q1, q2));
482 inline bool cgal_collides_triangle_triangle_3d(
const Point& p0,
489 return CGAL::do_intersect(convert_to_cgal_3d(p0, p1, p2),
490 convert_to_cgal_3d(q0, q1, q2));
493 inline bool cgal_collides_tetrahedron_point_3d(
const Point& p0,
499 const Tetrahedron_3 tet = convert_to_cgal_3d(p0, p1, p2, p3);
500 return !tet.has_on_unbounded_side(convert_to_cgal_3d(q0));
503 inline bool cgal_collides_tetrahedron_segment_3d(
const Point& p0,
510 if (cgal_collides_tetrahedron_point_3d(p0, p1, p2, p3, q0) or
511 cgal_collides_tetrahedron_point_3d(p0, p1, p2, p3, q1))
514 if (cgal_collides_triangle_segment_3d(p0, p1, p2, q0, q1) or
515 cgal_collides_triangle_segment_3d(p0, p2, p3, q0, q1) or
516 cgal_collides_triangle_segment_3d(p0, p3, p1, q0, q1) or
517 cgal_collides_triangle_segment_3d(p1, p3, p2, q0, q1))
523 inline bool cgal_collides_tetrahedron_triangle_3d(
const Point& p0,
531 return CGAL::do_intersect(convert_to_cgal_3d(p0, p1, p2, p3),
532 convert_to_cgal_3d(q0, q1, q2));
535 inline bool cgal_collides_tetrahedron_tetrahedron_3d(
const Point& p0,
545 if (cgal_collides_tetrahedron_point_3d(p0, p1, p2, p3, q0))
return true;
546 if (cgal_collides_tetrahedron_point_3d(p0, p1, p2, p3, q1))
return true;
547 if (cgal_collides_tetrahedron_point_3d(p0, p1, p2, p3, q2))
return true;
548 if (cgal_collides_tetrahedron_point_3d(p0, p1, p2, p3, q3))
return true;
549 if (cgal_collides_tetrahedron_point_3d(q0, q1, q2, q3, p0))
return true;
550 if (cgal_collides_tetrahedron_point_3d(q0, q1, q2, q3, p1))
return true;
551 if (cgal_collides_tetrahedron_point_3d(q0, q1, q2, q3, p2))
return true;
552 if (cgal_collides_tetrahedron_point_3d(q0, q1, q2, q3, p3))
return true;
555 tet_a.make_tetrahedron(convert_to_cgal_3d(p0),
556 convert_to_cgal_3d(p1),
557 convert_to_cgal_3d(p2),
558 convert_to_cgal_3d(p3));
561 tet_b.make_tetrahedron(convert_to_cgal_3d(q0),
562 convert_to_cgal_3d(q1),
563 convert_to_cgal_3d(q2),
564 convert_to_cgal_3d(q3));
569 CGAL::Counting_output_iterator out(&cnt);
570 CGAL::intersection_Polyhedron_3_Polyhedron_3<Polyhedron_3>(tet_a,
581 std::vector<Point> cgal_intersection_segment_segment_2d(
const Point& p0,
586 dolfin_assert(!is_degenerate_2d(p0, p1));
587 dolfin_assert(!is_degenerate_2d(q0, q1));
589 const auto I0 = convert_to_cgal_2d(p0, p1);
590 const auto I1 = convert_to_cgal_2d(q0, q1);
592 if (
const auto ii = CGAL::intersection(I0, I1))
594 if (
const Point_2* p = boost::get<Point_2>(&*ii))
596 return std::vector<Point>{convert_from_cgal(*p)};
598 else if (
const Segment_2* s = boost::get<Segment_2>(&*ii))
600 return convert_from_cgal(*s);
605 "cgal_intersection_segment_segment_2d",
606 "Unexpected behavior");
610 return std::vector<Point>();
614 std::vector<Point> cgal_intersection_segment_segment_3d(
const Point& p0,
619 dolfin_assert(!is_degenerate_3d(p0, p1));
620 dolfin_assert(!is_degenerate_3d(q0, q1));
622 const auto I0 = convert_to_cgal_3d(p0, p1);
623 const auto I1 = convert_to_cgal_3d(q0, q1);
625 if (
const auto ii = CGAL::intersection(I0, I1))
627 if (
const Point_3* p = boost::get<Point_3>(&*ii))
629 return std::vector<Point>{convert_from_cgal(*p)};
631 else if (
const Segment_3* s = boost::get<Segment_3>(&*ii))
633 return convert_from_cgal(*s);
638 "cgal_intersection_segment_segment_3d",
639 "Unexpected behavior");
643 return std::vector<Point>();
647 std::vector<Point> cgal_triangulate_segment_segment_2d(
const Point& p0,
652 return cgal_intersection_segment_segment_2d(p0, p1, q0, q1);
656 std::vector<Point> cgal_triangulate_segment_segment_3d(
const Point& p0,
661 return cgal_intersection_segment_segment_3d(p0, p1, q0, q1);
665 std::vector<Point> cgal_intersection_triangle_segment_2d(
const Point& p0,
671 dolfin_assert(!is_degenerate_2d(p0, p1, p2));
672 dolfin_assert(!is_degenerate_2d(q0, q1));
674 const auto T = convert_to_cgal_2d(p0, p1, p2);
675 const auto I = convert_to_cgal_2d(q0, q1);
677 if (
const auto ii = CGAL::intersection(T, I))
679 if (
const Point_2* p = boost::get<Point_2>(&*ii))
681 return std::vector<Point>{convert_from_cgal(*p)};
683 else if (
const Segment_2* s = boost::get<Segment_2>(&*ii))
685 return convert_from_cgal(*s);
690 "cgal_intersection_triangle_segment_2d",
691 "Unexpected behavior");
695 return std::vector<Point>();
699 std::vector<Point> cgal_intersection_triangle_segment_3d(
const Point& p0,
705 dolfin_assert(!is_degenerate_3d(p0, p1, p2));
706 dolfin_assert(!is_degenerate_3d(q0, q1));
708 const auto T = convert_to_cgal_3d(p0, p1, p2);
709 const auto I = convert_to_cgal_3d(q0, q1);
711 if (
const auto ii = CGAL::intersection(T, I))
713 if (
const Point_3* p = boost::get<Point_3>(&*ii))
714 return std::vector<Point>{convert_from_cgal(*p)};
715 else if (
const Segment_3* s = boost::get<Segment_3>(&*ii))
716 return convert_from_cgal(*s);
720 "cgal_intersection_triangle_segment_3d",
721 "Unexpected behavior");
725 return std::vector<Point>();
729 std::vector<Point> cgal_triangulate_triangle_segment_2d(
const Point& p0,
735 return cgal_intersection_triangle_segment_2d(p0, p1, p2, q0, q1);
739 std::vector<Point> cgal_triangulate_triangle_segment_3d(
const Point& p0,
745 return cgal_intersection_triangle_segment_3d(p0, p1, p2, q0, q1);
749 std::vector<Point> cgal_intersection_triangle_triangle_2d(
const Point& p0,
756 dolfin_assert(!is_degenerate_2d(p0, p1, p2));
757 dolfin_assert(!is_degenerate_2d(q0, q1, q2));
759 const Triangle_2 T0 = convert_to_cgal_2d(p0, p1, p2);
760 const Triangle_2 T1 = convert_to_cgal_2d(q0, q1, q2);
761 std::vector<Point> intersection;
763 if (
const auto ii = CGAL::intersection(T0, T1))
765 if (
const Point_2* p = boost::get<Point_2>(&*ii))
767 intersection.push_back(convert_from_cgal(*p));
769 else if (
const Segment_2* s = boost::get<Segment_2>(&*ii))
771 intersection = convert_from_cgal(*s);
773 else if (
const Triangle_2* t = boost::get<Triangle_2>(&*ii))
775 intersection = convert_from_cgal(*t);;
777 else if (
const std::vector<Point_2>* cgal_points = boost::get<std::vector<Point_2>>(&*ii))
779 for (Point_2 p : *cgal_points)
781 intersection.push_back(convert_from_cgal(p));
787 "cgal_intersection_triangle_triangle_2d",
788 "Unexpected behavior");
803 std::vector<Point> cgal_intersection_triangle_triangle_3d(
const Point& p0,
810 dolfin_assert(!is_degenerate_3d(p0, p1, p2));
811 dolfin_assert(!is_degenerate_3d(q0, q1, q2));
813 const Triangle_3 T0 = convert_to_cgal_3d(p0, p1, p2);
814 const Triangle_3 T1 = convert_to_cgal_3d(q0, q1, q2);
815 std::vector<Point> intersection;
817 if (
const auto ii = CGAL::intersection(T0, T1))
819 if (
const Point_3* p = boost::get<Point_3>(&*ii))
821 intersection.push_back(convert_from_cgal(*p));
823 else if (
const Segment_3* s = boost::get<Segment_3>(&*ii))
825 intersection = convert_from_cgal(*s);
827 else if (
const Triangle_3* t = boost::get<Triangle_3>(&*ii))
829 intersection = convert_from_cgal(*t);;
831 else if (
const std::vector<Point_3>* cgal_points = boost::get<std::vector<Point_3>>(&*ii))
833 for (Point_3 p : *cgal_points)
835 intersection.push_back(convert_from_cgal(p));
841 "cgal_intersection_triangle_triangle_3d",
842 "Unexpected behavior");
850 std::vector<std::vector<Point>>
851 cgal_triangulate_triangle_triangle_2d(
const Point& p0,
858 dolfin_assert(!is_degenerate_2d(p0, p1, p2));
859 dolfin_assert(!is_degenerate_2d(q0, q1, q2));
861 const std::vector<Point> intersection
862 = cgal_intersection_triangle_triangle_2d(p0, p1, p2, q0, q1, q2);
864 if (intersection.size() < 4)
866 return std::vector<std::vector<Point>>{intersection};
870 dolfin_assert(intersection.size() == 4 ||
871 intersection.size() == 5 ||
872 intersection.size() == 6);
873 return triangulate_polygon_2d(intersection);
878 std::vector<std::vector<Point>>
879 cgal_triangulate_triangle_triangle_3d(
const Point& p0,
886 dolfin_assert(!is_degenerate_3d(p0, p1, p2));
887 dolfin_assert(!is_degenerate_3d(q0, q1, q2));
889 const std::vector<Point> intersection
890 = cgal_intersection_triangle_triangle_3d(p0, p1, p2, q0, q1, q2);
892 if (intersection.size() < 4)
894 return std::vector<std::vector<Point>>{intersection};
898 dolfin_assert(intersection.size() == 4 ||
899 intersection.size() == 5 ||
900 intersection.size() == 6);
901 return triangulate_polygon_3d(intersection);
907 cgal_intersection_tetrahedron_triangle(
const Point& p0,
915 dolfin_assert(!is_degenerate_3d(p0, p1, p2, p3));
916 dolfin_assert(!is_degenerate_3d(q0, q1, q2));
922 tet.make_tetrahedron(convert_to_cgal_3d(p0),
923 convert_to_cgal_3d(p1),
924 convert_to_cgal_3d(p2),
925 convert_to_cgal_3d(p3));
927 tri.make_triangle(convert_to_cgal_3d(q0),
928 convert_to_cgal_3d(q1),
929 convert_to_cgal_3d(q2));
931 std::list<std::vector<Point_3> > triangulation;
932 CGAL::intersection_Polyhedron_3_Polyhedron_3(tet,
934 std::back_inserter(triangulation));
941 "cgal_intersection_tetrahedron_triangle",
944 return std::vector<Point>();
947 inline std::vector<std::vector<Point>>
948 cgal_triangulate_tetrahedron_triangle(
const Point& p0,
956 dolfin_assert(!is_degenerate_3d(p0, p1, p2, p3));
957 dolfin_assert(!is_degenerate_3d(q0, q1, q2));
959 std::vector<Point> intersection =
960 cgal_intersection_tetrahedron_triangle(p0, p1, p2, p3, q0, q1, q2);
964 "cgal_triangulation_tetrahedron_triangle",
967 return std::vector<std::vector<Point>>();
970 inline std::vector<Point>
971 cgal_intersection_tetrahedron_tetrahedron_3d(
const Point& p0,
980 dolfin_assert(!is_degenerate_3d(p0, p1, p2, p3));
981 dolfin_assert(!is_degenerate_3d(q0, q1, q2, q3));
984 tet_a.make_tetrahedron(convert_to_cgal_3d(p0),
985 convert_to_cgal_3d(p1),
986 convert_to_cgal_3d(p2),
987 convert_to_cgal_3d(p3));
989 tet_b.make_tetrahedron(convert_to_cgal_3d(q0),
990 convert_to_cgal_3d(q1),
991 convert_to_cgal_3d(q2),
992 convert_to_cgal_3d(q3));
994 const Nef_polyhedron_3 tet_a_nef(tet_a);
995 const Nef_polyhedron_3 tet_b_nef(tet_b);
997 const Nef_polyhedron_3 intersection_nef = tet_a_nef*tet_b_nef;
999 std::vector<Point> res;
1001 for (
auto vit = intersection_nef.vertices_begin();
1002 vit != intersection_nef.vertices_end(); ++vit)
1004 res.push_back(Point(CGAL::to_double(vit->point().x()),
1005 CGAL::to_double(vit->point().y()),
1006 CGAL::to_double(vit->point().z())));
1014 inline bool cgal_is_degenerate_2d(
const std::vector<Point>& s)
1016 if (s.size() < 2 or s.size() > 3)
1018 info(
"Degenerate 2D simplex with %d vertices.", s.size());
1024 case 2:
return is_degenerate_2d(s[0], s[1]);
1025 case 3:
return is_degenerate_2d(s[0], s[1], s[2]);
1030 "call cgal_is_degenerate_2d",
1031 "Only implemented for simplices of tdim 0, 1 and 2, not tdim = %d", s.size() - 1);
1036 inline bool cgal_is_degenerate_3d(
const std::vector<Point>& s)
1038 if (s.size() < 2 or s.size() > 4)
1040 info(
"Degenerate 3D simplex with %d vertices.", s.size());
1046 case 2:
return is_degenerate_3d(s[0], s[1]);
1047 case 3:
return is_degenerate_3d(s[0], s[1], s[2]);
1048 case 4:
return is_degenerate_3d(s[0], s[1], s[2], s[3]);
1053 "call cgal_is_degenerate_3d",
1054 "Only implemented for simplices of tdim 0, 1, 2 and 3, not tdim = %d", s.size() - 1);
1060 inline double cgal_polyhedron_volume(
const std::vector<Point>& ch)
1065 std::vector<Point_3> exact_points;
1066 exact_points.reserve(ch.size());
1067 for (
const Point& p : ch)
1069 exact_points.push_back(Point_3(p.x(), p.y(), p.z()));
1074 CGAL::convex_hull_3(exact_points.begin(), exact_points.end(), p);
1076 ExactNumber volume = .0;
1077 for (Polyhedron_3::Facet_const_iterator it = p.facets_begin();
1078 it != p.facets_end(); it++)
1080 const Polyhedron_3::Halfedge_const_handle h = it->halfedge();
1081 const Vector_3 V0 = h->vertex()->point()-CGAL::ORIGIN;
1082 const Vector_3 V1 = h->next()->vertex()->point()-CGAL::ORIGIN;
1083 const Vector_3 V2 = h->next()->next()->vertex()->point()-CGAL::ORIGIN;
1085 volume += V0*CGAL::cross_product(V1, V2);
1088 return std::abs(CGAL::to_double(volume/6.0));
1091 inline double cgal_tet_volume(
const std::vector<Point>& ch)
1093 dolfin_assert(ch.size() == 3);
1094 return CGAL::to_double(CGAL::volume(Point_3(ch[0].x(), ch[0].y(), ch[0].z()),
1095 Point_3(ch[1].x(), ch[1].y(), ch[1].z()),
1096 Point_3(ch[2].x(), ch[2].y(), ch[2].z()),
1097 Point_3(ch[3].x(), ch[3].y(), ch[3].z())));
1100 inline bool cgal_tet_is_degenerate(
const std::vector<Point>& t)
1102 Tetrahedron_3 tet(Point_3(t[0].x(), t[0].y(), t[0].z()),
1103 Point_3(t[1].x(), t[1].y(), t[1].z()),
1104 Point_3(t[2].x(), t[2].y(), t[2].z()),
1105 Point_3(t[3].x(), t[3].y(), t[3].z()));
1107 return tet.is_degenerate();
1111 inline bool cgal_triangulation_has_degenerate(std::vector<std::vector<Point>> triangulation)
1113 for (
const std::vector<Point>& t : triangulation)
1115 if (cgal_tet_is_degenerate(t))
1123 inline bool cgal_triangulation_overlap(std::vector<std::vector<Point>> triangulation)
1125 std::vector<Tetrahedron_3> tets;
1127 for (
const std::vector<Point>& t : triangulation)
1129 Tetrahedron_3 tet(Point_3(t[0].x(), t[0].y(), t[0].z()),
1130 Point_3(t[1].x(), t[1].y(), t[1].z()),
1131 Point_3(t[2].x(), t[2].y(), t[2].z()),
1132 Point_3(t[3].x(), t[3].y(), t[3].z()));
1134 for (
const Tetrahedron_3& t0 : tets)
1136 for (
int i = 0; i < 4; i++)
1138 if (t0.has_on_bounded_side(tet[i]) || tet.has_on_bounded_side(t0[i]))
1143 tets.push_back(tet);
void info(std::string msg,...)
Print message.
Definition: log.cpp:72
void dolfin_error(std::string location, std::string task, std::string reason,...)
Definition: log.cpp:129