From 277c5ef9e9e14aa1f5b473f2105d40fff35dab45 Mon Sep 17 00:00:00 2001 From: wmayer Date: Tue, 19 Oct 2021 15:14:36 +0200 Subject: [PATCH] Mesh: [skip ci] update tri-tri-intersection --- src/Mod/Mesh/App/Core/tritritest.h | 116 +++++++++++++++++------------ 1 file changed, 67 insertions(+), 49 deletions(-) diff --git a/src/Mod/Mesh/App/Core/tritritest.h b/src/Mod/Mesh/App/Core/tritritest.h index 7dc63b1774..35f34b7536 100644 --- a/src/Mod/Mesh/App/Core/tritritest.h +++ b/src/Mod/Mesh/App/Core/tritritest.h @@ -14,20 +14,38 @@ * Here is a version withouts divisions (a little faster) * int NoDivTriTriIsect(float V0[3],float V1[3],float V2[3], * float U0[3],float U1[3],float U2[3]); - * + * * This version computes the line of intersection as well (if they are not coplanar): - * int tri_tri_intersect_with_isectline(float V0[3],float V1[3],float V2[3], + * int tri_tri_intersect_with_isectline(float V0[3],float V1[3],float V2[3], * float U0[3],float U1[3],float U2[3],int *coplanar, * float isectpt1[3],float isectpt2[3]); * coplanar returns whether the tris are coplanar * isectpt1, isectpt2 are the endpoints of the line of intersection */ + /* +Copyright 2020 Tomas Akenine-Möller + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and +to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS +OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + + #include #define FABS(x) ((float)fabs(x)) /* implement as is fastest on your machine */ -/* if USE_EPSILON_TEST is true then we do a check: +/* if USE_EPSILON_TEST is true then we do a check: if |dv|=f) return 1; \ } \ - } + } #define EDGE_AGAINST_TRI_EDGES(V0,V1,U0,U1,U2) \ { \ @@ -172,7 +190,7 @@ int coplanar_tri_tri(float N[3],float V0[3],float V1[3],float V2[3], A[2]=fabs(N[2]); if(A[0]>A[1]) { - if(A[0]>A[2]) + if(A[0]>A[2]) { i0=1; /* A[0] is greatest */ i1=2; @@ -188,20 +206,20 @@ int coplanar_tri_tri(float N[3],float V0[3],float V1[3],float V2[3], if(A[2]>A[1]) { i0=0; /* A[2] is greatest */ - i1=1; + i1=1; } else { i0=0; /* A[1] is greatest */ i1=2; } - } - + } + /* test all edges of triangle 1 against the edges of triangle 2 */ EDGE_AGAINST_TRI_EDGES(V0,V1,U0,U1,U2); EDGE_AGAINST_TRI_EDGES(V1,V2,U0,U1,U2); EDGE_AGAINST_TRI_EDGES(V2,V0,U0,U1,U2); - + /* finally, test if tri1 is totally contained in tri2 or vice versa */ POINT_IN_TRI(V0,U0,U1,U2); POINT_IN_TRI(U0,V0,V1,V2); @@ -268,7 +286,7 @@ int tri_tri_intersect(float V0[3],float V1[3],float V2[3], dv0dv1=dv0*dv1; dv0dv2=dv0*dv2; - + if(dv0dv1>0.0f && dv0dv2>0.0f) /* same sign on all of them + not equal 0 ? */ return 0; /* no intersection occurs */ @@ -287,7 +305,7 @@ int tri_tri_intersect(float V0[3],float V1[3],float V2[3], vp0=V0[index]; vp1=V1[index]; vp2=V2[index]; - + up0=U0[index]; up1=U1[index]; up2=U2[index]; @@ -465,16 +483,16 @@ int NoDivTriTriIsect(float V0[3],float V1[3],float V2[3], inline void isect2(float VTX0[3],float VTX1[3],float VTX2[3],float VV0,float VV1,float VV2, - float D0,float D1,float D2,float *isect0,float *isect1,float isectpoint0[3],float isectpoint1[3]) + float D0,float D1,float D2,float *isect0,float *isect1,float isectpoint0[3],float isectpoint1[3]) { - float tmp=D0/(D0-D1); + float tmp=D0/(D0-D1); float diff[3]; - *isect0=VV0+(VV1-VV0)*tmp; + *isect0=VV0+(VV1-VV0)*tmp; SUB(diff,VTX1,VTX0); MULT(diff,diff,tmp); ADD(isectpoint0,diff,VTX0); - tmp=D0/(D0-D2); - *isect1=VV0+(VV2-VV0)*tmp; + tmp=D0/(D0-D2); + *isect1=VV0+(VV2-VV0)*tmp; SUB(diff,VTX2,VTX0); MULT(diff,diff,tmp); ADD(isectpoint1,VTX0,diff); @@ -500,33 +518,33 @@ inline int compute_intervals_isectline(float VERT0[3],float VERT1[3],float VERT2 float D0D1,float D0D2,float *isect0,float *isect1, float isectpoint0[3],float isectpoint1[3]) { - if(D0D1>0.0f) - { - /* here we know that D0D2<=0.0 */ + if(D0D1>0.0f) + { + /* here we know that D0D2<=0.0 */ /* that is D0, D1 are on the same side, D2 on the other or on the plane */ isect2(VERT2,VERT0,VERT1,VV2,VV0,VV1,D2,D0,D1,isect0,isect1,isectpoint0,isectpoint1); - } - else if(D0D2>0.0f) - { - /* here we know that d0d1<=0.0 */ + } + else if(D0D2>0.0f) + { + /* here we know that d0d1<=0.0 */ isect2(VERT1,VERT0,VERT2,VV1,VV0,VV2,D1,D0,D2,isect0,isect1,isectpoint0,isectpoint1); - } - else if(D1*D2>0.0f || D0!=0.0f) - { + } + else if(D1*D2>0.0f || D0!=0.0f) + { /* here we know that d0d1<=0.0 or that D0!=0.0 */ - isect2(VERT0,VERT1,VERT2,VV0,VV1,VV2,D0,D1,D2,isect0,isect1,isectpoint0,isectpoint1); - } - else if(D1!=0.0f) - { - isect2(VERT1,VERT0,VERT2,VV1,VV0,VV2,D1,D0,D2,isect0,isect1,isectpoint0,isectpoint1); - } - else if(D2!=0.0f) - { - isect2(VERT2,VERT0,VERT1,VV2,VV0,VV1,D2,D0,D1,isect0,isect1,isectpoint0,isectpoint1); - } - else - { - /* triangles are coplanar */ + isect2(VERT0,VERT1,VERT2,VV0,VV1,VV2,D0,D1,D2,isect0,isect1,isectpoint0,isectpoint1); + } + else if(D1!=0.0f) + { + isect2(VERT1,VERT0,VERT2,VV1,VV0,VV2,D1,D0,D2,isect0,isect1,isectpoint0,isectpoint1); + } + else if(D2!=0.0f) + { + isect2(VERT2,VERT0,VERT1,VV2,VV0,VV1,D2,D0,D1,isect0,isect1,isectpoint0,isectpoint1); + } + else + { + /* triangles are coplanar */ return 1; } return 0; @@ -538,7 +556,7 @@ inline int compute_intervals_isectline(float VERT0[3],float VERT1[3],float VERT2 /* here we know that D0D2<=0.0 */ \ /* that is D0, D1 are on the same side, D2 on the other or on the plane */ \ isect2(VERT2,VERT0,VERT1,VV2,VV0,VV1,D2,D0,D1,&isect0,&isect1,isectpoint0,isectpoint1); \ - } + } #if 0 else if(D0D2>0.0f) \ { \ @@ -628,7 +646,7 @@ int tri_tri_intersect_with_isectline(float V0[3],float V1[3],float V2[3], dv0dv1=dv0*dv1; dv0dv2=dv0*dv2; - + if(dv0dv1>0.0f && dv0dv2>0.0f) /* same sign on all of them + not equal 0 ? */ return 0; /* no intersection occurs */ @@ -647,7 +665,7 @@ int tri_tri_intersect_with_isectline(float V0[3],float V1[3],float V2[3], vp0=V0[index]; vp1=V1[index]; vp2=V2[index]; - + up0=U0[index]; up1=U1[index]; up2=U2[index]; @@ -655,7 +673,7 @@ int tri_tri_intersect_with_isectline(float V0[3],float V1[3],float V2[3], /* compute interval for triangle 1 */ *coplanar=compute_intervals_isectline(V0,V1,V2,vp0,vp1,vp2,dv0,dv1,dv2, dv0dv1,dv0dv2,&isect1[0],&isect1[1],isectpointA1,isectpointA2); - if(*coplanar) return coplanar_tri_tri(N1,V0,V1,V2,U0,U1,U2); + if(*coplanar) return coplanar_tri_tri(N1,V0,V1,V2,U0,U1,U2); /* compute interval for triangle 2 */ @@ -693,12 +711,12 @@ int tri_tri_intersect_with_isectline(float V0[3],float V1[3],float V2[3], if(isect2[1]>isect1[1]) { if(smallest1==0) { SET(isectpt2,isectpointA2); } - else { SET(isectpt2,isectpointA1); } + else { SET(isectpt2,isectpointA1); } } else { if(smallest2==0) { SET(isectpt2,isectpointB2); } - else { SET(isectpt2,isectpointB1); } + else { SET(isectpt2,isectpointB1); } } } return 1;