Files
EgtGraphics/SceneGeom.cpp
T
Dario Sassi 61a4c43aae EgtGraphics :
- piccola miglioria in visualizzazione vettori (max dim freccia).
2014-06-14 18:03:54 +00:00

356 lines
12 KiB
C++

//----------------------------------------------------------------------------
// 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/EGkSurfTriMesh.h"
#include "/EgtDev/Include/EGkExtText.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 nPass, MdStMk cParent)
{
// creo un iteratore
PtrOwner<IGdbIterator> pIter( CreateGdbIterator( m_pGeomDB)) ;
if ( ! ::IsValid( pIter))
return false ;
// recupero il gruppo
if ( ! pIter->GoTo( nId))
return false ;
// eseguo il disegno
return DrawGroup( *pIter, nPass, cParent) ;
}
//----------------------------------------------------------------------------
bool
Scene::DrawGroup( const IGdbIterator& iIter, int nPass, MdStMk cParent)
{
// 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<IGdbIterator> pIter( CreateGdbIterator( m_pGeomDB)) ;
if ( ! ::IsValid( pIter))
return false ;
// scandisco il gruppo
for ( bool bNext = pIter->GoToFirstInGroup( iIter) ;
bNext ;
bNext = pIter->GoToNext()) {
// 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, cParent.nMode) ;
// recupero e aggiorno lo stato dell'oggetto
int nStat = GDB_ST_ON ;
pIter->GetStatus( nStat) ;
nStat = ::CalcStatus( nStat, cParent.nStat) ;
nStat = ::AdjustStatusWithMode( nStat, nMode) ;
// recupero e aggiorno la marcatura dell'oggetto
int nMark = GDB_MK_OFF ;
pIter->GetMark( nMark) ;
nMark = ::CalcMark( nMark, cParent.nMark) ;
// se oggetto geometrico
if ( nGdbType == GDB_TY_GEO) {
// se non nascosto, lo disegno
if ( nStat != GDB_ST_OFF) {
if ( ! DrawGeoObj( *pIter, nPass, MdStMk( nMode, 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, nPass, MdStMk( nMode, nStat, nMark)))
return false ;
}
}
}
// se necessario, ripristino lo stack delle matrici
if ( bMatrix)
glPopMatrix() ;
return true ;
}
//----------------------------------------------------------------------------
bool
Scene::DrawGeoObj( const IGdbIterator& iIter, int nPass, MdStMk siObj)
{
// recupero l'oggetto geometrico
IGeoObj* pGeoObj = (const_cast<IGdbIterator*>(&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, 10, 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) ;
}
// se superficie trimesh
else if ( nGeoType == SRF_TRIMESH) {
// recupero la superficie
const ISurfTriMesh* pSTM = GetSurfTriMesh( pGeoObj) ;
if ( pSTM == nullptr)
return false ;
// recupero il materiale
Material mMat ;
if ( ! iIter.GetCalcMaterial( mMat))
mMat.Set( m_colDef) ;
// impostazioni iniziali
pGraphics->Clear() ;
pGraphics->AddColor( cCol) ; // per wireframe
pGraphics->AddMaterial( mMat.GetAmbient(), mMat.GetDiffuse(),
mMat.GetSpecular(), mMat.GetShininess()) ;
pGraphics->AddBackMaterial( GetSurfBackColor( mMat.GetDiffuse())) ;
pGraphics->StartTriangles( pSTM->GetTriangleSize()) ;
// ciclo sui triangoli della superficie
Triangle3d Tria ;
TriNormals3d TNrms ;
int nId = pSTM->GetFirstTriangle( Tria) ;
while ( nId != SVT_NULL) {
pSTM->GetTriangleSmoothNormals( nId, TNrms) ;
pGraphics->AddTriangle( Tria, TNrms) ;
nId = pSTM->GetNextTriangle( nId, Tria) ;
}
pGraphics->EndTriangles() ;
}
// se testo
else if ( nGeoType == EXT_TEXT) {
// recupero il testo
const IExtText* pTXT = GetExtText( pGeoObj) ;
if ( pTXT == nullptr)
return false ;
// calcolo la grafica
POLYLINELIST lstPL ;
pTXT->ApproxWithLines( 0.01, 5, lstPL) ;
pGraphics->Clear() ;
pGraphics->AddColor( cCol) ;
POLYLINELIST::iterator Iter ;
for ( Iter = lstPL.begin() ; Iter != lstPL.end() ; ++ Iter)
pGraphics->AddPolyLine( *Iter) ;
}
}
// se hiddenline
if ( m_nShowMode == SM_HIDDENLINE) {
// in prima passata disegno solo le superfici
if ( nPass == 1 && ( pGeoObj->GetType() & GEO_SURF) == 0)
return true ;
}
// se shading
if ( m_nShowMode == SM_SHADING) {
// in prima passata disegno solo le superfici
if ( nPass == 1 && ( pGeoObj->GetType() & GEO_SURF) == 0)
return true ;
// in seconda passata disegno solo dimensioni 0 e curve
if ( nPass == 2 && ( pGeoObj->GetType() & GEO_SURF) != 0)
return true ;
}
// visualizzo la grafica associata
return pGraphics->Draw( siObj.nStat, siObj.nMark) ;
}
//----------------------------------------------------------------------------
bool
Scene::DeleteObjGraphicsGroup( int nId)
{
// creo un iteratore
PtrOwner<IGdbIterator> 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 ;
}