From f0cf3c95592ebb841d2a35fc1df3c5893b2fa571 Mon Sep 17 00:00:00 2001 From: Daniele Bariletti Date: Fri, 4 Oct 2024 14:57:23 +0200 Subject: [PATCH] EgtGeomKernel : - rimozione memory leak - corretto bug nella triangolazione bezier. --- Tree.cpp | 129 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 73 insertions(+), 56 deletions(-) diff --git a/Tree.cpp b/Tree.cpp index 95c5db6..733a359 100644 --- a/Tree.cpp +++ b/Tree.cpp @@ -166,6 +166,7 @@ Tree::AdjustLoop( PolyLine& pl, POLYLINEVECTOR& vPl, BOOLVECTOR& vbOrientation) for ( auto itCrv = vCrv.begin() ; itCrv != vCrv.end() ; ++itCrv) { PolyLine plApprox ; (*itCrv)->ApproxWithLines( 0.01, 15, 0, plApprox) ; vPl.push_back( plApprox) ; + delete (*itCrv) ; } return true ; } @@ -3821,7 +3822,7 @@ Tree::SetRightEdgeIn( int nId) // RightEdgeIn -> 0 non contenuto ; 1 contenuto ; 2 in parte contenuto int nPass = (int) cCell.m_vInters.size() ; if ( nPass == 0) { - cCell.m_nRightEdgeIn = 0 ; + cCell.m_nRightEdgeIn = -1 ; return true ; } bool bDone = false ; @@ -3948,7 +3949,7 @@ Tree::CategorizeCell( int nId) else if ( vNeigh.size() == 1) { if ( m_mTree[vNeigh[0]].m_nRightEdgeIn == 1) cCell.m_nFlag = 4 ; - else if ( m_mTree[vNeigh[0]].m_nRightEdgeIn == 0) + else if ( m_mTree[vNeigh[0]].m_nRightEdgeIn == 0 || m_mTree[vNeigh[0]].m_nRightEdgeIn == -1) { // devo verificare se la cella è intersecata if ( m_mTree[vNeigh[0]].m_nFlag == 1 || m_mTree[vNeigh[0]].m_nFlag == 3) cCell.m_nFlag = 0 ; @@ -3958,6 +3959,7 @@ Tree::CategorizeCell( int nId) else if ( m_mTree[vNeigh[0]].m_nFlag == 0) cCell.m_nFlag = 0 ; } + } // se solo parte del right edge del vicino è compreso, allora devo verificare se la cella è contenuta o no // guardando nFlag del vicino bottom, che è già categorizzato! else if ( m_mTree[vNeigh[0]].m_nRightEdgeIn == 2) { @@ -3971,67 +3973,82 @@ Tree::CategorizeCell( int nId) cCell.m_nFlag = 4 ; } else if ( m_mTree[nNeigh].m_nFlag == 1 || m_mTree[nNeigh].m_nFlag == 3) { - if ( m_mTree[nNeigh].m_nRightEdgeIn == 0) - cCell.m_nFlag = 0 ; - else if ( m_mTree[nNeigh].m_nRightEdgeIn == 1) - cCell.m_nFlag = 4 ; - else if ( m_mTree[nNeigh].m_nRightEdgeIn == 2) { - // in questo caso devo verificare le intersezioni sul lato destro del vicino bottom - // scorro e cerco l'intersezione più alta, se è out la cella è dentro, se è in devo verificare l'out se è più a sinistra o a destra. - int nPass = (int) m_mTree[nNeigh].m_vInters.size() ; - bool bTopMost = false ; - bool bFound = false ; - Point3d ptInters, ptBr( m_mTree[nNeigh].GetTopRight().x, m_mTree[nNeigh].GetBottomLeft().y) ; - ptInters = ptBr ; // inizializzato a vertice bottom right - int nLoop ; + if ( m_mTree[nNeigh].m_nRightEdgeIn == 0 || m_mTree[nNeigh].m_nRightEdgeIn == 1){ + // devo capire dove viene tagliato il vicino bottom per poter trarre qualche informazione + // se sul lato top del vicino bottom l'intersezione più vicina alla cella in esame (al suo ptBr) è un'uscita, allora sono dentro + // in tutti gli altri casi sono fuori + int nPass = int( m_mTree[nNeigh].m_vInters.size()) ; + bool bIntersTop = false ; for ( int r = 0 ; r < nPass ; ++ r) { - // trovo il loop che ha l'ingresso o l'uscita più in alto sul lato destro - // verifico che o l'ingresso o l'uscita siano sul lato destro e che sia l'intersezione più alta su quel lato - if ( m_mTree[nNeigh].m_vInters[r].nIn == 3 && ! CheckIfBefore( m_mTree[nNeigh].m_vInters[r].nIn, m_mTree[nNeigh].m_vInters[r].vpt[0], ptInters)) { - nLoop = r ; - ptInters = m_mTree[nNeigh].m_vInters[r].vpt[0] ; - bFound = true ; - } - if ( m_mTree[nNeigh].m_vInters[r].nOut == 3 && ! CheckIfBefore( m_mTree[nNeigh].m_vInters[r].nOut, m_mTree[nNeigh].m_vInters[r].vpt.back(), ptInters)) { - nLoop = r ; - ptInters = m_mTree[nNeigh].m_vInters[r].vpt.back() ; - bFound = true ; - } - // controllo nei vertici - if ( m_mTree[nNeigh].m_vInters[r].nOut == 7 || m_mTree[nNeigh].m_vInters[r].nIn == 7) { - nLoop = r ; - ptInters = m_mTree[nNeigh].GetTopRight() ; - bFound = true ; + if ( m_mTree[nNeigh].m_vInters[r].nOut == 0 || m_mTree[nNeigh].m_vInters[r].nOut == 7) { + bIntersTop = true ; break ; } - if ( m_mTree[nNeigh].m_vInters[r].nOut == 6 || m_mTree[nNeigh].m_vInters[r].nIn == 6) { - nLoop = r ; - ptInters = ptBr ; - bFound = true ; - } } - if ( bFound && CheckIfBefore( m_mTree[nNeigh].m_vInters[nLoop])) { - bTopMost = true ; - } - if ( bFound && bTopMost) { - if ( AreSameEdge( m_mTree[nNeigh].m_vInters[nLoop].nIn, 3) && AreSameEdge( m_mTree[nNeigh].m_vInters[nLoop].nOut, 3)) { - if ( CheckIfBefore( m_mTree[nNeigh].m_vInters[nLoop])) - cCell.m_nFlag = 4 ; - else - cCell.m_nFlag = 0 ; + // se nella cella bottom non ho intersezioni con il lato top allora la cella in esame è fuori + if ( ! bIntersTop && m_mTree[nNeigh].m_nRightEdgeIn == 0) + cCell.m_nFlag = 0 ; + else if ( ! bIntersTop && m_mTree[nNeigh].m_nRightEdgeIn == 1) + cCell.m_nFlag = 4 ; + else { + Point3d ptBr = cCell.GetBottomRight() ; + bool bFound = false ; + Point3d ptLeftMostInters = m_mTree[nNeigh].GetTopRight() ; + for ( int r = 0 ; r < nPass ; ++ r) { + Point3d ptIntersOut = m_mTree[nNeigh].m_vInters[r].vpt.back() ; + Point3d ptIntersIn = m_mTree[nNeigh].m_vInters[r].vpt[0] ; + if ( (m_mTree[nNeigh].m_vInters[r].nOut == 0 || m_mTree[nNeigh].m_vInters[r].nOut == 7) && + ( CheckIfBefore( 2, ptBr, ptIntersOut) || AreSamePointApprox( ptBr, ptIntersOut))) { + if (ptIntersOut.x < ptLeftMostInters.x) { + ptLeftMostInters = ptIntersOut ; + bFound = true ; + } + } + if ( (m_mTree[nNeigh].m_vInters[r].nIn == 0 || m_mTree[nNeigh].m_vInters[r].nIn == 7) && + ( CheckIfBefore( 2, ptBr, ptIntersIn) || AreSamePointApprox( ptBr, ptIntersIn))) { + if (ptIntersIn.x < ptLeftMostInters.x) { + ptLeftMostInters = ptIntersIn ; + bFound = false ; + } + } } - else if ( AreSameEdge( m_mTree[nNeigh].m_vInters[nLoop].nOut, 3)) + if ( bFound) cCell.m_nFlag = 4 ; - else if ( AreSameEdge( m_mTree[nNeigh].m_vInters[nLoop].nIn, 3)) { - // devo verificare se l'uscita è più a sinistra o più a destra della cella - Point3d ptOut = m_mTree[nNeigh].m_vInters[nLoop].vpt.back() ; - Point3d ptBr( cCell.GetTopRight().x, cCell.GetBottomLeft().y) ; - if ( ptOut.x >= ptBr.x) - cCell.m_nFlag = 4 ; - else - cCell.m_nFlag = 0 ; + else + cCell.m_nFlag = 0 ; + } + } + else if ( m_mTree[nNeigh].m_nRightEdgeIn == 2) { + // in questo caso devo verificare le intersezioni sul lato destro e top del vicino bottom + // scorro e cerco l'intersezione più vicina al ptBr della cella in esame( percorrendo il bordo della cella bottom in senso orario) + // se è un nIn allora la cella in esame è dentro, altrimenti è fuori + int nPass = (int) m_mTree[nNeigh].m_vInters.size() ; + bool bFound = false ; + Point3d ptTopLeftMostInters = m_mTree[nNeigh].GetBottomRight() ; + for ( int r = 0 ; r < nPass ; ++ r) { + int nOut = m_mTree[nNeigh].m_vInters[r].nOut ; + int nIn = m_mTree[nNeigh].m_vInters[r].nIn ; + if ( (AreSameEdge( nOut, 3) || nOut == 0)) { + Point3d ptInters = m_mTree[nNeigh].m_vInters[r].vpt.back() ; + if ( ( abs( ptInters.x - ptTopLeftMostInters.x) > EPS_SMALL && ptInters.x < ptTopLeftMostInters.x) || + (abs( ptInters.y - ptTopLeftMostInters.y) > EPS_SMALL && ptInters.y > ptTopLeftMostInters.y)) { + ptTopLeftMostInters = ptInters ; + bFound = true ; + } + } + if ( (AreSameEdge( nIn, 3) || nIn == 0)) { + Point3d ptInters = m_mTree[nNeigh].m_vInters[r].vpt[0] ; + if ( ( abs( ptInters.x - ptTopLeftMostInters.x) > EPS_SMALL && ptInters.x < ptTopLeftMostInters.x) || + (abs( ptInters.y - ptTopLeftMostInters.y) > EPS_SMALL && ptInters.y > ptTopLeftMostInters.y)) { + ptTopLeftMostInters = ptInters ; + bFound = false ; + } } } + if ( bFound) + cCell.m_nFlag = 4 ; + else + cCell.m_nFlag = 0 ; } } } @@ -4067,7 +4084,7 @@ Tree::CategorizeCell( int nId) cCell.m_nFlag = 4 ; break ; } - else if ( m_mTree[vNeigh[r]].m_nRightEdgeIn == 0) { + else if ( m_mTree[vNeigh[r]].m_nRightEdgeIn == 0 || m_mTree[vNeigh[r]].m_nRightEdgeIn == -1) { if ( m_mTree[vNeigh[r]].m_nFlag == 4) { cCell.m_nFlag = 4 ; break ;