From 39d295f41250896ec2880533089e62146eda4c08 Mon Sep 17 00:00:00 2001 From: Riccardo Elitropi Date: Thu, 9 Oct 2025 09:50:07 +0200 Subject: [PATCH] EgtGeomKernel : - Migliorata e Corretta la funzione MakeUniform per VolZMap. --- VolZmap.cpp | 326 +++++++++++++++++++++++++++++----------------- VolZmap.h | 11 +- VolZmapVolume.cpp | 257 +++++++++++++++++++----------------- 3 files changed, 351 insertions(+), 243 deletions(-) diff --git a/VolZmap.cpp b/VolZmap.cpp index 03731c7..4f105f2 100644 --- a/VolZmap.cpp +++ b/VolZmap.cpp @@ -1,4 +1,4 @@ -//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- // EgalTech 2015-2016 //---------------------------------------------------------------------------- // File : VolZmap.cpp Data : 22.01.15 Versione : 1.6a4 @@ -563,10 +563,10 @@ VolZmap::GetPartLocalBBox( int nPart, BBox3d& b3Loc, int nFlag) const // Verifico lo stato. if ( m_nStatus != OK) return false ; - // Se una sola mappa o il numero di componenti è indefinito, vi è un errore. + // Se una sola mappa o il numero di componenti è indefinito, vi è un errore. if ( m_nMapNum == 1 || m_nConnectedCompoCount == - 1) return false ; - // Se la componente richiesta non esiste, vi è un errore. + // Se la componente richiesta non esiste, vi è un errore. if ( nPart < 0 || nPart > m_nConnectedCompoCount - 1) return false ; // Calcolo Bounding-box @@ -614,10 +614,10 @@ VolZmap::GetPartBBox( int nPart, const Frame3d& frRef, BBox3d& b3Ref, int nFlag) // Verifico lo stato. if ( m_nStatus != OK) return false ; - // Se una sola mappa o il numero di componenti è indefinito, vi è un errore. + // Se una sola mappa o il numero di componenti è indefinito, vi è un errore. if ( m_nMapNum == 1 || m_nConnectedCompoCount == - 1) return false ; - // Se la componente richiesta non esiste, vi è un errore. + // Se la componente richiesta non esiste, vi è un errore. if ( nPart < 0 || nPart > m_nConnectedCompoCount - 1) return false ; // Calcolo Bounding-box @@ -689,7 +689,7 @@ VolZmap::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, doub // verifico lo stato if ( m_nStatus != OK) return false ; - // verifico validità dell'asse di rotazione + // verifico validità dell'asse di rotazione if ( vtAx.IsSmall()) return false ; @@ -722,7 +722,7 @@ VolZmap::Mirror( const Point3d& ptOn, const Vector3d& vtNorm) // verifico lo stato if ( m_nStatus != OK) return false ; - // verifico validità del piano di specchiatura + // verifico validità del piano di specchiatura if ( vtNorm.IsSmall()) return false ; @@ -736,7 +736,7 @@ VolZmap::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& vtD // verifico lo stato if ( m_nStatus != OK) return false ; - // verifico validità dei parametri + // verifico validità dei parametri if ( vtNorm.IsSmall() || vtDir.IsSmall()) return false ; @@ -750,11 +750,11 @@ VolZmap::ToGlob( const Frame3d& frRef) // verifico lo stato if ( m_nStatus != OK) return false ; - // verifico validità del frame + // verifico validità del frame if ( frRef.GetType() == Frame3d::ERR) return false ; - // se frame identità, non devo fare alcunché + // se frame identità, non devo fare alcunché if ( IsGlobFrame( frRef)) return true ; @@ -773,11 +773,11 @@ VolZmap::ToLoc( const Frame3d& frRef) // verifico lo stato if ( m_nStatus != OK) return false ; - // verifico validità del frame + // verifico validità del frame if ( frRef.GetType() == Frame3d::ERR) return false ; - // se frame identità, non devo fare alcunché + // se frame identità, non devo fare alcunché if ( IsGlobFrame( frRef)) return true ; @@ -796,11 +796,11 @@ VolZmap::LocToLoc( const Frame3d& frOri, const Frame3d& frDest) // verifico lo stato if ( m_nStatus != OK) return false ; - // verifico validità dei frame + // verifico validità dei frame if ( frOri.GetType() == Frame3d::ERR || frDest.GetType() == Frame3d::ERR) return false ; - // se i due riferimenti coincidono, non devo fare alcunché + // se i due riferimenti coincidono, non devo fare alcunché if ( AreSameFrame( frOri, frDest)) return true ; @@ -816,10 +816,10 @@ VolZmap::LocToLoc( const Frame3d& frOri, const Frame3d& frDest) int VolZmap::GetPartCount( void) const { - // Se mono-dexel la connessione è incalcolabile. + // Se mono-dexel la connessione è incalcolabile. if ( m_nMapNum == 1) return - 1 ; - // Se il numero delle componenti è indefinito + // Se il numero delle componenti è indefinito // lo ricalcolo e restituisco il risultato. if ( m_nConnectedCompoCount == - 1) { const_cast(this)->CheckMapConnection() ; @@ -870,7 +870,7 @@ VolZmap::CheckMapConnection( void) IntervalsToProcessStackVec.resize( nThreadMax) ; // Mi espando dal primo intervallo mettendo gli intervalli che intersecano nei vari thread FirstExpansionFromZ( nThreadMax, NewInt, IntervalsToProcessStackVec) ; - // Lancio in parallelo più ricerche + // Lancio in parallelo più ricerche int nActiveThread = 0 ; vector> vRes ; vRes.resize( nThreadMax) ; @@ -891,7 +891,7 @@ VolZmap::CheckMapConnection( void) } } } - // Se l'intervallo non attraversa un nodo o ha già + // Se l'intervallo non attraversa un nodo o ha già // un indice assegnato salto questa iterazione. else continue ; @@ -935,7 +935,7 @@ VolZmap::ExpandFromXInterval( IntContainer& IntCont) double dZmin = m_Values[0][tGrIndex1 * m_nNx[0] + tI][tIntZ].dMin ; double dZmax = m_Values[0][tGrIndex1 * m_nNx[0] + tI][tIntZ].dMax ; // Se i segmenti si incrociano e il nuovo trovato non - // ha già un indice assegnato, assegno l'indice e + // ha già un indice assegnato, assegno l'indice e // aggiungo l'intervallo trovato allo stack. if ( dZmin - 2 * EPS_SMALL < dZ && dZmax + 2 * EPS_SMALL > dZ && @@ -955,7 +955,7 @@ VolZmap::ExpandFromXInterval( IntContainer& IntCont) double dYmin = m_Values[2][tI * m_nNx[2] + tGrIndex2][tIntY].dMin ; double dYmax = m_Values[2][tI * m_nNx[2] + tGrIndex2][tIntY].dMax ; // Se i segmenti si incrociano e il nuovo trovato non - // ha già un indice assegnato, assegno l'indice e + // ha già un indice assegnato, assegno l'indice e // aggiungo l'intervallo trovato allo stack. if ( dYmin - 2 * EPS_SMALL < dY && dYmax + 2 * EPS_SMALL > dY && @@ -1006,7 +1006,7 @@ VolZmap::ExpandFromYInterval( IntContainer& IntCont) double dZmin = m_Values[0][tJ * m_nNx[0] + tGrIndex2][tIntZ].dMin ; double dZmax = m_Values[0][tJ * m_nNx[0] + tGrIndex2][tIntZ].dMax ; // Se i segmenti si incrociano e il nuovo trovato non - // ha già un indice assegnato, assegno l'indice e + // ha già un indice assegnato, assegno l'indice e // aggiungo l'intervallo trovato allo stack. if ( dZmin - 2 * EPS_SMALL < dZ && dZmax + 2 * EPS_SMALL > dZ && @@ -1026,7 +1026,7 @@ VolZmap::ExpandFromYInterval( IntContainer& IntCont) double dXmin = m_Values[1][tGrIndex1 * m_nNx[1] + tJ][tIntX].dMin ; double dXmax = m_Values[1][tGrIndex1 * m_nNx[1] + tJ][tIntX].dMax ; // Se i segmenti si incrociano e il nuovo trovato non - // ha già un indice assegnato, assegno l'indice e + // ha già un indice assegnato, assegno l'indice e // aggiungo l'intervallo trovato allo stack. if ( dXmin - 2 * EPS_SMALL < dX && dXmax + 2 * EPS_SMALL > dX && @@ -1077,7 +1077,7 @@ VolZmap::ExpandFromZInterval( IntContainer& IntCont) double dXmin = m_Values[1][tK * m_nNx[1] + tGrIndex2][tIntX].dMin ; double dXmax = m_Values[1][tK * m_nNx[1] + tGrIndex2][tIntX].dMax ; // Se i segmenti si incrociano e il nuovo trovato non - // ha già un indice assegnato, assegno l'indice e + // ha già un indice assegnato, assegno l'indice e // aggiungo l'intervallo trovato allo stack. if ( dXmin - 2 * EPS_SMALL < dX && dXmax + 2 * EPS_SMALL > dX && @@ -1097,7 +1097,7 @@ VolZmap::ExpandFromZInterval( IntContainer& IntCont) double dYmin = m_Values[2][tGrIndex1 * m_nNx[2] + tK][tIntY].dMin ; double dYmax = m_Values[2][tGrIndex1 * m_nNx[2] + tK][tIntY].dMax ; // Se i segmenti si incrociano e il nuovo trovato non - // ha già un indice assegnato, assegno l'indice e + // ha già un indice assegnato, assegno l'indice e // aggiungo l'intervallo trovato allo stack. if ( dYmin - 2 * EPS_SMALL < dY && dYmax + 2 * EPS_SMALL > dY && @@ -1146,7 +1146,7 @@ VolZmap::FirstExpansionFromZ( int nNumThread, IntervalIndexes IntSt, IntContaine double dXmin = m_Values[1][tK * m_nNx[1] + tGrIndex2][tIntX].dMin ; double dXmax = m_Values[1][tK * m_nNx[1] + tGrIndex2][tIntX].dMax ; // Se i segmenti si incrociano e il nuovo trovato non - // ha già un indice assegnato, assegno l'indice e + // ha già un indice assegnato, assegno l'indice e // aggiungo l'intervallo trovato allo stack. if ( dXmin - 2 * EPS_SMALL < dX && dXmax + 2 * EPS_SMALL > dX && @@ -1167,7 +1167,7 @@ VolZmap::FirstExpansionFromZ( int nNumThread, IntervalIndexes IntSt, IntContaine double dYmin = m_Values[2][tGrIndex1 * m_nNx[2] + tK][tIntY].dMin ; double dYmax = m_Values[2][tGrIndex1 * m_nNx[2] + tK][tIntY].dMax ; // Se i segmenti si incrociano e il nuovo trovato non - // ha già un indice assegnato, assegno l'indice e + // ha già un indice assegnato, assegno l'indice e // aggiungo l'intervallo trovato allo stack. if ( dYmin - 2 * EPS_SMALL < dY && dYmax + 2 * EPS_SMALL > dY && @@ -1214,13 +1214,13 @@ VolZmap::ClonePart( int nPart) const // verifico lo stato if ( m_nStatus != OK) return nullptr ; - // Se è definita una sola griglia non sono definibili le parti, errore + // Se è definita una sola griglia non sono definibili le parti, errore if ( m_nMapNum == 1) return nullptr ; - // Se è richiesta una componente fuori intervallo, errore + // Se è richiesta una componente fuori intervallo, errore if ( nPart < 0 || nPart >= m_nConnectedCompoCount) return nullptr ; - // Se il numero di componenti è indefinito, lo ricalcolo. + // Se il numero di componenti è indefinito, lo ricalcolo. if ( m_nConnectedCompoCount == - 1) const_cast(this)->CheckMapConnection() ; // Se non vi sono componenti, errore @@ -1291,7 +1291,7 @@ VolZmap::ClonePart( int nPart) const pVolume->m_Values[nMap].resize( pVolume->m_nDim[nMap]) ; } - // Se almeno una griglia è nulla, non ha senso Zmap + // Se almeno una griglia è nulla, non ha senso Zmap if ( pVolume->m_nDim[0] == 0 || pVolume->m_nDim[1] == 0 || pVolume->m_nDim[2] == 0) @@ -1343,8 +1343,8 @@ VolZmap::ClonePart( int nPart) const dNewOy = nMinIndJ[0] * m_dStep ; dNewOz = nMinIndJ[1] * m_dStep ; - // Porto i dexel nel nuovo sistema di riferimento e le quote estreme Z. Non c'è bisogno di trasformare le normali, - // infatti i sistemi di riferimento in gioco differiscono al più per una traslazione. + // Porto i dexel nel nuovo sistema di riferimento e le quote estreme Z. Non c'è bisogno di trasformare le normali, + // infatti i sistemi di riferimento in gioco differiscono al più per una traslazione. for ( int nMap = 0 ; nMap < int( m_nMapNum) ; ++ nMap) { // Quote estreme Z switch ( nMap) { @@ -1407,10 +1407,10 @@ VolZmap::RemovePart( int nPart) // verifico lo stato if ( m_nStatus != OK) return false ; - // Se è definita una sola griglia non sono definibili le parti, errore + // Se è definita una sola griglia non sono definibili le parti, errore if ( m_nMapNum == 1) return false ; - // Se il numero di componenti è indefinito, lo ricalcolo + // Se il numero di componenti è indefinito, lo ricalcolo if ( m_nConnectedCompoCount == - 1) CheckMapConnection() ; // Se non vi sono componenti, abbiamo finito @@ -1452,7 +1452,7 @@ VolZmap::GetPartMinDistFromPoint( const Point3d& ptP) const // Verifico lo stato e che siano definibili le componenti connesse if ( m_nStatus != OK || m_nMapNum == 1) return - 1 ; - // Se il numero di componenti è indefinito, lo ricalcolo + // Se il numero di componenti è indefinito, lo ricalcolo if ( m_nConnectedCompoCount == -1) const_cast( this)->CheckMapConnection() ; // Se non vi sono componenti, abbiamo finito @@ -1485,7 +1485,7 @@ VolZmap::GetPartMinDistFromPoint( const Point3d& ptP) const swap( ptEn.y, ptEn.z) ; swap( ptEn.x, ptEn.z) ; } - // Calcolo la distanza del punto dal segmento corrente. Se è minore della minima distanza aggiorno quest'ultima + // Calcolo la distanza del punto dal segmento corrente. Se è minore della minima distanza aggiorno quest'ultima // e la corrispondente componente connessa di minima distanza con la distanza e la componente connessa correnti. double dDist ; DistPointLine DistCalc( ptPL, ptSt, ptEn) ; @@ -1677,107 +1677,197 @@ VolZmap::SubtractSurfTm( const ISurfTriMesh* pStm) //---------------------------------------------------------------------------- bool -VolZmap::MakeUniform( double dToler) +VolZmap::MakeUniform( double dToler, bool bIsExtensionFirst, int nToolNum) { - // controllo validità dello Zmap + // Controllo validità dello Zmap if ( ! IsValid()) return false ; - // la tolleranza deve essere minore dello step - dToler = min( dToler, 0.95 * m_dStep) ; - // creo lo Zmpa che andrà a sostituire il corrente - PtrOwner pOldVolZmap( CloneBasicVolZmap( this)) ; - if ( IsNull( pOldVolZmap)) + // creo lo ZMap per i riferimenti degli intervalli sulle griglie + PtrOwner pZMapCopy( CloneBasicVolZmap( this)) ; + if ( IsNull( pZMapCopy) || ! pZMapCopy->IsValid()) return false ; - // ciclo sulle griglie - for ( int nGrid = 0 ; nGrid < m_nMapNum ; ++ nGrid) { - // salvo lo Zmap prima di modificare gli spilloni - PtrOwner pVolZMapCurrGrid( CloneBasicVolZmap( this)) ; - if ( IsNull( pVolZMapCurrGrid)) + // creo uno ZMap per gli intervalli da aggiungere o da rimuovere + PtrOwner pZMapExtra( CreateBasicVolZmap()) ; + if ( IsNull( pZMapExtra) || + ! pZMapExtra->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 ; - // ciclo sul numero di dexel presenti - for ( int nDex = 0 ; nDex < int( m_Values[nGrid].size()) ; ++ nDex) { - // se il dexel corrente non ha sotto-intervalli passo al successivo - if ( int( m_Values[nGrid][nDex].size()) == 0) + + // Dovendo effettuare estensioni, allargo gli ingobri nelle direzioni principali + m_dMinZ[0] -= dToler ; + m_dMinZ[1] -= dToler ; + m_dMinZ[2] -= dToler ; + m_dMaxZ[0] += dToler ; + m_dMaxZ[1] += dToler ; + m_dMaxZ[2] += dToler ; + + // NB. Tutti i parametri sono sempre presi dalla Copia dello ZMap corrente + // Ciclo sulle griglie + for ( int nGrid = 0 ; nGrid < pZMapCopy->m_nMapNum ; ++ nGrid) { + // Ciclo sul numero di dexel presenti nella Copia + for ( int nDex = 0 ; nDex < int( pZMapCopy->m_Values[nGrid].size()) ; ++ nDex) { + // Se il dexel corrente non ha sotto-intervalli passo al successivo + if ( pZMapCopy->m_Values[nGrid][nDex].empty()) continue ; - // indici del dexel + // Indici del dexel int nI = nDex % m_nNx[nGrid] ; int nJ = nDex / m_nNx[nGrid] ; - // salvo le informazioni dei sotto-intervalli del dexel corrente - vector vInfo ; - for ( int nExtr = 0 ; nExtr < int( m_Values[nGrid][nDex].size()) ; ++ nExtr) - vInfo.push_back( m_Values[nGrid][nDex][nExtr]) ; - // per ogni sotto-intervallo, estendo a destra e a sinistra della tolleranza - int nSub_intervals = int( vInfo.size()) ; - // scorro gli intervalli - for ( int nInfo = 0 ; nInfo < int( pVolZMapCurrGrid->m_Values[nGrid][nDex].size()) ; ++ nInfo) { - // estremo inferiore - if ( vInfo[nInfo].dMin - dToler > m_dMinZ[nGrid]) { - AddIntervals( nGrid, nI, nJ, - vInfo[nInfo].dMin - dToler, - vInfo[nInfo].dMin + dToler, - vInfo[nInfo].vtMinN, vInfo[nInfo].vtMinN, vInfo[nInfo].nToolMin, - true) ; - // se si sono uniti degli intervalli, potrei dover aggiungere degli spilloni nelle altre due - // direzioni nel voxel corrispondente - if ( IsTriDexel() && dToler > 0.5 * m_dStep - EPS_SMALL && - nSub_intervals != int( m_Values[nGrid][nDex].size())) { - nSub_intervals = int( m_Values[nGrid][nDex].size()) ; // aggiorno gli intervalli correnti - // l'intervallo corrente si è unito con il precedente... - AddMissingIntervalsInVoxel( pOldVolZmap, nGrid, nI, nJ, vInfo[nInfo].dMin, dToler, - vInfo[nInfo].vtMinN, vInfo[nInfo].vtMinN, - vInfo[nInfo].nToolMin) ; + // Recupero il numero di intervalli presenti nel Dexel corrente + int nIntervals = int( pZMapCopy->m_Values[nGrid][nDex].size()) ; + // Scorro gli intervalli presenti + for ( int nInfo = 0 ; nInfo < int( pZMapCopy->m_Values[nGrid][nDex].size()) ; ++ nInfo) { + // Recupero l'intervallo corrente + Data& Interval = pZMapCopy->m_Values[nGrid][nDex][nInfo] ; + // --- Se richiesta prima estensione + if ( bIsExtensionFirst) { + // *** Estremo inferiore -> Intervallo : [ dMin - dToler, dMin + dToler ] + // Aggiungo l'intervallo nello Zmap corrente ( lascio invariato lo ZMapCopy) + AddIntervals( nGrid, nI, nJ, Interval.dMin - dToler, Interval.dMin + dToler, + Interval.vtMinN, Interval.vtMinN, nToolNum, true) ; + // Se si sono uniti degli intervalli, potrei dover aggiungere degli spilloni nelle altre due direzioni + if ( IsTriDexel() && nIntervals != int( m_Values[nGrid][nDex].size())) { + // Aggiorno gli intervalli correnti ( dato che il corrente si è unito al precedente) + // ( lascio invariato lo ZMapCopy) + nIntervals = int( m_Values[nGrid][nDex].size()) ; + pZMapExtra->UniformIntervalsInVoxel( nGrid, nI, nJ, + pZMapCopy->m_Values[nGrid][nDex][nInfo-1].dMax, + Interval.dMin, dToler, true, + nToolNum, V_INVALID, V_INVALID) ; + } + // *** Estremo superiore -> Intervallo : [ dMax - dToler, dMax + dToler ] + // Aggiungo l'intervallo nello Zmap corrente ( lascio invariato lo ZMapCopy) + AddIntervals( nGrid, nI, nJ, Interval.dMax - dToler, Interval.dMax + dToler, + Interval.vtMaxN, Interval.vtMaxN, nToolNum, true) ; + // Se si sono uniti degli intervalli, potrei dover aggiungere degli spilloni nelle altre due direzioni + if ( IsTriDexel() && nIntervals != int( m_Values[nGrid][nDex].size())) { + // Aggiorno gli intervalli correnti ( dato che il corrente si è unito al successivo) + // ( lascio invariato lo ZMapCopy) + nIntervals = int( m_Values[nGrid][nDex].size()) ; + pZMapExtra->UniformIntervalsInVoxel( nGrid, nI, nJ, + Interval.dMax, + pZMapCopy->m_Values[nGrid][nDex][nInfo+1].dMin, dToler, true, + nToolNum, V_INVALID, V_INVALID) ; } } - // estremo superiore - if ( vInfo[nInfo].dMax + dToler < m_dMaxZ[nGrid]) { - AddIntervals( nGrid, nI, nJ, - vInfo[nInfo].dMax - dToler, - vInfo[nInfo].dMax + dToler, - vInfo[nInfo].vtMaxN, vInfo[nInfo].vtMaxN, vInfo[nInfo].nToolMax, - true) ; - if ( IsTriDexel() && dToler > 0.5 * m_dStep - EPS_SMALL && - nSub_intervals != int( m_Values[nGrid][nDex].size())) { - nSub_intervals = int( m_Values[nGrid][nDex].size()) ; // aggiorno gli intervalli correnti - AddMissingIntervalsInVoxel( pOldVolZmap, nGrid, nI, nJ, vInfo[nInfo].dMax, dToler, - vInfo[nInfo].vtMaxN, vInfo[nInfo].vtMaxN, - vInfo[nInfo].nToolMax) ; + // --- Se richiesta prima restrizione + else { + // *** Estremo inferiore -> Intervallo : [ dMin - dToler, dMin + dToler ] + // Sottraggo l'intervallo nello Zmap corrente ( lascio invariato lo ZMapCopy) + SubtractIntervals( nGrid, nI, nJ, Interval.dMin - dToler, Interval.dMin + dToler, + Interval.vtMinN, Interval.vtMinN, nToolNum, true) ; + // Se l'intervallo si è annullato, potrei dover sottrarre degli spilloni nelle altre due direzioni + if ( IsTriDexel() && nIntervals != int( m_Values[nGrid][nDex].size())) { + // Aggiorno gli intervalli correnti ( lascio invariato lo ZMapCopy) + nIntervals = int( m_Values[nGrid][nDex].size()) ; + pZMapExtra->UniformIntervalsInVoxel( nGrid, nI, nJ, + Interval.dMin, + Interval.dMax, dToler, true, + Tool::UNDEF, V_INVALID, V_INVALID) ; + } + // *** Estremo superiore -> Intervallo : [ dMax - dToler, dMax + dToler ] + // Sottraggo l'intervallo nello Zmap corrente ( lascio invariato lo ZMapCopy) + SubtractIntervals( nGrid, nI, nJ, Interval.dMax - dToler, Interval.dMax + dToler, + Interval.vtMaxN, Interval.vtMaxN, nToolNum, true) ; + // Se l'intervallo si è annullato, potrei dover sottrarre degli spilloni nelle altre due direzioni + if ( IsTriDexel() && nIntervals != int( m_Values[nGrid][nDex].size())) { + // Aggiorno gli intervalli correnti ( lascio invariato lo ZMapCopy) + nIntervals = int( m_Values[nGrid][nDex].size()) ; + pZMapExtra->UniformIntervalsInVoxel( nGrid, nI, nJ, + Interval.dMin, + Interval.dMax, dToler, true, + Tool::UNDEF, V_INVALID, V_INVALID) ; } - } - } - // per ogni sotto-intervallo ricavato fino ad ora, restringo della tolleranza - // ( NB. avendo aggiunto intervalli, il dexel può modificare la sua struttura interna ) - for ( int nInfo = 0 ; nInfo < int( m_Values[nGrid][nDex].size()) ; ++ nInfo) { - // ( NB. la rimozione di un intervallo ora va definita per intervalli a destra e a sinistra, - // altrimenti rimuovo parti in eccesso ) - if ( ! pVolZMapCurrGrid->m_Values[nGrid][nDex].empty()) { - if ( nInfo != 0 || - pVolZMapCurrGrid->m_Values[nGrid][nDex][0].dMin - dToler > m_dMinZ[nGrid]) - m_Values[nGrid][nDex][nInfo].dMin += dToler ; - if ( nInfo != int( m_Values[nGrid][nDex].size()) - 1 || - pVolZMapCurrGrid->m_Values[nGrid][nDex].back().dMax + dToler < m_dMaxZ[nGrid]) - m_Values[nGrid][nDex][nInfo].dMax -= dToler ; } } } } + // Ciclo sulle griglie ( uso lo Zmap Corrente, lascio invariato pZMapCopy) + for ( int nGrid = 0 ; nGrid < m_nMapNum ; ++ nGrid) { + // Ciclo sul numero di dexel presenti + for ( int nDex = 0 ; nDex < int( m_Values[nGrid].size()) ; ++ nDex) { + // Se l'intervallo è vuoto, non faccio nulla + if ( m_Values[nGrid][nDex].empty()) + continue ; + // Per ogni intervallo ricavato fino ad ora, restringo della tolleranza + for ( int nInfo = 0 ; nInfo < int( m_Values[nGrid][nDex].size()) ; ++ nInfo) { + // --- Se richiesta prima estensione + if ( bIsExtensionFirst) { + m_Values[nGrid][nDex][nInfo].dMin += dToler ; + m_Values[nGrid][nDex][nInfo].dMax -= dToler ; + } + // --- Se richiesta prima restrizione + else { + m_Values[nGrid][nDex][nInfo].dMin -= dToler ; + m_Values[nGrid][nDex][nInfo].dMax += dToler ; + } + // Definisco il colore + for ( int nOrigInfo = 0 ; nOrigInfo < int( pZMapCopy->m_Values[nGrid][nDex].size()) ; ++ nOrigInfo) { + if ( pZMapCopy->m_Values[nGrid][nDex][nOrigInfo].dMin - m_Values[nGrid][nDex][nInfo].dMin < EPS_SMALL) + m_Values[nGrid][nDex][nInfo].nToolMin = pZMapCopy->m_Values[nGrid][nDex][nOrigInfo].nToolMin ; + if ( pZMapCopy->m_Values[nGrid][nDex][nOrigInfo].dMax - m_Values[nGrid][nDex][nInfo].dMax < EPS_SMALL) + m_Values[nGrid][nDex][nInfo].nToolMax = pZMapCopy->m_Values[nGrid][nDex][nOrigInfo].nToolMax ; + } + } + } + } + + // Gestisco le parti Extra ricavate + // Ciclo sulle griglie ( uso lo ZmapExtra, lascio invariato pZMapCopy) + for ( int nGrid = 0 ; nGrid < pZMapExtra->m_nMapNum ; ++ nGrid) { + // Ciclo sul numero di dexel presenti + for ( int nDex = 0 ; nDex < int( pZMapExtra->m_Values[nGrid].size()) ; ++ nDex) { + // Se l'intervallo è vuoto, non faccio nulla + if ( pZMapExtra->m_Values[nGrid][nDex].empty()) + continue ; + // Indici del dexel + int nI = nDex % m_nNx[nGrid] ; + int nJ = nDex / m_nNx[nGrid] ; + // Per ogni intervallo ricavato fino ad ora... + for ( int nInfo = 0 ; nInfo < int( pZMapExtra->m_Values[nGrid][nDex].size()) ; ++ nInfo) { + double dMin = pZMapExtra->m_Values[nGrid][nDex][nInfo].dMin ; + double dMax = pZMapExtra->m_Values[nGrid][nDex][nInfo].dMax ; + Vector3d vtNMin = pZMapExtra->m_Values[nGrid][nDex][nInfo].vtMinN ; + Vector3d vtNMax = pZMapExtra->m_Values[nGrid][nDex][nInfo].vtMaxN ; + // --- Se richiesta prima estensione + if ( bIsExtensionFirst) { + // ... aggiungo i contributi + AddIntervals( nGrid, nI, nJ, dMin, dMax, vtNMin, vtNMax, nToolNum, true) ; + } + // --- Se richiesta prima restrizione + else { + // ... sottraggo i contributi + SubtractIntervals( nGrid, nI, nJ, dMin, dMax, vtNMin, vtNMax, nToolNum, true) ; + } + } + } + } + + // Restringo gli ingombri espensi in precedenza + m_dMinZ[0] += dToler ; + m_dMinZ[1] += dToler ; + m_dMinZ[2] += dToler ; + m_dMaxZ[0] -= dToler ; + m_dMaxZ[1] -= dToler ; + m_dMaxZ[2] -= dToler ; + return true ; } - //---------------------------------------------------------------------------- bool VolZmap::SetToModifyDexelBlocks( int nGrid, int nDex, int nInt) { - // Controllo sulla validità della griglia + // Controllo sulla validità della griglia if ( nGrid < 0 || nGrid > 2) return false ; - // Controllo sulla validità del dexel + // Controllo sulla validità del dexel if ( nDex <= - 1 || nDex >= int( m_Values[nGrid].size())) return false ; - // Controllo sulla validità dell'intervallo + // Controllo sulla validità dell'intervallo if ( nInt <= - 1 || nInt >= int( m_Values[nGrid][nDex].size())) return false ; @@ -1957,7 +2047,7 @@ VolZmap::IsMapPartABox( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, do bool VolZmap::IsBox( void) { - // Se non tridexel, non posso stabilire con il metodo seguente se è un box + // Se non tridexel, non posso stabilire con il metodo seguente se è un box // Verifico solo che gli spilloni di una mappa o sono nulli o hanno gli stessi estremi if ( m_nMapNum == 1) return false ; @@ -1976,7 +2066,7 @@ VolZmap::IsBox( void) return true ; } - // Caso di più thread + // Caso di più thread m_bIsBox = true ; for ( int nMap = 0 ; nMap < m_nMapNum ; ++ nMap) { vector< future> vRes ; @@ -2021,7 +2111,7 @@ VolZmap::IsBox( void) } } } - // Se uno dei thread trova che la sua porzione non è un box, non lo può essere il solido intero. + // Se uno dei thread trova che la sua porzione non è un box, non lo può essere il solido intero. if ( ! m_bIsBox) return false ; // Controllo che gli estremi Z siano uguali. @@ -2058,7 +2148,7 @@ VolZmap::Cut( const Plane3d& plPlane) } // Ciclo sui dexel della mappa for ( int nD = 0 ; nD < int( m_Values[nMap].size()) ; ++ nD) { - // Se spillone già vuoto, passo al successivo + // Se spillone già vuoto, passo al successivo if ( m_Values[nMap][nD].empty()) continue ; // Indici di spillone @@ -2074,20 +2164,20 @@ VolZmap::Cut( const Plane3d& plPlane) double dEnDist = DistPointPlane( ptEn, plMyPlane) ; // Se entrambi sotto il piano if ( dStDist < EPS_SMALL && dEnDist < EPS_SMALL) - // Non devo fare alcunché + // Non devo fare alcunché ; // se altrimenti entrambi gli estremi sono oltre il piano else if ( dStDist > -EPS_SMALL && dEnDist > -EPS_SMALL) { // Si elimina tutto SubtractIntervals( nMap, nI, nJ, dMin, dMax, V_NULL, V_NULL, 1) ; } - // se altrimenti è da tenere il punto iniziale + // se altrimenti è da tenere il punto iniziale else if ( dStDist < 0) { // Si elimina la parte tra intersezione e punto finale double dInt = dMin + ( dMax - dMin) * abs( dStDist) / ( abs( dStDist) + abs( dEnDist)) ; SubtractIntervals( nMap, nI, nJ, dInt, dMax, plMyPlane.GetVersN(), V_NULL, 1) ; } - // se altrimenti è da tenere il punto finale + // se altrimenti è da tenere il punto finale else if (dEnDist < 0) { // Si elimina la parte tra punto iniziale e intersezione double dInt = dMin + ( dMax - dMin) * abs( dStDist) / ( abs( dStDist) + abs( dEnDist)) ; @@ -2177,7 +2267,7 @@ VolZmap::Compact( void) } } - // Se non vi è materiale + // Se non vi è materiale if ( ! bNotEmptyGrid) { m_nStatus = TO_VERIFY ; m_nNumBlock = 0 ; @@ -2199,8 +2289,8 @@ VolZmap::Compact( void) double dNewOy = nMinJ[0] * m_dStep ; double dNewOz = nMinJ[1] * m_dStep ; - // Porto i dexel nel nuovo sistema di riferimento e le quote estreme Z. Non c'è bisogno di trasformare le normali, - // infatti i sistemi di riferimento in gioco differiscono al più per una traslazione. + // Porto i dexel nel nuovo sistema di riferimento e le quote estreme Z. Non c'è bisogno di trasformare le normali, + // infatti i sistemi di riferimento in gioco differiscono al più per una traslazione. for ( int nMap = 0 ; nMap < int( m_nMapNum) ; ++ nMap) { // Quote estreme Z switch ( nMap) { diff --git a/VolZmap.h b/VolZmap.h index 146c9af..ee53485 100644 --- a/VolZmap.h +++ b/VolZmap.h @@ -151,7 +151,7 @@ class VolZmap : public IVolZmap, public IGeoObjRW int GetPartMinDistFromPoint( const Point3d& ptP) const override ; bool AddSurfTm( const ISurfTriMesh* pStm) override ; bool SubtractSurfTm( const ISurfTriMesh* pStm) override ; - bool MakeUniform( double dToler) override ; + bool MakeUniform( double dToler, bool bIsExtensionFirst, int nToolNum) override ; bool Offset( double dOffs, int nType) override ; public : // IGeoObjRW @@ -260,10 +260,11 @@ class VolZmap : public IVolZmap, public IGeoObjRW bool AddIntervals( int nGrid, int nI, int nJ, double dMin, double dMax, const Vector3d& vtNMin, const Vector3d& vtNMax, int nToolNum, bool bSkipSwap = false) ; - bool AddMissingIntervalsInVoxel( VolZmap* VolZmapRef, int nGrid, int nI, int nJ, double dZ, double dToler, - Vector3d vtToolMin, Vector3d vtToolMax, int nToolNum) ; - bool AddSubIntervalInVoxel( VolZmap* VolZmapRef, int nGrid, int nI, int nJ, int nK, double& dMin, double& dMax, - Vector3d& vtMin, Vector3d& vtMax) ; + 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 ManageSubIntervalInVoxel( VolZmap* VolZmapRef, int nGrid, int nI, int nJ, int nK, double& dMin, double& dMax, + Vector3d& vtMin, Vector3d& vtMax) ; // Spostamenti utensile bool MillingTranslationStep( const Point3d& ptPs, const Point3d& ptPe, const Vector3d& vtD, const Vector3d& vtA) ; bool MillingGeneralMotionStep( const Point3d& ptPs, const Vector3d& vtDs, const Vector3d& vtAs, diff --git a/VolZmapVolume.cpp b/VolZmapVolume.cpp index b306385..fd0b30b 100644 --- a/VolZmapVolume.cpp +++ b/VolZmapVolume.cpp @@ -615,134 +615,157 @@ VolZmap::AddIntervals( int nGrid, int nI, int nJ, //---------------------------------------------------------------------------- bool -VolZmap::AddSubIntervalInVoxel( VolZmap* VolZmapRef, int nGrid, int nI, int nJ, int nK, - double& dMin, double& dMax, Vector3d& vtMin, Vector3d& vtMax) +VolZmap::ManageSubIntervalInVoxel( VolZmap* VolZmapRef, int nGrid, int nI, int nJ, int nK, + double& dMin, double& dMax, Vector3d& vtMin, Vector3d& vtMax) { - // se non Tridex, esco + // 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]) + if ( nI < 0 && nI >= m_nNx[nGrid] && nJ < 0 && nJ >= m_nNy[nGrid]) return false ; - // valori di default - vector vTdMin = { -1., -1., -1., -1.} ; - vector vTdMax = { -1., -1., -1., -1.} ; - VCT3DVECTOR vtNMin = { V_INVALID, V_INVALID, V_INVALID, V_INVALID} ; - VCT3DVECTOR vtNMax = { V_INVALID, V_INVALID, V_INVALID, V_INVALID} ; + // Valori di Default + DBLVECTOR vdMin = { -1., -1., -1., -1.} ; + DBLVECTOR vdMax = { -1., -1., -1., -1.} ; + VCT3DVECTOR vNMin = { V_INVALID, V_INVALID, V_INVALID, V_INVALID} ; + VCT3DVECTOR vNMax = { V_INVALID, V_INVALID, V_INVALID, V_INVALID} ; - // se esiste un precedente lungo x-locale + // Se esiste un voxel precedente lungo x-locale ( nI - 1, nJ) if ( nI != 0) { - int nPos = nJ * m_nNx[nGrid] + ( nI - 1) ; // recupero posizione dexel - // cerco l'intervallo corretto sullo Zmap di riferimento + // Ne recupero la posizione + int nPos = nJ * m_nNx[nGrid] + ( nI - 1) ; + // Scorro tutti gli intervalli del dexel in (nI - 1, nJ) for ( int it = 0 ; it < int( VolZmapRef->m_Values[nGrid][nPos].size()) ; ++ it) { + // Se nei pressi dell'estremo superiore if ( VolZmapRef->m_Values[nGrid][nPos][it].dMax + EPS_SMALL > nK * m_dStep && VolZmapRef->m_Values[nGrid][nPos][it].dMax - EPS_SMALL < ( nK + 1) * m_dStep) { - vtNMax[0] = VolZmapRef->m_Values[nGrid][nPos][it].vtMaxN ; - vTdMax[0] = VolZmapRef->m_Values[nGrid][nPos][it].dMax ; + // Memorizzo i parametri + vNMax[0] = VolZmapRef->m_Values[nGrid][nPos][it].vtMaxN ; + vdMax[0] = VolZmapRef->m_Values[nGrid][nPos][it].dMax ; } + // Se nei pressi dell'estremo inferiore if ( VolZmapRef->m_Values[nGrid][nPos][it].dMin + EPS_SMALL > nK * m_dStep && VolZmapRef->m_Values[nGrid][nPos][it].dMin - EPS_SMALL < ( nK + 1) * m_dStep) { - vtNMin[0] = VolZmapRef->m_Values[nGrid][nPos][it].vtMinN ; - vTdMin[0] = VolZmapRef->m_Values[nGrid][nPos][it].dMin ; + // Memorizzo i parametri + vNMin[0] = VolZmapRef->m_Values[nGrid][nPos][it].vtMinN ; + vdMin[0] = VolZmapRef->m_Values[nGrid][nPos][it].dMin ; } } } - // se esiste il successivo lungo x-locale - if ( nI != m_dMaxZ[( nGrid + 2) % 3]) { - int nPos = nJ * m_nNx[nGrid] + ( nI + 1) ; // recupero posizione dexel + + // Se esiste un voxel successivo lungo x-locale, ne recupero la posizione + int nPos = nJ * m_nNx[nGrid] + ( nI + 1) ; + if ( nPos < int( VolZmapRef->m_Values[nGrid].size())) { + // Cerco l'intervallo corretto sullo Zmap di riferimento for ( int it = 0 ; it < int( VolZmapRef->m_Values[nGrid][nPos].size()) ; ++ it) { - // cerco l'intervallo corretto sullo Zmap di riferimento + // Se nei pressi dell'estremo superiore if ( VolZmapRef->m_Values[nGrid][nPos][it].dMax + EPS_SMALL > nK * m_dStep && VolZmapRef->m_Values[nGrid][nPos][it].dMax - EPS_SMALL < ( nK + 1) * m_dStep) { - vtNMax[1] = VolZmapRef->m_Values[nGrid][nPos][it].vtMaxN ; - vTdMax[1] = VolZmapRef->m_Values[nGrid][nPos][it].dMax ; + // Memorizzo i parametri + vNMax[1] = VolZmapRef->m_Values[nGrid][nPos][it].vtMaxN ; + vdMax[1] = VolZmapRef->m_Values[nGrid][nPos][it].dMax ; } + // Se nei pressi dell'estremo inferiore if ( VolZmapRef->m_Values[nGrid][nPos][it].dMin + EPS_SMALL > nK * m_dStep && VolZmapRef->m_Values[nGrid][nPos][it].dMin - EPS_SMALL < ( nK + 1) * m_dStep) { - vtNMin[1] = VolZmapRef->m_Values[nGrid][nPos][it].vtMinN ; - vTdMin[1] = VolZmapRef->m_Values[nGrid][nPos][it].dMin ; + // Memorizzo i parametri + vNMin[1] = VolZmapRef->m_Values[nGrid][nPos][it].vtMinN ; + vdMin[1] = VolZmapRef->m_Values[nGrid][nPos][it].dMin ; } } } - // se esiste il precedente lungo y-locale + + // Se esiste un voxel precedente lungo y-locale if ( nJ != 0) { - int nPos = ( nJ - 1) * m_nNx[nGrid] + nI ; // recupero posizione dexel + // Ne recupero la posizione + int nPos = ( nJ - 1) * m_nNx[nGrid] + nI ; + // Cerco l'intervallo corretto sullo Zmap di riferimento for ( int it = 0 ; it < int( VolZmapRef->m_Values[nGrid][nPos].size()) ; ++ it) { - // cerco l'intervallo corretto sullo Zmap di riferimento + // Se nei pressi dell'estremo superiore if ( VolZmapRef->m_Values[nGrid][nPos][it].dMax + EPS_SMALL > nK * m_dStep && VolZmapRef->m_Values[nGrid][nPos][it].dMax - EPS_SMALL < ( nK + 1) * m_dStep) { - vtNMax[2] = VolZmapRef->m_Values[nGrid][nPos][it].vtMaxN ; - vTdMax[2] = VolZmapRef->m_Values[nGrid][nPos][it].dMax ; + // Memorizzo i parametri + vNMax[2] = VolZmapRef->m_Values[nGrid][nPos][it].vtMaxN ; + vdMax[2] = VolZmapRef->m_Values[nGrid][nPos][it].dMax ; } + // Se nei pressi dell'estremo inferiore if ( VolZmapRef->m_Values[nGrid][nPos][it].dMin + EPS_SMALL > nK * m_dStep && VolZmapRef->m_Values[nGrid][nPos][it].dMin - EPS_SMALL < ( nK + 1) * m_dStep) { - vtNMin[2] = VolZmapRef->m_Values[nGrid][nPos][it].vtMinN ; - vTdMin[2] = VolZmapRef->m_Values[nGrid][nPos][it].dMin ; - } - } - } - // se esiste il successivo lungo y-locale - if ( nJ != m_dMaxZ[( nGrid + 1) % 3]) { - int nPos = ( nJ + 1) * m_nNx[nGrid] + nI ; // recupero posizione dexel - // cerco l'intervallo corretto sullo Zmap di riferimento - for ( int it = 0 ; it < int( VolZmapRef->m_Values[nGrid][nPos].size()) ; ++ it) { - if ( VolZmapRef->m_Values[nGrid][nPos][it].dMax + EPS_SMALL > nK * m_dStep && - VolZmapRef->m_Values[nGrid][nPos][it].dMax - EPS_SMALL < ( nK + 1) * m_dStep) { - vtNMax[3] = VolZmapRef->m_Values[nGrid][nPos][it].vtMaxN ; - vTdMax[3] = VolZmapRef->m_Values[nGrid][nPos][it].dMax ; - } - if ( VolZmapRef->m_Values[nGrid][nPos][it].dMin + EPS_SMALL > nK * m_dStep && - VolZmapRef->m_Values[nGrid][nPos][it].dMin - EPS_SMALL < ( nK + 1) * m_dStep) { - vtNMin[3] = VolZmapRef->m_Values[nGrid][nPos][it].vtMinN ; - vTdMin[3] = VolZmapRef->m_Values[nGrid][nPos][it].dMin ; + // Memorizzo i parametri + vNMin[2] = VolZmapRef->m_Values[nGrid][nPos][it].vtMinN ; + vdMin[2] = VolZmapRef->m_Values[nGrid][nPos][it].dMin ; } } } - // scelgo le normali che si discostano il meno possibile dalla normale della faccia del voxel + // Se esiste un voxel successivo lungo y-locale, ne recupero la posizione + nPos = ( nJ + 1) * m_nNx[nGrid] + nI ; + if ( nPos < int( VolZmapRef->m_Values[nGrid].size())) { + // Cerco l'intervallo corretto sullo Zmap di riferimento + for ( int it = 0 ; it < int( VolZmapRef->m_Values[nGrid][nPos].size()) ; ++ it) { + // Se nei pressi dell'estremo superiore + if ( VolZmapRef->m_Values[nGrid][nPos][it].dMax + EPS_SMALL > nK * m_dStep && + VolZmapRef->m_Values[nGrid][nPos][it].dMax - EPS_SMALL < ( nK + 1) * m_dStep) { + // Memorizzo i parametri + vNMax[3] = VolZmapRef->m_Values[nGrid][nPos][it].vtMaxN ; + vdMax[3] = VolZmapRef->m_Values[nGrid][nPos][it].dMax ; + } + // Se nei pressi dell'estremo inferiore + if ( VolZmapRef->m_Values[nGrid][nPos][it].dMin + EPS_SMALL > nK * m_dStep && + VolZmapRef->m_Values[nGrid][nPos][it].dMin - EPS_SMALL < ( nK + 1) * m_dStep) { + // Memorizzo i parametri + vNMin[3] = VolZmapRef->m_Values[nGrid][nPos][it].vtMinN ; + vdMin[3] = VolZmapRef->m_Values[nGrid][nPos][it].dMin ; + } + } + } - // analisi dei massimi e delle normali --------------------------- - // 1) angolo minimo tra la normale trovata la faccia del voxel + // --- Scelgo le normali che si discostano il meno possibile dalla normale della faccia del voxel + + // 1) Angolo minimo tra la normale trovata la faccia del voxel double dMinAngle = ANG_FULL ; - // 2) vettore di riferimento per la direzione della normale + // 2) Vettore di riferimento per la direzione della normale vtMax = ( nGrid == 0 ? m_MapFrame.VersZ() : - ( nGrid == 1 ? m_MapFrame.VersX() : m_MapFrame.VersY())) ; + nGrid == 1 ? m_MapFrame.VersX() : + nGrid == 2 ? m_MapFrame.VersY() : + V_INVALID) ; Vector3d vtRef = vtMax ; - // 3) determino il massimo per questo intervallo + // 3) Determino il massimo per questo intervallo dMax = ( nK + 1) * m_dStep ; - for ( int i = 0 ; i < 4 ; ++ i) { // scorro le normali - if ( vtNMax[i].IsValid()) { // se normale trovata, quindi valida... - double dCurrAngle ; // angolo corrente tra la normale della TriMesh e quella della faccia del voxel - vtNMax[i].GetAngle( vtRef, dCurrAngle) ; - if ( abs( dCurrAngle) < dMinAngle) { // se angolo minore del minimo trovato... - // aggiorno i parametri + for ( int i = 0 ; i < 4 ; ++ i) { + // Scorro le normali valide trovate + if ( vNMax[i].IsValid()) { + // Angolo corrente tra la normale di riferimento e quella della faccia del voxel + double dCurrAngle ; vNMax[i].GetAngle( vtRef, dCurrAngle) ; + // Se angolo minore del minimo trovato... + if ( abs( dCurrAngle) < dMinAngle) { + // ... Aggiorno i parametri dMinAngle = dCurrAngle ; - vtMax = vtNMax[i] ; - dMax = vTdMax[i] ; + vtMax = vNMax[i] ; + dMax = vdMax[i] ; } } } - // analisi dei minimi e delle normali --------------------------- + // Ripeto lo stesso ragionamento per le normali dei massimi dMinAngle = ANG_FULL ; vtRef.Invert() ; dMin = nK * m_dStep ; vtMin = vtRef ; for ( int i = 0 ; i < 4 ; ++ i) { - if ( vtNMin[i].IsValid()) { + if ( vNMin[i].IsValid()) { double dCurrAngle ; - vtNMin[i].GetAngle( vtRef, dCurrAngle) ; + vNMin[i].GetAngle( vtRef, dCurrAngle) ; if ( abs( dCurrAngle) < dMinAngle) { dMinAngle = dCurrAngle ; - vtMin = vtNMin[i] ; - dMin = vTdMin[i] ; + vtMin = vNMin[i] ; + dMin = vdMin[i] ; } } } @@ -752,72 +775,66 @@ VolZmap::AddSubIntervalInVoxel( VolZmap* VolZmapRef, int nGrid, int nI, int nJ, //---------------------------------------------------------------------------- bool -VolZmap::AddMissingIntervalsInVoxel( VolZmap* VolZmapRef, int nGrid, int nI, int nJ, double dZ, double dToler, - Vector3d vtToolMin, Vector3d vtToolMax, int nToolNum) +VolZmap::UniformIntervalsInVoxel( int nGrid, int nI, int nJ, double dZMin, + double dZMax, double dToler, bool bAdd, int nToolNum, const Vector3d& vtToolMin, + const Vector3d& vtToolMax) { - - // se non Tridex, esco + // 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]) + if ( nI < 0 && nI >= m_nNx[nGrid] && nJ < 0 && nJ >= m_nNy[nGrid]) return false ; - // passo da indici di dexel a indici di voxel - nI /= m_nDexVoxRatio ; - nJ /= m_nDexVoxRatio ; + // 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)) ; - // numero di voxel nel dexel corrente - int nVoxNum = int( m_nNy[(( nGrid+1) % 3)] / m_nDexVoxRatio + - ( m_nNy[(( nGrid+1) % 3)] % m_nDexVoxRatio == 0 ? 1 : 2)) ; - - int nK = 0 ; - for ( int i = 0 ; i < nVoxNum ; ++ i) { - // controllo se sono nel voxel corrente - if ( i * m_dStep < dZ && ( i + 1) * m_dStep > dZ) { - nK = i ; - break ; + // Scorro i Voxel correnti + for ( int nVox = 0 ; nVox < nVoxNum ; ++ nVox) { + // Considero solo i Voxel interni all'intervallo corrente + if ( dZMin - m_dStep / 2. < nVox * m_dStep && nVox * m_dStep < dZMax + m_dStep / 2.) { + // 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 ; // shift di -Step / 2 + double dMyMaxZ = ( nMyK + 1) * m_dStep ; // shift di Step / 2 + Vector3d vtMyMaxN = ( vtToolMax.IsValid() ? vtToolMax : + nMyGrid == 0 ? m_MapFrame.VersZ() : + nMyGrid == 1 ? m_MapFrame.VersX() : + m_MapFrame.VersY()) ; + Vector3d vtMyMinN = ( vtToolMin.IsValid() ? vtToolMin : - vtMyMaxN) ; + if ( bAdd) + AddIntervals( nMyGrid, nMyI, nMyJ, dMyMinZ, dMyMaxZ, vtMyMinN, vtMyMaxN, nToolNum, true) ; + else + SubtractIntervals( nMyGrid, nMyI, nMyJ, dMyMinZ, dMyMaxZ, vtMyMinN, vtMyMaxN, nToolNum, true) ; + // recupero gli indici della griglia precedente + nMyGrid = ( nGrid + 2) % 3 ; + nMyI = nVox ; + nMyJ = nI ; + nMyK = nJ ; + dMyMinZ = nMyK * m_dStep ; // shift di -Step / 2 + dMyMaxZ = ( nMyK + 1) * m_dStep ; // shift di Step / 2 + vtMyMaxN = ( vtToolMax.IsValid() ? vtToolMax : + nMyGrid == 0 ? m_MapFrame.VersZ() : + nMyGrid == 1 ? m_MapFrame.VersX() : + m_MapFrame.VersY()) ; + vtMyMinN = ( vtToolMin.IsValid() ? vtToolMin : - vtMyMaxN) ; + if ( bAdd) + AddIntervals( nMyGrid, nMyI, nMyJ, dMyMinZ, dMyMaxZ, vtMyMinN, vtMyMaxN, nToolNum, true) ; + else + SubtractIntervals( nMyGrid, nMyI, nMyJ, dMyMinZ, dMyMaxZ, vtMyMinN, vtMyMaxN, nToolNum, true) ; } } - // ----------- griglia successiva ----------- - { - int nMyGrid = ( nGrid + 1) % 3 ; - int nMyI = nJ ; - int nMyJ = nK ; - int nMyK = nI ; - double dMyMin ; - double dMyMax ; - Vector3d vtMyMin ; - Vector3d vtMyMax ; - AddSubIntervalInVoxel( VolZmapRef, nMyGrid, nMyI, nMyJ, nMyK, dMyMin, dMyMax, vtMyMin, vtMyMax) ; - AddIntervals( nMyGrid, nMyI, nMyJ, dMyMin - EPS_SMALL, dMyMax + EPS_SMALL, vtMyMin, vtMyMax, - nToolNum, true) ; - } - - // ----------- griglia precedente ----------- - { - int nMyGrid = ( nGrid + 2) % 3 ; - int nMyI = nK ; - int nMyJ = nI ; - int nMyK = nJ ; - double dMyMin ; - double dMyMax ; - Vector3d vtMyMin ; - Vector3d vtMyMax ; - AddSubIntervalInVoxel( VolZmapRef, nMyGrid, nMyI, nMyJ, nMyK, dMyMin, dMyMax, vtMyMin, vtMyMax) ; - AddIntervals( nMyGrid, nMyI, nMyJ, dMyMin - EPS_SMALL, dMyMax + EPS_SMALL, vtMyMin, vtMyMax, - nToolNum, true) ; - } - return true ; - } // ------------------------- BOUNDING BOX --------------------------------------------------------------------------------------