From ebda605497a9415c06a8a38ead3f359b141641ac Mon Sep 17 00:00:00 2001 From: Daniele Bariletti Date: Mon, 19 Jun 2023 08:50:47 +0200 Subject: [PATCH] EgftGeomKernel : - sistemati i bug noti - pulito il codice Da aggiungere : - calcolo del tree solo nelle bbox delle curve di trim --- Tree.cpp | 668 +++++++++++++++++++++++++++---------------------------- Tree.h | 7 +- 2 files changed, 336 insertions(+), 339 deletions(-) diff --git a/Tree.cpp b/Tree.cpp index c4022ed..6017b2e 100644 --- a/Tree.cpp +++ b/Tree.cpp @@ -115,19 +115,46 @@ Tree::SetSurf( const SurfBezier* pSrfBz, const bool bSplitPatches) // recupero la superficie di trim per avere accesso diretto ai loop e mantenendo le informazioni sui chunk Frame3d frSurf ; PtrOwner pTrimReg( m_pSrfBz->GetTrimRegion()->Clone()) ; + double dLinTol = 0.01 ; // questo è riferito allo spazio parametrico perché le curve di loop sono già state riscalate!!!!!! + double dAngTolDeg = 5 ; for ( int i = 0 ; i < pTrimReg->GetChunkCount() ; ++ i) { PtrOwner pChunk( pTrimReg->CloneChunk( i)) ; for ( int j = 0 ; j < pChunk->GetLoopCount( 0) ; ++ j) { vChunk.push_back( nLoop) ; - // i chunk della superficie orignale non possono avere dei sub chunk + // i chunk della falt region sono ancora flat region composte da 1 chunk PtrOwner pLoop ( pChunk->GetLoop( 0, j)) ; + PtrOwner pCrv( pLoop->Clone()) ; m_vLoop.emplace_back( Release( pLoop)) ; m_mChunk[nLoop] = i ; ++ nLoop ; + // approssimo i loop di trim con delle spezzate + PolyLine plApprox ; + int nType = 0 ; + pCrv->ApproxWithLines( dLinTol,dAngTolDeg, nType, plApprox) ; + // calcolo se il loop è CCW o CW + double dArea ; + Plane3d plExtPlane ; + bool bCCW ; + plApprox.IsClosedAndFlat( plExtPlane, dArea, 50 * EPS_SMALL) ; + if ( plExtPlane.GetVersN().z > 0) + bCCW = true ; + else + bCCW = false ; + m_vPlApprox.push_back( std::tuple(plApprox,bCCW)) ; } + // li riordino dal più grande al più piccolo + std::sort(vChunk.begin(), vChunk.end(), [this]( const int& a, const int& b) { double dArea1, dArea2 ; + m_vLoop[a]->GetAreaXY( dArea1) ; + m_vLoop[b]->GetAreaXY( dArea2) ; + return dArea1 > dArea2 ;}) ; m_vChunk.push_back( vChunk) ; vChunk.clear() ; } + // li riordino dal più grande al più piccolo + std::sort(m_vChunk.begin(), m_vChunk.end(), [this]( const INTVECTOR& a, const INTVECTOR& b) { double dArea1, dArea2 ; + m_vLoop[a[0]]->GetAreaXY( dArea1) ; + m_vLoop[b[0]]->GetAreaXY( dArea2) ; + return dArea1 > dArea2 ;}) ; } // salvo i vertici 3d della cella root Point3d ptBottom ( 0, 0) ; @@ -350,7 +377,7 @@ Tree::Split( const int& nId) //---------------------------------------------------------------------------- bool -Tree::BuildTree_test( double dLinTol_, double dSideMin, double dSideMax) +Tree::BuildTree_test( const double& dLinTol, const double& dSideMin, const double& dSideMax) { //int nCToSplit = -1 ; //celle 0,1 @@ -410,337 +437,328 @@ Tree::BuildTree_test( double dLinTol_, double dSideMin, double dSideMax) //---------------------------------------------------------------------------- bool -Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax) +Tree::BuildTree( const double& dLinTol, const double& dSideMin, const double& dSideMax) { - // suddivido lo spazio parametrico con divisioni a metà su uno dei due parametri + // suddivido lo spazio parametrico con divisioni a metà su uno dei due parametri int nCToSplit = -1 ; - //double dLinTol = 0.2 ; - //double dSideMin = 1 ; - if ( ! m_bTrimmed || m_bTrimmed) { - if ( ! m_bBilinear) { - while ( nCToSplit != -2 && m_mTree[nCToSplit].IsProcessed() == false) { - // controllo che la cella non sia già stata preliminarmente splittata - if ( m_mTree[nCToSplit].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 ; - if ( dLenParU <= 1. / m_nDegV || dLenParV <= 1. / m_nDegU) { - double dU = ( m_mTree[nCToSplit].GetTopRight().x + m_mTree[nCToSplit].GetBottomLeft().x) / 2 / SBZ_TREG_COEFF ; + if ( ! m_bBilinear) { + while ( nCToSplit != -2 && m_mTree[nCToSplit].IsProcessed() == false) { + // controllo che la cella non sia già stata preliminarmente splittata + if ( m_mTree[nCToSplit].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 ; + if ( dLenParU <= 1. / m_nDegV || dLenParV <= 1. / m_nDegU) { + 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 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) ; + 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) / SBZ_TREG_COEFF ; double dV = ( m_mTree[nCToSplit].GetTopRight().y + m_mTree[nCToSplit].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) ; + 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( 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) ; - Point3d ptV = ( 1 - dULoc) * ptP00P10 + dULoc * ptP11P01 ; - Point3d ptU = ( 1 - dVLoc) * ptP10P11 + dVLoc * ptP01P00 ; - dCurvV = Dist( ptV, ptPSrf) ; - dCurvU = Dist( ptU, ptPSrf) ; + CurveLine clV ; + clV.Set( ptP00P10, ptP11P01) ; + DistPointCurve dpc( ptPSrf, clV) ; + double dDist ; + dpc.GetDist( dDist) ; + dCurvV = std::max( dCurvV, dDist) ; } - // 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) / SBZ_TREG_COEFF ; - double dV = ( m_mTree[nCToSplit].GetTopRight().y + m_mTree[nCToSplit].GetBottomLeft().y) / 2 / SBZ_TREG_COEFF ; + 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 / SBZ_TREG_COEFF ; + double dV = ( k * m_mTree[nCToSplit].GetTopRight().y + ( 1 - k) * m_mTree[nCToSplit].GetBottomLeft().y) / SBZ_TREG_COEFF ; + if ( k == 0.5) + ptPSrf = ptPSrfMid ; + else 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) ; - CurveLine clV ; - clV.Set( ptP00P10, ptP11P01) ; - DistPointCurve dpc( ptPSrf, clV) ; - double dDist ; - dpc.GetDist( dDist) ; - dCurvV = std::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 / SBZ_TREG_COEFF ; - double dV = ( k * m_mTree[nCToSplit].GetTopRight().y + ( 1 - k) * m_mTree[nCToSplit].GetBottomLeft().y) / SBZ_TREG_COEFF ; - 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 / 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) ; - CurveLine clU ; - clU.Set( ptP01P00, ptP10P11) ; - DistPointCurve dpc( ptPSrf, clU) ; - double dDist ; - dpc.GetDist( dDist) ; - dCurvU = std::max( dCurvU, dDist) ; - } + 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) ; + CurveLine clU ; + clU.Set( ptP01P00, ptP10P11) ; + DistPointCurve dpc( ptPSrf, clU) ; + double dDist ; + dpc.GetDist( dDist) ; + dCurvU = std::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 - bVert = false ; + // 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 + bVert = false ; + } + else { + // lungo la direzione U ho una curvatura maggiore + bVert = true ; + } + m_mTree[nCToSplit].SetSplitDirVert( bVert) ; + Point3d ptP00, ptP10, ptP11, ptP01 ; + // distanza reale tra i vertici della cella + ptP00 = m_mVert[nCToSplit][0] ; + ptP10 = m_mVert[nCToSplit][1] ; + ptP11 = m_mVert[nCToSplit][2] ; + ptP01 = m_mVert[nCToSplit][3] ; + double dLen0 = Dist( ptP00, ptP10) ; + double dLen1 = Dist( ptP10, ptP11) ; + double dLen2 = Dist( ptP01, ptP11) ; + double dLen3 = Dist( ptP00, ptP01) ; + // verifico che la cella sia da splittare e che eventualmente sia abbastanza grande da poterlo fare + double dSideMinVal = 0, dSideMaxVal = 0 ; + if ( bVert) { + if ( dLen0 != 0 && dLen2 != 0) + dSideMinVal = std::max( dLen0, dLen2) ; + else + dSideMinVal = std::max( dLen0, dLen2) ; + } + else { + if ( dLen1 != 0 && dLen3 != 0) + dSideMinVal = std::max( dLen1, dLen3) ; + else + dSideMinVal = std::max( dLen1, dLen3) ; + } + // calcolo le diagonali per controllare la dimensione massima dei triangoli in cui dividerei la cella + dSideMaxVal = std::max( Dist( ptP00, ptP11), Dist( ptP10, ptP01)) ; + + // se la cella è abbastanza grande da poter essere divisa ancora, calcolo l'errore di approssimazione + bool bSplit = false ; + if ( dSideMinVal / 2 >= dSideMin && dSideMaxVal < dSideMax && ( dCurvV > dLinTol || dCurvU > dLinTol)) { + CurveLine cl0010, cl0001, cl1011, cl0111 ; + // U=0 + cl0010.Set( ptP00, ptP10) ; + // U=1 + cl0111.Set( ptP01, ptP11) ; + Point3d pt0010, pt0111, ptBz0, ptBz1, ptBzV ; + int nFlag ; + CurveLine clV ; + // determino quanti Step fare per ogni direzione parametrica + double dDimU = ( dLen0 >= dLen2 ? dLen0 / m_vDim[0] : dLen2 / m_vDim[2]) ; + dDimU = ( dDimU > 1 ? 1 : dDimU) ; + double dDimV = ( dLen1 >= dLen3 ? dLen1 / m_vDim[1] : dLen3 / m_vDim[3]) ; + dDimV = ( dDimV > 1 ? 1 : dDimV) ; + // numero di Step per campionare la superficie nelle due direzioni parametriche + int nStepsU = int( 51 * dDimU + 5 * ( 1 - dDimU)) ; + 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)) + return false ; + DistPointCurve dpc0010( ptBz0, cl0010) ; + DistPointCurve dpc0111( ptBz1, cl0111) ; + dpc0010.GetMinDistPoint( 0, pt0010, nFlag) ; + dpc0111.GetMinDistPoint( 0, pt0111, nFlag) ; + 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 ; + 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 > dLinTol) { + bSplit = true ; + break ; + } + } } - else { - // lungo la direzione U ho una curvatura maggiore + } + + if ( bSplit || dSideMaxVal > dSideMax) { + m_mTree[nCToSplit].SetSplitDirVert( bVert) ; + // effettuo lo split + Split( nCToSplit) ; + + // procedo con lo split del Child1 + nCToSplit = m_mTree[nCToSplit].m_nChild1 ; + } + else { + // sono arrivato ad una cella Leaf, quindi salvo la cella + m_vnLeaves.push_back( nCToSplit) ; + m_mTree[nCToSplit].SetProcessed() ; + // risalgo i parent finché non trovo il primo Child2 da processare + nCToSplit = m_mTree[nCToSplit].m_nParent ; + 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()) + break ; + } + nCToSplit = m_mTree[nCToSplit].m_nChild2 ; + } + } + else { + nCToSplit = m_mTree[nCToSplit].m_nChild1 ; + } + } + Balance() ; // da implementare quando dividerò ad un parametro a scelta e non a metà + } + // bilineare + else { + while ( nCToSplit != -2 && m_mTree[nCToSplit].IsProcessed() == false) { + if ( m_mTree[nCToSplit].IsLeaf()) { + // vertici della cella + Point3d ptP00, ptP10, ptP11, ptP01 ; + ptP00 = m_mVert[nCToSplit][0] ; + ptP10 = m_mVert[nCToSplit][1] ; + ptP11 = m_mVert[nCToSplit][2] ; + ptP01 = m_mVert[nCToSplit][3] ; + // distanza reale tra i vertici della cella + double dLen0 = Dist( ptP00, ptP10) ; + double dLen1 = Dist( ptP10, ptP11) ; + double dLen2 = Dist( ptP01, ptP11) ; + double dLen3 = Dist( ptP00, ptP01) ; + + 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 ; + PNTVECTOR vPtU, vPtV ; + if ( ! m_bMulti) { + if ( std::max( dLen0, dLen2) > std::max( dLen1, dLen3)) { bVert = true ; } - m_mTree[nCToSplit].SetSplitDirVert( bVert) ; - Point3d ptP00, ptP10, ptP11, ptP01 ; - // distanza reale tra i vertici della cella - ptP00 = m_mVert[nCToSplit][0] ; - ptP10 = m_mVert[nCToSplit][1] ; - ptP11 = m_mVert[nCToSplit][2] ; - ptP01 = m_mVert[nCToSplit][3] ; - double dLen0 = Dist( ptP00, ptP10) ; - double dLen1 = Dist( ptP10, ptP11) ; - double dLen2 = Dist( ptP01, ptP11) ; - double dLen3 = Dist( ptP00, ptP01) ; - // verifico che la cella sia da splittare e che eventualmente sia abbastanza grande da poterlo fare - double dSideMinVal = 0, dSideMaxVal = 0 ; - if ( bVert) { - if ( dLen0 != 0 && dLen2 != 0) - dSideMinVal = std::max( dLen0, dLen2) ; - else - dSideMinVal = std::max( dLen0, dLen2) ; - } else { - if ( dLen1 != 0 && dLen3 != 0) - dSideMinVal = std::max( dLen1, dLen3) ; - else - dSideMinVal = std::max( dLen1, dLen3) ; - } - // calcolo le diagonali per controllare la dimensione massima dei triangoli in cui dividerei la cella - dSideMaxVal = std::max( Dist( ptP00, ptP11), Dist( ptP10, ptP01)) ; - - // se la cella è abbastanza grande da poter essere divisa ancora, calcolo l'errore di approssimazione - bool bSplit = false ; - if ( dSideMinVal / 2 >= dSideMin && dSideMaxVal < dSideMax && ( dCurvV > dLinTol || dCurvU > dLinTol)) { - CurveLine cl0010, cl0001, cl1011, cl0111 ; - // U=0 - cl0010.Set( ptP00, ptP10) ; - // U=1 - cl0111.Set( ptP01, ptP11) ; - Point3d pt0010, pt0111, ptBz0, ptBz1, ptBzV ; - int nFlag ; - CurveLine clV ; - // determino quanti Step fare per ogni direzione parametrica - double dDimU = ( dLen0 >= dLen2 ? dLen0 / m_vDim[0] : dLen2 / m_vDim[2]) ; - dDimU = ( dDimU > 1 ? 1 : dDimU) ; - double dDimV = ( dLen1 >= dLen3 ? dLen1 / m_vDim[1] : dLen3 / m_vDim[3]) ; - dDimV = ( dDimV > 1 ? 1 : dDimV) ; - // numero di Step per campionare la superficie nelle due direzioni parametriche - int nStepsU = int( 51 * dDimU + 5 * ( 1 - dDimU)) ; - 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)) - return false ; - DistPointCurve dpc0010( ptBz0, cl0010) ; - DistPointCurve dpc0111( ptBz1, cl0111) ; - dpc0010.GetMinDistPoint( 0, pt0010, nFlag) ; - dpc0111.GetMinDistPoint( 0, pt0111, nFlag) ; - 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 ; - 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 > dLinTol) { - bSplit = true ; - break ; - } - } - } - } - - if ( bSplit || dSideMaxVal > dSideMax) { - m_mTree[nCToSplit].SetSplitDirVert( bVert) ; - // effettuo lo split - Split( nCToSplit) ; - - // procedo con lo split del Child1 - nCToSplit = m_mTree[nCToSplit].m_nChild1 ; - } - else { - // sono arrivato ad una cella Leaf, quindi salvo la cella - m_vnLeaves.push_back( nCToSplit) ; - m_mTree[nCToSplit].SetProcessed() ; - // risalgo i parent finché non trovo il primo Child2 da processare - nCToSplit = m_mTree[nCToSplit].m_nParent ; - 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()) - break ; - } - nCToSplit = m_mTree[nCToSplit].m_nChild2 ; + bVert = false ; } } else { - nCToSplit = m_mTree[nCToSplit].m_nChild1 ; + 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 ; + 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) ; + vPtV.push_back( ptPSrfV) ; + } + // devo guardare se i tre punti in vPtU e vPtV sono allineati + CurveLine clU, clV ; + clU.Set( vPtU[0], vPtU[1]) ; + clV.Set( vPtV[0], vPtV[1]) ; + DistPointCurve dpcU( vPtU[2], clU, false) ; + DistPointCurve dpcV( vPtV[2], clV, false) ; + dpcU.GetDist( dDistU) ; + dpcV.GetDist( dDistV) ; + if ( dDistU > dDistV) { + bVert = true ; + } + else { + bVert = false ; + } } - } - Balance() ; // da implementare quando dividerò ad un parametro a scelta e non a metà - } - // bilineare - else { - while ( nCToSplit != -2 && m_mTree[nCToSplit].IsProcessed() == false) { - if ( m_mTree[nCToSplit].IsLeaf()) { - // vertici della cella - Point3d ptP00, ptP10, ptP11, ptP01 ; - ptP00 = m_mVert[nCToSplit][0] ; - ptP10 = m_mVert[nCToSplit][1] ; - ptP11 = m_mVert[nCToSplit][2] ; - ptP01 = m_mVert[nCToSplit][3] ; - // distanza reale tra i vertici della cella - double dLen0 = Dist( ptP00, ptP10) ; - double dLen1 = Dist( ptP10, ptP11) ; - double dLen2 = Dist( ptP01, ptP11) ; - double dLen3 = Dist( ptP00, ptP01) ; - - 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 ; - PNTVECTOR vPtU, vPtV ; - if ( ! m_bMulti) { - if ( std::max( dLen0, dLen2) > std::max( dLen1, dLen3)) { - bVert = true ; - } - else { - bVert = false ; - } - } - 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 ; - 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) ; - vPtV.push_back( ptPSrfV) ; - } - // devo guardare se i tre punti in vPtU e vPtV sono allineati - CurveLine clU, clV ; - clU.Set( vPtU[0], vPtU[1]) ; - clV.Set( vPtV[0], vPtV[1]) ; - DistPointCurve dpcU( vPtU[2], clU, false) ; - DistPointCurve dpcV( vPtV[2], clV, false) ; - dpcU.GetDist( dDistU) ; - dpcV.GetDist( dDistV) ; - if ( dDistU > dDistV) { - bVert = true ; - } - else { - bVert = false ; - } - } - // verifico che la cella sia abbastanza grande da poter essere splittata - double dSideMinVal = 0, dSideMaxVal = 0 ; - if ( bVert) { - if ( dLen0 != 0 && dLen2 != 0) - dSideMinVal = std::max( dLen0, dLen2) ; - else - dSideMinVal = std::max( dLen0, dLen2) ; - } - else { - if ( dLen1 != 0 && dLen3 != 0) - dSideMinVal = std::max( dLen1, dLen3) ; - else - dSideMinVal = std::max( dLen1, dLen3) ; - } - // calcolo le diagonali per controllare la dimensione massima dei triangoli in cui dividerei la cella - dSideMaxVal = std::max( Dist( ptP00, ptP11), Dist( ptP10, ptP01)) ; + // verifico che la cella sia abbastanza grande da poter essere splittata + double dSideMinVal = 0, dSideMaxVal = 0 ; + if ( bVert) { + if ( dLen0 != 0 && dLen2 != 0) + dSideMinVal = std::max( dLen0, dLen2) ; + else + dSideMinVal = std::max( dLen0, dLen2) ; + } + else { + if ( dLen1 != 0 && dLen3 != 0) + dSideMinVal = std::max( dLen1, dLen3) ; + else + dSideMinVal = std::max( dLen1, dLen3) ; + } + // calcolo le diagonali per controllare la dimensione massima dei triangoli in cui dividerei la cella + dSideMaxVal = std::max( Dist( ptP00, ptP11), Dist( ptP10, ptP01)) ; - double dErr = 0 ; - if ( m_bMulti) { - Point3d ptPSrf ; - Plane3d plAppr ; - if ( ! AreSamePointApprox( ptP00, ptP10) && ! AreSamePointApprox( ptP00, ptP01)) - plAppr.Set( ptP00, ( ptP00 - ptP01) ^ ( ptP00 - ptP10)) ; - else if ( AreSamePointApprox( ptP00, ptP10)) { - plAppr.Set( ptP01, ( ptP00 - ptP01) ^ ( ptP01 - ptP11)) ; - } - else if ( AreSamePointApprox( ptP00, ptP01)) { - plAppr.Set( ptP10, ( ptP10 - ptP11) ^ ( ptP00 - ptP10)) ; - } - 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 ; - m_pSrfBz->GetPointD1D2( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrf) ; - dErr = std::max( abs( DistPointPlane( ptPSrf, plAppr)), dErr) ; - } - } + double dErr = 0 ; + if ( m_bMulti) { + Point3d ptPSrf ; + Plane3d plAppr ; + if ( ! AreSamePointApprox( ptP00, ptP10) && ! AreSamePointApprox( ptP00, ptP01)) + plAppr.Set( ptP00, ( ptP00 - ptP01) ^ ( ptP00 - ptP10)) ; + else if ( AreSamePointApprox( ptP00, ptP10)) { + plAppr.Set( ptP01, ( ptP00 - ptP01) ^ ( ptP01 - ptP11)) ; } - else { - dErr = 1. / 4. * ( ( ptP00 - ptP01) + ( ptP11 - ptP10)).Len() ; + else if ( AreSamePointApprox( ptP00, ptP01)) { + plAppr.Set( ptP10, ( ptP10 - ptP11) ^ ( ptP00 - ptP10)) ; } - // 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) ; - // effettuo lo split - Split( nCToSplit) ; - - // procedo con lo split del Child1 - nCToSplit = m_mTree[nCToSplit].m_nChild1 ; - } - else { - // sono arrivato ad una cella Leaf, quindi salvo la cella - m_vnLeaves.push_back( nCToSplit) ; - m_mTree[nCToSplit].SetProcessed() ; - // risalgo i parent finché non trovo il primo Child2 da processare - nCToSplit = m_mTree[nCToSplit].m_nParent ; - 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()) - break ; + 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 ; + m_pSrfBz->GetPointD1D2( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrf) ; + dErr = std::max( abs( DistPointPlane( ptPSrf, plAppr)), dErr) ; } - nCToSplit = m_mTree[nCToSplit].m_nChild2 ; } } else { + dErr = 1. / 4. * ( ( ptP00 - ptP01) + ( ptP11 - ptP10)).Len() ; + } + // 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) ; + // effettuo lo split + Split( nCToSplit) ; + + // procedo con lo split del Child1 nCToSplit = m_mTree[nCToSplit].m_nChild1 ; } + else { + // sono arrivato ad una cella Leaf, quindi salvo la cella + m_vnLeaves.push_back( nCToSplit) ; + m_mTree[nCToSplit].SetProcessed() ; + // risalgo i parent finché non trovo il primo Child2 da processare + nCToSplit = m_mTree[nCToSplit].m_nParent ; + 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()) + break ; + } + nCToSplit = m_mTree[nCToSplit].m_nChild2 ; + } + } + else { + nCToSplit = m_mTree[nCToSplit].m_nChild1 ; } } } - // NON IMPLEMENTATO - // se la superficie è trimmata creo l'albero solo all'interno dei bbox delle curve di trim ( se ho solo trim CW allora tengo il bordo) - else { - SurfFlatRegion sfrTrimReg ; - } return true ; } @@ -1225,7 +1243,7 @@ Tree::GetPolygons( std::vector& vPolygons) { int nPoly = 0 ; // scorro sui vettori intersezione della cella nId e sui suoi vertici // in questo for analizzo solo i loop che tagliano la cella - while( nPoly == 0 || (int)vToCheck.size() != 0) { + while( (int)vToCheck.size() != 0) { int nPolyBefore = nPoly ; CreateCellPolygons( i, vPolygons, vToCheck, nPoly, vnParentChunk, vPolygonsBasic[i]) ; if ( nPolyBefore == nPoly) @@ -1455,35 +1473,15 @@ Tree::FindCell( const Point3d& ptToAssign, const CurveLine& cl, INTVECTOR vCells bool Tree::TraceLoopLabelCell( void) { - // approssimo i loop di trim con delle spezzate - POLYLINEVECTOR vPlApprox ; - for ( int p = 0 ; p < (int) m_vLoop.size() ; ++ p){ - PtrOwner pCrv( m_vLoop[p]->Clone()) ; - double dLinTol = 0.01 ; // questo è riferito allo spazio parametrico perché le curve di loop sono già state riscalate!!!!!! - double dAngTolDeg = 5 ; - PolyLine plApprox ; - int nType = 0 ; - pCrv->ApproxWithLines( dLinTol,dAngTolDeg, nType, plApprox) ; - vPlApprox.push_back( plApprox) ; - } - // ora le curve di trim hanno lo stesso indice delle loro corrispondenti spezzate nel vettore vPlApprox - double dLinTol = - EPS_SMALL ; // questo è riferito allo spazio parametrico, quando è già stato riporatato al range 0..1 !!!!!! // il valore è negativo perché voglio considerare contenuto anche un punto che sta su un lato POLYLINEVECTOR vplPolygons ; GetPolygonsBasic( vplPolygons) ; // percorro i loop trovando le interezioni con le celle e riempiendo i vettori m_vInters delle varie celle - for ( int i = 0 ; i < (int) vPlApprox.size() ; ++ i) { - PolyLine plLoop = vPlApprox[i] ; - // calcolo se il loop è CCW o Cw - double dArea ; - Plane3d plExtPlane ; - bool bCCW ; - plLoop.IsClosedAndFlat( plExtPlane, dArea, 50 * EPS_SMALL) ; - if ( plExtPlane.GetVersN().z > 0) - bCCW = true ; - else - bCCW = false ; + for ( int i = 0 ; i < (int) m_vPlApprox.size() ; ++ i) { + PolyLine plLoop = std::get<0>(m_vPlApprox[i]) ; + // calcolo se il loop è CCW o CW + bool bCCW = std::get<1>(m_vPlApprox[i]) ; // trovo in quale cella è il ptStart Point3d ptStart ; plLoop.GetFirstPoint( ptStart) ; @@ -1514,11 +1512,11 @@ Tree::TraceLoopLabelCell( void) INTVECTOR :: iterator iter = find( m_vnLeaves.begin(), m_vnLeaves.end(), nId) ; int nIdPolygon = std::distance( m_vnLeaves.begin(), iter) ; bool bEraseNextPoint = false ; - // per debug - int c = 0 ; + //// per debug + //int c = 0 ; Cell cUnderWork ; while ( plLoop.GetNextPoint( ptCurr)) { - ++ c ; + //++ c ; // sto uscendo dalla cella, quindi cerco l'intersezione Point3d ptTStart, ptTEnd ; plLoop.GetPrevPoint( ptTStart) ; @@ -1536,7 +1534,6 @@ Tree::TraceLoopLabelCell( void) // al precedente FindInters avrei dovuto passare di cella if ( ! FindInters( nId, clTrim, vptInters, true)) { // scarterò il punto molto vicino al lato e tengo solo l'intersezione del trim col lato - //m_mTree[nId].m_vInters.back().vpt.pop_back() ; vptInters.pop_back() ; plLoop.GetPrevPoint( ptTEnd) ; plLoop.GetPrevPoint( ptTStart) ; @@ -1544,8 +1541,7 @@ Tree::TraceLoopLabelCell( void) clTrim.Set( ptTStart, ptTEnd) ; clTrim.ExtendEndByLen( EPS_SMALL * 2) ; clTrim.ExtendStartByLen( EPS_SMALL * 2) ; - //vptInters.clear() ; - if ( FindInters( nId, clTrim, vptInters, true)) + if ( ! FindInters( nId, clTrim, vptInters, true)) return false ; bEraseNextPoint = true ; } @@ -2401,7 +2397,6 @@ Tree::CreateIslandAndHoles( const int& nLeafId, std::vector& vPo // loop interni in una cella intersecata if ( m_mTree[nId].m_nFlag == 3 || m_mTree[nId].m_nFlag == 2) { PolyLine plInLoop ; - // numero dei loop interni passati Inters inA ; // se ho almeno un loop CW che non è contenuto in un altro poligono o in un loop interno CCW devo aggiungere il bordo bool bAllContained = true ; @@ -2469,10 +2464,9 @@ Tree::CreateIslandAndHoles( const int& nLeafId, std::vector& vPo plInLoop.GetFirstPoint( ptStart) ; int nOtherPoly = (int)vPolygons.size() ; for ( int r = 0 ; r < nPoly ; ++r) { - if ( IsPointInsidePolyLine( ptStart, vPolygons[nOtherPoly - r - 1][0], -0.01) && vnParentChunk[nLoop - r - 1] == inA.nChunk) { + if ( IsPointInsidePolyLine( ptStart, vPolygons[nOtherPoly - r - 1][0], -0.01) && vnParentChunk[nPoly - r - 1] == inA.nChunk) { vPolygons[nOtherPoly - r - 1].push_back( plInLoop) ; plInLoop.Clear() ; - vnParentChunk.push_back( inA.nChunk) ; bAdded = true ; break ; } @@ -2676,7 +2670,7 @@ Tree::AddVertex( const int& nId, const std::vector& vEdgeVertex, Poly plTrimmedPoly.GetLastPoint( ptLast) ; // verifico di essere allineato con un lato, sennò aggiungo e basta Vector3d vDir ; - if ( ! AreSamePointExact( ptToAdd, ptLast)) + if ( ! AreSamePointApprox( ptToAdd, ptLast)) vDir = ptToAdd - ptLast ; else return true ; @@ -2691,6 +2685,8 @@ Tree::AddVertex( const int& nId, const std::vector& vEdgeVertex, Poly plTrimmedPoly.AddUPoint( c, ptTl) ; else if ( AreSamePointApprox( ptToAdd, ptBL)) plTrimmedPoly.AddUPoint( c, ptBL) ; + else + plTrimmedPoly.AddUPoint( c, ptToAdd) ; ++ c ; return true ; } diff --git a/Tree.h b/Tree.h index 3f79dac..57bf9cd 100644 --- a/Tree.h +++ b/Tree.h @@ -117,9 +117,9 @@ public : Tree( void) ; Tree ( const SurfBezier* pSrfBz, const bool bSplitPatches = true) ; void SetSurf( const SurfBezier* pSrfBz, const bool bSplitPatches = true) ; - bool BuildTree( const double dLinTol = LIN_TOL_STD, const double dSideMin = 5, const double dSideMax = INFINITO) ; // dSideMax è il massimo per la dimensione maggiore di un triangolo della trimesh + bool BuildTree( const double& dLinTol = LIN_TOL_STD, const double& dSideMin = 5, const double& dSideMax = INFINITO) ; // dSideMax è il massimo per la dimensione maggiore di un triangolo della trimesh // dSideMin è lunghezza minima del lato di una cella nello spazio reale - bool BuildTree_test( const double dLinTol = LIN_TOL_STD, const double dSideMin = 5, const double dSideMax = INFINITO) ; + bool BuildTree_test( const double& dLinTol = LIN_TOL_STD, const double& dSideMin = 5, const double& dSideMax = INFINITO) ; bool GetPolygons( std::vector& vPolygons) ; bool GetPolygonsBasic( POLYLINEVECTOR& vPolygons) ; // restituisce il poligono corrispondente ad ogni cella foglia dell'albero // ad ogni poligono sono stati aggiunti tutti i vertici dei vicini posizionati sui suoi lati @@ -162,7 +162,8 @@ private : bool m_bTrimmed ; // superficie trimmata std::vector m_vChunk ; // elenco dei loop divisi per chunk std::map m_mChunk ; - ICURVEPOVECTOR m_vLoop ; // curve di loop. la 0 è il bordo dello spazio parametrico, le altre sono i loop interni + ICURVEPOVECTOR m_vLoop ; // curve di loop + std::vector> m_vPlApprox ; bool m_bBilinear ; // superficie bilineare bool m_bMulti ; // superficie multi-patch bool m_bClosed ; // superficie chiusa