//---------------------------------------------------------------------------- // EgalTech 2013-2014 //---------------------------------------------------------------------------- // File : SceneGeom.cpp Data : 10.02.14 Versione : 1.5b1 // Contenuto : Implementazione della gestione geometria della classe scena. // // // // Modifiche : 10.02.14 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "Scene.h" #include "ObjOldGraphics.h" #include "ObjNewGraphics.h" #include "/EgtDev/Include/EgtILogger.h" #include "/EgtDev/Include/EGnStringUtils.h" #include "/EgtDev/Include/EGkFrame3d.h" #include "/EgtDev/Include/EgtPointerOwner.h" #include "/EgtDev/Include/EGkGdbIterator.h" #include "/EgtDev/Include/EGkCurve.h" using namespace std ; //------------------------------ Constants ----------------------------------- const int OGLMAT_DIM = 16 ; //---------------------------------------------------------------------------- bool FrameToOpenGlMatrix( const Frame3d& frFrame, double Matrix[OGLMAT_DIM]) { if ( frFrame.GetType() == Frame3d::ERR) return false ; Matrix[0] = frFrame.VersX().x ; Matrix[1] = frFrame.VersX().y ; Matrix[2] = frFrame.VersX().z ; Matrix[3] = 0 ; Matrix[4] = frFrame.VersY().x ; Matrix[5] = frFrame.VersY().y ; Matrix[6] = frFrame.VersY().z ; Matrix[7] = 0 ; Matrix[8] = frFrame.VersZ().x ; Matrix[9] = frFrame.VersZ().y ; Matrix[10] = frFrame.VersZ().z ; Matrix[11] = 0 ; Matrix[12] = frFrame.Orig().x ; Matrix[13] = frFrame.Orig().y ; Matrix[14] = frFrame.Orig().z ; Matrix[15] = 1 ; return true ; } //---------------------------------------------------------------------------- ObjEGrGraphics* CreateObjEGrGraphics( bool bNewWay) { if ( bNewWay) return ( new ObjNewGraphics) ; else return ( new ObjOldGraphics) ; } //---------------------------------------------------------------------------- bool Scene::UpdateExtension( void) { BBox3d b3Ext ; if ( m_pGeomDB == nullptr || ! m_pGeomDB->GetLocalBBox( GDB_ID_ROOT, b3Ext)) return false ; return SetExtension( b3Ext) ; } //---------------------------------------------------------------------------- bool Scene::DrawGroup( int nId) { // recupero il riferimento del gruppo Frame3d frFrame ; if ( ! m_pGeomDB->GetGroupFrame( nId, frFrame)) return false ; // se non è identità, lo aggiungo sullo stack delle matrici MODELVIEW di OpenGL bool bMatrix = ( frFrame.GetType() != Frame3d::TOP || ! frFrame.Orig().IsSmall()) ; if ( bMatrix) { glPushMatrix() ; double Matrix[OGLMAT_DIM] ; if ( FrameToOpenGlMatrix( frFrame, Matrix)) glMultMatrixd( Matrix) ; } // creo un iteratore PtrOwner pIter( CreateGdbIterator()) ; if ( ! ::IsValid( pIter)) return false ; // scandisco il gruppo pIter->SetGDB( m_pGeomDB) ; bool bNext = pIter->GoToFirstInGroup( nId) ; while ( bNext) { // leggo il tipo di nodo int nGdbType = pIter->GetGdbType() ; // se oggetto geometrico if ( nGdbType == GDB_GEO) { // lo recupero IGeoObj* pGeoObj = pIter->GetGeoObj() ; if ( pGeoObj == nullptr) return false ; // lo disegno if ( ! DrawGeoObj( pGeoObj)) return false ; } // se gruppo else if ( nGdbType == GDB_GROUP) { // lo disegno if ( ! DrawGroup( pIter->GetId())) return false ; } // passo al successivo bNext = pIter->GoToNext() ; } // se necessario, ripristino lo stack delle matrici if ( bMatrix) glPopMatrix() ; return true ; } //---------------------------------------------------------------------------- bool Scene::DrawGeoObj( IGeoObj* pGeoObj) { // se non esiste grafica associata, la creo if ( pGeoObj->GetObjGraphics() == nullptr) { ObjEGrGraphics* pGraphics = CreateObjEGrGraphics( m_bNewWay) ; if ( pGraphics == nullptr) return false ; pGraphics->SetScene( this) ; pGeoObj->SetObjGraphics( pGraphics) ; } // leggo il tipo di oggetto geometrico int nGeoType = pGeoObj->GetType() ; // se curva if ( ( nGeoType & GEO_CURVE) != 0) { // recupero la curva const ICurve* pCurve = GetCurve( pGeoObj) ; if ( pCurve == nullptr) return false ; // se la grafica associata non è valida la ricalcolo ObjEGrGraphics* pGraphics = GetObjEGrGraphics( pGeoObj) ; if ( ! pGraphics->IsValid()) { PolyLine PL ; pCurve->ApproxWithLines( 0.1, 5, PL) ; pGraphics->AddPolyLine( PL) ; } // visualizzo la grafica associata pGraphics->Draw() ; } return true ; } //---------------------------------------------------------------------------- bool Scene::DeleteObjGraphicsGroup( int nId) { // creo un iteratore PtrOwner pIter( CreateGdbIterator()) ; if ( ! ::IsValid( pIter)) return false ; // scandisco il gruppo pIter->SetGDB( m_pGeomDB) ; bool bNext = pIter->GoToFirstInGroup( nId) ; while ( bNext) { // leggo il tipo di nodo int nGdbType = pIter->GetGdbType() ; // se oggetto geometrico if ( nGdbType == GDB_GEO) { // lo recupero IGeoObj* pGeoObj = pIter->GetGeoObj() ; if ( pGeoObj == nullptr) return false ; // ne cancello l'eventuale parte grafica ObjEGrGraphics* pGraph = GetObjEGrGraphics( pGeoObj) ; if ( pGraph != nullptr && pGraph->GetScene() == this) pGeoObj->SetObjGraphics( nullptr) ; } // se gruppo else if ( nGdbType == GDB_GROUP) { // ripeto sugli oggetti dello stesso if ( ! DeleteObjGraphicsGroup( pIter->GetId())) return false ; } // passo al successivo bNext = pIter->GoToNext() ; } return true ; }