- multithread in BuildTree
This commit is contained in:
+18
-5
@@ -315,17 +315,30 @@ SurfBezier::GetCentroid( Point3d& ptCen) const
|
||||
return m_pSTM->GetCentroid( ptCen) ;
|
||||
}
|
||||
|
||||
mutex mapBernstein ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfBezier::GetBernstein( double dU, int nDegU, DBLVECTOR& vBernU) const
|
||||
{
|
||||
INTINT key( nDegU, int( dU * pow(2,24))) ;
|
||||
if ( m_mBernCache.find( key) == m_mBernCache.end()) {
|
||||
bool bCalculated = false ;
|
||||
{
|
||||
lock_guard<mutex> lock( mapBernstein) ;
|
||||
bCalculated = m_mBernCache.find( key) != m_mBernCache.end() ;
|
||||
}
|
||||
if ( ! bCalculated) {
|
||||
DBLVECTOR vBern( nDegU + 1) ;
|
||||
GetAllBernstein( dU, nDegU, vBern) ;
|
||||
m_mBernCache[key] = vBern ;
|
||||
{
|
||||
lock_guard<mutex> lock( mapBernstein) ;
|
||||
m_mBernCache[key] = vBern ;
|
||||
}
|
||||
}
|
||||
{
|
||||
lock_guard<mutex> lock( mapBernstein) ;
|
||||
vBernU = m_mBernCache.at( key) ;
|
||||
}
|
||||
vBernU = m_mBernCache[key] ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -1620,7 +1633,7 @@ SurfBezier::GetAuxSurf( void) const
|
||||
if ( m_pSTM != nullptr)
|
||||
return m_pSTM ;
|
||||
// eseguo calcolo
|
||||
m_pSTM = GetApproxSurf( 50 * EPS_SMALL, 100 * EPS_SMALL) ;
|
||||
m_pSTM = GetApproxSurf( 1000 * EPS_SMALL, 100 * EPS_SMALL) ;
|
||||
return m_pSTM ;
|
||||
}
|
||||
|
||||
@@ -1959,7 +1972,7 @@ SurfBezier::GetLeaves( vector<tuple<int, Point3d, Point3d>>& vLeaves) const
|
||||
//Tree.BuildTree( 5 * LIN_TOL_FINE, 1) ; // per debug
|
||||
}
|
||||
else {
|
||||
Tree.BuildTree( 5 * LIN_TOL_FINE, 0.1) ;
|
||||
Tree.BuildTree( 100 * LIN_TOL_FINE, 0.1) ;
|
||||
}
|
||||
vector<Cell> vCells ;
|
||||
Tree.GetLeaves( vCells) ;
|
||||
|
||||
@@ -32,9 +32,6 @@
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
#include <execution>
|
||||
#include <queue>
|
||||
#include <condition_variable>
|
||||
#include <functional>
|
||||
#include <future>
|
||||
|
||||
using namespace std ;
|
||||
@@ -109,17 +106,30 @@ Tree::AdjustLoop( PolyLine& pl, POLYLINEVECTOR& vPl, BOOLVECTOR& vbOrientation)
|
||||
return true ;
|
||||
}
|
||||
|
||||
mutex map3D ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Tree::GetPoint( double dU, double dV, Point3d& pt) const
|
||||
{
|
||||
pair<int64_t, int64_t> key (static_cast<int64_t>(dU * pow(2,15)), static_cast<int64_t>(dV * pow(2,15))) ;
|
||||
bool bOk = true ;
|
||||
if ( m_mPt3d.find( key) == m_mPt3d.end()) {
|
||||
bOk = bOk && m_pSrfBz->GetPoint( dU / SBZ_TREG_COEFF, dV / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt) ;
|
||||
m_mPt3d[key] = pt ;
|
||||
bool bCalculated = false ;
|
||||
{
|
||||
lock_guard<mutex> lock( map3D) ;
|
||||
bCalculated = m_mPt3d.find( key) != m_mPt3d.end() ;
|
||||
}
|
||||
if ( ! bCalculated) {
|
||||
bOk = bOk && m_pSrfBz->GetPoint( dU / SBZ_TREG_COEFF, dV / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt) ;
|
||||
{
|
||||
lock_guard<mutex> lock( map3D) ;
|
||||
m_mPt3d[key] = pt ;
|
||||
}
|
||||
}
|
||||
{
|
||||
lock_guard<mutex> lock( map3D) ;
|
||||
pt = m_mPt3d[key] ;
|
||||
}
|
||||
pt = m_mPt3d[key] ;
|
||||
return bOk ;
|
||||
}
|
||||
|
||||
@@ -128,8 +138,15 @@ bool
|
||||
Tree::SavePoint( double dU, double dV, Point3d& pt)
|
||||
{
|
||||
pair<int64_t, int64_t> key (static_cast<int64_t>(dU * pow(2,15)), static_cast<int64_t>(dV * pow(2,15))) ;
|
||||
if ( m_mPt3d.find( key) == m_mPt3d.end())
|
||||
bool bCalculated = true ;
|
||||
{
|
||||
lock_guard<mutex> lock( map3D) ;
|
||||
bCalculated = m_mPt3d.find( key) != m_mPt3d.end() ;
|
||||
}
|
||||
if ( ! bCalculated){
|
||||
lock_guard<mutex> lock( map3D) ;
|
||||
m_mPt3d[key] = pt ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -147,6 +164,7 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi
|
||||
m_mChunk.clear() ;
|
||||
m_vPlApprox.clear() ;
|
||||
m_vCCLoop2D.clear() ;
|
||||
CellCounter = 0 ;
|
||||
|
||||
m_pSrfBz = pSrfBz ;
|
||||
m_bSplitPatches = bSplitPatches ;
|
||||
@@ -646,24 +664,30 @@ Tree::BuildTree_test( double dLinTol, double dSideMin, double dSideMax)
|
||||
return true ;
|
||||
}
|
||||
|
||||
mutex queueMutex ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
Tree::BranchManager( queue<function<void()>>& tasks, condition_variable& cv, bool& done)
|
||||
Tree::BranchManager( queue<function<void()>>& qTasks, condition_variable& cv, bool& done)
|
||||
{
|
||||
while (true) {
|
||||
function<void()> task ;
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mapMutex);
|
||||
cv.wait(lock, [&tasks, &done]() { return !tasks.empty() || done; });
|
||||
std::unique_lock<std::mutex> lock( queueMutex) ;
|
||||
cv.wait(lock, [&qTasks, &done]() { return ! qTasks.empty() || done; }) ;
|
||||
|
||||
if (tasks.empty() && done) {
|
||||
return;
|
||||
if ( qTasks.empty() && done) {
|
||||
return ;
|
||||
}
|
||||
task = move(tasks.front());
|
||||
tasks.pop();
|
||||
task = std::move( qTasks.front()) ;
|
||||
qTasks.pop() ;
|
||||
|
||||
// notifico il thread principale che non ci sono più task
|
||||
if ( qTasks.empty() && ! done)
|
||||
cv.notify_all() ;
|
||||
}
|
||||
|
||||
task(); // Execute the task
|
||||
task() ; // Execute the task
|
||||
}
|
||||
}
|
||||
|
||||
@@ -673,85 +697,108 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax)
|
||||
{
|
||||
// lancio in parallelo vari thread in modo da calcolare separatamente i branch da ogni foglia attuale
|
||||
int nThreadMax = ( thread::hardware_concurrency()) / 2 ;
|
||||
int nStartingLeaves = m_vnLeaves.size() ;
|
||||
int nStartingLeaves = m_vnParents.size() ;
|
||||
condition_variable cv ;
|
||||
vector<unordered_map<int, Cell>> vBranches( nStartingLeaves) ;
|
||||
// ad ogni ramo, metto come cella di partenza una foglia
|
||||
for ( int i = 0 ; i < nStartingLeaves ; ++i) {
|
||||
Cell cLeaf = m_mTree.at( i) ;
|
||||
vBranches[i].insert( pair<int,Cell>( i, cLeaf)) ;
|
||||
INTVECTOR vFirstCells ;
|
||||
|
||||
// creo la coda dei task
|
||||
queue<function<void()>> qTasks ;
|
||||
bool done = false ;
|
||||
for (int i = 0; i < nStartingLeaves; ++i) {
|
||||
// ad ogni ramo, metto come cella di partenza una foglia
|
||||
Cell cLeaf = m_mTree.at( m_vnParents[i]) ;
|
||||
vBranches[i].insert( pair<int,Cell>( cLeaf.m_nId, cLeaf)) ;
|
||||
int nFirst = cLeaf.m_nId ;
|
||||
vFirstCells.push_back( nFirst) ;
|
||||
qTasks.emplace([this, i, &vBranches, dLinTol, dSideMin, dSideMax, nFirst]
|
||||
{Tree::BuildBranch( nFirst, vBranches[i], dLinTol, dSideMin, dSideMax) ;} ) ;
|
||||
}
|
||||
|
||||
// Create worker threads
|
||||
vector<thread> workers ;
|
||||
for (int i = 0 ; i < nThreadMax ; ++i)
|
||||
workers.emplace_back( &Tree::BranchManager, this, std::ref( qTasks), std::ref( cv),std::ref( done)) ;
|
||||
|
||||
queue<function<void()>> tasks;
|
||||
// Add tasks to the queue
|
||||
// dico ai thread di iniziare a lavorare
|
||||
cv.notify_all() ;
|
||||
|
||||
// Wait for all tasks to be processed
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(queueMutex);
|
||||
for (int i = 0; i < nStartingLeaves; ++i) {
|
||||
tasks.emplace([this]() {});
|
||||
}
|
||||
unique_lock<mutex> lock( queueMutex);
|
||||
cv.wait( lock, [&qTasks] { return qTasks.empty(); }) ;
|
||||
}
|
||||
|
||||
// Notify threads that tasks are available
|
||||
cv.notify_all();
|
||||
|
||||
// Mark work as done and notify all threads to exit
|
||||
// Wait for all tasks to be processed
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(queueMutex);
|
||||
done = true;
|
||||
}
|
||||
cv.notify_all();
|
||||
|
||||
// Wait for all threads to finish
|
||||
for (auto& t : threads) {
|
||||
t.join();
|
||||
unique_lock<mutex> lock( queueMutex) ;
|
||||
done = true ;
|
||||
}
|
||||
|
||||
cv.notify_all() ;
|
||||
|
||||
vector<vector<pair<int, Cell>>> vectorBranches( nStartingLeaves);
|
||||
// Join all threads
|
||||
for ( auto& t : workers)
|
||||
t.join() ;
|
||||
|
||||
// Step 1: Convert each map to a vector in parallel
|
||||
for_each(execution::par, vectorBranches.begin(), vectorBranches.end(),
|
||||
[&](auto& map) {
|
||||
size_t index = &map - &vectorBranches[0]; // Get the index of the current map
|
||||
vectorBranches[index].assign( make_move_iterator(map.begin()),
|
||||
make_move_iterator(map.end()));
|
||||
});
|
||||
// debug
|
||||
for ( int i = 0 ; i < nStartingLeaves ; ++i)
|
||||
m_mTree.erase( vFirstCells[i]) ;
|
||||
for ( int i = 0 ; i < nStartingLeaves ; ++i)
|
||||
m_mTree.insert( vBranches[i].begin(), vBranches[i].end()) ;
|
||||
|
||||
// Step 2: Precompute total size and allocate final vector
|
||||
size_t totalSize = accumulate(vectorBranches.begin(), vectorBranches.end(), 0,
|
||||
[](size_t sum, const vector<pair<int, Cell>>& v) {
|
||||
return sum + v.size();
|
||||
}) ;
|
||||
return true ;
|
||||
// debug
|
||||
|
||||
vector<pair<int, Cell>> mergedVector( totalSize) ;
|
||||
|
||||
// Step 3: Assign thread-specific ranges and move elements in parallel
|
||||
vector<size_t> offsets( nStartingLeaves + 1, 0) ;
|
||||
for (size_t i = 0; i < nStartingLeaves; ++i)
|
||||
offsets[i + 1] = offsets[i] + vectorBranches[i].size() ;
|
||||
//vector<vector<pair<int, Cell>>> vectorBranches( nStartingLeaves);
|
||||
|
||||
for_each( execution::par, vectorBranches.begin(), vectorBranches.end(),
|
||||
[&]( auto& vec) {
|
||||
size_t index = &vec - &vectorBranches[0];
|
||||
move( vec.begin(), vec.end(), mergedVector.begin() + offsets[index]) ;
|
||||
});
|
||||
//// Step 1: Convert each map to a vector in parallel
|
||||
//for_each(execution::par, vBranches.begin(), vBranches.end(),
|
||||
// [&](auto& map) {
|
||||
// size_t index = &map - &vBranches[0]; // Get the index of the current map
|
||||
// vectorBranches[index].assign( make_move_iterator(map.begin()),
|
||||
// make_move_iterator(map.end()));
|
||||
// });
|
||||
|
||||
// Step 4: Construct final unordered_map in one bulk step
|
||||
//unordered_map<int, Cell> finalMap( mergedVector.begin(), mergedVector.end()) ;
|
||||
Cell cRoot = m_mTree.at( -1) ;
|
||||
m_mTree.clear() ;
|
||||
m_mTree.insert( pair<int, Cell>(cRoot.m_nId, cRoot)) ;
|
||||
m_mTree.insert( mergedVector.begin(), mergedVector.end()) ;
|
||||
//// Step 2: Precompute total size and allocate final vector
|
||||
//size_t totalSize = accumulate(vectorBranches.begin(), vectorBranches.end(), 0,
|
||||
// [](size_t sum, const vector<pair<int, Cell>>& v) {
|
||||
// return sum + v.size();
|
||||
// }) ;
|
||||
|
||||
//vector<pair<int, Cell>> mergedVector( totalSize) ;
|
||||
|
||||
//// Step 3: Assign thread-specific ranges and move elements in parallel
|
||||
//vector<size_t> offsets( nStartingLeaves + 1, 0) ;
|
||||
//for (int i = 0; i < nStartingLeaves; ++i)
|
||||
// offsets[i + 1] = offsets[i] + vectorBranches[i].size() ;
|
||||
|
||||
//for_each( execution::par, vectorBranches.begin(), vectorBranches.end(),
|
||||
// [&]( auto& vec) {
|
||||
// size_t index = &vec - &vectorBranches[0];
|
||||
// move( vec.begin(), vec.end(), mergedVector.begin() + offsets[index]) ;
|
||||
// });
|
||||
|
||||
//// Step 4: Construct final unordered_map in one bulk step
|
||||
////unordered_map<int, Cell> finalMap( mergedVector.begin(), mergedVector.end()) ;
|
||||
//Cell cRoot = m_mTree.at( -1) ;
|
||||
//m_mTree.clear() ;
|
||||
//unordered_map<int,Cell> mContainer( mergedVector.begin(), mergedVector.end()) ;
|
||||
//m_mTree = std::move( mContainer) ;
|
||||
//m_mTree.insert( pair<int, Cell>( cRoot.m_nId, cRoot)) ;
|
||||
|
||||
//return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Tree::BuildBranch( double dLinTol, double dSideMin, double dSideMax, Cell* cBranchRoot, unordered_map<int, Cell>& mBranch)
|
||||
Tree::BuildBranch( int nFirstCell, unordered_map<int, Cell>& mBranch, double dLinTol, double dSideMin, double dSideMax)
|
||||
{
|
||||
// suddivido lo spazio parametrico con divisioni a metà su uno dei due parametri
|
||||
int nCToSplit = cBranchRoot->m_nId ;
|
||||
int nBranchRoot = cBranchRoot->m_nId ;
|
||||
Cell* pcToSplit = cBranchRoot ;
|
||||
int nCToSplit = nFirstCell ;
|
||||
Cell* pcToSplit = &mBranch.at(nFirstCell) ;
|
||||
int nBranchRoot = pcToSplit->m_nParent ;
|
||||
bool bIsPlanar = m_pSrfBz->IsPlanar() ;
|
||||
if ( ! m_bBilinear) {
|
||||
while ( pcToSplit->IsProcessed() == false) {
|
||||
@@ -1017,7 +1064,7 @@ Tree::BuildBranch( double dLinTol, double dSideMin, double dSideMax, Cell* cBran
|
||||
|
||||
// procedo con lo split del Child1
|
||||
nCToSplit = pcToSplit->m_nChild1 ;
|
||||
pcToSplit = &m_mTree[nCToSplit] ;
|
||||
pcToSplit = &mBranch[nCToSplit] ;
|
||||
}
|
||||
else {
|
||||
// sono arrivato ad una cella Leaf, quindi salvo la cella
|
||||
@@ -1025,37 +1072,37 @@ Tree::BuildBranch( double dLinTol, double dSideMin, double dSideMax, Cell* cBran
|
||||
pcToSplit->SetProcessed() ;
|
||||
// risalgo i parent finché non trovo il primo Child2 da processare
|
||||
nCToSplit = pcToSplit->m_nParent ;
|
||||
pcToSplit = &m_mTree[nCToSplit] ;
|
||||
pcToSplit = &mBranch[nCToSplit] ;
|
||||
if ( nCToSplit == nBranchRoot)
|
||||
return true ;
|
||||
if ( m_mTree[pcToSplit->m_nChild1].IsProcessed() && m_mTree[pcToSplit->m_nChild2].IsProcessed())
|
||||
if ( mBranch[pcToSplit->m_nChild1].IsProcessed() && mBranch[pcToSplit->m_nChild2].IsProcessed())
|
||||
pcToSplit->SetProcessed() ;
|
||||
while ( m_mTree[pcToSplit->m_nChild2].IsProcessed()) {
|
||||
while ( mBranch[pcToSplit->m_nChild2].IsProcessed()) {
|
||||
if ( pcToSplit->m_nParent != nBranchRoot) {
|
||||
nCToSplit = pcToSplit->m_nParent ;
|
||||
pcToSplit = &m_mTree[nCToSplit] ;
|
||||
pcToSplit = &mBranch[nCToSplit] ;
|
||||
}
|
||||
else
|
||||
return true ;
|
||||
if ( m_mTree[pcToSplit->m_nChild1].IsProcessed() && m_mTree[pcToSplit->m_nChild2].IsProcessed())
|
||||
if ( mBranch[pcToSplit->m_nChild1].IsProcessed() && mBranch[pcToSplit->m_nChild2].IsProcessed())
|
||||
pcToSplit->SetProcessed() ;
|
||||
if ( nCToSplit == -1 && m_mTree[pcToSplit->m_nChild2].IsProcessed())
|
||||
if ( nCToSplit == -1 && mBranch[pcToSplit->m_nChild2].IsProcessed())
|
||||
break ;
|
||||
}
|
||||
nCToSplit = pcToSplit->m_nChild2 ;
|
||||
pcToSplit = &m_mTree[nCToSplit] ;
|
||||
pcToSplit = &mBranch[nCToSplit] ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
nCToSplit = pcToSplit->m_nChild1 ;
|
||||
pcToSplit = &m_mTree[nCToSplit] ;
|
||||
pcToSplit = &mBranch[nCToSplit] ;
|
||||
}
|
||||
}
|
||||
Balance() ; // da implementare quando dividerò ad un parametro a scelta e non a metà // probabilmente mi servirà salvare nella cella il livello di profondità
|
||||
}
|
||||
// bilineare
|
||||
else {
|
||||
while ( nCToSplit != -2 && pcToSplit->IsProcessed() == false) {
|
||||
while ( nCToSplit != nBranchRoot && pcToSplit->IsProcessed() == false) {
|
||||
if ( pcToSplit->IsLeaf()) {
|
||||
// vertici della cella
|
||||
Point3d ptP00, ptP10, ptP11, ptP01 ;
|
||||
@@ -1126,7 +1173,7 @@ Tree::BuildBranch( double dLinTol, double dSideMin, double dSideMax, Cell* cBran
|
||||
|
||||
// procedo con lo split del Child1
|
||||
nCToSplit = pcToSplit->m_nChild1 ;
|
||||
pcToSplit = &m_mTree[nCToSplit] ;
|
||||
pcToSplit = &mBranch[nCToSplit] ;
|
||||
}
|
||||
else {
|
||||
// sono arrivato ad una cella Leaf, quindi salvo la cella
|
||||
@@ -1134,28 +1181,28 @@ Tree::BuildBranch( double dLinTol, double dSideMin, double dSideMax, Cell* cBran
|
||||
pcToSplit->SetProcessed() ;
|
||||
// risalgo i parent finché non trovo il primo Child2 da processare
|
||||
nCToSplit = pcToSplit->m_nParent ;
|
||||
pcToSplit = &m_mTree[nCToSplit] ;
|
||||
if ( nCToSplit == -2)
|
||||
pcToSplit = &mBranch[nCToSplit] ;
|
||||
if ( nCToSplit == nBranchRoot)
|
||||
return true ;
|
||||
if ( m_mTree[pcToSplit->m_nChild1].IsProcessed() && m_mTree[pcToSplit->m_nChild2].IsProcessed())
|
||||
if ( mBranch[pcToSplit->m_nChild1].IsProcessed() && mBranch[pcToSplit->m_nChild2].IsProcessed())
|
||||
pcToSplit->SetProcessed() ;
|
||||
while ( m_mTree[pcToSplit->m_nChild2].IsProcessed()) {
|
||||
if ( pcToSplit->m_nParent != -2) {
|
||||
while ( mBranch[pcToSplit->m_nChild2].IsProcessed()) {
|
||||
if ( pcToSplit->m_nParent != nBranchRoot) {
|
||||
nCToSplit = pcToSplit->m_nParent ;
|
||||
pcToSplit = &m_mTree[nCToSplit] ;
|
||||
pcToSplit = &mBranch[nCToSplit] ;
|
||||
}
|
||||
if ( m_mTree[pcToSplit->m_nChild1].IsProcessed() && m_mTree[pcToSplit->m_nChild2].IsProcessed())
|
||||
if ( mBranch[pcToSplit->m_nChild1].IsProcessed() && mBranch[pcToSplit->m_nChild2].IsProcessed())
|
||||
pcToSplit->SetProcessed() ;
|
||||
if ( nCToSplit == -1 && m_mTree[pcToSplit->m_nChild2].IsProcessed())
|
||||
if ( nCToSplit == -1 && mBranch[pcToSplit->m_nChild2].IsProcessed())
|
||||
break ;
|
||||
}
|
||||
nCToSplit = pcToSplit->m_nChild2 ;
|
||||
pcToSplit = &m_mTree[nCToSplit] ;
|
||||
pcToSplit = &mBranch[nCToSplit] ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
nCToSplit = pcToSplit->m_nChild1 ;
|
||||
pcToSplit = &m_mTree[nCToSplit] ;
|
||||
pcToSplit = &mBranch[nCToSplit] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1173,6 +1220,8 @@ Tree::Balance()
|
||||
|
||||
// al momento il problema viene bypassato in fase di generazione dei poligoni, considerando per ogni cella, oltre ai propri vertici
|
||||
// i vertici dei vicini che giacciono sui suoi lati
|
||||
// in realtà non è vero: perchè non basta avere più triangoli nella singola cella, può servire proprio spezzare la cella e avere più celle che rappresentano
|
||||
// facce diverse (quindi con pendenze diverse)
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
@@ -21,6 +21,9 @@
|
||||
#include "/EgtDev/Include/EGkChainCurves.h"
|
||||
#include <map>
|
||||
#include <utility>
|
||||
#include <queue>
|
||||
#include <functional>
|
||||
#include <condition_variable>
|
||||
|
||||
struct PairHashInt64 {
|
||||
size_t operator()(const pair<int64_t, int64_t>& key) const {
|
||||
@@ -249,16 +252,16 @@ class Tree
|
||||
Tree( const Point3d ptBl, const Point3d ptTr) ; // creatore da usare solo nel caso in cui si voglia aggiungere tagli ad un'unica cella e del risultato ottenere il contorno
|
||||
bool SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches = true, const Point3d& ptMin = ORIG, const Point3d& ptMax = ORIG) ;
|
||||
bool GetIndependentTrees( BIPNTVECTOR& vTrees) ; // calcolo la suddivisione della superficie solo sulle singole bbox dei loop di trim ( unendo quelli vicini)
|
||||
void BranchManager( queue<std::function<void()>>& tasks, condition_variable& cv, bool& done) ;
|
||||
void BranchManager( queue<function<void()>>& tasks, condition_variable& cv, bool& done) ;
|
||||
bool BuildTree( double dLinTol = LIN_TOL_STD, double dSideMin = 1, double dSideMax = INFINITO) ;
|
||||
bool BuildBranch( double dLinTol = LIN_TOL_STD, double dSideMin = 1, double dSideMax = INFINITO, Cell* cBranchRoot, unordered_map<int, Cell>& mBranch) ; // dSideMax è il massimo per la dimensione maggiore di un triangolo della trimesh
|
||||
bool BuildBranch( int nFirstCell, unordered_map<int, Cell>& mBranch, double dLinTol = LIN_TOL_STD, double dSideMin = 1, double dSideMax = INFINITO) ; // dSideMax è il massimo per la dimensione maggiore di un triangolo della trimesh
|
||||
// dSideMin è lunghezza minima del lato di una cella nello spazio reale
|
||||
bool BuildTree_test( double dLinTol = LIN_TOL_STD, double dSideMin = 1, double dSideMax = INFINITO) ;
|
||||
bool GetPolygons( POLYLINEMATRIX& vvPolygons, POLYLINEMATRIX& vvPolygons3d, vector<ICRVCOMPOPOVECTOR>& vCCEdges3D, ICRVCOMPOPOVECTOR& vCCLoops) ;
|
||||
bool GetPolygonsBasic( POLYLINEVECTOR& vPolygons, POLYLINEVECTOR& vPolygonsCorrected, POLYLINEVECTOR& vPolygons3d) ; // restituisce il poligono corrispondente ad ogni cella foglia dell'albero
|
||||
// ad ogni poligono sono stati aggiunti tutti i vertici dei vicini posizionati sui suoi lati
|
||||
// ad alcuni poligoni potrebbero venire tolti dei punti per evitare errori dovuti ad eventuali poli sui bordi del parametrico
|
||||
bool GetLeaves ( std::vector<Cell>& vLeaves) const ; // restituisce gli indici delle foglie nell'albero
|
||||
bool GetLeaves ( vector<Cell>& vLeaves) const ; // restituisce gli indici delle foglie nell'albero
|
||||
bool GetEdges3D ( vector<ICRVCOMPOPOVECTOR>& mCCEdge, POLYLINEVECTOR& vPolygons) ; // restituisce gli edge 3D come polyline
|
||||
bool GetSplitLoops( ICRVCOMPOPOVECTOR& vCCLoopSplit) const // funzione che restituisce i loop splitatti ai confini delle celle
|
||||
{ for ( int i = 0 ; i < int( m_vCCLoop2D.size()); ++i) vCCLoopSplit.emplace_back( m_vCCLoop2D[i]->Clone()) ; return true ; };
|
||||
|
||||
Reference in New Issue
Block a user