From b2c6866effff297b940a26c77d29d98f710698e8 Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Mon, 20 Jan 2014 10:57:14 +0000 Subject: [PATCH] EgtGeomKernel : migliorata scalatura non uniforme, con conservazione del piano XY dei riferimenti di gruppo. --- Frame3d.cpp | 38 ++++++++++++++++++++++++++++++++++++++ GdbExecutor.cpp | 38 ++++++++++++++++++++++++++++++++------ GdbGroup.cpp | 26 +++++++++++++++++--------- GdbGroup.h | 4 ++++ GdbNode.h | 2 ++ GdbObj.cpp | 20 ++++++++++++++++++++ GdbObj.h | 2 ++ 7 files changed, 115 insertions(+), 15 deletions(-) diff --git a/Frame3d.cpp b/Frame3d.cpp index b5c2454..a323bba 100644 --- a/Frame3d.cpp +++ b/Frame3d.cpp @@ -196,6 +196,44 @@ Frame3d::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, doub return true ; } +//---------------------------------------------------------------------------- +bool +Frame3d::PartialScale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double dCoeffZ) +{ + const double AXIS_LEN = 100 ; + + // verifico validità del frame + if ( GetType() == ERR || frRef.GetType() == ERR) + return false ; + + // scalatura dell'origine + Point3d ptOrigS = m_ptOrig ; + ptOrigS.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ) ; + + // calcolo trasformazione del versore Z + Point3d ptDirZS = m_ptOrig + AXIS_LEN * m_vtVersZ ; + ptDirZS.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ) ; + Vector3d vtVersZS = ptDirZS - ptOrigS ; + vtVersZS.Normalize() ; + // se il versore Z non cambia, basta applicare l'origine scalata + if ( AreSameVectorExact( m_vtVersZ, vtVersZS)) { + m_ptOrig = ptOrigS ; + return true ; + } + + // altrimenti, devo scalare anche i versori X e Y + Point3d ptDirXS = m_ptOrig + AXIS_LEN * m_vtVersX ; + ptDirXS.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ) ; + Point3d ptDirYS = m_ptOrig + AXIS_LEN * m_vtVersY ; + ptDirYS.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ) ; + Frame3d frRefS ; + if ( frRefS.Set( ptOrigS, ptDirXS, ptDirYS)) { + *this = frRefS ; + return true ; + } + return false ; +} + //---------------------------------------------------------------------------- bool Frame3d::Invert( void) diff --git a/GdbExecutor.cpp b/GdbExecutor.cpp index 397019c..c30daa3 100644 --- a/GdbExecutor.cpp +++ b/GdbExecutor.cpp @@ -755,12 +755,38 @@ GdbExecutor::GetPointWParam( const std::string& sParam, Point3d& ptP, double& dW bool GdbExecutor::GetFrameParam( const std::string& sParam, Frame3d& frF) { - // deve essere nome di frame già nel DB - const IGeoFrame3d* pFr ; - if ( ( pFr = GetGeoFrame3d( m_pGDB->GetGeoObj( GetIdParam( sParam)))) == nullptr) - return false ; - frF = pFr->GetFrame() ; - return true ; + // 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 + Tokenize( sTmp, ",", "(", ")", vsParams) ; + // 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)) + return frF.Set( ptOrig, vtX, vtY, vtZ) ; + else + return false ; + } + // altrimenti nome di frame già nel DB + else { + const IGeoFrame3d* pFr ; + if ( ( pFr = GetGeoFrame3d( m_pGDB->GetGeoObj( GetIdParam( sParam)))) == nullptr) + return false ; + frF = pFr->GetFrame() ; + return true ; + } } //---------------------------------------------------------------------------- diff --git a/GdbGroup.cpp b/GdbGroup.cpp index f7436b8..5962fe6 100644 --- a/GdbGroup.cpp +++ b/GdbGroup.cpp @@ -199,23 +199,31 @@ GdbGroup::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, dou bool GdbGroup::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double dCoeffZ) { - bool bOk ; - bool bUniform ; - Frame3d frRefLoc ; GdbNode* pGdbNode ; - // non è possibile scalare il riferimento, devo agire sui nodi sottostanti + // parziale scalatura del riferimento (non può essere completa) + Frame3d frFrameS = m_gfrFrame.m_frF ; + frFrameS.PartialScale( frRef, dCoeffX, dCoeffY, dCoeffZ) ; - // determino se la scalatura è uniforme - bUniform = fabs( dCoeffX - dCoeffY) < EPS_SMALL && fabs( dCoeffX - dCoeffZ) < EPS_SMALL ; + // porto i nodi nel nuovo riferimento, senza modificarne la geometria in globale + Frame3d frTrasf = m_gfrFrame.m_frF ; + frTrasf.ToLoc( frFrameS) ; + pGdbNode = GetFirstNode() ; + while ( pGdbNode != nullptr) { + pGdbNode->ToGlob( frTrasf) ; + pGdbNode = pGdbNode->GetNext() ; + } - // basta portare il riferimento di scalatura nel riferimento del gruppo - frRefLoc = frRef ; + // assegno il nuovo riferimento + m_gfrFrame.m_frF = frFrameS ; + + // porto il riferimento di scalatura nel riferimento del gruppo + Frame3d frRefLoc = frRef ; frRefLoc.ToLoc( m_gfrFrame.m_frF) ; // ciclo sui nodi - bOk = true ; + bool bOk = true ; pGdbNode = GetFirstNode() ; while ( pGdbNode != nullptr) { if ( ! pGdbNode->Scale( frRefLoc, dCoeffX, dCoeffY, dCoeffZ)) diff --git a/GdbGroup.h b/GdbGroup.h index 9bdc0cf..787d899 100644 --- a/GdbGroup.h +++ b/GdbGroup.h @@ -37,6 +37,10 @@ class GdbGroup : public GdbNode { double dAngRad = dAngDeg * DEGTORAD ; return Rotate( ptAx, vtAx, cos( dAngRad), sin( dAngRad)) ; } virtual bool Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double dCoeffZ) ; + virtual bool ToGlob( const Frame3d& frRef) + { return m_gfrFrame.m_frF.ToGlob( frRef) ; } + virtual bool ToLoc( const Frame3d& frRef) + { return m_gfrFrame.m_frF.ToLoc( frRef) ; } public : GdbGroup( void) ; diff --git a/GdbNode.h b/GdbNode.h index 039901a..81aa2f2 100644 --- a/GdbNode.h +++ b/GdbNode.h @@ -37,6 +37,8 @@ class GdbNode virtual bool Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dAngRad) = 0 ; virtual bool Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double dCoeffZ) = 0 ; //virtual bool Mirror( const Point3d& ptOn, const Vector3d& vtNorm) = 0 ; + virtual bool ToGlob( const Frame3d& frRef) = 0 ; + virtual bool ToLoc( const Frame3d& frRef) = 0 ; public : GdbNode( void) ; diff --git a/GdbObj.cpp b/GdbObj.cpp index d83df5f..a8ef86a 100644 --- a/GdbObj.cpp +++ b/GdbObj.cpp @@ -184,3 +184,23 @@ GdbObj::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double dCoe else return false ; } + +//---------------------------------------------------------------------------- +bool +GdbObj::ToGlob( const Frame3d& frRef) +{ + if ( m_pGeoObj != nullptr) + return m_pGeoObj->ToGlob( frRef) ; + else + return false ; +} + +//---------------------------------------------------------------------------- +bool +GdbObj::ToLoc( const Frame3d& frRef) +{ + if ( m_pGeoObj != nullptr) + return m_pGeoObj->ToLoc( frRef) ; + else + return false ; +} diff --git a/GdbObj.h b/GdbObj.h index 0fb95f0..ff2bfc1 100644 --- a/GdbObj.h +++ b/GdbObj.h @@ -34,6 +34,8 @@ class GdbObj : public GdbNode { double dAngRad = dAngDeg * DEGTORAD ; return Rotate( ptAx, vtAx, cos( dAngRad), sin( dAngRad)) ; } virtual bool Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double dCoeffZ) ; + virtual bool ToGlob( const Frame3d& frRef) ; + virtual bool ToLoc( const Frame3d& frRef) ; public : GdbObj( void) ;