//---------------------------------------------------------------------------- // EgalTech 2013-2013 //---------------------------------------------------------------------------- // File : GdbGroup.cpp Data : 28.11.13 Versione : 1.4a2 // Contenuto : Implementazione della classe GdbGroup. // // // // Modifiche : 28.11.13 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "GdbGroup.h" #include "IdManager.h" #include "\EgtDev\Include\EGnStringUtils.h" using namespace std ; //---------------------------------------------------------------------------- GdbGroup::GdbGroup( void) : m_nObjCount( 0), m_pFirstObj( nullptr), m_pLastObj( nullptr) { } //---------------------------------------------------------------------------- GdbGroup::~GdbGroup( void) { // elimino i figli Clear() ; } //---------------------------------------------------------------------------- bool GdbGroup::Clear( void) { // disalloco gli oggetti GdbObj* pObj ; pObj = GetFirstObj() ; while ( pObj != nullptr) { // lo rimuovo dalla lista pObj->Remove() ; // lo disalloco delete pObj ; // passo al nuovo primo pObj = GetFirstObj() ; } return true ; } //---------------------------------------------------------------------------- GdbGroup* GdbGroup::Clone( int nId, IdManager& IdMgr) const { // alloco gruppo Gdb GdbGroup* pGdbGroup ; pGdbGroup = new(nothrow) GdbGroup ; if ( pGdbGroup == nullptr) return nullptr ; // copio dati oggetto Gdb pGdbGroup->GdbObj::Copy( this) ; // assegno nuovo Id pGdbGroup->m_nId = nId ; IdMgr.UpdateMaxId( nId) ; // copio dati gruppo pGdbGroup->m_gfrFrame = m_gfrFrame ; // clono gli oggetti figli const GdbObj* pObj = GetFirstObj() ; while ( pObj != nullptr) { // eseguo copia GdbObj* pNewObj = pObj->Clone( IdMgr.GetNewId(), IdMgr) ; if ( pNewObj == nullptr) { delete pGdbGroup ; return nullptr ; } // lo inserisco nella lista dei figli if ( ! pNewObj->AddTail( pGdbGroup)) { delete pNewObj ; delete pGdbGroup ; return nullptr ; } // lo inserisco nella mappa degli Id if ( ! IdMgr.AddObj( pNewObj->m_nId, pNewObj)) { delete pGdbGroup ; return nullptr ; } // passo al prossimo oggetto pObj = pObj->GetNext() ; } return pGdbGroup ; } //---------------------------------------------------------------------------- bool GdbGroup::Save( std::ostream& osOut) const { bool bOk = true ; // tipo entità osOut << GetKey() << endl ; // identificativi osOut << m_nId << "@" << GetParentId() << endl ; // attributi if ( ! GdbObj::SaveAttribs( osOut)) bOk = false ; // dati del riferimento osOut << "G" << endl ; if ( ! m_gfrFrame.Save( osOut)) bOk = false ; // salvataggio dei figli const GdbObj* pGdbObj = GetFirstObj() ; while ( pGdbObj != nullptr) { if ( ! pGdbObj->Save( osOut)) bOk = false ; pGdbObj = pGdbObj->GetNext() ; } return bOk ; } //---------------------------------------------------------------------------- bool GdbGroup::Load( const string& sType, Scanner& TheScanner, int& nParentId) { string sLine ; STRVECTOR vsParams ; // leggo la prossima linea if ( ! TheScanner.GetLine( sLine)) return false ; // la divido in parametri Tokenize( sLine, "@", vsParams) ; // 2 parametri : Id e ParentId if ( vsParams.size() != 2) return false ; // assegno l'identificativo if ( ! FromString( vsParams[0], m_nId)) return false ; // assegno l'Id del padre if ( ! FromString( vsParams[1], nParentId)) return false ; // leggo la prossima linea if ( ! TheScanner.GetLine( sLine)) return false ; // eventuali attributi if ( sLine == "A") { if ( ! GdbObj::LoadAttribs( TheScanner)) return false ; // leggo la prossima linea if ( ! TheScanner.GetLine( sLine)) return false ; } // verifico inizio dati geometrici if ( sLine != "G") return false ; // leggo i dati del riferimento m_gfrFrame.Load( TheScanner) ; return true ; } //---------------------------------------------------------------------------- bool GdbGroup::GetLocalBBox( BBox3d& b3Loc) const { b3Loc.Reset() ; const GdbObj* pGdbObj = GetFirstObj() ; while ( pGdbObj != nullptr) { BBox3d b3B ; // voglio il box come appare nel frame del gruppo, quindi passo frame identità if ( pGdbObj->GetBBox( GLOB_FRM, b3B)) b3Loc.Add( b3B) ; pGdbObj = pGdbObj->GetNext() ; } return true ; } //---------------------------------------------------------------------------- bool GdbGroup::GetBBox( const Frame3d& frRef, BBox3d& b3Ref) const { Frame3d frCurr = m_gfrFrame.m_frF * frRef ; b3Ref.Reset() ; const GdbObj* pGdbObj = GetFirstObj() ; while ( pGdbObj != nullptr) { BBox3d b3B ; if ( pGdbObj->GetBBox( frCurr, b3B)) b3Ref.Add( b3B) ; pGdbObj = pGdbObj->GetNext() ; } return true ; } //---------------------------------------------------------------------------- bool GdbGroup::Translate( const Vector3d& vtMove) { return m_gfrFrame.Translate( vtMove) ; } //---------------------------------------------------------------------------- bool GdbGroup::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, double dSinAng) { return m_gfrFrame.Rotate( ptAx, vtAx, dCosAng, dSinAng) ; } //---------------------------------------------------------------------------- bool GdbGroup::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double dCoeffZ) { GdbObj* pGdbObj ; // parziale scalatura del riferimento (non può essere completa) Frame3d frFrameS = m_gfrFrame.m_frF ; frFrameS.PseudoScale( frRef, dCoeffX, dCoeffY, dCoeffZ) ; // porto gli oggetti nel nuovo riferimento, senza modificarne la geometria in globale Frame3d frTrasf = m_gfrFrame.m_frF ; frTrasf.ToLoc( frFrameS) ; pGdbObj = GetFirstObj() ; while ( pGdbObj != nullptr) { pGdbObj->ToGlob( frTrasf) ; pGdbObj = pGdbObj->GetNext() ; } // 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 bool bOk = true ; pGdbObj = GetFirstObj() ; while ( pGdbObj != nullptr) { if ( ! pGdbObj->Scale( frRefLoc, dCoeffX, dCoeffY, dCoeffZ)) bOk = false ; pGdbObj = pGdbObj->GetNext() ; } return bOk ; } //---------------------------------------------------------------------------- bool GdbGroup::Mirror( const Point3d& ptOn, const Vector3d& vtNorm) { GdbObj* pGdbObj ; // parziale mirror del riferimento (non può essere completa) Frame3d frFrameS = m_gfrFrame.m_frF ; frFrameS.PseudoMirror( ptOn, vtNorm) ; // porto i nodi nel nuovo riferimento, senza modificarne la geometria in globale Frame3d frTrasf = m_gfrFrame.m_frF ; frTrasf.ToLoc( frFrameS) ; pGdbObj = GetFirstObj() ; while ( pGdbObj != nullptr) { pGdbObj->ToGlob( frTrasf) ; pGdbObj = pGdbObj->GetNext() ; } // assegno il nuovo riferimento m_gfrFrame.m_frF = frFrameS ; // porto i dati del piano di mirror nel riferimento del gruppo Point3d ptOnLoc = ptOn ; ptOnLoc.ToLoc( m_gfrFrame.m_frF) ; Vector3d vtNormLoc = vtNorm ; vtNormLoc.ToLoc( m_gfrFrame.m_frF) ; // ciclo sui nodi bool bOk = true ; pGdbObj = GetFirstObj() ; while ( pGdbObj != nullptr) { if ( ! pGdbObj->Mirror( ptOnLoc, vtNormLoc)) bOk = false ; pGdbObj = pGdbObj->GetNext() ; } return bOk ; } //---------------------------------------------------------------------------- bool GdbGroup::GetGlobFrame( Frame3d& frGlob) const { // assegno il proprio frame frGlob = m_gfrFrame.m_frF ; // mentre ci sono padri const GdbGroup* pParent ; pParent = GetParent() ; while ( pParent != nullptr) { // porto il riferimento corrente sopra il padre frGlob.ToGlob( pParent->m_gfrFrame.m_frF) ; // passo al successivo pParent = pParent->GetParent() ; } return true ; }