From ea3dc6c936a65bdbc7df6bfb57f8e7e4491c89ca Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 21 Oct 2019 16:18:46 +0200 Subject: [PATCH] Add Cub_3-T_3 intersection --- .../include/CGAL/Intersection_traits_3.h | 19 ++ .../Intersections_3/Iso_cuboid_3_Triangle_3.h | 4 +- .../Iso_cuboid_3_Triangle_3_intersection.h | 210 ++++++++++++++++++ .../Intersections_3/test_intersections_3.cpp | 71 +++++- 4 files changed, 302 insertions(+), 2 deletions(-) create mode 100644 Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Triangle_3_intersection.h diff --git a/Intersections_3/include/CGAL/Intersection_traits_3.h b/Intersections_3/include/CGAL/Intersection_traits_3.h index 88864987cb3..a72bb5c6a59 100644 --- a/Intersections_3/include/CGAL/Intersection_traits_3.h +++ b/Intersections_3/include/CGAL/Intersection_traits_3.h @@ -164,6 +164,25 @@ struct Intersection_traits { typedef typename boost::optional< variant_type > result_type; }; +// Iso_cuboid_3 Triangle_3, variant of 4 +template +struct Intersection_traits { + typedef typename + boost::variant< typename K::Point_3, typename K::Segment_3, + typename K::Triangle_3, std::vector > variant_type; + + typedef typename boost::optional< variant_type > result_type; +}; + +template +struct Intersection_traits { + typedef typename + boost::variant< typename K::Point_3, typename K::Segment_3, + typename K::Triangle_3, std::vector > variant_type; + + typedef typename boost::optional< variant_type > result_type; +}; + // Point_3 Line_3, variant of one template struct Intersection_traits { diff --git a/Intersections_3/include/CGAL/Intersections_3/Iso_cuboid_3_Triangle_3.h b/Intersections_3/include/CGAL/Intersections_3/Iso_cuboid_3_Triangle_3.h index 9c0e6ac71e2..9f56eece4bf 100644 --- a/Intersections_3/include/CGAL/Intersections_3/Iso_cuboid_3_Triangle_3.h +++ b/Intersections_3/include/CGAL/Intersections_3/Iso_cuboid_3_Triangle_3.h @@ -27,9 +27,11 @@ #include #include +#include namespace CGAL { - CGAL_DO_INTERSECT_FUNCTION(Iso_cuboid_3,Triangle_3, 3) + CGAL_DO_INTERSECT_FUNCTION(Iso_cuboid_3, Triangle_3, 3) + CGAL_INTERSECTION_FUNCTION(Iso_cuboid_3, Triangle_3, 3) } #endif // CGAL_INTERSECTIONS_3_BBOX_3_TRIANGLE_3_H diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Triangle_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Triangle_3_intersection.h new file mode 100644 index 00000000000..0e8f1ebc186 --- /dev/null +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Triangle_3_intersection.h @@ -0,0 +1,210 @@ +// Copyright (c) 2019 GeometryFactory(France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// +// +// Author(s) : Maxime Gimeno +// + +#ifndef CGAL_INTERSECTIONS_3_INTERNAL_ISO_CUBOID_3_TRIANGLE_3_INTERSECTION_H +#define CGAL_INTERSECTIONS_3_INTERNAL_ISO_CUBOID_3_TRIANGLE_3_INTERSECTION_H + +#include +#include + +#include +#include + +namespace CGAL { + +namespace Intersections { + +namespace internal { + +//only work for convex polygons, but in here that's always the case +template +void clip_poly_halfspace( + const std::vector& input, + const typename K::Plane_3& pl, + std::vector& output) +{ + if(input.empty()) + return; + + typedef typename K::Point_3 Point; + typedef typename K::Plane_3 Plane; + typedef typename K::Segment_3 S; + + typedef typename Intersection_traits, + CGAL::Segment_3 >::result_type SP_type; + + std::list p_list(input.begin(), input.end()); + auto it = p_list.begin(); + //corefine with plane. + while(it != p_list.end()) + { + Point p = *it; + ++it; + if(it == p_list.end()) + break; + if(do_intersect(S(p, *it), pl)) + { + SP_type inter = typename K::Intersect_3()(S(p, *it), pl); + if(inter) + { + Point* p_inter = boost::get(&*inter); + if(p_inter + && *p_inter != p + && *p_inter != *it) + p_list.insert(it, *p_inter); + } + } + } + + if(input.size() >2) + { + Point p2(p_list.front()), + p1(p_list.back()); + S seg(p1, p2); + if(do_intersect(seg, pl)) + { + SP_type inter = typename K::Intersect_3()(seg, pl); + if(inter) + { + Point* p_inter = boost::get(&*inter); + if(p_inter + && *p_inter != p1 + && *p_inter != p2) + p_list.push_back(*p_inter); + } + } + } + //remove all points on positive side + + for(auto p_it = p_list.begin(); + p_it != p_list.end();) + { + if(pl.has_on_positive_side(*p_it)) + p_it = p_list.erase(p_it); + else + ++p_it; + } + for(auto p : p_list) + output.push_back(p); + +} + +template +typename Intersection_traits::result_type +intersection( + const typename K::Iso_cuboid_3 &cub, + const typename K::Triangle_3 &tr, + const K&) +{ + typedef typename K::Point_3 Point; + typedef typename K::Segment_3 Segment; + typedef typename K::Triangle_3 Triangle; + typedef typename K::Plane_3 Plane_3; + typedef std::vector Poly; + + typedef typename Intersection_traits, + CGAL::Triangle_3 >::result_type Res_type; + + //Lazy implem: clip 6 times the input triangle. + Plane_3 planes[6]; + planes[0] = Plane_3(cub.vertex(0), + cub.vertex(1), + cub.vertex(5)); + + planes[1] = Plane_3(cub.vertex(0), + cub.vertex(4), + cub.vertex(3)); + + planes[2]=Plane_3(cub.vertex(0), + cub.vertex(3), + cub.vertex(1)); + + planes[3] = Plane_3(cub.vertex(7), + cub.vertex(6), + cub.vertex(1)); + + planes[4] = Plane_3(cub.vertex(7), + cub.vertex(3), + cub.vertex(4)); + + planes[5] = Plane_3(cub.vertex(7), + cub.vertex(4), + cub.vertex(6)); + + std::vector poly; + poly.push_back(tr.vertex(0)); + poly.push_back(tr.vertex(1)); + poly.push_back(tr.vertex(2)); + + for (int i = 0; i < 6; ++i) + { + Poly clipped; + clip_poly_halfspace(poly, planes[i], clipped); + poly = clipped; + } + + switch(poly.size()) + { + case 0: + return Res_type(); + break; + case 1: + { + Point res = poly.front(); + return Res_type(std::forward(res)); + } + break; + case 2: + { + Segment res = Segment(poly.front(), poly.back()); + return Res_type(std::forward(res)); + } + break; + case 3: + { + + Triangle res = Triangle (poly[0], poly[1], poly[2]); + return Res_type(std::forward(res)); + } + break; + default: + { + return Res_type(std::forward(poly)); + } + break; + } +} + +template +typename Intersection_traits::result_type +intersection( + const typename K::Triangle_3 &tr, + const typename K::Iso_cuboid_3 &cub, + const K& k) +{ + return intersection(cub, tr, k); +} +}}} + +#endif // CGAL_INTERSECTIONS_3_INTERNAL_ISO_CUBOID_3_TRIANGLE_3_INTERSECTION_H diff --git a/Intersections_3/test/Intersections_3/test_intersections_3.cpp b/Intersections_3/test/Intersections_3/test_intersections_3.cpp index b8c20156922..c4f1c4197d9 100644 --- a/Intersections_3/test/Intersections_3/test_intersections_3.cpp +++ b/Intersections_3/test/Intersections_3/test_intersections_3.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -563,7 +564,72 @@ struct Test { << do_intersect_counter << "\n"; } // end function Bbox_Tr - void run() + void Cub_Tr(bool is_exact) + { + std::cout << "Triangle_3 - Cuboid_3\n"; + + Cub cub(P(1,1,1), P(2,2,2)); + + check_no_intersection(cub, Tr(P(1.1, 2,0), + P(2, 3, 1), + P(4, 5, 6))); + + //tr in a face + check_intersection(cub, Tr(P(1,1.1,1), + P(1,1.5,1), + P(1,1,1.1)), + Tr(P(1,1.1,1), + P(1,1.5,1), + P(1,1,1.1)) + ); + //face in a tr + + typedef typename CGAL::Intersection_traits::result_type Res; + Tr tr(P(-3, -3, 1), P(3,-3,1), P(1.5,6,1)); + Res res = CGAL::intersection(cub, tr); + if(is_exact) + { + std::vector

