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
+145 -89
View File
@@ -17,8 +17,8 @@
#include "CurveLine.h"
#include "VolZmap.h"
#include "GeoConst.h"
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
#include "/EgtDev/Include/EgtNumUtils.h"
#include <future>
using namespace std ;
@@ -417,6 +417,111 @@ VolZmap::CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double
return true ;
}
//----------------------------------------------------------------------------
bool
VolZmap::CreateMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, const Vector3d& vtLen, const Point3d& ptMapOrig,
const ISurfTriMesh& Surf, IntersParLinesSurfTm& intPLSTM)
{
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) ;
// Determino le intersezioni della retta con la TriMesh
ILSIVECTOR IntersectionResults ;
intPLSTM.GetInters( ptP0, vtLen.v[(nMap+2)%3], IntersectionResults) ;
for ( int nI = 0 ; nI < int( IntersectionResults.size()) - 3 ; ++ nI) {
int nJ = nI + 1 ;
int nK = nJ + 1 ;
int nT = nK + 1 ;
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 ;
double dUJ = IntersectionResults[nJ].dU ;
double dUK = IntersectionResults[nK].dU ;
if ( nSgnI != 0 && nSgnI == nSgnJ && nSgnK != 0 && nSgnK == nSgnT && nSgnI == - nSgnT && abs( dUJ - dUK) < EPS_SMALL) {
IntersectionResults.erase( IntersectionResults.begin() + nK) ;
IntersectionResults.erase( IntersectionResults.begin() + nJ) ;
}
}
int nInt = int( IntersectionResults.size()) ;
int nPos = j * m_nNx[nMap] + i ;
bool bInside = false ;
Point3d ptIn ;
Vector3d vtInN ;
for ( int k = 0 ; k < nInt ; ++ k) {
int nIntType = IntersectionResults[k].nILTT ;
// Se c'è intersezione
if ( nIntType != ILTT_NO) {
double dCos = IntersectionResults[k].dCosDN ;
// entro nella superficie trimesh
if ( dCos < - EPS_SMALL) {
ptIn = IntersectionResults[k].ptI ;
int nT = IntersectionResults[k].nT ;
int nF = Surf.GetFacetFromTria( nT) ;
Surf.GetFacetNormal( nF, vtInN) ;
bInside = true ;
}
// esco dalla superficie trimesh
else if ( dCos > EPS_SMALL && bInside) {
Point3d ptOut = IntersectionResults[k].ptI ;
int nT = IntersectionResults[k].nT ;
int nF = Surf.GetFacetFromTria( nT) ;
Vector3d vtOutN ;
Surf.GetFacetNormal( nF, vtOutN) ;
int nCurrentSize = int( m_Values[nMap][nPos].size()) ;
// Aggiungo un tratto al dexel
m_Values[nMap][nPos].resize( nCurrentSize + 1) ;
// Aggiorno dati del tratto di dexel
m_Values[nMap][nPos][nCurrentSize].dMin = ptIn.v[(nMap+2)%3] - ptMapOrig.v[(nMap+2)%3] ;
m_Values[nMap][nPos][nCurrentSize].dMax = ptOut.v[(nMap+2)%3] - ptMapOrig.v[(nMap+2)%3] ;
m_Values[nMap][nPos][nCurrentSize].vtMinN = vtInN ;
m_Values[nMap][nPos][nCurrentSize].vtMaxN = vtOutN ;
m_Values[nMap][nPos][nCurrentSize].nToolMin = 0 ;
m_Values[nMap][nPos][nCurrentSize].nToolMax = 0 ;
m_Values[nMap][nPos][nCurrentSize].nCompo = 0 ;
bInside = false ;
}
}
}
}
}
return true ;
}
//----------------------------------------------------------------------------
bool
VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex)
@@ -487,6 +592,7 @@ VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex
return false ;
// ciclo sulle griglie
bool bCompleted = true ;
for ( int g = 0 ; g < m_nMapNum ; ++ g) {
// Definisco dei sistemi di riferimento ausiliari
@@ -501,93 +607,43 @@ VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex
// Oggetto per calcolo massivo intersezioni
IntersParLinesSurfTm intPLSTM( frMapFrame, Surf) ;
// Determinazione e ridimensionamento dei dexel interni alla trimesh
for ( int i = 0 ; i < m_nNx[g] ; ++ i) {
for ( int j = 0 ; j < m_nNy[g] ; ++ 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) ;
// Determino le intersezioni della retta con la TriMesh
ILSIVECTOR IntersectionResults ;
intPLSTM.GetInters( ptP0, vtLen.v[(g+2)%3], IntersectionResults) ;
for ( int nI = 0 ; nI < int( IntersectionResults.size()) - 3 ; ++ nI) {
int nJ = nI + 1 ;
int nK = nJ + 1 ;
int nT = nK + 1 ;
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 ;
double dUJ = IntersectionResults[nJ].dU ;
double dUK = IntersectionResults[nK].dU ;
if ( nSgnI != 0 && nSgnI == nSgnJ && nSgnK != 0 && nSgnK == nSgnT && nSgnI == - nSgnT && abs( dUJ - dUK) < EPS_SMALL) {
IntersectionResults.erase( IntersectionResults.begin() + nK) ;
IntersectionResults.erase( IntersectionResults.begin() + nJ) ;
}
}
int nInt = int( IntersectionResults.size()) ;
int nPos = j * m_nNx[g] + i ;
bool bInside = false ;
Point3d ptIn ;
Vector3d vtInN ;
for ( int k = 0 ; k < nInt ; ++ k) {
int nIntType = IntersectionResults[k].nILTT ;
// Se c'è intersezione
if ( nIntType != ILTT_NO) {
double dCos = IntersectionResults[k].dCosDN ;
// entro nella superficie trimesh
if ( dCos < - EPS_SMALL) {
ptIn = IntersectionResults[k].ptI ;
int nT = IntersectionResults[k].nT ;
int nF = Surf.GetFacetFromTria( nT) ;
Surf.GetFacetNormal( nF, vtInN) ;
bInside = true ;
}
// esco dalla superficie trimesh
else if ( dCos > EPS_SMALL && bInside) {
Point3d ptOut = IntersectionResults[k].ptI ;
int nT = IntersectionResults[k].nT ;
int nF = Surf.GetFacetFromTria( nT) ;
Vector3d vtOutN ;
Surf.GetFacetNormal( nF, vtOutN) ;
int nCurrentSize = int( m_Values[g][nPos].size()) ;
// Aggiungo un tratto al dexel
m_Values[g][nPos].resize( nCurrentSize + 1) ;
// Aggiorno dati del tratto di dexel
m_Values[g][nPos][nCurrentSize].dMin = ptIn.v[(g+2)%3] - ptMapOrig.v[(g+2)%3] ;
m_Values[g][nPos][nCurrentSize].dMax = ptOut.v[(g+2)%3] - ptMapOrig.v[(g+2)%3] ;
m_Values[g][nPos][nCurrentSize].vtMinN = vtInN ;
m_Values[g][nPos][nCurrentSize].vtMaxN = vtOutN ;
m_Values[g][nPos][nCurrentSize].nToolMin = 0 ;
m_Values[g][nPos][nCurrentSize].nToolMax = 0 ;
m_Values[g][nPos][nCurrentSize].nCompo = 0 ;
bInside = false ;
}
}
// Numero massimo di thread
int nThreadMax = max( 1, int( thread::hardware_concurrency()) - 1) ;
vector< future<bool>> vRes ;
vRes.resize( nThreadMax) ;
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 ;
for ( int nThread = 0 ; nThread < nThreadMax ; ++ nThread) {
nInfI = nSupI ;
nSupI = nInfI + ( nThread < nRemainder ? nDexNum + 1 : nDexNum) ;
vRes[nThread] = async( launch::async, &VolZmap::CreateMapPart, this, g,
nInfI, nSupI, 0, m_nNy[g], ref( vtLen), ref( ptMapOrig), ref( Surf), ref( intPLSTM)) ;
}
}
else {
int nDexNum = m_nNy[g] / nThreadMax ;
int nRemainder = m_nNy[g] % 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, g,
0, m_nNx[g], 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() ;
}
}
}
@@ -607,5 +663,5 @@ VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex
// Aggiornamento dello stato
m_nStatus = OK ;
return true ;
return bCompleted ;
}