df6b20d97f
- correzioni alle chiamate della ArcToBezierCurve.
467 lines
14 KiB
C++
467 lines
14 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2013-2013
|
|
//----------------------------------------------------------------------------
|
|
// File : GdbGeo.cpp Data : 24.11.13 Versione : 1.3a1
|
|
// Contenuto : Implementazione della classe GdbGeo oggetto del DB geometrico.
|
|
//
|
|
//
|
|
//
|
|
// Modifiche : 22.01.13 DS Creazione modulo.
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "stdafx.h"
|
|
#include "GdbGeo.h"
|
|
#include "GeoObjFactory.h"
|
|
#include "CurveAux.h"
|
|
#include "Attribs.h"
|
|
#include "NgeWriter.h"
|
|
#include "NgeReader.h"
|
|
#include "GeoObjRW.h"
|
|
#include "GeomDB.h"
|
|
#include "/EgtDev/Include/EGkCurveArc.h"
|
|
#include "/EgtDev/Include/EGkGdbFunct.h"
|
|
#include "/EgtDev/Include/EGkUserObj.h"
|
|
#include "/EgtDev/Include/EGnStringUtils.h"
|
|
#include <new>
|
|
|
|
using namespace std ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
GdbGeo::GdbGeo( void)
|
|
{
|
|
m_pGeoObj = nullptr ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
GdbGeo::~GdbGeo( void)
|
|
{
|
|
if ( m_pGeoObj != nullptr)
|
|
delete m_pGeoObj ;
|
|
m_pGeoObj = nullptr ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
GdbGeo*
|
|
GdbGeo::Clone( int nId) const
|
|
{
|
|
// alloco oggetto Gdb
|
|
GdbGeo* pGdbGeo = new(nothrow) GdbGeo ;
|
|
if ( pGdbGeo == nullptr)
|
|
return nullptr ;
|
|
|
|
// copio dati oggetto Gdb
|
|
pGdbGeo->GdbObj::CopyFrom( this) ;
|
|
|
|
// assegno nuovo Id
|
|
pGdbGeo->m_nId = nId ;
|
|
// l'aggiornamento del manager di Id viene fatto all'inserimento nel DB
|
|
// aggiorno eventuale UserObj
|
|
if ( pGdbGeo->m_pUserObj != nullptr)
|
|
pGdbGeo->m_pUserObj->SetOwner( nId, m_pGDB) ;
|
|
|
|
// assegno il riferimento al DB geometrico
|
|
pGdbGeo->SetGeomDB( m_pGDB) ;
|
|
|
|
// copio oggetto Geo
|
|
if ( m_pGeoObj != nullptr) {
|
|
pGdbGeo->m_pGeoObj = m_pGeoObj->Clone() ;
|
|
if ( pGdbGeo->m_pGeoObj == nullptr) {
|
|
delete pGdbGeo ;
|
|
return nullptr ;
|
|
}
|
|
}
|
|
|
|
return pGdbGeo ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
GeoObjType
|
|
GdbGeo::GetGeoType( void) const
|
|
{
|
|
// non esiste l'oggetto geometrico
|
|
if ( m_pGeoObj == nullptr)
|
|
return GEO_NONE ;
|
|
|
|
return m_pGeoObj->GetType() ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GdbGeo::Save( int nBaseId, NgeWriter& ngeOut, INTUNORDSET* pSavedIds) const
|
|
{
|
|
// eventuale verifica di già salvato
|
|
if ( pSavedIds != nullptr && ! pSavedIds->insert( m_nId).second)
|
|
return true ;
|
|
|
|
// recupero il gestore di lettura/scrittura dell'oggetto
|
|
IGeoObjRW* pGObjRW = dynamic_cast<IGeoObjRW*>( m_pGeoObj) ;
|
|
if ( pGObjRW == nullptr)
|
|
return false ;
|
|
|
|
// eventuali modifiche prima del salvataggio
|
|
if ( ! pGObjRW->PreSave( * const_cast<GdbGeo*>( this)))
|
|
return false ;
|
|
|
|
// tipo entità e identificativi
|
|
if ( ! ngeOut.WriteKey( pGObjRW->GetNgeId()))
|
|
return false ;
|
|
if ( ! ngeOut.WriteInt( m_nId - nBaseId, "@"))
|
|
return false ;
|
|
if ( ! ngeOut.WriteInt( max( GetParentId() - nBaseId, GDB_ID_ROOT), nullptr, true))
|
|
return false ;
|
|
|
|
// attributi
|
|
if ( ! GdbObj::SaveAttribs( ngeOut))
|
|
return false ;
|
|
|
|
// TextureData
|
|
if ( ! GdbObj::SaveTextureData( ngeOut))
|
|
return false ;
|
|
|
|
// UserObj
|
|
if ( ! GdbObj::SaveUserObj( nBaseId, ngeOut))
|
|
return false ;
|
|
|
|
// parametri geometrici
|
|
if ( ! ngeOut.WriteKey( NGE_G))
|
|
return false ;
|
|
if ( ! pGObjRW->Save( ngeOut))
|
|
return false ;
|
|
|
|
// eventuali ripristini dopo il salvataggio
|
|
return pGObjRW->PostSave( * const_cast<GdbGeo*>( this)) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GdbGeo::Load( int nNgeId, NgeReader& ngeIn, int nBaseGdbId, int& nParentId)
|
|
{
|
|
// creo l'oggetto geometrico corrispondente
|
|
int nType = GEOOBJ_NGEIDTOTYPE( nNgeId) ;
|
|
m_pGeoObj = GEOOBJ_CREATE( nType) ;
|
|
if ( m_pGeoObj == nullptr)
|
|
return false ;
|
|
|
|
// 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 ;
|
|
}
|
|
|
|
// eventuale TextureData
|
|
if ( nKey == NGE_T) {
|
|
if ( ! GdbObj::LoadTextureData( ngeIn))
|
|
return false ;
|
|
// leggo la prossima linea
|
|
if ( ! ngeIn.ReadKey( nKey))
|
|
return false ;
|
|
}
|
|
|
|
// eventuale UserObj
|
|
if ( nKey == NGE_U) {
|
|
if ( ! GdbObj::LoadUserObj( ngeIn, nBaseGdbId))
|
|
return false ;
|
|
// leggo la prossima linea
|
|
if ( ! ngeIn.ReadKey( nKey))
|
|
return false ;
|
|
}
|
|
|
|
// verifico inizio dati geometrici
|
|
if ( nKey != NGE_G)
|
|
return false ;
|
|
|
|
// parametri geometrici
|
|
IGeoObjRW* pGObjRW = dynamic_cast<IGeoObjRW*>( m_pGeoObj) ;
|
|
return ( pGObjRW != nullptr && pGObjRW->Load( ngeIn) && pGObjRW->PostLoad( *this)) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GdbGeo::GetLocalBBox( BBox3d& b3Loc, int nFlag, int nLev) const
|
|
{
|
|
if ( m_pGeoObj == nullptr)
|
|
return false ;
|
|
|
|
// 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) {
|
|
b3Loc.Reset() ;
|
|
return true ;
|
|
}
|
|
}
|
|
// se richiesto controllo non sia un testo
|
|
if ( ( nFlag & BBF_IGNORE_TEXT) != 0) {
|
|
// recupero il tipo di oggetto
|
|
if ( m_pGeoObj->GetType() == EXT_TEXT) {
|
|
b3Loc.Reset() ;
|
|
return true ;
|
|
}
|
|
}
|
|
// se richiesto controllo non sia una quota
|
|
if ( ( nFlag & BBF_IGNORE_DIM) != 0) {
|
|
// recupero il tipo di oggetto
|
|
if ( m_pGeoObj->GetType() == EXT_DIMENSION) {
|
|
b3Loc.Reset() ;
|
|
return true ;
|
|
}
|
|
}
|
|
|
|
return m_pGeoObj->GetLocalBBox( b3Loc, nFlag) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GdbGeo::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag, int nLev) const
|
|
{
|
|
if ( m_pGeoObj == nullptr)
|
|
return false ;
|
|
|
|
// 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) {
|
|
b3Ref.Reset() ;
|
|
return true ;
|
|
}
|
|
}
|
|
// se richiesto controllo non sia un testo
|
|
if ( ( nFlag & BBF_IGNORE_TEXT) != 0) {
|
|
// recupero il tipo di oggetto
|
|
if ( m_pGeoObj->GetType() == EXT_TEXT) {
|
|
b3Ref.Reset() ;
|
|
return true ;
|
|
}
|
|
}
|
|
// se richiesto controllo non sia una quota
|
|
if ( ( nFlag & BBF_IGNORE_DIM) != 0) {
|
|
// recupero il tipo di oggetto
|
|
if ( m_pGeoObj->GetType() == EXT_DIMENSION) {
|
|
b3Ref.Reset() ;
|
|
return true ;
|
|
}
|
|
}
|
|
|
|
return m_pGeoObj->GetBBox( frRef, b3Ref, nFlag) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GdbGeo::Translate( const Vector3d& vtMove)
|
|
{
|
|
if ( m_pGeoObj == nullptr)
|
|
return false ;
|
|
// eseguo traslazione
|
|
if ( ! m_pGeoObj->Translate( vtMove))
|
|
return false ;
|
|
if ( m_pUserObj != nullptr && ! m_pUserObj->Translate( vtMove))
|
|
return false ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GdbGeo::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, double dSinAng)
|
|
{
|
|
if ( m_pGeoObj == nullptr)
|
|
return false ;
|
|
// eseguo rotazione
|
|
if ( ! m_pGeoObj->Rotate( ptAx, vtAx, dCosAng, dSinAng))
|
|
return false ;
|
|
if ( m_pUserObj != nullptr && ! m_pUserObj->Rotate( ptAx, vtAx, dCosAng, dSinAng))
|
|
return false ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GdbGeo::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double dCoeffZ)
|
|
{
|
|
if ( m_pGeoObj == nullptr)
|
|
return false ;
|
|
|
|
// se arco e scalatura non omogenea nel suo piano, devo convertirlo in curva di Bezier
|
|
if ( m_pGeoObj->GetType() == CRV_ARC) {
|
|
bool bConvert = false ;
|
|
if ( AreSameOrOppositeVectorApprox( GetCurveArc( m_pGeoObj)->GetNormVersor(), frRef.VersZ()))
|
|
bConvert = abs( dCoeffX - dCoeffY) > EPS_SMALL ;
|
|
else if ( AreSameOrOppositeVectorApprox( GetCurveArc( m_pGeoObj)->GetNormVersor(), frRef.VersX()))
|
|
bConvert = abs( dCoeffY - dCoeffZ) > EPS_SMALL ;
|
|
else if ( AreSameOrOppositeVectorApprox( GetCurveArc( m_pGeoObj)->GetNormVersor(), frRef.VersY()))
|
|
bConvert = abs( dCoeffZ - dCoeffX) > EPS_SMALL ;
|
|
else
|
|
bConvert = (abs( dCoeffX - dCoeffY) > EPS_SMALL || abs( dCoeffX - dCoeffZ) > EPS_SMALL) ;
|
|
if ( bConvert) {
|
|
// curva originale
|
|
ICurve* pCrv = GetCurve( m_pGeoObj) ;
|
|
// trasformo in curva di Bezier (semplice o composta)
|
|
ICurve* pCrvNew = ArcToBezierCurve( GetCurveArc( pCrv)) ;
|
|
if ( pCrvNew == nullptr)
|
|
return false ;
|
|
// assegno alla nuova curva estrusione e spessore di quella originale
|
|
Vector3d vtExtr ;
|
|
if ( pCrv->GetExtrusion( vtExtr))
|
|
pCrvNew->SetExtrusion( vtExtr) ;
|
|
double dThick ;
|
|
if ( pCrv->GetThickness( dThick))
|
|
pCrvNew->SetThickness( dThick) ;
|
|
// elimino l'arco e lo sostituisco con la curva di Bezier
|
|
delete m_pGeoObj ;
|
|
m_pGeoObj = pCrvNew ;
|
|
}
|
|
}
|
|
|
|
// eseguo scalatura
|
|
if ( ! m_pGeoObj->Scale( frRef, dCoeffX, dCoeffY, dCoeffZ))
|
|
return false ;
|
|
if ( m_pUserObj != nullptr && ! m_pUserObj->Scale( frRef, dCoeffX, dCoeffY, dCoeffZ))
|
|
return false ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GdbGeo::Mirror( const Point3d& ptOn, const Vector3d& vtNorm)
|
|
{
|
|
if ( m_pGeoObj == nullptr)
|
|
return false ;
|
|
// eseguo mirror
|
|
if ( ! m_pGeoObj->Mirror( ptOn, vtNorm))
|
|
return false ;
|
|
if ( m_pUserObj != nullptr && ! m_pUserObj->Mirror( ptOn, vtNorm))
|
|
return false ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GdbGeo::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& vtDir, double dCoeff)
|
|
{
|
|
if ( m_pGeoObj == nullptr)
|
|
return false ;
|
|
|
|
// verifiche per arco
|
|
if ( m_pGeoObj->GetType() == CRV_ARC) {
|
|
// ricavo puntatore ad arco
|
|
ICurveArc* pArc = GetCurveArc( m_pGeoObj) ;
|
|
// se l'arco non è piatto o il piano di scorrimento non coincide con quello dell'arco
|
|
if ( ! pArc->IsPlane() ||
|
|
! AreSameOrOppositeVectorExact( pArc->GetNormVersor(), vtNorm)) {
|
|
// trasformo in curva di Bezier (semplice o composta)
|
|
ICurve* pCrvNew = ArcToBezierCurve( GetCurveArc( m_pGeoObj)) ;
|
|
if ( pCrvNew == nullptr)
|
|
return false ;
|
|
// assegno alla nuova curva estrusione e spessore di quella originale
|
|
Vector3d vtExtr ;
|
|
if ( pArc->GetExtrusion( vtExtr))
|
|
pCrvNew->SetExtrusion( vtExtr) ;
|
|
double dThick ;
|
|
if ( pArc->GetThickness( dThick))
|
|
pCrvNew->SetThickness( dThick) ;
|
|
// elimino l'arco e lo sostituisco con la curva di Bezier
|
|
delete m_pGeoObj ;
|
|
m_pGeoObj = pCrvNew ;
|
|
}
|
|
}
|
|
|
|
// eseguo scorrimento
|
|
if ( ! m_pGeoObj->Shear( ptOn, vtNorm, vtDir, dCoeff))
|
|
return false ;
|
|
if ( m_pUserObj != nullptr && ! m_pUserObj->Shear( ptOn, vtNorm, vtDir, dCoeff))
|
|
return false ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GdbGeo::ToGlob( const Frame3d& frRef)
|
|
{
|
|
if ( m_pGeoObj == nullptr)
|
|
return false ;
|
|
|
|
if ( ! m_pGeoObj->ToGlob( frRef))
|
|
return false ;
|
|
if ( m_pUserObj != nullptr && ! m_pUserObj->ToGlob( frRef))
|
|
return false ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GdbGeo::ToLoc( const Frame3d& frRef)
|
|
{
|
|
if ( m_pGeoObj == nullptr)
|
|
return false ;
|
|
|
|
if ( ! m_pGeoObj->ToLoc( frRef))
|
|
return false ;
|
|
if ( m_pUserObj != nullptr && ! m_pUserObj->ToLoc( frRef))
|
|
return false ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GdbGeo::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
|
{
|
|
if ( m_pGeoObj == nullptr)
|
|
return false ;
|
|
|
|
if ( ! m_pGeoObj->LocToLoc( frOri, frDest))
|
|
return false ;
|
|
if ( m_pUserObj != nullptr && ! m_pUserObj->LocToLoc( frOri, frDest))
|
|
return false ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
GdbGeo::OnSetMaterial( void)
|
|
{
|
|
if ( m_pGeoObj->GetObjGraphics() != nullptr)
|
|
m_pGeoObj->GetObjGraphics()->ResetAll() ;
|
|
|
|
return true ;
|
|
}
|