diff --git a/SurfBezier.cpp b/SurfBezier.cpp index d454768..626707f 100644 --- a/SurfBezier.cpp +++ b/SurfBezier.cpp @@ -1600,11 +1600,6 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin) const } } - // conto quanti punti ho in totale, senza eliminare le ripetizioni - int nTotPnt = 0 ; - for ( PolyLine& pl2D : vPL) - nTotPnt+= pl2D.GetPointNbr() ; - // se ho ottenuto meno triangoli di quelli che avrei dovuto avere allora potrei aver avuto un problema in prossimità di un polo // se comunque ho corrispondenza tra vPnt e vPnt3d allora eseguo la trinagolazione in 3d int nTriaNumber = ( vPnt.size() - 2) + (2 * (vPL.size() - 1)) - (vPL.size() > 2 ? vPL.size() - 2 : 0) - (vPL.size() != 1 ? vPL.size() : 0) ; @@ -1713,7 +1708,6 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin) const bool SurfBezier::ReorderPntVector( const POLYLINEVECTOR& vPL, bool bTriangulatedIn3D, const PNTVECTOR& vPnt, const POLYLINEVECTOR& vPLToOrd, PNTVECTOR& vPntOrd) const { - int nCurrPoint = 0 ; BOOLVECTOR vbPolyChecked( vPL.size()) ; fill( vbPolyChecked.begin(), vbPolyChecked.end(), false) ; for ( int p = 0 ; p < int(vPnt.size()) ; ++p) { @@ -4152,6 +4146,8 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int } // reinizializzo la superficie con il nuovo numero di span in U nSpanU = nSpanU0 + nRep1 ; + if( nSpanU != nSpanU1 + nRep0) + LOG_DBG_ERR( GetEGkLogger(), "There could be an errore in the creation of a ruled surface in mode RLT_B_MINDIST") ; if ( nSpanU < max(nSpanU0, nSpanU1)) nSpanU = max(nSpanU0, nSpanU1) ; nSecondRowInd = nDegU * nSpanU + 1 ; @@ -4413,7 +4409,6 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int int nAtEnd1 = 0 ; Point3d ptP0 ; plU0.GetFirstPoint( ptP0) ; int c = 0 ; - int nCrvCount = 0 ; int nRep0 = 0 ; // match interni consecutivi uguali di punti della curva U0 con punti della curva U1 int nRep1 = 0 ; double dLastParamMatch = 0 ; @@ -4453,7 +4448,6 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int else { dLastParamMatch = dParam ; ptLastPointMatch = ptJoint ; - nCrvCount = pCrvU1->GetCurveCount() ; // se sono già troppo vicino ad un split esistente allora non faccio nulla if ( abs(dParam - round( dParam)) < 100 * EPS_PARAM) { ++c ; @@ -4527,7 +4521,6 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int else { dLastParamMatch = dParam ; ptLastPointMatch = ptJoint ; - nCrvCount = pCrvU0->GetCurveCount() ; //se sono troppo vicino ad uno split esistente allora non faccio nulla if( abs(dParam - round( dParam)) < 100 * EPS_PARAM) { ++c ; @@ -4660,6 +4653,9 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int // ( numero di sottocurve che compongono la U0 + tutte le ripetizioni dei match di punti della curva U1 con i punti di U0) nSpanU = nSpanU0 + nAtStart0 + nAtEnd0 + nRep1 ; + if( nSpanU != nSpanU1 + nAtStart1 + nAtEnd1 + nRep0) + LOG_DBG_ERR( GetEGkLogger(), "There could be an error in the creation of a ruled surface in mode RLT_B_MINDIST_PLUS") ; + nSecondRowInd = nDegU * nSpanU + 1 ; // inizializzo la superficie Init( nDegU, nDegV, nSpanU, nSpanV, bRat) ; @@ -4912,7 +4908,6 @@ SurfBezier::CreateBySetOfCurves( const ICURVEPOVECTOR& vCrvBez) } SetControlPoint( n + (s * nDegU) + (nDegU * nSpanU + 1) * (g * 3 + 6), ptCtrl2) ; //// trovo i punti di controllo intermedi tra le curve usando la parabola che unisce queste tre curve//// - double dPar = double(n) / nDegU ; Point3d ptP0 = pCrv0->GetControlPoint( n) ; Point3d ptP1 = pCrv1->GetControlPoint( n) ; Point3d ptP2 = pCrv2->GetControlPoint( n) ; diff --git a/Tree.cpp b/Tree.cpp index e84fe62..3d4f2e9 100644 --- a/Tree.cpp +++ b/Tree.cpp @@ -327,14 +327,16 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi if ( ( AreSamePointApprox( ptP00, ptP01) || AreSamePointApprox( ptP10, ptP11)) || ( AreSamePointApprox( ptP00, ptP10) || AreSamePointApprox( ptP01, ptP11))) { // m_bClosed = true ; - if ( ( AreSamePointApprox( ptP00, ptP01) || AreSamePointApprox( ptP10, ptP11)) && (int) m_mTree.size() == 1) { - if ( AreSamePointApprox( ptP00, ptP01) && AreSamePointApprox( ptP10, ptP11)) { - m_mTree[-1].m_nTop = -1 ; - m_mTree[-1].m_nBottom = -1 ; - m_bClosedV = true ; + if ( ( AreSamePointApprox( ptP00, ptP01) || AreSamePointApprox( ptP10, ptP11))) { + if( int( m_mTree.size()) == 1) { + if ( AreSamePointApprox( ptP00, ptP01) && AreSamePointApprox( ptP10, ptP11)) { + m_mTree[-1].m_nTop = -1 ; + m_mTree[-1].m_nBottom = -1 ; + m_bClosedV = true ; + } + m_mTree[-1].SetSplitDirVert( false) ; + Split( -1) ; } - m_mTree[-1].SetSplitDirVert( false) ; - Split( -1) ; // qui devo fare il controllo capped ( chiusura a semisfera) // devo controllare se i punti ai parametri U=0 e U=1 sono tutti coincidenti // in caso devo fare uno split nell'altra direzione @@ -350,7 +352,7 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi } m_vbPole[1] = bPole0 ; m_vbPole[3] = bPole1 ; - if ( bPole0 && bPole1) { + if ( bPole0 && bPole1 && int( m_mTree.size() == 3)) { m_mTree[0].SetSplitDirVert( true) ; Split( 0) ; m_mTree[1].SetSplitDirVert( true) ; @@ -367,29 +369,29 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi } m_mTree[-1].SetSplitDirVert( true) ; Split( -1) ; - // devo controllare se i punti ai parametri V=0 e V=1 sono tutti coincidenti - // in caso devo fare uno split nell'altra direzione - bool bOk = false ; - bool bPole0 = true, bPole1 = true ; - Point3d ptV0, ptV1 ; - // controllo se tutti i punti sull'isoparametrica sono uguali - for ( int i = 1 ; i < nDegU * nSpanU + 1 ; ++ i) { - ptV0 = m_pSrfBz->GetControlPoint( i, &bOk) ; - bPole0 = bPole0 && AreSamePointApprox( ptP00, ptV0) ; - ptV1 = m_pSrfBz->GetControlPoint( i + ( nDegU * nSpanU + 1) * ( nDegV * nSpanV), &bOk) ; - bPole1 = bPole1 && AreSamePointApprox( ptP01, ptV1) ; - } - m_vbPole[0] = bPole0 ; - m_vbPole[2] = bPole1 ; - if ( bPole0 && bPole1) { - m_mTree[0].SetSplitDirVert( false) ; - Split( 0) ; - m_mTree[1].SetSplitDirVert( false) ; - Split( 1) ; - } + } + // devo controllare se i punti ai parametri V=0 e V=1 sono tutti coincidenti + // in caso devo fare uno split nell'altra direzione + bool bOk = false ; + bool bPole0 = true, bPole1 = true ; + Point3d ptV0, ptV1 ; + // controllo se tutti i punti sull'isoparametrica sono uguali + for ( int i = 1 ; i < nDegU * nSpanU + 1 ; ++ i) { + ptV0 = m_pSrfBz->GetControlPoint( i, &bOk) ; + bPole0 = bPole0 && AreSamePointApprox( ptP00, ptV0) ; + ptV1 = m_pSrfBz->GetControlPoint( i + ( nDegU * nSpanU + 1) * ( nDegV * nSpanV), &bOk) ; + bPole1 = bPole1 && AreSamePointApprox( ptP01, ptV1) ; + } + m_vbPole[0] = bPole1 ; + m_vbPole[2] = bPole0 ; + if ( bPole0 && bPole1 && int( m_mTree.size()) == 3) { + m_mTree[0].SetSplitDirVert( false) ; + Split( 0) ; + m_mTree[1].SetSplitDirVert( false) ; + Split( 1) ; } // se ho fatto solo 1 split orizzontale e ho due celle foglie nId = 0 e nId = 1 - else if ( (int) m_mTree.size() > 1 && (int) m_mTree.size() < 4 && ! m_mTree.at(-1).IsSplitVert()) { // si può mettere anche < 5 + if ( int( m_mTree.size() == 3) && ! m_mTree.at(-1).IsSplitVert()) { m_mTree[0].m_nLeft = -1 ; m_mTree[0].m_nRight = -1 ; m_mTree[1].m_nLeft = -1 ; @@ -695,27 +697,27 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax) { // suddivido lo spazio parametrico con divisioni a metà su uno dei due parametri int nCToSplit = -1 ; - Cell* cToSplit = &m_mTree[nCToSplit] ; + Cell* pcToSplit = &m_mTree[nCToSplit] ; if ( ! m_bBilinear) { - while ( nCToSplit != -2 && cToSplit->IsProcessed() == false) { + while ( nCToSplit != -2 && pcToSplit->IsProcessed() == false) { // controllo che la cella non sia già stata preliminarmente splittata - if ( cToSplit->IsLeaf()) { + if ( pcToSplit->IsLeaf()) { // calcolo in quale direzione ho più curvatura // ptP00P10 è un punto tra P00 e P10 double dCurvU = 0, dCurvV = 0 ; - double dLenParU = ( cToSplit->GetTopRight().x - cToSplit->GetBottomLeft().x) / SBZ_TREG_COEFF ; - double dLenParV = ( cToSplit->GetTopRight().y - cToSplit->GetBottomLeft().y) / SBZ_TREG_COEFF ; + double dLenParU = ( pcToSplit->GetTopRight().x - pcToSplit->GetBottomLeft().x) / SBZ_TREG_COEFF ; + double dLenParV = ( pcToSplit->GetTopRight().y - pcToSplit->GetBottomLeft().y) / SBZ_TREG_COEFF ; if ( dLenParU <= 1. / m_nDegV || dLenParV <= 1. / m_nDegU || Dist(m_mVert[nCToSplit][0], m_mVert[nCToSplit][2]) < dSideMin * 2 || Dist(m_mVert[nCToSplit][1], m_mVert[nCToSplit][3]) < dSideMin * 2) { - double dU = ( cToSplit->GetTopRight().x + cToSplit->GetBottomLeft().x) / 2 / SBZ_TREG_COEFF ; - double dV = ( cToSplit->GetTopRight().y + cToSplit->GetBottomLeft().y) / 2 / SBZ_TREG_COEFF ; + double dU = ( pcToSplit->GetTopRight().x + pcToSplit->GetBottomLeft().x) / 2 / SBZ_TREG_COEFF ; + double dV = ( pcToSplit->GetTopRight().y + pcToSplit->GetBottomLeft().y) / 2 / SBZ_TREG_COEFF ; double dULoc = 0.5, dVLoc = 0.5 ; Point3d ptPSrf, ptP00P10, ptP10P11, ptP11P01, ptP01P00 ; m_pSrfBz->GetPointD1D2( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrf) ; - m_pSrfBz->GetPointD1D2( dU, cToSplit->GetBottomLeft().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP00P10) ; - m_pSrfBz->GetPointD1D2( cToSplit->GetTopRight().x / SBZ_TREG_COEFF, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP10P11) ; - m_pSrfBz->GetPointD1D2( dU, cToSplit->GetTopRight().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP11P01) ; - m_pSrfBz->GetPointD1D2( cToSplit->GetBottomLeft().x / SBZ_TREG_COEFF, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP01P00) ; + m_pSrfBz->GetPointD1D2( dU, pcToSplit->GetBottomLeft().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP00P10) ; + m_pSrfBz->GetPointD1D2( pcToSplit->GetTopRight().x / SBZ_TREG_COEFF, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP10P11) ; + m_pSrfBz->GetPointD1D2( dU, pcToSplit->GetTopRight().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP11P01) ; + m_pSrfBz->GetPointD1D2( pcToSplit->GetBottomLeft().x / SBZ_TREG_COEFF, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP01P00) ; Point3d ptV = ( 1 - dULoc) * ptP00P10 + dULoc * ptP11P01 ; Point3d ptU = ( 1 - dVLoc) * ptP10P11 + dVLoc * ptP01P00 ; dCurvV = Dist( ptV, ptPSrf) ; @@ -727,13 +729,13 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax) Point3d ptPSrf, ptP00P10, ptP10P11, ptP11P01, ptP01P00, ptPSrfMid ; double dStep = 1. / ( m_nDegU * 2) ; for ( double k = dStep ; k < 1 + EPS_SMALL ; k = k + dStep) { - double dU = ( k * cToSplit->GetTopRight().x + ( 1 - k) * cToSplit->GetBottomLeft().x) / SBZ_TREG_COEFF ; - double dV = ( cToSplit->GetTopRight().y + cToSplit->GetBottomLeft().y) / 2 / SBZ_TREG_COEFF ; + double dU = ( k * pcToSplit->GetTopRight().x + ( 1 - k) * pcToSplit->GetBottomLeft().x) / SBZ_TREG_COEFF ; + double dV = ( pcToSplit->GetTopRight().y + pcToSplit->GetBottomLeft().y) / 2 / SBZ_TREG_COEFF ; m_pSrfBz->GetPointD1D2( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrf) ; if ( k == 0.5) ptPSrfMid = ptPSrf ; - m_pSrfBz->GetPointD1D2( dU, cToSplit->GetBottomLeft().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP00P10) ; - m_pSrfBz->GetPointD1D2( dU, cToSplit->GetTopRight().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP11P01) ; + m_pSrfBz->GetPointD1D2( dU, pcToSplit->GetBottomLeft().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP00P10) ; + m_pSrfBz->GetPointD1D2( dU, pcToSplit->GetTopRight().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP11P01) ; CurveLine clV ; clV.Set( ptP00P10, ptP11P01) ; DistPointCurve dpc( ptPSrf, clV) ; @@ -743,14 +745,14 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax) } dStep = 1. / ( m_nDegV * 2) ; for ( double k = dStep ; k < 1 + EPS_SMALL ; k = k + dStep) { - double dU = ( cToSplit->GetTopRight().x + cToSplit->GetBottomLeft().x) / 2 / SBZ_TREG_COEFF ; - double dV = ( k * cToSplit->GetTopRight().y + ( 1 - k) * cToSplit->GetBottomLeft().y) / SBZ_TREG_COEFF ; + double dU = ( pcToSplit->GetTopRight().x + pcToSplit->GetBottomLeft().x) / 2 / SBZ_TREG_COEFF ; + double dV = ( k * pcToSplit->GetTopRight().y + ( 1 - k) * pcToSplit->GetBottomLeft().y) / SBZ_TREG_COEFF ; if ( k == 0.5 && ! AreSamePointApprox( ORIG, ptPSrfMid)) ptPSrf = ptPSrfMid ; else m_pSrfBz->GetPointD1D2( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrf) ; - m_pSrfBz->GetPointD1D2( cToSplit->GetTopRight().x / SBZ_TREG_COEFF, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP10P11) ; - m_pSrfBz->GetPointD1D2( cToSplit->GetBottomLeft().x / SBZ_TREG_COEFF, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP01P00) ; + m_pSrfBz->GetPointD1D2( pcToSplit->GetTopRight().x / SBZ_TREG_COEFF, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP10P11) ; + m_pSrfBz->GetPointD1D2( pcToSplit->GetBottomLeft().x / SBZ_TREG_COEFF, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP01P00) ; CurveLine clU ; clU.Set( ptP01P00, ptP10P11) ; DistPointCurve dpc( ptPSrf, clU) ; @@ -807,7 +809,7 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax) // lungo la direzione U ho una curvatura maggiore bVert = true ; } - cToSplit->SetSplitDirVert( bVert) ; + pcToSplit->SetSplitDirVert( bVert) ; //Point3d ptP00, ptP10, ptP11, ptP01 ; //ptP00 = m_mVert[nCToSplit][0] ; //ptP10 = m_mVert[nCToSplit][1] ; @@ -819,19 +821,19 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax) double dLen2 = Dist( ptP01, ptP11) ; double dLen3 = Dist( ptP00, ptP01) ; if ( dLen0 < EPS_ZERO && dLen2 < EPS_ZERO ) { - double dV = ( cToSplit->GetBottomLeft().y + cToSplit->GetTopRight().y) / 2 / SBZ_TREG_COEFF ; + double dV = ( pcToSplit->GetBottomLeft().y + pcToSplit->GetTopRight().y) / 2 / SBZ_TREG_COEFF ; PtrOwner pCrvV( m_pSrfBz->GetCurveOnU( dV)) ; double dLenU0, dLenU1 ; - pCrvV->GetLengthAtParam( cToSplit->GetBottomLeft().x / SBZ_TREG_COEFF, dLenU0) ; - pCrvV->GetLengthAtParam( cToSplit->GetTopRight().x / SBZ_TREG_COEFF, dLenU1) ; + pCrvV->GetLengthAtParam( pcToSplit->GetBottomLeft().x / SBZ_TREG_COEFF, dLenU0) ; + pCrvV->GetLengthAtParam( pcToSplit->GetTopRight().x / SBZ_TREG_COEFF, dLenU1) ; dLen0 = abs( dLenU1 - dLenU0) ; } if ( dLen1 < EPS_ZERO && dLen3 < EPS_ZERO ) { - double dU = ( cToSplit->GetBottomLeft().x + cToSplit->GetTopRight().x) / 2 / SBZ_TREG_COEFF ; + double dU = ( pcToSplit->GetBottomLeft().x + pcToSplit->GetTopRight().x) / 2 / SBZ_TREG_COEFF ; PtrOwner pCrvU( m_pSrfBz->GetCurveOnV( dU)) ; double dLenV0, dLenV1 ; - pCrvU->GetLengthAtParam( cToSplit->GetBottomLeft().y / SBZ_TREG_COEFF, dLenV0) ; - pCrvU->GetLengthAtParam( cToSplit->GetTopRight().y / SBZ_TREG_COEFF, dLenV1) ; + pCrvU->GetLengthAtParam( pcToSplit->GetBottomLeft().y / SBZ_TREG_COEFF, dLenV0) ; + pCrvU->GetLengthAtParam( pcToSplit->GetTopRight().y / SBZ_TREG_COEFF, dLenV1) ; dLen1 = abs( dLenV1 - dLenV0) ; } // verifico che la cella sia da splittare e che eventualmente sia abbastanza grande da poterlo fare @@ -874,9 +876,9 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax) int nStepsV = int( 51 * dDimV + 5 * ( 1 - dDimV)) ; for ( int u = 0 ; u < nStepsU && ! bSplit ; ++ u) { double dU = double ( u) / double ( nStepsU - 1) ; - double dULoc = ( ( 1 - dU) * cToSplit->GetBottomLeft().x + dU * cToSplit->GetTopRight().x) / SBZ_TREG_COEFF ; - if ( ! m_pSrfBz->GetPointD1D2( dULoc, cToSplit->GetBottomLeft().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBz0) || - ! m_pSrfBz->GetPointD1D2( dULoc, cToSplit->GetTopRight().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBz1)) + double dULoc = ( ( 1 - dU) * pcToSplit->GetBottomLeft().x + dU * pcToSplit->GetTopRight().x) / SBZ_TREG_COEFF ; + if ( ! m_pSrfBz->GetPointD1D2( dULoc, pcToSplit->GetBottomLeft().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBz0) || + ! m_pSrfBz->GetPointD1D2( dULoc, pcToSplit->GetTopRight().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBz1)) return false ; // verifico che la cella non sia uno spicchio in verticale, cioè con ptP00 == ptP01 && ptP10 == ptP11 // ( vedi disegno sotto per uno spicchio verticale) @@ -897,7 +899,7 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax) clV.Set( pt0010, pt0111) ; for ( int v = 0 ; v < nStepsV ; ++ v) { double dV = double ( v) / double ( nStepsV - 1) ; - double dVLoc = ( ( 1 - dV) * cToSplit->GetBottomLeft().y + dV * cToSplit->GetTopRight().y) / SBZ_TREG_COEFF ; + double dVLoc = ( ( 1 - dV) * pcToSplit->GetBottomLeft().y + dV * pcToSplit->GetTopRight().y) / SBZ_TREG_COEFF ; if ( ! m_pSrfBz->GetPointD1D2( dULoc, dVLoc, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBzV)) return false ; DistPointCurve dpc( ptBzV, clV) ; @@ -934,42 +936,42 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax) } if ( bSplit || dSideMaxVal > dSideMax) { - cToSplit->SetSplitDirVert( bVert) ; + pcToSplit->SetSplitDirVert( bVert) ; // effettuo lo split Split( nCToSplit) ; // procedo con lo split del Child1 - nCToSplit = cToSplit->m_nChild1 ; - cToSplit = &m_mTree[nCToSplit] ; + nCToSplit = pcToSplit->m_nChild1 ; + pcToSplit = &m_mTree[nCToSplit] ; } else { // sono arrivato ad una cella Leaf, quindi salvo la cella m_vnLeaves.push_back( nCToSplit) ; - cToSplit->SetProcessed() ; + pcToSplit->SetProcessed() ; // risalgo i parent finché non trovo il primo Child2 da processare - nCToSplit = cToSplit->m_nParent ; - cToSplit = &m_mTree[nCToSplit] ; + nCToSplit = pcToSplit->m_nParent ; + pcToSplit = &m_mTree[nCToSplit] ; if ( nCToSplit == -2) return true ; - if ( m_mTree[cToSplit->m_nChild1].IsProcessed() && m_mTree[cToSplit->m_nChild2].IsProcessed()) - cToSplit->SetProcessed() ; - while ( m_mTree[cToSplit->m_nChild2].IsProcessed()) { - if ( cToSplit->m_nParent != -2) { - nCToSplit = cToSplit->m_nParent ; - cToSplit = &m_mTree[nCToSplit] ; + if ( m_mTree[pcToSplit->m_nChild1].IsProcessed() && m_mTree[pcToSplit->m_nChild2].IsProcessed()) + pcToSplit->SetProcessed() ; + while ( m_mTree[pcToSplit->m_nChild2].IsProcessed()) { + if ( pcToSplit->m_nParent != -2) { + nCToSplit = pcToSplit->m_nParent ; + pcToSplit = &m_mTree[nCToSplit] ; } - if ( m_mTree[cToSplit->m_nChild1].IsProcessed() && m_mTree[cToSplit->m_nChild2].IsProcessed()) - cToSplit->SetProcessed() ; - if ( nCToSplit == -1 && m_mTree[cToSplit->m_nChild2].IsProcessed()) + if ( m_mTree[pcToSplit->m_nChild1].IsProcessed() && m_mTree[pcToSplit->m_nChild2].IsProcessed()) + pcToSplit->SetProcessed() ; + if ( nCToSplit == -1 && m_mTree[pcToSplit->m_nChild2].IsProcessed()) break ; } - nCToSplit = cToSplit->m_nChild2 ; - cToSplit = &m_mTree[nCToSplit] ; + nCToSplit = pcToSplit->m_nChild2 ; + pcToSplit = &m_mTree[nCToSplit] ; } } else { - nCToSplit = cToSplit->m_nChild1 ; - cToSplit = &m_mTree[nCToSplit] ; + nCToSplit = pcToSplit->m_nChild1 ; + pcToSplit = &m_mTree[nCToSplit] ; } } Balance() ; // da implementare quando dividerò ad un parametro a scelta e non a metà // probabilmente mi servirà salvare nella cella il livello di profondità @@ -977,8 +979,8 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax) // bilineare else { bool bIsPlanar = m_pSrfBz->IsPlanar() ; - while ( nCToSplit != -2 && cToSplit->IsProcessed() == false) { - if ( cToSplit->IsLeaf()) { + while ( nCToSplit != -2 && pcToSplit->IsProcessed() == false) { + if ( pcToSplit->IsLeaf()) { // vertici della cella Point3d ptP00, ptP10, ptP11, ptP01 ; ptP00 = m_mVert[nCToSplit][0] ; @@ -1002,10 +1004,10 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax) } else { for ( double i = 0.25 ; i < 1 ; i = i + 0.25) { - dU = ( ( 1 - i) * cToSplit->GetBottomLeft().x + i * cToSplit->GetTopRight().x) / SBZ_TREG_COEFF ; - dV = ( ( 1 - i) * cToSplit->GetBottomLeft().y + i * cToSplit->GetTopRight().y) / SBZ_TREG_COEFF ; - double dVLoc = ( cToSplit->GetBottomLeft().y + cToSplit->GetTopRight().y) / 2 / SBZ_TREG_COEFF ; - double dULoc = ( cToSplit->GetBottomLeft().x + cToSplit->GetTopRight().x) / 2 / SBZ_TREG_COEFF ; + dU = ( ( 1 - i) * pcToSplit->GetBottomLeft().x + i * pcToSplit->GetTopRight().x) / SBZ_TREG_COEFF ; + dV = ( ( 1 - i) * pcToSplit->GetBottomLeft().y + i * pcToSplit->GetTopRight().y) / SBZ_TREG_COEFF ; + double dVLoc = ( pcToSplit->GetBottomLeft().y + pcToSplit->GetTopRight().y) / 2 / SBZ_TREG_COEFF ; + double dULoc = ( pcToSplit->GetBottomLeft().x + pcToSplit->GetTopRight().x) / 2 / SBZ_TREG_COEFF ; m_pSrfBz->GetPointD1D2( dU, dVLoc, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrfU) ; m_pSrfBz->GetPointD1D2( dULoc, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrfV) ; vPtU.push_back( ptPSrfU) ; @@ -1046,8 +1048,8 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax) } for ( double i = 0.25 ; i < 1 ; i = i + 0.25) { for ( double j = 0.25 ; j < 1 ; j = j + 0.25) { - double dU = ( ( 1 - i) * cToSplit->GetTopRight().x + i * cToSplit->GetBottomLeft().x) / SBZ_TREG_COEFF ; - double dV = ( ( 1 - j) * cToSplit->GetTopRight().y + j * cToSplit->GetBottomLeft().y) / SBZ_TREG_COEFF ; + double dU = ( ( 1 - i) * pcToSplit->GetTopRight().x + i * pcToSplit->GetBottomLeft().x) / SBZ_TREG_COEFF ; + double dV = ( ( 1 - j) * pcToSplit->GetTopRight().y + j * pcToSplit->GetBottomLeft().y) / SBZ_TREG_COEFF ; m_pSrfBz->GetPointD1D2( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrf) ; dErr = max( abs( DistPointPlane( ptPSrf, plAppr)), dErr) ; } @@ -1059,42 +1061,42 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax) } // se la cella è abbastanza grande da poter essere divisa ancora e devo approssimare meglio, la divido if ( dSideMinVal / 2 >= dSideMin && dSideMaxVal < dSideMax && dErr > dLinTol) { - cToSplit->SetSplitDirVert( bVert) ; + pcToSplit->SetSplitDirVert( bVert) ; // effettuo lo split Split( nCToSplit) ; // procedo con lo split del Child1 - nCToSplit = cToSplit->m_nChild1 ; - cToSplit = &m_mTree[nCToSplit] ; + nCToSplit = pcToSplit->m_nChild1 ; + pcToSplit = &m_mTree[nCToSplit] ; } else { // sono arrivato ad una cella Leaf, quindi salvo la cella m_vnLeaves.push_back( nCToSplit) ; - cToSplit->SetProcessed() ; + pcToSplit->SetProcessed() ; // risalgo i parent finché non trovo il primo Child2 da processare - nCToSplit = cToSplit->m_nParent ; - cToSplit = &m_mTree[nCToSplit] ; + nCToSplit = pcToSplit->m_nParent ; + pcToSplit = &m_mTree[nCToSplit] ; if ( nCToSplit == -2) return true ; - if ( m_mTree[cToSplit->m_nChild1].IsProcessed() && m_mTree[cToSplit->m_nChild2].IsProcessed()) - cToSplit->SetProcessed() ; - while ( m_mTree[cToSplit->m_nChild2].IsProcessed()) { - if ( cToSplit->m_nParent != -2) { - nCToSplit = cToSplit->m_nParent ; - cToSplit = &m_mTree[nCToSplit] ; + if ( m_mTree[pcToSplit->m_nChild1].IsProcessed() && m_mTree[pcToSplit->m_nChild2].IsProcessed()) + pcToSplit->SetProcessed() ; + while ( m_mTree[pcToSplit->m_nChild2].IsProcessed()) { + if ( pcToSplit->m_nParent != -2) { + nCToSplit = pcToSplit->m_nParent ; + pcToSplit = &m_mTree[nCToSplit] ; } - if ( m_mTree[cToSplit->m_nChild1].IsProcessed() && m_mTree[cToSplit->m_nChild2].IsProcessed()) - cToSplit->SetProcessed() ; - if ( nCToSplit == -1 && m_mTree[cToSplit->m_nChild2].IsProcessed()) + if ( m_mTree[pcToSplit->m_nChild1].IsProcessed() && m_mTree[pcToSplit->m_nChild2].IsProcessed()) + pcToSplit->SetProcessed() ; + if ( nCToSplit == -1 && m_mTree[pcToSplit->m_nChild2].IsProcessed()) break ; } - nCToSplit = cToSplit->m_nChild2 ; - cToSplit = &m_mTree[nCToSplit] ; + nCToSplit = pcToSplit->m_nChild2 ; + pcToSplit = &m_mTree[nCToSplit] ; } } else { - nCToSplit = cToSplit->m_nChild1 ; - cToSplit = &m_mTree[nCToSplit] ; + nCToSplit = pcToSplit->m_nChild1 ; + pcToSplit = &m_mTree[nCToSplit] ; } } } @@ -2285,12 +2287,13 @@ Tree::TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons) // qui mi devo salvare quanti elementi ho già nel vettore m_vInters della cella // per poter fare il merge con l'ultimo vptInters della curva di trim, che sarà ancora in questa cella // e terminerà nel punto di start - int nPass = (int) m_mTree[nId].m_vInters.size() ; - m_mTree[nId].m_vInters.emplace_back() ; + Cell* pCell = &m_mTree[nId] ; + int nPass = (int) pCell->m_vInters.size() ; + pCell->m_vInters.emplace_back() ; // salvo il verso del loop - m_mTree[nId].m_vInters.back().bCCW = bCCW ; + pCell->m_vInters.back().bCCW = bCCW ; // salvo il chunk del loop - m_mTree[nId].m_vInters.back().nChunk = m_mChunk[i] ; + pCell->m_vInters.back().nChunk = m_mChunk[i] ; bool bLoopInside = true ; Point3d ptCurr ; auto iter = find( m_vnLeaves.begin(), m_vnLeaves.end(), nId) ; @@ -2330,10 +2333,12 @@ Tree::TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons) // ricalcolo la posizione di nId nel vettore delle foglie iter = find( m_vnLeaves.begin(), m_vnLeaves.end(), nId) ; nIdPolygon = distance( m_vnLeaves.begin(), iter) ; + // aggiorno il puntatore alla cella + pCell = &m_mTree[nId] ; // salvo il verso del loop - m_mTree[nId].m_vInters.back().bCCW = bCCW ; + pCell->m_vInters.back().bCCW = bCCW ; // salvo il chunk del loop - m_mTree[nId].m_vInters.back().nChunk = m_mChunk[i] ; + pCell->m_vInters.back().nChunk = m_mChunk[i] ; // aggiorno la polyline splittata UpdateSplitLoop( plLoopSplit, nPtLoopSplit, vptInters.back()) ; } @@ -2347,16 +2352,16 @@ Tree::TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons) } if ( nId == nFirstCell) vptInters.pop_back() ; - m_mTree[nId].m_vInters.back().vpt = vptInters ; + pCell->m_vInters.back().vpt = vptInters ; if ( bLoopInside) { // setto la categoria della cella - if ( m_mTree[nId].m_nFlag == -1) - m_mTree[nId].m_nFlag = 2 ; - else if ( m_mTree[nId].m_nFlag == 1) - m_mTree[nId].m_nFlag = 3 ; + if ( pCell->m_nFlag == -1) + pCell->m_nFlag = 2 ; + else if ( pCell->m_nFlag == 1) + pCell->m_nFlag = 3 ; // setto i lati di ingresso e uscita a -1 per indicare che ho un loop interno alla cella - m_mTree[nId].m_vInters.back().nIn = -1 ; - m_mTree[nId].m_vInters.back().nOut = -1 ; + pCell->m_vInters.back().nIn = -1 ; + pCell->m_vInters.back().nOut = -1 ; } // sono tornato alla cella di partenza, quindi devo fare il merge dei due vettori di intersezione che ho creato per questa cella // per lo stesso loop @@ -2364,7 +2369,7 @@ Tree::TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons) // verifico se sono effettivamente nella cella di partenza o in una cella adiacente if ( nId != nFirstCell) { Point3d ptFirst = m_mTree[nFirstCell].m_vInters[nPass].vpt[0] ; - Point3d ptLast = m_mTree[nId].m_vInters.back().vpt.back() ; + Point3d ptLast = pCell->m_vInters.back().vpt.back() ; //sistemo l'ingresso della prima cella int nEdge ; if ( ! OnWhichEdge( nFirstCell, ptFirst, nEdge)) @@ -2373,23 +2378,23 @@ Tree::TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons) // sistemo l'uscita dell'ultima cella if ( ! OnWhichEdge( nId, ptLast, nEdge)) return false ; - m_mTree[nId].m_vInters.back().nOut = nEdge ; + pCell->m_vInters.back().nOut = nEdge ; // sistemo il flag dell'ultima cella - if ( m_mTree[nId].m_nFlag == -1) - m_mTree[nId].m_nFlag = 1 ; - else if ( m_mTree[nId].m_nFlag == 2) - m_mTree[nId].m_nFlag = 3 ; + if ( pCell->m_nFlag == -1) + pCell->m_nFlag = 1 ; + else if ( pCell->m_nFlag == 2) + pCell->m_nFlag = 3 ; } // sono tornato nella cella iniziale, quindi giunto i due vettori intersezione else if ( nId == nFirstCell) { - int nOut = m_mTree[nId].m_vInters[nPass].nOut ; - m_mTree[nId].m_vInters.back().vpt.insert( m_mTree[nId].m_vInters.back().vpt.end(), - m_mTree[nId].m_vInters[nPass].vpt.begin(), - m_mTree[nId].m_vInters[nPass].vpt.end()) ; - m_mTree[nId].m_vInters[nPass] = m_mTree[nId].m_vInters.back() ; - m_mTree[nId].m_vInters.pop_back() ; + int nOut = pCell->m_vInters[nPass].nOut ; + pCell->m_vInters.back().vpt.insert( pCell->m_vInters.back().vpt.end(), + pCell->m_vInters[nPass].vpt.begin(), + pCell->m_vInters[nPass].vpt.end()) ; + pCell->m_vInters[nPass] = pCell->m_vInters.back() ; + pCell->m_vInters.pop_back() ; // sistemo il lato d'uscita - m_mTree[nId].m_vInters[nPass].nOut = nOut ; + pCell->m_vInters[nPass].nOut = nOut ; } } // salvo la polyline splittata @@ -2545,8 +2550,9 @@ Tree::TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons) bool Tree::FindInters( int& nId, const CurveLine& clTrim, const PolyLine& plPolygon, PNTVECTOR& vptInters, bool bFirstInters) { - Point3d ptTR = m_mTree[nId].GetTopRight() ; - Point3d ptBL = m_mTree[nId].GetBottomLeft() ; + Cell* pCell = &m_mTree.at(nId) ; + Point3d ptTR = pCell->GetTopRight() ; + Point3d ptBL = pCell->GetBottomLeft() ; Point3d ptTl( ptBL.x , ptTR.y) ; Point3d ptBr( ptTR.x , ptBL.y) ; int nEdge ; // flag che indica il lato su cui ho l'intersezione a partire dal lato top in senso antiorario @@ -2586,7 +2592,7 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, const PolyLine& plPolygon, // determino il lato/vertice di uscita if( ! OnWhichEdge( nId, ptInters, nEdge)) return false ; - m_mTree[nId].m_vInters.back().nOut = nEdge ; + pCell->m_vInters.back().nOut = nEdge ; // se è risultato che sono abbastanza vicino( di EPS_SMALL) ad un vertice allora il punto aggiunto sarà il vertice vero e proprio // se è abbastanza vicino ad un lato allora modifico le sue coordinate in modo che sia esattamente sul lato if ( nEdge == 0) @@ -2616,15 +2622,15 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, const PolyLine& plPolygon, // salvo il vettore intersezione per la cella e capisco in quale altra cella passare if ( (int)vptInters.size() == 1) - m_mTree[nId].m_vInters.back().vpt.push_back( vptInters[0]) ; + pCell->m_vInters.back().vpt.push_back( vptInters[0]) ; else - m_mTree[nId].m_vInters.back().vpt = vptInters ; + pCell->m_vInters.back().vpt = vptInters ; vptInters.clear() ; // setto la categoria della cella - if ( m_mTree[nId].m_nFlag == -1) - m_mTree[nId].m_nFlag = 1 ; - else if ( m_mTree[nId].m_nFlag == 2) - m_mTree[nId].m_nFlag = 3 ; + if ( pCell->m_nFlag == -1) + pCell->m_nFlag = 1 ; + else if ( pCell->m_nFlag == 2) + pCell->m_nFlag = 3 ; // seleziono la cella successiva da analizzare // @@ -2640,16 +2646,18 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, const PolyLine& plPolygon, break ; } } - m_mTree[nId].m_vInters.emplace_back() ; - Point3d ptBr( m_mTree[nId].GetTopRight().x, m_mTree[nId].GetBottomLeft().y) ; - if ( ptInters.x > m_mTree[nId].GetBottomLeft().x + EPS_SMALL && ptInters.x < m_mTree[nId].GetTopRight().x - EPS_SMALL) - m_mTree[nId].m_vInters.back().nIn = 2 ; - else if ( AreSamePointXYApprox( ptInters, m_mTree[nId].GetBottomLeft())) - m_mTree[nId].m_vInters.back().nIn = 5 ; + // aggiorno il puntatore alla cella + pCell = &m_mTree.at(nId) ; + pCell->m_vInters.emplace_back() ; + Point3d ptBr( pCell->GetTopRight().x, pCell->GetBottomLeft().y) ; + if ( ptInters.x > pCell->GetBottomLeft().x + EPS_SMALL && ptInters.x < pCell->GetTopRight().x - EPS_SMALL) + pCell->m_vInters.back().nIn = 2 ; + else if ( AreSamePointXYApprox( ptInters, pCell->GetBottomLeft())) + pCell->m_vInters.back().nIn = 5 ; else if ( AreSamePointXYApprox( ptInters, ptBr)) - m_mTree[nId].m_vInters.back().nIn = 6 ; + pCell->m_vInters.back().nIn = 6 ; else - m_mTree[nId].m_vInters.back().nIn = 2 ; + pCell->m_vInters.back().nIn = 2 ; } else if ( nEdge == 1) { GetLeftNeigh( nId, vNeigh) ; @@ -2660,16 +2668,18 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, const PolyLine& plPolygon, break ; } } - m_mTree[nId].m_vInters.emplace_back() ; - Point3d ptBr( m_mTree[nId].GetTopRight().x, m_mTree[nId].GetBottomLeft().y) ; - if ( ptInters.y > m_mTree[nId].GetBottomLeft().y + EPS_SMALL && ptInters.y < m_mTree[nId].GetTopRight().y - EPS_SMALL) - m_mTree[nId].m_vInters.back().nIn = 3 ; + // aggiorno il puntatore alla cella + pCell = &m_mTree.at(nId) ; + pCell->m_vInters.emplace_back() ; + Point3d ptBr( pCell->GetTopRight().x, pCell->GetBottomLeft().y) ; + if ( ptInters.y > pCell->GetBottomLeft().y + EPS_SMALL && ptInters.y < pCell->GetTopRight().y - EPS_SMALL) + pCell->m_vInters.back().nIn = 3 ; else if ( AreSamePointXYApprox( ptInters, ptBr)) - m_mTree[nId].m_vInters.back().nIn = 6 ; - else if ( AreSamePointXYApprox( ptInters, m_mTree[nId].GetTopRight())) - m_mTree[nId].m_vInters.back().nIn = 7 ; + pCell->m_vInters.back().nIn = 6 ; + else if ( AreSamePointXYApprox( ptInters, pCell->GetTopRight())) + pCell->m_vInters.back().nIn = 7 ; else - m_mTree[nId].m_vInters.back().nIn = 3 ; + pCell->m_vInters.back().nIn = 3 ; } else if ( nEdge == 2) { GetBottomNeigh( nId, vNeigh) ; @@ -2679,16 +2689,18 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, const PolyLine& plPolygon, break ; } } - m_mTree[nId].m_vInters.emplace_back() ; - Point3d ptTl( m_mTree[nId].GetBottomLeft().x, m_mTree[nId].GetTopRight().y) ; - if ( ptInters.x > m_mTree[nId].GetBottomLeft().x + EPS_SMALL && ptInters.x < m_mTree[nId].GetTopRight().x - EPS_SMALL) - m_mTree[nId].m_vInters.back().nIn = 0 ; + // aggiorno il puntatore alla cella + pCell = &m_mTree.at(nId) ; + pCell->m_vInters.emplace_back() ; + Point3d ptTl( pCell->GetBottomLeft().x, pCell->GetTopRight().y) ; + if ( ptInters.x > pCell->GetBottomLeft().x + EPS_SMALL && ptInters.x < pCell->GetTopRight().x - EPS_SMALL) + pCell->m_vInters.back().nIn = 0 ; else if ( AreSamePointXYApprox( ptInters, ptTl)) - m_mTree[nId].m_vInters.back().nIn = 4 ; - else if ( AreSamePointXYApprox( ptInters, m_mTree[nId].GetTopRight())) - m_mTree[nId].m_vInters.back().nIn = 7 ; + pCell->m_vInters.back().nIn = 4 ; + else if ( AreSamePointXYApprox( ptInters, pCell->GetTopRight())) + pCell->m_vInters.back().nIn = 7 ; else - m_mTree[nId].m_vInters.back().nIn = 0 ; + pCell->m_vInters.back().nIn = 0 ; } else if ( nEdge == 3) { GetRightNeigh( nId, vNeigh) ; @@ -2698,16 +2710,18 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, const PolyLine& plPolygon, break ; } } - m_mTree[nId].m_vInters.emplace_back() ; - Point3d ptTl( m_mTree[nId].GetBottomLeft().x, m_mTree[nId].GetTopRight().y) ; - if ( ptInters.y > m_mTree[nId].GetBottomLeft().y + EPS_SMALL && ptInters.y < m_mTree[nId].GetTopRight().y - EPS_SMALL) - m_mTree[nId].m_vInters.back().nIn = 1 ; - else if ( AreSamePointXYApprox( ptInters, m_mTree[nId].GetBottomLeft())) - m_mTree[nId].m_vInters.back().nIn = 5 ; + // aggiorno il puntatore alla cella + pCell = &m_mTree.at(nId) ; + pCell->m_vInters.emplace_back() ; + Point3d ptTl( pCell->GetBottomLeft().x, pCell->GetTopRight().y) ; + if ( ptInters.y > pCell->GetBottomLeft().y + EPS_SMALL && ptInters.y < pCell->GetTopRight().y - EPS_SMALL) + pCell->m_vInters.back().nIn = 1 ; + else if ( AreSamePointXYApprox( ptInters, pCell->GetBottomLeft())) + pCell->m_vInters.back().nIn = 5 ; else if ( AreSamePointXYApprox( ptInters, ptTl)) - m_mTree[nId].m_vInters.back().nIn = 4 ; + pCell->m_vInters.back().nIn = 4 ; else - m_mTree[nId].m_vInters.back().nIn = 1 ; + pCell->m_vInters.back().nIn = 1 ; } // esco da uno dei vertici else if ( nEdge == 4) { @@ -2719,28 +2733,32 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, const PolyLine& plPolygon, // ingresso dal basso if ( ! nPossible.empty()) { nId = nPossible[0] ; - m_mTree[nId].m_vInters.emplace_back() ; + // aggiorno il puntatore alla cella + pCell = &m_mTree.at(nId) ; + pCell->m_vInters.emplace_back() ; // controllo se entro in un vertice o a metà lato - Point3d ptBr( m_mTree[nId].GetTopRight().x, m_mTree[nId].GetBottomLeft().y) ; + Point3d ptBr( pCell->GetTopRight().x, pCell->GetBottomLeft().y) ; if ( AreSamePointXYExact( ptInters, ptBr)) - m_mTree[nId].m_vInters.back().nIn = 6 ; - else if ( AreSamePointXYExact( ptInters, m_mTree[nId].GetBottomLeft())) - m_mTree[nId].m_vInters.back().nIn = 5 ; + pCell->m_vInters.back().nIn = 6 ; + else if ( AreSamePointXYExact( ptInters, pCell->GetBottomLeft())) + pCell->m_vInters.back().nIn = 5 ; else - m_mTree[nId].m_vInters.back().nIn = 2 ; + pCell->m_vInters.back().nIn = 2 ; } // ingresso da destra else if ( ! nPossible1.empty()) { nId = nPossible1.back() ; - m_mTree[nId].m_vInters.emplace_back() ; + // aggiorno il puntatore alla cella + pCell = &m_mTree.at(nId) ; + pCell->m_vInters.emplace_back() ; // controllo se entro in un vertice o a metà lato - Point3d ptBr( m_mTree[nId].GetTopRight().x, m_mTree[nId].GetBottomLeft().y) ; + Point3d ptBr( pCell->GetTopRight().x, pCell->GetBottomLeft().y) ; if ( AreSamePointXYExact( ptInters, ptBr)) - m_mTree[nId].m_vInters.back().nIn = 6 ; - else if ( AreSamePointXYExact( ptInters, m_mTree[nId].GetTopRight())) - m_mTree[nId].m_vInters.back().nIn = 7 ; + pCell->m_vInters.back().nIn = 6 ; + else if ( AreSamePointXYExact( ptInters, pCell->GetTopRight())) + pCell->m_vInters.back().nIn = 7 ; else - m_mTree[nId].m_vInters.back().nIn = 3 ; + pCell->m_vInters.back().nIn = 3 ; } // ingresso in diagonale else { @@ -2770,28 +2788,32 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, const PolyLine& plPolygon, // ingresso dal destra if ( ! nPossible.empty()) { nId = nPossible[0] ; - m_mTree[nId].m_vInters.emplace_back() ; + // aggiorno il puntatore alla cella + pCell = &m_mTree.at(nId) ; + pCell->m_vInters.emplace_back() ; // controllo se entro in un vertice o a metà lato - Point3d ptBr( m_mTree[nId].GetTopRight().x, m_mTree[nId].GetBottomLeft().y) ; + Point3d ptBr( pCell->GetTopRight().x, pCell->GetBottomLeft().y) ; if ( AreSamePointXYExact( ptInters, ptBr)) - m_mTree[nId].m_vInters.back().nIn = 6 ; - else if ( AreSamePointXYExact( ptInters, m_mTree[nId].GetTopRight())) - m_mTree[nId].m_vInters.back().nIn = 7 ; + pCell->m_vInters.back().nIn = 6 ; + else if ( AreSamePointXYExact( ptInters, pCell->GetTopRight())) + pCell->m_vInters.back().nIn = 7 ; else - m_mTree[nId].m_vInters.back().nIn = 3 ; + pCell->m_vInters.back().nIn = 3 ; } // ingresso dall'alto else if ( ! nPossible1.empty()) { nId = nPossible1[0] ; - m_mTree[nId].m_vInters.emplace_back() ; + // aggiorno il puntatore alla cella + pCell = &m_mTree.at(nId) ; + pCell->m_vInters.emplace_back() ; // controllo se entro in un vertice o a metà lato - Point3d ptTl( m_mTree[nId].GetBottomLeft().x, m_mTree[nId].GetTopRight().y) ; + Point3d ptTl( pCell->GetBottomLeft().x, pCell->GetTopRight().y) ; if ( AreSamePointXYExact( ptInters, ptTl)) - m_mTree[nId].m_vInters.back().nIn = 4 ; - else if ( AreSamePointXYExact( ptInters, m_mTree[nId].GetTopRight())) - m_mTree[nId].m_vInters.back().nIn = 7 ; + pCell->m_vInters.back().nIn = 4 ; + else if ( AreSamePointXYExact( ptInters, pCell->GetTopRight())) + pCell->m_vInters.back().nIn = 7 ; else - m_mTree[nId].m_vInters.back().nIn = 0 ; + pCell->m_vInters.back().nIn = 0 ; } // ingresso in diagonale else { @@ -2821,28 +2843,32 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, const PolyLine& plPolygon, // ingresso dall'alto if ( ! nPossible.empty()) { nId = nPossible.back() ; - m_mTree[nId].m_vInters.emplace_back() ; + // aggiorno il puntatore alla cella + pCell = &m_mTree.at(nId) ; + pCell->m_vInters.emplace_back() ; // controllo se entro in un vertice o a metà lato - Point3d ptTl( m_mTree[nId].GetBottomLeft().x, m_mTree[nId].GetTopRight().y) ; + Point3d ptTl( pCell->GetBottomLeft().x, pCell->GetTopRight().y) ; if ( AreSamePointXYExact( ptInters, ptTl)) - m_mTree[nId].m_vInters.back().nIn = 4 ; - else if ( AreSamePointXYExact( ptInters, m_mTree[nId].GetTopRight())) - m_mTree[nId].m_vInters.back().nIn = 7 ; + pCell->m_vInters.back().nIn = 4 ; + else if ( AreSamePointXYExact( ptInters, pCell->GetTopRight())) + pCell->m_vInters.back().nIn = 7 ; else - m_mTree[nId].m_vInters.back().nIn = 0 ; + pCell->m_vInters.back().nIn = 0 ; } // ingresso da sinistra else if ( ! nPossible1.empty()) { nId = nPossible1[0] ; - m_mTree[nId].m_vInters.emplace_back() ; + // aggiorno il puntatore alla cella + pCell = &m_mTree.at(nId) ; + pCell->m_vInters.emplace_back() ; // controllo se entro in un vertice o a metà lato - Point3d ptTl( m_mTree[nId].GetBottomLeft().x, m_mTree[nId].GetTopRight().y) ; + Point3d ptTl( pCell->GetBottomLeft().x, pCell->GetTopRight().y) ; if ( AreSamePointXYExact( ptInters, ptTl)) - m_mTree[nId].m_vInters.back().nIn = 4 ; - else if ( AreSamePointXYExact( ptInters, m_mTree[nId].GetBottomLeft())) - m_mTree[nId].m_vInters.back().nIn = 5 ; + pCell->m_vInters.back().nIn = 4 ; + else if ( AreSamePointXYExact( ptInters, pCell->GetBottomLeft())) + pCell->m_vInters.back().nIn = 5 ; else - m_mTree[nId].m_vInters.back().nIn = 1 ; + pCell->m_vInters.back().nIn = 1 ; } // ingresso in diagonale else { @@ -2872,28 +2898,32 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, const PolyLine& plPolygon, // ingresso da sinistra if ( ! nPossible.empty()) { nId = nPossible.back() ; - m_mTree[nId].m_vInters.emplace_back() ; + // aggiorno il puntatore alla cella + pCell = &m_mTree.at(nId) ; + pCell->m_vInters.emplace_back() ; // controllo se entro in un vertice o a metà lato - Point3d ptTl( m_mTree[nId].GetBottomLeft().x, m_mTree[nId].GetTopRight().y) ; + Point3d ptTl( pCell->GetBottomLeft().x, pCell->GetTopRight().y) ; if ( AreSamePointXYExact( ptInters, ptTl)) - m_mTree[nId].m_vInters.back().nIn = 4 ; - else if ( AreSamePointXYExact( ptInters, m_mTree[nId].GetBottomLeft())) - m_mTree[nId].m_vInters.back().nIn = 5 ; + pCell->m_vInters.back().nIn = 4 ; + else if ( AreSamePointXYExact( ptInters, pCell->GetBottomLeft())) + pCell->m_vInters.back().nIn = 5 ; else - m_mTree[nId].m_vInters.back().nIn = 1 ; + pCell->m_vInters.back().nIn = 1 ; } // ingresso dal basso else if ( ! nPossible1.empty()) { nId = nPossible1.back() ; - m_mTree[nId].m_vInters.emplace_back() ; + // aggiorno il puntatore alla cella + pCell = &m_mTree.at(nId) ; + pCell->m_vInters.emplace_back() ; // controllo se entro in un vertice o a metà lato - Point3d ptBr( m_mTree[nId].GetTopRight().x, m_mTree[nId].GetBottomLeft().y) ; + Point3d ptBr( pCell->GetTopRight().x, pCell->GetBottomLeft().y) ; if ( AreSamePointXYExact( ptInters, ptBr)) - m_mTree[nId].m_vInters.back().nIn = 6 ; - else if ( AreSamePointXYExact( ptInters, m_mTree[nId].GetBottomLeft())) - m_mTree[nId].m_vInters.back().nIn = 5 ; + pCell->m_vInters.back().nIn = 6 ; + else if ( AreSamePointXYExact( ptInters, pCell->GetBottomLeft())) + pCell->m_vInters.back().nIn = 5 ; else - m_mTree[nId].m_vInters.back().nIn = 2 ; + pCell->m_vInters.back().nIn = 2 ; } // ingresso in diagonale else { @@ -2926,12 +2956,13 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX { // conto quanti vertici in più ho per lato e creo un vettore dei vertici per lato int nId = m_vnLeaves[nLeafId] ; + Cell& cCell = m_mTree[nId] ; PNTMATRIX vEdgeVertex(4) ; PNTMATRIX vEdgeVertex3d(4) ; - Point3d ptBL = m_mTree[nId].GetBottomLeft() ; - Point3d ptTR = m_mTree[nId].GetTopRight() ; - Point3d ptTl = m_mTree[nId].GetTopLeft() ; - Point3d ptBr = m_mTree[nId].GetBottomRight() ; + Point3d ptBL = cCell.GetBottomLeft() ; + Point3d ptTR = cCell.GetTopRight() ; + Point3d ptTl = cCell.GetTopLeft() ; + Point3d ptBr = cCell.GetBottomRight() ; int nVertToErase = m_mTree.at(nId).m_nVertToErase ; if( nVertToErase != 2) vEdgeVertex[0].push_back( ptTR) ; @@ -3011,12 +3042,12 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX INTVECTOR vAddedLoops ; Point3d ptLastAdded( -1, -1, 0) ; for ( int w = 0 ; w < (int)vToCheckNow.size() ; ++ w) { - if ( m_mTree[nId].m_vInters[w].vpt.size() < 2) { + if ( cCell.m_vInters[w].vpt.size() < 2) { continue ; } // indice del loop in m_vInters int j = vToCheckNow[w] ; - Inters inA = m_mTree[nId].m_vInters[j] ; + Inters inA = cCell.m_vInters[j] ; if ( inA.nIn != -1) { int nEdge ; if ( nEdgeIn == -1) { @@ -3109,10 +3140,10 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX int nNext ; // ciclo sui loop successivi per vedere se ne ho uno con un valid start for ( int t = w + 1 ; t < nPassToCheck ; ++ t) { - bValidNextStart = CheckIfBetween( m_mTree[nId].m_vInters[j], m_mTree[nId].m_vInters[vToCheckNow[t]]) ; + bValidNextStart = CheckIfBetween( cCell.m_vInters[j], cCell.m_vInters[vToCheckNow[t]]) ; if ( bValidNextStart) { nNext = t ; - bAtNextStart = AreSameEdge( m_mTree[nId].m_vInters[j].nOut, m_mTree[nId].m_vInters[vToCheckNow[t]].nIn) ; + bAtNextStart = AreSameEdge( cCell.m_vInters[j].nOut, cCell.m_vInters[vToCheckNow[t]].nIn) ; break ; } else { @@ -3142,7 +3173,7 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX // aggiorno le condizioni per il while if ( bValidNextStart) - bAtNextStart = AreSameEdge( nEdge, m_mTree[nId].m_vInters[vToCheckNow[nNext]].nIn) ; + bAtNextStart = AreSameEdge( nEdge, cCell.m_vInters[vToCheckNow[nNext]].nIn) ; bNotCameBack = ! ( AreSameEdge( nEdge, nEdgeIn) && CheckIfBefore( plTrimmedPoly, nEdge)) ; } @@ -3151,7 +3182,7 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX if ( bValidNextStart) { Point3d ptLast ; plTrimmedPoly.GetLastPoint( ptLast) ; for ( int p = nEdge == nEdgeWithVertexSkipped ? 0 : 1 ; p < (int) vEdgeVertex[nEdge].size() ; ++ p) { - if ( CheckIfBefore( nEdge, vEdgeVertex[nEdge][p], m_mTree[nId].m_vInters[vToCheckNow[nNext]].vpt[0]) && + if ( CheckIfBefore( nEdge, vEdgeVertex[nEdge][p], cCell.m_vInters[vToCheckNow[nNext]].vpt[0]) && CheckIfBefore( nEdge, ptLast, vEdgeVertex[nEdge][p])) { plTrimmedPoly.AddUPoint( c, vEdgeVertex[nEdge][p]) ; plTrimmedPoly3d.AddUPoint( c, vEdgeVertex3d[nEdge][p]) ; @@ -3260,29 +3291,30 @@ Tree::CreateIslandAndHoles( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATR POLYLINEVECTOR vCellPolygons3d ; // costruisco i poligoni partendo dal vettore delle intersezioni int nId = m_vnLeaves[nLeafId] ; + Cell& cCell = m_mTree[nId] ; //capisco se sono in modalità ForTriangulation // loop interni in una cella intersecata int nChunkBiggestCW = -1 ; - if ( m_mTree[nId].m_nFlag == 3 || m_mTree[nId].m_nFlag == 2) { + if ( cCell.m_nFlag == 3 || cCell.m_nFlag == 2) { PolyLine plInLoop ; PolyLine plInLoop3d ; Inters inA ; // se ho almeno un loop CW che non è contenuto in un altro poligono o in un loop interno CCW devo aggiungere il bordo bool bAllContained = true ; bool bContained = false ; - int nInters = (int) m_mTree[nId].m_vInters.size() ; + int nInters = (int) cCell.m_vInters.size() ; for ( int n = 0 ; n < nInters ; ++ n) { - inA = m_mTree[nId].m_vInters[n] ; + inA = cCell.m_vInters[n] ; if ( inA.nIn == -1) { // per ogni loop CW verifico che ci sia un loop CCW dello stesso chunk ( che quindi lo contiene) if ( ! inA.bCCW) { if ( nChunkBiggestCW == -1) nChunkBiggestCW = inA.nChunk ; bContained = false ; - Inters inB = m_mTree[nId].m_vInters[0] ; + Inters inB = cCell.m_vInters[0] ; for( int c = 0 ; c < nInters ; ++ c){ - inB = m_mTree[nId].m_vInters[c] ; + inB = cCell.m_vInters[c] ; if ( inB.nIn == -1) { if ( inB != inA && inB.nChunk == inA.nChunk && inB.bCCW) { bContained = true ; @@ -3299,15 +3331,15 @@ Tree::CreateIslandAndHoles( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATR break ; } - if ( m_mTree[nId].m_nFlag == 2 && ! bAllContained) { + if ( cCell.m_nFlag == 2 && ! bAllContained) { // i loop esterni sono CW, quindi prima dei loop di trim aggiungo il bordo cella - Point3d ptVert = m_mTree[nId].GetTopRight() ; + Point3d ptVert = cCell.GetTopRight() ; plInLoop.AddUPoint( 0, ptVert) ; - ptVert = m_mTree[nId].GetTopLeft() ; + ptVert = cCell.GetTopLeft() ; plInLoop.AddUPoint( 1, ptVert) ; - ptVert = m_mTree[nId].GetBottomLeft() ; + ptVert = cCell.GetBottomLeft() ; plInLoop.AddUPoint( 2, ptVert) ; - ptVert = m_mTree[nId].GetBottomRight() ; + ptVert = cCell.GetBottomRight() ; plInLoop.AddUPoint( 3, ptVert) ; plInLoop.Close() ; vCellPolygons.push_back( plInLoop) ; @@ -3330,7 +3362,7 @@ Tree::CreateIslandAndHoles( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATR plInLoop.Clear() ; } for ( int nLoop = 0 ; nLoop < nInters ; ++ nLoop) { - inA = m_mTree[nId].m_vInters[nLoop] ; + inA = cCell.m_vInters[nLoop] ; if ( inA.nIn == -1) { // numero di vertici aggiunti al nuovo poligono int k = 0 ; @@ -3751,28 +3783,29 @@ Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVe bool Tree::SetRightEdgeIn( int nId) { + Cell& cCell = m_mTree[nId] ; // categorizzo la cella in base a quanta parte del lato destro è contenuta all'interno delle curve di trim // RightEdgeIn -> 0 non contenuto ; 1 contenuto ; 2 in parte contenuto - int nPass = (int) m_mTree[nId].m_vInters.size() ; + int nPass = (int) cCell.m_vInters.size() ; if ( nPass == 0) { - m_mTree[nId].m_nRightEdgeIn = 0 ; + cCell.m_nRightEdgeIn = 0 ; return true ; } bool bDone = false ; // se ho solo loop interni devo controllare se il più esterno è CCW ( lato destro esterno) o CW ( lato destro interno) - if ( m_mTree[nId].m_nFlag == 2) { + if ( cCell.m_nFlag == 2) { bool bAllContained = true ; bool bContained = false ; Inters inA ; - int nInters = (int) m_mTree[nId].m_vInters.size() ; + int nInters = (int) cCell.m_vInters.size() ; for ( int n = 0 ; n < nInters ; ++ n) { - inA = m_mTree[nId].m_vInters[n] ; + inA = cCell.m_vInters[n] ; if ( inA.nIn == -1) { if ( ! inA.bCCW) { bContained = false ; - Inters inB = m_mTree[nId].m_vInters[0] ; + Inters inB = cCell.m_vInters[0] ; for ( int c = 0 ; c < nInters ; ++ c) { - inB = m_mTree[nId].m_vInters[c] ; + inB = cCell.m_vInters[c] ; if ( inB.nIn == -1) { if ( inB != inA && inB.nChunk == inA.nChunk && inB.bCCW) { bContained = true ; @@ -3791,27 +3824,27 @@ Tree::SetRightEdgeIn( int nId) // se i loop CW interni sono tutti contenuti in un loop CW allora il right edge è esterno bool bRightEdgeIn = ! bAllContained ; if ( bRightEdgeIn) - m_mTree[nId].m_nRightEdgeIn = 1 ; + cCell.m_nRightEdgeIn = 1 ; else - m_mTree[nId].m_nRightEdgeIn = 0 ; + cCell.m_nRightEdgeIn = 0 ; return true ; } // se ho inters sul lato destro ( nEdge == 3) allora in parte è dentro for ( int k = 0 ; k < nPass ; ++ k) { - if ( m_mTree[nId].m_vInters[k].nIn == 3 || m_mTree[nId].m_vInters[k].nOut == 3) { - m_mTree[nId].m_nRightEdgeIn = 2 ; + if ( cCell.m_vInters[k].nIn == 3 || cCell.m_vInters[k].nOut == 3) { + cCell.m_nRightEdgeIn = 2 ; bDone = true ; break ; } // considero anche ingressi/ uscite dai vertici 6 e 7 // controllo nei vertici - else if ( m_mTree[nId].m_vInters[k].nOut == 6 && m_mTree[nId].m_vInters[k].nIn == 7) { - m_mTree[nId].m_nRightEdgeIn = 1 ; + else if ( cCell.m_vInters[k].nOut == 6 && cCell.m_vInters[k].nIn == 7) { + cCell.m_nRightEdgeIn = 1 ; bDone = true ; break ; } - else if ( m_mTree[nId].m_vInters[k].nOut == 7 && m_mTree[nId].m_vInters[k].nIn == 6) { - m_mTree[nId].m_nRightEdgeIn = 0 ; + else if ( cCell.m_vInters[k].nOut == 7 && cCell.m_vInters[k].nIn == 6) { + cCell.m_nRightEdgeIn = 0 ; bDone = true ; break ; } @@ -3822,27 +3855,27 @@ Tree::SetRightEdgeIn( int nId) bool bFound = false ; bool bRightMost = false ; int nEdgeUp = 6, nEdgeDown = 7, nLoop ; - Point3d ptDown( m_mTree[nId].GetTopRight().x, m_mTree[nId].GetBottomLeft().y) ; - Point3d ptUp = m_mTree[nId].GetTopRight() ; + Point3d ptDown( cCell.GetTopRight().x, cCell.GetBottomLeft().y) ; + Point3d ptUp = cCell.GetTopRight() ; for ( int k = 0 ; k < nPass ; ++ k) { - if ( m_mTree[nId].m_vInters[k].nIn != -1) { + if ( cCell.m_vInters[k].nIn != -1) { // trovo il loop che ha l'ingresso o l'uscita più a destra - if ( CheckIfBefore( m_mTree[nId].m_vInters[k].nIn, m_mTree[nId].m_vInters[k].vpt[0], nEdgeUp, ptUp) || - CheckIfBefore( m_mTree[nId].m_vInters[k].nOut, m_mTree[nId].m_vInters[k].vpt.back(), nEdgeUp, ptUp) || - CheckIfBefore( nEdgeDown, ptDown, m_mTree[nId].m_vInters[k].nIn, m_mTree[nId].m_vInters[k].vpt[0]) || - CheckIfBefore( nEdgeDown, ptDown, m_mTree[nId].m_vInters[k].nOut, m_mTree[nId].m_vInters[k].vpt.back())) { + if ( CheckIfBefore( cCell.m_vInters[k].nIn, cCell.m_vInters[k].vpt[0], nEdgeUp, ptUp) || + CheckIfBefore( cCell.m_vInters[k].nOut, cCell.m_vInters[k].vpt.back(), nEdgeUp, ptUp) || + CheckIfBefore( nEdgeDown, ptDown, cCell.m_vInters[k].nIn, cCell.m_vInters[k].vpt[0]) || + CheckIfBefore( nEdgeDown, ptDown, cCell.m_vInters[k].nOut, cCell.m_vInters[k].vpt.back())) { nLoop = k ; - if ( CheckIfBefore( m_mTree[nId].m_vInters[k])) { - ptUp = m_mTree[nId].m_vInters[k].vpt[0] ; - nEdgeUp = m_mTree[nId].m_vInters[k].nIn ; - ptDown = m_mTree[nId].m_vInters[k].vpt.back() ; - nEdgeDown = m_mTree[nId].m_vInters[k].nOut ; + if ( CheckIfBefore( cCell.m_vInters[k])) { + ptUp = cCell.m_vInters[k].vpt[0] ; + nEdgeUp = cCell.m_vInters[k].nIn ; + ptDown = cCell.m_vInters[k].vpt.back() ; + nEdgeDown = cCell.m_vInters[k].nOut ; } else { - ptUp = m_mTree[nId].m_vInters[k].vpt.back() ; - nEdgeUp = m_mTree[nId].m_vInters[k].nOut ; - ptDown = m_mTree[nId].m_vInters[k].vpt[0] ; - nEdgeDown = m_mTree[nId].m_vInters[k].nIn ; + ptUp = cCell.m_vInters[k].vpt.back() ; + nEdgeUp = cCell.m_vInters[k].nOut ; + ptDown = cCell.m_vInters[k].vpt[0] ; + nEdgeDown = cCell.m_vInters[k].nIn ; } bFound = true ; } @@ -3850,24 +3883,25 @@ Tree::SetRightEdgeIn( int nId) else continue ; } - if ( bFound && CheckIfBefore( m_mTree[nId].m_vInters[nLoop])) { + if ( bFound && CheckIfBefore( cCell.m_vInters[nLoop])) { bRightMost = true ; } // se il mio campione attraversa dall'alto al basso allora il lato destro è dentro!!! if ( bFound && bRightMost) - m_mTree[nId].m_nRightEdgeIn = 1 ; + cCell.m_nRightEdgeIn = 1 ; else - m_mTree[nId].m_nRightEdgeIn = 0 ; + cCell.m_nRightEdgeIn = 0 ; } - return ( m_mTree[nId].m_nRightEdgeIn != -1) ; + return ( cCell.m_nRightEdgeIn != -1) ; } //---------------------------------------------------------------------------- bool Tree::CategorizeCell( int nId) { - if ( m_mTree[nId].m_nFlag != -1) { + Cell& cCell = m_mTree[nId] ; + if ( cCell.m_nFlag != -1) { return true ; } INTVECTOR vNeigh, vNeigh1 ; @@ -3876,20 +3910,20 @@ Tree::CategorizeCell( int nId) // nRightEdgeIn // 0 right edge fuori, 1 right edge dentro, 2 metà e metà // nFlag // 0 fuori, 1 intersecata, 2 contiene loop, 3 = 1 & 2, 4 dentro if ( vNeigh.empty()) { - m_mTree[nId].m_nFlag = 0 ; + cCell.m_nFlag = 0 ; } else if ( vNeigh.size() == 1) { if ( m_mTree[vNeigh[0]].m_nRightEdgeIn == 1) - m_mTree[nId].m_nFlag = 4 ; + cCell.m_nFlag = 4 ; else if ( m_mTree[vNeigh[0]].m_nRightEdgeIn == 0) // devo verificare se la cella è intersecata if ( m_mTree[vNeigh[0]].m_nFlag == 1 || m_mTree[vNeigh[0]].m_nFlag == 3) - m_mTree[nId].m_nFlag = 0 ; + cCell.m_nFlag = 0 ; else { if ( m_mTree[vNeigh[0]].m_nFlag == 4) - m_mTree[nId].m_nFlag = 4 ; + cCell.m_nFlag = 4 ; else if ( m_mTree[vNeigh[0]].m_nFlag == 0) - m_mTree[nId].m_nFlag = 0 ; + cCell.m_nFlag = 0 ; } // se solo parte del right edge del vicino è compreso, allora devo verificare se la cella è contenuta o no // guardando nFlag del vicino bottom, che è già categorizzato! @@ -3898,16 +3932,16 @@ Tree::CategorizeCell( int nId) if ( ! vNeigh1.empty()) { int nNeigh = vNeigh1[0] ; if ( m_mTree[nNeigh].m_nFlag == 0 || m_mTree[nNeigh].m_nFlag == 2) { - m_mTree[nId].m_nFlag = 0 ; + cCell.m_nFlag = 0 ; } else if ( m_mTree[nNeigh].m_nFlag == 4) { - m_mTree[nId].m_nFlag = 4 ; + cCell.m_nFlag = 4 ; } else if ( m_mTree[nNeigh].m_nFlag == 1 || m_mTree[nNeigh].m_nFlag == 3) { if ( m_mTree[nNeigh].m_nRightEdgeIn == 0) - m_mTree[nId].m_nFlag = 0 ; + cCell.m_nFlag = 0 ; else if ( m_mTree[nNeigh].m_nRightEdgeIn == 1) - m_mTree[nId].m_nFlag = 4 ; + cCell.m_nFlag = 4 ; else if ( m_mTree[nNeigh].m_nRightEdgeIn == 2) { // in questo caso devo verificare le intersezioni sul lato destro del vicino bottom // scorro e cerco l'intersezione più alta, se è out la cella è dentro, se è in devo verificare l'out se è più a sinistra o a destra. @@ -3949,20 +3983,20 @@ Tree::CategorizeCell( int nId) if ( bFound && bTopMost) { if ( AreSameEdge( m_mTree[nNeigh].m_vInters[nLoop].nIn, 3) && AreSameEdge( m_mTree[nNeigh].m_vInters[nLoop].nOut, 3)) { if ( CheckIfBefore( m_mTree[nNeigh].m_vInters[nLoop])) - m_mTree[nId].m_nFlag = 4 ; + cCell.m_nFlag = 4 ; else - m_mTree[nId].m_nFlag = 0 ; + cCell.m_nFlag = 0 ; } else if ( AreSameEdge( m_mTree[nNeigh].m_vInters[nLoop].nOut, 3)) - m_mTree[nId].m_nFlag = 4 ; + cCell.m_nFlag = 4 ; else if ( AreSameEdge( m_mTree[nNeigh].m_vInters[nLoop].nIn, 3)) { // devo verificare se l'uscita è più a sinistra o più a destra della cella Point3d ptOut = m_mTree[nNeigh].m_vInters[nLoop].vpt.back() ; - Point3d ptBr( m_mTree[nId].GetTopRight().x, m_mTree[nId].GetBottomLeft().y) ; + Point3d ptBr( cCell.GetTopRight().x, cCell.GetBottomLeft().y) ; if ( ptOut.x >= ptBr.x) - m_mTree[nId].m_nFlag = 4 ; + cCell.m_nFlag = 4 ; else - m_mTree[nId].m_nFlag = 0 ; + cCell.m_nFlag = 0 ; } } } @@ -3988,25 +4022,25 @@ Tree::CategorizeCell( int nId) } } if ( bIntersIn) - m_mTree[nId].m_nFlag = 4 ; + cCell.m_nFlag = 4 ; else - m_mTree[nId].m_nFlag = 0 ; + cCell.m_nFlag = 0 ; } } } else { for ( int r = 0 ; r < (int)vNeigh.size() ; ++ r) { if ( m_mTree[vNeigh[r]].m_nRightEdgeIn == 1) { - m_mTree[nId].m_nFlag = 4 ; + cCell.m_nFlag = 4 ; break ; } else if ( m_mTree[vNeigh[r]].m_nRightEdgeIn == 0) { if ( m_mTree[vNeigh[r]].m_nFlag == 4) { - m_mTree[nId].m_nFlag = 4 ; + cCell.m_nFlag = 4 ; break ; } else if ( m_mTree[vNeigh[r]].m_nFlag == 0) { - m_mTree[nId].m_nFlag = 0 ; + cCell.m_nFlag = 0 ; break ; } } diff --git a/Tree.h b/Tree.h index e2d5adc..8b307b1 100644 --- a/Tree.h +++ b/Tree.h @@ -218,6 +218,7 @@ class Cell 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 attraversamento della cella int m_nVertToErase ; // vertice da eliminare dal poligono della cella, in caso di lato sovrapposto ad un lato di polo + // contati in senso CCW a partire dal bottom left private : Point3d m_ptPbl ; // punto bottom left