From 7de56883b3699739affca5aaaa60426a97e67184 Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Mon, 16 Dec 2013 09:37:57 +0000 Subject: [PATCH] EgtGeomKernel 1.4l1 : Aggiunto Trim di curve a lunghezza e parametro. --- CurveArc.cpp | 103 +++++++++++++++ CurveArc.h | 6 + CurveBezier.cpp | 235 ++++++++++++++++++++++++++++++++-- CurveBezier.h | 13 +- CurveComposite.cpp | 231 ++++++++++++++++++++++++++++++++- CurveComposite.h | 5 + CurveLine.cpp | 99 ++++++++++++++ CurveLine.h | 6 + EgtGeomKernel.rc | Bin 7630 -> 7634 bytes EgtGeomKernel.vcxproj | 1 + EgtGeomKernel.vcxproj.filters | 3 + GdbExecutor.cpp | 102 +++++++++++++++ GdbExecutor.h | 5 +- GdbGroup.cpp | 10 +- GdbObj.cpp | 24 +++- 15 files changed, 814 insertions(+), 29 deletions(-) diff --git a/CurveArc.cpp b/CurveArc.cpp index 67bc934..d7fbb52 100644 --- a/CurveArc.cpp +++ b/CurveArc.cpp @@ -23,6 +23,10 @@ using namespace std ; //---------------------------------------------------------------------------- GEOOBJ_REGISTER( CRV_ARC, "C_ARC", CurveArc) ; +//---------------------------------------------------------------------------- +const double CurveArc::PAR_START = 0 ; +const double CurveArc::PAR_END = 1 ; + //---------------------------------------------------------------------------- CurveArc::CurveArc( void) { @@ -306,6 +310,105 @@ CurveArc::Reverse( void) return true ; } +//---------------------------------------------------------------------------- +bool +CurveArc::TrimStartAtParam( double dUTrim) +{ + double dLen ; + + + // riporto i parametri nel loro range + dUTrim = ( ( dUTrim < PAR_START) ? PAR_START : (( dUTrim > PAR_END) ? PAR_END : dUTrim)) ; + + // recupero lunghezza + if ( ! GetLength( dLen)) + return false ; + + // utilizzo il trim sulle lunghezze + return TrimStartAtLen( dUTrim * dLen) ; +} + +//---------------------------------------------------------------------------- +bool +CurveArc::TrimEndAtParam( double dUTrim) +{ + double dLen ; + + + // riporto i parametri nel loro range + dUTrim = ( ( dUTrim < PAR_START) ? PAR_START : (( dUTrim > PAR_END) ? PAR_END : dUTrim)) ; + + // recupero lunghezza + if ( ! GetLength( dLen)) + return false ; + + // utilizzo il trim sulle lunghezze + return TrimEndAtLen( dUTrim * dLen) ; +} + +//---------------------------------------------------------------------------- +bool +CurveArc::TrimStartAtLen( double dLenTrim) +{ + double dLen ; + double dAngRot ; + double dMoveN ; + + + // lunghezze negative vengono considerate nulle + dLenTrim = __max( dLenTrim, 0) ; + + // verifico che sia abbastanza lunga + if ( ! GetLength( dLen)) + return false ; + if ( ( dLen - dLenTrim) < EPS_SMALL) + return false ; + + // eseguo il trim + if ( dLenTrim > EPS_ZERO) { + dAngRot = m_dAngCenDeg * dLenTrim / dLen ; + m_VtS.Rotate( m_VtN, dAngRot * DEGTORAD) ; + m_dAngCenDeg -= dAngRot ; + if ( fabs( m_dDeltaN) > EPS_ZERO) { + dMoveN = m_dDeltaN * dLenTrim / dLen ; + m_PtCen.Translate( m_VtN * dMoveN) ; + m_dDeltaN -= dMoveN ; + } + } + + // con i controlli sopra fatti rimane validata + + return true ; +} + +//---------------------------------------------------------------------------- +bool +CurveArc::TrimEndAtLen( double dLenTrim) +{ + double dLen ; + + + // lunghezze negative vengono considerate nulle + dLenTrim = __max( dLenTrim, 0) ; + + // verifico che sia abbastanza lunga + if ( ! GetLength( dLen)) + return false ; + if ( dLenTrim < EPS_SMALL) + return false ; + + // eseguo il trim + if ( ( dLen - dLenTrim) > EPS_ZERO) { + m_dAngCenDeg *= dLenTrim / dLen ; + if ( fabs( m_dDeltaN) > EPS_ZERO) + m_dDeltaN *= dLenTrim / dLen ; + } + + // con i controlli sopra fatti rimane validata + + return true ; +} + //---------------------------------------------------------------------------- bool CurveArc::Translate( const Vector3d& vtMove) diff --git a/CurveArc.h b/CurveArc.h index d7f3b7a..cca98f2 100644 --- a/CurveArc.h +++ b/CurveArc.h @@ -52,6 +52,10 @@ class CurveArc : public ICurveArc virtual bool GetPointTangNormCurv( double dU, Point3d& ptPos, Vector3d& vtT, Vector3d& vtN, double& dCurv) const { return ::GetPointTangNormCurv( *this, dU, ptPos, vtT, vtN, dCurv) ; } virtual bool Reverse( void) ; + virtual bool TrimStartAtParam( double dUTrim) ; + virtual bool TrimEndAtParam( double dUTrim) ; + virtual bool TrimStartAtLen( double dLenTrim) ; + virtual bool TrimEndAtLen( double dLenTrim) ; public : virtual bool Set( const Point3d& ptCen, const Vector3d& vtN, double dRad, @@ -86,6 +90,8 @@ class CurveArc : public ICurveArc private : enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ; + static const double PAR_START ; + static const double PAR_END ; private : Status m_nStatus ; // stato diff --git a/CurveBezier.cpp b/CurveBezier.cpp index 4430404..572218b 100644 --- a/CurveBezier.cpp +++ b/CurveBezier.cpp @@ -13,16 +13,21 @@ //--------------------------- Include ---------------------------------------- #include "stdafx.h" -#include -#include "\EgtDev\Include\EGnStringUtils.h" #include "CurveBezier.h" #include "GeoObjFactory.h" +#include "\EgtDev\Include\EGnStringUtils.h" +#include "\EgtDev\Include\EGkCurveArc.h" +#include using namespace std ; //---------------------------------------------------------------------------- GEOOBJ_REGISTER( CRV_BEZ, "C_BEZ", CurveBezier) ; +//---------------------------------------------------------------------------- +const double CurveBezier::PAR_START = 0 ; +const double CurveBezier::PAR_END = 1 ; + //---------------------------------------------------------------------------- CurveBezier::CurveBezier( void) { @@ -109,7 +114,7 @@ bool CurveBezier::SetControlPoint( int nInd, const Point3d& ptCtrl) { // verifico validità indice - if ( m_nStatus != OK || nInd < 0 || nInd > m_nDeg) + if ( m_nStatus != OK || m_bRat || nInd < 0 || nInd > m_nDeg) return false ; // assegno il valore @@ -141,6 +146,39 @@ CurveBezier::SetControlPoint( int nInd, const Point3d& ptCtrl, double dW) return true ; } +//---------------------------------------------------------------------------- +bool +CurveBezier::SetFromArc( const ICurveArc& crArc) +{ + double dAngCen ; + double dCosAhalf ; + Point3d ptStart ; + Point3d ptEnd ; + Point3d ptMed ; + Point3d ptNew ; + Vector3d vtDir ; + + + if ( ! crArc.IsValid()) + return false ; + dAngCen = crArc.GetAngCenter() ; + if ( fabs( dAngCen) > 120.0) + return false ; + dCosAhalf = cos( 0.5 * dAngCen * DEGTORAD) ; + crArc.GetStartPoint( ptStart) ; + crArc.GetEndPoint( ptEnd) ; + ptMed = Media( ptStart, ptEnd, 0.5) ; + vtDir = ptMed - crArc.GetCenter() ; + ptNew = crArc.GetCenter() + vtDir / ( dCosAhalf * dCosAhalf) ; + + Init( 2, true ) ; + SetControlPoint( 0, ptStart, 1) ; + SetControlPoint( 1, ptNew, dCosAhalf) ; + SetControlPoint( 2, ptEnd, 1) ; + + return true ; +} + //---------------------------------------------------------------------------- const Point3d& CurveBezier::GetControlPoint( int nInd, bool* pbOk) const @@ -342,10 +380,10 @@ CurveBezier::GetPointD1D2( double dU, Point3d& ptPos, Vector3d& vtDer1, Vector3d return false ; // il parametro U deve essere compreso tra 0 e 1 - if ( dU < 0) - dU = 0 ; - else if ( dU > 1) - dU = 1 ; + if ( dU < PAR_START) + dU = PAR_START ; + else if ( dU > PAR_END) + dU = PAR_END ; // se forma polinomiale (o integrale) if ( ! m_bRat) { @@ -466,9 +504,17 @@ CurveBezier::IncreaseBernsteinOneDegree( double dU, int nDeg, double dBern[]) co bool CurveBezier::GetLength( double& dLen) const { - const int NUM_SEG = 20 ; + return ( GetLengthAtParam( 1, dLen) && dLen > EPS_SMALL) ; +} + +//---------------------------------------------------------------------------- +bool +CurveBezier::GetLengthAtParam( double dU, double& dLen) const +{ + const int NUM_SEG = 50 ; int i ; - double dU ; + double dPar ; + double dSegLen ; Point3d ptIni ; Point3d ptFin ; @@ -477,20 +523,83 @@ CurveBezier::GetLength( double& dLen) const if ( m_nStatus != OK) return false ; + // fuori dominio del parametro -> errore + if ( dU < PAR_START - EPS_ZERO) + return false ; + if ( dU > ( PAR_END + EPS_ZERO)) + return false ; + + // inizio + if ( dU < PAR_START + EPS_ZERO) { + dLen = 0 ; + return true ; + } + // approssimo la curva con un numero fisso di segmenti !!! DA MIGLIORARE !!! dLen = 0 ; for ( i = 0 ; i <= NUM_SEG ; ++ i) { // ricavo il punto - dU = i / (double) NUM_SEG ; - GetPoint( dU, ptFin) ; + dPar = i / (double) NUM_SEG ; + GetPoint( dPar, ptFin) ; // dal secondo posso calcolare la lunghezza - if ( i > 0) - dLen += Dist( ptIni, ptFin) ; + if ( i > 0) { + dSegLen = Dist( ptIni, ptFin) ; + dLen += dSegLen ; + if ( dPar >= dU) { + dLen += ( dU - dPar) * NUM_SEG * dSegLen ; + break ; + } + } // nuovo iniziale prende i valori del finale ptIni = ptFin ; } - return ( dLen > EPS_SMALL) ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +CurveBezier::GetParamAtLength( double dLen, double& dU) const +{ + const int NUM_SEG = 50 ; + int i ; + double dPar ; + double dSegLen ; + double dCurrLen ; + Point3d ptIni ; + Point3d ptFin ; + + + // la curva deve essere validata + if ( m_nStatus != OK) + return false ; + + // inizio + if ( dLen < EPS_SMALL) { + dU = PAR_START ; + return true ; + } + + // approssimo la curva con un numero fisso di segmenti !!! DA MIGLIORARE !!! + dCurrLen = 0 ; + for ( i = 0 ; i <= NUM_SEG ; ++ i) { + // ricavo il punto + dPar = i / (double) NUM_SEG ; + GetPoint( dPar, ptFin) ; + // dal secondo posso calcolare la lunghezza + if ( i > 0) { + dSegLen = Dist( ptIni, ptFin) ; + dCurrLen += dSegLen ; + if ( dCurrLen >= dLen) { + dU = dPar - ( dCurrLen - dLen) / ( dSegLen * NUM_SEG) ; + break ; + } + } + // nuovo iniziale prende i valori del finale + ptIni = ptFin ; + } + + return true ; } //---------------------------------------------------------------------------- @@ -517,6 +626,104 @@ CurveBezier::Reverse( void) return true ; } +//---------------------------------------------------------------------------- +bool +CurveBezier::TrimStartAtParam( double dUTrim) +{ + int i ; + int k ; + + + // se devo togliere dall'inizio o prima non tolgo niente + if ( dUTrim <= PAR_START) + return true ; + // se devo togliere a partire dalla fine o dopo non rimane niente + if ( dUTrim >= PAR_END) + return false ; + // eseguo il trim (algoritmo di de Casteljau) + for ( k = 1 ; k <= m_nDeg ; k ++) { + for ( i = 0 ; i <= m_nDeg - k ; i ++) { + if ( ! m_bRat) { + m_aPtCtrl[i] = ( 1 - dUTrim) * m_aPtCtrl[i] + dUTrim * m_aPtCtrl[i+1] ; + } + else { + m_aPtCtrl[i] = ( 1 - dUTrim) * m_aPtCtrl[i] * m_aWeCtrl[i] + dUTrim * m_aPtCtrl[i+1] * m_aWeCtrl[i+1] ; + m_aWeCtrl[i] = ( 1 - dUTrim) * m_aWeCtrl[i] + dUTrim * m_aWeCtrl[i+1] ; + m_aPtCtrl[i] = m_aPtCtrl[i] * ( 1 / m_aWeCtrl[i]) ; + } + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +CurveBezier::TrimEndAtParam( double dUTrim) +{ + int i ; + int k ; + + + // se devo togliere a partire dall'inizio o prima non rimane niente + if ( dUTrim <= PAR_START) + return false ; + // se devo togliere dalla fine o dopo non tolgo niente + if ( dUTrim >= PAR_END) + return true ; + // eseguo il trim (algoritmo di de Casteljau) + for ( k = 1 ; k <= m_nDeg ; k ++) { + for ( i = m_nDeg ; i >= k ; i --) { + if ( ! m_bRat) { + m_aPtCtrl[i] = ( 1 - dUTrim) * m_aPtCtrl[i-1] + dUTrim * m_aPtCtrl[ i] ; + } + else { + m_aPtCtrl[i] = ( 1 - dUTrim) * m_aPtCtrl[i-1] * m_aWeCtrl[i-1] + dUTrim * m_aPtCtrl[ i] * m_aWeCtrl[ i] ; + m_aWeCtrl[i] = ( 1 - dUTrim) * m_aWeCtrl[i-1] + dUTrim * m_aWeCtrl[ i] ; + m_aPtCtrl[i] = m_aPtCtrl[i] * ( 1 / m_aWeCtrl[i]) ; + } + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +CurveBezier::TrimStartAtLen( double dLenTrim) +{ + double dUTrim ; + + + // lunghezze negative vengono considerate nulle + dLenTrim = __max( dLenTrim, 0) ; + + // converto le lunghezze in valori parametrici + if ( ! GetParamAtLength( dLenTrim, dUTrim)) + return false ; + + // utilizzo il trim sui parametri + return TrimStartAtParam( dUTrim) ; +} + +//---------------------------------------------------------------------------- +bool +CurveBezier::TrimEndAtLen( double dLenTrim) +{ + double dUTrim ; + + + // lunghezze negative vengono considerate nulle + dLenTrim = __max( dLenTrim, 0) ; + + // converto le lunghezze in valori parametrici + if ( ! GetParamAtLength( dLenTrim, dUTrim)) + return false ; + + // utilizzo il trim sui parametri + return TrimEndAtParam( dUTrim) ; +} + //---------------------------------------------------------------------------- bool CurveBezier::Translate( const Vector3d& vtMove) diff --git a/CurveBezier.h b/CurveBezier.h index c6cb0c7..2309106 100644 --- a/CurveBezier.h +++ b/CurveBezier.h @@ -44,6 +44,8 @@ class CurveBezier : public ICurveBezier virtual bool GetEndPoint( Point3d& ptEnd) const ; virtual bool GetDomain( double& dStart, double& dEnd) const ; virtual bool GetLength( double& dLen) const ; + virtual bool GetLengthAtParam( double dU, double& dLen) const ; + virtual bool GetParamAtLength( double dLen, double& dU) const ; virtual bool GetPointD1D2( double dU, Point3d& ptPos, Vector3d& vtDer1, Vector3d& vtDer2) const ; virtual bool GetPoint( double dU, Point3d& ptPos) const { return ::GetPoint( *this, dU, ptPos) ; } @@ -52,11 +54,16 @@ class CurveBezier : public ICurveBezier virtual bool GetPointTangNormCurv( double dU, Point3d& ptPos, Vector3d& vtT, Vector3d& vtN, double& dCurv) const { return ::GetPointTangNormCurv( *this, dU, ptPos, vtT, vtN, dCurv) ; } virtual bool Reverse( void) ; + virtual bool TrimStartAtParam( double dUTrim) ; + virtual bool TrimEndAtParam( double dUTrim) ; + virtual bool TrimStartAtLen( double dLenTrim) ; + virtual bool TrimEndAtLen( double dLenTrim) ; public : virtual bool Init( int nDeg, bool bIsRational) ; virtual bool SetControlPoint( int nInd, const Point3d& ptCtrl) ; virtual bool SetControlPoint( int nInd, const Point3d& ptCtrl, double dW) ; + virtual bool SetFromArc( const ICurveArc& crArc) ; virtual int GetDegree( void) const { return m_nDeg ; } virtual bool IsRational( void) const @@ -82,10 +89,12 @@ class CurveBezier : public ICurveBezier private : enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ; - - private : static const int MAXDEG = 11 ; static const int ST_PTC = 4 ; + static const double PAR_START ; + static const double PAR_END ; + + private : Status m_nStatus ; // stato int m_nDeg ; // grado bool m_bRat ; // flag di razionale/polinomiale diff --git a/CurveComposite.cpp b/CurveComposite.cpp index 50efc8b..d382b47 100644 --- a/CurveComposite.cpp +++ b/CurveComposite.cpp @@ -23,6 +23,9 @@ using namespace std ; //---------------------------------------------------------------------------- GEOOBJ_REGISTER( CRV_COMPO, "C_CMP", CurveComposite) ; +//---------------------------------------------------------------------------- +const double CurveComposite::PAR_START = 0 ; + //---------------------------------------------------------------------------- CurveComposite::CurveComposite( void) { @@ -327,7 +330,7 @@ CurveComposite::GetDomain( double& dStart, double& dEnd) const return false ; // assegno gli estremi del dominio - dStart = 0 ; + dStart = PAR_START ; dEnd = m_nCounter ; return true ; @@ -341,8 +344,8 @@ CurveComposite::GetPointD1D2( double dU, Point3d& ptPos, Vector3d& vtDer1, Vecto // il parametro U deve essere compreso tra 0 e m_nCounter - if ( dU < 0) - dU = 0 ; + if ( dU < PAR_START) + dU = PAR_START ; else if ( dU > m_nCounter) dU = m_nCounter ; @@ -397,6 +400,228 @@ CurveComposite::Reverse( void) return true ; } +//---------------------------------------------------------------------------- +bool +CurveComposite::TrimStartAtParam( double dUTrim) +{ + double dUToTrim ; + PCRVSMPL_LIST::iterator Iter ; + + + // ciclo sulle diverse curve dall'inizio + dUToTrim = dUTrim ; + for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ;) { + // dominio parametrico della curva sempre 1 + // lunghezza parametrica progressiva + dUToTrim -= 1 ; + // se lunghezza ancora da tagliare non nulla + if ( dUToTrim > EPS_ZERO) { + delete (*Iter) ; + Iter ++ ; + m_CrvSmplS.pop_front() ; + m_nCounter -- ; + } + // se lunghezza ancora da tagliare nulla (entro la tolleranza) + else if ( dUToTrim > - EPS_ZERO) { + delete (*Iter) ; + Iter ++ ; + m_CrvSmplS.pop_front() ; + m_nCounter -- ; + if ( m_nCounter == 0) + return false ; + (*Iter)->GetStartPoint( m_PtStart) ; + m_bClosed = ( AreSamePointNear( m_PtStart, m_PtEnd)) ; + break ; + } + // altrimenti superata lunghezza ancora da tagliare + else { + if ( ! (*Iter)->TrimStartAtParam( 1 + dUToTrim)) { + m_nStatus = ERR ; + return false ; + } + (*Iter)->GetStartPoint( m_PtStart) ; + m_bClosed = ( AreSamePointNear( m_PtStart, m_PtEnd)) ; + break ; + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +CurveComposite::TrimEndAtParam( double dUTrim) +{ + bool bToErase ; + double dUToTrim ; + PCRVSMPL_LIST::iterator Iter ; + + + // ciclo sulle diverse curve dalla fine + bToErase = false ; + dUToTrim = dUTrim ; + for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ;) { + // dominio parametrico delle curve semplici sempre 1 + // lunghezza parametrica progressiva + dUToTrim -= 1 ; + // se da cancellare + if ( bToErase) { + // cancello l'entità, la tolgo dalla lista e passo alla successiva + delete (*Iter) ; + Iter = m_CrvSmplS.erase( Iter) ; + // decremento il numero di entità + m_nCounter -- ; + } + // se lunghezza parametrica ancora da tagliare non nulla + else if ( dUToTrim > EPS_ZERO) { + Iter ++ ; + } + // se lunghezza parametrica ancora da tagliare nulla (entro la tolleranza) + else if ( dUToTrim > - EPS_ZERO) { + // imposto punto finale e verifico curva chiusa + (*Iter)->GetEndPoint( m_PtEnd) ; + m_bClosed = ( AreSamePointNear( m_PtStart, m_PtEnd)) ; + // passo alla entità successiva + ++ Iter ; + // dichiaro ingresso in zona da cancellare + bToErase = true ; + } + // altrimenti superata lunghezza parametrica ancora da tagliare + else { + // trimmo la curva semplice + if ( ! (*Iter)->TrimEndAtParam( 1 + dUToTrim)) { + m_nStatus = ERR ; + return false ; + } + // imposto punto finale e verifica curva chiusa + (*Iter)->GetEndPoint( m_PtEnd) ; + m_bClosed = ( AreSamePointNear( m_PtStart, m_PtEnd)) ; + // passo alla entità successiva + ++ Iter ; + // dichiaro ingresso in zona da cancellare + bToErase = true ; + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +CurveComposite::TrimStartAtLen( double dLenTrim) +{ + double dLenToTrim ; + double dCrvLen ; + PCRVSMPL_LIST::iterator Iter ; + + + // ciclo sulle diverse curve dall'inizio + dLenToTrim = dLenTrim ; + for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ;) { + // lunghezza della curva + if ( ! (*Iter)->GetLength( dCrvLen)) + return false ; + // lunghezza progressiva + dLenToTrim -= dCrvLen ; + // se lunghezza ancora da tagliare non nulla + if ( dLenToTrim > EPS_SMALL) { + delete (*Iter) ; + Iter ++ ; + m_CrvSmplS.pop_front() ; + m_nCounter -- ; + } + // se lunghezza ancora da tagliare nulla (entro la tolleranza) + else if ( dLenToTrim > - EPS_SMALL) { + delete (*Iter) ; + Iter ++ ; + m_CrvSmplS.pop_front() ; + m_nCounter -- ; + if ( m_nCounter == 0) + return false ; + (*Iter)->GetStartPoint( m_PtStart) ; + m_bClosed = ( AreSamePointNear( m_PtStart, m_PtEnd)) ; + break ; + } + // altrimenti superata lunghezza ancora da tagliare + else { + if ( ! (*Iter)->TrimStartAtLen( dCrvLen + dLenToTrim)) { + m_nStatus = ERR ; + return false ; + } + (*Iter)->GetStartPoint( m_PtStart) ; + m_bClosed = ( AreSamePointNear( m_PtStart, m_PtEnd)) ; + break ; + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +CurveComposite::TrimEndAtLen( double dLenTrim) +{ + bool bToErase ; + double dLenToTrim ; + double dCrvLen ; + PCRVSMPL_LIST::iterator Iter ; + + + // ciclo sulle diverse curve dalla fine + bToErase = false ; + dLenToTrim = dLenTrim ; + for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ;) { + // se non sono già nella zona da cancellare, aggiorno lunghezze + if ( ! bToErase) { + // lunghezza della curva + if ( ! (*Iter)->GetLength( dCrvLen)) + return false ; + // lunghezza progressiva + dLenToTrim -= dCrvLen ; + } + // se da cancellare + if ( bToErase) { + // cancello l'entità, la tolgo dalla lista e passo alla successiva + delete (*Iter) ; + Iter = m_CrvSmplS.erase( Iter) ; + // decremento il numero di entità + m_nCounter -- ; + } + // se lunghezza ancora da tagliare non nulla + else if ( dLenToTrim > EPS_SMALL) { + // passo alla entità successiva + ++ Iter ; + } + // se lunghezza ancora da tagliare nulla (entro la tolleranza) + else if ( dLenToTrim > - EPS_SMALL) { + // imposto punto finale e verifica curva chiusa + (*Iter)->GetEndPoint( m_PtEnd) ; + m_bClosed = ( AreSamePointNear( m_PtStart, m_PtEnd)) ; + // passo alla entità successiva + ++ Iter ; + // dichiaro ingresso in zona da cancellare + bToErase = true ; + } + // altrimenti superata lunghezza ancora da tagliare + else { + // trimmo la curva semplice + if ( ! (*Iter)->TrimEndAtLen( dCrvLen + dLenToTrim)) { + m_nStatus = ERR ; + return false ; + } + // imposto punto finale e verifica curva chiusa + (*Iter)->GetEndPoint( m_PtEnd) ; + m_bClosed = ( AreSamePointNear( m_PtStart, m_PtEnd)) ; + // passo alla entità successiva + ++ Iter ; + // dichiaro ingresso in zona da cancellare + bToErase = true ; + } + } + + return true ; +} + //---------------------------------------------------------------------------- bool CurveComposite::Translate( const Vector3d& vtMove) diff --git a/CurveComposite.h b/CurveComposite.h index 7566651..4183b91 100644 --- a/CurveComposite.h +++ b/CurveComposite.h @@ -56,6 +56,10 @@ class CurveComposite : public ICurveComposite virtual bool GetPointTangNormCurv( double dU, Point3d& ptPos, Vector3d& vtT, Vector3d& vtN, double& dCurv) const { return ::GetPointTangNormCurv( *this, dU, ptPos, vtT, vtN, dCurv) ; } virtual bool Reverse( void) ; + virtual bool TrimStartAtParam( double dUTrim) ; + virtual bool TrimEndAtParam( double dUTrim) ; + virtual bool TrimStartAtLen( double dLenTrim) ; + virtual bool TrimEndAtLen( double dLenTrim) ; public : virtual bool Clear( void) ; @@ -81,6 +85,7 @@ class CurveComposite : public ICurveComposite private : enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ; + static const double PAR_START ; private : Status m_nStatus ; // stato diff --git a/CurveLine.cpp b/CurveLine.cpp index af2835d..a53f425 100644 --- a/CurveLine.cpp +++ b/CurveLine.cpp @@ -23,6 +23,10 @@ using namespace std ; //---------------------------------------------------------------------------- GEOOBJ_REGISTER( CRV_LINE, "C_LIN", CurveLine) ; +//---------------------------------------------------------------------------- +const double CurveLine::PAR_START = 0 ; +const double CurveLine::PAR_END = 1 ; + //---------------------------------------------------------------------------- CurveLine::CurveLine( void) { @@ -188,6 +192,11 @@ CurveLine::GetPointD1D2( double dU, Point3d& ptPos, Vector3d& vtDer1, Vector3d& bool CurveLine::GetLength( double& dLen) const { + // verifico lo stato + if ( m_nStatus != OK) + return false ; + + // la lunghezza è la distanza tra gli estremi dLen = Dist( m_PtStart, m_PtEnd) ; return ( dLen > EPS_SMALL) ; @@ -197,12 +206,102 @@ CurveLine::GetLength( double& dLen) const bool CurveLine::Reverse( void) { + // verifico lo stato + if ( m_nStatus != OK) + return false ; + // inverto i punti estremi swap( m_PtStart, m_PtEnd) ; return true ; } +//---------------------------------------------------------------------------- +bool +CurveLine::TrimStartAtParam( double dUTrim) +{ + double dLen ; + + + // riporto i parametri nel loro range + dUTrim = ( ( dUTrim < PAR_START) ? PAR_START : (( dUTrim > PAR_END) ? PAR_END : dUTrim)) ; + + // recupero lunghezza + if ( ! GetLength( dLen)) + return false ; + + // utilizzo il trim sulle lunghezze + return TrimStartAtLen( dUTrim * dLen) ; +} + +//---------------------------------------------------------------------------- +bool +CurveLine::TrimEndAtParam( double dUTrim) +{ + double dLen ; + + + // riporto i parametri nel loro range + dUTrim = ( ( dUTrim < PAR_START) ? PAR_START : (( dUTrim > PAR_END) ? PAR_END : dUTrim)) ; + + // recupero lunghezza + if ( ! GetLength( dLen)) + return false ; + + // utilizzo il trim sulle lunghezze + return TrimEndAtLen( dUTrim * dLen) ; +} + +//---------------------------------------------------------------------------- +bool +CurveLine::TrimStartAtLen( double dLenTrim) +{ + double dLen ; + + + // lunghezze negative vengono considerate nulle + dLenTrim = __max( dLenTrim, 0) ; + + // verifico che sia abbastanza lunga + if ( ! GetLength( dLen)) + return false ; + if ( ( dLen - dLenTrim) < EPS_SMALL) + return false ; + + // eseguo il trim + if ( dLenTrim > EPS_ZERO) + m_PtStart = Media( m_PtStart, m_PtEnd, ( dLenTrim / dLen)) ; + + // con i controlli sopra fatti rimane validata + + return true ; +} + +//---------------------------------------------------------------------------- +bool +CurveLine::TrimEndAtLen( double dLenTrim) +{ + double dLen ; + + + // lunghezze negative vengono considerate nulle + dLenTrim = __max( dLenTrim, 0) ; + + // verifico che sia abbastanza lunga + if ( ! GetLength( dLen)) + return false ; + if ( dLenTrim < EPS_SMALL) + return false ; + + // eseguo il trim + if ( ( dLen - dLenTrim) > EPS_ZERO) + m_PtEnd = Media( m_PtStart, m_PtEnd, ( dLenTrim / dLen)) ; + + // con i controlli sopra fatti rimane validata + + return true ; +} + //---------------------------------------------------------------------------- bool CurveLine::Translate( const Vector3d& vtMove) diff --git a/CurveLine.h b/CurveLine.h index c12a6ac..2831d10 100644 --- a/CurveLine.h +++ b/CurveLine.h @@ -52,6 +52,10 @@ class CurveLine : public ICurveLine virtual bool GetPointTangNormCurv( double dU, Point3d& ptPos, Vector3d& vtT, Vector3d& vtN, double& dCurv) const { return ::GetPointTangNormCurv( *this, dU, ptPos, vtT, vtN, dCurv) ; } virtual bool Reverse( void) ; + virtual bool TrimStartAtParam( double dUTrim) ; + virtual bool TrimEndAtParam( double dUTrim) ; + virtual bool TrimStartAtLen( double dLenTrim) ; + virtual bool TrimEndAtLen( double dLenTrim) ; public : virtual bool Set( const Point3d& ptStart, const Point3d& ptEnd) ; @@ -72,6 +76,8 @@ class CurveLine : public ICurveLine private : enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ; + static const double PAR_START ; + static const double PAR_END ; private : Status m_nStatus ; // stato diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index cfed786bb1d97cbc65b173fc05799ecf070469fc..68c9bdf26b1eda855bc02d88285c405d7159d327 100644 GIT binary patch delta 72 zcmX?SeaU*m7dBQS1|0^&&1d<}Gfn;{tTVZRlVkE5K^f*82E)mX!n&I+glrf$H*tF~ N!xdUHBS}u<1^{)@75@ML delta 64 zcmca)ea?Er7dB=c2Gh+K`OY&<=Ht + diff --git a/EgtGeomKernel.vcxproj.filters b/EgtGeomKernel.vcxproj.filters index 7396a04..d836bf1 100644 --- a/EgtGeomKernel.vcxproj.filters +++ b/EgtGeomKernel.vcxproj.filters @@ -215,6 +215,9 @@ File di intestazione + + File di intestazione + diff --git a/GdbExecutor.cpp b/GdbExecutor.cpp index ff1e6dc..6765d27 100644 --- a/GdbExecutor.cpp +++ b/GdbExecutor.cpp @@ -106,6 +106,8 @@ GdbExecutor::Execute( const string& sCmd1, const string& sCmd2, const STRVECTOR& return ExecuteScale( vsParams) ; else if ( sCmd1 == "MIRROR") return ExecuteMirror( vsParams) ; + else if ( sCmd1 == "TRIMCURVE" || sCmd1 == "TRC") + return ExecuteTrimCurve( sCmd2, vsParams) ; else if ( sCmd1 == "LOAD") return ExecuteLoad( vsParams) ; else if ( sCmd1 == "SAVE") @@ -426,6 +428,45 @@ GdbExecutor::ExecuteCurveBez( const string& sCmd2, const STRVECTOR& vsParams) return false ; } } + // curva di Bezier equivalente ad un arco + else if ( sCmd2 == "ARC" || sCmd2 == "A") { + Point3d ptCen ; + Vector3d vtN ; + double dRad ; + Vector3d vtS ; + double dAngCenDeg ; + double dDeltaZ ; + // 8 parametri + if ( vsParams.size() != 8) + return false ; + // centro + if ( ! GetPointParam( vsParams[2], ptCen)) + return false ; + // versore ortogonale al piano della circonferenza + if ( ! GetVectorParam( vsParams[3], vtN)) + return false ; + // raggio + if ( ! FromString( vsParams[4], dRad)) + return false ; + // versore iniziale + if ( ! GetVectorParam( vsParams[5], vtS)) + return false ; + // angolo al centro + if ( ! FromString( vsParams[6], dAngCenDeg)) + return false ; + // deltaZ + if ( ! FromString( vsParams[7], dDeltaZ)) + return false ; + // imposto l'arco + PtrOwner pCrvArc( CreateCurveArc()) ; + if ( ! IsValid( pCrvArc)) + return false ; + if ( ! pCrvArc->Set( ptCen, vtN, dRad, vtS, dAngCenDeg, dDeltaZ)) + return false ; + // ne deduco la curva di Bezier + if ( ! pCrvBez->SetFromArc( *pCrvArc)) + return false ; + } // altrimenti errore else return false ; @@ -798,6 +839,67 @@ GdbExecutor::ExecuteMirror( const STRVECTOR& vsParams) return true ; } +//---------------------------------------------------------------------------- +bool +GdbExecutor::ExecuteTrimCurve( const std::string& sCmd2, const STRVECTOR& vsParams) +{ + enum SeLp { SL, EL, SP, EP} ; + SeLp StEnLenPar ; + double dPar ; + STRVECTOR vsNames ; + STRVECTOR::iterator Iter ; + ICurve* pCurve ; + + + // 2 parametri ( Nome, parametro) + if ( vsParams.size() != 2) + return false ; + // recupero lista nomi + if ( ! GetNamesParam( vsParams[0], vsNames)) + return false ; + // recupero i dati di inizio + if ( ! FromString( vsParams[1], dPar)) + return false ; + // determino il tipo di trim + if ( sCmd2 == "STARTLEN" || sCmd2 == "SL") + StEnLenPar = SL ; + else if ( sCmd2 == "ENDLEN" || sCmd2 == "EL") + StEnLenPar = EL ; + else if ( sCmd2 == "STARTPAR" || sCmd2 == "SP") + StEnLenPar = SP ; + else if ( sCmd2 == "ENDPAR" || sCmd2 == "EP") + StEnLenPar = EP ; + else + return false ; + // esecuzione trim + for ( Iter = vsNames.begin() ; Iter != vsNames.end() ; ++Iter) { + if ( ( pCurve = GetCurve( m_pGDB->GetGeoObj( GetIdParam( *Iter)))) != nullptr) { + switch ( StEnLenPar) { + case SL : + if ( ! pCurve->TrimStartAtLen( dPar)) + return false ; + break ; + case EL : + if ( ! pCurve->TrimEndAtLen( dPar)) + return false ; + break ; + case SP : + if ( ! pCurve->TrimStartAtParam( dPar)) + return false ; + break ; + case EP : + if ( ! pCurve->TrimEndAtParam( dPar)) + return false ; + break ; + } + } + else + return false ; + } + + return true ; +} + //---------------------------------------------------------------------------- bool GdbExecutor::ExecuteLoad( const STRVECTOR& vsParams) diff --git a/GdbExecutor.h b/GdbExecutor.h index bffef3a..979e261 100644 --- a/GdbExecutor.h +++ b/GdbExecutor.h @@ -44,12 +44,13 @@ class GdbExecutor : public IGdbExecutor bool ExecuteCurveArc( const std::string& sCmd2, const STRVECTOR& vsParams) ; bool ExecuteCurveBez( const std::string& sCmd2, const STRVECTOR& vsParams) ; bool ExecuteCurveCompo( const std::string& sCmd2, const STRVECTOR& vsParams) ; + bool ExecuteCopy( const STRVECTOR& vsParams) ; + bool ExecuteErase( const STRVECTOR& vsParams) ; bool ExecuteTranslate( const STRVECTOR& vsParams) ; bool ExecuteRotate( const STRVECTOR& vsParams) ; bool ExecuteScale( const STRVECTOR& vsParams) ; bool ExecuteMirror( const STRVECTOR& vsParams) ; - bool ExecuteCopy( const STRVECTOR& vsParams) ; - bool ExecuteErase( const STRVECTOR& vsParams) ; + bool ExecuteTrimCurve( const std::string& sCmd2, const STRVECTOR& vsParams) ; bool ExecuteLoad( const STRVECTOR& vsParams) ; bool ExecuteSave( const STRVECTOR& vsParams) ; bool ExecuteOutScl( const std::string& sCmd2, const STRVECTOR& vsParams) ; diff --git a/GdbGroup.cpp b/GdbGroup.cpp index 30cbca2..a6905a1 100644 --- a/GdbGroup.cpp +++ b/GdbGroup.cpp @@ -181,13 +181,13 @@ GdbGroup::Scale( const Point3d& ptCen, double dCoeffX, double dCoeffY, double dC bUniform = fabs( dCoeffX - dCoeffY) < EPS_SMALL && fabs( dCoeffX - dCoeffZ) < EPS_SMALL ; // se la scalatura è uniforme, basta portare il centro nel riferimento del gruppo - if ( bUniform) { + //if ( bUniform) { ptCenLoc = ptCen ; ptCenLoc.ToLoc( m_gfrFrame.m_frF) ; - } - // altrimenti si deve propagare il riferimento rispetto al centro - else - return false ; // !!!!! TODO !!!!! + // } + //// altrimenti si deve propagare il riferimento rispetto al centro + // else + // return false ; // !!!!! TODO !!!!! // ciclo sui nodi bOk = true ; diff --git a/GdbObj.cpp b/GdbObj.cpp index a398fa0..8cd2811 100644 --- a/GdbObj.cpp +++ b/GdbObj.cpp @@ -13,10 +13,13 @@ //--------------------------- Include ---------------------------------------- #include "stdafx.h" -#include -#include "\EgtDev\Include\EGnStringUtils.h" #include "GdbObj.h" #include "GeoObjFactory.h" +#include "/EgtDev/Include/EGnStringUtils.h" +#include "/EgtDev/Include/EgtPointerOwner.h" +#include "/EgtDev/Include/EgkCurveBezier.h" +#include "/EgtDev/Include/EgkCurveArc.h" +#include using namespace std ; @@ -143,8 +146,23 @@ GdbObj::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, doubl bool GdbObj::Scale( const Point3d& ptCen, double dCoeffX, double dCoeffY, double dCoeffZ) { - if ( m_pGeoObj != nullptr) + if ( m_pGeoObj != nullptr) { + // se scalatura non omogenea e arco, devo trasformare in curva di Bezier + if ( m_pGeoObj->GetType() == CRV_ARC && + (fabs( dCoeffX - dCoeffY) > EPS_SMALL || fabs( dCoeffX - dCoeffZ) > EPS_SMALL)) { + // creo la curva di Bezier + PtrOwner pCrvBez( CreateCurveBezier()) ; + if ( ! IsValid( pCrvBez)) + return false ; + if ( ! pCrvBez->SetFromArc( *GetCurveArc( m_pGeoObj))) + return false ; + // elimino l'arco e lo sostituisco con la curva di Bezier + delete m_pGeoObj ; + m_pGeoObj = Release( pCrvBez) ; + } + // eseguo scalatura return m_pGeoObj->Scale( ptCen, dCoeffX, dCoeffY, dCoeffZ) ; + } else return false ; }