EgtGeomKernel 1.9h1 :

- sistemazioni varie in CAvToolTriangle
- utilizzo di std::async in CAvToolSurfTm
- corretto GetAllTriaAroundVertex di SurfTm
- aggiunto ( nothrow) a tutti i new.
This commit is contained in:
Dario Sassi
2018-08-08 11:02:56 +00:00
parent d0fb939541
commit 866ed0b3d7
28 changed files with 618 additions and 475 deletions
+86 -24
View File
@@ -17,9 +17,14 @@
#include "DistPointLine.h"
#include "DllMain.h"
#include "/EgtDev/Include/EGnStringUtils.h"
#include <thread>
#include <future>
using namespace std ;
//----------------------------------------------------------------------------
const int STEP_PE = 50 ;
//----------------------------------------------------------------------------
ICAvToolSurfTm*
CreateCAvToolSurfTm( void)
@@ -32,7 +37,7 @@ CreateCAvToolSurfTm( void)
// CAvToolSurfTm
//----------------------------------------------------------------------------
CAvToolSurfTm::CAvToolSurfTm( void)
: m_pSTm( nullptr), m_Tool( false), m_nTriaCAv( 0)
: m_pSTm( nullptr), m_Tool( false)
{
}
@@ -98,10 +103,74 @@ CAvToolSurfTm::TestPath( PNTULIST& lPntM, const Vector3d& vtDir, double dLinTol)
// Predispongo Hash Grid
if ( ! PrepareHashGrid())
return false ;
// Determino il numero di punti del path
m_nTotPnt = int( lPntM.size()) ;
// Recupero il numero massimo di thread concorrenti
int nThreadMax = thread::hardware_concurrency() ;
bool bOk = true ;
// Se un solo thread o pochi punti
if ( nThreadMax <= 1 || m_nTotPnt < 500) {
bOk = TestSubPath( -1, lPntM, vtDir, dLinTol) ;
ProcessEvents( 100, 0) ;
}
// altrimenti
else {
const int MAX_PARTS = 16 ;
PNTULIST vlPntM[MAX_PARTS] ;
// divido la lista in parti
int nPartCnt = min( nThreadMax, MAX_PARTS) ;
int nPartDim = m_nTotPnt / nPartCnt ;
for ( int i = nPartCnt - 1 ; i > 0 ; -- i) {
auto itSplit = prev( lPntM.end(), nPartDim) ;
vlPntM[i].splice( vlPntM[i].end(), lPntM, itSplit, lPntM.end()) ;
vlPntM[i].push_front( lPntM.back()) ;
}
vlPntM[0].splice( vlPntM[0].end(), lPntM) ;
// processo le parti
m_nCurrPnt = 0 ;
m_bBreak = false ;
future<bool> vRes[MAX_PARTS] ;
for ( int i = 0 ; i < nPartCnt ; ++ i)
vRes[i] = async( launch::any, &CAvToolSurfTm::TestSubPath, this, i, ref( vlPntM[i]), vtDir, dLinTol) ;
// attendo i risultati
int nFin = 0 ;
int nNextPE = 0 ;
while ( nFin < nPartCnt) {
for ( int i = 0 ; i < nPartCnt ; ++ i) {
if ( vRes[i].valid() && vRes[i].wait_for( chrono::milliseconds{ 1}) == future_status::ready) {
bOk = vRes[i].get() && bOk ;
++ nFin ;
}
}
if ( m_nCurrPnt > nNextPE) {
int nRes = ProcessEvents( int( m_nCurrPnt * 100. / m_nTotPnt), 10) ;
nNextPE += STEP_PE ;
if ( nRes == 0)
m_bBreak = true ;
}
}
// unisco le liste risultati
for ( int i = 0 ; i < nPartCnt ; ++ i) {
if ( i > 0)
lPntM.pop_back() ;
lPntM.splice( lPntM.end(), vlPntM[i]) ;
}
ProcessEvents( 100, 0) ;
}
// pulisco HashGrid 2d
m_HGrids.Clear() ;
return bOk ;
}
//----------------------------------------------------------------------------
bool
CAvToolSurfTm::TestSubPath( int nId, PNTULIST& lPntM, const Vector3d& vtDir, double dLinTol)
{
// Se lista vuota, non devo fare alcunché
if ( lPntM.empty())
return true ;
// Ciclo sui punti
int nCount = int( lPntM.size()) ;
int nCurr = 0 ;
m_nTriaCAv = 0 ;
Point3d ptPrev, ptCurr ;
auto itPntMPrev = lPntM.end() ;
auto itPntMCurr = lPntM.begin() ;
@@ -109,11 +178,8 @@ CAvToolSurfTm::TestPath( PNTULIST& lPntM, const Vector3d& vtDir, double dLinTol)
// verifico il punto
ptCurr = itPntMCurr->first ;
itPntMCurr->second = MyTestPositionHG( itPntMCurr->first, vtDir) ;
if ( itPntMCurr->second < - EPS_SMALL) {
// pulisco HashGrid 2d
m_HGrids.Clear() ;
if ( itPntMCurr->second < - EPS_SMALL)
return false ;
}
// se esiste il punto precedente devo verificare il medio
if ( itPntMPrev != lPntM.end()) {
MyTestMidPointHG( lPntM, itPntMPrev, itPntMCurr, ptPrev, ptCurr, vtDir, dLinTol, 1) ;
@@ -122,24 +188,22 @@ CAvToolSurfTm::TestPath( PNTULIST& lPntM, const Vector3d& vtDir, double dLinTol)
ptPrev = ptCurr ;
itPntMPrev = itPntMCurr ;
++ itPntMCurr ;
// gestione eventi (ogni 50 punti)
++ nCurr ;
if ( ( nCurr % 50) == 0) {
int nRes = ProcessEvents( int( nCurr * 100. / nCount), 0) ;
if ( nRes == 0) {
// pulisco HashGrid 2d
m_HGrids.Clear() ;
return false ;
++ m_nCurrPnt ;
// se singolo thread
if ( nId == -1) {
// gestione eventi (ogni STEP_PE punti)
if (( m_nCurrPnt % STEP_PE) == 0) {
int nRes = ProcessEvents( int( m_nCurrPnt * 100. / m_nTotPnt), 0) ;
if ( nRes == 0)
return false ;
}
}
// altrimenti multithread
else {
if ( m_bBreak)
return false ;
}
}
// evento completamento
ProcessEvents( 100, 0) ;
// pulisco HashGrid 2d
m_HGrids.Clear() ;
// Per debug
string sLog = "TriaCav=" + ToString( m_nTriaCAv) ;
LOG_INFO( GetEGkLogger(), sLog.c_str()) ;
return true ;
}
@@ -185,7 +249,6 @@ CAvToolSurfTm::MyTestPosition( Point3d& ptT, const Vector3d& vtDir)
for ( int nTria = m_pSTm->GetFirstTriangle( Tria) ;
nTria != SVT_NULL ;
nTria = m_pSTm->GetNextTriangle( nTria, Tria)) {
++ m_nTriaCAv ;
double dDist = CAvToolTriangle( m_Tool, ptT, vtDir, Tria, m_frMove.VersZ()) ;
if ( dDist < - EPS_SMALL)
return -1 ;
@@ -239,7 +302,6 @@ CAvToolSurfTm::MyTestPositionHG( Point3d& ptT, const Vector3d& vtDir)
Triangle3d Tria ;
if ( ! m_pSTm->GetTriangle( nT, Tria))
return -1 ;
++ m_nTriaCAv ;
double dDist = CAvToolTriangle( m_Tool, ptT, vtDir, Tria, m_frMove.VersZ()) ;
if ( dDist > EPS_SMALL) {
dTotDist += dDist ;