diff --git a/VolZmap.cpp b/VolZmap.cpp index 79780b8..1bdd9cb 100644 --- a/VolZmap.cpp +++ b/VolZmap.cpp @@ -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 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) diff --git a/VolZmap.h b/VolZmap.h index b41d063..6401bd9 100644 --- a/VolZmap.h +++ b/VolZmap.h @@ -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 diff --git a/VolZmapVolume.cpp b/VolZmapVolume.cpp index 13eb9f4..ed4cc26 100644 --- a/VolZmapVolume.cpp +++ b/VolZmapVolume.cpp @@ -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 -------------------------------------------------------------------------------------- //----------------------------------------------------------------------------