This commit is contained in:
Sébastien Loriot 2021-02-09 17:58:25 +01:00
parent fb731259d7
commit b363977c87
1 changed files with 93 additions and 91 deletions

View File

@ -8,7 +8,7 @@
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
// //
// //
// Author(s) : Maxime Gimeno // Author(s) : Sebastien Loriot and Andreas Fabri
// //
#ifndef CGAL_INTERNAL_INTERSECTIONS_3_ISO_CUBOID_3_PLANE_3_INTERSECTION_H #ifndef CGAL_INTERNAL_INTERSECTIONS_3_ISO_CUBOID_3_PLANE_3_INTERSECTION_H
@ -28,7 +28,7 @@ namespace CGAL {
namespace Intersections { namespace Intersections {
namespace internal { namespace internal {
template <class Geom_traits, class Plane_3, class Point_3> template <class K, class Plane_3, class Point_3>
int int
inter_pt_index(int i, int j, inter_pt_index(int i, int j,
const Plane_3& plane, const Plane_3& plane,
@ -39,7 +39,7 @@ inter_pt_index(int i, int j,
id_map.insert(std::make_pair(make_sorted_pair(i, j), id_map.insert(std::make_pair(make_sorted_pair(i, j),
static_cast<int> (points.size()))); static_cast<int> (points.size())));
if (res.second) if (res.second)
points.push_back(typename Geom_traits::Construct_plane_line_intersection_point_3() points.push_back(typename K::Construct_plane_line_intersection_point_3()
(plane, points[i], points[j])); (plane, points[i], points[j]));
return res.first->second; return res.first->second;
@ -54,8 +54,8 @@ intersection(
const K& k) const K& k)
{ {
typedef typename K::Point_3 Point_3; typedef typename K::Point_3 Point_3;
typedef std::vector<Point_3> Poly;
typedef typename Intersection_traits<K, typename K::Iso_cuboid_3, typename K::Plane_3>::result_type result_type; typedef typename Intersection_traits<K, typename K::Iso_cuboid_3, typename K::Plane_3>::result_type result_type;
typename K::Oriented_side_3 oriented_side = k.oriented_side_3_object();
std::vector<Point_3> corners(8); std::vector<Point_3> corners(8);
corners.reserve(14); // 8 corners + up to 6 polygon points corners.reserve(14); // 8 corners + up to 6 polygon points
@ -69,14 +69,14 @@ intersection(
corners[7] = cub[6]; corners[7] = cub[6];
std::array<CGAL::Oriented_side, 8> orientations = { { std::array<CGAL::Oriented_side, 8> orientations = { {
plane.oriented_side(corners[0]), oriented_side(plane, corners[0]),
plane.oriented_side(corners[1]), oriented_side(plane, corners[1]),
plane.oriented_side(corners[2]), oriented_side(plane, corners[2]),
plane.oriented_side(corners[3]), oriented_side(plane, corners[3]),
plane.oriented_side(corners[4]), oriented_side(plane, corners[4]),
plane.oriented_side(corners[5]), oriented_side(plane, corners[5]),
plane.oriented_side(corners[6]), oriented_side(plane, corners[6]),
plane.oriented_side(corners[7]) oriented_side(plane, corners[7])
} }; } };
// description of faces of the bbox // description of faces of the bbox
@ -95,8 +95,8 @@ intersection(
std::vector<int> next(14, -1); std::vector<int> next(14, -1);
std::vector<int> prev(14, -1); std::vector<int> prev(14, -1);
int start = -1; int start_id = -1;
int solo = -1; int solo_id = -1;
// for each face of the bbox, we look for intersection of the plane with its edges // for each face of the bbox, we look for intersection of the plane with its edges
std::vector<int> ids; std::vector<int> ids;
for (int i = 0; i < 6; ++i) for (int i = 0; i < 6; ++i)
@ -127,8 +127,7 @@ intersection(
// check for intersection of the edge // check for intersection of the edge
if (orientations[next_id] == ON_NEGATIVE_SIDE) if (orientations[next_id] == ON_NEGATIVE_SIDE)
{ {
ids.push_back( ids.push_back(inter_pt_index<K>(current_id, next_id, plane, corners, id_map));
inter_pt_index<K>(current_id, next_id, plane, corners, id_map));
} }
break; break;
} }
@ -139,18 +138,20 @@ intersection(
} }
} }
} }
if (ids.size() == 4){
std::vector<Point_3> res(4); switch (ids.size())
res[0] = corners[ids[0]];
res[1] = corners[ids[1]];
res[2] = corners[ids[2]];
res[3] = corners[ids[3]];
return result_type(std::forward<Poly>(res));
} else
{ {
if (ids.size() == 2) case 4:
{ {
if (start == -1) start = ids[0]; std::vector<Point_3> res({ corners[ids[0]],
corners[ids[1]],
corners[ids[2]],
corners[ids[3]] });
return result_type(res);
}
case 2:
{
if (start_id == -1) start_id = ids[0];
if (next[ids[0]] == -1) { if (next[ids[0]] == -1) {
next[ids[0]] = ids[1]; next[ids[0]] = ids[1];
} }
@ -163,37 +164,38 @@ intersection(
else { else {
prev[ids[1]] = ids[0]; prev[ids[1]] = ids[0];
} }
break;
} }
else case 1:
if (ids.size() == 1) solo_id = ids[0];
solo = ids[0]; default:
break;
} }
} }
if (all_in || all_out) return boost::none; if (all_in || all_out) return boost::none;
if (start == -1) return { result_type(corners[solo]) }; if (start_id == -1) return { result_type(corners[solo_id]) };
int pre = -1; int prv_id = -1;
int cur = start; int cur_id = start_id;
std::vector<Point_3> res; std::vector<Point_3> res;
res.reserve(6); res.reserve(6);
do { do {
res.push_back(corners[cur]); res.push_back(corners[cur_id]);
int n = next[cur] == pre ? prev[cur] : next[cur]; int nxt_id = next[cur_id] == prv_id ? prev[cur_id] : next[cur_id];
if (n == -1 || n == start){ if (nxt_id == -1 || nxt_id == start_id){
if(res.size() == 2){ if(res.size() == 2){
typename K::Segment_3 seg(res[0], res[1]); typename K::Segment_3 seg(res[0], res[1]);
return result_type(std::forward<typename K::Segment_3>(seg)); return result_type(seg);
} }
if(res.size() == 3){ if(res.size() == 3){
typename K::Triangle_3 tr(res[0], res[1], res[2]); typename K::Triangle_3 tr(res[0], res[1], res[2]);
return result_type(std::forward<typename K::Triangle_3>(tr)); return result_type(tr);
} }
return result_type(std::forward<Poly>(res));; return result_type(res);
} }
pre = cur; prv_id = cur_id;
cur = n; cur_id = nxt_id;
} while (true); } while (true);
} }
@ -210,6 +212,6 @@ intersection(
return intersection(cub, pl, k); return intersection(cub, pl, k);
} }
}}} }}}
#endif // CGAL_INTERNAL_INTERSECTIONS_3_ISO_CUBOID_3_PLANE_3_INTERSECTION_H #endif // CGAL_INTERNAL_INTERSECTIONS_3_ISO_CUBOID_3_PLANE_3_INTERSECTION_H