36547c24c2
- in Close di CurveComposite si usa una tolleranza di EPS_SMALL/10 per verificare se la curva è chiusa - in OffsetCurve se la curva originale era chiusa e tale va considerata si verifica la chiusura dei risultati ed eventualmente si sistemano.
142 lines
5.2 KiB
C++
142 lines
5.2 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2015-2015
|
|
//----------------------------------------------------------------------------
|
|
// File : SurfFlatRegionOffset.cpp Data : 01.11.15 Versione : 1.6k1
|
|
// Contenuto : Implementazione della funzione offset per SurfFlatRegion.
|
|
//
|
|
//
|
|
//
|
|
// Modifiche : 01.11.15 DS Creazione modulo.
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "stdafx.h"
|
|
#include "GeoConst.h"
|
|
#include "CurveComposite.h"
|
|
#include "SurfFlatRegion.h"
|
|
#include "/EgtDev/Include/EGkOffsetCurve.h"
|
|
#include "/EgtDev/Include/EgtPointerOwner.h"
|
|
|
|
using namespace std ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
SurfFlatRegion::Offset( double dDist, int nType)
|
|
{
|
|
// recupero il numero dei chunk
|
|
int nChunk = GetChunkCount() ;
|
|
if ( nChunk == 0)
|
|
return false ;
|
|
// se offset nullo, non devo fare alcunché
|
|
if ( abs( dDist) < 10 * EPS_SMALL)
|
|
return true ;
|
|
// creo una nuova regione
|
|
PtrOwner<SurfFlatRegion> pSfr( new( nothrow) SurfFlatRegion) ;
|
|
if ( IsNull( pSfr))
|
|
return false ;
|
|
bool bFirstRegion = true ;
|
|
// ciclo sui chunk
|
|
for ( int i = 0 ; i < nChunk ; ++ i) {
|
|
// creo la regione del chunk
|
|
PtrOwner<SurfFlatRegion> pSfrChk( new( nothrow) SurfFlatRegion) ;
|
|
if ( IsNull( pSfrChk))
|
|
return false ;
|
|
bool bFirstCurve = true ;
|
|
// ciclo sui loop di ogni chunk
|
|
int nLoop = GetLoopCount( i) ;
|
|
for ( int j = 0 ; j < nLoop ; ++ j) {
|
|
// recupero il loop
|
|
ICurve* pLoop = GetMyLoop( i, j) ;
|
|
if ( pLoop == nullptr)
|
|
return false ;
|
|
// ne eseguo l'offset
|
|
OffsetCurve OffsCrv ;
|
|
bool bOk = OffsCrv.Make( pLoop, dDist, nType) ;
|
|
// recupero le curve di offset
|
|
PtrOwner<ICurve> pOffs( OffsCrv.GetLongerCurve()) ;
|
|
while ( bOk && ! IsNull( pOffs)) {
|
|
if ( pOffs->GetType() == CRV_COMPO) {
|
|
CurveComposite* pOffsCompo = GetBasicCurveComposite( pOffs) ;
|
|
// assegno proprietà
|
|
pOffsCompo->SetTempProp( j, 1) ;
|
|
for ( int k = 0 ; k < pOffsCompo->GetCurveCount() ; ++k)
|
|
pOffsCompo->SetCurveTempProp( k, j, 1) ;
|
|
// unisco parti allineate
|
|
if ( ! pOffsCompo->MergeCurves( 10 * EPS_SMALL, ANG_TOL_STD_DEG, true))
|
|
return false ;
|
|
}
|
|
else
|
|
pOffs->SetTempProp( j, 1) ;
|
|
// se prima curva esterna, è il primo contorno esterno della nuova regione
|
|
if ( j == 0 && bFirstCurve) {
|
|
if ( ! pSfrChk->AddExtLoop( Release( pOffs)))
|
|
return false ;
|
|
bFirstCurve = false ;
|
|
}
|
|
// altrimenti aggiungo o sottraggo la regione della curva alla nuova regione
|
|
else if ( ! bFirstCurve) {
|
|
// verifico se loop interno o esterno
|
|
double dArea ;
|
|
if ( ! pOffs->GetAreaXY( dArea))
|
|
return false ;
|
|
bool bExtLoop = ( dArea > 0) ;
|
|
// se loop interno, inverto la curva
|
|
if ( ! bExtLoop)
|
|
pOffs->Invert() ;
|
|
// creo la regione
|
|
PtrOwner<SurfFlatRegion> pSfr2( new( nothrow) SurfFlatRegion) ;
|
|
if ( IsNull( pSfr2) || ! pSfr2->AddExtLoop( Release( pOffs)))
|
|
return false ;
|
|
// se era loop esterno, lo aggiungo alla nuova regione
|
|
if ( bExtLoop) {
|
|
if ( ! pSfrChk->Add( *pSfr2))
|
|
return false ;
|
|
}
|
|
// altrimenti loop interno, lo sottraggo alla nuova regione
|
|
else {
|
|
if ( ! pSfrChk->Subtract( *pSfr2))
|
|
return false ;
|
|
}
|
|
}
|
|
// passo alla successiva
|
|
pOffs.Set( OffsCrv.GetLongerCurve()) ;
|
|
}
|
|
}
|
|
// se regione di chunk valida
|
|
if ( ! bFirstCurve) {
|
|
// se prima regione di chunk, ne sposto i dati nella nuova regione
|
|
if ( bFirstRegion) {
|
|
pSfr->m_vExtInd = pSfrChk->m_vExtInd ;
|
|
pSfr->m_vpLoop = pSfrChk->m_vpLoop ;
|
|
for ( auto& pLoop : pSfrChk->m_vpLoop)
|
|
pLoop = nullptr ;
|
|
pSfr->m_nStatus = pSfrChk->m_nStatus ;
|
|
bFirstRegion = false ;
|
|
}
|
|
// altrimenti la aggiungo alla nuova regione
|
|
else {
|
|
if ( ! pSfr->Add( *pSfrChk))
|
|
return false ;
|
|
}
|
|
}
|
|
}
|
|
|
|
// pulisco la superficie corrente
|
|
for ( auto& pLoop : m_vpLoop)
|
|
delete pLoop ;
|
|
m_vpLoop.clear() ;
|
|
|
|
// sposto i dati della nuova superficie in quella corrente
|
|
m_vExtInd = pSfr->m_vExtInd ;
|
|
m_vpLoop = pSfr->m_vpLoop ;
|
|
for ( auto& pLoop : pSfr->m_vpLoop)
|
|
pLoop = nullptr ;
|
|
m_nStatus = pSfr->m_nStatus ;
|
|
|
|
// imposto ricalcolo della grafica
|
|
ResetAuxSurf() ;
|
|
m_OGrMgr.Reset() ;
|
|
return true ;
|
|
} |