Files
EgtGeomKernel/RemoveCurveOverlaps.cpp
T
Dario Sassi 41f8b0d103 EgtGeomKernel :
- piccola miglioria a costruzione Regioni su piani generici.
2015-11-04 11:25:41 +00:00

161 lines
5.5 KiB
C++

//----------------------------------------------------------------------------
// 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 <algorithm>
using namespace std ;
//----------------------------------------------------------------------------
bool
RemoveCurveOverlaps( ICurve* pCurve, bool bRemoveSam, bool bRemoveCtr, ICURVEPLIST& CrvLst)
{
// Pulisco lista di ritorno
CrvLst.clear() ;
// Acquisisco la curva
PtrOwner<ICurve> 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 ;
}