//---------------------------------------------------------------------------- // 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/EGkGeoVector3d.h" #include "/EgtDev/Include/EGkGeoPoint3d.h" #include "/EgtDev/Include/EGkCurve.h" #include "/EgtDev/Include/EGkGdbFunct.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, BBF_ONLY_VISIBLE)) return false ; return SetExtension( b3Ext) ; } //---------------------------------------------------------------------------- bool Scene::SetMark( Color colMark) { m_colMark = colMark ; return true ; } //---------------------------------------------------------------------------- bool Scene::DrawGroup( int nId, int nParentMode, int nParentStat, int nParentMark) { // creo un iteratore PtrOwner pIter( CreateGdbIterator( m_pGeomDB)) ; if ( ! ::IsValid( pIter)) return false ; // recupero il gruppo if ( ! pIter->GoTo( nId)) return false ; // eseguo il disegno return DrawGroup( *pIter, nParentMode, nParentStat, nParentMark) ; } //---------------------------------------------------------------------------- bool Scene::DrawGroup( const IGdbIterator& iIter, int nParentMode, int nParentStat, int nParentMark) { // recupero il riferimento del gruppo Frame3d frFrame ; if ( ! iIter.GetGroupFrame( 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( m_pGeomDB)) ; if ( ! ::IsValid( pIter)) return false ; // scandisco il gruppo bool bNext = pIter->GoToFirstInGroup( iIter) ; while ( bNext) { // leggo il tipo di oggetto int nGdbType = pIter->GetGdbType() ; // recupero e aggiorno il modo dell'oggetto int nMode = GDB_MD_STD ; pIter->GetMode( nMode) ; nMode = ::CalcMode( nMode, nParentMode) ; // recupero e aggiorno lo stato dell'oggetto int nStat = GDB_ST_ON ; pIter->GetStatus( nStat) ; nStat = ::CalcStatus( nStat, nParentStat) ; nStat = ::AdjustStatusWithMode( nStat, nMode) ; // recupero e aggiorno la marcatura dell'oggetto int nMark = GDB_MK_OFF ; pIter->GetMark( nMark) ; nMark = ::CalcMark( nMark, nParentMark) ; // se oggetto geometrico if ( nGdbType == GDB_TY_GEO) { // se non nascosto, lo disegno if ( nStat != GDB_ST_OFF) { if ( ! DrawGeoObj( *pIter, nStat, nMark)) return false ; } } // se gruppo else if ( nGdbType == GDB_TY_GROUP) { // se non nascosto, lo disegno if ( nStat != GDB_ST_OFF) { if ( ! DrawGroup( *pIter, nMode, nStat, nMark)) return false ; } } // passo al successivo bNext = pIter->GoToNext() ; } // se necessario, ripristino lo stack delle matrici if ( bMatrix) glPopMatrix() ; return true ; } //---------------------------------------------------------------------------- bool Scene::DrawGeoObj( const IGdbIterator& iIter, int nObjStat, int nObjMark) { // recupero l'oggetto geometrico IGeoObj* pGeoObj = (const_cast(&iIter))->GetGeoObj() ; if ( pGeoObj == nullptr) return false ; // 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) ; } // se la grafica associata non è valida la ricalcolo ObjEGrGraphics* pGraphics = GetObjEGrGraphics( pGeoObj) ; if ( ! pGraphics->IsValid()) { // leggo il tipo di oggetto geometrico int nGeoType = pGeoObj->GetType() ; // recupero il colore Color cCol ; if ( ! iIter.GetCalcMaterial( cCol)) cCol = m_colDef ; // se vettore if ( nGeoType == GEO_VECT3D) { // recupero il vettore const IGeoVector3d* pVector = GetGeoVector3d( pGeoObj) ; if ( pVector == nullptr) return false ; // calcolo la grafica PolyLine PL ; pVector->GetDrawWithArrowHead( 0.1, PL) ; pGraphics->Clear() ; pGraphics->AddColor( cCol) ; pGraphics->AddPolyLine( PL) ; } // se punto else if ( nGeoType == GEO_PNT3D) { // recupero il punto const IGeoPoint3d* pPoint = GetGeoPoint3d( pGeoObj) ; if ( pPoint == nullptr) return false ; // calcolo la grafica pGraphics->Clear() ; pGraphics->AddColor( cCol) ; pGraphics->AddPoint( pPoint->GetPoint()) ; } // se riferimento else if ( nGeoType == GEO_FRAME3D) { // recupero il riferimento const IGeoFrame3d* pFrame = GetGeoFrame3d( pGeoObj) ; if ( pFrame == nullptr) return false ; // aggiorno la grafica (colori speciali) PolyLine plX, plY, plZ ; pFrame->GetDrawWithArrowHeads( 10, 0.1, plX, plY, plZ) ; pGraphics->Clear() ; pGraphics->AddColor( RED) ; pGraphics->AddPolyLine( plX) ; pGraphics->AddColor( GREEN) ; pGraphics->AddPolyLine( plY) ; pGraphics->AddColor( BLUE) ; pGraphics->AddPolyLine( plZ) ; } // se curva else if ( ( nGeoType & GEO_CURVE) != 0) { // recupero la curva const ICurve* pCurve = GetCurve( pGeoObj) ; if ( pCurve == nullptr) return false ; // calcolo la grafica PolyLine PL ; pCurve->ApproxWithLines( 0.01, 5, PL) ; pGraphics->Clear() ; pGraphics->AddColor( cCol) ; pGraphics->AddPolyLine( PL) ; } } // visualizzo la grafica associata return pGraphics->Draw( nObjStat, nObjMark) ; } //---------------------------------------------------------------------------- bool Scene::DeleteObjGraphicsGroup( int nId) { // creo un iteratore PtrOwner pIter( CreateGdbIterator( m_pGeomDB)) ; if ( ! ::IsValid( pIter)) return false ; // scandisco il gruppo bool bNext = pIter->GoToFirstInGroup( nId) ; while ( bNext) { // leggo il tipo di nodo int nGdbType = pIter->GetGdbType() ; // se oggetto geometrico if ( nGdbType == GDB_TY_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_TY_GROUP) { // ripeto sugli oggetti dello stesso if ( ! DeleteObjGraphicsGroup( pIter->GetId())) return false ; } // passo al successivo bNext = pIter->GoToNext() ; } return true ; }