mirror of https://github.com/CGAL/cgal
WIP: try to do plane/tet intersection. I think the edge indexing is wrong
This commit is contained in:
parent
482db1f0cc
commit
75cb1593d0
|
|
@ -32,101 +32,169 @@ template <class K>
|
||||||
typename Intersection_traits<K, typename K::Tetrahedron_3, typename K::Plane_3>::result_type
|
typename Intersection_traits<K, typename K::Tetrahedron_3, typename K::Plane_3>::result_type
|
||||||
intersection(
|
intersection(
|
||||||
const typename K::Tetrahedron_3 &tet,
|
const typename K::Tetrahedron_3 &tet,
|
||||||
const typename K::Plane_3 &pl,
|
const typename K::Plane_3 &plane,
|
||||||
const K&)
|
const K& k)
|
||||||
{
|
{
|
||||||
typedef typename Intersection_traits<K,
|
typedef typename K::Point_3 Point_3;
|
||||||
typename K::Tetrahedron_3,
|
typedef typename Intersection_traits<K, typename K::Tetrahedron_3, typename K::Plane_3>::result_type result_type;
|
||||||
typename K::Plane_3>::result_type result_type;
|
typename K::Oriented_side_3 oriented_side = k.oriented_side_3_object();
|
||||||
|
|
||||||
typedef typename Intersection_traits<K,
|
std::vector<Point_3> corners(4);
|
||||||
typename K::Triangle_3,
|
corners.reserve(8); // 4 corners + up to 4 polygon points
|
||||||
typename K::Plane_3>::result_type Inter_type;
|
corners[0] = tet[0];
|
||||||
|
corners[1] = tet[1];
|
||||||
|
corners[2] = tet[2];
|
||||||
|
corners[3] = tet[3];
|
||||||
|
|
||||||
typedef typename K::Segment_3 Segment_3;
|
const std::array<CGAL::Oriented_side, 4> orientations { {
|
||||||
Inter_type intersections[4];
|
oriented_side(plane, corners[0]),
|
||||||
int p_id = -1;
|
oriented_side(plane, corners[1]),
|
||||||
std::vector<typename K::Point_3> points;
|
oriented_side(plane, corners[2]),
|
||||||
std::vector<Segment_3> segments;
|
oriented_side(plane, corners[3])
|
||||||
for(int i = 0; i < 4; ++i)
|
} };
|
||||||
|
|
||||||
|
// description of faces of the bbox
|
||||||
|
constexpr std::array<int, 12> face_indices
|
||||||
|
{ { 0, 1, 2,
|
||||||
|
0, 1, 3,
|
||||||
|
1, 2, 3,
|
||||||
|
2, 0, 3 } };
|
||||||
|
|
||||||
|
constexpr std::array<int, 12> edge_indices
|
||||||
|
{ { 0, 1, 2,
|
||||||
|
0, 3, 5,
|
||||||
|
1, 4, 3,
|
||||||
|
2, 5, 4 } };
|
||||||
|
|
||||||
|
std::array<int, 12> edge_ipt_id;
|
||||||
|
edge_ipt_id.fill(-1);
|
||||||
|
|
||||||
|
auto inter_pt_index =
|
||||||
|
[&plane, &corners, &edge_ipt_id](int i, int j, int edge_id)
|
||||||
{
|
{
|
||||||
const typename K::Triangle_3 triangle(tet.vertex((i+1)%4),
|
if (edge_ipt_id[edge_id]==-1)
|
||||||
tet.vertex((i+2)%4),
|
{
|
||||||
tet.vertex((i+3)%4));
|
edge_ipt_id[edge_id] = static_cast<int> (corners.size());
|
||||||
intersections[i] = typename K::Intersect_3()(pl, triangle);
|
corners.push_back(typename K::Construct_plane_line_intersection_point_3()
|
||||||
if(intersections[i]){
|
(plane, corners[i], corners[j]));
|
||||||
if(const typename K::Triangle_3* tr = boost::get<typename K::Triangle_3>(&*intersections[i]))
|
}
|
||||||
|
|
||||||
|
return edge_ipt_id[edge_id];
|
||||||
|
};
|
||||||
|
|
||||||
|
bool all_in = true;
|
||||||
|
bool all_out = true;
|
||||||
|
|
||||||
|
std::vector<std::array<int,2>> neighbor_ids(8, {-1,-1});
|
||||||
|
|
||||||
|
auto add_neighbor = [&neighbor_ids](int i, int j)
|
||||||
|
{
|
||||||
|
if (neighbor_ids[i][0] == -1 ) {
|
||||||
|
neighbor_ids[i][0] = j;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (neighbor_ids[i][0]!=j && neighbor_ids[i][1]==-1)
|
||||||
{
|
{
|
||||||
typename K::Triangle_3 res = *tr;
|
neighbor_ids[i][1] = j;
|
||||||
return result_type(std::forward<typename K::Triangle_3>(res));
|
|
||||||
}
|
|
||||||
else if( const Segment_3* s
|
|
||||||
= boost::get<Segment_3>(&*intersections[i]))
|
|
||||||
{
|
|
||||||
segments.push_back(*s);
|
|
||||||
}
|
|
||||||
else if( const typename K::Point_3* p
|
|
||||||
= boost::get<typename K::Point_3>(&*intersections[i]))
|
|
||||||
{
|
|
||||||
points.push_back(*p);
|
|
||||||
p_id = i;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
CGAL_assertion(segments.size() != 1);
|
|
||||||
|
|
||||||
switch(segments.size())
|
int start_id = -1;
|
||||||
|
int solo_id = -1;
|
||||||
|
// for each face of the bbox, we look for intersection of the plane with its edges
|
||||||
|
std::vector<int> ids;
|
||||||
|
for (int i = 0; i < 4; ++i)
|
||||||
{
|
{
|
||||||
case 0:
|
ids.clear();
|
||||||
{
|
for (int k = 0; k < 3; ++k)
|
||||||
if(p_id == -1)
|
|
||||||
return result_type();
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
typename K::Point_3 p
|
|
||||||
= *boost::get<typename K::Point_3>(&*intersections[p_id]);
|
|
||||||
|
|
||||||
return result_type(std::forward<typename K::Point_3>(p));
|
int current_id = face_indices[3 * i + k];
|
||||||
|
int next_id = face_indices[3 * i + (k + 1) % 3];
|
||||||
|
int edge_id = edge_indices[3 * i + k];
|
||||||
|
|
||||||
|
switch (orientations[current_id])
|
||||||
|
{
|
||||||
|
case ON_NEGATIVE_SIDE:
|
||||||
|
{
|
||||||
|
all_out = false;
|
||||||
|
// check for intersection of the edge
|
||||||
|
if (orientations[next_id] == ON_POSITIVE_SIDE)
|
||||||
|
{
|
||||||
|
ids.push_back(
|
||||||
|
inter_pt_index(current_id, next_id, edge_id));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ON_POSITIVE_SIDE:
|
||||||
|
{
|
||||||
|
all_in = false;
|
||||||
|
// check for intersection of the edge
|
||||||
|
if (orientations[next_id] == ON_NEGATIVE_SIDE)
|
||||||
|
{
|
||||||
|
ids.push_back(inter_pt_index(current_id, next_id, edge_id));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ON_ORIENTED_BOUNDARY:
|
||||||
|
{
|
||||||
|
all_in = all_out = false;
|
||||||
|
ids.push_back(current_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
switch (ids.size())
|
||||||
case 2:
|
|
||||||
{
|
|
||||||
return result_type(std::forward<typename K::Segment_3>(segments.back()));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
std::set<typename K::Point_3> all_points;
|
|
||||||
for (const auto& s : segments)
|
|
||||||
{
|
{
|
||||||
all_points.insert(s.source());
|
case 3:
|
||||||
all_points.insert(s.target());
|
{
|
||||||
}
|
std::vector<Point_3> res({ corners[ids[0]],
|
||||||
if(all_points.size() == 3)
|
corners[ids[1]],
|
||||||
{
|
corners[ids[2]] });
|
||||||
auto p_it = all_points.begin();
|
return result_type(res);
|
||||||
++p_it;
|
}
|
||||||
typename K::Point_3 mid_point = *p_it;
|
case 2:
|
||||||
++p_it;
|
{
|
||||||
typename K::Triangle_3 result(*all_points.begin(), mid_point, *p_it );
|
if (start_id == -1) start_id = ids[0];
|
||||||
return result_type(std::forward<typename K::Triangle_3>(result));
|
add_neighbor(ids[0], ids[1]);
|
||||||
}
|
add_neighbor(ids[1], ids[0]);
|
||||||
else //size = 4
|
break;
|
||||||
{
|
}
|
||||||
std::list<Segment_3> segs(segments.begin(), segments.end());
|
case 1:
|
||||||
std::list<typename K::Point_3> tmp;
|
solo_id = ids[0];
|
||||||
fill_points_list(segs, tmp);
|
default:
|
||||||
std::vector<typename K::Point_3> res;
|
break;
|
||||||
for( const auto& p : tmp)
|
|
||||||
res.push_back(p);
|
|
||||||
return result_type(std::forward<std::vector<typename K::Point_3> >(res));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
if (all_in || all_out) return boost::none;
|
||||||
CGAL_assertion(false);
|
if (start_id == -1) return { result_type(corners[solo_id]) };
|
||||||
return result_type();
|
|
||||||
|
int prv_id = -1;
|
||||||
|
int cur_id = start_id;
|
||||||
|
std::vector<Point_3> res;
|
||||||
|
res.reserve(4);
|
||||||
|
do {
|
||||||
|
res.push_back(corners[cur_id]);
|
||||||
|
int nxt_id = neighbor_ids[cur_id][0] == prv_id
|
||||||
|
? neighbor_ids[cur_id][1]
|
||||||
|
: neighbor_ids[cur_id][0];
|
||||||
|
if (nxt_id == -1 || nxt_id == start_id){
|
||||||
|
if(res.size() == 2){
|
||||||
|
typename K::Segment_3 seg(res[0], res[1]);
|
||||||
|
return result_type(seg);
|
||||||
|
}
|
||||||
|
if(res.size() == 3){
|
||||||
|
typename K::Triangle_3 tr(res[0], res[1], res[2]);
|
||||||
|
return result_type(tr);
|
||||||
|
}
|
||||||
|
return result_type(res);
|
||||||
|
}
|
||||||
|
prv_id = cur_id;
|
||||||
|
cur_id = nxt_id;
|
||||||
|
} while (true);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class K>
|
template <class K>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue