From f0429aefa491b35f51cd926ea81c224291b8762f Mon Sep 17 00:00:00 2001 From: Daniele Bariletti Date: Thu, 18 May 2023 15:07:27 +0200 Subject: [PATCH] EgtGeomKernel : - migliorata la robustezza per il calcolo della curvatura - pulizia del codice Da aggiungere : - gestione trim. --- Tree.cpp | 400 ++++++++++++++++++++++++++++++------------------------- Tree.h | 35 ++--- 2 files changed, 237 insertions(+), 198 deletions(-) diff --git a/Tree.cpp b/Tree.cpp index bce006f..3ef45ea 100644 --- a/Tree.cpp +++ b/Tree.cpp @@ -34,9 +34,9 @@ Cell::Cell( void) //---------------------------------------------------------------------------- -Cell::Cell( Point3d ptBL, Point3d ptTR) +Cell::Cell( Point3d& ptBL, 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_ptPbl( ptBL), m_ptPtr(ptTR), m_bProcessed ( false) , m_bSplitVert ( true) + m_nChild1( -2), m_nChild2( -2), m_ptPbl( ptBL), m_ptPtr( ptTR), m_bProcessed ( false) , m_bSplitVert ( true) {} @@ -47,7 +47,7 @@ Cell::~Cell( void) //---------------------------------------------------------------------------- inline bool -Cell::IsSame( Cell cOtherCell) const +Cell::IsSame( const Cell& cOtherCell) const { if ( m_nId == cOtherCell.m_nId) return true ; @@ -95,14 +95,17 @@ void Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches) bool bIsRat, bTrimmed ; m_pSrfBz->GetInfo( nDegU, nDegV, nSpanU, nSpanV, bIsRat, bTrimmed) ; m_bTrimmed = bTrimmed ; + m_nDegU = nDegU ; + m_nDegV = nDegV ; if ( nDegU == 1 && nDegV == 1) m_bBilinear = true ; if ( nSpanU * nSpanV != 1) m_bMulti = true ; // salvo i vertici 3d della cella root + Point3d ptBottom ( 0, 0) ; Point3d ptTop( nSpanU, nSpanV) ; - Cell cRoot( ORIG, ptTop) ; + Cell cRoot( ptBottom, ptTop) ; m_mTree.insert( pair< int, Cell>( -1, cRoot)) ; Point3d ptP00, ptP10, ptP11, ptP01 ; bool bOk = false ; @@ -224,7 +227,7 @@ Tree::Split( int nId, double dSplitValue) // controllo che lo split non venga fatto sul lato della cella if ( ( m_mTree[nId].IsSplitVert() && dSplitValue > m_mTree[nId].GetBottomLeft().x + EPS_SMALL && dSplitValue < m_mTree[nId].GetTopRight().x - EPS_SMALL) || ( ! m_mTree[nId].IsSplitVert() && dSplitValue > m_mTree[nId].GetBottomLeft().y + EPS_SMALL && dSplitValue < m_mTree[nId].GetTopRight().y - EPS_SMALL)) { - // per lo split a parametro libero devo impedire che si facciano split troppo vicini al bordo!!!!!!!!!!!!!!!!!!! + // per lo split a parametro libero dovrò impedire che si facciano split troppo vicini al bordo!!!!!!!!!!!!!!!!!!! m_mTree[nId].m_dSplit = dSplitValue ; Cell cChild1, cChild2 ; cChild1.m_nDepth = m_mTree[nId].m_nDepth + 1 ; @@ -330,21 +333,65 @@ bool Tree::BuildTree( double dLinTol_, double dSideMin, double dSideMax) if ( m_mTree[nCToSplit].IsLeaf()) { // calcolo in quale direzione ho più curvatura // ptP00P10 è un punto tra P00 e P10 - double dU = ( m_mTree[nCToSplit].GetTopRight().x + m_mTree[nCToSplit].GetBottomLeft().x) / 2 ; - double dV = ( m_mTree[nCToSplit].GetTopRight().y + m_mTree[nCToSplit].GetBottomLeft().y) / 2 ; - 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, m_mTree[nCToSplit].GetBottomLeft().y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP00P10) ; - m_pSrfBz->GetPointD1D2( m_mTree[nCToSplit].GetTopRight().x, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP10P11) ; - m_pSrfBz->GetPointD1D2( dU, m_mTree[nCToSplit].GetTopRight().y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP11P01) ; - m_pSrfBz->GetPointD1D2( m_mTree[nCToSplit].GetBottomLeft().x, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP01P00) ; - Point3d ptV = ( 1 - dULoc) * ptP00P10 + dULoc * ptP11P01 ; - Point3d ptU = ( 1 - dVLoc) * ptP10P11 + dVLoc * ptP01P00 ; - // per lo split scelgo la direzione che è più vicina alla superficie originale nel punto di maggior distanza - // misura approssimativa della curvatura in una direzione - double dCurvV = Dist( ptV, ptPSrf) ; - double dCurvU = Dist( ptU, ptPSrf) ; + double dCurvU = 0, dCurvV = 0 ; + double dLenParU = m_mTree[nCToSplit].GetTopRight().x - m_mTree[nCToSplit].GetBottomLeft().x ; + double dLenParV = m_mTree[nCToSplit].GetTopRight().y - m_mTree[nCToSplit].GetBottomLeft().y ; + if ( dLenParU <= 1. / m_nDegV || dLenParV <= 1. / m_nDegU) { + double dU = ( m_mTree[nCToSplit].GetTopRight().x + m_mTree[nCToSplit].GetBottomLeft().x) / 2 ; + double dV = ( m_mTree[nCToSplit].GetTopRight().y + m_mTree[nCToSplit].GetBottomLeft().y) / 2 ; + 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, m_mTree[nCToSplit].GetBottomLeft().y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP00P10) ; + m_pSrfBz->GetPointD1D2( m_mTree[nCToSplit].GetTopRight().x, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP10P11) ; + m_pSrfBz->GetPointD1D2( dU, m_mTree[nCToSplit].GetTopRight().y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP11P01) ; + m_pSrfBz->GetPointD1D2( m_mTree[nCToSplit].GetBottomLeft().x, 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) ; + dCurvU = Dist( ptU, ptPSrf) ; + } + // faccio un'analisi più fine della curvatura se almeno il grado di una curva di uno dei due parametri è alto e + // se sto ancora guardando una cella abbastanza grande + else{ + Point3d ptPSrf, ptP00P10, ptP10P11, ptP11P01, ptP01P00, ptPSrfMid; + double dStep = 1. / m_nDegU ; + for ( double k = dStep ; k < 1 ; k = k + dStep) { + double dU = k * m_mTree[nCToSplit].GetTopRight().x + ( 1 - k) * m_mTree[nCToSplit].GetBottomLeft().x ; + double dV = ( m_mTree[nCToSplit].GetTopRight().y + m_mTree[nCToSplit].GetBottomLeft().y) / 2 ; + m_pSrfBz->GetPointD1D2( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrf) ; + if ( k == 0.5) + ptPSrfMid = ptPSrf ; + m_pSrfBz->GetPointD1D2( dU, m_mTree[nCToSplit].GetBottomLeft().y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP00P10) ; + m_pSrfBz->GetPointD1D2( dU, m_mTree[nCToSplit].GetTopRight().y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP11P01) ; + CurveLine clV ; + clV.Set( ptP00P10, ptP11P01) ; + DistPointCurve dpc( ptPSrf, clV) ; + double dDist ; + dpc.GetDist( dDist) ; + dCurvV = max( dCurvV, dDist) ; + } + dStep = 1. / m_nDegV ; + for ( double k = dStep ; k < 1 ; k = k + dStep) { + double dU = ( m_mTree[nCToSplit].GetTopRight().x + m_mTree[nCToSplit].GetBottomLeft().x) / 2 ; + double dV = k * m_mTree[nCToSplit].GetTopRight().y + ( 1 - k) * m_mTree[nCToSplit].GetBottomLeft().y ; + if ( k == 0.5) + ptPSrf = ptPSrfMid ; + else + m_pSrfBz->GetPointD1D2( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrf) ; + m_pSrfBz->GetPointD1D2( m_mTree[nCToSplit].GetTopRight().x, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP10P11) ; + m_pSrfBz->GetPointD1D2( m_mTree[nCToSplit].GetBottomLeft().x, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP01P00) ; + CurveLine clU ; + clU.Set( ptP01P00, ptP10P11) ; + DistPointCurve dpc( ptPSrf, clU) ; + double dDist ; + dpc.GetDist( dDist) ; + dCurvU = max( dCurvU, dDist) ; + } + } + + // per lo split scelgo la direzione che è più vicina alla superficie originale nel punto di maggior distanza + // misura approssimativa della curvatura in una direzione bool bVert ; if ( dCurvV > dCurvU) { // lungo la direzione V ho una curvatura maggiore @@ -383,7 +430,6 @@ bool Tree::BuildTree( double dLinTol_, double dSideMin, double dSideMax) dSideMaxVal = max( Dist( ptP00, ptP11), Dist( ptP10, ptP01)) ; // se la cella è abbastanza grande da poter essere divisa ancora, calcolo l'errore di approssimazione - double dErr = 0 ; bool bSplit = false ; if ( dSideMinVal / 2 >= dSideMin && dSideMaxVal < dSideMax && ( dCurvV > dLinTol || dCurvU > dLinTol)) { CurveLine cl0010, cl0001, cl1011, cl0111 ; @@ -403,8 +449,8 @@ bool Tree::BuildTree( double dLinTol_, double dSideMin, double dSideMax) int nStepsU = int( 51 * dDimU + 5 * ( 1 - dDimU)) ; int nStepsV = int( 51 * dDimV + 5 * ( 1 - dDimV)) ; for ( int u = 0 ; u < nStepsU && ! bSplit ; ++ u) { - dU = double ( u) / double ( nStepsU - 1) ; - dULoc = ( 1 - dU) * m_mTree[nCToSplit].GetBottomLeft().x + dU * m_mTree[nCToSplit].GetTopRight().x ; + double dU = double ( u) / double ( nStepsU - 1) ; + double dULoc = ( 1 - dU) * m_mTree[nCToSplit].GetBottomLeft().x + dU * m_mTree[nCToSplit].GetTopRight().x ; if ( ! m_pSrfBz->GetPointD1D2( dULoc, m_mTree[nCToSplit].GetBottomLeft().y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBz0) || ! m_pSrfBz->GetPointD1D2( dULoc, m_mTree[nCToSplit].GetTopRight().y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBz1)) return false ; @@ -414,16 +460,14 @@ bool Tree::BuildTree( double dLinTol_, double dSideMin, double dSideMax) dpc0111.GetMinDistPoint( 0, pt0111, nFlag) ; clV.Set( pt0010, pt0111) ; for ( int v = 0 ; v < nStepsV ; ++ v) { - dV = double ( v) / double ( nStepsV - 1) ; - dVLoc = ( 1 - dV) * m_mTree[nCToSplit].GetBottomLeft().y + dV * m_mTree[nCToSplit].GetTopRight().y ; + double dV = double ( v) / double ( nStepsV - 1) ; + double dVLoc = ( 1 - dV) * m_mTree[nCToSplit].GetBottomLeft().y + dV * m_mTree[nCToSplit].GetTopRight().y ; if ( ! m_pSrfBz->GetPointD1D2( dULoc, dVLoc, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBzV)) return false ; DistPointCurve dpc( ptBzV, clV) ; // distanza di approssimazione locale double dDist ; dpc.GetDist( dDist) ; - //if ( dDist > dErr) - // dErr = dDist ; if ( dDist > dLinTol) { bSplit = true ; break ; @@ -432,7 +476,6 @@ bool Tree::BuildTree( double dLinTol_, double dSideMin, double dSideMax) } } - //if ( dErr > dLinTol || dSideMaxVal > dSideMax) { if ( bSplit || dSideMaxVal > dSideMax) { m_mTree[nCToSplit].SetSplitDirVert( bVert) ; // effettuo lo split @@ -481,19 +524,12 @@ bool Tree::BuildTree( double dLinTol_, double dSideMin, double dSideMax) double dLen1 = Dist( ptP10, ptP11) ; double dLen2 = Dist( ptP01, ptP11) ; double dLen3 = Dist( ptP00, ptP01) ; - // calcolo se è migliore la divisione in orizzontale o in verticale - Point3d ptP00P10, ptP00P01 , ptP01P11, ptP10P11 ; - ptP00P10 = ( ptP00 + ptP10) / 2 ; - ptP10P11 = ( ptP10 + ptP11) / 2 ; - ptP01P11 = ( ptP01 + ptP11) / 2 ; - ptP00P01 = ( ptP00 + ptP01) / 2 ; bool bVert = false ; // calcolo in quale direzione è meglio dividere in base allo stretch Point3d ptPSrfU, ptPSrfV ; double dU = 0, dV = 0 ; double dDistU = 0, dDistV = 0 ; - double dULoc, dVLoc ; PNTVECTOR vPtU, vPtV ; if ( ! m_bMulti) { if ( max(dLen0, dLen2) > max(dLen1, dLen3)) { @@ -507,8 +543,8 @@ bool Tree::BuildTree( double dLinTol_, double dSideMin, double dSideMax) for ( double i = 0.25 ; i < 1 ; i = i + 0.25 ) { dU = ( 1 - i) * m_mTree[nCToSplit].GetBottomLeft().x + i * m_mTree[nCToSplit].GetTopRight().x ; dV = ( 1 - i) * m_mTree[nCToSplit].GetBottomLeft().y + i * m_mTree[nCToSplit].GetTopRight().y ; - dVLoc = ( m_mTree[nCToSplit].GetBottomLeft().y + m_mTree[nCToSplit].GetTopRight().y) / 2 ; - dULoc = ( m_mTree[nCToSplit].GetBottomLeft().x + m_mTree[nCToSplit].GetTopRight().x) / 2 ; + double dVLoc = ( m_mTree[nCToSplit].GetBottomLeft().y + m_mTree[nCToSplit].GetTopRight().y) / 2 ; + double dULoc = ( m_mTree[nCToSplit].GetBottomLeft().x + m_mTree[nCToSplit].GetTopRight().x) / 2 ; 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) ; @@ -623,37 +659,37 @@ void Tree::Balance() } //---------------------------------------------------------------------------- -void Tree::GetTopNeigh( int nId, INTVECTOR& vTopNeighs) +void Tree::GetTopNeigh( int nId, INTVECTOR& vTopNeighs) const { if ( (int) vTopNeighs.size() == 0) { - if ( m_mTree[nId].m_nTop == -2) + if ( m_mTree.at(nId).m_nTop == -2) return ; - if ( m_mTree[m_mTree[nId].m_nTop].IsLeaf()) - vTopNeighs.push_back( m_mTree[nId].m_nTop) ; + if ( m_mTree.at(m_mTree.at(nId).m_nTop).IsLeaf()) + vTopNeighs.push_back( m_mTree.at(nId).m_nTop) ; else { - if ( m_mTree[m_mTree[nId].m_nTop].IsSplitVert()) { + if ( m_mTree.at(m_mTree.at(nId).m_nTop).IsSplitVert()) { // se la cella vicina è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima - if ( m_mTree[m_mTree[nId].m_nTop].GetTopRight().x - m_mTree[m_mTree[nId].m_nTop].GetBottomLeft().x <= - m_mTree[nId].GetTopRight().x - m_mTree[nId].GetBottomLeft().x) { - vTopNeighs.push_back( m_mTree[m_mTree[nId].m_nTop].m_nChild1) ; - vTopNeighs.push_back( m_mTree[m_mTree[nId].m_nTop].m_nChild2) ; + if ( m_mTree.at(m_mTree.at(nId).m_nTop).GetTopRight().x - m_mTree.at(m_mTree.at(nId).m_nTop).GetBottomLeft().x <= + m_mTree.at(nId).GetTopRight().x - m_mTree.at(nId).GetBottomLeft().x) { + vTopNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nTop).m_nChild1) ; + vTopNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nTop).m_nChild2) ; } // altrimenti solo uno dei figli lo sarà else{ - if ( m_mTree[m_mTree[m_mTree[nId].m_nTop].m_nChild1].GetTopRight().x <= m_mTree[nId].GetBottomLeft().x || - m_mTree[m_mTree[m_mTree[nId].m_nTop].m_nChild1].GetBottomLeft().x >= m_mTree[nId].GetTopRight().x ) - vTopNeighs.push_back( m_mTree[m_mTree[nId].m_nTop].m_nChild2) ; + if ( m_mTree.at(m_mTree.at(m_mTree.at(nId).m_nTop).m_nChild1).GetTopRight().x <= m_mTree.at(nId).GetBottomLeft().x || + m_mTree.at(m_mTree.at(m_mTree.at(nId).m_nTop).m_nChild1).GetBottomLeft().x >= m_mTree.at(nId).GetTopRight().x ) + vTopNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nTop).m_nChild2) ; else - vTopNeighs.push_back( m_mTree[m_mTree[nId].m_nTop].m_nChild1) ; + vTopNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nTop).m_nChild1) ; } } else { - vTopNeighs.push_back( m_mTree[m_mTree[nId].m_nTop].m_nChild2) ; + vTopNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nTop).m_nChild2) ; } } bool bAllLeaves = true ; for ( int i : vTopNeighs ) { - if ( ! m_mTree[i].IsLeaf()) + if ( ! m_mTree.at(i).IsLeaf()) bAllLeaves = false ; } if ( ! bAllLeaves ) @@ -662,38 +698,38 @@ void Tree::GetTopNeigh( int nId, INTVECTOR& vTopNeighs) } else { for ( int j = 0 ; j != (int) vTopNeighs.size() ; ++ j) { - int i = vTopNeighs[j] ; - if ( m_mTree[i].IsLeaf()) + int i = vTopNeighs.at(j) ; + if ( m_mTree.at(i).IsLeaf()) continue; else { // se la cella non è leaf la tolgo dal vettore delle foglie e aggiungo invece i suoi child vTopNeighs.erase( remove( vTopNeighs.begin(),vTopNeighs.end(),i)) ; -- j ; - if ( m_mTree[i].IsSplitVert() ) { + if ( m_mTree.at(i).IsSplitVert() ) { // se la cella è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima - if ( m_mTree[i].GetTopRight().x - m_mTree[i].GetBottomLeft().x <= - m_mTree[nId].GetTopRight().x - m_mTree[nId].GetBottomLeft().x) { - vTopNeighs.push_back( m_mTree[i].m_nChild1) ; - vTopNeighs.push_back( m_mTree[i].m_nChild2) ; + if ( m_mTree.at(i).GetTopRight().x - m_mTree.at(i).GetBottomLeft().x <= + m_mTree.at(nId).GetTopRight().x - m_mTree.at(nId).GetBottomLeft().x) { + vTopNeighs.push_back( m_mTree.at(i).m_nChild1) ; + vTopNeighs.push_back( m_mTree.at(i).m_nChild2) ; } // altrimenti solo uno dei figli lo sarà else { - if ( m_mTree[m_mTree[i].m_nChild1].GetTopRight().x <= m_mTree[nId].GetBottomLeft().x || - m_mTree[m_mTree[i].m_nChild1].GetBottomLeft().x >= m_mTree[nId].GetTopRight().x ) - vTopNeighs.push_back( m_mTree[i].m_nChild2) ; + if ( m_mTree.at(m_mTree.at(i).m_nChild1).GetTopRight().x <= m_mTree.at(nId).GetBottomLeft().x || + m_mTree.at(m_mTree.at(i).m_nChild1).GetBottomLeft().x >= m_mTree.at(nId).GetTopRight().x ) + vTopNeighs.push_back( m_mTree.at(i).m_nChild2) ; else - vTopNeighs.push_back( m_mTree[i].m_nChild1) ; + vTopNeighs.push_back( m_mTree.at(i).m_nChild1) ; } } else { - vTopNeighs.push_back( m_mTree[i].m_nChild2) ; + vTopNeighs.push_back( m_mTree.at(i).m_nChild2) ; } } } } vector vCells ; for ( int k : vTopNeighs) - vCells.push_back( m_mTree[k]) ; + vCells.push_back( m_mTree.at(k)) ; std::sort( vCells.begin(), vCells.end(), Cell::minorX) ; vTopNeighs.clear() ; for ( Cell c : vCells) @@ -702,37 +738,37 @@ void Tree::GetTopNeigh( int nId, INTVECTOR& vTopNeighs) //---------------------------------------------------------------------------- -void Tree::GetBottomNeigh( int nId, INTVECTOR& vBottomNeighs) +void Tree::GetBottomNeigh( int nId, INTVECTOR& vBottomNeighs) const { if ( (int) vBottomNeighs.size() == 0) { - if ( m_mTree[nId].m_nBottom == -2) + if ( m_mTree.at(nId).m_nBottom == -2) return ; - if ( m_mTree[m_mTree[nId].m_nBottom].IsLeaf()) - vBottomNeighs.push_back( m_mTree[nId].m_nBottom) ; + if ( m_mTree.at(m_mTree.at(nId).m_nBottom).IsLeaf()) + vBottomNeighs.push_back( m_mTree.at(nId).m_nBottom) ; else { - if ( m_mTree[m_mTree[nId].m_nBottom].IsSplitVert()) { + if ( m_mTree.at(m_mTree.at(nId).m_nBottom).IsSplitVert()) { // se la cella vicina è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima - if ( m_mTree[m_mTree[nId].m_nBottom].GetTopRight().x - m_mTree[m_mTree[nId].m_nBottom].GetBottomLeft().x <= - m_mTree[nId].GetTopRight().x - m_mTree[nId].GetBottomLeft().x) { - vBottomNeighs.push_back( m_mTree[m_mTree[nId].m_nBottom].m_nChild1) ; - vBottomNeighs.push_back( m_mTree[m_mTree[nId].m_nBottom].m_nChild2) ; + if ( m_mTree.at(m_mTree.at(nId).m_nBottom).GetTopRight().x - m_mTree.at(m_mTree.at(nId).m_nBottom).GetBottomLeft().x <= + m_mTree.at(nId).GetTopRight().x - m_mTree.at(nId).GetBottomLeft().x) { + vBottomNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nBottom).m_nChild1) ; + vBottomNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nBottom).m_nChild2) ; } // altrimenti solo uno dei figli lo sarà else{ - if ( m_mTree[m_mTree[m_mTree[nId].m_nBottom].m_nChild1].GetTopRight().x <= m_mTree[nId].GetBottomLeft().x || - m_mTree[m_mTree[m_mTree[nId].m_nBottom].m_nChild1].GetBottomLeft().x >= m_mTree[nId].GetTopRight().x ) - vBottomNeighs.push_back( m_mTree[m_mTree[nId].m_nBottom].m_nChild2) ; + if ( m_mTree.at(m_mTree.at(m_mTree.at(nId).m_nBottom).m_nChild1).GetTopRight().x <= m_mTree.at(nId).GetBottomLeft().x || + m_mTree.at(m_mTree.at(m_mTree.at(nId).m_nBottom).m_nChild1).GetBottomLeft().x >= m_mTree.at(nId).GetTopRight().x ) + vBottomNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nBottom).m_nChild2) ; else - vBottomNeighs.push_back( m_mTree[m_mTree[nId].m_nBottom].m_nChild1) ; + vBottomNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nBottom).m_nChild1) ; } } else { - vBottomNeighs.push_back( m_mTree[m_mTree[nId].m_nBottom].m_nChild1) ; + vBottomNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nBottom).m_nChild1) ; } } bool bAllLeaves = true ; for ( int i : vBottomNeighs) { - if ( ! m_mTree[i].IsLeaf()) + if ( ! m_mTree.at(i).IsLeaf()) bAllLeaves = false ; } if ( ! bAllLeaves ) @@ -741,38 +777,38 @@ void Tree::GetBottomNeigh( int nId, INTVECTOR& vBottomNeighs) } else { for ( int j = 0 ; j != (int) vBottomNeighs.size() ; ++ j) { - int i = vBottomNeighs[j] ; - if ( m_mTree[i].IsLeaf()) + int i = vBottomNeighs.at(j) ; + if ( m_mTree.at(i).IsLeaf()) continue; else { // se la cella non è leaf la tolgo dal vettore delle foglie e aggiungo invece i suoi child vBottomNeighs.erase( remove( vBottomNeighs.begin(),vBottomNeighs.end(),i)) ; -- j ; - if ( m_mTree[i].IsSplitVert()) { + if ( m_mTree.at(i).IsSplitVert()) { // se la cella è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima - if ( m_mTree[i].GetTopRight().x - m_mTree[i].GetBottomLeft().x <= - m_mTree[nId].GetTopRight().x - m_mTree[nId].GetBottomLeft().x) { - vBottomNeighs.push_back( m_mTree[i].m_nChild1) ; - vBottomNeighs.push_back( m_mTree[i].m_nChild2) ; + if ( m_mTree.at(i).GetTopRight().x - m_mTree.at(i).GetBottomLeft().x <= + m_mTree.at(nId).GetTopRight().x - m_mTree.at(nId).GetBottomLeft().x) { + vBottomNeighs.push_back( m_mTree.at(i).m_nChild1) ; + vBottomNeighs.push_back( m_mTree.at(i).m_nChild2) ; } // altrimenti solo uno dei figli lo sarà else { - if ( m_mTree[m_mTree[i].m_nChild1].GetTopRight().x <= m_mTree[nId].GetBottomLeft().x || - m_mTree[m_mTree[i].m_nChild1].GetBottomLeft().x >= m_mTree[nId].GetTopRight().x) - vBottomNeighs.push_back( m_mTree[i].m_nChild2) ; + if ( m_mTree.at(m_mTree.at(i).m_nChild1).GetTopRight().x <= m_mTree.at(nId).GetBottomLeft().x || + m_mTree.at(m_mTree.at(i).m_nChild1).GetBottomLeft().x >= m_mTree.at(nId).GetTopRight().x) + vBottomNeighs.push_back( m_mTree.at(i).m_nChild2) ; else - vBottomNeighs.push_back( m_mTree[i].m_nChild1) ; + vBottomNeighs.push_back( m_mTree.at(i).m_nChild1) ; } } else { - vBottomNeighs.push_back( m_mTree[i].m_nChild1) ; + vBottomNeighs.push_back( m_mTree.at(i).m_nChild1) ; } } } } vector vCells ; for ( int k : vBottomNeighs) - vCells.push_back( m_mTree[k]) ; + vCells.push_back( m_mTree.at(k)) ; std::sort( vCells.begin(), vCells.end(), Cell::minorX) ; vBottomNeighs.clear() ; for ( Cell c : vCells) @@ -781,37 +817,37 @@ void Tree::GetBottomNeigh( int nId, INTVECTOR& vBottomNeighs) //---------------------------------------------------------------------------- -void Tree::GetLeftNeigh( int nId, INTVECTOR& vLeftNeighs) +void Tree::GetLeftNeigh( int nId, INTVECTOR& vLeftNeighs) const { if ( (int) vLeftNeighs.size() == 0) { - if ( m_mTree[nId].m_nLeft == -2) + if ( m_mTree.at(nId).m_nLeft == -2) return ; - if ( m_mTree[m_mTree[nId].m_nLeft].IsLeaf()) - vLeftNeighs.push_back( m_mTree[nId].m_nLeft) ; + if ( m_mTree.at(m_mTree.at(nId).m_nLeft).IsLeaf()) + vLeftNeighs.push_back( m_mTree.at(nId).m_nLeft) ; else { - if ( ! m_mTree[m_mTree[nId].m_nLeft].IsSplitVert()) { + if ( ! m_mTree.at(m_mTree.at(nId).m_nLeft).IsSplitVert()) { // se la cella vicina è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima - if ( m_mTree[m_mTree[nId].m_nLeft].GetTopRight().y - m_mTree[m_mTree[nId].m_nLeft].GetBottomLeft().y <= - m_mTree[nId].GetTopRight().y - m_mTree[nId].GetBottomLeft().y) { - vLeftNeighs.push_back( m_mTree[m_mTree[nId].m_nLeft].m_nChild1) ; - vLeftNeighs.push_back( m_mTree[m_mTree[nId].m_nLeft].m_nChild2) ; + if ( m_mTree.at(m_mTree.at(nId).m_nLeft).GetTopRight().y - m_mTree.at(m_mTree.at(nId).m_nLeft).GetBottomLeft().y <= + m_mTree.at(nId).GetTopRight().y - m_mTree.at(nId).GetBottomLeft().y) { + vLeftNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nLeft).m_nChild1) ; + vLeftNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nLeft).m_nChild2) ; } // altrimenti solo uno dei figli lo sarà else{ - if ( m_mTree[m_mTree[m_mTree[nId].m_nLeft].m_nChild1].GetTopRight().y <= m_mTree[nId].GetBottomLeft().y || - m_mTree[m_mTree[m_mTree[nId].m_nLeft].m_nChild1].GetBottomLeft().y >= m_mTree[nId].GetTopRight().y) - vLeftNeighs.push_back( m_mTree[m_mTree[nId].m_nLeft].m_nChild2) ; + if ( m_mTree.at(m_mTree.at(m_mTree.at(nId).m_nLeft).m_nChild1).GetTopRight().y <= m_mTree.at(nId).GetBottomLeft().y || + m_mTree.at(m_mTree.at(m_mTree.at(nId).m_nLeft).m_nChild1).GetBottomLeft().y >= m_mTree.at(nId).GetTopRight().y) + vLeftNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nLeft).m_nChild2) ; else - vLeftNeighs.push_back( m_mTree[m_mTree[nId].m_nLeft].m_nChild1) ; + vLeftNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nLeft).m_nChild1) ; } } else { - vLeftNeighs.push_back( m_mTree[m_mTree[nId].m_nLeft].m_nChild2) ; + vLeftNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nLeft).m_nChild2) ; } } bool bAllLeaves = true ; for ( int i : vLeftNeighs) { - if ( ! m_mTree[i].IsLeaf()) + if ( ! m_mTree.at(i).IsLeaf()) bAllLeaves = false ; } if ( ! bAllLeaves ) @@ -820,38 +856,38 @@ void Tree::GetLeftNeigh( int nId, INTVECTOR& vLeftNeighs) } else { for ( int j = 0 ; j != (int) vLeftNeighs.size() ; ++ j) { - int i = vLeftNeighs[j] ; - if ( m_mTree[i].IsLeaf()) + int i = vLeftNeighs.at(j) ; + if ( m_mTree.at(i).IsLeaf()) continue; else { // se la cella non è leaf la tolgo dal vettore delle foglie e aggiungo invece i suoi child vLeftNeighs.erase( remove( vLeftNeighs.begin(),vLeftNeighs.end(),i)) ; -- j ; - if ( ! m_mTree[i].IsSplitVert()) { + if ( ! m_mTree.at(i).IsSplitVert()) { // se la cella è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima - if ( m_mTree[i].GetTopRight().y - m_mTree[i].GetBottomLeft().y <= - m_mTree[nId].GetTopRight().y - m_mTree[nId].GetBottomLeft().y) { - vLeftNeighs.push_back( m_mTree[i].m_nChild1) ; - vLeftNeighs.push_back( m_mTree[i].m_nChild2) ; + if ( m_mTree.at(i).GetTopRight().y - m_mTree.at(i).GetBottomLeft().y <= + m_mTree.at(nId).GetTopRight().y - m_mTree.at(nId).GetBottomLeft().y) { + vLeftNeighs.push_back( m_mTree.at(i).m_nChild1) ; + vLeftNeighs.push_back( m_mTree.at(i).m_nChild2) ; } // altrimenti solo uno dei figli lo sarà else { - if ( m_mTree[m_mTree[i].m_nChild1].GetTopRight().y <= m_mTree[nId].GetBottomLeft().y || - m_mTree[m_mTree[i].m_nChild1].GetBottomLeft().y >= m_mTree[nId].GetTopRight().y) - vLeftNeighs.push_back( m_mTree[i].m_nChild2) ; + if ( m_mTree.at(m_mTree.at(i).m_nChild1).GetTopRight().y <= m_mTree.at(nId).GetBottomLeft().y || + m_mTree.at(m_mTree.at(i).m_nChild1).GetBottomLeft().y >= m_mTree.at(nId).GetTopRight().y) + vLeftNeighs.push_back( m_mTree.at(i).m_nChild2) ; else - vLeftNeighs.push_back( m_mTree[i].m_nChild1) ; + vLeftNeighs.push_back( m_mTree.at(i).m_nChild1) ; } } else { - vLeftNeighs.push_back( m_mTree[i].m_nChild2) ; + vLeftNeighs.push_back( m_mTree.at(i).m_nChild2) ; } } } } vector vCells ; for ( int k : vLeftNeighs) - vCells.push_back( m_mTree[k]) ; + vCells.push_back( m_mTree.at(k)) ; std::sort( vCells.begin(), vCells.end(), Cell::minorY) ; vLeftNeighs.clear() ; for ( Cell c : vCells) @@ -859,37 +895,37 @@ void Tree::GetLeftNeigh( int nId, INTVECTOR& vLeftNeighs) } //---------------------------------------------------------------------------- -void Tree::GetRightNeigh( int nId, INTVECTOR& vRightNeighs) +void Tree::GetRightNeigh( int nId, INTVECTOR& vRightNeighs) const { if ( (int) vRightNeighs.size() == 0) { - if ( m_mTree[nId].m_nRight == -2) + if ( m_mTree.at(nId).m_nRight == -2) return ; - if ( m_mTree[m_mTree[nId].m_nRight].IsLeaf()) - vRightNeighs.push_back( m_mTree[nId].m_nRight) ; + if ( m_mTree.at(m_mTree.at(nId).m_nRight).IsLeaf()) + vRightNeighs.push_back( m_mTree.at(nId).m_nRight) ; else { - if ( ! m_mTree[m_mTree[nId].m_nRight].IsSplitVert()) { + if ( ! m_mTree.at(m_mTree.at(nId).m_nRight).IsSplitVert()) { // se la cella vicina è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima - if ( m_mTree[m_mTree[nId].m_nRight].GetTopRight().y - m_mTree[m_mTree[nId].m_nRight].GetBottomLeft().y <= - m_mTree[nId].GetTopRight().y - m_mTree[nId].GetBottomLeft().y) { - vRightNeighs.push_back( m_mTree[m_mTree[nId].m_nRight].m_nChild1) ; - vRightNeighs.push_back( m_mTree[m_mTree[nId].m_nRight].m_nChild2) ; + if ( m_mTree.at(m_mTree.at(nId).m_nRight).GetTopRight().y - m_mTree.at(m_mTree.at(nId).m_nRight).GetBottomLeft().y <= + m_mTree.at(nId).GetTopRight().y - m_mTree.at(nId).GetBottomLeft().y) { + vRightNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nRight).m_nChild1) ; + vRightNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nRight).m_nChild2) ; } // altrimenti solo uno dei figli lo sarà else{ - if ( m_mTree[m_mTree[m_mTree[nId].m_nRight].m_nChild1].GetTopRight().y <= m_mTree[nId].GetBottomLeft().y || - m_mTree[m_mTree[m_mTree[nId].m_nRight].m_nChild1].GetBottomLeft().y >= m_mTree[nId].GetTopRight().y) - vRightNeighs.push_back( m_mTree[m_mTree[nId].m_nRight].m_nChild2) ; + if ( m_mTree.at(m_mTree.at(m_mTree.at(nId).m_nRight).m_nChild1).GetTopRight().y <= m_mTree.at(nId).GetBottomLeft().y || + m_mTree.at(m_mTree.at(m_mTree.at(nId).m_nRight).m_nChild1).GetBottomLeft().y >= m_mTree.at(nId).GetTopRight().y) + vRightNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nRight).m_nChild2) ; else - vRightNeighs.push_back( m_mTree[m_mTree[nId].m_nRight].m_nChild1) ; + vRightNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nRight).m_nChild1) ; } } else { - vRightNeighs.push_back( m_mTree[m_mTree[nId].m_nRight].m_nChild1) ; + vRightNeighs.push_back( m_mTree.at(m_mTree.at(nId).m_nRight).m_nChild1) ; } } bool bAllLeaves = true ; for ( int i : vRightNeighs) { - if ( ! m_mTree[i].IsLeaf()) + if ( ! m_mTree.at(i).IsLeaf()) bAllLeaves = false ; } if ( ! bAllLeaves ) @@ -898,38 +934,38 @@ void Tree::GetRightNeigh( int nId, INTVECTOR& vRightNeighs) } else { for ( int j = 0 ; j != (int) vRightNeighs.size() ; ++ j) { - int i = vRightNeighs[j] ; - if ( m_mTree[i].IsLeaf()) + int i = vRightNeighs.at(j) ; + if ( m_mTree.at(i).IsLeaf()) continue; else { // se la cella non è leaf la tolgo dal vettore delle foglie e aggiungo invece i suoi child vRightNeighs.erase( remove( vRightNeighs.begin(),vRightNeighs.end(), i)) ; -- j ; - if ( ! m_mTree[i].IsSplitVert()) { + if ( ! m_mTree.at(i).IsSplitVert()) { // se la cella è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima - if ( m_mTree[i].GetTopRight().y - m_mTree[i].GetBottomLeft().y <= - m_mTree[nId].GetTopRight().y - m_mTree[nId].GetBottomLeft().y) { - vRightNeighs.push_back( m_mTree[i].m_nChild1) ; - vRightNeighs.push_back( m_mTree[i].m_nChild2) ; + if ( m_mTree.at(i).GetTopRight().y - m_mTree.at(i).GetBottomLeft().y <= + m_mTree.at(nId).GetTopRight().y - m_mTree.at(nId).GetBottomLeft().y) { + vRightNeighs.push_back( m_mTree.at(i).m_nChild1) ; + vRightNeighs.push_back( m_mTree.at(i).m_nChild2) ; } // altrimenti solo uno dei figli lo sarà else { - if ( m_mTree[m_mTree[i].m_nChild1].GetTopRight().y <= m_mTree[nId].GetBottomLeft().y || - m_mTree[m_mTree[i].m_nChild1].GetBottomLeft().y >= m_mTree[nId].GetTopRight().y) - vRightNeighs.push_back( m_mTree[i].m_nChild2) ; + if ( m_mTree.at(m_mTree.at(i).m_nChild1).GetTopRight().y <= m_mTree.at(nId).GetBottomLeft().y || + m_mTree.at(m_mTree.at(i).m_nChild1).GetBottomLeft().y >= m_mTree.at(nId).GetTopRight().y) + vRightNeighs.push_back( m_mTree.at(i).m_nChild2) ; else - vRightNeighs.push_back( m_mTree[i].m_nChild1) ; + vRightNeighs.push_back( m_mTree.at(i).m_nChild1) ; } } else { - vRightNeighs.push_back( m_mTree[i].m_nChild1) ; + vRightNeighs.push_back( m_mTree.at(i).m_nChild1) ; } } } } vector vCells ; for ( int k : vRightNeighs) - vCells.push_back( m_mTree[k]) ; + vCells.push_back( m_mTree.at(k)) ; std::sort( vCells.begin(), vCells.end(), Cell::minorY) ; vRightNeighs.clear() ; for ( Cell c : vCells) @@ -937,51 +973,51 @@ void Tree::GetRightNeigh( int nId, INTVECTOR& vRightNeighs) } //---------------------------------------------------------------------------- -int Tree::GetHeightLeaves( int nId, INTVECTOR& vnLeaves, int d) +int Tree::GetHeightLeaves( int nId, INTVECTOR& vnLeaves, int d) const { - if ( nId == -1 && m_mTree[-1].IsLeaf()) { + if ( nId == -1 && m_mTree.at(-1).IsLeaf()) { vnLeaves.push_back( -1) ; return 0 ; } else { if ( (int) vnLeaves.size() == 0) { - if ( m_mTree[nId].IsLeaf()) + if ( m_mTree.at(nId).IsLeaf()) return d ; else { - vnLeaves.push_back( m_mTree[nId].m_nChild1) ; - vnLeaves.push_back( m_mTree[nId].m_nChild2) ; - if ( ! m_mTree[m_mTree[nId].m_nChild1].IsLeaf() || ! m_mTree[m_mTree[nId].m_nChild2].IsLeaf()) + vnLeaves.push_back( m_mTree.at(nId).m_nChild1) ; + vnLeaves.push_back( m_mTree.at(nId).m_nChild2) ; + if ( ! m_mTree.at(m_mTree.at(nId).m_nChild1).IsLeaf() || ! m_mTree.at(m_mTree.at(nId).m_nChild2).IsLeaf()) // almeno un child non è leaf quindi devo richiamare ricorsivamente questa funzione sui child in questione - d = GetHeightLeaves( nId, vnLeaves, m_mTree[m_mTree[nId].m_nChild1].m_nDepth) ; + d = GetHeightLeaves( nId, vnLeaves, m_mTree.at(m_mTree.at(nId).m_nChild1).m_nDepth) ; } } else { for ( int j = 0 ; j != (int) vnLeaves.size() ; ++ j) { - int i = vnLeaves[j] ; - if ( m_mTree[i].IsLeaf() ) { + int i = vnLeaves.at(j) ; + if ( m_mTree.at(i).IsLeaf() ) { continue ; } else { // se la cella non è leaf la tolgo dal vettore delle foglie e aggiungo invece i suoi child vnLeaves.erase( remove( vnLeaves.begin(),vnLeaves.end(),i)) ; -- j ; - vnLeaves.push_back( m_mTree[i].m_nChild1) ; - vnLeaves.push_back( m_mTree[i].m_nChild2) ; - d = max ( d, m_mTree[m_mTree[i].m_nChild1].m_nDepth) ; + vnLeaves.push_back( m_mTree.at(i).m_nChild1) ; + vnLeaves.push_back( m_mTree.at(i).m_nChild2) ; + d = max ( d, m_mTree.at(m_mTree.at(i).m_nChild1).m_nDepth) ; } } return d ; } - return d - m_mTree[nId].m_nDepth ; + return d - m_mTree.at(nId).m_nDepth ; } } //---------------------------------------------------------------------------- -int Tree::GetDepth( int nId, int nRef = -2) +int Tree::GetDepth( int nId, int nRef = -2) const { int c = 0 ; - while ( m_mTree[nId].m_nParent != nRef) { - nId = m_mTree[nId].m_nParent ; + while ( m_mTree.at(nId).m_nParent != nRef) { + nId = m_mTree.at(nId).m_nParent ; ++ c ; } return c ; @@ -998,12 +1034,12 @@ bool Tree::GetPolygons( POLYLINEVECTOR& vPolygons) for ( int nId : m_vnLeaves) { vVertices.clear() ; vNeigh.clear() ; - vVertices.push_back( m_mTree[nId].GetBottomLeft()) ; + vVertices.push_back( m_mTree.at(nId).GetBottomLeft()) ; GetBottomNeigh( nId, vNeigh) ; // aggiungo i vertici che sono sul lato bottom, solo se ho più di un vicino bottom if ( (int) vNeigh.size() != 0 && (int) vNeigh.size() != 1){ for ( int j : vNeigh ) - vVertices.push_back( m_mTree[j].GetTopRight()) ; + vVertices.push_back( m_mTree.at(j).GetTopRight()) ; bBottomRight = true ; } else @@ -1013,21 +1049,21 @@ bool Tree::GetPolygons( POLYLINEVECTOR& vPolygons) // aggiungo i vertici che sono sul lato right, solo se ho più di un vicino right if ( (int) vNeigh.size() != 0 && (int) vNeigh.size() != 1){ for ( int j : vNeigh ) - vVertices.push_back( m_mTree[j].GetBottomLeft()) ; + vVertices.push_back( m_mTree.at(j).GetBottomLeft()) ; } // se non l'ho già aggiunto tramite i vicini bottom aggiungo il punto bottom right else if ( ! bBottomRight ) { - Point3d ptBr( m_mTree[nId].GetTopRight().x, m_mTree[nId].GetBottomLeft().y) ; + Point3d ptBr( m_mTree.at(nId).GetTopRight().x, m_mTree.at(nId).GetBottomLeft().y) ; vVertices.push_back( ptBr) ; } vNeigh.clear() ; - vVertices.push_back( m_mTree[nId].GetTopRight()) ; + vVertices.push_back( m_mTree.at(nId).GetTopRight()) ; GetTopNeigh ( nId, vNeigh) ; std::reverse( vNeigh.begin(), vNeigh.end()) ; // aggiungo i vertici che sono sul lato top, solo se ho più di un vicino top if ( (int) vNeigh.size() != 0 && (int) vNeigh.size() != 1) { for ( int j : vNeigh) - vVertices.push_back( m_mTree[j].GetBottomLeft()) ; + vVertices.push_back( m_mTree.at(j).GetBottomLeft()) ; bTopLeft = true ; } else @@ -1038,39 +1074,39 @@ bool Tree::GetPolygons( POLYLINEVECTOR& vPolygons) // aggiungo i vertici che sono sul lato left, solo se ho più di un vicino left if ( (int) vNeigh.size() != 0 && (int) vNeigh.size() != 1) { for ( int j : vNeigh) - vVertices.push_back( m_mTree[j].GetTopRight()) ; + vVertices.push_back( m_mTree.at(j).GetTopRight()) ; } // se non l'ho già aggiunto tramite i vicini top aggiungo il punto top left else if ( ! bTopLeft) { - Point3d ptTl( m_mTree[nId].GetBottomLeft().x, m_mTree[nId].GetTopRight().y) ; + Point3d ptTl( m_mTree.at(nId).GetBottomLeft().x, m_mTree.at(nId).GetTopRight().y) ; vVertices.push_back( ptTl) ; } vNeigh.clear() ; - vVertices.push_back( m_mTree[nId].GetBottomLeft()) ; + vVertices.push_back( m_mTree.at(nId).GetBottomLeft()) ; // se ho una cella con vicino dello stesso grado ( quindi il poligono ha solo 5 punti) controllo la curvatura nella cella e // se necessario cambio l'ordine dei vertici per scegliere la diagonale di split migliore if ( vVertices.size() == 5) { Point3d ptPSrf, ptP00, ptP10, ptP11, ptP01; double dU, dV ; - dU = ( m_mTree[nId].GetBottomLeft().x + m_mTree[nId].GetTopRight().x) / 2 ; - dV = ( m_mTree[nId].GetBottomLeft().y + m_mTree[nId].GetTopRight().y) / 2 ; + dU = ( m_mTree.at(nId).GetBottomLeft().x + m_mTree.at(nId).GetTopRight().x) / 2 ; + dV = ( m_mTree.at(nId).GetBottomLeft().y + m_mTree.at(nId).GetTopRight().y) / 2 ; m_pSrfBz->GetPointD1D2( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrf) ; - ptP00 = m_mVert[nId][0] ; - ptP10 = m_mVert[nId][1] ; - ptP11 = m_mVert[nId][2] ; - ptP01 = m_mVert[nId][3] ; + ptP00 = m_mVert.at(nId).at(0) ; + ptP10 = m_mVert.at(nId).at(1) ; + ptP11 = m_mVert.at(nId).at(2) ; + ptP01 = m_mVert.at(nId).at(3) ; Point3d ptP00P11 = ( ptP00 + ptP11) / 2 ; Point3d ptP10P01 = ( ptP10 + ptP01) / 2 ; // ho la curvatura maggiore sulla diagonale tra P10 e P01, ruoto l'ordine dei vertici, in modo che triangulate prenda la diagonale giusta if ( Dist(ptP00P11, ptPSrf) + EPS_SMALL > Dist(ptP10P01, ptPSrf)) { rotate(vVertices.begin(), vVertices.begin() + 1,vVertices.end()) ; - vVertices.back() = vVertices[0] ; + vVertices.back() = vVertices.at(0) ; } } m_vPolygons.emplace_back() ; for ( int i = 0 ; i < (int) vVertices.size() ; ++i) { - m_vPolygons.back().AddUPoint( i, vVertices[i]) ; + m_vPolygons.back().AddUPoint( i, vVertices.at(i)) ; } } } diff --git a/Tree.h b/Tree.h index 7ccbc33..751c21f 100644 --- a/Tree.h +++ b/Tree.h @@ -24,18 +24,18 @@ class Cell public : ~Cell( void) ; Cell( void) ; - Cell( Point3d ptBL, Point3d ptTR) ; - inline bool IsSame( Cell cOtherCell) const ; + Cell( Point3d& ptBL, Point3d& ptTR) ; + inline bool IsSame( const Cell& cOtherCell) const ; void SetBottomLeft( Point3d ptBL) { m_ptPbl = ptBL ; } void SetTopRight( Point3d ptTR) { m_ptPtr = ptTR ; } void SetSplitDirVert( bool bVert) { m_bSplitVert = bVert ; } - void SetParent(int nParent) { m_nParent = nParent ; } + void SetParent( int nParent) { m_nParent = nParent ; } Point3d GetBottomLeft( void) const { return m_ptPbl ; } Point3d GetTopRight( void) const { return m_ptPtr ; } double GetSplitValue( void) const { return m_dSplit ; } - bool IsSplitVert( void) const { return m_bSplitVert ; } - bool IsLeaf( void) const ; - bool IsProcessed( void) const { return m_bProcessed ; } + bool IsSplitVert( void) const { return m_bSplitVert ; } // se true la cella verrebbe splittata verticalmente, sennò orizzontalmente + bool IsLeaf( void) const ; // flag che indica se la cella ha figli o se è una foglia + bool IsProcessed( void) const { return m_bProcessed ; } // flag che indica se tutti i figli della cella, se ce ne sono, sono stati processati void Processed( void) { m_bProcessed = true ; } static bool minorX ( const Cell& c1, const Cell& c2) { return c1.m_ptPbl.x < c2.m_ptPbl.x ; } static bool minorY ( const Cell& c1, const Cell& c2) { return c1.m_ptPbl.y < c2.m_ptPbl.y ; } @@ -69,18 +69,19 @@ public : void SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches = true) ; bool BuildTree( double dLinTol = LIN_TOL_STD, double dSideMin = 5, 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 GetPolygons( POLYLINEVECTOR& vPolygons) ; + bool GetPolygons( 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 private : - void Split( int nId, double dSplitValue) ; // funzione di split di una cella al parametro indicato nella direzione data da bVert - void Split( int nId) ; // funzione di split di una cella dell'albero a metà nella direzione data da bVert - void Balance () ; // 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) ; // altezza del subtree a partire dal nodo nId - int GetDepth ( int nId, int nRef) ; // livello del nodo nId - void GetTopNeigh( int nId, INTVECTOR& vTopNeighs) ; // restituisce le celle foglie che sono adiacenti al lato top - void GetBottomNeigh( int nId, INTVECTOR& vBottomNeighs) ; // restituisce le celle foglie che sono adiacenti al lato bottom - void GetLeftNeigh( int nId, INTVECTOR& vLeftNeighs) ; // restituisce le celle foglie che sono adiacenti al lato left - void GetRightNeigh( int nId, INTVECTOR& vRightNeighs) ; // restituisce le celle foglie che sono adiacenti al lato right + void Split( int nId, double dSplitValue) ; // funzione di split di una cella al parametro indicato nella direzione data da bVert + void Split( int nId) ; // funzione di split di una cella dell'albero a metà nella direzione data da bVert + void Balance () ; // 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 + void GetBottomNeigh( int nId, INTVECTOR& vBottomNeighs) const ; // restituisce le celle foglie che sono adiacenti al lato bottom + void GetLeftNeigh( int nId, INTVECTOR& vLeftNeighs) const ; // restituisce le celle foglie che sono adiacenti al lato left + void GetRightNeigh( int nId, INTVECTOR& vRightNeighs) const ; // restituisce le celle foglie che sono adiacenti al lato right private : const SurfBezier* m_pSrfBz ; // superficie di bezier @@ -89,6 +90,8 @@ private : bool m_bBilinear ; // superficie bilineare bool m_bMulti ; // superficie multi-patch bool m_bClosed ; // superficie chiusa + int m_nDegU ; // grado della superficie nel parametro U + int m_nDegV ; // grado della superficie nel parametro V POLYLINEVECTOR m_vPolygons ; // vettore 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