//---------------------------------------------------------------------------- // EgalTech 2015-2015 //---------------------------------------------------------------------------- // File : RemoveCurveOverlaps.cpp Data : 02.11.15 Versione : 1.6K1 // Contenuto : Implementazione rimozione sovrapposizioni di curva. // // // // Modifiche : 02.11.15 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "GeoConst.h" #include "CurveComposite.h" #include "RemoveCurveOverlaps.h" #include "/EgtDev/Include/EGkIntersCurves.h" #include "/EgtDev/Include/EGkIntervals.h" #include "/EgtDev/Include/EgtPointerOwner.h" #include using namespace std ; //---------------------------------------------------------------------------- bool RemoveCurveOverlaps( ICurve* pCurve, bool bRemoveSam, bool bRemoveCtr, ICURVEPLIST& CrvLst) { // Pulisco lista di ritorno CrvLst.clear() ; // Acquisisco la curva PtrOwner pMyCrv( pCurve) ; // Verifico validità curva if ( IsNull( pMyCrv) || ! pMyCrv->IsValid()) return false ; // Se nulla da rimuovere, non devo fare alcunché if ( ! bRemoveSam && ! bRemoveCtr) { CrvLst.push_back( Release( pMyCrv)) ; return true ; } // --- la verifica ed eventuale rimozione va effettuata in un piano perpendicolare al vettore estrusione --- // verifico il vettore estrusione Vector3d vtExtr ; pMyCrv->GetExtrusion( vtExtr) ; bool bNeedRef = ( ! vtExtr.IsSmall() && ! vtExtr.IsZplus()) ; // se necessario cambio il riferimento Frame3d frExtr ; if ( bNeedRef) { // calcolo il riferimento OCS con VtExtr come asse Z if ( ! frExtr.Set( ORIG, vtExtr)) return false ; // esprimo la curva in questo riferimento pMyCrv->ToLoc( frExtr) ; } // Calcolo le auto intersezioni SelfIntersCurve sintC( *pMyCrv) ; // se non ci sono sovrapposizioni, non devo fare alcunché if ( ! sintC.GetOverlaps()) { // riporto la curva nel riferimento originale if ( bNeedRef) pMyCrv->ToGlob( frExtr) ; // la inserisco in lista CrvLst.push_back( Release( pMyCrv)) ; return true ; } // Determino intervallo complessivo della curva double dStart, dEnd ; if ( ! pMyCrv->GetDomain( dStart, dEnd)) return false ; Intervals inOk( EPS_PARAM) ; inOk.Set( dStart, dEnd) ; // Tolgo le parti in sovrapposizione da eliminare IntCrvCrvInfo iccInfo ; for ( int i = 0 ; sintC.GetIntCrvCrvInfo( i, iccInfo) ; ++ i) { // se sovrapposti if ( iccInfo.bOverlap) { // se equiversi e da eliminare, elimino solo uno dei due tratti if ( iccInfo.bCBOverEq && bRemoveSam) { inOk.Subtract( iccInfo.IciB[0].dU, iccInfo.IciB[1].dU) ; } // se altrimenti controversi e da eliminare, elimino entrambi i tratti else if ( ! iccInfo.bCBOverEq && bRemoveCtr) { inOk.Subtract( iccInfo.IciA[0].dU, iccInfo.IciA[1].dU) ; inOk.Subtract( iccInfo.IciB[0].dU, iccInfo.IciB[1].dU) ; } } } // Copio le parti da conservare double dParS, dParE ; bool bFound = inOk.GetFirst( dParS, dParE) ; while ( bFound) { ICurve* pCrv = pMyCrv->CopyParamRange( dParS, dParE) ; if ( pCrv != nullptr) { if ( pCrv->GetType() == CRV_COMPO) CrvLst.push_back( pCrv) ; else { CurveComposite* pCrvCo = new( std::nothrow) CurveComposite ; if ( pCrvCo != nullptr) { pCrvCo->AddCurve( pCrv) ; CrvLst.push_back( pCrvCo) ; } } } bFound = inOk.GetNext( dParS, dParE) ; } // Concateno i percorsi risultanti (senza cambiare verso) for ( auto iIter = CrvLst.begin() ; iIter != CrvLst.end() ;) { CurveComposite* pCrvCo = GetBasicCurveComposite( *iIter) ; // recupero punti iniziale e finale della curva Point3d ptStart, ptEnd ; pCrvCo->GetStartPoint( ptStart) ; pCrvCo->GetEndPoint( ptEnd) ; // ciclo sulle curve successive per verificare se possibile concatenamento for ( auto iIter2 = next( iIter) ; iIter2 != CrvLst.end() ;) { CurveComposite* pCrvCo2 = GetBasicCurveComposite( *iIter2) ; // recupero punti iniziale e finale della curva Point3d ptStart2, ptEnd2 ; pCrvCo2->GetStartPoint( ptStart2) ; pCrvCo2->GetEndPoint( ptEnd2) ; // verifiche di concatenamento if ( AreSamePointEpsilon( ptEnd, ptStart2, 10 * EPS_SMALL)) { pCrvCo->AddCurve( pCrvCo2, true, 10 * EPS_SMALL) ; CrvLst.erase( iIter2) ; ptEnd = ptEnd2 ; iIter2 = next( iIter) ; } else if ( AreSamePointEpsilon( ptEnd2, ptStart, 10 * EPS_SMALL)) { pCrvCo->AddCurve( pCrvCo2, false, 10 * EPS_SMALL) ; CrvLst.erase( iIter2) ; ptStart = ptStart2 ; iIter2 = next( iIter) ; } else ++ iIter2 ; } ++ iIter ; } // riporto le curve nel riferimento originale if ( bNeedRef) { for ( auto pCrv : CrvLst) pCrv->ToGlob( frExtr) ; } // assegno il versore estrusione originale for ( auto pCrv : CrvLst) pCrv->SetExtrusion( vtExtr) ; return true ; }