Fix Operazioni booleane e taglio trimesh con un piano
This commit is contained in:
@@ -75,10 +75,10 @@ IntersSurfTmSurfTm( const ISurfTriMesh& Stm1, const ISurfTriMesh& Stm2,
|
||||
// intersezione tra i triangoli
|
||||
Point3d ptInt, ptInt2 ;
|
||||
TRIA3DVECTOR vIttTria ;
|
||||
int nResEx = IntersTriaTria( TriaA, TriaB, ptInt, ptInt2, vIttTria) ;
|
||||
int nRes = FromSpecialToNormal( nResEx) ;
|
||||
int nRes = IntersTriaTria( TriaA, TriaB, ptInt, ptInt2, vIttTria) ;
|
||||
// se punto
|
||||
if ( nRes == ITTT_VERT || nRes == ITTT_PNT) {
|
||||
if ( nRes == ITTT_VERT_VERT || nRes == ITTT_VERT_EDGE || nRes == ITTT_VERT_INT ||
|
||||
nRes == ITTT_EDGE_VERT || nRes == ITTT_EDGE_EDGE_PNT || nRes == ITTT_INT_VERT) {
|
||||
// verifico se punto già inserito
|
||||
int nId ;
|
||||
if ( ! PtGrid.Find( ptInt, 10 * EPS_SMALL, nId)) {
|
||||
@@ -87,7 +87,8 @@ IntersSurfTmSurfTm( const ISurfTriMesh& Stm1, const ISurfTriMesh& Stm2,
|
||||
}
|
||||
}
|
||||
// se altrimenti segmento
|
||||
else if ( nRes == ITTT_EDGE || nRes == ITTT_YES) {
|
||||
else if ( nRes == ITTT_EDGE_EDGE_SEG || nRes == ITTT_EDGE_INT ||
|
||||
nRes == ITTT_INT_EDGE || nRes == ITTT_INT_INT_SEG ) {
|
||||
// se abbastanza lungo
|
||||
if ( ! AreSamePointApprox( ptInt, ptInt2)) {
|
||||
// verifico se già inserito
|
||||
@@ -217,3 +218,4 @@ IntersSurfTmSurfTm( const ISurfTriMesh& Stm1, const ISurfTriMesh& Stm2,
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
+337
-51
@@ -25,20 +25,16 @@
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int nTriaTriaIntersCases[6][6] = { { ITTTS_NO, ITTTS_NO, ITTTS_NO, ITTTS_NO, ITTTS_NO, ITTTS_NO },
|
||||
{ ITTTS_NO, ITTTS_INT_INT_SEG, ITTTS_INT_EDGE, ITTTS_NO, ITTTS_NO, ITTTS_NO },
|
||||
{ ITTTS_NO, ITTTS_EDGE_INT, ITTTS_EDGE_EDGE_SEG, ITTTS_NO, ITTTS_NO, ITTTS_NO },
|
||||
{ ITTTS_NO, ITTTS_NO, ITTTS_NO, ITTTS_VERT_VERT, ITTTS_VERT_EDGE, ITTTS_VERT_INT },
|
||||
{ ITTTS_NO, ITTTS_NO, ITTTS_NO, ITTTS_EDGE_VERT, ITTTS_EDGE_EDGE_PNT, ITTTS_NO },
|
||||
{ ITTTS_NO, ITTTS_NO, ITTTS_NO, ITTTS_INT_VERT, ITTTS_NO, ITTTS_NO } } ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static int IntersCoplanarTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, TRIA3DVECTOR& vTria) ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static int FindTriaTriaIntersType( const Triangle3d& trTria1, const Triangle3d& trTria2, const Point3d& ptLineSt, const Vector3d& vtLineDir,
|
||||
double dStU1, double dEnU1, double dStU2, double dEnU2, int nRes1, int nRes2, double& dIntStU, double& dIntEnU) ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
IntersTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, Point3d& ptInt, Point3d& ptInt2, TRIA3DVECTOR& vTria)
|
||||
IntersTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, Point3d& ptInt, Point3d& ptInt2, TRIA3DVECTOR& vTria, bool bSpecial)
|
||||
{
|
||||
// piano del secondo triangolo
|
||||
Plane3d plTria2 ;
|
||||
@@ -79,8 +75,8 @@ IntersTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, Point3d& p
|
||||
return ITTT_NO ;
|
||||
|
||||
// intersezione tra i piani dei due triangoli
|
||||
Point3d ptL1 ; Vector3d vtL1 ;
|
||||
int nResPP = IntersPlanePlane( plTria1, plTria2, ptL1, vtL1) ;
|
||||
Point3d ptL ; Vector3d vtL ;
|
||||
int nResPP = IntersPlanePlane( plTria1, plTria2, ptL, vtL) ;
|
||||
if ( nResPP == IPPT_NO)
|
||||
return ITTT_NO ;
|
||||
|
||||
@@ -91,47 +87,22 @@ IntersTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, Point3d& p
|
||||
return IntersCoplanarTriaTria( trTria1, trTria2, vTria) ;
|
||||
|
||||
// limito la linea di intersezione con il primo triangolo
|
||||
int nRes1 = IntersCoplanarLineTria( ptL1, vtL1, 100.0, trTria1, ptInt, ptInt2, false) ;
|
||||
if ( nRes1 == ILTT_NO)
|
||||
return ITTT_NO ;
|
||||
|
||||
// il segmento calcolato va limitato col secondo triangolo
|
||||
Point3d ptL2 = ptInt ;
|
||||
Vector3d vtL2 = vtL1 ;
|
||||
double dLen = 0 ;
|
||||
if ( nRes1 != ILTT_VERT) {
|
||||
vtL2 = ptInt2 - ptInt ;
|
||||
dLen = vtL2.Len() ;
|
||||
vtL2 /= dLen ;
|
||||
}
|
||||
Point3d ptI1 = ptInt ;
|
||||
Point3d ptI12 = ptInt2 ;
|
||||
int nRes2 = IntersCoplanarLineTria( ptL2, vtL2, dLen, trTria2, ptInt, ptInt2, true) ;
|
||||
|
||||
// gestione casi speciali apparentemente incongruenti
|
||||
if ( ( nRes1 == ILTT_SEGM && nRes2 == ILTT_EDGE) || ( nRes1 == ILTT_EDGE && nRes2 == ILTT_SEGM)) {
|
||||
if ( nRes1 == ILTT_SEGM) {
|
||||
if ( PointInTria( ptI1, trTria2) != PTT_OUT && PointInTria( ptI12, trTria2) != PTT_OUT) {
|
||||
ptInt = ( ptI1 + ptI12) / 2 ;
|
||||
ptInt2 = ( ptI1 + ptI12) / 2 ;
|
||||
return ITTTS_EDGE_EDGE_PNT ;
|
||||
}
|
||||
else
|
||||
return ITTTS_NO ;
|
||||
}
|
||||
else {
|
||||
Point3d ptI3, ptI32 ;
|
||||
IntersCoplanarLineTria( ptL1, vtL1, 100.0, trTria2, ptI3, ptI32, false) ;
|
||||
if ( PointInTria( ptI3, trTria1) != PTT_OUT && PointInTria( ptI32, trTria1) != PTT_OUT) {
|
||||
ptInt = ( ptI3 + ptI32) / 2 ;
|
||||
ptInt2 = ( ptI3 + ptI32) / 2 ;
|
||||
return ITTTS_EDGE_EDGE_PNT ;
|
||||
}
|
||||
else
|
||||
return ITTTS_NO ;
|
||||
}
|
||||
Point3d ptSt1, ptEn1 ;
|
||||
int nRes1 = IntersCoplanarLineTria( ptL, vtL, 100.0, trTria1, ptSt1, ptEn1, false) ;
|
||||
// limito la liena di intersezione con il secondo triangolo
|
||||
Point3d ptSt2, ptEn2 ;
|
||||
int nRes2 = IntersCoplanarLineTria( ptL, vtL, 100.0, trTria2, ptSt2, ptEn2, false) ;
|
||||
double dIntStU, dIntEnU;
|
||||
int nIntType = FindTriaTriaIntersType( trTria1, trTria2, ptL, vtL,
|
||||
( ptSt1 - ptL) * vtL, ( ptEn1 - ptL) * vtL,
|
||||
( ptSt2 - ptL) * vtL, ( ptEn2 - ptL) * vtL,
|
||||
nRes1, nRes2, dIntStU, dIntEnU) ;
|
||||
if ( nIntType != ITTT_NO) {
|
||||
ptInt = ptL + dIntStU * vtL ;
|
||||
ptInt2 = ptL + dIntEnU * vtL ;
|
||||
return nIntType ;
|
||||
}
|
||||
return nTriaTriaIntersCases[nRes1][nRes2] ;
|
||||
return ITTT_NO;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -225,3 +196,318 @@ IntersCoplanarTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, TR
|
||||
|
||||
return ITTT_OVERLAPS ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
FindTriaTriaIntersType( const Triangle3d& trTria1, const Triangle3d& trTria2, const Point3d& ptLineSt, const Vector3d& vtLineDir,
|
||||
double dStU1, double dEnU1, double dStU2, double dEnU2, int nRes1, int nRes2, double& dIntStU, double& dIntEnU)
|
||||
{
|
||||
// Controllo su validità input
|
||||
if ( ! ( trTria1.IsValid() && trTria2.IsValid() && vtLineDir.IsNormalized()))
|
||||
return ITTT_NO ;
|
||||
// Casi
|
||||
if ( nRes1 == ILTT_SEGM) {
|
||||
if ( nRes2 == ILTT_SEGM) {
|
||||
if ( dEnU2 < dStU1 - EPS_SMALL)
|
||||
return ITTT_NO ;
|
||||
else if ( dEnU2 < dStU1 + EPS_SMALL) {
|
||||
dIntStU = 0.5 * ( dStU1 + dEnU2) ;
|
||||
dIntEnU = 0.5 * ( dStU1 + dEnU2) ;
|
||||
Point3d ptInt = ptLineSt + dIntStU * vtLineDir ;
|
||||
bool bOnVert1 = false ;
|
||||
bool bOnVert2 = false ;
|
||||
for ( int n = 0 ; n < 3 ; ++ n) {
|
||||
if ( AreSamePointApprox( trTria1.GetP( n), ptInt))
|
||||
bOnVert1 = true ;
|
||||
if ( AreSamePointApprox( trTria2.GetP( n), ptInt))
|
||||
bOnVert2 = true ;
|
||||
}
|
||||
if ( bOnVert1) {
|
||||
if ( bOnVert2)
|
||||
return ITTT_VERT_VERT ;
|
||||
else
|
||||
return ITTT_VERT_EDGE ;
|
||||
}
|
||||
else if ( bOnVert2)
|
||||
return ITTT_EDGE_VERT ;
|
||||
else
|
||||
return ITTT_EDGE_EDGE_PNT ;
|
||||
}
|
||||
else if ( dStU2 < dEnU1 - EPS_SMALL) {
|
||||
dIntStU = max( dStU1, dStU2) ;
|
||||
dIntEnU = min( dEnU1, dEnU2) ;
|
||||
return ITTT_INT_INT_SEG ;
|
||||
}
|
||||
else if ( dStU2 < dEnU1 + EPS_SMALL) {
|
||||
dIntStU = 0.5 * ( dStU2 + dEnU1) ;
|
||||
dIntEnU = 0.5 * ( dStU2 + dEnU1) ;
|
||||
Point3d ptInt = ptLineSt + dIntStU * vtLineDir ;
|
||||
bool bOnVert1 = false;
|
||||
bool bOnVert2 = false;
|
||||
for ( int n = 0 ; n < 3 ; ++ n) {
|
||||
if ( AreSamePointApprox( trTria1.GetP( n), ptInt))
|
||||
bOnVert1 = true ;
|
||||
if ( AreSamePointApprox( trTria2.GetP( n), ptInt))
|
||||
bOnVert2 = true ;
|
||||
}
|
||||
if ( bOnVert1) {
|
||||
if ( bOnVert2)
|
||||
return ITTT_VERT_VERT ;
|
||||
else
|
||||
return ITTT_VERT_EDGE ;
|
||||
}
|
||||
else if ( bOnVert2)
|
||||
return ITTT_EDGE_VERT ;
|
||||
else
|
||||
return ITTT_EDGE_EDGE_PNT ;
|
||||
}
|
||||
else
|
||||
return ITTT_NO ;
|
||||
}
|
||||
else if ( nRes2 == ILTT_SEGM_ON_EDGE) {
|
||||
if ( dEnU2 < dStU1 - EPS_SMALL)
|
||||
return ITTT_NO ;
|
||||
else if ( dEnU2 < dStU1 + EPS_SMALL) {
|
||||
dIntStU = 0.5 * ( dStU1 + dEnU2) ;
|
||||
dIntEnU = 0.5 * ( dStU1 + dEnU2) ;
|
||||
Point3d ptInt = ptLineSt + dIntStU * vtLineDir ;
|
||||
bool bOnVert1 = false ;
|
||||
for ( int n = 0 ; n < 3 ; ++ n) {
|
||||
if ( AreSamePointApprox( trTria1.GetP( n), ptInt))
|
||||
bOnVert1 = true ;
|
||||
}
|
||||
if ( bOnVert1)
|
||||
return ITTT_VERT_VERT ;
|
||||
else
|
||||
return ITTT_EDGE_VERT ;
|
||||
}
|
||||
else if ( dStU2 < dEnU1 - EPS_SMALL) {
|
||||
dIntStU = max( dStU1, dStU2) ;
|
||||
dIntEnU = min( dEnU1, dEnU2) ;
|
||||
return ITTT_INT_EDGE ;
|
||||
}
|
||||
else if ( dStU2 < dEnU1 + EPS_SMALL) {
|
||||
dIntStU = 0.5 * ( dStU2 + dEnU1) ;
|
||||
dIntEnU = 0.5 * ( dStU2 + dEnU1) ;
|
||||
Point3d ptInt = ptLineSt + dIntStU * vtLineDir ;
|
||||
bool bOnVert1 = false ;
|
||||
for ( int n = 0 ; n < 3 ; ++ n) {
|
||||
if ( AreSamePointApprox( trTria1.GetP( n), ptInt))
|
||||
bOnVert1 = true ;
|
||||
}
|
||||
if ( bOnVert1)
|
||||
return ITTT_VERT_VERT ;
|
||||
else
|
||||
return ITTT_EDGE_VERT ;
|
||||
}
|
||||
else
|
||||
return ITTT_NO ;
|
||||
}
|
||||
else if ( nRes2 == ILTT_VERT) {
|
||||
dEnU2 = dStU2 ;
|
||||
if ( dStU2 < dStU1 - EPS_SMALL)
|
||||
return ITTT_NO ;
|
||||
else if ( dStU2 < dStU1 + EPS_SMALL) {
|
||||
dIntStU = 0.5 * ( dStU1 + dStU2) ;
|
||||
dIntEnU = 0.5 * ( dStU1 + dStU2) ;
|
||||
Point3d ptInt = ptLineSt + dIntStU * vtLineDir ;
|
||||
bool bOnVert1 = false ;
|
||||
for ( int n = 0 ; n < 3 ; ++ n) {
|
||||
if ( AreSamePointApprox( trTria1.GetP( n), ptInt))
|
||||
bOnVert1 = true ;
|
||||
}
|
||||
if ( bOnVert1)
|
||||
return ITTT_VERT_VERT ;
|
||||
else
|
||||
return ITTT_EDGE_VERT ;
|
||||
}
|
||||
else if ( dStU2 < dEnU1 - EPS_SMALL) {
|
||||
dIntStU = max( dStU1, dStU2) ;
|
||||
dIntEnU = min( dEnU1, dEnU2) ;
|
||||
return ITTT_INT_VERT ;
|
||||
}
|
||||
else if ( dStU2 < dEnU1 + EPS_SMALL) {
|
||||
dIntStU = 0.5 * ( dStU2 + dEnU1) ;
|
||||
dIntEnU = 0.5 * ( dStU2 + dEnU1) ;
|
||||
Point3d ptInt = ptLineSt + dIntStU * vtLineDir ;
|
||||
bool bOnVert1 = false ;
|
||||
for ( int n = 0 ; n < 3 ; ++ n) {
|
||||
if ( AreSamePointApprox( trTria1.GetP( n), ptInt))
|
||||
bOnVert1 = true ;
|
||||
}
|
||||
if ( bOnVert1)
|
||||
return ITTT_VERT_VERT ;
|
||||
else
|
||||
return ITTT_EDGE_VERT ;
|
||||
}
|
||||
else
|
||||
return ITTT_NO ;
|
||||
}
|
||||
else
|
||||
return ITTT_NO ;
|
||||
}
|
||||
else if ( nRes1 == ILTT_SEGM_ON_EDGE) {
|
||||
if ( nRes2 == ILTT_SEGM) {
|
||||
if ( dEnU2 < dStU1 - EPS_SMALL)
|
||||
return ITTT_NO ;
|
||||
else if ( dEnU2 < dStU1 + EPS_SMALL) {
|
||||
dIntStU = 0.5 * ( dStU1 + dEnU2) ;
|
||||
dIntEnU = 0.5 * ( dStU1 + dEnU2) ;
|
||||
Point3d ptInt = ptLineSt + dIntStU * vtLineDir ;
|
||||
bool bOnVert2 = false ;
|
||||
for ( int n = 0 ; n < 3 ; ++ n) {
|
||||
if ( AreSamePointApprox( trTria2.GetP( n), ptInt))
|
||||
bOnVert2 = true ;
|
||||
}
|
||||
if ( bOnVert2)
|
||||
return ITTT_VERT_VERT ;
|
||||
else
|
||||
return ITTT_VERT_EDGE ;
|
||||
}
|
||||
else if ( dStU2 < dEnU1 - EPS_SMALL) {
|
||||
dIntStU = max( dStU1, dStU2) ;
|
||||
dIntEnU = min( dEnU1, dEnU2) ;
|
||||
return ITTT_EDGE_INT ;
|
||||
}
|
||||
else if ( dStU2 < dEnU1 + EPS_SMALL) {
|
||||
dIntStU = 0.5 * ( dStU2 + dEnU1) ;
|
||||
dIntEnU = 0.5 * ( dStU2 + dEnU1) ;
|
||||
Point3d ptInt = ptLineSt + dIntStU * vtLineDir ;
|
||||
bool bOnVert2 = false ;
|
||||
for ( int n = 0 ; n < 3 ; ++ n) {
|
||||
if ( AreSamePointApprox( trTria2.GetP( n), ptInt))
|
||||
bOnVert2 = true ;
|
||||
}
|
||||
if ( bOnVert2)
|
||||
return ITTT_VERT_VERT ;
|
||||
else
|
||||
return ITTT_VERT_EDGE ;
|
||||
}
|
||||
else
|
||||
return ITTT_NO ;
|
||||
}
|
||||
else if ( nRes2 == ILTT_SEGM_ON_EDGE) {
|
||||
if ( dEnU2 < dStU1 - EPS_SMALL)
|
||||
return ITTT_NO ;
|
||||
else if ( dEnU2 < dStU1 + EPS_SMALL) {
|
||||
dIntStU = 0.5 * ( dStU1 + dEnU2) ;
|
||||
dIntEnU = 0.5 * ( dStU1 + dEnU2) ;
|
||||
return ITTT_VERT_VERT ;
|
||||
}
|
||||
else if ( dStU2 < dEnU1 - EPS_SMALL) {
|
||||
dIntStU = max( dStU1, dStU2) ;
|
||||
dIntEnU = min( dEnU1, dEnU2) ;
|
||||
return ITTT_EDGE_EDGE_SEG ;
|
||||
}
|
||||
else if ( dStU2 < dEnU1 + EPS_SMALL) {
|
||||
dIntStU = 0.5 * ( dStU2 + dEnU1) ;
|
||||
dIntEnU = 0.5 * ( dStU2 + dEnU1) ;
|
||||
return ITTT_VERT_VERT ;
|
||||
}
|
||||
else
|
||||
return ITTT_NO ;
|
||||
}
|
||||
else if ( nRes2 == ILTT_VERT) {
|
||||
dEnU2 = dStU2 ;
|
||||
if ( dEnU2 < dStU1 - EPS_SMALL)
|
||||
return ITTT_NO ;
|
||||
else if ( dEnU2 < dStU1 + EPS_SMALL) {
|
||||
dIntStU = 0.5 * ( dStU1 + dEnU2) ;
|
||||
dIntEnU = 0.5 * ( dStU1 + dEnU2) ;
|
||||
return ITTT_VERT_VERT ;
|
||||
}
|
||||
else if ( dStU2 < dEnU1 - EPS_SMALL) {
|
||||
dIntStU = max( dStU1, dStU2) ;
|
||||
dIntEnU = min( dEnU1, dEnU2) ;
|
||||
return ITTT_EDGE_VERT ;
|
||||
}
|
||||
else if ( dStU2 < dEnU1 + EPS_SMALL) {
|
||||
dIntStU = 0.5 * ( dStU2 + dEnU1) ;
|
||||
dIntEnU = 0.5 * ( dStU2 + dEnU1) ;
|
||||
return ITTT_VERT_VERT ;
|
||||
}
|
||||
else
|
||||
return ITTT_NO ;
|
||||
}
|
||||
else
|
||||
return ITTT_NO ;
|
||||
}
|
||||
else if ( nRes1 == ILTT_VERT) {
|
||||
dEnU1 = dStU1 ;
|
||||
if ( nRes2 == ILTT_SEGM) {
|
||||
if ( dEnU2 < dStU1 - EPS_SMALL)
|
||||
return ITTT_NO ;
|
||||
else if ( dEnU2 < dStU1 + EPS_SMALL) {
|
||||
dIntStU = 0.5 * ( dStU1 + dEnU2) ;
|
||||
dIntEnU = 0.5 * ( dStU1 + dEnU2) ;
|
||||
Point3d ptInt = ptLineSt + dIntStU * vtLineDir ;
|
||||
bool bOnVert2 = false ;
|
||||
for ( int n = 0 ; n < 3 ; ++ n) {
|
||||
if ( AreSamePointApprox( trTria2.GetP( n), ptInt))
|
||||
bOnVert2 = true ;
|
||||
}
|
||||
if ( bOnVert2)
|
||||
return ITTT_VERT_VERT ;
|
||||
else
|
||||
return ITTT_VERT_EDGE ;
|
||||
}
|
||||
else if ( dStU2 < dEnU1 - EPS_SMALL) {
|
||||
dIntStU = max( dStU1, dStU2) ;
|
||||
dIntEnU = min( dEnU1, dEnU2) ;
|
||||
return ITTT_VERT_INT ;
|
||||
}
|
||||
else if ( dStU2 < dEnU1 + EPS_SMALL) {
|
||||
dIntStU = 0.5 * ( dStU2 + dEnU1) ;
|
||||
dIntEnU = 0.5 * ( dStU2 + dEnU1) ;
|
||||
Point3d ptInt = ptLineSt + dIntStU * vtLineDir ;
|
||||
bool bOnVert2 = false ;
|
||||
for ( int n = 0 ; n < 3 ; ++ n) {
|
||||
if ( AreSamePointApprox( trTria2.GetP( n), ptInt))
|
||||
bOnVert2 = true ;
|
||||
}
|
||||
if ( bOnVert2)
|
||||
return ITTT_VERT_VERT ;
|
||||
else
|
||||
return ITTT_VERT_EDGE ;
|
||||
}
|
||||
else
|
||||
return ITTT_NO ;
|
||||
}
|
||||
else if ( nRes2 == ILTT_SEGM_ON_EDGE) {
|
||||
if ( dEnU2 < dStU1 - EPS_SMALL)
|
||||
return ITTT_NO ;
|
||||
else if ( dEnU2 < dStU1 + EPS_SMALL) {
|
||||
dIntStU = 0.5 * ( dStU1 + dEnU2) ;
|
||||
dIntEnU = 0.5 * ( dStU1 + dEnU2) ;
|
||||
return ITTT_VERT_VERT ;
|
||||
}
|
||||
else if ( dStU2 < dEnU1 - EPS_SMALL) {
|
||||
dIntStU = max( dStU1, dStU2) ;
|
||||
dIntEnU = min( dEnU1, dEnU2) ;
|
||||
return ITTT_VERT_EDGE ;
|
||||
}
|
||||
else if ( dStU2 < dEnU1 + EPS_SMALL) {
|
||||
dIntStU = 0.5 * ( dStU1 + dStU2) ;
|
||||
dIntEnU = 0.5 * ( dStU1 + dStU2) ;
|
||||
return ITTT_VERT_VERT ;
|
||||
}
|
||||
else
|
||||
return ITTT_NO ;
|
||||
}
|
||||
else if ( nRes2 == ILTT_VERT) {
|
||||
if ( dStU2 < dStU1 - EPS_SMALL)
|
||||
return ITTT_NO ;
|
||||
else if ( dStU2 < dStU1 + EPS_SMALL) {
|
||||
dIntStU = 0.5 * ( dStU1 + dStU2) ;
|
||||
dIntEnU = 0.5 * ( dStU1 + dStU2) ;
|
||||
return ITTT_VERT_VERT ;
|
||||
}
|
||||
else
|
||||
return ITTT_NO ;
|
||||
}
|
||||
else
|
||||
return ITTT_NO ;
|
||||
}
|
||||
else
|
||||
return ITTT_NO ;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "CurveComposite.h"
|
||||
#include "SurfFlatRegion.h"
|
||||
#include "GeoConst.h"
|
||||
#include "/EgtDev/Include/EgkPolyLine.h"
|
||||
#include "/EgtDev/Include/EgkBiArcs.h"
|
||||
#include "/EgtDev/Include/EgkOffsetCurve.h"
|
||||
#include "/EgtDev/Include/EGkSfrCreate.h"
|
||||
@@ -275,6 +276,68 @@ GetSurfFlatRegionFromFatCurve( ICurve* pCrv, double dRadius, bool bSquareEnds, b
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
ISurfFlatRegion*
|
||||
GetSurfFlatRegionFromPolyLine( const PolyLine& ContourPolyLine)
|
||||
{
|
||||
// Creo la regione.
|
||||
PtrOwner<SurfFlatRegion> pSfr( CreateBasicSurfFlatRegion()) ;
|
||||
if ( IsNull( pSfr))
|
||||
return nullptr ;
|
||||
// Creo curva composita.
|
||||
PtrOwner<CurveComposite> pLoop( CreateBasicCurveComposite()) ;
|
||||
if ( IsNull( pLoop))
|
||||
return nullptr ;
|
||||
Point3d ptSt, ptEn ;
|
||||
bool bContinue = ContourPolyLine.GetFirstPoint( ptSt) &&
|
||||
ContourPolyLine.GetNextPoint( ptEn) ;
|
||||
while ( bContinue) {
|
||||
CurveLine cvLine ;
|
||||
cvLine.Set( ptSt, ptEn) ;
|
||||
pLoop->AddCurve( cvLine) ;
|
||||
ptSt = ptEn ;
|
||||
bContinue = ContourPolyLine.GetNextPoint( ptEn) ;
|
||||
}
|
||||
pSfr->AddExtLoop( Release( pLoop)) ;
|
||||
return Release( pSfr) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
ISurfFlatRegion*
|
||||
GetSurfFlatRegionFromPolyLineVector( const POLYLINEVECTOR& vContoursPolyLineVec)
|
||||
{
|
||||
// Creo la regione.
|
||||
PtrOwner<SurfFlatRegion> pSfr( CreateBasicSurfFlatRegion()) ;
|
||||
if ( IsNull( pSfr))
|
||||
return nullptr ;
|
||||
// Ciclo sulle PolyLine.
|
||||
for ( int nL = 0 ; nL < int( vContoursPolyLineVec.size()) ; ++ nL) {
|
||||
// Creo curva composita.
|
||||
PtrOwner<CurveComposite> pLoop( CreateBasicCurveComposite()) ;
|
||||
if ( IsNull( pLoop))
|
||||
return nullptr ;
|
||||
Point3d ptSt, ptEn ;
|
||||
bool bContinue = vContoursPolyLineVec[nL].GetFirstPoint( ptSt) &&
|
||||
vContoursPolyLineVec[nL].GetNextPoint( ptEn) ;
|
||||
while ( bContinue) {
|
||||
CurveLine cvLine ;
|
||||
cvLine.Set( ptSt, ptEn) ;
|
||||
pLoop->AddCurve( cvLine) ;
|
||||
ptSt = ptEn ;
|
||||
bContinue = vContoursPolyLineVec[nL].GetNextPoint( ptEn) ;
|
||||
}
|
||||
// Loop esterno
|
||||
if ( nL == 0) {
|
||||
pSfr->AddExtLoop( Release( pLoop)) ;
|
||||
}
|
||||
// Loop interno
|
||||
else {
|
||||
pSfr->AddIntLoop( Release( pLoop)) ;
|
||||
}
|
||||
}
|
||||
return Release( pSfr) ;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Classe SurfFlatRegionByContours
|
||||
//-------------------------------------------------------------------------------
|
||||
|
||||
+83
-3
@@ -21,10 +21,13 @@
|
||||
#include "DistPointLine.h"
|
||||
#include "Triangulate.h"
|
||||
#include "GeoConst.h"
|
||||
#include "SurfFlatRegion.h"
|
||||
#include "/EgtDev/Include/EGkIntersLinePlane.h"
|
||||
#include "/EgtDev/Include/EGkPointGrid3d.h"
|
||||
#include "/EgtDev/Include/EGkPolyLine.h"
|
||||
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
||||
#include "/EgtDev/Include/EGkUiUnits.h"
|
||||
#include "/EgtDev/Include/EgkSfrCreate.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
#include <new>
|
||||
#include <set>
|
||||
@@ -3298,7 +3301,9 @@ SurfTriMesh::Invert( void)
|
||||
bool
|
||||
SurfTriMesh::Cut( const Plane3d& plPlane, bool bSaveOnEq)
|
||||
{
|
||||
// la superficie deve essere validata
|
||||
#define UseTria 0
|
||||
#if UseTria
|
||||
// la superficie deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
@@ -3502,14 +3507,89 @@ SurfTriMesh::Cut( const Plane3d& plPlane, bool bSaveOnEq)
|
||||
}
|
||||
}
|
||||
|
||||
// se effettuate modifiche
|
||||
// se effettuate modifiche
|
||||
if ( bModif) {
|
||||
// aggiorno tutto
|
||||
// aggiorno tutto
|
||||
if ( ! AdjustVertices() || ! DoCompacting())
|
||||
return false ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
#endif
|
||||
|
||||
#if ! UseTria
|
||||
|
||||
bool bModif = false ;
|
||||
|
||||
// Setto il triangolo come né fuori né dentro.
|
||||
int nTriaNum = GetTriangleSize();
|
||||
for ( int nT = 0 ; nT < nTriaNum ; ++ nT) {
|
||||
m_vTria[nT].nTempPart = 0 ;
|
||||
}
|
||||
|
||||
INTERSCHAINMAP IntersLineMap ;
|
||||
INTERSEDGEMAP EdgeInterLineMap ;
|
||||
INTERSEDGEMAP EdgeEdgeLineMap ;
|
||||
|
||||
// Ciclo su tutte le facce.
|
||||
int nFacetNum = GetFacetCount() ;
|
||||
for ( int nF = 0 ; nF < nFacetNum ; ++ nF) {
|
||||
// Dati della faccia
|
||||
POLYLINEVECTOR vLoopVec ;
|
||||
GetFacetLoops( nF, vLoopVec) ;
|
||||
if ( vLoopVec.empty())
|
||||
continue ;
|
||||
PtrOwner<SurfFlatRegion> pReg( GetBasicSurfFlatRegion( GetSurfFlatRegionFromPolyLineVector( vLoopVec))) ;
|
||||
if ( pReg == nullptr)
|
||||
return false ;
|
||||
SurfFlatRegion Region = *pReg ;
|
||||
LineFacetClassVector IntersLinePart ;
|
||||
int nIntType = IntersFacetPlane( Region, vLoopVec[0], plPlane, IntersLinePart) ;
|
||||
if ( nIntType == FacetPlaneIntersType::FPI_CUT) {
|
||||
for ( int nPart = 0 ; nPart < int( IntersLinePart.size()) ; ++ nPart) {
|
||||
// Salvo intersezione per la faccia.
|
||||
auto it = IntersLineMap.find( nF) ;
|
||||
if ( it != IntersLineMap.end()) {
|
||||
it->second.emplace_back( IntersInnSeg( IntersLinePart[nPart].ptSt, IntersLinePart[nPart].ptEn)) ;
|
||||
}
|
||||
else {
|
||||
IntersLineMap.emplace( nF, IntersInnChain( 1, IntersInnSeg( IntersLinePart[nPart].ptSt, IntersLinePart[nPart].ptEn))) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( nIntType == FacetPlaneIntersType::FPI_ON) {
|
||||
INTVECTOR vT ;
|
||||
GetAllTriaInFacet( nF, vT) ;
|
||||
for ( auto& nT : vT)
|
||||
m_vTria[nT].nTempPart = Region.GetNormVersor() * plPlane.GetVersN() > 0. ? 2 : - 2 ;
|
||||
}
|
||||
else if ( nIntType == FacetPlaneIntersType::FPI_INN) {
|
||||
INTVECTOR vT ;
|
||||
GetAllTriaInFacet( nF, vT) ;
|
||||
for ( auto& nT : vT)
|
||||
m_vTria[nT].nTempPart = 1 ;
|
||||
}
|
||||
else if ( nIntType == FacetPlaneIntersType::FPI_OUT) {
|
||||
INTVECTOR vT ;
|
||||
GetAllTriaInFacet( nF, vT) ;
|
||||
for ( auto& nT : vT)
|
||||
m_vTria[nT].nTempPart = - 1 ;
|
||||
}
|
||||
else
|
||||
;
|
||||
}
|
||||
// Divido le facce.
|
||||
PieceMap NewFacet ;
|
||||
SplitFacet( IntersLineMap, NewFacet) ;
|
||||
RetriangulateFacetPieces( NewFacet, EdgeInterLineMap, EdgeEdgeLineMap) ;
|
||||
|
||||
int nNumTria = GetTriangleSize() ;
|
||||
for ( int nT = 0 ; nT < nNumTria ; ++ nT)
|
||||
if ( m_vTria[nT].nTempPart == - 1 || m_vTria[nT].nTempPart == - 2 || ( ! bSaveOnEq && m_vTria[nT].nTempPart == 2))
|
||||
RemoveTriangle( nT) ;
|
||||
|
||||
return AdjustVertices() && DoCompacting() ;
|
||||
#endif
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#include <deque>
|
||||
#include <set>
|
||||
|
||||
class SurfFlatRegion ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Classe Vertice
|
||||
class StmVert
|
||||
@@ -110,6 +112,70 @@ typedef std::vector<TJuncLoop> TJuncLoopVec ;
|
||||
// Set di TEdgeId
|
||||
typedef std::set<TEdgeId> TJEdgeSet ;
|
||||
|
||||
// Definizione strutture intersezione linea-faccia
|
||||
//----------------------------------------------------------------------------
|
||||
struct LineFacetClass {
|
||||
Point3d ptSt, ptEn ;
|
||||
int nTypeA, nTypeB ;
|
||||
LineFacetClass() {
|
||||
nTypeA = 0 ;
|
||||
nTypeB = 0 ;
|
||||
}
|
||||
LineFacetClass( const Point3d& ptS, const Point3d ptE, int nTpA, int nTpB) {
|
||||
ptSt = ptS ;
|
||||
ptEn = ptE ;
|
||||
nTypeA = nTpA ;
|
||||
nTypeB = nTpB ;
|
||||
}
|
||||
} ;
|
||||
typedef std::vector<LineFacetClass> LineFacetClassVector ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
enum FacetPlaneIntersType { FPI_ERROR = 0, FPI_CUT = 1, FPI_INN = 2, FPI_OUT = 3, FPI_ON = 4 } ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Definizione strutture e contenitori
|
||||
// Contatti interno-interno
|
||||
struct IntersInnSeg {
|
||||
Point3d ptSt ;
|
||||
Point3d ptEn ;
|
||||
Vector3d vtOuter ;
|
||||
IntersInnSeg(void) {
|
||||
;
|
||||
}
|
||||
IntersInnSeg(const Point3d& ptS, const Point3d& ptE) {
|
||||
ptSt = ptS;
|
||||
ptEn = ptE;
|
||||
}
|
||||
IntersInnSeg(const Point3d& ptS, const Point3d& ptE, const Vector3d& vtO) {
|
||||
ptSt = ptS;
|
||||
ptEn = ptE;
|
||||
vtOuter = vtO;
|
||||
}
|
||||
};
|
||||
typedef std::vector<IntersInnSeg> IntersInnChain ;
|
||||
typedef std::vector<IntersInnChain> INNCHAINVECTOR ;
|
||||
typedef std::unordered_map<int, IntersInnChain> INTERSCHAINMAP ;
|
||||
// Contatti con spigolo
|
||||
struct IntersEdge {
|
||||
Point3d ptSt ;
|
||||
Point3d ptEn ;
|
||||
INTVECTOR vOthFacetIndex ;
|
||||
IntersEdge( const Point3d& ptS, const Point3d& ptE, const INTVECTOR& vOFI) {
|
||||
ptSt = ptS;
|
||||
ptEn = ptE;
|
||||
vOthFacetIndex = vOFI;
|
||||
}
|
||||
} ;
|
||||
typedef std::vector<IntersEdge> IntersEdgeVec ;
|
||||
typedef std::unordered_map<int, IntersEdgeVec> INTERSEDGEMAP ;
|
||||
// Parte di faccia
|
||||
struct FacetPiece {
|
||||
POLYLINEVECTOR vPieceLoop ;
|
||||
int nPiecePart ;
|
||||
} ;
|
||||
typedef std::unordered_map<int, std::vector<FacetPiece>> PieceMap ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
||||
{
|
||||
@@ -318,6 +384,22 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
||||
bool RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECTORMAP& Ambiguos, SurfTriMesh& Surf, bool& bModif) ;
|
||||
bool AmbiguosTriangleManager( TRIA3DVECTORMAP& Ambiguos, SurfTriMesh& Surf) ;
|
||||
bool IntersectTriMeshTriangle( SurfTriMesh& Other) ;
|
||||
int IntersFacetPlane( const SurfFlatRegion& Region, const PolyLine& ExtLoop, const Plane3d& plCutPlane,
|
||||
LineFacetClassVector& IntersLinePart) ;
|
||||
bool IntersFacetFacet( const SurfFlatRegion& RegionA, const PolyLine& ExtLoopA,
|
||||
const SurfFlatRegion& RegionB, const PolyLine& ExtLoopB,
|
||||
LineFacetClassVector& IntersLinePart) ;
|
||||
bool ItersectTriMeshFacets( SurfTriMesh& Other) ;
|
||||
bool RetriangulateFacetPieces( const PieceMap& NewFacet,
|
||||
const INTERSEDGEMAP& EdgeInterLineMap,
|
||||
const INTERSEDGEMAP& EdgeEdgeLineMap) ;
|
||||
bool EdgeInteriorContactManager( const SurfTriMesh& OthSurf,
|
||||
const INTERSCHAINMAP& InterInterLineMap,
|
||||
const INTERSEDGEMAP& EdgeInterLineMap) ;
|
||||
bool EdgeEdgeContactManager( const SurfTriMesh& OthSurf,
|
||||
const INTERSCHAINMAP& InterInterLineMap,
|
||||
const INTERSEDGEMAP& EdgeEdgeLineMap) ;
|
||||
bool SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet);
|
||||
bool IdentifyParts( void) const ;
|
||||
bool RemoveTJunctions( void) ;
|
||||
bool RemoveCaps( void) ;
|
||||
@@ -347,6 +429,14 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
||||
mutable BBox3d m_b3HGrd3d ; // Box3d collegato a Hash Grid 3d
|
||||
} ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool ChangePolyLineStart( const Point3d& ptNewStart, PolyLine& Loop) ;
|
||||
// nSegNum 0-based
|
||||
static bool PointPositionOnPolyLine( const Point3d& ptPoint, /*const*/ PolyLine& Loop, int& nSegNum, double& dParOnSeg) ;
|
||||
static bool IsPointInsidePolyLine( const Point3d& ptP, /*const*/ PolyLine& plPoly) ;
|
||||
static bool SplitPolyLineAtPoint( const Point3d& ptPoint, /*const*/ PolyLine& Loop, PolyLine& Loop1, PolyLine& Loop2) ;
|
||||
static bool AddPolyLineToPolyLine(PolyLine& Poly, PolyLine& PolyToAdd) ;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
inline SurfTriMesh* CreateBasicSurfTriMesh( void)
|
||||
{ return ( static_cast<SurfTriMesh*>( CreateGeoObj( SRF_TRIMESH))) ; }
|
||||
|
||||
+2198
-39
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user