EgtGeomKernel :
- creazione Zmap aggiungendo TriMesh.
This commit is contained in:
+183
-1
@@ -25,6 +25,8 @@
|
||||
#include "/EgtDev/Include/EGkIntervals.h"
|
||||
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
|
||||
#include <thread>
|
||||
#include <future>
|
||||
|
||||
@@ -1500,7 +1502,187 @@ VolZmap::GetPartMinDistFromPoint( const Point3d& ptP) const
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
VolZmap::SetToModifyDexelBlocks( int nGrid, int nDex, int nInt)
|
||||
VolZmap::AddSurfTm( const ISurfTriMesh* pStm)
|
||||
{
|
||||
// controllo sulla superficie
|
||||
double dVol ;
|
||||
if ( pStm == nullptr || ! pStm->IsValid() || ! pStm->IsClosed() ||
|
||||
! pStm->GetVolume( dVol) || dVol < 0)
|
||||
return false ;
|
||||
|
||||
// controllo se il Box3d della superficie si interseca con il Box3d dello Zmap corrente
|
||||
BBox3d BBox_stm, BBox_curr ;
|
||||
if ( ! pStm->GetLocalBBox( BBox_stm) || ! GetLocalBBox( BBox_curr))
|
||||
return false ;
|
||||
BBox3d BBox_inters ;
|
||||
if ( BBox_stm.FindIntersection( BBox_curr, BBox_inters) && BBox_inters.IsEmpty())
|
||||
return true ; // se non ci sono intersezioni, la superficie non influenza lo Zmap
|
||||
Vector3d vtLen = BBox_curr.GetMax() - BBox_curr.GetMin() ; // dimensione massima dello spillone
|
||||
|
||||
// ciclo sulle griglie
|
||||
bool bCompleted = true ;
|
||||
for ( int g = 0 ; g < m_nMapNum ; ++ g) {
|
||||
// definisco dei sistemi di riferimento ausiliari
|
||||
Frame3d frMapFrame ;
|
||||
if ( g == 0)
|
||||
frMapFrame = m_MapFrame ;
|
||||
else if ( g == 1)
|
||||
frMapFrame.Set( m_MapFrame.Orig(), Y_AX, Z_AX, X_AX) ;
|
||||
else if ( g == 2)
|
||||
frMapFrame.Set( m_MapFrame.Orig(), Z_AX, X_AX, Y_AX) ;
|
||||
|
||||
// oggetto per calcolo massivo intersezioni
|
||||
IntersParLinesSurfTm intPLSTM( frMapFrame, *pStm) ;
|
||||
|
||||
// numero massimo di thread
|
||||
int nThreadMax = max( 1, int( thread::hardware_concurrency()) - 1) ;
|
||||
vector<future<bool>> vRes ;
|
||||
vRes.resize( nThreadMax) ;
|
||||
// se dimensione griglia in X maggiore di dimensione Y
|
||||
if ( m_nNx[g] > m_nNy[g]) {
|
||||
int nDexNum = m_nNx[g] / nThreadMax ;
|
||||
int nRemainder = m_nNx[g] % nThreadMax ;
|
||||
int nInfI = 0 ;
|
||||
int nSupI = 0 ;
|
||||
// aggiungo le parti interessate alla mappa
|
||||
for ( int nThread = 0 ; nThread < nThreadMax ; ++ nThread) {
|
||||
nInfI = nSupI ;
|
||||
nSupI = nInfI + ( nThread < nRemainder ? nDexNum + 1 : nDexNum) ;
|
||||
vRes[nThread] = async( launch::async, &VolZmap::AddMapPart, this, g,
|
||||
nInfI, nSupI, 0, m_nNy[g], ref( vtLen), ref( m_MapFrame.Orig()),
|
||||
ref( *pStm), ref( intPLSTM)) ;
|
||||
}
|
||||
}
|
||||
// se dimensione griglia in Y maggiore di dimensione X
|
||||
else {
|
||||
int nDexNum = m_nNy[g] / nThreadMax ;
|
||||
int nRemainder = m_nNy[g] % nThreadMax ;
|
||||
int nInfJ = 0 ;
|
||||
int nSupJ = 0 ;
|
||||
// aggiungo le parti interessate alla mappa
|
||||
for ( int nThread = 0 ; nThread < nThreadMax ; ++ nThread) {
|
||||
nInfJ = nSupJ ;
|
||||
nSupJ = nInfJ + ( nThread < nRemainder ? nDexNum + 1 : nDexNum) ;
|
||||
vRes[nThread] = async( launch::async, &VolZmap::AddMapPart, this, g,
|
||||
0, m_nNx[g], nInfJ, nSupJ, ref( vtLen), ref( m_MapFrame.Orig()),
|
||||
ref( *pStm), ref( intPLSTM)) ;
|
||||
}
|
||||
}
|
||||
|
||||
// ciclo per attendere che tutti gli async abbiano terminato.
|
||||
int nTerminated = 0 ;
|
||||
while ( nTerminated < nThreadMax) {
|
||||
for ( int nL = 0 ; nL < nThreadMax ; ++ nL) {
|
||||
// async terminato
|
||||
if ( vRes[nL].valid() && vRes[nL].wait_for( chrono::microseconds{ 1}) == future_status::ready) {
|
||||
++ nTerminated ;
|
||||
bCompleted = bCompleted && vRes[nL].get() ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! bCompleted)
|
||||
return false ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
VolZmap::MakeUniform( double dToler)
|
||||
{
|
||||
// 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<VolZmap> pOldVolZmap( CloneBasicVolZmap( this)) ;
|
||||
if ( IsNull( pOldVolZmap))
|
||||
return false ;
|
||||
|
||||
// ciclo sulle griglie
|
||||
for ( int nGrid = 0 ; nGrid < m_nMapNum ; ++ nGrid) {
|
||||
// salvo lo Zmap prima di modificare gli spilloni
|
||||
PtrOwner<VolZmap> pVolZMapCurrGrid( CloneBasicVolZmap( this)) ;
|
||||
if ( IsNull( pVolZMapCurrGrid))
|
||||
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)
|
||||
continue ;
|
||||
// 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<Data> 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) ;
|
||||
}
|
||||
}
|
||||
// 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) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 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 ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
VolZmap::SetToModifyDexelBlocks( int nGrid, int nDex, int nInt)
|
||||
{
|
||||
// Controllo sulla validità della griglia
|
||||
if ( nGrid < 0 || nGrid > 2)
|
||||
|
||||
@@ -143,6 +143,8 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
||||
VolZmap* ClonePart( int nPart) const override ;
|
||||
bool RemovePart( int nPart) override ;
|
||||
int GetPartMinDistFromPoint( const Point3d& ptP) const override ;
|
||||
bool AddSurfTm( const ISurfTriMesh* pStm) override ;
|
||||
bool MakeUniform( double dToler) override ;
|
||||
|
||||
public : // IGeoObjRW
|
||||
int GetNgeId( void) const override ;
|
||||
@@ -243,9 +245,15 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
||||
INTVECTOR& vAdjBlockVoxComp, INTVECTOR& vAdjBordBlockVoxComp) const ;
|
||||
// OPERAZIONI SU INTERVALLI
|
||||
bool SubtractIntervals( int nGrid, int nI, int nJ,
|
||||
double dMin, double dMax, const Vector3d& vtNMin, const Vector3d& vtNMax, int nToolNum) ;
|
||||
double dMin, double dMax, const Vector3d& vtNMin, const Vector3d& vtNMax,
|
||||
int nToolNum, bool bSkipSwap = false) ;
|
||||
bool AddIntervals( int nGrid, int nI, int nJ,
|
||||
double dMin, double dMax, const Vector3d& vtNMin, const Vector3d& vtNMax, int nToolNum) ;
|
||||
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) ;
|
||||
// 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,
|
||||
@@ -422,6 +430,8 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
||||
// Funzione per crezione solido in parallelo
|
||||
bool CreateMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, const Vector3d& vtLen, const Point3d& ptMapOrig,
|
||||
const ISurfTriMesh& Surf, IntersParLinesSurfTm& intPLSTM) ;
|
||||
bool AddMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, const Vector3d& vtLen, const Point3d& ptMapOrig,
|
||||
const ISurfTriMesh& Surf, IntersParLinesSurfTm& intPLSTM) ;
|
||||
|
||||
private :
|
||||
enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ;
|
||||
@@ -455,6 +465,7 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
||||
} ;
|
||||
std::vector<std::vector<Data>> m_Values[N_MAPS] ; // dexel delle 3 griglie
|
||||
|
||||
|
||||
int m_nShape ; // Forma : 0 generica, 1 box, 2 estrusione
|
||||
|
||||
int m_nVoxNumPerBlock ; // Numero di voxel per blocco
|
||||
|
||||
@@ -597,6 +597,99 @@ VolZmap::CreateMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, co
|
||||
return true ;
|
||||
}
|
||||
|
||||
bool
|
||||
VolZmap::AddMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, const Vector3d& vtLen, const Point3d& ptMapOrig,
|
||||
const ISurfTriMesh& Surf, IntersParLinesSurfTm& intPLSTM)
|
||||
{
|
||||
// controllo sui parametri
|
||||
if ( nMap < 0 || nMap > 2 ||
|
||||
nInfI < 0 || nInfI > m_nNx[nMap] ||
|
||||
nSupI < 0 || nSupI > m_nNx[nMap] ||
|
||||
nInfJ < 0 || nInfJ > m_nNy[nMap] ||
|
||||
nSupJ < 0 || nSupJ > m_nNy[nMap])
|
||||
return false ;
|
||||
|
||||
// determinazione e ridimensionamento dei dexel interni alla trimesh
|
||||
for ( int i = nInfI ; i < nSupI ; ++ i) {
|
||||
for ( int j = nInfJ ; j < nSupJ ; ++ j) {
|
||||
|
||||
// definisco la retta da intersecare con la trimesh
|
||||
double dX = ( i + 0.5) * m_dStep ;
|
||||
double dY = ( j + 0.5) * m_dStep ;
|
||||
Point3d ptP0( dX, dY, 0) ;
|
||||
|
||||
// intersezioni della retta con la TriMesh
|
||||
ILSIVECTOR IntersectionResults ;
|
||||
intPLSTM.GetInters( ptP0, vtLen.v[(nMap+2)%3], IntersectionResults) ;
|
||||
|
||||
// rimuovo le intersezioni in eccesso
|
||||
for ( int nI = 0 ; nI < int( IntersectionResults.size()) - 3 ; ++ nI) {
|
||||
int nJ = nI + 1 ; // prima successiva
|
||||
int nK = nJ + 1 ; // seconda successiva
|
||||
int nT = nK + 1 ; // terza successiva
|
||||
// determino i segni delle 4 intersezioni tra la linea e il trangolo della TriMesh
|
||||
int nSgnI = IntersectionResults[nI].dCosDN > EPS_SMALL ? 1 : IntersectionResults[nI].dCosDN > -EPS_SMALL ? 0 : - 1 ;
|
||||
int nSgnJ = IntersectionResults[nJ].dCosDN > EPS_SMALL ? 1 : IntersectionResults[nJ].dCosDN > -EPS_SMALL ? 0 : - 1 ;
|
||||
int nSgnK = IntersectionResults[nK].dCosDN > EPS_SMALL ? 1 : IntersectionResults[nK].dCosDN > -EPS_SMALL ? 0 : - 1 ;
|
||||
int nSgnT = IntersectionResults[nT].dCosDN > EPS_SMALL ? 1 : IntersectionResults[nT].dCosDN > -EPS_SMALL ? 0 : - 1 ;
|
||||
// parametri dell'intersezione sulla linea
|
||||
double dUJ = IntersectionResults[nJ].dU ;
|
||||
double dUK = IntersectionResults[nK].dU ;
|
||||
// controllo coerenza con segni...
|
||||
if ( nSgnI != 0 && nSgnI == nSgnJ &&
|
||||
nSgnK != 0 && nSgnK == nSgnT &&
|
||||
nSgnI == - nSgnT &&
|
||||
abs( dUJ - dUK) < EPS_SMALL) {
|
||||
// ... ed elimino le intersezioni in eccesso...
|
||||
IntersectionResults.erase( IntersectionResults.begin() + nK) ;
|
||||
IntersectionResults.erase( IntersectionResults.begin() + nJ) ;
|
||||
}
|
||||
}
|
||||
|
||||
int nInt = int( IntersectionResults.size()) ; // numero di intersezioni valide
|
||||
int nPos = j * m_nNx[nMap] + i ; // posizione del dexel corrente
|
||||
bool bInside = false ; // Flag entrata/uscita per tratto di retta
|
||||
Point3d ptIn ; Vector3d vtInN ;
|
||||
|
||||
// per ogni intersezione valida trovata...
|
||||
for ( int k = 0 ; k < nInt ; ++ k) {
|
||||
// ricavo il tipo di intersezione
|
||||
int nIntType = IntersectionResults[k].nILTT ;
|
||||
// se c'è intersezione
|
||||
if ( nIntType != ILTT_NO) {
|
||||
// ricavo il cos tra i vettori ( normale del triangolo e tangente alla retta)
|
||||
double dCos = IntersectionResults[k].dCosDN ;
|
||||
|
||||
// se entro nella superficie trimesh...
|
||||
if ( dCos < - EPS_SMALL) {
|
||||
ptIn = IntersectionResults[k].ptI ; // punto di intersezione
|
||||
int nT = IntersectionResults[k].nT ; // triangolo di interesse
|
||||
int nF = Surf.GetFacetFromTria( nT) ; // faccia di interesse
|
||||
Surf.GetFacetNormal( nF, vtInN) ;
|
||||
bInside = true ; // entrata
|
||||
}
|
||||
// ...se esco dalla superficie trimesh ( prima sono per forza entrato)
|
||||
else if ( dCos > EPS_SMALL && bInside) {
|
||||
Point3d ptOut = IntersectionResults[k].ptI ; // punto di intersezione
|
||||
int nT = IntersectionResults[k].nT ; // triangolo di interesse
|
||||
int nF = Surf.GetFacetFromTria( nT) ; // faccia di interesse
|
||||
Vector3d vtOutN ; Surf.GetFacetNormal( nF, vtOutN) ; // vettore d'uscita
|
||||
|
||||
// Aggiungo un tratto al dexel
|
||||
AddIntervals( nMap, i, j,
|
||||
ptIn.v[(nMap+2)%3] - ptMapOrig.v[(nMap+2)%3],
|
||||
ptOut.v[(nMap+2)%3] - ptMapOrig.v[(nMap+2)%3],
|
||||
vtInN, vtOutN, 0, true) ;
|
||||
bInside = false ; // uscita
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex)
|
||||
|
||||
+22
-12
@@ -3327,12 +3327,12 @@ VolZmap::IsThereMat( int nI, int nJ, int nK) const
|
||||
nK *= m_nDexVoxRatio ;
|
||||
|
||||
// Se l'indice è alla frontiera del reticolo non vi è materiale
|
||||
if ( nI <= - 1 || nI >= int( m_nNx[0]) ||
|
||||
if ( nI <= - 1 || nI >= int( m_nNx[0]) ||
|
||||
nJ <= - 1 || nJ >= int( m_nNy[0]) ||
|
||||
nK <= - 1 || nK >= int( m_nNy[1]))
|
||||
nK <= - 1 || nK >= int( m_nNy[1]))
|
||||
return false ;
|
||||
|
||||
// ciclo sulle griglie
|
||||
// ciclo sulle griglie
|
||||
int nCount = 0 ;
|
||||
int nMinPos[3] = { -1, -1, -1} ;
|
||||
int nMinIndex[3] ;
|
||||
@@ -3361,18 +3361,22 @@ VolZmap::IsThereMat( int nI, int nJ, int nK) const
|
||||
}
|
||||
// verifica spillone su vertice
|
||||
double dMinDist = INFINITO ;
|
||||
int nIndex = 0 ;
|
||||
int nIndex = 0 ;
|
||||
int nPos = nGrJ * m_nNx[nGrid] + nGrI ;
|
||||
nDexSize[nGrid] = int( m_Values[nGrid][nPos].size()) ;
|
||||
// scorro i sotto-interalli dello spillone
|
||||
while ( nIndex < nDexSize[nGrid]) {
|
||||
// distanza tra la "Z" attuale e il parametro minimo e massimo dell'intervallo nIndex-esimo
|
||||
double dDistInf = dZ[nGrid] - m_Values[nGrid][nPos][nIndex].dMin + 2 * EPS_SMALL ;
|
||||
double dDistSup = dZ[nGrid] - m_Values[nGrid][nPos][nIndex].dMax - 2 * EPS_SMALL ;
|
||||
// se "Z" attuale a cavallo tra queste due distanze...
|
||||
if ( dDistInf > 0. && dDistSup < 0.) {
|
||||
nMinIndex[nGrid] = nIndex ;
|
||||
nMinIndex[nGrid] = nIndex ; // aggiorno l'indice
|
||||
++ nCount ;
|
||||
bInterOnNode[nGrid] = true ;
|
||||
bInterOnNode[nGrid] = true ; // flag T per griglia zero
|
||||
break ;
|
||||
}
|
||||
// se "Z" attuale tutta sopra o tutta sotto
|
||||
else {
|
||||
double dDist = min( abs( dDistInf), abs( dDistSup)) ;
|
||||
if ( dDist < dMinDist) {
|
||||
@@ -3380,16 +3384,22 @@ VolZmap::IsThereMat( int nI, int nJ, int nK) const
|
||||
nMinIndex[nGrid] = nIndex ;
|
||||
dMinDist = dDist ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// sotto-intervallo successivo
|
||||
nIndex += 1 ;
|
||||
}
|
||||
}
|
||||
if ( nCount == 3)
|
||||
} // fine ciclo sulle griglie
|
||||
|
||||
if ( nCount == 3) // ... se interno a tutte e 3 le griglie, allora c'è materiale ...
|
||||
return true ;
|
||||
else if ( nCount == 2) {
|
||||
else if ( nCount == 2) { // ... se interno solo a 2 griglie ...
|
||||
// recupero la griglia sulla quale è esterno
|
||||
int nGrid = ( bInterOnNode[0] ? ( bInterOnNode[1] ? 2 : 1) : 0) ;
|
||||
// se tale griglia non ha sotto-intervalli allora non c'è materiale
|
||||
if ( nDexSize[nGrid] == 0)
|
||||
return false ;
|
||||
// se il valore in "Z" dello spillone è vicino al punto ( 1/10 dello step), aggiorno il
|
||||
// parametro minimo e massimo e considero la presenza di materiale
|
||||
if ( dZ[nGrid] > m_Values[nGrid][nMinPos[nGrid]][nMinIndex[nGrid]].dMin - 0.1 * m_dStep &&
|
||||
dZ[nGrid] < m_Values[nGrid][nMinPos[nGrid]][nMinIndex[nGrid]].dMax + 0.1 * m_dStep) {
|
||||
double dDistInf = abs( dZ[nGrid] - m_Values[nGrid][nMinPos[nGrid]][nMinIndex[nGrid]].dMin) ;
|
||||
@@ -3401,9 +3411,9 @@ VolZmap::IsThereMat( int nI, int nJ, int nK) const
|
||||
return true ;
|
||||
}
|
||||
else
|
||||
return false ;
|
||||
return false ;
|
||||
}
|
||||
else
|
||||
else // ... se invece interno a 1 o a nessuna delle griglie, allora non c'è materiale
|
||||
return false ;
|
||||
}
|
||||
|
||||
|
||||
+223
-10
@@ -30,7 +30,8 @@ using namespace std ;
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
VolZmap::SubtractIntervals( int nGrid, int nI, int nJ,
|
||||
double dMin, double dMax, const Vector3d& vtNMin, const Vector3d& vtNMax, int nToolNum)
|
||||
double dMin, double dMax, const Vector3d& vtNMin, const Vector3d& vtNMax,
|
||||
int nToolNum, bool bSkipSwap)
|
||||
{
|
||||
// Controllo che dMin e dMax non siano quasi coincidenti
|
||||
if ( abs( dMax - dMin) < EPS_ZERO)
|
||||
@@ -54,13 +55,13 @@ VolZmap::SubtractIntervals( int nGrid, int nI, int nJ,
|
||||
}
|
||||
|
||||
// Riporto le coordinate cicliche delle normali nell'ordine di partenza (da griglia a sistema intrinseco)
|
||||
if ( nGrid == 1) {
|
||||
if ( !bSkipSwap && nGrid == 1) {
|
||||
swap( vtNmi.x, vtNmi.z) ;
|
||||
swap( vtNmi.y, vtNmi.z) ;
|
||||
swap( vtNma.x, vtNma.z) ;
|
||||
swap( vtNma.y, vtNma.z) ;
|
||||
}
|
||||
else if ( nGrid == 2) {
|
||||
else if ( !bSkipSwap && nGrid == 2) {
|
||||
swap( vtNmi.y, vtNmi.z) ;
|
||||
swap( vtNmi.x, vtNmi.z) ;
|
||||
swap( vtNma.y, vtNma.z) ;
|
||||
@@ -250,7 +251,8 @@ VolZmap::SubtractIntervals( int nGrid, int nI, int nJ,
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
VolZmap::AddIntervals( int nGrid, int nI, int nJ,
|
||||
double dMin, double dMax, const Vector3d& vtNMin, const Vector3d& vtNMax, int nToolNum)
|
||||
double dMin, double dMax, const Vector3d& vtNMin, const Vector3d& vtNMax,
|
||||
int nToolNum, bool bSkipSwap)
|
||||
{
|
||||
// Controllo che il numero di griglia sia entro i limiti
|
||||
if ( nGrid < 0 || nGrid > 2)
|
||||
@@ -272,19 +274,23 @@ VolZmap::AddIntervals( int nGrid, int nI, int nJ,
|
||||
// Restringo minimo e massimo entro i limiti della mappa
|
||||
if ( dMin < m_dMinZ[nGrid]) {
|
||||
dMin = m_dMinZ[nGrid] ;
|
||||
vtNmi = - Z_AX ;
|
||||
if ( ! bSkipSwap)
|
||||
vtNmi = - Z_AX ;
|
||||
}
|
||||
else if ( dMin > m_dMaxZ[nGrid]) {
|
||||
dMin = m_dMaxZ[nGrid] ;
|
||||
vtNmi = - Z_AX ;
|
||||
if ( ! bSkipSwap)
|
||||
vtNmi = - Z_AX ;
|
||||
}
|
||||
if ( dMax < m_dMinZ[nGrid]) {
|
||||
dMax = m_dMinZ[nGrid] ;
|
||||
vtNma = Z_AX ;
|
||||
if ( ! bSkipSwap)
|
||||
vtNma = Z_AX ;
|
||||
}
|
||||
else if ( dMax > m_dMaxZ[nGrid]) {
|
||||
dMax = m_dMaxZ[nGrid] ;
|
||||
vtNma = Z_AX ;
|
||||
if ( ! bSkipSwap)
|
||||
vtNma = Z_AX ;
|
||||
}
|
||||
|
||||
// Controllo che dMin e dMax non siano quasi coincidenti
|
||||
@@ -292,13 +298,13 @@ VolZmap::AddIntervals( int nGrid, int nI, int nJ,
|
||||
return true ;
|
||||
|
||||
// Riporto le coordinate cicliche nell'ordine di partenza
|
||||
if ( nGrid == 1) {
|
||||
if ( !bSkipSwap && nGrid == 1) {
|
||||
swap( vtNmi.x, vtNmi.z) ;
|
||||
swap( vtNmi.y, vtNmi.z) ;
|
||||
swap( vtNma.x, vtNma.z) ;
|
||||
swap( vtNma.y, vtNma.z) ;
|
||||
}
|
||||
else if ( nGrid == 2) {
|
||||
else if ( !bSkipSwap && nGrid == 2) {
|
||||
swap( vtNmi.y, vtNmi.z) ;
|
||||
swap( vtNmi.x, vtNmi.z) ;
|
||||
swap( vtNma.y, vtNma.z) ;
|
||||
@@ -600,6 +606,213 @@ VolZmap::AddIntervals( int nGrid, int nI, int nJ,
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
VolZmap::AddSubIntervalInVoxel( VolZmap* VolZmapRef, int nGrid, int nI, int nJ, int nK,
|
||||
double& dMin, double& dMax, Vector3d& vtMin, Vector3d& vtMax)
|
||||
{
|
||||
// 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 ;
|
||||
|
||||
// valori di default
|
||||
vector<double> vTdMin = { -1., -1., -1., -1.} ;
|
||||
vector<double> 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} ;
|
||||
|
||||
// se esiste un precedente lungo x-locale
|
||||
if ( nI != 0) {
|
||||
int nPos = nJ * m_nNx[nGrid] + ( nI - 1) ; // 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[0] = VolZmapRef->m_Values[nGrid][nPos][it].vtMaxN ;
|
||||
vTdMax[0] = 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[0] = VolZmapRef->m_Values[nGrid][nPos][it].vtMinN ;
|
||||
vTdMin[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
|
||||
for ( int it = 0 ; it < int( VolZmapRef->m_Values[nGrid][nPos].size()) ; ++ it) {
|
||||
// cerco l'intervallo corretto sullo Zmap di riferimento
|
||||
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 ;
|
||||
}
|
||||
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 ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// se esiste il precedente lungo y-locale
|
||||
if ( nJ != 0) {
|
||||
int nPos = ( nJ - 1) * m_nNx[nGrid] + nI ; // recupero posizione dexel
|
||||
for ( int it = 0 ; it < int( VolZmapRef->m_Values[nGrid][nPos].size()) ; ++ it) {
|
||||
// cerco l'intervallo corretto sullo Zmap di riferimento
|
||||
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 ;
|
||||
}
|
||||
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 ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// scelgo le normali che si discostano il meno possibile dalla normale della faccia del voxel
|
||||
|
||||
// analisi dei massimi e delle normali ---------------------------
|
||||
// 1) angolo minimo tra la normale trovata la faccia del voxel
|
||||
double dMinAngle = ANG_FULL ;
|
||||
// 2) vettore di riferimento per la direzione della normale
|
||||
vtMax = ( nGrid == 0 ? m_MapFrame.VersZ() :
|
||||
( nGrid == 1 ? m_MapFrame.VersX() : m_MapFrame.VersY())) ;
|
||||
Vector3d vtRef = vtMax ;
|
||||
// 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
|
||||
dMinAngle = dCurrAngle ;
|
||||
vtMax = vtNMax[i] ;
|
||||
dMax = vTdMax[i] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// analisi dei minimi e delle normali ---------------------------
|
||||
dMinAngle = ANG_FULL ;
|
||||
vtRef.Invert() ;
|
||||
dMin = nK * m_dStep ;
|
||||
vtMin = vtRef ;
|
||||
for ( int i = 0 ; i < 4 ; ++ i) {
|
||||
if ( vtNMin[i].IsValid()) {
|
||||
double dCurrAngle ;
|
||||
vtNMin[i].GetAngle( vtRef, dCurrAngle) ;
|
||||
if ( abs( dCurrAngle) < dMinAngle) {
|
||||
dMinAngle = dCurrAngle ;
|
||||
vtMin = vtNMin[i] ;
|
||||
dMin = vTdMin[i] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
VolZmap::AddMissingIntervalsInVoxel( VolZmap* VolZmapRef, int nGrid, int nI, int nJ, double dZ, double dToler,
|
||||
Vector3d vtToolMin, Vector3d vtToolMax, int nToolNum)
|
||||
{
|
||||
|
||||
// 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 ;
|
||||
|
||||
// passo da indici di dexel a indici di voxel
|
||||
nI /= m_nDexVoxRatio ;
|
||||
nJ /= m_nDexVoxRatio ;
|
||||
|
||||
// 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 ;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------- 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 ;
|
||||
|
||||
}
|
||||
|
||||
// ------------------------- LAVORAZIONI --------------------------------------------------------------------------------------
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user