EgtGraphics 1.5j1 :

- aggiunta gestione selezione con mouse
- aggiunta gestione selezione punti notevoli (snap points).
This commit is contained in:
Dario Sassi
2014-10-10 06:36:30 +00:00
parent 13bf590449
commit 3c0d573c46
8 changed files with 386 additions and 32 deletions
BIN
View File
Binary file not shown.
+2 -1
View File
@@ -230,7 +230,8 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
<ClCompile Include="SceneBasic.cpp" />
<ClCompile Include="SceneCamera.cpp" />
<ClCompile Include="SceneGeom.cpp" />
<ClCompile Include="SceneAux.cpp" />
<ClCompile Include="SceneDirect.cpp" />
<ClCompile Include="SceneSnap.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
+4 -1
View File
@@ -98,7 +98,10 @@
<ClCompile Include="SceExecutor.cpp">
<Filter>File di origine</Filter>
</ClCompile>
<ClCompile Include="SceneAux.cpp">
<ClCompile Include="SceneDirect.cpp">
<Filter>File di origine</Filter>
</ClCompile>
<ClCompile Include="SceneSnap.cpp">
<Filter>File di origine</Filter>
</ClCompile>
</ItemGroup>
+45 -6
View File
@@ -31,6 +31,15 @@ class MdStMk
int nMark ;
} ;
//----------------------------------------------------------------------------
struct SelRec { // record di selezione per OpenGL (buffer di GLuint)
GLuint nLen ; // numero di Id sullo stack dei nomi al momento del disegno (sempre 1)
GLuint nZmin ; // Zdepth minima
GLuint nZmax ; // Zdepth massima
GLuint nId ; // nome dell'oggetto
} ;
//----------------------------------------------------------------------------
class Scene : public IEGrScene
{
@@ -44,11 +53,17 @@ class Scene : public IEGrScene
virtual std::string GetOpenGLInfo( void) ;
virtual std::string GetGLSLInfo( void) ;
virtual std::string GetPixelFormatInfo( void) ;
virtual IGeomDB* GetGeomDB( void)
{ return m_pGeomDB ; }
virtual bool RedrawWindow( void) ;
virtual bool Resize( int nW, int nH) ;
virtual bool SetBackground( Color colBackTop, Color colBackBottom) ;
virtual bool Prepare( void) ;
virtual bool Draw( void) ;
virtual bool Select( const Point3d& ptView, int nW, int nH, int& nSel) ;
virtual bool GetSelectedObjs( INTVECTOR& nIds) ;
virtual int GetFirstSelectedObj( void) ;
virtual int GetNextSelectedObj( void) ;
virtual double GetSelectedObjWinZ( int nSel = - 1) ;
virtual bool Project( const Point3d& ptWorld, Point3d& ptView) ;
virtual bool UnProject( const Point3d& ptView, Point3d& ptWorld) ;
virtual void Destroy( void) ;
@@ -85,10 +100,15 @@ class Scene : public IEGrScene
virtual bool SetExtension( const BBox3d& b3Ext) ;
virtual bool UpdateExtension( void) ;
virtual bool SetMark( Color colMark) ;
// Aux
// Direct
virtual bool SetGeoLineAttribs( Color GLcol) ;
virtual bool SetGeoLine( const Point3d& ptP1, const Point3d& ptP2) ;
virtual bool ResetGeoLine( void) ;
virtual bool SetWinRectAttribs( bool bOutline, Color WRcol) ;
virtual bool SetWinRect( const Point3d& ptWinRectP1, const Point3d& ptWinRectP2) ;
virtual bool ResetWinRect( void) ;
// Snap
virtual bool GetSelectedSnapPoint( int nSnap, const Point3d& ptWin, int nW, int nH, Point3d& ptSel) ;
public :
// Basic
@@ -110,6 +130,7 @@ class Scene : public IEGrScene
bool AdjustDimView( double dHalfWidth, double dHalfHeight) ;
bool CalcClippingPlanesFromExtView( void) ;
bool Background( void) ;
bool Prepare( void) ;
// Camera
bool VerifyCamera( void) ;
bool CalcDirUp( void) ;
@@ -119,8 +140,13 @@ class Scene : public IEGrScene
bool DrawGroup( const IGdbIterator& iIter, int nPass, MdStMk siParent) ;
bool DrawGeoObj( const IGdbIterator& iIter, int nPass, MdStMk siObj) ;
bool DeleteObjGraphicsGroup( int nId) ;
// Aux
// Direct
bool DrawDirect( void) ;
bool DrawGeoLine( void) ;
bool DrawWinRect( void) ;
// Snap
bool VerifySnapPoint( const Point3d& ptP, const Point3d& ptWin, double& dMinSqDist) ;
private :
HDC m_hDC ; // Device Context
@@ -143,6 +169,15 @@ class Scene : public IEGrScene
int m_nShowMode ; // modo di visualizzazione (wireframe, hiddenline, shading)
bool m_bShowCurveDirection ; // flag di visualizzazione direzione curve
bool m_bSelect ; // flag di selezione attiva
Point3d m_ptSelCent ; // centro di selezione
int m_nSelW ; // larghezza finestra di selezione
int m_nSelH ; // altezza finestra di selezione
int m_nSelNbr ; // numero di selezioni registrate
int m_nSelCurr ; // indice oggetto selezionato corrente
static const int DIM_SEL_BUF = 4096 ;
SelRec m_nSelBuff[DIM_SEL_BUF] ; // buffer per selezione con OpenGL
IGeomDB* m_pGeomDB ; // puntatore al DB geometrico
Color m_colDef ; // colore di default
Color m_colMark ; // colore per marcatura
@@ -155,9 +190,13 @@ class Scene : public IEGrScene
double m_dZNear ; // distanza del piano di clipping vicino
double m_dZFar ; // distanza del piano di clipping lontano
Color m_colorGL ; // colore per GeoLine
bool m_bGeoLine ; // flag esistenza linea diretta in finestra
Point3d m_ptGeoLineP1 ; // primo estremo della linea diretta
Point3d m_ptGeoLineP2 ; // secondo estremo della linea diretta
bool m_bOutlineWR ; // flag per disegno WinRect con solo contorno o pieno
Color m_colorWR ; // colore per WinRect
bool m_bWinRect ; // flag esistenza rettangolo temporaneo in finestra
Point3d m_ptWinRectP1 ; // primo estremo del rettangolo temporaneo
Point3d m_ptWinRectP2 ; // secondo estremo del rettangolo temporaneo
bool m_bWinRect ; // flag esistenza rettangolo diretto in finestra
Point3d m_ptWinRectP1 ; // primo estremo del rettangolo diretto
Point3d m_ptWinRectP2 ; // secondo estremo del rettangolo diretto
} ;
+131 -5
View File
@@ -56,6 +56,9 @@ Scene::Scene( void)
m_colBackBottom.Set( 128, 128, 128) ;
// Modalità di visualizzazione
m_nShowMode = SM_WIREFRAME ;
// Selezione
m_bSelect = false ;
m_nSelCurr = - 1 ;
// GeomData
m_pGeomDB = nullptr ;
m_colDef.Set( 0, 0, 0) ;
@@ -63,7 +66,9 @@ Scene::Scene( void)
// Extension
SetExtension( BBox3d( -MIN_EXTENSION, -MIN_EXTENSION, -MIN_EXTENSION,
MIN_EXTENSION, MIN_EXTENSION, MIN_EXTENSION)) ;
// WinRect
// Direct
m_colorGL.Set( 0, 0, 0) ;
m_bGeoLine = false ;
m_bOutlineWR = true ;
m_colorWR.Set( 0, 0, 0) ;
m_bWinRect = false ;
@@ -600,6 +605,13 @@ Scene::Prepare( void)
// imposto matrice di proiezione
glMatrixMode( GL_PROJECTION) ;
glLoadIdentity() ;
if ( m_bSelect) {
// recupero viewport
GLint Viewport[4] ;
glGetIntegerv( GL_VIEWPORT, Viewport) ;
// imposto area di pick
gluPickMatrix( m_ptSelCent.x, ( Viewport[3] - m_ptSelCent.y), m_nSelW, m_nSelH, Viewport) ;
}
glOrtho( - m_dHalfWidth, m_dHalfWidth, - m_dHalfHeight, m_dHalfHeight, m_dZNear, m_dZFar) ;
// imposto matrice modello/vista
@@ -704,7 +716,7 @@ Scene::Draw( void)
glDisable( GL_DEPTH_TEST) ;
glDisable( GL_LIGHTING) ;
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL) ;
DrawWinRect() ;
DrawDirect() ;
// aggiorno
glFlush() ;
@@ -723,6 +735,120 @@ Scene::Draw( void)
return true ;
}
//----------------------------------------------------------------------------
int
CompareSelRec( const void* pSr1, const void* pSr2)
{
if ( ((SelRec*)pSr1)->nZmin > ((SelRec*)pSr2)->nZmin)
return 1 ;
else if ( ((SelRec*)pSr1)->nZmin < ((SelRec*)pSr2)->nZmin)
return - 1 ;
else {
if ( ((SelRec*)pSr1)->nId > ((SelRec*)pSr2)->nId)
return 1 ;
else if ( ((SelRec*)pSr1)->nId < ((SelRec*)pSr2)->nId)
return - 1 ;
else
return 0 ;
}
}
//----------------------------------------------------------------------------
bool
Scene::Select( const Point3d& ptSelCenter, int nW, int nH, int& nSel)
{
// inizializzo selezione
m_bSelect = true ;
m_ptSelCent = ptSelCenter ;
m_nSelW = nW ;
m_nSelH = nH ;
m_nSelNbr = 0 ;
// sfondo e Zbuffer non interessano
// imposto la camera, riducendo la viewport all'area di selezione
if ( ! Prepare()) {
m_bSelect = false ;
nSel = m_nSelNbr ;
return false ;
}
// imposto modalità di selezione
glSelectBuffer( DIM_SEL_BUF, (GLuint*)m_nSelBuff) ;
glRenderMode( GL_SELECT) ;
// inizializzo stack dei nomi
glInitNames() ;
glPushName( 0) ;
// eseguo disegno
// disabilito illuminazione
glDisable( GL_LIGHTING) ;
// non imposto glPolygonMode secondo il tipo di rendering perchè ignorato in selezione
// disegno le geometrie del DB in una sola passata
DrawGroup( GDB_ID_ROOT, 1, MdStMk( GDB_MD_STD, GDB_ST_ON, GDB_MK_OFF)) ;
// pulisco stack nomi
glPopName() ;
// chiudo modalità selezione, recupero buffer ripristino le matrici di OpenGL
m_nSelNbr = glRenderMode( GL_RENDER) ;
if ( m_nSelNbr < 0)
m_nSelNbr = DIM_SEL_BUF ;
m_bSelect = false ;
Prepare() ;
// riordino il buffer di selezione secondo la Zdepth minima crescente
qsort( m_nSelBuff, m_nSelNbr, sizeof( SelRec), CompareSelRec) ;
nSel = m_nSelNbr ;
return true ;
}
//----------------------------------------------------------------------------
bool
Scene::GetSelectedObjs( INTVECTOR& nIds)
{
// inizializzo vettore Id
nIds.clear() ;
try { nIds.reserve( m_nSelNbr) ; }
catch(...) { return false ; }
// inserisco l'Id degli oggetti selezionati
for ( int i = 0 ; i < m_nSelNbr ; ++ i)
nIds.push_back( m_nSelBuff[i].nId) ;
return true ;
}
//----------------------------------------------------------------------------
int
Scene::GetFirstSelectedObj( void)
{
m_nSelCurr = - 1 ;
return GetNextSelectedObj() ;
}
//----------------------------------------------------------------------------
int
Scene::GetNextSelectedObj( void)
{
// fuori dal range
m_nSelCurr ++ ;
if ( m_nSelCurr < 0 || m_nSelCurr >= m_nSelNbr)
return GDB_ID_NULL ;
return m_nSelBuff[m_nSelCurr].nId ;
}
//----------------------------------------------------------------------------
double
Scene::GetSelectedObjWinZ( int nSel)
{
if ( nSel < 0)
nSel = m_nSelCurr ;
if ( nSel < 0 || nSel >= m_nSelNbr)
return 0.5 ;
return 0.5 * ( double( m_nSelBuff[nSel].nZmin) + double( m_nSelBuff[nSel].nZmax)) / UINT_MAX ;
}
/*------------------------------------------------------------------------------------------*/
bool
Scene::Project( const Point3d& ptWorld, Point3d& ptView)
@@ -741,9 +867,9 @@ Scene::Project( const Point3d& ptWorld, Point3d& ptView)
// eseguo la proiezione
// l'asse y della vista OpenGL va in alto con l'origine in basso,
// quello di Windows va in basso con l'origine in alto
int nRes =gluProject( ptWorld.x, ptWorld.y, ptWorld.z,
ModelView, Projection, Viewport,
&ptView.x, &ptView.y, &ptView.z) ;
int nRes = gluProject( ptWorld.x, ptWorld.y, ptWorld.z,
ModelView, Projection, Viewport,
&ptView.x, &ptView.y, &ptView.z) ;
ptView.y = (double) Viewport[3] - ptView.y ;
return ( nRes == GL_TRUE) ;
+62 -7
View File
@@ -1,8 +1,8 @@
//----------------------------------------------------------------------------
// EgalTech 2014-2014
//----------------------------------------------------------------------------
// File : SceneAux.cpp Data : 25.02.14 Versione : 1.5b4
// Contenuto : Implementazione della gestione ausiliari della classe scena.
// File : SceneDirect.cpp Data : 09.10.14 Versione : 1.5j1
// Contenuto : Implementazione disegno diretto nella scena.
//
//
//
@@ -26,7 +26,34 @@
using namespace std ;
//------------------------------ Constants -----------------------------------
//----------------------------------------------------------------------------
bool
Scene::SetGeoLineAttribs( Color GLcol)
{
m_colorGL = GLcol ;
return true ;
}
//----------------------------------------------------------------------------
bool
Scene::SetGeoLine( const Point3d& ptP1, const Point3d& ptP2)
{
m_bGeoLine = true ;
m_ptGeoLineP1 = ptP1 ;
m_ptGeoLineP2 = ptP2 ;
return ( ! AreSamePointApprox( m_ptGeoLineP1, m_ptGeoLineP2)) ;
}
//----------------------------------------------------------------------------
bool
Scene::ResetGeoLine( void)
{
bool bOld = m_bGeoLine ;
m_bGeoLine = false ;
return bOld ;
}
//----------------------------------------------------------------------------
bool
@@ -58,14 +85,42 @@ Scene::ResetWinRect( void)
return bOld ;
}
//----------------------------------------------------------------------------
bool
Scene::DrawDirect( void)
{
// eseguo disegni diretti
bool bOk = true ;
if ( m_bGeoLine) {
if ( ! DrawGeoLine())
bOk = false ;
}
if ( m_bWinRect) {
if ( ! DrawWinRect())
bOk = false ;
}
return bOk ;
}
//----------------------------------------------------------------------------
bool
Scene::DrawGeoLine( void)
{
// disegno linea in geometria globale
glBegin( GL_LINES) ;
glColor3f( m_colorGL.GetRed(), m_colorGL.GetGreen(), m_colorGL.GetBlue()) ;
glVertex3f( float( m_ptGeoLineP1.x), float( m_ptGeoLineP1.y), float( m_ptGeoLineP1.z)) ;
glVertex3f( float( m_ptGeoLineP2.x), float( m_ptGeoLineP2.y), float( m_ptGeoLineP2.z)) ;
glEnd() ;
return true ;
}
//----------------------------------------------------------------------------
bool
Scene::DrawWinRect( void)
{
// verifico sia da disegnare
if ( ! m_bWinRect)
return true ;
// rendo neutre matrici di proiezione e di modello/vista
glMatrixMode( GL_PROJECTION) ;
glPushMatrix() ;
+17 -12
View File
@@ -80,6 +80,10 @@ Scene::DrawGroup( int nId, int nPass, MdStMk cParent)
bool
Scene::DrawGroup( const IGdbIterator& iIter, int nPass, MdStMk cParent)
{
// creo un iteratore
PtrOwner<IGdbIterator> pIter( CreateGdbIterator( m_pGeomDB)) ;
if ( IsNull( pIter))
return false ;
// recupero il riferimento del gruppo
Frame3d frFrame ;
if ( ! iIter.GetGroupFrame( frFrame))
@@ -92,13 +96,10 @@ Scene::DrawGroup( const IGdbIterator& iIter, int nPass, MdStMk cParent)
if ( FrameToOpenGlMatrix( frFrame, Matrix))
glMultMatrixd( Matrix) ;
}
// creo un iteratore
PtrOwner<IGdbIterator> pIter( CreateGdbIterator( m_pGeomDB)) ;
if ( IsNull( pIter))
return false ;
// scandisco il gruppo
bool bOk = true ;
for ( bool bNext = pIter->GoToFirstInGroup( iIter) ;
bNext ;
bNext && bOk ;
bNext = pIter->GoToNext()) {
// leggo il tipo di oggetto
int nGdbType = pIter->GetGdbType() ;
@@ -120,7 +121,7 @@ Scene::DrawGroup( const IGdbIterator& iIter, int nPass, MdStMk cParent)
// se non nascosto, lo disegno
if ( nStat != GDB_ST_OFF) {
if ( ! DrawGeoObj( *pIter, nPass, MdStMk( nMode, nStat, nMark)))
return false ;
bOk = false ;
}
}
// se gruppo
@@ -128,7 +129,7 @@ Scene::DrawGroup( const IGdbIterator& iIter, int nPass, MdStMk cParent)
// se non nascosto, lo disegno
if ( nStat != GDB_ST_OFF) {
if ( ! DrawGroup( *pIter, nPass, MdStMk( nMode, nStat, nMark)))
return false ;
bOk = false ;
}
}
}
@@ -136,7 +137,7 @@ Scene::DrawGroup( const IGdbIterator& iIter, int nPass, MdStMk cParent)
if ( bMatrix)
glPopMatrix() ;
return true ;
return bOk ;
}
//----------------------------------------------------------------------------
@@ -293,15 +294,15 @@ Scene::DrawGeoObj( const IGdbIterator& iIter, int nPass, MdStMk siObj)
}
}
// se hiddenline
if ( m_nShowMode == SM_HIDDENLINE) {
// se hiddenline e non selezione
if ( m_nShowMode == SM_HIDDENLINE && ! m_bSelect) {
// in prima passata disegno solo le superfici
if ( nPass == 1 && ( nGeoType & GEO_SURF) == 0)
return true ;
}
// se shading
if ( m_nShowMode == SM_SHADING) {
// se shading e non selezione
if ( m_nShowMode == SM_SHADING && ! m_bSelect) {
// in prima passata disegno solo le superfici
if ( nPass == 1 && ( nGeoType & GEO_SURF) == 0)
return true ;
@@ -310,6 +311,10 @@ Scene::DrawGeoObj( const IGdbIterator& iIter, int nPass, MdStMk siObj)
return true ;
}
// se in selezione, carico il nome
if ( m_bSelect)
glLoadName( iIter.GetId()) ;
// se richiesto, visualizzo la grafica associata
bool bShowAux = false ;
if ( ( nGeoType & GEO_CURVE) != 0 && m_bShowCurveDirection)
+125
View File
@@ -0,0 +1,125 @@
//----------------------------------------------------------------------------
// EgalTech 2014-2014
//----------------------------------------------------------------------------
// File : SceneSnap.cpp Data : 09.10.14 Versione : 1.5j1
// Contenuto : Implementazione snap di punti trmite selezione.
//
//
//
// Modifiche : 09.10.14 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "Scene.h"
#include "/EgtDev/Include/EGkGeomDB.h"
#include "/EgtDev/Include/EGkFrame3d.h"
#include "/EgtDev/Include/EGkCurve.h"
#include "/EgtDev/Include/EGkDistPointCurve.h"
using namespace std ;
//----------------------------------------------------------------------------
bool
Scene::GetSelectedSnapPoint( int nSnap, const Point3d& ptWin, int nW, int nH, Point3d& ptSel)
{
// verifico siano state selezionate delle entità
int nSel ;
Select( ptWin, nW, nH, nSel) ;
if ( nSel <= 0)
return false ;
// recupero le entità selezionate
INTVECTOR nIds ;
GetSelectedObjs( nIds) ;
// cerco il punto estremo più vicino alla selezione
bool bFound = false ;
double dMinSqDist = INFINITO * INFINITO ;
for ( size_t i = 0 ; i < nIds.size() ; ++ i) {
// recupero geometria e frame dell'entità
const ICurve* pCrv = GetCurve( m_pGeomDB->GetGeoObj( nIds[i])) ;
if ( pCrv == nullptr)
continue ;
Frame3d frEnt ;
if ( ! m_pGeomDB->GetGlobFrame( nIds[i], frEnt))
continue ;
// recupero il punto
Point3d ptP ;
switch ( nSnap) {
case SP_END :
// punto iniziale
if ( pCrv->GetStartPoint( ptP)) {
ptP.ToGlob( frEnt) ;
if ( VerifySnapPoint( ptP, ptWin, dMinSqDist)) {
bFound = true ;
ptSel = ptP ;
}
}
// punto finale
if ( pCrv->GetEndPoint( ptP)) {
ptP.ToGlob( frEnt) ;
if ( VerifySnapPoint( ptP, ptWin, dMinSqDist)) {
bFound = true ;
ptSel = ptP ;
}
}
break ;
case SP_MID :
if ( pCrv->GetMidPoint( ptP)) {
ptP.ToGlob( frEnt) ;
if ( VerifySnapPoint( ptP, ptWin, dMinSqDist)) {
bFound = true ;
ptSel = ptP ;
}
}
break ;
case SP_CENTER :
if ( pCrv->GetCenterPoint( ptP)) {
ptP.ToGlob( frEnt) ;
if ( VerifySnapPoint( ptP, ptWin, dMinSqDist)) {
bFound = true ;
ptSel = ptP ;
}
}
break ;
case SP_NEAR :
{ // il punto di riferimento deriva da XY su viewport e Z da selezione
Point3d ptRefWin( ptWin.x, ptWin.y, GetSelectedObjWinZ( int( i))) ;
Point3d ptRef ;
// lo porto da spazio grafico a spazio geometrico globale
UnProject( ptRefWin, ptRef) ;
// lo porto nel frame della curva
ptRef.ToLoc( frEnt) ;
// determino il punto più vicino della curva a questo
int nFlag ;
DistPointCurve dstPtCurve( ptRef, *pCrv) ;
if ( dstPtCurve.GetMinDistPoint( 0, ptP, nFlag)) {
ptP.ToGlob( frEnt) ;
if ( VerifySnapPoint( ptP, ptWin, dMinSqDist)) {
bFound = true ;
ptSel = ptP ;
}
}
} break ;
}
}
return bFound ;
}
//----------------------------------------------------------------------------
bool
Scene::VerifySnapPoint( const Point3d& ptP, const Point3d& ptWin, double& dMinSqDist)
{
// proietto il punto sulla viewport
Point3d ptWinP ;
Project( ptP, ptWinP) ;
// confronto le distanze
double dSqDist = SqDistXY( ptWin, ptWinP) ;
if ( dSqDist < dMinSqDist) {
dMinSqDist = dSqDist ;
return true ;
}
return false ;
}