EgtGeomKernel :

- correzioni e miglioramenti per la triangolazione bezier.
This commit is contained in:
Daniele Bariletti
2024-07-24 09:27:38 +02:00
parent 0a8f26c993
commit 89c22ffd06
2 changed files with 91 additions and 44 deletions
+86 -40
View File
@@ -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