diff --git a/SurfBezier.cpp b/SurfBezier.cpp index f5852f8..19b6516 100644 --- a/SurfBezier.cpp +++ b/SurfBezier.cpp @@ -1607,17 +1607,17 @@ SurfBezier::GetCurveOnVApproxLen( double dU) const return dLen ; } -//---------------------------------------------------------------------------- -bool -SurfBezier::UpdateEdgesFromTree( Tree& tr) const -{ - tr.GetEdges3D( m_mCCEdge) ; - - if ( m_bTrimmed) - tr.GetSplitLoops( m_vCCLoop) ; - - return true ; -} +////---------------------------------------------------------------------------- +//bool +//SurfBezier::UpdateEdgesFromTree( Tree& tr) const +//{ +// tr.GetEdges3D( m_mCCEdge) ; +// +// if ( m_bTrimmed) +// tr.GetSplitLoops( m_vCCLoop) ; +// +// return true ; +//} //---------------------------------------------------------------------------- const SurfTriMesh* @@ -1676,15 +1676,15 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin) const Tree.BuildTree( dTol, dSideMin) ; //Tree.BuildTree( 1, 5) ; //debug } - if ( ! Tree.GetPolygons( vvPL, vvPL3d)) + if ( ! Tree.GetPolygons( vvPL, vvPL3d, m_mCCEdge, m_vCCLoop)) continue ; //Tree.GetPolygonsBasic( vPL, true) ; // per usare i polygon basic // aggiorno la chiusura della superficie m_bClosedU = m_bClosedU || Tree.IsClosedU() ; m_bClosedV = m_bClosedV || Tree.IsClosedV() ; - // salvo i bordi in 3d, che servono in caso si voglia trimmare la superficie DOPO aver costruito la trimesh ausiliaria - UpdateEdgesFromTree( Tree) ; + //// salvo i bordi in 3d, che servono in caso si voglia trimmare la superficie DOPO aver costruito la trimesh ausiliaria + // UpdateEdgesFromTree( Tree) ; } //// per usare i polygon basic////////////////////// diff --git a/SurfBezier.h b/SurfBezier.h index 691f73f..4b8ef2f 100644 --- a/SurfBezier.h +++ b/SurfBezier.h @@ -212,7 +212,7 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW ISurfFlatRegion* CreateTrimRegionFromCuts( ICRVCOMPOPOVECTOR& vpCCOpen, ICRVCOMPOPOVECTOR& vpCCClosed) const ; // restituisce il singolo edge della superficie non trimmata ICurveComposite* GetSingleEdge3D( bool bLineOrBezier, int nEdge) const ; - bool UpdateEdgesFromTree( Tree& tr) const ; + //bool UpdateEdgesFromTree( Tree& tr) const ; // funzione che calcola se gli edge sono collassati in poli bool CalcPoles( void) const ; bool FindMatchByParam( const PolyLine& pl0, const PolyLine& pl1, INTVECTOR& vMatch, int& nLong) const ; diff --git a/Tree.cpp b/Tree.cpp index 184cb8b..a83cc9a 100644 --- a/Tree.cpp +++ b/Tree.cpp @@ -42,14 +42,6 @@ Tree::Tree( void) m_mTree.insert( pair< int, Cell>( -1, cRoot)) ; } -////---------------------------------------------------------------------------- -//Tree::Tree( const SurfBezier* pSrfBz, const bool bSplitPatches, const Point3d& ptMin, const Point3d& ptMax) -// : m_pSrfBz( nullptr), m_bTrimmed( false), m_bBilinear( false), m_bMulti( false), m_bClosedU( false), m_bClosedV( false), m_vbPole( { false, false, false, false}), -// m_bSplitPatches( true), m_bTestMode( false) -//{ -// SetSurf( pSrfBz, bSplitPatches, ptMin, ptMax) ; -//} - //---------------------------------------------------------------------------- Tree::~Tree( void) { @@ -64,69 +56,6 @@ Tree::Tree( const Point3d ptBl, const Point3d ptTr) m_mTree.insert( pair< int, Cell>( -1, cRoot)) ; } -//---------------------------------------------------------------------------- -bool -Tree::LimitLoop( PolyLine& pl, POLYLINEVECTOR& vPl, BOOLVECTOR& vbOrientation) const -{ - //// CON LE CURVE ( INTERSEZIONI CON BORDO PARAMETRICO) - PtrOwner pCCEdge( CreateCurveComposite()) ; - pCCEdge->AddPoint( m_mTree.at(-1).GetTopRight()) ; - pCCEdge->AddLine( m_mTree.at(-1).GetTopLeft()) ; - pCCEdge->AddLine( m_mTree.at(-1).GetBottomLeft()) ; - pCCEdge->AddLine( m_mTree.at(-1).GetBottomRight()) ; - pCCEdge->Close() ; - - PtrOwner pCC( CreateCurveComposite()) ; - pCC->FromPolyLine( pl) ; - ICURVEPLIST vCrv ; - AdjustLoops( Release( pCC), vCrv, false) ; - - if ( vCrv.size() > 1) - VerifyLoopOrientation( vCrv, vbOrientation) ; - for ( auto itCrv = vCrv.begin() ; itCrv != vCrv.end() ; ++itCrv) { - IntersCurveCurve icc( *pCCEdge, *(*itCrv)) ; - CRVCVECTOR vCrvClass ; - ICRVCOMPOPOVECTOR vCC ; - if ( ! icc.GetCurveClassification( 1, 0.01, vCrvClass)) - return false ; // se non riesco a calcolare la classificazione potrei provare a ricostruire a mano usando le intersezioni trovate - int nLast = 0 ; - if ( vCrvClass.size() > 1) { - for ( int i = 0 ; i < int( vCrvClass.size()) ; ++i) { - if ( vCrvClass[i].nClass != CRVC_OUT) { - // se continua la curva precedente allora la giunta - if ( ! vCC.empty() && vCrvClass[i].dParS == vCrvClass[nLast].dParE) - vCC.back()->AddCurve( (*itCrv)->CopyParamRange( vCrvClass[i].dParS, vCrvClass[i].dParE)) ; - // sennò creo una nuova curva - else - vCC.emplace_back( GetCurveComposite( (*itCrv)->CopyParamRange( vCrvClass[i].dParS, vCrvClass[i].dParE))) ; - nLast = i ; - } - } - - POLYLINEVECTOR vPL ; - // qui devo ricostruire la curva con i pezzi da tenere - for ( int i = 0 ; i < int( vCC.size()) ; ++i) { - PolyLine plApprox ; - vCC[i]->ApproxWithLines( 0.01,15, 0, plApprox) ; - vPL.push_back( plApprox) ; - } - PolyLine plNew ; - // ricostruzione col bordo - CloseOpenCuts( vPL, plNew) ; - vPl.push_back( plNew) ; - } - else { - PolyLine plApprox ; (*itCrv)->ApproxWithLines( 0.01, 15, 0, plApprox) ; - vPl.push_back( plApprox) ; - } - } - - for ( auto it = vCrv.begin() ; it != vCrv.end() ; ++it) - delete (*it) ; - - return true ; -} - //---------------------------------------------------------------------------- bool Tree::VerifyLoopOrientation( ICURVEPLIST& vpCrv, BOOLVECTOR& vbOrientation) const @@ -218,11 +147,10 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi m_vnLeaves.clear() ; m_vnParents.clear() ; m_mPt3d.clear() ; - //m_vLoop.clear() ; m_mChunk.clear() ; m_vPlApprox.clear() ; - m_vPolygons.clear() ; - m_vPolygonsCorr.clear() ; + //m_vPolygons.clear() ; + //m_vPolygonsCorr.clear() ; m_vCCLoop2D.clear() ; m_pSrfBz = pSrfBz ; @@ -578,7 +506,7 @@ Tree::GetIndependentTrees( BIPNTVECTOR& vTrees) bool Tree::Split( int nId, double dSplitValue) { - Cell& cToSplit = m_mTree[nId] ; + Cell& cToSplit = m_mTree.at(nId) ; // controllo che lo split non venga fatto sul lato della cella if ( ( cToSplit.IsSplitVert() && dSplitValue > cToSplit.GetBottomLeft().x + EPS_SMALL && dSplitValue < cToSplit.GetTopRight().x - EPS_SMALL) || @@ -652,10 +580,11 @@ bool Tree::Split( int nId) { double dValue ; - if ( m_mTree[nId].IsSplitVert()) - dValue = ( m_mTree[nId].GetBottomLeft().x + m_mTree[nId].GetTopRight().x) / 2 ; + Cell& cCell = m_mTree.at(nId) ; + if ( cCell.IsSplitVert()) + dValue = ( cCell.GetBottomLeft().x + cCell.GetTopRight().x) / 2 ; else - dValue = ( m_mTree[nId].GetBottomLeft().y + m_mTree[nId].GetTopRight().y) / 2 ; + dValue = ( cCell.GetBottomLeft().y + cCell.GetTopRight().y) / 2 ; return Split( nId, dValue) ; } @@ -1235,7 +1164,7 @@ Tree::GetTopNeigh( int nId, INTVECTOR& vTopNeighs) const // le celle restituite sono ordinate per x crescente std::sort( vCells.begin(), vCells.end(), Cell::minorX) ; vTopNeighs.clear() ; - for ( Cell c : vCells) + for ( Cell& c : vCells) vTopNeighs.push_back( c.m_nId) ; } @@ -1318,7 +1247,7 @@ Tree::GetBottomNeigh( int nId, INTVECTOR& vBottomNeighs) const // le celle restituite sono ordinate per x crescente std::sort( vCells.begin(), vCells.end(), Cell::minorX) ; vBottomNeighs.clear() ; - for ( Cell c : vCells) + for ( Cell& c : vCells) vBottomNeighs.push_back( c.m_nId) ; } @@ -1400,7 +1329,7 @@ Tree::GetLeftNeigh( int nId, INTVECTOR& vLeftNeighs) const // le celle restituite sono ordinate per y crescente std::sort( vCells.begin(), vCells.end(), Cell::minorY) ; vLeftNeighs.clear() ; - for ( Cell c : vCells) + for ( Cell& c : vCells) vLeftNeighs.push_back( c.m_nId) ; } @@ -1482,7 +1411,7 @@ Tree::GetRightNeigh( int nId, INTVECTOR& vRightNeighs) const // le celle restituite sono ordinate per y crescente std::sort( vCells.begin(), vCells.end(), Cell::minorY) ; vRightNeighs.clear() ; - for ( Cell c : vCells) + for ( Cell& c : vCells) vRightNeighs.push_back( c.m_nId) ; } @@ -1586,66 +1515,30 @@ Tree::GetDepth( int nId, int nRef = -2) const //---------------------------------------------------------------------------- bool -Tree::GetPolygons( POLYLINEMATRIX& vvPolygons) +Tree::GetPolygons( POLYLINEMATRIX& vvPolygons, POLYLINEMATRIX& vvPolygons3d, vector& vvCCEdges3D, ICRVCOMPOPOVECTOR& vCCLoops) { - POLYLINEMATRIX vvPolygonsBasic3d ; - return GetPolygons( vvPolygons, false, vvPolygonsBasic3d) ; -} - -//---------------------------------------------------------------------------- -bool -Tree::GetPolygons( POLYLINEMATRIX& vvPolygons, POLYLINEMATRIX& vPolygonsBasic3d) -{ - return GetPolygons( vvPolygons, true, vPolygonsBasic3d) ; -} - -//---------------------------------------------------------------------------- -bool -Tree::GetPolygons( POLYLINEMATRIX& vvPolygons, bool bForTriangulation, POLYLINEMATRIX& vvPolygons3d) -{ - if ( m_vPolygons.empty()) { + POLYLINEVECTOR vPolygonsBasic ; + POLYLINEVECTOR vPolygonsCorrected ; + POLYLINEVECTOR vPolygonsBasic3d ; + //if ( m_vPolygons.empty()) { if ( ! m_bTrimmed) { vvPolygons.clear() ; - POLYLINEVECTOR vPolygonsBasic ; - POLYLINEVECTOR vPolygonsCorrected ; - POLYLINEVECTOR vPolygonsBasic3d ; - if ( bForTriangulation) - GetPolygonsBasic( vPolygonsBasic, vPolygonsCorrected, vPolygonsBasic3d) ; - else - GetPolygonsBasic( vPolygonsBasic) ; + + GetPolygonsBasic( vPolygonsBasic, vPolygonsCorrected, vPolygonsBasic3d) ; if (vPolygonsBasic.empty()) return false ; int c = 0; - if( bForTriangulation) { - for ( PolyLine pl : vPolygonsCorrected) { - POLYLINEVECTOR vSinglePolygon ; - vSinglePolygon.push_back( pl) ; - vvPolygons.push_back( vSinglePolygon) ; - POLYLINEVECTOR vSinglePolygon3d ; - vSinglePolygon3d.push_back( vPolygonsBasic3d[c]) ; - vvPolygons3d.push_back( vSinglePolygon3d) ; - ++c ; - } + for ( PolyLine& pl : vPolygonsCorrected) { + vvPolygons.emplace_back() ; + vvPolygons.back().emplace_back(std::move(pl)) ; + vvPolygons3d.emplace_back() ; + vvPolygons3d.back().emplace_back(std::move(vPolygonsBasic3d[c])) ; + ++c ; } - else { - for ( PolyLine pl : vPolygonsBasic) { - POLYLINEVECTOR vSinglePolygon ; - vSinglePolygon.push_back( pl) ; - vvPolygons.push_back( vSinglePolygon) ; - ++c ; - } - } - return true ; } // trimmata else { - POLYLINEVECTOR vPolygonsBasic ; - POLYLINEVECTOR vPolygonsCorrected ; - POLYLINEVECTOR vPolygonsBasic3d ; - if ( bForTriangulation) - GetPolygonsBasic( vPolygonsBasic, vPolygonsCorrected, vPolygonsBasic3d) ; - else - GetPolygonsBasic( vPolygonsBasic) ; + GetPolygonsBasic( vPolygonsBasic, vPolygonsCorrected, vPolygonsBasic3d) ; if (vPolygonsBasic.empty()) return false ; // aggiungo 4 elementi al vettore che contiene ciò che resta degli edge dopo il trim @@ -1664,24 +1557,10 @@ Tree::GetPolygons( POLYLINEMATRIX& vvPolygons, bool bForTriangulation, POLYLINEM int nId = m_vnLeaves[i] ; if ( m_mTree[nId].m_nFlag == 4) { // vettore dei poligoni ( loop) della cella nId - POLYLINEVECTOR vCellPolygons ; - if( bForTriangulation) - vCellPolygons.push_back( vPolygonsCorrected[i]) ; - else - vCellPolygons.push_back( vPolygonsBasic[i]) ; - vvPolygons.push_back( vCellPolygons) ; - if ( bForTriangulation ) { - POLYLINEVECTOR vCellPolygons3d ; - //PolyLine plPolygon3d ; - //plPolygon3d.AddUPoint( 0, m_mVert[nId][0]) ; - //plPolygon3d.AddUPoint( 1, m_mVert[nId][1]) ; - //plPolygon3d.AddUPoint( 2, m_mVert[nId][2]) ; - //plPolygon3d.AddUPoint( 3, m_mVert[nId][3]) ; - //plPolygon3d.AddUPoint( 0, m_mVert[nId][0]) ; - //vCellPolygons3d.push_back( plPolygon3d) ; - vCellPolygons3d.push_back( vPolygonsBasic3d[i]) ; - vvPolygons3d.push_back( vCellPolygons3d) ; - } + vvPolygons.emplace_back() ; + vvPolygons.back().push_back(std::move(vPolygonsCorrected[i])) ; + vvPolygons3d.emplace_back() ; + vvPolygons3d.back().push_back(std::move(vPolygonsBasic3d[i])) ; } else if ( m_mTree[nId].m_nFlag == 0) continue ; @@ -1699,64 +1578,45 @@ Tree::GetPolygons( POLYLINEMATRIX& vvPolygons, bool bForTriangulation, POLYLINEM while ( ! vToCheck.empty()) { int nPolyBefore = nPoly ; PolyLine pl3d ; - if ( bForTriangulation) - pl3d = vPolygonsBasic3d[i] ; - if ( bForTriangulation) - CreateCellPolygons( i, vvPolygons, vvPolygons3d, vToCheck, nPoly, vnParentChunk, vPolygonsCorrected[i], pl3d) ; - else - CreateCellPolygons( i, vvPolygons, vvPolygons3d, vToCheck, nPoly, vnParentChunk, vPolygonsBasic[i], pl3d) ; + CreateCellPolygons( i, vvPolygons, vvPolygons3d, vToCheck, nPoly, vnParentChunk, vPolygonsCorrected[i], vPolygonsBasic3d[i]) ; if ( nPolyBefore == nPoly) break ; } // ora analizzo anche i loop che sono contenuti nella cella - if ( bForTriangulation) - CreateIslandAndHoles( i, vvPolygons, vvPolygons3d, nPoly, vnParentChunk, bForTriangulation, vPolygonsCorrected[i], vPolygonsBasic3d[i]) ; - else - CreateIslandAndHoles( i, vvPolygons, vvPolygons3d, nPoly, vnParentChunk, bForTriangulation, vPolygonsBasic[i], vPolygonsBasic3d[i]) ; + CreateIslandAndHoles( i, vvPolygons, vvPolygons3d, nPoly, vnParentChunk, vPolygonsCorrected[i], vPolygonsBasic3d[i]) ; } } - return true ; } - } + + // aggiorno gli edge 3d e i loop della superficie + GetEdges3D( vvCCEdges3D, vPolygonsCorrected) ; + GetSplitLoops( vCCLoops) ; + return true ; + /*} else { vvPolygons = m_vPolygons ; return true ; - } + }*/ } //---------------------------------------------------------------------------- bool Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygonsCorrected, POLYLINEVECTOR& vPolygons3d) -{ - return GetPolygonsBasic( vPolygonsBasic, vPolygonsCorrected, true, vPolygons3d) ; -} - -//---------------------------------------------------------------------------- -bool -Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, INTVECTOR vCells) -{ - POLYLINEVECTOR vPolygons3d ; - POLYLINEVECTOR vPolygonsCorrected ; - return GetPolygonsBasic( vPolygonsBasic, vPolygonsCorrected, false, vPolygons3d, vCells) ; -} - -//---------------------------------------------------------------------------- -bool -Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygonsCorrected, bool bForTriangulation, POLYLINEVECTOR& vPolygons3d, INTVECTOR vCells) { // condizioni per il calcolo dei poligoni di base PNTVECTOR vVertices ; PNTVECTOR vVerticesCorr ; PNTVECTOR vVertices3d ; - if ( m_vPolygons.empty() || // se non li ho mai calcolati - ( ! m_vPolygons.empty() && ! vCells.empty()) || // se ho già calcolato dei poligoni ma ne sto chiedendo di un altro gruppo di celle - ( vCells.empty() && m_vPolygons.size() != m_vnLeaves.size()) || // se sto chiedendo i poligoni di tutte le celle, ma i poligoni già calcolati sono meno delle celle - bForTriangulation) { // oppure se sto chiedendo i poligoni per la triangolazione ( devo fare considerazioni particolari se ho dei poli sui lati del parametrico) - m_vPolygons.clear() ; - m_vPolygons3d.clear() ; - // se non ho dato un elenco di celle in input do per scontato che la chiamata sia per calcolare i poligoni di tutte le foglie - if ( vCells.empty()) - vCells = m_vnLeaves ; + //if ( m_vPolygons.empty() || // se non li ho mai calcolati + // ( ! m_vPolygons.empty() && ! vCells.empty()) || // se ho già calcolato dei poligoni ma ne sto chiedendo di un altro gruppo di celle + // ( vCells.empty() && m_vPolygons.size() != m_vnLeaves.size()) || // se sto chiedendo i poligoni di tutte le celle, ma i poligoni già calcolati sono meno delle celle + // bForTriangulation) { // oppure se sto chiedendo i poligoni per la triangolazione ( devo fare considerazioni particolari se ho dei poli sui lati del parametrico) + //m_vPolygons.clear() ; + //m_vPolygons3d.clear() ; + + //// se non ho dato un elenco di celle in input do per scontato che la chiamata sia per calcolare i poligoni di tutte le foglie + //if ( vCells.empty()) + // vCells = m_vnLeaves ; INTVECTOR vNeigh ; // setto le celle che sono sul LeftEdge e sul TopEdge @@ -1777,7 +1637,8 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon // scorro lungo tutte le celle leaves e oltre agli angoli della cella aggiungo alla polyline della cella anche i vertici, delle celle adiacenti, // che sono sui lati della cella corrente // N.B. :i poligoni sono costruiti a partire dal ptBL !!! - for ( int nId : vCells) { + int c = 0 ; + for ( int nId : m_vnLeaves) { Cell& cell = m_mTree.at( nId) ; vVertices.clear() ; vVertices3d.clear() ; @@ -1787,7 +1648,7 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon vVertices3d.push_back( pt3d) ; INTVECTOR vnVert ; BOOLVECTOR vbBonusVert(4) ; - fill( vbBonusVert.begin(), vbBonusVert.end(), false) ; + std::fill( vbBonusVert.begin(), vbBonusVert.end(), false) ; vnVert.push_back( int(vVertices.size()) - 1) ; GetBottomNeigh( nId, vNeigh) ; Point3d ptP00, ptP10, ptP11, ptP01 ; @@ -1932,128 +1793,126 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon vnVert.push_back( int(vVertices.size()) - 1) ; BOOLVECTOR vbKeepPoint( vVertices.size()) ; - fill( vbKeepPoint.begin(), vbKeepPoint.end(), true) ; + std::fill( vbKeepPoint.begin(), vbKeepPoint.end(), true) ; // se non è trimmata aggiusto subito il vettore dei vertici, sennò i salvo le informazioni per quando creerò i poligoni trimmato vVerticesCorr = vVertices ; - if ( bForTriangulation){ - // ora devo controllare se uno dei lati della cella è collassato in un punto. - // se così, devo guardare se sui due lati adiacenti a quello di polo ho messo dei punti extra - // se ne ho messi solo su uno dei due allora devo togliere il vertice dell'altro lato - if ( AreSamePointApprox(ptP00, ptP10)) { - // sennò devo togliere l'estremo del lato su cui NON ho punti bonus - if ( vbBonusVert[1] && ! vbBonusVert[3]) {// lati contati a partire da quello sopra in senso CCW - if ( ! m_bTrimmed) { - vVerticesCorr.erase(vVerticesCorr.begin() + vnVert[1]) ; // vertici della cella contati a partire da ptBL in senso CCW - vVertices3d.erase(vVertices3d.begin() + vnVert[1]) ; - } - vbKeepPoint[vnVert[1]] = false ; - cell.m_nVertToErase = 1 ; // ptBr - } - else if ( ! vbBonusVert[1] && vbBonusVert[3] ) { - if ( ! m_bTrimmed) { - // dovrei eliminare ptBL, quindi devo eliminare il primo e l'ultimo punto della polyline e poi chiuderla con quello che era il penultimo punto - vVerticesCorr.pop_back() ; - vVerticesCorr[0] = vVerticesCorr.end()[-1] ; - vVertices3d.pop_back() ; - vVertices3d[0] = vVertices3d.end()[-1] ; - } - vbKeepPoint[0] = false ; - vbKeepPoint.back() = false ; - cell.m_nVertToErase = 0 ; // ptBL - } - // se non ho bonus su nessuno dei due - else { - // ne scelgo uno dei due da togliere - vbKeepPoint[vnVert[1]] = false ; - cell.m_nVertToErase = 1 ; // ptBr + // ora devo controllare se uno dei lati della cella è collassato in un punto. + // se così, devo guardare se sui due lati adiacenti a quello di polo ho messo dei punti extra + // se ne ho messi solo su uno dei due allora devo togliere il vertice dell'altro lato + if ( AreSamePointApprox(ptP00, ptP10)) { + // sennò devo togliere l'estremo del lato su cui NON ho punti bonus + if ( vbBonusVert[1] && ! vbBonusVert[3]) {// lati contati a partire da quello sopra in senso CCW + if ( ! m_bTrimmed) { + vVerticesCorr.erase(vVerticesCorr.begin() + vnVert[1]) ; // vertici della cella contati a partire da ptBL in senso CCW + vVertices3d.erase(vVertices3d.begin() + vnVert[1]) ; } + vbKeepPoint[vnVert[1]] = false ; + cell.m_nVertToErase = 1 ; // ptBr } - if ( AreSamePointApprox(ptP10, ptP11)) { - // sennò devo togliere l'estremo del lato su cui NON ho punti bonus - if ( vbBonusVert[0] && ! vbBonusVert[2]){ // lati contati a partire da quello sopra in senso CCW - if ( ! m_bTrimmed) { - vVerticesCorr.erase(vVerticesCorr.begin() + vnVert[1]) ; // vertici della cella contati a partire da ptBL in senso CCW - vVertices3d.erase(vVertices3d.begin() + vnVert[1]) ; - } - vbKeepPoint[vnVert[1]] = false ; - cell.m_nVertToErase = 1 ; // ptBr - } - else if ( ! vbBonusVert[0] && vbBonusVert[2] ){ - if ( ! m_bTrimmed) { - vVerticesCorr.erase(vVerticesCorr.begin() + vnVert[2]) ; - vVertices3d.erase(vVertices3d.begin() + vnVert[2]) ; - } - vbKeepPoint[vnVert[2]] = false ; - cell.m_nVertToErase = 2 ; // ptTR - } - // se non ho bonus su nessuno dei due - else { - // ne scelgo uno dei due da togliere - vbKeepPoint[vnVert[2]] = false ; - cell.m_nVertToErase = 2 ; // ptTR + else if ( ! vbBonusVert[1] && vbBonusVert[3] ) { + if ( ! m_bTrimmed) { + // dovrei eliminare ptBL, quindi devo eliminare il primo e l'ultimo punto della polyline e poi chiuderla con quello che era il penultimo punto + vVerticesCorr.pop_back() ; + vVerticesCorr[0] = vVerticesCorr.end()[-1] ; + vVertices3d.pop_back() ; + vVertices3d[0] = vVertices3d.end()[-1] ; } + vbKeepPoint[0] = false ; + vbKeepPoint.back() = false ; + cell.m_nVertToErase = 0 ; // ptBL } - if ( AreSamePointApprox(ptP11, ptP01)) { - // sennò devo togliere l'estremo del lato su cui NON ho punti bonus - if ( vbBonusVert[1] && ! vbBonusVert[3]){ // lati contati a partire da quello sopra in senso CCW - if ( ! m_bTrimmed) { - vVerticesCorr.erase(vVerticesCorr.begin() + vnVert[2]) ; // vertici della cella contati a partire da ptBL in senso CCW - vVertices3d.erase(vVertices3d.begin() + vnVert[2]) ; - } - vbKeepPoint[vnVert[2]] = false ; - cell.m_nVertToErase = 2 ; // ptTR - } - else if ( ! vbBonusVert[1] && vbBonusVert[3]) { - if ( ! m_bTrimmed) { - vVerticesCorr.erase(vVerticesCorr.begin() + vnVert[3]) ; - vVertices3d.erase(vVertices3d.begin() + vnVert[3]) ; - } - vbKeepPoint[vnVert[3]] = false ; - cell.m_nVertToErase = 3 ; // ptTl - } - // se non ho bonus su nessuno dei due - else { - // ne scelgo uno dei due da togliere - vbKeepPoint[vnVert[3]] = false ; - cell.m_nVertToErase = 3 ; // ptTl - } + // se non ho bonus su nessuno dei due + else { + // ne scelgo uno dei due da togliere + vbKeepPoint[vnVert[1]] = false ; + cell.m_nVertToErase = 1 ; // ptBr } - if ( AreSamePointApprox(ptP01, ptP00)) { - // sennò devo togliere l'estremo del lato su cui NON ho punti bonus - if ( vbBonusVert[0] && ! vbBonusVert[2]) { // lati contati a partire da quello sopra in senso CCW - if ( ! m_bTrimmed) { - // dovrei eliminare ptBL, quindi devo eliminare il primo e l'ultimo punto della polyline e poi chiuderla con quello che era il penultimo punto - vVerticesCorr.pop_back() ; - vVerticesCorr[0] = vVerticesCorr.end()[-1] ; - vVertices3d.pop_back() ; - vVertices3d[0] = vVertices3d.end()[-1] ; - } - vbKeepPoint[0] = false ; - vbKeepPoint.back() = false ; - cell.m_nVertToErase = 0 ; // ptBL + } + if ( AreSamePointApprox(ptP10, ptP11)) { + // sennò devo togliere l'estremo del lato su cui NON ho punti bonus + if ( vbBonusVert[0] && ! vbBonusVert[2]){ // lati contati a partire da quello sopra in senso CCW + if ( ! m_bTrimmed) { + vVerticesCorr.erase(vVerticesCorr.begin() + vnVert[1]) ; // vertici della cella contati a partire da ptBL in senso CCW + vVertices3d.erase(vVertices3d.begin() + vnVert[1]) ; } - else if ( ! vbBonusVert[0] && vbBonusVert[2]) { - if ( ! m_bTrimmed) { - vVerticesCorr.erase(vVerticesCorr.begin() + vnVert[3]) ; - vVertices3d.erase(vVertices3d.begin() + vnVert[3]) ; - } - vbKeepPoint[vnVert[3]] = false ; - cell.m_nVertToErase = 3 ; // ptTl + vbKeepPoint[vnVert[1]] = false ; + cell.m_nVertToErase = 1 ; // ptBr + } + else if ( ! vbBonusVert[0] && vbBonusVert[2] ){ + if ( ! m_bTrimmed) { + vVerticesCorr.erase(vVerticesCorr.begin() + vnVert[2]) ; + vVertices3d.erase(vVertices3d.begin() + vnVert[2]) ; } - // se non ho bonus su nessuno dei due - else { - // ne scelgo uno dei due da togliere - vbKeepPoint[vnVert[3]] = false ; - cell.m_nVertToErase = 3 ; // ptTl + vbKeepPoint[vnVert[2]] = false ; + cell.m_nVertToErase = 2 ; // ptTR + } + // se non ho bonus su nessuno dei due + else { + // ne scelgo uno dei due da togliere + vbKeepPoint[vnVert[2]] = false ; + cell.m_nVertToErase = 2 ; // ptTR + } + } + if ( AreSamePointApprox(ptP11, ptP01)) { + // sennò devo togliere l'estremo del lato su cui NON ho punti bonus + if ( vbBonusVert[1] && ! vbBonusVert[3]){ // lati contati a partire da quello sopra in senso CCW + if ( ! m_bTrimmed) { + vVerticesCorr.erase(vVerticesCorr.begin() + vnVert[2]) ; // vertici della cella contati a partire da ptBL in senso CCW + vVertices3d.erase(vVertices3d.begin() + vnVert[2]) ; } + vbKeepPoint[vnVert[2]] = false ; + cell.m_nVertToErase = 2 ; // ptTR + } + else if ( ! vbBonusVert[1] && vbBonusVert[3]) { + if ( ! m_bTrimmed) { + vVerticesCorr.erase(vVerticesCorr.begin() + vnVert[3]) ; + vVertices3d.erase(vVertices3d.begin() + vnVert[3]) ; + } + vbKeepPoint[vnVert[3]] = false ; + cell.m_nVertToErase = 3 ; // ptTl + } + // se non ho bonus su nessuno dei due + else { + // ne scelgo uno dei due da togliere + vbKeepPoint[vnVert[3]] = false ; + cell.m_nVertToErase = 3 ; // ptTl + } + } + if ( AreSamePointApprox(ptP01, ptP00)) { + // sennò devo togliere l'estremo del lato su cui NON ho punti bonus + if ( vbBonusVert[0] && ! vbBonusVert[2]) { // lati contati a partire da quello sopra in senso CCW + if ( ! m_bTrimmed) { + // dovrei eliminare ptBL, quindi devo eliminare il primo e l'ultimo punto della polyline e poi chiuderla con quello che era il penultimo punto + vVerticesCorr.pop_back() ; + vVerticesCorr[0] = vVerticesCorr.end()[-1] ; + vVertices3d.pop_back() ; + vVertices3d[0] = vVertices3d.end()[-1] ; + } + vbKeepPoint[0] = false ; + vbKeepPoint.back() = false ; + cell.m_nVertToErase = 0 ; // ptBL + } + else if ( ! vbBonusVert[0] && vbBonusVert[2]) { + if ( ! m_bTrimmed) { + vVerticesCorr.erase(vVerticesCorr.begin() + vnVert[3]) ; + vVertices3d.erase(vVertices3d.begin() + vnVert[3]) ; + } + vbKeepPoint[vnVert[3]] = false ; + cell.m_nVertToErase = 3 ; // ptTl + } + // se non ho bonus su nessuno dei due + else { + // ne scelgo uno dei due da togliere + vbKeepPoint[vnVert[3]] = false ; + cell.m_nVertToErase = 3 ; // ptTl } } 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 && ( ! bForTriangulation || (bForTriangulation && vVerticesCorr.size() == 5))) { + if ( vVertices.size() == 5) { Point3d ptPSrf ; double dU, dV ; dU = ( cell.GetBottomLeft().x + cell.GetTopRight().x) / 2 / SBZ_TREG_COEFF ; @@ -2075,38 +1934,39 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon } } - cell.AddPoly( m_vPolygons.size()) ; - m_vPolygons.emplace_back() ; - m_vPolygons.back().emplace_back() ; - m_vPolygonsCorr.emplace_back() ; - m_vPolygonsCorr.back().emplace_back() ; - m_vPolygons3d.emplace_back() ; - m_vPolygons3d.back().emplace_back() ; + cell.AddPoly( c) ; + // aggiorno il contatore dei poligoni + c += 1 ; + vPolygonsBasic.emplace_back() ; + //m_vPolygons.back().emplace_back() ; + vPolygonsCorrected.emplace_back() ; + //m_vPolygonsCorr.back().emplace_back() ; + vPolygons3d.emplace_back() ; + //m_vPolygons3d.back().emplace_back() ; int nVertCorr = int(vVerticesCorr.size()); for ( int i = 0 ; i < (int) vVertices.size() ; ++i) { int dPar = i ; if( ! vbKeepPoint[i]) dPar = -1 ; - m_vPolygons.back().back().AddUPoint( dPar, vVertices.at( i)) ; - if( bForTriangulation && i < nVertCorr){ - m_vPolygonsCorr.back().back().AddUPoint( dPar, vVerticesCorr.at( i)) ; - m_vPolygons3d.back().back().AddUPoint( dPar, vVertices3d.at( i)) ; + vPolygonsBasic.back().AddUPoint( dPar, vVertices.at( i)) ; + if( i < nVertCorr){ + vPolygonsCorrected.back().AddUPoint( dPar, vVerticesCorr.at( i)) ; + vPolygons3d.back().AddUPoint( dPar, vVertices3d.at( i)) ; } } - } - } + //} - // restituisco i poligoni delle celle del tree nello spazio parametrico - for ( int t = 0 ; t < (int)m_vPolygons.size() ; ++ t) { - for ( int z = 0 ; z < (int)m_vPolygons[t].size() ; ++z) { - vPolygonsBasic.push_back( m_vPolygons[t][z]) ; - if( bForTriangulation) { - vPolygonsCorrected.push_back( m_vPolygonsCorr[t][z]) ; - vPolygons3d.push_back( m_vPolygons3d[t][z]) ; - } - } - } + //// restituisco i poligoni delle celle del tree nello spazio parametrico + //for ( int t = 0 ; t < (int)m_vPolygons.size() ; ++ t) { + // for ( int z = 0 ; z < (int)m_vPolygons[t].size() ; ++z) { + // vPolygonsBasic.push_back( std::move(m_vPolygons[t][z])) ; + // if( bForTriangulation) { + // vPolygonsCorrected.push_back( std::move(m_vPolygonsCorr[t][z])) ; + // vPolygons3d.push_back( std::move(m_vPolygons3d[t][z])) ; + // } + // } + //} return true ; } @@ -3116,9 +2976,6 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX // comincio a costruire il poligono INTVECTOR vToCheckNow = vToCheck ; - // vettore dei poligoni ( loop) della cella nId - POLYLINEVECTOR vCellPolygons ; - POLYLINEVECTOR vCellPolygons3d ; // costruisco i poligoni partendo dal vettore delle intersezioni, come spiegato a pag15 di Cripps PolyLine plTrimmedPoly ; PolyLine plTrimmedPoly3d ; @@ -3146,7 +3003,7 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX nEdgeIn = inA.nIn ; nFirstLoopInPoly = j ; } - for ( Point3d ptInt : inA.vpt) { + for ( Point3d& ptInt : inA.vpt) { AddVertex( nId, vEdgeVertex, vEdgeVertex3d, plTrimmedPoly, c, ptInt, plTrimmedPoly3d, bForTriangulation, ptLastAdded) ; } vAddedLoops.push_back( j) ; @@ -3341,13 +3198,11 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX plTrimmedPoly.GetAreaXY( dArea) ; //if ( dArea > SQ_EPS_SMALL) { if ( dArea > 0) { - vCellPolygons.push_back( plTrimmedPoly) ; - vPolygons.push_back( vCellPolygons) ; - vCellPolygons.clear() ; + vPolygons.emplace_back() ; + vPolygons.back().push_back(std::move(plTrimmedPoly)) ; if( bForTriangulation) { - vCellPolygons3d.push_back( plTrimmedPoly3d) ; - vPolygons3d.push_back( vCellPolygons3d) ; - vCellPolygons3d.clear() ; + vPolygons3d.emplace_back() ; + vPolygons3d.back().push_back(std::move(plTrimmedPoly3d)) ; } ++ nPoly ; vnParentChunk.push_back( inA.nChunk) ; @@ -3374,12 +3229,9 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX //---------------------------------------------------------------------------- bool -Tree::CreateIslandAndHoles( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX& vPolygons3d, int& nPoly, INTVECTOR& vnParentChunk, bool bForTriangulation, +Tree::CreateIslandAndHoles( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX& vPolygons3d, int& nPoly, INTVECTOR& vnParentChunk, const PolyLine& plPolygonsBasic, const PolyLine& plPolygonsBasic3d) { - // vettore dei poligoni ( loop) della cella nId - POLYLINEVECTOR vCellPolygons ; - POLYLINEVECTOR vCellPolygons3d ; // costruisco i poligoni partendo dal vettore delle intersezioni int nId = m_vnLeaves[nLeafId] ; Cell& cCell = m_mTree[nId] ; @@ -3433,28 +3285,24 @@ Tree::CreateIslandAndHoles( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATR ptVert = cCell.GetBottomRight() ; plInLoop.AddUPoint( 3, ptVert) ; plInLoop.Close() ; - vCellPolygons.push_back( plInLoop) ; - vPolygons.push_back( vCellPolygons) ; + vPolygons.emplace_back() ; + vPolygons.back().push_back( std::move(plInLoop)) ; ++ nPoly ; - if ( bForTriangulation) { - Point3d ptP00, ptP10, ptP11, ptP01 ; - GetPoint( cCell.GetBottomLeft().x, cCell.GetBottomLeft().y, ptP00) ; - GetPoint( cCell.GetTopRight().x, cCell.GetBottomLeft().y, ptP10) ; - GetPoint( cCell.GetTopRight().x, cCell.GetTopRight().y, ptP11) ; - GetPoint( cCell.GetBottomLeft().x, cCell.GetTopRight().y, ptP01) ; - plInLoop3d.AddUPoint( 0, ptP11) ; - plInLoop3d.AddUPoint( 1, ptP01) ; - plInLoop3d.AddUPoint( 2, ptP00) ; - plInLoop3d.AddUPoint( 3, ptP10) ; - plInLoop3d.Close() ; - vCellPolygons3d.push_back( plInLoop3d) ; - vPolygons3d.push_back( vCellPolygons3d) ; - vCellPolygons3d.clear() ; - plInLoop3d.Clear() ; - } + Point3d ptP00, ptP10, ptP11, ptP01 ; + GetPoint( cCell.GetBottomLeft().x, cCell.GetBottomLeft().y, ptP00) ; + GetPoint( cCell.GetTopRight().x, cCell.GetBottomLeft().y, ptP10) ; + GetPoint( cCell.GetTopRight().x, cCell.GetTopRight().y, ptP11) ; + GetPoint( cCell.GetBottomLeft().x, cCell.GetTopRight().y, ptP01) ; + plInLoop3d.AddUPoint( 0, ptP11) ; + plInLoop3d.AddUPoint( 1, ptP01) ; + plInLoop3d.AddUPoint( 2, ptP00) ; + plInLoop3d.AddUPoint( 3, ptP10) ; + plInLoop3d.Close() ; + vPolygons3d.emplace_back() ; + vPolygons3d.back().push_back( std::move(plInLoop3d)) ; + plInLoop3d.Clear() ; // imposto il chunk del loop CW più grande ( il primo che ho incontrato) vnParentChunk.push_back( nChunkBiggestCW) ; - vCellPolygons.clear() ; plInLoop.Clear() ; } for ( int nLoop = 0 ; nLoop < nInters ; ++ nLoop) { @@ -3462,17 +3310,14 @@ Tree::CreateIslandAndHoles( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATR if ( inA.nIn == -1) { // numero di vertici aggiunti al nuovo poligono int k = 0 ; - for ( Point3d ptInt : inA.vpt) { + for ( Point3d& ptInt : inA.vpt) { plInLoop.AddUPoint( k, ptInt) ; - if ( bForTriangulation) { - Point3d pt3d ; GetPoint( ptInt.x, ptInt.y, pt3d) ; - plInLoop3d.AddUPoint( k, pt3d) ; - } + Point3d pt3d ; GetPoint( ptInt.x, ptInt.y, pt3d) ; + plInLoop3d.AddUPoint( k, pt3d) ; ++ k ; } plInLoop.Close() ; - if ( bForTriangulation) - plInLoop3d.Close() ; + plInLoop3d.Close() ; bool bAdded = false ; // se il loop è CW devo controllare in quale altro dei poligoni che ho già aggiunto è contenuto if ( ! inA.bCCW) { @@ -3483,32 +3328,25 @@ Tree::CreateIslandAndHoles( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATR if ( IsPointInsidePolyLine( ptStart, vPolygons[nOtherPoly - r - 1][0], -0.01) && vnParentChunk[nPoly - r - 1] == inA.nChunk) { vPolygons[nOtherPoly - r - 1].push_back( plInLoop) ; plInLoop.Clear() ; - if ( bForTriangulation) { - vPolygons3d[nOtherPoly - r - 1].push_back( plInLoop3d) ; - plInLoop3d.Clear() ; - } + vPolygons3d[nOtherPoly - r - 1].push_back( std::move(plInLoop3d)) ; + plInLoop3d.Clear() ; bAdded = true ; break ; } } } if ( ! bAdded) { - vCellPolygons.push_back( plInLoop) ; - vPolygons.push_back( vCellPolygons) ; + vPolygons.emplace_back() ; + vPolygons.back().push_back( std::move(plInLoop)) ; plInLoop.Clear() ; - vCellPolygons.clear() ; - if ( bForTriangulation) { - vCellPolygons3d.push_back( plInLoop3d) ; - vPolygons3d.push_back( vCellPolygons3d) ; - plInLoop3d.Clear() ; - vCellPolygons3d.clear() ; - } + vPolygons3d.emplace_back( ) ; + vPolygons3d.back().push_back( std::move(plInLoop3d)) ; + plInLoop3d.Clear() ; ++ nPoly ; vnParentChunk.push_back( inA.nChunk) ; } plInLoop.Clear() ; - if ( bForTriangulation) - plInLoop3d.Clear() ; + plInLoop3d.Clear() ; } else continue ; @@ -4098,7 +3936,7 @@ Tree::CategorizeCell( int nId) else { Point3d ptInters = m_mTree[vNeigh[0]].GetTopRight() ; int nEdge = 3 ; - bool bIntersIn ; + bool bIntersIn = false ; for ( int k = 0 ; k < (int) m_mTree[vNeigh[0]].m_vInters.size() ; ++ k) { if ( AreSameEdge( m_mTree[vNeigh[0]].m_vInters[k].nIn, 3)) { if ( CheckIfBefore( nEdge, m_mTree[vNeigh[0]].m_vInters[k].vpt[0], ptInters, 3)) { @@ -4296,7 +4134,7 @@ Tree::OnWhichEdge( int nId, const Point3d& ptToAssign, int& nEdge) const //---------------------------------------------------------------------------- bool -Tree::GetEdges3D( vector& mCCEdges) +Tree::GetEdges3D( vector& mCCEdges, POLYLINEVECTOR& vPolygons) { // se la superficie non è trimmata ricostruisco dalle celle al bordo if ( ! m_bTrimmed) { @@ -4314,17 +4152,6 @@ Tree::GetEdges3D( vector& mCCEdges) GetRootNeigh( 2, vEdges[2]) ; vEdges.emplace_back() ; GetRootNeigh( 3, vEdges[3]) ; - - // recupero i poligoni base delle celle sui bordi - //POLYLINEMATRIX mPL ; - //mPL.emplace_back() ; - //GetPolygonsBasic( mPL[0], vEdges[0]) ; - //mPL.emplace_back() ; - //GetPolygonsBasic( mPL[1], vEdges[1]) ; - //mPL.emplace_back() ; - //GetPolygonsBasic( mPL[2], vEdges[2]) ; - //mPL.emplace_back() ; - //GetPolygonsBasic( mPL[3], vEdges[3]) ; // scorro sui gruppi di polyline che rappresentano i poligoni delle celle lungo un lato for ( int i = 0 ; i < int( vEdges.size()) ; ++i) { @@ -4333,7 +4160,7 @@ Tree::GetEdges3D( vector& mCCEdges) // scorro sui poligoni delle celle di un lato for ( int c = 0 ; c < int( vEdges[i].size()) ; ++c) { Cell& cNeigh = m_mTree.at(vEdges[i][c]) ; - PolyLine& plCell = m_vPolygons[cNeigh.m_vnPolyId[0]][0] ; + PolyLine& plCell = vPolygons[cNeigh.m_vnPolyId[0]] ; Point3d pt ; plCell.GetFirstPoint( pt) ; Point3d pt3d ; // a seconda del lato controllo di stare scorrendo il poligono prendendo solo i punti su quel lato @@ -4585,217 +4412,5 @@ Tree::CreateCellContour( POLYLINEMATRIX& vPolygons) if ( nPolyBefore == nPoly) break ; } - return true ; -} - -//---------------------------------------------------------------------------- -bool -Tree::CloseOpenCuts( POLYLINEVECTOR& vPL, PolyLine& plNew) const // da verificare e comunque funzione probabilmente inutile -{ - if ( vPL.size() == 1 && vPL[0].IsClosed()) { - plNew = vPL[0] ; - return true ; - } - - vector vInters ; - for ( int i = 0 ; i < int( vPL.size()) ; ++i) { - vInters.emplace_back() ; - Point3d ptStart ; vPL[i].GetFirstPoint( ptStart) ; - OnWhichEdge( -1, ptStart, vInters.back().nIn) ; - Point3d ptEnd ; vPL[i].GetLastPoint( ptEnd) ; - OnWhichEdge( -1, ptEnd, vInters.back().nOut) ; - PNTULIST lPnt = vPL[i].GetUPointList() ; - for ( auto it = lPnt.begin() ; it != lPnt.end() ; ++it) - vInters.back().vpt.push_back( (*it).first) ; - } - - std::sort( vInters.begin(), vInters.end(), [](Inters &left, Inters &right) { return left < right;}) ; - bool bNotCameBack = true ; - int nEdge = vInters[0].nOut ; - PNTULIST lPnt = vPL[0].GetUPointList() ; - for ( auto it = lPnt.begin() ; it != lPnt.end() ; ++it) - plNew.AddUPoint( (*it).second, (*it).first) ; - // se ero in un vertice passo all'edge successivo - if ( nEdge > 3 && nEdge != 7) - nEdge = nEdge - 4 ; - else if ( nEdge == 7) - nEdge = 0 ; - int nInters = 0 ; - while ( bNotCameBack) { - bool bAtNextStart = false ; - //PolyLine plEdge ; - double dCount ; plNew.GetLastU( dCount) ; - plNew.AddUPoint( dCount, vInters[nInters].vpt.back()) ; - ++ dCount ; - ++ nInters ; - if ( nInters == vInters.size()) - nInters = 0 ; - // scorro tutti i lati finché non torno allo start del loop - while( ! bAtNextStart) { - Point3d ptToAdd ; - if ( nEdge == 0) - ptToAdd = m_mTree.at(-1).GetTopLeft() ; - else if ( nEdge == 1) - ptToAdd = m_mTree.at(-1).GetBottomLeft() ; - else if ( nEdge == 2) - ptToAdd = m_mTree.at(-1).GetBottomRight() ; - else if ( nEdge == 3) - ptToAdd = m_mTree.at(-1).GetTopRight() ; - if ( plNew.AddUPoint( dCount, ptToAdd)) - ++ dCount ; - if ( nEdge > 3 && nEdge != 7) - nEdge = nEdge - 4 ; - else if ( nEdge < 3) - ++ nEdge ; - else - nEdge = 0 ; - if ( AreSameEdge(nEdge,vInters[nInters].nIn)) - bAtNextStart = true ; - } - if ( nInters != 0 && nInters < int(vPL.size())) { - // aggiungo la polyline successiva - PNTULIST lPnt = vPL[nInters].GetUPointList() ; - double dLastU ; vPL[nInters-1].GetLastU( dLastU) ; - ++ dLastU ; - for ( auto it = lPnt.begin() ; it != lPnt.end() ; ++it) - plNew.AddUPoint( dLastU + (*it).second, (*it).first) ; - } - if ( AreSameEdge(nEdge, vInters[0].nIn)) { - plNew.Close() ; - bNotCameBack = false ; - } - } - return true ; -} - -//---------------------------------------------------------------------------- -bool -Tree::CloseOpenCuts( void) -{ - int nRoot = -1 ; - // tra i loop del parametrico seleziono quelli aperti - // creo il vettore inters, lo riordino e poi rendo chiusi i loop ( che possono restare indipendenti o unirsi ad altri loop aperti) - INTVECTOR vOpen ; - for ( int i = 0 ; i < int(m_vPlApprox.size()) ; ++i ) { - if ( ! get<0>(m_vPlApprox[i]).IsClosed()) { - m_mTree.at( nRoot).m_vInters.emplace_back() ; - Point3d ptStart ; get<0>(m_vPlApprox[i]).GetFirstPoint( ptStart) ; - OnWhichEdge( nRoot, ptStart, m_mTree.at( nRoot).m_vInters.back().nIn) ; - Point3d ptEnd ; get<0>(m_vPlApprox[i]).GetLastPoint( ptEnd) ; - OnWhichEdge( nRoot, ptEnd, m_mTree.at( nRoot).m_vInters.back().nOut) ; - vOpen.push_back( i) ; - } - } - // riordino le intersezioni - std::sort( m_mTree.at(nRoot).m_vInters.begin(), m_mTree.at(nRoot).m_vInters.end()) ; - - m_vnLeaves.push_back( -1) ; - // chiamo la GetPolygons - POLYLINEMATRIX mPL ; - GetPolygons( mPL) ; - - //creo il nuovo vettore di polyline di trim - // tengo quelli che erano i trim chiusi - for ( int t = int(vOpen.size()) - 1 ; t > -1 ; ++t ) { - m_vPlApprox.erase( m_vPlApprox.begin() + vOpen[t]) ; - } - - // aggiungo i nuovi trim creati - for ( int t = 0 ; t < int( mPL[0].size()) ; ++t) { - m_vPlApprox.push_back( pair(mPL[0][t], true)) ; - } - - m_vnLeaves.clear() ; - m_mTree.at( nRoot).m_vInters.clear() ; - - //// tra i loop del parametrico seleziono quelli aperti - //// creo il vettore inters, lo riordino e poi rendo chiusi i loop ( che possono restare indipendenti o unirsi ad altri loop aperti) - //vector> vInters ; - //INTVECTOR vClosed ; - //for ( int i = 0 ; i < int(m_vPlApprox.size()) ; ++i ) { - // if ( ! get<0>(m_vPlApprox[i]).IsClosed()) { - // vInters.emplace_back() ; - // vInters.back().first = i ; - // Point3d ptStart ; get<0>(m_vPlApprox[i]).GetFirstPoint( ptStart) ; - // OnWhichEdge( -1, ptStart, vInters.back().second.nIn) ; - // Point3d ptEnd ; get<0>(m_vPlApprox[i]).GetLastPoint( ptEnd) ; - // OnWhichEdge( -1, ptEnd, vInters.back().second.nOut) ; - // } - // else - // vClosed.push_back( i) ; - //} - - //// A MANO - //// chiudo le curve aperte e se necessario le giunto tra loro - //if ( ! vInters.empty()) { - // ICurveComposite* pCCOpen ( CreateBasicCurveComposite()) ; - // pCCOpen->FromPolyLine( get<0>(m_vPlApprox[vInters[0].first])) ; - // //sort( vInters.begin(), vInters.end()) ; - // sort( vInters.begin(), vInters.end(), [](pair &left, pair &right) { return left.second < right.second;}) ; - // bool bNotCameBack = true ; - // int nEdge = vInters[0].second.nOut ; - - // // se ero in un vertice passo all'edge successivo - // if ( nEdge > 3 && nEdge != 7) - // nEdge = nEdge - 4 ; - // else if ( nEdge == 7) - // nEdge = 0 ; - // int nInters = 0 ; - // while ( bNotCameBack) { - // bool bAtNextStart = false ; - // PolyLine plEdge ; - // int nCount = 0 ; - // plEdge.AddUPoint( nCount, vInters[nInters].ptEnd) ; - // ++ nCount ; - // ++ nInters ; - // if ( nInters == vInters.size()) - // nInters = 0 ; - // // scorro tutti i lati finché non torno allo start del loop - // while( ! bAtNextStart) { - // Point3d ptToAdd ; - // if ( nEdge == 0) - // ptToAdd = m_mTree.at(-1).GetTopLeft() ; - // else if ( nEdge == 1) - // ptToAdd = m_mTree.at(-1).GetBottomLeft() ; - // else if ( nEdge == 2) - // ptToAdd = m_mTree.at(-1).GetBottomRight() ; - // else if ( nEdge == 3) - // ptToAdd = m_mTree.at(-1).GetTopRight() ; - // if ( plEdge.AddUPoint( nCount, ptToAdd)) - // ++ nCount ; - // if ( nEdge > 3 && nEdge != 7) - // nEdge = nEdge - 4 ; - // else if ( nEdge < 3) - // ++ nEdge ; - // else - // nEdge = 0 ; - // if ( AreSameEdge(nEdge,vInters[nInters].second.nIn)) - // bAtNextStart = true ; - // } - // ICurveComposite* pCC( CreateCurveComposite()) ; - // pCC->FromPolyLine( plEdge) ; - // // aggiungo il tratto di edge - // pCCOpen->AddCurve( pCC) ; - // // agggiungo il prossio taglio - // if ( nInters != 0) - // pCCOpen->AddCurve( Release( vInters[nInters].pCrv)) ; - // if ( AreSameEdge(nEdge, vInters[0].second.nIn)) { - // pCCOpen->Close() ; - // bNotCameBack = false ; - // } - // } - // if ( ! pCCOpen->IsClosed()) { - // LOG_ERROR( pGenLog, "Error creating the contour from open trims") ; - // return nullptr ; - // } - // if ( ! bPlanarSurf) { - // if ( ! SimplifyCurve( pCCOpen)) { - // LOG_ERROR( pGenLog, "Error simplifying the contour recreated from the open trims") ; - // return nullptr ; - // } - // } - // SfrCntr.AddCurve( pCCOpen) ; - //} - return true ; } \ No newline at end of file diff --git a/Tree.h b/Tree.h index 2b501be..bdeba1e 100644 --- a/Tree.h +++ b/Tree.h @@ -252,17 +252,14 @@ class Tree 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& vvPolygons) ; - bool GetPolygons( POLYLINEMATRIX& vvPolygons, POLYLINEMATRIX& vvPolygons3d) ; - bool GetPolygons( POLYLINEMATRIX& vPolygons, bool bForTriangulation, POLYLINEMATRIX& vvPolygons3d) ; - bool GetPolygonsBasic( POLYLINEVECTOR& vPolygons, POLYLINEVECTOR& vPolygonsCorrected, // restituisce il poligono corrispondente ad ogni cella foglia dell'albero - bool bForTriangulation, POLYLINEVECTOR& vPolygons3d, INTVECTOR vCells = {}) ; // ad ogni poligono sono stati aggiunti tutti i vertici dei vicini posizionati sui suoi lati - // se richiesti per la triangolazione ad alcuni poligoni potrebbero venire tolti dei punti per evitare errori dovuti ad eventuali poli sui bordi del parametrico + bool GetPolygons( POLYLINEMATRIX& vvPolygons, POLYLINEMATRIX& vvPolygons3d, vector& vCCEdges3D, ICRVCOMPOPOVECTOR& vCCLoops) ; + //bool GetPolygonsBasic( POLYLINEVECTOR& vPolygons, POLYLINEVECTOR& vPolygonsCorrected, // restituisce il poligono corrispondente ad ogni cella foglia dell'albero + // bool bForTriangulation, POLYLINEVECTOR& vPolygons3d, INTVECTOR vCells = {}) ; // ad ogni poligono sono stati aggiunti tutti i vertici dei vicini posizionati sui suoi lati + // // se richiesti per la triangolazione ad alcuni poligoni potrebbero venire tolti dei punti per evitare errori dovuti ad eventuali poli sui bordi del parametrico bool GetPolygonsBasic( POLYLINEVECTOR& vPolygons, POLYLINEVECTOR& vPolygonsCorrected, POLYLINEVECTOR& vPolygons3d) ; - bool GetPolygonsBasic( POLYLINEVECTOR& vPolygons, INTVECTOR vCells = {}) ; bool GetLeaves ( std::vector& vLeaves) const ; // restituisce gli indici delle foglie nell'albero - bool GetEdges3D ( vector& mCCEdge) ; // restituisce gli edge 3D come polyline - bool GetSplitLoops( ICRVCOMPOPOVECTOR& vCCLoopSplit) const // funzione che restituisce i loop splitatti ai confini delle celle + bool GetEdges3D ( vector& mCCEdge, POLYLINEVECTOR& vPolygons) ; // restituisce gli edge 3D come polyline + bool GetSplitLoops( ICRVCOMPOPOVECTOR& vCCLoopSplit) const // funzione che restituisce i loop splitatti ai confini delle celle { for ( int i = 0 ; i < int( m_vCCLoop2D.size()); ++i) vCCLoopSplit.emplace_back( m_vCCLoop2D[i]->Clone()) ; return true ; }; void SetTestMode( void) { m_bTestMode = true ;} ; // attivando la test mode, per la costruzione dell'albero viene usata la funzione BuiltTree_test e viene corretta di conseguenza la FindCell // funzioni da usare per ricostruire tagli che vanno aggiunti allo spazio parametrico @@ -273,7 +270,6 @@ class Tree std::vector GetPoles( void) { return m_vbPole ;} ; // funzione che restituisce i flag che indicano se i lati sono collassati in dei poli 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 @@ -291,7 +287,7 @@ class Tree bool FindInters( int& nId, const CurveLine& clTrim, const PolyLine& plPolygon, 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 bool CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX& vPolygons3d, INTVECTOR& vToCheck, int& nPoly, INTVECTOR& vnParentChunk, const PolyLine& plCell, const PolyLine& plCell3d) ; // crea i poligoni della cella passata. richiede anche la funzione CreateIslandAndHoles per completare i poligoni. - bool CreateIslandAndHoles( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX& vvPolygons3d, int& nPoly, INTVECTOR& vnParentChunk, bool bForTriangulation, + bool CreateIslandAndHoles( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX& vvPolygons3d, int& nPoly, INTVECTOR& vnParentChunk, const PolyLine& plPolygonsBasic, const PolyLine& plPolygonsBasic3d) ; // ai poligoni generati da CreatePolygonsCell aggiunge i loop che creano isole o buchi all'interno della singola cella bool CheckIfBefore( const PolyLine& pl, int nEdge) const ; // controllo se ptEnd è prima di ptStart sul lato nEdge rispetto al senso antiorario bool CheckIfBefore( const Inters& inA) const ; // controlla se l'ingresso è prima dell'uscita in senso antiorario a partire da ptTR. @@ -307,8 +303,6 @@ class Tree bool OnWhichEdge( int nId, const Point3d& ptToAssign, int& nEdge) const ; // indica a quale edge o vertice il punto è vicino entro EPS_SMALL bool AdjustCuts( void) ; bool UpdateSplitLoop( ICurveComposite* pCC, Point3d& pt) ; - bool CloseOpenCuts( void) ; - bool CloseOpenCuts( POLYLINEVECTOR& vPL, PolyLine& pl) const ; bool VerifyLoopOrientation( ICURVEPLIST& vpCrv, BOOLVECTOR& vbOrientation) const ; // verifico l'orientazione ( CCW o CW) delle polyline in base a come sono contenute le une nelle altre bool AdjustLoop( PolyLine& pl, POLYLINEVECTOR& vPl, BOOLVECTOR& vbOrientation) const ; bool GetPoint(double dU, double dV, Point3d& pt) const ; @@ -333,9 +327,9 @@ class Tree int m_nDegV ; // grado della superficie nel parametro V 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 - POLYLINEMATRIX m_vPolygonsCorr ; // matrice dei poligoni del tree, corretti per i punti che sono nei poli - POLYLINEMATRIX m_vPolygons3d ; // matrice dei poligoni3d del tree + //POLYLINEMATRIX m_vPolygons ; // matrice dei poligoni del tree + //POLYLINEMATRIX m_vPolygonsCorr ; // matrice dei poligoni del tree, corretti per i punti che sono nei poli + //POLYLINEMATRIX m_vPolygons3d ; // matrice dei poligoni3d del tree unordered_map m_mTree ; // mappa che contiene tutti i nodi e le foglie dell'albero. -2 è puntatore Null e -1 è root mutable unordered_map,Point3d, PairHashInt64> m_mPt3d ; // mappa che contiene tutti i punti 3d della superficie calcolati (la chiave sono le coordinate, moltiplicate per 2^24 e trasformate in int) INTVECTOR m_vnLeaves ; // vettore delle foglie