//---------------------------------------------------------------------------- // 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 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( m_pGeoObj) ; if ( pGObjRW == nullptr) return false ; // eventuali modifiche prima del salvataggio if ( ! pGObjRW->PreSave( * const_cast( 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( 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( 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 ; }