Compare commits

..

8 Commits

Author SHA1 Message Date
Daniele Bariletti 5fc04c2791 EgtGeomKernel :
- passaggio da mutex a shared_mutex nelle Bezier.
2025-04-02 12:52:55 +02:00
Daniele Bariletti 8f13d8d198 EgtGeomKernel :
- aggiunto un controllo nel TraceLoop.
2025-04-01 16:27:50 +02:00
Daniele Bariletti a1b4a6be6e EgtGeomKernel :
- rimessi come locali i vettori temporanei per il calcolo di punti 3D di una bezier.
2025-04-01 15:15:46 +02:00
Daniele Bariletti dfec7c3a4c EgtGeomKernel: - aggiunto mutex per l'accesso a m_vnLeaves
- creazione in parallelo della mappa finale m_mTree.
2025-04-01 15:14:43 +02:00
Daniele Bariletti 562f750200 - multithread in BuildTree 2025-03-31 16:28:49 +02:00
Daniele Bariletti 9c662e2799 Merge remote-tracking branch 'origin/master' into FasterBezier 2025-03-27 16:00:58 +01:00
Daniele Bariletti 18661ee70d Merge remote-tracking branch 'origin/master' into FasterBezier 2025-03-27 10:24:00 +01:00
Daniele Bariletti 3b9be09b4b - imbastimento del multiThread per il calcolo del tree. 2025-03-26 17:51:49 +01:00
11 changed files with 904 additions and 925 deletions
BIN
View File
Binary file not shown.
-39
View File
@@ -60,8 +60,6 @@ OffsetCurve::Reset( void)
}
}
m_CrvLst.clear() ;
m_ptOffs = P_INVALID ;
m_vtOut = V_INVALID ;
return true ;
}
@@ -706,18 +704,6 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
double dCorr = ( dDist > 0 ? - VRONI_OFFS_TOL : VRONI_OFFS_TOL) ;
voronoiObj->CalcOffset( vOffs, dDist + dCorr, nType) ;
}
// se ancora vuoto calcolo i punti speciali di offset ( punti e direzioni sui bisettore alla distanza richiesta)
if ( vOffs.empty()) {
PNTVECTVECTOR vPntOffs ;
voronoiObj->CalcSpecialPointOffset( vPntOffs, dDist) ;
// NB al momento vengono gestiti solo i casi in cui vi è un unico punto di offset. Se si ottengono più punti di offset
// ( e.g. alcune curve aperte) non se ne restiusce nessuno. Da estendere, se necessario, individuando i punti dal lato
// di offset richiesto
if ( vPntOffs.size() == 1) {
m_ptOffs = vPntOffs[0].first ;
m_vtOut = vPntOffs[0].second ;
}
}
}
for ( int i = 0 ; i < ( int)vOffs.size() ; i ++)
@@ -747,21 +733,10 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
pCrv->Scale( GLOB_FRM, 1 / dExtrOnN, 1, 1) ;
pCrv->ToGlob( frCopy) ;
}
if ( m_ptOffs.IsValid()) {
m_ptOffs.Scale( GLOB_FRM, 1 / dExtrOnN, 1, 1) ;
m_ptOffs.ToGlob( frCopy) ;
m_vtOut.Scale( GLOB_FRM, 1 / dExtrOnN, 1, 1) ;
m_vtOut.ToGlob( frCopy) ;
}
}
else if ( bNeedRef) {
for ( auto pCrv : m_CrvLst)
pCrv->ToGlob( frCopy) ;
if ( m_ptOffs.IsValid()) {
m_ptOffs.ToGlob( frCopy) ;
m_vtOut.ToGlob( frCopy) ;
}
}
// assegno estrusione e spessore come curva originale e unisco parti allineate
@@ -839,20 +814,6 @@ OffsetCurve::GetShorterCurve( void)
return pCrv ;
}
//----------------------------------------------------------------------------
bool
OffsetCurve::GetPointOffset( Point3d& ptOffs, Vector3d& vtOut)
{
// verifico se valori validi da restituire
if ( ! m_ptOffs.IsValid() || ! m_vtOut.IsValid())
return false ;
ptOffs = m_ptOffs ;
vtOut = m_vtOut ;
return true ;
}
//----------------------------------------------------------------------------
bool
PreviousIsLine( ICURVEPLIST::const_iterator iIter, const ICURVEPLIST& CrvLst, bool bClosed)
+4 -2
View File
@@ -577,8 +577,10 @@ SurfFlatRegionByContours::GetUnusedCurveTempProps( INTVECTOR& vId)
bool
CalcRegionPolyLines( const POLYLINEVECTOR& vPL, Vector3d& vtN, INTMATRIX& vnPLIndMat, BOOLVECTOR& vbInvert)
{
// vnPLIndMat : ogni riga corrisponde ad un chunk, in posizione 0 c'è il loop esterno e nelle successive i loop interni
// vbInvert : riferito al vettore delle polyline, riporta true se la polyline è stata invertita
// matrice di interi : ogni riga corrisponde ad un chunk, dove in posizione 0 c'è il loop esterno e nelle
// successive i loop interni
//INTMATRIX vnPLIndMat ;
// vettore di bool : riferito al vettore originale delle polyline, riporta true se la polyline è stata invertita
// ricavo versore normale
Plane3d plPlane ; double dArea ;
+458 -509
View File
File diff suppressed because it is too large Load Diff
+6 -8
View File
@@ -126,7 +126,6 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
bool GetControlCurveOnU( int nIndV, PolyLine& plCtrlU) const override ;
bool GetControlCurveOnV( int nIndU, PolyLine& plCtrlV) const override ;
const SurfTriMesh* GetAuxSurf( void) const override ;
const SurfTriMesh* GetAuxSurfRefined( void) const override ;
SurfTriMesh* GetApproxSurf( double dTol, double dSideMin = 100 * EPS_SMALL) const override ;
// funzione per ottenere la suddivisione dello spazio parametrico nelle celle utilizzate per la triangolazione.
bool GetLeaves( std::vector<std::tuple<int, Point3d, Point3d>>& vLeaves) const override ;
@@ -222,8 +221,7 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
private :
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
mutable SurfTriMesh* m_pSTM ; // superficie trimesh ausiliaria per la visualizzazione
mutable SurfTriMesh* m_pSTMRefined ; // superficie trimesh ausiliaria raffinata per i calcoli
mutable SurfTriMesh* m_pSTM ; // superficie trimesh ausiliaria
Status m_nStatus ; // stato
int m_nDegU ; // grado in U
int m_nDegV ; // grado in V
@@ -243,12 +241,12 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
mutable ICRVCOMPOPOVECTOR m_vCCLoop ; // vettore dei loop della superficie trimmata
mutable int m_nIsPlanar ; // enum che indica se la superficie è piana ( -1, non è stato calcolato)
mutable DBLVECTOR m_vBernU ;
mutable PNTVECTOR m_ptTemp ;
mutable DBLVECTOR m_vBernV ;
mutable PNTVECTOR m_ptTempW ;
mutable DBLVECTOR m_dTempW ;
mutable PNTVECTOR m_vPtWCtrlLoc ;
mutable DBLVECTOR m_vWeCtrlLoc ;
//mutable PNTVECTOR m_ptTemp ;
//mutable PNTVECTOR m_ptTempW ;
//mutable DBLVECTOR m_dTempW ;
//mutable PNTVECTOR m_vPtWCtrlLoc ;
//mutable DBLVECTOR m_vWeCtrlLoc ;
} ;
//-----------------------------------------------------------------------------
-11
View File
@@ -2091,17 +2091,6 @@ SurfTriMesh::CreateByFlatContour( const PolyLine& PL)
return AdjustTopology() ;
}
//----------------------------------------------------------------------------
bool
SurfTriMesh::CreateByPolygonWithHoles( const POLYLINEVECTOR& vPL)
{
INTMATRIX vnPLIndMat ;
vnPLIndMat.push_back( { 0}) ;
for ( int i = 1 ; i < int( vPL.size()) ; ++ i)
vnPLIndMat[0].push_back( i) ;
return CreateByRegion( vPL, vnPLIndMat) ;
}
//----------------------------------------------------------------------------
bool
SurfTriMesh::CreateByRegion( const POLYLINEVECTOR& vPL, const INTMATRIX& vnPLIndMat)
+2 -3
View File
@@ -1,7 +1,7 @@
//----------------------------------------------------------------------------
// EgalTech 2014-2025
// EgalTech 2014-2023
//----------------------------------------------------------------------------
// File : SurfTriMesh.h Data : 28.03.25 Versione : 2.7c4
// File : SurfTriMesh.h Data : 09.12.23 Versione : 2.5l2
// Contenuto : Dichiarazione della classe Superficie TriMesh.
//
//
@@ -251,7 +251,6 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
bool RemoveTriangle( int nId) override ;
bool AdjustTopology( void) override ;
bool CreateByFlatContour( const PolyLine& PL) override ;
bool CreateByPolygonWithHoles( const POLYLINEVECTOR& vPL) override ;
bool CreateByExtrusion( const PolyLine& PL, const Vector3d& vtExtr) override ;
bool CreateByPointCurve( const Point3d& ptP, const PolyLine& PL) override ;
bool CreateByTwoCurves( const PolyLine& PL1, const PolyLine& PL2, int nRuledType) override ;
+411 -253
View File
File diff suppressed because it is too large Load Diff
+13 -8
View File
@@ -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 {
@@ -164,7 +167,7 @@ class Cell
~Cell( void) {}
Cell( void)
: m_nId( -1),m_nTop ( -2), m_nBottom( -2), m_nLeft( -2), m_nRight ( -2), m_nParent( -2), m_nDepth( 0),
m_nChild1( -2), m_nChild2( -2), m_nFlag( -1), m_bLabelled( false), m_nRightEdgeIn( -1), m_bOnLeftEdge( false), m_bOnTopEdge( false), m_nVertToErase( -1),
m_nChild1( -2), m_nChild2( -2), m_nFlag( -1), m_nFlag2( 0), m_nRightEdgeIn( -1), m_bOnLeftEdge( false), m_bOnTopEdge( false), m_nVertToErase( -1),
m_ptPbl( ORIG), m_ptPtr( SBZ_TREG_COEFF, SBZ_TREG_COEFF, 0), m_bProcessed( false), m_bSplitVert( true)
{
Point3d ptTr ( 1 * SBZ_TREG_COEFF, 1 * SBZ_TREG_COEFF) ;
@@ -172,7 +175,7 @@ class Cell
}
Cell( const Point3d& ptBL, const Point3d& ptTR)
: m_nId( -1),m_nTop ( -2), m_nBottom( -2), m_nLeft( -2), m_nRight ( -2), m_nParent( -2), m_nDepth( 0),
m_nChild1( -2), m_nChild2( -2), m_nFlag( -1), m_bLabelled( 0), m_nRightEdgeIn( -1), m_bOnLeftEdge( false), m_bOnTopEdge( false), m_nVertToErase( -1),
m_nChild1( -2), m_nChild2( -2), m_nFlag( -1), m_nFlag2( 0), m_nRightEdgeIn( -1), m_bOnLeftEdge( false), m_bOnTopEdge( false), m_nVertToErase( -1),
m_ptPbl( ptBL), m_ptPtr( ptTR), m_bProcessed( false), m_bSplitVert( true) {}
bool IsSame( const Cell& cOtherCell) const
{ return ( m_nId == cOtherCell.m_nId) ; }
@@ -220,9 +223,9 @@ class Cell
double m_dSplit ; // parametro a cui è stata splittata la cella
int m_nChild1 ; // prima cella figlio
int m_nChild2 ; // seconda cella figlio
int m_nFlag ; // flag che indica la caratterizzazione della cella rispetto ai loop di trim
int m_nFlag ; // falg che indica la caratterizzazione della cella rispetto ai loop di trim
// 0 esterna, 1 intersecata, 2 contiene un loop, 3 intersecata e contenente un loop, 4 contenuta in un loop
bool m_bLabelled ; // flag che indica se la cella è stata attraversata durante l'ultima fase del labelling
int m_nFlag2 ; // falg che indica se la cella è stata attraversata durante l'ultima fase del labelling
int m_nRightEdgeIn ; // 0 right edge fuori, 1 right edge dentro, 2 metà e metà
bool m_bOnLeftEdge ; // flag che indica se la cella è sul lato sinistro ( per superfici chiuse sul parametro U)
bool m_bOnTopEdge ; // flag che indica se la cella è sul lato top ( per superfici chiuse sul parametro V)
@@ -249,14 +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)
bool BuildTree( double dLinTol = LIN_TOL_STD, double dSideMin = 1, double dSideMax = INFINITO) ; // dSideMax è il massimo per la dimensione maggiore di un triangolo della trimesh
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( 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 ; };
@@ -269,8 +274,8 @@ class Tree
std::vector<bool> GetPoles( void) { return m_vbPole ;} ; // funzione che restituisce i flag che indicano se i lati sono collassati in dei poli
private :
bool Split( int nId, double dSplitValue) ; // funzione di split di una cella al parametro indicato nella direzione data da bVert
bool Split( int nId) ; // funzione di split di una cella dell'albero a metà nella direzione data da bVert
bool Split( int nId, double dSplitValue, unordered_map<int, Cell>& mBranch) ;// funzione di split di una cella al parametro indicato nella direzione data da bVert
bool Split( int nId,unordered_map<int, Cell>& mBranch) ; // funzione di split di una cella dell'albero a metà nella direzione data da bVert
void Balance( void) ; // creo rami in modo che tutte tutte le foglie abbiano come adiacenti foglie ad una profondità di +- 1
int GetHeightLeaves( int nId, INTVECTOR& vnLeaves, int d = 0) const ; // altezza del subtree a partire dal nodo nId
int GetDepth( int nId, int nRef) const ; // livello del nodo nId
+10 -91
View File
@@ -574,7 +574,7 @@ Voronoi::CalcMedialAxis( ICURVEPOVECTOR& vCrvs, int nSide)
if ( m_vroni->IsWMATEdge( i)) {
PtrOwner<ICurve> pCrv( GetBisectorCurve( i)) ;
if ( ! IsNull( pCrv) && pCrv->IsValid())
vCrvs.emplace_back( Release( pCrv)) ;
vCrvs.emplace_back( Release( pCrv)) ;
}
}
@@ -594,7 +594,7 @@ bool
Voronoi::CalcOffset( ICURVEPOVECTOR& vOffs, double dOffs, int nType)
{
vOffs.clear() ;
if ( ! IsValid())
return false ;
@@ -767,77 +767,6 @@ Voronoi::CalcSingleCurvesOffset( ICURVEPOVECTOR& vOffs, double dOffs)
return true ;
}
//----------------------------------------------------------------------------
bool
Voronoi::CalcSpecialPointOffset( PNTVECTVECTOR& vResult, double dOffs)
{
// calcola i punti e le tangenti sui bisettori del medial axis in corrispondenza del valore di offset richiesto
vResult.clear() ;
if ( abs( dOffs) < EPS_SMALL)
return true ;
if ( ! IsValid())
return false ;
try {
// verifico se necessario ricalcolo Voronoi
UpdateVoronoi( dOffs) ;
// indivudio lato medial axis per curve chiuse ( suppongo di chiamare la funzione dalla singola curva, quindi vale controllare
// la chiusura solo sulla prima curva. Eventualmente da estendere)
bool bLeft = true, bRight = true ;
if ( m_vpCrvs[0]->IsClosed()) {
bLeft = dOffs < 0 ;
bRight = ! bLeft ;
}
// calcolo medial axis
m_vroni->apiComputeWMAT( false, 0.0, 0.0, false, bLeft, bRight) ;
for ( int i = 4 ; i < m_vroni->GetNumberOfEdges() ; i ++) {
// verifico se il lato appartiene al medial axis
if ( m_vroni->IsWMATEdge( i)) {
// verifico se coinvolto dall'offset
double dParS, dParE ;
m_vroni->GetBisectorParams( i, dParS, dParE) ;
if ( dParS > dParE)
swap( dParS, dParE) ;
if ( abs( dOffs) < dParS || abs( dOffs) > dParE)
continue ;
// calcolo il punto sul bisettore in corrispondenza dell'offset
Point3d pt ;
m_vroni->GetBisectorPointAtParam( i, abs( dOffs), pt.v) ;
pt.ToGlob( m_Frame) ;
// calcolo il vettore tangente
PtrOwner<ICurve> pCrv( GetBisectorCurve( i)) ;
if ( IsNull( pCrv))
return false ;
double dPar ;
Point3d ptTemp ;
Vector3d vtDir ;
if ( ! pCrv->GetParamAtPoint( pt, dPar, 100 * EPS_SMALL) || ! pCrv->GetPointD1D2( dPar, ICurve::FROM_MINUS, ptTemp, &vtDir))
return false ;
vtDir.Normalize() ;
vResult.emplace_back( pt, vtDir) ;
}
}
// libero la memoria di vroni utilizzata per calcolare bisettori
m_vroni->apiFreeBisectorBuffer() ;
}
catch (...) {
LOG_ERROR( GetEGkLogger(), m_vroni->GetExceptionMessage()) ;
return false ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
Voronoi::CalcFatCurve( ICURVEPOVECTOR& vCrvs, double dOffs, bool bSquareEnds, bool bSquareMids)
@@ -957,24 +886,14 @@ Voronoi::CalcVroniOffset( ICRVCOMPOPLIST& OffsList, double dOffs)
}
else {
PtrOwner<CurveArc> pArc( CreateBasicCurveArc()) ;
if ( ! pArc->SetC2P( ptC, ptS, ptE)) {
// se raggio minore di EPS_SMALL approssimo con linea
if ( AreSamePointApprox( ptC, ptS)) {
if ( ! pCrvOffs->AddLine( ptE))
return false ;
}
else
return false ;
}
else {
// verifico orientamento
double dAng = pArc->GetAngCenter() ;
if ( ( nType == CCW && dAng < - EPS_ANG_SMALL) || ( nType == CW && dAng > EPS_ANG_SMALL))
pArc->ToExplementary() ;
// aggiungo alla composita
if ( ! pCrvOffs->AddCurve( Release( pArc)))
return false ;
}
pArc->SetC2P( ptC, ptS, ptE) ;
// verifico orientamento
double dAng = pArc->GetAngCenter() ;
if ( ( nType == CCW && dAng < - EPS_ANG_SMALL) || ( nType == CW && dAng > EPS_ANG_SMALL))
pArc->ToExplementary() ;
// aggiungo alla composita
if ( ! pCrvOffs->AddCurve( Release( pArc)))
return false ;
}
// setto come info la sottocurva da cui si è generata
-1
View File
@@ -56,7 +56,6 @@ class Voronoi
bool CalcVoronoiDiagram( ICURVEPOVECTOR& vCrvs, int nBound = VORONOI_STD_BOUND) ;
bool CalcOffset( ICURVEPOVECTOR& vOffs, double dOffs, int nType) ;
bool CalcSingleCurvesOffset( ICURVEPOVECTOR& vOffs, double dOffs) ;
bool CalcSpecialPointOffset( PNTVECTVECTOR& vResult, double dOffs) ;
bool CalcFatCurve( ICURVEPOVECTOR& vOffs, double dOffs, bool bSquareEnds, bool bSquareMids) ;
bool CalcMedialAxis( ICURVEPOVECTOR& vCrvs, int nSide) ;
bool CalcLimitOffset( int nCrv, bool bLeft, double& dOffs) ;