diff --git a/Tree.cpp b/Tree.cpp index 8bbe74e..f64fdf3 100644 --- a/Tree.cpp +++ b/Tree.cpp @@ -28,7 +28,7 @@ //---------------------------------------------------------------------------- Cell::Cell( void) : m_nId( -1),m_nTop ( -2), m_nBottom( -2), m_nLeft( -2), m_nRight ( -2), m_nParent( -2), m_nDepth( 0), - m_nChild1( -2), m_nChild2( -2), m_nFlag( 0), m_nFlag2( 0), m_nRightEdgeIn( 0), m_ptPbl(ORIG), m_ptPtr(), m_bProcessed(false), m_bSplitVert(true) + m_nChild1( -2), m_nChild2( -2), m_nFlag( -1), m_nFlag2( 0), m_nRightEdgeIn( -1), m_ptPbl(ORIG), m_ptPtr(), m_bProcessed(false), m_bSplitVert(true) { Point3d ptTr ( 1, 1) ; m_ptPtr = ptTr ; @@ -38,7 +38,7 @@ Cell::Cell( void) //---------------------------------------------------------------------------- Cell::Cell( Point3d& ptBL, Point3d& ptTR) : m_nId( -1),m_nTop ( -2), m_nBottom( -2), m_nLeft( -2), m_nRight ( -2), m_nParent( -2), m_nDepth( 0), - m_nChild1( -2), m_nChild2( -2), m_nFlag( 0), m_nFlag2( 0), m_nRightEdgeIn( 0), m_ptPbl(ptBL), m_ptPtr(ptTR), m_bProcessed(false), m_bSplitVert(true) + m_nChild1( -2), m_nChild2( -2), m_nFlag( -1), m_nFlag2( 0), m_nRightEdgeIn( -1), m_ptPbl(ptBL), m_ptPtr(ptTR), m_bProcessed(false), m_bSplitVert(true) {} @@ -1204,7 +1204,7 @@ Tree::GetPolygons( std::vector& vPolygons) { int nId = m_vnLeaves[i] ; // vettore in cui salvo il chunk di appartenenza di ogni loop che attraversa la cella INTVECTOR vnParentChunk ; - int nEdgeIn = -1 ; + //int nEdgeIn = -1 ; // vettore in cui salvo i loop che non appartengono al poligono che sto cotruendo nel ciclo attuale e da cui ripasserò dopo INTVECTOR vToCheck( (int) m_mTree[nId].m_vInters.size()) ; std::generate_n( vToCheck.begin(), (int) m_mTree[nId].m_vInters.size(), generator()) ; @@ -1214,7 +1214,7 @@ Tree::GetPolygons( std::vector& vPolygons) { // in questo for analizzo solo i loop che tagliano la cella while( nPoly == 0 || (int)vToCheck.size() != 0) { int nPolyBefore = nPoly ; - CreateCellPolygons( i, vPolygons, vToCheck, nPoly, vnParentChunk) ; + CreateCellPolygons( i, vPolygons, vToCheck, nPoly, vnParentChunk, vPolygonsBasic[i]) ; if ( nPolyBefore == nPoly) break ; } @@ -1291,24 +1291,26 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons) } vNeigh.clear() ; vVertices.push_back( m_mTree.at(nId).GetBottomLeft()) ; - // 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) { - Point3d ptPSrf, ptP00, ptP10, ptP11, ptP01; - double dU, dV ; - dU = ( m_mTree.at(nId).GetBottomLeft().x + m_mTree.at(nId).GetTopRight().x) / 2 ; - dV = ( m_mTree.at(nId).GetBottomLeft().y + m_mTree.at(nId).GetTopRight().y) / 2 ; - m_pSrfBz->GetPointD1D2( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrf) ; - ptP00 = m_mVert.at(nId).at(0) ; - ptP10 = m_mVert.at(nId).at(1) ; - ptP11 = m_mVert.at(nId).at(2) ; - ptP01 = m_mVert.at(nId).at(3) ; - Point3d ptP00P11 = ( ptP00 + ptP11) / 2 ; - Point3d ptP10P01 = ( ptP10 + ptP01) / 2 ; - // ho la curvatura maggiore sulla diagonale tra P10 e P01, ruoto l'ordine dei vertici, in modo che triangulate prenda la diagonale giusta - if ( Dist(ptP00P11, ptPSrf) + EPS_SMALL > Dist(ptP10P01, ptPSrf)) { - rotate(vVertices.begin(), vVertices.begin() + 1,vVertices.end()) ; - vVertices.back() = vVertices.at(0) ; + 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) { + Point3d ptPSrf, ptP00, ptP10, ptP11, ptP01; + double dU, dV ; + dU = ( m_mTree.at(nId).GetBottomLeft().x + m_mTree.at(nId).GetTopRight().x) / 2 ; + dV = ( m_mTree.at(nId).GetBottomLeft().y + m_mTree.at(nId).GetTopRight().y) / 2 ; + m_pSrfBz->GetPointD1D2( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrf) ; + ptP00 = m_mVert.at(nId).at(0) ; + ptP10 = m_mVert.at(nId).at(1) ; + ptP11 = m_mVert.at(nId).at(2) ; + ptP01 = m_mVert.at(nId).at(3) ; + Point3d ptP00P11 = ( ptP00 + ptP11) / 2 ; + Point3d ptP10P01 = ( ptP10 + ptP01) / 2 ; + // ho la curvatura maggiore sulla diagonale tra P10 e P01, ruoto l'ordine dei vertici, in modo che triangulate prenda la diagonale giusta + if ( Dist(ptP00P11, ptPSrf) + EPS_SMALL > Dist(ptP10P01, ptPSrf)) { + rotate(vVertices.begin(), vVertices.begin() + 1,vVertices.end()) ; + vVertices.back() = vVertices.at(0) ; + } } } @@ -1333,7 +1335,8 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons) //---------------------------------------------------------------------------- void Tree::ResetTree( void) -{ +{ + //// setto tutti i nodi (foglie comprese) a Processed = false //int nCToReset = -1 ; //while ( nCToReset != -2 && m_mTree[nCToReset].IsProcessed() == true) { // if ( m_mTree[nCToReset].IsLeaf()) { @@ -1366,20 +1369,25 @@ Tree::ResetTree( void) } //---------------------------------------------------------------------------- -int -Tree::FindCell( const Point3d& ptToAssign) const +INTVECTOR +Tree::FindCell( const Point3d& ptToAssign, CurveLine& clTrim) const { - // se fallisce ritorna -2 + // riordino le celle da sinistra a destra ( rispetto al verso della cl) + // devo ancora aggiungerla questa feature!!!//////////////////////////////////////////////////////////////////////////////////////////////////////////// + INTVECTOR nCells ; + int nId = -1 ; + // se fallisce ritorna un vettore vuoto // verifico che il punto sia all'interno dello spazio parametrico if ( ptToAssign.x < m_mTree.at(-1).GetBottomLeft().x || ptToAssign.x > m_mTree.at( -1).GetTopRight().x || - ptToAssign.y < m_mTree.at(-1).GetBottomLeft().y || ptToAssign.y > m_mTree.at( -1).GetTopRight().y ) - return -2 ; + ptToAssign.y < m_mTree.at(-1).GetBottomLeft().y || ptToAssign.y > m_mTree.at( -1).GetTopRight().y ) { + //nCells.push_back( - 2) ; + return nCells ; + } - int nId = -1 ; while ( ! m_mTree.at(nId).IsLeaf()) { if ( m_mTree.at(nId).IsSplitVert()) { double dMid = ( m_mTree.at(nId).GetBottomLeft().x + m_mTree.at(nId).GetTopRight().x) / 2 ; - if ( ptToAssign.x < dMid) { + if ( ptToAssign.x < dMid + EPS_SMALL) { nId = m_mTree.at(nId).m_nChild1 ; } else { @@ -1388,7 +1396,7 @@ Tree::FindCell( const Point3d& ptToAssign) const } else { double dMid = ( m_mTree.at(nId).GetBottomLeft().y + m_mTree.at(nId).GetTopRight().y) / 2 ; - if ( ptToAssign.y < dMid ) { + if ( ptToAssign.y < dMid + EPS_SMALL ) { nId = m_mTree.at(nId).m_nChild2 ; } else { @@ -1396,9 +1404,95 @@ Tree::FindCell( const Point3d& ptToAssign) const } } } - if ( nId == -1) - nId = -2 ; - return nId ; + if ( nId != -1) + nCells.push_back( nId) ; + //if ( nId == -1) + // nId = -2 ; + + //// devo verificare se sono sul bordo di una cella: in questo caso dovrei restituire anche il vicino con cui condivido quel lato!! ///////////////////// + + 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) ; + //IntCrvCrvInfo aInfo, bInfo ; + //CurveLine clEdge, clEdge2 ; + //if ( AreSamePointApprox(ptToAssign, ptTl)){ + // // lato top + // clEdge.Set( m_mTree.at(nId).GetTopRight(), ptTl) ; + // IntersLineLine illTrimEdge( clTrim, clEdge, true) ; + // illTrimEdge.GetIntCrvCrvInfo( aInfo) ; + // // lato sinistro + // clEdge2.Set( ptTl, m_mTree.at(nId).GetBottomLeft()) ; + // IntersLineLine illTrimEdge2( clTrim, clEdge2, true) ; + // illTrimEdge2.GetIntCrvCrvInfo( bInfo) ; + // if ( aInfo.bOverlap) { + // if ( aInfo.bCBOverEq ) { + + // } + // } + //} + //else if ( AreSamePointApprox( ptToAssign, m_mTree.at(nId).GetBottomLeft())) { + + //} + //else if ( AreSamePointApprox(ptToAssign, ptBr)) { + + //} + //else if (AreSamePointApprox( ptToAssign, ptTl)) { + + //} + + + if ( AreSamePointApprox(ptToAssign, ptTl) || + AreSamePointApprox( ptToAssign, m_mTree.at(nId).GetBottomLeft()) || + AreSamePointApprox(ptToAssign, ptBr) || + AreSamePointApprox( ptToAssign, ptTl)) + { + 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 * EPS_SMALL ; + } + nCells = FindCell( ptToAssignPlus, clTrim) ; + if ( nCells.empty()) { + ptToAssignPlus = ptToAssignPlus - 2 * vDir * EPS_SMALL ; + nCells = FindCell( ptToAssignPlus, clTrim) ; + } + } + return nCells ; +} + +//---------------------------------------------------------------------------- +INTVECTOR +Tree::FindCell( const Point3d& ptToAssign, CurveLine& cl, INTVECTOR vCells) const +{ + // se non trova nulla restituisce un vettore vuoto + // restituisce sempre solo una cella + + // la CurveLine è il segmento di trim su cui giace ptToAssign + // devo usare ptInters + qualcosa/////////////////////////////////////////////// + Point3d ptIntersPlus ; + double dParam ; + Vector3d vDir ; + cl.GetParamAtPoint( ptToAssign, dParam, EPS_SMALL) ; + cl.GetPointTang( dParam + EPS_SMALL, ICurve::FROM_MINUS, ptIntersPlus, vDir) ; + INTVECTOR nCells ; + int nId = -1 ; + bool bFound = false ; + for ( int nCell : vCells ) { + if ( ptIntersPlus.x >= m_mTree.at(nCell).GetBottomLeft().x && ptIntersPlus.x <= m_mTree.at(nCell).GetTopRight().x && + ptIntersPlus.y >= m_mTree.at(nCell).GetBottomLeft().y && ptIntersPlus.y <= m_mTree.at(nCell).GetTopRight().y) { + nId = nCell ; + nCells.push_back( nId) ; + } + //if ( bFound) + // break ; + //if ( nCells.size() > 0) + // bFound = true ; + } + return nCells ; } //---------------------------------------------------------------------------- @@ -1438,7 +1532,22 @@ Tree::TraceLoopLabelCell( void) // trovo in quale cella è il ptStart Point3d ptStart ; plLoop.GetFirstPoint( ptStart) ; - int nId = FindCell( ptStart) ; + PNTULIST lPt = plLoop.GetUPointList() ; + PNTULIST:: iterator ptFirst = lPt.begin(); + PNTULIST:: iterator ptSecond = ptFirst ; + std::advance( ptSecond, 1) ; + CurveLine clFirst ; + clFirst.Set( ptFirst->first, ptSecond->first) ; + INTVECTOR nCells = FindCell( ptStart, clFirst) ; + int nId ; + if ( (int)nCells.size() == 1) { + nId = nCells[0] ; + } + else { + nId = nCells.back() ; + // qui devo scegliere da quale cella partire!! /////////////////////////////////////////////////////////////////////////////////////////////////// + // fatto + } // trovo quali punti della polyline sono nella cella e l'intersezione PNTVECTOR vptInters ; vptInters.push_back( ptStart) ; @@ -1455,6 +1564,7 @@ Tree::TraceLoopLabelCell( void) Point3d ptCurr ; INTVECTOR :: iterator iter = find( m_vnLeaves.begin(), m_vnLeaves.end(), nId) ; int nIdPolygon = std::distance( m_vnLeaves.begin(), iter) ; + bool bVertex = false ; while ( plLoop.GetNextPoint( ptCurr)) { // sto uscendo dalla cella, quindi cerco l'intersezione Point3d ptStart, ptEnd ; @@ -1465,7 +1575,8 @@ Tree::TraceLoopLabelCell( void) while( ! IsPointInsidePolyLine( ptCurr, vplPolygons[nIdPolygon], dLinTol)) { /// qui devo mettere una tolleranza negativa per poter tener conto anche dei punti che sono SULLA curva bLoopInside = false ; // trovo l'intersezione e passo alla cella successiva. nId viene aggiornato dalla funzione FindInters - FindInters( nId, clTrim, vptInters) ; + bVertex = false ; + FindInters( nId, clTrim, vptInters, bVertex) ; // ricalcolo la posizione di nId nel vettore delle foglie iter = find( m_vnLeaves.begin(), m_vnLeaves.end(), nId) ; nIdPolygon = std::distance( m_vnLeaves.begin(), iter) ; @@ -1482,7 +1593,7 @@ Tree::TraceLoopLabelCell( void) if ( bLoopInside) { m_mTree[nId].m_vnLoop.push_back( i) ; // setto la categoria della cella - if ( m_mTree[nId].m_nFlag == 0) + if ( m_mTree[nId].m_nFlag == -1) m_mTree[nId].m_nFlag = 2 ; else if ( m_mTree[nId].m_nFlag == 1) m_mTree[nId].m_nFlag = 3 ; @@ -1493,6 +1604,22 @@ Tree::TraceLoopLabelCell( void) // sono tornato alla cella di partenza, quindi devo fare il merge dei due vettori di intersezione che ho creato per questa cella // per lo stesso loop else { + // devo verificare se il loop finisce in un vertice! in questo caso sono nella penultima cella! e devo fare un FindInters di nuovo per sistemare + Point3d ptLast = m_mTree[nId].m_vInters.back().vpt.back() ; + Point3d ptTl( m_mTree[nId].GetBottomLeft().x, m_mTree[nId].GetTopRight().y) ; + Point3d ptBr( m_mTree[nId].GetTopRight().x, m_mTree[nId].GetBottomLeft().y) ; + if ( AreSamePointApprox( m_mTree[nId].GetTopRight(), ptLast) || + AreSamePointApprox( ptTl, ptLast) || + AreSamePointApprox( m_mTree[nId].GetBottomLeft(), ptLast) || + AreSamePointApprox( ptBr, ptLast)) { + Point3d ptStart, ptEnd ; + plLoop.GetPrevPoint( ptEnd) ; + plLoop.GetPrevPoint( ptStart) ; + CurveLine clTrim ; + clTrim.Set( ptStart, ptEnd) ; + vptInters.clear() ; + FindInters( nId, clTrim, vptInters, bVertex) ; + } int nOut = m_mTree[nId].m_vInters[nPass].nOut ; m_mTree[nId].m_vInters.back().vpt.insert( m_mTree[nId].m_vInters.back().vpt.end(), m_mTree[nId].m_vInters[nPass].vpt.begin(), @@ -1504,12 +1631,13 @@ Tree::TraceLoopLabelCell( void) } } - // riordino i vettori di intersezione per ogni cella + // riordino i vettori di intersezione per ogni cella e setto il flag RightEdgeIn for ( int nId : m_vnLeaves) { std::sort( m_mTree[nId].m_vInters.begin( ), m_mTree[nId].m_vInters.end()) ; + SetRightEdgeIn( nId) ; } - // devo riconoscere le celle dentro i loop che sono ancora con label nFlag = -1 + // devo riconoscere le celle dentro i loop che sono ancora con label nFlag2 = 0 ResetTree() ; INTVECTOR vNeigh, vFirst ; GetRootNeigh( 1, vFirst) ; @@ -1521,6 +1649,7 @@ Tree::TraceLoopLabelCell( void) while ( nCell != nLastLeft && ! bAllDone) { // categorizzo la cella m_mTree[nCell].m_nFlag2 = 1 ; + CategorizeCell( nCell) ; // fintanto che la cella ha tra i vicini a destra una cella non elaborata mi sposto a destra // definisco una cella Processed se tutto il ramo a destra è categorizzato @@ -1614,7 +1743,7 @@ Tree::TraceLoopLabelCell( void) //---------------------------------------------------------------------------- bool -Tree::FindInters( int& nId, CurveLine& clTrim, PNTVECTOR& vptInters) +Tree::FindInters( int& nId, CurveLine& clTrim, PNTVECTOR& vptInters, bool& bVertex) { CurveLine clEdge , clEdge2 ; Point3d ptStart , ptEnd ; @@ -1628,39 +1757,46 @@ Tree::FindInters( int& nId, CurveLine& clTrim, PNTVECTOR& vptInters) int nEdge ; // flag che indica il lato su cui ho l'intersezione a partire dal lato top in senso antiorario // oltre il 3 sono le celle adiacenti in diagonale al vertice-> 4 corrisponde al ptTl e da lì in senso antiorario // -1 se la curva è sempre dentro la cella - if ( ptEnd.y > ptTR.y && ptEnd.x <= ptTR.x) { + if ( ptEnd.y >= ptTR.y && ptEnd.x <= ptTR.x) { nEdge = 0 ; // lato sopra - if ( ptEnd.x >= ptBL.x) - clEdge.Set( ptTR, ptTl) ; - // lato sinistro - else //if ( ptEnd.x < ptBL.x) + clEdge.Set( ptTR, ptTl) ; + //if ( ptEnd.x >= ptBL.x) + // ;// lato sinistro + //else //if ( ptEnd.x < ptBL.x) + if ( ptEnd.x < ptBL.x) clEdge2.Set( ptTl, ptBL) ; } - else if ( ptEnd.x < ptBL.x && ptEnd.y <= ptTR.y) { + else if ( ptEnd.x <= ptBL.x && ptEnd.y <= ptTR.y) { nEdge = 1 ; // lato sinistro - if ( ptEnd.y >= ptBL.y) - clEdge.Set( ptTl, ptBL) ; - // lato sotto - else //if ( ptEnd.y < ptBL.y) + clEdge.Set( ptTl, ptBL) ; + //if ( ptEnd.y >= ptBL.y) + // ; + //// lato sotto + //else //if ( ptEnd.y < ptBL.y) + if ( ptEnd.y < ptBL.y) clEdge2.Set( ptBL, ptBr) ; } - else if ( ptEnd.y < ptBL.y && ptEnd.x >= ptBL.x) { + else if ( ptEnd.y <= ptBL.y && ptEnd.x >= ptBL.x) { nEdge = 2 ; // lato sotto - if ( ptEnd.x <= ptTR.x) - clEdge.Set( ptBL, ptBr) ; - // lato destro - else if ( ptEnd.x > ptTR.x) + clEdge.Set( ptBL, ptBr) ; + //if ( ptEnd.x <= ptTR.x) + // ; + //// lato destro + //else //if ( ptEnd.x > ptTR.x) + if ( ptEnd.x > ptTR.x) clEdge2.Set( ptBr, ptTR) ; } - else if ( ptEnd.x > ptTR.x && ptEnd.y >= ptBL.y) { + else if ( ptEnd.x >= ptTR.x && ptEnd.y >= ptBL.y) { nEdge = 3 ; // lato desto - if ( ptEnd.y <= ptTR.y) - clEdge.Set( ptBr, ptTR) ; - // lato sopra + clEdge.Set( ptBr, ptTR) ; + //if ( ptEnd.y <= ptTR.y) + // ; + //// lato sopra + //else //if ( ptEnd.y > ptTR.y) if ( ptEnd.y > ptTR.y) clEdge2.Set( ptTR, ptTl) ; } @@ -1671,26 +1807,31 @@ Tree::FindInters( int& nId, CurveLine& clTrim, PNTVECTOR& vptInters) IntersLineLine illExit( clTrim, clEdge, true) ; IntCrvCrvInfo aInfo, aInfo2 ; Point3d ptInters ; - if ( ! illExit.GetIntCrvCrvInfo( aInfo) ) - return false ; + //if ( ! illExit.GetIntCrvCrvInfo( aInfo) ) + // return false ; + illExit.GetIntCrvCrvInfo( aInfo) ; if ( clEdge2.IsValid()){ IntersLineLine illExit2( clTrim, clEdge2, true) ; - if ( ! illExit2.GetIntCrvCrvInfo( aInfo2) ) - return false ; + //if ( ! illExit2.GetIntCrvCrvInfo( aInfo2) ) + // return false ; // verifico su quale dei due lati ho l'intersezione - if ( illExit2.GetNumInters() == 0) + if ( ! illExit2.GetIntCrvCrvInfo( aInfo2)) ptInters = aInfo.IciA[0].ptI ; else { // solo intersezione sul lato 2 - if ( illExit.GetNumInters() == 0) { + if ( illExit.GetNumInters() == 0 ) { ptInters = aInfo2.IciA[0].ptI ; - if ( nEdge == 3) - nEdge = 0 ; - else + if ( nEdge > 3 && nEdge != 7) + nEdge = nEdge - 4 ; + else if ( nEdge < 3 ) ++ nEdge ; + else + nEdge = 0 ; } // intersezione sul vertice della cella else { + ptInters = aInfo2.IciA[0].ptI ; + bVertex = true ; // la cella adiacente in diagonale a quel vertice nEdge = nEdge + 4 ; } @@ -1704,12 +1845,12 @@ Tree::FindInters( int& nId, CurveLine& clTrim, PNTVECTOR& vptInters) m_mTree[nId].m_vInters.back().vpt = vptInters ; vptInters.clear() ; // setto la categoria della cella - if ( m_mTree[nId].m_nFlag == 0) + if ( m_mTree[nId].m_nFlag == -1) m_mTree[nId].m_nFlag = 1 ; else if ( m_mTree[nId].m_nFlag == 2) m_mTree[nId].m_nFlag = 3 ; // seleziono la cella successiva da analizzare - INTVECTOR vNeigh ; + INTVECTOR vNeigh, vNeigh1 ; if ( nEdge == 0) { GetTopNeigh( nId, vNeigh) ; std::reverse( vNeigh.begin(), vNeigh.end()) ; @@ -1720,7 +1861,13 @@ Tree::FindInters( int& nId, CurveLine& clTrim, PNTVECTOR& vptInters) } } m_mTree[nId].m_vInters.emplace_back() ; - m_mTree[nId].m_vInters.back().nIn = 2 ; + Point3d ptBr( m_mTree[nId].GetTopRight().x, m_mTree[nId].GetBottomLeft().y) ; + if ( ptInters.x > m_mTree[nId].GetBottomLeft().x && ptInters.x < m_mTree[nId].GetTopRight().x ) + m_mTree[nId].m_vInters.back().nIn = 2 ; + else if ( AreSamePointApprox( ptInters, m_mTree[nId].GetBottomLeft())) + m_mTree[nId].m_vInters.back().nIn = 5 ; + else if ( AreSamePointApprox( ptInters, ptBr)) + m_mTree[nId].m_vInters.back().nIn = 6 ; } else if ( nEdge == 1) { GetLeftNeigh( nId, vNeigh) ; @@ -1732,7 +1879,13 @@ Tree::FindInters( int& nId, CurveLine& clTrim, PNTVECTOR& vptInters) } } m_mTree[nId].m_vInters.emplace_back() ; - m_mTree[nId].m_vInters.back().nIn = 3 ; + Point3d ptBr( m_mTree[nId].GetTopRight().x, m_mTree[nId].GetBottomLeft().y) ; + if ( ptInters.y > m_mTree[nId].GetBottomLeft().y && ptInters.y < m_mTree[nId].GetTopRight().y ) + m_mTree[nId].m_vInters.back().nIn = 3 ; + else if ( AreSamePointApprox( ptInters, ptBr)) + m_mTree[nId].m_vInters.back().nIn = 6 ; + else if ( AreSamePointApprox( ptInters, m_mTree[nId].GetTopRight())) + m_mTree[nId].m_vInters.back().nIn = 7 ; } else if ( nEdge == 2) { GetBottomNeigh( nId, vNeigh) ; @@ -1743,7 +1896,13 @@ Tree::FindInters( int& nId, CurveLine& clTrim, PNTVECTOR& vptInters) } } m_mTree[nId].m_vInters.emplace_back() ; - m_mTree[nId].m_vInters.back().nIn = 0 ; + Point3d ptTl( m_mTree[nId].GetBottomLeft().x, m_mTree[nId].GetTopRight().y) ; + if ( ptInters.x > m_mTree[nId].GetBottomLeft().x && ptInters.x < m_mTree[nId].GetTopRight().x ) + m_mTree[nId].m_vInters.back().nIn = 0 ; + else if ( AreSamePointApprox( ptInters, ptTl)) + m_mTree[nId].m_vInters.back().nIn = 4 ; + else if ( AreSamePointApprox( ptInters, m_mTree[nId].GetTopRight())) + m_mTree[nId].m_vInters.back().nIn = 7 ; } else if ( nEdge == 3) { GetRightNeigh( nId, vNeigh) ; @@ -1754,45 +1913,155 @@ Tree::FindInters( int& nId, CurveLine& clTrim, PNTVECTOR& vptInters) } } m_mTree[nId].m_vInters.emplace_back() ; - m_mTree[nId].m_vInters.back().nIn = 1 ; + Point3d ptTl( m_mTree[nId].GetBottomLeft().x, m_mTree[nId].GetTopRight().y) ; + if ( ptInters.y > m_mTree[nId].GetBottomLeft().y && ptInters.y < m_mTree[nId].GetTopRight().y ) + m_mTree[nId].m_vInters.back().nIn = 1 ; + else if ( AreSamePointApprox( ptInters, m_mTree[nId].GetBottomLeft())) + m_mTree[nId].m_vInters.back().nIn = 5 ; + else if ( AreSamePointApprox( ptInters, ptTl)) + m_mTree[nId].m_vInters.back().nIn = 4 ; } - // per nEdge > 3 sto parlando di intersezioni sui vertici, che vengono attraversati in diagonale e non paralleli ad uno dei due lati - // se attraversati adiacenti ad uno dei due lati, viene considerata l'intersezione col lato perpendicolare + // esco da uno dei vertici else if ( nEdge == 4) { GetTopNeigh( nId, vNeigh) ; - int nIdTemp = vNeigh[0] ; - vNeigh.clear() ; - GetLeftNeigh( nIdTemp, vNeigh) ; - nId = vNeigh[0] ; - m_mTree[nId].m_vInters.emplace_back() ; - m_mTree[nId].m_vInters.back().nIn = 6 ; + GetLeftNeigh( nId, vNeigh1) ; + INTVECTOR nPossible, nPossible1 ; + nPossible = FindCell( ptInters, clTrim, vNeigh) ; + nPossible1 = FindCell( ptInters, clTrim, vNeigh1) ; + // ingresso dal basso + if ( ! nPossible.empty()) { + nId = nPossible[0] ; + m_mTree[nId].m_vInters.emplace_back() ; + m_mTree[nId].m_vInters.back().nIn = 2 ; + } + // ingresso da destra + else if ( ! nPossible1.empty()) { + nId = nPossible1.back() ; + m_mTree[nId].m_vInters.emplace_back() ; + m_mTree[nId].m_vInters.back().nIn = 3 ; + } + // ingresso in diagonale + else { + if ( ! vNeigh.empty()) { + int nIdTemp = vNeigh[0] ; + vNeigh.clear() ; + GetLeftNeigh( nIdTemp, vNeigh) ; + nId = vNeigh[0] ; + m_mTree[nId].m_vInters.emplace_back() ; + m_mTree[nId].m_vInters.back().nIn = 6 ; + } + else { + nId = vNeigh1.back() ; + m_mTree[nId].m_vInters.emplace_back() ; + m_mTree[nId].m_vInters.back().nIn = 7 ; + } + } } else if ( nEdge == 5) { GetLeftNeigh( nId, vNeigh) ; - int nIdTemp = vNeigh[0] ; - vNeigh.clear() ; - GetBottomNeigh( nIdTemp, vNeigh) ; - nId = vNeigh.back() ; - m_mTree[nId].m_vInters.emplace_back() ; - m_mTree[nId].m_vInters.back().nIn = 7 ; + GetBottomNeigh( nId, vNeigh1) ; + INTVECTOR nPossible, nPossible1 ; + nPossible = FindCell( ptInters, clTrim, vNeigh) ; + nPossible1 = FindCell( ptInters, clTrim, vNeigh1) ; + // ingresso dal destra + if ( ! nPossible.empty()) { + nId = nPossible[0] ; + m_mTree[nId].m_vInters.emplace_back() ; + m_mTree[nId].m_vInters.back().nIn = 3 ; + } + // ingresso dall'alto + else if ( ! nPossible1.empty()) { + nId = nPossible1[0] ; + m_mTree[nId].m_vInters.emplace_back() ; + m_mTree[nId].m_vInters.back().nIn = 0 ; + } + // ingresso in diagonale + else { + if ( ! vNeigh.empty()) { + int nIdTemp = vNeigh[0] ; + vNeigh.clear() ; + GetBottomNeigh( nIdTemp, vNeigh) ; + nId = vNeigh.back() ; + m_mTree[nId].m_vInters.emplace_back() ; + m_mTree[nId].m_vInters.back().nIn = 7 ; + } + else { + nId = vNeigh[0] ; + m_mTree[nId].m_vInters.emplace_back() ; + m_mTree[nId].m_vInters.back().nIn = 4 ; + } + } } else if ( nEdge == 6) { GetBottomNeigh( nId, vNeigh) ; - int nIdTemp = vNeigh.back() ; - vNeigh.clear() ; - GetRightNeigh( nIdTemp, vNeigh) ; - nId = vNeigh[0] ; - m_mTree[nId].m_vInters.emplace_back() ; - m_mTree[nId].m_vInters.back().nIn = 4 ; + GetRightNeigh( nId, vNeigh1) ; + INTVECTOR nPossible, nPossible1 ; + nPossible = FindCell( ptInters, clTrim, vNeigh) ; + nPossible1 = FindCell( ptInters, clTrim, vNeigh1) ; + // ingresso dall'alto + if ( ! nPossible.empty()) { + nId = nPossible.back() ; + m_mTree[nId].m_vInters.emplace_back() ; + m_mTree[nId].m_vInters.back().nIn = 0 ; + } + // ingresso da sinistra + else if ( ! nPossible1.empty()) { + nId = nPossible1[0] ; + m_mTree[nId].m_vInters.emplace_back() ; + m_mTree[nId].m_vInters.back().nIn = 1 ; + } + // ingresso in diagonale + else { + if ( ! vNeigh.empty()){ + int nIdTemp = vNeigh.back() ; + vNeigh.clear() ; + GetRightNeigh( nIdTemp, vNeigh) ; + nId = vNeigh.back() ; + m_mTree[nId].m_vInters.emplace_back() ; + m_mTree[nId].m_vInters.back().nIn = 4 ; + } + else { + GetRightNeigh( nId, vNeigh) ; + nId = vNeigh[0] ; + m_mTree[nId].m_vInters.emplace_back() ; + m_mTree[nId].m_vInters.back().nIn = 5 ; + } + } } else if ( nEdge == 7) { GetRightNeigh( nId, vNeigh) ; - int nIdTemp = vNeigh.back() ; - vNeigh.clear() ; - GetTopNeigh( nIdTemp, vNeigh) ; - nId = vNeigh[0] ; - m_mTree[nId].m_vInters.emplace_back() ; - m_mTree[nId].m_vInters.back().nIn = 5 ; + GetTopNeigh( nId, vNeigh1) ; + INTVECTOR nPossible, nPossible1 ; + nPossible = FindCell( ptInters, clTrim, vNeigh) ; + nPossible1 = FindCell( ptInters, clTrim, vNeigh1) ; + // ingresso da sinistra + if ( ! nPossible.empty()) { + nId = nPossible.back() ; + m_mTree[nId].m_vInters.emplace_back() ; + m_mTree[nId].m_vInters.back().nIn = 1 ; + } + // ingresso dal basso + else if ( ! nPossible1.empty()) { + nId = nPossible1.back() ; + m_mTree[nId].m_vInters.emplace_back() ; + m_mTree[nId].m_vInters.back().nIn = 2 ; + } + // ingresso in diagonale + else { + if ( ! vNeigh.empty()) { + int nIdTemp = vNeigh.back() ; + vNeigh.clear() ; + GetTopNeigh( nIdTemp, vNeigh) ; + nId = vNeigh[0] ; + m_mTree[nId].m_vInters.emplace_back() ; + m_mTree[nId].m_vInters.back().nIn = 5 ; + } + else { + nId = vNeigh.back() ; + m_mTree[nId].m_vInters.emplace_back() ; + m_mTree[nId].m_vInters.back().nIn = 6 ; + } + } } // aggiungo l'intersezione al vettore delle intersezioni della prossima cella vptInters.push_back( ptInters) ; @@ -1801,14 +2070,42 @@ Tree::FindInters( int& nId, CurveLine& clTrim, PNTVECTOR& vptInters) //---------------------------------------------------------------------------- bool -Tree::CreateCellPolygons( int nLeafId, std::vector& vPolygons, INTVECTOR& vToCheck, int& nPoly, INTVECTOR& vnParentChunk) +Tree::CreateCellPolygons( int nLeafId, std::vector& vPolygons, INTVECTOR& vToCheck, int& nPoly, INTVECTOR& vnParentChunk, PolyLine plCell) { + // conto quanti vertici in più ho per lato e creo un vettore dei vertici per lato + int nId = m_vnLeaves[nLeafId] ; + std::vector vEdgeVertex ; + Point3d ptTl(m_mTree[nId].GetBottomLeft().x, m_mTree[nId].GetTopRight().y) ; + Point3d ptBr(m_mTree[nId].GetTopRight().x, m_mTree[nId].GetBottomLeft().y) ; + vEdgeVertex.emplace_back() ; + vEdgeVertex.back().push_back( m_mTree[nId].GetTopRight()) ; + vEdgeVertex.emplace_back() ; + vEdgeVertex.back().push_back( ptTl) ; + vEdgeVertex.emplace_back() ; + vEdgeVertex.back().push_back( m_mTree[nId].GetBottomLeft()) ; + vEdgeVertex.emplace_back() ; + vEdgeVertex.back().push_back( ptBr) ; + // la PolyLine è riempita a partire dal lato bottom + Point3d ptStart ; + plCell.GetFirstPoint( ptStart) ; + INTVECTOR vEdge = { 2, 3, 0, 1} ; + for ( int p = 0 ; p < 4 ; ++ p) { + int j = vEdge[p] ; + int next = j +1 ; + if ( j == 3) + next = 0 ; + Point3d ptToAdd ; + while ( plCell.GetNextPoint( ptToAdd) && ! AreSamePointExact( ptToAdd, vEdgeVertex[next][0])) { + vEdgeVertex[j].push_back( ptToAdd) ; + } + } + + // comincio a costruire il poligono INTVECTOR vToCheckNow = vToCheck ; vToCheck.clear() ; // vettore dei poligoni ( loop) della cella nId POLYLINEVECTOR vCellPolygons ; // costruisco i poligoni partendo dal vettore delle intersezioni, come spiegato a pag15 di Cripps - int nId = m_vnLeaves[nLeafId] ; PolyLine plTrimmedPoly ; // numero di volte che la cella è stata attraversata da una curva di trim int nPassToCheck = (int) vToCheckNow.size() ; @@ -1817,6 +2114,7 @@ Tree::CreateCellPolygons( int nLeafId, std::vector& vPolygons, I // scorro sui vettori intersezione della cella nId e sui suoi vertici // in questo for analizzo solo i loop che tagliano la cella int nEdgeIn = -1 ; + int nFirstLoopInPoly = -1 ; for ( int w = 0 ; w < (int)vToCheckNow.size() ; ++ w) { int j = vToCheckNow[w] ; Inters inA = m_mTree[nId].m_vInters[j] ; @@ -1826,8 +2124,9 @@ Tree::CreateCellPolygons( int nLeafId, std::vector& vPolygons, I // salvo il lato di ingresso del primo lato del poligono che sto costruendo nEdgeIn = inA.nIn ; for ( Point3d ptInt : inA.vpt ) { - plTrimmedPoly.AddUPoint(c, ptInt) ; - ++c ; + AddVertex( nId, vEdgeVertex, plTrimmedPoly, c, ptInt) ; + //plTrimmedPoly.AddUPoint(c, ptInt) ; + //++c ; } nEdge = inA.nOut ; // se la curva è CW devo verifica di non essere uscito in un vertice, con un tratto sovrapposto al lato che ripercorrerò tra poco @@ -1838,8 +2137,7 @@ Tree::CreateCellPolygons( int nLeafId, std::vector& vPolygons, I Vector3d vLast = ptLast - ptSecondToLast ; vLast.Normalize(); Vector3d vEdge ; - if ( nEdge == 0 ) { - Point3d ptTl(m_mTree[nId].GetBottomLeft().x, m_mTree[nId].GetTopRight().y) ; + if ( AreSameEdge( nEdge, 0)) { if ( AreSamePointApprox(ptLast, ptTl) ) { vEdge = m_mTree[nId].GetBottomLeft() - ptTl ; vEdge.Normalize() ; @@ -1849,8 +2147,7 @@ Tree::CreateCellPolygons( int nLeafId, std::vector& vPolygons, I } } } - else if ( nEdge == 1 && AreSamePointApprox(ptLast, m_mTree[nId].GetBottomLeft()) ) { - Point3d ptBr(m_mTree[nId].GetTopRight().x, m_mTree[nId].GetBottomLeft().y) ; + else if ( AreSameEdge( nEdge, 1) && AreSamePointApprox(ptLast, m_mTree[nId].GetBottomLeft()) ) { vEdge = ptBr - m_mTree[nId].GetBottomLeft() ; vEdge.Normalize() ; if ( AreOppositeVectorApprox(vLast, vEdge) ) { @@ -1858,8 +2155,7 @@ Tree::CreateCellPolygons( int nLeafId, std::vector& vPolygons, I nEdge = 2 ; } } - else if ( nEdge == 2 ) { - Point3d ptBr(m_mTree[nId].GetTopRight().x, m_mTree[nId].GetBottomLeft().y) ; + else if ( AreSameEdge( nEdge, 2) ) { if ( AreSamePointApprox(ptLast, ptBr) ) { vEdge = m_mTree[nId].GetTopRight() - ptBr ; vEdge.Normalize() ; @@ -1869,8 +2165,7 @@ Tree::CreateCellPolygons( int nLeafId, std::vector& vPolygons, I } } } - else if ( nEdge == 3 && AreSamePointApprox(ptLast, m_mTree[nId].GetTopRight()) ) { - Point3d ptTl(m_mTree[nId].GetBottomLeft().x, m_mTree[nId].GetTopRight().y) ; + else if ( AreSameEdge( nEdge, 3) && AreSamePointApprox(ptLast, m_mTree[nId].GetTopRight()) ) { vEdge = ptTl - m_mTree[nId].GetTopRight() ; vEdge.Normalize() ; if ( AreOppositeVectorApprox(vLast, vEdge) ) { @@ -1899,34 +2194,35 @@ Tree::CreateCellPolygons( int nLeafId, std::vector& vPolygons, I // ciclo sui loop successivi per vedere se ne ho uno su questo lato con un valid start for ( int t = w ; t < nPassToCheck -1 ; ++ t) { - if ( nEdge == m_mTree[nId].m_vInters[j].nIn ) { + if ( AreSameEdge( nEdge, m_mTree[nId].m_vInters[j].nIn) ) { if ( m_mTree[nId].m_vInters[j].bCCW) { - bValidNextStart = ( m_mTree[nId].m_vInters[vToCheckNow[t + 1]].nIn == nEdge) && // loop successivo inizia su questo lato + bValidNextStart = ( AreSameEdge( m_mTree[nId].m_vInters[vToCheckNow[t + 1]].nIn, nEdge)) && // loop successivo inizia su questo lato ! CheckIfAfter( plTrimmedPoly, m_mTree[nId].m_vInters[vToCheckNow[t + 1]].vpt[0], nEdge) ; // in posizione giusta da essere concatenato } else { // se il loop è CW e sono tornato sul lato di partenza allora controllo se sono prima del primo punto della polyline - bValidNextStart = ( m_mTree[nId].m_vInters[vToCheckNow[t + 1]].nIn == nEdge) && + bValidNextStart = ( AreSameEdge( m_mTree[nId].m_vInters[vToCheckNow[t + 1]].nIn, nEdge)) && CheckIfAfter( plTrimmedPoly, m_mTree[nId].m_vInters[vToCheckNow[t + 1]].vpt[0], nEdge) ; } } else - bValidNextStart = true ; - if ( m_mTree[nId].m_vInters[vToCheckNow[t + 1]].nIn != nEdge || bValidNextStart) + bValidNextStart = CheckIfAfter( plTrimmedPoly, m_mTree[nId].m_vInters[vToCheckNow[t + 1]].vpt[0], nEdge) ; + if ( ! AreSameEdge( m_mTree[nId].m_vInters[vToCheckNow[t + 1]].nIn, nEdge) || bValidNextStart) break ; // se ho trovato un loop successivo che devo saltare, lo salvo e considero i loop più avanti. - if ( m_mTree[nId].m_vInters[vToCheckNow[t + 1]].nIn == nEdge && ! bValidNextStart){ + if ( AreSameEdge( m_mTree[nId].m_vInters[vToCheckNow[t + 1]].nIn, nEdge) && ! bValidNextStart){ ++ nSecondCheck ; vToCheck.push_back( t + 1) ; } } if ( m_mTree[nId].m_vInters[j].bCCW) { - bNotCameBack = m_mTree[nId].m_vInters[j].nIn != nEdge && // sono tornato al lato di ingresso di questo loop - nEdge != nEdgeIn ; // sono tornato sul lato di ingresso di questo poligono ( solo se la curva è CCW) + //bNotCameBack = ! AreSameEdge( m_mTree[nId].m_vInters[j].nIn, nEdge) && // sono tornato al lato di ingresso di questo loop + // ! AreSameEdge( nEdge, nEdgeIn) ; // sono tornato sul lato di ingresso di questo poligono ( solo se la curva è CCW) + bNotCameBack = ! ( AreSameEdge( nEdge, nEdgeIn) && CheckIfBefore( plTrimmedPoly, nEdge)) ; } else { // il loop è CW e sono tornato sul lato di partenza allora controllo se sono prima del primo punto della polyline - if ( nEdge == nEdgeIn ) { + if ( AreSameEdge( nEdge, nEdgeIn)) { bool bBefore = CheckIfBefore( plTrimmedPoly, nEdge) ; bNotCameBack = bNotCameBack && !bBefore ; } @@ -1935,20 +2231,27 @@ Tree::CreateCellPolygons( int nLeafId, std::vector& vPolygons, I while ( ! bValidNextStart && bNotCameBack) { Point3d ptVert ; if ( nEdge == 0) { - ptVert.x = m_mTree[nId].GetBottomLeft().x ; - ptVert.y = m_mTree[nId].GetTopRight().y ; + //ptVert.x = m_mTree[nId].GetBottomLeft().x ; + //ptVert.y = m_mTree[nId].GetTopRight().y ; + ptVert = ptTl ; } - else if ( nEdge == 1) + else if ( nEdge == 1) { ptVert = m_mTree[nId].GetBottomLeft() ; - else if ( nEdge == 2) { - ptVert.x = m_mTree[nId].GetTopRight().x ; - ptVert.y = m_mTree[nId].GetBottomLeft().y ; } - else if ( nEdge == 3) + else if ( nEdge == 2) { + //ptVert.x = m_mTree[nId].GetTopRight().x ; + //ptVert.y = m_mTree[nId].GetBottomLeft().y ; + ptVert = ptBr ; + } + else if ( nEdge == 3) { ptVert = m_mTree[nId].GetTopRight() ; - plTrimmedPoly.AddUPoint( c, ptVert) ; - ++c ; - if ( nEdge != 3) + } + AddVertex( nId, vEdgeVertex, plTrimmedPoly, c, ptVert) ; + //plTrimmedPoly.AddUPoint( c, ptVert) ; + //++c ; + if ( nEdge > 3 && nEdge != 7) + nEdge = nEdge - 4 ; + else if ( nEdge < 3 ) ++ nEdge ; else nEdge = 0 ; @@ -1956,34 +2259,35 @@ Tree::CreateCellPolygons( int nLeafId, std::vector& vPolygons, I // aggiorno le condizioni per il while // ciclo sui loop successivi per vedere se ne ho uno su questo lato con un valid start for ( int t = w ; t < nPassToCheck -1 ; ++ t) { - if ( nEdge == m_mTree[nId].m_vInters[j].nIn ) { + if ( AreSameEdge( nEdge, m_mTree[nId].m_vInters[j].nIn) ) { if ( m_mTree[nId].m_vInters[j].bCCW) { - bValidNextStart = ( m_mTree[nId].m_vInters[vToCheckNow[t + 1]].nIn == nEdge) && // loop successivo inizia su questo lato + bValidNextStart = ( AreSameEdge( m_mTree[nId].m_vInters[vToCheckNow[t + 1]].nIn, nEdge)) && // loop successivo inizia su questo lato ! CheckIfAfter( plTrimmedPoly, m_mTree[nId].m_vInters[vToCheckNow[t + 1]].vpt[0], nEdge) ; // in posizione giusta da essere concatenato } else { // se il loop è CW e sono tornato sul lato di partenza allora controllo se sono prima del primo punto della polyline - bValidNextStart = ( m_mTree[nId].m_vInters[vToCheckNow[t + 1]].nIn == nEdge) && + bValidNextStart = ( AreSameEdge( m_mTree[nId].m_vInters[vToCheckNow[t + 1]].nIn, nEdge)) && CheckIfAfter( plTrimmedPoly, m_mTree[nId].m_vInters[vToCheckNow[t + 1]].vpt[0], nEdge) ; } } else - bValidNextStart = true ; - if ( m_mTree[nId].m_vInters[vToCheckNow[t + 1]].nIn != nEdge || bValidNextStart) + bValidNextStart = CheckIfAfter( plTrimmedPoly, m_mTree[nId].m_vInters[vToCheckNow[t + 1]].vpt[0], nEdge) ; + if ( ! AreSameEdge( m_mTree[nId].m_vInters[vToCheckNow[t + 1]].nIn, nEdge) || bValidNextStart) break ; // se ho trovato un loop successivo che devo saltare, lo salvo e considero i loop più avanti. - if ( m_mTree[nId].m_vInters[vToCheckNow[t + 1]].nIn == nEdge && ! bValidNextStart){ + if ( AreSameEdge( m_mTree[nId].m_vInters[vToCheckNow[t + 1]].nIn, nEdge) && ! bValidNextStart){ ++ nSecondCheck ; vToCheck.push_back( t + 1) ; } } if ( m_mTree[nId].m_vInters[j].bCCW) { - bNotCameBack = m_mTree[nId].m_vInters[j].nIn != nEdge && // sono tornato al lato di ingresso di questo loop - nEdge != nEdgeIn ; // sono tornato sul lato di ingresso di questo poligono ( solo se la curva è CCW) + //bNotCameBack = ! AreSameEdge( m_mTree[nId].m_vInters[j].nIn, nEdge) && // sono tornato al lato di ingresso di questo loop + // ! AreSameEdge( nEdge, nEdgeIn) ; // sono tornato sul lato di ingresso di questo poligono ( solo se la curva è CCW) + bNotCameBack = ! ( AreSameEdge( nEdge, nEdgeIn) && CheckIfBefore( plTrimmedPoly, nEdge)) ; } else { - // se il loop è CW e sono tornato sul lato di partenza allora controllo se sono prima del primo punto della polyline - if ( nEdge == nEdgeIn ) { + // il loop è CW e sono tornato sul lato di partenza allora controllo se sono prima del primo punto della polyline + if ( AreSameEdge( nEdge, nEdgeIn)) { bool bBefore = CheckIfBefore( plTrimmedPoly, nEdge) ; bNotCameBack = bNotCameBack && !bBefore ; } @@ -1991,20 +2295,22 @@ Tree::CreateCellPolygons( int nLeafId, std::vector& vPolygons, I } // se ho trovato un altro loop salto all'inizio del for - if ( m_mTree[nId].m_vInters[vToCheckNow[w + 1 + nSecondCheck]].nIn == nEdge) { - w = w + nSecondCheck ; + // + //if ( AreSameEdge( m_mTree[nId].m_vInters[vToCheckNow[w + 1 + nSecondCheck]].nIn, nEdge) && bValidNextStart) { // qui ho aggiunto bValidNextStart///////////////////////// + if ( bValidNextStart) { /////////////////////////////// + w = w + nSecondCheck ; continue ; } } // non ho altri loop quindi aggiungo vertici finché torno al punto di partenza else { if ( m_mTree[nId].m_vInters[j].bCCW ) { - bNotCameBack = m_mTree[nId].m_vInters[j].nIn != nEdge && // sono tornato al lato di ingresso di questo loop - nEdge != nEdgeIn ; // sono tornato sul lato di ingresso di questo poligono ( solo se la curva è CCW) + bNotCameBack = ! AreSameEdge( m_mTree[nId].m_vInters[j].nIn, nEdge) && // sono tornato al lato di ingresso di questo loop + ! AreSameEdge( nEdge, nEdgeIn) ; // sono tornato sul lato di ingresso di questo poligono ( solo se la curva è CCW) } else { // se il loop è CW e sono tornato sul lato di partenza allora controllo se sono prima del primo punto della polyline - if ( nEdge == nEdgeIn ) { + if ( AreSameEdge( nEdge, nEdgeIn) ) { bool bBefore = CheckIfBefore( plTrimmedPoly, nEdge) ; bNotCameBack = bNotCameBack && ! bBefore ; } @@ -2012,30 +2318,35 @@ Tree::CreateCellPolygons( int nLeafId, std::vector& vPolygons, I while ( bNotCameBack) { Point3d ptVert ; if ( nEdge == 0) { - ptVert.x = m_mTree[nId].GetBottomLeft().x ; - ptVert.y = m_mTree[nId].GetTopRight().y ; + //ptVert.x = m_mTree[nId].GetBottomLeft().x ; + //ptVert.y = m_mTree[nId].GetTopRight().y ; + ptVert = ptTl ; } else if ( nEdge == 1) ptVert = m_mTree[nId].GetBottomLeft() ; else if ( nEdge == 2) { - ptVert.x = m_mTree[nId].GetTopRight().x ; - ptVert.y = m_mTree[nId].GetBottomLeft().y ; + //ptVert.x = m_mTree[nId].GetTopRight().x ; + //ptVert.y = m_mTree[nId].GetBottomLeft().y ; + ptVert = ptBr ; } else if ( nEdge == 3) ptVert = m_mTree[nId].GetTopRight() ; - plTrimmedPoly.AddUPoint( c, ptVert) ; - ++c ; - if ( nEdge != 3) + AddVertex( nId, vEdgeVertex, plTrimmedPoly, c, ptVert) ; + //plTrimmedPoly.AddUPoint( c, ptVert) ; + //++c ; + if ( nEdge > 3 && nEdge != 7) + nEdge = nEdge - 4 ; + else if ( nEdge < 3 ) ++ nEdge ; else nEdge = 0 ; // aggiorno le condizioni per il while if ( m_mTree[nId].m_vInters[j].bCCW ) { - bNotCameBack = m_mTree[nId].m_vInters[j].nIn != nEdge && - nEdge != nEdgeIn ; + bNotCameBack = ! AreSameEdge( m_mTree[nId].m_vInters[j].nIn, nEdge) && + ! AreSameEdge( nEdge, nEdgeIn) ; } else { - if ( nEdge == nEdgeIn ) { + if ( AreSameEdge( nEdge, nEdgeIn)) { bool bBefore = CheckIfBefore( plTrimmedPoly, nEdge) ; bNotCameBack = bNotCameBack && ! bBefore ; } @@ -2043,11 +2354,15 @@ Tree::CreateCellPolygons( int nLeafId, std::vector& vPolygons, I } } plTrimmedPoly.Close() ; - vCellPolygons.push_back( plTrimmedPoly) ; - vPolygons.push_back( vCellPolygons) ; - ++ nPoly ; - vnParentChunk.push_back( inA.nChunk) ; - vCellPolygons.clear() ; + double dArea ; + plTrimmedPoly.GetAreaXY( dArea) ; + if ( dArea > EPS_SMALL ) { + vCellPolygons.push_back( plTrimmedPoly) ; + vPolygons.push_back( vCellPolygons) ; + ++ nPoly ; + vnParentChunk.push_back( inA.nChunk) ; + vCellPolygons.clear() ; + } c = 0 ; plTrimmedPoly.Clear() ; nEdgeIn = -1 ; @@ -2078,7 +2393,7 @@ Tree::CreateIslandAndHoles( int nLeafId, std::vector& vPolygons, // numero dei loop interni passati int n = 0 ; Inters inA = m_mTree[nId].m_vInters[n] ; - if ( m_mTree[nId].m_nFlag == 2 && inA.nOut == -3) { + if ( m_mTree[nId].m_nFlag == 2 && ! inA.bCCW) { // i loop esterni sono CW, quindi prima dei loop di trim aggiungo il bordo cella Point3d ptVert = m_mTree[nId].GetTopRight() ; plInLoop.AddUPoint( 0, ptVert) ; @@ -2143,6 +2458,7 @@ Tree::CreateIslandAndHoles( int nLeafId, std::vector& vPolygons, bool Tree::CheckIfBefore( PolyLine& pl, int nEdge) const { + // controllo se ptEnd è prima di ptStart sul lato nEdge rispetto al senso antiorario ( quindi se è dopo in senso orario) Point3d ptStart, ptEnd ; pl.GetFirstPoint( ptStart) ; pl.GetLastPoint( ptEnd) ; @@ -2161,24 +2477,381 @@ Tree::CheckIfBefore( PolyLine& pl, int nEdge) const return false ; } +//---------------------------------------------------------------------------- +bool +Tree::CheckIfBefore( Inters& inA) const +{ + int nEdge1 = inA.nIn ; + int nEdge2 = inA.nOut ; + PolyLine pl ; + //int c = 0 ; + //for ( int p = 0 ; p < (int)inA.vpt.size(); ++p ) { + // Point3d ptToAdd = inA.vpt[p] ; + // pl.AddUPoint( c, ptToAdd) ; + // ++ c ; + //} + pl.AddUPoint( 0, inA.vpt[0]) ; + pl.AddUPoint( 1, inA.vpt.back()) ; + INTVECTOR vEdges = { 7, 0, 4, 1, 5, 2, 6} ; + // controllo se nEdge1 viene prima di nEdge2. la partenza è da ptTR e l'arrivo è ptBr + + INTVECTOR :: iterator iter1 = find( vEdges.begin(), vEdges.end(), nEdge1) ; + int nPos1 = std::distance( vEdges.begin(), iter1) ; + INTVECTOR :: iterator iter2 = find( vEdges.begin(), vEdges.end(), nEdge2) ; + int nPos2 = std::distance( vEdges.begin(), iter2) ; + if ( nPos1 < nPos2) + return true ; + else if ( nPos1 > nPos2) + return false ; + // nPos1 == nPos2 + else { + if ( CheckIfBefore( pl, vEdges[nPos1])) { + return true ; + } + else + return false ; + } +} + +//---------------------------------------------------------------------------- +bool +Tree::CheckIfBefore( int& nEdge1, Point3d& ptP1, int& nEdge2, Point3d& ptP2) const +{ + INTVECTOR vEdges = { 7, 0, 4, 1, 5, 2, 6} ; + // controllo se nEdge1 viene prima di nEdge2. la partenza è da ptTR e l'arrivo è ptBr + INTVECTOR :: iterator iter1 = find( vEdges.begin(), vEdges.end(), nEdge1) ; + int nPos1 = std::distance( vEdges.begin(), iter1) ; + INTVECTOR :: iterator iter2 = find( vEdges.begin(), vEdges.end(), nEdge2) ; + int nPos2 = std::distance( vEdges.begin(), iter2) ; + if ( nPos1 < nPos2) + return true ; + else if ( nPos1 > nPos2) + return false ; + // ( nPos1 == nPos2) + else { + PolyLine pl ; + pl.AddUPoint( 0, ptP2) ; + pl.AddUPoint( 1, ptP1) ; + if ( CheckIfBefore( pl, vEdges[nPos1])) + return true ; + else + return false ; + } +} + //---------------------------------------------------------------------------- bool Tree::CheckIfAfter( PolyLine& pl, Point3d& ptNextStart, int nEdge) const { + // controllo se ptNextStart è più avanti rispetto a ptEnd in senso antiorario + + // se i punti non sono sullo stesso lato ritorno false Point3d ptEnd ; pl.GetLastPoint( ptEnd) ; if ( nEdge == 0 ) { - return ptEnd.x > ptNextStart.x ; + if ( ptNextStart.y > ptEnd.y - EPS_SMALL && ptNextStart.y < ptEnd.y + EPS_SMALL) + return ptEnd.x > ptNextStart.x ; + else + return false ; } else if ( nEdge == 1 ) { - return ptEnd.y > ptNextStart.y ; + if ( ptNextStart.x > ptEnd.x - EPS_SMALL && ptNextStart.x < ptEnd.x + EPS_SMALL) + return ptEnd.y > ptNextStart.y ; + else + return false ; } else if ( nEdge == 2 ) { - return ptEnd.x < ptNextStart.x ; + if ( ptNextStart.y > ptEnd.y - EPS_SMALL && ptNextStart.y < ptEnd.y + EPS_SMALL) + return ptEnd.x < ptNextStart.x ; + else + return false ; } else if ( nEdge == 3 ) { - return ptEnd.y < ptNextStart.y ; + if ( ptNextStart.x > ptEnd.x - EPS_SMALL && ptNextStart.x < ptEnd.x + EPS_SMALL) + return ptEnd.y < ptNextStart.y ; + else + return false ; } return false ; } +//---------------------------------------------------------------------------- +bool +Tree::AreSameEdge( int nEdge1, int nEdge2) const +{ + if ( nEdge1 == 0) { + if ( nEdge2 == 4 || nEdge2 == 0 || nEdge2 == 7) + return true; + else + return false ; + } + else if ( nEdge1 == 1) { + if ( nEdge2 == 4 || nEdge2 == 1 || nEdge2 == 5) + return true; + else + return false ; + } + else if ( nEdge1 == 2) { + if ( nEdge2 == 6 || nEdge2 == 2 || nEdge2 == 5) + return true; + else + return false ; + } + else if ( nEdge1 == 3) { + if ( nEdge2 == 6 || nEdge2 == 3 || nEdge2 == 7) + return true; + else + return false ; + } + else if ( nEdge1 == 4) { + if ( nEdge2 == 0 || nEdge2 == 1 || nEdge2 == 7 || nEdge2 == 5) + return true; + else + return false ; + } + else if ( nEdge1 == 5) { + if ( nEdge2 == 2 || nEdge2 == 1 || nEdge2 == 4 || nEdge2 == 6) + return true; + else + return false ; + } + else if ( nEdge1 == 6) { + if ( nEdge2 == 2 || nEdge2 == 3 || nEdge2 == 5 || nEdge2 == 7) + return true; + else + return false ; + } + else if ( nEdge1 == 7) { + if ( nEdge2 == 0 || nEdge2 == 3 || nEdge2 == 4 || nEdge2 == 6) + return true; + else + return false ; + } + else + return false ; +} + +//---------------------------------------------------------------------------- +bool +Tree::AddVertex( int nId, std::vector& vEdgeVertex, PolyLine& plTrimmedPoly, int& c, Point3d& ptToAdd) const +{ + 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) ; + Point3d ptBL = m_mTree.at(nId).GetBottomLeft() ; + Point3d ptTR = m_mTree.at(nId).GetTopRight() ; + Point3d ptLast ; + plTrimmedPoly.GetLastPoint( ptLast) ; + // verifico di essere allineato con un lato, sennò aggiungo e basta + Vector3d vDir = ptToAdd - ptLast ; + vDir.Normalize() ; + if ( abs( vDir.x) > 1 - EPS_SMALL || abs( vDir.y) > 1 - EPS_SMALL) { + // se su un edge devo fare dei controlli + // edge 0 + if ( ptToAdd.x >= ptBL.x && ptToAdd.x <= ptTR.x && ptToAdd.y == ptTR.y && abs(vDir.x) > 1 - EPS_SMALL) { + for ( int t = 0 ; t < (int)vEdgeVertex[0].size() ; ++ t) { + Point3d ptIntermed = vEdgeVertex[0][t] ; + if ( ptIntermed.x > ptToAdd.x ) { + plTrimmedPoly.AddUPoint( c, ptIntermed) ; + ++ c ; + } + else + break ; + } + plTrimmedPoly.AddUPoint( c, ptToAdd) ; + ++ c ; + } + // edge 1 + else if ( ptToAdd.y >= ptBL.y && ptToAdd.y <= ptTR.y && ptToAdd.x == ptBL.x && abs(vDir.y) > 1 - EPS_SMALL) { + for ( int t = 0 ; t < (int)vEdgeVertex[1].size() ; ++ t) { + Point3d ptIntermed = vEdgeVertex[1][t] ; + if ( ptIntermed.y > ptToAdd.y ) { + plTrimmedPoly.AddUPoint( c, ptIntermed) ; + ++ c ; + } + else + break ; + } + plTrimmedPoly.AddUPoint( c, ptToAdd) ; + ++ c ; + } + // edge 2 + else if ( ptToAdd.x >= ptBL.x && ptToAdd.x <= ptTR.x && ptToAdd.y == ptBL.y && abs(vDir.x) > 1 - EPS_SMALL) { + for ( int t = 0 ; t < (int)vEdgeVertex[2].size() ; ++ t) { + Point3d ptIntermed = vEdgeVertex[2][t] ; + if ( ptIntermed.x < ptToAdd.x ) { + plTrimmedPoly.AddUPoint( c, ptIntermed) ; + ++ c ; + } + else + break ; + } + plTrimmedPoly.AddUPoint( c, ptToAdd) ; + ++ c ; + } + // edge 3 + else if ( ptToAdd.y >= ptBL.y && ptToAdd.y <= ptTR.y && ptToAdd.x == ptTR.x && abs(vDir.y) > 1 - EPS_SMALL) { + for ( int t = 0 ; t < (int)vEdgeVertex[3].size() ; ++ t) { + Point3d ptIntermed = vEdgeVertex[3][t] ; + if ( ptIntermed.y < ptToAdd.y ) { + plTrimmedPoly.AddUPoint( c, ptIntermed) ; + ++ c ; + } + else + break ; + } + plTrimmedPoly.AddUPoint( c, ptToAdd) ; + ++ c ; + } + // sono allineato con un lato, ma NON sono su un lato + // aggiungo e basta + else { + plTrimmedPoly.AddUPoint( c, ptToAdd); + ++ c ; + } + } + // non su un edge, quindi aggiungo e basta + else { + plTrimmedPoly.AddUPoint( c, ptToAdd); + ++ c ; + } + return true ; +} + +////---------------------------------------------------------------------------- +//bool +//Tree::SetRightEdgeIn( int nId, std::vector& vEdgeVertex, PolyLine& plTrimmedPoly) +//{ +// Point3d ptBr( m_mTree.at(nId).GetTopRight().x , m_mTree.at(nId).GetBottomLeft().y) ; +// Point3d ptTR = m_mTree.at(nId).GetTopRight() ; +// int nPos0 = -1 , nPos1 = -1 ; +// bool bSave = false ; +// PNTLIST lPtInt ; +// for ( int k = 0 ; k < plTrimmedPoly.GetPointNbr() ; ++ k) { +// Point3d ptIter ; +// plTrimmedPoly. GetNextPoint( ptIter) ; +// if ( AreSamePointExact( ptIter, ptBr) ) { +// nPos0 = k ; +// bSave = bSave ^ true ; +// } +// if ( AreSamePointExact( ptIter, ptTR) ) { +// nPos1 = k ; +// bSave = bSave ^ true ; +// } +// if ( bSave) { +// lPtInt.push_back( ptIter) ; +// } +// } +// lPtInt.pop_front() ; +// // verifico se ci sono tutti e due i punti +// if ( nPos0 != -1 && nPos1 != -1 ) { +// // se sono di seguito tutto il lato destro è dentro +// if ( nPos1 == nPos0 + 1 || nPos0 == nPos1 + 1) { +// m_mTree[nId].m_nRightEdgeIn = 1 ; +// } +// // ci sono dei punti in mezzo, devo capire se sono allineati o no +// else { +// // verifico se tutti i punti intermedi sono allineati o no +// CurveLine clRightEdge ; +// clRightEdge.Set( ptBr, ptTR) ; +// bool bAllOn = true ; +// +// PNTLIST::iterator lIter = lPtInt.begin() ; +// std::advance(lIter, 0) ; +// for ( int p = 0 ; p < (int)lPtInt.size() ; ++ p) { +// if ( ! clRightEdge.IsPointOn( *lIter)) { +// bAllOn = false ; +// break ; +// } +// } +// // divisi da punti allineati e quindi lato dentro +// if ( bAllOn) { +// m_mTree[nId].m_nRightEdgeIn = 1 ; +// } +// // se sono dentro, ma non allineati, allora solo in parte +// else { +// m_mTree[nId].m_nRightEdgeIn = 2 ; +// } +// } +// } +// // il lato destro è sicuramente esterno +// else { +// m_mTree[nId].m_nRightEdgeIn = 0 ; +// } +// return true ; +//} + +//---------------------------------------------------------------------------- +bool +Tree::SetRightEdgeIn( int nId) +{ + Point3d ptBr( m_mTree.at(nId).GetTopRight().x , m_mTree.at(nId).GetBottomLeft().y) ; + Point3d ptTR = m_mTree.at(nId).GetTopRight() ; + // se ho inters sul lato destro allora in parte è dentro + int nPass = (int) m_mTree[nId].m_vInters.size() ; + bool bDone = false ; + for ( int k = 0 ; k < nPass ; ++ k) { + if ( m_mTree[nId].m_vInters[k].nIn == 3 || m_mTree[nId].m_vInters[k].nOut == 3 ) { + m_mTree[nId].m_nRightEdgeIn = 2 ; + bDone = true ; + break ; + } + // considero anche ingressi/ uscite dai vertici 6 e 7 + if ( AreSameEdge( m_mTree[nId].m_vInters[k].nIn, 3) || AreSameEdge( m_mTree[nId].m_vInters[k].nOut, 3) ) { + m_mTree[nId].m_nRightEdgeIn = 2 ; + bDone = true ; + break ; + } + } + // se non ho inters sul lato destro devo verificare se è tutto dentro o tutto fuori + if ( ! bDone) { + // ciclo sulle inters e cerco se ho dei passaggi con un'uscita più bassa di un'entrata e se eventualmente è la più a destra! + bool bFound = false ; + bool bRightMost = false ; + int nEdgeIn = 6, nEdgeOut = 7, nLoop ; + Point3d ptIn, ptOut ; + for ( int k = 0 ; k < nPass ; ++ k) { + // trovo il loop che ha l'ingresso o l'uscita più a destra + if ( CheckIfBefore( m_mTree[nId].m_vInters[k].nIn, m_mTree[nId].m_vInters[k].vpt[0], nEdgeIn, ptIn) || + CheckIfBefore( nEdgeOut, ptOut, m_mTree[nId].m_vInters[k].nOut, m_mTree[nId].m_vInters[k].vpt.back())) { + nLoop = k ; + nEdgeIn = m_mTree[nId].m_vInters[k].nIn ; + ptIn = m_mTree[nId].m_vInters[k].vpt[0] ; + nEdgeOut = m_mTree[nId].m_vInters[k].nOut ; + ptOut = m_mTree[nId].m_vInters[k].vpt.back() ; + bFound = true ; + } + } + if ( bFound && CheckIfBefore( m_mTree[nId].m_vInters[nLoop])) { + bRightMost = true ; + } + // se il mio campione attraversa dall'alto al basso allora il lato destro è dentro!!! + if ( bFound && bRightMost) + m_mTree[nId].m_nRightEdgeIn = 1 ; + else + m_mTree[nId].m_nRightEdgeIn = 0 ; + + } + + if ( m_mTree[nId].m_nRightEdgeIn != -1) + return true ; + else + return false ; +} + +//---------------------------------------------------------------------------- +bool +Tree::CategorizeCell( int& nId) +{ + //if ( m_mTree[nId].m_nFlag != -1) { + // return true ; + //} + //INTVECTOR vNeigh ; + //GetLeftNeigh( nId, vNeigh) ; + //// mi servono i vicini di sinistra per capire se sono dentro il loop o fuori + //// 0 right edge fuori, 1 right edge dentro, 2 metà e metà + //if ( ) { + + //} + // m_mTree[nId].m_nFlag2 = 1 ; + return true ; +} diff --git a/Tree.h b/Tree.h index b442371..d3ab143 100644 --- a/Tree.h +++ b/Tree.h @@ -24,6 +24,7 @@ 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 @@ -115,14 +116,22 @@ private : void GetRightNeigh( int nId, INTVECTOR& vRightNeighs) const ; // restituisce le celle foglie che sono adiacenti al lato right 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 - int FindCell ( const Point3d& ptToAssign) const ; // dato un punto, trova la cella foglia a cui appartiene + INTVECTOR FindCell ( const Point3d& ptToAssign, CurveLine& cl) const ; // dato un punto, trova la cella foglia a cui appartiene + INTVECTOR FindCell ( const Point3d& ptToAssign, CurveLine& cl, INTVECTOR vCells) const ; // dato un punto, trova la cella foglia a cui appartiene bool TraceLoopLabelCell( void) ; // tracing dei loop e labelling delle celle - bool FindInters( int& nId, CurveLine& clTrim, PNTVECTOR& vptInters) ; // trova le intersezioni tra una cella e una linea di trim + bool FindInters( int& nId, CurveLine& clTrim, PNTVECTOR& vptInters, bool& bVertex) ; // 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 - bool CreateCellPolygons ( int nLeafId, std::vector& vPolygons, INTVECTOR& vToCheck, int& nPoly, INTVECTOR& vnParentChunk) ; + bool CreateCellPolygons ( int nLeafId, std::vector& vPolygons, INTVECTOR& vToCheck, int& nPoly, INTVECTOR& vnParentChunk, PolyLine plCell) ; bool CreateIslandAndHoles ( int nLeafId, std::vector& vPolygons, int& nPoly, INTVECTOR& vnParentChunk) ; bool CheckIfBefore( PolyLine& pl, int nEdge) const ; + bool CheckIfBefore( Inters& inA) const ; + bool CheckIfBefore( int& nEdge1, Point3d& ptP1, int& nEdge2, Point3d& ptP2) const ; bool CheckIfAfter( PolyLine& pl, Point3d& ptNextStart, int nEdge) const ; + bool AreSameEdge( int nEdge1, int nEdge2) const ; + bool AddVertex( int nId, std::vector& vEdgeVertex, PolyLine& plTrimmedPoly, int& c, Point3d& ptToAdd) const ; + //bool SetRightEdgeIn( int nId, std::vector& vEdgeVertex, PolyLine& plTrimmedPoly) ; + bool SetRightEdgeIn( int nId) ; + bool CategorizeCell( int& nId) ; private : const SurfBezier* m_pSrfBz ; // superficie di bezier