diff --git a/SurfBezier.cpp b/SurfBezier.cpp index 39265ce..d454768 100644 --- a/SurfBezier.cpp +++ b/SurfBezier.cpp @@ -1582,8 +1582,10 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin) const PNTVECTOR vPnt ; INTVECTOR vTria ; Triangulate Tri ; - if ( ! Tri.Make( vPL, vPnt, vTria)) + if ( ! Tri.Make( vPL, vPnt, vTria)) { + LOG_DBG_ERR( GetEGkLogger(), "ERROR : Triangulation failed in Bezier Surface") ; return nullptr ; + } POLYLINEVECTOR vPL3d = vvPL3d[c] ; @@ -1612,14 +1614,15 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin) const if ( bTriangulationFailedIn2D) { PNTVECTOR vPntBackup = vPnt ; INTVECTOR vTriaBackup = vTria ; + bool bTriangulationSucceded = true ; if ( ! Tri.Make( vPL3d, vPnt, vTria)) - return nullptr ; - bool bTriangulationSucceded = ( vPnt.size() - 2) + (2 * (vPL.size() - 1)) - (vPL.size() > 2 ? vPL.size() - 2 : 0) - (vPL.size() != 1 ? vPL.size() : 0) == ( vTria.size() ) / 3 ; + bTriangulationSucceded = false ; + bTriangulationSucceded = bTriangulationSucceded && ( vPnt.size() - 2) + (2 * (vPL.size() - 1)) - (vPL.size() > 2 ? vPL.size() - 2 : 0) - (vPL.size() != 1 ? vPL.size() : 0) == ( vTria.size() ) / 3 ; if( bTriangulationFailedIn2D) { if ( bTriangulationSucceded) LOG_INFO( GetEGkLogger(), "Info : Last problem in MakeByEC23(1) RESOLVED") else - LOG_INFO( GetEGkLogger(), "Info : Last problem in MakeByEC23(1) is the same as the previous one") + LOG_INFO( GetEGkLogger(), "Info : This problem in MakeByEC23(1) is the same as the previous one") } if( bTriangulationSucceded) { bTriangulatedIn3D = true ; diff --git a/Tree.cpp b/Tree.cpp index 0273ea6..e84fe62 100644 --- a/Tree.cpp +++ b/Tree.cpp @@ -523,87 +523,90 @@ Tree::GetIndependentTrees( BIPNTVECTOR& vTrees) bool Tree::Split( int nId, double dSplitValue) { + Cell& cToSplit = m_mTree[nId] ; // 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)) { + if ( ( cToSplit.IsSplitVert() && dSplitValue > cToSplit.GetBottomLeft().x + EPS_SMALL && + dSplitValue < cToSplit.GetTopRight().x - EPS_SMALL) || + ( ! cToSplit.IsSplitVert() && dSplitValue > cToSplit.GetBottomLeft().y + EPS_SMALL && + dSplitValue < cToSplit.GetTopRight().y - EPS_SMALL)) { // quando si implementerà lo split a parametro libero bisognerà impedire che si facciano split troppo vicini al bordo della cella!!!!!!!!!!!!!!!!!!! - m_mTree[nId].m_dSplit = dSplitValue ; + cToSplit.m_dSplit = dSplitValue ; Cell cChild1, cChild2 ; - cChild1.m_nDepth = m_mTree[nId].m_nDepth + 1 ; - cChild2.m_nDepth = m_mTree[nId].m_nDepth + 1 ; + cChild1.m_nDepth = cToSplit.m_nDepth + 1 ; + cChild2.m_nDepth = cToSplit.m_nDepth + 1 ; int nNodes = (int) m_mTree.size() ; cChild1.m_nId = nNodes - 1 ; - m_mTree[nId].m_nChild1 = nNodes - 1 ; + cToSplit.m_nChild1 = nNodes - 1 ; cChild2.m_nId = nNodes ; - m_mTree[nId].m_nChild2 = nNodes ; - m_mTree.insert( pair( nNodes - 1, cChild1)) ; - m_mTree.insert( pair( nNodes, cChild2)) ; + cToSplit.m_nChild2 = nNodes ; Point3d ptVert1, ptVert2 ; - PNTVECTOR vVert ; - m_mVert.insert( pair( nNodes - 1, vVert)) ; - m_mVert.insert( pair( nNodes, vVert)) ; - if ( ! m_mTree[nId].IsSplitVert()) { + PNTVECTOR vVert1, vVert2 ; + if ( ! cToSplit.IsSplitVert()) { // la cella figlio 1 è quella sopra - Point3d ptBL( m_mTree[nId].GetBottomLeft().x, dSplitValue) ; - m_mTree[m_mTree[nId].m_nChild1].SetBottomLeft( ptBL) ; - m_mTree[m_mTree[nId].m_nChild1].SetTopRight( m_mTree[nId].GetTopRight()) ; - m_mTree[m_mTree[nId].m_nChild1].m_nTop = m_mTree[nId].m_nTop ; - m_mTree[m_mTree[nId].m_nChild1].m_nBottom = m_mTree[nId].m_nChild2 ; - m_mTree[m_mTree[nId].m_nChild1].m_nLeft = m_mTree[nId].m_nLeft ; - m_mTree[m_mTree[nId].m_nChild1].m_nRight = m_mTree[nId].m_nRight ; - Point3d ptTR( m_mTree[nId].GetTopRight().x, dSplitValue) ; - m_mTree[m_mTree[nId].m_nChild2].SetBottomLeft( m_mTree[nId].GetBottomLeft()) ; - m_mTree[m_mTree[nId].m_nChild2].SetTopRight( ptTR) ; - m_mTree[m_mTree[nId].m_nChild2].m_nTop = m_mTree[nId].m_nChild1 ; - m_mTree[m_mTree[nId].m_nChild2].m_nBottom = m_mTree[nId].m_nBottom ; - m_mTree[m_mTree[nId].m_nChild2].m_nLeft = m_mTree[nId].m_nLeft ; - m_mTree[m_mTree[nId].m_nChild2].m_nRight = m_mTree[nId].m_nRight ; + Point3d ptBL( cToSplit.GetBottomLeft().x, dSplitValue) ; + cChild1.SetBottomLeft( ptBL) ; + cChild1.SetTopRight( cToSplit.GetTopRight()) ; + cChild1.m_nTop = cToSplit.m_nTop ; + cChild1.m_nBottom = cToSplit.m_nChild2 ; + cChild1.m_nLeft = cToSplit.m_nLeft ; + cChild1.m_nRight = cToSplit.m_nRight ; + Point3d ptTR( cToSplit.GetTopRight().x, dSplitValue) ; + cChild2.SetBottomLeft( cToSplit.GetBottomLeft()) ; + cChild2.SetTopRight( ptTR) ; + cChild2.m_nTop = cToSplit.m_nChild1 ; + cChild2.m_nBottom = cToSplit.m_nBottom ; + cChild2.m_nLeft = cToSplit.m_nLeft ; + cChild2.m_nRight = cToSplit.m_nRight ; // metto i corrispondenti 3d dei punti dello split nella mappa m_mVert // per ogni cella i punti devono essere nell'ordine ptP00, ptP10, ptP11, ptP01 - m_pSrfBz->GetPointD1D2( m_mTree[nId].GetBottomLeft().x / SBZ_TREG_COEFF, dSplitValue / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptVert1) ; - m_pSrfBz->GetPointD1D2( m_mTree[nId].GetTopRight().x / SBZ_TREG_COEFF, dSplitValue / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptVert2) ; - m_mVert[nNodes - 1].push_back( ptVert1) ; - m_mVert[nNodes - 1].push_back( ptVert2) ; - m_mVert[nNodes - 1].push_back( m_mVert[nId][2]) ; - m_mVert[nNodes - 1].push_back( m_mVert[nId][3]) ; - m_mVert[nNodes].push_back( m_mVert[nId][0]) ; - m_mVert[nNodes].push_back( m_mVert[nId][1]) ; - m_mVert[nNodes].push_back( ptVert2) ; - m_mVert[nNodes].push_back( ptVert1) ; + m_pSrfBz->GetPointD1D2( cToSplit.GetBottomLeft().x / SBZ_TREG_COEFF, dSplitValue / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptVert1) ; + m_pSrfBz->GetPointD1D2( cToSplit.GetTopRight().x / SBZ_TREG_COEFF, dSplitValue / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptVert2) ; + vVert1.push_back( ptVert1) ; + vVert1.push_back( ptVert2) ; + vVert1.push_back( m_mVert[nId][2]) ; + vVert1.push_back( m_mVert[nId][3]) ; + vVert2.push_back( m_mVert[nId][0]) ; + vVert2.push_back( m_mVert[nId][1]) ; + vVert2.push_back( ptVert2) ; + vVert2.push_back( ptVert1) ; } else { // la cella figlio 1 è quella di sinistra - Point3d ptTR( dSplitValue, m_mTree[nId].GetTopRight().y) ; - m_mTree[m_mTree[nId].m_nChild1].SetBottomLeft( m_mTree[nId].GetBottomLeft()) ; - m_mTree[m_mTree[nId].m_nChild1].SetTopRight( ptTR) ; - m_mTree[m_mTree[nId].m_nChild1].m_nTop = m_mTree[nId].m_nTop ; - m_mTree[m_mTree[nId].m_nChild1].m_nBottom = m_mTree[nId].m_nBottom ; - m_mTree[m_mTree[nId].m_nChild1].m_nLeft = m_mTree[nId].m_nLeft ; - m_mTree[m_mTree[nId].m_nChild1].m_nRight = m_mTree[nId].m_nChild2 ; - Point3d ptBL( dSplitValue, m_mTree[nId].GetBottomLeft().y) ; - m_mTree[m_mTree[nId].m_nChild2].SetBottomLeft( ptBL) ; - m_mTree[m_mTree[nId].m_nChild2].SetTopRight( m_mTree[nId].GetTopRight()) ; - m_mTree[m_mTree[nId].m_nChild2].m_nTop = m_mTree[nId].m_nTop ; - m_mTree[m_mTree[nId].m_nChild2].m_nBottom = m_mTree[nId].m_nBottom ; - m_mTree[m_mTree[nId].m_nChild2].m_nLeft = m_mTree[nId].m_nChild1 ; - m_mTree[m_mTree[nId].m_nChild2].m_nRight = m_mTree[nId].m_nRight ; + Point3d ptTR( dSplitValue, cToSplit.GetTopRight().y) ; + cChild1.SetBottomLeft( cToSplit.GetBottomLeft()) ; + cChild1.SetTopRight( ptTR) ; + cChild1.m_nTop = cToSplit.m_nTop ; + cChild1.m_nBottom = cToSplit.m_nBottom ; + cChild1.m_nLeft = cToSplit.m_nLeft ; + cChild1.m_nRight = cToSplit.m_nChild2 ; + Point3d ptBL( dSplitValue, cToSplit.GetBottomLeft().y) ; + cChild2.SetBottomLeft( ptBL) ; + cChild2.SetTopRight( cToSplit.GetTopRight()) ; + cChild2.m_nTop = cToSplit.m_nTop ; + cChild2.m_nBottom = cToSplit.m_nBottom ; + cChild2.m_nLeft = cToSplit.m_nChild1 ; + cChild2.m_nRight = cToSplit.m_nRight ; // metto i corrispondenti 3d dei punti dello split nella mappa m_mVert // per ogni cella i punti devono essere nell'ordine ptP00, ptP10, ptP11, ptP01 - m_pSrfBz->GetPointD1D2( dSplitValue / SBZ_TREG_COEFF, m_mTree[nId].GetBottomLeft().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptVert2) ; - m_pSrfBz->GetPointD1D2( dSplitValue / SBZ_TREG_COEFF, m_mTree[nId].GetTopRight().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptVert1) ; - m_mVert[nNodes - 1].push_back( m_mVert[nId][0]) ; - m_mVert[nNodes - 1].push_back( ptVert2) ; - m_mVert[nNodes - 1].push_back( ptVert1) ; - m_mVert[nNodes - 1].push_back( m_mVert[nId][3]) ; - m_mVert[nNodes].push_back( ptVert2) ; - m_mVert[nNodes].push_back( m_mVert[nId][1]) ; - m_mVert[nNodes].push_back( m_mVert[nId][2]) ; - m_mVert[nNodes].push_back( ptVert1) ; + m_pSrfBz->GetPointD1D2( dSplitValue / SBZ_TREG_COEFF, cToSplit.GetBottomLeft().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptVert2) ; + m_pSrfBz->GetPointD1D2( dSplitValue / SBZ_TREG_COEFF, cToSplit.GetTopRight().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptVert1) ; + vVert1.push_back( m_mVert[nId][0]) ; + vVert1.push_back( ptVert2) ; + vVert1.push_back( ptVert1) ; + vVert1.push_back( m_mVert[nId][3]) ; + vVert2.push_back( ptVert2) ; + vVert2.push_back( m_mVert[nId][1]) ; + vVert2.push_back( m_mVert[nId][2]) ; + vVert2.push_back( ptVert1) ; } - m_mTree[m_mTree[nId].m_nChild1].SetParent( nId) ; - m_mTree[m_mTree[nId].m_nChild2].SetParent( nId) ; + cChild1.SetParent( nId) ; + cChild2.SetParent( nId) ; + // inserisco i vertici 3d + m_mVert.insert( pair( nNodes - 1, vVert1)) ; + m_mVert.insert( pair( nNodes, vVert2)) ; + // inserisco nell'albero + m_mTree.insert( pair( nNodes - 1, cChild1)) ; + m_mTree.insert( pair( nNodes, cChild2)) ; return true ; } return false ; @@ -692,26 +695,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] ; if ( ! m_bBilinear) { - while ( nCToSplit != -2 && m_mTree[nCToSplit].IsProcessed() == false) { + while ( nCToSplit != -2 && cToSplit->IsProcessed() == false) { // controllo che la cella non sia già stata preliminarmente splittata - if ( m_mTree[nCToSplit].IsLeaf()) { + if ( cToSplit->IsLeaf()) { // calcolo in quale direzione ho più curvatura // ptP00P10 è un punto tra P00 e P10 double dCurvU = 0, dCurvV = 0 ; - double dLenParU = ( m_mTree[nCToSplit].GetTopRight().x - m_mTree[nCToSplit].GetBottomLeft().x) / SBZ_TREG_COEFF ; - double dLenParV = ( m_mTree[nCToSplit].GetTopRight().y - m_mTree[nCToSplit].GetBottomLeft().y) / SBZ_TREG_COEFF ; + double dLenParU = ( cToSplit->GetTopRight().x - cToSplit->GetBottomLeft().x) / SBZ_TREG_COEFF ; + double dLenParV = ( cToSplit->GetTopRight().y - cToSplit->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 = ( m_mTree[nCToSplit].GetTopRight().x + m_mTree[nCToSplit].GetBottomLeft().x) / 2 / SBZ_TREG_COEFF ; - double dV = ( m_mTree[nCToSplit].GetTopRight().y + m_mTree[nCToSplit].GetBottomLeft().y) / 2 / SBZ_TREG_COEFF ; + 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 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 / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP00P10) ; - m_pSrfBz->GetPointD1D2( m_mTree[nCToSplit].GetTopRight().x / SBZ_TREG_COEFF, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP10P11) ; - m_pSrfBz->GetPointD1D2( dU, m_mTree[nCToSplit].GetTopRight().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP11P01) ; - m_pSrfBz->GetPointD1D2( m_mTree[nCToSplit].GetBottomLeft().x / SBZ_TREG_COEFF, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP01P00) ; + 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) ; Point3d ptV = ( 1 - dULoc) * ptP00P10 + dULoc * ptP11P01 ; Point3d ptU = ( 1 - dVLoc) * ptP10P11 + dVLoc * ptP01P00 ; dCurvV = Dist( ptV, ptPSrf) ; @@ -723,13 +727,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 * m_mTree[nCToSplit].GetTopRight().x + ( 1 - k) * m_mTree[nCToSplit].GetBottomLeft().x) / SBZ_TREG_COEFF ; - double dV = ( m_mTree[nCToSplit].GetTopRight().y + m_mTree[nCToSplit].GetBottomLeft().y) / 2 / SBZ_TREG_COEFF ; + 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 ; 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 / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP00P10) ; - m_pSrfBz->GetPointD1D2( dU, m_mTree[nCToSplit].GetTopRight().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP11P01) ; + 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) ; CurveLine clV ; clV.Set( ptP00P10, ptP11P01) ; DistPointCurve dpc( ptPSrf, clV) ; @@ -739,14 +743,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 = ( m_mTree[nCToSplit].GetTopRight().x + m_mTree[nCToSplit].GetBottomLeft().x) / 2 / SBZ_TREG_COEFF ; - double dV = ( k * m_mTree[nCToSplit].GetTopRight().y + ( 1 - k) * m_mTree[nCToSplit].GetBottomLeft().y) / SBZ_TREG_COEFF ; + 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 ; 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( m_mTree[nCToSplit].GetTopRight().x / SBZ_TREG_COEFF, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP10P11) ; - m_pSrfBz->GetPointD1D2( m_mTree[nCToSplit].GetBottomLeft().x / SBZ_TREG_COEFF, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP01P00) ; + 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) ; CurveLine clU ; clU.Set( ptP01P00, ptP10P11) ; DistPointCurve dpc( ptPSrf, clU) ; @@ -803,7 +807,7 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax) // lungo la direzione U ho una curvatura maggiore bVert = true ; } - m_mTree[nCToSplit].SetSplitDirVert( bVert) ; + cToSplit->SetSplitDirVert( bVert) ; //Point3d ptP00, ptP10, ptP11, ptP01 ; //ptP00 = m_mVert[nCToSplit][0] ; //ptP10 = m_mVert[nCToSplit][1] ; @@ -815,19 +819,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 = ( m_mTree[nCToSplit].GetBottomLeft().y + m_mTree[nCToSplit].GetTopRight().y) / 2 / SBZ_TREG_COEFF ; + double dV = ( cToSplit->GetBottomLeft().y + cToSplit->GetTopRight().y) / 2 / SBZ_TREG_COEFF ; PtrOwner pCrvV( m_pSrfBz->GetCurveOnU( dV)) ; double dLenU0, dLenU1 ; - pCrvV->GetLengthAtParam( m_mTree[nCToSplit].GetBottomLeft().x / SBZ_TREG_COEFF, dLenU0) ; - pCrvV->GetLengthAtParam( m_mTree[nCToSplit].GetTopRight().x / SBZ_TREG_COEFF, dLenU1) ; + pCrvV->GetLengthAtParam( cToSplit->GetBottomLeft().x / SBZ_TREG_COEFF, dLenU0) ; + pCrvV->GetLengthAtParam( cToSplit->GetTopRight().x / SBZ_TREG_COEFF, dLenU1) ; dLen0 = abs( dLenU1 - dLenU0) ; } if ( dLen1 < EPS_ZERO && dLen3 < EPS_ZERO ) { - double dU = ( m_mTree[nCToSplit].GetBottomLeft().x + m_mTree[nCToSplit].GetTopRight().x) / 2 / SBZ_TREG_COEFF ; + double dU = ( cToSplit->GetBottomLeft().x + cToSplit->GetTopRight().x) / 2 / SBZ_TREG_COEFF ; PtrOwner pCrvU( m_pSrfBz->GetCurveOnV( dU)) ; double dLenV0, dLenV1 ; - pCrvU->GetLengthAtParam( m_mTree[nCToSplit].GetBottomLeft().y / SBZ_TREG_COEFF, dLenV0) ; - pCrvU->GetLengthAtParam( m_mTree[nCToSplit].GetTopRight().y / SBZ_TREG_COEFF, dLenV1) ; + pCrvU->GetLengthAtParam( cToSplit->GetBottomLeft().y / SBZ_TREG_COEFF, dLenV0) ; + pCrvU->GetLengthAtParam( cToSplit->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 @@ -870,9 +874,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) * m_mTree[nCToSplit].GetBottomLeft().x + dU * m_mTree[nCToSplit].GetTopRight().x) / SBZ_TREG_COEFF ; - if ( ! m_pSrfBz->GetPointD1D2( dULoc, m_mTree[nCToSplit].GetBottomLeft().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBz0) || - ! m_pSrfBz->GetPointD1D2( dULoc, m_mTree[nCToSplit].GetTopRight().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBz1)) + 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)) 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) @@ -893,7 +897,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) * m_mTree[nCToSplit].GetBottomLeft().y + dV * m_mTree[nCToSplit].GetTopRight().y) / SBZ_TREG_COEFF ; + double dVLoc = ( ( 1 - dV) * cToSplit->GetBottomLeft().y + dV * cToSplit->GetTopRight().y) / SBZ_TREG_COEFF ; if ( ! m_pSrfBz->GetPointD1D2( dULoc, dVLoc, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBzV)) return false ; DistPointCurve dpc( ptBzV, clV) ; @@ -930,36 +934,42 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax) } if ( bSplit || dSideMaxVal > dSideMax) { - m_mTree[nCToSplit].SetSplitDirVert( bVert) ; + cToSplit->SetSplitDirVert( bVert) ; // effettuo lo split Split( nCToSplit) ; // procedo con lo split del Child1 - nCToSplit = m_mTree[nCToSplit].m_nChild1 ; + nCToSplit = cToSplit->m_nChild1 ; + cToSplit = &m_mTree[nCToSplit] ; } else { // sono arrivato ad una cella Leaf, quindi salvo la cella m_vnLeaves.push_back( nCToSplit) ; - m_mTree[nCToSplit].SetProcessed() ; + cToSplit->SetProcessed() ; // risalgo i parent finché non trovo il primo Child2 da processare - nCToSplit = m_mTree[nCToSplit].m_nParent ; + nCToSplit = cToSplit->m_nParent ; + cToSplit = &m_mTree[nCToSplit] ; if ( nCToSplit == -2) return true ; - if ( m_mTree[m_mTree[nCToSplit].m_nChild1].IsProcessed() && m_mTree[m_mTree[nCToSplit].m_nChild2].IsProcessed()) - m_mTree[nCToSplit].SetProcessed() ; - while ( m_mTree[m_mTree[nCToSplit].m_nChild2].IsProcessed()) { - if ( m_mTree[nCToSplit].m_nParent != -2) - nCToSplit = m_mTree[nCToSplit].m_nParent ; - if ( m_mTree[m_mTree[nCToSplit].m_nChild1].IsProcessed() && m_mTree[m_mTree[nCToSplit].m_nChild2].IsProcessed()) - m_mTree[nCToSplit].SetProcessed() ; - if ( nCToSplit == -1 && m_mTree[m_mTree[nCToSplit].m_nChild2].IsProcessed()) + 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[cToSplit->m_nChild1].IsProcessed() && m_mTree[cToSplit->m_nChild2].IsProcessed()) + cToSplit->SetProcessed() ; + if ( nCToSplit == -1 && m_mTree[cToSplit->m_nChild2].IsProcessed()) break ; } - nCToSplit = m_mTree[nCToSplit].m_nChild2 ; + nCToSplit = cToSplit->m_nChild2 ; + cToSplit = &m_mTree[nCToSplit] ; } } else { - nCToSplit = m_mTree[nCToSplit].m_nChild1 ; + nCToSplit = cToSplit->m_nChild1 ; + cToSplit = &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à @@ -967,9 +977,8 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax) // bilineare else { bool bIsPlanar = m_pSrfBz->IsPlanar() ; - - while ( nCToSplit != -2 && m_mTree[nCToSplit].IsProcessed() == false) { - if ( m_mTree[nCToSplit].IsLeaf()) { + while ( nCToSplit != -2 && cToSplit->IsProcessed() == false) { + if ( cToSplit->IsLeaf()) { // vertici della cella Point3d ptP00, ptP10, ptP11, ptP01 ; ptP00 = m_mVert[nCToSplit][0] ; @@ -993,10 +1002,10 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax) } else { 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) / SBZ_TREG_COEFF ; - dV = ( ( 1 - i) * m_mTree[nCToSplit].GetBottomLeft().y + i * m_mTree[nCToSplit].GetTopRight().y) / SBZ_TREG_COEFF ; - double dVLoc = ( m_mTree[nCToSplit].GetBottomLeft().y + m_mTree[nCToSplit].GetTopRight().y) / 2 / SBZ_TREG_COEFF ; - double dULoc = ( m_mTree[nCToSplit].GetBottomLeft().x + m_mTree[nCToSplit].GetTopRight().x) / 2 / SBZ_TREG_COEFF ; + 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 ; 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) ; @@ -1037,8 +1046,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) * m_mTree[nCToSplit].GetTopRight().x + i * m_mTree[nCToSplit].GetBottomLeft().x) / SBZ_TREG_COEFF ; - double dV = ( ( 1 - j) * m_mTree[nCToSplit].GetTopRight().y + j * m_mTree[nCToSplit].GetBottomLeft().y) / SBZ_TREG_COEFF ; + 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 ; m_pSrfBz->GetPointD1D2( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrf) ; dErr = max( abs( DistPointPlane( ptPSrf, plAppr)), dErr) ; } @@ -1050,36 +1059,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) { - m_mTree[nCToSplit].SetSplitDirVert( bVert) ; + cToSplit->SetSplitDirVert( bVert) ; // effettuo lo split Split( nCToSplit) ; // procedo con lo split del Child1 - nCToSplit = m_mTree[nCToSplit].m_nChild1 ; + nCToSplit = cToSplit->m_nChild1 ; + cToSplit = &m_mTree[nCToSplit] ; } else { // sono arrivato ad una cella Leaf, quindi salvo la cella m_vnLeaves.push_back( nCToSplit) ; - m_mTree[nCToSplit].SetProcessed() ; + cToSplit->SetProcessed() ; // risalgo i parent finché non trovo il primo Child2 da processare - nCToSplit = m_mTree[nCToSplit].m_nParent ; + nCToSplit = cToSplit->m_nParent ; + cToSplit = &m_mTree[nCToSplit] ; if ( nCToSplit == -2) return true ; - if ( m_mTree[m_mTree[nCToSplit].m_nChild1].IsProcessed() && m_mTree[m_mTree[nCToSplit].m_nChild2].IsProcessed()) - m_mTree[nCToSplit].SetProcessed() ; - while ( m_mTree[m_mTree[nCToSplit].m_nChild2].IsProcessed()) { - if ( m_mTree[nCToSplit].m_nParent != -2) - nCToSplit = m_mTree[nCToSplit].m_nParent ; - if ( m_mTree[m_mTree[nCToSplit].m_nChild1].IsProcessed() && m_mTree[m_mTree[nCToSplit].m_nChild2].IsProcessed()) - m_mTree[nCToSplit].SetProcessed() ; - if ( nCToSplit == -1 && m_mTree[m_mTree[nCToSplit].m_nChild2].IsProcessed()) + 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[cToSplit->m_nChild1].IsProcessed() && m_mTree[cToSplit->m_nChild2].IsProcessed()) + cToSplit->SetProcessed() ; + if ( nCToSplit == -1 && m_mTree[cToSplit->m_nChild2].IsProcessed()) break ; } - nCToSplit = m_mTree[nCToSplit].m_nChild2 ; + nCToSplit = cToSplit->m_nChild2 ; + cToSplit = &m_mTree[nCToSplit] ; } } else { - nCToSplit = m_mTree[nCToSplit].m_nChild1 ; + nCToSplit = cToSplit->m_nChild1 ; + cToSplit = &m_mTree[nCToSplit] ; } } } @@ -1103,31 +1118,32 @@ Tree::Balance() void Tree::GetTopNeigh( int nId, INTVECTOR& vTopNeighs) const { + const Cell& cell = m_mTree.at( nId) ; // le celle restituite sono ordinate per x crescente if ( vTopNeighs.empty()) { - if ( m_mTree.at( nId).m_nTop == -2) + if ( cell.m_nTop == -2) return ; - if ( m_mTree.at( m_mTree.at( nId).m_nTop).IsLeaf()) - vTopNeighs.push_back( m_mTree.at( nId).m_nTop) ; + if ( m_mTree.at( cell.m_nTop).IsLeaf()) + vTopNeighs.push_back( cell.m_nTop) ; else { - if ( m_mTree.at( m_mTree.at( nId).m_nTop).IsSplitVert()) { + if ( m_mTree.at( cell.m_nTop).IsSplitVert()) { // se la cella vicina è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima - 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) ; + if ( m_mTree.at( cell.m_nTop).GetTopRight().x - m_mTree.at( cell.m_nTop).GetBottomLeft().x <= + cell.GetTopRight().x - cell.GetBottomLeft().x) { + vTopNeighs.push_back( m_mTree.at( cell.m_nTop).m_nChild1) ; + vTopNeighs.push_back( m_mTree.at( cell.m_nTop).m_nChild2) ; } // altrimenti solo uno dei figli lo sarà else { - 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) ; + if ( m_mTree.at( m_mTree.at( cell.m_nTop).m_nChild1).GetTopRight().x <= cell.GetBottomLeft().x || + m_mTree.at( m_mTree.at( cell.m_nTop).m_nChild1).GetBottomLeft().x >= cell.GetTopRight().x ) + vTopNeighs.push_back( m_mTree.at( cell.m_nTop).m_nChild2) ; else - vTopNeighs.push_back( m_mTree.at( m_mTree.at( nId).m_nTop).m_nChild1) ; + vTopNeighs.push_back( m_mTree.at( cell.m_nTop).m_nChild1) ; } } else { - vTopNeighs.push_back( m_mTree.at( m_mTree.at( nId).m_nTop).m_nChild2) ; + vTopNeighs.push_back( m_mTree.at( cell.m_nTop).m_nChild2) ; } } bool bAllLeaves = true ; @@ -1151,14 +1167,14 @@ Tree::GetTopNeigh( int nId, INTVECTOR& vTopNeighs) const 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.at( i).GetTopRight().x - m_mTree.at( i).GetBottomLeft().x <= - m_mTree.at( nId).GetTopRight().x - m_mTree.at( nId).GetBottomLeft().x) { + cell.GetTopRight().x - cell.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.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 ) + if ( m_mTree.at( m_mTree.at( i).m_nChild1).GetTopRight().x <= cell.GetBottomLeft().x || + m_mTree.at( m_mTree.at( i).m_nChild1).GetBottomLeft().x >= cell.GetTopRight().x ) vTopNeighs.push_back( m_mTree.at( i).m_nChild2) ; else vTopNeighs.push_back( m_mTree.at( i).m_nChild1) ; @@ -1185,31 +1201,32 @@ Tree::GetTopNeigh( int nId, INTVECTOR& vTopNeighs) const void Tree::GetBottomNeigh( int nId, INTVECTOR& vBottomNeighs) const { + const Cell& cell = m_mTree.at( nId) ; // le celle restituite sono ordinate per x crescente if ( vBottomNeighs.empty()) { - if ( m_mTree.at( nId).m_nBottom == -2) + if ( cell.m_nBottom == -2) return ; - if ( m_mTree.at( m_mTree.at( nId).m_nBottom).IsLeaf()) - vBottomNeighs.push_back( m_mTree.at( nId).m_nBottom) ; + if ( m_mTree.at( cell.m_nBottom).IsLeaf()) + vBottomNeighs.push_back( cell.m_nBottom) ; else { - if ( m_mTree.at( m_mTree.at( nId).m_nBottom).IsSplitVert()) { + if ( m_mTree.at( cell.m_nBottom).IsSplitVert()) { // se la cella vicina è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima - 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) ; + if ( m_mTree.at( cell.m_nBottom).GetTopRight().x - m_mTree.at( cell.m_nBottom).GetBottomLeft().x <= + cell.GetTopRight().x - cell.GetBottomLeft().x) { + vBottomNeighs.push_back( m_mTree.at( cell.m_nBottom).m_nChild1) ; + vBottomNeighs.push_back( m_mTree.at( cell.m_nBottom).m_nChild2) ; } // altrimenti solo uno dei figli lo sarà else{ - 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) ; + if ( m_mTree.at( m_mTree.at( cell.m_nBottom).m_nChild1).GetTopRight().x <= cell.GetBottomLeft().x || + m_mTree.at( m_mTree.at( cell.m_nBottom).m_nChild1).GetBottomLeft().x >= cell.GetTopRight().x ) + vBottomNeighs.push_back( m_mTree.at( cell.m_nBottom).m_nChild2) ; else - vBottomNeighs.push_back( m_mTree.at( m_mTree.at( nId).m_nBottom).m_nChild1) ; + vBottomNeighs.push_back( m_mTree.at( cell.m_nBottom).m_nChild1) ; } } else { - vBottomNeighs.push_back( m_mTree.at( m_mTree.at( nId).m_nBottom).m_nChild1) ; + vBottomNeighs.push_back( m_mTree.at( cell.m_nBottom).m_nChild1) ; } } bool bAllLeaves = true ; @@ -1233,14 +1250,14 @@ Tree::GetBottomNeigh( int nId, INTVECTOR& vBottomNeighs) const 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.at( i).GetTopRight().x - m_mTree.at( i).GetBottomLeft().x <= - m_mTree.at( nId).GetTopRight().x - m_mTree.at( nId).GetBottomLeft().x) { + cell.GetTopRight().x - cell.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.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) + if ( m_mTree.at( m_mTree.at( i).m_nChild1).GetTopRight().x <= cell.GetBottomLeft().x || + m_mTree.at( m_mTree.at( i).m_nChild1).GetBottomLeft().x >= cell.GetTopRight().x) vBottomNeighs.push_back( m_mTree.at( i).m_nChild2) ; else vBottomNeighs.push_back( m_mTree.at( i).m_nChild1) ; @@ -1266,31 +1283,32 @@ Tree::GetBottomNeigh( int nId, INTVECTOR& vBottomNeighs) const void Tree::GetLeftNeigh( int nId, INTVECTOR& vLeftNeighs) const { + const Cell& cell = m_mTree.at( nId) ; // le celle restituite sono ordinate per y crescente if ( vLeftNeighs.empty()) { - if ( m_mTree.at( nId).m_nLeft == -2) + if ( cell.m_nLeft == -2) return ; - if ( m_mTree.at( m_mTree.at( nId).m_nLeft).IsLeaf()) - vLeftNeighs.push_back( m_mTree.at( nId).m_nLeft) ; + if ( m_mTree.at( cell.m_nLeft).IsLeaf()) + vLeftNeighs.push_back( cell.m_nLeft) ; else { - if ( ! m_mTree.at( m_mTree.at( nId).m_nLeft).IsSplitVert()) { + if ( ! m_mTree.at( cell.m_nLeft).IsSplitVert()) { // se la cella vicina è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima - 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) ; + if ( m_mTree.at( cell.m_nLeft).GetTopRight().y - m_mTree.at( cell.m_nLeft).GetBottomLeft().y <= + cell.GetTopRight().y - cell.GetBottomLeft().y) { + vLeftNeighs.push_back( m_mTree.at( cell.m_nLeft).m_nChild1) ; + vLeftNeighs.push_back( m_mTree.at( cell.m_nLeft).m_nChild2) ; } // altrimenti solo uno dei figli lo sarà else{ - 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) ; + if ( m_mTree.at( m_mTree.at( cell.m_nLeft).m_nChild1).GetTopRight().y <= cell.GetBottomLeft().y || + m_mTree.at( m_mTree.at( cell.m_nLeft).m_nChild1).GetBottomLeft().y >= cell.GetTopRight().y) + vLeftNeighs.push_back( m_mTree.at( cell.m_nLeft).m_nChild2) ; else - vLeftNeighs.push_back( m_mTree.at( m_mTree.at( nId).m_nLeft).m_nChild1) ; + vLeftNeighs.push_back( m_mTree.at( cell.m_nLeft).m_nChild1) ; } } else { - vLeftNeighs.push_back( m_mTree.at( m_mTree.at( nId).m_nLeft).m_nChild2) ; + vLeftNeighs.push_back( m_mTree.at( cell.m_nLeft).m_nChild2) ; } } bool bAllLeaves = true ; @@ -1314,14 +1332,14 @@ Tree::GetLeftNeigh( int nId, INTVECTOR& vLeftNeighs) const 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.at( i).GetTopRight().y - m_mTree.at( i).GetBottomLeft().y <= - m_mTree.at( nId).GetTopRight().y - m_mTree.at( nId).GetBottomLeft().y) { + cell.GetTopRight().y - cell.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.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) + if ( m_mTree.at( m_mTree.at( i).m_nChild1).GetTopRight().y <= cell.GetBottomLeft().y || + m_mTree.at( m_mTree.at( i).m_nChild1).GetBottomLeft().y >= cell.GetTopRight().y) vLeftNeighs.push_back( m_mTree.at( i).m_nChild2) ; else vLeftNeighs.push_back( m_mTree.at( i).m_nChild1) ; @@ -1347,31 +1365,32 @@ Tree::GetLeftNeigh( int nId, INTVECTOR& vLeftNeighs) const void Tree::GetRightNeigh( int nId, INTVECTOR& vRightNeighs) const { + const Cell& cell = m_mTree.at( nId) ; // le celle restituite sono ordinate per y crescente if ( vRightNeighs.empty()) { - if ( m_mTree.at( nId).m_nRight == -2) + if ( cell.m_nRight == -2) return ; - if ( m_mTree.at( m_mTree.at( nId).m_nRight).IsLeaf()) - vRightNeighs.push_back( m_mTree.at( nId).m_nRight) ; + if ( m_mTree.at( cell.m_nRight).IsLeaf()) + vRightNeighs.push_back( cell.m_nRight) ; else { - if ( ! m_mTree.at( m_mTree.at( nId).m_nRight).IsSplitVert()) { + if ( ! m_mTree.at( cell.m_nRight).IsSplitVert()) { // se la cella vicina è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima - 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) ; + if ( m_mTree.at( cell.m_nRight).GetTopRight().y - m_mTree.at( cell.m_nRight).GetBottomLeft().y <= + cell.GetTopRight().y - cell.GetBottomLeft().y) { + vRightNeighs.push_back( m_mTree.at( cell.m_nRight).m_nChild1) ; + vRightNeighs.push_back( m_mTree.at( cell.m_nRight).m_nChild2) ; } // altrimenti solo uno dei figli lo sarà else{ - 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) ; + if ( m_mTree.at( m_mTree.at( cell.m_nRight).m_nChild1).GetTopRight().y <= cell.GetBottomLeft().y || + m_mTree.at( m_mTree.at( cell.m_nRight).m_nChild1).GetBottomLeft().y >= cell.GetTopRight().y) + vRightNeighs.push_back( m_mTree.at( cell.m_nRight).m_nChild2) ; else - vRightNeighs.push_back( m_mTree.at( m_mTree.at( nId).m_nRight).m_nChild1) ; + vRightNeighs.push_back( m_mTree.at( cell.m_nRight).m_nChild1) ; } } else { - vRightNeighs.push_back( m_mTree.at( m_mTree.at( nId).m_nRight).m_nChild1) ; + vRightNeighs.push_back( m_mTree.at( cell.m_nRight).m_nChild1) ; } } bool bAllLeaves = true ; @@ -1395,14 +1414,14 @@ Tree::GetRightNeigh( int nId, INTVECTOR& vRightNeighs) const 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.at( i).GetTopRight().y - m_mTree.at( i).GetBottomLeft().y <= - m_mTree.at( nId).GetTopRight().y - m_mTree.at( nId).GetBottomLeft().y) { + cell.GetTopRight().y - cell.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.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) + if ( m_mTree.at( m_mTree.at( i).m_nChild1).GetTopRight().y <= cell.GetBottomLeft().y || + m_mTree.at( m_mTree.at( i).m_nChild1).GetBottomLeft().y >= cell.GetTopRight().y) vRightNeighs.push_back( m_mTree.at( i).m_nChild2) ; else vRightNeighs.push_back( m_mTree.at( i).m_nChild1) ; @@ -1712,10 +1731,11 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon // che sono sui lati della cella corrente // N.B. :i poligoni sono costruiti a partire dal ptBL !!! for ( int nId : vCells) { + Cell& cell = m_mTree.at( nId) ; vVertices.clear() ; vVertices3d.clear() ; vNeigh.clear() ; - vVertices.push_back( m_mTree.at( nId).GetBottomLeft()) ; + vVertices.push_back( cell.GetBottomLeft()) ; vVertices3d.push_back( m_mVert.at( nId)[0]) ; INTVECTOR vnVert ; BOOLVECTOR vbBonusVert(4) ; @@ -1728,7 +1748,7 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon // devo aggiungere i vertici tenendo conto della periodicità dello spazio parametrico. if ( m_bClosedV && m_mTree.at(vNeigh[0]).m_bOnTopEdge) { for ( int j : vNeigh) { - Point3d pt( m_mTree.at( j).GetTopRight().x, m_mTree.at( nId).GetBottomLeft().y) ; + Point3d pt( m_mTree.at( j).GetTopRight().x, cell.GetBottomLeft().y) ; vVertices.push_back( pt) ; vVertices3d.push_back( m_mVert[j][2]) ; } @@ -1753,7 +1773,7 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon vnVert.push_back( int(vVertices.size())) ; if ( m_bClosedU && m_mTree.at( vNeigh[0]).m_bOnLeftEdge ) { for ( int j : vNeigh) { - Point3d pt( m_mTree.at( nId).GetTopRight().x, m_mTree.at(j).GetBottomLeft().y) ; + Point3d pt( cell.GetTopRight().x, m_mTree.at(j).GetBottomLeft().y) ; vVertices.push_back( pt) ; vVertices3d.push_back( m_mVert[j][0]) ; } @@ -1768,13 +1788,13 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon } // se non l'ho già aggiunto tramite i vicini bottom aggiungo il punto bottom right else if ( ! bBottomRight) { - Point3d ptBr( m_mTree.at( nId).GetTopRight().x, m_mTree.at( nId).GetBottomLeft().y) ; + Point3d ptBr( cell.GetTopRight().x, cell.GetBottomLeft().y) ; vVertices.push_back( ptBr) ; vVertices3d.push_back( m_mVert[nId][1]) ; vnVert.push_back( int(vVertices.size()) - 1) ; } vNeigh.clear() ; - vVertices.push_back( m_mTree.at( nId).GetTopRight()) ; + vVertices.push_back( cell.GetTopRight()) ; vVertices3d.push_back( m_mVert[nId][2]) ; vnVert.push_back( int(vVertices.size()) - 1) ; GetTopNeigh ( nId, vNeigh) ; @@ -1784,9 +1804,9 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon // se la superficie è chiusa lungo il parametro V e la cella è sul lato top // devo aggiungere i vertici tenendo conto della periodicità dello spazio parametrico. vnVert.push_back( int(vVertices.size())) ; - if ( m_bClosedV && m_mTree.at( nId).m_bOnTopEdge) { + if ( m_bClosedV && cell.m_bOnTopEdge) { for ( int j : vNeigh) { - Point3d pt( m_mTree.at( j).GetBottomLeft().x, m_mTree.at( nId).GetTopRight().y) ; + Point3d pt( m_mTree.at( j).GetBottomLeft().x, cell.GetTopRight().y) ; vVertices.push_back( pt) ; vVertices3d.push_back( m_mVert[j][0]) ; } @@ -1810,9 +1830,9 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon // se la superficie è chiusa lungo il parametro U e la cella è sul lato left // devo aggiungere i vertici tenendo conto della periodicità dello spazio parametrico. vnVert.push_back( int(vVertices.size())) ; - if ( m_bClosedU && m_mTree.at( nId).m_bOnLeftEdge) { + if ( m_bClosedU && cell.m_bOnLeftEdge) { for ( int j : vNeigh) { - Point3d pt( m_mTree.at( nId).GetBottomLeft().x, m_mTree.at(j).GetTopRight().y) ; + Point3d pt( cell.GetBottomLeft().x, m_mTree.at(j).GetTopRight().y) ; vVertices.push_back( pt) ; vVertices3d.push_back( m_mVert[j][2]) ; } @@ -1827,13 +1847,13 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon } // se non l'ho già aggiunto tramite i vicini top aggiungo il punto top left else if ( ! bTopLeft) { - Point3d ptTl( m_mTree.at( nId).GetBottomLeft().x, m_mTree.at( nId).GetTopRight().y) ; + Point3d ptTl( cell.GetBottomLeft().x, cell.GetTopRight().y) ; vVertices.push_back( ptTl) ; vVertices3d.push_back( m_mVert[nId][3]) ; vnVert.push_back( int(vVertices.size()) - 1) ; } vNeigh.clear() ; - vVertices.push_back( m_mTree.at( nId).GetBottomLeft()) ; + vVertices.push_back( cell.GetBottomLeft()) ; vVertices3d.push_back( m_mVert[nId][0]) ; vnVert.push_back( int(vVertices.size()) - 1) ; @@ -1854,7 +1874,7 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon vVertices3d.erase(vVertices3d.begin() + vnVert[1]) ; } vbKeepPoint[vnVert[1]] = false ; - m_mTree[nId].m_nVertToErase = 1 ; // ptBr + cell.m_nVertToErase = 1 ; // ptBr } else if ( ! vbBonusVert[1] && vbBonusVert[3] ) { if ( ! m_bTrimmed) { @@ -1866,13 +1886,13 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon } vbKeepPoint[0] = false ; vbKeepPoint.back() = false ; - m_mTree[nId].m_nVertToErase = 0 ; // ptBL + cell.m_nVertToErase = 0 ; // ptBL } // se non ho bonus su nessuno dei due else { // ne scelgo uno dei due da togliere vbKeepPoint[vnVert[1]] = false ; - m_mTree[nId].m_nVertToErase = 1 ; // ptBr + cell.m_nVertToErase = 1 ; // ptBr } } if ( AreSamePointApprox(m_mVert.at(nId).at(1), m_mVert.at(nId).at(2))) { @@ -1883,7 +1903,7 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon vVertices3d.erase(vVertices3d.begin() + vnVert[1]) ; } vbKeepPoint[vnVert[1]] = false ; - m_mTree[nId].m_nVertToErase = 1 ; // ptBr + cell.m_nVertToErase = 1 ; // ptBr } else if ( ! vbBonusVert[0] && vbBonusVert[2] ){ if ( ! m_bTrimmed) { @@ -1891,13 +1911,13 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon vVertices3d.erase(vVertices3d.begin() + vnVert[2]) ; } vbKeepPoint[vnVert[2]] = false ; - m_mTree[nId].m_nVertToErase = 2 ; // ptTR + cell.m_nVertToErase = 2 ; // ptTR } // se non ho bonus su nessuno dei due else { // ne scelgo uno dei due da togliere vbKeepPoint[vnVert[2]] = false ; - m_mTree[nId].m_nVertToErase = 2 ; // ptTR + cell.m_nVertToErase = 2 ; // ptTR } } if ( AreSamePointApprox(m_mVert.at(nId).at(2), m_mVert.at(nId).at(3))) { @@ -1908,7 +1928,7 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon vVertices3d.erase(vVertices3d.begin() + vnVert[2]) ; } vbKeepPoint[vnVert[2]] = false ; - m_mTree[nId].m_nVertToErase = 2 ; // ptTR + cell.m_nVertToErase = 2 ; // ptTR } else if ( ! vbBonusVert[1] && vbBonusVert[3]) { if ( ! m_bTrimmed) { @@ -1916,13 +1936,13 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon vVertices3d.erase(vVertices3d.begin() + vnVert[3]) ; } vbKeepPoint[vnVert[3]] = false ; - m_mTree[nId].m_nVertToErase = 3 ; // ptTl + cell.m_nVertToErase = 3 ; // ptTl } // se non ho bonus su nessuno dei due else { // ne scelgo uno dei due da togliere vbKeepPoint[vnVert[3]] = false ; - m_mTree[nId].m_nVertToErase = 3 ; // ptTl + cell.m_nVertToErase = 3 ; // ptTl } } if ( AreSamePointApprox(m_mVert.at(nId).at(3), m_mVert.at(nId).at(0))) { @@ -1937,7 +1957,7 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon } vbKeepPoint[0] = false ; vbKeepPoint.back() = false ; - m_mTree[nId].m_nVertToErase = 0 ; // ptBL + cell.m_nVertToErase = 0 ; // ptBL } else if ( ! vbBonusVert[0] && vbBonusVert[2]) { if ( ! m_bTrimmed) { @@ -1945,13 +1965,13 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon vVertices3d.erase(vVertices3d.begin() + vnVert[3]) ; } vbKeepPoint[vnVert[3]] = false ; - m_mTree[nId].m_nVertToErase = 3 ; // ptTl + cell.m_nVertToErase = 3 ; // ptTl } // se non ho bonus su nessuno dei due else { // ne scelgo uno dei due da togliere vbKeepPoint[vnVert[3]] = false ; - m_mTree[nId].m_nVertToErase = 3 ; // ptTl + cell.m_nVertToErase = 3 ; // ptTl } } } @@ -1962,8 +1982,8 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon if ( vVertices.size() == 5 && ( ! bForTriangulation || (bForTriangulation && vVerticesCorr.size() == 5))) { Point3d ptPSrf, ptP00, ptP10, ptP11, ptP01 ; double dU, dV ; - dU = ( m_mTree.at( nId).GetBottomLeft().x + m_mTree.at( nId).GetTopRight().x) / 2 / SBZ_TREG_COEFF ; - dV = ( m_mTree.at( nId).GetBottomLeft().y + m_mTree.at( nId).GetTopRight().y) / 2 / SBZ_TREG_COEFF ; + dU = ( cell.GetBottomLeft().x + cell.GetTopRight().x) / 2 / SBZ_TREG_COEFF ; + dV = ( cell.GetBottomLeft().y + cell.GetTopRight().y) / 2 / SBZ_TREG_COEFF ; m_pSrfBz->GetPointD1D2( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrf) ; ptP00 = m_mVert.at( nId).at( 0) ; ptP10 = m_mVert.at( nId).at( 1) ; @@ -3129,8 +3149,10 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX // se ho trovato un altro loop salto all'inizio del for, dopo aver aggiunto eventuali punti intermedi 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], m_mTree[nId].m_vInters[vToCheckNow[nNext]].vpt[0]) && + CheckIfBefore( nEdge, ptLast, vEdgeVertex[nEdge][p])) { plTrimmedPoly.AddUPoint( c, vEdgeVertex[nEdge][p]) ; plTrimmedPoly3d.AddUPoint( c, vEdgeVertex3d[nEdge][p]) ; ++ c ; diff --git a/Tree.h b/Tree.h index fd8b8a1..e2d5adc 100644 --- a/Tree.h +++ b/Tree.h @@ -197,7 +197,7 @@ class Cell { 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 ; } - + public : int m_nId ; // Id della cella int m_nTop ; // cella adiacente al lato top @@ -305,7 +305,7 @@ class Tree DBLVECTOR m_vDim ; // distanze tra i vertici della superficie di bezier in 3d in ordine antiorario a partire da ptP00 bool m_bTrimmed ; // superficie trimmata //INTMATRIX m_vChunk ; // elenco dei loop divisi per chunk - std::map m_mChunk ; // mappa in cui vengono salvati chunk di appartenza per ogni loop di trim + std::unordered_map m_mChunk ; // mappa in cui vengono salvati chunk di appartenza per ogni loop di trim //ICURVEPOVECTOR m_vLoop ; // curve di loop std::vector> m_vPlApprox ; // vettore contenente le approssimazioni dei loop // il bool indica se la curva è CCW bool m_bBilinear ; // superficie bilineare