//---------------------------------------------------------------------------- // EgalTech 2013-2013 //---------------------------------------------------------------------------- // File : GeomDB.cpp Data : 08.04.13 Versione : 1.3a5 // Contenuto : Implementazione della classe GeomDB. // // // // Modifiche : 22.01.13 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "GeomDB.h" #include "GdbGeo.h" #include "DllMain.h" #include "Attribs.h" #include "/EgtDev/Include/EgnStringUtils.h" #include "/EgtDev/Include/EgnStringConverter.h" #include "/EgtDev/Include/EgtPointerOwner.h" #include using namespace std ; //---------------------------------------------------------------------------- IGeomDB* CreateGeomDB( void) { return static_cast ( new(nothrow) GeomDB) ; } //---------------------------------------------------------------------------- // GeomDB //---------------------------------------------------------------------------- GeomDB::GeomDB( void) { m_GrpRadix.m_nId = GDB_ID_ROOT ; m_GrpRadix.SetColor( Color( 0, 0, 0)) ; } //---------------------------------------------------------------------------- GeomDB::~GeomDB( void) { Clear() ; } //---------------------------------------------------------------------------- bool GeomDB::Init( void) { // imposto numero minimo buckets del map degli Id m_IdManager.Init( 1024) ; // imposto colore di default m_GrpRadix.SetColor( Color( 0, 0, 0)) ; return true ; } //---------------------------------------------------------------------------- bool GeomDB::Clear( void) { // elimino mappa degli identificatori m_IdManager.Clear() ; // disalloco i gruppi e gli oggetti m_GrpRadix.Clear() ; return true ; } //---------------------------------------------------------------------------- bool GeomDB::Load( const std::string& sFileIn) { bool bOk ; bool bEnd ; Scanner TheScanner ; // inizializzo lo scanner if ( ! TheScanner.Init( sFileIn)) { LOG_ERROR( GetEGkLogger(), "GeomDbLoad : Error on Init ") return false ; } // leggo l'intestazione if ( ! LoadStart( TheScanner)) { string sOut = "GeomDbLoad : Error on line " + ToString( TheScanner.GetCurrLineNbr()) ; LOG_ERROR( GetEGkLogger(), sOut.c_str()) return false ; } // ciclo di lettura dei nodi bOk = true ; do { if ( ! LoadOneObj( TheScanner, bEnd)) { bOk = false ; string sOut = "GeomDbLoad : Error on line " + ToString( TheScanner.GetCurrLineNbr()) ; LOG_ERROR( GetEGkLogger(), sOut.c_str()) } } while ( ! bEnd) ; return bOk ; } //---------------------------------------------------------------------------- bool GeomDB::LoadStart( Scanner& 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::LoadOneObj( Scanner& TheScanner, bool& bEnd) { int nParentId ; string sType ; GdbObj* pGdbObj ; // 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()) { pGdbObj = new( nothrow) GdbGroup ; } // se copia TODO ("X_CPY").. //else if ( sType == GdbCopy::GetKey) { // pGdbObj = new( nothrow) GdbCopy ; //} // altrimenti oggetto geometrico else pGdbObj = new( nothrow) GdbGeo ; // verifico l'oggetto GDB if ( pGdbObj == nullptr) return false ; // se lettura dati e inserimento nel DB vanno bene if ( pGdbObj->Load( sType, TheScanner, nParentId) && AddToGeomDB( pGdbObj, nParentId)) return true ; // altrimenti errore else { delete pGdbObj ; return false ; } } //---------------------------------------------------------------------------- bool GeomDB::Save( const std::string& sFileOut) const { ofstream ofSave ; // apertura file ofSave.open( stringtoW( sFileOut)) ; if ( ! ofSave.good()) return false ; // intestazione ofSave << "START" << endl ; ofSave << "GeomDB,1.5c1" << endl ; // ciclo di scrittura degli oggetti bool bOk = true ; const GdbObj* pGdbObj = m_GrpRadix.GetFirstObj() ; while ( pGdbObj != nullptr) { // oggetto geometrico if ( ! pGdbObj->Save( ofSave)) bOk = false ; pGdbObj = pGdbObj->GetNext() ; } ofSave << "END" << endl ; // chiusura file ofSave.close() ; return bOk ; } //---------------------------------------------------------------------------- bool GeomDB::ExistsObj( int nId) const { return ( (const_cast(this))->GetGdbObj( nId) != nullptr) ; } //---------------------------------------------------------------------------- GdbObj* GeomDB::GetGdbObj( int nId) { // impossibile if ( nId < GDB_ID_ROOT) return nullptr ; // radice else if ( nId == GDB_ID_ROOT) return &m_GrpRadix ; // un nodo qualubque else return m_IdManager.FindObj( nId) ; } //---------------------------------------------------------------------------- bool GeomDB::AddToGeomDB( GdbObj* pGObj, int nParentId) { // verifico validità oggetto puntato if ( pGObj == nullptr) return false ; // verifica validità e unicità del nome if ( pGObj->m_nId <= GDB_ID_ROOT || ExistsObj( pGObj->m_nId)) return false ; // cerco il padre GdbGroup* pGroup = GetGdbGroup( nParentId) ; if ( pGroup == nullptr) return false ; // inserisco in coda alla lista del padre if ( ! pGObj->AddTail( pGroup)) return false ; // aggiorno gestore Id m_IdManager.UpdateMaxId( pGObj->m_nId) ; // inserisco in mappa nomi return m_IdManager.AddObj( pGObj->m_nId, pGObj) ; } //---------------------------------------------------------------------------- int GeomDB::AddGroup( int nId, int nParentId, const Frame3d& frFrame) { GdbGroup* pGdbGroup ; // verifico validità ParentId if ( nParentId < GDB_ID_ROOT) return GDB_ID_NULL ; // verifico validità Id if ( nId <= GDB_ID_ROOT) nId = m_IdManager.GetNewId() ; if ( ExistsObj( nId)) return GDB_ID_NULL ; // alloco gruppo Gdb pGdbGroup = new(nothrow) GdbGroup ; if ( pGdbGroup == nullptr) return GDB_ID_NULL ; // assegno identificativo pGdbGroup->m_nId = nId ; // assegno riferimento pGdbGroup->m_gfrFrame.m_frF = frFrame ; // inserisco nel DB if ( ! AddToGeomDB( pGdbGroup, nParentId)) { delete pGdbGroup ; return GDB_ID_NULL ; } return nId ; } //---------------------------------------------------------------------------- int GeomDB::AddGeoObj( int nId, int nParentId, IGeoObj* pGeoObj) { GdbGeo* pGdbGeo ; // assegno GeoObj a gestore puntatore con rilascio automatico PtrOwner pRPGeoObj( pGeoObj) ; // verifico validità identificativo if ( nId <= GDB_ID_ROOT) nId = m_IdManager.GetNewId() ; if ( ExistsObj( nId)) return GDB_ID_NULL ; // verifico validità oggetto Geo if ( ! IsValid( pRPGeoObj) || ! pRPGeoObj->IsValid()) return GDB_ID_NULL ; // alloco oggetto Gdb pGdbGeo = new(nothrow) GdbGeo ; if ( pGdbGeo == nullptr) return GDB_ID_NULL ; // assegno identificativo pGdbGeo->m_nId = nId ; // assegno dati pGdbGeo->m_pGeoObj = Release( pRPGeoObj) ; // inserisco nel DB if ( ! AddToGeomDB( pGdbGeo, nParentId)) { delete pGdbGeo ; return GDB_ID_NULL ; } return nId ; } //---------------------------------------------------------------------------- GdbType GeomDB::GetGdbType( int nId) const { const GdbObj* pGdbObj ; // recupero l'oggetto if ( ( pGdbObj = (const_cast (this))->GetGdbObj( nId)) == nullptr) return GDB_NONE ; // se oggetto geometrico if ( ::GetGdbGeo( pGdbObj) != nullptr) return GDB_GEO ; // se gruppo else if ( ::GetGdbGroup( pGdbObj) != nullptr) return GDB_GROUP ; // altro else return GDB_NONE ; } //---------------------------------------------------------------------------- IGeoObj* GeomDB::GetGeoObj( int nId) { // recupero l'oggetto Gdb const GdbGeo* pGdbGeo ; if ( ( pGdbGeo = GetGdbGeo( nId)) == nullptr) return nullptr ; // restituisco il suo contenuto geometrico return pGdbGeo->m_pGeoObj ; } //---------------------------------------------------------------------------- IGeoFrame3d* GeomDB::GetGeoFrame( int nId) { // recupero il gruppo Gdb GdbGroup* pGdbGroup ; if ( ( pGdbGroup = GetGdbGroup( nId)) == nullptr) return nullptr ; // restituisco il suo riferimento return &(pGdbGroup->m_gfrFrame) ; } //---------------------------------------------------------------------------- bool GeomDB::GetGroupFrame( int nId, Frame3d& frGrp) const { // recupero il gruppo Gdb const GdbGroup* pGdbGroup ; if ( ( pGdbGroup = (const_cast (this))->GetGdbGroup( nId)) == nullptr) return false ; // copio il riferimento frGrp = pGdbGroup->m_gfrFrame.m_frF ; return true ; } //---------------------------------------------------------------------------- bool GeomDB::GetGroupGlobFrame( int nId, Frame3d& frGlob) const { // recupero il gruppo Gdb const GdbGroup* pGdbGroup ; if ( ( pGdbGroup = (const_cast (this))->GetGdbGroup( nId)) == nullptr) return false ; // ne faccio calcolare il riferimento globale return pGdbGroup->GetGlobFrame( frGlob) ; } //---------------------------------------------------------------------------- int GeomDB::GetGroupObjs( int nId) const { // recupero il gruppo Gdb const GdbGroup* pGdbGroup ; if ( ( pGdbGroup = (const_cast (this))->GetGdbGroup( nId)) == nullptr) return 0 ; // restituisco il numero di nodi (figli) return pGdbGroup->GetObjCount() ; } //---------------------------------------------------------------------------- int GeomDB::GetParentId( int nId) const { // recupero l'oggetto Gdb const GdbObj* pGdbObj ; if ( ( pGdbObj = (const_cast (this))->GetGdbObj( nId)) == nullptr) return GDB_ID_NULL ; // restituisco l'Id del padre return pGdbObj->GetParentId() ; } //---------------------------------------------------------------------------- bool GeomDB::GetLocalBBox( int nId, BBox3d& b3Loc) const { const GdbObj* pGdbObj ; // recupero l'oggetto if ( ( pGdbObj = (const_cast (this))->GetGdbObj( nId)) == nullptr) return false ; // eseguo l'operazione return pGdbObj->GetLocalBBox( b3Loc) ; } //---------------------------------------------------------------------------- bool GeomDB::GetGlobalBBox( int nId, BBox3d& b3Glob) const { // recupero l'oggetto const GdbObj* pGdbObj ; if ( ( pGdbObj = (const_cast (this))->GetGdbObj( nId)) == nullptr) return false ; // recupero il riferimento globale del gruppo cui appartiene Frame3d frGlob ; if ( ! GetGroupGlobFrame( pGdbObj->GetParentId(), frGlob)) return false ; // eseguo l'operazione return pGdbObj->GetBBox( frGlob, b3Glob) ; } //---------------------------------------------------------------------------- bool GeomDB::GetRefBBox( int nId, const Frame3d& frRef, BBox3d& b3Ref) const { // recupero l'oggetto const GdbObj* pGdbObj ; if ( ( pGdbObj = (const_cast (this))->GetGdbObj( nId)) == nullptr) return false ; // recupero il riferimento globale del gruppo cui appartiene Frame3d frGlob ; if ( ! GetGroupGlobFrame( pGdbObj->GetParentId(), frGlob)) return false ; // lo porto nel riferimento passato frGlob.ToLoc( frRef) ; // eseguo l'operazione return pGdbObj->GetBBox( frGlob, b3Ref) ; } //---------------------------------------------------------------------------- int GeomDB::Copy( int nIdSou, int nIdDest, int nParentIdDest) { // verifico Id destinazione if ( nIdDest <= GDB_ID_ROOT) nIdDest = m_IdManager.GetNewId() ; if ( ExistsObj( nIdDest)) return GDB_ID_NULL ; // verifico esistenza del sorgente GdbObj* pGdOSou ; if ( ( pGdOSou = GetGdbObj( nIdSou)) == nullptr) return GDB_ID_NULL ; // eseguo la copia GdbObj* pGdODest ; if ( ( pGdODest = pGdOSou->Clone( nIdDest, m_IdManager)) == nullptr) return GDB_ID_NULL ; // inserisco nel DB if ( ! AddToGeomDB( pGdODest, nParentIdDest)) { delete pGdODest ; return GDB_ID_NULL ; } return nIdDest ; } //---------------------------------------------------------------------------- int GeomDB::CopyGlob( int nIdSou, int nIdDest, int nParentIdDest) { // verifico Id destinazione if ( nIdDest <= GDB_ID_ROOT) nIdDest = m_IdManager.GetNewId() ; if ( ExistsObj( nIdDest)) return GDB_ID_NULL ; // verifico esistenza del sorgente GdbObj* pGdOSou ; if ( ( pGdOSou = GetGdbObj( nIdSou)) == nullptr) return GDB_ID_NULL ; // recupero il riferimento del sorgente Frame3d frSou ; if ( ! GetGlobFrame( nIdSou, frSou)) return false ; // recupero il riferimento del gruppo destinazione Frame3d frDest ; if ( ! GetGroupGlobFrame( nParentIdDest, frDest)) return false ; // eseguo la copia GdbObj* pGdODest ; if ( ( pGdODest = pGdOSou->Clone( nIdDest, m_IdManager)) == nullptr) return GDB_ID_NULL ; // porto la copia da riferimento sorgente a quello destinazione if ( ! AreSameFrame( frSou, frDest)) { pGdODest->ToGlob( frSou) ; pGdODest->ToLoc( frDest) ; } // inserisco nel DB if ( ! AddToGeomDB( pGdODest, nParentIdDest)) { delete pGdODest ; return GDB_ID_NULL ; } return nIdDest ; } //---------------------------------------------------------------------------- bool GeomDB::Erase( int nId) { INTPGDBO_UMAP::const_iterator Iter ; GdbObj* pGdbObj ; // non si può cancellare il gruppo radice (escludo anche Id non validi) if ( nId <= GDB_ID_ROOT) return false ; // recupero l'oggetto pGdbObj = m_IdManager.FindObj( nId) ; if ( pGdbObj == nullptr) return false ; // elimino da mappa dei nomi m_IdManager.RemoveObj( nId) ; // lo tolgo dalla lista pGdbObj->Remove() ; // lo disalloco (distruttore virtuale) delete pGdbObj ; return true ; } //---------------------------------------------------------------------------- bool GeomDB::Translate( int nId, const Vector3d& vtMove) { // recupero l'oggetto GdbObj* pGdbObj ; if ( ( pGdbObj = GetGdbObj( nId)) == nullptr) return false ; // eseguo la traslazione return pGdbObj->Translate( vtMove) ; } //---------------------------------------------------------------------------- bool GeomDB::TranslateGlob( int nId, const Vector3d& vtMove) { // recupero l'oggetto GdbObj* pGdbObj ; if ( ( pGdbObj = GetGdbObj( nId)) == nullptr) return false ; // recupero il riferimento in cui è immerso Frame3d frObj ; if ( ! GetGlobFrame( nId, frObj)) return false ; // porto il movimento in locale Vector3d vtMoveLoc = vtMove ; if ( ! vtMoveLoc.ToLoc( frObj)) return false ; // eseguo la traslazione return pGdbObj->Translate( vtMoveLoc) ; } //---------------------------------------------------------------------------- bool GeomDB::Rotate( int nId, const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, double dSinAng) { // recupero l'oggetto GdbObj* pGdbObj ; if ( ( pGdbObj = GetGdbObj( nId)) == nullptr) return false ; // eseguo la rotazione return pGdbObj->Rotate( ptAx, vtAx, dCosAng, dSinAng) ; } //---------------------------------------------------------------------------- bool GeomDB::RotateGlob( int nId, const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, double dSinAng) { // recupero l'oggetto GdbObj* pGdbObj ; if ( ( pGdbObj = GetGdbObj( nId)) == nullptr) return false ; // recupero il riferimento in cui è immerso Frame3d frObj ; if ( ! GetGlobFrame( nId, frObj)) return false ; // porto i parametri di rotazione in locale Point3d ptAxLoc = ptAx ; if ( ! ptAxLoc.ToLoc( frObj)) return false ; Vector3d vtAxLoc = vtAx ; if ( ! vtAxLoc.ToLoc( frObj)) return false ; // eseguo la rotazione return pGdbObj->Rotate( ptAxLoc, vtAxLoc, dCosAng, dSinAng) ; } //---------------------------------------------------------------------------- bool GeomDB::Scale( int nId, const Frame3d& frRef, double dCoeffX, double dCoeffY, double dCoeffZ) { // recupero l'oggetto GdbObj* pGdbObj ; if ( ( pGdbObj = GetGdbObj( nId)) == nullptr) return false ; // eseguo la scalatura return pGdbObj->Scale( frRef, dCoeffX, dCoeffY, dCoeffZ) ; } //---------------------------------------------------------------------------- bool GeomDB::ScaleGlob( int nId, const Frame3d& frRef, double dCoeffX, double dCoeffY, double dCoeffZ) { // recupero l'oggetto GdbObj* pGdbObj ; if ( ( pGdbObj = GetGdbObj( nId)) == nullptr) return false ; // recupero il riferimento in cui è immerso Frame3d frObj ; if ( ! GetGlobFrame( nId, frObj)) return false ; // porto il riferimento di scalatura in locale Frame3d frRefLoc = frRef ; if ( ! frRefLoc.ToLoc( frObj)) return false ; // eseguo la scalatura return pGdbObj->Scale( frRefLoc, dCoeffX, dCoeffY, dCoeffZ) ; } //---------------------------------------------------------------------------- bool GeomDB::Mirror( int nId, const Point3d& ptOn, const Vector3d& vtNorm) { // recupero l'oggetto GdbObj* pGdbObj ; if ( ( pGdbObj = GetGdbObj( nId)) == nullptr) return false ; // eseguo l'operazione return pGdbObj->Mirror( ptOn, vtNorm) ; } //---------------------------------------------------------------------------- bool GeomDB::MirrorGlob( int nId, const Point3d& ptOn, const Vector3d& vtNorm) { // recupero l'oggetto GdbObj* pGdbObj ; if ( ( pGdbObj = GetGdbObj( nId)) == nullptr) return false ; // recupero il riferimento in cui è immerso Frame3d frObj ; if ( ! GetGlobFrame( nId, frObj)) return false ; // porto i parametri di mirror in locale Point3d ptOnLoc = ptOn ; if ( ! ptOnLoc.ToLoc( frObj)) return false ; Vector3d vtNormLoc = vtNorm ; if ( ! vtNormLoc.ToLoc( frObj)) return false ; // eseguo l'operazione return pGdbObj->Mirror( ptOnLoc, vtNormLoc) ; } //---------------------------------------------------------------------------- // Attributes //---------------------------------------------------------------------------- bool GeomDB::DumpAttributes( int nId, string& sOut, const char* szNewLine) const { // recupero l'oggetto const GdbObj* pGdbObj ; if ( ( pGdbObj = (const_cast(this))->GetGdbObj( nId)) == nullptr) return false ; // eseguo il dump if ( pGdbObj->m_pAttribs != nullptr) return pGdbObj->m_pAttribs->Dump( sOut, szNewLine) ; else { Attribs attr ; return attr.Dump( sOut, szNewLine) ; } } //---------------------------------------------------------------------------- bool GeomDB::SetDefaultColor( Color cCol) { // recupero l'oggetto GdbObj* pGdbObj ; if ( ( pGdbObj = GetGdbObj( GDB_ID_ROOT)) == nullptr) return false ; // assegno il colore return pGdbObj->SetColor( cCol) ; } //---------------------------------------------------------------------------- bool GeomDB::SetColor( int nId, Color cCol) { // recupero l'oggetto GdbObj* pGdbObj ; if ( ( pGdbObj = GetGdbObj( nId)) == nullptr) return false ; // assegno il colore return pGdbObj->SetColor( cCol) ; } //---------------------------------------------------------------------------- bool GeomDB::GetColor( int nId, Color& cCol) const { // recupero l'oggetto const GdbObj* pGdbObj ; if ( ( pGdbObj = (const_cast(this))->GetGdbObj( nId)) == nullptr) return false ; // recupero il colore return pGdbObj->GetColor( cCol) ; }