* poly = boost::get >(&*res); + CGAL_assertion(poly != nullptr); + CGAL_assertion(poly->size() == 4); + for(auto p : *poly) + { + CGAL_assertion(tr.has_on(p) && cub.has_on_boundary(p)); + } + } + + //tr adj to a point + + check_intersection (cub, Tr(P(1, 0.5, 0.5), + P(3, 2, 1), + P(3, 1, 2)), + P(2,1,1)); + //tr adj to an edge + check_intersection (cub, Tr(P(1,0,4), P(2,1,0), P(4,3,0)), + S(P(2,1,2), P(2,1,1))); + //tr inside + check_intersection (cub, Tr(P(1.1,1.1,1.1), P(1.8,1.8,1.8), P(1.5,1.8,1.1)), + Tr(P(1.1,1.1,1.1), P(1.8,1.8,1.8), P(1.5,1.8,1.1))); + //tr through + tr = Tr(P(2, 4, 2), + P(1, 3.5, -0.5), + P(1, -1, 1)); + res = CGAL::intersection(cub, tr); + if(is_exact) + { + std::vector

* poly = boost::get >(&*res); + CGAL_assertion(poly != nullptr); + CGAL_assertion(poly->size() == 4); + for(auto p : *poly) + { + CGAL_assertion(tr.has_on(p) && cub.has_on_boundary(p)); + } + } + } + + void run(bool is_exact = false) { std::cout << "3D Intersection tests\n"; P_do_intersect(); @@ -584,6 +650,7 @@ struct Test { Bbox_L(); Bbox_R(); Bbox_Tr(); + Cub_Tr(is_exact); } }; @@ -592,6 +659,8 @@ int main() { Test< CGAL::Simple_cartesian >().run(); Test< CGAL::Homogeneous >().run(); + Test< CGAL::Epeck >().run(true); + Test< CGAL::Homogeneous >().run(true); // TODO : test more kernels. }