diff --git a/SurfBezier.cpp b/SurfBezier.cpp index 513306f..d17618f 100644 --- a/SurfBezier.cpp +++ b/SurfBezier.cpp @@ -1530,6 +1530,10 @@ SurfBezier::GetAuxSurf( void) const // vvPL.back().push_back(vPL[k]) ; //} //// per usare i polygon basic/////////////////// + + // qui non sarebbe male stampare un messaggio di errore nel log se avevo un'area da disegnare ma non sono usciti dei poligoni + if ( int(vvPL.size()) == 0) + LOG_DBG_ERR( GetEGkLogger(), "ERROR : Bezier Surface couldn't be triangulated, hence wasn't drawn") ; StmFromTriangleSoup stmSoup ; if ( ! stmSoup.Start()) diff --git a/Tree.cpp b/Tree.cpp index 387568c..1771f7c 100644 --- a/Tree.cpp +++ b/Tree.cpp @@ -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 pLoop ( pChunk->GetLoop( 0, j)) ; - PtrOwner pCrv( pLoop->Clone()) ; + // rimuovo i difetti dei loop prima di salvarli + PtrOwner pCrvCompo( GetBasicCurveComposite(pLoop->Clone())) ; + pCrvCompo->RemoveSmallDefects(dLinTol, dAngTolDeg, true) ; + pCrvCompo->RemoveSmallParts(dLinTol, dAngTolDeg) ; + PtrOwner 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 ; diff --git a/Tree.h b/Tree.h index d9ff804..da648dc 100644 --- a/Tree.h +++ b/Tree.h @@ -189,7 +189,7 @@ class Tree void GetRootNeigh( int nEdge, INTVECTOR& vNeigh) ; // restituisce le foglie dell'albero che sono adiacenti al lato nEdge, numerato a partire dal top ( 0) in senso antiorario void ResetTree( void) ; // resetto m_bProcessed a false per tutti i nodi dell'albero INTVECTOR FindCell( const Point3d& ptToAssign, const CurveLine& cl, bool bRecurs = false) const ; // dato un punto, trova la cella foglia a cui appartiene - INTVECTOR FindCell( const Point3d& ptToAssign, const CurveLine& cl, INTVECTOR vCells) const ; // dato un punto, trova la cella foglia a cui appartiene + INTVECTOR FindCell( const Point3d& ptToAssign, const CurveLine& cl, INTVECTOR vCells, bool bRecurs = false) const ; // dato un punto, trova la cella foglia a cui appartiene bool TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons) ; // tracing dei loop e labelling delle celle bool FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool bFirstInters = true) ; // trova le intersezioni tra una cella e una linea di trim // resituisce l'id della cella verso cui la curva di trim esce e il vettore delle intersezioni per la cella successiva con il primo punto