//---------------------------------------------------------------------------- // EgalTech 2013-2023 //---------------------------------------------------------------------------- // File : GeomDB.cpp Data : 29.05.23 Versione : 2.5e5 // 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 "TextureData.h" #include "NgeReader.h" #include "NgeWriter.h" #include "/EgtDev/Include/EGkStringUtils3d.h" #include "/EgtDev/Include/EGnGetKeyData.h" #include "/EgtDev/Include/EgtStringConverter.h" #include "/EgtDev/Include/EgtPointerOwner.h" #include "/EgtDev/Include/EgtNumCollection.h" #include "/EgtDev/Include/EgtKeyCodes.h" #include "/EgtDev/Include/SELkLockId.h" #include "/EgtDev/Include/SELkKeyProc.h" #include #include #include using namespace std ; //---------------------------------------------------------------------------- class LockAddErase { public : LockAddErase( atomic_flag& bAddEraseOn, bool bUse = true) : m_bAddEraseOn( bAddEraseOn), m_bUse( bUse) { if ( ! m_bUse) return ; while ( m_bAddEraseOn.test_and_set( memory_order_acquire)) { m_bAddEraseOn.wait( true, memory_order_relaxed) ; } } ; ~LockAddErase( void) { if ( ! m_bUse) return ; m_bAddEraseOn.clear( memory_order_release) ; m_bAddEraseOn.notify_one() ; } ; private : atomic_flag& m_bAddEraseOn ; bool m_bUse ; } ; //---------------------------------------------------------------------------- IGeomDB* CreateGeomDB( void) { // verifico la chiave e le opzioni unsigned int nOpt1, nOpt2 ; int nOptExpDays ; int nRet = GetEGnKeyOptions( KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV, nOpt1, nOpt2, nOptExpDays) ; if ( ! GetEGkNetHwKey()) nRet = GetKeyOptions( GetEGkKey(), KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV, nOpt1, nOpt2, nOptExpDays) ; // controllo i risultati if ( nRet != KEY_OK && ! EqualNoCase( GetEGkKey(), "EGkBase")) { if ( nRet != KEY_OK) { string sErr = "Error on Key (GKC/" + ToString( nRet) + ")" ; LOG_ERROR( GetEGkLogger(), sErr.c_str()) ; return nullptr ; } if ( ( nOpt1 & KEYOPT_EGK_BASE) == 0 || nOptExpDays < GetCurrDay()) { string sErr = "Error on Key (GKC/OPT)" ; LOG_ERROR( GetEGkLogger(), sErr.c_str()) ; return nullptr ; } } // creo il GeomDB return static_cast ( new( nothrow) GeomDB) ; } //---------------------------------------------------------------------------- // GeomDB //---------------------------------------------------------------------------- GeomDB::GeomDB( void) { m_bAddEraseOn.clear() ; m_GrpRadix.SetGeomDB( this) ; m_GrpRadix.m_nId = GDB_ID_ROOT ; m_GrpRadix.SetMaterial( Color()) ; } //---------------------------------------------------------------------------- GeomDB::~GeomDB( void) { // pulisco tutto Clear() ; } //---------------------------------------------------------------------------- bool GeomDB::Init( void) { // pulizia Clear() ; // imposto numero minimo buckets del map degli Id m_IdManager.Init( 8192) ; // imposto materiale di default m_GrpRadix.SetMaterial( Color()) ; // imposto riferimento griglia standard m_GridFrame = GLOB_FRM ; return true ; } //---------------------------------------------------------------------------- bool GeomDB::Clear( void) { // deseleziono tutto (velocizza, perchè segue ordine lista selezione) ClearSelection() ; // disalloco i gruppi e gli oggetti m_GrpRadix.Clear() ; // pulisco mappa degli identificatori m_IdManager.Clear() ; // cancello i materiali custom m_MatManager.Clear() ; return true ; } //---------------------------------------------------------------------------- bool GeomDB::Load( const string& sFileIn, int nGroupId) { // recupero massimo Id (diventa Id base per entità da caricare) int nBaseGdbId = m_IdManager.GetMaxId() ; // apertura file NgeReader ngeIn ; if ( ! ngeIn.Init( sFileIn)) { LOG_ERROR( GetEGkLogger(), "GeomDbLoad : Error on Init ") return false ; } // leggo l'intestazione if ( ! LoadHeader( ngeIn, ( nBaseGdbId == 0))) { string sOut = "GeomDbLoad : Error on pos " + ToString( ngeIn.GetCurrPos()) ; LOG_ERROR( GetEGkLogger(), sOut.c_str()) return false ; } // leggo i materiali custom INTVECTOR vBaseMatId ; vBaseMatId.reserve( 48) ; if ( ! m_MatManager.Load( ngeIn, vBaseMatId)) { string sOut = "GeomDbLoad : Error on pos " + ToString( ngeIn.GetCurrPos()) ; LOG_ERROR( GetEGkLogger(), sOut.c_str()) return false ; } // ciclo di lettura dei nodi bool bEnd ; bool bOk = true ; do { if ( ! LoadOneObj( ngeIn, nGroupId, nBaseGdbId, vBaseMatId, bEnd)) { bOk = false ; string sOut = "GeomDbLoad : Error on pos " + ToString( ngeIn.GetCurrPos()) ; LOG_ERROR( GetEGkLogger(), sOut.c_str()) } } while ( bOk && ! bEnd) ; return bOk ; } //---------------------------------------------------------------------------- bool GeomDB::LoadHeader( NgeReader& ngeIn, bool bSave) { // intestazione int nKey ; if ( ! ngeIn.ReadKey( nKey) || nKey != NGE_START) return false ; string sVal ; // tipo file e versione if ( ! ngeIn.ReadString( sVal, ",") || sVal != NGE_GEOMDB) return false ; int nFileVer ; if ( ! ngeIn.ReadInt( nFileVer, ";", true)) return false ; ngeIn.SetFileVersion( nFileVer) ; // materiale di default come colore if ( ! ngeIn.ReadKey( nKey) || nKey != NGE_MAT_DEF) return false ; Color colDef( 0, 0, 0, 0) ; if ( ! ngeIn.ReadCol( colDef, ";", true)) return false ; if ( bSave) return SetDefaultMaterial(colDef) ; else return true ; } //---------------------------------------------------------------------------- bool GeomDB::LoadOneObj( NgeReader& ngeIn, int nGroupId, int nBaseGdbId, const INTVECTOR& vBaseMatId, bool& bEnd) { // in generale non è fine file bEnd = false ; // leggo la prossima linea : tipo di nodo int nKey ; if ( ! ngeIn.ReadKey( nKey)) return false ; // se fine dati GdbObj* pGdbObj ; if ( nKey == NGE_END) { bEnd = true ; return true ; } // se gruppo else if ( nKey == NGE_A_GRP) { 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 va bene int nParentId ; if ( pGdbObj->Load( nKey, ngeIn, nBaseGdbId, nParentId)) { // aggiusto Id pGdbObj->m_nId += nBaseGdbId ; // aggiusto Id del gruppo di appartenenza if ( nParentId == GDB_ID_ROOT) nParentId += nGroupId ; else nParentId += nBaseGdbId ; // aggiusto eventuale indice del materiale int nMat ; if ( pGdbObj->GetMaterial( nMat) && nMat > 0 && nMat < int( vBaseMatId.size())) pGdbObj->SetMaterial( vBaseMatId[nMat]) ; // se gruppo, eventuale aggiornamento indici per swap registrato e duplo if ( ::GetGdbGroup( pGdbObj) != nullptr) { int nVal ; if ( pGdbObj->GetInfo( GDB_SI_SOURCE, nVal)) pGdbObj->SetInfo( GDB_SI_SOURCE, nVal + nBaseGdbId) ; if ( pGdbObj->GetInfo( GDB_SI_BASE, nVal)) pGdbObj->SetInfo( GDB_SI_BASE, nVal + nBaseGdbId) ; if ( pGdbObj->GetInfo( GDB_SI_COPY, nVal)) pGdbObj->SetInfo( GDB_SI_COPY, nVal + nBaseGdbId) ; if ( pGdbObj->GetInfo( GDB_SI_MGRPONLY, nVal)) pGdbObj->SetInfo( GDB_SI_MGRPONLY, nVal + nBaseGdbId) ; if ( pGdbObj->GetInfo( GDB_SI_DUPSOU, nVal)) pGdbObj->SetInfo( GDB_SI_DUPSOU, nVal + nBaseGdbId) ; INTVECTOR vnVal ; if ( pGdbObj->GetInfo( GDB_SI_LIST, vnVal)) { transform( vnVal.begin(), vnVal.end(), vnVal.begin(), [nBaseGdbId]( const int& nV) { return nV + nBaseGdbId ; }) ; pGdbObj->SetInfo( GDB_SI_LIST, vnVal) ; } vnVal.clear() ; if ( pGdbObj->GetInfo( GDB_SI_DUPLIST, vnVal)) { transform( vnVal.begin(), vnVal.end(), vnVal.begin(), [nBaseGdbId]( const int& nV) { return nV + nBaseGdbId ; }) ; pGdbObj->SetInfo( GDB_SI_DUPLIST, vnVal) ; } } // se inserimento nel DB va bene, ritorno con successo if ( InsertInGeomDB( pGdbObj, nParentId, GDB_LAST_SON)) { if ( pGdbObj->m_pUserObj != nullptr) pGdbObj->m_pUserObj->SetOwner( pGdbObj->m_nId, this) ; return true ; } } // altrimenti errore delete pGdbObj ; return false ; } //---------------------------------------------------------------------------- bool GeomDB::Save( int nId, const string& sFileOut, int nFlag) const { // verifico la chiave e le opzioni unsigned int nOpt1, nOpt2 ; int nOptExpDays ; int nRet = GetEGnKeyOptions( KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV, nOpt1, nOpt2, nOptExpDays) ; if ( ! GetEGkNetHwKey()) nRet = GetKeyOptions( GetEGkKey(), KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV, nOpt1, nOpt2, nOptExpDays) ; // controllo i risultati if ( nRet != KEY_OK) { string sErr = "Error on Key (GKS/" + ToString( nRet) + ")" ; LOG_ERROR( GetEGkLogger(), sErr.c_str()) ; return false ; } if ( ( nOpt1 & KEYOPT_EGK_SAVE) == 0 || nOptExpDays < GetCurrDay()) { string sErr = "Error on Key (GKS/OPT)" ; LOG_ERROR( GetEGkLogger(), sErr.c_str()) ; return false ; } // assegno Id base int nBaseId = GDB_ID_ROOT ; // se salvataggio parziale if ( nId != GDB_ID_ROOT) { // recupero l'oggetto const GdbObj* pGO = GetGdbObj( nId) ; if ( pGO != nullptr) { int nMinId = pGO->m_nId ; // risalgo alla radice const GdbObj* pParent = pGO->GetParent() ; while ( pParent != nullptr) { if ( pParent->m_nId != GDB_ID_ROOT && pParent->m_nId < nMinId) nMinId = pParent->m_nId ; pParent = pParent->GetParent() ; } // se gruppo, verifico tutti i figli if ( pGO->GetGdbType() == GDB_TY_GROUP) { const GdbGroup* pGdbGroup = ::GetGdbGroup( pGO) ; nMinId = min( nMinId, pGdbGroup->GetMinId()) ; } // aggiorno Id base nBaseId = max( nBaseId, nMinId - 1) ; } } // apertura file NgeWriter ngeOut ; if ( ! ngeOut.Init( sFileOut, nFlag)) { LOG_ERROR( GetEGkLogger(), "GeomDbSave : Error on Init ") return false ; } // intestazione if ( ! SaveHeader( ngeOut)) return false ; // materiali custom if ( ! m_MatManager.Save( ngeOut)) return false ; // recupero l'oggetto const GdbObj* pGdbObj = GetGdbObj( nId) ; // se oggetto geometrico if ( pGdbObj != nullptr && pGdbObj->GetGdbType() == GDB_TY_GEO) { // recupero l'oggetto geometrico const GdbGeo* pGdbGeo = ::GetGdbGeo( pGdbObj) ; // se non è temporaneo lo salvo insieme con la sua gerarchia int nGrpLevel ; if ( pGdbGeo->GetCalcLevel( nGrpLevel) && nGrpLevel != GDB_LV_TEMP) { // recupero il padre const GdbGroup* pGdbGroup = pGdbObj->GetParent() ; // salvo il padre dopo la sua gerarchia e poi l'oggetto if ( ! SaveGroupHierarchy( pGdbGroup, nBaseId, ngeOut) || ! pGdbObj->Save( nBaseId, ngeOut)) return false ; } } // se altrimenti gruppo else if ( pGdbObj != nullptr && pGdbObj->GetGdbType() == GDB_TY_GROUP) { // recupero il gruppo const GdbGroup* pGdbGroup = ::GetGdbGroup( pGdbObj) ; // se non è il gruppo radice if ( pGdbGroup != &m_GrpRadix) { // se non è temporaneo lo salvo insieme con la sua gerarchia int nGrpLevel ; if ( pGdbGroup->GetCalcLevel( nGrpLevel) && nGrpLevel != GDB_LV_TEMP) { if ( ! SaveGroupHierarchy( pGdbGroup, nBaseId, ngeOut)) return false ; } // altrimenti dichiaro gruppo da saltare else pGdbGroup = nullptr ; } // ciclo di scrittura degli oggetti del gruppo if ( pGdbGroup != nullptr) { if ( ! pGdbGroup->SaveChildren( nBaseId, ngeOut)) return false ; } } // terminazione if ( ! SaveFooter( ngeOut)) return false ; // chiusura file return ngeOut.Close() ; } //---------------------------------------------------------------------------- bool GeomDB::Save( const INTVECTOR& vId, const string& sFileOut, int nFlag) const { // verifico la chiave e le opzioni unsigned int nOpt1, nOpt2 ; int nOptExpDays ; int nRet = GetEGnKeyOptions( KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV, nOpt1, nOpt2, nOptExpDays) ; if ( ! GetEGkNetHwKey()) nRet = GetKeyOptions( GetEGkKey(), KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV, nOpt1, nOpt2, nOptExpDays) ; // controllo i risultati if ( nRet != KEY_OK) { string sErr = "Error on Key (GKS/" + ToString( nRet) + ")" ; LOG_ERROR( GetEGkLogger(), sErr.c_str()) ; return false ; } if ( ( nOpt1 & KEYOPT_EGK_SAVE) == 0 || nOptExpDays < GetCurrDay()) { string sErr = "Error on Key (GKS/OPT)" ; LOG_ERROR( GetEGkLogger(), sErr.c_str()) ; return false ; } // assegno Id base (nessuna riduzione degli Id) int nBaseId = GDB_ID_ROOT ; // apertura file NgeWriter ngeOut ; if ( ! ngeOut.Init( sFileOut, nFlag)) { LOG_ERROR( GetEGkLogger(), "GeomDbSave : Error on Init ") return false ; } // intestazione if ( ! SaveHeader( ngeOut)) return false ; // materiali custom if ( ! m_MatManager.Save( ngeOut)) return false ; // ciclo sugli oggetti da esportare INTUNORDSET usSavedId ; for ( const auto nId : vId) { // se già salvato, passo oltre if ( usSavedId.find( nId) != usSavedId.end()) continue ; // recupero l'oggetto const GdbObj* pGdbObj = GetGdbObj( nId) ; // se oggetto geometrico if ( pGdbObj != nullptr && pGdbObj->GetGdbType() == GDB_TY_GEO) { // recupero l'oggetto geometrico const GdbGeo* pGdbGeo = ::GetGdbGeo( pGdbObj) ; // se non è temporaneo lo salvo insieme con la sua gerarchia int nGrpLevel ; if ( pGdbGeo->GetCalcLevel( nGrpLevel) && nGrpLevel != GDB_LV_TEMP) { // recupero il padre const GdbGroup* pGdbGroup = pGdbObj->GetParent() ; // salvo il padre dopo la sua gerarchia e poi l'oggetto if ( ! SaveGroupHierarchy( pGdbGroup, nBaseId, ngeOut, &usSavedId) || ! pGdbObj->Save( nBaseId, ngeOut, &usSavedId)) return false ; } } // se altrimenti gruppo else if ( pGdbObj != nullptr && pGdbObj->GetGdbType() == GDB_TY_GROUP) { // recupero il gruppo const GdbGroup* pGdbGroup = ::GetGdbGroup( pGdbObj) ; // se non è il gruppo radice if ( pGdbGroup != &m_GrpRadix) { // se non è temporaneo lo salvo insieme con la sua gerarchia int nGrpLevel ; if ( pGdbGroup->GetCalcLevel( nGrpLevel) && nGrpLevel != GDB_LV_TEMP) { if ( ! SaveGroupHierarchy( pGdbGroup, nBaseId, ngeOut, &usSavedId)) return false ; } // altrimenti dichiaro gruppo da saltare else pGdbGroup = nullptr ; } // ciclo di scrittura degli oggetti del gruppo if ( pGdbGroup != nullptr) { if ( ! pGdbGroup->SaveChildren( nBaseId, ngeOut, &usSavedId)) return false ; } } } // terminazione if ( ! SaveFooter( ngeOut)) return false ; // chiusura file return ngeOut.Close() ; } //---------------------------------------------------------------------------- bool GeomDB::SaveGroupHierarchy( const GdbGroup* pGdbGroup, int nBaseId, NgeWriter& ngeOut, INTUNORDSET* pSavedIds) const { // costruisco la gerarchia del gruppo typedef stack PGGSTACK ; PGGSTACK GrpStack ; try { while ( pGdbGroup != nullptr && pGdbGroup != &m_GrpRadix) { GrpStack.push( pGdbGroup) ; pGdbGroup = pGdbGroup->GetParent() ; } } catch ( ...) { return false ; } // salvo la gerarchia del gruppo while ( ! GrpStack.empty()) { if ( ! GrpStack.top()->SaveEmpty( nBaseId, ngeOut, pSavedIds)) return false ; GrpStack.pop() ; } return true ; } //---------------------------------------------------------------------------- bool GeomDB::SaveHeader( NgeWriter& ngeOut) const { // intestazione if ( ! ngeOut.WriteKey( NGE_START)) return false ; if ( ! ngeOut.WriteString( NGE_GEOMDB, ",")) return false ; if ( ! ngeOut.WriteInt( NGE_VER_LAST, ";", true)) return false ; // LockId del sistema come commento string sLockId ; if ( GetEGkNetHwKey()) { sLockId = "NET-000000" ; } else if ( ! GetLockId( sLockId)) { LOG_ERROR( GetEGkLogger(), "Error on Key (1)") return false ; } if ( ! ngeOut.WriteRemark( "LWR=" + sLockId)) return false ; // materiale di default come colore Color colDef( 0, 0, 0, 0) ; GetDefaultMaterial( colDef) ; if ( ! ngeOut.WriteKey( NGE_MAT_DEF)) return false ; if ( ! ngeOut.WriteCol( colDef, ";", true)) return false ; return true ; } //---------------------------------------------------------------------------- bool GeomDB::SaveFooter( NgeWriter& ngeOut) const { // terminazione return ngeOut.WriteKey( NGE_END) ; } //---------------------------------------------------------------------------- bool GeomDB::ExistsObj( int nId) const { return ( 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) ; } //---------------------------------------------------------------------------- const GdbObj* GeomDB::GetGdbObj( int nId) const { // impossibile if ( nId < GDB_ID_ROOT) return nullptr ; // radice else if ( nId == GDB_ID_ROOT) return &m_GrpRadix ; // un nodo qualunque else return m_IdManager.FindObj( nId) ; } //---------------------------------------------------------------------------- bool GeomDB::InsertInGeomDB( GdbObj* pGObj, int nRefId, int nSonBeforeAfter, bool bLockAddErase, bool bTestId) { // verifico validità oggetto puntato if ( pGObj == nullptr) return false ; // verifico validità del riferimento if ( nRefId < GDB_ID_ROOT) return false ; // oggetto e riferimento non possono essere la stessa cosa if ( pGObj->m_nId == nRefId) return ( ! IS_GDB_SON( nSonBeforeAfter)) ; // verifico unicità esecuzione, se necessaria LockAddErase Lock( m_bAddEraseOn, bLockAddErase) ; // cerco il riferimento GdbObj* pGRef = GetGdbObj( nRefId) ; if ( pGRef == nullptr) return false ; // se richiesta, verifica validità e unicità del nome if ( bTestId && ( pGObj->m_nId <= GDB_ID_ROOT || ExistsObj( pGObj->m_nId))) return false ; // assegno il riferimento al DB geometrico pGObj->SetGeomDB( this) ; // inserisco prima del riferimento if ( nSonBeforeAfter == GDB_BEFORE) { if ( ! pGObj->InsertBefore( pGRef)) return false ; } // inserisco dopo il riferimento else if ( nSonBeforeAfter == GDB_AFTER) { if ( ! pGObj->InsertAfter( pGRef)) return false ; } // inserisco come figlio, in testa alla lista del padre else if ( nSonBeforeAfter == GDB_FIRST_SON) { GdbGroup* pGroup = ::GetGdbGroup( pGRef) ; if ( pGroup == nullptr) return false ; // inserisco in testa alla lista del padre if ( ! pGObj->AddHead( pGroup)) return false ; } // inserisco come figlio, in coda alla lista del padre else { GdbGroup* pGroup = ::GetGdbGroup( pGRef) ; if ( pGroup == nullptr) return false ; // inserisco in coda alla lista del padre if ( ! pGObj->AddTail( pGroup)) return false ; } // se richiesto, inserisco in mappa Id if ( bTestId) return m_IdManager.AddObj( pGObj->m_nId, pGObj) ; else return true ; } //---------------------------------------------------------------------------- int GeomDB::AddGroup( int nId, int nParentId, const Frame3d& frFrame) { return InsertGroup( nId, nParentId, GDB_LAST_SON, frFrame) ; } //---------------------------------------------------------------------------- int GeomDB::InsertGroup( int nId, int nRefId, int nSonBeforeAfter, const Frame3d& frFrame) { // verifico validità apparente RefId if ( nRefId < GDB_ID_ROOT) return GDB_ID_NULL ; // verifico unicità esecuzione LockAddErase Lock( m_bAddEraseOn) ; // verifico validità Id if ( nId <= GDB_ID_ROOT) nId = m_IdManager.GetNewId() ; if ( ExistsObj( nId)) return GDB_ID_NULL ; // alloco gruppo Gdb GdbGroup* pGdbGroup = new( nothrow) GdbGroup ; if ( pGdbGroup == nullptr) return GDB_ID_NULL ; // assegno identificativo pGdbGroup->m_nId = nId ; // assegno riferimento pGdbGroup->SetFrame( frFrame) ; // inserisco nel DB if ( ! InsertInGeomDB( pGdbGroup, nRefId, nSonBeforeAfter, false)) { delete pGdbGroup ; return GDB_ID_NULL ; } return nId ; } //---------------------------------------------------------------------------- int GeomDB::AddGeoObj( int nId, int nParentId, IGeoObj* pGeoObj) { return InsertGeoObj( nId, nParentId, GDB_LAST_SON, pGeoObj) ; } //---------------------------------------------------------------------------- int GeomDB::InsertGeoObj( int nId, int nRefId, int nSonBeforeAfter, IGeoObj* pGeoObj) { // assegno GeoObj a gestore puntatore con rilascio automatico PtrOwner pRPGeoObj( pGeoObj) ; // verifico unicità esecuzione LockAddErase Lock( m_bAddEraseOn) ; // verifico validità identificativo if ( nId <= GDB_ID_ROOT) nId = m_IdManager.GetNewId() ; if ( ExistsObj( nId)) return GDB_ID_NULL ; // verifico validità oggetto Geo if ( IsNull( pRPGeoObj) || ! pRPGeoObj->IsValid()) return GDB_ID_NULL ; // alloco oggetto Gdb GdbGeo* 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 ( ! InsertInGeomDB( pGdbGeo, nRefId, nSonBeforeAfter, false)) { delete pGdbGeo ; return GDB_ID_NULL ; } return nId ; } //---------------------------------------------------------------------------- bool GeomDB::ReplaceGeoObj( int nId, IGeoObj* pGeoObj) { // assegno GeoObj a gestore puntatore con rilascio automatico PtrOwner pRPGeoObj( pGeoObj) ; if ( IsNull( pRPGeoObj)) return false ; // recupero l'oggetto Gdb GdbGeo* pGdbGeo = GetGdbGeo( nId) ; if ( pGdbGeo == nullptr) return false ; // elimino il vecchio oggetto e lo sostituisco con il nuovo delete pGdbGeo->m_pGeoObj ; pGdbGeo->m_pGeoObj = Release( pRPGeoObj) ; return true ; } //---------------------------------------------------------------------------- int GeomDB::GetFirstInGroup( int nGroupId) const { // recupero il gruppo const GdbGroup* pGdbGroup = GetGdbGroup( nGroupId) ; if ( pGdbGroup == nullptr) return GDB_ID_NULL ; // recupero il primo oggetto del gruppo const GdbObj* pGdbO = pGdbGroup->GetFirstObj() ; if ( pGdbO == nullptr) return GDB_ID_NULL ; return ( pGdbO->m_nId) ; } //---------------------------------------------------------------------------- int GeomDB::GetNext( int nId) const { // recupero l'oggetto const GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return GDB_ID_NULL ; // recupero il successivo const GdbObj* pGdbNext = pGdbObj->GetNext() ; if ( pGdbNext == nullptr) return GDB_ID_NULL ; return ( pGdbNext->m_nId) ; } //---------------------------------------------------------------------------- int GeomDB::GetLastInGroup( int nGroupId) const { // recupero il gruppo const GdbGroup* pGdbGroup = GetGdbGroup( nGroupId) ; if ( pGdbGroup == nullptr) return GDB_ID_NULL ; // recupero l'ultimo oggetto del gruppo const GdbObj* pGdbO = pGdbGroup->GetLastObj() ; if ( pGdbO == nullptr) return GDB_ID_NULL ; return ( pGdbO->m_nId) ; } //---------------------------------------------------------------------------- int GeomDB::GetPrev( int nId) const { // recupero l'oggetto const GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return GDB_ID_NULL ; // recupero il precedente const GdbObj* pGdbPrev = pGdbObj->GetPrev() ; if ( pGdbPrev == nullptr) return GDB_ID_NULL ; return ( pGdbPrev->m_nId) ; } //---------------------------------------------------------------------------- static bool AnalyzeName( string& sToFind) { bool bRepl = ( ReplaceString( sToFind, "**", "\n") != 0) ; bool bWild = ( sToFind.back() == '*') ; if ( bWild) sToFind.pop_back() ; if ( bRepl) ReplaceString( sToFind, "\n", "*") ; return bWild ; } //---------------------------------------------------------------------------- int GeomDB::GetFirstNameInGroup( int nGroupId, const string& sName) const { // verifico validità minima di stringa con nome if ( IsEmptyOrSpaces( sName)) return GDB_ID_NULL ; // determinazione tipo di ricerca string sToFind = sName ; bool bWild = AnalyzeName( sToFind) ; // recupero il gruppo const GdbGroup* pGdbGroup = GetGdbGroup( nGroupId) ; if ( pGdbGroup == nullptr) return GDB_ID_NULL ; // recupero il primo oggetto del gruppo const GdbObj* pGdbO = pGdbGroup->GetFirstObj() ; while ( pGdbO != nullptr) { // se ha il nome o la parte iniziale di nome cercato string sObjName ; if ( pGdbO->GetName( sObjName) && (( ! bWild && sObjName == sToFind) || ( bWild && sObjName.rfind( sToFind, 0) == 0))) return ( pGdbO->m_nId) ; // passo al successivo pGdbO = pGdbO->GetNext() ; } return GDB_ID_NULL ; } //---------------------------------------------------------------------------- int GeomDB::GetNextName( int nId, const string& sName) const { // verifico validità minima di stringa con nome if ( IsEmptyOrSpaces( sName)) return GDB_ID_NULL ; // determinazione tipo di ricerca string sToFind = sName ; bool bWild = AnalyzeName( sToFind) ; // recupero l'oggetto const GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return GDB_ID_NULL ; // recupero il successivo const GdbObj* pGdbNext = pGdbObj->GetNext() ; while ( pGdbNext != nullptr) { // se ha il nome o la parte iniziale di nome cercato string sObjName ; if ( pGdbNext->GetName( sObjName) && (( ! bWild && sObjName == sToFind) || ( bWild && sObjName.rfind( sToFind, 0) == 0))) return ( pGdbNext->m_nId) ; // passo al successivo pGdbNext = pGdbNext->GetNext() ; } return GDB_ID_NULL ; } //---------------------------------------------------------------------------- int GeomDB::GetLastNameInGroup( int nGroupId, const string& sName) const { // verifico validità minima di stringa con nome if ( IsEmptyOrSpaces( sName)) return GDB_ID_NULL ; // determinazione tipo di ricerca string sToFind = sName ; bool bWild = AnalyzeName( sToFind) ; // recupero il gruppo const GdbGroup* pGdbGroup = GetGdbGroup( nGroupId) ; if ( pGdbGroup == nullptr) return GDB_ID_NULL ; // recupero l'ultimo oggetto del gruppo const GdbObj* pGdbO = pGdbGroup->GetLastObj() ; while ( pGdbO != nullptr) { // se ha il nome o la parte iniziale di nome cercato string sObjName ; if ( pGdbO->GetName( sObjName) && (( ! bWild && sObjName == sToFind) || ( bWild && sObjName.rfind( sToFind, 0) == 0))) return ( pGdbO->m_nId) ; // passo al precedente pGdbO = pGdbO->GetPrev() ; } return GDB_ID_NULL ; } //---------------------------------------------------------------------------- int GeomDB::GetPrevName( int nId, const string& sName) const { // verifico validità minima di stringa con nome if ( IsEmptyOrSpaces( sName)) return GDB_ID_NULL ; // determinazione tipo di ricerca string sToFind = sName ; bool bWild = AnalyzeName( sToFind) ; // recupero l'oggetto const GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return GDB_ID_NULL ; // recupero il precedente const GdbObj* pGdbPrev = pGdbObj->GetPrev() ; while ( pGdbPrev != nullptr) { // se ha il nome o la parte iniziale di nome cercato string sObjName ; if ( pGdbPrev->GetName( sObjName) && (( ! bWild && sObjName == sToFind) || ( bWild && sObjName.rfind( sToFind, 0) == 0))) return ( pGdbPrev->m_nId) ; // passo al precedente pGdbPrev = pGdbPrev->GetPrev() ; } return GDB_ID_NULL ; } //---------------------------------------------------------------------------- int GeomDB::GetFirstGroupInGroup( int nGroupId) const { // recupero il gruppo const GdbGroup* pGdbGroup = GetGdbGroup( nGroupId) ; if ( pGdbGroup == nullptr) return GDB_ID_NULL ; // recupero il primo oggetto del gruppo const GdbObj* pGdbO = pGdbGroup->GetFirstObj() ; while ( pGdbO != nullptr) { // se di tipo gruppo if ( ::GetGdbGroup( pGdbO) != nullptr) return ( pGdbO->m_nId) ; // passo al successivo pGdbO = pGdbO->GetNext() ; } return GDB_ID_NULL ; } //---------------------------------------------------------------------------- int GeomDB::GetNextGroup( int nId) const { // recupero l'oggetto const GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return GDB_ID_NULL ; // recupero il successivo const GdbObj* pGdbNext = pGdbObj->GetNext() ; while ( pGdbNext != nullptr) { // se di tipo gruppo if ( ::GetGdbGroup( pGdbNext) != nullptr) return ( pGdbNext->m_nId) ; // passo al successivo pGdbNext = pGdbNext->GetNext() ; } return GDB_ID_NULL ; } //---------------------------------------------------------------------------- int GeomDB::GetLastGroupInGroup( int nGroupId) const { // recupero il gruppo const GdbGroup* pGdbGroup = GetGdbGroup( nGroupId) ; if ( pGdbGroup == nullptr) return GDB_ID_NULL ; // recupero l'ultimo oggetto del gruppo const GdbObj* pGdbO = pGdbGroup->GetLastObj() ; while ( pGdbO != nullptr) { // se di tipo gruppo if ( ::GetGdbGroup( pGdbO) != nullptr) return ( pGdbO->m_nId) ; // passo al precedente pGdbO = pGdbO->GetPrev() ; } return GDB_ID_NULL ; } //---------------------------------------------------------------------------- int GeomDB::GetPrevGroup( int nId) const { // recupero l'oggetto const GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return GDB_ID_NULL ; // recupero il precedente const GdbObj* pGdbPrev = pGdbObj->GetPrev() ; while ( pGdbPrev != nullptr) { // se di tipo gruppo if ( ::GetGdbGroup( pGdbPrev) != nullptr) return ( pGdbPrev->m_nId) ; // passo al precedente pGdbPrev = pGdbPrev->GetPrev() ; } return GDB_ID_NULL ; } //---------------------------------------------------------------------------- int GeomDB::GetGdbType( int nId) const { // recupero l'oggetto const GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return GDB_TY_NONE ; return pGdbObj->GetGdbType() ; } //---------------------------------------------------------------------------- int GeomDB::GetGeoType( int nId) const { // recupero l'oggetto const GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return GEO_NONE ; // se oggetto geometrico if ( ::GetGdbGeo( pGdbObj) != nullptr) return ::GetGdbGeo( pGdbObj)->GetGeoType() ; else return GEO_NONE ; } //---------------------------------------------------------------------------- IGeoObj* GeomDB::GetGeoObj( int nId) { // recupero l'oggetto Gdb GdbGeo* pGdbGeo = GetGdbGeo( nId) ; if ( pGdbGeo == nullptr) return nullptr ; // restituisco il suo contenuto geometrico return pGdbGeo->m_pGeoObj ; } //---------------------------------------------------------------------------- const IGeoObj* GeomDB::GetGeoObj( int nId) const { // recupero l'oggetto Gdb const GdbGeo* pGdbGeo = GetGdbGeo( nId) ; if ( pGdbGeo == nullptr) return nullptr ; // restituisco il suo contenuto geometrico return pGdbGeo->m_pGeoObj ; } //---------------------------------------------------------------------------- Frame3d* GeomDB::GetGroupFrame( int nId) { // recupero il gruppo Gdb GdbGroup* pGdbGroup = GetGdbGroup( nId) ; if ( pGdbGroup == nullptr) return nullptr ; // restituisco il suo indirizzo return &(pGdbGroup->GetFrame()) ; } //---------------------------------------------------------------------------- const Frame3d* GeomDB::GetGroupFrame( int nId) const { // recupero il gruppo Gdb const GdbGroup* pGdbGroup = GetGdbGroup( nId) ; if ( pGdbGroup == nullptr) return nullptr ; // restituisco il suo indirizzo return &(pGdbGroup->GetFrame()) ; } //---------------------------------------------------------------------------- bool GeomDB::GetGroupFrame( int nId, Frame3d& frGrp) const { // recupero il gruppo Gdb const GdbGroup* pGdbGroup = GetGdbGroup( nId) ; if ( pGdbGroup == nullptr) return false ; // copio il riferimento frGrp = pGdbGroup->GetFrame() ; return true ; } //---------------------------------------------------------------------------- bool GeomDB::GetGroupGlobFrame( int nId, Frame3d& frGlob) const { // recupero il gruppo Gdb const GdbGroup* pGdbGroup = GetGdbGroup( nId) ; if ( pGdbGroup == 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 = GetGdbGroup( nId) ; if ( pGdbGroup == 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 = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return GDB_ID_NULL ; // restituisco l'Id del padre return pGdbObj->GetParentId() ; } //---------------------------------------------------------------------------- bool GeomDB::GetLocalBBox( int nId, BBox3d& b3Loc, int nFlag) const { // recupero l'oggetto const GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // eseguo l'operazione return pGdbObj->GetLocalBBox( b3Loc, nFlag) ; } //---------------------------------------------------------------------------- bool GeomDB::GetGlobalBBox( int nId, BBox3d& b3Glob, int nFlag) const { // recupero l'oggetto const GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // se non è la radice, recupero il riferimento globale del gruppo cui appartiene Frame3d frGlob ; if ( nId != GDB_ID_ROOT && ! GetGroupGlobFrame( pGdbObj->GetParentId(), frGlob)) return false ; // eseguo l'operazione return pGdbObj->GetBBox( frGlob, b3Glob, nFlag) ; } //---------------------------------------------------------------------------- bool GeomDB::GetRefBBox( int nId, const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const { // recupero l'oggetto const GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == 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, nFlag) ; } //---------------------------------------------------------------------------- int GeomDB::Copy( int nIdSou, int nIdDest, int nRefId, int nSonBeforeAfter, bool bGlob) { // verifico unicità esecuzione LockAddErase Lock( m_bAddEraseOn) ; // 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 = GetGdbObj( nIdSou) ; if ( pGdOSou == nullptr) return GDB_ID_NULL ; // verifico esistenza del padre GdbGroup* pGroupSou = pGdOSou->GetParent() ; if ( pGroupSou == nullptr) return GDB_ID_NULL ; // cerco il padre di destinazione int nParentIdDest = ( IS_GDB_SON( nSonBeforeAfter) ? nRefId : GetParentId( nRefId)) ; GdbGroup* pGroupDest = GetGdbGroup( nParentIdDest) ; if ( pGroupDest == nullptr) return GDB_ID_NULL ; // eseguo la copia PtrOwner pGdODest( pGdOSou->Clone( nIdDest)) ; if ( IsNull( pGdODest)) return GDB_ID_NULL ; // se in globale if ( bGlob) { // recupero il riferimento del sorgente Frame3d frSou ; if ( ! pGroupSou->GetGlobFrame( frSou)) return GDB_ID_NULL ; // recupero il riferimento del gruppo destinazione Frame3d frDest ; if ( ! pGroupDest->GetGlobFrame( frDest)) return GDB_ID_NULL ; // porto la copia da riferimento sorgente a quello destinazione pGdODest->LocToLoc( frSou, frDest) ; } // inserisco nel DB (non rilascio il puntatore) if ( ! InsertInGeomDB( pGdODest, nRefId, nSonBeforeAfter, false)) return GDB_ID_NULL ; // rilascio il puntatore ::Release( pGdODest) ; return nIdDest ; } //---------------------------------------------------------------------------- bool GeomDB::Relocate( int nId, int nRefId, int nSonBeforeAfter, bool bGlob) { // verifico validità del riferimento if ( nRefId < GDB_ID_ROOT) return false ; // l'oggetto e il riferimento non possono coincidere if ( nId == nRefId) return ( ! IS_GDB_SON( nSonBeforeAfter)) ; // verifico unicità esecuzione LockAddErase Lock( m_bAddEraseOn) ; // verifico esistenza dell'oggetto GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // verifico esistenza del padre GdbGroup* pGroup = pGdbObj->GetParent() ; if ( pGroup == nullptr) return false ; // cerco il nuovo padre int nNewParentId = ( IS_GDB_SON( nSonBeforeAfter) ? nRefId : GetParentId( nRefId)) ; GdbGroup* pNewGroup = GetGdbGroup( nNewParentId) ; if ( pNewGroup == nullptr) return false ; // verifico se l'oggetto rimane nello stesso gruppo bool bSameGroup = ( pGroup->m_nId == pNewGroup->m_nId) ; // salvo identificativo del successivo int nNextId = ( pGdbObj->GetNext() != nullptr ? pGdbObj->GetNext()->m_nId : GDB_ID_NULL) ; // se cambia gruppo e rilocazione in globale if ( ! bSameGroup && bGlob) { // recupero il riferimento del sorgente Frame3d frCurr ; if ( ! pGroup->GetGlobFrame( frCurr)) return false ; // recupero il riferimento del nuovo padre Frame3d frNew ; if ( ! pNewGroup->GetGlobFrame( frNew)) return false ; // porto l'oggetto dal riferimento originale a quello nuovo pGdbObj->LocToLoc( frCurr, frNew) ; } // sistemazioni in eventuali GdbIterator con quell'oggetto corrente m_IterManager.ResetObjIfSame( pGdbObj) ; // lo estraggo dalla posizione corrente del DB geometrico pGdbObj->Remove() ; // lo inserisco nella posizione opportuna if ( ! InsertInGeomDB( pGdbObj, nRefId, nSonBeforeAfter, false, false)) { // in caso di errore (condizione assai remota qui) cancello tutto m_IdManager.RemoveObj( pGdbObj->m_nId) ; m_SelManager.RemoveObj( pGdbObj) ; delete pGdbObj ; return false ; } // se cambia gruppo e il materiale è ereditato, notifico che può essere cambiato int nMat ; if ( ! bSameGroup && ( ! pGdbObj->GetMaterial( nMat) || nMat == GDB_MT_PARENT)) pGdbObj->OnSetMaterial() ; // notifico eventuale UserObj if ( pGdbObj->m_pUserObj != nullptr && ! pGdbObj->m_pUserObj->Relocate( pGroup->m_nId, nNextId, nRefId, nSonBeforeAfter, bGlob)) return false ; return true ; } //---------------------------------------------------------------------------- bool GeomDB::GroupSwap( int nId1, int nId2, bool bSwapRef, bool bMark) { // se i due oggetti coincidono non devo fare alcunchè if ( nId1 == nId2) return true ; // verifico esistenza dei due gruppi GdbGroup* pGdbGrp1 = GetGdbGroup( nId1) ; GdbGroup* pGdbGrp2 = GetGdbGroup( nId2) ; if ( pGdbGrp1 == nullptr || pGdbGrp2 == nullptr) return false ; // annullo eventuali iteratori che riferiscono questi oggetti m_IterManager.ResetObjIfSame( pGdbGrp1) ; m_IterManager.ResetObjIfSame( pGdbGrp2) ; // scambio gli oggetti pGdbGrp1->Swap( pGdbGrp2) ; // sistemazioni per materiali ereditati int nMat ; if ( ! pGdbGrp1->GetMaterial( nMat) || nMat == GDB_MT_PARENT) pGdbGrp1->OnSetMaterial() ; if ( ! pGdbGrp2->GetMaterial( nMat) || nMat == GDB_MT_PARENT) pGdbGrp2->OnSetMaterial() ; // se richiesto, scambio i riferimenti if ( bSwapRef) swap( pGdbGrp1->GetFrame(), pGdbGrp2->GetFrame()) ; // se richiesto contrassegno if ( bMark) { // sorgente : aggiorno la base e la lista (devo tornare alla stessa base) pGdbGrp1->RemoveInfo( GDB_SI_SOURCE) ; int nRef ; if ( ! pGdbGrp1->GetInfo( GDB_SI_BASE, nRef)) pGdbGrp1->SetInfo( GDB_SI_BASE, nId2) ; else if ( nRef == nId2) pGdbGrp1->RemoveInfo( GDB_SI_BASE) ; INTVECTOR vnRef ; pGdbGrp1->GetInfo( GDB_SI_LIST, vnRef) ; if ( find( vnRef.begin(), vnRef.end(), nId2) == vnRef.end()) { vnRef.push_back( nId2) ; pGdbGrp1->SetInfo( GDB_SI_LIST, vnRef) ; } // altro : aggiorno il sorgente pGdbGrp2->RemoveInfo( GDB_SI_BASE) ; pGdbGrp2->RemoveInfo( GDB_SI_LIST) ; pGdbGrp2->SetInfo( GDB_SI_SOURCE, nId1) ; } return true ; } //---------------------------------------------------------------------------- int GeomDB::GetNewId( void) const { return m_IdManager.GetNewId() ; } //---------------------------------------------------------------------------- bool GeomDB::ChangeId( int nId, int nNewId) { // se Id non validi, ritorno errore if ( nId <= GDB_ID_ROOT || nNewId <= GDB_ID_ROOT) return false ; // se Id identici, non faccio alcunché if ( nNewId == nId) return true ; // verifico unicità esecuzione LockAddErase Lock( m_bAddEraseOn) ; // verifico nuovo Id if ( ExistsObj( nNewId)) return false ; // recupero l'oggetto GdbObj* pGdO = GetGdbObj( nId) ; if ( pGdO == nullptr) return false ; // elimino da mappa dei nomi vecchio Id e inserisco nuovo m_IdManager.RemoveObj( nId) ; m_IdManager.AddObj( nNewId, pGdO) ; // lista selezionati e GdbIterator non richiedono modifiche // cambio Id dell'oggetto pGdO->m_nId = nNewId ; return true ; } //---------------------------------------------------------------------------- bool GeomDB::Erase( int nId) { // non si può cancellare il gruppo radice (escludo anche Id non validi) if ( nId <= GDB_ID_ROOT) return false ; // recupero l'oggetto GdbObj* pGdbObj = m_IdManager.FindObj( nId) ; if ( pGdbObj == nullptr) return false ; return Erase( pGdbObj) ; } //---------------------------------------------------------------------------- bool GeomDB::Erase( GdbObj* pGdbObj) { // deve essere valido e non il gruppo radice if ( pGdbObj == nullptr || pGdbObj == &m_GrpRadix) return false ; // verifico unicità esecuzione LockAddErase Lock( m_bAddEraseOn) ; // notifico eventuale UserObj if ( pGdbObj->m_pUserObj != nullptr) { // recupero il successivo const GdbObj* pGdbNext = pGdbObj->GetNext() ; int nNextId = ( pGdbNext != nullptr ? pGdbNext->m_nId : GDB_ID_NULL) ; if ( ! pGdbObj->m_pUserObj->Removing( pGdbObj->GetParentId(), nNextId)) return false ; } // lo tolgo dalla lista pGdbObj->Remove() ; // lo disalloco (distruttore virtuale) con sistemazione mappa nomi, lista selezionati e GdbIterator delete pGdbObj ; return true ; } //---------------------------------------------------------------------------- IGeoObj* GeomDB::RemoveGeoObjAndErase( int nId) { // non si può cancellare il gruppo radice (escludo anche Id non validi) if ( nId <= GDB_ID_ROOT) return nullptr ; // verifico unicità esecuzione LockAddErase Lock( m_bAddEraseOn) ; // recupero l'oggetto geometrico GdbGeo* pGdbGeo = ::GetGdbGeo( m_IdManager.FindObj( nId)) ; if ( pGdbGeo == nullptr) return nullptr ; IGeoObj* pGeoObj = pGdbGeo->m_pGeoObj ; // annullo il riferimento alla geometria nell'entità pGdbGeo->m_pGeoObj = nullptr ; // tolgo dalla lista e disalloco pGdbGeo->Remove() ; delete pGdbGeo ; return pGeoObj ; } //---------------------------------------------------------------------------- bool GeomDB::EmptyGroup( int nId) { // escludo Id non validi if ( nId < GDB_ID_ROOT) return false ; // recupero l'oggetto GdbObj* pGdbObj ; pGdbObj = m_IdManager.FindObj( nId) ; if ( pGdbObj == nullptr) return false ; return EmptyGroup( pGdbObj) ; } //---------------------------------------------------------------------------- bool GeomDB::EmptyGroup( GdbObj* pGdbObj) { // deve essere valido e non il gruppo radice if ( pGdbObj == nullptr || pGdbObj == &m_GrpRadix) return false ; // deve essere un gruppo GdbGroup* pGrp = ::GetGdbGroup( pGdbObj) ; if ( pGrp == nullptr) return false ; // verifico unicità esecuzione LockAddErase Lock( m_bAddEraseOn) ; // lo svuoto return pGrp->Clear() ; } //---------------------------------------------------------------------------- bool GeomDB::Translate( int nId, const Vector3d& vtMove) { // non si può modificare il gruppo radice (escludo anche Id non validi) if ( nId <= GDB_ID_ROOT) return false ; // recupero l'oggetto GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // eseguo la traslazione return pGdbObj->Translate( vtMove) ; } //---------------------------------------------------------------------------- bool GeomDB::TranslateGlob( int nId, const Vector3d& vtMove) { // non si può modificare il gruppo radice (escludo anche Id non validi) if ( nId <= GDB_ID_ROOT) return false ; // recupero l'oggetto GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == 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) ; } //---------------------------------------------------------------------------- // La traslazione è espressa nel riferimento del gruppo (ovvero il proprio). //---------------------------------------------------------------------------- bool GeomDB::TranslateGroup( int nId, const Vector3d& vtMove) { // non si può modificare il gruppo radice (escludo anche Id non validi) if ( nId <= GDB_ID_ROOT) return false ; // recupero il gruppo Gdb GdbGroup* pGdbGroup = GetGdbGroup( nId) ; if ( pGdbGroup == nullptr) return false ; // utilizzo il riferimento proprio // porto il movimento nel riferimento in cui è immerso Vector3d vtMoveLoc = vtMove ; if ( ! vtMoveLoc.ToGlob( pGdbGroup->GetFrame())) return false ; // eseguo la traslazione return pGdbGroup->Translate( vtMoveLoc) ; } //---------------------------------------------------------------------------- bool GeomDB::Rotate( int nId, const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, double dSinAng) { // non si può modificare il gruppo radice (escludo anche Id non validi) if ( nId <= GDB_ID_ROOT) return false ; // recupero l'oggetto GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == 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) { // non si può modificare il gruppo radice (escludo anche Id non validi) if ( nId <= GDB_ID_ROOT) return false ; // recupero l'oggetto GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == 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) ; } //---------------------------------------------------------------------------- // La rotazione è espressa nel riferimento del gruppo (ovvero il proprio). //---------------------------------------------------------------------------- bool GeomDB::RotateGroup( int nId, const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, double dSinAng) { // non si può modificare il gruppo radice (escludo anche Id non validi) if ( nId <= GDB_ID_ROOT) return false ; // recupero il gruppo Gdb GdbGroup* pGdbGroup ; if ( ( pGdbGroup = GetGdbGroup( nId)) == nullptr) return false ; // utilizzo il riferimento proprio // porto i parametri di rotazione nel riferimento in cui è immerso Point3d ptAxLoc = ptAx ; if ( ! ptAxLoc.ToGlob( pGdbGroup->GetFrame())) return false ; Vector3d vtAxLoc = vtAx ; if ( ! vtAxLoc.ToGlob( pGdbGroup->GetFrame())) return false ; // eseguo la rotazione return pGdbGroup->Rotate( ptAxLoc, vtAxLoc, dCosAng, dSinAng) ; } //---------------------------------------------------------------------------- bool GeomDB::Scale( int nId, const Frame3d& frRef, double dCoeffX, double dCoeffY, double dCoeffZ) { // non si può modificare il gruppo radice (escludo anche Id non validi) if ( nId <= GDB_ID_ROOT) return false ; // recupero l'oggetto GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == 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) { // non si può modificare il gruppo radice (escludo anche Id non validi) if ( nId <= GDB_ID_ROOT) return false ; // recupero l'oggetto GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == 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) ; } //---------------------------------------------------------------------------- // La scalatura è espressa nel riferimento del gruppo (ovvero il proprio). //---------------------------------------------------------------------------- bool GeomDB::ScaleGroup( int nId, const Frame3d& frRef, double dCoeffX, double dCoeffY, double dCoeffZ) { // non si può modificare il gruppo radice (escludo anche Id non validi) if ( nId <= GDB_ID_ROOT) return false ; // recupero il gruppo Gdb GdbGroup* pGdbGroup ; if ( ( pGdbGroup = GetGdbGroup( nId)) == nullptr) return false ; // utilizzo il riferimento proprio // porto il riferimento di scalatura nel riferimento in cui è immerso Frame3d frRefLoc = frRef ; if ( ! frRefLoc.ToGlob( pGdbGroup->GetFrame())) return false ; // eseguo la scalatura return pGdbGroup->Scale( frRefLoc, dCoeffX, dCoeffY, dCoeffZ) ; } //---------------------------------------------------------------------------- bool GeomDB::Mirror( int nId, const Point3d& ptOn, const Vector3d& vtNorm) { // non si può modificare il gruppo radice (escludo anche Id non validi) if ( nId <= GDB_ID_ROOT) return false ; // recupero l'oggetto GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // eseguo l'operazione return pGdbObj->Mirror( ptOn, vtNorm) ; } //---------------------------------------------------------------------------- bool GeomDB::MirrorGlob( int nId, const Point3d& ptOn, const Vector3d& vtNorm) { // non si può modificare il gruppo radice (escludo anche Id non validi) if ( nId <= GDB_ID_ROOT) return false ; // recupero l'oggetto GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == 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) ; } //---------------------------------------------------------------------------- // La specchiatura è espressa nel riferimento del gruppo (ovvero il proprio). //---------------------------------------------------------------------------- bool GeomDB::MirrorGroup( int nId, const Point3d& ptOn, const Vector3d& vtNorm) { // non si può modificare il gruppo radice (escludo anche Id non validi) if ( nId <= GDB_ID_ROOT) return false ; // recupero il gruppo Gdb GdbGroup* pGdbGroup ; if ( ( pGdbGroup = GetGdbGroup( nId)) == nullptr) return false ; // utilizzo il riferimento proprio // porto i parametri di mirror nel riferimento in cui è immerso Point3d ptOnLoc = ptOn ; if ( ! ptOnLoc.ToGlob( pGdbGroup->GetFrame())) return false ; Vector3d vtNormLoc = vtNorm ; if ( ! vtNormLoc.ToGlob( pGdbGroup->GetFrame())) return false ; // eseguo l'operazione return pGdbGroup->Mirror( ptOnLoc, vtNormLoc) ; } //---------------------------------------------------------------------------- bool GeomDB::Shear( int nId, const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& vtDir, double dCoeff) { // non si può modificare il gruppo radice (escludo anche Id non validi) if ( nId <= GDB_ID_ROOT) return false ; // recupero l'oggetto GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // eseguo l'operazione return pGdbObj->Shear( ptOn, vtNorm, vtDir, dCoeff) ; } //---------------------------------------------------------------------------- bool GeomDB::ShearGlob( int nId, const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& vtDir, double dCoeff) { // non si può modificare il gruppo radice (escludo anche Id non validi) if ( nId <= GDB_ID_ROOT) return false ; // recupero l'oggetto GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // recupero il riferimento in cui è immerso Frame3d frObj ; if ( ! GetGlobFrame( nId, frObj)) return false ; // porto i parametri di shear in locale Point3d ptOnLoc = ptOn ; if ( ! ptOnLoc.ToLoc( frObj)) return false ; Vector3d vtNormLoc = vtNorm ; if ( ! vtNormLoc.ToLoc( frObj)) return false ; Vector3d vtDirLoc = vtDir ; if ( ! vtDirLoc.ToLoc( frObj)) return false ; // eseguo l'operazione return pGdbObj->Shear( ptOnLoc, vtNormLoc, vtDirLoc, dCoeff) ; } //---------------------------------------------------------------------------- // La specchiatura è espressa nel riferimento del gruppo (ovvero il proprio). //---------------------------------------------------------------------------- bool GeomDB::ShearGroup( int nId, const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& vtDir, double dCoeff) { // non si può modificare il gruppo radice (escludo anche Id non validi) if ( nId <= GDB_ID_ROOT) return false ; // recupero il gruppo Gdb GdbGroup* pGdbGroup ; if ( ( pGdbGroup = GetGdbGroup( nId)) == nullptr) return false ; // utilizzo il riferimento proprio // porto i parametri di mirror nel riferimento in cui è immerso Point3d ptOnLoc = ptOn ; if ( ! ptOnLoc.ToGlob( pGdbGroup->GetFrame())) return false ; Vector3d vtNormLoc = vtNorm ; if ( ! vtNormLoc.ToGlob( pGdbGroup->GetFrame())) return false ; Vector3d vtDirLoc = vtDir ; if ( ! vtDirLoc.ToLoc( pGdbGroup->GetFrame())) return false ; // eseguo l'operazione return pGdbGroup->Shear( ptOnLoc, vtNormLoc, vtDirLoc, dCoeff) ; } //---------------------------------------------------------------------------- // Selection //---------------------------------------------------------------------------- bool GeomDB::SelectObj( int nId, bool bOnlyIfVisible) { // recupero l'oggetto GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // se richiesta verifica visibilità if ( bOnlyIfVisible) { int nOldStat = GDB_ST_ON ; pGdbObj->GetCalcStatus( nOldStat) ; if ( nOldStat == GDB_ST_OFF) return true ; } return SetStatus( pGdbObj, GDB_ST_SEL) ; } //---------------------------------------------------------------------------- bool GeomDB::DeselectObj( int nId) { // recupero l'oggetto GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // se selezionato, lo deseleziono if ( pGdbObj->IsSelected()) return RevertStatus( pGdbObj, false) ; // altrimenti, va già bene else return true ; } //---------------------------------------------------------------------------- bool GeomDB::SelectGroupObjs( int nId, int nFilter, bool bOnlyIfVisible) { // recupero il gruppo Gdb GdbGroup* pGdbGroup ; if ( ( pGdbGroup = GetGdbGroup( nId)) == nullptr) return false ; // ciclo sugli oggetti del gruppo e li seleziono for ( GdbObj* pGdbObj = pGdbGroup->GetFirstObj() ; pGdbObj != nullptr ; pGdbObj = pGdbObj->GetNext()) { // eventuale filtro if ( nFilter != 0) { // se richiesti solo gruppi if ( nFilter == GDB_TY_GROUP && ::GetGdbGroup( pGdbObj) == nullptr) continue ; // altrimenti richiesti solo oggetti geometrici di una o più classi ( GEO_ZERODIM, GEO_CURVE, ...) else { GdbGeo* pGObj = ::GetGdbGeo( pGdbObj) ; if ( pGObj == nullptr || ( pGObj->GetGeoType() & nFilter) == 0) continue ; } } // se richiesta verifica visibilità if ( bOnlyIfVisible) { int nOldStat = GDB_ST_ON ; pGdbObj->GetCalcStatus( nOldStat) ; if ( nOldStat == GDB_ST_OFF) continue ; } // eseguo selezione if ( ! SetStatus( pGdbObj, GDB_ST_SEL)) return false ; } return true ; } //---------------------------------------------------------------------------- bool GeomDB::DeselectGroupObjs( int nId) { // recupero il gruppo Gdb GdbGroup* pGdbGroup ; if ( ( pGdbGroup = GetGdbGroup( nId)) == nullptr) return false ; // ciclo sugli oggetti del gruppo e li seleziono GdbObj* pGdbObj = pGdbGroup->GetFirstObj() ; while ( pGdbObj != nullptr) { // se selezionato, lo deseleziono if ( pGdbObj->IsSelected()) { if ( ! RevertStatus( pGdbObj, false)) return false ; } pGdbObj = pGdbObj->GetNext() ; } return true ; } //---------------------------------------------------------------------------- bool GeomDB::IsSelectedObj( int nId) const { // recupero l'oggetto const GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // recupero lo stato return pGdbObj->IsSelected() ; } //---------------------------------------------------------------------------- int GeomDB::GetSelectedObjNbr( void) const { return m_SelManager.GetSize() ; } //---------------------------------------------------------------------------- int GeomDB::GetFirstSelectedObj( void) const { GdbObj* pGObj = m_SelManager.GetFirstObj() ; return (( pGObj == nullptr) ? GDB_ID_NULL : pGObj->m_nId) ; } //---------------------------------------------------------------------------- int GeomDB::GetNextSelectedObj( void) const { GdbObj* pGObj = m_SelManager.GetNextObj() ; return (( pGObj == nullptr) ? GDB_ID_NULL : pGObj->m_nId) ; } //---------------------------------------------------------------------------- int GeomDB::GetLastSelectedObj( void) const { GdbObj* pGObj = m_SelManager.GetLastObj() ; return (( pGObj == nullptr) ? GDB_ID_NULL : pGObj->m_nId) ; } //---------------------------------------------------------------------------- int GeomDB::GetPrevSelectedObj( void) const { GdbObj* pGObj = m_SelManager.GetPrevObj() ; return (( pGObj == nullptr) ? GDB_ID_NULL : pGObj->m_nId) ; } //---------------------------------------------------------------------------- bool GeomDB::ClearSelection( void) { GdbObj* pGObj = m_SelManager.GetFirstObj() ; while ( pGObj != nullptr) { m_SelManager.RemoveObj( pGObj) ; RevertStatus( pGObj, false) ; pGObj = m_SelManager.GetFirstObj() ; } return true ; } //---------------------------------------------------------------------------- // Attributes //---------------------------------------------------------------------------- bool GeomDB::DumpAttributes( int nId, string& sOut, bool bMM, const char* szNewLine) const { // recupero l'oggetto const GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // eseguo il dump if ( pGdbObj->m_pAttribs != nullptr) return pGdbObj->m_pAttribs->Dump( *this, sOut, bMM, szNewLine) ; else { Attribs attr ; return attr.Dump( *this, sOut, bMM, szNewLine) ; } } //---------------------------------------------------------------------------- bool GeomDB::CopyAttributes( int nIdSou, int nIdDest) { // verifico esistenza del sorgente GdbObj* pGdOSou = GetGdbObj( nIdSou) ; if ( pGdOSou == nullptr) return false ; // verifico esistenza della destinazione GdbObj* pGdODest = GetGdbObj( nIdDest) ; if ( pGdODest == nullptr) return false ; // eseguo la copia return pGdODest->CopyAttribsFrom( pGdOSou) ; } //---------------------------------------------------------------------------- bool GeomDB::SetLevel( int nId, int nLevel) { // recupero l'oggetto GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // assegno il livello return pGdbObj->SetLevel( nLevel) ; } //---------------------------------------------------------------------------- bool GeomDB::RevertLevel( int nId) { // recupero l'oggetto GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // ripristino il livello precedente return pGdbObj->RevertLevel() ; } //---------------------------------------------------------------------------- bool GeomDB::GetLevel( int nId, int& nLevel) const { // recupero l'oggetto const GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // recupero il livello return pGdbObj->GetLevel( nLevel) ; } //---------------------------------------------------------------------------- bool GeomDB::GetCalcLevel( int nId, int& nLevel) const { // recupero l'oggetto const GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // recupero il livello calcolato return pGdbObj->GetCalcLevel( nLevel) ; } //---------------------------------------------------------------------------- bool GeomDB::SetMode( int nId, int nMode) { // recupero l'oggetto GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // assegno il modo return pGdbObj->SetMode( nMode) ; } //---------------------------------------------------------------------------- bool GeomDB::RevertMode( int nId) { // recupero l'oggetto GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // ripristino il modo precedente return pGdbObj->RevertMode() ; } //---------------------------------------------------------------------------- bool GeomDB::GetMode( int nId, int& nMode) const { // recupero l'oggetto const GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // recupero il modo return pGdbObj->GetMode( nMode) ; } //---------------------------------------------------------------------------- bool GeomDB::GetCalcMode( int nId, int& nMode) const { // recupero l'oggetto const GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // recupero il modo calcolato return pGdbObj->GetCalcMode( nMode) ; } //---------------------------------------------------------------------------- bool GeomDB::SetStatus( int nId, int nStat) { // recupero l'oggetto GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; return SetStatus( pGdbObj, nStat) ; } //---------------------------------------------------------------------------- bool GeomDB::SetStatus( GdbObj* pGdbObj, int nStat) { // verifico validità oggetto if ( pGdbObj == nullptr) return false ; // recupero lo stato precedente int nOldStat = GDB_ST_ON ; pGdbObj->GetStatus( nOldStat) ; // assegno lo stato if ( ! pGdbObj->SetStatus( nStat)) return false ; // se lo stato è cambiato if ( nStat != nOldStat) { // se il nuovo stato è di selezionato, inserisco oggetto in lista selezionati if ( nStat == GDB_ST_SEL) m_SelManager.AddObj( pGdbObj) ; // altrimenti provo a toglierlo else m_SelManager.RemoveObj( pGdbObj) ; } return true ; } //---------------------------------------------------------------------------- bool GeomDB::RevertStatus( int nId) { // recupero l'oggetto GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; return RevertStatus( pGdbObj) ; } //---------------------------------------------------------------------------- bool GeomDB::RevertStatus( GdbObj* pGdbObj, bool bOkSel) { // verifico validità oggetto if ( pGdbObj == nullptr) return false ; // recupero lo stato precedente int nOldStat = GDB_ST_ON ; pGdbObj->GetStatus( nOldStat) ; // ripristino lo stato precedente if ( ! pGdbObj->RevertStatus()) return false ; // recupero il nuovo stato int nStat = GDB_ST_ON ; pGdbObj->GetStatus( nStat) ; // se inibito ritorno a selezionato e selezionato, imposto visibile if ( ! bOkSel && nStat == GDB_ST_SEL) pGdbObj->SetStatus( GDB_ST_ON) ; // se lo stato è cambiato if ( nStat != nOldStat) { // se il nuovo stato è di selezionato, inserisco oggetto in lista selezionati if ( nStat == GDB_ST_SEL) m_SelManager.AddObj( pGdbObj) ; // altrimenti provo a toglierlo else m_SelManager.RemoveObj( pGdbObj) ; } return true ; } //---------------------------------------------------------------------------- bool GeomDB::GetStatus( int nId, int& nStat) const { // recupero l'oggetto const GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // recupero lo stato return pGdbObj->GetStatus( nStat) ; } //---------------------------------------------------------------------------- bool GeomDB::GetCalcStatus( int nId, int& nStat) const { // recupero l'oggetto const GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // recupero lo stato calcolato return pGdbObj->GetCalcStatus( nStat) ; } //---------------------------------------------------------------------------- bool GeomDB::SetMark( int nId, int nMark) { // recupero l'oggetto GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // imposto la marcatura return pGdbObj->SetMark( nMark) ; } //---------------------------------------------------------------------------- bool GeomDB::ResetMark( int nId) { // recupero l'oggetto GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // cancello la marcatura return pGdbObj->ResetMark() ; } //---------------------------------------------------------------------------- bool GeomDB::GetMark( int nId, int& nMark) const { // recupero l'oggetto const GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // recupero la marcatura return pGdbObj->GetMark( nMark) ; } //---------------------------------------------------------------------------- bool GeomDB::GetCalcMark( int nId, int& nMark) const { // recupero l'oggetto const GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // recupero la marcatura calcolata return pGdbObj->GetCalcMark( nMark) ; } //---------------------------------------------------------------------------- bool GeomDB::CopyMaterial( int nIdSou, int nIdDest) { // verifico esistenza del sorgente GdbObj* pGdOSou = GetGdbObj( nIdSou) ; if ( pGdOSou == nullptr) return false ; // verifico esistenza della destinazione GdbObj* pGdODest = GetGdbObj( nIdDest) ; if ( pGdODest == nullptr) return false ; // recupero l'indice del materiale int nMat ; if ( ! pGdOSou->GetMaterial( nMat)) nMat = GDB_MT_PARENT ; // impostazione switch ( nMat) { case GDB_MT_COLOR : { Color cCol ; if ( ! pGdOSou->GetMaterial( cCol)) GetDefaultMaterial( cCol) ; pGdODest->SetMaterial( cCol) ; } break ; case GDB_MT_PARENT : // hanno lo stesso padre if ( pGdOSou->GetParentId() == pGdODest->GetParentId()) pGdODest->SetMaterial( nMat) ; // altrimenti hanno padre diverso else { // recupero indice calcolato pGdOSou->GetCalcMaterial( nMat) ; // se diverso da colore, lo posso assegnare direttamente if ( nMat != GDB_MT_COLOR) pGdODest->SetMaterial( nMat) ; // altrimenti devo calcolare il colore e assegnarlo else { Color cCol ; if ( ! pGdOSou->GetCalcMaterial( cCol)) GetDefaultMaterial( cCol) ; pGdODest->SetMaterial( cCol) ; } } break ; default : pGdODest->SetMaterial( nMat) ; break ; } return true ; } //---------------------------------------------------------------------------- bool GeomDB::SetDefaultMaterial( Color cCol) { // recupero l'oggetto radice GdbObj* pGdbObj = GetGdbObj( GDB_ID_ROOT) ; if ( pGdbObj == nullptr) return false ; // assegno il colore return pGdbObj->SetMaterial( cCol) ; } //---------------------------------------------------------------------------- bool GeomDB::GetDefaultMaterial( Color& cCol) const { // recupero l'oggetto radice const GdbObj* pGdbObj = GetGdbObj( GDB_ID_ROOT) ; if ( pGdbObj == nullptr) return false ; // recupero il colore return pGdbObj->GetMaterial( cCol) ; } //---------------------------------------------------------------------------- bool GeomDB::SetMaterial( int nId, int nMat) { return SetMaterial( GetGdbObj( nId), nMat) ; } //---------------------------------------------------------------------------- bool GeomDB::SetMaterial( GdbObj* pGdbObj, int nMat) { // verifico validità oggetto if ( pGdbObj == nullptr) return false ; // se materiale da padre if ( nMat == GDB_MT_PARENT) return pGdbObj->SetMaterial( nMat) ; // verifico che il materiale esista if ( ! ExistsMaterial( nMat)) return false ; // recupero il materiale per assegnare anche il colore Material mMat ; GetMaterialData( nMat, mMat) ; // assegno il materiale tramite indice return ( pGdbObj->SetMaterial( mMat.GetDiffuse()) && pGdbObj->SetMaterial( nMat)) ; } //---------------------------------------------------------------------------- bool GeomDB::SetMaterial( int nId, const string& sMatName) { return SetMaterial( GetGdbObj( nId), sMatName) ; } //---------------------------------------------------------------------------- bool GeomDB::SetMaterial( GdbObj* pGdbObj, const string& sMatName) { // verifico validità oggetto if ( pGdbObj == nullptr) return false ; // cerco il materiale nella libreria (indice materiali 1 based) int nMatId = FindMaterial( sMatName) ; if ( nMatId <= GDB_MT_NULL) return false ; // recupero il materiale per assegnare anche il colore Material mMat ; GetMaterialData( nMatId, mMat) ; // assegno il materiale tramite indice return ( pGdbObj->SetMaterial( mMat.GetDiffuse()) && pGdbObj->SetMaterial( nMatId)) ; } //---------------------------------------------------------------------------- bool GeomDB::SetMaterial( int nId, Color cCol) { // recupero l'oggetto GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // assegno il materiale tramite colore return pGdbObj->SetMaterial( cCol) ; } //---------------------------------------------------------------------------- bool GeomDB::GetMaterial( int nId, int& nMat) const { // recupero l'oggetto const GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // recupero l'indice del materiale return pGdbObj->GetMaterial( nMat) ; } //---------------------------------------------------------------------------- bool GeomDB::GetMaterial( int nId, Material& mMat) const { return GetMaterial( GetGdbObj( nId), mMat) ; } //---------------------------------------------------------------------------- bool GeomDB::GetMaterial( const GdbObj* pGdbObj, Material& mMat) const { // verifico validità oggetto if ( pGdbObj == nullptr) return false ; // recupero l'indice del materiale int nMatId ; if ( ! pGdbObj->GetMaterial( nMatId) || nMatId == GDB_MT_PARENT || nMatId == GDB_MT_COLOR) return false ; // recupero il materiale return GetMaterialData( nMatId, mMat) ; } //---------------------------------------------------------------------------- bool GeomDB::GetMaterial( int nId, Color& cCol) const { // recupero l'oggetto const GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // recupero il colore del materiale return pGdbObj->GetMaterial( cCol) ; } //---------------------------------------------------------------------------- bool GeomDB::GetCalcMaterial( int nId, int& nMat) const { // recupero l'oggetto const GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // recupero l'indice del materiale calcolato return pGdbObj->GetCalcMaterial( nMat) ; } //---------------------------------------------------------------------------- bool GeomDB::GetCalcMaterial( int nId, Material& mMat) const { return GetCalcMaterial( GetGdbObj( nId), mMat) ; } //---------------------------------------------------------------------------- bool GeomDB::GetCalcMaterial( const GdbObj* pGdbObj, Material& mMat) const { // verifico validità oggetto if ( pGdbObj == nullptr) return false ; // recupero il materiale tramite l'indice int nIdMat ; if ( pGdbObj->GetCalcMaterial( nIdMat)) { if ( nIdMat == GDB_MT_COLOR) { Color cCol ; if ( pGdbObj->GetCalcMaterial( cCol)) { mMat.Set( cCol) ; Color cDiff = cCol ; cDiff.Intensify( 1.25) ; mMat.SetDiffuse( cDiff) ; return true ; } } else if ( GetMaterialData( nIdMat, mMat)) return true ; } // qualcosa è andato male, recupero il colore di default Color cDef ; GetDefaultMaterial( cDef) ; mMat.Set( cDef) ; return true ; } //---------------------------------------------------------------------------- bool GeomDB::GetCalcMaterial( int nId, Color& cCol) const { // recupero l'oggetto const GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // recupero il colore del materiale calcolato return pGdbObj->GetCalcMaterial( cCol) ; } //---------------------------------------------------------------------------- bool GeomDB::UsedMaterialInGroup( int nMat, const GdbGroup* pGdbGroup) const { // verifico se il gruppo utilizza direttamente il materiale int nObjMat ; if ( pGdbGroup->GetMaterial( nObjMat) && nObjMat == nMat) return true ; // scandisco il gruppo for ( const GdbObj* pGdbObj = pGdbGroup->GetFirstObj() ; pGdbObj != nullptr ; pGdbObj = pGdbObj->GetNext()) { // verifico utilizzo del materiale da parte dell'oggetto if ( pGdbObj->GetMaterial( nObjMat) && nObjMat == nMat) return true ; // se l'oggetto è un gruppo, devo cercare nei suoi figli const GdbGroup* pGdbSubGrp ; if ( ( pGdbSubGrp = ::GetGdbGroup( pGdbObj)) != nullptr) { if ( UsedMaterialInGroup( nMat, pGdbSubGrp)) return true ; } } return false ; } //---------------------------------------------------------------------------- bool GeomDB::NotifyObjectsWithMaterialInGroup( int nMat, Color cCol, bool bByParent, GdbGroup* pGdbGroup) { // verifico se il gruppo utilizza direttamente il materiale int nObjMat ; // recupero il materiale if ( ! pGdbGroup->GetMaterial( nObjMat)) nObjMat = GDB_MT_PARENT ; // se il materiale è usato dal gruppo bByParent = ( nObjMat == nMat || ( nObjMat == GDB_MT_PARENT && bByParent)) ; // eventuale aggiornamento del colore if ( nObjMat == nMat) { pGdbGroup->SetMaterial( cCol) ; pGdbGroup->SetMaterial( nMat) ; } // scandisco il gruppo bool bOk = true ; for ( GdbObj* pGdbObj = pGdbGroup->GetFirstObj() ; pGdbObj != nullptr ; pGdbObj = pGdbObj->GetNext()) { // se sottogruppo, devo cercare nei suoi figli GdbGroup* pGdbSubGrp ; if ( ( pGdbSubGrp = ::GetGdbGroup( pGdbObj)) != nullptr) { if ( ! NotifyObjectsWithMaterialInGroup( nMat, cCol, bByParent, pGdbSubGrp)) bOk = false ; } // altrimenti oggetto else { // recupero il materiale if ( ! pGdbObj->GetMaterial( nObjMat)) nObjMat = GDB_MT_PARENT ; // se il materiale è usato dall'oggetto if ( nObjMat == nMat || ( nObjMat == GDB_MT_PARENT && bByParent)) { if ( ! pGdbObj->OnSetMaterial()) bOk = false ; } // eventuale aggiornamento del colore if ( nObjMat == nMat) { pGdbObj->SetMaterial( cCol) ; pGdbObj->SetMaterial( nMat) ; } } } return bOk ; } //---------------------------------------------------------------------------- bool GeomDB::SetName( int nId, const string& sName) { // recupero l'oggetto GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // assegno il nome return pGdbObj->SetName( sName) ; } //---------------------------------------------------------------------------- bool GeomDB::GetName( int nId, string& sName) const { // recupero l'oggetto const GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // recupero il nome return pGdbObj->GetName( sName) ; } //---------------------------------------------------------------------------- bool GeomDB::ExistsName( int nId) const { // recupero l'oggetto const GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // recupero il nome return pGdbObj->ExistsName() ; } //---------------------------------------------------------------------------- bool GeomDB::RemoveName( int nId) { // recupero l'oggetto GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // rimuovo il nome return pGdbObj->RemoveName() ; } //---------------------------------------------------------------------------- bool GeomDB::SetInfo( int nId, const string& sKey, const string& sInfo) { // recupero l'oggetto GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // assegno l'Info return pGdbObj->SetInfo( sKey, sInfo) ; } //---------------------------------------------------------------------------- bool GeomDB::SetInfo( int nId, const string& sKey, bool bInfo) { return SetInfo( nId, sKey, ToString( bInfo)) ; } //---------------------------------------------------------------------------- bool GeomDB::SetInfo( int nId, const string& sKey, int nInfo) { return SetInfo( nId, sKey, ToString( nInfo)) ; } //---------------------------------------------------------------------------- bool GeomDB::SetInfo( int nId, const string& sKey, double dInfo) { int nErr ; return ( SetInfo( nId, sKey, ToString( dInfo, 6, &nErr)) && nErr == 0) ; } //---------------------------------------------------------------------------- bool GeomDB::SetInfo( int nId, const string& sKey, const Point3d& ptInfo) { return SetInfo( nId, sKey, ToString( ptInfo)) ; } //---------------------------------------------------------------------------- bool GeomDB::SetInfo( int nId, const string& sKey, const Vector3d& vtInfo) { return SetInfo( nId, sKey, ToString( vtInfo)) ; } //---------------------------------------------------------------------------- bool GeomDB::SetInfo( int nId, const string& sKey, const BBox3d& b3Info) { return SetInfo( nId, sKey, ToString( b3Info)) ; } //---------------------------------------------------------------------------- bool GeomDB::SetInfo( int nId, const string& sKey, const Frame3d& frInfo) { return SetInfo( nId, sKey, ToString( frInfo)) ; } //---------------------------------------------------------------------------- bool GeomDB::SetInfo( int nId, const string& sKey, const INTVECTOR& vnInfo) { return SetInfo( nId, sKey, ToString( vnInfo)) ; } //---------------------------------------------------------------------------- bool GeomDB::SetInfo( int nId, const string& sKey, const DBLVECTOR& vdInfo) { return SetInfo( nId, sKey, ToString( vdInfo)) ; } //---------------------------------------------------------------------------- bool GeomDB::SetInfo( int nId, const string& sKey, const STRVECTOR& vsInfo) { return SetInfo( nId, sKey, ToString( vsInfo)) ; } //---------------------------------------------------------------------------- bool GeomDB::GetInfo( int nId, const string& sKey, string& sInfo) const { // recupero l'oggetto const GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // recupero l'Info return pGdbObj->GetInfo( sKey, sInfo) ; } //---------------------------------------------------------------------------- bool GeomDB::GetInfo( int nId, const string& sKey, bool& bInfo) const { string sInfo ; return ( GetInfo( nId, sKey, sInfo) && FromString( sInfo, bInfo)) ; } //---------------------------------------------------------------------------- bool GeomDB::GetInfo( int nId, const string& sKey, int& nInfo) const { string sInfo ; return ( GetInfo( nId, sKey, sInfo) && FromString( sInfo, nInfo)) ; } //---------------------------------------------------------------------------- bool GeomDB::GetInfo( int nId, const string& sKey, double& dInfo) const { string sInfo ; return ( GetInfo( nId, sKey, sInfo) && FromString( sInfo, dInfo)) ; } //---------------------------------------------------------------------------- bool GeomDB::GetInfo( int nId, const string& sKey, Point3d& ptInfo) const { string sInfo ; return ( GetInfo( nId, sKey, sInfo) && FromString( sInfo, ptInfo)) ; } //---------------------------------------------------------------------------- bool GeomDB::GetInfo( int nId, const string& sKey, Vector3d& vtInfo) const { string sInfo ; return ( GetInfo( nId, sKey, sInfo) && FromString( sInfo, vtInfo)) ; } //---------------------------------------------------------------------------- bool GeomDB::GetInfo( int nId, const string& sKey, BBox3d& b3Info) const { string sInfo ; return ( GetInfo( nId, sKey, sInfo) && FromString( sInfo, b3Info)) ; } //---------------------------------------------------------------------------- bool GeomDB::GetInfo( int nId, const string& sKey, Frame3d& frInfo) const { string sInfo ; return ( GetInfo( nId, sKey, sInfo) && FromString( sInfo, frInfo)) ; } //---------------------------------------------------------------------------- bool GeomDB::GetInfo( int nId, const string& sKey, INTVECTOR& vnInfo) const { string sInfo ; return ( GetInfo( nId, sKey, sInfo) && FromString( sInfo, vnInfo)) ; } //---------------------------------------------------------------------------- bool GeomDB::GetInfo( int nId, const string& sKey, DBLVECTOR& vdInfo) const { string sInfo ; return ( GetInfo( nId, sKey, sInfo) && FromString( sInfo, vdInfo)) ; } //---------------------------------------------------------------------------- bool GeomDB::GetInfo( int nId, const string& sKey, STRVECTOR& vsInfo) const { string sInfo ; return ( GetInfo( nId, sKey, sInfo) && FromString( sInfo, vsInfo)) ; } //---------------------------------------------------------------------------- bool GeomDB::ExistsInfo( int nId, const string& sKey) const { // recupero l'oggetto const GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // verifico l'esistenza dell'Info return pGdbObj->ExistsInfo( sKey) ; } //---------------------------------------------------------------------------- bool GeomDB::RemoveInfo( int nId, const string& sKey) { // recupero l'oggetto GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // rimuovo l'Info return pGdbObj->RemoveInfo( sKey) ; } //---------------------------------------------------------------------------- bool GeomDB::GetAllInfo( int nId, STRVECTOR& vsInfo) const { // recupero l'oggetto const GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // recupero tutte le Info return pGdbObj->GetAllInfo( vsInfo) ; } //---------------------------------------------------------------------------- bool GeomDB::CopyAllInfoFrom( int nId, int nSouId) { // recupero l'oggetto destinazione GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // recupero l'oggetto sorgente const GdbObj* pGdbObjSou = GetGdbObj( nSouId) ; if ( pGdbObjSou == nullptr) return false ; // copio tutte le Info if ( pGdbObj != pGdbObjSou && pGdbObjSou->m_pAttribs != nullptr) { pGdbObj->GetSafeAttribs() ; return ( pGdbObj->m_pAttribs != nullptr && pGdbObj->m_pAttribs->CopyAllInfoFrom( *(pGdbObjSou->m_pAttribs))) ; } else return true ; } //---------------------------------------------------------------------------- // Stipple (significativo solo per curve) //---------------------------------------------------------------------------- bool GeomDB::DumpStipple( int nId, string& sOut, bool bMM, const char* szNewLine) const { // recupero l'oggetto const GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // eseguo il dump if ( pGdbObj->m_nStpFactor != 0) { // nome della texture sOut += "Stipple=" ; sOut += ToString( pGdbObj->m_nStpFactor) ; sOut += "-" + ToString( pGdbObj->m_nStpPattern, 1, 16) ; sOut += szNewLine ; } return true ; } //---------------------------------------------------------------------------- bool GeomDB::SetStipple( int nId, int nFactor, int nPattern) { // recupero l'oggetto GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // imposto lo stipple return pGdbObj->SetStipple( nFactor, nPattern) ; } //---------------------------------------------------------------------------- bool GeomDB::GetStipple( int nId, int& nFactor, int& nPattern) const { // recupero l'oggetto const GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // recupero lo stipple return pGdbObj->GetStipple( nFactor, nPattern) ; } //---------------------------------------------------------------------------- // TextureData //---------------------------------------------------------------------------- bool GeomDB::DumpTextureData( int nId, string& sOut, bool bMM, const char* szNewLine) const { // recupero l'oggetto const GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // eseguo il dump if ( pGdbObj->m_pTxrData != nullptr) return pGdbObj->m_pTxrData->Dump( *this, sOut, bMM, szNewLine) ; else return true ; } //---------------------------------------------------------------------------- bool GeomDB::SetTextureName( int nId, const string& sTxrName) { // recupero l'oggetto GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // imposto il nome della texture return pGdbObj->SetTextureName( sTxrName) ; } //---------------------------------------------------------------------------- bool GeomDB::SetTextureFrame( int nId, const Frame3d& frTxrRef) { // recupero l'oggetto GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // imposto il nome della texture return pGdbObj->SetTextureFrame( frTxrRef) ; } //---------------------------------------------------------------------------- bool GeomDB::RemoveTextureData( int nId) { // recupero l'oggetto GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // rimuovo i dati della texture return pGdbObj->RemoveTextureData() ; } //---------------------------------------------------------------------------- bool GeomDB::GetTextureName( int nId, string& sTxrName) const { // recupero l'oggetto const GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // recupero il nome della texture return pGdbObj->GetTextureName( sTxrName) ; } //---------------------------------------------------------------------------- bool GeomDB::GetTextureFrame( int nId, Frame3d& frTxrRef) const { // recupero l'oggetto const GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // recupero il riferimento della texture return pGdbObj->GetTextureFrame( frTxrRef) ; } //---------------------------------------------------------------------------- // UserObj //---------------------------------------------------------------------------- bool GeomDB::SetUserObj( int nId, IUserObj* pUserObj) { // recupero l'oggetto GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // cancello eventuale precedente UserObj if ( pGdbObj->m_pUserObj != nullptr) delete pGdbObj->m_pUserObj ; // assegno if ( pUserObj != nullptr) pUserObj->SetOwner( nId, this) ; pGdbObj->m_pUserObj = pUserObj ; return true ; } //---------------------------------------------------------------------------- IUserObj* GeomDB::GetUserObj( int nId) { // recupero l'oggetto GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return nullptr ; // restituisco il puntatore a IUserObj return pGdbObj->m_pUserObj ; } //---------------------------------------------------------------------------- const IUserObj* GeomDB::GetUserObj( int nId) const { // recupero l'oggetto const GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return nullptr ; // restituisco il puntatore a IUserObj return pGdbObj->m_pUserObj ; } //---------------------------------------------------------------------------- bool GeomDB::DumpUserObj( int nId, string& sOut, bool bMM, const char* szNewLine) const { // recupero l'oggetto const GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // eseguo il dump if ( pGdbObj->m_pUserObj != nullptr) return pGdbObj->m_pUserObj->Dump( sOut, bMM, szNewLine) ; else return true ; } //---------------------------------------------------------------------------- bool GeomDB::CopyUserObj( int nIdSou, int nIdDest) { // verifico esistenza del sorgente GdbObj* pGdOSou = GetGdbObj( nIdSou) ; if ( pGdOSou == nullptr) return false ; // verifico esistenza della destinazione GdbObj* pGdODest = GetGdbObj( nIdDest) ; if ( pGdODest == nullptr) return false ; // eseguo la copia return pGdODest->CopyUserObjFrom( pGdOSou) ; } //---------------------------------------------------------------------------- bool GeomDB::RemoveUserObj( int nId) { // recupero l'oggetto GdbObj* pGdbObj = GetGdbObj( nId) ; if ( pGdbObj == nullptr) return false ; // cancello eventuale precedente UserObj if ( pGdbObj->m_pUserObj != nullptr) delete pGdbObj->m_pUserObj ; // reset puntatore a UserObj pGdbObj->m_pUserObj = nullptr ; return true ; } //---------------------------------------------------------------------------- // Material Library //---------------------------------------------------------------------------- int GeomDB::AddMaterial( const string& sName, const Material& matM) { return m_MatManager.AddMaterial( sName, matM) ; } //---------------------------------------------------------------------------- int GeomDB::FindMaterial( const string& sName) const { return m_MatManager.FindMaterial( sName) ; } //---------------------------------------------------------------------------- bool GeomDB::EraseMaterial( int nMat, bool& bInUse) { // verifico validità Id if ( nMat <= GDB_MT_NULL) { bInUse = false ; return false ; } // verifico esistenza materiale if ( ! m_MatManager.ExistsMaterial( nMat)) { bInUse = false ; return true ; } // verifico se usato da qualche oggetto if ( UsedMaterialInGroup( nMat, &m_GrpRadix)) { bInUse = true ; return false ; } // elimino il materiale bInUse = false ; return m_MatManager.EraseMaterial( nMat) ; } //---------------------------------------------------------------------------- bool GeomDB::GetMaterialData( int nMat, Material& matM) const { return m_MatManager.GetMaterialData( nMat, matM) ; } //---------------------------------------------------------------------------- bool GeomDB::GetMaterialName( int nMat, string& sName) const { return m_MatManager.GetMaterialName( nMat, sName) ; } //---------------------------------------------------------------------------- int GeomDB::GetMaxMaterialId( void) const { return m_MatManager.GetMaxMaterialId() ; } //---------------------------------------------------------------------------- bool GeomDB::ExistsMaterial( int nMat) const { return m_MatManager.ExistsMaterial( nMat) ; } //---------------------------------------------------------------------------- bool GeomDB::IsCustomMaterial( int nMat, bool& bCustom) const { return m_MatManager.IsCustomMaterial( nMat, bCustom) ; } //---------------------------------------------------------------------------- bool GeomDB::ModifyMaterialData( int nMat, const Material& matM) { if ( ! m_MatManager.ModifyMaterialData( nMat, matM)) return false ; // notifico gli oggetti che usano questo materiale (e gli aggiorno il colore) NotifyObjectsWithMaterialInGroup( nMat, matM.GetDiffuse(), false, &m_GrpRadix) ; return true ; } //---------------------------------------------------------------------------- bool GeomDB::ModifyMaterialName( int nMat, const string& sName) { return m_MatManager.ModifyMaterialName( nMat, sName) ; }