From e2008bd479c3de739aa0794659a3c2e966e89823 Mon Sep 17 00:00:00 2001 From: Daniele Bariletti Date: Fri, 7 Jun 2024 17:41:39 +0200 Subject: [PATCH] EgtGeomKernel : - correzione ulteriore alla triangolazione delle superfici bezier con patch con lati collassati. --- Tree.cpp | 81 ++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 70 insertions(+), 11 deletions(-) diff --git a/Tree.cpp b/Tree.cpp index 5b4be0f..f005dbe 100644 --- a/Tree.cpp +++ b/Tree.cpp @@ -1674,6 +1674,10 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, INTVECTOR vCells) vVertices.clear() ; vNeigh.clear() ; vVertices.push_back( m_mTree.at( nId).GetBottomLeft()) ; + INTVECTOR vnVert ; + BOOLVECTOR vbBonusVert(4) ; + fill( vbBonusVert.begin(), vbBonusVert.end(), false) ; + vnVert.push_back( int(vVertices.size()) - 1) ; GetBottomNeigh( nId, vNeigh) ; // aggiungo i vertici che sono sul lato bottom, solo se ho più di un vicino bottom if ( (int) vNeigh.size() != 0 && (int) vNeigh.size() != 1){ @@ -1690,6 +1694,7 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, INTVECTOR vCells) vVertices.push_back( m_mTree.at( j).GetTopRight()) ; } bBottomRight = true ; + vbBonusVert[2] = true ; } else bBottomRight = false ; @@ -1699,6 +1704,7 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, INTVECTOR vCells) if ( (int) vNeigh.size() != 0 && (int) vNeigh.size() != 1){ // se la superficie è chiusa lungo il parametro U e le celle vicine right sono sul lato Left // devo aggiungere i vertici tenendo conto della periodicità dello spazio parametrico. + vnVert.push_back( int(vVertices.size())) ; if ( m_bClosedU && m_mTree.at( vNeigh[0]).m_bOnLeftEdge ) { for ( int j : vNeigh) { Point3d pt( m_mTree.at( nId).GetTopRight().x, m_mTree.at(j).GetBottomLeft().y) ; @@ -1709,24 +1715,24 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, INTVECTOR vCells) for ( int j : vNeigh) vVertices.push_back( m_mTree.at( j).GetBottomLeft()) ; } - + vbBonusVert[3] = true ; } // se non l'ho già aggiunto tramite i vicini bottom aggiungo il punto bottom right - // controllo anche che ptBL e ptBr non coincidano ( nel 3D). Altrimenti vuol dire che quel lato della cella è su un lato di polo e basta aggiungere un punto solo - else if ( ! bBottomRight && ! AreSamePointApprox( m_mVert.at(nId).at(0), m_mVert.at(nId).at(1)) ) { + else if ( ! bBottomRight) { Point3d ptBr( m_mTree.at( nId).GetTopRight().x, m_mTree.at( nId).GetBottomLeft().y) ; vVertices.push_back( ptBr) ; + vnVert.push_back( int(vVertices.size()) - 1) ; } vNeigh.clear() ; - // se il lato destro della cella non sta su un lato di polo ( ptTR != ptBr nel 3D) allora aggiungo anche ptTR - if( ! AreSamePointApprox( m_mVert.at(nId).at(1), m_mVert.at(nId).at(2))) - vVertices.push_back( m_mTree.at( nId).GetTopRight()) ; + vVertices.push_back( m_mTree.at( nId).GetTopRight()) ; + vnVert.push_back( int(vVertices.size()) - 1) ; GetTopNeigh ( nId, vNeigh) ; std::reverse( vNeigh.begin(), vNeigh.end()) ; // aggiungo i vertici che sono sul lato top, solo se ho più di un vicino top if ( ! vNeigh.empty() && vNeigh.size() != 1) { // se la superficie è chiusa lungo il parametro V e la cella è sul lato top // devo aggiungere i vertici tenendo conto della periodicità dello spazio parametrico. + vnVert.push_back( int(vVertices.size())) ; if ( m_bClosedV && m_mTree.at( nId).m_bOnTopEdge) { for ( int j : vNeigh) { Point3d pt( m_mTree.at( j).GetBottomLeft().x, m_mTree.at( nId).GetTopRight().y) ; @@ -1738,6 +1744,7 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, INTVECTOR vCells) vVertices.push_back( m_mTree.at( j).GetBottomLeft()) ; } bTopLeft = true ; + vbBonusVert[0] = true ; } else bTopLeft = false ; @@ -1748,6 +1755,7 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, INTVECTOR vCells) if ( (int) vNeigh.size() != 0 && (int) vNeigh.size() != 1) { // se la superficie è chiusa lungo il parametro U e la cella è sul lato left // devo aggiungere i vertici tenendo conto della periodicità dello spazio parametrico. + vnVert.push_back( int(vVertices.size())) ; if ( m_bClosedU && m_mTree.at( nId).m_bOnLeftEdge) { for ( int j : vNeigh) { Point3d pt( m_mTree.at( nId).GetBottomLeft().x, m_mTree.at(j).GetTopRight().y) ; @@ -1758,17 +1766,68 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, INTVECTOR vCells) for ( int j : vNeigh) vVertices.push_back( m_mTree.at( j).GetTopRight()) ; } + vbBonusVert[1] = true ; } // se non l'ho già aggiunto tramite i vicini top aggiungo il punto top left - // controllo anche che ptTl e ptTR non coincidano ( nel 3D). Altrimenti vuol dire che quel lato della cella è su un lato di polo e basta aggiungere un punto solo - else if ( ! bTopLeft && ! AreSamePointApprox( m_mVert.at(nId).at(2), m_mVert.at(nId).at(3))) { + else if ( ! bTopLeft) { Point3d ptTl( m_mTree.at( nId).GetBottomLeft().x, m_mTree.at( nId).GetTopRight().y) ; vVertices.push_back( ptTl) ; + vnVert.push_back( int(vVertices.size()) - 1) ; } vNeigh.clear() ; - // se il lato sinistro della cella non sta su un lato di polo ( ptTR != ptBr nel 3D) allora aggiungo anche ptTR - if( ! AreSamePointApprox( m_mVert.at(nId).at(3), m_mVert.at(nId).at(0))) - vVertices.push_back( m_mTree.at( nId).GetBottomLeft()) ; + vVertices.push_back( m_mTree.at( nId).GetBottomLeft()) ; + vnVert.push_back( int(vVertices.size()) - 1) ; + + // 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)) && ( vbBonusVert[1] || vbBonusVert[3])) { + // se ho punti bonus su entrambi i lati non devo fare nulla + 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 + 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] ; + } + } + } + if ( AreSamePointApprox(m_mVert.at(nId).at(1), m_mVert.at(nId).at(2)) && ( vbBonusVert[0] || vbBonusVert[2])) { + // se ho punti bonus su entrambi i lati non devo fare nulla + 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 + else if ( vbBonusVert[2]) + vVertices.erase( vVertices.begin() + vnVert[2]) ; + } + } + if ( AreSamePointApprox(m_mVert.at(nId).at(2), m_mVert.at(nId).at(3)) && ( vbBonusVert[1] || vbBonusVert[3])) { + // se ho punti bonus su entrambi i lati non devo fare nulla + 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 + else if ( vbBonusVert[3]) + vVertices.erase( vVertices.begin() + vnVert[3]) ; + } + } + if ( AreSamePointApprox(m_mVert.at(nId).at(3), m_mVert.at(nId).at(0)) && ( vbBonusVert[0] || vbBonusVert[2])) { + // se ho punti bonus su entrambi i lati non devo fare nulla + 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] ; + } + else if ( vbBonusVert[2]) + vVertices.erase( vVertices.begin() + vnVert[3]) ; + } + } + 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