EgtGeomKernel :

- aggiunta funzione EraseFins per gli Zmap ( prima versione semplice).
This commit is contained in:
Riccardo Elitropi
2026-03-19 18:45:38 +01:00
parent a2ca0ac6f7
commit 48b2029d19
3 changed files with 166 additions and 0 deletions
+103
View File
@@ -1864,6 +1864,109 @@ VolZmap::MakeUniform( double dToler, bool bIsExtensionFirst, int nToolNum)
return true ;
}
//----------------------------------------------------------------------------
bool
VolZmap::EraseFins( const Vector3d& vtDir, double dThick)
{
// Verifico la Validità dello ZMap
if ( ! IsValid())
return false ;
// Per sicurezza normalizzo la direzione
Vector3d vtMyDir = vtDir ;
if ( ! vtMyDir.Normalize())
return false ;
double dMyThick = max( 10. * EPS_SMALL, dThick) ;
// Creo lo ZMap per i riferimenti degli intervalli sulle griglie
PtrOwner<VolZmap> pZMapCopy( CloneBasicVolZmap( this)) ;
if ( IsNull( pZMapCopy) || ! pZMapCopy->IsValid())
return false ;
// Creo uno ZMap per gli intervalli da aggiungere e successivamente da rimuovere
VolZmap ZMapExtra ;
if ( ! ZMapExtra.CreateEmpty( m_MapFrame.Orig(), m_dMaxZ[1] - m_dMinZ[1], m_dMaxZ[2] - m_dMinZ[2], m_dMaxZ[0] - m_dMinZ[0],
m_dStep, IsTriDexel()))
return false ;
const double FIN_ANG_DEG_TOL = 55. ; // approssimazione per eccesso dell'angolo massimo possibile tra una direzione generica
// e un versore della terna globale ( arccos( 1 / sqrt( 3) ~ 54.375)
const double COS_FIN_ANG_DEG_TOL = cos( FIN_ANG_DEG_TOL * DEGTORAD) ;
// NB. Tutti i parametri sono sempre presi dalla Copia dello ZMap corrente
// Ciclo sulle griglie
for ( int nGrid = 0 ; nGrid < pZMapCopy->m_nMapNum ; ++ nGrid) {
// Verifico se l'angolo tra la direzione degli spilloni della griglia corrente è sotto alla tolleranza riseptto alla direzione
double dCosDir = ( nGrid == 0 ? vtMyDir.z : ( nGrid == 1 ? vtMyDir.x : vtMyDir.y)) ;
if ( abs( dCosDir) < COS_FIN_ANG_DEG_TOL + EPS_ANG_SMALL)
continue ;
// Aggiorno l'effettivo valore dello spessore da considerare
double dCurrThick = dMyThick / abs( dCosDir) ; // sicuramente esiste, essendo 55deg il limite
// Ciclo sul numero di dexel presenti nella Copia
for ( int nDex = 0 ; nDex < ssize( pZMapCopy->m_Values[nGrid]) ; ++ nDex) {
// Se il dexel corrente non ha sotto-intervalli passo al successivo
if ( pZMapCopy->m_Values[nGrid][nDex].empty())
continue ;
// Indici del dexel
int nI = nDex % m_nNx[nGrid] ;
int nJ = nDex / m_nNx[nGrid] ;
// Recupero il numero di intervalli presenti nel Dexel corrente
int nIntervals = ssize( pZMapCopy->m_Values[nGrid][nDex]) ;
// Scorro gli intervalli presenti
for ( int nInfo = 0 ; nInfo < ssize( pZMapCopy->m_Values[nGrid][nDex]) ; ++ nInfo) {
// Recupero l'intervallo corrente
Data& Interval = pZMapCopy->m_Values[nGrid][nDex][nInfo] ;
// Se entrambi gli estremi dell'intervallo non sono stati toccati dall'utensile, allora passo al successivo
bool bAnalyze = ( ( Interval.nToolMin == 1 && Interval.nToolMax == 1) ||
( Interval.dMax > m_dMaxZ[nGrid] - EPS_SMALL || Interval.dMin < m_dMinZ[nGrid] + EPS_SMALL)) ;
if ( ! bAnalyze)
continue ;
// if ( Interval.nToolMin != 1 || Interval.nToolMax != 1)
// continue ;
// Se la lunghezza dell'intervallo è supriore allo spessore richiesto, non faccio nulla
double dLen = Interval.dMax - Interval.dMin ;
if ( dLen > dCurrThick - EPS_SMALL)
continue ;
// Se ZMap composto da una sola griglia, elimino il contributo lungo la direzione corrente
if ( ! IsTriDexel()) {
SubtractIntervals( nGrid, nI, nJ, Interval.dMin - EPS_SMALL, Interval.dMax + EPS_SMALL,
Interval.vtMinN, Interval.vtMaxN, 1, true) ;
}
// Se Tridexel, aggiungo il contributo del cubetto corrente allo ZMap Extra
else
ZMapExtra.AddStripInterval( nGrid, nI, nJ, Interval.dMin - EPS_SMALL, Interval.dMax + EPS_SMALL) ;
}
}
}
// Se non ho aggiunto alcun elemento allo ZMap Extra, non devo fare nulla
if ( ! ZMapExtra.IsValid())
return true ;
// Ciclo sulle griglie dello ZMap Extra
for ( int nGrid = 0 ; nGrid < ZMapExtra.m_nMapNum ; ++ nGrid) {
// Ciclo sul numero di dexel presenti
for ( int nDex = 0 ; nDex < ssize( ZMapExtra.m_Values[nGrid]) ; ++ nDex) {
// Se l'intervallo è vuoto, non faccio nulla
if ( ZMapExtra.m_Values[nGrid][nDex].empty())
continue ;
// Indici del dexel
int nI = nDex % m_nNx[nGrid] ;
int nJ = nDex / m_nNx[nGrid] ;
// Scorro i gli Intervalli dello Spillone corrente
for ( int nInfo = 0 ; nInfo < ssize( ZMapExtra.m_Values[nGrid][nDex]) ; ++ nInfo) {
double dMin = ZMapExtra.m_Values[nGrid][nDex][nInfo].dMin ;
double dMax = ZMapExtra.m_Values[nGrid][nDex][nInfo].dMax ;
Vector3d vtNMin = ZMapExtra.m_Values[nGrid][nDex][nInfo].vtMinN ;
Vector3d vtNMax = ZMapExtra.m_Values[nGrid][nDex][nInfo].vtMaxN ;
// sottraggo tali contributi
SubtractIntervals( nGrid, nI, nJ, dMin, dMax, vtNMin, vtNMax, 1, true) ;
}
}
}
return true ;
}
//----------------------------------------------------------------------------
bool
VolZmap::SetToModifyDexelBlocks( int nGrid, int nDex, int nInt)
+2
View File
@@ -151,6 +151,7 @@ class VolZmap : public IVolZmap, public IGeoObjRW
bool AddSurfTm( const ISurfTriMesh* pStm) override ;
bool SubtractSurfTm( const ISurfTriMesh* pStm) override ;
bool MakeUniform( double dToler, bool bIsExtensionFirst, int nToolNum) override ;
bool EraseFins( const Vector3d& vtDir, double dThick) override ;
bool Offset( double dOffs, int nType) override ;
public : // IGeoObjRW
@@ -262,6 +263,7 @@ class VolZmap : public IVolZmap, public IGeoObjRW
bool UniformIntervalsInVoxel( int nGrid, int nI, int nJ, double dZMin, double dZMax,
double dToler, bool bAdd, int nToolNum, const Vector3d& vtToolMin,
const Vector3d& vtToolMax) ;
bool AddStripInterval( int nGrid, int nI, int nJ, double dZMin, double dZMax) ;
bool ManageSubIntervalInVoxel( VolZmap* VolZmapRef, int nGrid, int nI, int nJ, int nK, double& dMin, double& dMax,
Vector3d& vtMin, Vector3d& vtMax) ;
// Spostamenti utensile
+61
View File
@@ -845,6 +845,67 @@ VolZmap::UniformIntervalsInVoxel( int nGrid, int nI, int nJ, double dZMin,
return true ;
}
//----------------------------------------------------------------------------
bool
VolZmap::AddStripInterval( int nGrid, int nI, int nJ, double dZMin, double dZMax)
{
// Se non Tridex, esco
if ( ! IsTriDexel())
return true ;
// Controllo che il numero di griglia sia entro i limiti
if ( nGrid < 0 || nGrid > 2)
return false ;
// Controllo che indici nI, nJ siano entro i limiti
if ( nI < 0 && nI >= m_nNx[nGrid] && nJ < 0 && nJ >= m_nNy[nGrid])
return false ;
// Numero di voxel contenuti nel dexel corrente ( uguale per ogni dexel di una specifica griglia)
int nVoxNum = int( m_nNy[(( nGrid + 1) % 3)] / m_nDexVoxRatio +
( m_nNy[(( nGrid + 1) % 3)] % m_nDexVoxRatio == 0 ? 1 : 2)) ;
// Scorro i Voxel correnti
for ( int nVox = - 1 ; nVox < nVoxNum - 1 ; ++ nVox) {
// Considero solo i Voxel interni all'intervallo corrente
if ( ( nVox + 1) * m_dStep > dZMin && ( nVox - 1) * m_dStep < dZMax) {
// Recupero gli indici per la griglia successiva
int nMyGrid = ( nGrid + 1) % 3 ;
int nMyI = nJ ;
int nMyJ = nVox ;
int nMyK = nI ;
double dMyMinZ = nMyK * m_dStep ;
double dMyMaxZ = ( nMyK + 1) * m_dStep ;
Vector3d vtMyMaxN = ( nMyGrid == 0 ? m_MapFrame.VersZ() :
nMyGrid == 1 ? m_MapFrame.VersX() :
m_MapFrame.VersY()) ;
Vector3d vtMyMinN = - vtMyMaxN ;
AddIntervals( nMyGrid, nMyI, nMyJ, dMyMinZ - EPS_SMALL, dMyMaxZ + EPS_SMALL, vtMyMinN, vtMyMaxN, 2, true) ;
// Recupero gli indici della griglia precedente
nMyGrid = ( nGrid + 2) % 3 ;
nMyI = nVox ;
nMyJ = nI ;
nMyK = nJ ;
dMyMinZ = nMyK * m_dStep ;
dMyMaxZ = ( nMyK + 1) * m_dStep ;
vtMyMaxN = ( nMyGrid == 0 ? m_MapFrame.VersZ() :
nMyGrid == 1 ? m_MapFrame.VersX() :
m_MapFrame.VersY()) ;
vtMyMinN = - vtMyMaxN ;
AddIntervals( nMyGrid, nMyI, nMyJ, dMyMinZ, dMyMaxZ, vtMyMinN, vtMyMaxN, 2, true) ;
}
}
// Aggiungo l'intervallo corrente
Vector3d vtMyMaxN = ( nGrid == 0 ? m_MapFrame.VersZ() :
nGrid == 1 ? m_MapFrame.VersX() :
m_MapFrame.VersY()) ;
Vector3d vtMyMinN = - vtMyMaxN ;
AddIntervals( nGrid, nI, nJ, dZMin, dZMax, vtMyMaxN, vtMyMinN, 2, true) ;
return true ;
}
// ------------------------- BOUNDING BOX --------------------------------------------------------------------------------------
//----------------------------------------------------------------------------