From ef75e1d83a76e29d7e9264235383ff944c7b9b40 Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Mon, 12 May 2014 08:58:11 +0000 Subject: [PATCH] EgtGeomKernel 1.5e3 : - correzioni a Trimesh - modifiche varie per gestione punti notevoli - creazione linee con DirLen e con VersLen - crezione curve composite da vettori di punti anche con bulge. --- CurveArc.cpp | 58 ++- CurveArc.h | 9 + CurveAux.cpp | 8 + CurveAux.h | 1 + CurveBezier.cpp | 62 ++- CurveBezier.h | 11 + CurveComposite.cpp | 133 +++++- CurveComposite.h | 11 + CurveLine.cpp | 75 +++- CurveLine.h | 10 + EgtGeomKernel.rc | Bin 11710 -> 11710 bytes Frame3d.cpp | 17 + GdbExecutor.cpp | 995 ++++++++++++++++++++++++++++++++++++++------- GdbExecutor.h | 12 +- GeoFrame3d.cpp | 20 + GeoFrame3d.h | 2 + Point3d.cpp | 13 + SurfTriMesh.cpp | 25 +- Vector3d.cpp | 13 + 19 files changed, 1283 insertions(+), 192 deletions(-) diff --git a/CurveArc.cpp b/CurveArc.cpp index 3a8fb19..245241c 100644 --- a/CurveArc.cpp +++ b/CurveArc.cpp @@ -108,7 +108,7 @@ CurveArc::Set( const Point3d& ptIni, const Point3d& ptFin, const Vector3d& vtN, m_dDeltaN = 0 ; // verifico sia un arco (uso la lunghezza della saetta) double dDist = vtDiff.Len() ; - if ( fabs( dBulge * 0.5 * dDist) < EPS_SMALL) + if ( fabs( dBulge * 0.5 * dDist) < EPS_ZERO) return false ; // calcolo del centro Vector3d vtOrtho = vtDiff ; @@ -414,6 +414,62 @@ CurveArc::GetEndPoint( Point3d& ptEnd) const return true ; } +//---------------------------------------------------------------------------- +bool +CurveArc::GetMidPoint( Point3d& ptMid) const +{ + // verifico lo stato + if ( m_nStatus != OK) + return false ; + + // calcolo il punto + double dAng = 0.5 * m_dAngCenDeg * DEGTORAD ; + Vector3d vtDir = cos( dAng) * m_VtS + sin( dAng) * ( m_VtN ^ m_VtS) ; + ptMid = m_PtCen + m_dRad * vtDir ; + if ( fabs( m_dDeltaN) > EPS_ZERO) + ptMid += ( 0.5 * m_dDeltaN) * m_VtN ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +CurveArc::GetCenterPoint( Point3d& ptCen) const +{ + // verifico lo stato + if ( m_nStatus != OK) + return false ; + + // assegno il centro + ptCen = m_PtCen ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +CurveArc::GetDir( double dU, Vector3d& vtDir) const +{ + // la curva deve essere valida + if ( m_nStatus != OK) + return false ; + + // il parametro U deve essere compreso tra 0 e 1 + if ( dU < 0) + dU = 0 ; + else if ( dU > 1) + dU = 1 ; + + // versore al punto nel piano della circonferenza (ruoto m_VtS di dU * m_dAngCenDeg attorno a m_VtN) + double dAng = dU * m_dAngCenDeg * DEGTORAD ; + Vector3d vtRad = cos( dAng) * m_VtS + sin( dAng) * ( m_VtN ^ m_VtS) ; + // calcolo della tangente nel punto finale + vtDir = ( m_dRad * m_dAngCenDeg * DEGTORAD) * ( m_VtN ^ vtRad) ; + if ( fabs( m_dDeltaN) > EPS_ZERO) + vtDir += m_dDeltaN * m_VtN ; + // normalizzo + return vtDir.Normalize() ; +} + //---------------------------------------------------------------------------- bool CurveArc::GetPointD1D2( double dU, Side nS, Point3d& ptPos, Vector3d* pvtDer1, Vector3d* pvtDer2) const diff --git a/CurveArc.h b/CurveArc.h index b5dd953..6f5f0eb 100644 --- a/CurveArc.h +++ b/CurveArc.h @@ -54,6 +54,14 @@ class CurveArc : public ICurveArc, public IGeoObjRW { return ::IsClosed( *this) ; } virtual bool GetStartPoint( Point3d& ptStart) const ; virtual bool GetEndPoint( Point3d& ptEnd) const ; + virtual bool GetMidPoint( Point3d& ptMid) const ; + virtual bool GetCenterPoint( Point3d& ptCen) const ; + virtual bool GetStartDir( Vector3d& vtDir) const + { return GetDir( 0, vtDir) ; } + virtual bool GetEndDir( Vector3d& vtDir) const + { return GetDir( 1, vtDir) ; } + virtual bool GetMidDir( Vector3d& vtDir) const + { return GetDir( 0.5, vtDir) ; } virtual bool GetDomain( double& dStart, double& dEnd) const { dStart = 0 ; dEnd = 1 ; return ( m_nStatus == OK) ; } virtual bool GetLength( double& dLen) const ; @@ -114,6 +122,7 @@ class CurveArc : public ICurveArc, public IGeoObjRW private : bool Copy( const CurveArc& caSrc) ; bool Validate( void) ; + bool GetDir( double dU, Vector3d& vtDir) const ; private : enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ; diff --git a/CurveAux.cpp b/CurveAux.cpp index bd777ae..56a9448 100644 --- a/CurveAux.cpp +++ b/CurveAux.cpp @@ -31,6 +31,14 @@ IsClosed( const ICurve& crvC) return ( crvC.GetStartPoint( ptStart) && crvC.GetEndPoint( ptEnd) && AreSamePointNear( ptStart, ptEnd)) ; } +//---------------------------------------------------------------------------- +bool +GetTang( const ICurve& crvC, double dU, ICurve::Side nS, Vector3d& vtTang) +{ + Point3d ptPos ; + return GetPointTang( crvC, dU, nS, ptPos, vtTang) ; +} + //---------------------------------------------------------------------------- bool GetPointTang( const ICurve& crvC, double dU, ICurve::Side nS, Point3d& ptPos, Vector3d& vtTang) diff --git a/CurveAux.h b/CurveAux.h index 09db63d..0caf30e 100644 --- a/CurveAux.h +++ b/CurveAux.h @@ -17,6 +17,7 @@ //---------------------------------------------------------------------------- bool IsClosed( const ICurve& crvC) ; +bool GetTang( const ICurve& crvC, double dU, ICurve::Side nS, Vector3d& vtTang) ; bool GetPointTang( const ICurve& crvC, double dU, ICurve::Side nS, Point3d& ptPos, Vector3d& vtTang) ; bool GetPointDiffGeom( const ICurve& crvC, double dU, ICurve::Side nS, CrvPointDiffGeom& oDiffG) ; diff --git a/CurveBezier.cpp b/CurveBezier.cpp index 1e00eff..ebadb96 100644 --- a/CurveBezier.cpp +++ b/CurveBezier.cpp @@ -490,10 +490,48 @@ CurveBezier::GetEndPoint( Point3d& ptEnd) const } //---------------------------------------------------------------------------- -// Calcolo i polinomi di Bernstein e da questi il punto ( vedi Piegl-Tiller) +bool +CurveBezier::GetMidPoint( Point3d& ptMid) const +{ + // verifico lo stato + if ( m_nStatus != OK) + return false ; + + // calcolo il punto + return GetPointD1D2( 0.5, ptMid) ; +} + //---------------------------------------------------------------------------- bool CurveBezier::GetPointD1D2( double dU, Side nS, Point3d& ptPos, Vector3d* pvtDer1, Vector3d* pvtDer2) const +{ + // la curva deve essere validata + if ( m_nStatus != OK) + return false ; + + // il parametro U deve essere compreso tra 0 e 1 + if ( dU < 0) + dU = 0 ; + else if ( dU > 1) + dU = 1 ; + + // verifico se punto singolare + double dSingU ; + if ( GetSingularParam( dSingU) > 0 && fabs( dU - dSingU) < EPS_PARAM) { + if ( nS == ICurve::FROM_MINUS) + dU -= 100 * EPS_PARAM ; + else + dU += 100 * EPS_PARAM ; + } + + return GetPointD1D2( dU, ptPos, pvtDer1, pvtDer2) ; +} + +//---------------------------------------------------------------------------- +// Calcolo i polinomi di Bernstein e da questi il punto ( vedi Piegl-Tiller) +//---------------------------------------------------------------------------- +bool +CurveBezier::GetPointD1D2( double dU, Point3d& ptPos, Vector3d* pvtDer1, Vector3d* pvtDer2) const { int i ; double dBern[MAXDEG] ; @@ -709,13 +747,13 @@ CurveBezier::CalcSingularParam( void) const DBLVECTOR vdRoot ; int nZ = pol3P.FindMainComponentRoots( vdRoot) ; // scarto gli zeri fuori dall'intervallo aperto 0-1 e quelli ripetuti - nZ = FilterMultipleAndOutOfRangeRoots( vdRoot, 0 + EPS_ZERO, 1 - EPS_ZERO, EPS_ZERO) ; + nZ = FilterMultipleAndOutOfRangeRoots( vdRoot, 0 + EPS_PARAM, 1 - EPS_PARAM, EPS_PARAM) ; // verifico se in corrispondenza di qualche zero si annulla la derivata Point3d ptPos ; Vector3d vtDer1 ; for ( int i = 0 ; i < nZ ; ++ i) { - GetPointD1D2( vdRoot[i], FROM_MINUS, ptPos, &vtDer1) ; + GetPointD1D2( vdRoot[i], ptPos, &vtDer1) ; if ( vtDer1.IsZero()) { m_dParSing = vdRoot[i] ; LOG_DBG_INFO( GetEGkLogger(), "INFO : Found Singularity in CurveBezier") @@ -898,12 +936,12 @@ CurveBezier::GetSegmentLength( int nLev, double dU0, double dU1, double dU2, // prima metà dUMid = 0.5 * ( dU0 + dU1) ; - GetPointD1D2( dUMid, ICurve::FROM_MINUS, ptMid) ; + GetPointD1D2( dUMid, ptMid) ; double dD3 = GetSegmentLength( nLev +1, dU0, dUMid, dU1, ptP0, ptMid, ptP1) ; // seconda metà dUMid = 0.5 * ( dU1 + dU2) ; - GetPointD1D2( dUMid, ICurve::FROM_MINUS, ptMid) ; + GetPointD1D2( dUMid, ptMid) ; double dD4 = GetSegmentLength( nLev + 1, dU1, dUMid, dU2, ptP1, ptMid, ptP2) ; @@ -933,13 +971,13 @@ CurveBezier::GetLengthAtParam( double dU, double& dLen) const return false ; // fuori dominio del parametro -> errore - if ( dU < 0 - EPS_ZERO) + if ( dU < 0 - EPS_PARAM) return false ; - if ( dU > ( 1 + EPS_ZERO)) + if ( dU > ( 1 + EPS_PARAM)) return false ; // inizio - if ( dU < 0 + EPS_ZERO) { + if ( dU < 0 + EPS_PARAM) { dLen = 0 ; return true ; } @@ -947,11 +985,11 @@ CurveBezier::GetLengthAtParam( double dU, double& dLen) const // parto con un numero fisso di punti e poi affino dove serve dLen = 0 ; dUIni = 0 ; - GetPointD1D2( 0, ICurve::FROM_MINUS, ptIni) ; + GetPointD1D2( 0, ptIni) ; for ( int i = 1 ; i <= NUM_SEG ; ++ i) { // ricavo il punto dUFin = i / (double) NUM_SEG * dU ; - GetPointD1D2( dUFin, ICurve::FROM_MINUS, ptFin) ; + GetPointD1D2( dUFin, ptFin) ; // se punto dispari if ( ( i % 2) == 1) { // assegno nuovo medio @@ -984,11 +1022,11 @@ CurveBezier::GetSegmentParam( double dLen, double& dCurrLen, double& dSegLen, double dUStart = dUIni ; double dUEnd = dUFin ; - GetPointD1D2( dUIni, ICurve::FROM_MINUS, ptIni) ; + GetPointD1D2( dUIni, ptIni) ; for ( int i = 1 ; i <= NUM_SEG ; ++ i) { // ricavo il punto dUFin = dUStart + i / (double) NUM_SEG * ( dUEnd - dUStart) ; - GetPointD1D2( dUFin, ICurve::FROM_MINUS, ptFin) ; + GetPointD1D2( dUFin, ptFin) ; // se punto dispari if ( ( i % 2) == 1) { // assegno nuovo medio diff --git a/CurveBezier.h b/CurveBezier.h index 6815178..f76dab7 100644 --- a/CurveBezier.h +++ b/CurveBezier.h @@ -55,6 +55,15 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW { return ::IsClosed( *this) ; } virtual bool GetStartPoint( Point3d& ptStart) const ; virtual bool GetEndPoint( Point3d& ptEnd) const ; + virtual bool GetMidPoint( Point3d& ptMid) const ; + virtual bool GetCenterPoint( Point3d& ptCen) const + { return GetMidPoint( ptCen) ; } + virtual bool GetStartDir( Vector3d& vtDir) const + { return ::GetTang( *this, 0, FROM_PLUS, vtDir) ; } + virtual bool GetEndDir( Vector3d& vtDir) const + { return ::GetTang( *this, 1, FROM_MINUS, vtDir) ; } + virtual bool GetMidDir( Vector3d& vtDir) const + { return ::GetTang( *this, 0.5, FROM_MINUS, vtDir) ; } virtual bool GetDomain( double& dStart, double& dEnd) const { dStart = 0 ; dEnd = 1 ; return ( m_nStatus == OK) ; } virtual bool GetLength( double& dLen) const ; @@ -104,6 +113,8 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW private : bool Copy( const CurveBezier& cbSrc) ; bool Validate( void) ; + bool GetPointD1D2( double dU, Point3d& ptPos, + Vector3d* pvtDer1 = nullptr, Vector3d* pvtDer2 = nullptr) const ; void IncreaseBernsteinOneDegree( double dU, int nDeg, double dBern[]) const ; bool CalcSingularParam( void) const ; double GetSegmentLength( int nLev, double dU0, double dU1, double dU2, diff --git a/CurveComposite.cpp b/CurveComposite.cpp index 17dea4c..6de2262 100644 --- a/CurveComposite.cpp +++ b/CurveComposite.cpp @@ -20,6 +20,7 @@ #include "NgeReader.h" #include "/EgtDev/Include/EGnStringUtils.h" #include "/EgtDev/Include/EgtPointerOwner.h" +#include "/EgtDev/Include/EGkCurveLine.h" #include "/EgtDev/Include/EGkCurveArc.h" #include "/EgtDev/Include/EGkCurveBezier.h" #include @@ -73,10 +74,8 @@ CurveComposite::AddCurve( const ICurve& cCrv) if ( pSmplCrv == nullptr) return false ; // inserisco la curva - if ( ! AddSimpleCurve( pSmplCrv)) { - delete pSmplCrv ; + if ( ! AddSimpleCurve( pSmplCrv)) return false ; - } } // altrimenti curva composta, devo aggiungere le singole curve semplici else { @@ -94,10 +93,8 @@ CurveComposite::AddCurve( const ICurve& cCrv) if ( pSmplCrv == nullptr) return false ; // inserisco la curva - if ( ! AddSimpleCurve( pSmplCrv)) { - delete pSmplCrv ; + if ( ! AddSimpleCurve( pSmplCrv)) return false ; - } // passo alla prossima curva componente pCrvOri = pCrvCompo->GetNextCurve() ; } @@ -116,10 +113,8 @@ CurveComposite::AddCurve( ICurve* pCrv) // se curva semplice if ( pCrv->IsSimple()) { // inserisco la curva - if ( ! AddSimpleCurve( pCrv)) { - delete pCrv ; + if ( ! AddSimpleCurve( pCrv)) return false ; - } } // altrimenti curva composta, devo aggiungere le singole curve semplici else { @@ -131,10 +126,8 @@ CurveComposite::AddCurve( ICurve* pCrv) ICurve* pSmplCrv ; while ( ( pSmplCrv = pCrvCompo->RemoveFirstCurve()) != nullptr) { // inserisco la curva - if ( ! AddSimpleCurve( pSmplCrv)) { - delete pSmplCrv ; + if ( ! AddSimpleCurve( pSmplCrv)) return false ; - } } // cancello la curva composita originaria delete pCrvCompo ; @@ -154,16 +147,21 @@ CurveComposite::AddSimpleCurve( ICurve* pSmplCrv) Point3d ptEnd ; + // prendo la proprietà del puntatore + PtrOwner pCrv( pSmplCrv) ; + if ( ! ::IsValid( pCrv)) + return false ; + // verifico lo stato if ( m_nStatus != OK && ! ( m_nCounter == 0 && m_nStatus == TO_VERIFY)) return false ; // verifico che il parametro sia una curva semplice - if ( ! pSmplCrv->IsSimple()) + if ( ! pCrv->IsSimple()) return false ; // recupero i punti iniziali e finali della curva - if ( ! pSmplCrv->GetStartPoint( ptStart) || ! pSmplCrv->GetEndPoint( ptEnd)) + if ( ! pCrv->GetStartPoint( ptStart) || ! pCrv->GetEndPoint( ptEnd)) return false ; // se non è la prima, verifico sia in continuità con il finale corrente @@ -175,7 +173,7 @@ CurveComposite::AddSimpleCurve( ICurve* pSmplCrv) m_PtStart = ptStart ; // inserisco la curva nella lista - m_CrvSmplS.push_back( pSmplCrv) ; + m_CrvSmplS.push_back( ::Release( pCrv)) ; m_nCounter ++ ; // assegno il punto finale @@ -233,6 +231,90 @@ CurveComposite::FromSplit( const ICurve& cCrv, int nParts) return true ; } +//---------------------------------------------------------------------------- +bool +CurveComposite::FromPointVector( const PNTVECTOR& vPnt) +{ + // verifico lo stato + if ( m_nCounter != 0 || m_nStatus != TO_VERIFY) + return false ; + // devono essere almeno 2 punti + if ( vPnt.size() < 2) + return false ; + + // ciclo di inserimento dei segmenti che uniscono i punti + int iPrev = 0 ; + for ( int i = 1 ; i < int( vPnt.size()) ; ++ i) { + // se i punti della coppia coincidono, passo alla coppia successiva + if ( AreSamePointNear( vPnt[iPrev], vPnt[i])) + continue ; + // creo il segmento di retta + PtrOwner pCrvLine( CreateCurveLine()) ; + if ( ! ::IsValid( pCrvLine)) + return false ; + // assegno i punti estremi + if ( ! pCrvLine->Set( vPnt[iPrev], vPnt[i])) + return false ; + // aggiungo la retta alla curva composita + if ( ! AddSimpleCurve( Release( pCrvLine))) + return false ; + // aggiorno indice punto ultimo inserito + iPrev = i ; + } + + // imposto ricalcolo della grafica + m_OGrMgr.Reset() ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +CurveComposite::FromPointBulgeVector( const UPNTVECTOR& vUPnt, const Vector3d& vtN) +{ + // verifico lo stato + if ( m_nCounter != 0 || m_nStatus != TO_VERIFY) + return false ; + // devono essere almeno 2 punti + if ( vUPnt.size() < 2) + return false ; + + // Creo le diverse curve semplici e le inserisco in quella composita + for ( int i = 1 ; i < int( vUPnt.size()) ; ++i) { + // se i punti della coppia coincidono, passo alla coppia successiva + if ( AreSamePointNear( vUPnt[i-1].second, vUPnt[i].second)) + continue ; + // se retta + if ( fabs( vUPnt[i-1].first) < EPS_SMALL) { + // creo la retta + PtrOwner pCrvLine( CreateCurveLine()) ; + if ( ! ::IsValid( pCrvLine)) + return false ; + // setto la linea + if ( ! pCrvLine->Set( vUPnt[i-1].second, vUPnt[i].second)) + return false ; + // inserisco la linea nella curva composta + if ( ! AddSimpleCurve( ::Release( pCrvLine))) + return false ; + } + // altrimenti arco + else { + // creo l'arco + PtrOwner pCrvArc( CreateCurveArc()) ; + if ( ! ::IsValid( pCrvArc)) + return false ; + // setto l'arco + if ( ! pCrvArc->Set( vUPnt[i-1].second, vUPnt[i].second, vtN, vUPnt[i-1].first)) + return false ; + // inserisco l'arco nella curva composta + if ( ! AddSimpleCurve( Release( pCrvArc))) + return false ; + } + } + + return true ; +} + //---------------------------------------------------------------------------- CurveComposite* CurveComposite::Clone( void) const @@ -383,10 +465,8 @@ CurveComposite::Load( NgeReader& ngeIn) // aggiungo questa curva (sicuramente semplice) bOk = bOk && AddSimpleCurve( pCrv) ; // se errore - if ( ! bOk) { - delete pGeoO ; + if ( ! bOk) return false ; - } } return true ; @@ -512,6 +592,23 @@ CurveComposite::GetEndPoint( Point3d& ptEnd) const return true ; } +//---------------------------------------------------------------------------- +bool +CurveComposite::GetMidPoint( Point3d& ptMid) const +{ + // verifico lo stato + if ( m_nStatus != OK) + return false ; + + // determino il valore medio del parametro della curva + double dStart, dEnd, dMid ; + GetDomain( dStart, dEnd) ; + dMid = 0.5 * ( dStart + dEnd) ; + + // calcolo il punto + return GetPointD1D2( dMid, FROM_MINUS, ptMid) ; +} + //---------------------------------------------------------------------------- bool CurveComposite::GetDomain( double& dStart, double& dEnd) const diff --git a/CurveComposite.h b/CurveComposite.h index 6333f92..28a7bc6 100644 --- a/CurveComposite.h +++ b/CurveComposite.h @@ -55,6 +55,15 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW { return ::IsClosed( *this) ; } virtual bool GetStartPoint( Point3d& ptStart) const ; virtual bool GetEndPoint( Point3d& ptEnd) const ; + virtual bool GetMidPoint( Point3d& ptMid) const ; + virtual bool GetCenterPoint( Point3d& ptCen) const + { return GetMidPoint( ptCen) ; } + virtual bool GetStartDir( Vector3d& vtDir) const + { return ::GetTang( *this, 0, FROM_PLUS, vtDir) ; } + virtual bool GetEndDir( Vector3d& vtDir) const + { return ::GetTang( *this, 1, FROM_MINUS, vtDir) ; } + virtual bool GetMidDir( Vector3d& vtDir) const + { return ::GetTang( *this, 0.5, FROM_MINUS, vtDir) ; } virtual bool GetDomain( double& dStart, double& dEnd) const ; virtual bool GetLength( double& dLen) const ; virtual bool GetPointD1D2( double dU, Side nS, Point3d& ptPos, @@ -77,6 +86,8 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW virtual bool AddCurve( const ICurve& cCrv) ; virtual bool AddCurve( ICurve* pCrv) ; virtual bool FromSplit( const ICurve& cCrv, int nParts) ; + virtual bool FromPointVector( const PNTVECTOR& vPnt) ; + virtual bool FromPointBulgeVector( const UPNTVECTOR& vUPnt, const Vector3d& vtN) ; virtual int GetCurveNumber( void) const { return m_nCounter ; } virtual const ICurve* GetFirstCurve( void) const ; virtual const ICurve* GetNextCurve( void) const ; diff --git a/CurveLine.cpp b/CurveLine.cpp index 1779fb6..716b443 100644 --- a/CurveLine.cpp +++ b/CurveLine.cpp @@ -1,13 +1,13 @@ //---------------------------------------------------------------------------- -// EgalTech 2013-2013 +// EgalTech 2014-2014 //---------------------------------------------------------------------------- -// File : CurveLine.cpp Data : 16.04.13 Versione : 1.1d1 +// File : CurveLine.cpp Data : 06.05.14 Versione : 1.5e3 // Contenuto : Implementazione della classe Segmento di Linea. // // // // Modifiche : 16.04.13 DS Creazione modulo. -// +// 06.05.14 DS Aggiunta Set per Pini, vtDir, Len e per Pini, AngDir, Len. // //---------------------------------------------------------------------------- @@ -51,6 +51,42 @@ CurveLine::Set( const Point3d& ptStart, const Point3d& ptEnd) return Validate() ; } +//---------------------------------------------------------------------------- +bool +CurveLine::Set( const Point3d& ptStart, const Vector3d& vtDir, double dLen) +{ + // assegno i dati + m_PtStart = ptStart ; + Vector3d vtDelta = vtDir ; + if ( ! vtDelta.Normalize()) + return false ; + vtDelta *= dLen ; + m_PtEnd = ptStart + vtDelta ; + m_nStatus = TO_VERIFY ; + + // imposto ricalcolo della grafica + m_OGrMgr.Reset() ; + + return Validate() ; +} + +//---------------------------------------------------------------------------- +bool +CurveLine::Set( const Point3d& ptStart, double dDirAngDeg, double dLen) +{ + // assegno i dati + m_PtStart = ptStart ; + Vector3d vtDelta ; + vtDelta.FromPolar( dLen, dDirAngDeg) ; + m_PtEnd = ptStart + vtDelta ; + m_nStatus = TO_VERIFY ; + + // imposto ricalcolo della grafica + m_OGrMgr.Reset() ; + + return Validate() ; +} + //---------------------------------------------------------------------------- CurveLine* CurveLine::Clone( void) const @@ -108,7 +144,11 @@ CurveLine::Dump( string& sOut, const char* szNewLine) const // parametri : punti iniziale e finale sOut += "P1(" + ToString( m_PtStart, 3) + ")" + szNewLine ; sOut += "P2(" + ToString( m_PtEnd, 3) + ")" + szNewLine ; - + // altri dati : angolo vert, angolo orizz, lunghezza + double dLen, dAngVertDeg, dAngOrizzDeg ; + ( m_PtEnd - m_PtStart).ToSpherical( &dLen, &dAngVertDeg, &dAngOrizzDeg) ; + sOut += "Av=" + ToString( dAngVertDeg, 3) + " Ao=" + ToString( dAngOrizzDeg, 3) + + " L=" + ToString( dLen, 3) + szNewLine ; return true ; } @@ -216,6 +256,33 @@ CurveLine::GetEndPoint( Point3d& ptEnd) const return true ; } +//---------------------------------------------------------------------------- +bool +CurveLine::GetMidPoint( Point3d& ptMid) const +{ + // verifico lo stato + if ( m_nStatus != OK) + return false ; + + // assegno il punto + ptMid = Media( m_PtStart, m_PtEnd, 0.5) ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +CurveLine::GetStartDir( Vector3d& vtDir) const +{ + // verifico lo stato + if ( m_nStatus != OK) + return false ; + + // calcolo la direzione + vtDir = m_PtEnd - m_PtStart ; + return vtDir.Normalize() ; +} + //---------------------------------------------------------------------------- bool CurveLine::GetPointD1D2( double dU, Side nS, Point3d& ptPos, Vector3d* pvtDer1, Vector3d* pvtDer2) const diff --git a/CurveLine.h b/CurveLine.h index a7dd988..2556799 100644 --- a/CurveLine.h +++ b/CurveLine.h @@ -54,6 +54,14 @@ class CurveLine : public ICurveLine, public IGeoObjRW { return ::IsClosed( *this) ; } virtual bool GetStartPoint( Point3d& ptStart) const ; virtual bool GetEndPoint( Point3d& ptEnd) const ; + virtual bool GetMidPoint( Point3d& ptMid) const ; + virtual bool GetCenterPoint( Point3d& ptCen) const + { return GetMidPoint( ptCen) ; } + virtual bool GetStartDir( Vector3d& vtDir) const ; + virtual bool GetEndDir( Vector3d& vtDir) const + { return GetStartDir( vtDir) ; } + virtual bool GetMidDir( Vector3d& vtDir) const + { return GetStartDir( vtDir) ; } virtual bool GetDomain( double& dStart, double& dEnd) const { dStart = 0 ; dEnd = 1 ; return ( m_nStatus == OK) ; } virtual bool GetLength( double& dLen) const ; @@ -74,6 +82,8 @@ class CurveLine : public ICurveLine, public IGeoObjRW public : // ICurveLine virtual bool Copy( const IGeoObj* pGObjSrc) ; virtual bool Set( const Point3d& ptStart, const Point3d& ptEnd) ; + virtual bool Set( const Point3d& ptStart, const Vector3d& vtDir, double dLen) ; + virtual bool Set( const Point3d& ptStart, double dDirAngDeg, double dLen) ; virtual const Point3d& GetStart( void) const { return m_PtStart ; } virtual const Point3d& GetEnd( void) const diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index efacc53409690714dde8b138ba21d1998d0baead..7dc06ef133e7b66db1660348a388a7d7dd4699b7 100644 GIT binary patch delta 81 zcmdlNy)SyhH#SD&&FAG5nSsGetGroupGlobFrame( GetIdParam( vsParams[1]), frRef)) return false ; + // recupero il riferimento + if ( vsParams.size() >= 3) { + if ( ! GetFrameParam( vsParams[2], frRef, frFrame)) + return false ; + } + else + frFrame = GLOB_FRM ; } // gruppo orientato come il padre else if ( sCmd2 == "XY" || sCmd2 == "PLANEXY") { @@ -204,8 +201,12 @@ GdbExecutor::ExecuteGroup( const string& sCmd2, const STRVECTOR& vsParams) // 3 parametri : Id, Id del padre, Orig if ( vsParams.size() != 3) return false ; + // recupero il riferimento in cui è immerso + Frame3d frRef ; + if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef)) + return false ; // recupero i componenti - if ( ! GetPointParam( vsParams[2], ptOrig)) + if ( ! GetPointParam( vsParams[2], frRef, ptOrig)) return false ; // costruisco il riferimento if ( ! frFrame.Set( ptOrig, Frame3d::TOP)) @@ -231,13 +232,15 @@ GdbExecutor::ExecutePoint( const string& sCmd2, const STRVECTOR& vsParams) // analisi ed esecuzione dei comandi if ( sCmd2 == "" || sCmd2 == "MAKE") { Point3d Pnt ; - // 5 parametri : Id, IdParent e 3 coordinate - if ( vsParams.size() != 5) + // 3 parametri : Id, IdParent e punto + if ( vsParams.size() != 3) return false ; - // recupero le tre coordinate - if ( ! FromString( vsParams[2], Pnt.x) || - ! FromString( vsParams[3], Pnt.y) || - ! FromString( vsParams[4], Pnt.z)) + // recupero il riferimento in cui è immerso + Frame3d frPnt ; + if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frPnt)) + return false ; + // recupero il punto + if ( ! GetPointParam( vsParams[2], frPnt, Pnt)) return false ; // creo il punto IGeoPoint3d* pGPnt = CreateGeoPoint3d() ; @@ -254,16 +257,18 @@ GdbExecutor::ExecutePoint( const string& sCmd2, const STRVECTOR& vsParams) bool GdbExecutor::ExecuteVector( const string& sCmd2, const STRVECTOR& vsParams) { - // analisi ed esecuzione dei comandi + // definizione diretta if ( sCmd2 == "" || sCmd2 == "MAKE") { Vector3d Vect ; - // 5 parametri - if ( vsParams.size() != 5) + // 3 parametri : Id, IdParent e vettore + if ( vsParams.size() != 3) + return false ; + // recupero il riferimento in cui è immerso + Frame3d frVect ; + if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frVect)) return false ; // recupero i tre componenti - if ( ! FromString( vsParams[2], Vect.x) || - ! FromString( vsParams[3], Vect.y) || - ! FromString( vsParams[4], Vect.z)) + if ( ! GetVectorParam( vsParams[2], frVect, Vect)) return false ; // creo il vettore IGeoVector3d* pGVect = CreateGeoVector3d() ; @@ -272,6 +277,68 @@ GdbExecutor::ExecuteVector( const string& sCmd2, const STRVECTOR& vsParams) pGVect->Set( Vect) ; return AddGeoObj( vsParams[0], vsParams[1], pGVect) ; } + // definizione come differenza di due punti + else if ( sCmd2 == "D" || sCmd2 == "DIFF") { + // 4 o 5 parametri : Id, IdParent, ptP1, ptP2 [, bNorm] + if ( vsParams.size() != 4 && vsParams.size() != 5) + return false ; + // recupero il riferimento in cui è immerso + Frame3d frVect ; + if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frVect)) + return false ; + // recupero il primo punto + Point3d ptP1 ; + if ( ! GetPointParam( vsParams[2], frVect, ptP1)) + return false ; + // recupero il secondo punto + Point3d ptP2 ; + if ( ! GetPointParam( vsParams[3], frVect, ptP2)) + return false ; + // flag di normalizzazione + bool bNorm = false ; + if ( vsParams.size() >= 5) + bNorm = ( vsParams[4] == "N") ; + // creo il vettore + IGeoVector3d* pGVect = CreateGeoVector3d() ; + if ( pGVect == nullptr) + return false ; + Vector3d vtV = ptP2 - ptP1 ; + if ( bNorm) + vtV.Normalize() ; + pGVect->Set( vtV) ; + return AddGeoObj( vsParams[0], vsParams[1], pGVect) ; + } + // definizione come prodotto vettoriale di due vettori + else if ( sCmd2 == "CP" || sCmd2 == "CROSSPROD") { + // 4 o 5 parametri : Id, IdParent, vtV1, vtV2 [, bNorm] + if ( vsParams.size() != 4 && vsParams.size() != 5) + return false ; + // recupero il riferimento in cui è immerso + Frame3d frVect ; + if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frVect)) + return false ; + // recupero il primo vettore + Vector3d vtV1 ; + if ( ! GetVectorParam( vsParams[2], frVect, vtV1)) + return false ; + // recupero il secondo vettore + Vector3d vtV2 ; + if ( ! GetVectorParam( vsParams[3], frVect, vtV2)) + return false ; + // flag di normalizzazione + bool bNorm = false ; + if ( vsParams.size() >= 5) + bNorm = ( vsParams[4] == "N") ; + // creo il vettore + IGeoVector3d* pGVect = CreateGeoVector3d() ; + if ( pGVect == nullptr) + return false ; + Vector3d vtCross = vtV1 ^ vtV2 ; + if ( bNorm) + vtCross.Normalize() ; + pGVect->Set( vtCross) ; + return AddGeoObj( vsParams[0], vsParams[1], pGVect) ; + } return false ; } @@ -280,26 +347,68 @@ GdbExecutor::ExecuteVector( const string& sCmd2, const STRVECTOR& vsParams) bool GdbExecutor::ExecuteFrame( const string& sCmd2, const STRVECTOR& vsParams) { - // analisi ed esecuzione dei comandi + // riferimento generico if ( sCmd2 == "" || sCmd2 == "MAKE") { - Point3d ptOrig ; - Vector3d vtDirX ; - Vector3d vtDirY ; - Vector3d vtDirZ ; - // 6 parametri - if ( vsParams.size() != 6) + // 3 parametri : Id, ParentId, Frame + if ( vsParams.size() != 3) return false ; - // recupero i componenti - if ( ! GetPointParam( vsParams[2], ptOrig) || - ! GetVectorParam( vsParams[3], vtDirX) || - ! GetVectorParam( vsParams[4], vtDirY) || - ! GetVectorParam( vsParams[5], vtDirZ)) + // recupero il riferimento in cui è immerso + Frame3d frRef ; + if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef)) + return false ; + // recupero il riferimento + Frame3d frFrame ; + if ( ! GetFrameParam( vsParams[2], frRef, frFrame)) return false ; // creo il riferimento IGeoFrame3d* pGFrame = CreateGeoFrame3d() ; if ( pGFrame == nullptr) return false ; - pGFrame->Set( ptOrig, vtDirX, vtDirY, vtDirZ) ; + pGFrame->Set( frFrame) ; + return AddGeoObj( vsParams[0], vsParams[1], pGFrame) ; + } + // riferimento da 3 punti + else if ( sCmd2 == "3P") { + // 5 parametri : Id, ParentId, ptOrig, ptOnX, ptNearY + if ( vsParams.size() != 5) + return false ; + // recupero il riferimento in cui è immerso + Frame3d frRef ; + if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef)) + return false ; + // recupero i componenti + Point3d ptOrig, ptOnX, ptNearY ; + if ( ! GetPointParam( vsParams[2], frRef, ptOrig) || + ! GetPointParam( vsParams[3], frRef, ptOnX) || + ! GetPointParam( vsParams[4], frRef, ptNearY)) + return false ; + // creo il riferimento + IGeoFrame3d* pGFrame = CreateGeoFrame3d() ; + if ( pGFrame == nullptr) + return false ; + pGFrame->Set( ptOrig, ptOnX, ptNearY) ; + return AddGeoObj( vsParams[0], vsParams[1], pGFrame) ; + } + // riferimento OCS + else if ( sCmd2 == "OCS") { + // 4 parametri + if ( vsParams.size() != 4) + return false ; + // recupero il riferimento in cui è immerso + Frame3d frRef ; + if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef)) + return false ; + // recupero i componenti + Point3d ptOrig ; + Vector3d vtDirZ ; + if ( ! GetPointParam( vsParams[2], frRef, ptOrig) || + ! GetVectorParam( vsParams[3], frRef, vtDirZ)) + return false ; + // creo il riferimento + IGeoFrame3d* pGFrame = CreateGeoFrame3d() ; + if ( pGFrame == nullptr) + return false ; + pGFrame->Set( ptOrig, vtDirZ) ; return AddGeoObj( vsParams[0], vsParams[1], pGFrame) ; } @@ -315,39 +424,89 @@ GdbExecutor::ExecuteCurveLine( const string& sCmd2, const STRVECTOR& vsParams) if ( ! IsValid( pCrvLine)) return false ; - // creazione linea dando gli estremi + // creazione linea da : ptStart, ptEnd if ( sCmd2 == "" || sCmd2 == "MAKE") { - // 4 parametri + // 4 parametri : Id, IdParent, ptStart, ptEnd if ( vsParams.size() != 4) return false ; + // recupero il riferimento in cui è immerso + Frame3d frRef ; + if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef)) + return false ; // recupero punto iniziale Point3d ptStart ; - if ( ! GetPointParam( vsParams[2], ptStart)) + if ( ! GetPointParam( vsParams[2], frRef, ptStart)) return false ; // recupero punto finale Point3d ptEnd ; - if ( ! GetPointParam( vsParams[3], ptEnd)) + if ( ! GetPointParam( vsParams[3], frRef, ptEnd)) return false ; // setto la linea if ( ! pCrvLine->Set( ptStart, ptEnd)) return false ; } + // creazione linea da : ptStart, vtDir, dLen + else if ( sCmd2 == "VL" || sCmd2 == "VersorLength") { + // 5 parametri : Id, IdParent, ptStart, vtDir, dLen + if ( vsParams.size() != 5) + return false ; + // recupero il riferimento in cui è immerso + Frame3d frRef ; + if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef)) + return false ; + // recupero punto iniziale + Point3d ptStart ; + if ( ! GetPointParam( vsParams[2], frRef, ptStart)) + return false ; + // recupero vettore direzione + Vector3d vtDir ; + if ( ! GetVectorParam( vsParams[3], frRef, vtDir)) + return false ; + // recupero lunghezza + double dLen ; + if ( ! GetLengthParam( vsParams[4], dLen)) + return false ; + // setto la linea + if ( ! pCrvLine->Set( ptStart, vtDir, dLen)) + return false ; + } + // creazione linea da : ptStart, dDirAngDeg, dLen + else if ( sCmd2 == "DL" || sCmd2 == "DirLength") { + // 5 parametri : Id, IdParent, ptStart, dAngDeg, dLen + if ( vsParams.size() != 5) + return false ; + // recupero il riferimento in cui è immerso + Frame3d frRef ; + if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef)) + return false ; + // recupero punto iniziale + Point3d ptStart ; + if ( ! GetPointParam( vsParams[2], frRef, ptStart)) + return false ; + // recupero direzione in gradi + double dDirAngDeg ; + if ( ! GetDirParam( vsParams[3], frRef, dDirAngDeg)) + return false ; + // recupero lunghezza + double dLen ; + if ( ! GetLengthParam( vsParams[4], dLen)) + return false ; + // setto la linea + if ( ! pCrvLine->Set( ptStart, dDirAngDeg, dLen)) + return false ; + } // creazione linea di minima distanza tra punto e curva else if ( sCmd2 == "MPC" || sCmd2 == "MINPOINTCURVE") { // almeno 4 parametri if ( vsParams.size() < 4) return false ; - // recupero l'identificativo del gruppo destinazione - int nIdParent ; - if ( ( nIdParent = GetIdParam( vsParams[1])) == CMD_ID_ERROR) - return false ; // recupero il riferimento del gruppo destinazione Frame3d frPoint ; - if ( ! m_pGDB->GetGroupGlobFrame( nIdParent, frPoint)) + if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frPoint)) return false ; // recupero il punto Point3d ptStart ; - if ( ! GetPointParam( vsParams[2], ptStart)) + if ( ! GetPointParam( vsParams[2], frPoint, ptStart)) return false ; // recupero l'identificativo della curva int nId ; @@ -404,13 +563,17 @@ GdbExecutor::ExecuteCurveArc( const string& sCmd2, const STRVECTOR& vsParams) // 8 parametri if ( vsParams.size() != 8) return false ; + // recupero il riferimento in cui è immerso + Frame3d frRef ; + if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef)) + return false ; // centro Point3d ptCen ; - if ( ! GetPointParam( vsParams[2], ptCen)) + if ( ! GetPointParam( vsParams[2], frRef, ptCen)) return false ; // versore ortogonale al piano della circonferenza Vector3d vtN ; - if ( ! GetVectorParam( vsParams[3], vtN)) + if ( ! GetVectorParam( vsParams[3], frRef, vtN)) return false ; // raggio double dRad ; @@ -418,7 +581,7 @@ GdbExecutor::ExecuteCurveArc( const string& sCmd2, const STRVECTOR& vsParams) return false ; // versore iniziale Vector3d vtS ; - if ( ! GetVectorParam( vsParams[5], vtS)) + if ( ! GetVectorParam( vsParams[5], frRef, vtS)) return false ; // angolo al centro double dAngCenDeg ; @@ -437,9 +600,13 @@ GdbExecutor::ExecuteCurveArc( const string& sCmd2, const STRVECTOR& vsParams) // 7 parametri if ( vsParams.size() != 7) return false ; + // recupero il riferimento in cui è immerso + Frame3d frRef ; + if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef)) + return false ; // centro Point3d ptCen ; - if ( ! GetPointParam( vsParams[2], ptCen)) + if ( ! GetPointParam( vsParams[2], frRef, ptCen)) return false ; // raggio double dRad ; @@ -461,14 +628,43 @@ GdbExecutor::ExecuteCurveArc( const string& sCmd2, const STRVECTOR& vsParams) if ( ! pCrvArc->Set( ptCen, dRad, dAngIniDeg, dAngCenDeg, dDeltaZ)) return false ; } + // circonferenza + else if ( sCmd2 == "C" || sCmd2 == "CIRCLE") { + // 5 parametri + if ( vsParams.size() != 5) + return false ; + // recupero il riferimento in cui è immerso + Frame3d frRef ; + if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef)) + return false ; + // centro + Point3d ptCen ; + if ( ! GetPointParam( vsParams[2], frRef, ptCen)) + return false ; + // versore ortogonale al piano della circonferenza + Vector3d vtN ; + if ( ! GetVectorParam( vsParams[3], frRef, vtN)) + return false ; + // raggio + double dRad ; + if ( ! FromString( vsParams[4], dRad)) + return false ; + // setto l'arco + if ( ! pCrvArc->Set( ptCen, vtN, dRad)) + return false ; + } // circonferenza nel piano XY else if ( sCmd2 == "CXY" || sCmd2 == "CIRCLEXY") { // 4 parametri if ( vsParams.size() != 4) return false ; + // recupero il riferimento in cui è immerso + Frame3d frRef ; + if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef)) + return false ; // centro Point3d ptCen ; - if ( ! GetPointParam( vsParams[2], ptCen)) + if ( ! GetPointParam( vsParams[2], frRef, ptCen)) return false ; // raggio double dRad ; @@ -512,9 +708,13 @@ GdbExecutor::ExecuteCurveBez( const string& sCmd2, const STRVECTOR& vsParams) // inizializzo la curva di Bezier if ( ! pCrvBez->Init( nDeg, false)) return false ; + // recupero il riferimento in cui è immersa + Frame3d frRef ; + if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef)) + return false ; // recupero e setto punti di controllo for ( i = 0 ; i <= nDeg ; ++ i) { - if ( ! GetPointParam( vsParams[i+3], ptP) || + if ( ! GetPointParam( vsParams[i+3], frRef, ptP) || ! pCrvBez->SetControlPoint( i, ptP)) return false ; } @@ -534,9 +734,13 @@ GdbExecutor::ExecuteCurveBez( const string& sCmd2, const STRVECTOR& vsParams) // inizializzo la curva di Bezier if ( ! pCrvBez->Init( nDeg, true)) return false ; + // recupero il riferimento in cui è immersa + Frame3d frRef ; + if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef)) + return false ; // recupero e setto punti di controllo for ( i = 0 ; i <= nDeg ; ++ i) { - if ( ! GetPointWParam( vsParams[i+3], ptP, dW) || + if ( ! GetPointWParam( vsParams[i+3], frRef, ptP, dW) || ! pCrvBez->SetControlPoint( i, ptP, dW)) return false ; } @@ -777,14 +981,19 @@ GdbExecutor::ExecuteSurfTriMesh( const string& sCmd2, const STRVECTOR& vsParams) { // se inizio creazione con componenti elementari if ( sCmd2 == "BEGIN") { - // 2 parametri opzionali : numero vertici e numero triangoli - if ( vsParams.size() > 2) + // 4 parametri (2 opzionali) : Id, ParentId[, numero vertici e numero triangoli] + if ( vsParams.size() < 2) return false ; - // recupero eventuali parametri + // recupero Id e ParentId + m_sId = vsParams[0] ; + m_sParentId = vsParams[1] ; + // recupero i parametri opzionali int nNumVert = 3 ; - FromString( vsParams[0], nNumVert) ; + if ( vsParams.size() >= 3) + FromString( vsParams[2], nNumVert) ; int nNumTria = 1 ; - FromString( vsParams[1], nNumTria) ; + if ( vsParams.size() >= 4) + FromString( vsParams[3], nNumTria) ; // creo la superficie ISurfTriMesh* pSTM = CreateSurfTriMesh() ; if ( pSTM == nullptr) @@ -803,9 +1012,13 @@ GdbExecutor::ExecuteSurfTriMesh( const string& sCmd2, const STRVECTOR& vsParams) // 1 parametro : punto if ( vsParams.size() != 1) return false ; + // recupero il riferimento in cui va inserito + Frame3d frRef ; + if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( m_sParentId), frRef)) + return false ; // recupero il punto Point3d ptP ; - if ( ! GetPointParam( vsParams[0], ptP)) + if ( ! GetPointParam( vsParams[0], frRef, ptP)) return false ; // recupero la superficie ISurfTriMesh* pSTM = GetSurfTriMesh( m_pGeoObj) ; @@ -834,8 +1047,8 @@ GdbExecutor::ExecuteSurfTriMesh( const string& sCmd2, const STRVECTOR& vsParams) } // se fine creazione else if ( sCmd2 == "END") { - // 2 parametri : Id e ParentId - if ( vsParams.size() != 2) + // nessun parametro + if ( vsParams.size() != 0) return false ; // recupero la superficie ISurfTriMesh* pSTM = GetSurfTriMesh( m_pGeoObj) ; @@ -846,7 +1059,10 @@ GdbExecutor::ExecuteSurfTriMesh( const string& sCmd2, const STRVECTOR& vsParams) return false ; // inserisco la superficie trimesh nel DB m_pGeoObj = nullptr ; - return AddGeoObj( vsParams[0], vsParams[1], pSTM) ; + bool bOk = AddGeoObj( m_sId, m_sParentId, pSTM) ; + m_sId.clear() ; + m_sParentId.clear() ; + return bOk ; } // se creazione per triangolazione di un contorno chiuso e piano else if ( sCmd2 == "CONT" || sCmd2 == "BYCONTOUR") { @@ -898,7 +1114,7 @@ GdbExecutor::ExecuteSurfTriMesh( const string& sCmd2, const STRVECTOR& vsParams) return false ; // recupero il vettore di estrusione Vector3d vtExtr ; - if ( ! GetVectorParam( vsParams[3], vtExtr)) + if ( ! GetVectorParam( vsParams[3], frDest, vtExtr)) return false ; // creo la superficie PtrOwner pSTM( CreateSurfTriMesh()) ; @@ -998,11 +1214,11 @@ GdbExecutor::SurfTriMeshByScrewing( bool bMove, const STRVECTOR& vsParams) return false ; // recupero il punto dell'asse di rivoluzione Point3d ptAx ; - if ( ! GetPointParam( vsParams[3], ptAx)) + if ( ! GetPointParam( vsParams[3], frDest, ptAx)) return false ; // recupero il vettore dell'asse di rivoluzione Vector3d vtAx ; - if ( ! GetVectorParam( vsParams[4], vtAx)) + if ( ! GetVectorParam( vsParams[4], frDest, vtAx)) return false ; // recupero l'angolo di rotazione double dAngRotDeg ; @@ -1112,7 +1328,7 @@ GdbExecutor::GetNamesParam( const string& sParam, INTVECTOR& vnNames) //---------------------------------------------------------------------------- bool -GdbExecutor::GetVectorParam( const string& sParam, Vector3d& vtV) +GdbExecutor::GetVectorParam( const string& sParam, const Frame3d& frVect, Vector3d& vtV) { // se insieme di tre componenti if ( sParam[0] == '(') { @@ -1159,21 +1375,144 @@ GdbExecutor::GetVectorParam( const string& sParam, Vector3d& vtV) vtV = - Z_AX ; return true ; } + // se altrimenti vettore notevole + else if ( sParam[0] == 'V') { + // recupero il tipo di vettore notevole + const char cType = sParam[1] ; + // recupero i parametri associati + STRVECTOR vsParams ; + Tokenize( sParam.substr( 3, sParam.length()-4), ",", "(", ")", vsParams) ; + STRVECTOR::iterator Iter ; + for ( Iter = vsParams.begin() ; Iter != vsParams.end() ; ++Iter) + Trim( (*Iter), " \t\r\n") ; + // ci deve essere almeno un parametro + if ( vsParams.size() < 1) + return false ; + // recupero l'indice dell'entità indicata dal primo parametro + int nIdEnt = GetIdParam( vsParams[0]) ; + // recupero il riferimento in cui è immersa + Frame3d frEnt ; + if ( ! m_pGDB->GetGlobFrame( nIdEnt, frEnt)) + return false ; + // se gruppo + const IGeoFrame3d* pGF ; + if ( ( pGF = m_pGDB->GetGeoFrame( nIdEnt)) != nullptr) { + switch ( cType) { + case 'X' : // versore X + vtV = pGF->GetFrame().VersX() ; + return vtV.LocToLoc( frEnt, frVect) ; + case 'Y' : // versore Y + vtV = pGF->GetFrame().VersY() ; + return vtV.LocToLoc( frEnt, frVect) ; + case 'Z' : // versore Z + vtV = pGF->GetFrame().VersZ() ; + return vtV.LocToLoc( frEnt, frVect) ; + default : + return false ; + } + } + // se entità geometrica + const IGeoObj* pGObj ; + if ( ( pGObj = m_pGDB->GetGeoObj( nIdEnt)) != nullptr) { + // se curva + if ( ( pGObj->GetType() & GEO_CURVE) != 0) { + // recupero la curva + const ICurve* pCrv = GetCurve( pGObj) ; + switch ( cType) { + case 'S' : // versore direzione iniziale + if ( ! pCrv->GetStartDir( vtV)) + return false ; + return vtV.LocToLoc( frEnt, frVect) ; + case 'E' : // versore direzione finale + if ( ! pCrv->GetEndDir( vtV)) + return false ; + return vtV.LocToLoc( frEnt, frVect) ; + case 'M' : // versore direzione media + if ( ! pCrv->GetMidDir( vtV)) + return false ; + return vtV.LocToLoc( frEnt, frVect) ; + case 'U' : // versore direzione posizione parametrica + { + // secondo parametro : U + double dU = 0 ; + if ( vsParams.size() < 2 || ! FromString( vsParams[1], dU)) + return false ; + // terzo parametro opzionale : direzione di calcolo (+ o -) + ICurve::Side nSide = ICurve::FROM_MINUS ; + if ( vsParams.size() >= 3 && vsParams[2] == "+") + nSide = ICurve::FROM_PLUS ; + // recupero la direzione + Point3d ptP ; + if ( ! pCrv->GetPointTang( dU, nSide, ptP, vtV)) + return false ; + return vtV.LocToLoc( frEnt, frVect) ; + } + case 'N' : // versore direzione nel punto più vicino a punto dato + { + // secondo parametro : punto di riferimento + Point3d ptRef ; + if ( vsParams.size() < 2 || ! GetPointParam( vsParams[1], frEnt, ptRef)) + return false ; + // terzo parametro opzionale : direzione di calcolo (+ o -) + ICurve::Side nSide = ICurve::FROM_MINUS ; + if ( vsParams.size() >= 3 && vsParams[2] == "+") + nSide = ICurve::FROM_PLUS ; + // calcolo il parametro del punto della curva più vicino al punto di riferimento + DistPointCurve dstPC( ptRef, *pCrv) ; + int nFlag ; + double dU ; + if ( ! dstPC.GetParamAtMinDistPoint( 0, dU, nFlag)) + return false ; + // recupero la direzione + Point3d ptP ; + if ( ! pCrv->GetPointTang( dU, nSide, ptP, vtV)) + return false ; + return vtV.LocToLoc( frEnt, frVect) ; + } + //case 'I' : // versore direzione nel punto di intersezione con un'altra curva + } + } + // se frame + else if ( pGObj->GetType() == GEO_FRAME3D) { + // recupero il frame + const IGeoFrame3d* pGF = GetGeoFrame3d( pGObj) ; + switch ( cType) { + case 'X' : // versore X + vtV = pGF->GetFrame().VersX() ; + return vtV.LocToLoc( frEnt, frVect) ; + case 'Y' : // versore Y + vtV = pGF->GetFrame().VersY() ; + return vtV.LocToLoc( frEnt, frVect) ; + case 'Z' : // versore Z + vtV = pGF->GetFrame().VersZ() ; + return vtV.LocToLoc( frEnt, frVect) ; + default : + return false ; + } + } + } + return false ; + } // altrimenti nome di vettore già nel DB else { + int nIdEnt = GetIdParam( sParam) ; const IGeoVector3d* pV ; - if ( ( pV = GetGeoVector3d( m_pGDB->GetGeoObj( GetIdParam( sParam)))) == nullptr) + if ( ( pV = GetGeoVector3d( m_pGDB->GetGeoObj( nIdEnt))) == nullptr) return false ; vtV = pV->GetVector() ; - return true ; + // recupero il riferimento del punto + Frame3d frEnt ; + if ( ! m_pGDB->GetGlobFrame( nIdEnt, frEnt)) + return false ; + return vtV.LocToLoc( frEnt, frVect) ; } } //---------------------------------------------------------------------------- bool -GdbExecutor::GetPointParam( const string& sParam, Point3d& ptP) +GdbExecutor::GetPointParam( const string& sParam, const Frame3d& frPnt, Point3d& ptP) { - // se insieme di tre coordinate + // se insieme di tre coordinate (considerate già nel riferimento frPnt) if ( sParam[0] == '(') { // divido in parti STRVECTOR vsParams ; @@ -1188,24 +1527,124 @@ GdbExecutor::GetPointParam( const string& sParam, Point3d& ptP) FromString( vsParams[1], ptP.y) && FromString( vsParams[2], ptP.z)) ; } - // se altrimenti punto predefinito ORIG + // se altrimenti punto predefinito ORIG (considerato già nel riferimento frPnt) else if ( sParam == "ORIG") { ptP = ORIG ; return true ; } + // se altrimenti punto notevole + else if ( sParam[0] == 'P') { + // recupero il tipo di punto notevole + const char cType = sParam[1] ; + // recupero i parametri associati + STRVECTOR vsParams ; + Tokenize( sParam.substr( 3, sParam.length()-4), ",", "(", ")", vsParams) ; + STRVECTOR::iterator Iter ; + for ( Iter = vsParams.begin() ; Iter != vsParams.end() ; ++Iter) + Trim( (*Iter), " \t\r\n") ; + // ci deve essere almeno un parametro + if ( vsParams.size() < 1) + return false ; + // recupero l'indice dell'entità indicata dal primo parametro + int nIdEnt = GetIdParam( vsParams[0]) ; + // recupero il riferimento in cui è immersa + Frame3d frEnt ; + if ( ! m_pGDB->GetGlobFrame( nIdEnt, frEnt)) + return false ; + // se gruppo + const IGeoFrame3d* pGF ; + if ( ( pGF = m_pGDB->GetGeoFrame( nIdEnt)) != nullptr) { + switch ( cType) { + case 'O' : // origine + ptP = pGF->GetFrame().Orig() ; + return ptP.LocToLoc( frEnt, frPnt) ; + default : + return false ; + } + } + // se entità geometrica + const IGeoObj* pGObj ; + if ( ( pGObj = m_pGDB->GetGeoObj( nIdEnt)) != nullptr) { + // se curva + if ( ( pGObj->GetType() & GEO_CURVE) != 0) { + // recupero la curva + const ICurve* pCrv = GetCurve( pGObj) ; + switch ( cType) { + case 'S' : // punto iniziale + if ( ! pCrv->GetStartPoint( ptP)) + return false ; + return ptP.LocToLoc( frEnt, frPnt) ; + case 'E' : // punto finale + if ( ! pCrv->GetEndPoint( ptP)) + return false ; + return ptP.LocToLoc( frEnt, frPnt) ; + case 'M' : // punto medio + if ( ! pCrv->GetMidPoint( ptP)) + return false ; + return ptP.LocToLoc( frEnt, frPnt) ; + case 'C' : // centro + if ( ! pCrv->GetCenterPoint( ptP)) + return false ; + return ptP.LocToLoc( frEnt, frPnt) ; + case 'U' : // posizione parametrica + { + double dU = 0 ; + Vector3d vtTg ; + if ( vsParams.size() < 2 || ! FromString( vsParams[1], dU)) + return false ; + if ( ! pCrv->GetPointTang( dU, ICurve::FROM_MINUS, ptP, vtTg)) + return false ; + return ptP.LocToLoc( frEnt, frPnt) ; + } + case 'N' : // punto più vicino a punto dato + { + // secondo parametro : punto di riferimento + Point3d ptRef ; + if ( vsParams.size() < 2 || ! GetPointParam( vsParams[1], frEnt, ptRef)) + return false ; + // calcolo il punto della curva più vicino al punto di riferimento + DistPointCurve dstPC( ptRef, *pCrv) ; + int nFlag ; + if ( ! dstPC.GetMinDistPoint( 0, ptP, nFlag)) + return false ; + return ptP.LocToLoc( frEnt, frPnt) ; + } + //case 'I' : // punto di intersezione con un'altra curva + } + } + // se frame + else if ( pGObj->GetType() == GEO_FRAME3D) { + // recupero il frame + const IGeoFrame3d* pGF = GetGeoFrame3d( pGObj) ; + switch ( cType) { + case 'O' : // origine + ptP = pGF->GetFrame().Orig() ; + return ptP.LocToLoc( frEnt, frPnt) ; + default : + return false ; + } + } + } + return false ; + } // altrimenti nome di punto già nel DB else { + int nIdEnt = GetIdParam( sParam) ; const IGeoPoint3d* pPt ; - if ( ( pPt = GetGeoPoint3d( m_pGDB->GetGeoObj( GetIdParam( sParam)))) == nullptr) + if ( ( pPt = GetGeoPoint3d( m_pGDB->GetGeoObj( nIdEnt))) == nullptr) return false ; ptP = pPt->GetPoint() ; - return true ; + // recupero il riferimento del punto + Frame3d frEnt ; + if ( ! m_pGDB->GetGlobFrame( nIdEnt, frEnt)) + return false ; + return ptP.LocToLoc( frEnt, frPnt) ; } } //---------------------------------------------------------------------------- bool -GdbExecutor::GetPointWParam( const string& sParam, Point3d& ptP, double& dW) +GdbExecutor::GetPointWParam( const string& sParam, const Frame3d& frPnt, Point3d& ptP, double& dW) { // deve essere insieme di dati if ( sParam[0] != '(') @@ -1225,18 +1664,11 @@ GdbExecutor::GetPointWParam( const string& sParam, Point3d& ptP, double& dW) FromString( vsParams[2], ptP.z) && FromString( vsParams[3], dW)) ; } - // se 2 parti, nome di punto predefinito o già nel DB e un peso + // se 2 parti, nome di punto predefinito, punto notevole o già nel DB e un peso else if ( vsParams.size() == 2) { // recupero il punto - if ( vsParams[0] == "ORIG") { - ptP = ORIG ; - } - else { - const IGeoPoint3d* pPt ; - if ( ( pPt = GetGeoPoint3d( m_pGDB->GetGeoObj( GetIdParam( vsParams[0])))) == nullptr) - return false ; - ptP = pPt->GetPoint() ; - } + if ( ! GetPointParam( vsParams[0], frPnt, ptP)) + return false ; // recupero il peso return FromString( vsParams[1], dW) ; } @@ -1247,44 +1679,253 @@ GdbExecutor::GetPointWParam( const string& sParam, Point3d& ptP, double& dW) //---------------------------------------------------------------------------- bool -GdbExecutor::GetFrameParam( const string& sParam, Frame3d& frF) +GdbExecutor::GetLengthParam( const string& sParam, double& dLen) +{ + // se lunghezza notevole + if ( sParam[0] == 'L') { + // recupero i parametri associati + STRVECTOR vsParams ; + Tokenize( sParam.substr( 1), ",", vsParams) ; + STRVECTOR::iterator Iter ; + for ( Iter = vsParams.begin() ; Iter != vsParams.end() ; ++Iter) + Trim( (*Iter), " \t\r\n()") ; + // ci deve essere almeno un parametro + if ( vsParams.size() < 1) + return false ; + // recupero l'entità indicata dal primo parametro + const IGeoObj* pGObj ; + if ( ( pGObj = m_pGDB->GetGeoObj( GetIdParam( vsParams[0]))) == nullptr) + return false ; + // se curva + if ( ( pGObj->GetType() & GEO_CURVE) != 0) { + // recupero la curva + const ICurve* pCrv = GetCurve( pGObj) ; + return pCrv->GetLength( dLen) ; + } + return false ; + } + // altrimenti valore numerico + else { + return FromString( sParam, dLen) ; + } +} + +//---------------------------------------------------------------------------- +bool +GdbExecutor::GetDirParam( const string& sParam, const Frame3d& frDir, double& dDir) +{ + // se direzione notevole + if ( sParam[0] == 'D') { + // recupero il tipo di direzione notevole + const char cType = sParam[1] ; + // recupero i parametri associati + STRVECTOR vsParams ; + Tokenize( sParam.substr( 3, sParam.length()-4), ",", "(", ")", vsParams) ; + STRVECTOR::iterator Iter ; + for ( Iter = vsParams.begin() ; Iter != vsParams.end() ; ++Iter) + Trim( (*Iter), " \t\r\n") ; + // ci deve essere almeno un parametro + if ( vsParams.size() < 1) + return false ; + // recupero l'entità indicata dal primo parametro + int nIdEnt = GetIdParam( vsParams[0]) ; + const IGeoObj* pGObj ; + if ( ( pGObj = m_pGDB->GetGeoObj( nIdEnt)) == nullptr) + return false ; + // recupero il riferimento in cui è immersa + Frame3d frEnt ; + if ( ! m_pGDB->GetGlobFrame( nIdEnt, frEnt)) + return false ; + // se curva + if ( ( pGObj->GetType() & GEO_CURVE) != 0) { + // recupero la curva + const ICurve* pCrv = GetCurve( pGObj) ; + Vector3d vtDir ; + switch ( cType) { + case 'S' : // direzione iniziale + if ( ! pCrv->GetStartDir( vtDir) || ! vtDir.LocToLoc( frEnt, frDir)) + return false ; + vtDir.ToSpherical( nullptr, nullptr, &dDir) ; + // se esiste un secondo parametro è un offset di rotazione + if ( vsParams.size() >= 2) { + double dOffsetDeg = 0 ; + FromString( vsParams[1], dOffsetDeg) ; + dDir += dOffsetDeg ; + } + return true ; + case 'E' : // direzione finale + if ( ! pCrv->GetEndDir( vtDir) || ! vtDir.LocToLoc( frEnt, frDir)) + return false ; + vtDir.ToSpherical( nullptr, nullptr, &dDir) ; + // se esiste un secondo parametro è un offset di rotazione + if ( vsParams.size() >= 2) { + double dOffsetDeg = 0 ; + FromString( vsParams[1], dOffsetDeg) ; + dDir += dOffsetDeg ; + } + return true ; + case 'M' : // direzione media + if ( ! pCrv->GetMidDir( vtDir) || ! vtDir.LocToLoc( frEnt, frDir)) + return false ; + vtDir.ToSpherical( nullptr, nullptr, &dDir) ; + // se esiste un secondo parametro è un offset di rotazione + if ( vsParams.size() >= 2) { + double dOffsetDeg = 0 ; + FromString( vsParams[1], dOffsetDeg) ; + dDir += dOffsetDeg ; + } + return true ; + case 'U' : // direzione parametrica + { + // secondo parametro : U + double dU = 0 ; + if ( vsParams.size() < 2 || ! FromString( vsParams[1], dU)) + return false ; + // terzo parametro opzionale : direzione di calcolo (+ o -) + ICurve::Side nSide = ICurve::FROM_MINUS ; + if ( vsParams.size() >= 3 && vsParams[2] == "+") + nSide = ICurve::FROM_PLUS ; + // recupero la direzione + Point3d ptP ; + if ( ! pCrv->GetPointTang( dU, nSide, ptP, vtDir) || + ! vtDir.LocToLoc( frEnt, frDir)) + return false ; + vtDir.ToSpherical( nullptr, nullptr, &dDir) ; + // quarto parametro opzionale : offset di rotazione + if ( vsParams.size() >= 4) { + double dOffsetDeg = 0 ; + FromString( vsParams[3], dOffsetDeg) ; + dDir += dOffsetDeg ; + } + return true ; + } + case 'N' : // versore direzione nel punto più vicino a punto dato + { + // secondo parametro : punto di riferimento + Point3d ptRef ; + if ( vsParams.size() < 2 || ! GetPointParam( vsParams[1], frEnt, ptRef)) + return false ; + // terzo parametro opzionale : direzione di calcolo (+ o -) + ICurve::Side nSide = ICurve::FROM_MINUS ; + if ( vsParams.size() >= 3 && vsParams[2] == "+") + nSide = ICurve::FROM_PLUS ; + // calcolo il parametro del punto della curva più vicino al punto di riferimento + DistPointCurve dstPC( ptRef, *pCrv) ; + int nFlag ; + double dU ; + if ( ! dstPC.GetParamAtMinDistPoint( 0, dU, nFlag)) + return false ; + // recupero la direzione + Point3d ptP ; + if ( ! pCrv->GetPointTang( dU, nSide, ptP, vtDir) || + ! vtDir.LocToLoc( frEnt, frDir)) + return false ; + vtDir.ToSpherical( nullptr, nullptr, &dDir) ; + // quarto parametro opzionale : offset di rotazione + if ( vsParams.size() >= 4) { + double dOffsetDeg = 0 ; + FromString( vsParams[3], dOffsetDeg) ; + dDir += dOffsetDeg ; + } + return true ; + } + //case 'I' : + } + } + return false ; + } + // altrimenti valore numerico + else { + return FromString( sParam, dDir) ; + } +} + +//---------------------------------------------------------------------------- +bool +GdbExecutor::GetFrameParam( const string& sParam, const Frame3d& frRef, Frame3d& frF) { // se insieme di punto origine e tre versori if ( sParam[0] == '(') { - Point3d ptOrig ; - Vector3d vtX ; - Vector3d vtY ; - Vector3d vtZ ; - string sTmp ; - STRVECTOR vsParams ; - STRVECTOR::iterator Iter ; // elimino primo e ultimo carattere - sTmp = sParam.substr( 1, sParam.size()-2) ; - // divido in parti + string sTmp = sParam.substr( 1, sParam.size() - 2) ; + // divido in parti ed elimino spazi iniziali/finali + STRVECTOR vsParams ; Tokenize( sTmp, ",", "(", ")", vsParams) ; + STRVECTOR::iterator Iter ; + for ( Iter = vsParams.begin() ; Iter != vsParams.end() ; ++Iter) + Trim( (*Iter), " \t\r\n") ; // verifico siano 4 parti e le converto if ( vsParams.size() != 4) return false ; - if ( GetPointParam( vsParams[0], ptOrig) && - GetVectorParam( vsParams[1], vtX) && - GetVectorParam( vsParams[2], vtY) && - GetVectorParam( vsParams[3], vtZ)) + Point3d ptOrig ; + Vector3d vtX, vtY, vtZ ; + if ( GetPointParam( vsParams[0], frRef, ptOrig) && + GetVectorParam( vsParams[1], frRef, vtX) && + GetVectorParam( vsParams[2], frRef, vtY) && + GetVectorParam( vsParams[3], frRef, vtZ)) return frF.Set( ptOrig, vtX, vtY, vtZ) ; else return false ; } - // se altrimenti riferimento predefinito GLOB - else if ( sParam == "GLOB") { - frF = GLOB_FRM ; + // se altrimenti riferimento predefinito + else if ( sParam[0] == 'R') { + // recupero il tipo di riferimento notevole + const char cType = sParam[1] ; + // recupero i parametri associati + // elimino primi 3 e ultimo caratteri + string sTmp ; + if ( sParam.size() > 4) + sTmp = sParam.substr( 3, sParam.size() - 4) ; + // divido in parti ed elimino spazi iniziali/finali + STRVECTOR vsParams ; + Tokenize( sTmp, ",", "(", ")", vsParams) ; + STRVECTOR::iterator Iter ; + for ( Iter = vsParams.begin() ; Iter != vsParams.end() ; ++Iter) + Trim( (*Iter), " \t\r\n") ; + // se c'è un parametro è l'origine + Point3d ptOrig ; + if ( vsParams.size() >= 1) { + if ( ! GetPointParam( vsParams[0], frRef, ptOrig)) + return false ; + } + // costruisco il riferimento a seconda del tipo + switch ( cType) { + case 'T' : // top + frF.Set( ptOrig, Frame3d::TOP) ; + break ; + case 'U' : // bottom (under) + frF.Set( ptOrig, Frame3d::BOTTOM) ; + break ; + case 'F' : // front + frF.Set( ptOrig, Frame3d::FRONT) ; + break ; + case 'B' : // back + frF.Set( ptOrig, Frame3d::BACK) ; + break ; + case 'L' : // left + frF.Set( ptOrig, Frame3d::LEFT) ; + break ; + case 'R' : // right + frF.Set( ptOrig, Frame3d::RIGHT) ; + break ; + default : + return false ; + } return true ; } - // altrimenti nome di frame già nel DB + // altrimenti nome di gruppo o di frame già nel DB else { + int nIdEnt = GetIdParam( sParam) ; const IGeoFrame3d* pFr ; - if ( ( pFr = GetGeoFrame3d( m_pGDB->GetGeoObj( GetIdParam( sParam)))) == nullptr) + if ( ( pFr = m_pGDB->GetGeoFrame( nIdEnt)) == nullptr && + ( pFr = GetGeoFrame3d( m_pGDB->GetGeoObj( nIdEnt))) == nullptr) return false ; frF = pFr->GetFrame() ; - return true ; + // recupero il riferimento del frame + Frame3d frEnt ; + if ( ! m_pGDB->GetGlobFrame( nIdEnt, frEnt)) + return false ; + return frF.LocToLoc( frEnt, frRef) ; } } @@ -1842,17 +2483,28 @@ GdbExecutor::ExecuteTranslate( const string& sCmd2, const STRVECTOR& vsParams) INTVECTOR vnNames ; if ( ! GetNamesParam( vsParams[0], vnNames)) return false ; - // recupero il vettore - Vector3d vtVN ; - if ( ! GetVectorParam( vsParams[1], vtVN)) - return false ; // recupero flag per locale/globale/gruppo enum { TRA_LOC = 0, TRA_GLOB = 1, TRA_GROUP = 2} ; - int nTraType = TRA_LOC ; - if ( sCmd2 == "GLOB" || sCmd2 == "G") + int nTraType ; + Frame3d frRef ; + if ( sCmd2 == "GLOB" || sCmd2 == "G") { nTraType = TRA_GLOB ; - else if ( sCmd2 == "GROUP" || sCmd2 == "GR") + frRef = GLOB_FRM ; + } + else if ( sCmd2 == "GROUP" || sCmd2 == "GR") { nTraType = TRA_GROUP ; + if ( ! m_pGDB->GetGroupGlobFrame( vnNames[0], frRef)) + return false ; + } + else { + nTraType = TRA_LOC ; + if ( ! m_pGDB->GetGlobFrame( vnNames[0], frRef)) + return false ; + } + // recupero il vettore + Vector3d vtVN ; + if ( ! GetVectorParam( vsParams[1], frRef, vtVN)) + return false ; // esecuzione traslazioni INTVECTOR::iterator Iter ; for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) { @@ -1886,25 +2538,38 @@ GdbExecutor::ExecuteRotate( const string& sCmd2, const STRVECTOR& vsParams) INTVECTOR vnNames ; if ( ! GetNamesParam( vsParams[0], vnNames)) return false ; + if ( vnNames.empty()) + return true ; + // recupero flag e riferimento per globale/gruppo/locale + enum { ROT_LOC = 0, ROT_GLOB = 1, ROT_GROUP = 2} ; + int nRotType ; + Frame3d frRef ; + if ( sCmd2 == "GLOB" || sCmd2 == "G") { + nRotType = ROT_GLOB ; + frRef = GLOB_FRM ; + } + else if ( sCmd2 == "GROUP" || sCmd2 == "GR") { + nRotType = ROT_GROUP ; + if ( ! m_pGDB->GetGroupGlobFrame( vnNames[0], frRef)) + return false ; + } + else { + nRotType = ROT_LOC ; + if ( ! m_pGDB->GetGlobFrame( vnNames[0], frRef)) + return false ; + } // recupero il punto Point3d ptPC ; - if ( ! GetPointParam( vsParams[1], ptPC)) + if ( ! GetPointParam( vsParams[1], frRef, ptPC)) return false ; // recupero il vettore Vector3d vtVN ; - if ( ! GetVectorParam( vsParams[2], vtVN)) + if ( ! GetVectorParam( vsParams[2], frRef, vtVN)) return false ; // recupero i coefficienti double dAngDeg ; if ( ! FromString( vsParams[3], dAngDeg)) return false ; - // recupero flag per locale/globale/gruppo - enum { ROT_LOC = 0, ROT_GLOB = 1, ROT_GROUP = 2} ; - int nRotType = ROT_LOC ; - if ( sCmd2 == "GLOB" || sCmd2 == "G") - nRotType = ROT_GLOB ; - else if ( sCmd2 == "GROUP" || sCmd2 == "GR") - nRotType = ROT_GROUP ; // esecuzione rotazioni INTVECTOR::iterator Iter ; for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) { @@ -1938,13 +2603,33 @@ GdbExecutor::ExecuteScale( const string& sCmd2, const STRVECTOR& vsParams) INTVECTOR vnNames ; if ( ! GetNamesParam( vsParams[0], vnNames)) return false ; + if ( vnNames.empty()) + return true ; + // recupero flag e riferimento per globale/gruppo/locale + enum { SCA_LOC = 0, SCA_GLOB = 1, SCA_GROUP = 2} ; + int nScaType ; + Frame3d frRef ; + if ( sCmd2 == "GLOB" || sCmd2 == "G") { + nScaType = SCA_GLOB ; + frRef = GLOB_FRM ; + } + else if ( sCmd2 == "GROUP" || sCmd2 == "GR") { + nScaType = SCA_GROUP ; + if ( ! m_pGDB->GetGroupGlobFrame( vnNames[0], frRef)) + return false ; + } + else { + nScaType = SCA_LOC ; + if ( ! m_pGDB->GetGlobFrame( vnNames[0], frRef)) + return false ; + } // provo a recuperare un punto Point3d ptPC ; - Frame3d frRef ; - if ( GetPointParam( vsParams[1], ptPC)) - frRef.Set( ptPC, Frame3d::TOP) ; + Frame3d frFrame ; + if ( GetPointParam( vsParams[1], frRef, ptPC)) + frFrame.Set( ptPC, Frame3d::TOP) ; // provo a recuperare un frame - else if ( GetFrameParam( vsParams[1], frRef)) + else if ( GetFrameParam( vsParams[1], frRef, frFrame)) ; // altrimenti errore else @@ -1955,27 +2640,20 @@ GdbExecutor::ExecuteScale( const string& sCmd2, const STRVECTOR& vsParams) ! FromString( vsParams[3], dCoeffY) || ! FromString( vsParams[4], dCoeffZ)) return false ; - // recupero flag per locale/globale/gruppo - enum { SCA_LOC = 0, SCA_GLOB = 1, SCA_GROUP = 2} ; - int nScaType = SCA_LOC ; - if ( sCmd2 == "GLOB" || sCmd2 == "G") - nScaType = SCA_GLOB ; - else if ( sCmd2 == "GROUP" || sCmd2 == "GR") - nScaType = SCA_GROUP ; // esecuzione scalature INTVECTOR::iterator Iter ; for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) { switch ( nScaType) { case SCA_LOC : - if ( ! m_pGDB->Scale( *Iter, frRef, dCoeffX, dCoeffY, dCoeffZ)) + if ( ! m_pGDB->Scale( *Iter, frFrame, dCoeffX, dCoeffY, dCoeffZ)) return false ; break ; case SCA_GLOB : - if ( ! m_pGDB->ScaleGlob( *Iter, frRef, dCoeffX, dCoeffY, dCoeffZ)) + if ( ! m_pGDB->ScaleGlob( *Iter, frFrame, dCoeffX, dCoeffY, dCoeffZ)) return false ; break ; case SCA_GROUP : - if ( ! m_pGDB->ScaleGroup( *Iter, frRef, dCoeffX, dCoeffY, dCoeffZ)) + if ( ! m_pGDB->ScaleGroup( *Iter, frFrame, dCoeffX, dCoeffY, dCoeffZ)) return false ; break ; } @@ -1995,21 +2673,32 @@ GdbExecutor::ExecuteMirror( const string& sCmd2, const STRVECTOR& vsParams) INTVECTOR vnNames ; if ( ! GetNamesParam( vsParams[0], vnNames)) return false ; + // recupero flag e riferimento per globale/gruppo/locale + enum { MIR_LOC = 0, MIR_GLOB = 1, MIR_GROUP = 2} ; + int nMirType ; + Frame3d frRef ; + if ( sCmd2 == "GLOB" || sCmd2 == "G") { + nMirType = MIR_GLOB ; + frRef = GLOB_FRM ; + } + else if ( sCmd2 == "GROUP" || sCmd2 == "GR") { + nMirType = MIR_GROUP ; + if ( ! m_pGDB->GetGroupGlobFrame( vnNames[0], frRef)) + return false ; + } + else { + nMirType = MIR_LOC ; + if ( ! m_pGDB->GetGlobFrame( vnNames[0], frRef)) + return false ; + } // recupero il punto Point3d ptPC ; - if ( ! GetPointParam( vsParams[1], ptPC)) + if ( ! GetPointParam( vsParams[1], frRef, ptPC)) return false ; // recupero il vettore Vector3d vtVN ; - if ( ! GetVectorParam( vsParams[2], vtVN)) + if ( ! GetVectorParam( vsParams[2], frRef, vtVN)) return false ; - // recupero flag per locale/globale/gruppo - enum { MIR_LOC = 0, MIR_GLOB = 1, MIR_GROUP = 2} ; - int nMirType = MIR_LOC ; - if ( sCmd2 == "GLOB" || sCmd2 == "G") - nMirType = MIR_GLOB ; - else if ( sCmd2 == "GROUP" || sCmd2 == "GR") - nMirType = MIR_GROUP ; // esecuzione specchiature INTVECTOR::iterator Iter ; for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) { @@ -2157,11 +2846,14 @@ GdbExecutor::ExecuteLoad( const string& sCmd2, const STRVECTOR& vsParams) // 1 parametro ( NomeFile) if ( vsParams.size() != 1) return false ; + // eventuale conversione di token nel nome file + string sFile = vsParams[0] ; + m_pParser->DirReplace( sFile) ; // pulizia e reinizializzazione del DB geometrico m_pGDB->Clear() ; m_pGDB->Init() ; // esecuzione caricamento - return m_pGDB->Load( vsParams[0]) ; + return m_pGDB->Load( sFile) ; } //---------------------------------------------------------------------------- @@ -2171,6 +2863,9 @@ GdbExecutor::ExecuteSave( const string& sCmd2, const STRVECTOR& vsParams) // almeno 1 parametro ( NomeFile) if ( vsParams.size() < 1) return false ; + // eventuale conversione di token nel nome file + string sFile = vsParams[0] ; + m_pParser->DirReplace( sFile) ; // il secondo parametro, opzionale, indica il formato del file bool bBinary = false ; if ( vsParams.size() == 2) { @@ -2179,7 +2874,7 @@ GdbExecutor::ExecuteSave( const string& sCmd2, const STRVECTOR& vsParams) bBinary = ( sBinary == "B" || sBinary == "BINARY") ; } // esecuzione salvataggio - return m_pGDB->Save( vsParams[0], bBinary) ; + return m_pGDB->Save( sFile, bBinary) ; } //---------------------------------------------------------------------------- diff --git a/GdbExecutor.h b/GdbExecutor.h index e6b66bf..3b75a50 100644 --- a/GdbExecutor.h +++ b/GdbExecutor.h @@ -40,10 +40,12 @@ class GdbExecutor : public IGdbExecutor bool AddGeoObj( const std::string& sId, const std::string& sIdParent, IGeoObj* pGeoObj) ; int GetIdParam( const std::string& sParam, bool bNewAllowed = false) ; bool GetNamesParam( const std::string& sParam, INTVECTOR& vnNames) ; - bool GetVectorParam( const std::string& sParam, Vector3d& vtV) ; - bool GetPointParam( const std::string& sParam, Point3d& ptP) ; - bool GetPointWParam( const std::string& sParam, Point3d& ptP, double& dW) ; - bool GetFrameParam( const std::string& sParam, Frame3d& frF) ; + bool GetVectorParam( const std::string& sParam, const Frame3d& frVect, Vector3d& vtV) ; + bool GetPointParam( const std::string& sParam, const Frame3d& frPnt, Point3d& ptP) ; + bool GetPointWParam( const std::string& sParam, const Frame3d& frPnt, Point3d& ptP, double& dW) ; + bool GetLengthParam( const std::string& sParam, double& dLen) ; + bool GetDirParam( const std::string& sParam, const Frame3d& frDir, double& dDir) ; + bool GetFrameParam( const std::string& sParam, const Frame3d& frRef, Frame3d& frF) ; bool GetColorParam( const std::string& sParam, bool& bByParent, Color& cCol) ; bool GetPolylineFromCurve( int nId, const Frame3d& frDest, double dLinTol, PolyLine& PL) ; bool ExecuteGroup( const std::string& sCmd2, const STRVECTOR& vsParams) ; @@ -89,5 +91,7 @@ class GdbExecutor : public IGdbExecutor ICmdParser* m_pParser ; ExecManager m_ExecMgr ; OutTsc m_OutTsc ; + std::string m_sId ; + std::string m_sParentId ; IGeoObj* m_pGeoObj ; } ; diff --git a/GeoFrame3d.cpp b/GeoFrame3d.cpp index e6e587f..3735f66 100644 --- a/GeoFrame3d.cpp +++ b/GeoFrame3d.cpp @@ -48,6 +48,26 @@ GeoFrame3d::Set( const Point3d& ptOrig, const Vector3d& vtDirX, return m_frF.Set( ptOrig, vtDirX, vtDirY, vtDirZ) ; } +//---------------------------------------------------------------------------- +bool +GeoFrame3d::Set( const Point3d& ptOrig, const Point3d& ptOnX, const Point3d& ptNearY) +{ + // imposto ricalcolo della grafica + m_OGrMgr.Reset() ; + // assegno i dati + return m_frF.Set( ptOrig, ptOnX, ptNearY) ; +} + +//---------------------------------------------------------------------------- +bool +GeoFrame3d::Set( const Point3d& ptOrig, const Vector3d& vtDirZ) +{ + // imposto ricalcolo della grafica + m_OGrMgr.Reset() ; + // assegno i dati + return m_frF.Set( ptOrig, vtDirZ) ; +} + //---------------------------------------------------------------------------- bool GeoFrame3d::Set( const Frame3d& frF) diff --git a/GeoFrame3d.h b/GeoFrame3d.h index 07623a6..fb60d34 100644 --- a/GeoFrame3d.h +++ b/GeoFrame3d.h @@ -59,6 +59,8 @@ class GeoFrame3d : public IGeoFrame3d, public IGeoObjRW virtual bool Copy( const IGeoObj* pGObjSrc) ; virtual bool Set( const Point3d& ptOrig, const Vector3d& vtDirX, const Vector3d& vtDirY, const Vector3d& vtDirZ) ; + virtual bool Set( const Point3d& ptOrig, const Point3d& ptOnX, const Point3d& ptNearY) ; + virtual bool Set( const Point3d& ptOrig, const Vector3d& vtDirZ) ; virtual bool Set( const Frame3d& frF) ; virtual const Frame3d& GetFrame( void) const { return m_frF ; } diff --git a/Point3d.cpp b/Point3d.cpp index 9b339e0..acb4dcf 100644 --- a/Point3d.cpp +++ b/Point3d.cpp @@ -158,3 +158,16 @@ Point3d::ToLoc( const Frame3d& frRef) return true ; } + +//---------------------------------------------------------------------------- +// Cambio di riferimento : dal primo riferimento al secondo +//---------------------------------------------------------------------------- +bool +Point3d::LocToLoc( const Frame3d& frOri, const Frame3d& frDest) +{ + // se i due riferimenti coincidono, non devo fare alcunché + if ( AreSameFrame( frOri, frDest)) + return true ; + + return ( ToGlob( frOri) && ToLoc( frDest)) ; +} diff --git a/SurfTriMesh.cpp b/SurfTriMesh.cpp index 24bdb37..a50cd1b 100644 --- a/SurfTriMesh.cpp +++ b/SurfTriMesh.cpp @@ -114,6 +114,22 @@ SurfTriMesh::AddTriangle( const int nIdVert[3]) nIdVert[1] == nIdVert[2] || nIdVert[2] == nIdVert[0]) return SVT_DEL ; + // verifico che i tre vertici siano ben definiti + if ( nIdVert[0] < 0 || nIdVert[0] >= int( m_vVert.size()) || + m_vVert[nIdVert[0]].nIdTria == SVT_DEL || + nIdVert[1] < 0 || nIdVert[1] >= int( m_vVert.size()) || + m_vVert[nIdVert[1]].nIdTria == SVT_DEL || + nIdVert[2] < 0 || nIdVert[2] >= int( m_vVert.size()) || + m_vVert[nIdVert[2]].nIdTria == SVT_DEL) + return SVT_DEL ; + // verifico che la normale sia ben definita + // calcolo vettori come due lati consecutivi del triangolo + Vector3d vtV1 = m_vVert[nIdVert[1]].ptP - m_vVert[nIdVert[0]].ptP ; + Vector3d vtV2 = m_vVert[nIdVert[2]].ptP - m_vVert[nIdVert[1]].ptP ; + // normale da prodotto vettoriale + Vector3d vtN = vtV1 ^ vtV2 ; + if ( vtN.IsZero()) + return SVT_DEL ; // imposto ricalcolo m_nStatus = TO_VERIFY ; m_OGrMgr.Reset() ; @@ -473,8 +489,8 @@ SurfTriMesh::Validate( void) m_vVert[ m_vTria[i].nIdVert[j]].nIdTria == SVT_DEL) m_nStatus = ERR ; } - // calcolo eventuali normale mancante - if ( m_vTria[i].vtN.IsSmall()) + // calcolo eventuale normale mancante + if ( m_nStatus == OK && m_vTria[i].vtN.IsSmall()) CalcTriangleNormal( i) ; } } @@ -1513,10 +1529,13 @@ SurfTriMesh::CalcTriangleNormal( int nT) if ( m_vTria[nT].nIdVert[0] == SVT_DEL) return false ; // controllo validità vertici riferiti dal triangolo - if ( m_vTria[nT].nIdVert[0] >= GetVertexNum() || + if ( m_vTria[nT].nIdVert[0] < 0 || + m_vTria[nT].nIdVert[0] >= GetVertexNum() || m_vVert[m_vTria[nT].nIdVert[0]].nIdTria == SVT_DEL || + m_vTria[nT].nIdVert[1] < 0 || m_vTria[nT].nIdVert[1] >= GetVertexNum() || m_vVert[m_vTria[nT].nIdVert[1]].nIdTria == SVT_DEL || + m_vTria[nT].nIdVert[2] < 0 || m_vTria[nT].nIdVert[2] >= GetVertexNum() || m_vVert[m_vTria[nT].nIdVert[2]].nIdTria == SVT_DEL) return false ; diff --git a/Vector3d.cpp b/Vector3d.cpp index adc5f02..63bf9a3 100644 --- a/Vector3d.cpp +++ b/Vector3d.cpp @@ -284,6 +284,19 @@ Vector3d::ToLoc( const Frame3d& frRef) return true ; } +//---------------------------------------------------------------------------- +// Cambio di riferimento : dal primo riferimento al secondo +//---------------------------------------------------------------------------- +bool +Vector3d::LocToLoc( const Frame3d& frOri, const Frame3d& frDest) +{ + // se i due riferimenti coincidono, non devo fare alcunché + if ( AreSameFrame( frOri, frDest)) + return true ; + + return ( ToGlob( frOri) && ToLoc( frDest)) ; +} + //---------------------------------------------------------------------------- // Calcolo dell'angolo tra il vettore e un altro //----------------------------------------------------------------------------