From b6a7ce4eefb3a60853b38c89ca862943bbb9c91b Mon Sep 17 00:00:00 2001 From: SaraP Date: Tue, 9 Jul 2024 10:25:24 +0200 Subject: [PATCH] EgtGeomKernel : - aggiunte funzioni che restituiscono il valore di offset che fa sparire una curva chiusa, una flat region o un suo chunk. --- CurveAux.cpp | 23 ++++++++++ OffsetAux.cpp | 14 +++--- OffsetAux.h | 4 +- SurfFlatRegion.cpp | 37 +++++++++++++++ SurfFlatRegion.h | 2 + Voronoi.cpp | 110 +++++++++++++++++++++++++++++++++------------ Voronoi.h | 2 + 7 files changed, 153 insertions(+), 39 deletions(-) diff --git a/CurveAux.cpp b/CurveAux.cpp index b2edb45..2036ac9 100644 --- a/CurveAux.cpp +++ b/CurveAux.cpp @@ -1472,6 +1472,29 @@ CalcCurveFatCurve( const ICurve& crvC, ICURVEPOVECTOR& vCrvs, double dRadius, bo return pVoronoiObj->CalcFatCurve( vCrvs, dRadius, bSquareEnds, bSquareMids) ; } +//---------------------------------------------------------------------------- +bool +CalcCurveLimitOffset( const ICurve& crvC, double& dOffs) +{ + // se curva aperta errore + if ( ! crvC.IsClosed()) + return false ; + + Voronoi* pVoronoiObj = GetCurveVoronoi( crvC) ; + if ( pVoronoiObj == nullptr) + return false ; + + // verifico l'orientamento della curva rispetto al piano di vroni per capire se l'offset critico è quello a destra ( offset > 0) + // oppure quello a sinistra ( offset < 0) + Plane3d plPlane, plPlaneVroni ; + double dArea ; + if ( ! CurveGetArea( crvC, plPlane, dArea) || ! pVoronoiObj->GetVroniPlane( plPlaneVroni)) + return false ; + bool bLeft = AreSameVectorApprox( plPlane.GetVersN(), plPlaneVroni.GetVersN()) ; + + return pVoronoiObj->CalcLimitOffset( 0, bLeft, dOffs) ; +} + //---------------------------------------------------------------------------- void ResetCurveVoronoi( const ICurve& crvC) diff --git a/OffsetAux.cpp b/OffsetAux.cpp index ad683bb..9b5c30e 100644 --- a/OffsetAux.cpp +++ b/OffsetAux.cpp @@ -2,7 +2,7 @@ // EgalTech 2013-2013 //---------------------------------------------------------------------------- // File : OffsetAux.cpp Data : 23.11.23 Versione : 2.5k5 -// Contenuto : Implementazione di alcune funzioni di utilità per gli offset delle curve. +// Contenuto : Implementazione di alcune funzioni di utilità per gli offset delle curve. // // // @@ -25,11 +25,7 @@ IdentifyFillets( ICurveComposite* pCrvCo, double dDist) { // identifico le sottocurve di tipo fillet e assegno loro temp param 1.0 per riconoscerle nella funzione AdjustCurveFillets for ( int i = 0 ; i < pCrvCo->GetCurveCount() ; i ++) { - // recupero la curva - PtrOwner pCrv( pCrvCo->GetCurve(i)->Clone()) ; - if ( IsNull( pCrv)) - return false ; - if ( IsFillet( pCrv, dDist)) + if ( IsFillet( pCrvCo->GetCurve( i), dDist)) pCrvCo->SetCurveTempParam( i, 1.0) ; else pCrvCo->SetCurveTempParam( i, 0.0) ; @@ -39,12 +35,14 @@ IdentifyFillets( ICurveComposite* pCrvCo, double dDist) //---------------------------------------------------------------------------- bool -IsFillet( ICurve* pCrv, double dDist) +IsFillet( const ICurve* pCrv, double dDist) { + if ( pCrv == nullptr) + return false ; // deve essere un arco if ( pCrv->GetType() != CRV_ARC) return false ; - CurveArc* pArc = GetBasicCurveArc( pCrv) ; + const CurveArc* pArc = GetBasicCurveArc( pCrv) ; // deve avere raggio uguale alla distanza di offset if ( abs( pArc->GetRadius() - abs( dDist)) > EPS_SMALL) return false ; diff --git a/OffsetAux.h b/OffsetAux.h index 6564059..488af20 100644 --- a/OffsetAux.h +++ b/OffsetAux.h @@ -2,7 +2,7 @@ // EgalTech 2013-2013 //---------------------------------------------------------------------------- // File : OffsetAux.h Data : 23.11.23 Versione : 2.5k5 -// Contenuto : Dichiarazione di alcune funzioni di utilità per gli offset delle curve. +// Contenuto : Dichiarazione di alcune funzioni di utilità per gli offset delle curve. // // // @@ -16,6 +16,6 @@ //---------------------------------------------------------------------------- bool IdentifyFillets( ICurveComposite* pCrvCo, double dDist) ; -bool IsFillet( ICurve* pCrv, double dDist) ; +bool IsFillet( const ICurve* pCrv, double dDist) ; bool AdjustCurveFillets( ICurveComposite* pCrvCo, double dDist, int nType) ; bool ModifyFillet( ICurve* pCrv, double dDist, int nType, ICurveComposite& ccAux) ; diff --git a/SurfFlatRegion.cpp b/SurfFlatRegion.cpp index 0391dc8..0027f7c 100644 --- a/SurfFlatRegion.cpp +++ b/SurfFlatRegion.cpp @@ -1481,6 +1481,43 @@ SurfFlatRegion::CalcMedialAxis( ICURVEPOVECTOR& vCrvs, int nSide) const return m_pVoronoiObj->CalcMedialAxis( vCrvs, nSide) ; } +//---------------------------------------------------------------------------- +bool +SurfFlatRegion::GetChunkMaxOffset( int nChunk, double& dOffs) const +{ + // verifico se è stato calcolato Voronoi + if ( m_pVoronoiObj == nullptr) + if ( ! CalcVoronoiObject()) + return false ; + + // il massimo offset per il chunk è il massimo offset del suo loop esterno + // ( il diagramma di Voronoi tiene già conto della limitazione con i loop interni) + int nInd = GetIndFromChunkLoop( nChunk, 0) ; + return m_pVoronoiObj->CalcLimitOffset( nInd, true, dOffs) ; +} + +//---------------------------------------------------------------------------- +bool +SurfFlatRegion::GetMaxOffset( double& dOffs) const +{ + int nChunks = GetChunkCount() ; + if ( nChunks == 0) + return false ; + + // calcolo il massimo fra gli offset limite di tutti i suoi chunks + if ( ! GetChunkMaxOffset( 0, dOffs)) + return false ; + for ( int i = 1 ; i < nChunks ; i++) { + double dCurrOffs ; + if ( ! GetChunkMaxOffset( i, dCurrOffs)) + return false ; + if ( dCurrOffs > dOffs) + dOffs = dCurrOffs ; + } + + return true ; +} + //---------------------------------------------------------------------------- bool SurfFlatRegion::SetCurveTempProp( int nChunk, int nLoop, int nCrv, int nProp, int nPropInd) diff --git a/SurfFlatRegion.h b/SurfFlatRegion.h index 9173c1c..c1198e8 100644 --- a/SurfFlatRegion.h +++ b/SurfFlatRegion.h @@ -105,6 +105,8 @@ class SurfFlatRegion : public ISurfFlatRegion, public IGeoObjRW int GetChunkSimpleClassification( int nChunk, const ISurfFlatRegion& Other, int nOthChunk) const override ; // compare only outsides bool CalcVoronoiDiagram( ICURVEPOVECTOR& vCrvs, int nBound = 3) const override ; bool CalcMedialAxis( ICURVEPOVECTOR& vCrvs, int nSide) const override ; + bool GetChunkMaxOffset( int nChunk, double& dOffs) const override ; + bool GetMaxOffset( double& dOffs) const override ; void ResetVoronoiObject( void) const override ; bool SetCurveTempProp( int nChunk, int nLoop, int nCrv, int nProp, int nPropInd = 0) override ; bool GetCurveTempProp( int nChunk, int nLoop, int nCrv, int& nProp, int nPropInd = 0) const override ; diff --git a/Voronoi.cpp b/Voronoi.cpp index 2c894bd..7d05caa 100644 --- a/Voronoi.cpp +++ b/Voronoi.cpp @@ -371,6 +371,16 @@ Voronoi::GetCurve( int nId) const return pCrv ; } +//---------------------------------------------------------------------------- +bool +Voronoi::GetVroniPlane( Plane3d& plPlane) const +{ + if ( ! IsValid()) + return false ; + plPlane.Set( m_Frame.Orig(), m_Frame.VersZ()) ; + return plPlane.IsValid() ; +} + //---------------------------------------------------------------------------- bool Voronoi::CalcVoronoi( int nBound) @@ -512,12 +522,12 @@ Voronoi::CalcVoronoiDiagram( ICURVEPOVECTOR& vCrvs, int nBound) // verifico se necessario calcolo Voronoi if ( ! m_bVDComputed || nBound != m_nBound) CalcVoronoi( nBound) ; - + for ( int i = 4 ; i < m_vroni->GetNumberOfEdges() ; i ++) { // recupero la curva del bisettore PtrOwner pCrv( GetBisectorCurve( i)) ; if ( ! IsNull( pCrv) && pCrv->IsValid()) - vCrvs.emplace_back( Release( pCrv)) ; + vCrvs.emplace_back( Release( pCrv)) ; } // libero la memoria di vroni utilizzata per calcolare bisettore @@ -609,31 +619,31 @@ Voronoi::CalcOffset( ICURVEPOVECTOR& vOffs, double dOffs, int nType) AdjustClosedOffsetCurve( *pCrv, dOffs) ; else AdjustOpenOffsetCurve( *pCrv, dOffs) ; - - if ( pCrv->IsValid()) { - // eventuale inversione - if ( dOffs > EPS_SMALL) - pCrv->Invert() ; + + if ( pCrv->IsValid()) { + // eventuale inversione + if ( dOffs > EPS_SMALL) + pCrv->Invert() ; - // sistemo i raccordi - if ( ( nType & ICurve::OFF_CHAMFER) != 0 || ( nType & ICurve::OFF_EXTEND) != 0) { - IdentifyFillets( pCrv, dOffs) ; - AdjustCurveFillets( pCrv, dOffs, nType) ; - } + // sistemo i raccordi + if ( ( nType & ICurve::OFF_CHAMFER) != 0 || ( nType & ICurve::OFF_EXTEND) != 0) { + IdentifyFillets( pCrv, dOffs) ; + AdjustCurveFillets( pCrv, dOffs, nType) ; + } - if ( bClosed) { - // forzo chiusura della curva per evitare piccole imprecisioni - pCrv->Close() ; - // sistemo il punto di inizio - AdjustOffsetStart( *pCrv) ; - } + if ( bClosed) { + // forzo chiusura della curva per evitare piccole imprecisioni + pCrv->Close() ; + // sistemo il punto di inizio + AdjustOffsetStart( *pCrv) ; + } - // porto nel frame globale - pCrv->ToGlob( m_Frame) ; - // unisco le parti allineate - pCrv->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG, true, true) ; - // aggiungo al vettore finale - vOffs.emplace_back( pCrv) ; + // porto nel frame globale + pCrv->ToGlob( m_Frame) ; + // unisco le parti allineate + pCrv->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG, true, true) ; + // aggiungo al vettore finale + vOffs.emplace_back( pCrv) ; } else delete pCrv ; @@ -1011,7 +1021,8 @@ Voronoi::Translate( const Vector3d & vtMove) } //--------------------------------------------------------------------------- -bool Voronoi::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dAngDeg) +bool +Voronoi::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dAngDeg) { if ( ! IsValid()) return false ; @@ -1019,7 +1030,8 @@ bool Voronoi::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dAngDeg) } //--------------------------------------------------------------------------- -bool Voronoi::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, double dSinAng) +bool +Voronoi::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, double dSinAng) { if ( ! IsValid()) return false ; @@ -1027,7 +1039,8 @@ bool Voronoi::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, } //--------------------------------------------------------------------------- -bool Voronoi::ToGlob( const Frame3d& frRef) +bool +Voronoi::ToGlob( const Frame3d& frRef) { if ( ! IsValid()) return false ; @@ -1035,7 +1048,8 @@ bool Voronoi::ToGlob( const Frame3d& frRef) } //--------------------------------------------------------------------------- -bool Voronoi::ToLoc( const Frame3d& frRef) +bool +Voronoi::ToLoc( const Frame3d& frRef) { if ( ! IsValid()) return false ; @@ -1043,9 +1057,47 @@ bool Voronoi::ToLoc( const Frame3d& frRef) } //--------------------------------------------------------------------------- -bool Voronoi::LocToLoc( const Frame3d& frOri, const Frame3d& frDest) +bool +Voronoi::LocToLoc( const Frame3d& frOri, const Frame3d& frDest) { if ( ! IsValid()) return false ; return m_Frame.LocToLoc( frOri, frDest) ; } + +//--------------------------------------------------------------------------- +bool +Voronoi::CalcLimitOffset( int nCrv, bool bLeft, double& dOffs) +{ + if ( nCrv < 0 || nCrv > int( m_vpCrvs.size()) - 1) + return false ; + // se curva aperta errore + if ( ! m_vpCrvs[nCrv]->IsClosed()) + return false ; + + dOffs = - INFINITO ; + try { + // verifico se necessario calcolo Voronoi + if ( ! m_bVDComputed) + CalcVoronoi() ; + + for ( int i = 4 ; i < m_vroni->GetNumberOfEdges() ; i ++) { + // verifico se è un bisettore relativo alla curva richiesta e dal lato opportuno + if ( m_vroni->IsRelatedEdge( i, nCrv, bLeft)) { + // calcolo i parametri del bisettore + double dParS, dParE ; + m_vroni->GetBisectorParams( i, dParS, dParE) ; + dOffs = max( { dParS, dParE, dOffs}) ; + } + } + + // libero la memoria di vroni dedicata agli offset + m_vroni->apiFreeOffsetData() ; + } + catch (...) { + LOG_ERROR( GetEGkLogger(), m_vroni->GetExceptionMessage()) ; + return false ; + } + + return true ; +} diff --git a/Voronoi.h b/Voronoi.h index 5ffc9d6..502cf91 100644 --- a/Voronoi.h +++ b/Voronoi.h @@ -50,10 +50,12 @@ class Voronoi ICurve* GetCurve( int nId) const ; int GetCurveCount( void) const { return m_vpCrvs.size() ; } ; + bool GetVroniPlane( Plane3d& plPlane) const ; bool CalcVoronoiDiagram( ICURVEPOVECTOR& vCrvs, int nBound = VORONOI_STD_BOUND) ; bool CalcOffset( ICURVEPOVECTOR& vOffs, double dOffs, int nType) ; bool CalcFatCurve( ICURVEPOVECTOR& vOffs, double dOffs, bool bSquareEnds, bool bSquareMids) ; bool CalcMedialAxis( ICURVEPOVECTOR& vCrvs, int nSide) ; + bool CalcLimitOffset( int nCrv, bool bLeft, double& dOffs) ; bool Translate( const Vector3d& vtMove) ; bool Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dAngDeg) ;