diff --git a/Tree.cpp b/Tree.cpp index c8dc7bf..d2d7e67 100644 --- a/Tree.cpp +++ b/Tree.cpp @@ -171,6 +171,42 @@ Tree::AdjustLoop( PolyLine& pl, POLYLINEVECTOR& vPl, BOOLVECTOR& vbOrientation) return true ; } +//---------------------------------------------------------------------------- +bool +Tree::GetPoint( double dU, double dV, Point3d& pt) const +{ + //INTINT key ( int( dU * pow(2,15)), int( dV * pow(2,15))) ; + //INTINT key ( int( dU * 100), int( dV * 100)) ; + //if (dU > 100000 || dV > 100000) + // int a = 0 ; + //double dDecimal = 5 ; + //DBLDBL key( trunc(dU * dDecimal) / dDecimal, trunc(dV * dDecimal) / dDecimal) ; + pair key (static_cast(dU * pow(2,15)), static_cast(dV * pow(2,15))) ; + bool bOk = true ; + if ( m_mPt3d.find( key) == m_mPt3d.end()) { + bOk = bOk && m_pSrfBz->GetPoint( dU / SBZ_TREG_COEFF, dV / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt) ; + m_mPt3d[key] = pt ; + } + pt = m_mPt3d[key] ; + return bOk ; +} + +//---------------------------------------------------------------------------- +bool +Tree::SavePoint( double dU, double dV, Point3d& pt) +{ + //INTINT key ( int( dU * pow(2,15)), int( dV * pow(2,15))) ; + //INTINT key ( int( dU * 100), int( dV * 100)) ; + //if (dU > 100000 || dV > 100000) + // int a = 0 ; + //double dDecimal = 5 ; + //DBLDBL key( trunc(dU * dDecimal) / dDecimal, trunc(dV * dDecimal) / dDecimal) ; + pair key (static_cast(dU * pow(2,15)), static_cast(dV * pow(2,15))) ; + if ( m_mPt3d.find( key) == m_mPt3d.end()) + m_mPt3d[key] = pt ; + return true ; +} + //---------------------------------------------------------------------------- bool Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMin, const Point3d& ptMax) @@ -181,7 +217,7 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi m_mTree.clear() ; m_vnLeaves.clear() ; m_vnParents.clear() ; - m_mVert.clear() ; + m_mPt3d.clear() ; //m_vLoop.clear() ; m_mChunk.clear() ; m_vPlApprox.clear() ; @@ -264,29 +300,20 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi bool bOk = false ; if ( ! bLimited) { ptP00 = m_pSrfBz->GetControlPoint( 0, &bOk) ; + SavePoint( 0, 0, ptP00) ; ptP10 = m_pSrfBz->GetControlPoint( nDegU * nSpanU, &bOk) ; + SavePoint( nSpanU * SBZ_TREG_COEFF, 0, ptP10) ; ptP11 = m_pSrfBz->GetControlPoint( ( nDegU * nSpanU + 1) * ( nDegV * nSpanV + 1) - 1, &bOk) ; + SavePoint( nSpanU * SBZ_TREG_COEFF, nSpanV * SBZ_TREG_COEFF, ptP11) ; ptP01 = m_pSrfBz->GetControlPoint( ( nDegU * nSpanU + 1) * ( nDegV * nSpanV), &bOk) ; + SavePoint( 0, nSpanV * SBZ_TREG_COEFF, ptP01) ; } else { - m_pSrfBz->GetPoint( ptMin.x / SBZ_TREG_COEFF, ptMin.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP00) ; - m_pSrfBz->GetPoint( ptMax.x / SBZ_TREG_COEFF, ptMin.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP10) ; - m_pSrfBz->GetPoint( ptMax.x / SBZ_TREG_COEFF, ptMax.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP11) ; - m_pSrfBz->GetPoint( ptMin.x / SBZ_TREG_COEFF, ptMax.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP01) ; - - - Point3d pt1, pt2, pt3, pt4 ; - m_pSrfBz->GetPointD1D2( ptMin.x / SBZ_TREG_COEFF, ptMin.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt1) ; - m_pSrfBz->GetPointD1D2( ptMax.x / SBZ_TREG_COEFF, ptMin.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt2) ; - m_pSrfBz->GetPointD1D2( ptMax.x / SBZ_TREG_COEFF, ptMax.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3) ; - m_pSrfBz->GetPointD1D2( ptMin.x / SBZ_TREG_COEFF, ptMax.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt4) ; + GetPoint( ptMin.x, ptMin.y, ptP00) ; + GetPoint( ptMax.x, ptMin.y, ptP10) ; + GetPoint( ptMax.x, ptMax.y, ptP11) ; + GetPoint( ptMin.x, ptMax.y, ptP01) ; } - PNTVECTOR vVert ; - vVert.push_back( ptP00) ; - vVert.push_back( ptP10) ; - vVert.push_back( ptP11) ; - vVert.push_back( ptP01) ; - m_mVert.insert( pair( -1, vVert)) ; // se richiesto divido preliminarmente le patches m_vnParents.clear() ; bool bIsPlanar = m_pSrfBz->IsPlanar() ; @@ -568,7 +595,6 @@ Tree::Split( int nId, double dSplitValue) cChild2.m_nId = nNodes ; cToSplit.m_nChild2 = nNodes ; Point3d ptVert1, ptVert2 ; - PNTVECTOR vVert1, vVert2 ; if ( ! cToSplit.IsSplitVert()) { // la cella figlio 1 è quella sopra Point3d ptBL( cToSplit.GetBottomLeft().x, dSplitValue) ; @@ -587,16 +613,8 @@ Tree::Split( int nId, double dSplitValue) 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->GetPoint( cToSplit.GetBottomLeft().x / SBZ_TREG_COEFF, dSplitValue / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptVert1) ; - m_pSrfBz->GetPoint( 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) ; + GetPoint( cToSplit.GetBottomLeft().x, dSplitValue, ptVert1) ; + GetPoint( cToSplit.GetTopRight().x, dSplitValue, ptVert2) ; } else { // la cella figlio 1 è quella di sinistra @@ -616,22 +634,11 @@ Tree::Split( int nId, double dSplitValue) 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->GetPoint( dSplitValue / SBZ_TREG_COEFF, cToSplit.GetBottomLeft().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptVert2) ; - m_pSrfBz->GetPoint( 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) ; + GetPoint( dSplitValue, cToSplit.GetBottomLeft().y, ptVert2) ; + GetPoint( dSplitValue, cToSplit.GetTopRight().y, ptVert1) ; } 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)) ; @@ -734,17 +741,23 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax) double dCurvU = 0, dCurvV = 0 ; double dLenParU = ( pcToSplit->GetTopRight().x - pcToSplit->GetBottomLeft().x) / SBZ_TREG_COEFF ; double dLenParV = ( pcToSplit->GetTopRight().y - pcToSplit->GetBottomLeft().y) / SBZ_TREG_COEFF ; - if ( dLenParU <= 1. / m_nDegV || dLenParV <= 1. / m_nDegU || Dist(m_mVert[nCToSplit][0], m_mVert[nCToSplit][2]) < dSideMin * 2 - || Dist(m_mVert[nCToSplit][1], m_mVert[nCToSplit][3]) < dSideMin * 2) { - double dU = ( pcToSplit->GetTopRight().x + pcToSplit->GetBottomLeft().x) / 2 / SBZ_TREG_COEFF ; - double dV = ( pcToSplit->GetTopRight().y + pcToSplit->GetBottomLeft().y) / 2 / SBZ_TREG_COEFF ; + Point3d ptP00, ptP10, ptP11, ptP01 ; + // i vertici della cella + GetPoint(pcToSplit->GetBottomLeft().x, pcToSplit->GetBottomLeft().y, ptP00) ; + GetPoint(pcToSplit->GetTopRight().x, pcToSplit->GetBottomLeft().y, ptP10) ; + GetPoint(pcToSplit->GetTopRight().x, pcToSplit->GetTopRight().y, ptP11) ; + GetPoint(pcToSplit->GetBottomLeft().x, pcToSplit->GetTopRight().y, ptP01) ; + if ( dLenParU <= 1. / m_nDegV || dLenParV <= 1. / m_nDegU || Dist(ptP00, ptP11) < dSideMin * 2 + || Dist(ptP10, ptP01) < dSideMin * 2) { + double dU = ( pcToSplit->GetTopRight().x + pcToSplit->GetBottomLeft().x) / 2 ; + double dV = ( pcToSplit->GetTopRight().y + pcToSplit->GetBottomLeft().y) / 2 ; double dULoc = 0.5, dVLoc = 0.5 ; Point3d ptPSrf, ptP00P10, ptP10P11, ptP11P01, ptP01P00 ; - m_pSrfBz->GetPoint( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrf) ; - m_pSrfBz->GetPoint( dU, pcToSplit->GetBottomLeft().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP00P10) ; - m_pSrfBz->GetPoint( pcToSplit->GetTopRight().x / SBZ_TREG_COEFF, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP10P11) ; - m_pSrfBz->GetPoint( dU, pcToSplit->GetTopRight().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP11P01) ; - m_pSrfBz->GetPoint( pcToSplit->GetBottomLeft().x / SBZ_TREG_COEFF, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP01P00) ; + GetPoint( dU, dV, ptPSrf) ; + GetPoint( dU, pcToSplit->GetBottomLeft().y, ptP00P10) ; + GetPoint( pcToSplit->GetTopRight().x, dV, ptP10P11) ; + GetPoint( dU, pcToSplit->GetTopRight().y, ptP11P01) ; + GetPoint( pcToSplit->GetBottomLeft().x, dV, ptP01P00) ; Point3d ptV = ( 1 - dULoc) * ptP00P10 + dULoc * ptP11P01 ; Point3d ptU = ( 1 - dVLoc) * ptP10P11 + dVLoc * ptP01P00 ; dCurvV = Dist( ptV, ptPSrf) ; @@ -756,13 +769,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 * pcToSplit->GetTopRight().x + ( 1 - k) * pcToSplit->GetBottomLeft().x) / SBZ_TREG_COEFF ; - double dV = ( pcToSplit->GetTopRight().y + pcToSplit->GetBottomLeft().y) / 2 / SBZ_TREG_COEFF ; - m_pSrfBz->GetPoint( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrf) ; + double dU = ( k * pcToSplit->GetTopRight().x + ( 1 - k) * pcToSplit->GetBottomLeft().x) ; + double dV = ( pcToSplit->GetTopRight().y + pcToSplit->GetBottomLeft().y) / 2 ; + GetPoint( dU, dV, ptPSrf) ; if ( k == 0.5) ptPSrfMid = ptPSrf ; - m_pSrfBz->GetPoint( dU, pcToSplit->GetBottomLeft().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP00P10) ; - m_pSrfBz->GetPoint( dU, pcToSplit->GetTopRight().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP11P01) ; + GetPoint( dU, pcToSplit->GetBottomLeft().y, ptP00P10) ; + GetPoint( dU, pcToSplit->GetTopRight().y, ptP11P01) ; CurveLine clV ; clV.Set( ptP00P10, ptP11P01) ; DistPointCurve dpc( ptPSrf, clV) ; @@ -772,14 +785,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 = ( pcToSplit->GetTopRight().x + pcToSplit->GetBottomLeft().x) / 2 / SBZ_TREG_COEFF ; - double dV = ( k * pcToSplit->GetTopRight().y + ( 1 - k) * pcToSplit->GetBottomLeft().y) / SBZ_TREG_COEFF ; + double dU = ( pcToSplit->GetTopRight().x + pcToSplit->GetBottomLeft().x) / 2 ; + double dV = ( k * pcToSplit->GetTopRight().y + ( 1 - k) * pcToSplit->GetBottomLeft().y) ; if ( k == 0.5 && ! AreSamePointApprox( ORIG, ptPSrfMid)) ptPSrf = ptPSrfMid ; else - m_pSrfBz->GetPoint( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrf) ; - m_pSrfBz->GetPoint( pcToSplit->GetTopRight().x / SBZ_TREG_COEFF, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP10P11) ; - m_pSrfBz->GetPoint( pcToSplit->GetBottomLeft().x / SBZ_TREG_COEFF, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP01P00) ; + GetPoint( dU, dV, ptPSrf) ; + GetPoint( pcToSplit->GetTopRight().x, dV, ptP10P11) ; + GetPoint( pcToSplit->GetBottomLeft().x, dV, ptP01P00) ; CurveLine clU ; clU.Set( ptP01P00, ptP10P11) ; DistPointCurve dpc( ptPSrf, clU) ; @@ -793,12 +806,6 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax) // NON posso guardare la distanza tra il punto medio delle diagonali e il punto centrale della cella ( uLoc = 0.5, vLoc = 0.5) // posso guardare la distanza tra le due diagonali bool bTwist = false ; - Point3d ptP00, ptP10, ptP11, ptP01 ; - // i vertici della cella - ptP00 = m_mVert[nCToSplit][0] ; - ptP10 = m_mVert[nCToSplit][1] ; - ptP11 = m_mVert[nCToSplit][2] ; - ptP01 = m_mVert[nCToSplit][3] ; // serve una valutazione più fine, sennò approssimo la superficie in modo troppo grossolano DistLineLine dll( ptP00, ptP11, ptP10, ptP01, true, true) ; double dDist = 0 ; dll.GetDist( dDist) ; @@ -818,9 +825,9 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax) plCell.AddUPoint(0,ptP00) ; plCell.AddUPoint(1,ptP10) ; plCell.AddUPoint(2,ptP11) ; - double dU = (pcToSplit->GetTopRight().x + pcToSplit->GetBottomLeft().x) / (SBZ_TREG_COEFF * 2) ; - double dV = (pcToSplit->GetTopRight().y + pcToSplit->GetBottomLeft().y) / (SBZ_TREG_COEFF * 2) ; - Point3d ptCen ; m_pSrfBz->GetPoint( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptCen) ; + double dU = (pcToSplit->GetTopRight().x + pcToSplit->GetBottomLeft().x) / 2 ; + double dV = (pcToSplit->GetTopRight().y + pcToSplit->GetBottomLeft().y) / 2 ; + Point3d ptCen ; GetPoint( dU, dV, ptCen) ; plCell.AddUPoint(3,ptCen) ; plCell.AddUPoint(4,ptP01) ; plCell.Close() ; @@ -928,9 +935,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) * pcToSplit->GetBottomLeft().x + dU * pcToSplit->GetTopRight().x) / SBZ_TREG_COEFF ; - if ( ! m_pSrfBz->GetPoint( dULoc, pcToSplit->GetBottomLeft().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBz0) || - ! m_pSrfBz->GetPoint( dULoc, pcToSplit->GetTopRight().y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBz1)) + double dULoc = ( ( 1 - dU) * pcToSplit->GetBottomLeft().x + dU * pcToSplit->GetTopRight().x) ; + if ( ! GetPoint( dULoc, pcToSplit->GetBottomLeft().y, ptBz0) || + ! GetPoint( dULoc, pcToSplit->GetTopRight().y, 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) @@ -951,8 +958,8 @@ 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) * pcToSplit->GetBottomLeft().y + dV * pcToSplit->GetTopRight().y) / SBZ_TREG_COEFF ; - if ( ! m_pSrfBz->GetPoint( dULoc, dVLoc, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBzV)) + double dVLoc = ( ( 1 - dV) * pcToSplit->GetBottomLeft().y + dV * pcToSplit->GetTopRight().y) ; + if ( ! GetPoint( dULoc, dVLoc, ptBzV)) return false ; DistPointCurve dpc( ptBzV, clV) ; // distanza di approssimazione locale @@ -1034,10 +1041,10 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax) if ( pcToSplit->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] ; + GetPoint(pcToSplit->GetBottomLeft().x, pcToSplit->GetBottomLeft().y, ptP00) ; + GetPoint(pcToSplit->GetTopRight().x, pcToSplit->GetBottomLeft().y, ptP10) ; + GetPoint(pcToSplit->GetTopRight().x, pcToSplit->GetTopRight().y, ptP11) ; + GetPoint(pcToSplit->GetBottomLeft().x, pcToSplit->GetTopRight().y, ptP01) ; // distanza reale tra i vertici della cella double dLen0 = Dist( ptP00, ptP10) ; double dLen1 = Dist( ptP10, ptP11) ; @@ -1082,13 +1089,9 @@ 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) * pcToSplit->GetTopRight().x + i * pcToSplit->GetBottomLeft().x) / SBZ_TREG_COEFF ; - double dV = ( ( 1 - j) * pcToSplit->GetTopRight().y + j * pcToSplit->GetBottomLeft().y) / SBZ_TREG_COEFF ; - m_pSrfBz->GetPoint( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrf) ; - //debug - Point3d ptPSrf_old ; - m_pSrfBz->GetPointD1D2( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrf_old) ; - //debug + double dU = ( ( 1 - i) * pcToSplit->GetTopRight().x + i * pcToSplit->GetBottomLeft().x) ; + double dV = ( ( 1 - j) * pcToSplit->GetTopRight().y + j * pcToSplit->GetBottomLeft().y) ; + GetPoint( dU, dV, ptPSrf) ; dErr = max( abs( DistPointPlane( ptPSrf, plAppr)), dErr) ; } } @@ -1780,27 +1783,38 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon vVertices3d.clear() ; vNeigh.clear() ; vVertices.push_back( cell.GetBottomLeft()) ; - vVertices3d.push_back( m_mVert.at( nId)[0]) ; + Point3d pt3d ; GetPoint( cell.GetBottomLeft().x, cell.GetBottomLeft().y, pt3d) ; + vVertices3d.push_back( pt3d) ; INTVECTOR vnVert ; BOOLVECTOR vbBonusVert(4) ; fill( vbBonusVert.begin(), vbBonusVert.end(), false) ; vnVert.push_back( int(vVertices.size()) - 1) ; GetBottomNeigh( nId, vNeigh) ; + Point3d ptP00, ptP10, ptP11, ptP01 ; + GetPoint( cell.GetBottomLeft().x, cell.GetBottomLeft().y, ptP00) ; + GetPoint( cell.GetTopRight().x, cell.GetBottomLeft().y, ptP10) ; + GetPoint( cell.GetTopRight().x, cell.GetTopRight().y, ptP11) ; + GetPoint( cell.GetBottomLeft().x, cell.GetTopRight().y, ptP01) ; + // aggiungo i vertici che sono sul lato bottom, solo se ho più di un vicino bottom if ( vNeigh.size() > 1){ // se la superficie è chiusa lungo il parametro V e le celle vicine bottom sono sul lato Top // 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, cell.GetBottomLeft().y) ; + Cell& cNeigh = m_mTree.at(j) ; + Point3d pt( cNeigh.GetTopRight().x, cell.GetBottomLeft().y) ; vVertices.push_back( pt) ; - vVertices3d.push_back( m_mVert[j][2]) ; + Point3d pt3d ; GetPoint( cNeigh.GetTopRight().x, cNeigh.GetTopRight().y, pt3d) ; + vVertices3d.push_back( pt3d) ; } } else { for ( int j : vNeigh) { - vVertices.push_back( m_mTree.at( j).GetTopRight()) ; - vVertices3d.push_back( m_mVert[j][2]) ; + Cell& cNeigh = m_mTree.at(j) ; + vVertices.push_back( cNeigh.GetTopRight()) ; + Point3d pt3d ; GetPoint( cNeigh.GetTopRight().x, cNeigh.GetTopRight().y, pt3d) ; + vVertices3d.push_back( pt3d) ; } } bBottomRight = true ; @@ -1817,15 +1831,19 @@ 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( cell.GetTopRight().x, m_mTree.at(j).GetBottomLeft().y) ; + Cell& cNeigh = m_mTree.at(j) ; + Point3d pt( cell.GetTopRight().x, cNeigh.GetBottomLeft().y) ; vVertices.push_back( pt) ; - vVertices3d.push_back( m_mVert[j][0]) ; + Point3d pt3d ; GetPoint( cNeigh.GetBottomLeft().x, cNeigh.GetBottomLeft().y, pt3d) ; + vVertices3d.push_back( pt3d) ; } } else { for ( int j : vNeigh) { - vVertices.push_back( m_mTree.at( j).GetBottomLeft()) ; - vVertices3d.push_back( m_mVert[j][0]) ; + Cell& cNeigh = m_mTree.at(j) ; + vVertices.push_back( cNeigh.GetBottomLeft()) ; + Point3d pt3d ; GetPoint( cNeigh.GetBottomLeft().x, cNeigh.GetBottomLeft().y, pt3d) ; + vVertices3d.push_back( pt3d) ; } } vbBonusVert[3] = true ; @@ -1834,12 +1852,14 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon else if ( ! bBottomRight) { Point3d ptBr( cell.GetTopRight().x, cell.GetBottomLeft().y) ; vVertices.push_back( ptBr) ; - vVertices3d.push_back( m_mVert[nId][1]) ; + Point3d pt3d ; GetPoint( cell.GetTopRight().x, cell.GetBottomLeft().y, pt3d) ; + vVertices3d.push_back( pt3d) ; vnVert.push_back( int(vVertices.size()) - 1) ; } vNeigh.clear() ; vVertices.push_back( cell.GetTopRight()) ; - vVertices3d.push_back( m_mVert[nId][2]) ; + pt3d = ORIG ; GetPoint( cell.GetTopRight().x, cell.GetTopRight().y, pt3d) ; + vVertices3d.push_back( pt3d) ; vnVert.push_back( int(vVertices.size()) - 1) ; GetTopNeigh ( nId, vNeigh) ; std::reverse( vNeigh.begin(), vNeigh.end()) ; @@ -1852,13 +1872,17 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon for ( int j : vNeigh) { Point3d pt( m_mTree.at( j).GetBottomLeft().x, cell.GetTopRight().y) ; vVertices.push_back( pt) ; - vVertices3d.push_back( m_mVert[j][0]) ; + Cell& cNeigh = m_mTree.at(j) ; + Point3d pt3d ; GetPoint( cNeigh.GetBottomLeft().x, cNeigh.GetBottomLeft().y, pt3d) ; + vVertices3d.push_back( pt3d) ; } } else { for ( int j : vNeigh) { vVertices.push_back( m_mTree.at( j).GetBottomLeft()) ; - vVertices3d.push_back( m_mVert[j][0]) ; + Cell& cNeigh = m_mTree.at(j) ; + Point3d pt3d ; GetPoint( cNeigh.GetBottomLeft().x, cNeigh.GetBottomLeft().y, pt3d) ; + vVertices3d.push_back( pt3d) ; } } bTopLeft = true ; @@ -1876,15 +1900,19 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon vnVert.push_back( int(vVertices.size())) ; if ( m_bClosedU && cell.m_bOnLeftEdge) { for ( int j : vNeigh) { - Point3d pt( cell.GetBottomLeft().x, m_mTree.at(j).GetTopRight().y) ; + Cell& cNeigh = m_mTree.at(j) ; + Point3d pt( cell.GetBottomLeft().x, cNeigh.GetTopRight().y) ; vVertices.push_back( pt) ; - vVertices3d.push_back( m_mVert[j][2]) ; + Point3d pt3d ; GetPoint( cNeigh.GetTopRight().x, cNeigh.GetTopRight().y, pt3d) ; + vVertices3d.push_back( pt3d) ; } } else { for ( int j : vNeigh) { - vVertices.push_back( m_mTree.at( j).GetTopRight()) ; - vVertices3d.push_back( m_mVert[j][2]) ; + Cell& cNeigh = m_mTree.at(j) ; + vVertices.push_back( cNeigh.GetTopRight()) ; + Point3d pt3d ; GetPoint( cNeigh.GetTopRight().x, cNeigh.GetTopRight().y, pt3d) ; + vVertices3d.push_back( pt3d) ; } } vbBonusVert[1] = true ; @@ -1893,12 +1921,14 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon else if ( ! bTopLeft) { Point3d ptTl( cell.GetBottomLeft().x, cell.GetTopRight().y) ; vVertices.push_back( ptTl) ; - vVertices3d.push_back( m_mVert[nId][3]) ; + Point3d pt3d ; GetPoint( cell.GetBottomLeft().x, cell.GetTopRight().y, pt3d) ; + vVertices3d.push_back( pt3d) ; vnVert.push_back( int(vVertices.size()) - 1) ; } vNeigh.clear() ; vVertices.push_back( cell.GetBottomLeft()) ; - vVertices3d.push_back( m_mVert[nId][0]) ; + pt3d = ORIG ; GetPoint( cell.GetBottomLeft().x, cell.GetBottomLeft().y, pt3d) ; + vVertices3d.push_back( pt3d) ; vnVert.push_back( int(vVertices.size()) - 1) ; BOOLVECTOR vbKeepPoint( vVertices.size()) ; @@ -1910,7 +1940,7 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon // ora devo controllare se uno dei lati della cella è collassato in un punto. // se così, devo guardare se sui due lati adiacenti a quello di polo ho messo dei punti extra // se ne ho messi solo su uno dei due allora devo togliere il vertice dell'altro lato - if ( AreSamePointApprox(m_mVert.at(nId).at(0), m_mVert.at(nId).at(1))) { + if ( AreSamePointApprox(ptP00, ptP10)) { // sennò devo togliere l'estremo del lato su cui NON ho punti bonus if ( vbBonusVert[1] && ! vbBonusVert[3]) {// lati contati a partire da quello sopra in senso CCW if ( ! m_bTrimmed) { @@ -1939,7 +1969,7 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon cell.m_nVertToErase = 1 ; // ptBr } } - if ( AreSamePointApprox(m_mVert.at(nId).at(1), m_mVert.at(nId).at(2))) { + if ( AreSamePointApprox(ptP10, ptP11)) { // sennò devo togliere l'estremo del lato su cui NON ho punti bonus if ( vbBonusVert[0] && ! vbBonusVert[2]){ // lati contati a partire da quello sopra in senso CCW if ( ! m_bTrimmed) { @@ -1964,7 +1994,7 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon cell.m_nVertToErase = 2 ; // ptTR } } - if ( AreSamePointApprox(m_mVert.at(nId).at(2), m_mVert.at(nId).at(3))) { + if ( AreSamePointApprox(ptP11, ptP01)) { // sennò devo togliere l'estremo del lato su cui NON ho punti bonus if ( vbBonusVert[1] && ! vbBonusVert[3]){ // lati contati a partire da quello sopra in senso CCW if ( ! m_bTrimmed) { @@ -1989,7 +2019,7 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon cell.m_nVertToErase = 3 ; // ptTl } } - if ( AreSamePointApprox(m_mVert.at(nId).at(3), m_mVert.at(nId).at(0))) { + if ( AreSamePointApprox(ptP01, ptP00)) { // sennò devo togliere l'estremo del lato su cui NON ho punti bonus if ( vbBonusVert[0] && ! vbBonusVert[2]) { // lati contati a partire da quello sopra in senso CCW if ( ! m_bTrimmed) { @@ -2024,15 +2054,11 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon // 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 && ( ! bForTriangulation || (bForTriangulation && vVerticesCorr.size() == 5))) { - Point3d ptPSrf, ptP00, ptP10, ptP11, ptP01 ; + Point3d ptPSrf ; double dU, dV ; dU = ( cell.GetBottomLeft().x + cell.GetTopRight().x) / 2 / SBZ_TREG_COEFF ; dV = ( cell.GetBottomLeft().y + cell.GetTopRight().y) / 2 / SBZ_TREG_COEFF ; - m_pSrfBz->GetPoint( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrf) ; - 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) ; + GetPoint( dU, dV, ptPSrf) ; 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 @@ -3024,14 +3050,22 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX // capisco se sono in modalità ForTriangulation bool bForTriangulation = plCell3d.GetPointNbr() != 0 ; if ( bForTriangulation) { - if( nVertToErase != 2) - vEdgeVertex3d[0].push_back( m_mVert[nId][2]) ; - if( nVertToErase != 3) - vEdgeVertex3d[1].push_back( m_mVert[nId][3]) ; - if( nVertToErase != 0) - vEdgeVertex3d[2].push_back( m_mVert[nId][0]) ; - if( nVertToErase != 1) - vEdgeVertex3d[3].push_back( m_mVert[nId][1]) ; + if( nVertToErase != 2) { + Point3d pt3d ; GetPoint( cCell.GetTopRight().x, cCell.GetTopRight().y, pt3d) ; + vEdgeVertex3d[0].push_back( pt3d) ; + } + if( nVertToErase != 3){ + Point3d pt3d ; GetPoint( cCell.GetBottomLeft().x, cCell.GetTopRight().y, pt3d) ; + vEdgeVertex3d[1].push_back( pt3d) ; + } + if( nVertToErase != 0) { + Point3d pt3d ; GetPoint( cCell.GetBottomLeft().x, cCell.GetBottomLeft().y, pt3d) ; + vEdgeVertex3d[2].push_back( pt3d) ; + } + if( nVertToErase != 1) { + Point3d pt3d ; GetPoint( cCell.GetTopRight().x, cCell.GetBottomLeft().y, pt3d) ; + vEdgeVertex3d[3].push_back( pt3d) ; + } } @@ -3395,10 +3429,15 @@ Tree::CreateIslandAndHoles( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATR vPolygons.push_back( vCellPolygons) ; ++ nPoly ; if ( bForTriangulation) { - plInLoop3d.AddUPoint( 0, m_mVert[nId][2]) ; - plInLoop3d.AddUPoint( 1, m_mVert[nId][3]) ; - plInLoop3d.AddUPoint( 2, m_mVert[nId][0]) ; - plInLoop3d.AddUPoint( 3, m_mVert[nId][1]) ; + Point3d ptP00, ptP10, ptP11, ptP01 ; + GetPoint( cCell.GetBottomLeft().x, cCell.GetBottomLeft().y, ptP00) ; + GetPoint( cCell.GetTopRight().x, cCell.GetBottomLeft().y, ptP10) ; + GetPoint( cCell.GetTopRight().x, cCell.GetTopRight().y, ptP11) ; + GetPoint( cCell.GetBottomLeft().x, cCell.GetTopRight().y, ptP01) ; + plInLoop3d.AddUPoint( 0, ptP11) ; + plInLoop3d.AddUPoint( 1, ptP01) ; + plInLoop3d.AddUPoint( 2, ptP00) ; + plInLoop3d.AddUPoint( 3, ptP10) ; plInLoop3d.Close() ; vCellPolygons3d.push_back( plInLoop3d) ; vPolygons3d.push_back( vCellPolygons3d) ; @@ -3418,7 +3457,7 @@ Tree::CreateIslandAndHoles( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATR for ( Point3d ptInt : inA.vpt) { plInLoop.AddUPoint( k, ptInt) ; if ( bForTriangulation) { - Point3d pt3d ; m_pSrfBz->GetPoint( ptInt.x / SBZ_TREG_COEFF, ptInt.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ; + Point3d pt3d ; GetPoint( ptInt.x, ptInt.y, pt3d) ; plInLoop3d.AddUPoint( k, pt3d) ; } ++ k ; @@ -3643,7 +3682,7 @@ Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVe plTrimmedPoly.AddUPoint( c, ptToAdd) ; if ( bForTriangulation) { Point3d pt3d ; - m_pSrfBz->GetPoint( ptToAdd.x / SBZ_TREG_COEFF, ptToAdd.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ; + GetPoint( ptToAdd.x, ptToAdd.y, pt3d) ; plTrimmedPoly3d.AddUPoint( c, pt3d) ; } ++ c ; @@ -3687,11 +3726,7 @@ Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVe if ( nVert != nVertToSkip) { plTrimmedPoly.AddUPoint( c, ptVert) ; if( bForTriangulation){ - Point3d pt3d ; - if ( nVert != -1) - pt3d = m_mVert.at(nId)[nVert] ; - else - m_pSrfBz->GetPoint( ptVert.x, ptVert.y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ; + Point3d pt3d ; GetPoint( ptVert.x, ptVert.y, pt3d) ; plTrimmedPoly3d.AddUPoint( c, pt3d) ; } ++ c ; @@ -3717,11 +3752,7 @@ Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVe if ( ! ( nVertToSkip == 3 && bVert)) { plTrimmedPoly.AddUPoint( c, ptToAdd) ; if( bForTriangulation){ - Point3d pt3d ; - if( ! bVert) - m_pSrfBz->GetPoint( ptToAdd.x / SBZ_TREG_COEFF, ptToAdd.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ; - else - pt3d = vEdgeVertex3d[1][0] ; + Point3d pt3d ; GetPoint( ptToAdd.x, ptToAdd.y, pt3d) ; plTrimmedPoly3d.AddUPoint( c, pt3d) ; } ++ c ; @@ -3742,11 +3773,7 @@ Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVe if ( ! ( nVertToSkip == 0 && bVert)) { plTrimmedPoly.AddUPoint( c, ptToAdd) ; if( bForTriangulation) { - Point3d pt3d ; - if( ! bVert) - m_pSrfBz->GetPoint( ptToAdd.x / SBZ_TREG_COEFF, ptToAdd.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ; - else - pt3d = vEdgeVertex3d[2][0] ; + Point3d pt3d ; GetPoint( ptToAdd.x, ptToAdd.y, pt3d) ; plTrimmedPoly3d.AddUPoint( c, pt3d) ; } ++ c ; @@ -3767,11 +3794,7 @@ Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVe if ( ! ( nVertToSkip == 1 && bVert)) { plTrimmedPoly.AddUPoint( c, ptToAdd) ; if( bForTriangulation){ - Point3d pt3d ; - if( ! bVert) - m_pSrfBz->GetPoint( ptToAdd.x / SBZ_TREG_COEFF, ptToAdd.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ; - else - pt3d = vEdgeVertex3d[3][0] ; + Point3d pt3d ; GetPoint( ptToAdd.x, ptToAdd.y, pt3d) ; plTrimmedPoly3d.AddUPoint( c, pt3d) ; } ++ c ; @@ -3792,11 +3815,7 @@ Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVe if ( ! ( nVertToSkip == 2 && bVert)) { plTrimmedPoly.AddUPoint( c, ptToAdd) ; if( bForTriangulation) { - Point3d pt3d ; - if( ! bVert) - m_pSrfBz->GetPoint( ptToAdd.x / SBZ_TREG_COEFF, ptToAdd.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ; - else - pt3d = vEdgeVertex3d[0][0] ; + Point3d pt3d ; GetPoint( ptToAdd.x, ptToAdd.y, pt3d) ; plTrimmedPoly3d.AddUPoint( c, pt3d) ; } ++ c ; @@ -3807,7 +3826,7 @@ Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVe else { plTrimmedPoly.AddUPoint( c, ptToAdd) ; if( bForTriangulation) { - Point3d pt3d ; m_pSrfBz->GetPoint( ptToAdd.x / SBZ_TREG_COEFF, ptToAdd.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ; + Point3d pt3d ; GetPoint( ptToAdd.x, ptToAdd.y, pt3d) ; plTrimmedPoly3d.AddUPoint( c, pt3d) ; } ++ c ; @@ -3817,7 +3836,7 @@ Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVe else { plTrimmedPoly.AddUPoint( c, ptToAdd) ; if( bForTriangulation) { - Point3d pt3d ; m_pSrfBz->GetPoint( ptToAdd.x / SBZ_TREG_COEFF, ptToAdd.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ; + Point3d pt3d ; GetPoint( ptToAdd.x, ptToAdd.y, pt3d) ; plTrimmedPoly3d.AddUPoint( c, pt3d) ; } ++ c ; @@ -4313,60 +4332,72 @@ Tree::GetEdges3D( POLYLINEMATRIX& mPLEdges) while ( ! AreSamePointXYApprox(pt, m_mTree.at(vEdges[0][c]).GetTopRight()) && mPL[i][c].GetNextPoint( pt)) { continue ; } - mPLEdges.back().back().AddUPoint( nPtCount, m_mVert.at(vEdges[0][c])[2]) ; + Cell& cNeigh = m_mTree.at(vEdges[0][c]) ; + Point3d pt3d ; GetPoint( cNeigh.GetTopRight().x, cNeigh.GetTopRight().y, pt3d) ; + mPLEdges.back().back().AddUPoint( nPtCount, pt3d) ; ++ nPtCount ; // scorro fino alla fine di quel lato while ( mPL[i][c].GetNextPoint( pt) && ! AreSamePointXYApprox(pt, m_mTree.at(vEdges[0][c]).GetTopLeft())) { - m_pSrfBz->GetPoint( pt.x / SBZ_TREG_COEFF, pt.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ; + GetPoint( pt.x, pt.y, pt3d) ; mPLEdges.back().back().AddUPoint( nPtCount, pt3d) ; ++ nPtCount ; } - mPLEdges.back().back().AddUPoint( nPtCount, m_mVert.at(vEdges[0][c])[3]) ; + pt3d = ORIG ; GetPoint( cNeigh.GetBottomLeft().x, cNeigh.GetTopRight().y, pt3d) ; + mPLEdges.back().back().AddUPoint( nPtCount, pt3d) ; ++ nPtCount ; } else if ( i == 1 ) { while ( ! AreSamePointXYApprox(pt, m_mTree.at(vEdges[1][c]).GetTopLeft()) && mPL[i][c].GetNextPoint( pt)) { continue ; } - mPLEdges.back().back().AddUPoint( nPtCount, m_mVert.at(vEdges[1][c])[3]) ; + Cell& cNeigh = m_mTree.at(vEdges[1][c]) ; + Point3d pt3d ; GetPoint( cNeigh.GetBottomLeft().x, cNeigh.GetTopRight().y, pt3d) ; + mPLEdges.back().back().AddUPoint( nPtCount, pt3d) ; ++ nPtCount ; // scorro fino alla fine di quel lato while ( mPL[i][c].GetNextPoint( pt) && ! AreSamePointXYApprox(pt, m_mTree.at(vEdges[1][c]).GetBottomLeft())) { - m_pSrfBz->GetPoint( pt.x / SBZ_TREG_COEFF, pt.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ; + GetPoint( pt.x, pt.y, pt3d) ; mPLEdges.back().back().AddUPoint( nPtCount, pt3d) ; ++ nPtCount ; } - mPLEdges.back().back().AddUPoint( nPtCount, m_mVert.at(vEdges[1][c])[0]) ; + pt3d = ORIG ; GetPoint( cNeigh.GetBottomLeft().x, cNeigh.GetBottomLeft().y, pt3d) ; + mPLEdges.back().back().AddUPoint( nPtCount, pt3d) ; ++ nPtCount ; } else if ( i == 2) { while ( ! AreSamePointXYApprox(pt, m_mTree.at(vEdges[2][c]).GetBottomLeft()) && mPL[i][c].GetNextPoint( pt)) { continue ; } - mPLEdges.back().back().AddUPoint( nPtCount, m_mVert.at(vEdges[2][c])[0]) ; + Cell& cNeigh = m_mTree.at(vEdges[2][c]) ; + Point3d pt3d ; GetPoint( cNeigh.GetBottomLeft().x, cNeigh.GetBottomLeft().y, pt3d) ; + mPLEdges.back().back().AddUPoint( nPtCount, pt3d) ; ++ nPtCount ; // scorro fino alla fine di quel lato while ( mPL[i][c].GetNextPoint( pt) && ! AreSamePointXYApprox(pt, m_mTree.at(vEdges[2][c]).GetBottomRight())) { - m_pSrfBz->GetPoint( pt.x / SBZ_TREG_COEFF, pt.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ; + GetPoint( pt.x, pt.y, pt3d) ; mPLEdges.back().back().AddUPoint( nPtCount, pt3d) ; ++ nPtCount ; } - mPLEdges.back().back().AddUPoint( nPtCount, m_mVert.at(vEdges[2][c])[1]) ; + pt3d = ORIG ; GetPoint( cNeigh.GetTopRight().x, cNeigh.GetBottomLeft().y, pt3d) ; + mPLEdges.back().back().AddUPoint( nPtCount, pt3d) ; ++ nPtCount ; } else if ( i == 3) { while ( ! AreSamePointXYApprox(pt, m_mTree.at(vEdges[3][c]).GetBottomRight()) && mPL[i][c].GetNextPoint( pt)) { continue ; } - mPLEdges.back().back().AddUPoint( nPtCount, m_mVert.at(vEdges[3][c])[1]) ; + Cell& cNeigh = m_mTree.at(vEdges[3][c]) ; + Point3d pt3d ; GetPoint( cNeigh.GetTopRight().x, cNeigh.GetBottomLeft().y, pt3d) ; + mPLEdges.back().back().AddUPoint( nPtCount, pt3d) ; ++ nPtCount ; // scorro fino alla fine di quel lato while ( mPL[i][c].GetNextPoint( pt) && ! AreSamePointXYApprox(pt, m_mTree.at(vEdges[3][c]).GetTopRight())) { - m_pSrfBz->GetPoint( pt.x / SBZ_TREG_COEFF, pt.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ; + GetPoint( pt.x, pt.y, pt3d) ; mPLEdges.back().back().AddUPoint( nPtCount, pt3d) ; ++ nPtCount ; } - mPLEdges.back().back().AddUPoint( nPtCount, m_mVert.at(vEdges[3][c])[2]) ; + pt3d = ORIG ; GetPoint( cNeigh.GetTopRight().x, cNeigh.GetTopRight().y, pt3d) ; + mPLEdges.back().back().AddUPoint( nPtCount, pt3d) ; ++ nPtCount ; } } @@ -4383,13 +4414,13 @@ Tree::GetEdges3D( POLYLINEMATRIX& mPLEdges) PolyLine pl3D ; int nInd = abs( vId[0]) - 1 ; Point3d pt2D = m_vCEdge2D[i].first[nInd].first ; - Point3d pt3D ; m_pSrfBz->GetPoint( pt2D.x / SBZ_TREG_COEFF, pt2D.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3D) ; + Point3d pt3D ; GetPoint( pt2D.x, pt2D.y, pt3D) ; pl3D.AddUPoint( 0, pt3D) ; int nCount = 1 ; for ( int j = 1 ; j < int( vId.size()) ; ++j) { nInd = abs( vId[j]) - 1 ; pt2D = m_vCEdge2D[i].first[nInd].second ; - m_pSrfBz->GetPoint( pt2D.x / SBZ_TREG_COEFF, pt2D.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3D) ; + GetPoint( pt2D.x, pt2D.y, pt3D) ; if ( pl3D.AddUPoint( nCount, pt3D)) ++ nCount ; } @@ -4532,10 +4563,15 @@ Tree::CreateCellContour( POLYLINEMATRIX& vPolygons) pl.AddUPoint(3, m_mTree.at(nRoot).GetBottomRight()) ; pl.Close() ; PolyLine pl3d ; - pl3d.AddUPoint(0, m_mVert.at(nRoot)[2]) ; - pl3d.AddUPoint(1, m_mVert.at(nRoot)[3]) ; - pl3d.AddUPoint(2, m_mVert.at(nRoot)[0]) ; - pl3d.AddUPoint(3, m_mVert.at(nRoot)[1]) ; + Cell& cRoot = m_mTree.at(nRoot) ; + Point3d pt3d11 ; GetPoint( cRoot.GetTopRight().x, cRoot.GetTopRight().y, pt3d11) ; + pl3d.AddUPoint(0, pt3d11) ; + Point3d pt3d01 ; GetPoint( cRoot.GetBottomLeft().x, cRoot.GetTopRight().y, pt3d01) ; + pl3d.AddUPoint(1, pt3d01) ; + Point3d pt3d00 ; GetPoint( cRoot.GetBottomLeft().x, cRoot.GetBottomLeft().y, pt3d00) ; + pl3d.AddUPoint(2, pt3d00) ; + Point3d pt3d10 ; GetPoint( cRoot.GetTopRight().x, cRoot.GetBottomLeft().y, pt3d10) ; + pl3d.AddUPoint(3, pt3d10) ; pl3d.Close() ; // ora posso creare il poligono della cella con i tagli POLYLINEMATRIX vPolygons3d ; diff --git a/Tree.h b/Tree.h index 8b307b1..95cc251 100644 --- a/Tree.h +++ b/Tree.h @@ -20,6 +20,15 @@ #include "/EgtDev/Include/EGkPolyLine.h" #include "/EgtDev/Include/EGkChainCurves.h" #include +#include + +struct PairHashInt64 { + size_t operator()(const pair& key) const { + size_t h1 = std::hash{}(key.first) ; + size_t h2 = std::hash{}(key.second) ; + return h1 ^ (h2 << 1); // Combine hashes + } +}; //---------------------------------------------------------------------------- struct Inters { @@ -299,16 +308,18 @@ class Tree bool CloseOpenCuts( POLYLINEVECTOR& vPL, PolyLine& pl) const ; bool VerifyLoopOrientation( ICURVEPLIST& vpCrv, BOOLVECTOR& vbOrientation) const ; // verifico l'orientazione ( CCW o CW) delle polyline in base a come sono contenute le une nelle altre bool AdjustLoop( PolyLine& pl, POLYLINEVECTOR& vPl, BOOLVECTOR& vbOrientation) const ; + bool GetPoint(double dU, double dV, Point3d& pt) const ; + bool SavePoint( double dU, double dV, Point3d& pt) ; private : const SurfBezier* m_pSrfBz ; // superficie di bezier 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::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 + //INTMATRIX m_vChunk ; // elenco dei loop divisi per chunk + unordered_map m_mChunk ; // mappa in cui vengono salvati chunk di appartenza per ogni loop di trim + //ICURVEPOVECTOR m_vLoop ; // curve di loop + vector> m_vPlApprox ; // vettore contenente le approssimazioni dei loop // il bool indica se la curva è CCW bool m_bBilinear ; // superficie bilineare bool m_bMulti ; // superficie multi-patch bool m_bClosedU ; // superficie chiusa lungo il parametro U @@ -321,12 +332,12 @@ class Tree int m_nSpanV ; // numero di span lungo il parametro V POLYLINEMATRIX m_vPolygons ; // matrice dei poligoni del tree POLYLINEMATRIX m_vPolygonsCorr ; // matrice dei poligoni del tree, corretti per i punti che sono nei poli - POLYLINEMATRIX m_vPolygons3d ; // matrice dei poligoni3d del tree - std::unordered_map m_mTree ; // mappa che contiene tutti i nodi e le foglie dell'albero. -2 è puntatore Null e -1 è root - std::unordered_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. I punti sono nell'ordine P00, P10, P11, P01 + POLYLINEMATRIX m_vPolygons3d ; // matrice dei poligoni3d del tree + unordered_map m_mTree ; // mappa che contiene tutti i nodi e le foglie dell'albero. -2 è puntatore Null e -1 è root + mutable unordered_map,Point3d, PairHashInt64> m_mPt3d ; // mappa che contiene tutti i punti 3d della superficie calcolati (la chiave sono le coordinate, moltiplicate per 2^24 e trasformate in int) INTVECTOR m_vnLeaves ; // vettore delle foglie INTVECTOR m_vnParents ; // vettore delle celle ottenute dalla divisione preliminare in singole patch bool m_bTestMode ; // bool che indica se la test mode è attiva POLYLINEVECTOR m_vPlLoop2D ; // vettore che contiene le polyline che rappresentano i loop di trim tenendo conto della divisione in celle - std::vector> m_vCEdge2D ; // vettore che le chain che rappresentano ciò che resta degli edge originali, tenendo conto dei trim. + vector> m_vCEdge2D ; // vettore che le chain che rappresentano ciò che resta degli edge originali, tenendo conto dei trim. } ; \ No newline at end of file