//---------------------------------------------------------------------------- // EgalTech 2013-2013 //---------------------------------------------------------------------------- // File : GeomDB.cpp Data : 08.04.13 Versione : 1.1c1 // Contenuto : Implementazione della classe GeomDB. // // // // Modifiche : 22.01.13 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include #include #include "/EgtDev/Include/EgnStringUtils.h" #include "/EgtDev/Include/EgtReleasePointer.h" #include "GdbObj.h" #include "GeomDB.h" using namespace std ; //---------------------------------------------------------------------------- IGeomDB* CreateGeomDB( void) { return static_cast ( new GeomDB) ; } //---------------------------------------------------------------------------- // GeomDB //---------------------------------------------------------------------------- GeomDB::GeomDB( void) { m_GrpRadix.m_nId = 0 ; } //---------------------------------------------------------------------------- GeomDB::~GeomDB( void) { Clear() ; } //---------------------------------------------------------------------------- bool GeomDB::Init( void) { // imposto numero minimo buckets di m_GdbIdMap m_GdbIdMap.rehash( 1024) ; return true ; } //---------------------------------------------------------------------------- bool GeomDB::Clear( void) { // elimino mappa degli identificatori m_GdbIdMap.clear() ; // disalloco i gruppi e gli oggetti m_GrpRadix.Clear() ; return true ; } //---------------------------------------------------------------------------- bool GeomDB::Load( std::ifstream& osIn) { bool bOk ; bool bEnd ; CScan TheScanner ; // inizializzo lo scanner if ( ! TheScanner.Initialize( osIn)) { cout << "GeomDbLoad : Error on Init " << endl ; return false ; } // leggo l'intestazione if ( ! LoadStart( TheScanner)) { cout << "GeomDbLoad : Error on line " << TheScanner.GetCurrLineNbr() << endl ; return false ; } // ciclo di lettura dei nodi bOk = true ; do { if ( ! LoadOneNode( TheScanner, bEnd)) { bOk = false ; cout << "GeomDbLoad : Error on line " << TheScanner.GetCurrLineNbr() << endl ; } } while ( ! bEnd) ; return bOk ; } //---------------------------------------------------------------------------- bool GeomDB::LoadStart( CScan& TheScanner) { string sLine ; // recupero la prima linea if ( ! TheScanner.GetLine( sLine)) return false ; // deve essere l'intestazione if ( sLine != "START") return false ; // recupero la riga successiva if ( ! TheScanner.GetLine( sLine)) return false ; // leggo i parametri // TODO return true ; } //---------------------------------------------------------------------------- bool GeomDB::LoadOneNode( CScan& TheScanner, bool& bEnd) { int nParentId ; string sType ; GdbNode* pGdbNode ; // in generale non è fine file bEnd = false ; // leggo la prossima linea : tipo di nodo if ( ! TheScanner.GetLine( sType)) return false ; // se fine dati if ( sType == "END") { bEnd = true ; return true ; } // se gruppo else if ( sType == GdbGroup::GetKey()) { pGdbNode = new( nothrow) GdbGroup ; } // se copia TODO ("X_CPY").. //else if ( sType == GdbCopy::GetKey) { // pGdbNode = new( nothrow) GdbCopy ; //} // altrimenti oggetto geometrico else pGdbNode = new( nothrow) GdbObj ; // verifico il nodo GDB if ( pGdbNode == nullptr) return false ; // se lettura dati e inserimento nel DB vanno bene if ( pGdbNode->Load( sType, TheScanner, nParentId) && AddToGeomDB( pGdbNode, nParentId)) return true ; // altrimenti errore else { delete pGdbNode ; return false ; } } //---------------------------------------------------------------------------- bool GeomDB::Save( std::ofstream& osOut) const { bool bOk = true ; // intestazione osOut << "START" << endl ; osOut << "GeomDB,1.4a1" << endl ; // ciclo di scrittura degli oggetti const GdbNode* pGdbNode = m_GrpRadix.GetFirstNode() ; while ( pGdbNode != nullptr) { // oggetto geometrico if ( ! pGdbNode->Save( osOut)) bOk = false ; pGdbNode = pGdbNode->GetNext() ; } osOut << "END" << endl ; return bOk ; } //---------------------------------------------------------------------------- bool GeomDB::ExistsNode( int nId) const { INTPGDBN_UMAP::const_iterator Iter ; Iter = m_GdbIdMap.find( nId) ; return ( Iter != m_GdbIdMap.end()) ; } //---------------------------------------------------------------------------- GdbNode* GeomDB::GetGdbNode( int nId) { // impossibile if ( nId < 0) return nullptr ; // radice else if ( nId == 0) return &m_GrpRadix ; // un nodo qualubque else { INTPGDBN_UMAP::const_iterator Iter = m_GdbIdMap.find( nId) ; if ( Iter != m_GdbIdMap.end()) return Iter->second ; else return nullptr ; } } //---------------------------------------------------------------------------- bool GeomDB::AddToGeomDB( GdbNode* pGNode, int nParentId) { // verifico validità oggetto puntato if ( pGNode == nullptr) return false ; // verifica validità e unicità del nome if ( pGNode->m_nId <= 0 || ExistsNode( pGNode->m_nId)) return false ; // cerco il padre GdbGroup* pGroup = GetGdbGroup( nParentId) ; if ( pGroup == nullptr) return false ; // inserisco in coda alla lista del padre if ( ! pGNode->AddTail( pGroup)) return false ; // inserisco in mappa nomi return m_GdbIdMap.insert( pair< int, GdbNode*>( pGNode->m_nId, pGNode)).second ; } //---------------------------------------------------------------------------- bool GeomDB::AddGroup( int nId, int nParentId) { GdbGroup* pGdbGroup ; // verifico validità Id e ParentId if ( nId <= 0 || nParentId < 0) return false ; // alloco gruppo Gdb pGdbGroup = new(nothrow) GdbGroup ; if ( pGdbGroup == nullptr) return false ; // assegno identificativo pGdbGroup->m_nId = nId ; // assegno dati // TODO ... // inserisco nel DB if ( ! AddToGeomDB( pGdbGroup, nParentId)) { delete pGdbGroup ; return false ; } return true ; } //---------------------------------------------------------------------------- bool GeomDB::AddGeoObj( int nId, int nParentId, IGeoObj* pGeoObj) { GdbObj* pGdbObj ; // assegno GeoObj a gestore puntatore con rilascio automatico ReleasePtr pRPGeoObj( pGeoObj) ; // verifico validità identificativo if ( nId <= 0) return false ; // verifico validità oggetto Geo if ( ! IsValid( pRPGeoObj) || ! pRPGeoObj->IsValid()) return false ; // alloco oggetto Gdb pGdbObj = new(nothrow) GdbObj ; if ( pGdbObj == nullptr) return false ; // assegno identificativo pGdbObj->m_nId = nId ; // assegno dati ( ma non ne trasferisco il possesso) pGdbObj->m_pGeoObj = Get( pRPGeoObj) ; // inserisco nel DB if ( ! AddToGeomDB( pGdbObj, nParentId)) { delete pGdbObj ; return false ; } // rilascio il possesso di GeoObj Release( pRPGeoObj) ; return true ; } //---------------------------------------------------------------------------- GeoObjType GeomDB::GetObjType( int nId) const { const GdbObj* pGdbObj ; // recupero l'oggetto if ( ( pGdbObj = (const_cast(this))->GetGdbObj( nId)) == nullptr) return GEO_NONE ; // ne identifico il tipo return pGdbObj->GetType() ; } //---------------------------------------------------------------------------- IGeoObj* GeomDB::GetGeoObj( int nId) { const GdbObj* pGdbObj ; // recupero l'oggetto Gdb if ( ( pGdbObj = GetGdbObj( nId)) == nullptr) return nullptr ; // restituisco il suo contenuto geometrico return pGdbObj->m_pGeoObj ; } //---------------------------------------------------------------------------- bool GeomDB::Copy( int nIdSou, int nIdDest, int nParentIdDest) { GdbNode* pGdNSou ; GdbNode* pGdNDest ; // verifico validità Id destinazione if ( nIdDest <= 0 || ExistsNode( nIdDest)) return false ; // verifico esistenza del sorgente if ( ( pGdNSou = GetGdbNode( nIdSou)) == nullptr) return false ; // eseguo la copia if ( ( pGdNDest = pGdNSou->Clone( nIdDest)) == nullptr) return false ; // inserisco nel DB if ( ! AddToGeomDB( pGdNDest, nParentIdDest)) { delete pGdNDest ; return false ; } return true ; } //---------------------------------------------------------------------------- bool GeomDB::Erase( int nId) { INTPGDBN_UMAP::const_iterator Iter ; GdbNode* pGdbNode ; // recupero l'oggetto Iter = m_GdbIdMap.find( nId) ; if ( Iter == m_GdbIdMap.end()) return false ; pGdbNode = Iter->second ; // elimino da mappa dei nomi m_GdbIdMap.erase( nId) ; // lo tolgo dalla lista pGdbNode->Remove() ; // lo disalloco (distruttore virtuale) delete pGdbNode ; return true ; } //---------------------------------------------------------------------------- bool GeomDB::Translate( int nId, const Vector3d& vtMove) { GdbObj* pGdbObj ; // recupero l'oggetto if ( ( pGdbObj = GetGdbObj( nId)) == nullptr) return false ; // eseguo l'operazione if ( pGdbObj->m_pGeoObj != nullptr) return pGdbObj->m_pGeoObj->Translate( vtMove) ; else return false ; } //---------------------------------------------------------------------------- bool GeomDB::Rotate( int nId, const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, double dSinAng) { GdbObj* pGdbObj ; // recupero l'oggetto if ( ( pGdbObj = GetGdbObj( nId)) == nullptr) return false ; // eseguo l'operazione if ( pGdbObj->m_pGeoObj != nullptr) return pGdbObj->m_pGeoObj->Rotate( ptAx, vtAx, dCosAng, dSinAng) ; else return false ; } //---------------------------------------------------------------------------- bool GeomDB::Scale( int nId, const Point3d& ptCen, double dCoeffX, double dCoeffY, double dCoeffZ) { GdbObj* pGdbObj ; // recupero l'oggetto if ( ( pGdbObj = GetGdbObj( nId)) == nullptr) return false ; // eseguo l'operazione if ( pGdbObj->m_pGeoObj != nullptr) return pGdbObj->m_pGeoObj->Scale( ptCen, dCoeffX, dCoeffY, dCoeffZ) ; else return false ; } //---------------------------------------------------------------------------- bool GeomDB::Mirror( int nId, const Point3d& ptOn, const Vector3d& vtNorm) { GdbObj* pGdbObj ; // recupero l'oggetto if ( ( pGdbObj = GetGdbObj( nId)) == nullptr) return false ; // eseguo l'operazione if ( pGdbObj->m_pGeoObj != nullptr) return pGdbObj->m_pGeoObj->Mirror( ptOn, vtNorm) ; else return false ; }