EgtGeomKernel 2.3a4 :

- in Zmap parallelizzata creazione da superficie TriMesh.
This commit is contained in:
Dario Sassi
2021-01-28 19:32:01 +00:00
parent cbd2c582ab
commit b002058933
5 changed files with 244 additions and 106 deletions
+90 -15
View File
@@ -1561,18 +1561,16 @@ VolZmap::SetToModifyDexelBlocks( int nGrid, int nDex, int nInt)
}
//----------------------------------------------------------------------------
bool
VolZmap::IsBox( void)
bool
VolZmap::IsMapPartABox( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, double& dMinZ, double& dMaxZ)
{
// se non tridexel, non posso stabilire con il metodo seguente se è un box
if ( m_nMapNum == 1)
return false ;
// analisi dei tridexel
bool bFound = true ;
for ( int nMap = 0 ; nMap < m_nMapNum ; ++ nMap) {
double dMinZ = m_dMaxZ[nMap] ;
double dMaxZ = m_dMinZ[nMap] ;
for ( int n = 0 ; n < int( m_nDim[nMap]) ; ++ n) {
dMinZ = m_dMaxZ[nMap] ;
dMaxZ = m_dMinZ[nMap] ;
for ( int i = nInfI ; i < nSupI ; ++ i) {
for ( int j = nInfJ ; j < nSupJ ; ++ j) {
if ( ! m_bIsBox)
return true ;
int n = j * m_nNx[nMap] + i ;
int nSize = int( m_Values[nMap][n].size()) ;
if ( nSize > 1)
return false ;
@@ -1586,12 +1584,89 @@ VolZmap::IsBox( void)
abs( m_Values[nMap][n][0].dMax - dMaxZ) > EPS_SMALL)
return false ;
}
}
}
}
if ( dMaxZ < dMinZ)
bFound = false ;
}
return bFound ;
return ( dMaxZ >= dMinZ) ;
}
//----------------------------------------------------------------------------
bool
VolZmap::IsBox( void)
{
// Se non tridexel, non posso stabilire con il metodo seguente se è un box
if ( m_nMapNum == 1)
return false ;
// Numero massimo di thread per il calcolo parallelo.
int nThreadMax = max( 1, int( thread::hardware_concurrency()) - 1) ;
// Disponibile un solo thread
if ( nThreadMax == 1) {
for ( int nMap = 0 ; nMap < m_nMapNum ; ++ nMap) {
double dMinZ, dMaxZ ;
if ( ! IsMapPartABox( nMap, 0, m_nNx[nMap], 0, m_nNy[nMap], dMinZ, dMaxZ))
return false ;
}
return true ;
}
// Caso di più thread
m_bIsBox = true ;
for ( int nMap = 0 ; nMap < m_nMapNum ; ++ nMap) {
vector< future<bool>> vRes ;
vRes.resize( nThreadMax) ;
std::vector<double> vMinZ, vMaxZ ;
vMinZ.resize( nThreadMax) ;
vMaxZ.resize( nThreadMax) ;
if ( m_nNx[nMap] > m_nNy[nMap]) {
int nDexNum = m_nNx[nMap] / nThreadMax ;
int nRemainder = m_nNx[nMap] % nThreadMax ;
int nInfI = 0 ;
int nSupI = 0 ;
for ( int nThread = 0 ; nThread < nThreadMax ; ++ nThread) {
nInfI = nSupI ;
nSupI = nInfI + ( nThread < nRemainder ? nDexNum + 1 : nDexNum) ;
vRes[nThread] = async( launch::async, &VolZmap::IsMapPartABox, this, nMap,
nInfI, nSupI, 0, m_nNy[nMap], ref( vMinZ[nThread]), ref( vMaxZ[nThread])) ;
}
}
else {
int nDexNum = m_nNy[nMap] / nThreadMax ;
int nRemainder = m_nNy[nMap] % nThreadMax ;
int nInfJ = 0 ;
int nSupJ = 0 ;
for ( int nThread = 0 ; nThread < nThreadMax ; ++ nThread) {
nInfJ = nSupJ ;
nSupJ = nInfJ + ( nThread < nRemainder ? nDexNum + 1 : nDexNum) ;
vRes[nThread] = async( launch::async, &VolZmap::IsMapPartABox, this, nMap,
0, m_nNx[nMap], nInfJ, nSupJ, ref(vMinZ[nThread]), ref(vMaxZ[nThread])) ;
}
}
// 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 ;
if ( ! vRes[nL].get()) {
m_bIsBox = false ;
}
}
}
}
// 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.
for ( int nT = 1 ; nT < nThreadMax ; ++ nT) {
if ( abs( vMinZ[nT] - vMinZ[0]) > EPS_SMALL)
return false ;
if ( abs( vMaxZ[nT] - vMaxZ[0]) > EPS_SMALL)
return false ;
}
}
return m_bIsBox ;
}
//----------------------------------------------------------------------------