41a38fef3b
- aggiunta entità testo (con font Nfe e di sistema) - in tutte le rotate ora l'angolo è in gradi - aggiunta trasformazione Shear (scorrimento) - aggiunta trsformazione LocToLoc - Set/GetInfo specializzate per i diversi tipi di informazioni - Copy e Relocate con possibilità di indicare l'entità di riferimento rispetto a cui inserire - aggiunte trasformazioni a PolyLine.
422 lines
12 KiB
C++
422 lines
12 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2013-2013
|
|
//----------------------------------------------------------------------------
|
|
// File : GdbGroup.cpp Data : 28.11.13 Versione : 1.4a2
|
|
// Contenuto : Implementazione della classe GdbGroup.
|
|
//
|
|
//
|
|
//
|
|
// Modifiche : 28.11.13 DS Creazione modulo.
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "stdafx.h"
|
|
#include "GdbGroup.h"
|
|
#include "IdManager.h"
|
|
#include "NgeWriter.h"
|
|
#include "NgeReader.h"
|
|
#include "/EgtDev/Include/EGkGdbFunct.h"
|
|
#include "/EgtDev/Include/EGnStringUtils.h"
|
|
|
|
using namespace std ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
GdbGroup::GdbGroup( void)
|
|
: m_nObjCount( 0), m_pFirstObj( nullptr), m_pLastObj( nullptr)
|
|
{
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
GdbGroup::~GdbGroup( void)
|
|
{
|
|
// elimino i figli
|
|
Clear() ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GdbGroup::Clear( void)
|
|
{
|
|
// disalloco gli oggetti
|
|
GdbObj* pObj ;
|
|
pObj = GetFirstObj() ;
|
|
while ( pObj != nullptr) {
|
|
// lo rimuovo dalla lista
|
|
pObj->Remove() ;
|
|
// lo disalloco
|
|
delete pObj ;
|
|
// passo al nuovo primo
|
|
pObj = GetFirstObj() ;
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
GdbGroup*
|
|
GdbGroup::Clone( int nId, IdManager& IdMgr) const
|
|
{
|
|
// alloco gruppo Gdb
|
|
GdbGroup* pGdbGroup ;
|
|
pGdbGroup = new(nothrow) GdbGroup ;
|
|
if ( pGdbGroup == nullptr)
|
|
return nullptr ;
|
|
|
|
// copio dati oggetto Gdb
|
|
pGdbGroup->GdbObj::Copy( this) ;
|
|
|
|
// assegno nuovo Id
|
|
pGdbGroup->m_nId = nId ;
|
|
IdMgr.UpdateMaxId( nId) ;
|
|
|
|
// copio dati gruppo
|
|
pGdbGroup->m_gfrFrame = m_gfrFrame ;
|
|
|
|
// clono gli oggetti figli
|
|
const GdbObj* pObj = GetFirstObj() ;
|
|
while ( pObj != nullptr) {
|
|
// eseguo copia
|
|
GdbObj* pNewObj = pObj->Clone( IdMgr.GetNewId(), IdMgr) ;
|
|
if ( pNewObj == nullptr) {
|
|
delete pGdbGroup ;
|
|
return nullptr ;
|
|
}
|
|
// lo inserisco nella lista dei figli
|
|
if ( ! pNewObj->AddTail( pGdbGroup)) {
|
|
delete pNewObj ;
|
|
delete pGdbGroup ;
|
|
return nullptr ;
|
|
}
|
|
// lo inserisco nella mappa degli Id
|
|
if ( ! IdMgr.AddObj( pNewObj->m_nId, pNewObj)) {
|
|
delete pGdbGroup ;
|
|
return nullptr ;
|
|
}
|
|
// passo al prossimo oggetto
|
|
pObj = pObj->GetNext() ;
|
|
}
|
|
|
|
return pGdbGroup ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GdbGroup::Save( NgeWriter& ngeOut) const
|
|
{
|
|
bool bOk = true ;
|
|
|
|
// tipo entità e identificativi
|
|
ngeOut.WriteKey( NGE_A_GRP) ;
|
|
ngeOut.WriteInt( m_nId, "@") ;
|
|
ngeOut.WriteInt( GetParentId(), nullptr, true) ;
|
|
|
|
// attributi
|
|
if ( ! GdbObj::SaveAttribs( ngeOut))
|
|
bOk = false ;
|
|
|
|
// dati geometrici
|
|
ngeOut.WriteKey( NGE_G) ;
|
|
// puntatore alla prima copia (per ora NULL)
|
|
ngeOut.WriteInt( GDB_ID_NULL, nullptr, true) ;
|
|
// frame
|
|
if ( ! m_gfrFrame.Save( ngeOut))
|
|
bOk = false ;
|
|
|
|
// salvataggio dei figli
|
|
const GdbObj* pGdbObj = GetFirstObj() ;
|
|
while ( pGdbObj != nullptr) {
|
|
if ( ! pGdbObj->Save( ngeOut))
|
|
bOk = false ;
|
|
pGdbObj = pGdbObj->GetNext() ;
|
|
}
|
|
|
|
return bOk ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GdbGroup::Load( int nNgeId, NgeReader& ngeIn, int& nParentId)
|
|
{
|
|
// leggo la prossima linea
|
|
if ( ! ngeIn.ReadInt( m_nId, "@"))
|
|
return false ;
|
|
if ( ! ngeIn.ReadInt( nParentId, nullptr, true))
|
|
return false ;
|
|
|
|
// leggo la prossima linea
|
|
int nKey ;
|
|
if ( ! ngeIn.ReadKey( nKey))
|
|
return false ;
|
|
|
|
// eventuali attributi
|
|
if ( nKey == NGE_A) {
|
|
if ( ! GdbObj::LoadAttribs( ngeIn))
|
|
return false ;
|
|
// leggo la prossima linea
|
|
if ( ! ngeIn.ReadKey( nKey))
|
|
return false ;
|
|
}
|
|
|
|
// verifico inizio dati geometrici
|
|
if ( nKey != NGE_G)
|
|
return false ;
|
|
|
|
// leggo il puntatore alla prima copia
|
|
int nCopyId ;
|
|
if ( ! ngeIn.ReadInt( nCopyId, nullptr, true))
|
|
return false ;
|
|
|
|
// leggo i dati del riferimento
|
|
return m_gfrFrame.Load( ngeIn) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GdbGroup::GetLocalBBox( BBox3d& b3Loc, int nFlag, int nLev) const
|
|
{
|
|
b3Loc.Reset() ;
|
|
// se richiesto controllo visibilità oggetto
|
|
if ( ( nFlag & BBF_ONLY_VISIBLE) != 0) {
|
|
// recupero lo stato dell'oggetto
|
|
int nStat = GDB_ST_ON ;
|
|
if ( nLev == 0)
|
|
// questa funzione già tiene conto del modo
|
|
GetCalcStatus( nStat) ;
|
|
else {
|
|
// devo aggiustare lo stato con il modo
|
|
GetStatus( nStat) ;
|
|
int nMode = GDB_MD_STD ;
|
|
GetMode( nMode) ;
|
|
nStat = ::AdjustStatusWithMode( nStat, nMode) ;
|
|
}
|
|
// se non visibile
|
|
if ( nStat == GDB_ST_OFF)
|
|
return true ;
|
|
}
|
|
// ciclo sui figli
|
|
const GdbObj* pGdbObj = GetFirstObj() ;
|
|
while ( pGdbObj != nullptr) {
|
|
BBox3d b3B ;
|
|
// voglio il box come appare nel frame del gruppo, quindi passo frame identità
|
|
if ( pGdbObj->GetBBox( GLOB_FRM, b3B, nFlag, ( nLev + 1)))
|
|
b3Loc.Add( b3B) ;
|
|
pGdbObj = pGdbObj->GetNext() ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GdbGroup::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag, int nLev) const
|
|
{
|
|
b3Ref.Reset() ;
|
|
// se richiesto controllo visibilità oggetto
|
|
if ( ( nFlag & BBF_ONLY_VISIBLE) != 0) {
|
|
// recupero lo stato dell'oggetto
|
|
int nStat = GDB_ST_ON ;
|
|
if ( nLev == 0)
|
|
// questa funzione già tiene conto del modo
|
|
GetCalcStatus( nStat) ;
|
|
else {
|
|
// devo aggiustare lo stato con il modo
|
|
GetStatus( nStat) ;
|
|
int nMode = GDB_MD_STD ;
|
|
GetMode( nMode) ;
|
|
nStat = ::AdjustStatusWithMode( nStat, nMode) ;
|
|
}
|
|
// se non visibile
|
|
if ( nStat == GDB_ST_OFF)
|
|
return true ;
|
|
}
|
|
// ciclo sui figli
|
|
Frame3d frCurr = m_gfrFrame.GetFrame() * frRef ;
|
|
const GdbObj* pGdbObj = GetFirstObj() ;
|
|
while ( pGdbObj != nullptr) {
|
|
BBox3d b3B ;
|
|
if ( pGdbObj->GetBBox( frCurr, b3B, nFlag, ( nLev + 1)))
|
|
b3Ref.Add( b3B) ;
|
|
pGdbObj = pGdbObj->GetNext() ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GdbGroup::Translate( const Vector3d& vtMove)
|
|
{
|
|
return m_gfrFrame.Translate( vtMove) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GdbGroup::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, double dSinAng)
|
|
{
|
|
return m_gfrFrame.Rotate( ptAx, vtAx, dCosAng, dSinAng) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GdbGroup::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double dCoeffZ)
|
|
{
|
|
GdbObj* pGdbObj ;
|
|
|
|
|
|
// parziale scalatura del riferimento (non può essere completa)
|
|
Frame3d frFrameS = m_gfrFrame.GetFrame() ;
|
|
frFrameS.PseudoScale( frRef, dCoeffX, dCoeffY, dCoeffZ) ;
|
|
|
|
// porto gli oggetti nel nuovo riferimento, senza modificarne la geometria in globale
|
|
Frame3d frTrasf = m_gfrFrame.GetFrame() ;
|
|
frTrasf.ToLoc( frFrameS) ;
|
|
pGdbObj = GetFirstObj() ;
|
|
while ( pGdbObj != nullptr) {
|
|
pGdbObj->ToGlob( frTrasf) ;
|
|
pGdbObj = pGdbObj->GetNext() ;
|
|
}
|
|
|
|
// assegno il nuovo riferimento
|
|
m_gfrFrame.Set( frFrameS) ;
|
|
|
|
// porto il riferimento di scalatura nel riferimento del gruppo
|
|
Frame3d frRefLoc = frRef ;
|
|
frRefLoc.ToLoc( m_gfrFrame.GetFrame()) ;
|
|
|
|
// ciclo sugli oggetti
|
|
bool bOk = true ;
|
|
pGdbObj = GetFirstObj() ;
|
|
while ( pGdbObj != nullptr) {
|
|
if ( ! pGdbObj->Scale( frRefLoc, dCoeffX, dCoeffY, dCoeffZ))
|
|
bOk = false ;
|
|
pGdbObj = pGdbObj->GetNext() ;
|
|
}
|
|
|
|
return bOk ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GdbGroup::Mirror( const Point3d& ptOn, const Vector3d& vtNorm)
|
|
{
|
|
GdbObj* pGdbObj ;
|
|
|
|
|
|
// parziale mirror del riferimento (non può essere completa)
|
|
Frame3d frFrameS = m_gfrFrame.GetFrame() ;
|
|
frFrameS.PseudoMirror( ptOn, vtNorm) ;
|
|
|
|
// porto i nodi nel nuovo riferimento, senza modificarne la geometria in globale
|
|
Frame3d frTrasf = m_gfrFrame.GetFrame() ;
|
|
frTrasf.ToLoc( frFrameS) ;
|
|
pGdbObj = GetFirstObj() ;
|
|
while ( pGdbObj != nullptr) {
|
|
pGdbObj->ToGlob( frTrasf) ;
|
|
pGdbObj = pGdbObj->GetNext() ;
|
|
}
|
|
|
|
// assegno il nuovo riferimento
|
|
m_gfrFrame.Set( frFrameS) ;
|
|
|
|
// porto i dati del piano di mirror nel riferimento del gruppo
|
|
Point3d ptOnLoc = ptOn ;
|
|
ptOnLoc.ToLoc( m_gfrFrame.GetFrame()) ;
|
|
Vector3d vtNormLoc = vtNorm ;
|
|
vtNormLoc.ToLoc( m_gfrFrame.GetFrame()) ;
|
|
|
|
// ciclo sugli oggetti
|
|
bool bOk = true ;
|
|
pGdbObj = GetFirstObj() ;
|
|
while ( pGdbObj != nullptr) {
|
|
if ( ! pGdbObj->Mirror( ptOnLoc, vtNormLoc))
|
|
bOk = false ;
|
|
pGdbObj = pGdbObj->GetNext() ;
|
|
}
|
|
|
|
return bOk ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GdbGroup::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& vtDir, double dCoeff)
|
|
{
|
|
GdbObj* pGdbObj ;
|
|
|
|
|
|
// parziale scorrimento del riferimento (non può essere completa)
|
|
Frame3d frFrameS = m_gfrFrame.GetFrame() ;
|
|
frFrameS.PseudoShear( ptOn, vtNorm, vtDir, dCoeff) ;
|
|
|
|
// porto gli oggetti nel nuovo riferimento, senza modificarne la geometria in globale
|
|
Frame3d frTrasf = m_gfrFrame.GetFrame() ;
|
|
frTrasf.ToLoc( frFrameS) ;
|
|
pGdbObj = GetFirstObj() ;
|
|
while ( pGdbObj != nullptr) {
|
|
pGdbObj->ToGlob( frTrasf) ;
|
|
pGdbObj = pGdbObj->GetNext() ;
|
|
}
|
|
|
|
// assegno il nuovo riferimento
|
|
m_gfrFrame.Set( frFrameS) ;
|
|
|
|
// porto i dati di scorrimento nel riferimento del gruppo
|
|
Point3d ptOnLoc = ptOn ;
|
|
ptOnLoc.ToLoc( m_gfrFrame.GetFrame()) ;
|
|
Vector3d vtNormLoc = vtNorm ;
|
|
vtNormLoc.ToLoc( m_gfrFrame.GetFrame()) ;
|
|
Vector3d vtDirLoc = vtDir ;
|
|
vtDirLoc.ToLoc( m_gfrFrame.GetFrame()) ;
|
|
|
|
// ciclo sugli oggetti
|
|
bool bOk = true ;
|
|
pGdbObj = GetFirstObj() ;
|
|
while ( pGdbObj != nullptr) {
|
|
if ( ! pGdbObj->Shear( ptOnLoc, vtNormLoc, vtDirLoc, dCoeff))
|
|
bOk = false ;
|
|
pGdbObj = pGdbObj->GetNext() ;
|
|
}
|
|
|
|
return bOk ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GdbGroup::OnSetMaterial( void)
|
|
{
|
|
// ciclo sugli oggetti
|
|
bool bOk = true ;
|
|
GdbObj* pGdbObj = GetFirstObj() ;
|
|
while ( pGdbObj != nullptr) {
|
|
// se non ci sono attributi o ci si deve riferire al padre
|
|
int nMat ;
|
|
if ( ! pGdbObj->GetMaterial( nMat) || nMat == GDB_MT_PARENT) {
|
|
if ( ! pGdbObj->OnSetMaterial())
|
|
bOk = false ;
|
|
}
|
|
// passo al prossimo
|
|
pGdbObj = pGdbObj->GetNext() ;
|
|
}
|
|
|
|
return bOk ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GdbGroup::GetGlobFrame( Frame3d& frGlob) const
|
|
{
|
|
// assegno il proprio frame
|
|
frGlob = m_gfrFrame.GetFrame() ;
|
|
|
|
// mentre ci sono padri
|
|
const GdbGroup* pParent ;
|
|
pParent = GetParent() ;
|
|
while ( pParent != nullptr) {
|
|
// porto il riferimento corrente sopra il padre
|
|
frGlob.ToGlob( pParent->m_gfrFrame.GetFrame()) ;
|
|
// passo al successivo
|
|
pParent = pParent->GetParent() ;
|
|
}
|
|
|
|
return true ;
|
|
}
|