Speed up of libigl SelfIntersectMesh:
The test for intersection of two triangles sharing a common edge
has been optimized to reject non-overlaping triangles with
the least amount of exact arithmetics predicates.
Cherry pick of
d367762468
This commit is contained in:
parent
992a0c3d7a
commit
73f69f3387
1 changed files with 27 additions and 22 deletions
|
@ -635,13 +635,30 @@ inline bool igl::copyleft::cgal::SelfIntersectMesh<
|
||||||
{
|
{
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
// must be co-planar
|
auto opposite_vertex = [](const Index a0, const Index a1) {
|
||||||
if(
|
// get opposite index of A
|
||||||
A.supporting_plane() != B.supporting_plane() &&
|
int a2=-1;
|
||||||
A.supporting_plane() != B.supporting_plane().opposite())
|
for(int c=0;c<3;++c)
|
||||||
{
|
if(c!=a0 && c!=a1) {
|
||||||
return false;
|
a2 = c;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
assert(a2 != -1);
|
||||||
|
return a2;
|
||||||
|
};
|
||||||
|
|
||||||
|
// must be co-planar
|
||||||
|
Index a2 = opposite_vertex(shared[0].first, shared[1].first);
|
||||||
|
if (! B.supporting_plane().has_on(A.vertex(a2)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Index b2 = opposite_vertex(shared[0].second, shared[1].second);
|
||||||
|
|
||||||
|
if (int(CGAL::coplanar_orientation(A.vertex(shared[0].first), A.vertex(shared[1].first), A.vertex(a2))) *
|
||||||
|
int(CGAL::coplanar_orientation(B.vertex(shared[0].second), B.vertex(shared[1].second), B.vertex(b2))) < 0)
|
||||||
|
// There is certainly no self intersection as the non-shared triangle vertices lie on opposite sides of the shared edge.
|
||||||
|
return false;
|
||||||
|
|
||||||
// Since A and B are non-degenerate the intersection must be a polygon
|
// Since A and B are non-degenerate the intersection must be a polygon
|
||||||
// (triangle). Either
|
// (triangle). Either
|
||||||
// - the vertex of A (B) opposite the shared edge of lies on B (A), or
|
// - the vertex of A (B) opposite the shared edge of lies on B (A), or
|
||||||
|
@ -650,22 +667,10 @@ inline bool igl::copyleft::cgal::SelfIntersectMesh<
|
||||||
// Determine if the vertex opposite edge (a0,a1) in triangle A lies in
|
// Determine if the vertex opposite edge (a0,a1) in triangle A lies in
|
||||||
// (intersects) triangle B
|
// (intersects) triangle B
|
||||||
const auto & opposite_point_inside = [](
|
const auto & opposite_point_inside = [](
|
||||||
const Triangle_3 & A, const Index a0, const Index a1, const Triangle_3 & B)
|
const Triangle_3 & A, const Index a2, const Triangle_3 & B)
|
||||||
-> bool
|
-> bool
|
||||||
{
|
{
|
||||||
// get opposite index
|
return CGAL::do_intersect(A.vertex(a2),B);
|
||||||
Index a2 = -1;
|
|
||||||
for(int c = 0;c<3;c++)
|
|
||||||
{
|
|
||||||
if(c != a0 && c != a1)
|
|
||||||
{
|
|
||||||
a2 = c;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assert(a2 != -1);
|
|
||||||
bool ret = CGAL::do_intersect(A.vertex(a2),B);
|
|
||||||
return ret;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Determine if edge opposite vertex va in triangle A intersects edge
|
// Determine if edge opposite vertex va in triangle A intersects edge
|
||||||
|
@ -681,8 +686,8 @@ inline bool igl::copyleft::cgal::SelfIntersectMesh<
|
||||||
};
|
};
|
||||||
|
|
||||||
if(
|
if(
|
||||||
!opposite_point_inside(A,shared[0].first,shared[1].first,B) &&
|
!opposite_point_inside(A,a2,B) &&
|
||||||
!opposite_point_inside(B,shared[0].second,shared[1].second,A) &&
|
!opposite_point_inside(B,b2,A) &&
|
||||||
!opposite_edges_intersect(A,shared[0].first,B,shared[1].second) &&
|
!opposite_edges_intersect(A,shared[0].first,B,shared[1].second) &&
|
||||||
!opposite_edges_intersect(A,shared[1].first,B,shared[0].second))
|
!opposite_edges_intersect(A,shared[1].first,B,shared[0].second))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue