From a149384fbb145bc4d5b26affc923fbc2a03f8d60 Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Wed, 19 Dec 2018 08:45:59 +0000 Subject: [PATCH] EgtGeomKernel 1.9l3 : - modifiche a ApproxWithArcsEx di CurveComposite per eliminare le parti allineate in tolleranza - migliorate RemoveAlignedPoints di PolyLine e PolyArc - migliorata GetSurfFlatRegionFromFatCurve. --- CurveComposite.cpp | 3 +- EgtGeomKernel.rc | Bin 11718 -> 11718 bytes MC_Tables.h | 2 + PolyArc.cpp | 90 ++++++++++++++++++++++++++++++++++++++++++++- PolyLine.cpp | 31 +++++++++++----- SfrCreate.cpp | 17 ++++++--- 6 files changed, 126 insertions(+), 17 deletions(-) diff --git a/CurveComposite.cpp b/CurveComposite.cpp index e6a7a8f..b2f55a9 100644 --- a/CurveComposite.cpp +++ b/CurveComposite.cpp @@ -1416,7 +1416,8 @@ CurveComposite::ApproxWithArcsEx( double dLinTol, double dAngTolDeg, double dLin // assegno estrusione della curva composita PA.SetExtrusion( m_VtExtr) ; - return true ; + // eliminazione dei punti in tolleranza + return PA.RemoveAlignedPoints( dLinTol) ; } //---------------------------------------------------------------------------- diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index bfe00a4392112675be6cc7c01ca7eb395ef63768..b0c67ead7185071af67ce92b90bede1a420cdf88 100644 GIT binary patch delta 110 zcmX>WeJpyzA2vqg&G-4vGfl1&(wY2&Q;pGhvZAo=W*@FeEMOU1X1ItO delta 110 zcmX>WeJpyzA2vp#&G-4vGfl1&(wY2&Q;pGRvZAo=W*@FeEMOU1X1ItO +using namespace std ; //---------------------------------------------------------------------------- PolyArc::PolyArc( void) @@ -508,4 +512,88 @@ PolyArc::Invert( bool bInvertU) } } return true ; -} \ No newline at end of file +} + +//---------------------------------------------------------------------------- +static bool +PointsInTolerance( const PNTVECTOR& vRPT, const Point3d& ptP1, const Point3d& ptP2, double dSqTol) +{ + for ( const auto& ptQ : vRPT) { + double dSqDist ; + if ( ! DistPointLine( ptQ, ptP1, ptP2).GetSqDist( dSqDist) || dSqDist > dSqTol) + return false ; + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +PolyArc::RemoveAlignedPoints( double dToler) +{ + // se non ci sono almeno 3 punti, esco subito + if ( m_lUPointBs.size() < 3) + return true ; + // controllo minimo valore di tolleranza + dToler = max( dToler, LIN_TOL_MIN) ; + double dSqTol = dToler * dToler ; + // si analizza la distanza di un punto dal segmento che unisce precedente e successivo + // punto precedente + auto precP = m_lUPointBs.begin() ; + // punto corrente + auto currP = next( precP) ; + // punto successivo + auto nextP = next( currP) ; + // lista dei punti appena rimossi + PNTVECTOR vRPT ; vRPT.reserve( 20) ; + // mentre esiste un successivo + while ( nextP != m_lUPointBs.end()) { + double dSqDist = 2 * dSqTol ; + // se precedente e corrente non hanno bulge (non sono archi i due tratti) + if ( abs( precP->dB) < EPS_SMALL && abs( currP->dB) < EPS_SMALL) { + // distanza del punto corrente dal segmento che unisce gli adiacenti + DistPointLine( currP->ptP, precP->ptP, nextP->ptP).GetSqDist( dSqDist) ; + } + // se da eliminare e gli altri eliminati stanno nella tolleranza + if ( dSqDist < dSqTol && PointsInTolerance( vRPT, precP->ptP, nextP->ptP, dSqTol)) { + // aggiungo il punto nella lista dei rimossi + vRPT.emplace_back( currP->ptP) ; + // elimino il punto + m_lUPointBs.erase( currP) ; + // avanzo con corrente e successivo + currP = nextP ; + ++ nextP ; + } + // altrimenti da tenere + else { + // cancello la lista dei rimossi + vRPT.clear() ; + // avanzo il terzetto di uno step + precP = currP ; + currP = nextP ; + ++ nextP ; + } + } + // se curva chiusa con almeno 4 punti, devo analizzare il terzetto attorno alla chiusura + if ( IsClosed() && m_lUPointBs.size() >= 4) { + // precP e currP sono già corretti + // il primo punto ripete l'ultimo (geometricamente coincide con currP) + auto firstP = m_lUPointBs.begin() ; + // questo è il vero successivo + nextP = next( firstP) ; + double dSqDist = 2 * dSqTol ; + // se precedente e corrente non hanno bulge (non sono archi i due tratti) + if ( abs( precP->dB) < EPS_SMALL && abs( firstP->dB) < EPS_SMALL) { + // distanza del punto corrente dal segmento che unisce gli adiacenti + DistPointLine( currP->ptP, precP->ptP, nextP->ptP).GetSqDist( dSqDist) ; + } + // se da eliminare + if ( dSqDist < dSqTol && PointsInTolerance( vRPT, precP->ptP, nextP->ptP, dSqTol)) { + // faccio coincidere il primo punto con il precedente + firstP->ptP = precP->ptP ; + // elimino il punto corrente + m_lUPointBs.erase( currP) ; + } + } + + return true ; +} diff --git a/PolyLine.cpp b/PolyLine.cpp index f6cd7bf..4a755b0 100644 --- a/PolyLine.cpp +++ b/PolyLine.cpp @@ -672,6 +672,18 @@ PolyLine::AdjustForMaxSegmentLen( double dMaxLen) return true ; } +//---------------------------------------------------------------------------- +static bool +PointsInTolerance( const PNTVECTOR& vRPT, const Point3d& ptP1, const Point3d& ptP2, double dSqTol) +{ + for ( const auto& ptQ : vRPT) { + double dSqDist ; + if ( ! DistPointLine( ptQ, ptP1, ptP2).GetSqDist( dSqDist) || dSqDist > dSqTol) + return false ; + } + return true ; +} + //---------------------------------------------------------------------------- bool PolyLine::RemoveAlignedPoints( double dToler) @@ -681,8 +693,7 @@ PolyLine::RemoveAlignedPoints( double dToler) return true ; // controllo minimo valore di tolleranza dToler = max( dToler, LIN_TOL_MIN) ; - // coefficiente deduzione tolleranza - const double COEFF_TOL = 0.90 ; + double dSqTol = dToler * dToler ; // si analizza la distanza di un punto dal segmento che unisce precedente e successivo // punto precedente auto precP = m_lUPoints.begin() ; @@ -690,17 +701,17 @@ PolyLine::RemoveAlignedPoints( double dToler) auto currP = next( precP) ; // punto successivo auto nextP = next( currP) ; - // assegno la tolleranza corrente - double dCurrToler = dToler ; + // lista dei punti appena rimossi + PNTVECTOR vRPT ; vRPT.reserve( 20) ; // mentre esiste un successivo while ( nextP != m_lUPoints.end()) { // distanza del punto corrente dal segmento che unisce gli adiacenti DistPointLine dPL( currP->first, precP->first, nextP->first) ; double dSqDist ; // se da eliminare - if ( dPL.GetSqDist( dSqDist) && dSqDist < dCurrToler * dCurrToler) { - // diminuisco la tolleranza corrente dell'errore attuale - dCurrToler -= COEFF_TOL * sqrt( dSqDist) ; + if ( dPL.GetSqDist( dSqDist) && dSqDist < dSqTol && PointsInTolerance( vRPT, precP->first, nextP->first, dSqTol)) { + // aggiungo il punto nella lista dei rimossi + vRPT.emplace_back( currP->first) ; // elimino il punto m_lUPoints.erase( currP) ; // avanzo con corrente e successivo @@ -709,8 +720,8 @@ PolyLine::RemoveAlignedPoints( double dToler) } // altrimenti da tenere else { - // ripristino la tolleranza corrente - dCurrToler = dToler ; + // cancello la lista dei rimossi + vRPT.clear() ; // avanzo il terzetto di uno step precP = currP ; currP = nextP ; @@ -728,7 +739,7 @@ PolyLine::RemoveAlignedPoints( double dToler) DistPointLine dPL( currP->first, precP->first, nextP->first) ; double dSqDist ; // se da eliminare - if ( dPL.GetSqDist( dSqDist) && dSqDist < dCurrToler * dCurrToler) { + if ( dPL.GetSqDist( dSqDist) && dSqDist < dSqTol && PointsInTolerance( vRPT, precP->first, nextP->first, dSqTol)) { // faccio coincidere il primo punto con il precedente firstP->first = precP->first ; // elimino il punto corrente diff --git a/SfrCreate.cpp b/SfrCreate.cpp index 59a568c..6a4e091 100644 --- a/SfrCreate.cpp +++ b/SfrCreate.cpp @@ -18,6 +18,7 @@ #include "CurveComposite.h" #include "SurfFlatRegion.h" #include "GeoConst.h" +#include "/EgtDev/Include/EgkBiArcs.h" #include "/EgtDev/Include/EgkOffsetCurve.h" #include "/EgtDev/Include/EGkSfrCreate.h" #include "/EgtDev/Include/EgtPointerOwner.h" @@ -122,16 +123,22 @@ GetSurfFlatRegionFromFatCurve( ICurve* pCrv, double dRadius, bool bSquareEnds, b if ( IsNull( pCompo1) || ! pCompo1->AddCurve( Release( pCurve))) return nullptr ; // se distanza tra gli estremi minore di due volte il raggio la chiudo, purchè curva abbastanza lunga - double dLen ; - Point3d ptStart, ptEnd ; + Point3d ptStart, ptEnd, ptMid ; Vector3d vtStart, vtEnd ; pCompo1->GetStartPoint( ptStart) ; pCompo1->GetStartDir( vtStart) ; pCompo1->GetEndPoint( ptEnd) ; pCompo1->GetEndDir( vtEnd) ; - pCompo1->GetLength( dLen) ; - if ( dLen > 2 * dRadius && Dist( ptStart, ptEnd) <= 2 * dRadius) - pCompo1->Close() ; + pCompo1->GetMidPoint( ptMid) ; + if ( Dist( ptStart, ptEnd) <= 2 * dRadius && Dist( ptStart, ptMid) > 2 * dRadius && Dist( ptEnd, ptMid) > 2 * dRadius) { + double dAngEnd ; vtEnd.ToSpherical( nullptr, nullptr, &dAngEnd) ; + double dAngStart ; vtStart.ToSpherical( nullptr, nullptr, &dAngStart) ; + PtrOwner pClose( GetBiArc( ptEnd, dAngEnd, ptStart, dAngStart, 0.5)) ; + if ( ! IsNull( pClose)) + pCompo1->AddCurve( Release( pClose)) ; + else + pCompo1->Close() ; + } // tipo di offset int nOffsType = ( bSquareMids ? ICurve::OFF_EXTEND : ICurve::OFF_FILLET) ; // se curva chiusa