From 469e660da085903e4abecceece07d1baf6848813 Mon Sep 17 00:00:00 2001 From: DarioS Date: Mon, 24 Apr 2023 15:47:41 +0200 Subject: [PATCH] EgtGeomKernel 2.5d4 : - in ApproxWithLines di CurveComposite aggiunta gestione tipo approssimazione APL_SPECIAL_INT (come SPECIAL ma con garanzia di tre punti su curve non rettilinee) - migliorato calcolo AreaXY e Area di Curve grazie al nuovo tipo di approssimazione - migliorata in Dump gestione decimali di Area - in OffsetCurve corretto possibile errore con curve chiuse dovuto a mancata unione tratti tra autointersezioni suddiviso tra inizio e fine curva. --- CurveAux.cpp | 12 +++++++----- CurveComposite.cpp | 16 ++++++++++++++-- EgtGeomKernel.rc | Bin 11710 -> 11710 bytes OffsetCurve.cpp | 34 ++++++++++++++++++++++++++++++---- 4 files changed, 51 insertions(+), 11 deletions(-) diff --git a/CurveAux.cpp b/CurveAux.cpp index 239b8df..4e0ba4d 100644 --- a/CurveAux.cpp +++ b/CurveAux.cpp @@ -294,7 +294,7 @@ CurveGetAreaXY( const ICurve& crvC, double& dArea) return false ; // approssimo la curva con una polilinea PolyLine PL ; - crvC.ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL) ; + crvC.ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL_INT, PL) ; // calcolo l'area double dAreaXY = 0 ; PL.GetAreaXY( dAreaXY) ; @@ -313,7 +313,7 @@ CurveGetArea( const ICurve& crvC, Plane3d& plPlane, double& dArea) return false ; // approssimo la curva con una polilinea PolyLine PL ; - crvC.ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL) ; + crvC.ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL_INT, PL) ; // calcolo l'area Plane3d plMyPlane ; double dMyArea = 0 ; @@ -364,9 +364,11 @@ CurveDump( const ICurve& crvC, string& sOut, bool bMM, const char* szNewLine) // altri dati per curva chiusa double dAreaXY ; if ( CurveGetAreaXY( crvC, dAreaXY)) { - bool bCCW = ( dAreaXY > 0) ; + bool bCCW = ( dAreaXY > 0) ; + double dAreaUi = GetAreaInUiUnits( abs( dAreaXY), bMM) ; + int nDec = ( dAreaUi > 100 ? 1 : ( dAreaUi > 0.1 ? 3 : 6)) ; sOut += string( "Closed") + ( bCCW ? " CCW" : " CW") + " AreaXY=" + - ToString( GetAreaInUiUnits( abs( dAreaXY), bMM),1) + szNewLine ; + ToString( dAreaUi, nDec) + szNewLine ; } return true ; @@ -728,7 +730,7 @@ FlattenCurve( const ICurve& crCrv, double dToler, double dAngToler, int nFlag) return nullptr ; // Verifico se curva già piatta PolyLine PL ; - if ( ! crCrv.ApproxWithLines( LIN_TOL_FINE, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL)) + if ( ! crCrv.ApproxWithLines( LIN_TOL_FINE, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL_INT, PL)) return nullptr ; bool bFlat = true ; Plane3d plFlat ; plFlat.Set( ptCen, plMid.GetVersN()) ; diff --git a/CurveComposite.cpp b/CurveComposite.cpp index a642003..d94b97a 100644 --- a/CurveComposite.cpp +++ b/CurveComposite.cpp @@ -985,7 +985,7 @@ CurveComposite::GetCentroid( Point3d& ptCen) const return false ; // approssimo la curva con una polilinea PolyLine PL ; - if ( ! ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, APL_SPECIAL, PL)) + if ( ! ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, APL_SPECIAL_INT, PL)) return false ; // calcolo il centro mediante PolygonPlane Point3d ptP ; @@ -1313,7 +1313,7 @@ CurveComposite::ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, P dAngTolDeg = max( dAngTolDeg, ANG_TOL_MIN_DEG) ; // se speciale, approssimo ogni singola entità e conservo le estremità interne (joint) - if ( nType == APL_SPECIAL) { + if ( nType == APL_SPECIAL || nType == APL_SPECIAL_INT) { // eseguo approssimazione double dStartPar = 0 ; for ( auto& pCrv : m_CrvSmplS) { @@ -1324,6 +1324,18 @@ CurveComposite::ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, P PolyLine PLSmpl ; if ( ! pCrv->ApproxWithLines( dLinTol, dAngTolDeg, nType, PLSmpl)) return false ; + // se richiesto almeno un punto interno con curve non rettilinee e ci sono solo gli estremi + if ( nType == APL_SPECIAL_INT && pCrv->GetType() != CRV_LINE && PLSmpl.GetPointNbr() == 2) { + // aggiungo il punto interno + Point3d ptMid ; + if ( ! pCrv->GetMidPoint( ptMid)) + return false ; + double dU ; + PLSmpl.GetLastU( dU) ; + dU /= 2 ; + PNTULIST& List = PLSmpl.GetUPointList() ; + List.insert( ++ List.begin(), { ptMid, dU}) ; + } // ripristino estrusione e spessore della curva semplice (annullandoli) pCrv->SetExtrusion( V_NULL) ; pCrv->SetThickness( 0) ; diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index 40c1ad1bd2ee110498c80bafc2197922d8e985ac..895c8519d66f4df6570b11769272dccd40f8a290 100644 GIT binary patch delta 94 zcmdlNy)SyhFE&P#&A-_cnHfzcD{|{@_Trkr0u;H;XNwSVW8B;$>;>dw2zN+>g;Df- LFmBFL4&ed-WjGrO delta 94 zcmdlNy)SyhFE&Qw&A-_cnHh~ID{|{@_Trkr0u;H;XNwSVW8B;$>;>dw2zN+>g;Df- LFmBFL4&ed-W11TR diff --git a/OffsetCurve.cpp b/OffsetCurve.cpp index d3e5adc..a41817d 100644 --- a/OffsetCurve.cpp +++ b/OffsetCurve.cpp @@ -422,6 +422,10 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType) m_CrvLst.push_back( Release( pCrvCompo)) ; CurveComposite* pCompo1 = GetBasicCurveComposite( m_CrvLst.front()) ; + // salvo punto iniziale + Point3d ptStart ; + pCompo1->GetStartPoint( ptStart) ; + // quinto passo : spezzatura della curva composita negli eventuali punti di auto-intersezione // calcolo le auto-intersezioni SelfIntersCurve sintC( *pCompo1) ; @@ -454,7 +458,6 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType) vLen.pop_back() ; } // eseguo la divisione - int nCount = 1 ; double dUPrev = 0 ; double dLenPrev = 0 ; for ( int i = 0 ; i < int( vU.size()) ; ++ i) { @@ -466,7 +469,6 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType) if ( IsNull( pCopy)) return false ; m_CrvLst.push_back( Release( pCopy)) ; - ++ nCount ; // trimmo l'originale pCompo1->TrimStartEndAtParam( dUPrev, vU[i]) ; // la copia diventa il nuovo corrente @@ -474,9 +476,20 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType) dUPrev = vU[i] ; dLenPrev = vLen[i] ; } - // se fatta almeno una suddivisione, trimmo l'ultima parte - if ( dUPrev > EPS_PARAM) + // se fatta almeno una suddivisione + if ( dUPrev > EPS_PARAM) { + // trimmo l'ultima parte pCompo1->TrimStartAtParam( dUPrev) ; + // sistemo le curve chiuse con due parti di una stessa curva all'inizio e alla fine + if ( bClosed) { + if ( vU[0] > EPS_PARAM && vLen[0] >= 2 * EPS_SMALL) { + // accodo il finale al'iniziale + pCompo1 = GetBasicCurveComposite( m_CrvLst.front()) ; + pCompo1->AddCurve( m_CrvLst.back(), false, 10 * EPS_SMALL) ; + m_CrvLst.pop_back() ; + } + } + } // sesto passo : se curva aperta, elimino i tratti che stanno nella circonferenza di offset dei punti estremi if ( ! bClosed) { @@ -631,6 +644,19 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType) } ++ iIter ; } + // se chiusa riporto l'inizio del primo loop alla posizione iniziale + if ( bClosed) { + for ( auto iIter = m_CrvLst.begin() ; iIter != m_CrvLst.end() ; ++ iIter) { + CurveComposite* pCrvCo = GetBasicCurveComposite( *iIter) ; + DistPointCurve dstPC( ptStart, *pCrvCo) ; + if ( dstPC.IsEpsilon( 10 * EPS_SMALL)) { + double dU ; int nFlag ; + dstPC.GetParamAtMinDistPoint( 0, dU, nFlag) ; + pCrvCo->ChangeStartPoint( round( dU)) ; + break ; + } + } + } // nono passo : se con smusso o estensione, sostituisco i fillet con questi if ( ( nType & ICurve::OFF_CHAMFER) != 0 || ( nType & ICurve::OFF_EXTEND) != 0) {