diff --git a/CurveBezier.cpp b/CurveBezier.cpp index 703ddec..1060f52 100644 --- a/CurveBezier.cpp +++ b/CurveBezier.cpp @@ -440,9 +440,8 @@ CurveBezier::Validate( void) } } } - if ( m_nStatus == TO_VERIFY) - m_nStatus = ( ( m_nDeg > 0 && m_vPtCtrl.size() > 0) ? OK : ERR) ; + m_nStatus = ( ( m_nDeg >= 1 && m_vPtCtrl.size() >= 2) ? OK : ERR) ; return ( m_nStatus == OK) ; } @@ -620,7 +619,7 @@ CurveBezier::GetMidPoint( Point3d& ptMid) const return false ; // determino il valore del parametro a metà lunghezza double dLen, dMid ; - if ( ! GetLength( dLen) || ! GetParamAtLength( 0.5 * dLen, dMid)) + if ( ! GetLengthAtParam( 1, dLen) || ! GetParamAtLength( 0.5 * dLen, dMid)) return false ; // calcolo il punto return GetPointD1D2( dMid, ptMid) ; @@ -657,7 +656,7 @@ CurveBezier::GetMidDir( Vector3d& vtDir) const return false ; // determino il valore del parametro a metà lunghezza double dLen, dMid ; - if ( ! GetLength( dLen) || ! GetParamAtLength( 0.5 * dLen, dMid)) + if ( ! GetLengthAtParam( 1, dLen) || ! GetParamAtLength( 0.5 * dLen, dMid)) return false ; // calcolo la direzione return ::GetTang( *this, dMid, FROM_MINUS, vtDir) ; @@ -1755,7 +1754,7 @@ CurveBezier::ExtendStartByLen( double dLenExt) return false ; // determino la lunghezza originale della curva double dLen ; - if ( ! GetLength( dLen)) + if ( ! GetLengthAtParam( 1, dLen)) return false ; // stimo il valore del parametro al nuovo punto iniziale double dUTrim = - dLenExt / dLen ; @@ -1803,7 +1802,7 @@ CurveBezier::ExtendEndByLen( double dLenExt) return false ; // determino la lunghezza originale della curva double dLen ; - if ( ! GetLength( dLen)) + if ( ! GetLengthAtParam( 1, dLen)) return false ; // stimo il valore del parametro al nuovo punto finale double dUTrim = 1 + dLenExt / dLen ; diff --git a/CurveComposite.cpp b/CurveComposite.cpp index 68d74e0..9b69a31 100644 --- a/CurveComposite.cpp +++ b/CurveComposite.cpp @@ -230,8 +230,15 @@ CurveComposite::AddSimpleCurve( ICurve* pSmplCrv, bool bEndOrStart, double dLinT if ( ! AreSamePointEpsilon( ptCrvEnd, ptStart, 0.01 * EPS_SMALL)) { // se in tolleranza, modifico la fine dell'entità if ( SqDist( ptCrvEnd, ptStart) < ( dLinTol * dLinTol)) { + // lunghezza della curva originale + double dOldLen ; pCrv->GetLength( dOldLen) ; + // eseguo modifica if ( ! pCrv->ModifyEnd( ptStart)) return false ; + // verifico che la lunghezza non sia variata troppo + double dNewLen ; pCrv->GetLength( dNewLen) ; + if ( abs( dNewLen - dOldLen) > 10 * dLinTol) + return false ; } else return false ; @@ -3226,11 +3233,18 @@ CurveComposite::MergeCurves( double dLinTol, double dAngTolDeg, bool bStartEnd, return true ; } +//---------------------------------------------------------------------------- +bool +CurveComposite::RemoveSmallParts( double dLinTol, double dAngTolDeg) +{ + return ( RemoveCurveSmallParts( this, dLinTol)) ; +} + //---------------------------------------------------------------------------- bool CurveComposite::RemoveSmallDefects( double dLinTol, double dAngTolDeg, bool bAlsoSpikes) { - return (( ! bAlsoSpikes || RemoveCurveSpikes( this, dLinTol)) && RemoveCurveSmallZs(this, dLinTol)) ; + return (( ! bAlsoSpikes || RemoveCurveSpikes( this, dLinTol)) && RemoveCurveSmallZs( this, dLinTol)) ; } //---------------------------------------------------------------------------- diff --git a/CurveComposite.h b/CurveComposite.h index 5f1cf2f..bd280a0 100644 --- a/CurveComposite.h +++ b/CurveComposite.h @@ -158,6 +158,7 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW bool ArcsBezierCurvesToArcsPerpExtr( double dLinTol, double dAngTolDeg) override ; bool StraightArcsToLines( double dLinTol, double dAngTolDeg) override ; bool MergeCurves( double dLinTol, double dAngTolDeg, bool bStartEnd = true, bool bNeedSameProp = false) override ; + bool RemoveSmallParts( double dLinTol, double dAngTolDeg) override ; bool RemoveSmallDefects( double dLinTol, double dAngTolDeg, bool bAlsoSpikes = false) override ; bool RemoveUndercutOnY( double dLinTol, double dAngTolDeg) override ; bool IsAPoint( void) const override ; diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index 7329ae6..e22251d 100644 Binary files a/EgtGeomKernel.rc and b/EgtGeomKernel.rc differ diff --git a/OffsetCurve.cpp b/OffsetCurve.cpp index 7553528..f304224 100644 --- a/OffsetCurve.cpp +++ b/OffsetCurve.cpp @@ -165,6 +165,10 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType) if ( ! RemoveCurveSmallZs( &ccCopy, 10 * EPS_SMALL)) return false ; + // elimino tratti molto corti + if ( ! RemoveCurveSmallParts( &ccCopy, 10 * EPS_SMALL)) + return false ; + // converto archi diritti in segmenti di retta const double ANG_CEN_MAX = 0.5 ; if ( ! ccCopy.StraightArcsToLines( 2 * EPS_SMALL, ANG_CEN_MAX)) diff --git a/RemoveCurveDefects.cpp b/RemoveCurveDefects.cpp index c0f95fa..1a14bef 100644 --- a/RemoveCurveDefects.cpp +++ b/RemoveCurveDefects.cpp @@ -135,3 +135,70 @@ RemoveCurveSmallZs( ICurveComposite* pCurve, double dLinTol) return true ; } + +//---------------------------------------------------------------------------- +bool +RemoveCurveSmallParts( ICurveComposite* pCurve, double dLinTol) +{ + // verifico validità curva + if ( pCurve == nullptr) + return false ; + // verifico e sistemo tolleranza lineare + dLinTol = max( dLinTol, EPS_SMALL) ; + // recupero il numero di curve semplici componenti la composta + int nCrvCount = pCurve->GetCurveCount() ; + if ( nCrvCount < 2 || ( nCrvCount < 3 && pCurve->IsClosed())) + return true ; + // se aperta, verifico le due curve agli estremi + if ( ! pCurve->IsClosed()) { + // curva iniziale + const ICurve* pFirstCrv = pCurve->GetFirstCurve() ; + double dFirstLen ; pFirstCrv->GetLength( dFirstLen) ; + if ( dFirstLen < dLinTol) { + Point3d ptStart ; pFirstCrv->GetStartPoint( ptStart) ; + delete( pCurve->RemoveFirstOrLastCurve( false)) ; + pCurve->ModifyStart( ptStart) ; + } + // curva finale + const ICurve* pLastCrv = pCurve->GetLastCurve() ; + double dLastLen ; pLastCrv->GetLength( dLastLen) ; + if ( dLastLen < dLinTol) { + Point3d ptEnd ; pLastCrv->GetStartPoint( ptEnd) ; + delete( pCurve->RemoveFirstOrLastCurve( true)) ; + pCurve->ModifyEnd( ptEnd) ; + } + } + // ciclo sulle curve elementari della composita + int nStart = pCurve->IsClosed() ? 0 : 1 ; + int nEnd = pCurve->IsClosed() ? nCrvCount : nCrvCount - 1 ; + for ( int i = nStart ; i < nEnd ; ++ i) { + // recupero tre curve consecutive + const ICurve* pPrevCrv = pCurve->GetCurve( ( i > 0 ? i - 1 : nCrvCount - 1)) ; + const ICurve* pCurrCrv = pCurve->GetCurve( i) ; + const ICurve* pNextCrv = pCurve->GetCurve( ( i < nCrvCount - 1 ? i + 1 : 0)) ; + // se la curva corrente è troppo corta + double dLen ; pCurrCrv->GetLength( dLen) ; + if ( dLen < dLinTol) { + // recupero il punto medio della curva + Point3d ptMid ; pCurrCrv->GetMidPoint( ptMid) ; + // rimuovo il segmento + if ( pCurve->RemoveJoint( i)) { + -- nCrvCount ; + -- nEnd ; + -- i ; + // porto il nuovo estremo sul punto medio + pCurve->ModifyJoint( i + 1, ptMid) ; + } + // altrimenti devo rimuovere anche il successivo + else if ( pCurve->RemoveJoint( i + 1) && pCurve->RemoveJoint( i)) { + nCrvCount -= 2 ; + nEnd -= 2 ; + -- i ; + // porto il nuovo estremo sul punto medio + pCurve->ModifyJoint( i + 1, ptMid) ; + } + } + } + + return true ; +} diff --git a/RemoveCurveDefects.h b/RemoveCurveDefects.h index ef044b9..ca117eb 100644 --- a/RemoveCurveDefects.h +++ b/RemoveCurveDefects.h @@ -1,13 +1,13 @@ //---------------------------------------------------------------------------- // EgalTech 2017-2022 //---------------------------------------------------------------------------- -// File : RemoveCurveDefects.h Data : 13.11.22 Versione : 2.4k2 +// File : RemoveCurveDefects.h Data : 03.11.23 Versione : 2.5k1 // Contenuto : Dichiarazione funzioni rimozione difetti curve. // // // // Modifiche : 02.10.17 DS Creazione modulo. -// +// 03.11.23 DS Aggiunta RemoveCurveSmallParts. // //---------------------------------------------------------------------------- @@ -19,3 +19,4 @@ //---------------------------------------------------------------------------- bool RemoveCurveSpikes( ICurveComposite* pCurve, double dLinTol = EPS_SMALL) ; bool RemoveCurveSmallZs( ICurveComposite* pCurve, double dLinTol = EPS_SMALL) ; +bool RemoveCurveSmallParts( ICurveComposite* pCurve, double dLinTol = EPS_SMALL) ; diff --git a/SurfFlatRegionBooleans.cpp b/SurfFlatRegionBooleans.cpp index a06921e..c2c3bf4 100644 --- a/SurfFlatRegionBooleans.cpp +++ b/SurfFlatRegionBooleans.cpp @@ -363,6 +363,9 @@ SurfFlatRegion::MyChainCurves( PCRV_DEQUE& vpCurve, PCRV_DEQUE& vpLoop) if ( ! bOk) return false ; } + + // pulisco + pCrvCompo->RemoveSmallParts( 2 * EPS_SMALL, EPS_ANG_SMALL) ; // aggiorno il nuovo punto vicino if ( pCrvCompo->GetCurveCount() > 0) pCrvCompo->GetEndPoint( ptNearStart) ;