diff --git a/Tree.cpp b/Tree.cpp index 34cd085..8e72991 100644 --- a/Tree.cpp +++ b/Tree.cpp @@ -222,6 +222,7 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi m_mChunk.clear() ; m_vPlApprox.clear() ; m_vPolygons.clear() ; + m_vPolygonsCorr.clear() ; m_vPlLoop2D.clear() ; m_pSrfBz = pSrfBz ; @@ -1589,33 +1590,43 @@ Tree::GetPolygons( POLYLINEMATRIX& vvPolygons, bool bForTriangulation, POLYLINEM if ( ! m_bTrimmed) { vvPolygons.clear() ; POLYLINEVECTOR vPolygonsBasic ; + POLYLINEVECTOR vPolygonsCorrected ; POLYLINEVECTOR vPolygonsBasic3d ; if ( bForTriangulation) - GetPolygonsBasic( vPolygonsBasic, vPolygonsBasic3d) ; + GetPolygonsBasic( vPolygonsBasic, vPolygonsCorrected, vPolygonsBasic3d) ; else GetPolygonsBasic( vPolygonsBasic) ; int c = 0; - for ( PolyLine pl : vPolygonsBasic) { - POLYLINEVECTOR vSinglePolygon ; - vSinglePolygon.push_back( pl) ; - vvPolygons.push_back( vSinglePolygon) ; - if ( bForTriangulation) { + if( bForTriangulation) { + for ( PolyLine pl : vPolygonsCorrected) { + POLYLINEVECTOR vSinglePolygon ; + vSinglePolygon.push_back( pl) ; + vvPolygons.push_back( vSinglePolygon) ; POLYLINEVECTOR vSinglePolygon3d ; vSinglePolygon3d.push_back( vPolygonsBasic3d[c]) ; vvPolygons3d.push_back( vSinglePolygon3d) ; + ++c ; + } + } + else { + for ( PolyLine pl : vPolygonsBasic) { + POLYLINEVECTOR vSinglePolygon ; + vSinglePolygon.push_back( pl) ; + vvPolygons.push_back( vSinglePolygon) ; + ++c ; } - ++c ; } return true ; } // trimmata else { POLYLINEVECTOR vPolygonsBasic ; - GetPolygonsBasic( vPolygonsBasic) ; - POLYLINEVECTOR vPolygons ; + POLYLINEVECTOR vPolygonsCorrected ; POLYLINEVECTOR vPolygonsBasic3d ; if ( bForTriangulation) - GetPolygonsBasic( vPolygons, vPolygonsBasic3d) ; + GetPolygonsBasic( vPolygonsBasic, vPolygonsCorrected, vPolygonsBasic3d) ; + else + GetPolygonsBasic( vPolygonsBasic) ; // aggiungo 4 elementi al vettore che contiene ciò che resta degli edge dopo il trim m_vCEdge2D.clear() ; for ( int i = 0 ; i < 4 ; ++i) { @@ -1633,7 +1644,10 @@ Tree::GetPolygons( POLYLINEMATRIX& vvPolygons, bool bForTriangulation, POLYLINEM if ( m_mTree[nId].m_nFlag == 4) { // vettore dei poligoni ( loop) della cella nId POLYLINEVECTOR vCellPolygons ; - vCellPolygons.push_back( vPolygonsBasic[i]) ; + if( bForTriangulation) + vCellPolygons.push_back( vPolygonsCorrected[i]) ; + else + vCellPolygons.push_back( vPolygonsBasic[i]) ; vvPolygons.push_back( vCellPolygons) ; if ( bForTriangulation ) { POLYLINEVECTOR vCellPolygons3d ; @@ -1642,6 +1656,7 @@ Tree::GetPolygons( POLYLINEMATRIX& vvPolygons, bool bForTriangulation, POLYLINEM plPolygon3d.AddUPoint( 1, m_mVert[nId][1]) ; plPolygon3d.AddUPoint( 2, m_mVert[nId][2]) ; plPolygon3d.AddUPoint( 3, m_mVert[nId][3]) ; + plPolygon3d.AddUPoint( 0, m_mVert[nId][0]) ; vCellPolygons3d.push_back( plPolygon3d) ; vvPolygons3d.push_back( vCellPolygons3d) ; } @@ -1664,7 +1679,10 @@ Tree::GetPolygons( POLYLINEMATRIX& vvPolygons, bool bForTriangulation, POLYLINEM PolyLine pl3d ; if( bForTriangulation) pl3d = vPolygonsBasic3d[i] ; - CreateCellPolygons( i, vvPolygons, vvPolygons3d, vToCheck, nPoly, vnParentChunk, vPolygonsBasic[i], pl3d) ; + if( bForTriangulation) + CreateCellPolygons( i, vvPolygons, vvPolygons3d, vToCheck, nPoly, vnParentChunk, vPolygonsCorrected[i], pl3d) ; + else + CreateCellPolygons( i, vvPolygons, vvPolygons3d, vToCheck, nPoly, vnParentChunk, vPolygonsBasic[i], pl3d) ; if ( nPolyBefore == nPoly) break ; } @@ -1683,24 +1701,28 @@ Tree::GetPolygons( POLYLINEMATRIX& vvPolygons, bool bForTriangulation, POLYLINEM //---------------------------------------------------------------------------- bool -Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, POLYLINEVECTOR& vPolygons3d) +Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygonsCorrected, POLYLINEVECTOR& vPolygons3d) { - return GetPolygonsBasic( vPolygons, true, vPolygons3d) ; + return GetPolygonsBasic( vPolygonsBasic, vPolygonsCorrected, true, vPolygons3d) ; } //---------------------------------------------------------------------------- bool -Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, INTVECTOR vCells) +Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, INTVECTOR vCells) { POLYLINEVECTOR vPolygons3d ; - return GetPolygonsBasic( vPolygons, false, vPolygons3d, vCells) ; + POLYLINEVECTOR vPolygonsCorrected ; + return GetPolygonsBasic( vPolygonsBasic, vPolygonsCorrected, false, vPolygons3d, vCells) ; } //---------------------------------------------------------------------------- bool -Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, bool bForTriangulation, POLYLINEVECTOR& vPolygons3d, INTVECTOR vCells) +Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygonsCorrected, bool bForTriangulation, POLYLINEVECTOR& vPolygons3d, INTVECTOR vCells) { // condizioni per il calcolo dei poligoni di base + PNTVECTOR vVertices ; + PNTVECTOR vVerticesCorr ; + PNTVECTOR vVertices3d ; if ( m_vPolygons.empty() || // se non li ho mai calcolati ( ! m_vPolygons.empty() && ! vCells.empty()) || // se ho già calcolato dei poligoni ma ne sto chiedendo di un altro gruppo di celle ( vCells.empty() && m_vPolygons.size() != m_vnLeaves.size()) || // se sto chiedendo i poligoni di tutte le celle, ma i poligoni già calcolati sono meno delle celle @@ -1711,8 +1733,6 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, bool bForTriangulation, POLYL if ( vCells.empty()) vCells = m_vnLeaves ; - PNTVECTOR vVertices ; - PNTVECTOR vVertices3d ; INTVECTOR vNeigh ; // setto le celle che sono sul LeftEdge e sul TopEdge if ( m_bClosedU) { @@ -1861,7 +1881,8 @@ 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 + // se non è trimmata aggiusto subito il vettore dei vertici, sennò i salvo le informazioni per quando creerò i poligoni trimmato + vVerticesCorr = vVertices ; 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 @@ -1872,7 +1893,7 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, bool bForTriangulation, POLYL // 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 if ( ! m_bTrimmed) { - vVertices.erase(vVertices.begin() + vnVert[1]) ; // vertici della cella contati a partire da ptBL in senso CCW + vVerticesCorr.erase(vVerticesCorr.begin() + vnVert[1]) ; // vertici della cella contati a partire da ptBL in senso CCW vVertices3d.erase(vVertices3d.begin() + vnVert[1]) ; } vbKeepPoint[vnVert[1]] = false ; @@ -1881,8 +1902,8 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, bool bForTriangulation, POLYL else if ( vbBonusVert[3] ) { 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] ; + vVerticesCorr.pop_back() ; + vVerticesCorr[0] = vVerticesCorr.end()[-1] ; vVertices3d.pop_back() ; vVertices3d[0] = vVertices3d.end()[-1] ; } @@ -1898,7 +1919,7 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, bool bForTriangulation, POLYL // 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 if ( ! m_bTrimmed) { - vVertices.erase(vVertices.begin() + vnVert[1]) ; // vertici della cella contati a partire da ptBL in senso CCW + vVerticesCorr.erase(vVerticesCorr.begin() + vnVert[1]) ; // vertici della cella contati a partire da ptBL in senso CCW vVertices3d.erase(vVertices3d.begin() + vnVert[1]) ; } vbKeepPoint[vnVert[1]] = false ; @@ -1906,7 +1927,7 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, bool bForTriangulation, POLYL } else if ( vbBonusVert[2] ){ if ( ! m_bTrimmed) { - vVertices.erase(vVertices.begin() + vnVert[2]) ; + vVerticesCorr.erase(vVerticesCorr.begin() + vnVert[2]) ; vVertices3d.erase(vVertices3d.begin() + vnVert[2]) ; } vbKeepPoint[vnVert[2]] = false ; @@ -1920,7 +1941,7 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, bool bForTriangulation, POLYL // 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 if ( ! m_bTrimmed) { - vVertices.erase(vVertices.begin() + vnVert[2]) ; // vertici della cella contati a partire da ptBL in senso CCW + vVerticesCorr.erase(vVerticesCorr.begin() + vnVert[2]) ; // vertici della cella contati a partire da ptBL in senso CCW vVertices3d.erase(vVertices3d.begin() + vnVert[2]) ; } vbKeepPoint[vnVert[2]] = false ; @@ -1928,7 +1949,7 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, bool bForTriangulation, POLYL } else if ( vbBonusVert[3] ) { if ( ! m_bTrimmed) { - vVertices.erase(vVertices.begin() + vnVert[3]) ; + vVerticesCorr.erase(vVerticesCorr.begin() + vnVert[3]) ; vVertices3d.erase(vVertices3d.begin() + vnVert[3]) ; } vbKeepPoint[vnVert[3]] = false ; @@ -1943,8 +1964,8 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, bool bForTriangulation, POLYL if ( vbBonusVert[0] ) { // lati contati a partire da quello sopra in senso CCW 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] ; + vVerticesCorr.pop_back() ; + vVerticesCorr[0] = vVerticesCorr.end()[-1] ; vVertices3d.pop_back() ; vVertices3d[0] = vVertices3d.end()[-1] ; } @@ -1954,7 +1975,7 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, bool bForTriangulation, POLYL } else if ( vbBonusVert[2] ) { if ( ! m_bTrimmed) { - vVertices.erase(vVertices.begin() + vnVert[3]) ; + vVerticesCorr.erase(vVerticesCorr.begin() + vnVert[3]) ; vVertices3d.erase(vVertices3d.begin() + vnVert[3]) ; } vbKeepPoint[vnVert[3]] = false ; @@ -1967,7 +1988,7 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, bool bForTriangulation, POLYL if ( ! m_bTrimmed) { // 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) { + if ( vVertices.size() == 5 && ( ! bForTriangulation || (bForTriangulation && vVerticesCorr.size() == 5))) { Point3d ptPSrf, ptP00, ptP10, ptP11, ptP01 ; double dU, dV ; dU = ( m_mTree.at( nId).GetBottomLeft().x + m_mTree.at( nId).GetTopRight().x) / 2 / SBZ_TREG_COEFF ; @@ -1987,20 +2008,28 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, bool bForTriangulation, POLYL vVertices3d.back() = vVertices3d.at( 0) ; rotate( vbKeepPoint.begin(), vbKeepPoint.begin() + 1,vbKeepPoint.end()) ; vbKeepPoint.back() = vbKeepPoint.at( 0) ; + rotate( vVerticesCorr.begin(), vVerticesCorr.begin() + 1,vVerticesCorr.end()) ; + vVerticesCorr.back() = vVerticesCorr.at( 0) ; } } } m_vPolygons.emplace_back() ; m_vPolygons.back().emplace_back() ; + m_vPolygonsCorr.emplace_back() ; + m_vPolygonsCorr.back().emplace_back() ; m_vPolygons3d.emplace_back() ; m_vPolygons3d.back().emplace_back() ; + int nVertCorr = int(vVerticesCorr.size()); for ( int i = 0 ; i < (int) vVertices.size() ; ++i) { int dPar = i ; if( ! vbKeepPoint[i]) dPar = -1 ; m_vPolygons.back().back().AddUPoint( dPar, vVertices.at( i)) ; - m_vPolygons3d.back().back().AddUPoint( dPar, vVertices3d.at( i)) ; + if( bForTriangulation && i < nVertCorr){ + m_vPolygonsCorr.back().back().AddUPoint( dPar, vVerticesCorr.at( i)) ; + m_vPolygons3d.back().back().AddUPoint( dPar, vVertices3d.at( i)) ; + } } } @@ -2009,8 +2038,11 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, bool bForTriangulation, POLYL // restituisco i poligoni delle celle del tree nello spazio parametrico for ( int t = 0 ; t < (int)m_vPolygons.size() ; ++ t) { for ( int z = 0 ; z < (int)m_vPolygons[t].size() ; ++z) { - vPolygons.push_back( m_vPolygons[t][z]) ; - vPolygons3d.push_back( m_vPolygons3d[t][z]) ; + vPolygonsBasic.push_back( m_vPolygons[t][z]) ; + if( bForTriangulation) { + vPolygonsCorrected.push_back( m_vPolygonsCorr[t][z]) ; + vPolygons3d.push_back( m_vPolygons3d[t][z]) ; + } } } return true ; @@ -3082,10 +3114,17 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX vEdgeVertex[j].push_back( ptToAdd) ; } else { - while ( plCell.GetNextPoint( ptToAdd) && plCell3d.GetNextPoint( pt3d) && ! AreSamePointExact( ptToAdd, ptNextVert)) { + double dPar = 0 ; + bool bAdvanced = false ; + while ( plCell.GetNextUPoint( &dPar, &ptToAdd) && ! AreSamePointExact( ptToAdd, ptNextVert)) { vEdgeVertex[j].push_back( ptToAdd) ; + if ( dPar > 0) + plCell3d.GetNextPoint( pt3d) ; vEdgeVertex3d[j].push_back( pt3d) ; + bAdvanced = true ; } + if ( ! bAdvanced && dPar > 0) + plCell3d.GetNextPoint( pt3d) ; } } @@ -3621,8 +3660,20 @@ bool Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVertex3d, PolyLine& plTrimmedPoly, int& c, const Point3d& ptToAdd, PolyLine& plTrimmedPoly3d, bool bForTriangulation) const { + Point3d ptBr = m_mTree.at(nId).GetBottomRight() ; + 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 ; // se è il primo punto della PolyLine lo aggiungo if ( plTrimmedPoly.GetPointNbr() == 0) { + // se cerco di aggiungere il vertice che devo saltare, non faccio nulla + if( ( nVertToSkip == 0 && AreSamePointApprox( ptToAdd, ptBL)) || + ( nVertToSkip == 1 && AreSamePointApprox( ptToAdd, ptBr)) || + ( nVertToSkip == 2 && AreSamePointApprox( ptToAdd, ptTR)) || + ( nVertToSkip == 3 && AreSamePointApprox( ptToAdd, ptTl))) + return true ; + plTrimmedPoly.AddUPoint( c, ptToAdd) ; if ( bForTriangulation) { Point3d pt3d ; @@ -3632,11 +3683,6 @@ Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVe ++ c ; return true ; } - Point3d ptBr = m_mTree.at(nId).GetBottomRight() ; - 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 diff --git a/Tree.h b/Tree.h index 4cbc176..59d769c 100644 --- a/Tree.h +++ b/Tree.h @@ -242,10 +242,10 @@ class Tree bool GetPolygons( POLYLINEMATRIX& vvPolygons) ; bool GetPolygons( POLYLINEMATRIX& vvPolygons, POLYLINEMATRIX& vvPolygons3d) ; bool GetPolygons( POLYLINEMATRIX& vPolygons, bool bForTriangulation, POLYLINEMATRIX& vvPolygons3d) ; - bool GetPolygonsBasic( POLYLINEVECTOR& vPolygons, bool bForTriangulation, POLYLINEVECTOR& vPolygons3d, INTVECTOR vCells = {}) ; // 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 - // se richiesti per la triangolazione ad alcuni poligoni potrebbero venire tolti dei punti per evitare errori dovuti ad eventuali poli sui bordi del parametrico - bool GetPolygonsBasic( POLYLINEVECTOR& vPolygons, POLYLINEVECTOR& vPolygons3d) ; + bool GetPolygonsBasic( POLYLINEVECTOR& vPolygons, POLYLINEVECTOR& vPolygonsCorrected, // restituisce il poligono corrispondente ad ogni cella foglia dell'albero + bool bForTriangulation, POLYLINEVECTOR& vPolygons3d, INTVECTOR vCells = {}) ; // ad ogni poligono sono stati aggiunti tutti i vertici dei vicini posizionati sui suoi lati + // se richiesti per la triangolazione ad alcuni poligoni potrebbero venire tolti dei punti per evitare errori dovuti ad eventuali poli sui bordi del parametrico + bool GetPolygonsBasic( POLYLINEVECTOR& vPolygons, POLYLINEVECTOR& vPolygonsCorrected, POLYLINEVECTOR& vPolygons3d) ; bool GetPolygonsBasic( POLYLINEVECTOR& vPolygons, INTVECTOR vCells = {}) ; bool GetLeaves ( std::vector& vLeaves) const ; // restituisce gli indici delle foglie nell'albero bool GetEdges3D ( POLYLINEMATRIX& mPLEdges) ; // restituisce gli edge 3D come polyline @@ -317,6 +317,7 @@ class Tree int m_nSpanU ; // numero di span lungo il parametro U 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