Add Cub_3-T_3 intersection

This commit is contained in:
Maxime Gimeno 2019-10-21 16:18:46 +02:00
parent 708d022849
commit ea3dc6c936
4 changed files with 302 additions and 2 deletions

View File

@ -164,6 +164,25 @@ struct Intersection_traits<K, typename K::Iso_cuboid_3, typename K::Point_3> {
typedef typename boost::optional< variant_type > result_type;
};
// Iso_cuboid_3 Triangle_3, variant of 4
template<typename K>
struct Intersection_traits<K, typename K::Iso_cuboid_3, typename K::Triangle_3> {
typedef typename
boost::variant< typename K::Point_3, typename K::Segment_3,
typename K::Triangle_3, std::vector<typename K::Point_3> > variant_type;
typedef typename boost::optional< variant_type > result_type;
};
template<typename K>
struct Intersection_traits<K, typename K::Triangle_3, typename K::Iso_cuboid_3> {
typedef typename
boost::variant< typename K::Point_3, typename K::Segment_3,
typename K::Triangle_3, std::vector<typename K::Point_3> > variant_type;
typedef typename boost::optional< variant_type > result_type;
};
// Point_3 Line_3, variant of one
template<typename K>
struct Intersection_traits<K, typename K::Point_3, typename K::Line_3> {

View File

@ -27,9 +27,11 @@
#include <CGAL/Triangle_3.h>
#include <CGAL/Intersections_3/internal/Iso_cuboid_3_Triangle_3_do_intersect.h>
#include <CGAL/Intersections_3/internal/Iso_cuboid_3_Triangle_3_intersection.h>
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

View File

@ -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 <CGAL/kernel_basic.h>
#include <CGAL/intersections.h>
#include <vector>
#include <list>
namespace CGAL {
namespace Intersections {
namespace internal {
//only work for convex polygons, but in here that's always the case
template<class K>
void clip_poly_halfspace(
const std::vector<typename K::Point_3>& input,
const typename K::Plane_3& pl,
std::vector<typename K::Point_3>& 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<K,
CGAL::Plane_3<K>,
CGAL::Segment_3<K> >::result_type SP_type;
std::list<Point> 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<Point>(&*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<Point>(&*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 <class K>
typename Intersection_traits<K, typename K::Iso_cuboid_3, typename K::Triangle_3>::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<Point> Poly;
typedef typename Intersection_traits<K,
CGAL::Iso_cuboid_3<K>,
CGAL::Triangle_3<K> >::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<Point> 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<K>(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<Point>(res));
}
break;
case 2:
{
Segment res = Segment(poly.front(), poly.back());
return Res_type(std::forward<Segment>(res));
}
break;
case 3:
{
Triangle res = Triangle (poly[0], poly[1], poly[2]);
return Res_type(std::forward<Triangle>(res));
}
break;
default:
{
return Res_type(std::forward<Poly>(poly));
}
break;
}
}
template <class K>
typename Intersection_traits<K, typename K::Iso_cuboid_3, typename K::Triangle_3>::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

View File

@ -3,6 +3,7 @@
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Homogeneous.h>
#include <CGAL/MP_Float.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/AABB_tree.h>
#include <CGAL/AABB_traits.h>
@ -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<K,
typename K::Triangle_3,
typename K::Iso_cuboid_3>::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<P>* poly = boost::get<std::vector<P> >(&*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<P>* poly = boost::get<std::vector<P> >(&*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<double> >().run();
Test< CGAL::Homogeneous<CGAL::MP_Float> >().run();
Test< CGAL::Epeck >().run(true);
Test< CGAL::Homogeneous<CGAL::Epeck_ft> >().run(true);
// TODO : test more kernels.
}