diff --git a/Tree.cpp b/Tree.cpp index 3f9ee28..34cd085 100644 --- a/Tree.cpp +++ b/Tree.cpp @@ -242,8 +242,9 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi // creo la cella Root Point3d ptTop( nSpanU * SBZ_TREG_COEFF, nSpanV * SBZ_TREG_COEFF) ; bool bLimited = false ; - if ( ! AreSamePointExact( ptMax,ORIG) && ! AreSamePointExact( ptMax,ptTop)) { - ptTop = ptMax ; + if ( ! AreSamePointExact( ptMax,ORIG)) { + if ( ! AreSamePointExact( ptMax,ptTop)) + ptTop = ptMax ; bLimited = true ; } Cell cRoot( ptMin, ptTop) ; @@ -1860,6 +1861,7 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, bool bForTriangulation, POLYL BOOLVECTOR vbKeepPoint( vVertices.size()) ; fill( vbKeepPoint.begin(), vbKeepPoint.end(), true) ; + // se non è trimmata aggiusto subito il vettore dei vertici, sennò i salvo le informazioni per qunado creerò il poligoni trimmato if ( bForTriangulation){ // 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 @@ -1869,17 +1871,21 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, bool bForTriangulation, POLYL if ( !( vbBonusVert[1] && vbBonusVert[3] ) ) { // sennò devo togliere l'estremo del lato su cui NON ho punti bonus if ( vbBonusVert[1] ) {// lati contati a partire da quello sopra in senso CCW - //vVertices.erase(vVertices.begin() + vnVert[1]) ; // vertici della cella contati a partire da ptBL in senso CCW - //vVertices3d.erase(vVertices3d.begin() + vnVert[1]) ; + if ( ! m_bTrimmed) { + vVertices.erase(vVertices.begin() + vnVert[1]) ; // vertici della cella contati a partire da ptBL in senso CCW + vVertices3d.erase(vVertices3d.begin() + vnVert[1]) ; + } vbKeepPoint[vnVert[1]] = false ; m_mTree[nId].m_nVertToErase = 1 ; // ptBr } else if ( vbBonusVert[3] ) { - //// dovrei eliminare ptBL, quindi devo eliminare il primo e l'ultimo punto della polyline e poi chiuderla con quello che era il penultimo punto - //vVertices.pop_back() ; - //vVertices[0] = vVertices.end()[-1] ; - //vVertices3d.pop_back() ; - //vVertices3d[0] = vVertices3d.end()[-1] ; + if ( ! m_bTrimmed) { + // dovrei eliminare ptBL, quindi devo eliminare il primo e l'ultimo punto della polyline e poi chiuderla con quello che era il penultimo punto + vVertices.pop_back() ; + vVertices[0] = vVertices.end()[-1] ; + vVertices3d.pop_back() ; + vVertices3d[0] = vVertices3d.end()[-1] ; + } vbKeepPoint[0] = false ; vbKeepPoint.back() = false ; m_mTree[nId].m_nVertToErase = 0 ; // ptBL @@ -1891,14 +1897,18 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, bool bForTriangulation, POLYL if ( !( vbBonusVert[0] && vbBonusVert[2] ) ) { // sennò devo togliere l'estremo del lato su cui NON ho punti bonus if ( vbBonusVert[0] ){ // lati contati a partire da quello sopra in senso CCW - //vVertices.erase(vVertices.begin() + vnVert[1]) ; // vertici della cella contati a partire da ptBL in senso CCW - //vVertices3d.erase(vVertices3d.begin() + vnVert[1]) ; + if ( ! m_bTrimmed) { + vVertices.erase(vVertices.begin() + vnVert[1]) ; // vertici della cella contati a partire da ptBL in senso CCW + vVertices3d.erase(vVertices3d.begin() + vnVert[1]) ; + } vbKeepPoint[vnVert[1]] = false ; m_mTree[nId].m_nVertToErase = 1 ; // ptBr } else if ( vbBonusVert[2] ){ - //vVertices.erase(vVertices.begin() + vnVert[2]) ; - //vVertices3d.erase(vVertices3d.begin() + vnVert[2]) ; + if ( ! m_bTrimmed) { + vVertices.erase(vVertices.begin() + vnVert[2]) ; + vVertices3d.erase(vVertices3d.begin() + vnVert[2]) ; + } vbKeepPoint[vnVert[2]] = false ; m_mTree[nId].m_nVertToErase = 2 ; // ptTR } @@ -1909,14 +1919,18 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, bool bForTriangulation, POLYL if ( !( vbBonusVert[1] && vbBonusVert[3] ) ) { // sennò devo togliere l'estremo del lato su cui NON ho punti bonus if ( vbBonusVert[1] ){ // lati contati a partire da quello sopra in senso CCW - //vVertices.erase(vVertices.begin() + vnVert[2]) ; // vertici della cella contati a partire da ptBL in senso CCW - //vVertices3d.erase(vVertices3d.begin() + vnVert[2]) ; + if ( ! m_bTrimmed) { + vVertices.erase(vVertices.begin() + vnVert[2]) ; // vertici della cella contati a partire da ptBL in senso CCW + vVertices3d.erase(vVertices3d.begin() + vnVert[2]) ; + } vbKeepPoint[vnVert[2]] = false ; m_mTree[nId].m_nVertToErase = 2 ; // ptTR } else if ( vbBonusVert[3] ) { - //vVertices.erase(vVertices.begin() + vnVert[3]) ; - //vVertices3d.erase(vVertices3d.begin() + vnVert[3]) ; + if ( ! m_bTrimmed) { + vVertices.erase(vVertices.begin() + vnVert[3]) ; + vVertices3d.erase(vVertices3d.begin() + vnVert[3]) ; + } vbKeepPoint[vnVert[3]] = false ; m_mTree[nId].m_nVertToErase = 3 ; // ptTl } @@ -1927,18 +1941,22 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, bool bForTriangulation, POLYL if ( !( vbBonusVert[0] && vbBonusVert[2] ) ) { // sennò devo togliere l'estremo del lato su cui NON ho punti bonus if ( vbBonusVert[0] ) { // lati contati a partire da quello sopra in senso CCW - //// dovrei eliminare ptBL, quindi devo eliminare il primo e l'ultimo punto della polyline e poi chiuderla con quello che era il penultimo punto - //vVertices.pop_back() ; - //vVertices[0] = vVertices.end()[-1] ; - //vVertices3d.pop_back() ; - //vVertices3d[0] = vVertices3d.end()[-1] ; + if ( ! m_bTrimmed) { + // dovrei eliminare ptBL, quindi devo eliminare il primo e l'ultimo punto della polyline e poi chiuderla con quello che era il penultimo punto + vVertices.pop_back() ; + vVertices[0] = vVertices.end()[-1] ; + vVertices3d.pop_back() ; + vVertices3d[0] = vVertices3d.end()[-1] ; + } vbKeepPoint[0] = false ; vbKeepPoint.back() = false ; m_mTree[nId].m_nVertToErase = 0 ; // ptBL } else if ( vbBonusVert[2] ) { - //vVertices.erase(vVertices.begin() + vnVert[3]) ; - //vVertices3d.erase(vVertices3d.begin() + vnVert[3]) ; + if ( ! m_bTrimmed) { + vVertices.erase(vVertices.begin() + vnVert[3]) ; + vVertices3d.erase(vVertices3d.begin() + vnVert[3]) ; + } vbKeepPoint[vnVert[3]] = false ; m_mTree[nId].m_nVertToErase = 3 ; // ptTl } @@ -3115,12 +3133,14 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX vLast.Normalize() ; Vector3d vEdge ; // estendo: se l'ultimo tratto è sovrapposto e controverso allora elimino l'ultimo punto + bool bNotEquiverseOverlap = false ; if ( nEdge == 0 || nEdge == 7 ) { vEdge.Set( 1,0,0) ; if ( AreOppositeVectorApprox( vLast, vEdge)) { plTrimmedPoly.EraseLastUPoint() ; plTrimmedPoly3d.EraseLastUPoint() ; nEdge = 0 ; + bNotEquiverseOverlap = true ; } } else if ( nEdge == 1 || nEdge == 4 ) { @@ -3129,6 +3149,7 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX plTrimmedPoly.EraseLastUPoint() ; plTrimmedPoly3d.EraseLastUPoint() ; nEdge = 1 ; + bNotEquiverseOverlap = true ; } } else if ( nEdge == 2 || nEdge == 5 ) { @@ -3137,6 +3158,7 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX plTrimmedPoly.EraseLastUPoint() ; plTrimmedPoly3d.EraseLastUPoint() ; nEdge = 2 ; + bNotEquiverseOverlap = true ; } } else if ( nEdge == 3 || nEdge == 6 ) { @@ -3145,12 +3167,13 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX plTrimmedPoly.EraseLastUPoint() ; plTrimmedPoly3d.EraseLastUPoint() ; nEdge = 3 ; + bNotEquiverseOverlap = true ; } } // se mi è rimasto solo un punto sulla polyline vuol dire che avevo solo un tratto parallelo ad lato // quindi salto al prossimo loop - if ( plTrimmedPoly.GetPointNbr() == 1) { + if ( plTrimmedPoly.GetPointNbr() == 1 && bNotEquiverseOverlap) { plTrimmedPoly.Clear() ; plTrimmedPoly3d.Clear() ; if ( j == nFirstLoopInPoly) @@ -3613,6 +3636,7 @@ Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVe Point3d ptTR = m_mTree.at(nId).GetTopRight() ; Point3d ptTl = m_mTree.at(nId).GetTopLeft() ; Point3d ptBL = m_mTree.at(nId).GetBottomLeft() ; + int nVertToSkip = m_mTree.at(nId).m_nVertToErase ; Point3d ptLast ; plTrimmedPoly.GetLastPoint( ptLast) ; // verifico di essere allineato con un lato, sennò aggiungo e basta @@ -3624,6 +3648,7 @@ Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVe // se non riesco a normalizzare perché sono troppo vicino ad un vertice allora aggiungo direttamente il vertice if ( ! vDir.Normalize()) { plTrimmedPoly.EraseLastUPoint() ; + plTrimmedPoly3d.EraseLastUPoint() ; Point3d ptVert ; int nVert = -1 ; if ( AreSamePointApprox( ptToAdd, ptBr)){ @@ -3644,16 +3669,18 @@ Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVe } else ptVert = ptToAdd ; - plTrimmedPoly.AddUPoint( c, ptVert) ; - if( bForTriangulation){ - Point3d pt3d ; - if ( nVert != -1) - pt3d = m_mVert.at(nId)[nVert] ; - else - m_pSrfBz->GetPointD1D2( ptVert.x, ptVert.y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ; - plTrimmedPoly3d.AddUPoint( c, pt3d) ; + if ( nVert != nVertToSkip) { + plTrimmedPoly.AddUPoint( c, ptVert) ; + if( bForTriangulation){ + Point3d pt3d ; + if ( nVert != -1) + pt3d = m_mVert.at(nId)[nVert] ; + else + m_pSrfBz->GetPointD1D2( ptVert.x, ptVert.y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ; + plTrimmedPoly3d.AddUPoint( c, pt3d) ; + } + ++ c ; } - ++ c ; return true ; } if ( abs( vDir.x) > 1 - EPS_SMALL || abs( vDir.y) > 1 - EPS_SMALL) { @@ -3669,16 +3696,19 @@ Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVe ++ c ; } } - plTrimmedPoly.AddUPoint( c, ptToAdd) ; - if( bForTriangulation){ - Point3d pt3d ; - if( ! AreSamePointApprox(ptToAdd, ptTl)) - m_pSrfBz->GetPointD1D2( ptToAdd.x / SBZ_TREG_COEFF, ptToAdd.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ; - else - pt3d = vEdgeVertex3d[1][0] ; - plTrimmedPoly3d.AddUPoint( c, pt3d) ; + bool bVert = AreSamePointApprox( ptToAdd, ptTl) ; + if ( ! ( nVertToSkip == 3 && bVert)) { + plTrimmedPoly.AddUPoint( c, ptToAdd) ; + if( bForTriangulation){ + Point3d pt3d ; + if( ! bVert) + m_pSrfBz->GetPointD1D2( ptToAdd.x / SBZ_TREG_COEFF, ptToAdd.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ; + else + pt3d = vEdgeVertex3d[1][0] ; + plTrimmedPoly3d.AddUPoint( c, pt3d) ; + } + ++ c ; } - ++ c ; } // edge 1 else if ( ptToAdd.y >= ptBL.y && ptToAdd.y <= ptTR.y && ptToAdd.x == ptBL.x && abs( vDir.y) > 1 - EPS_SMALL) { @@ -3691,16 +3721,19 @@ Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVe ++ c ; } } - plTrimmedPoly.AddUPoint( c, ptToAdd) ; - if( bForTriangulation) { - Point3d pt3d ; - if( ! AreSamePointApprox(ptToAdd, ptBL)) - m_pSrfBz->GetPointD1D2( ptToAdd.x / SBZ_TREG_COEFF, ptToAdd.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ; - else - pt3d = vEdgeVertex3d[2][0] ; - plTrimmedPoly3d.AddUPoint( c, pt3d) ; + bool bVert = AreSamePointApprox( ptToAdd, ptBL) ; + if ( ! ( nVertToSkip == 0 && bVert)) { + plTrimmedPoly.AddUPoint( c, ptToAdd) ; + if( bForTriangulation) { + Point3d pt3d ; + if( ! bVert) + m_pSrfBz->GetPointD1D2( ptToAdd.x / SBZ_TREG_COEFF, ptToAdd.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ; + else + pt3d = vEdgeVertex3d[2][0] ; + plTrimmedPoly3d.AddUPoint( c, pt3d) ; + } + ++ c ; } - ++ c ; } // edge 2 else if ( ptToAdd.x >= ptBL.x && ptToAdd.x <= ptTR.x && ptToAdd.y == ptBL.y && abs( vDir.x) > 1 - EPS_SMALL) { @@ -3713,16 +3746,19 @@ Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVe ++ c ; } } - plTrimmedPoly.AddUPoint( c, ptToAdd) ; - if( bForTriangulation){ - Point3d pt3d ; - if( ! AreSamePointApprox(ptToAdd, ptBr)) - m_pSrfBz->GetPointD1D2( ptToAdd.x / SBZ_TREG_COEFF, ptToAdd.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ; - else - pt3d = vEdgeVertex3d[3][0] ; - plTrimmedPoly3d.AddUPoint( c, pt3d) ; + bool bVert = AreSamePointApprox( ptToAdd, ptBr) ; + if ( ! ( nVertToSkip == 1 && bVert)) { + plTrimmedPoly.AddUPoint( c, ptToAdd) ; + if( bForTriangulation){ + Point3d pt3d ; + if( ! bVert) + m_pSrfBz->GetPointD1D2( ptToAdd.x / SBZ_TREG_COEFF, ptToAdd.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ; + else + pt3d = vEdgeVertex3d[3][0] ; + plTrimmedPoly3d.AddUPoint( c, pt3d) ; + } + ++ c ; } - ++ c ; } // edge 3 else if ( ptToAdd.y >= ptBL.y && ptToAdd.y <= ptTR.y && ptToAdd.x == ptTR.x && abs( vDir.y) > 1 - EPS_SMALL) { @@ -3735,16 +3771,19 @@ Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVe ++ c ; } } - plTrimmedPoly.AddUPoint( c, ptToAdd) ; - if( bForTriangulation) { - Point3d pt3d ; - if( ! AreSamePointApprox(ptToAdd, ptTR)) - m_pSrfBz->GetPointD1D2( ptToAdd.x / SBZ_TREG_COEFF, ptToAdd.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ; - else - pt3d = vEdgeVertex3d[0][0] ; - plTrimmedPoly3d.AddUPoint( c, pt3d) ; + bool bVert = AreSamePointApprox( ptToAdd, ptTR) ; + if ( ! ( nVertToSkip == 2 && bVert)) { + plTrimmedPoly.AddUPoint( c, ptToAdd) ; + if( bForTriangulation) { + Point3d pt3d ; + if( ! bVert) + m_pSrfBz->GetPointD1D2( ptToAdd.x / SBZ_TREG_COEFF, ptToAdd.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ; + else + pt3d = vEdgeVertex3d[0][0] ; + plTrimmedPoly3d.AddUPoint( c, pt3d) ; + } + ++ c ; } - ++ c ; } // sono allineato con un lato, ma NON sono su un lato // aggiungo e basta diff --git a/Tree.h b/Tree.h index 7d6a1e8..4cbc176 100644 --- a/Tree.h +++ b/Tree.h @@ -318,8 +318,8 @@ class Tree int m_nSpanV ; // numero di span lungo il parametro V POLYLINEMATRIX m_vPolygons ; // matrice dei poligoni del tree POLYLINEMATRIX m_vPolygons3d ; // matrice dei poligoni3d del tree - std::map m_mTree ; // mappa che contiene tutti i nodi e le foglie dell'albero. -2 è puntatore Null e -1 è root - std::map m_mVert ; // mappa che contiene tutti i vertici 3d delle celle del tree. L'Id è lo stesso che la cella ha in m_mTree. I punti sono nell'ordine P00, P10, P11, P01 + 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 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