3908e11d18
- modifiche per permettere Mark di tipo 2.
384 lines
11 KiB
C++
384 lines
11 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2014-2014
|
|
//----------------------------------------------------------------------------
|
|
// File : Attribs.cpp Data : 05.03.14 Versione : 1.5c1
|
|
// Contenuto : Implementazione della classe Attribs.
|
|
//
|
|
//
|
|
//
|
|
// Modifiche : 05.03.14 DS Creazione modulo.
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "stdafx.h"
|
|
#include "Attribs.h"
|
|
#include "NgeWriter.h"
|
|
#include "NgeReader.h"
|
|
#include "GeomDB.h"
|
|
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
|
#include "/EgtDev/Include/EGnStringKeyVal.h"
|
|
|
|
using namespace std ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
static const string NAME = "N" ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Attribs::Dump( const GeomDB& GDB, string& sOut, bool bMM, const char* szNewLine) const
|
|
{
|
|
// livello
|
|
sOut += "Lev=" ;
|
|
switch ( m_Data[LEVEL]) {
|
|
default : /* GDB_LV_USER */ sOut += "user" ; break ;
|
|
case GDB_LV_SYSTEM : sOut += "system" ; break ;
|
|
case GDB_LV_TEMP : sOut += "temp" ; break ;
|
|
}
|
|
// modo
|
|
sOut += " Mod=" ;
|
|
switch ( m_Data[MODE]) {
|
|
default : /* GDB_MD_STD */ sOut += "std" ; break ;
|
|
case GDB_MD_LOCKED : sOut += "locked" ; break ;
|
|
case GDB_MD_HIDDEN : sOut += "hidden" ; break ;
|
|
}
|
|
// stato
|
|
sOut += " Sta=" ;
|
|
switch ( m_Data[STATUS]) {
|
|
case GDB_ST_OFF : sOut += "off" ; break ;
|
|
default : /* GDB_ST_ON */ sOut += "on" ; break ;
|
|
case GDB_ST_SEL : sOut += "sel" ; break ;
|
|
}
|
|
sOut += szNewLine ;
|
|
// materiale
|
|
sOut += "Mat=" ;
|
|
switch ( m_Material) {
|
|
case GDB_MT_COLOR : sOut += "color" ; break ;
|
|
case GDB_MT_PARENT : sOut += "by parent" ; break ;
|
|
}
|
|
// eventuale colore
|
|
if ( m_Material == GDB_MT_COLOR) {
|
|
sOut += " Col=" ;
|
|
string sColName ;
|
|
if ( GetNameOfStdColor( m_Color, sColName))
|
|
sOut += sColName ;
|
|
sOut += "(" + ToString( m_Color.GetIntRed()) ;
|
|
sOut += "," + ToString( m_Color.GetIntGreen()) ;
|
|
sOut += "," + ToString( m_Color.GetIntBlue()) ;
|
|
if ( m_Color.GetIntAlpha() != 100)
|
|
sOut += "," + ToString( m_Color.GetIntAlpha()) ;
|
|
sOut += ")" ;
|
|
}
|
|
// eventuale materiale
|
|
else if ( m_Material > GDB_MT_PARENT) {
|
|
string sMatName ;
|
|
if ( GDB.GetMaterialName( m_Material, sMatName))
|
|
sOut += " " + sMatName ;
|
|
else
|
|
sOut += " ??" ;
|
|
sOut += " (" + ToString( m_Material) + ")" ;
|
|
}
|
|
sOut += szNewLine ;
|
|
// eventuali nome e stringhe informative
|
|
for ( auto iIter = m_slInfo.cbegin() ; iIter != m_slInfo.cend() ; ++ iIter)
|
|
sOut += *iIter + szNewLine ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Attribs::Save( NgeWriter& ngeOut) const
|
|
{
|
|
// flag presenza attributi
|
|
if ( ! ngeOut.WriteKey( NGE_A))
|
|
return false ;
|
|
// livello
|
|
if ( ! ngeOut.WriteUchar( m_Data[LEVEL], ","))
|
|
return false ;
|
|
// modo
|
|
if ( ! ngeOut.WriteUchar( m_Data[MODE], ","))
|
|
return false ;
|
|
// stato (se SEL è convertito in ON)
|
|
int nStat = (( m_Data[STATUS] > GDB_ST_ON) ? GDB_ST_ON : m_Data[STATUS]) ;
|
|
if ( ! ngeOut.WriteUchar( nStat, ","))
|
|
return false ;
|
|
// marcatura (sempre OFF)
|
|
if ( ! ngeOut.WriteUchar( GDB_MK_OFF, ";"))
|
|
return false ;
|
|
// materiale
|
|
if ( ! ngeOut.WriteInt( m_Material, ";"))
|
|
return false ;
|
|
// colore
|
|
if ( ! ngeOut.WriteCol( m_Color, ";"))
|
|
return false ;
|
|
// numero di stringhe di info (nelle linee successive)
|
|
if ( ! ngeOut.WriteInt( int( m_slInfo.size()), ";", true))
|
|
return false ;
|
|
// stringhe di info
|
|
for ( auto iIter = m_slInfo.cbegin() ; iIter != m_slInfo.cend() ; ++ iIter) {
|
|
if ( ! ngeOut.WriteString( *iIter, nullptr, true))
|
|
return false ;
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Attribs::Load( NgeReader& ngeIn)
|
|
{
|
|
// livello
|
|
unsigned char ucLev ;
|
|
if ( ! ngeIn.ReadUchar( ucLev, ","))
|
|
return false ;
|
|
m_Data[LEVEL] = Clamp( ucLev, GDB_LV_USER, GDB_LV_TEMP) ;
|
|
// modo
|
|
unsigned char ucMode ;
|
|
if ( ! ngeIn.ReadUchar( ucMode, ","))
|
|
return false ;
|
|
m_Data[MODE] = Clamp( ucMode, GDB_MD_STD, GDB_MD_HIDDEN) ;
|
|
// stato (se SEL è convertito in ON)
|
|
unsigned char ucStat ;
|
|
if ( ! ngeIn.ReadUchar( ucStat, ","))
|
|
return false ;
|
|
m_Data[STATUS] = Clamp( ucStat, GDB_ST_OFF, GDB_ST_ON) ;
|
|
// marcatura (sempre OFF)
|
|
unsigned char ucMark ;
|
|
if ( ! ngeIn.ReadUchar( ucMark, ";"))
|
|
return false ;
|
|
m_Data[MARK] = Clamp( ucMark, GDB_MK_OFF, GDB_MK_OFF) ;
|
|
// materiale
|
|
if ( ! ngeIn.ReadInt( m_Material, ";"))
|
|
return false ;
|
|
// colore
|
|
if ( ! ngeIn.ReadCol( m_Color, ";"))
|
|
return false ;
|
|
// numero di stringhe di info (nelle linee successive)
|
|
int nNext ;
|
|
if ( ! ngeIn.ReadInt( nNext, ";", true))
|
|
return false ;
|
|
// leggo le eventuali stringhe
|
|
string sLine ;
|
|
for ( int i = 0 ; i < nNext ; ++i) {
|
|
// leggo la linea
|
|
if ( ! ngeIn.ReadString( sLine, nullptr, true))
|
|
return false ;
|
|
// la carico in lista
|
|
m_slInfo.push_back( sLine) ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Attribs::DataFromString( const string& sParam)
|
|
{
|
|
// il primo parametro è diviso in 4 parti
|
|
STRVECTOR vsParams ;
|
|
Tokenize( sParam, ",", vsParams) ;
|
|
// 4 parti
|
|
if ( vsParams.size() != 4)
|
|
return false ;
|
|
// livello
|
|
int nLev ;
|
|
if ( ! FromString( vsParams[0], nLev))
|
|
return false ;
|
|
m_Data[LEVEL] = Clamp( nLev, GDB_LV_USER, GDB_LV_TEMP) ;
|
|
// modo
|
|
int nMode ;
|
|
if ( ! FromString( vsParams[1], nMode))
|
|
return false ;
|
|
m_Data[MODE] = Clamp( nMode, GDB_MD_STD, GDB_MD_HIDDEN) ;
|
|
// stato (ammessi solo OFF e ON)
|
|
int nStat ;
|
|
if ( ! FromString( vsParams[2], nStat))
|
|
return false ;
|
|
m_Data[STATUS] = Clamp( nStat, GDB_ST_OFF, GDB_ST_ON) ;
|
|
// marcatura (ammesso solo OFF)
|
|
int nMark ;
|
|
if ( ! FromString( vsParams[3], nMark))
|
|
return false ;
|
|
m_Data[MARK] = Clamp( nMark, GDB_MK_OFF, GDB_MK_OFF) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Attribs::SetName( const string& sName)
|
|
{
|
|
// se nome non valido, esco con errore
|
|
if ( sName.empty() || ! IsValidVal( sName))
|
|
return false ;
|
|
|
|
// può essere solo la prima stringa
|
|
auto iIter = m_slInfo.begin() ;
|
|
if ( iIter != m_slInfo.end() && FindKey( *iIter, NAME)) {
|
|
*iIter = NAME + EQUAL + sName ;
|
|
return true ;
|
|
}
|
|
|
|
// altrimenti devo inserire la stringa prima dell'inizio
|
|
try {
|
|
m_slInfo.push_front( NAME + EQUAL + sName) ;
|
|
}
|
|
catch(...) {
|
|
return false ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Attribs::GetName( string& sName) const
|
|
{
|
|
// può essere solo la prima stringa
|
|
const auto iIter = m_slInfo.cbegin() ;
|
|
if ( iIter != m_slInfo.cend() && FindKey( *iIter, NAME)) {
|
|
sName = iIter->substr( NAME.length() + 1) ;
|
|
return true ;
|
|
}
|
|
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Attribs::ExistsName( void) const
|
|
{
|
|
// può essere solo la prima stringa
|
|
const auto iIter = m_slInfo.cbegin() ;
|
|
return ( iIter != m_slInfo.cend() && FindKey( *iIter, NAME)) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Attribs::RemoveName( void)
|
|
{
|
|
// può essere solo la prima stringa
|
|
const auto iIter = m_slInfo.cbegin() ;
|
|
if ( iIter != m_slInfo.cend() && FindKey( *iIter, NAME)) {
|
|
m_slInfo.pop_front() ;
|
|
return true ;
|
|
}
|
|
|
|
// non trovato, il nome non richiede rimozione
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Attribs::SetInfo( const string& sKey, const string& sVal)
|
|
{
|
|
// se chiave o valore non validi, esco con errore
|
|
if ( ! IsValidKey( sKey) || sVal.empty() || ! IsValidVal( sVal))
|
|
return false ;
|
|
|
|
// se è il nome
|
|
if ( sKey == NAME)
|
|
return SetName( sVal) ;
|
|
|
|
// se esiste già una stringa con quella chiave la sostituisco
|
|
for ( auto iIter = m_slInfo.begin() ; iIter != m_slInfo.end() ; ++ iIter) {
|
|
if ( FindKey( *iIter, sKey)) {
|
|
*iIter = sKey + EQUAL + sVal ;
|
|
return true ;
|
|
}
|
|
}
|
|
// altrimenti la appendo
|
|
try {
|
|
m_slInfo.push_back( sKey + EQUAL + sVal) ;
|
|
}
|
|
catch(...) {
|
|
return false ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Attribs::GetInfo( const string& sKey, string& sVal) const
|
|
{
|
|
// se chiave non valida, esco con errore
|
|
if ( ! IsValidKey( sKey))
|
|
return false ;
|
|
// cerco una stringa con la chiave
|
|
for ( auto iIter = m_slInfo.cbegin() ; iIter != m_slInfo.cend() ; ++ iIter) {
|
|
if ( FindKey( *iIter, sKey)) {
|
|
sVal = iIter->substr( sKey.length() + 1) ;
|
|
return true ;
|
|
}
|
|
}
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Attribs::ExistsInfo( const string& sKey) const
|
|
{
|
|
// se chiave non valida, esco con errore
|
|
if ( ! IsValidKey( sKey))
|
|
return false ;
|
|
// cerco una stringa con la chiave
|
|
for ( auto iIter = m_slInfo.cbegin() ; iIter != m_slInfo.cend() ; ++ iIter) {
|
|
if ( FindKey( *iIter, sKey))
|
|
return true ;
|
|
}
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Attribs::RemoveInfo( const string& sKey)
|
|
{
|
|
// se chiave non valida, esco con errore
|
|
if ( ! IsValidKey( sKey))
|
|
return false ;
|
|
// cerco una stringa con la chiave
|
|
for ( auto iIter = m_slInfo.cbegin() ; iIter != m_slInfo.cend() ; ++ iIter) {
|
|
if ( FindKey( *iIter, sKey)) {
|
|
m_slInfo.erase( iIter) ;
|
|
return true ;
|
|
}
|
|
}
|
|
// non trovata, la info non richiede rimozione
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Attribs::GetAllInfo( STRVECTOR& vsInfo) const
|
|
{
|
|
// riservo spazio opportuno per il vettore delle stringhe
|
|
vsInfo.clear() ;
|
|
|
|
// se non ci sono info esco
|
|
if ( m_slInfo.empty())
|
|
return true ;
|
|
|
|
vsInfo.reserve( m_slInfo.size()) ;
|
|
// recupero tutte le info tranne il nome (se presente sempre al primo posto)
|
|
auto iIter = m_slInfo.cbegin() ;
|
|
if ( FindKey( *iIter, NAME))
|
|
++ iIter ;
|
|
for ( ; iIter != m_slInfo.cend() ; ++ iIter)
|
|
vsInfo.emplace_back( *iIter) ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Attribs::CopyAllInfoFrom( const Attribs& attrSou)
|
|
{
|
|
// eseguo copia di tutte le info tranne il nome
|
|
for ( auto iIter = attrSou.m_slInfo.cbegin() ; iIter != attrSou.m_slInfo.cend() ; ++ iIter) {
|
|
string sKey, sVal ;
|
|
SplitFirst( *iIter, string( "") + EQUAL, sKey, sVal) ;
|
|
if ( sKey != NAME)
|
|
SetInfo( sKey, sVal) ;
|
|
}
|
|
return true ;
|
|
}
|