diff --git a/SurfBezier.cpp b/SurfBezier.cpp index b1316f7..b9c07e0 100644 --- a/SurfBezier.cpp +++ b/SurfBezier.cpp @@ -1577,7 +1577,7 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin) const // prendo i punti di ogni polyline dell'albero, li triangolo e li porto in 3d int c = 0 ; - for ( POLYLINEVECTOR vPL : vvPL) { + for ( POLYLINEVECTOR& vPL : vvPL) { PNTVECTOR vPnt ; INTVECTOR vTria ; Triangulate Tri ; @@ -1590,7 +1590,7 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin) const PNTVECTOR vPnt3d ; for( int i = 0 ; i < int( vPL3d.size()) ; ++i) { - PolyLine pl3d = vPL3d[i] ; + PolyLine& pl3d = vPL3d[i] ; Point3d pt3d ; pl3d.GetFirstPoint( pt3d) ; //vPnt3d.push_back( pt3d) ; while ( pl3d.GetNextPoint( pt3d)) { @@ -1600,29 +1600,52 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin) const // se ho ottenuto meno triangoli di quelli che avrei dovuto avere allora potrei aver avuto un problema in prossimità di un polo // se comunque ho corrispondenza tra vPnt e vPnt3d allora eseguo la trinagolazione in 3d - if ( ( vPnt.size() - 2 ) != ( vTria.size() ) / 3 && vPnt.size() == vPnt3d.size() ) { + bool bTriangulationFailedIn2D = ( vPnt.size() - 2) != ( vTria.size()) / 3 ; + bool bMismatch2D3D = vPnt.size() != vPnt3d.size() ; + bool bTriangulatedIn3D = false ; + if ( bTriangulationFailedIn2D || bMismatch2D3D) { + PNTVECTOR vPntBackup ; + if( ! bTriangulationFailedIn2D && bMismatch2D3D) + vPntBackup = vPnt ; if ( ! Tri.Make( vPL3d, vPnt, vTria)) return nullptr ; - if ( ( vPnt.size() - 2 ) == ( vTria.size() ) / 3 ) - LOG_INFO( GetEGkLogger(), "Info : Last problem in MakeByEC23(1) RESOLVED") - else - LOG_INFO( GetEGkLogger(), "Info : Last problem in MakeByEC23(1) is the same as the previous one") + bool bTriangulationSucceded = ( vPnt.size() - 2 ) == ( vTria.size() ) / 3 ; + if( bTriangulationFailedIn2D) { + if ( bTriangulationSucceded) + LOG_INFO( GetEGkLogger(), "Info : Last problem in MakeByEC23(1) RESOLVED") + else + LOG_INFO( GetEGkLogger(), "Info : Last problem in MakeByEC23(1) is the same as the previous one") + } + if( bMismatch2D3D && ! bTriangulationSucceded) + vPnt = vPntBackup ; + else if( bTriangulationSucceded) + bTriangulatedIn3D = true ; } // controllo per ogni polyline se è stato invertito il vettore dei punti int nCurrPoint = 0 ; for( int i = 0 ; i < int( vPL.size()) ; ++i) { - Point3d pt3d ; vPL[i].GetFirstPoint( pt3d) ; - vPL[i].GetNextPoint( pt3d) ; - int nPoints = vPL[i].GetPointNbr() - 2 ; - if ( ! AreSamePointApprox( vPnt[nCurrPoint], pt3d)) - reverse( vPnt3d.begin() + nCurrPoint, vPnt3d.begin() + nCurrPoint + nPoints) ; - nCurrPoint += nPoints ; + if( ! bTriangulatedIn3D) { + Point3d pt ; vPL[i].GetFirstPoint( pt) ; + vPL[i].GetNextPoint( pt) ; + int nPoints = vPL[i].GetPointNbr() - 2 ; + if ( ! AreSamePointApprox( vPnt[nCurrPoint], pt)) + reverse( vPnt3d.begin() + nCurrPoint, vPnt3d.begin() + nCurrPoint + nPoints) ; + nCurrPoint += nPoints ; + } + else { + Point3d pt ; vPL3d[i].GetFirstPoint( pt) ; + vPL3d[i].GetNextPoint( pt) ; + int nPoints = vPL3d[i].GetPointNbr() - 2 ; + if ( ! AreSamePointApprox( vPnt[nCurrPoint], pt)) + reverse( vPnt3d.begin() + nCurrPoint, vPnt3d.begin() + nCurrPoint + nPoints) ; + nCurrPoint += nPoints ; + } } //controllo che i due vettori vPnt e vPnt3d abbiano la stessa lunghezza, sennò vuol dire che nel vettore vPnt3d ho avuto dei Rejected e devo ricalcolarli // i punti in eccesso verranno poi scartati dalla trimesh - if( vPnt.size() != vPnt3d.size()) { + if( vPnt.size() != vPnt3d.size() && ! bTriangulatedIn3D) { vPnt3d.clear() ; for ( int i = 0 ; i < int( vPnt.size()) ; ++ i) { Point3d pt3d ; diff --git a/Tree.cpp b/Tree.cpp index de68f01..9a4b186 100644 --- a/Tree.cpp +++ b/Tree.cpp @@ -224,18 +224,15 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi PtrOwner pChunk( pTrimReg->CloneChunk( i)) ; for ( int j = 0 ; j < pChunk->GetLoopCount( 0) ; ++ j) { // i chunk della falt region sono ancora flat region composte da 1 chunk - PtrOwner pLoop ( pChunk->GetLoop( 0, j)) ; // rimuovo i difetti dei loop prima di salvarli - PtrOwner pCrvCompo( GetBasicCurveComposite(pLoop->Clone())) ; - pCrvCompo->MergeCurves( dLinTol, dAngTolDeg) ; - pCrvCompo->RemoveSmallDefects( dLinTol, dAngTolDeg, true) ; - pCrvCompo->RemoveSmallParts( dLinTol, dAngTolDeg) ; - PtrOwner pCrv( pCrvCompo->Clone()) ; - + PtrOwner pLoop( GetBasicCurveComposite( pChunk->GetLoop( 0, j))) ; + pLoop->MergeCurves( dLinTol, dAngTolDeg) ; + pLoop->RemoveSmallDefects( dLinTol, dAngTolDeg, true) ; + pLoop->RemoveSmallParts( dLinTol, dAngTolDeg) ; // approssimo i loop di trim con delle spezzate PolyLine plApprox ; int nType = 0 ; - pCrv->ApproxWithLines( dLinTol,dAngTolDeg, nType, plApprox) ; + pLoop->ApproxWithLines( dLinTol,dAngTolDeg, nType, plApprox) ; // calcolo se il loop è CCW o CW double dArea ; Plane3d plExtPlane ; @@ -444,7 +441,7 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi } //---------------------------------------------------------------------------- -bool +static bool AddOrMergeBBox( const BBox3d& bBox3dA, vector& vBBox, bool bAdd = true, int nInd = 0) { Point3d ptMin = bBox3dA.GetMin() ; @@ -487,7 +484,7 @@ Tree::GetIndependentTrees( BIPNTVECTOR& vTrees) // se ho dei loop di trim trovo le loro BBox3d per costruire l'albero solo all'interno di queste BBox BOXVECTOR vBBox ; for ( int i = 0 ; i < int( m_vPlApprox.size()) ; ++ i) { - PolyLine plLoop = get<0>( m_vPlApprox[i]) ; + PolyLine& plLoop = get<0>( m_vPlApprox[i]) ; // calcolo la BBox3d Point3d ptP ; plLoop.GetFirstPoint( ptP) ; @@ -502,7 +499,7 @@ Tree::GetIndependentTrees( BIPNTVECTOR& vTrees) bool bIsRoot = false ; Point3d ptTR( m_nSpanU * SBZ_TREG_COEFF, m_nSpanV * SBZ_TREG_COEFF) ; for ( int i = 0 ; i < int( vBBox.size()) ; ++ i) { - BBox3d bBox3d = vBBox[i] ; + BBox3d& bBox3d = vBBox[i] ; if ( AreSamePointEpsilon( bBox3d.GetMin(), ORIG, 10) && AreSamePointEpsilon( bBox3d.GetMax(), ptTR, 10)) { bIsRoot = true ; break ; @@ -1750,7 +1747,7 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon if ( (int) vNeigh.size() != 0 && (int) vNeigh.size() != 1){ // se la superficie è chiusa lungo il parametro U e le celle vicine right sono sul lato Left // devo aggiungere i vertici tenendo conto della periodicità dello spazio parametrico. - vnVert.push_back( int(vVertices.size() - 1)) ; + vnVert.push_back( int(vVertices.size())) ; if ( m_bClosedU && m_mTree.at( vNeigh[0]).m_bOnLeftEdge ) { for ( int j : vNeigh) { Point3d pt( m_mTree.at( nId).GetTopRight().x, m_mTree.at(j).GetBottomLeft().y) ; @@ -1783,7 +1780,7 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon if ( ! vNeigh.empty() && vNeigh.size() != 1) { // se la superficie è chiusa lungo il parametro V e la cella è sul lato top // devo aggiungere i vertici tenendo conto della periodicità dello spazio parametrico. - vnVert.push_back( int(vVertices.size() - 1)) ; + vnVert.push_back( int(vVertices.size())) ; if ( m_bClosedV && m_mTree.at( nId).m_bOnTopEdge) { for ( int j : vNeigh) { Point3d pt( m_mTree.at( j).GetBottomLeft().x, m_mTree.at( nId).GetTopRight().y) ; @@ -1809,7 +1806,7 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon if ( (int) vNeigh.size() != 0 && (int) vNeigh.size() != 1) { // se la superficie è chiusa lungo il parametro U e la cella è sul lato left // devo aggiungere i vertici tenendo conto della periodicità dello spazio parametrico. - vnVert.push_back( int(vVertices.size() - 1)) ; + vnVert.push_back( int(vVertices.size())) ; if ( m_bClosedU && m_mTree.at( nId).m_bOnLeftEdge) { for ( int j : vNeigh) { Point3d pt( m_mTree.at( nId).GetBottomLeft().x, m_mTree.at(j).GetTopRight().y) ; @@ -1847,123 +1844,111 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon // 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(m_mVert.at(nId).at(0), m_mVert.at(nId).at(1))) { - // se ho punti bonus su entrambi i lati non devo fare nulla - if ( !( vbBonusVert[1] && vbBonusVert[3] ) ) { - // sennò devo togliere l'estremo del lato su cui NON ho punti bonus - if ( vbBonusVert[1] ) {// 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 ; - m_mTree[nId].m_nVertToErase = 1 ; // ptBr + // 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]) ; } - else if ( 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 ; - m_mTree[nId].m_nVertToErase = 0 ; // ptBL - } - // se non ho bonus su nessuno dei due - else { - // ne scelgo uno dei due da togliere - vbKeepPoint[vnVert[1]] = false ; - m_mTree[nId].m_nVertToErase = 1 ; // ptBr + vbKeepPoint[vnVert[1]] = false ; + m_mTree[nId].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 ; + m_mTree[nId].m_nVertToErase = 0 ; // ptBL + } + // se non ho bonus su nessuno dei due + else { + // ne scelgo uno dei due da togliere + vbKeepPoint[vnVert[1]] = false ; + m_mTree[nId].m_nVertToErase = 1 ; // ptBr } } if ( AreSamePointApprox(m_mVert.at(nId).at(1), m_mVert.at(nId).at(2))) { - // se ho punti bonus su entrambi i lati non devo fare nulla - if ( !( vbBonusVert[0] && vbBonusVert[2] ) ) { - // sennò devo togliere l'estremo del lato su cui NON ho punti bonus - if ( vbBonusVert[0] ){ // 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 ; - m_mTree[nId].m_nVertToErase = 1 ; // ptBr + // 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[2] ){ - if ( ! m_bTrimmed) { - vVerticesCorr.erase(vVerticesCorr.begin() + vnVert[2]) ; - vVertices3d.erase(vVertices3d.begin() + vnVert[2]) ; - } - vbKeepPoint[vnVert[2]] = false ; - m_mTree[nId].m_nVertToErase = 2 ; // ptTR - } - // se non ho bonus su nessuno dei due - else { - // ne scelgo uno dei due da togliere - vbKeepPoint[vnVert[2]] = false ; - m_mTree[nId].m_nVertToErase = 2 ; // ptTR + vbKeepPoint[vnVert[1]] = false ; + m_mTree[nId].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 ; + m_mTree[nId].m_nVertToErase = 2 ; // ptTR + } + // se non ho bonus su nessuno dei due + else { + // ne scelgo uno dei due da togliere + vbKeepPoint[vnVert[2]] = false ; + m_mTree[nId].m_nVertToErase = 2 ; // ptTR } } if ( AreSamePointApprox(m_mVert.at(nId).at(2), m_mVert.at(nId).at(3))) { - // se ho punti bonus su entrambi i lati non devo fare nulla - if ( !( vbBonusVert[1] && vbBonusVert[3] ) ) { - // sennò devo togliere l'estremo del lato su cui NON ho punti bonus - if ( vbBonusVert[1] ){ // 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 ; - m_mTree[nId].m_nVertToErase = 2 ; // ptTR + // 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]) ; } - else if ( vbBonusVert[3] ) { - if ( ! m_bTrimmed) { - vVerticesCorr.erase(vVerticesCorr.begin() + vnVert[3]) ; - vVertices3d.erase(vVertices3d.begin() + vnVert[3]) ; - } - vbKeepPoint[vnVert[3]] = false ; - m_mTree[nId].m_nVertToErase = 3 ; // ptTl - } - // se non ho bonus su nessuno dei due - else { - // ne scelgo uno dei due da togliere - vbKeepPoint[vnVert[3]] = false ; - m_mTree[nId].m_nVertToErase = 3 ; // ptTl + vbKeepPoint[vnVert[2]] = false ; + m_mTree[nId].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 ; + m_mTree[nId].m_nVertToErase = 3 ; // ptTl + } + // se non ho bonus su nessuno dei due + else { + // ne scelgo uno dei due da togliere + vbKeepPoint[vnVert[3]] = false ; + m_mTree[nId].m_nVertToErase = 3 ; // ptTl } } if ( AreSamePointApprox(m_mVert.at(nId).at(3), m_mVert.at(nId).at(0))) { - // se ho punti bonus su entrambi i lati non devo fare nulla - if ( !( vbBonusVert[0] && vbBonusVert[2] ) ) { - // sennò devo togliere l'estremo del lato su cui NON ho punti bonus - if ( vbBonusVert[0] ) { // 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 ; - m_mTree[nId].m_nVertToErase = 0 ; // ptBL + // 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] ; } - else if ( vbBonusVert[2] ) { - if ( ! m_bTrimmed) { - vVerticesCorr.erase(vVerticesCorr.begin() + vnVert[3]) ; - vVertices3d.erase(vVertices3d.begin() + vnVert[3]) ; - } - vbKeepPoint[vnVert[3]] = false ; - m_mTree[nId].m_nVertToErase = 3 ; // ptTl - } - // se non ho bonus su nessuno dei due - else { - // ne scelgo uno dei due da togliere - vbKeepPoint[vnVert[3]] = false ; - m_mTree[nId].m_nVertToErase = 3 ; // ptTl + vbKeepPoint[0] = false ; + vbKeepPoint.back() = false ; + m_mTree[nId].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 ; + m_mTree[nId].m_nVertToErase = 3 ; // ptTl + } + // se non ho bonus su nessuno dei due + else { + // ne scelgo uno dei due da togliere + vbKeepPoint[vnVert[3]] = false ; + m_mTree[nId].m_nVertToErase = 3 ; // ptTl } } } @@ -3001,6 +2986,7 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX int nEdgeIn = -1 ; int nFirstLoopInPoly = -1 ; INTVECTOR vAddedLoops ; + Point3d ptLastAdded( -1, -1, 0) ; for ( int w = 0 ; w < (int)vToCheckNow.size() ; ++ w) { if ( m_mTree[nId].m_vInters[w].vpt.size() < 2) { continue ; @@ -3016,7 +3002,7 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX nFirstLoopInPoly = j ; } for ( Point3d ptInt : inA.vpt) { - AddVertex( nId, vEdgeVertex, vEdgeVertex3d, plTrimmedPoly, c, ptInt, plTrimmedPoly3d, bForTriangulation) ; + AddVertex( nId, vEdgeVertex, vEdgeVertex3d, plTrimmedPoly, c, ptInt, plTrimmedPoly3d, bForTriangulation, ptLastAdded) ; } vAddedLoops.push_back( j) ; nEdge = inA.nOut ; @@ -3115,7 +3101,7 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX ptVert = ptBr ; else if ( nEdge == 3) ptVert = ptTR ; - AddVertex( nId, vEdgeVertex, vEdgeVertex3d, plTrimmedPoly, c, ptVert, plTrimmedPoly3d, bForTriangulation) ; + AddVertex( nId, vEdgeVertex, vEdgeVertex3d, plTrimmedPoly, c, ptVert, plTrimmedPoly3d, bForTriangulation, ptLastAdded) ; if ( nEdge > 3 && nEdge != 7) nEdge = nEdge - 4 ; else if ( nEdge < 3) @@ -3172,7 +3158,7 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX ptVert = ptBr ; else if ( nEdge == 3) ptVert = ptTR ; - AddVertex( nId, vEdgeVertex, vEdgeVertex3d, plTrimmedPoly, c, ptVert, plTrimmedPoly3d, bForTriangulation) ; + AddVertex( nId, vEdgeVertex, vEdgeVertex3d, plTrimmedPoly, c, ptVert, plTrimmedPoly3d, bForTriangulation, ptLastAdded) ; if ( nEdge > 3 && nEdge != 7) nEdge = nEdge - 4 ; else if ( nEdge < 3) @@ -3194,6 +3180,7 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX } plTrimmedPoly.Close() ; plTrimmedPoly3d.Close() ; + ptLast.Set( -1,-1,0) ; // controllo sull'area del poligono, se è 0 ( quindi un segmento), non lo aggiungo double dArea ; plTrimmedPoly.GetAreaXY( dArea) ; @@ -3519,7 +3506,7 @@ Tree::AreSameEdge( int nEdge1, int nEdge2) const //---------------------------------------------------------------------------- bool Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVertex3d, PolyLine& plTrimmedPoly, int& c, - const Point3d& ptToAdd, PolyLine& plTrimmedPoly3d, bool bForTriangulation) const + const Point3d& ptToAdd, PolyLine& plTrimmedPoly3d, bool bForTriangulation, Point3d& ptLast) const { Point3d ptBr = m_mTree.at(nId).GetBottomRight() ; Point3d ptTR = m_mTree.at(nId).GetTopRight() ; @@ -3532,8 +3519,11 @@ Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVe if( ( nVertToSkip == 0 && AreSamePointApprox( ptToAdd, ptBL)) || ( nVertToSkip == 1 && AreSamePointApprox( ptToAdd, ptBr)) || ( nVertToSkip == 2 && AreSamePointApprox( ptToAdd, ptTR)) || - ( nVertToSkip == 3 && AreSamePointApprox( ptToAdd, ptTl))) + ( nVertToSkip == 3 && AreSamePointApprox( ptToAdd, ptTl))) { + // aggiorno l'ultimo punto aggiunto + ptLast.Set( ptToAdd.x, ptToAdd.y, 0) ; return true ; + } plTrimmedPoly.AddUPoint( c, ptToAdd) ; if ( bForTriangulation) { @@ -3542,10 +3532,13 @@ Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVe plTrimmedPoly3d.AddUPoint( c, pt3d) ; } ++ c ; + // aggiorno l'ultimo punto aggiunto + ptLast.Set( ptToAdd.x, ptToAdd.y, 0) ; return true ; } - Point3d ptLast ; - plTrimmedPoly.GetLastPoint( ptLast) ; + //Point3d ptLast ; + //plTrimmedPoly.GetLastPoint( ptLast) ; + // verifico di essere allineato con un lato, sennò aggiungo e basta Vector3d vDir ; if ( ! AreSamePointApprox( ptToAdd, ptLast)) @@ -3588,13 +3581,15 @@ Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVe } ++ c ; } + // aggiorno l'ultimo punto aggiunto + ptLast.Set( ptToAdd.x, ptToAdd.y, 0) ; return true ; } 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 = 1 ; t < (int)vEdgeVertex[0].size() ; ++ t) { + for ( int t = nVertToSkip == 2 ? 0 : 1 ; t < (int)vEdgeVertex[0].size() ; ++ t) { Point3d ptIntermed = vEdgeVertex[0][t] ; if ( ptIntermed.x > ptToAdd.x && ptIntermed.x < ptLast.x) { plTrimmedPoly.AddUPoint( c, ptIntermed) ; @@ -3619,7 +3614,7 @@ Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVe } // 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 = 1 ; t < (int)vEdgeVertex[1].size() ; ++ t) { + for ( int t = nVertToSkip == 3 ? 0 : 1 ; t < (int)vEdgeVertex[1].size() ; ++ t) { Point3d ptIntermed = vEdgeVertex[1][t] ; if ( ptIntermed.y > ptToAdd.y && ptIntermed.y < ptLast.y) { plTrimmedPoly.AddUPoint( c, ptIntermed) ; @@ -3644,7 +3639,7 @@ Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVe } // 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 = 1 ; t < (int)vEdgeVertex[2].size() ; ++ t) { + for ( int t = nVertToSkip == 0 ? 0 : 1 ; t < (int)vEdgeVertex[2].size() ; ++ t) { Point3d ptIntermed = vEdgeVertex[2][t] ; if ( ptIntermed.x < ptToAdd.x && ptIntermed.x > ptLast.x) { plTrimmedPoly.AddUPoint( c, ptIntermed) ; @@ -3669,7 +3664,7 @@ Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVe } // 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 = 1 ; t < (int)vEdgeVertex[3].size() ; ++ t) { + for ( int t = nVertToSkip == 1 ? 0 : 1 ; t < (int)vEdgeVertex[3].size() ; ++ t) { Point3d ptIntermed = vEdgeVertex[3][t] ; if ( ptIntermed.y < ptToAdd.y && ptIntermed.y > ptLast.y) { plTrimmedPoly.AddUPoint( c, ptIntermed) ; @@ -3712,6 +3707,8 @@ Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVe } ++ c ; } + // aggiorno l'ultimo punto aggiunto + ptLast.Set( ptToAdd.x, ptToAdd.y, 0) ; return true ; } @@ -4060,6 +4057,36 @@ Tree::CheckIfBetween( const Inters& inA, const Inters& inB) const return bFound ; } +//---------------------------------------------------------------------------- +bool +Tree::CheckIfBefore( int nEdgeA, int nEdgeB) const +{ + // questa funzione è pensata per edge che sono uguali per la funzione AreSameEdge + // su quell'edge verifico se EdgeA viene prima di EdgeB ( il senso di precorrenza è sempre antiorario) + switch ( nEdgeA ) { + case 0 : return nEdgeB == 4 ? true : false ; break ; + case 1 : return nEdgeB == 5 ? true : false ; break ; + case 2 : return nEdgeB == 6 ? true : false ; break ; + case 3 : return nEdgeB == 7 ? true : false ; break ; + case 4 : + if ( nEdgeB == 1 || nEdgeB == 5) + return true ; + break ; + case 5 : + if ( nEdgeB == 2 || nEdgeB == 6) + return true ; + break ; + case 6 : + if ( nEdgeB == 3 || nEdgeB == 7) + return true ; + break ; + case 7 : + if ( nEdgeB == 0 || nEdgeB == 4) + return true ; + break ; + } +} + //---------------------------------------------------------------------------- bool Tree::GetLeaves( vector& vLeaves) const diff --git a/Tree.h b/Tree.h index 59d769c..20d6e2f 100644 --- a/Tree.h +++ b/Tree.h @@ -284,8 +284,9 @@ class Tree bool CheckIfBefore( int nEdge1, const Point3d& ptP1, int nEdge2, const Point3d& ptP2) const ; // verifico quale punto viene prima tra pt1 e pt2 a partire da ptTR girando in senso CCW (punto 1 su edge 1 e punto 2 su edge 2, rispetto al lato 3) bool CheckIfBefore( int nEdge, const Point3d& ptP1, const Point3d& ptP2, int nEdge2 = -1) const ; // sul lato nEdge controllo se ptP1 viene prima di ptP2. bool AreSameEdge( int nEdge1, int nEdge2) const ; // indica se i due edge sono lo stesso. Un vertice adiacente ad un edge viene considerato uguale a questo edge + bool CheckIfBefore( int nEdgeA, int nEdgeB) const ; // per due edge uguali per la funzione AreSameEdge chiedo se EdgeA viene prima di EdgeB bool AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVertex3d, PolyLine& plTrimmedPoly, int& c, - const Point3d& ptToAdd, PolyLine& plTrimmedPoly3d, bool ForTriangulation) const ; // aggiunge un punto ad un poligono in una cella, premurandosi di aggiungere eventualmente vertici o punti di celle vicine di cui tenere conto + const Point3d& ptToAdd, PolyLine& plTrimmedPoly3d, bool ForTriangulation, Point3d& ptLast) const ; // aggiunge un punto ad un poligono in una cella, premurandosi di aggiungere eventualmente vertici o punti di celle vicine di cui tenere conto bool SetRightEdgeIn( int nId) ; // categorizza la cella in base all'edge destro per poter poi definire m_nFlag bool CategorizeCell( int nId) ; // categorizza la cella in base al flag m_nFlag (dentro, fuori, intersecata) bool CheckIfBetween( const Inters& inA, const Inters& inB) const ; // / controllo se inB è compreso tra l'end e lo start di inA (in senso CCW)