EgtGeomKernel :

- miglioramenti e correzione di alcuni bug nella triangolazione delle
superfici di bezier.
This commit is contained in:
Daniele Bariletti
2024-01-30 16:03:39 +01:00
parent cc312f1529
commit 3d326c9ca2
3 changed files with 93 additions and 26 deletions
+88 -25
View File
@@ -98,7 +98,11 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi
vChunk.push_back( nLoop) ;
// i chunk della falt region sono ancora flat region composte da 1 chunk
PtrOwner<ICurve> pLoop ( pChunk->GetLoop( 0, j)) ;
PtrOwner<ICurve> pCrv( pLoop->Clone()) ;
// rimuovo i difetti dei loop prima di salvarli
PtrOwner<ICurveComposite> pCrvCompo( GetBasicCurveComposite(pLoop->Clone())) ;
pCrvCompo->RemoveSmallDefects(dLinTol, dAngTolDeg, true) ;
pCrvCompo->RemoveSmallParts(dLinTol, dAngTolDeg) ;
PtrOwner<ICurve> pCrv( pCrvCompo->Clone()) ;
m_vLoop.emplace_back( Release( pLoop)) ;
m_mChunk[nLoop] = i ;
++ nLoop ;
@@ -1609,6 +1613,8 @@ Tree::FindCell( const Point3d& ptToAssign, const CurveLine& clTrim, bool bRecurs
// in cui individuare la foglia giusta
if ( (m_bSplitPatches && ( m_nSpanU > 1 || m_nSpanV > 1)) || m_bTestMode) {
INTVECTOR nParents = FindCell( ptToAssign, clTrim, m_vnParents) ;
if ( nParents.empty())
return nCells ;
nId = nParents.back() ;
if ( m_bTestMode ) {
nCells.push_back(nId) ;
@@ -1676,7 +1682,7 @@ Tree::FindCell( const Point3d& ptToAssign, const CurveLine& clTrim, bool bRecurs
//----------------------------------------------------------------------------
INTVECTOR
Tree::FindCell( const Point3d& ptToAssign, const CurveLine& cl, INTVECTOR vCells) const
Tree::FindCell( const Point3d& ptToAssign, const CurveLine& cl, INTVECTOR vCells, bool bRecurs) const
{
// se non trova nulla restituisce un vettore vuoto
// restituisce sempre solo una cella
@@ -1692,32 +1698,89 @@ Tree::FindCell( const Point3d& ptToAssign, const CurveLine& cl, INTVECTOR vCells
}
}
// se non ho trovato nulla vuol dire che sono su un vertice o su un lato
if ( (int)nCells.size() == 0 ) {
if ( (int)nCells.size() == 0 && ! bRecurs) {
int nEdge = -1 ;
for ( int nCell : vCells) {
if ( ptToAssign.x > m_mTree.at( nCell).GetBottomLeft().x - EPS_ZERO && ptToAssign.x < m_mTree.at( nCell).GetTopRight().x + EPS_ZERO &&
ptToAssign.y > m_mTree.at( nCell).GetBottomLeft().y - EPS_ZERO && ptToAssign.y < m_mTree.at( nCell).GetTopRight().y + EPS_ZERO) {
nId = nCell ;
nCells.push_back( nId) ;
OnWhichEdge( nCell,ptToAssign, nEdge) ;
if ( nEdge != -1)
break ;
}
Vector3d vtDir ;
cl.GetStartDir( vtDir) ;
Point3d ptIntersPlus = ptToAssign ;
// N.B. DESTRA e SINISTRA SONO SEMPRE RIFERITE al guardare nella direzione del vettore di partenza della curva di trim
// 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 ) {
Vector3d vtDirDX = vtDir ; vtDirDX.Rotate( Z_AX, -90) ;
ptIntersPlus = ptIntersPlus + vtDirDX * EPS_SMALL ;
}
else if ( (nEdge == 0 || nEdge == 2) && abs(vtDir.y) > EPS_SMALL)
ptIntersPlus.y += Sign( vtDir.y) * EPS_SMALL ;
else if ( ( nEdge == 1 || nEdge == 3 ) && abs(vtDir.y) > 1 - EPS_SMALL ) {
Vector3d vtDirDX = vtDir ; vtDirDX.Rotate( Z_AX, -90) ;
ptIntersPlus = ptIntersPlus + vtDirDX * EPS_SMALL ;
}
else if ( (nEdge == 1 || nEdge == 3) && abs(vtDir.x) > EPS_SMALL)
ptIntersPlus.x += Sign( vtDir.x) * 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 )
ptIntersPlus = ptIntersPlus + vtDir * EPS_SMALL ;
// altrimenti ruoto a destra
else {
Vector3d vtDirDX = vtDir ; vtDirDX.Rotate( Z_AX, -45) ;
ptIntersPlus = ptIntersPlus + vtDirDX * EPS_SMALL ;
}
}
if ( (int)nCells.size() == 1)
return nCells ;
// sono su vertice o un lato, quindi avanzo con il parametro lungo la curva
else if ( (int)nCells.size() >= 1 ) {
// la CurveLine è il segmento di trim su cui giace ptToAssign
Point3d ptIntersPlus ;
Vector3d vtDir ;
cl.GetStartDir( vtDir) ;
// mi sposto appena più avanti di ptToAssign
// se la curva è orientata come l'asse x o y mi sto muovendo su un lato e sarò ancora sul lato, quindi dovrei ruotare il vettore prima di spostarmi
if ( abs( vtDir.x) >= 1 - EPS_SMALL || abs( vtDir.y) >= 1 - EPS_SMALL)
vtDir.Rotate( Z_AX, -45) ;
ptIntersPlus = ptToAssign + vtDir * EPS_SMALL ;
nCells = FindCell( ptIntersPlus, cl, vCells) ;
}
// se vuoto allora il punto non è in nessuna delle celle passate in input
//
else
return nCells ;
// controllo di non essere uscito dallo spazio parametrico (in tal caso riparto da ptToAssign e mi muovo a sinistra)
if ( ptIntersPlus.x < m_mTree.at( -1).GetBottomLeft().x || ptIntersPlus.x > m_mTree.at( -1).GetTopRight().x ||
ptIntersPlus.y < m_mTree.at( -1).GetBottomLeft().y || ptIntersPlus.y > m_mTree.at( -1).GetTopRight().y) {
Vector3d vtDirSX = vtDir ; vtDirSX.Rotate(Z_AX, 45) ;
ptIntersPlus = ptToAssign + vtDirSX * EPS_SMALL ;
}
// rilancio la rigida ricerca
nCells = FindCell( ptIntersPlus, cl, vCells, true) ;
/////////////////////////// questa versione funziona, ma forse potrebbe fallire in alcuni casi///
// for ( int nCell : vCells) {
// if ( ptToAssign.x > m_mTree.at( nCell).GetBottomLeft().x - EPS_SMALL && ptToAssign.x < m_mTree.at( nCell).GetTopRight().x + EPS_SMALL &&
// ptToAssign.y > m_mTree.at( nCell).GetBottomLeft().y - EPS_SMALL && ptToAssign.y < m_mTree.at( nCell).GetTopRight().y + EPS_SMALL) {
// nId = nCell ;
// nCells.push_back( nId) ;
// }
// }
// if ( (int)nCells.size() == 1)
// return nCells ;
// // sono su vertice o un lato, quindi avanzo con il parametro lungo la curva
// else if ( (int)nCells.size() > 1 ) {
// // la CurveLine è il segmento di trim su cui giace ptToAssign
// Point3d ptIntersPlus ;
// Vector3d vtDir ;
// cl.GetStartDir( vtDir) ;
// // mi sposto appena più avanti di ptToAssign
// // se la curva è orientata come l'asse x o y mi sto muovendo su un lato e sarò ancora sul lato, quindi dovrei ruotare il vettore a destra prima di spostarmi
// if ( abs( vtDir.x) >= 1 - EPS_SMALL || abs( vtDir.y) >= 1 - EPS_SMALL)
// vtDir.Rotate( Z_AX, -45) ;
// ptIntersPlus = ptToAssign + vtDir * EPS_SMALL ;
// // se sono finito fuori dallo spazio parametrico giro invece a sinistra
// if ( ptIntersPlus.x < m_mTree.at( -1).GetBottomLeft().x - EPS_SMALL || ptIntersPlus.x > m_mTree.at( -1).GetTopRight().x + EPS_SMALL||
// ptIntersPlus.y < m_mTree.at( -1).GetBottomLeft().y - EPS_SMALL || ptIntersPlus.y > m_mTree.at( -1).GetTopRight().y + EPS_SMALL) {
// vtDir.Rotate( Z_AX, 90) ;
// ptIntersPlus = ptToAssign + vtDir * EPS_SMALL ;
// }
// nCells = FindCell( ptIntersPlus, cl, vCells) ;
// }
//// se vuoto allora il punto non è in nessuna delle celle passate in input
// else
// return nCells ;
//////////////////////////////////////////////////////////////////////////
}
return nCells ;
@@ -1752,8 +1815,8 @@ Tree::TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons)
if ( ! nCells.empty())
nId = nCells.back() ;
else
// il loop è fuori dalla cella root che sto analizzando
continue ;
// il loop è risultato fuori dallo spazio parametrico
return false ;
int nFirstCell = nId ;
// trovo quali punti della polyline sono nella cella e l'intersezione
PNTVECTOR vptInters ;