diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index 7610b3c..4a54f39 100644 Binary files a/EgtGeomKernel.rc and b/EgtGeomKernel.rc differ diff --git a/VolZmap.cpp b/VolZmap.cpp index d4e59aa..8eb4b4b 100644 --- a/VolZmap.cpp +++ b/VolZmap.cpp @@ -23,6 +23,8 @@ #include "/EgtDev/Include/EGkIntervals.h" #include "/EgtDev/Include/EGkStringUtils3d.h" #include "/EgtDev/Include/EgtNumUtils.h" +#include +#include using namespace std ; @@ -734,7 +736,8 @@ VolZmap::CheckMapConnection( void) } } } - + // Numero massimo di thread + int nThreadMax = max( 1, int( thread::hardware_concurrency()) - 1) ; // Ciclo sui dexel lungo Z for ( int tI = 0 ; tI < m_nNx[0] ; ++ tI) { for ( int tJ = 0 ; tJ < m_nNy[0] ; ++ tJ) { @@ -754,24 +757,29 @@ VolZmap::CheckMapConnection( void) NewInt.tMap = 0 ; NewInt.tDex = tJ * m_nNx[0] + tI ; NewInt.tInt = tIntZ ; - // Stack di segmenti - IntContaier IntervalsToProcess ; - // Aggiungo il segmento corrente - IntervalsToProcess.push( NewInt) ; - - // Processo gli intervalli trovati - while ( ! IntervalsToProcess.empty()) { - - switch ( IntervalsToProcess.top().tMap) { - case 0 : - ExpandFromZInterval( IntervalsToProcess) ; - break ; - case 1 : - ExpandFromXInterval( IntervalsToProcess) ; - break ; - case 2 : - ExpandFromYInterval( IntervalsToProcess) ; - break ; + // Vettore di stack di segmenti + IntContainerVec IntervalsToProcessStackVec ; + 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 + int nActiveThread = 0 ; + vector> vRes ; + vRes.resize( nThreadMax) ; + for ( int i = 0 ; i < nThreadMax ; ++ i) { + if ( ! IntervalsToProcessStackVec[i].empty()) { + ++ nActiveThread ; + vRes[i] = async( launch::async, &VolZmap::ProcessIntervals, this, ref( IntervalsToProcessStackVec[i])) ; + } + } + // Attendo che tutti i porcessi terminino + int nTerminated = 0 ; + while ( nTerminated < nActiveThread) { + for ( int i = 0 ; i < nThreadMax ; ++ i) { + if ( vRes[i].valid() && vRes[i].wait_for( chrono::microseconds{ 1 }) == future_status::ready) { + vRes[i].get() ; + ++ nTerminated ; + } } } } @@ -788,7 +796,7 @@ VolZmap::CheckMapConnection( void) //---------------------------------------------------------------------------- bool -VolZmap::ExpandFromXInterval( IntContaier& IntCont) +VolZmap::ExpandFromXInterval( IntContainer& IntCont) { // Copio i dati dell'intervallo corrente IntervalIndexes CurrInterval = IntCont.top() ; @@ -859,7 +867,7 @@ VolZmap::ExpandFromXInterval( IntContaier& IntCont) //---------------------------------------------------------------------------- bool -VolZmap::ExpandFromYInterval( IntContaier& IntCont) +VolZmap::ExpandFromYInterval( IntContainer& IntCont) { // Copio i dati dell'intervallo corrente IntervalIndexes CurrInterval = IntCont.top() ; @@ -930,7 +938,7 @@ VolZmap::ExpandFromYInterval( IntContaier& IntCont) //---------------------------------------------------------------------------- bool -VolZmap::ExpandFromZInterval( IntContaier& IntCont) +VolZmap::ExpandFromZInterval( IntContainer& IntCont) { // Copio i dati dell'intervallo corrente IntervalIndexes CurrInterval = IntCont.top() ; @@ -999,6 +1007,98 @@ VolZmap::ExpandFromZInterval( IntContaier& IntCont) return true ; } +//---------------------------------------------------------------------------- +bool +VolZmap::FirstExpansionFromZ( int nNumThread, IntervalIndexes IntSt, IntContainerVec& IntervalsToProcessStackVec) +{ + int tDex = IntSt.tDex ; + int tGrIndex1 = IntSt.tDex % m_nNx[0] ; + int tGrIndex2 = IntSt.tDex / m_nNx[0] ; + int tInt = IntSt.tInt ; + // Quote estreme del segmento lungo Z + double dMinZ = m_Values[0][tDex][tInt].dMin ; + double dMaxZ = m_Values[0][tDex][tInt].dMax ; + double dMinDZ = max( floor( ( dMinZ - 2 * EPS_SMALL) / m_dStep - 0.5), 0.) ; + double dMaxDZ = max( floor( ( dMaxZ + 2 * EPS_SMALL) / m_dStep - 0.5), 0.) ; + // Indici estremi dei dexel ortogonali + // che possono intersecare il segmento di partenza + int tStartK = min( int( dMinDZ), ( m_nNy[1] - 1)) ; + int tStopK = min( int( dMaxDZ), ( m_nNy[1] - 1)) ; + // Posizione XY del dexel + double dX = ( tGrIndex1 + 0.5) * m_dStep ; + double dY = ( tGrIndex2 + 0.5) * m_dStep ; + // Ciclo sugli indici dei dexel che potrebbero + // intersecare il segmento di partenza + int nCurStack = 0 ; + for ( int tK = tStartK ; tK <= tStopK ; ++ tK) { + // Analizzo i dexel della griglia 1. + int tStopX = int( m_Values[1][tK * m_nNx[1] + tGrIndex2].size()) ; + for ( int tIntX = 0 ; tIntX < tStopX ; ++ tIntX) { + // Estremi del segmento del dexel lungo X + 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 + // aggiungo l'intervallo trovato allo stack. + if ( dXmin - 2 * EPS_SMALL < dX && + dXmax + 2 * EPS_SMALL > dX && + m_Values[1][tK * m_nNx[1] + tGrIndex2][tIntX].nCompo == 0) { + m_Values[1][tK * m_nNx[1] + tGrIndex2][tIntX].nCompo = m_Values[0][tDex][tInt].nCompo ; + IntervalIndexes NewInterval ; + NewInterval.tMap = 1 ; + NewInterval.tDex = tK * m_nNx[1] + tGrIndex2 ; + NewInterval.tInt = tIntX ; + IntervalsToProcessStackVec[nCurStack].push( NewInterval) ; + nCurStack = ( ++ nCurStack) % int( IntervalsToProcessStackVec.size()) ; + } + } + // Analizzo i dexel della griglia 2 + int tStopY = int( m_Values[2][tGrIndex1 * m_nNx[2] + tK].size()) ; + for ( int tIntY = 0 ; tIntY < tStopY ; ++ tIntY) { + // Estremi del segmento del dexel lungo Y + 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 + // aggiungo l'intervallo trovato allo stack. + if ( dYmin - 2 * EPS_SMALL < dY && + dYmax + 2 * EPS_SMALL > dY && + m_Values[2][tGrIndex1 * m_nNx[2] + tK][tIntY].nCompo == 0) { + m_Values[2][tGrIndex1 * m_nNx[2] + tK][tIntY].nCompo = m_Values[0][tDex][tInt].nCompo ; + IntervalIndexes NewInterval ; + NewInterval.tMap = 2 ; + NewInterval.tDex = tGrIndex1 * m_nNx[2] + tK ; + NewInterval.tInt = tIntY ; + IntervalsToProcessStackVec[nCurStack].push( NewInterval) ; + nCurStack = ( ++ nCurStack) % int( IntervalsToProcessStackVec.size()) ; + } + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::ProcessIntervals( IntContainer& IntervalsToProcess) +{ + // Processo gli intervalli trovati + while ( ! IntervalsToProcess.empty()) { + switch ( IntervalsToProcess.top().tMap) { + case 0: + ExpandFromZInterval( IntervalsToProcess) ; + break ; + case 1: + ExpandFromXInterval( IntervalsToProcess) ; + break ; + case 2: + ExpandFromYInterval( IntervalsToProcess) ; + break ; + } + } + return true ; +} + //---------------------------------------------------------------------------- VolZmap* VolZmap::ClonePart( int nPart) const diff --git a/VolZmap.h b/VolZmap.h index 3686bc3..850dcab 100644 --- a/VolZmap.h +++ b/VolZmap.h @@ -342,11 +342,14 @@ class VolZmap : public IVolZmap, public IGeoObjRW int tDex ; int tInt ; } ; - typedef std::stack IntContaier ; + typedef std::stack IntContainer ; + typedef std::vector IntContainerVec ; bool CheckMapConnection( void) ; - bool ExpandFromXInterval( IntContaier& IntCont) ; - bool ExpandFromYInterval( IntContaier& IntCont) ; - bool ExpandFromZInterval( IntContaier& IntCont) ; + bool ExpandFromXInterval( IntContainer& IntCont) ; + bool ExpandFromYInterval( IntContainer& IntCont) ; + bool ExpandFromZInterval( IntContainer& IntCont) ; + bool FirstExpansionFromZ( int nNumThread, IntervalIndexes IntSt, IntContainerVec& IntervalsToProcessStackVec) ; + bool ProcessIntervals( IntContainer& IntervalsToProcess) ; bool IsBox( void) ; private :