41f8b0d103
- piccola miglioria a costruzione Regioni su piani generici.
161 lines
5.5 KiB
C++
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 ;
|
|
} |