From 5afe1ddf16d7364ff453997692e0c9ff0db37f0e Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Mon, 3 Sep 2018 05:28:48 +0000 Subject: [PATCH] EgtGeomKernel : - aggiunta gestione parti coincidenti in intersezione superfici TriMesh - migliorie a distanza punti da curve. --- ChainCurves.cpp | 2 +- CircleCenTgCurve.cpp | 3 +- CurveArc.cpp | 8 +--- CurveBezier.cpp | 9 ++-- CurveComposite.cpp | 8 +--- DistPointArc.h | 6 +++ DistPointCrvBezier.h | 6 +++ DistPointCrvComposite.h | 6 +++ DistPointLine.h | 6 ++- DistPointTria.cpp | 2 +- IntersPlaneSurfTm.cpp | 10 ++-- IntersSurfTmSurfTm.cpp | 80 ++++++++++++++++---------------- IntersTriaTria.cpp | 100 +++++++++++++++++++++++----------------- 13 files changed, 134 insertions(+), 112 deletions(-) diff --git a/ChainCurves.cpp b/ChainCurves.cpp index 1b702d5..c629838 100644 --- a/ChainCurves.cpp +++ b/ChainCurves.cpp @@ -25,7 +25,7 @@ bool ChainCurves::Init( bool bAllowInvert, double dToler, int nCrvNbrHint) { m_bAllowInvert = bAllowInvert ; - m_dToler = dToler ; + m_dToler = max( dToler, EPS_SMALL) ; m_sCrvId.clear() ; m_sCrvId.rehash( nCrvNbrHint) ; m_vCrvData.clear() ; diff --git a/CircleCenTgCurve.cpp b/CircleCenTgCurve.cpp index 35ad93d..cd046ce 100644 --- a/CircleCenTgCurve.cpp +++ b/CircleCenTgCurve.cpp @@ -83,8 +83,7 @@ GetCircleCenTgLine( const Point3d& ptCen, const Vector3d& vtN, const CurveLine& if ( ! DistPointLine( ptCen, ptP1, ptP2, false).GetMinDistPoint( ptTg)) return nullptr ; // verifico che stia sul segmento - double dSqDist ; - if ( ! DistPointLine( ptTg, ptP1, ptP2).GetSqDist( dSqDist) || dSqDist > SQ_EPS_SMALL) + if ( ! DistPointLine( ptTg, ptP1, ptP2).IsSmall()) return nullptr ; // creo l'arco diff --git a/CurveArc.cpp b/CurveArc.cpp index 024399a..beb71bf 100644 --- a/CurveArc.cpp +++ b/CurveArc.cpp @@ -1044,19 +1044,15 @@ bool CurveArc::IsPointOn( const Point3d& ptP, double dTol) const { // verifico la distanza - double dSqDist ; - dTol = max( dTol, EPS_ZERO) ; - return ( DistPointArc( ptP, *this).GetSqDist( dSqDist) && dSqDist < dTol * dTol) ; + return ( DistPointArc( ptP, *this).IsEpsilon( dTol)) ; } //---------------------------------------------------------------------------- bool CurveArc::GetParamAtPoint( const Point3d& ptP, double& dPar, double dTol) const { - double dSqDist ; - dTol = max( dTol, EPS_ZERO) ; DistPointArc DPA( ptP, *this) ; - if ( ! DPA.GetSqDist( dSqDist) || dSqDist > dTol * dTol) + if ( ! DPA.IsEpsilon( dTol)) return false ; int nFlag ; return DPA.GetParamAtMinDistPoint( 0, dPar, nFlag) ; diff --git a/CurveBezier.cpp b/CurveBezier.cpp index 8f90c0c..3e0f717 100644 --- a/CurveBezier.cpp +++ b/CurveBezier.cpp @@ -1281,19 +1281,16 @@ CurveBezier::GetParamAtLength( double dLen, double& dU) const bool CurveBezier::IsPointOn( const Point3d& ptP, double dTol) const { - double dSqDist ; - dTol = max( dTol, EPS_ZERO) ; - return ( DistPointCrvBezier( ptP, *this).GetSqDist( dSqDist) && dSqDist < dTol * dTol) ; + // verifico la distanza + return ( DistPointCrvBezier( ptP, *this).IsEpsilon( dTol)) ; } //---------------------------------------------------------------------------- bool CurveBezier::GetParamAtPoint( const Point3d& ptP, double& dPar, double dTol) const { - double dSqDist ; - dTol = max( dTol, EPS_ZERO) ; DistPointCrvBezier DPB( ptP, *this) ; - if ( ! DPB.GetSqDist( dSqDist) || dSqDist > dTol * dTol) + if ( ! DPB.IsEpsilon( dTol)) return false ; int nFlag ; return DPB.GetParamAtMinDistPoint( 0, dPar, nFlag) ; diff --git a/CurveComposite.cpp b/CurveComposite.cpp index 10647fa..4e381fb 100644 --- a/CurveComposite.cpp +++ b/CurveComposite.cpp @@ -1214,19 +1214,15 @@ CurveComposite::IsPointOn( const Point3d& ptP, double dTol) const if ( m_nStatus != OK) return false ; // verifico che il punto sia sulla curva ( distanza minore di tolleranza) - double dSqDist ; - dTol = max( dTol, EPS_ZERO) ; - return ( DistPointCrvComposite( ptP, *this).GetSqDist( dSqDist) && dSqDist < dTol * dTol) ; + return ( DistPointCrvComposite( ptP, *this).IsEpsilon( dTol)) ; } //---------------------------------------------------------------------------- bool CurveComposite::GetParamAtPoint( const Point3d& ptP, double& dPar, double dTol) const { - double dSqDist ; - dTol = max( dTol, EPS_ZERO) ; DistPointCrvComposite DPC( ptP, *this) ; - if ( ! DPC.GetSqDist( dSqDist) || dSqDist > dTol * dTol) + if ( ! DPC.IsEpsilon( dTol)) return false ; int nFlag ; return DPC.GetParamAtMinDistPoint( 0, dPar, nFlag) ; diff --git a/DistPointArc.h b/DistPointArc.h index 2c70a4a..8998dd6 100644 --- a/DistPointArc.h +++ b/DistPointArc.h @@ -29,6 +29,12 @@ class DistPointArc public : bool GetSqDist( double& dSqDist) ; bool GetDist( double& dDist) ; + bool IsEpsilon( double dTol) + { double dSqDist ; return ( GetSqDist( dSqDist) && ( dSqDist < SQ_EPS_ZERO || dSqDist < dTol * dTol)) ; } + bool IsSmall( void) + { return IsEpsilon( EPS_SMALL) ; } + bool IsZero( void) + { return IsEpsilon( EPS_ZERO) ; } int GetNbrMinDist( void) { return (int) m_Info.size() ; } bool GetMinDistPoint( int nInd, Point3d& ptMinDist, int& nFlag) ; bool GetParamAtMinDistPoint( int nInd, double& dParam, int& nFlag) ; diff --git a/DistPointCrvBezier.h b/DistPointCrvBezier.h index b278d93..1cac563 100644 --- a/DistPointCrvBezier.h +++ b/DistPointCrvBezier.h @@ -29,6 +29,12 @@ class DistPointCrvBezier public : bool GetSqDist( double& dSqDist) ; bool GetDist( double& dDist) ; + bool IsEpsilon( double dTol) + { double dSqDist ; return ( GetSqDist( dSqDist) && ( dSqDist < SQ_EPS_ZERO || dSqDist < dTol * dTol)) ; } + bool IsSmall( void) + { return IsEpsilon( EPS_SMALL) ; } + bool IsZero( void) + { return IsEpsilon( EPS_ZERO) ; } int GetNbrMinDist( void) { return (int) m_Info.size() ; } bool GetMinDistPoint( int nInd, Point3d& ptMinDist, int& nFlag) ; bool GetParamAtMinDistPoint( int nInd, double& dParam, int& nFlag) ; diff --git a/DistPointCrvComposite.h b/DistPointCrvComposite.h index 3c050b3..c35f489 100644 --- a/DistPointCrvComposite.h +++ b/DistPointCrvComposite.h @@ -28,6 +28,12 @@ class DistPointCrvComposite public : bool GetSqDist( double& dSqDist) ; bool GetDist( double& dDist) ; + bool IsEpsilon( double dTol) + { double dSqDist ; return ( GetSqDist( dSqDist) && ( dSqDist < SQ_EPS_ZERO || dSqDist < dTol * dTol)) ; } + bool IsSmall( void) + { return IsEpsilon( EPS_SMALL) ; } + bool IsZero( void) + { return IsEpsilon( EPS_ZERO) ; } int GetNbrMinDist( void) { return (int) m_Info.size() ; } bool GetMinDistPoint( int nInd, Point3d& ptMinDist, int& nFlag) ; bool GetParamAtMinDistPoint( int nInd, double& dParam, int& nFlag) ; diff --git a/DistPointLine.h b/DistPointLine.h index 42573ce..e6b92be 100644 --- a/DistPointLine.h +++ b/DistPointLine.h @@ -33,10 +33,12 @@ class DistPointLine public : bool GetSqDist( double& dSqDist) ; bool GetDist( double& dDist) ; + bool IsEpsilon( double dTol) + { double dSqDist ; return ( GetSqDist( dSqDist) && ( dSqDist < SQ_EPS_ZERO || dSqDist < dTol * dTol)) ; } bool IsSmall( void) - { double dSqDist ; return ( GetSqDist( dSqDist) && dSqDist < SQ_EPS_SMALL) ; } + { return IsEpsilon( EPS_SMALL) ; } bool IsZero( void) - { double dSqDist ; return ( GetSqDist( dSqDist) && dSqDist < SQ_EPS_ZERO) ; } + { return IsEpsilon( EPS_ZERO) ; } int GetNbrMinDist( void) { return (( m_dSqDist < 0) ? 0 : 1) ; } bool GetMinDistPoint( Point3d& ptMinDist) ; diff --git a/DistPointTria.cpp b/DistPointTria.cpp index 34e8a09..087baaf 100644 --- a/DistPointTria.cpp +++ b/DistPointTria.cpp @@ -39,7 +39,7 @@ void DistPointTriangle::Calculate( const Point3d& ptP, const Triangle3d& Tria) { // Proiezione del punto sul piano del triangolo - Point3d ptQ = ptP - (( ptP - Tria.GetP( 0)) * Tria.GetN()) * Tria.GetN() ; + Point3d ptQ = ptP - (( ptP - Tria.GetCentroid()) * Tria.GetN()) * Tria.GetN() ; // Verifico se il punto proiettato sta nel triangolo if ( PointInTria( ptQ, Tria) != PTT_OUT) { diff --git a/IntersPlaneSurfTm.cpp b/IntersPlaneSurfTm.cpp index 08ddebc..6b449b9 100644 --- a/IntersPlaneSurfTm.cpp +++ b/IntersPlaneSurfTm.cpp @@ -148,8 +148,7 @@ IntersPlaneSurfTm( const Plane3d& plPlane, const ISurfTriMesh& Stm, if ( LnGrid.Find( b3Pnt, vnIds)) { for ( int j = 0 ; j < int( vnIds.size()) ; ++ j) { int nA = vnIds[j] ; - double dSqDist ; - if ( DistPointLine( vPnt[i], vBpt[nA].first, vBpt[nA].second).GetSqDist( dSqDist) && dSqDist < 100 * SQ_EPS_SMALL) { + if ( DistPointLine( vPnt[i], vBpt[nA].first, vBpt[nA].second).IsEpsilon( 10 * EPS_SMALL)) { bFound = true ; break ; } @@ -169,8 +168,7 @@ IntersPlaneSurfTm( const Plane3d& plPlane, const ISurfTriMesh& Stm, for ( int j = 0 ; j < int( vnIds.size()) ; ++ j) { int nA = vnIds[j] ; const Triangle3d& trOth = vTria[nA] ; - double dSqDist ; - if ( DistPointTriangle( vPnt[i], trOth).GetSqDist( dSqDist) && dSqDist < 100 * SQ_EPS_SMALL) { + if ( DistPointTriangle( vPnt[i], trOth).IsEpsilon( 10 * EPS_SMALL)) { bFound = true ; break ; } @@ -191,8 +189,8 @@ IntersPlaneSurfTm( const Plane3d& plPlane, const ISurfTriMesh& Stm, for ( int j = 0 ; j < int( vnIds.size()) ; ++ j) { int nA = vnIds[j] ; const Triangle3d& trOth = vTria[nA] ; - Point3d ptInt, ptInt2 ; - if ( IntersLineTria( ptStart, ptEnd, trOth, ptInt, ptInt2) == ILTT_SEGM_ON_EDGE) { + if ( DistPointTriangle( ptStart, trOth).IsEpsilon( 10 * EPS_SMALL) && + DistPointTriangle( ptEnd, trOth).IsEpsilon( 10 * EPS_SMALL)) { bFound = true ; break ; } diff --git a/IntersSurfTmSurfTm.cpp b/IntersSurfTmSurfTm.cpp index 47f2f7a..92915b1 100644 --- a/IntersSurfTmSurfTm.cpp +++ b/IntersSurfTmSurfTm.cpp @@ -62,14 +62,14 @@ IntersSurfTmSurfTm( const ISurfTriMesh& Stm1, const ISurfTriMesh& Stm2, HashGrids3d HHGrids ; const int LIM_SRFNBRSQUARED = 4095 ; HHGrids.SetActivationGrid( long long( nTriaNbr1) * long long(nTriaNbr2) > LIM_SRFNBRSQUARED) ; - Triangle3d Tria ; - int nT = ( bHash1 ? Stm1.GetFirstTriangle( Tria) : Stm2.GetFirstTriangle( Tria)) ; + Triangle3d TriaH ; + int nT = ( bHash1 ? Stm1.GetFirstTriangle( TriaH) : Stm2.GetFirstTriangle( TriaH)) ; while ( nT != SVT_NULL) { BBox3d boxT ; - Tria.GetLocalBBox( boxT) ; + TriaH.GetLocalBBox( boxT) ; if ( ! HHGrids.Add( nT, boxT)) return false ; - nT = ( bHash1 ? Stm1.GetNextTriangle( nT, Tria) : Stm2.GetNextTriangle( nT, Tria)) ; + nT = ( bHash1 ? Stm1.GetNextTriangle( nT, TriaH) : Stm2.GetNextTriangle( nT, TriaH)) ; } if ( ! HHGrids.Update()) return false ; @@ -88,8 +88,8 @@ IntersSurfTmSurfTm( const ISurfTriMesh& Stm1, const ISurfTriMesh& Stm2, if ( bHash1 ? Stm1.GetTriangle( nB, TriaB) : Stm2.GetTriangle( nB, TriaB)) { // intersezione tra i triangoli Point3d ptInt, ptInt2 ; - PNTVECTOR vPnt ; - int nRes = IntersTriaTria( TriaA, TriaB, ptInt, ptInt2, vPnt) ; + TRIA3DVECTOR vIttTria ; + int nRes = IntersTriaTria( TriaA, TriaB, ptInt, ptInt2, vIttTria) ; // se punto if ( nRes == ITTT_VERT || nRes == ITTT_PNT) { // verifico se punto già inserito @@ -131,34 +131,36 @@ IntersSurfTmSurfTm( const ISurfTriMesh& Stm1, const ISurfTriMesh& Stm2, } // se altrimenti sovrapposizione else if ( nRes == ITTT_OVERLAPS) { - //// verifico se triangolo già inserito - // bool bFound = false ; - // BBox3d b3Tria( Tria.GetP( 0), Tria.GetP( 1)) ; - // b3Tria.Add( Tria.GetP( 2)) ; - // INTVECTOR vnIds ; - // if ( TrGrid.Find( b3Tria, vnIds)) { - // for ( int i = 0 ; i < int( vnIds.size()) ; ++ i) { - // int nA = vnIds[i] ; - // const Triangle3d& trOth = vTria[nA] ; - // array< bool, 3> bOth = { false, false, false} ; - // for ( int j = 0 ; j < 3 ; ++ j) { - // for ( int k = 0 ; k < 3 ; ++ k) { - // if ( ! bOth[k]) - // bOth[k] = AreSamePointEpsilon( Tria.GetP( j), trOth.GetP( k), 10 * EPS_SMALL) ; - // } - // } - // if ( bOth[0] && bOth[1] && bOth[2]) { - // bFound = true ; - // break ; - // } - // } - // } - //// se non inserito, procedo - // if ( ! bFound) { - // vTria.emplace_back( Tria) ; - // TrGrid.Add( int( vTria.size()) - 1, b3Tria) ; - // TrGrid.Update() ; - // } + for each ( const auto& Tria in vIttTria) { + // verifico se triangolo già inserito + bool bFound = false ; + BBox3d b3Tria ; + Tria.GetLocalBBox( b3Tria) ; + INTVECTOR vnIds ; + if ( TrGrid.Find( b3Tria, vnIds)) { + for ( int i = 0 ; i < int( vnIds.size()) ; ++ i) { + int nA = vnIds[i] ; + const Triangle3d& trOth = vTria[nA] ; + array< bool, 3> bOth = { false, false, false} ; + for ( int j = 0 ; j < 3 ; ++ j) { + for ( int k = 0 ; k < 3 ; ++ k) { + if ( ! bOth[k]) + bOth[k] = AreSamePointEpsilon( Tria.GetP( j), trOth.GetP( k), 10 * EPS_SMALL) ; + } + } + if ( bOth[0] && bOth[1] && bOth[2]) { + bFound = true ; + break ; + } + } + } + // se non inserito, procedo + if ( ! bFound) { + vTria.emplace_back( Tria) ; + TrGrid.Add( int( vTria.size()) - 1, b3Tria) ; + TrGrid.Update() ; + } + } } } } @@ -176,8 +178,7 @@ IntersSurfTmSurfTm( const ISurfTriMesh& Stm1, const ISurfTriMesh& Stm2, if ( LnGrid.Find( b3Pnt, vnIds)) { for ( int j = 0 ; j < int( vnIds.size()) ; ++ j) { int nA = vnIds[j] ; - double dSqDist ; - if ( DistPointLine( vPnt[i], vBpt[nA].first, vBpt[nA].second).GetSqDist( dSqDist) && dSqDist < 100 * SQ_EPS_SMALL) { + if ( DistPointLine( vPnt[i], vBpt[nA].first, vBpt[nA].second).IsEpsilon( 10 * EPS_SMALL)) { bFound = true ; break ; } @@ -197,8 +198,7 @@ IntersSurfTmSurfTm( const ISurfTriMesh& Stm1, const ISurfTriMesh& Stm2, for ( int j = 0 ; j < int( vnIds.size()) ; ++ j) { int nA = vnIds[j] ; const Triangle3d& trOth = vTria[nA] ; - double dSqDist ; - if ( DistPointTriangle( vPnt[i], trOth).GetSqDist( dSqDist) && dSqDist < 100 * SQ_EPS_SMALL) { + if ( DistPointTriangle( vPnt[i], trOth).IsEpsilon( 10 * EPS_SMALL)) { bFound = true ; break ; } @@ -219,8 +219,8 @@ IntersSurfTmSurfTm( const ISurfTriMesh& Stm1, const ISurfTriMesh& Stm2, for ( int j = 0 ; j < int( vnIds.size()) ; ++ j) { int nA = vnIds[j] ; const Triangle3d& trOth = vTria[nA] ; - Point3d ptInt, ptInt2 ; - if ( IntersLineTria( ptStart, ptEnd, trOth, ptInt, ptInt2) == ILTT_SEGM_ON_EDGE) { + if ( DistPointTriangle( ptStart, trOth).IsEpsilon( 10 * EPS_SMALL) && + DistPointTriangle( ptEnd, trOth).IsEpsilon( 10 * EPS_SMALL)) { bFound = true ; break ; } diff --git a/IntersTriaTria.cpp b/IntersTriaTria.cpp index 32f7acc..3aa70be 100644 --- a/IntersTriaTria.cpp +++ b/IntersTriaTria.cpp @@ -15,6 +15,10 @@ #include "stdafx.h" #include "ProjPlane.h" #include "IntersLineTria.h" +#include "CurveComposite.h" +#include "SurfFlatRegion.h" +#include "Triangulate.h" +#include "GeoConst.h" #include "/EgtDev/Include/EGkIntersTriaTria.h" #include "/EgtDev/Include/EGkIntersPlanePlane.h" #include @@ -22,11 +26,11 @@ using namespace std ; //---------------------------------------------------------------------------- -static int IntersCoplanarTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, PNTVECTOR& vPnt) ; +static int IntersCoplanarTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, TRIA3DVECTOR& vTria) ; //---------------------------------------------------------------------------- int -IntersTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, Point3d& ptInt, Point3d& ptInt2, PNTVECTOR& vPnt) +IntersTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, Point3d& ptInt, Point3d& ptInt2, TRIA3DVECTOR& vTria) { // piano del secondo triangolo Plane3d plTria2 ; @@ -68,7 +72,7 @@ IntersTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, Point3d& p // se i triangoli sono complanari if ( ( nVertPos1 == 0 && nVertNeg1 == 0) || ( nVertPos2 == 0 && nVertNeg2 == 0)) - return IntersCoplanarTriaTria( trTria1, trTria2, vPnt) ; + return IntersCoplanarTriaTria( trTria1, trTria2, vTria) ; // intersezione tra i piani dei due triangoli Point3d ptL1 ; Vector3d vtL1 ; @@ -101,48 +105,60 @@ IntersTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, Point3d& p case ILTT_EDGE : return ITTT_PNT ; default : return ITTT_NO ; } - - -#if 0 - // interseco il primo triangolo con il piano del secondo - Plane3d plPlane2 ; - plPlane2.Set( trTria2.GetCentroid(), trTria2.GetN()) ; - int nPtRes = IntersPlaneTria( plPlane2, trTria1, ptInt, ptInt2) ; - // se non c'è intersezione - if ( nPtRes == IPTT_NO) - return ITTT_NO ; - // se altrimenti complanari - else if ( nPtRes == IPTT_OVERLAPS) - return IntersCoplanarTriaTria( trTria1, trTria2, vPnt) ; - // se intersezione in un vertice - else if ( nPtRes == IPTT_VERT) { - // se l'intersezione sta anche nel secondo triangolo - if ( PointInTria( ptInt, trTria2)) - return ITTT_VERT ; - else - return ITTT_NO ; - } - // altrimenti è un segmento, va limitato col secondo triangolo - Point3d ptL = ptInt ; - Vector3d vtL = ptInt2 - ptInt ; - double dLen = vtL.Len() ; - vtL /= dLen ; - int nRes = IntersCoplanarLineTria( ptL, vtL, dLen, trTria2, ptInt, ptInt2, true) ; - switch( nRes) { - case ILTT_NO : return ITTT_NO ; - case ILTT_SEGM : return ITTT_YES ; - case ILTT_SEGM_ON_EDGE : return ITTT_EDGE ; - case ILTT_VERT : return ITTT_VERT ; - case ILTT_EDGE : return ITTT_PNT ; - default : return ITTT_NO ; - } -#endif } //---------------------------------------------------------------------------- int -IntersCoplanarTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, PNTVECTOR& vPnt) +IntersCoplanarTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, TRIA3DVECTOR& vTria) { - // !!! PROVVISORIO !!! - return ITTT_NO ; + // creo la regione equivalente al primo triangolo + SurfFlatRegion sfrTria1 ; + PtrOwner pCcTria1( CreateBasicCurveComposite()) ; + if ( IsNull( pCcTria1)) + return ITTT_NO ; + pCcTria1->AddPoint( trTria1.GetP( 0)) ; + pCcTria1->AddLine( trTria1.GetP( 1)) ; + pCcTria1->AddLine( trTria1.GetP( 2)) ; + pCcTria1->Close() ; + if ( ! sfrTria1.AddExtLoop( Release( pCcTria1))) + return ITTT_NO ; + + // creo la regione equivalente al secondo triangolo + SurfFlatRegion sfrTria2 ; + PtrOwner pCcTria2( CreateBasicCurveComposite()) ; + if ( IsNull( pCcTria2)) + return ITTT_NO ; + pCcTria2->AddPoint( trTria2.GetP( 0)) ; + pCcTria2->AddLine( trTria2.GetP( 1)) ; + pCcTria2->AddLine( trTria2.GetP( 2)) ; + pCcTria2->Close() ; + if ( ! sfrTria2.AddExtLoop( Release( pCcTria2))) + return ITTT_NO ; + if ( sfrTria1.GetNormVersor() * sfrTria2.GetNormVersor() < 0) + sfrTria2.Invert() ; + + // calcolo l'intersezione tra le due regioni + if ( ! sfrTria1.Intersect( sfrTria2) || ! sfrTria1.IsValid()) + return ITTT_NO ; + + // recupero il contorno esterno del risultato come polilinea + PolyLine PL ; + if ( ! sfrTria1.ApproxLoopWithLines( 0, 0, LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_STD, PL)) + return ITTT_NO ; + + // eseguo una triangolazione del contorno chiuso + PNTVECTOR vPnt ; + INTVECTOR vTrVert ; + Triangulate Tri ; + if ( ! Tri.Make( PL, vPnt, vTrVert)) + return ITTT_NO ; + int nTrVert = int( vTrVert.size()) / 3 ; + for ( int i = 0 ; i < nTrVert ; ++i) { + Triangle3d Tria ; + Tria.Set( vPnt[vTrVert[3*i]], vPnt[vTrVert[3*i+1]], vPnt[vTrVert[3*i+2]]) ; + if ( Tria.Validate( true)) + vTria.emplace_back( Tria) ; + } + + return ITTT_OVERLAPS ; }