//---------------------------------------------------------------------------- // EgalTech 2017-2022 //---------------------------------------------------------------------------- // File : RemoveCurveDefects.cpp Data : 28.11.22 Versione : 2.4k6 // Contenuto : Implementazione rimozione spikes di curva. // // // // Modifiche : 02.10.17 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "GeoConst.h" #include "CurveComposite.h" #include "DistPointLine.h" #include "RemoveCurveDefects.h" #include "/EgtDev/Include/EGkDistPointCurve.h" #include using namespace std ; //---------------------------------------------------------------------------- bool RemoveCurveSpikes( ICurveComposite* pCurve, double dLinTol) { // verifico validità curva if ( pCurve == nullptr) return false ; // verifico e sistemo tolleranza lineare dLinTol = max( dLinTol, EPS_SMALL) ; // recupero il numero di curve semplici componenti la composta int nCrvCount = pCurve->GetCurveCount() ; if ( nCrvCount < 2 || ( nCrvCount < 3 && pCurve->IsClosed())) return true ; // ciclo sulle curve elementari della composita int nStart = pCurve->IsClosed() ? 0 : 1 ; for ( int i = nStart ; i < nCrvCount ; ++ i) { // recupero due curve consecutive const ICurve* pPrevCrv = pCurve->GetCurve( ( i > 0 ? i - 1 : nCrvCount - 1)) ; const ICurve* pNextCrv = pCurve->GetCurve( i) ; // se sono entrambe rette if ( pPrevCrv->GetType() == CRV_LINE && pNextCrv->GetType() == CRV_LINE) { // recupero i punti estremi Point3d ptStart ; pPrevCrv->GetStartPoint( ptStart) ; Point3d ptMid ; pPrevCrv->GetEndPoint( ptMid) ; Point3d ptEnd ; pNextCrv->GetEndPoint( ptEnd) ; // recupero le direzioni negli estremi Vector3d vtPrev ; pPrevCrv->GetStartDir( vtPrev) ; Vector3d vtNext ; pNextCrv->GetStartDir( vtNext) ; // verifico se spike double dPrevDist, dNextDist ; if ( vtPrev * vtNext < cos( 175 * DEGTORAD) && (( DistPointLine( ptStart, ptMid, ptEnd).GetDist( dPrevDist) && dPrevDist < dLinTol) || ( DistPointLine( ptEnd, ptStart, ptMid).GetDist( dNextDist) && dNextDist < dLinTol))) { // se spike ha base abbastanza larga, basta togliere uno dei due lati if ( SqDist( ptStart, ptEnd) > SQ_EPS_SMALL) { pCurve->RemoveJoint( i) ; -- nCrvCount ; -- i ; } // altrimenti bisogna togliere entrambi else { pCurve->RemoveJoint( i - 1) ; pCurve->RemoveJoint( i) ; nCrvCount -= 2 ; i = max( i - 2, nStart - 1) ; } } } // !!! Aggiungere la gestione degli altri tipi di curve !!! } return true ; } //---------------------------------------------------------------------------- bool RemoveCurveSmallZs( ICurveComposite* pCurve, double dLinTol) { // verifico validità curva if ( pCurve == nullptr) return false ; // verifico e sistemo tolleranza lineare dLinTol = max( dLinTol, EPS_SMALL) ; // recupero il numero di curve semplici componenti la composta int nCrvCount = pCurve->GetCurveCount() ; if ( nCrvCount < 2 || ( nCrvCount < 3 && pCurve->IsClosed())) return true ; // ciclo sulle curve elementari della composita int nStart = pCurve->IsClosed() ? 0 : 1 ; int nEnd = pCurve->IsClosed() ? nCrvCount : nCrvCount - 1 ; for ( int i = nStart ; i < nEnd ; ++ i) { // recupero tre curve consecutive const ICurve* pPrevCrv = pCurve->GetCurve( ( i > 0 ? i - 1 : nCrvCount - 1)) ; const ICurve* pCurrCrv = pCurve->GetCurve( i) ; const ICurve* pNextCrv = pCurve->GetCurve( ( i < nCrvCount - 1 ? i + 1 : 0)) ; // se la curva corrente è una retta if ( pCurrCrv->GetType() == CRV_LINE) { // recupero tre punti notevoli della curva Point3d ptStart ; pCurrCrv->GetStartPoint( ptStart) ; Point3d ptMid ; pCurrCrv->GetMidPoint( ptMid) ; Point3d ptEnd ; pCurrCrv->GetEndPoint( ptEnd) ; // recupero le direzioni negli estremi Vector3d vtPrev ; pPrevCrv->GetEndDir( vtPrev) ; Vector3d vtNext ; pNextCrv->GetStartDir( vtNext) ; // verifico se Small Z double dDistS, dDistM1, dDistM2, dDistE ; if ( vtPrev * vtNext > cos( 30 * DEGTORAD) && (( DistPointCurve( ptStart, *pNextCrv).GetDist( dDistS) && dDistS < dLinTol) && ( DistPointCurve( ptMid, *pNextCrv).GetDist( dDistM1) && dDistM1 < dLinTol) && ( DistPointCurve( ptMid, *pPrevCrv).GetDist( dDistM2) && dDistM2 < dLinTol) && ( DistPointCurve( ptEnd, *pPrevCrv).GetDist( dDistE) && dDistE < dLinTol))) { // rimuovo il segmento if ( pCurve->RemoveJoint( i)) { -- nCrvCount ; -- nEnd ; -- i ; // porto il nuovo estremo sul punto medio pCurve->ModifyJoint( i + 1, ptMid) ; } // altrimenti devo rimuovere anche il successivo else if ( pCurve->RemoveJoint( i + 1) && pCurve->RemoveJoint( i)) { nCrvCount -= 2 ; nEnd -= 2 ; -- i ; // porto il nuovo estremo sul punto medio pCurve->ModifyJoint( i + 1, ptMid) ; } } } } return true ; }