From a632e322fc49df59d1a355e4b36b710e52db44a4 Mon Sep 17 00:00:00 2001 From: vsv Date: Wed, 26 Mar 2014 17:32:22 +0400 Subject: [PATCH] Connect to OCCT Viewer --- src/XGUI/CMakeLists.txt | 16 +- src/XGUI/XGUI_MainWindow.cpp | 13 +- src/XGUI/XGUI_MainWindow.h | 8 + src/XGUI/XGUI_ViewPort.cpp | 417 +++++++++++++++++++++++++++++++++++ src/XGUI/XGUI_ViewPort.h | 57 +++++ src/XGUI/XGUI_ViewWindow.cpp | 113 ++++++---- src/XGUI/XGUI_ViewWindow.h | 22 +- src/XGUI/XGUI_Viewer.cpp | 93 ++++++++ src/XGUI/XGUI_Viewer.h | 42 ++++ src/XGUI/XGUI_Workshop.cpp | 7 + 10 files changed, 742 insertions(+), 46 deletions(-) create mode 100644 src/XGUI/XGUI_ViewPort.cpp create mode 100644 src/XGUI/XGUI_ViewPort.h create mode 100644 src/XGUI/XGUI_Viewer.cpp create mode 100644 src/XGUI/XGUI_Viewer.h diff --git a/src/XGUI/CMakeLists.txt b/src/XGUI/CMakeLists.txt index 56aadf140..3e8407b6a 100644 --- a/src/XGUI/CMakeLists.txt +++ b/src/XGUI/CMakeLists.txt @@ -1,6 +1,8 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8.11) INCLUDE(Common) +INCLUDE(FindCAS) + SET(CMAKE_AUTOMOC ON) SET(PROJECT_HEADERS @@ -12,6 +14,8 @@ SET(PROJECT_HEADERS XGUI_Workbench.h XGUI_Workshop.h XGUI_ViewWindow.h + XGUI_ViewPort.h + XGUI_Viewer.h ) SET(PROJECT_AUTOMOC @@ -28,6 +32,8 @@ SET(PROJECT_SOURCES XGUI_Workbench.cpp XGUI_Workshop.cpp XGUI_ViewWindow.cpp + XGUI_ViewPort.cpp + XGUI_Viewer.cpp ) SET(PROJECT_RESOURCES @@ -39,9 +45,12 @@ SET(TEXT_RESOURCES ) SET(PROJECT_LIBRARIES + opengl32 Event Config ${Qt5Widgets_LIBRARIES} + ${CAS_VIEWER} + ${CAS_KERNEL} ) QT5_ADD_RESOURCES(PROJECT_COMPILED_RESOURCES ${PROJECT_RESOURCES}) @@ -50,8 +59,11 @@ QT5_ADD_TRANSLATION(QM_RESOURCES ${TEXT_RESOURCES}) SOURCE_GROUP ("Generated Files" FILES ${PROJECT_AUTOMOC} ${PROJECT_COMPILED_RESOURCES} ${QM_RESOURCES}) SOURCE_GROUP ("Resource Files" FILES ${TEXT_RESOURCES} ${PROJECT_RESOURCES}) -INCLUDE_DIRECTORIES (${PROJECT_SOURCE_DIR}/src/Event) -INCLUDE_DIRECTORIES (${PROJECT_SOURCE_DIR}/src/Config) +ADD_DEFINITIONS(${CAS_DEFINITIONS} ) + +INCLUDE_DIRECTORIES (${PROJECT_SOURCE_DIR}/src/Event + ${PROJECT_SOURCE_DIR}/src/Config + ${CAS_INCLUDE_DIRS}) ADD_EXECUTABLE(XGUI WIN32 ${PROJECT_SOURCES} diff --git a/src/XGUI/XGUI_MainWindow.cpp b/src/XGUI/XGUI_MainWindow.cpp index 1a995322f..9f2f85b8c 100644 --- a/src/XGUI/XGUI_MainWindow.cpp +++ b/src/XGUI/XGUI_MainWindow.cpp @@ -1,6 +1,7 @@ #include "XGUI_MainWindow.h" #include "XGUI_MainMenu.h" #include "XGUI_ViewWindow.h" +#include "XGUI_Viewer.h" #include #include @@ -47,8 +48,9 @@ XGUI_MainWindow::XGUI_MainWindow(QWidget* parent) : QMdiArea* aMdiArea = new QMdiArea(this); setCentralWidget(aMdiArea); - aMdiArea->addSubWindow(new XGUI_ViewWindow(), Qt::FramelessWindowHint); - aMdiArea->addSubWindow(new XGUI_ViewWindow(), Qt::FramelessWindowHint); + myViewer = new XGUI_Viewer(this); + //aMdiArea->addSubWindow(new XGUI_ViewWindow(), Qt::FramelessWindowHint); + //aMdiArea->addSubWindow(new XGUI_ViewWindow(), Qt::FramelessWindowHint); fillObjectBrowser(); addPropertyPanel(); @@ -58,6 +60,13 @@ XGUI_MainWindow::~XGUI_MainWindow(void) { } +//****************************************************** +QMdiArea* XGUI_MainWindow::mdiArea() const +{ + return static_cast(centralWidget()); +} + + //****************************************************** void XGUI_MainWindow::showObjectBrowser() { diff --git a/src/XGUI/XGUI_MainWindow.h b/src/XGUI/XGUI_MainWindow.h index dc9e34fee..3b318389e 100644 --- a/src/XGUI/XGUI_MainWindow.h +++ b/src/XGUI/XGUI_MainWindow.h @@ -4,7 +4,9 @@ #include class XGUI_MainMenu; +class XGUI_Viewer; class QTreeWidget; +class QMdiArea; class XGUI_MainWindow : public QMainWindow { @@ -20,6 +22,10 @@ public: void showObjectBrowser(); void hideObjectBrowser(); + QMdiArea* mdiArea() const; + + XGUI_Viewer* viewer() const { return myViewer; } + private: //!! For test purposes only //QWidget* getSubWindow(); @@ -30,6 +36,8 @@ private: XGUI_MainMenu* myMenuBar; QTreeWidget* myObjectBrowser; + + XGUI_Viewer* myViewer; }; #endif \ No newline at end of file diff --git a/src/XGUI/XGUI_ViewPort.cpp b/src/XGUI/XGUI_ViewPort.cpp new file mode 100644 index 000000000..1ec3731f6 --- /dev/null +++ b/src/XGUI/XGUI_ViewPort.cpp @@ -0,0 +1,417 @@ +#ifndef WIN32 +# ifndef GLX_GLXEXT_LEGACY +# define GLX_GLXEXT_LEGACY +# endif +# include +# include +#else +# include +# include +#endif + +#include "XGUI_ViewPort.h" +#include "XGUI_ViewWindow.h" +#include "XGUI_Viewer.h" + +#include +#include +#include + +#include +#include +#include + +#ifdef WIN32 +#include +#else +#include +#endif + +#include + + +/*! + Create native view window for CasCade view [ static ] +*/ +Handle(Aspect_Window) CreateCasWindow( const Handle(V3d_View)& view, WId winId ) +{ + Aspect_Handle aWindowHandle = (Aspect_Handle)winId; +#ifdef WIN32 + Handle(WNT_Window) viewWindow = new WNT_Window( aWindowHandle ); +#else + Handle(Aspect_DisplayConnection) aDispConnection = view->Viewer()->Driver()->GetDisplayConnection(); + Handle(Xw_Window) viewWindow = new Xw_Window( aDispConnection, aWindowHandle ); +#endif + return viewWindow; +} + + + +class OpenGLUtils_FrameBuffer +{ +public: + OpenGLUtils_FrameBuffer(); + ~OpenGLUtils_FrameBuffer(); + + bool init( const GLsizei&, const GLsizei& ); + void release(); + + void bind(); + void unbind(); + +private: + GLuint textureId; + GLuint fboId; + GLuint rboId; +}; + + +#ifndef APIENTRY +#define APIENTRY +#endif +#ifndef APIENTRYP +#define APIENTRYP APIENTRY * +#endif + +#ifndef GL_FRAMEBUFFER_EXT +#define GL_FRAMEBUFFER_EXT 0x8D40 +#endif + +#ifndef GL_RENDERBUFFER_EXT +#define GL_RENDERBUFFER_EXT 0x8D41 +#endif + +#ifndef GL_COLOR_ATTACHMENT0_EXT +#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 +#endif + +#ifndef GL_DEPTH_ATTACHMENT_EXT +#define GL_DEPTH_ATTACHMENT_EXT 0x8D00 +#endif + +#ifndef GL_FRAMEBUFFER_COMPLETE_EXT +#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 +#endif + +typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint *framebuffers); +typedef void (APIENTRYP PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target); +typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint *framebuffers); +typedef void (APIENTRYP PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint *renderbuffers); +typedef void (APIENTRYP PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer); +typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint *renderbuffers); + +static PFNGLGENFRAMEBUFFERSEXTPROC vglGenFramebuffersEXT = NULL; +static PFNGLBINDFRAMEBUFFEREXTPROC vglBindFramebufferEXT = NULL; +static PFNGLFRAMEBUFFERTEXTURE2DEXTPROC vglFramebufferTexture2DEXT = NULL; +static PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC vglCheckFramebufferStatusEXT = NULL; +static PFNGLDELETEFRAMEBUFFERSEXTPROC vglDeleteFramebuffersEXT = NULL; +static PFNGLGENRENDERBUFFERSEXTPROC vglGenRenderbuffersEXT = NULL; +static PFNGLBINDRENDERBUFFEREXTPROC vglBindRenderbufferEXT = NULL; +static PFNGLRENDERBUFFERSTORAGEEXTPROC vglRenderbufferStorageEXT = NULL; +static PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC vglFramebufferRenderbufferEXT = NULL; +static PFNGLDELETERENDERBUFFERSEXTPROC vglDeleteRenderbuffersEXT = NULL; + +#ifndef WIN32 +#define GL_GetProcAddress( x ) glXGetProcAddressARB( (const GLubyte*)x ) +#else +#define GL_GetProcAddress( x ) wglGetProcAddress( (const LPCSTR)x ) +#endif + +bool InitializeEXT() +{ + vglGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC)GL_GetProcAddress( "glGenFramebuffersEXT" ); + vglBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)GL_GetProcAddress( "glBindFramebufferEXT" ); + vglFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)GL_GetProcAddress( "glFramebufferTexture2DEXT" ); + vglCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)GL_GetProcAddress( "glCheckFramebufferStatusEXT" ); + vglDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC)GL_GetProcAddress( "glDeleteFramebuffersEXT" ); + vglGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC)GL_GetProcAddress( "glGenRenderbuffersEXT" ); + vglBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC)GL_GetProcAddress( "glBindRenderbufferEXT" ); + vglRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC)GL_GetProcAddress( "glRenderbufferStorageEXT" ); + vglFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)GL_GetProcAddress( "glFramebufferRenderbufferEXT" ); + vglDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC)GL_GetProcAddress( "glDeleteRenderbuffersEXT" ); + + bool ok = vglGenFramebuffersEXT && vglBindFramebufferEXT && vglFramebufferTexture2DEXT && + vglCheckFramebufferStatusEXT && vglDeleteFramebuffersEXT && vglGenRenderbuffersEXT && + vglBindRenderbufferEXT && vglRenderbufferStorageEXT && vglFramebufferRenderbufferEXT && + vglDeleteRenderbuffersEXT; + + return ok; +} + +static bool IsEXTInitialized = InitializeEXT(); + +OpenGLUtils_FrameBuffer::OpenGLUtils_FrameBuffer() + : textureId( 0 ), + fboId( 0 ), + rboId( 0 ) +{ +} + +OpenGLUtils_FrameBuffer::~OpenGLUtils_FrameBuffer() +{ + release(); +} + +bool OpenGLUtils_FrameBuffer::init( const GLsizei& xSize, const GLsizei& ySize ) +{ + char* ext = (char*)glGetString( GL_EXTENSIONS ); + if( !IsEXTInitialized || + strstr( ext, "GL_EXT_framebuffer_object" ) == NULL ) + { + qDebug( "Initializing OpenGL FrameBuffer extension failed" ); + return false; + } + + // create a texture object + glEnable( GL_TEXTURE_2D ); + glGenTextures( 1, &textureId ); + glBindTexture( GL_TEXTURE_2D, textureId ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, xSize, ySize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL ); + glBindTexture( GL_TEXTURE_2D, 0 ); + + // create a renderbuffer object to store depth info + vglGenRenderbuffersEXT( 1, &rboId ); + vglBindRenderbufferEXT( GL_RENDERBUFFER_EXT, rboId ); + vglRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, xSize, ySize ); + vglBindRenderbufferEXT( GL_RENDERBUFFER_EXT, 0 ); + + // create a framebuffer object + vglGenFramebuffersEXT( 1, &fboId ); + vglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fboId ); + + // attach the texture to FBO color attachment point + vglFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, textureId, 0 ); + + // attach the renderbuffer to depth attachment point + vglFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rboId ); + + // check FBO status + GLenum status = vglCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT ); + + // Unbind FBO + vglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 ); + + return status == GL_FRAMEBUFFER_COMPLETE_EXT; +} + +void OpenGLUtils_FrameBuffer::release() +{ + if( !IsEXTInitialized ) + return; + + glDeleteTextures( 1, &textureId ); + textureId = 0; + + vglDeleteFramebuffersEXT( 1, &fboId ); + fboId = 0; + + vglDeleteRenderbuffersEXT( 1, &rboId ); + rboId = 0; +} + +void OpenGLUtils_FrameBuffer::bind() +{ + if( !IsEXTInitialized ) + return; + + vglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fboId ); +} + +void OpenGLUtils_FrameBuffer::unbind() +{ + if( !IsEXTInitialized ) + return; + + vglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 ); +} + + + +//************************************************************************ +//************************************************************************ +//************************************************************************ +XGUI_ViewPort::XGUI_ViewPort(XGUI_ViewWindow* theParent, + const Handle(V3d_Viewer)& theViewer, + V3d_TypeOfView theType) : +QWidget(theParent), + myPaintersRedrawing(false) +{ + setMouseTracking( true ); + setBackgroundRole( QPalette::NoRole ); + + // set focus policy to threat QContextMenuEvent from keyboard + setFocusPolicy( Qt::StrongFocus ); + setAttribute( Qt::WA_PaintOnScreen ); + setAttribute( Qt::WA_NoSystemBackground ); + + if ( theType == V3d_ORTHOGRAPHIC ) { + myOrthoView = new V3d_OrthographicView( theViewer ); + myActiveView = myOrthoView; + myPerspView = 0; + } else { + myPerspView = new V3d_PerspectiveView( theViewer ); + myActiveView = myPerspView; + } + //setBackground( Qtx::BackgroundData( Qt::black ) ); // set default background +} + +//*********************************************** +XGUI_ViewPort::~XGUI_ViewPort() +{ +} + +//*********************************************** +bool XGUI_ViewPort::mapView( const Handle(V3d_View)& theView) +{ + if ( !setWindow( theView ) ) + return false; + + if ( !mapped( theView ) ) { + theView->SetWindow( myWindow ); + if ( theView != activeView() ) + theView->View()->Deactivate(); + } + + /* create static trihedron (16551: EDF PAL 501) */ + //OCCViewer_ViewWindow* aVW = dynamic_cast( parentWidget()->parentWidget()->parentWidget() ); + //if ( aVW ) { + // OCCViewer_Viewer* aViewModel = dynamic_cast( aVW->getViewManager()->getViewModel() ); + // if ( aViewModel && aViewModel->isStaticTrihedronDisplayed() ){ + //theView->ZBufferTriedronSetup(); + theView->TriedronDisplay( Aspect_TOTP_LEFT_LOWER, Quantity_NOC_WHITE, 0.05, V3d_ZBUFFER ); + // } + //} + + emit( vpMapped() ); + + return true; +} + +//*********************************************** +bool XGUI_ViewPort::setWindow( const Handle(V3d_View)& theView) +{ + if ( !myWindow.IsNull() ) + return true; + + if ( theView.IsNull() ) + return false; + + attachWindow( theView, CreateCasWindow( theView, winId() ) ); + + myWindow = theView->Window(); + return !myWindow.IsNull(); +} + +//*********************************************** +bool XGUI_ViewPort::mapped( const Handle(V3d_View)& theView) const +{ + return ( !theView.IsNull() && theView->View()->IsDefined() ); +} + +//*********************************************** +void XGUI_ViewPort::updateBackground() +{ +} + +//*********************************************** +void XGUI_ViewPort::attachWindow( const Handle(V3d_View)& theView, const Handle(Aspect_Window)& theWnd) +{ + if (!theView.IsNull()) { + theView->SetWindow( theWnd ); + updateBackground(); + } +} + +//*********************************************** +void XGUI_ViewPort::paintEvent( QPaintEvent* theEvent) +{ +#ifndef WIN32 + /* X11 : map before show doesn't work */ + if ( !mapped( activeView() ) ) + mapView( activeView() ); +#endif + if ( !myWindow.IsNull() ) { + //QGuiApplication::sync(); + QRect rc = theEvent->rect(); + //if ( !myPaintersRedrawing ) { + //activeView()->Redraw(); + activeView()->Redraw( rc.x(), rc.y(), rc.width(), rc.height() ); + //} + } + //if ( myPaintersRedrawing ) { + // QPainter p( this ); + // //emit vpDrawExternal( &p ); + // myPaintersRedrawing = false; + //} +} + +//*********************************************** +void XGUI_ViewPort::resizeEvent( QResizeEvent* ) +{ +#ifdef WIN32 + /* Win32 : map before first show to avoid flicker */ + if ( !mapped( activeView() ) ) + mapView( activeView() ); +#endif + //QGuiApplication::sync(); + if ( !activeView().IsNull() ) + activeView()->MustBeResized(); +} + +//*********************************************** +QImage XGUI_ViewPort::dumpView() +{ + Handle(V3d_View) view = getView(); + if ( view.IsNull() ) + return QImage(); + + int aWidth = width(); + int aHeight = height(); + //QApplication::syncX(); + view->Redraw(); // In order to reactivate GL context + //view->Update(); + + OpenGLUtils_FrameBuffer aFrameBuffer; + if( aFrameBuffer.init( aWidth, aHeight ) ) + { + QImage anImage( aWidth, aHeight, QImage::Format_RGB32 ); + + glPushAttrib( GL_VIEWPORT_BIT ); + glViewport( 0, 0, aWidth, aHeight ); + aFrameBuffer.bind(); + + // draw scene + view->Redraw(); + + aFrameBuffer.unbind(); + glPopAttrib(); + + aFrameBuffer.bind(); + glReadPixels( 0, 0, aWidth, aHeight, GL_RGBA, GL_UNSIGNED_BYTE, anImage.bits() ); + aFrameBuffer.unbind(); + + anImage = anImage.rgbSwapped(); + anImage = anImage.mirrored(); + return anImage; + } + // if frame buffers are unsupported, use old functionality + //view->Redraw(); + + unsigned char* data = new unsigned char[ aWidth*aHeight*4 ]; + + QPoint p = mapFromParent(geometry().topLeft()); + + glReadPixels( p.x(), p.y(), aWidth, aHeight, GL_RGBA, GL_UNSIGNED_BYTE, + data); + + QImage anImage( data, aWidth, aHeight, QImage::Format_ARGB32 ); + anImage = anImage.mirrored(); + anImage = anImage.rgbSwapped(); + return anImage; +} diff --git a/src/XGUI/XGUI_ViewPort.h b/src/XGUI/XGUI_ViewPort.h new file mode 100644 index 000000000..1be2c4932 --- /dev/null +++ b/src/XGUI/XGUI_ViewPort.h @@ -0,0 +1,57 @@ + +#ifndef XGUI_ViewPort_H +#define XGUI_ViewPort_H + +#include +#include +#include + +class XGUI_ViewWindow; + +class XGUI_ViewPort : public QWidget +{ + Q_OBJECT +public: + XGUI_ViewPort(XGUI_ViewWindow* theParent, + const Handle(V3d_Viewer)& theViewer, + V3d_TypeOfView theType = V3d_ORTHOGRAPHIC); + ~XGUI_ViewPort(); + + virtual QPaintEngine* paintEngine() const { return 0; } + + QImage dumpView(); + + Handle(V3d_View) getView() const { return activeView(); } + +signals: + //void vpChangeBackground( const Qtx::BackgroundData& ); + void vpClosed(); + void vpMapped(); + + +protected: + virtual void paintEvent( QPaintEvent* ); + virtual void resizeEvent( QResizeEvent* ); + + +private: + Handle(V3d_View) activeView() const { return myActiveView; } + + bool mapView( const Handle(V3d_View)& theView); + bool setWindow( const Handle(V3d_View)& theView); + bool mapped( const Handle(V3d_View)& theView) const; + void updateBackground(); + void attachWindow( const Handle(V3d_View)& theView, const Handle(Aspect_Window)& theWnd); + + + Handle(V3d_View) myOrthoView; + Handle(V3d_View) myPerspView; + Handle(V3d_View) myActiveView; + + Handle(Aspect_Window) myWindow; + + bool myPaintersRedrawing; +}; + + +#endif \ No newline at end of file diff --git a/src/XGUI/XGUI_ViewWindow.cpp b/src/XGUI/XGUI_ViewWindow.cpp index c453028af..5499ec8cc 100644 --- a/src/XGUI/XGUI_ViewWindow.cpp +++ b/src/XGUI/XGUI_ViewWindow.cpp @@ -1,5 +1,6 @@ #include "XGUI_ViewWindow.h" - +#include "XGUI_ViewPort.h" +#include "XGUI_Viewer.h" #include #include @@ -9,32 +10,36 @@ #include #include #include +#include #define BORDER_SIZE 2 -XGUI_ViewWindow::XGUI_ViewWindow(): -QWidget(), + + +XGUI_ViewWindow::XGUI_ViewWindow(XGUI_Viewer* theViewer, + V3d_TypeOfView theType): +QFrame(), + myViewer(theViewer), myMoving(false), - ViewPortPxm(":pictures/ViewPort.png"), MinimizeIco(":pictures/wnd_minimize.png"), MaximizeIco(":pictures/wnd_maximize.png"), CloseIco(":pictures/wnd_close.png"), RestoreIco(":pictures/wnd_restore.png") { - + setFrameStyle(QFrame::Raised); + setFrameShape(QFrame::Panel); + setLineWidth(BORDER_SIZE); setMouseTracking(true); + QVBoxLayout* aLay = new QVBoxLayout(this); aLay->setContentsMargins(BORDER_SIZE,BORDER_SIZE,BORDER_SIZE,BORDER_SIZE); - myViewPort = new QLabel(this); + myViewPort = new XGUI_ViewPort(this, myViewer->v3dViewer(), theType); aLay->addWidget(myViewPort); - myViewPort->setFrameStyle(QFrame::Raised); - myViewPort->setCursor(Qt::ArrowCursor); - myViewPort->setFrameShape(QFrame::Panel); - myViewPort->setPixmap(ViewPortPxm); - myViewPort->setScaledContents(true); - - myPicture = new QLabel(this); - aLay->addWidget(myPicture); + + myPicture = new QLabel(); + myPicture->setFrameStyle(QFrame::Sunken); + myPicture->setFrameShape(QFrame::Panel); + //aLay->addWidget(myPicture); myPicture->setMouseTracking(true); myPicture->installEventFilter(this); myPicture->hide(); @@ -56,11 +61,14 @@ QWidget(), myGripWgt = new QLabel(this); myGripWgt->setPixmap(QPixmap(":pictures/wnd_grip.png")); - myGripWgt->setGeometry(BORDER_SIZE + 2, BORDER_SIZE + 4, 25, 25); + myGripWgt->setGeometry(BORDER_SIZE + 2, BORDER_SIZE + 2, 19, 32); myGripWgt->setMouseTracking(true); myGripWgt->installEventFilter(this); + myGripWgt->setAutoFillBackground(true); myViewBar = new QToolBar(this); + myViewBar->setAutoFillBackground(true); + QAction* aBtn; for (int i = 0; i < aTitles.length(); i++) { aBtn = new QAction(QIcon(aPictures.at(i)), aTitles.at(i), myViewBar); @@ -68,6 +76,7 @@ QWidget(), } myWindowBar = new QToolBar(this); + myWindowBar->setAutoFillBackground(true); myMinimizeBtn = new QAction(myWindowBar); myMinimizeBtn->setIcon(MinimizeIco); @@ -101,8 +110,11 @@ void XGUI_ViewWindow::resizeEvent(QResizeEvent* theEvent) QSize aWndBarSize = myWindowBar->sizeHint(); QSize myViewBarSize = myViewBar->sizeHint(); - myWindowBar->move(aSize.width() - aWndBarSize.width() - BORDER_SIZE, BORDER_SIZE); - myViewBar->setGeometry(BORDER_SIZE + 16, BORDER_SIZE, aSize.width() - aWndBarSize.width(), myViewBarSize.height()); + myWindowBar->move(aSize.width() - aWndBarSize.width() - BORDER_SIZE - 4, BORDER_SIZE); + int aViewBarWidth = aSize.width() - aWndBarSize.width() - myGripWgt->width() - 8; + if (aViewBarWidth > myViewBarSize.width()) + aViewBarWidth = myViewBarSize.width(); + myViewBar->setGeometry(BORDER_SIZE + 18, BORDER_SIZE, aViewBarWidth, myViewBarSize.height()); } //**************************************************************** @@ -111,15 +123,28 @@ void XGUI_ViewWindow::changeEvent(QEvent* theEvent) if (theEvent->type() == QEvent::WindowStateChange) { if (isMinimized()) { - parentWidget()->setGeometry(parentWidget()->x(), parentWidget()->y(), 110, 80); - myViewPort->hide(); - myViewBar->hide(); - myGripWgt->hide(); - myWindowBar->hide(); + //parentWidget()->setGeometry(parentWidget()->x(), parentWidget()->y(), 100, 80); + //myViewPort->hide(); + //myViewBar->hide(); + //myGripWgt->hide(); + //myWindowBar->hide(); + //myMinimizeBtn->setIcon(RestoreIco); + //myMaximizeBtn->setIcon(MaximizeIco); + + if (!myPicture->parentWidget()) { + QMdiSubWindow* aParent = static_cast(parentWidget()); + QMdiArea* aMDIArea = aParent->mdiArea(); + myPicture->setParent(aMDIArea); + } + myPicture->move(parentWidget()->x(), parentWidget()->y()); myPicture->show(); } else { - myViewPort->show(); + //myViewPort->show(); myPicture->hide(); + if (isMaximized()) { + myMinimizeBtn->setIcon(MinimizeIco); + myMaximizeBtn->setIcon(RestoreIco); + } } } else QWidget::changeEvent(theEvent); @@ -155,17 +180,22 @@ void XGUI_ViewWindow::leaveEvent(QEvent* theEvent) //**************************************************************** void XGUI_ViewWindow::onMinimize() { - QPixmap aPMap = grab(); - myPicture->setPixmap(aPMap.scaled(110, 80)); + //QPixmap aPMap = myViewPort->grab(); + QPixmap aPMap = QPixmap::fromImage(myViewPort->dumpView()); + int aW = width(); + int aH = height(); + double aR = aW / 100.; + myPicture->setPixmap(aPMap.scaled(100, int(aH / aR))); - if (isMinimized()) { - myMinimizeBtn->setIcon(MinimizeIco); - showNormal(); - } else { - myMinimizeBtn->setIcon(RestoreIco); - showMinimized(); - } - myMaximizeBtn->setIcon(MaximizeIco); + myLastState = isMaximized()? MaximizedState : NormalState; + //if (isMinimized()) { + //myMinimizeBtn->setIcon(MinimizeIco); + //showNormal(); + //} else { + //myMinimizeBtn->setIcon(RestoreIco); + showMinimized(); + //} + //myMaximizeBtn->setIcon(MaximizeIco); } //**************************************************************** @@ -187,6 +217,7 @@ void XGUI_ViewWindow::onMaximize() bool XGUI_ViewWindow::eventFilter(QObject *theObj, QEvent *theEvent) { if ((theObj == myGripWgt) || (theObj == myPicture)) { + QWidget* aWgt = (theObj == myPicture)? myPicture : static_cast(parentWidget()); switch (theEvent->type()) { case QEvent::MouseButtonPress: { @@ -217,15 +248,23 @@ bool XGUI_ViewWindow::eventFilter(QObject *theObj, QEvent *theEvent) QPoint aPnt = aEvent->globalPos(); QPoint aMDIPnt = aMDIArea->mapFromGlobal(aPnt); if (aMDIArea->rect().contains(aMDIPnt)) { - int aX = aParent->x() + (aPnt.x() - myMousePnt.x()); - int aY = aParent->y() + (aPnt.y() - myMousePnt.y()); - aParent->move(aX, aY); + int aX = aWgt->x() + (aPnt.x() - myMousePnt.x()); + int aY = aWgt->y() + (aPnt.y() - myMousePnt.y()); + aWgt->move(aX, aY); myMousePnt = aPnt; } return true; } } } + if ((theObj == myPicture) && (theEvent->type() == QEvent::MouseButtonDblClick)) { + myMoving = false; + if (myLastState == MaximizedState) + showMaximized(); + else + showNormal(); + return true; + } } - return QWidget::eventFilter(theObj, theEvent); + return QFrame::eventFilter(theObj, theEvent); } \ No newline at end of file diff --git a/src/XGUI/XGUI_ViewWindow.h b/src/XGUI/XGUI_ViewWindow.h index aefbd3dc7..1f37dc3fe 100644 --- a/src/XGUI/XGUI_ViewWindow.h +++ b/src/XGUI/XGUI_ViewWindow.h @@ -1,17 +1,24 @@ #ifndef XGUI_ViewWindow_H #define XGUI_ViewWindow_H -#include +#include #include +#include +#include + class QLabel; class QToolBar; +class XGUI_ViewPort; +class XGUI_Viewer; -class XGUI_ViewWindow : public QWidget +class XGUI_ViewWindow : public QFrame { Q_OBJECT public: - XGUI_ViewWindow(); + XGUI_ViewWindow(XGUI_Viewer* theViewer, + V3d_TypeOfView theType); + virtual ~XGUI_ViewWindow(); protected: @@ -30,16 +37,19 @@ private slots: void onMaximize(); private: + enum WindowState { MinimizedState, MaximizedState, NormalState }; + + + XGUI_Viewer* myViewer; QLabel* myPicture; - QLabel* myViewPort; QLabel* myGripWgt; + XGUI_ViewPort* myViewPort; QToolBar* myViewBar; QToolBar* myWindowBar; QAction* myMinimizeBtn; QAction* myMaximizeBtn; - QPixmap ViewPortPxm; QIcon MinimizeIco; QIcon MaximizeIco; QIcon CloseIco; @@ -47,6 +57,8 @@ private: bool myMoving; QPoint myMousePnt; + + WindowState myLastState; }; #endif \ No newline at end of file diff --git a/src/XGUI/XGUI_Viewer.cpp b/src/XGUI/XGUI_Viewer.cpp new file mode 100644 index 000000000..8e7744373 --- /dev/null +++ b/src/XGUI/XGUI_Viewer.cpp @@ -0,0 +1,93 @@ +#include "XGUI_Viewer.h" +#include "XGUI_MainWindow.h" +#include "XGUI_ViewWindow.h" + +#include +#include + +#include + +#include +#include +#include + +#ifdef WIN32 +#include +#else +#include +#endif + + +/*! + Creates viewer 3d [ static ] +*/ +Handle(V3d_Viewer) CreateViewer( const Standard_ExtString name, + const Standard_CString displayName, + const Standard_CString domain, + const Standard_Real viewSize , + const V3d_TypeOfOrientation viewProjection, + const Standard_Boolean computedMode, + const Standard_Boolean defaultComputedMode ) +{ + static Handle(Graphic3d_GraphicDriver) aGraphicDriver; + if (aGraphicDriver.IsNull()) + { + Handle(Aspect_DisplayConnection) aDisplayConnection; +#ifndef WIN32 + aDisplayConnection = new Aspect_DisplayConnection( displayName ); +#else + aDisplayConnection = new Aspect_DisplayConnection(); +#endif + aGraphicDriver = Graphic3d::InitGraphicDriver( aDisplayConnection ); + } + + return new V3d_Viewer( aGraphicDriver, name, domain, viewSize, viewProjection, + Quantity_NOC_GRAY30, V3d_ZBUFFER, V3d_GOURAUD, V3d_WAIT, + computedMode, defaultComputedMode, V3d_TEX_NONE ); +} + + + +XGUI_Viewer::XGUI_Viewer(XGUI_MainWindow* theParent) : +QObject(theParent), myMainWindow(theParent) +{ + // init CasCade viewers + myV3dViewer = CreateViewer(TCollection_ExtendedString("Viewer3d").ToExtString(), + "", "", 1000.0, V3d_XposYnegZpos, Standard_True, Standard_True ); + //myV3dViewer->Init(); // to avoid creation of the useless perspective view (see OCCT issue 0024267) + myV3dViewer->SetDefaultLights(); + + // init selector + myAISContext = new AIS_InteractiveContext( myV3dViewer ); + myAISContext->SelectionColor( Quantity_NOC_WHITE ); + + // display isoline on planar faces (box for ex.) + myAISContext->IsoOnPlane( true ); +} + + +XGUI_Viewer::~XGUI_Viewer(void) +{ +} + + +QMdiSubWindow* XGUI_Viewer::createView(V3d_TypeOfView theType) +{ + // create view frame + XGUI_ViewWindow* view = new XGUI_ViewWindow(this, theType); + // get main view window (created by view frame) + //OCCViewer_ViewWindow* vw = view->getView(OCCViewer_ViewFrame::MAIN_VIEW); + // initialize main view window + //initView( vw ); + // set default background for view window + //vw->setBackground( background(0) ); // 0 means MAIN_VIEW (other views are not yet created here) + //// connect signal from viewport + //connect(view->getViewPort(), SIGNAL(vpClosed()), this, SLOT(onViewClosed())); + //connect(view->getViewPort(), SIGNAL(vpMapped()), this, SLOT(onViewMapped())); + + QMdiArea* aMDI = myMainWindow->mdiArea(); + QMdiSubWindow* aWnd = aMDI->addSubWindow(view, Qt::FramelessWindowHint); + aWnd->setGeometry(0,0, aMDI->width() / 2, aMDI->height() / 2); + aWnd->show(); + return aWnd; +} \ No newline at end of file diff --git a/src/XGUI/XGUI_Viewer.h b/src/XGUI/XGUI_Viewer.h new file mode 100644 index 000000000..1b315e999 --- /dev/null +++ b/src/XGUI/XGUI_Viewer.h @@ -0,0 +1,42 @@ + +#ifndef XGUI_Viewer_H +#define XGUI_Viewer_H + +#include +#include +#include +#include + +class XGUI_MainWindow; +class QMdiSubWindow; + +class XGUI_Viewer : public QObject +{ + Q_OBJECT +public: + enum { + HorizontalGradient, VerticalGradient, + Diagonal1Gradient, Diagonal2Gradient, + Corner1Gradient, Corner2Gradient, + Corner3Gradient, Corner4Gradient, + LastGradient = Corner4Gradient + }; + + XGUI_Viewer(XGUI_MainWindow* theParent); + ~XGUI_Viewer(); + + QMdiSubWindow* createView(V3d_TypeOfView theType = V3d_ORTHOGRAPHIC); + + XGUI_MainWindow* mainWindow() const { return myMainWindow; } + + Handle(V3d_Viewer) v3dViewer() const { return myV3dViewer; } + +private: + XGUI_MainWindow* myMainWindow; + + Handle(V3d_Viewer) myV3dViewer; + Handle(AIS_Trihedron) myTrihedron; + Handle(AIS_InteractiveContext) myAISContext; +}; + +#endif \ No newline at end of file diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index 21a334db5..44620ea9f 100644 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -6,6 +6,7 @@ #include "XGUI_Tools.h" #include "XGUI_Workbench.h" #include "XGUI_Workshop.h" +#include "XGUI_Viewer.h" #include #include @@ -13,9 +14,13 @@ #include #include #include +#include + + #ifdef _DEBUG #include #endif + #ifdef WIN32 #include #else @@ -47,6 +52,8 @@ void XGUI_Workshop::startApplication() aLoop->RegisterListener(this, aPartSetId); activateModule(); myMainWindow->show(); + QMdiSubWindow* aWnd = myMainWindow->viewer()->createView(); + aWnd->showMaximized(); } //****************************************************** -- 2.39.2