EgtGeomKernel :

- correzione ulteriore alla triangolazione delle superfici bezier con patch con lati collassati.
This commit is contained in:
Daniele Bariletti
2024-06-07 17:41:39 +02:00
parent e32b85bc2d
commit e2008bd479
+70 -11
View File
@@ -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