From 788a5bc4ebd65b9538eda819195b68cb8eaf02fb Mon Sep 17 00:00:00 2001 From: Daniele Bariletti Date: Wed, 17 Apr 2024 14:52:07 +0200 Subject: [PATCH] EgtGeomKernel : - correzioni nella gestione dei trim delle superfici di Bezier. - correzioni varie alle superfici di Bezier. --- SurfAux.cpp | 6 ++--- SurfBezier.cpp | 12 ++++++--- Tree.cpp | 69 +++++++++++++++++++++++++++++++------------------- Tree.h | 4 +-- 4 files changed, 57 insertions(+), 34 deletions(-) diff --git a/SurfAux.cpp b/SurfAux.cpp index 2c8b4ff..50e1be2 100644 --- a/SurfAux.cpp +++ b/SurfAux.cpp @@ -604,7 +604,7 @@ MakeUniform( ISurfFlatRegion*& pSfr, bool& bRescaled, const DBLVECTOR& vU0, cons pSfr_copy->Translate( vtJoin) ; // se sto ritentando MakeUniform, allora faccio anche OFFSET e controOFFSET if ( bRetry) - pSfr_copy->Offset( 10 * EPS_SMALL, ICurve::OFF_FILLET) ; // OFFSET + pSfr_copy->Offset( 10 * EPS_SMALL, ICurve::OFF_CHAMFER) ; // OFFSET if ( pRescaledSfr->IsValid()) { if ( ! pRescaledSfr->Add( *pSfr_copy)) return false ; @@ -617,7 +617,7 @@ MakeUniform( ISurfFlatRegion*& pSfr, bool& bRescaled, const DBLVECTOR& vU0, cons dScaleU = ((int)vU.size() - 1) * SBZ_TREG_COEFF ; if ( pRescaledSfr->IsValid()) { if ( bRetry) - pRescaledSfr->Offset( -10 * EPS_SMALL, ICurve::OFF_FILLET) ; //contro OFFSET + pRescaledSfr->Offset( -10 * EPS_SMALL, ICurve::OFF_CHAMFER) ; //contro OFFSET pSfr = Release( pRescaledSfr) ; } } @@ -628,7 +628,7 @@ MakeUniform( ISurfFlatRegion*& pSfr, bool& bRescaled, const DBLVECTOR& vU0, cons if ( ! IsNull( pRescaledSfr) && pRescaledSfr->IsValid()) { if ( bRetry) - pRescaledSfr->Offset( -10 * EPS_SMALL, ICurve::OFF_FILLET) ; // contro OFFSET + pRescaledSfr->Offset( -10 * EPS_SMALL, ICurve::OFF_CHAMFER) ; // contro OFFSET pSfr = Release( pRescaledSfr) ; } diff --git a/SurfBezier.cpp b/SurfBezier.cpp index 3aee5ae..0c5df9d 100644 --- a/SurfBezier.cpp +++ b/SurfBezier.cpp @@ -1515,7 +1515,10 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin) const // costruttore della superficie POLYLINEMATRIX vvPL ; //POLYLINEVECTOR vPL ; // per usare i polygon basic - Tree Tree( this, true) ; + //Tree Tree( this, true) ; + Tree Tree ; + if ( ! Tree.SetSurf( this, true)) + return nullptr ; BIPNTVECTOR vTrees ; Tree.GetIndependentTrees( vTrees) ; bool bTest = false ; // per debug @@ -1536,7 +1539,8 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin) const //Tree.BuildTree( 5 * LIN_TOL_FINE, 0.1) ; Tree.BuildTree( dTol, dSideMin) ; } - Tree.GetPolygons( vvPL) ; + if ( ! Tree.GetPolygons( vvPL)) + continue ; //Tree.GetPolygonsBasic( vPL) ; // per usare i polygon basic // aggiorno la chiusura della superficie @@ -1597,7 +1601,9 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin) const bool SurfBezier::GetLeaves( vector>& vLeaves) const { - Tree Tree( this, true) ; + Tree Tree ; + if ( ! Tree.SetSurf( this, true)) + return false ; BIPNTVECTOR vTrees ; Tree.GetIndependentTrees( vTrees) ; for ( int i = 0 ; i < int( vTrees.size()) ; ++ i) { diff --git a/Tree.cpp b/Tree.cpp index b27bf97..f7f4224 100644 --- a/Tree.cpp +++ b/Tree.cpp @@ -26,6 +26,7 @@ #include "DistPointCrvComposite.h" #include "/EgtDev/Include/EGkSfrCreate.h" #include +#include using namespace std ; @@ -39,13 +40,13 @@ Tree::Tree( void) m_mTree.insert( pair< int, Cell>( -1, cRoot)) ; } -//---------------------------------------------------------------------------- -Tree::Tree( const SurfBezier* pSrfBz, const bool bSplitPatches, const Point3d& ptMin, const Point3d& ptMax) - : m_pSrfBz( nullptr), m_bTrimmed( false), m_bBilinear( false), m_bMulti( false), m_bClosedU( false), m_bClosedV( false), m_vbPole( { false, false, false, false}), - m_bSplitPatches( true), m_bTestMode( false) -{ - SetSurf( pSrfBz, bSplitPatches, ptMin, ptMax) ; -} +////---------------------------------------------------------------------------- +//Tree::Tree( const SurfBezier* pSrfBz, const bool bSplitPatches, const Point3d& ptMin, const Point3d& ptMax) +// : m_pSrfBz( nullptr), m_bTrimmed( false), m_bBilinear( false), m_bMulti( false), m_bClosedU( false), m_bClosedV( false), m_vbPole( { false, false, false, false}), +// m_bSplitPatches( true), m_bTestMode( false) +//{ +// SetSurf( pSrfBz, bSplitPatches, ptMin, ptMax) ; +//} //---------------------------------------------------------------------------- Tree::~Tree( void) @@ -73,8 +74,11 @@ Tree::LimitLoop( PolyLine& pl, POLYLINEVECTOR& vPl) const bInverted = true ; } PtrOwner pParamTrim( GetSurfFlatRegionRectangle( SBZ_TREG_COEFF * m_nSpanU, SBZ_TREG_COEFF * m_nSpanV)) ; - if ( ! pParamTrim->Intersect( *pSfrTrim) || ! pParamTrim->IsValid()) - return false ; + if ( ! pParamTrim->Intersect( *pSfrTrim) || ! pParamTrim->IsValid()) { + pParamTrim->Offset( 10 * EPS_SMALL, ICurve::OFF_EXTEND) ; + if ( ! pParamTrim->Intersect( *pSfrTrim) || ! pParamTrim->IsValid()) + return false ; + } // ricostruisco la curva tenendo solo le parti dentro lo spazio parametrico // devo recuperare la polyline dei bordi dei vari chunk creati @@ -90,14 +94,17 @@ Tree::LimitLoop( PolyLine& pl, POLYLINEVECTOR& vPl) const vPl.push_back( plApprox) ; } - return false ; + return true ; } //---------------------------------------------------------------------------- -void +bool Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMin, const Point3d& ptMax) { + if ( pSrfBz == nullptr || ! pSrfBz->IsValid()) + return false ; // pulisco i vettori membri + m_mTree.clear() ; m_vnLeaves.clear() ; m_vnParents.clear() ; m_mVert.clear() ; @@ -159,7 +166,8 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi bCCW = false ; // limito il loop allo spazio parametrico // potrei ottenere più loop a partire da quello originale POLYLINEVECTOR vPlLimited ; - LimitLoop( plApprox, vPlLimited) ; + if ( ! LimitLoop( plApprox, vPlLimited)) + return false ; for ( int k = 0 ; k < int( vPlLimited.size()) ; ++k) m_vPlApprox.push_back( tuple(vPlLimited[k], bCCW)) ; } @@ -172,7 +180,7 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi ptTop = ptMax ; bLimited = true ; } - m_mTree.clear() ; + //m_mTree.clear() ; Cell cRoot( ptMin, ptTop) ; m_mTree.insert( pair< int, Cell>( -1, cRoot)) ; Point3d ptP00, ptP10, ptP11, ptP01 ; @@ -350,6 +358,7 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi m_vDim.push_back( ( dLen1 > EPS_ZERO ? dLen1 : 1)) ; m_vDim.push_back( ( dLen2 > EPS_ZERO ? dLen2 : 1)) ; m_vDim.push_back( ( dLen3 > EPS_ZERO ? dLen3 : 1)) ; + return true ; } //---------------------------------------------------------------------------- @@ -1388,15 +1397,15 @@ Tree::GetDepth( int nId, int nRef = -2) const return i ; } -//---------------------------------------------------------------------------- -struct generator -{ - int value ; - generator( void) - { value = -1 ; } - int operator() () - { return ++value ; } -} ; +////---------------------------------------------------------------------------- +//struct generator +//{ +// int value ; +// generator( void) +// { value = -1 ; } +// int operator() () +// { return ++value ; } +//} ; //---------------------------------------------------------------------------- bool @@ -1444,7 +1453,8 @@ Tree::GetPolygons( POLYLINEMATRIX& vPolygons) INTVECTOR vnParentChunk ; // vettore in cui salvo i loop che non appartengono al poligono che sto cotruendo nel ciclo attuale e da cui ripasserò dopo INTVECTOR vToCheck( (int) m_mTree[nId].m_vInters.size()) ; - generate_n( vToCheck.begin(), (int) m_mTree[nId].m_vInters.size(), generator()) ; + //generate_n( vToCheck.begin(), (int) m_mTree[nId].m_vInters.size(), generator()) ; + iota (vToCheck.begin(), vToCheck.end(), 0) ; // numero di poligoni aggiunti int nPoly = 0 ; // scorro sui vettori intersezione della cella nId e sui suoi vertici @@ -3531,10 +3541,16 @@ Tree::CheckIfBetween( const Inters& inA, const Inters& inB) const } else if ( nEdge == 7) nEdge = 0 ; - if ( AreSameEdge( inA.nIn, inA.nOut) && ! CheckIfBefore( inA.nIn, inA.vpt[0], inA.vpt.back())) + if ( AreSameEdge( inA.nIn, inA.nOut) && ! CheckIfBefore( inA.nIn, inA.vpt[0], inA.vpt.back(), nEdge)) vEdges.push_back( nEdge) ; + int nEdgeIn = inA.nIn ; + if ( nEdgeIn > 3 && nEdgeIn != 7) { + nEdgeIn = nEdgeIn - 4 ; + } + else if ( nEdgeIn == 7) + nEdgeIn = 0 ; // creo la sequenza di Edges da scorrere per trovare i possibili validNextStart - while ( ! AreSameEdge( nEdge, inA.nIn) || (int) vEdges.size() == 0) { + while ( ! AreSameEdge( nEdge, nEdgeIn) || (int) vEdges.size() == 0) { vEdges.push_back( nEdge) ; if ( nEdge == 3) nEdge = 0 ; @@ -3883,7 +3899,8 @@ Tree::CreateCellContour( POLYLINEMATRIX& vPolygons) // preparo tutto per poter chiamare la createCellPolygon m_vnLeaves.push_back( nRoot) ; INTVECTOR vToCheck( (int) m_mTree.at(nRoot).m_vInters.size()) ; - generate_n( vToCheck.begin(), (int) m_mTree.at(nRoot).m_vInters.size(), generator()) ; + //generate_n( vToCheck.begin(), (int) m_mTree.at(nRoot).m_vInters.size(), generator()) ; + iota( vToCheck.begin(), vToCheck.end(), 0) ; int nPoly = 0 ; INTVECTOR vnParentChunk ; PolyLine pl ; diff --git a/Tree.h b/Tree.h index 22dc08c..e656220 100644 --- a/Tree.h +++ b/Tree.h @@ -231,9 +231,9 @@ class Tree public : ~Tree( void) ; Tree( void) ; - Tree ( const SurfBezier* pSrfBz, bool bSplitPatches = true, const Point3d& ptMin = ORIG, const Point3d& ptMax = ORIG) ; + //Tree ( const SurfBezier* pSrfBz, bool bSplitPatches = true, const Point3d& ptMin = ORIG, const Point3d& ptMax = ORIG) ; 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 - void SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches = true, const Point3d& ptMin = ORIG, const Point3d& ptMax = ORIG) ; + 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 // dSideMin � lunghezza minima del lato di una cella nello spazio reale