//---------------------------------------------------------------------------- // EgalTech 2014-2017 //---------------------------------------------------------------------------- // File : GdbMaterialMgr.cpp Data : 02.03.17 Versione : 1.8c1 // Contenuto : Implementazione classe gestore materiali in GeomDB. // // // // Modifiche : 24.04.14 DS Creazione modulo. // 02.03.17 DS Cambiato controllo nome, ora meno restrittivo. // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "GdbMaterialMgr.h" #include "NgeWriter.h" #include "NgeReader.h" #include "/EgtDev/Include/EGnStringKeyVal.h" using namespace std ; //---------------------------------------------------------------------------- static const string RESERVED_NAME = "$$" ; //---------------------------------------------------------------------------- GdbMaterialMgr::GdbMaterialMgr( void) { // riservo spazio per 48 materiali m_GdbMats.reserve( 48) ; // inserisco i materiali standard string sName ; Material matM ; for ( int i = 0 ; GetStdMaterial( i, sName, matM) ; ++ i) AddMaterial( sName, matM) ; // salvo il numero dei materiali standard m_nStdNum = int( m_GdbMats.size()) ; } //---------------------------------------------------------------------------- bool GdbMaterialMgr::Clear( void) { // cancello i materiali custom if ( int( m_GdbMats.size()) > m_nStdNum) m_GdbMats.resize( m_nStdNum) ; return true ; } //---------------------------------------------------------------------------- bool GdbMaterialMgr::Save( NgeWriter& ngeOut) const { // intestazione libreria if ( ! ngeOut.WriteKey( NGE_MAT_LIB)) return false ; // numero di materiali custom int nCustNum = int( m_GdbMats.size()) - m_nStdNum ; if ( ! ngeOut.WriteInt( nCustNum, ";", true)) return false ; // scrittura dei materiali custom for ( int i = m_nStdNum ; i < int( m_GdbMats.size()) ; ++ i) { // Nome, Id, Tipo (1=materiale senza texture) string sMatName = ( m_GdbMats[i].sName.empty() ? RESERVED_NAME : m_GdbMats[i].sName) ; if ( ! ngeOut.WriteString( sMatName, ",")) return false ; if ( ! ngeOut.WriteInt( i + 1, ",")) return false ; if ( ! ngeOut.WriteInt( 1, ";", true)) return false ; // dati del materiale if ( ! ngeOut.WriteCol( m_GdbMats[i].matM.GetAmbient(), ";")) return false ; if ( ! ngeOut.WriteCol( m_GdbMats[i].matM.GetDiffuse(), ";")) return false ; if ( ! ngeOut.WriteCol( m_GdbMats[i].matM.GetSpecular(), ";")) return false ; if ( ! ngeOut.WriteDouble( m_GdbMats[i].matM.GetShininess(), ";", true, 1)) return false ; } return true ; } //---------------------------------------------------------------------------- bool GdbMaterialMgr::Load( NgeReader& ngeIn, INTVECTOR& vBaseMatId) { // lettura eventuale intestazione libreria int nKey ; if ( ! ngeIn.ReadKey( nKey)) return false ; if ( nKey != NGE_MAT_LIB) { ngeIn.UngetKey() ; return true ; } // aggiorno indice rilocazione per materiali standard (1 based) vBaseMatId.resize( m_nStdNum + 1, 0) ; for ( int i = 0 ; i <= m_nStdNum ; ++ i) vBaseMatId[i] = i ; // lettura numero di materiali custom int nCustNum ; if ( ! ngeIn.ReadInt( nCustNum, ";", true)) return false ; // lettura dei materiali custom for ( int i = 0 ; i < nCustNum ; ++ i) { // Nome, Id, Tipo (1=materiale senza texture) string sMatName ; if ( ! ngeIn.ReadString( sMatName, ",")) return false ; int nInd ; if ( ! ngeIn.ReadInt( nInd, ",")) return false ; int nType ; if ( ! ngeIn.ReadInt( nType, ";", true)) return false ; // verifico correttezza indice if ( nInd != m_nStdNum + i + 1) return false ; // dati del materiale Color colAmb ; if ( ! ngeIn.ReadCol( colAmb, ";")) return false ; Color colDiff ; if ( ! ngeIn.ReadCol( colDiff, ";")) return false ; Color colSpec ; if ( ! ngeIn.ReadCol( colSpec, ";")) return false ; double dShin ; if ( ! ngeIn.ReadDouble( dShin, ";", true)) return false ; // inserisco il materiale, verificando non sia giā presente (escludo nome riservato) int nNew = (( sMatName != RESERVED_NAME) ? FindMaterial( sMatName) : GDB_MT_NULL) ; if ( nNew == GDB_MT_NULL) nNew = AddMaterial( sMatName, Material( colAmb, colDiff, colSpec, dShin), true) ; if ( nNew == GDB_MT_NULL) return false ; vBaseMatId.push_back( nNew) ; } // sistemazione dei materiali cancellati for ( int i = m_nStdNum ; i < int( m_GdbMats.size()) ; ++ i) { if ( m_GdbMats[i].sName == RESERVED_NAME) EraseMaterial( i + 1) ; } return true ; } //---------------------------------------------------------------------------- int GdbMaterialMgr::AddMaterial( const string& sName, const Material& matM, bool bLoad) { // verifico validitā nome if ( ! IsValidVal( sName) || ( ! bLoad && sName == RESERVED_NAME)) return GDB_MT_NULL ; // se il materiale giā esiste ritorno errore if ( sName != RESERVED_NAME && FindMaterial( sName) > 0) return GDB_MT_NULL ; // provo ad inserire al posto del primo cancellato int nId = FindFirstErased() ; if ( nId > GDB_MT_NULL) { m_GdbMats[nId-1].sName = sName ; m_GdbMats[nId-1].matM = matM ; return nId ; } // aggiungo il materiale nella collezione GdbMaterial gdbmatM ; gdbmatM.sName = sName ; gdbmatM.matM = matM ; try { m_GdbMats.push_back( gdbmatM) ; } catch (...) { return GDB_MT_NULL ; } return int( m_GdbMats.size()) ; } //---------------------------------------------------------------------------- int GdbMaterialMgr::FindFirstErased( void) const { for ( int i = 0 ; i < int( m_GdbMats.size()) ; ++ i) { if ( m_GdbMats[i].sName.empty()) return ( i + 1) ; } return GDB_MT_NULL ; } //---------------------------------------------------------------------------- bool GdbMaterialMgr::EraseMaterial( int nId) { // controllo indice ( 1 based) if ( nId <= GDB_MT_NULL || nId > int( m_GdbMats.size())) return false ; // se standard, non posso cancellarlo if ( nId <= m_nStdNum) return false ; // se giā cancellato, non devo fare alcunchč if ( m_GdbMats[nId-1].sName.empty()) return true ; // lo cancello m_GdbMats[nId-1].sName.clear() ; return true ; } //---------------------------------------------------------------------------- int GdbMaterialMgr::FindMaterial( const string& sName) const { // verifico validitā nome if ( ! IsValidVal( sName)) return GDB_MT_NULL ; // cerco nella collezione (confronto tra nomi in maiuscolo) string sToFind = sName ; ToUpper( sToFind) ; string sUpName ; for ( int i = 0 ; i < int( m_GdbMats.size()) ; ++ i) { sUpName = m_GdbMats[i].sName ; ToUpper( sUpName) ; if ( sToFind == sUpName) return ( i + 1) ; } return GDB_MT_NULL ; } //---------------------------------------------------------------------------- bool GdbMaterialMgr::GetMaterialData( int nId, Material& matM) const { if ( ! ExistsMaterial( nId)) return false ; // recupero i dati del materiale matM = m_GdbMats[nId-1].matM ; return true ; } //---------------------------------------------------------------------------- bool GdbMaterialMgr::GetMaterialName( int nId, string& sName) const { if ( ! ExistsMaterial( nId)) return false ; // recupero il nome del materiale sName = m_GdbMats[nId-1].sName ; return true ; } //---------------------------------------------------------------------------- bool GdbMaterialMgr::IsCustomMaterial( int nId, bool& bCustom) const { if ( ! ExistsMaterial( nId)) return false ; // recupero il tipo del materiale bCustom = ( nId > m_nStdNum) ; return true ; } //---------------------------------------------------------------------------- bool GdbMaterialMgr::ModifyMaterialData( int nId, const Material& matM) { if ( ! ExistsMaterial( nId)) return false ; // se standard, non č modificabile if ( nId <= m_nStdNum) return false ; // modifico i dati del materiale nella collezione m_GdbMats[nId-1].matM = matM ; return true ; } //---------------------------------------------------------------------------- bool GdbMaterialMgr::ModifyMaterialName( int nId, const string& sName) { if ( ! ExistsMaterial( nId)) return false ; // se standard, non č modificabile if ( nId <= m_nStdNum) return false ; // verifico validitā nome if ( ! IsValidVal( sName)) return false ; // modifico il nome del materiale nella collezione m_GdbMats[nId-1].sName = sName ; return true ; }