diff --git a/VolZmap.cpp b/VolZmap.cpp index 35a6ecd..03731c7 100644 --- a/VolZmap.cpp +++ b/VolZmap.cpp @@ -1929,8 +1929,6 @@ VolZmap::SetToModifyDexelBlocks( int nGrid, int nDex, int nInt) bool VolZmap::IsMapPartABox( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, double& dMinZ, double& dMaxZ) { - if ( ! m_bIsBox) - return true ; dMinZ = m_dMaxZ[nMap] ; dMaxZ = m_dMinZ[nMap] ; for ( int i = nInfI ; i < nSupI ; ++ i) { @@ -1960,6 +1958,7 @@ bool VolZmap::IsBox( void) { // 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 ; // Numero massimo di thread per il calcolo parallelo. @@ -1968,9 +1967,12 @@ VolZmap::IsBox( void) 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)) + if ( ! IsMapPartABox( nMap, 0, m_nNx[nMap], 0, m_nNy[nMap], dMinZ, dMaxZ)) { + m_bIsBox = false ; return false ; + } } + m_bIsBox = true ; return true ; } @@ -2024,10 +2026,11 @@ VolZmap::IsBox( void) 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) + if ( abs( vMinZ[nT] - vMinZ[0]) > EPS_SMALL || + abs( vMaxZ[nT] - vMaxZ[0]) > EPS_SMALL) { + m_bIsBox = false ; return false ; + } } } diff --git a/VolZmap.h b/VolZmap.h index c2e3ba1..93047ab 100644 --- a/VolZmap.h +++ b/VolZmap.h @@ -85,7 +85,7 @@ class VolZmap : public IVolZmap, public IGeoObjRW bool Create( const Point3d& ptO, double dDimX, double dDimY, double dDimZ, double dStep, bool bTriDex) override ; bool CreateEmpty( const Point3d& ptO, double dDimX, double dDimY, double dDimZ, double dStep, bool bTriDex) override ; bool CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double dStep, bool bTriDex) override ; - bool CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex, double dExtraBox = 100 * EPS_SMALL) override ; + bool CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex, double dExtraBox = 0) override ; int GetBlockCount( void) const override ; int GetBlockUpdatingCounter( int nBlock) const override ; bool GetBlockTriangles( int nBlock, TRIA3DEXVECTOR& vTria) const override ; diff --git a/VolZmapCreation.cpp b/VolZmapCreation.cpp index 1421676..fca89e5 100644 --- a/VolZmapCreation.cpp +++ b/VolZmapCreation.cpp @@ -790,11 +790,6 @@ VolZmap::SubtractMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, bool VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex, double dExtraBox) { - -#if false - #define MULTITHREAD -#endif - // Se la superficie non รจ chiusa oppure orientata al contrario non ha senso continuare double dVol ; if ( ! Surf.IsClosed() || ! Surf.GetVolume( dVol) || dVol < 0) @@ -811,6 +806,8 @@ VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex // quindi espandiamo il bounding box per ovviare al problema. if ( dExtraBox > EPS_ZERO) SurfBBox.Expand( dExtraBox) ; + else + dExtraBox = 0 ; // Determino i punti estremi del bounding box Point3d ptMapOrig, ptMapEnd ; @@ -877,67 +874,69 @@ VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex // Oggetto per calcolo massivo intersezioni IntersParLinesSurfTm intPLSTM( frMapFrame, Surf) ; -#ifdef MULTITHREAD + // Standarda รจ multithread + const bool MULTITHREAD = true ; + if ( MULTITHREAD) { - // Numero massimo di thread - int nThreadMax = max( 1, int( thread::hardware_concurrency()) - 1) ; - vector< future> vRes ; - vRes.resize( nThreadMax) ; - if ( m_nNx[nG] > m_nNy[nG]) { - int nDexNum = m_nNx[nG] / nThreadMax ; - int nRemainder = m_nNx[nG] % 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::CreateMapPart, this, nG, - nInfI, nSupI, 0, m_nNy[nG], ref( vtLen), ref( ptMapOrig), ref( Surf), ref( intPLSTM)) ; + // Numero massimo di thread + int nThreadMax = max( 1, int( thread::hardware_concurrency()) - 1) ; + vector< future> vRes ; + vRes.resize( nThreadMax) ; + if ( m_nNx[nG] > m_nNy[nG]) { + int nDexNum = m_nNx[nG] / nThreadMax ; + int nRemainder = m_nNx[nG] % 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::CreateMapPart, this, nG, + nInfI, nSupI, 0, m_nNy[nG], ref( vtLen), ref( ptMapOrig), ref( Surf), ref( intPLSTM)) ; + } } - } - else { - int nDexNum = m_nNy[nG] / nThreadMax ; - int nRemainder = m_nNy[nG] % 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::CreateMapPart, this, nG, - 0, m_nNx[nG], nInfJ, nSupJ, ref( vtLen), ref( ptMapOrig), ref( Surf),ref( intPLSTM)) ; + else { + int nDexNum = m_nNy[nG] / nThreadMax ; + int nRemainder = m_nNy[nG] % 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::CreateMapPart, this, nG, + 0, m_nNx[nG], nInfJ, nSupJ, ref( vtLen), ref( ptMapOrig), ref( Surf),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() ; + // 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() ; + } } } } -#endif -#ifndef MULTITHREAD - // debug ///// NON multiTHREAD - CreateMapPart( nG, 0, m_nNx[nG], 0, m_nNy[nG], vtLen, ptMapOrig, Surf, intPLSTM) ; - // debug -#endif + // !!!! NON MULTITHREAD : SOLO PER DEBUG !!!! + else { + CreateMapPart( nG, 0, m_nNx[nG], 0, m_nNy[nG], vtLen, ptMapOrig, Surf, intPLSTM) ; + } } // Assegno il minimo e massimo valore di Z della mappa m_dMinZ[0] = dExtraBox ; m_dMaxZ[0] = vtLen.z - dExtraBox ; - m_dMinZ[1] = dExtraBox ; + m_dMinZ[1] = ( bTriDex ? dExtraBox : 0) ; m_dMaxZ[1] = ( bTriDex ? vtLen.x - dExtraBox : 0) ; - m_dMinZ[2] = dExtraBox ; + m_dMinZ[2] = ( bTriDex ? dExtraBox : 0) ; m_dMaxZ[2] = ( bTriDex ? vtLen.y - dExtraBox : 0) ; // Tipologia - m_nShape = ( dExtraBox > EPS_ZERO && IsBox() ? BOX : GENERIC) ; + // Con espansione non va considerato box (calcolo trimesh va in crash) + m_nShape = ( dExtraBox <= EPS_ZERO && IsBox() ? BOX : GENERIC) ; // Aggiornamento dello stato m_nStatus = OK ; diff --git a/VolZmapGraphics.cpp b/VolZmapGraphics.cpp index 9fff5ef..bb37919 100644 --- a/VolZmapGraphics.cpp +++ b/VolZmapGraphics.cpp @@ -950,25 +950,41 @@ VolZmap::UpdateTripleMapGraphics( void) const } } - // Calcolo i triangoli sui blocchi - int nBlockUpdated = 0 ; - vector< future> vRes ; - vRes.resize( m_nNumBlock) ; - for ( int i = 0 ; i < m_nNumBlock ; ++ i) { - // Se il blocco deve essere processato - if ( m_BlockToUpdate[i]) { - // processo ... - ++ nBlockUpdated ; - vRes[i] = async( launch::async, &VolZmap::ExtMarchingCubes, this, i, ref( vVoxContainerVec[i])) ; + // Standarda ่ multithread + const bool MULTITHREAD = true ; + if ( MULTITHREAD) { + + // Calcolo i triangoli sui blocchi + int nBlockUpdated = 0 ; + vector< future> vRes ; + vRes.resize( m_nNumBlock) ; + for ( int i = 0 ; i < m_nNumBlock ; ++ i) { + // Se il blocco deve essere processato + if ( m_BlockToUpdate[i]) { + // processo ... + ++ nBlockUpdated ; + vRes[i] = async( launch::async, &VolZmap::ExtMarchingCubes, this, i, ref( vVoxContainerVec[i])) ; + } + } + bool bOk = true ; + int nTerminated = 0 ; + while ( nTerminated < nBlockUpdated) { + for ( int i = 0 ; i < m_nNumBlock ; ++ i) { + if ( m_BlockToUpdate[i] && vRes[i].valid() && vRes[i].wait_for( chrono::nanoseconds{ 1}) == future_status::ready) { + bOk = vRes[i].get() && bOk ; + ++ nTerminated ; + } + } } } - bool bOk = true ; - int nTerminated = 0 ; - while ( nTerminated < nBlockUpdated) { + else { + // Calcolo i triangoli sui blocchi + bool bOk = true ; for ( int i = 0 ; i < m_nNumBlock ; ++ i) { - if ( m_BlockToUpdate[i] && vRes[i].valid() && vRes[i].wait_for( chrono::nanoseconds{ 1}) == future_status::ready) { - bOk = vRes[i].get() && bOk ; - ++ nTerminated ; + // Se il blocco deve essere processato + if ( m_BlockToUpdate[i]) { + // processo ... + bOk = ExtMarchingCubes( i, vVoxContainerVec[i]) && bOk ; } } }