EgtGeomKernel :

- eliminata la funzione GetZigZagInfill dalla classe SurfFlatRegion ( sostituita da CalcZigZagInfill)
- modifica alle funzioni di Pocketing.
This commit is contained in:
Riccardo Elitropi
2023-11-29 12:04:52 +01:00
parent 4903fcd9d2
commit b1e30147ea
3 changed files with 263 additions and 488 deletions
+263 -239
View File
File diff suppressed because it is too large Load Diff
-248
View File
@@ -1424,254 +1424,6 @@ SurfFlatRegion::GetChunkSimpleClassification( int nChunk, const ISurfFlatRegion&
}
}
//----------------------------------------
bool
SurfFlatRegion::GetZigZagInfill( double dStep, bool bStepCorrection, bool bInvert, ICRVCOMPOPOVECTOR& vpCrvs) const
{
// ingombro della regione
BBox3d b3Pocket ;
GetLocalBBox( b3Pocket) ;
Point3d ptMin ; double dDimX, dDimY, dDimZ ;
b3Pocket.GetMinDim( ptMin, dDimX, dDimY, dDimZ) ;
// lunghezza dei contorni
DBLVECTOR vLen( m_vpLoop.size()) ;
for ( size_t i = 0 ; i < vLen.size() ; i++)
m_vpLoop[i]->GetLength( vLen[i]) ;
// passi in Y
double dYStep = dStep ;
int nYStep = static_cast<int>( floor( dDimY / dStep)) ;
int nRef = 0 ;
if ( bStepCorrection) {
// se permesso, lo modifico per coprire uniformemente la regione
nYStep = static_cast<int>( ceil( ( dDimY - 30 * EPS_SMALL) / dStep)) ;
dYStep = ( nYStep > 0 ? ( dDimY - 30 * EPS_SMALL) / nYStep : 0) ;
nRef = ( ( nYStep + ( bInvert ? 0 : 1)) % 2) ;
}
// tratto valido
struct Section {
bool bActive ;
Point3d ptS ;
Point3d ptE ;
double dOs ;
double dOe ;
size_t nIdxS ; // indice del loop a cui appartiene ptS
size_t nIdxE ; // indice del loop a cui appartiene ptE
} ;
// raccolta di tratti
typedef vector<vector<Section>> VECVECSECT ;
VECVECSECT vvSec ;
vvSec.resize( nYStep + 1) ;
// calcolo le linee di svuotatura
int nCount = 0 ;
for ( int i = 0 ; i <= nYStep ; ++ i) {
// determino senso
bool bPlus = (( i % 2) == nRef) ;
// definisco correzione per essere sicura di poter fare primo e ultimo step
double dCorr = 0 ;
if ( i == 0)
dCorr = 10 * EPS_SMALL ;
else if ( i == nYStep)
dCorr = - 10 * EPS_SMALL ;
// definisco la linea
PtrOwner<CurveLine> pLine( CreateBasicCurveLine()) ;
const double EXP_LEN = 1.0 ;
Point3d ptStart( ptMin.x - EXP_LEN, ptMin.y + dCorr + i * dYStep, ptMin.z + dDimZ) ;
if ( IsNull( pLine) || ! pLine->SetPVL( ptStart, X_AX , dDimX + 2 * EXP_LEN)) {
return false ;
}
// calcolo la classificazione della curva rispetto alla regione
CRVCVECTOR ccClass ;
if ( ! GetCurveClassification( *pLine, EPS_SMALL, ccClass))
return false ;
// determino gli intervalli di curva da conservare
Intervals inOk ;
for ( auto& ccOne : ccClass) {
if ( ccOne.nClass == CRVC_IN || ccOne.nClass == CRVC_ON_P || ccOne.nClass == CRVC_ON_M)
inOk.Add( ccOne.dParS, ccOne.dParE) ;
}
// inserisco i tratti validi (secondo X+ i pari, secondo X- i dispari)
double dParS, dParE ;
bool bFound = ( bPlus ? inOk.GetFirst( dParS, dParE) : inOk.GetLast( dParE, dParS)) ;
while ( bFound) {
// determino i dati della sezione
Section Sect ;
Sect.bActive = true ;
pLine->GetPointD1D2( dParS, ICurve::FROM_PLUS, Sect.ptS) ;
pLine->GetPointD1D2( dParE, ICurve::FROM_MINUS, Sect.ptE) ;
// porto i punti nel riferimento della curva
if ( ! AreSameFrame( m_frF, GLOB_FRM)) {
Sect.ptS.ToLoc( m_frF) ;
Sect.ptE.ToLoc( m_frF) ;
}
// cerco la curva della regione che passa per ptS
bool bCrvFound = false ;
for ( size_t k = 0 ; ! bCrvFound && k < m_vpLoop.size() ; k++) {
bCrvFound = m_vpLoop[k]->GetParamAtPoint( Sect.ptS, Sect.dOs, 10 * EPS_SMALL) ;
if ( bCrvFound)
Sect.nIdxS = k ;
}
if ( ! bCrvFound)
return false ;
// cerco la curva della regione che passa per ptE
bCrvFound = false ;
for ( size_t k = 0 ; ! bCrvFound && k < m_vpLoop.size() ; k++) {
bCrvFound = m_vpLoop[k]->GetParamAtPoint( Sect.ptE, Sect.dOe, 10 * EPS_SMALL) ;
if ( bCrvFound)
Sect.nIdxE = k ;
}
if ( ! bCrvFound)
return false ;
// inserisco nel contenitore
vvSec[i].emplace_back( Sect) ;
++ nCount ;
// recupero intervallo successivo
bFound = ( bPlus ? inOk.GetNext( dParS, dParE) : inOk.GetPrev( dParE, dParS)) ;
}
}
// dominio del contorno
DBLVECTOR vUmax( m_vpLoop.size()) ;
DBLVECTOR vUmin( m_vpLoop.size()) ;
DBLVECTOR vUspan( m_vpLoop.size()) ;
for ( size_t i = 0 ; i < m_vpLoop.size() ; i++) {
m_vpLoop[i]->GetDomain( vUmin[i], vUmax[i]) ;
vUspan[i] = vUmax[i] - vUmin[i] ;
}
// creo i percorsi di svuotatura
vpCrvs.reserve( nCount) ;
int nI = -1, nJ = -1 ;
while ( true) {
// se sezione non valida
if ( nI < 0 || nJ < 0) {
// ricerco la prima valida
for ( int k = 0 ; k < int( vvSec.size()) && nI < 0 ; ++ k) {
for ( int l = 0 ; l < int( vvSec[k].size()) && nJ < 0 ; ++ l) {
if ( vvSec[k][l].bActive) {
nI = k ;
nJ = l ;
}
}
}
// se trovata, creo nuova curva composita
if ( nI >= 0 && nJ >= 0) {
// creo la curva
vpCrvs.emplace_back( CreateCurveComposite()) ;
// aggiungo punto iniziale
vpCrvs.back()->AddPoint( vvSec[nI][nJ].ptS) ;
}
// altrimenti, esco
else
break ;
}
// determino senso
bool bPlus = (( nI % 2) == nRef) ;
// aggiungo la sezione alla curva
Section& Sec = vvSec[nI][nJ] ;
Sec.bActive = false ;
vpCrvs.back()->AddLine( vvSec[nI][nJ].ptE) ;
// cerco nella stessa fila o in quella successiva sezione successiva raccordabile tramite il contorno
double dUstart = Sec.dOe ;
double dUref = ( bPlus ? INFINITO : - INFINITO) ;
int nNextI = -1 ;
int nNextJ = -1 ;
int li = nJ + 1 ;
for ( int k = nI ; k <= nI + 1 && k < int( vvSec.size()) ; ++ k) {
for ( int l = li ; l < int( vvSec[k].size()) ; ++ l) {
if ( ! vvSec[k][l].bActive)
continue ;
// la nuova sezione deve partire dalla stessa curva su cui ci si è fermati
if ( vvSec[k][l].nIdxS != Sec.nIdxE)
continue ;
double dU = vvSec[k][l].dOs ;
if ( bPlus) {
if ( dU < dUstart)
dU += vUspan[Sec.nIdxE] ;
if ( dU < dUref) {
dUref = dU ;
nNextI = k ;
nNextJ = l ;
}
}
else {
if ( dU > dUstart)
dU -= vUspan[Sec.nIdxE] ;
if ( dU > dUref) {
dUref = dU ;
nNextI = k ;
nNextJ = l ;
}
}
}
li = 0 ;
}
// se trovato, aggiungo il tratto di contorno e continuo
if ( nNextI != -1) {
PtrOwner<ICurve> pCopy ;
size_t idx = vvSec[nNextI][nNextJ].nIdxS ;
if ( bPlus) {
if ( dUref > vUmax[idx])
dUref -= vUspan[idx] ;
pCopy.Set( m_vpLoop[idx]->CopyParamRange( dUstart, dUref)) ;
if ( ! IsNull( pCopy)) {
double dCLen ; pCopy->GetLength( dCLen) ;
if ( dCLen > 0.5 * vLen[idx]) {
pCopy.Set( m_vpLoop[idx]->CopyParamRange( dUref, dUstart)) ;
if ( ! IsNull( pCopy))
pCopy->Invert() ;
}
}
}
else {
if ( dUref < vUmin[idx])
dUref += vUspan[idx] ;
pCopy.Set( m_vpLoop[idx]->CopyParamRange( dUref, dUstart)) ;
if ( ! IsNull( pCopy)) {
pCopy->Invert() ;
double dCLen ; pCopy->GetLength( dCLen) ;
if ( dCLen > 0.5 * vLen[idx])
pCopy.Set( m_vpLoop[idx]->CopyParamRange( dUstart, dUref)) ;
}
}
BBox3d b3Copy ;
if ( ! IsNull( pCopy))
pCopy->GetBBox( m_frF, b3Copy) ;
if ( ! b3Copy.IsEmpty() && ( b3Copy.GetMax().y - b3Copy.GetMin().y) < dYStep + 10 * EPS_SMALL) {
vpCrvs.back()->AddCurve( Release( pCopy)) ;
nI = nNextI ;
nJ = nNextJ ;
}
else {
nI = -1 ;
nJ = -1 ;
}
}
else {
nI = -1 ;
nJ = -1 ;
}
}
// porto le curve calcolate nel riferimento globale
if ( ! AreSameFrame( m_frF, GLOB_FRM)) {
for ( int i = 0 ; i < ( int) vpCrvs.size() ; i++)
vpCrvs[i]->ToGlob( m_frF) ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
SurfFlatRegion::CalcVoronoiObject() const
-1
View File
@@ -101,7 +101,6 @@ class SurfFlatRegion : public ISurfFlatRegion, public IGeoObjRW
bool GetChunkCentroid( int nChunk, Point3d& ptCen) const override ;
bool GetCurveClassification( const ICurve& Crv, double dLenMin, CRVCVECTOR& ccClass) const override ;
int GetChunkSimpleClassification( int nChunk, const ISurfFlatRegion& Other, int nOthChunk) const override ; // compare only outsides
bool GetZigZagInfill( double dStep, bool bStepCorrection, bool bInvert, ICRVCOMPOPOVECTOR& vpCrvs) const override ;
Voronoi* GetVoronoiObject( void) const override ;
bool CalcVoronoiDiagram( ICURVEPOVECTOR& vCrvs, int nBound = VORONOI_STD_BOUND) const override ;
bool CalcMedialAxis( ICURVEPOVECTOR& vCrvs, int nSide) const override ;