EgtGeomKernel :

- correzione alla triangolazione di sup. di Bezier con patch con lati collassati in un polo.
This commit is contained in:
Daniele Bariletti
2024-06-07 16:00:24 +02:00
parent 35fc94d8cb
commit e32b85bc2d
2 changed files with 23 additions and 17 deletions
+15 -9
View File
@@ -1712,12 +1712,15 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, INTVECTOR vCells)
}
// se non l'ho già aggiunto tramite i vicini bottom aggiungo il punto bottom right
else if ( ! bBottomRight) {
// 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)) ) {
Point3d ptBr( m_mTree.at( nId).GetTopRight().x, m_mTree.at( nId).GetBottomLeft().y) ;
vVertices.push_back( ptBr) ;
}
vNeigh.clear() ;
vVertices.push_back( m_mTree.at( nId).GetTopRight()) ;
// 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()) ;
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
@@ -1757,12 +1760,15 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, INTVECTOR vCells)
}
}
// se non l'ho già aggiunto tramite i vicini top aggiungo il punto top left
else if ( ! bTopLeft) {
// 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))) {
Point3d ptTl( m_mTree.at( nId).GetBottomLeft().x, m_mTree.at( nId).GetTopRight().y) ;
vVertices.push_back( ptTl) ;
}
vNeigh.clear() ;
vVertices.push_back( m_mTree.at( nId).GetBottomLeft()) ;
// 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()) ;
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
@@ -1932,23 +1938,23 @@ Tree::FindCell( const Point3d& ptToAssign, const CurveLine& cl, INTVECTOR vCells
// potrei essere su un lato
if ( nEdge == 0 || nEdge == 1 || nEdge == 2 || nEdge == 3) {
// se è orientato con il lato mi sposto a destra
if ( ( nEdge == 0 || nEdge == 2 ) && abs(vtDir.x) > 1 - EPS_SMALL ) {
if ( ( nEdge == 0 || nEdge == 2 ) && abs(vtDir.x) > 1 - EPS_SMALL/100 ) {
Vector3d vtDirDX = vtDir ; vtDirDX.Rotate( Z_AX, -90) ;
ptIntersPlus = ptIntersPlus + vtDirDX * EPS_SMALL ;
}
else if ( (nEdge == 0 || nEdge == 2) && abs(vtDir.y) > EPS_SMALL)
else if ( (nEdge == 0 || nEdge == 2) && abs(vtDir.y) > EPS_SMALL/100)
ptIntersPlus.y += (vtDir.y > 0 ? 1 : -1) * EPS_SMALL ;
else if ( ( nEdge == 1 || nEdge == 3 ) && abs(vtDir.y) > 1 - EPS_SMALL ) {
else if ( ( nEdge == 1 || nEdge == 3 ) && abs(vtDir.y) > 1 - EPS_SMALL/100 ) {
Vector3d vtDirDX = vtDir ; vtDirDX.Rotate( Z_AX, -90) ;
ptIntersPlus = ptIntersPlus + vtDirDX * EPS_SMALL ;
}
else if ( (nEdge == 1 || nEdge == 3) && abs(vtDir.x) > EPS_SMALL)
else if ( (nEdge == 1 || nEdge == 3) && abs(vtDir.x) > EPS_SMALL/100)
ptIntersPlus.x += (vtDir.x > 0 ? 1 : -1) * EPS_SMALL ;
}
// o in un vertice
else if ( nEdge == 4 || nEdge == 5 || nEdge == 6 || nEdge == 7) {
// se non è orientato con gli assi procedo con la direzione del trim
if ( abs(vtDir.x) < 1 - EPS_SMALL && abs(vtDir.y) < 1 - EPS_SMALL )
if ( abs(vtDir.x) < 1 - EPS_SMALL/100 && abs(vtDir.y) < 1 - EPS_SMALL/100 )
ptIntersPlus = ptIntersPlus + vtDir * EPS_SMALL ;
// altrimenti ruoto a destra
else {
+8 -8
View File
@@ -185,9 +185,9 @@ class Cell
{ return Point3d( m_ptPtr.x, m_ptPbl.y); }
double GetSplitValue( void) const
{ return m_dSplit ; }
bool IsSplitVert( void) const // se true la cella verrebbe splittata verticalmente, senn orizzontalmente
bool IsSplitVert( void) const // se true la cella verrebbe splittata verticalmente, sennò orizzontalmente
{ return m_bSplitVert ; }
bool IsLeaf( void) const // flag che indica se la cella ha figli o se una foglia
bool IsLeaf( void) const // flag che indica se la cella ha figli o se è una foglia
{ return ( m_nChild1 == -2 && m_nChild2 == -2) ; }
bool IsProcessed( void) const // flag che indica se tutti i figli della cella, se ce ne sono, sono stati processati
{ return m_bProcessed ; }
@@ -235,8 +235,8 @@ class Tree
Tree( const Point3d ptBl, const Point3d ptTr) ; // creatore da usare solo nel caso in cui si voglia aggiungere tagli ad un'unica cella e del risultato ottenere il contorno
bool SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches = true, const Point3d& ptMin = ORIG, const Point3d& ptMax = ORIG) ;
bool GetIndependentTrees( BIPNTVECTOR& vTrees) ; // calcolo la suddivisione della superficie solo sulle singole bbox dei loop di trim ( unendo quelli vicini)
bool BuildTree( double dLinTol = LIN_TOL_STD, double dSideMin = 1, double dSideMax = INFINITO) ; // dSideMax il massimo per la dimensione maggiore di un triangolo della trimesh
// dSideMin lunghezza minima del lato di una cella nello spazio reale
bool BuildTree( double dLinTol = LIN_TOL_STD, double dSideMin = 1, double dSideMax = INFINITO) ; // dSideMax è il massimo per la dimensione maggiore di un triangolo della trimesh
// dSideMin è lunghezza minima del lato di una cella nello spazio reale
bool BuildTree_test( double dLinTol = LIN_TOL_STD, double dSideMin = 1, double dSideMax = INFINITO) ;
bool GetPolygons( POLYLINEMATRIX& vPolygons) ;
bool GetPolygonsBasic( POLYLINEVECTOR& vPolygons, INTVECTOR vCells = {}) ; // restituisce il poligono corrispondente ad ogni cella foglia dell'albero
@@ -256,8 +256,8 @@ class Tree
private :
bool LimitLoop( PolyLine& pl, POLYLINEVECTOR& vPl, BOOLVECTOR& vbOrientation) const ; // funzione che limita i loop di trim allo spazio parametrico
bool Split( int nId, double dSplitValue) ; // funzione di split di una cella al parametro indicato nella direzione data da bVert
bool Split( int nId) ; // funzione di split di una cella dell'albero a met nella direzione data da bVert
void Balance( void) ; // creo rami in modo che tutte tutte le foglie abbiano come adiacenti foglie ad una profondit di +- 1
bool Split( int nId) ; // funzione di split di una cella dell'albero a metà nella direzione data da bVert
void Balance( void) ; // creo rami in modo che tutte tutte le foglie abbiano come adiacenti foglie ad una profondità di +- 1
int GetHeightLeaves( int nId, INTVECTOR& vnLeaves, int d = 0) const ; // altezza del subtree a partire dal nodo nId
int GetDepth( int nId, int nRef) const ; // livello del nodo nId
void GetTopNeigh( int nId, INTVECTOR& vTopNeighs) const ; // restituisce le celle foglie che sono adiacenti al lato top
@@ -310,8 +310,8 @@ 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
std::map<int,Cell> m_mTree ; // mappa che contiene tutti i nodi e le foglie dell'albero. -2 puntatore Null e -1 root
std::map<int,PNTVECTOR> m_mVert ; // mappa che contiene tutti i vertici 3d delle celle del tree. L'Id lo stesso che la cella ha in m_mTree
std::map<int,Cell> m_mTree ; // mappa che contiene tutti i nodi e le foglie dell'albero. -2 è puntatore Null e -1 è root
std::map<int,PNTVECTOR> 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