diff --git a/SurfBezier.cpp b/SurfBezier.cpp index d1ee4a1..513306f 100644 --- a/SurfBezier.cpp +++ b/SurfBezier.cpp @@ -54,7 +54,7 @@ SurfBezier::~SurfBezier( void) bool SurfBezier::Init( int nDegU, int nDegV, int nSpanU, int nSpanV, bool bIsRational) { - // verifico validità grado + // verifico validit� grado if ( nDegU < 1 || nDegU > MAXDEG || nDegV < 1 || nDegV > MAXDEG || nSpanU < 1 || nSpanV < 1) return false ; @@ -86,7 +86,7 @@ SurfBezier::Init( int nDegU, int nDegV, int nSpanU, int nSpanV, bool bIsRational bool SurfBezier::SetControlPoint( int nInd, const Point3d& ptCtrl) { - // verifico validità indice + // verifico validit� indice if ( m_nStatus != OK || m_bRat || nInd < 0 || nInd >= GetDim()) return false ; @@ -108,7 +108,7 @@ SurfBezier::SetControlPoint( int nInd, const Point3d& ptCtrl) bool SurfBezier::SetControlPoint( int nInd, const Point3d& ptCtrl, double dW) { - // verifico validità, razionalità e indice + // verifico validit�, razionalit� e indice if ( m_nStatus != OK || ! m_bRat || nInd < 0 || nInd >= GetDim()) return false ; @@ -158,7 +158,7 @@ SurfBezier::GetTrimRegion( void) const bool SurfBezier::GetInfo( int& nDegU, int& nDegV, int& nSpanU, int& nSpanV, bool& bIsRat, bool& bTrimmed) const { - // verifico validità superficie + // verifico validit� superficie if ( m_nStatus != OK) return false ; // restituisco gradi e flag di razionale @@ -175,7 +175,7 @@ SurfBezier::GetInfo( int& nDegU, int& nDegV, int& nSpanU, int& nSpanV, bool& bIs const Point3d& SurfBezier::GetControlPoint( int nInd, bool* pbOk) const { - // verifico validità e indice + // verifico validit� e indice if ( m_nStatus != OK || nInd < 0 || nInd >= GetDim()) { if ( pbOk != NULL) *pbOk = false ; @@ -191,7 +191,7 @@ SurfBezier::GetControlPoint( int nInd, bool* pbOk) const double SurfBezier::GetControlWeight( int nInd, bool* pbOk) const { - // verifico validità, razionalità e indice + // verifico validit�, razionalit� e indice if ( m_nStatus != OK || ! m_bRat || nInd < 0 || nInd >= GetDim()) { if ( pbOk != NULL) *pbOk = false ; @@ -503,7 +503,7 @@ SurfBezier::GetPointNrmD1D2( double dU, double dV, Side nUs, Side nVs, if ( vtN.Normalize()) return true ; - // se solo una delle due derivate è piccola, mi sposto lungo il relativo parametro e uso le tangenti + // se solo una delle due derivate � piccola, mi sposto lungo il relativo parametro e uso le tangenti if ( pvtDerU->Len() < EPS_SMALL && pvtDerV->Len() > 10 * EPS_SMALL) { double dCoeff = ( dU - 1000 * EPS_PARAM < 0. ? 1 : -1) ; double dUm = dU + 1000 * EPS_PARAM * dCoeff ; @@ -610,7 +610,7 @@ SurfBezier::GetTitle( void) const bool SurfBezier::Dump( string& sOut, bool bMM, const char* szNewLine) const { - // verifico validità superficie + // verifico validit� superficie if ( m_nStatus != OK) sOut += string( "Status=Invalid") + szNewLine ; // area @@ -843,7 +843,7 @@ SurfBezier::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, d // la superficie deve essere validata if ( m_nStatus != OK) return false ; - // verifico validità dell'asse di rotazione + // verifico validit� dell'asse di rotazione if ( vtAx.IsSmall()) return false ; @@ -899,7 +899,7 @@ SurfBezier::Mirror( const Point3d& ptOn, const Vector3d& vtNorm) // la superficie deve essere validata if ( m_nStatus != OK) return false ; - // verifico validità del piano di specchiatura + // verifico validit� del piano di specchiatura if ( vtNorm.IsSmall()) return false ; @@ -922,7 +922,7 @@ SurfBezier::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& // la superficie deve essere validata if ( m_nStatus != OK) return false ; - // verifico validità dei parametri + // verifico validit� dei parametri if ( vtNorm.IsSmall() || vtDir.IsSmall()) return false ; @@ -944,11 +944,11 @@ SurfBezier::ToGlob( const Frame3d& frRef) // la superficie deve essere validata if ( m_nStatus != OK) return false ; - // verifico validità del frame + // verifico validit� del frame if ( frRef.GetType() == Frame3d::ERR) return false ; - // se frame identità, non devo fare alcunché + // se frame identit�, non devo fare alcunch� if ( IsGlobFrame( frRef)) return true ; @@ -970,11 +970,11 @@ SurfBezier::ToLoc( const Frame3d& frRef) // la superficie deve essere validata if ( m_nStatus != OK) return false ; - // verifico validità del frame + // verifico validit� del frame if ( frRef.GetType() == Frame3d::ERR) return false ; - // se frame identità, non devo fare alcunché + // se frame identit�, non devo fare alcunch� if ( IsGlobFrame( frRef)) return true ; @@ -996,11 +996,11 @@ SurfBezier::LocToLoc( const Frame3d& frOri, const Frame3d& frDest) // la superficie deve essere validata if ( m_nStatus != OK) return false ; - // verifico validità dei frame + // verifico validit� dei frame if ( frOri.GetType() == Frame3d::ERR || frDest.GetType() == Frame3d::ERR) return false ; - // se i due riferimenti coincidono, non devo fare alcunché + // se i due riferimenti coincidono, non devo fare alcunch� if ( AreSameFrame( frOri, frDest)) return true ; @@ -1263,7 +1263,7 @@ SurfBezier::GetLoop( int nLoop) const // se loop chiuso lo restituisco, altrimenti errore return ( pLoop->IsClosed() ? Release( pLoop) : nullptr) ; } - // la superficie è trimmata, quindi devo cercare nei vari chunck il loop corrispondente + // la superficie � trimmata, quindi devo cercare nei vari chunck il loop corrispondente else { if ( nLoop > m_pTrimReg->GetChunkCount()) return nullptr ; @@ -1421,7 +1421,7 @@ SurfBezier::GetCurveOnVApproxLen( double dU) const // ResetAuxSurf() ; // return nullptr ; // } -// // se già calcolata, la restituisco +// // se gi� calcolata, la restituisco // if ( m_pSTM != nullptr) // return m_pSTM ; // // costruttore della superficie @@ -1497,7 +1497,7 @@ SurfBezier::GetAuxSurf( void) const ResetAuxSurf() ; return nullptr ; } - // se già calcolata, la restituisco + // se gi� calcolata, la restituisco if ( m_pSTM != nullptr) return m_pSTM ; @@ -1507,12 +1507,21 @@ SurfBezier::GetAuxSurf( void) const Tree Tree( this, true) ; BIPNTVECTOR vTrees ; Tree.GetIndependentTrees( vTrees) ; + bool bTest = false ; // per debug for ( int i = 0 ; i < (int) vTrees.size() ; ++ i) { Point3d ptMin = std::get<0>( vTrees[i]) ; Point3d ptMax = std::get<1>( vTrees[i]) ; Tree.SetSurf( this, true, ptMin, ptMax) ; - Tree.BuildTree( 5 * LIN_TOL_FINE, 0.1) ; + if ( bTest) { + Tree.BuildTree_test() ; // per debug + //Tree.BuildTree( 5 * LIN_TOL_FINE, 1) ; // per debug + Tree.SetTestMode() ; + } + else { + Tree.BuildTree( 5 * LIN_TOL_FINE, 0.1) ; + } Tree.GetPolygons( vvPL) ; + //Tree.GetPolygonsBasic( vPL) ; // per usare i polygon basic } //// per usare i polygon basic////////////////////// @@ -1571,7 +1580,14 @@ SurfBezier::GetLeaves( vector>& vLeaves) const Point3d ptMin = get<0>( vTrees[i]) ; Point3d ptMax = get<1>( vTrees[i]) ; Tree.SetSurf( this, true, ptMin, ptMax) ; - Tree.BuildTree( 5 * LIN_TOL_FINE, 0.1) ; + bool bTest = false ; // per debug + if ( bTest) { + Tree.BuildTree_test() ; // per debug + //Tree.BuildTree( 5 * LIN_TOL_FINE, 1) ; // per debug + } + else { + Tree.BuildTree( 5 * LIN_TOL_FINE, 0.1) ; + } vector vCells ; Tree.GetLeaves( vCells) ; for ( int k = 0 ; k < int( vCells.size()) ; ++ k) { diff --git a/SurfTriMeshBooleans.cpp b/SurfTriMeshBooleans.cpp index c3dfa8e..1704a4d 100644 --- a/SurfTriMeshBooleans.cpp +++ b/SurfTriMeshBooleans.cpp @@ -1272,6 +1272,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other) RetriangulationForBooleanOperation( LineMapB, AmbiguosB, SurfB, bModif) ; // Se i triangoli delle superfici non si intersecano, una delle due è totalmente interna o esterna all'altra. + // non mi basta fare un controllo sulle bbox perché non so come sono orientate le superfici e che potrebbero anche non essere chiuse bool bRetriangulated = true ; if ( ! bModif && ( int( AmbiguosA.size()) == 0 || int( AmbiguosB.size()) == 0)) { bRetriangulated = false ; @@ -1280,7 +1281,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other) int nCurVert = GetFirstVertex( ptFirstV) ; int nInOutNum = 0 ; while ( nInOutNum == 0 && nCurVert != SVT_NULL) { - int nTriaNum = - 1 ; + INTVECTOR vnTriaNum ; double dMinDist = DBL_MAX ; for ( int nTB = 0 ; nTB < nTriaNumB ; ++ nTB) { // Se il triangolo B non è valido, continuo @@ -1288,18 +1289,66 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other) if ( ! SurfB.GetTriangle( nTB, trTriaB) || ! trTriaB.Validate( true)) continue ; double dDist ; - if ( DistPointTriangle( ptFirstV, trTriaB).GetDist( dDist) && dDist < dMinDist) { - nTriaNum = nTB ; - dMinDist = dDist ; + // potrei trovare più triangolo equidistanti, li salvo tutti + if ( DistPointTriangle( ptFirstV, trTriaB).GetDist( dDist)) { + if ( abs(dDist - dMinDist) < EPS_SMALL) + vnTriaNum.push_back( nTB) ; + else if ( dDist < dMinDist){ + vnTriaNum.clear() ; + vnTriaNum.push_back( nTB) ; + dMinDist = dDist ; + } } } - if ( nTriaNum >= 0) { + if ( ! vnTriaNum.empty()) { Triangle3d trTriaB ; - SurfB.GetTriangle( nTriaNum, trTriaB) ; - if ( ( ptFirstV - trTriaB.GetP(0)) * trTriaB.GetN() < - EPS_SMALL) - nInOutNum = 1 ; - else if ( ( ptFirstV - trTriaB.GetP(0)) * trTriaB.GetN() > EPS_SMALL) - nInOutNum = - 1 ; + bool bSame = true ; + // controllo se rispetto a questi triangoli il punto risulta sempre fuori o sempre dentro + for ( int nTriaNum : vnTriaNum) { + SurfB.GetTriangle( nTriaNum, trTriaB) ; + if ( ( ptFirstV - trTriaB.GetP(0)) * trTriaB.GetN() < - EPS_SMALL) { + if ( nInOutNum == 0) + nInOutNum = 1 ; + else if (nInOutNum == -1) { + bSame = false ; + break ; + } + } + else if ( ( ptFirstV - trTriaB.GetP(0)) * trTriaB.GetN() > EPS_SMALL) { + if ( nInOutNum == 0) + nInOutNum = -1 ; + else if (nInOutNum == 1) { + bSame = false ; + break ; + } + } + } + // se le informazioni date dalle normali dei triangoli non sono concordi valuto il triangolo più vicino + // e ricalcolo l'informazione che mi dà la sua normale + if ( ! bSame ) { + Point3d ptBar_tot ; + for (int nTriaNum : vnTriaNum) { + SurfB.GetTriangle( nTriaNum, trTriaB) ; + ptBar_tot += trTriaB.GetCentroid(); + } + ptBar_tot /= (int)vnTriaNum.size() ; + for (int nTriaNum : vnTriaNum) { + SurfB.GetTriangle( nTriaNum, trTriaB) ; + Point3d ptInters1, ptInters2 ; + int nInters = IntersLineTria(ptFirstV, ptBar_tot, trTriaB, ptInters1, ptInters2, true) ; + if (nInters == ILTT_NO) + continue ; + else if ( nInters == ILTT_IN ) { + if ( ( ptFirstV - trTriaB.GetP(0)) * trTriaB.GetN() < - EPS_SMALL) + nInOutNum = 1 ; + else if ( ( ptFirstV - trTriaB.GetP(0)) * trTriaB.GetN() > EPS_SMALL) + nInOutNum = -1 ; + break ; + } + else + nInOutNum = 0 ; + } + } } if ( nInOutNum == 0) { nCurVert = GetNextVertex( nVertNum, ptFirstV) ; @@ -1313,7 +1362,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other) nCurVert = SurfB.GetFirstVertex( ptFirstV) ; nInOutNum = 0 ; while ( nInOutNum == 0 && nCurVert != SVT_NULL) { - int nTriaNum = - 1 ; + INTVECTOR vnTriaNum ; double dMinDist = DBL_MAX ; for ( int nTA = 0 ; nTA < nTriaNumA ; ++ nTA) { // Se il triangolo A non è valido, continuo @@ -1323,19 +1372,65 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other) DistPointTriangle DistCalculator( ptFirstV, trTriaA) ; double dDist ; DistCalculator.GetDist( dDist) ; - if ( dDist < dMinDist) { - nTriaNum = nTA ; - dMinDist = dDist ; + // potrei trovare più triangolo equidistanti, li salvo tutti + if ( DistPointTriangle( ptFirstV, trTriaA).GetDist( dDist)) { + if ( abs(dDist - dMinDist) < EPS_SMALL) + vnTriaNum.push_back( nTA) ; + else if ( dDist < dMinDist){ + vnTriaNum.clear() ; + vnTriaNum.push_back( nTA) ; + dMinDist = dDist ; + } } } - if ( nTriaNum >= 0) { + if ( ! vnTriaNum.empty()) { Triangle3d trTriaA ; - GetTriangle( nTriaNum, trTriaA) ; - if ( ( ptFirstV - trTriaA.GetP( 0)) * trTriaA.GetN() < - EPS_SMALL) { - nInOutNum = 1 ; + bool bSame = true ; + // controllo se rispetto a questi triangoli il punto risulta sempre fuori o sempre dentro + for ( int nTriaNum : vnTriaNum) { + GetTriangle( nTriaNum, trTriaA) ; + if ( ( ptFirstV - trTriaA.GetP(0)) * trTriaA.GetN() < - EPS_SMALL) { + if ( nInOutNum == 0) + nInOutNum = 1 ; + else if (nInOutNum == -1) { + bSame = false ; + break ; + } + } + else if ( ( ptFirstV - trTriaA.GetP(0)) * trTriaA.GetN() > EPS_SMALL) { + if ( nInOutNum == 0) + nInOutNum = -1 ; + else if (nInOutNum == 1) { + bSame = false ; + break ; + } + } } - else if ( ( ptFirstV - trTriaA.GetP(0)) * trTriaA.GetN() > EPS_SMALL) { - nInOutNum = - 1 ; + // se le informazioni date dalle normali dei triangoli non sono concordi valuto il triangolo più vicino + // e ricalcolo l'informazione che mi dà la sua normale + if ( ! bSame ) { + Point3d ptBar_tot ; + for (int nTriaNum : vnTriaNum) { + GetTriangle( nTriaNum, trTriaA) ; + ptBar_tot += trTriaA.GetCentroid(); + } + ptBar_tot /= (int)vnTriaNum.size() ; + for (int nTriaNum : vnTriaNum) { + GetTriangle( nTriaNum, trTriaA) ; + Point3d ptInters1, ptInters2 ; + int nInters = IntersLineTria(ptFirstV, ptBar_tot, trTriaA, ptInters1, ptInters2, true) ; + if (nInters == ILTT_NO) + continue ; + else if ( nInters == ILTT_IN ) { + if ( ( ptFirstV - trTriaA.GetP(0)) * trTriaA.GetN() < - EPS_SMALL) + nInOutNum = 1 ; + else if ( ( ptFirstV - trTriaA.GetP(0)) * trTriaA.GetN() > EPS_SMALL) + nInOutNum = -1 ; + break ; + } + else + nInOutNum = 0 ; + } } } if ( nInOutNum == 0) { diff --git a/Tree.cpp b/Tree.cpp index 276448e..387568c 100644 --- a/Tree.cpp +++ b/Tree.cpp @@ -23,13 +23,19 @@ #include "/EgtDev/Include/EGkPolyLine.h" #include "/EgtDev/Include/EGkDistPointCurve.h" #include "/EgtDev/Include/EGkCurve.h" +#include "DistPointCrvComposite.h" +///////////per debug +//#include "/EgtDev/Include/EGkStringUtils3d.h" +//#include "/EgtDev/Include/EExDllMain.h" +///////////per debug + #include using namespace std ; //---------------------------------------------------------------------------- Tree::Tree( void) - : m_pSrfBz( nullptr), m_bTrimmed( false), m_bBilinear( false), m_bMulti( false), m_bClosedU( false), m_bClosedV( false), m_bSplitPatches( true) + : m_pSrfBz( nullptr), m_bTrimmed( false), m_bBilinear( false), m_bMulti( false), m_bClosedU( false), m_bClosedV( false), m_bSplitPatches( true), m_bTestMode( false) { Point3d ptBl( 0, 0), ptTr ( 1 * SBZ_TREG_COEFF, 1 * SBZ_TREG_COEFF) ; Cell cRoot( ptBl, ptTr) ; @@ -38,7 +44,7 @@ Tree::Tree( void) //---------------------------------------------------------------------------- Tree::Tree( const SurfBezier* pSrfBz, const bool bSplitPatches, const Point3d& ptMin, const Point3d& ptMax) - : m_pSrfBz( nullptr), m_bTrimmed( false), m_bBilinear( false), m_bMulti( false), m_bClosedU( false), m_bClosedV( false), m_bSplitPatches( true) + : m_pSrfBz( nullptr), m_bTrimmed( false), m_bBilinear( false), m_bMulti( false), m_bClosedU( false), m_bClosedV( false), m_bSplitPatches( true), m_bTestMode( false) { SetSurf( pSrfBz, bSplitPatches, ptMin, ptMax) ; } @@ -194,8 +200,6 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi } } vLeaves.clear() ; - GetHeightLeaves( -1, vLeaves) ; - m_vnParents = vLeaves ; } // controllo se la superficie è chiusa. // se è chiusa e non ho già fatto split preliminare, splitto sul parametro su cui è chiusa @@ -273,6 +277,10 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi } } } + // calcolo i parent che ho creato con le eventuali divisioni preliminari + INTVECTOR vLeaves ; + GetHeightLeaves( -1, vLeaves) ; + m_vnParents = vLeaves ; // calcolo e salvo la lunghezza reale delle curve di bezier di bordo PtrOwner pCrvV0( m_pSrfBz->GetCurveOnU( 0)) ; @@ -546,6 +554,8 @@ Tree::BuildTree_test( double dLinTol, double dSideMin, double dSideMax) Split( 10) ; m_vnLeaves.push_back( 20) ; m_vnLeaves.push_back( 21) ; + // riempio anche la lista dei parent delle celle + m_vnParents = m_vnLeaves ; return true ; } @@ -1367,7 +1377,12 @@ Tree::GetPolygons( POLYLINEMATRIX& vPolygons) // scorro sulle celle e costruisco i poligoni int nCells = int( vPolygonsBasic.size()) ; for ( int i = 0 ; i < nCells ; ++ i) { - + + ///////////per debug + //std::string sOut = std::to_string( i) ; + //LOG_ERROR( GetEGkLogger(), sOut.c_str()) ; + ///////////per debug + // // costruisco i poligoni partendo dal vettore delle intersezioni, come spiegato a pag15 di Cripps int nId = m_vnLeaves[i] ; if ( m_mTree[nId].m_nFlag == 4) { @@ -1483,9 +1498,9 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons) reverse( vNeigh.begin(), vNeigh.end()) ; // aggiungo i vertici che sono sul lato top, solo se ho più di un vicino top if ( ! vNeigh.empty() && vNeigh.size() != 1) { - // se la superficie è chiusa lungo il parametro U e la cella è sul lato top + // se la superficie è chiusa lungo il parametro V e la cella è sul lato top // devo aggiungere i vertici tenendo conto della periodicità dello spazio parametrico. - if ( m_bClosedU && m_mTree.at( nId).m_bOnTopEdge) { + if ( m_bClosedV && m_mTree.at( nId).m_bOnTopEdge) { for ( int j : vNeigh) { Point3d pt( m_mTree.at( j).GetBottomLeft().x, m_mTree.at( nId).GetTopRight().y) ; vVertices.push_back( pt) ; @@ -1577,12 +1592,13 @@ Tree::ResetTree( void) //---------------------------------------------------------------------------- INTVECTOR -Tree::FindCell( const Point3d& ptToAssign, const CurveLine& clTrim) const +Tree::FindCell( const Point3d& ptToAssign, const CurveLine& clTrim, bool bRecurs) const { INTVECTOR nCells ; int nId = -1 ; // se fallisce ritorna un vettore vuoto // verifico che il punto sia all'interno dello spazio parametrico + // allargo i bordi in modo da tenere anche i punti sul bordo dello spazio parametrico if ( ptToAssign.x < m_mTree.at( -1).GetBottomLeft().x - EPS_SMALL || ptToAssign.x > m_mTree.at( -1).GetTopRight().x + EPS_SMALL|| ptToAssign.y < m_mTree.at( -1).GetBottomLeft().y - EPS_SMALL || ptToAssign.y > m_mTree.at( -1).GetTopRight().y + EPS_SMALL) { //nCells.push_back( - 2) ; @@ -1591,15 +1607,19 @@ Tree::FindCell( const Point3d& ptToAssign, const CurveLine& clTrim) const // se ho diviso preliminarmente le patches e in uno dei due parametri ho un numero dispari di patches devo individuare a mano la cella parent // in cui individuare la foglia giusta - if ( m_bSplitPatches && ( m_nSpanU > 1 || m_nSpanV > 1)) { + if ( (m_bSplitPatches && ( m_nSpanU > 1 || m_nSpanV > 1)) || m_bTestMode) { INTVECTOR nParents = FindCell( ptToAssign, clTrim, m_vnParents) ; nId = nParents.back() ; + if ( m_bTestMode ) { + nCells.push_back(nId) ; + return nCells ; + } } // individuo la foglia in cui ho lo start del loop while ( ! m_mTree.at( nId).IsLeaf()) { if ( m_mTree.at( nId).IsSplitVert()) { double dMid = ( m_mTree.at( nId).GetBottomLeft().x + m_mTree.at( nId).GetTopRight().x) / 2 ; - if ( ptToAssign.x < dMid + EPS_SMALL) { + if ( ptToAssign.x < dMid) { nId = m_mTree.at( nId).m_nChild1 ; } else { @@ -1608,7 +1628,7 @@ Tree::FindCell( const Point3d& ptToAssign, const CurveLine& clTrim) const } else { double dMid = ( m_mTree.at( nId).GetBottomLeft().y + m_mTree.at( nId).GetTopRight().y) / 2 ; - if ( ptToAssign.y < dMid + EPS_SMALL) { + if ( ptToAssign.y < dMid) { nId = m_mTree.at( nId).m_nChild2 ; } else { @@ -1618,26 +1638,37 @@ Tree::FindCell( const Point3d& ptToAssign, const CurveLine& clTrim) const } nCells.push_back( nId) ; - - // se sono in un vertice o su un lato devo controllare di aver trovato la cella giusta - Point3d ptBr( m_mTree.at( nId).GetTopRight().x , m_mTree.at( nId).GetBottomLeft().y) ; - Point3d ptTl( m_mTree.at( nId).GetBottomLeft().x , m_mTree.at( nId).GetTopRight().y) ; - if ( abs( ptToAssign.x - ptTl.x) < EPS_SMALL || abs( ptToAssign.x - ptBr.x) < EPS_SMALL || - abs( ptToAssign.y - ptTl.y) < EPS_SMALL || abs( ptToAssign.y - ptBr.y) < EPS_SMALL) - { - Point3d ptToAssignPlus ; - double dParam ; - Vector3d vDir ; - clTrim.GetParamAtPoint( ptToAssign, dParam, EPS_SMALL) ; - clTrim.GetPointTang( dParam + EPS_SMALL, ICurve::FROM_MINUS, ptToAssignPlus, vDir) ; - if ( abs( vDir.x) > 1 - EPS_SMALL || abs( vDir.y) > 1 - EPS_SMALL) { - vDir.Rotate( Z_AX, -90) ; - ptToAssignPlus = ptToAssignPlus + vDir * 2 * EPS_SMALL ; - } - nCells = FindCell( ptToAssignPlus, clTrim) ; - if ( nCells.empty()) { - ptToAssignPlus = ptToAssignPlus - 4 * vDir * EPS_SMALL ; - nCells = FindCell( ptToAssignPlus, clTrim) ; + if ( ! bRecurs) { + // se sono in un vertice o su un lato devo controllare di aver trovato la cella giusta + Point3d ptBr( m_mTree.at( nId).GetTopRight().x , m_mTree.at( nId).GetBottomLeft().y) ; + Point3d ptTl( m_mTree.at( nId).GetBottomLeft().x , m_mTree.at( nId).GetTopRight().y) ; + if ( abs( ptToAssign.x - ptTl.x) < EPS_SMALL || abs( ptToAssign.x - ptBr.x) < EPS_SMALL || + abs( ptToAssign.y - ptTl.y) < EPS_SMALL || abs( ptToAssign.y - ptBr.y) < EPS_SMALL) + { + Vector3d vtDir ; + clTrim.GetStartDir( vtDir) ; + // proseguo lungo la curva di trim di EPS_SMALL + Point3d ptToAssignPlus = ptToAssign + vtDir * EPS_SMALL ; + // se la curva di trim è praticamente parallela ad un lato allora giro a destra, perché voglio considerare intersecate le celle esterne ( sul bordo) al loop + if ( abs( vtDir.x) > 1 - EPS_SMALL || abs( vtDir.y) > 1 - EPS_SMALL) { + Vector3d vtDirDX = vtDir ; vtDirDX.Rotate( Z_AX, 90) ; + ptToAssignPlus = ptToAssignPlus + vtDir * EPS_SMALL ; + // controllo di non essere uscito dallo spazio parametrico ed eventualmente giro a sinistra + if ( ptToAssignPlus.x < m_mTree.at( -1).GetBottomLeft().x - EPS_SMALL || ptToAssignPlus.x > m_mTree.at( -1).GetTopRight().x + EPS_SMALL|| + ptToAssignPlus.y < m_mTree.at( -1).GetBottomLeft().y - EPS_SMALL || ptToAssignPlus.y > m_mTree.at( -1).GetTopRight().y + EPS_SMALL) { + // rispetto al punto di partenza avanzo lungo la curva di trim + ptToAssignPlus = ptToAssign + vtDir * EPS_SMALL ; + Vector3d vtDirSX = vtDir ; vtDirSX.Rotate( Z_AX, -90) ; + // e poi giro a sinistra + ptToAssignPlus = ptToAssign + vtDir * EPS_SMALL ; + } + } + INTVECTOR nCellsSave = nCells ; + nCells = FindCell( ptToAssignPlus, clTrim, true) ; + if ( nCells.empty()) { + // se nonostante tutto non trovo nulla allora tengo il risultato ottenuto scorrendo l'albero + nCells = nCellsSave ; + } } } return nCells ; @@ -1650,22 +1681,45 @@ Tree::FindCell( const Point3d& ptToAssign, const CurveLine& cl, INTVECTOR vCells // se non trova nulla restituisce un vettore vuoto // restituisce sempre solo una cella - // la CurveLine è il segmento di trim su cui giace ptToAssign - Point3d ptIntersPlus ; - double dParam ; - Vector3d vDir ; - cl.GetParamAtPoint( ptToAssign, dParam, EPS_SMALL) ; - // mi sposto appena più avanti di ptToAssign - cl.GetPointTang( dParam + EPS_SMALL, ICurve::FROM_MINUS, ptIntersPlus, vDir) ; + // questo punto va trovato con precisione, perché se seleziono la cella sbagliata si incasina tutto INTVECTOR nCells ; int nId = -1 ; for ( int nCell : vCells) { - if ( ptIntersPlus.x > m_mTree.at( nCell).GetBottomLeft().x - EPS_ZERO && ptIntersPlus.x < m_mTree.at( nCell).GetTopRight().x + EPS_ZERO && - ptIntersPlus.y > m_mTree.at( nCell).GetBottomLeft().y - EPS_ZERO && ptIntersPlus.y < m_mTree.at( nCell).GetTopRight().y + EPS_ZERO) { + if ( ptToAssign.x > m_mTree.at( nCell).GetBottomLeft().x && ptToAssign.x < m_mTree.at( nCell).GetTopRight().x && + ptToAssign.y > m_mTree.at( nCell).GetBottomLeft().y && ptToAssign.y < m_mTree.at( nCell).GetTopRight().y) { nId = nCell ; nCells.push_back( nId) ; } } + // se non ho trovato nulla vuol dire che sono su un vertice o su un lato + if ( (int)nCells.size() == 0 ) { + for ( int nCell : vCells) { + if ( ptToAssign.x > m_mTree.at( nCell).GetBottomLeft().x - EPS_ZERO && ptToAssign.x < m_mTree.at( nCell).GetTopRight().x + EPS_ZERO && + ptToAssign.y > m_mTree.at( nCell).GetBottomLeft().y - EPS_ZERO && ptToAssign.y < m_mTree.at( nCell).GetTopRight().y + EPS_ZERO) { + nId = nCell ; + nCells.push_back( nId) ; + } + } + if ( (int)nCells.size() == 1) + return nCells ; + // sono su vertice o un lato, quindi avanzo con il parametro lungo la curva + else if ( (int)nCells.size() >= 1 ) { + // la CurveLine è il segmento di trim su cui giace ptToAssign + Point3d ptIntersPlus ; + Vector3d vtDir ; + cl.GetStartDir( vtDir) ; + // mi sposto appena più avanti di ptToAssign + // se la curva è orientata come l'asse x o y mi sto muovendo su un lato e sarò ancora sul lato, quindi dovrei ruotare il vettore prima di spostarmi + if ( abs( vtDir.x) >= 1 - EPS_SMALL || abs( vtDir.y) >= 1 - EPS_SMALL) + vtDir.Rotate( Z_AX, -45) ; + ptIntersPlus = ptToAssign + vtDir * EPS_SMALL ; + nCells = FindCell( ptIntersPlus, cl, vCells) ; + } + // se vuoto allora il punto non è in nessuna delle celle passate in input + else + return nCells ; + } + return nCells ; } @@ -1781,10 +1835,12 @@ Tree::TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons) Point3d ptLast = m_mTree[nId].m_vInters.back().vpt.back() ; //sistemo l'ingresso della prima cella int nEdge ; - OnWhichEdge( nFirstCell, ptFirst, nEdge) ; + if ( ! OnWhichEdge( nFirstCell, ptFirst, nEdge)) + return false ; m_mTree[nFirstCell].m_vInters[nPass].nIn = nEdge ; // sistemo l'uscita dell'ultima cella - OnWhichEdge( nId, ptLast, nEdge) ; + if ( ! OnWhichEdge( nId, ptLast, nEdge)) + return false ; m_mTree[nId].m_vInters.back().nOut = nEdge ; // sistemo il flag dell'ultima cella if ( m_mTree[nId].m_nFlag == -1) @@ -1967,7 +2023,6 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool int nEdge ; // flag che indica il lato su cui ho l'intersezione a partire dal lato top in senso antiorario // oltre il 3 sono le celle adiacenti in diagonale al vertice-> 4 corrisponde al ptTl e da lì in senso antiorario // -1 se la curva è sempre dentro la cella - bool bIntersFound = false ; Point3d ptInters ; int nEdge2 ; if ( ptEnd.y >= ptTR.y && ptEnd.x <= ptTR.x) { @@ -1979,16 +2034,6 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool nEdge2 = 1 ; clEdge2.Set( ptTl, ptBL) ; } - //else if ( AreSamePointExact( ptEnd, ptTl) && bFirstInters) { - // nEdge = 4 ; - // ptInters = ptTl ; - // bIntersFound = true ; - //} - //else if ( AreSamePointExact( ptEnd, ptTR) && bFirstInters) { - // nEdge = 7 ; - // ptInters = ptTR ; - // bIntersFound = true ; - //} } else if ( ptEnd.x <= ptBL.x && ptEnd.y <= ptTR.y) { nEdge = 1 ; @@ -1999,16 +2044,6 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool nEdge2 = 2 ; clEdge2.Set( ptBL, ptBr) ; } - //else if ( AreSamePointExact( ptEnd, ptBL) && bFirstInters) { - // nEdge = 5 ; - // ptInters = ptBL ; - // bIntersFound = true ; - //} - //else if ( AreSamePointExact( ptEnd, ptTl) && bFirstInters) { - // nEdge = 4 ; - // ptInters = ptTl ; - // bIntersFound = true ; - //} } else if ( ptEnd.y <= ptBL.y && ptEnd.x >= ptBL.x) { nEdge = 2 ; @@ -2019,16 +2054,6 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool nEdge2 = 3 ; clEdge2.Set( ptBr, ptTR) ; } - //else if ( AreSamePointExact( ptEnd, ptBr) && bFirstInters) { - // nEdge = 6 ; - // ptInters = ptBr ; - // bIntersFound = true ; - //} - //else if ( AreSamePointExact( ptEnd, ptBL) && bFirstInters) { - // nEdge = 5 ; - // ptInters = ptBL ; - // bIntersFound = true ; - //} } else if ( ptEnd.x >= ptTR.x && ptEnd.y >= ptBL.y) { nEdge = 3 ; @@ -2039,65 +2064,44 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool nEdge2 = 0 ; clEdge2.Set( ptTR, ptTl) ; } - //else if ( AreSamePointExact( ptEnd, ptTR) && bFirstInters) { - // nEdge = 7 ; - // ptInters = ptTR ; - // bIntersFound = true ; - //} - //else if ( AreSamePointExact( ptEnd, ptBr) && bFirstInters) { - // nEdge = 6 ; - // ptInters = ptBr ; - // bIntersFound = true ; - //} } else return false ; - bool bIntersOn2Found = false ; - if ( ! bIntersFound) { - // intersezione e controlli - IntersLineLine illExit( clTrim, clEdge, true) ; - IntCrvCrvInfo aInfo, aInfo2 ; - bool bIntersOn1Found = true ; - if ( ! illExit.GetIntCrvCrvInfo( aInfo)) { - bIntersOn1Found = false ; - if ( ! clEdge2.IsValid()) - return false ; - } - else if ( aInfo.bOverlap && ! bFirstInters) { - ptInters = aInfo.IciA[1].ptI ; - bIntersFound = true ; - } - if ( clEdge2.IsValid() && ! bIntersFound){ - IntersLineLine illExit2( clTrim, clEdge2, true) ; - // verifico su quale dei due lati ho l'intersezione - if ( ! illExit2.GetIntCrvCrvInfo( aInfo2)){ - if ( bIntersOn1Found) { - // se ho intersezione su Edge1 con sovrapposizione, seleziono o il primo punto o il secondo. - if ( aInfo.bOverlap && ! bFirstInters) - ptInters = aInfo.IciA[1].ptI ; - else - ptInters = aInfo.IciA[0].ptI ; - } - else - return false ; - } - else { - //// solo intersezione sul lato 2 - bIntersOn2Found = true ; - if ( aInfo2.bOverlap && ! bFirstInters) - ptInters = aInfo2.IciA[1].ptI ; - else - ptInters = aInfo2.IciA[0].ptI ; - } - } - else - ptInters = aInfo.IciA[0].ptI ; // qui devo mettere il controllo su prima o seconda intersezione? + bool bIntersFound = false ; + // intersezione e controlli + IntersLineLine illExit( clTrim, clEdge, true) ; + IntCrvCrvInfo aInfo, aInfo2 ; + if ( ! illExit.GetIntCrvCrvInfo( aInfo)) { + bIntersFound = false ; + if ( ! clEdge2.IsValid()) + return false ; } - if ( ! bIntersOn2Found) - OnWhichEdge( nId, ptInters, nEdge) ; - else - nEdge = nEdge2 ; + else { + bIntersFound = true ; + if ( aInfo.bOverlap) + ptInters = aInfo.IciA[1].ptI ; + else + ptInters = aInfo.IciA[0].ptI ; + } + if ( clEdge2.IsValid() && ! bIntersFound){ + IntersLineLine illExit2( clTrim, clEdge2, true) ; + // verifico su quale dei due lati ho l'intersezione + if ( ! illExit2.GetIntCrvCrvInfo( aInfo2)) + bIntersFound = false ; + else { + bIntersFound = true ; + //// solo intersezione sul lato 2 + if ( aInfo2.bOverlap) + ptInters = aInfo2.IciA[1].ptI ; + else + ptInters = aInfo2.IciA[0].ptI ; + } + } + if ( ! bIntersFound) + return false ; + // determino il lato/vertice di uscita + OnWhichEdge( nId, ptInters, nEdge) ; m_mTree[nId].m_vInters.back().nOut = nEdge ; if ( (int)vptInters.size() == 0 || ! AreSamePointExact( ptInters , vptInters.back())) vptInters.push_back( ptInters) ; @@ -2239,11 +2243,13 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool m_mTree[nId].m_vInters.emplace_back() ; m_mTree[nId].m_vInters.back().nIn = 6 ; } - else { + else if (! vNeigh1.empty()) { nId = vNeigh1.back() ; m_mTree[nId].m_vInters.emplace_back() ; m_mTree[nId].m_vInters.back().nIn = 7 ; } + else + return false ; } } else if ( nEdge == 5) { @@ -2288,11 +2294,13 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool m_mTree[nId].m_vInters.emplace_back() ; m_mTree[nId].m_vInters.back().nIn = 7 ; } - else { + else if (! vNeigh1.empty()) { nId = vNeigh1[0] ; m_mTree[nId].m_vInters.emplace_back() ; m_mTree[nId].m_vInters.back().nIn = 4 ; } + else + return false ; } } else if ( nEdge == 6) { @@ -2337,11 +2345,13 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool m_mTree[nId].m_vInters.emplace_back() ; m_mTree[nId].m_vInters.back().nIn = 4 ; } - else { + else if (! vNeigh1.empty()) { nId = vNeigh1[0] ; m_mTree[nId].m_vInters.emplace_back() ; m_mTree[nId].m_vInters.back().nIn = 5 ; } + else + return false ; } } else if ( nEdge == 7) { @@ -2386,11 +2396,13 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool m_mTree[nId].m_vInters.emplace_back() ; m_mTree[nId].m_vInters.back().nIn = 5 ; } - else { + else if (! vNeigh1.empty()) { nId = vNeigh1.back() ; m_mTree[nId].m_vInters.emplace_back() ; m_mTree[nId].m_vInters.back().nIn = 6 ; } + else + return false ; } } // aggiungo l'intersezione al vettore delle intersezioni della prossima cella @@ -3376,14 +3388,6 @@ Tree::OnWhichEdge( int nId, const Point3d& ptToAssign, int& nEdge) const Point3d ptTl ( ptBL.x, ptTR.y) ; Point3d ptBr ( ptTR.x, ptBL.y) ; - if ( ptToAssign.x > ptBL.x && ptToAssign.x < ptTR.x && abs( ptToAssign.y - ptTR.y) < EPS_SMALL) - nEdge = 0 ; - else if ( ptToAssign.y > ptBL.y && ptToAssign.y < ptTR.y && abs( ptToAssign.x - ptBL.x) < EPS_SMALL) - nEdge = 1 ; - else if ( ptToAssign.x > ptBL.x && ptToAssign.x < ptTR.x && abs( ptToAssign.y - ptBL.y) < EPS_SMALL) - nEdge = 2 ; - else if ( ptToAssign.y > ptBL.y && ptToAssign.y < ptTR.y && abs( ptToAssign.x - ptTR.x) < EPS_SMALL) - nEdge = 3 ; if ( AreSamePointApprox( ptToAssign, ptTR)) nEdge = 7 ; else if ( AreSamePointApprox( ptToAssign, ptTl)) @@ -3392,6 +3396,14 @@ Tree::OnWhichEdge( int nId, const Point3d& ptToAssign, int& nEdge) const nEdge = 5 ; else if ( AreSamePointApprox( ptToAssign, ptBr)) nEdge = 6 ; + else if ( ptToAssign.x > ptBL.x && ptToAssign.x < ptTR.x && abs( ptToAssign.y - ptTR.y) < EPS_SMALL) + nEdge = 0 ; + else if ( ptToAssign.y > ptBL.y && ptToAssign.y < ptTR.y && abs( ptToAssign.x - ptBL.x) < EPS_SMALL) + nEdge = 1 ; + else if ( ptToAssign.x > ptBL.x && ptToAssign.x < ptTR.x && abs( ptToAssign.y - ptBL.y) < EPS_SMALL) + nEdge = 2 ; + else if ( ptToAssign.y > ptBL.y && ptToAssign.y < ptTR.y && abs( ptToAssign.x - ptTR.x) < EPS_SMALL) + nEdge = 3 ; else return false ; return true ; diff --git a/Tree.h b/Tree.h index ca485ca..d9ff804 100644 --- a/Tree.h +++ b/Tree.h @@ -26,13 +26,12 @@ struct Inters { PNTVECTOR vpt ; int nOut ; bool bCCW ; - bool bVertex ; int nChunk ; // riordino le intersezioni per lato in senso antiorario dal top - // se ho più intersezioni che entrano in un lato le riordino considerando che percorro i lati in senso antiorario a partire da ptTR + // se ho pi� intersezioni che entrano in un lato le riordino considerando che percorro i lati in senso antiorario a partire da ptTR bool operator < ( Inters& b) { - // trovo in che ordine stanno i due strat, tenendo conto anche della possibilità che siano vertici + // trovo in che ordine stanno i due strat, tenendo conto anche della possibilit� che siano vertici INTVECTOR vEdges = { 7, 0, 4, 1, 5, 2, 6, 3} ; const auto iter1 = find( vEdges.begin(), vEdges.end(), nIn) ; int nPos1 = std::distance( vEdges.begin(), iter1) ; @@ -53,7 +52,7 @@ struct Inters { pl.Close() ; pl.GetAreaXY( dAreaB) ; } - // se nIn è un vertice sistemo il valore + // se nIn � un vertice sistemo il valore int nEdgeIn = nIn ; if ( nIn > 3) nEdgeIn = nIn - 4 ; @@ -74,8 +73,8 @@ struct Inters { } } ; // nIn e nOut sono flag che indicano da quale lato ho l'ingresso e l'uscita a partire dal lato top in senso antiorario -// oltre il 3 sono le celle adiacenti in diagonale al vertice-> 4 corrisponde al ptTl e da lì in senso antiorario -// -1 se la curva è sempre dentro la cella +// oltre il 3 sono le celle adiacenti in diagonale al vertice-> 4 corrisponde al ptTl e da l� in senso antiorario +// -1 se la curva � sempre dentro la cella //---------------------------------------------------------------------------- class Cell @@ -90,11 +89,16 @@ class Cell // |_________________| // Edge 5 ( SW) Edge 2 (Bottom) Edge 6 ( SE) public : + ~Cell( void) {} Cell( void) : m_nId( -1),m_nTop ( -2), m_nBottom( -2), m_nLeft( -2), m_nRight ( -2), m_nParent( -2), m_nDepth( 0), m_nChild1( -2), m_nChild2( -2), m_nFlag( -1), m_nFlag2( 0), m_nRightEdgeIn( -1), m_bOnLeftEdge( false), m_bOnTopEdge( false), - m_ptPbl( ORIG), m_ptPtr( SBZ_TREG_COEFF, SBZ_TREG_COEFF, 0), m_bProcessed( false), m_bSplitVert( true) {} - Cell( const Point3d& ptBL, const Point3d& ptTR) + m_ptPbl( ORIG), m_ptPtr( SBZ_TREG_COEFF, SBZ_TREG_COEFF, 0), m_bProcessed( false), m_bSplitVert( true) + { + Point3d ptTr ( 1 * SBZ_TREG_COEFF, 1 * SBZ_TREG_COEFF) ; + m_ptPtr = ptTr ; + } + Cell( const Point3d& ptBL, const Point3d& ptTR) : m_nId( -1),m_nTop ( -2), m_nBottom( -2), m_nLeft( -2), m_nRight ( -2), m_nParent( -2), m_nDepth( 0), m_nChild1( -2), m_nChild2( -2), m_nFlag( -1), m_nFlag2( 0), m_nRightEdgeIn( -1), m_bOnLeftEdge( false), m_bOnTopEdge( false), m_ptPbl( ptBL), m_ptPtr( ptTR), m_bProcessed( false), m_bSplitVert( true) {} @@ -114,9 +118,9 @@ class Cell { return m_ptPtr ; } double GetSplitValue( void) const { return m_dSplit ; } - bool IsSplitVert( void) const // se true la cella verrebbe splittata verticalmente, sennò orizzontalmente + bool IsSplitVert( void) const // se true la cella verrebbe splittata verticalmente, senn� orizzontalmente { return m_bSplitVert ; } - bool IsLeaf( void) const // flag che indica se la cella ha figli o se è una foglia + bool IsLeaf( void) const // flag che indica se la cella ha figli o se � una foglia { return ( m_nChild1 == -2 && m_nChild2 == -2) ; } bool IsProcessed( void) const // flag che indica se tutti i figli della cella, se ce ne sono, sono stati processati { return m_bProcessed ; } @@ -134,24 +138,24 @@ class Cell int m_nLeft ; // cella adiacente al lato left int m_nRight ; // cella adiacente al lato right int m_nParent ; // cella genitore - int m_nDepth ; // profondità della cella rispetto a root - double m_dSplit ; // parametro a cui è stata splittata la cella + int m_nDepth ; // profondit� della cella rispetto a root + double m_dSplit ; // parametro a cui � stata splittata la cella int m_nChild1 ; // prima cella figlio int m_nChild2 ; // seconda cella figlio int m_nFlag ; // falg che indica la caratterizzazione della cella rispetto ai loop di trim // 0 esterna, 1 intersecata, 2 contiene un loop, 3 intersecata e contenente un loop, 4 contenuta in un loop - int m_nFlag2 ; // falg che indica se la cella è stata attraversata durante l'ultima fase del labelling - int m_nRightEdgeIn ; // 0 right edge fuori, 1 right edge dentro, 2 metà e metà - bool m_bOnLeftEdge ; // flag che indica se la cella è sul lato sinistro ( per superfici chiuse sul parametro U) - bool m_bOnTopEdge ; // flag che indica se la cella è sul lato top ( per superfici chiuse sul parametro V) + int m_nFlag2 ; // falg che indica se la cella � stata attraversata durante l'ultima fase del labelling + int m_nRightEdgeIn ; // 0 right edge fuori, 1 right edge dentro, 2 met� e met� + bool m_bOnLeftEdge ; // flag che indica se la cella � sul lato sinistro ( per superfici chiuse sul parametro U) + bool m_bOnTopEdge ; // flag che indica se la cella � sul lato top ( per superfici chiuse sul parametro V) std::vector m_vInters ; // vettore delle intersezioni della cella con i loop di trim - // ogni elemento del vettore è l'insieme dei punti che caratterizza un atrtaversamento della cella + // ogni elemento del vettore � l'insieme dei punti che caratterizza un atrtaversamento della cella private : Point3d m_ptPbl ; // punto bottom left Point3d m_ptPtr ; // punto top right - bool m_bProcessed ; // flag che indica se la cella è stata processata - bool m_bSplitVert ; // flag che indica in quale direzione è stata divisa la cella + bool m_bProcessed ; // flag che indica se la cella � stata processata + bool m_bSplitVert ; // flag che indica in quale direzione � stata divisa la cella } ; //---------------------------------------------------------------------------- @@ -163,18 +167,19 @@ class Tree Tree ( const SurfBezier* pSrfBz, bool bSplitPatches = true, const Point3d& ptMin = ORIG, const Point3d& ptMax = ORIG) ; void SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches = true, const Point3d& ptMin = ORIG, const Point3d& ptMax = ORIG) ; bool GetIndependentTrees( BIPNTVECTOR& vTrees) ; // calcolo la suddivisione della superficie solo sulle singole bbox dei loop di trim ( unendo quelli vicini) - bool BuildTree( double dLinTol = LIN_TOL_STD, double dSideMin = 1, double dSideMax = INFINITO) ; // dSideMax è il massimo per la dimensione maggiore di un triangolo della trimesh - // dSideMin è lunghezza minima del lato di una cella nello spazio reale + bool BuildTree( double dLinTol = LIN_TOL_STD, double dSideMin = 1, double dSideMax = INFINITO) ; // dSideMax � il massimo per la dimensione maggiore di un triangolo della trimesh + // dSideMin � lunghezza minima del lato di una cella nello spazio reale bool BuildTree_test( double dLinTol = LIN_TOL_STD, double dSideMin = 1, double dSideMax = INFINITO) ; bool GetPolygons( POLYLINEMATRIX& vPolygons) ; bool GetPolygonsBasic( POLYLINEVECTOR& vPolygons) ; // restituisce il poligono corrispondente ad ogni cella foglia dell'albero // ad ogni poligono sono stati aggiunti tutti i vertici dei vicini posizionati sui suoi lati bool GetLeaves ( std::vector& vLeaves) const ; + void SetTestMode( void) { m_bTestMode = true ;} ; private : bool Split( int nId, double dSplitValue) ; // funzione di split di una cella al parametro indicato nella direzione data da bVert - bool Split( int nId) ; // funzione di split di una cella dell'albero a metà nella direzione data da bVert - void Balance( void) ; // creo rami in modo che tutte tutte le foglie abbiano come adiacenti foglie ad una profonditù di +- 1 + bool Split( int nId) ; // funzione di split di una cella dell'albero a met� nella direzione data da bVert + void Balance( void) ; // creo rami in modo che tutte tutte le foglie abbiano come adiacenti foglie ad una profondit� di +- 1 int GetHeightLeaves( int nId, INTVECTOR& vnLeaves, int d = 0) const ; // altezza del subtree a partire dal nodo nId int GetDepth( int nId, int nRef) const ; // livello del nodo nId void GetTopNeigh( int nId, INTVECTOR& vTopNeighs) const ; // restituisce le celle foglie che sono adiacenti al lato top @@ -183,7 +188,7 @@ class Tree void GetRightNeigh( int nId, INTVECTOR& vRightNeighs) const ; // restituisce le celle foglie che sono adiacenti al lato right void GetRootNeigh( int nEdge, INTVECTOR& vNeigh) ; // restituisce le foglie dell'albero che sono adiacenti al lato nEdge, numerato a partire dal top ( 0) in senso antiorario void ResetTree( void) ; // resetto m_bProcessed a false per tutti i nodi dell'albero - INTVECTOR FindCell( const Point3d& ptToAssign, const CurveLine& cl) const ; // dato un punto, trova la cella foglia a cui appartiene + INTVECTOR FindCell( const Point3d& ptToAssign, const CurveLine& cl, bool bRecurs = false) const ; // dato un punto, trova la cella foglia a cui appartiene INTVECTOR FindCell( const Point3d& ptToAssign, const CurveLine& cl, INTVECTOR vCells) const ; // dato un punto, trova la cella foglia a cui appartiene bool TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons) ; // tracing dei loop e labelling delle celle bool FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool bFirstInters = true) ; // trova le intersezioni tra una cella e una linea di trim @@ -219,8 +224,9 @@ class Tree int m_nSpanU ; int m_nSpanV ; POLYLINEMATRIX m_vPolygons ; // matrice dei poligoni del tree - std::map m_mTree ; // mappa che contiene tutti i nodi e le foglie dell'albero. -2 è puntatore Null e -1 è root - std::map m_mVert ; // mappa che contiene tutti i vertici 3d delle celle del tree. L'Id è lo stesso che la cella ha in m_mTree + std::map m_mTree ; // mappa che contiene tutti i nodi e le foglie dell'albero. -2 � puntatore Null e -1 � root + std::map m_mVert ; // mappa che contiene tutti i vertici 3d delle celle del tree. L'Id � lo stesso che la cella ha in m_mTree INTVECTOR m_vnLeaves ; // vettore delle foglie INTVECTOR m_vnParents ; // vettore delle celle ottenute dalla divisione preliminare in singole patch + bool m_bTestMode ; // bool che indica se la test mode è attiva } ; \ No newline at end of file