diff --git a/SurfBezier.cpp b/SurfBezier.cpp index b005b74..25b86b4 100644 --- a/SurfBezier.cpp +++ b/SurfBezier.cpp @@ -1511,10 +1511,12 @@ SurfBezier::GetAuxSurf( void) const Point3d ptMin = std::get<0>( vTrees[i]) ; Point3d ptMax = std::get<1>( vTrees[i]) ; Tree.SetSurf( this, true, ptMin, ptMax) ; - //Tree.BuildTree_test() ; // per debug - //Tree.BuildTree( 5 * LIN_TOL_FINE, 1) ; - Tree.BuildTree( 5 * LIN_TOL_FINE, 0.1) ; + Tree.BuildTree_test() ; // per debug + Tree.BuildTree( 5 * LIN_TOL_FINE, 1) ; // per debug + // + //Tree.BuildTree( 5 * LIN_TOL_FINE, 0.1) ; // per ENDER Tree.GetPolygons( vvPL) ; + // //Tree.GetPolygonsBasic( vPL) ; // per usare i polygon basic } //// per usare i polygon basic////////////////////// @@ -1575,9 +1577,9 @@ SurfBezier::GetLeaves( std::vector>& vLeaves) Point3d ptMin = std::get<0>( vTrees[i]) ; Point3d ptMax = std::get<1>( vTrees[i]) ; Tree.SetSurf( this, true, ptMin, ptMax) ; - //Tree.BuildTree_test() ; - //Tree.BuildTree( 5 * LIN_TOL_FINE, 1) ; - Tree.BuildTree( 5 * LIN_TOL_FINE, 0.1) ; + Tree.BuildTree_test() ; // per debug + Tree.BuildTree( 5 * LIN_TOL_FINE, 1) ; // per debug + //Tree.BuildTree( 5 * LIN_TOL_FINE, 0.1) ; // per ENDER Tree.GetLeaves( vCells) ; for (int k = 0 ; k < (int)vCells.size(); ++ k ) { std::tuple tCell ; diff --git a/Tree.cpp b/Tree.cpp index a6ffae9..e0340ef 100644 --- a/Tree.cpp +++ b/Tree.cpp @@ -25,6 +25,10 @@ #include "/EgtDev/Include/EGkDistPointCurve.h" #include "/EgtDev/Include/EGkCurve.h" #include "DistPointCrvComposite.h" +///////////per debug +//#include "/EgtDev/Include/EGkStringUtils3d.h" +//#include "/EgtDev/Include/EExDllMain.h" +///////////per debug //---------------------------------------------------------------------------- Cell::Cell( void) @@ -239,8 +243,6 @@ Tree::SetSurf( const SurfBezier* pSrfBz, const bool bSplitPatches, const Point3d } } vLeaves.clear() ; - GetHeightLeaves( -1, vLeaves) ; - m_vnParents = vLeaves ; } // controllo se la superficie è chiusa. // se è chiusa e non ho già fatto split preliminare, splitto sul parametro su cui è chiusa @@ -318,6 +320,10 @@ Tree::SetSurf( const SurfBezier* pSrfBz, const bool bSplitPatches, const Point3d } } } + // calcolo i parent che ho creato con le eventuali divisioni preliminari + INTVECTOR vLeaves ; + GetHeightLeaves( -1, vLeaves) ; + m_vnParents = vLeaves ; // calcolo e salvo la lunghezza reale delle curve di bezier di bordo PtrOwner pCrvV0( m_pSrfBz->GetCurveOnU( 0)) ; @@ -1428,7 +1434,12 @@ Tree::GetPolygons( std::vector& vPolygons) { // scorro sulle celle e costruisco i poligoni int nCells = (int)vPolygonsBasic.size() ; for ( int i = 0 ; i < nCells ; ++i) { - + + ///////////per debug + //std::string sOut = std::to_string( i) ; + //LOG_ERROR( GetEGkLogger(), sOut.c_str()) ; + ///////////per debug + // // costruisco i poligoni partendo dal vettore delle intersezioni, come spiegato a pag15 di Cripps int nId = m_vnLeaves[i] ; if ( m_mTree[nId].m_nFlag == 4) { @@ -1638,7 +1649,7 @@ Tree::ResetTree( void) //---------------------------------------------------------------------------- INTVECTOR -Tree::FindCell( const Point3d& ptToAssign, const CurveLine& clTrim) const +Tree::FindCell( const Point3d& ptToAssign, const CurveLine& clTrim, bool bRecurs) const { INTVECTOR nCells ; int nId = -1 ; @@ -1679,26 +1690,31 @@ Tree::FindCell( const Point3d& ptToAssign, const CurveLine& clTrim) const } nCells.push_back( nId) ; - - // se sono in un vertice o su un lato devo controllare di aver trovato la cella giusta - Point3d ptBr( m_mTree.at( nId).GetTopRight().x , m_mTree.at( nId).GetBottomLeft().y) ; - Point3d ptTl( m_mTree.at( nId).GetBottomLeft().x , m_mTree.at( nId).GetTopRight().y) ; - if ( abs( ptToAssign.x - ptTl.x) < EPS_SMALL || abs( ptToAssign.x - ptBr.x) < EPS_SMALL || - abs( ptToAssign.y - ptTl.y) < EPS_SMALL || abs( ptToAssign.y - ptBr.y) < EPS_SMALL) - { - Point3d ptToAssignPlus ; - double dParam ; - Vector3d vDir ; - clTrim.GetParamAtPoint( ptToAssign, dParam, EPS_SMALL) ; - clTrim.GetPointTang( dParam + EPS_SMALL, ICurve::FROM_MINUS, ptToAssignPlus, vDir) ; - if ( abs( vDir.x) > 1 - EPS_SMALL || abs( vDir.y) > 1 - EPS_SMALL) { - vDir.Rotate( Z_AX, -90) ; - ptToAssignPlus = ptToAssignPlus + vDir * 2 * EPS_SMALL ; - } - nCells = FindCell( ptToAssignPlus, clTrim) ; - if ( nCells.empty()) { - ptToAssignPlus = ptToAssignPlus - 4 * vDir * EPS_SMALL ; - nCells = FindCell( ptToAssignPlus, clTrim) ; + if ( ! bRecurs) { + // se sono in un vertice o su un lato devo controllare di aver trovato la cella giusta + Point3d ptBr( m_mTree.at( nId).GetTopRight().x , m_mTree.at( nId).GetBottomLeft().y) ; + Point3d ptTl( m_mTree.at( nId).GetBottomLeft().x , m_mTree.at( nId).GetTopRight().y) ; + if ( abs( ptToAssign.x - ptTl.x) < EPS_SMALL || abs( ptToAssign.x - ptBr.x) < EPS_SMALL || + abs( ptToAssign.y - ptTl.y) < EPS_SMALL || abs( ptToAssign.y - ptBr.y) < EPS_SMALL) + { + Point3d ptToAssignPlus ; + double dParam ; + Vector3d vtDir ; + clTrim.GetParamAtPoint( ptToAssign, dParam, EPS_SMALL) ; + clTrim.GetPointTang( dParam + EPS_SMALL, ICurve::FROM_MINUS, ptToAssignPlus, vtDir) ; + if ( abs( vtDir.x) > 1 - EPS_SMALL || abs( vtDir.y) > 1 - EPS_SMALL) { + vtDir.Rotate( Z_AX, -90) ; + ptToAssignPlus = ptToAssignPlus + vtDir * 2 * EPS_SMALL ; + } + nCells = FindCell( ptToAssignPlus, clTrim, true) ; + if ( nCells.empty()) { + ptToAssignPlus = ptToAssignPlus - 2 * vtDir * EPS_SMALL ; + vtDir.Rotate( Z_AX, 90) ; + ptToAssignPlus = ptToAssignPlus + 10 * vtDir * EPS_SMALL ; + nCells = FindCell( ptToAssignPlus, clTrim, true) ; + if ( nCells.empty()) + nCells.push_back( nId) ; + } } } return nCells ; @@ -1711,22 +1727,47 @@ Tree::FindCell( const Point3d& ptToAssign, const CurveLine& cl, INTVECTOR vCells // se non trova nulla restituisce un vettore vuoto // restituisce sempre solo una cella - // la CurveLine è il segmento di trim su cui giace ptToAssign - Point3d ptIntersPlus ; - double dParam ; - Vector3d vDir ; - cl.GetParamAtPoint( ptToAssign, dParam, EPS_SMALL) ; - // mi sposto appena più avanti di ptToAssign - cl.GetPointTang( dParam + EPS_SMALL, ICurve::FROM_MINUS, ptIntersPlus, vDir) ; + // questo punto va trovato con precisione, perché se seleziono la cella sbagliata si incasina tutto INTVECTOR nCells ; int nId = -1 ; for ( int nCell : vCells) { - if ( ptIntersPlus.x > m_mTree.at( nCell).GetBottomLeft().x - EPS_ZERO && ptIntersPlus.x < m_mTree.at( nCell).GetTopRight().x + EPS_ZERO && - ptIntersPlus.y > m_mTree.at( nCell).GetBottomLeft().y - EPS_ZERO && ptIntersPlus.y < m_mTree.at( nCell).GetTopRight().y + EPS_ZERO) { + if ( ptToAssign.x > m_mTree.at( nCell).GetBottomLeft().x && ptToAssign.x < m_mTree.at( nCell).GetTopRight().x && + ptToAssign.y > m_mTree.at( nCell).GetBottomLeft().y && ptToAssign.y < m_mTree.at( nCell).GetTopRight().y) { nId = nCell ; nCells.push_back( nId) ; } } + // se non ho trovato nulla vuol dire che sono su un vertice o su un lato + if ( (int)nCells.size() == 0 ) { + 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) ; + } + } + 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 ; + double dParam ; + Vector3d vDir ; + cl.GetParamAtPoint( ptToAssign, dParam, EPS_SMALL) ; + cl.GetStartDir( vDir) ; + // 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( vDir.x) >= 1 - EPS_SMALL || abs( vDir.y) >= 1 - EPS_SMALL) + vDir.Rotate( Z_AX, -45) ; + ptIntersPlus = ptToAssign + vDir * 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 ; } @@ -1842,10 +1883,12 @@ Tree::TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons) Point3d ptLast = m_mTree[nId].m_vInters.back().vpt.back() ; //sistemo l'ingresso della prima cella int nEdge ; - OnWhichEdge( nFirstCell, ptFirst, nEdge) ; + if ( ! OnWhichEdge( nFirstCell, ptFirst, nEdge)) + return false ; m_mTree[nFirstCell].m_vInters[nPass].nIn = nEdge ; // sistemo l'uscita dell'ultima cella - OnWhichEdge( nId, ptLast, nEdge) ; + if ( ! OnWhichEdge( nId, ptLast, nEdge)) + return false ; m_mTree[nId].m_vInters.back().nOut = nEdge ; // sistemo il flag dell'ultima cella if ( m_mTree[nId].m_nFlag == -1) @@ -2125,11 +2168,13 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool if ( ! clEdge2.IsValid()) return false ; } - else if ( aInfo.bOverlap && ! bFirstInters) { - ptInters = aInfo.IciA[1].ptI ; - bIntersFound = true ; - } - if ( clEdge2.IsValid() && ! bIntersFound){ + //else if ( aInfo.bOverlap && ! bFirstInters) { + // ptInters = aInfo.IciA[1].ptI ; + // bIntersFound = true ; + //} + else + bIntersOn1Found = true ; + if ( clEdge2.IsValid() && ! bIntersOn1Found){ IntersLineLine illExit2( clTrim, clEdge2, true) ; // verifico su quale dei due lati ho l'intersezione if ( ! illExit2.GetIntCrvCrvInfo( aInfo2)){ @@ -2152,8 +2197,12 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool ptInters = aInfo2.IciA[0].ptI ; } } - else - ptInters = aInfo.IciA[0].ptI ; // qui devo mettere il controllo su prima o seconda intersezione? + else { + if ( aInfo.bOverlap && ! bFirstInters) + ptInters = aInfo.IciA[1].ptI ; + else + ptInters = aInfo.IciA[0].ptI ; + } } if ( ! bIntersOn2Found) OnWhichEdge( nId, ptInters, nEdge) ; diff --git a/Tree.h b/Tree.h index 541101f..baab0c1 100644 --- a/Tree.h +++ b/Tree.h @@ -25,7 +25,6 @@ struct Inters { PNTVECTOR vpt ; int nOut ; bool bCCW ; - bool bVertex ; int nChunk ; // riordino le intersezioni per lato in senso antiorario dal top // se ho più intersezioni che entrano in un lato le riordino considerando che percorro i lati in senso antiorario a partire da ptTR @@ -160,7 +159,7 @@ private : void GetRightNeigh( const int& nId, INTVECTOR& vRightNeighs) const ; // restituisce le celle foglie che sono adiacenti al lato right void GetRootNeigh( const 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) const ; // dato un punto, trova la cella foglia a cui appartiene + 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 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