541 lines
13 KiB
C++
541 lines
13 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2013-2013
|
|
//----------------------------------------------------------------------------
|
|
// File : GeomDB.cpp Data : 08.04.13 Versione : 1.3a5
|
|
// Contenuto : Implementazione della classe GeomDB.
|
|
//
|
|
//
|
|
//
|
|
// Modifiche : 22.01.13 DS Creazione modulo.
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "stdafx.h"
|
|
#include "GeomDB.h"
|
|
#include "GdbObj.h"
|
|
#include "/EgtDev/Include/EgnStringUtils.h"
|
|
#include "/EgtDev/Include/EgnStringConverter.h"
|
|
#include "/EgtDev/Include/EgtPointerOwner.h"
|
|
#include <new>
|
|
|
|
using namespace std ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
IGeomDB*
|
|
CreateGeomDB( void)
|
|
{
|
|
return static_cast<IGeomDB*> ( new(nothrow) GeomDB) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// GeomDB
|
|
//----------------------------------------------------------------------------
|
|
GeomDB::GeomDB( void)
|
|
{
|
|
m_GrpRadix.m_nId = GDB_ID_ROOT ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
GeomDB::~GeomDB( void)
|
|
{
|
|
Clear() ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GeomDB::Init( ILogger* pLogger)
|
|
{
|
|
m_pLogger = pLogger ;
|
|
|
|
// imposto numero minimo buckets del map degli Id
|
|
m_IdManager.Init( 1024) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GeomDB::ReInit( void)
|
|
{
|
|
|
|
// imposto numero minimo buckets del map degli Id
|
|
m_IdManager.Init( 1024) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GeomDB::Clear( void)
|
|
{
|
|
// elimino mappa degli identificatori
|
|
m_IdManager.Clear() ;
|
|
|
|
// disalloco i gruppi e gli oggetti
|
|
m_GrpRadix.Clear() ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GeomDB::Load( const std::string& sFileIn)
|
|
{
|
|
bool bOk ;
|
|
bool bEnd ;
|
|
Scanner TheScanner ;
|
|
|
|
|
|
// inizializzo lo scanner
|
|
if ( ! TheScanner.Init( sFileIn)) {
|
|
LOG_ERROR( m_pLogger, "GeomDbLoad : Error on Init ") ;
|
|
return false ;
|
|
}
|
|
|
|
// leggo l'intestazione
|
|
if ( ! LoadStart( TheScanner)) {
|
|
string sOut = "GeomDbLoad : Error on line " + ToString( TheScanner.GetCurrLineNbr()) ;
|
|
LOG_ERROR( m_pLogger, sOut.c_str()) ;
|
|
return false ;
|
|
}
|
|
|
|
// ciclo di lettura dei nodi
|
|
bOk = true ;
|
|
do {
|
|
if ( ! LoadOneNode( TheScanner, bEnd)) {
|
|
bOk = false ;
|
|
string sOut = "GeomDbLoad : Error on line " + ToString( TheScanner.GetCurrLineNbr()) ;
|
|
LOG_ERROR( m_pLogger, sOut.c_str()) ;
|
|
}
|
|
} while ( ! bEnd) ;
|
|
|
|
return bOk ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GeomDB::LoadStart( Scanner& TheScanner)
|
|
{
|
|
string sLine ;
|
|
|
|
|
|
// recupero la prima linea
|
|
if ( ! TheScanner.GetLine( sLine))
|
|
return false ;
|
|
|
|
// deve essere l'intestazione
|
|
if ( sLine != "START")
|
|
return false ;
|
|
|
|
// recupero la riga successiva
|
|
if ( ! TheScanner.GetLine( sLine))
|
|
return false ;
|
|
|
|
// leggo i parametri
|
|
// TODO
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GeomDB::LoadOneNode( Scanner& TheScanner, bool& bEnd)
|
|
{
|
|
int nParentId ;
|
|
string sType ;
|
|
GdbNode* pGdbNode ;
|
|
|
|
|
|
// in generale non è fine file
|
|
bEnd = false ;
|
|
|
|
// leggo la prossima linea : tipo di nodo
|
|
if ( ! TheScanner.GetLine( sType))
|
|
return false ;
|
|
|
|
// se fine dati
|
|
if ( sType == "END") {
|
|
bEnd = true ;
|
|
return true ;
|
|
}
|
|
// se gruppo
|
|
else if ( sType == GdbGroup::GetKey()) {
|
|
pGdbNode = new( nothrow) GdbGroup ;
|
|
}
|
|
// se copia TODO ("X_CPY")..
|
|
//else if ( sType == GdbCopy::GetKey) {
|
|
// pGdbNode = new( nothrow) GdbCopy ;
|
|
//}
|
|
// altrimenti oggetto geometrico
|
|
else
|
|
pGdbNode = new( nothrow) GdbObj ;
|
|
|
|
// verifico il nodo GDB
|
|
if ( pGdbNode == nullptr)
|
|
return false ;
|
|
|
|
// se lettura dati e inserimento nel DB vanno bene
|
|
if ( pGdbNode->Load( sType, TheScanner, nParentId) &&
|
|
AddToGeomDB( pGdbNode, nParentId))
|
|
return true ;
|
|
// altrimenti errore
|
|
else {
|
|
delete pGdbNode ;
|
|
return false ;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GeomDB::Save( const std::string& sFileOut) const
|
|
{
|
|
ofstream ofSave ;
|
|
|
|
|
|
// apertura file
|
|
ofSave.open( stringtoW( sFileOut)) ;
|
|
if ( ! ofSave.good())
|
|
return false ;
|
|
|
|
// intestazione
|
|
ofSave << "START" << endl ;
|
|
ofSave << "GeomDB,1.4a4" << endl ;
|
|
// ciclo di scrittura degli oggetti
|
|
bool bOk = true ;
|
|
const GdbNode* pGdbNode = m_GrpRadix.GetFirstNode() ;
|
|
while ( pGdbNode != nullptr) {
|
|
// oggetto geometrico
|
|
if ( ! pGdbNode->Save( ofSave))
|
|
bOk = false ;
|
|
pGdbNode = pGdbNode->GetNext() ;
|
|
}
|
|
ofSave << "END" << endl ;
|
|
|
|
// chiusura file
|
|
ofSave.close() ;
|
|
|
|
return bOk ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GeomDB::ExistsNode( int nId) const
|
|
{
|
|
return ( (const_cast<GeomDB*>(this))->GetGdbNode(nId) != nullptr) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
GdbNode*
|
|
GeomDB::GetGdbNode( 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.FindNode( nId) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GeomDB::AddToGeomDB( GdbNode* pGNode, int nParentId)
|
|
{
|
|
// verifico validità oggetto puntato
|
|
if ( pGNode == nullptr)
|
|
return false ;
|
|
|
|
// verifica validità e unicità del nome
|
|
if ( pGNode->m_nId <= GDB_ID_ROOT || ExistsNode( pGNode->m_nId))
|
|
return false ;
|
|
|
|
// cerco il padre
|
|
GdbGroup* pGroup = GetGdbGroup( nParentId) ;
|
|
if ( pGroup == nullptr)
|
|
return false ;
|
|
// inserisco in coda alla lista del padre
|
|
if ( ! pGNode->AddTail( pGroup))
|
|
return false ;
|
|
|
|
// aggiorno gestore Id
|
|
m_IdManager.UpdateMaxId( pGNode->m_nId) ;
|
|
|
|
// inserisco in mappa nomi
|
|
return m_IdManager.AddNode( pGNode->m_nId, pGNode) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
GeomDB::AddGroup( int nId, int nParentId, const Frame3d& frFrame)
|
|
{
|
|
GdbGroup* pGdbGroup ;
|
|
|
|
|
|
// verifico validità ParentId
|
|
if ( nParentId < GDB_ID_ROOT)
|
|
return GDB_ID_NULL ;
|
|
// verifico validità Id
|
|
if ( nId <= GDB_ID_ROOT)
|
|
nId = m_IdManager.GetNewId() ;
|
|
if ( ExistsNode( nId))
|
|
return GDB_ID_NULL ;
|
|
// alloco gruppo Gdb
|
|
pGdbGroup = new(nothrow) GdbGroup ;
|
|
if ( pGdbGroup == nullptr)
|
|
return GDB_ID_NULL ;
|
|
// assegno identificativo
|
|
pGdbGroup->m_nId = nId ;
|
|
// assegno riferimento
|
|
pGdbGroup->m_gfrFrame.m_frF = frFrame ;
|
|
// inserisco nel DB
|
|
if ( ! AddToGeomDB( pGdbGroup, nParentId)) {
|
|
delete pGdbGroup ;
|
|
return GDB_ID_NULL ;
|
|
}
|
|
|
|
return nId ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
GeomDB::AddGeoObj( int nId, int nParentId, IGeoObj* pGeoObj)
|
|
{
|
|
GdbObj* pGdbObj ;
|
|
|
|
|
|
// assegno GeoObj a gestore puntatore con rilascio automatico
|
|
PtrOwner<IGeoObj> pRPGeoObj( pGeoObj) ;
|
|
// verifico validità identificativo
|
|
if ( nId <= GDB_ID_ROOT)
|
|
nId = m_IdManager.GetNewId() ;
|
|
if ( ExistsNode( nId))
|
|
return GDB_ID_NULL ;
|
|
// verifico validità oggetto Geo
|
|
if ( ! IsValid( pRPGeoObj) || ! pRPGeoObj->IsValid())
|
|
return GDB_ID_NULL ;
|
|
// alloco oggetto Gdb
|
|
pGdbObj = new(nothrow) GdbObj ;
|
|
if ( pGdbObj == nullptr)
|
|
return GDB_ID_NULL ;
|
|
// assegno identificativo
|
|
pGdbObj->m_nId = nId ;
|
|
// assegno dati
|
|
pGdbObj->m_pGeoObj = Release( pRPGeoObj) ;
|
|
// inserisco nel DB
|
|
if ( ! AddToGeomDB( pGdbObj, nParentId)) {
|
|
delete pGdbObj ;
|
|
return GDB_ID_NULL ;
|
|
}
|
|
|
|
return nId ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
GdbType
|
|
GeomDB::GetGdbType( int nId) const
|
|
{
|
|
const GdbNode* pGdbNode ;
|
|
|
|
|
|
// recupero il nodo
|
|
if ( ( pGdbNode = (const_cast<GeomDB*> (this))->GetGdbNode( nId)) == nullptr)
|
|
return GDB_NONE ;
|
|
|
|
// se oggetto geometrico
|
|
if ( ::GetGdbObj( pGdbNode) != nullptr)
|
|
return GDB_GEO ;
|
|
// se gruppo
|
|
else if ( ::GetGdbGroup( pGdbNode) != nullptr)
|
|
return GDB_GROUP ;
|
|
// altro
|
|
else
|
|
return GDB_NONE ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
IGeoObj*
|
|
GeomDB::GetGeoObj( int nId)
|
|
{
|
|
const GdbObj* pGdbObj ;
|
|
|
|
|
|
// recupero l'oggetto Gdb
|
|
if ( ( pGdbObj = GetGdbObj( nId)) == nullptr)
|
|
return nullptr ;
|
|
|
|
// restituisco il suo contenuto geometrico
|
|
return pGdbObj->m_pGeoObj ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
Frame3d*
|
|
GeomDB::GetGroupFrame( int nId)
|
|
{
|
|
GdbGroup* pGdbGroup ;
|
|
|
|
|
|
// recupero il gruppo Gdb
|
|
if ( ( pGdbGroup = GetGdbGroup( nId)) == nullptr)
|
|
return nullptr ;
|
|
|
|
// restituisco il suo riferimento
|
|
return &(pGdbGroup->m_gfrFrame.m_frF) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GeomDB::GetGroupGlobFrame( int nId, Frame3d& frGlob)
|
|
{
|
|
GdbGroup* pGdbGroup ;
|
|
|
|
|
|
// recupero il gruppo Gdb
|
|
if ( ( pGdbGroup = GetGdbGroup( nId)) == nullptr)
|
|
return false ;
|
|
|
|
// ne faccio calcolare il riferimento globale
|
|
return pGdbGroup->GetGlobFrame( frGlob) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
GeomDB::GetParentId( int nId)
|
|
{
|
|
GdbNode* pGdbNode ;
|
|
|
|
|
|
// recupero il nodo Gdb
|
|
if ( ( pGdbNode = GetGdbNode( nId)) == nullptr)
|
|
return GDB_ID_NULL ;
|
|
|
|
// restituisco l'Id del padre
|
|
return pGdbNode->GetParentId() ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
GeomDB::Copy( int nIdSou, int nIdDest, int nParentIdDest)
|
|
{
|
|
GdbNode* pGdNSou ;
|
|
GdbNode* pGdNDest ;
|
|
|
|
|
|
// verifico Id destinazione
|
|
if ( nIdDest <= GDB_ID_ROOT)
|
|
nIdDest = m_IdManager.GetNewId() ;
|
|
if ( ExistsNode( nIdDest))
|
|
return GDB_ID_NULL ;
|
|
|
|
// verifico esistenza del sorgente
|
|
if ( ( pGdNSou = GetGdbNode( nIdSou)) == nullptr)
|
|
return GDB_ID_NULL ;
|
|
|
|
// eseguo la copia
|
|
if ( ( pGdNDest = pGdNSou->Clone( nIdDest, m_IdManager)) == nullptr)
|
|
return GDB_ID_NULL ;
|
|
|
|
// inserisco nel DB
|
|
if ( ! AddToGeomDB( pGdNDest, nParentIdDest)) {
|
|
delete pGdNDest ;
|
|
return GDB_ID_NULL ;
|
|
}
|
|
|
|
return nIdDest ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GeomDB::Erase( int nId)
|
|
{
|
|
INTPGDBN_UMAP::const_iterator Iter ;
|
|
GdbNode* pGdbNode ;
|
|
|
|
|
|
// non si può cancellare il gruppo radice (escludo anche Id non validi)
|
|
if ( nId <= GDB_ID_ROOT)
|
|
return false ;
|
|
|
|
// recupero l'oggetto
|
|
pGdbNode = m_IdManager.FindNode( nId) ;
|
|
if ( pGdbNode == nullptr)
|
|
return false ;
|
|
|
|
// elimino da mappa dei nomi
|
|
m_IdManager.RemoveNode( nId) ;
|
|
|
|
// lo tolgo dalla lista
|
|
pGdbNode->Remove() ;
|
|
|
|
// lo disalloco (distruttore virtuale)
|
|
delete pGdbNode ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GeomDB::Translate( int nId, const Vector3d& vtMove)
|
|
{
|
|
GdbNode* pGdbNode ;
|
|
|
|
|
|
// recupero l'oggetto
|
|
if ( ( pGdbNode = GetGdbNode( nId)) == nullptr)
|
|
return false ;
|
|
|
|
// eseguo la traslazione
|
|
return pGdbNode->Translate( vtMove) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GeomDB::Rotate( int nId, const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, double dSinAng)
|
|
{
|
|
GdbNode* pGdbNode ;
|
|
|
|
|
|
// recupero l'oggetto
|
|
if ( ( pGdbNode = GetGdbNode( nId)) == nullptr)
|
|
return false ;
|
|
|
|
// eseguo la rotazione
|
|
return pGdbNode->Rotate( ptAx, vtAx, dCosAng, dSinAng) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GeomDB::Scale( int nId, const Point3d& ptCen, double dCoeffX, double dCoeffY, double dCoeffZ)
|
|
{
|
|
GdbNode* pGdbNode ;
|
|
|
|
|
|
// recupero l'oggetto
|
|
if ( ( pGdbNode = GetGdbNode( nId)) == nullptr)
|
|
return false ;
|
|
|
|
// eseguo la scalatura
|
|
return pGdbNode->Scale( ptCen, dCoeffX, dCoeffY, dCoeffZ) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GeomDB::Mirror( int nId, const Point3d& ptOn, const Vector3d& vtNorm)
|
|
{
|
|
GdbObj* pGdbObj ;
|
|
|
|
|
|
// recupero l'oggetto
|
|
if ( ( pGdbObj = GetGdbObj( nId)) == nullptr)
|
|
return false ;
|
|
|
|
// eseguo l'operazione
|
|
if ( pGdbObj->m_pGeoObj != nullptr)
|
|
return pGdbObj->m_pGeoObj->Mirror( ptOn, vtNorm) ;
|
|
else
|
|
return false ;
|
|
}
|