diff --git a/src/Mod/Sandbox/Gui/CMakeLists.txt b/src/Mod/Sandbox/Gui/CMakeLists.txt index ee9598b6e..d2fa450a9 100644 --- a/src/Mod/Sandbox/Gui/CMakeLists.txt +++ b/src/Mod/Sandbox/Gui/CMakeLists.txt @@ -24,6 +24,13 @@ set(SandboxGui_LIBS FreeCADGui ) +set(SandboxGui_MOC_HDRS + GLGraphicsView.h +) + +fc_wrap_cpp(SandboxGui_MOC_SRCS ${SandboxGui_MOC_HDRS}) +SOURCE_GROUP("Moc" FILES ${SandboxGui_MOC_SRCS}) + qt4_add_resources(Resource_SRCS Resources/Sandbox.qrc) SET(Resource_SRCS ${Resource_SRCS} @@ -34,6 +41,10 @@ SOURCE_GROUP("Resource" FILES ${Resource_SRCS}) SET(SandboxGui_SRCS AppSandboxGui.cpp Command.cpp + GLGraphicsView.cpp + GLGraphicsView.h + Overlay.cpp + Overlay.h PreCompiled.cpp PreCompiled.h Workbench.cpp diff --git a/src/Mod/Sandbox/Gui/Command.cpp b/src/Mod/Sandbox/Gui/Command.cpp index 1a7e9313d..2393350ae 100644 --- a/src/Mod/Sandbox/Gui/Command.cpp +++ b/src/Mod/Sandbox/Gui/Command.cpp @@ -78,6 +78,7 @@ #include #include #include "Workbench.h" +#include "GLGraphicsView.h" DEF_STD_CMD(CmdSandboxDocumentThread); @@ -1424,6 +1425,31 @@ void CmdMengerSponge::activated(int iMsg) feature->purgeTouched(); } +DEF_STD_CMD_A(CmdTestGraphicsView); + +CmdTestGraphicsView::CmdTestGraphicsView() + : Command("Std_TestGraphicsView") +{ + sGroup = QT_TR_NOOP("Standard-Test"); + sMenuText = QT_TR_NOOP("Create new graphics view"); + sToolTipText= QT_TR_NOOP("Creates a new view window for the active document"); + sStatusTip = QT_TR_NOOP("Creates a new view window for the active document"); +} + +void CmdTestGraphicsView::activated(int iMsg) +{ + Gui::GraphicsView3D* view3D = new Gui::GraphicsView3D(getActiveGuiDocument(), Gui::getMainWindow()); + view3D->setWindowTitle(QString::fromAscii("Graphics scene")); + view3D->setWindowIcon(QApplication::windowIcon()); + view3D->resize(400, 300); + Gui::getMainWindow()->addWindow(view3D); +} + +bool CmdTestGraphicsView::isActive(void) +{ + return (getActiveGuiDocument()!=NULL); +} + void CreateSandboxCommands(void) { @@ -1457,4 +1483,5 @@ void CreateSandboxCommands(void) rcCmdMgr.addCommand(new CmdSandboxExaminerViewer()); rcCmdMgr.addCommand(new CmdSandboxFlyViewer()); rcCmdMgr.addCommand(new CmdMengerSponge()); + rcCmdMgr.addCommand(new CmdTestGraphicsView()); } diff --git a/src/Mod/Sandbox/Gui/GLGraphicsView.cpp b/src/Mod/Sandbox/Gui/GLGraphicsView.cpp new file mode 100644 index 000000000..26c7bf441 --- /dev/null +++ b/src/Mod/Sandbox/Gui/GLGraphicsView.cpp @@ -0,0 +1,395 @@ +/*************************************************************************** + * Copyright (c) 2013 Werner Mayer * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#include "PreCompiled.h" + +#ifndef _PreComp_ +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "GLGraphicsView.h" +#include +#include + +using namespace Gui; + +// http://doc.qt.digia.com/qq/qq26-openglcanvas.html + +class GraphicsView : public QGraphicsView +{ +public: + GraphicsView() + { + } + +protected: + void resizeEvent(QResizeEvent *event) { + if (scene()) + scene()->setSceneRect( + QRect(QPoint(0, 0), event->size())); + QGraphicsView::resizeEvent(event); + } +}; + + +#ifndef GL_MULTISAMPLE +#define GL_MULTISAMPLE 0x809D +#endif + +#include +#include +#include + +QDialog *GraphicsScene::createDialog(const QString &windowTitle) const +{ + QDialog *dialog = new QDialog(0, Qt::CustomizeWindowHint | Qt::WindowTitleHint); + + dialog->setWindowOpacity(0.8); + dialog->setWindowTitle(windowTitle); + dialog->setLayout(new QVBoxLayout); + + return dialog; +} + +GraphicsScene::GraphicsScene() + : m_wireframeEnabled(false) + , m_normalsEnabled(false) + , m_modelColor(153, 255, 0) + , m_backgroundColor(0, 170, 255) + , m_lastTime(0) + , m_distance(1.4f) +{ + rootNode = new SoSeparator(); + rootNode->ref(); + sceneCamera = new SoOrthographicCamera(); + rootNode->addChild(sceneCamera); + rootNode->addChild(new SoDirectionalLight()); + sceneNode = new SoSeparator(); + sceneNode->ref(); + rootNode->addChild(sceneNode); + + this->addEllipse(20,20, 120, 60); + QWidget *controls = createDialog(tr("Controls")); + + m_modelButton = new QPushButton(tr("Load model")); + //connect(m_modelButton, SIGNAL(clicked()), this, SLOT(loadModel())); + controls->layout()->addWidget(m_modelButton); + + QCheckBox *wireframe = new QCheckBox(tr("Render as wireframe")); + //connect(wireframe, SIGNAL(toggled(bool)), this, SLOT(enableWireframe(bool))); + controls->layout()->addWidget(wireframe); + + QCheckBox *normals = new QCheckBox(tr("Display normals vectors")); + //connect(normals, SIGNAL(toggled(bool)), this, SLOT(enableNormals(bool))); + controls->layout()->addWidget(normals); + + QPushButton *colorButton = new QPushButton(tr("Choose model color")); + //connect(colorButton, SIGNAL(clicked()), this, SLOT(setModelColor())); + controls->layout()->addWidget(colorButton); + + QPushButton *backgroundButton = new QPushButton(tr("Choose background color")); + //connect(backgroundButton, SIGNAL(clicked()), this, SLOT(setBackgroundColor())); + controls->layout()->addWidget(backgroundButton); + + QWidget *statistics = createDialog(tr("Model info")); + statistics->layout()->setMargin(20); + + for (int i = 0; i < 4; ++i) { + m_labels[i] = new QLabel; + statistics->layout()->addWidget(m_labels[i]); + } + + QWidget *instructions = createDialog(tr("Instructions")); + instructions->layout()->addWidget(new QLabel(tr("Use mouse wheel to zoom model, and click and drag to rotate model"))); + instructions->layout()->addWidget(new QLabel(tr("Move the sun around to change the light position"))); + + addWidget(instructions); + addWidget(controls); + addWidget(statistics); + + QPointF pos(10, 10); + Q_FOREACH (QGraphicsItem *item, items()) { + item->setFlag(QGraphicsItem::ItemIsMovable); + item->setCacheMode(QGraphicsItem::DeviceCoordinateCache); + + const QRectF rect = item->boundingRect(); + item->setPos(pos.x() - rect.x(), pos.y() - rect.y()); + pos += QPointF(0, 10 + rect.height()); + } + + //QRadialGradient gradient(40, 40, 40, 40, 40); + //gradient.setColorAt(0.2, Qt::yellow); + //gradient.setColorAt(1, Qt::transparent); + + //m_lightItem = new QGraphicsRectItem(0, 0, 80, 80); + //m_lightItem->setPen(Qt::NoPen); + //m_lightItem->setBrush(gradient); + //m_lightItem->setFlag(QGraphicsItem::ItemIsMovable); + //m_lightItem->setPos(800, 200); + //addItem(m_lightItem); + + loadModel(QLatin1String("qt.obj")); + m_time.start(); +} + +GraphicsScene::~GraphicsScene() +{ + sceneNode->unref(); + rootNode->unref(); +} + +void GraphicsScene::viewAll() +{ + sceneCamera->viewAll(rootNode, SbViewportRegion(width(),height())); +} + +SoSeparator* GraphicsScene::getSceneGraph() const +{ + return sceneNode; +} + +#include +#include + +void GraphicsScene::drawBackground(QPainter *painter, const QRectF &) +{ + if (painter->paintEngine()->type() != QPaintEngine::OpenGL) { + qWarning("GraphicsScene: drawBackground needs a QGLWidget to be set as viewport on the graphics view"); + return; + } + + glViewport(0, 0, width(), height()); +/**/ + glClearColor(m_backgroundColor.redF(), m_backgroundColor.greenF(), m_backgroundColor.blueF(), 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + //glDepthRange(0.1,1.0); // + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + //gluPerspective(70, width() / height(), 0.01, 1000); + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + //const float pos[] = { m_lightItem->x() - width() / 2, height() / 2 - m_lightItem->y(), 512, 0 }; + //glLightfv(GL_LIGHT0, GL_POSITION, pos); + glColor4f(m_modelColor.redF(), m_modelColor.greenF(), m_modelColor.blueF(), 1.0f); + + const int delta = m_time.elapsed() - m_lastTime; + m_lastTime += delta; + + //glTranslatef(0, 0, -m_distance); + //glRotatef(m_rotation.x, 1, 0, 0); + //glRotatef(m_rotation.y, 0, 1, 0); + //glRotatef(m_rotation.z, 0, 0, 1); + + //glEnable(GL_MULTISAMPLE); + //m_model->render(m_wireframeEnabled, m_normalsEnabled); + //glDisable(GL_MULTISAMPLE); + + glPopMatrix(); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); +/**/ +/**/ + glPushAttrib(GL_ALL_ATTRIB_BITS); + glViewport(0, 0, width(), height()); + glEnable(GL_DEPTH_TEST); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glDepthRange(0.1,1.0); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + + SoGLRenderAction gl(SbViewportRegion(width(),height())); + gl.apply(rootNode); + + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + + glPopAttrib(); + + glViewport(0, 0, width(), height()); + glColor3f(1,1,1); + glLineWidth(4); + glBegin(GL_LINES); + glVertex3i(0, 0, 0); + glVertex3i(400, 400, 0); + glEnd(); +/**/ + + painter->save(); + painter->fillRect(40,40,40,60,Qt::lightGray); + painter->drawText(50,50, QString::fromAscii("Done with QPainter")); + painter->restore(); + + QTimer::singleShot(20, this, SLOT(update())); +} + +void GraphicsScene::loadModel() +{ + loadModel(QFileDialog::getOpenFileName(0, tr("Choose model"), QString(), QLatin1String("*.obj"))); +} + +void GraphicsScene::loadModel(const QString &filePath) +{ + if (filePath.isEmpty()) + return; + + m_modelButton->setEnabled(false); + QApplication::setOverrideCursor(Qt::BusyCursor); + modelLoaded(); +} + +void GraphicsScene::modelLoaded() +{ + m_modelButton->setEnabled(true); + QApplication::restoreOverrideCursor(); +} + +void GraphicsScene::enableWireframe(bool enabled) +{ + m_wireframeEnabled = enabled; + update(); +} + +void GraphicsScene::enableNormals(bool enabled) +{ + m_normalsEnabled = enabled; + update(); +} + +void GraphicsScene::setModelColor() +{ + const QColor color = QColorDialog::getColor(m_modelColor); + if (color.isValid()) { + m_modelColor = color; + update(); + } +} + +void GraphicsScene::setBackgroundColor() +{ + const QColor color = QColorDialog::getColor(m_backgroundColor); + if (color.isValid()) { + m_backgroundColor = color; + update(); + } +} + +void GraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + QGraphicsScene::mouseMoveEvent(event); + if (event->isAccepted()) + return; + if (event->buttons() & Qt::LeftButton) { + const QPointF delta = event->scenePos() - event->lastScenePos(); + //const Point3d angularImpulse = Point3d(delta.y(), delta.x(), 0) * 0.1; + + //m_rotation += angularImpulse; + //m_accumulatedMomentum += angularImpulse; + + event->accept(); + update(); + } +} + +void GraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + QGraphicsScene::mousePressEvent(event); + if (event->isAccepted()) + return; + + m_mouseEventTime = m_time.elapsed(); + //m_angularMomentum = m_accumulatedMomentum = Point3d(); + event->accept(); +} + +void GraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + QGraphicsScene::mouseReleaseEvent(event); + if (event->isAccepted()) + return; + + const int delta = m_time.elapsed() - m_mouseEventTime; + //m_angularMomentum = m_accumulatedMomentum * (1000.0 / qMax(1, delta)); + event->accept(); + update(); +} + +void GraphicsScene::wheelEvent(QGraphicsSceneWheelEvent *event) +{ + QGraphicsScene::wheelEvent(event); + if (event->isAccepted()) + return; + + //m_distance *= qPow(1.2, -event->delta() / 120); + event->accept(); + update(); +} + + +GraphicsView3D::GraphicsView3D(Gui::Document* doc, QWidget* parent) + : Gui::MDIView(doc, parent), m_Scene(new GraphicsScene()), m_view(new GraphicsView) +{ + m_view->setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers))); + m_view->setViewportUpdateMode(QGraphicsView::FullViewportUpdate); + m_view->setScene(m_Scene); + + std::vector v = doc->getViewProvidersOfType(ViewProvider::getClassTypeId()); + for (std::vector::iterator it = v.begin(); it != v.end(); ++it) + m_Scene->getSceneGraph()->addChild((*it)->getRoot()); + setCentralWidget(m_view); + m_Scene->viewAll(); +} + +GraphicsView3D::~GraphicsView3D() +{ +} + +#include "moc_GLGraphicsView.cpp" diff --git a/src/Mod/Sandbox/Gui/GLGraphicsView.h b/src/Mod/Sandbox/Gui/GLGraphicsView.h new file mode 100644 index 000000000..01b581db6 --- /dev/null +++ b/src/Mod/Sandbox/Gui/GLGraphicsView.h @@ -0,0 +1,108 @@ +/*************************************************************************** + * Copyright (c) 2013 Werner Mayer * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#ifndef GUI_GRAPHICSVIEW_H +#define GUI_GRAPHICSVIEW_H + +#include +#include +#include + +class QGraphicsView; +class QDialog; +class QLabel; +class SoCamera; +class SoSeparator; + +namespace Gui { + +class /*GuiExport*/ GraphicsScene : public QGraphicsScene +{ + Q_OBJECT + +public: + GraphicsScene(); + virtual ~GraphicsScene(); + + void drawBackground(QPainter *painter, const QRectF &rect); + + void enableWireframe(bool enabled); + void enableNormals(bool enabled); + void setModelColor(); + void setBackgroundColor(); + void loadModel(); + void loadModel(const QString &filePath); + void modelLoaded(); + void viewAll(); + SoSeparator* getSceneGraph() const; + +protected: + void mousePressEvent(QGraphicsSceneMouseEvent *event); + void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + void wheelEvent(QGraphicsSceneWheelEvent * wheelEvent); + +private: + QDialog *createDialog(const QString &windowTitle) const; + + bool m_wireframeEnabled; + bool m_normalsEnabled; + + QColor m_modelColor; + QColor m_backgroundColor; + + QTime m_time; + int m_lastTime; + int m_mouseEventTime; + + float m_distance; + + QLabel *m_labels[4]; + QWidget *m_modelButton; + + SoSeparator* rootNode; + mutable SoSeparator* sceneNode; + SoCamera* sceneCamera; + + QGraphicsRectItem *m_lightItem; +}; + +class /*GuiExport*/ GraphicsView3D : public Gui::MDIView +{ + Q_OBJECT + +public: + GraphicsView3D(Gui::Document* doc, QWidget* parent = 0); + virtual ~GraphicsView3D(); + GraphicsScene* getScene() + { return m_Scene; } + +private: + GraphicsScene *m_Scene; + QGraphicsView *m_view; +}; + +} // namespace Gui + +#endif // GUI_GRAPHICSVIEW_H + diff --git a/src/Mod/Sandbox/Gui/Overlay.cpp b/src/Mod/Sandbox/Gui/Overlay.cpp new file mode 100644 index 000000000..ce0f68309 --- /dev/null +++ b/src/Mod/Sandbox/Gui/Overlay.cpp @@ -0,0 +1,643 @@ +/*************************************************************************** + * Copyright (c) 2013 Werner Mayer * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#include "PreCompiled.h" +#ifndef _PreComp_ +# include +# include +# include +# include +# include +# include +# include +#endif + +#include +#include +#include +#include +#include +#include + + +#include "Overlay.h" + +using namespace SandboxGui; + + +class MyPaintable : public Gui::GLGraphicsItem +{ + QGLFramebufferObject* fbo; + SoQtViewer* view; + QImage img; +public: + ~MyPaintable() + { + } + MyPaintable(Gui::View3DInventorViewer* v) :view(v), img(v->getGLWidget()->size(), QImage::Format_ARGB32) + { + img.fill(qRgba(255, 255, 255, 0)); + { + QPainter p(&img); + p.setPen(Qt::white); + p.drawText(200,200,QString::fromAscii("Render to QImage")); + } + + img = QGLWidget::convertToGLFormat(img); + fbo = new QGLFramebufferObject(v->getGLWidget()->size()); + fbo->bind(); + //glClear(GL_COLOR_BUFFER_BIT); + fbo->release(); + { + QPainter p(fbo); + p.setPen(Qt::white); + p.drawText(200,200,QString::fromAscii("Render to QGLFramebufferObject")); + p.end(); + //img = fbo->toImage(); + //img = QGLWidget::convertToGLFormat(img); + } + //fbo->bind(); + //glEnable(GL_DEPTH_TEST); + //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + //glDepthRange(0.1,1.0); + //glEnable(GL_LINE_SMOOTH); + //SoGLRenderAction a(SbViewportRegion(128,128)); + //a.apply(v->getSceneManager()->getSceneGraph()); + //fbo->release(); + //img = fbo->toImage(); + //img = QGLWidget::convertToGLFormat(img); + + view->scheduleRedraw(); + } + #ifndef GL_MULTISAMPLE + #define GL_MULTISAMPLE 0x809D + #endif + void paintGL() + { + const SbViewportRegion vp = view->getViewportRegion(); + SbVec2s size = vp.getViewportSizePixels(); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0, size[0], 0, size[1], -1, 1); + + glPushAttrib(GL_ALL_ATTRIB_BITS); + glEnable(GL_BLEND); + glDisable(GL_DEPTH_TEST); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor4d(0.0,0.0,1.0,0.0f); + glRasterPos2d(0,0); + + //http://wiki.delphigl.com/index.php/Multisampling + //glDrawPixels(img.width(),img.height(),GL_RGBA,GL_UNSIGNED_BYTE,img.bits()); +/* + fbo->bind(); + GLuint* buf = new GLuint[size[0]*size[1]]; + glReadPixels(0, 0, size[0], size[1], GL_RGBA, GL_UNSIGNED_BYTE, buf); + fbo->release(); + glDrawPixels(size[0],size[1],GL_RGBA,GL_UNSIGNED_BYTE,buf); + delete [] buf; +*/ +/* + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, fbo->texture()); + glBegin(GL_QUADS); + glTexCoord2f(0.0,0.0); + glVertex2f(-1.0,-1.0); + glTexCoord2f(0.0,1.0); + glVertex2f(-1.0,1.0); + glTexCoord2f(1.0,1.0); + glVertex2f(1.0,1.0); + glTexCoord2f(1.0,0.0); + glVertex2f(1.0,-1.0); + glEnd(); + glDisable(GL_TEXTURE_2D); +*/ + + + glPopAttrib(); + glPopMatrix(); + } +}; + +class Teapots : public Gui::GLGraphicsItem +{ + QGLFramebufferObject *fbObject; + GLuint glTeapotObject; + QPoint rubberBandCorner1; + QPoint rubberBandCorner2; + bool rubberBandIsShown; + SoQtViewer* view; + +public: +Teapots(Gui::View3DInventorViewer* v) :view(v) +{ + const SbViewportRegion vp = view->getViewportRegion(); + SbVec2s size = vp.getViewportSizePixels(); + + rubberBandIsShown = false; + +// makeCurrent(); + fbObject = new QGLFramebufferObject(size[0],size[1], + QGLFramebufferObject::Depth); + //initializeGL(); + resizeGL(size[0],size[1]); + + rubberBandIsShown = true; + rubberBandCorner1.setX(200); + rubberBandCorner1.setY(200); + rubberBandCorner2.setX(800); + rubberBandCorner2.setY(600); + + view->scheduleRedraw(); +} + +~Teapots() +{ + delete fbObject; + glDeleteLists(glTeapotObject, 1); +} + +void initializeGL() +{ + static const GLfloat ambient[] = { 0.0, 0.0, 0.0, 1.0 }; + static const GLfloat diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; + static const GLfloat position[] = { 0.0, 3.0, 3.0, 0.0 }; + static const GLfloat lmodelAmbient[] = { 0.2f, 0.2f, 0.2f, 1.0f }; + static const GLfloat localView[] = { 0.0 }; + + glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); + glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); + glLightfv(GL_LIGHT0, GL_POSITION, position); + glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodelAmbient); + glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, localView); + + glFrontFace(GL_CW); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_AUTO_NORMAL); + glEnable(GL_NORMALIZE); + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); +} + +void resizeGL(int width, int height) +{ +#if 0 + fbObject->bind(); + + glDisable(GL_TEXTURE_2D); + glEnable(GL_LIGHTING); + glEnable(GL_DEPTH_TEST); + + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + if (width <= height) { + glOrtho(0.0, 20.0, 0.0, 20.0 * GLfloat(height) / GLfloat(width), + -10.0, 10.0); + } else { + glOrtho(0.0, 20.0 * GLfloat(width) / GLfloat(height), 0.0, 20.0, + -10.0, 10.0); + } + glMatrixMode(GL_MODELVIEW); + drawTeapots(); + + fbObject->release(); +#else + fbObject->bind(); + glDisable(GL_TEXTURE_2D); + glEnable(GL_LIGHTING); + glEnable(GL_DEPTH_TEST); + glEnable(GL_LINE_SMOOTH); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glDepthRange(0.1,1.0); + SoGLRenderAction gl(SbViewportRegion(fbObject->size().width(),fbObject->size().height())); + gl.apply(view->getSceneManager()->getSceneGraph()); + fbObject->release(); +#endif +} + +void paintGL() +{ + const SbViewportRegion vp = view->getViewportRegion(); + SbVec2s size = vp.getViewportSizePixels(); + + + glDisable(GL_LIGHTING); + glViewport(0, 0, size[0], size[1]); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glDisable(GL_DEPTH_TEST); + + glClear(GL_COLOR_BUFFER_BIT); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, fbObject->texture()); + glColor3f(1.0, 1.0, 1.0); + GLfloat s = size[0] / GLfloat(fbObject->size().width()); + GLfloat t = size[1] / GLfloat(fbObject->size().height()); + + glBegin(GL_QUADS); + glTexCoord2f(0.0, 0.0); + glVertex2f(-1.0, -1.0); + glTexCoord2f(s, 0.0); + glVertex2f(1.0, -1.0); + glTexCoord2f(s, t); + glVertex2f(1.0, 1.0); + glTexCoord2f(0.0, t); + glVertex2f(-1.0, 1.0); + glEnd(); + + if (rubberBandIsShown) { + glMatrixMode(GL_PROJECTION); + glOrtho(0, size[0], size[1], 0, 0, 100); + glMatrixMode(GL_MODELVIEW); + glDisable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glLineWidth(4.0); + glColor4f(1.0f, 1.0f, 1.0f, 0.2f); + glRecti(rubberBandCorner1.x(), rubberBandCorner1.y(), + rubberBandCorner2.x(), rubberBandCorner2.y()); + glColor4f(1.0, 1.0, 0.0, 0.5); + glLineStipple(3, 0xAAAA); + glEnable(GL_LINE_STIPPLE); + + glBegin(GL_LINE_LOOP); + glVertex2i(rubberBandCorner1.x(), rubberBandCorner1.y()); + glVertex2i(rubberBandCorner2.x(), rubberBandCorner1.y()); + glVertex2i(rubberBandCorner2.x(), rubberBandCorner2.y()); + glVertex2i(rubberBandCorner1.x(), rubberBandCorner2.y()); + glEnd(); + + glLineWidth(1.0); + glDisable(GL_LINE_STIPPLE); + glDisable(GL_BLEND); + } + + glEnable(GL_LIGHTING); + glEnable(GL_DEPTH_TEST); +} + +void mousePressEvent(QMouseEvent *event) +{ + rubberBandCorner1 = event->pos(); + rubberBandCorner2 = event->pos(); + rubberBandIsShown = true; +} + +void mouseMoveEvent(QMouseEvent *event) +{ + if (rubberBandIsShown) { + rubberBandCorner2 = event->pos(); +// updateGL(); + } +} + +void mouseReleaseEvent(QMouseEvent * /* event */) +{ + if (rubberBandIsShown) { + rubberBandIsShown = false; +// updateGL(); + } +} + +}; + +class Rubberband : public Gui::GLGraphicsItem +{ + QPoint rubberBandCorner1; + QPoint rubberBandCorner2; + Gui::View3DInventorViewer* view; + +public: +Rubberband(Gui::View3DInventorViewer* v) :view(v) +{ + rubberBandCorner1.setX(200); + rubberBandCorner1.setY(200); + rubberBandCorner2.setX(800); + rubberBandCorner2.setY(600); + v->setRenderFramebuffer(true); + v->scheduleRedraw(); +} + +~Rubberband() +{ +} + +void paintGL() +{ + const SbViewportRegion vp = view->getViewportRegion(); + SbVec2s size = vp.getViewportSizePixels(); + + + //glDisable(GL_LIGHTING); + //glViewport(0, 0, size[0], size[1]); + //glMatrixMode(GL_PROJECTION); + //glLoadIdentity(); + //glMatrixMode(GL_MODELVIEW); + //glLoadIdentity(); + //glDisable(GL_DEPTH_TEST); + + //glClear(GL_COLOR_BUFFER_BIT); + + glMatrixMode(GL_PROJECTION); + glOrtho(0, size[0], size[1], 0, 0, 100); + glMatrixMode(GL_MODELVIEW); + glDisable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glLineWidth(4.0); + glColor4f(1.0f, 1.0f, 1.0f, 0.2f); + glRecti(rubberBandCorner1.x(), rubberBandCorner1.y(), + rubberBandCorner2.x(), rubberBandCorner2.y()); + glColor4f(1.0, 1.0, 0.0, 0.5); + glLineStipple(3, 0xAAAA); + glEnable(GL_LINE_STIPPLE); + + glBegin(GL_LINE_LOOP); + glVertex2i(rubberBandCorner1.x(), rubberBandCorner1.y()); + glVertex2i(rubberBandCorner2.x(), rubberBandCorner1.y()); + glVertex2i(rubberBandCorner2.x(), rubberBandCorner2.y()); + glVertex2i(rubberBandCorner1.x(), rubberBandCorner2.y()); + glEnd(); + + glLineWidth(1.0); + glDisable(GL_LINE_STIPPLE); + glDisable(GL_BLEND); + + //glEnable(GL_LIGHTING); + //glEnable(GL_DEPTH_TEST); +} + +}; + + +void paintSelection() +{ +#if 0 + SoAnnotation* hudRoot = new SoAnnotation; + hudRoot->ref(); + + SoOrthographicCamera* hudCam = new SoOrthographicCamera(); + hudCam->viewportMapping = SoCamera::LEAVE_ALONE; + // Set the position in the window. + // [0, 0] is in the center of the screen. + // + SoTranslation* hudTrans = new SoTranslation; + hudTrans->translation.setValue(-1.0f, -1.0f, 0.0f); + + QImage image(100,100,QImage::Format_ARGB32_Premultiplied); + image.fill(0x00000000); + SoSFImage sfimage; + Gui::BitmapFactory().convert(image, sfimage); + SoImage* hudImage = new SoImage(); + hudImage->image = sfimage; + + // Assemble the parts... + // + hudRoot->addChild(hudCam); + hudRoot->addChild(hudTrans); + hudRoot->addChild(hudImage); + + Gui::View3DInventorViewer* viewer = this->getViewer(); + static_cast(viewer->getSceneGraph())->addChild(hudRoot); + + QWidget* gl = viewer->getGLWidget(); + DrawingPlane pln(hudImage->image, viewer, gl); + gl->installEventFilter(&pln); + QEventLoop loop; + QObject::connect(&pln, SIGNAL(emitSelection()), &loop, SLOT(quit())); + loop.exec(); + static_cast(viewer->getSceneGraph())->removeChild(hudRoot); +#endif +} + +// --------------------------------------- +#include +#include +#include +#if 0 +void MeshSelection::prepareBrushSelection(bool add) +{ + // a rubberband to select a rectangle area of the meshes + Gui::View3DInventorViewer* viewer = this->getViewer(); + if (viewer) { + stopInteractiveCallback(viewer); + startInteractiveCallback(viewer, selectGLCallback); + // set cross cursor + DrawingPlane* brush = new DrawingPlane(); + //brush->setColor(1.0f,0.0f,0.0f); + //brush->setLineWidth(3.0f); + viewer->navigationStyle()->startSelection(brush); + SoQtCursor::CustomCursor custom; + custom.dim.setValue(16, 16); + custom.hotspot.setValue(7, 7); + custom.bitmap = cross_bitmap; + custom.mask = cross_mask_bitmap; + viewer->setComponentCursor(SoQtCursor(&custom)); + this->addToSelection = add; + } +} +#endif +DrawingPlane::DrawingPlane() +{ + //image.fill(qRgba(255, 255, 255, 0)); + + myPenWidth = 50; + + QRgb p = qRgba(255,255,0,0); + int q = p;//((p << 16) & 0xff0000) | ((p >> 16) & 0xff) | (p & 0xff00ff00); + int r = qRed(q); + int g = qGreen(q); + int b = qBlue(q); + myPenColor = qRgb(r,g,b);//Qt::yellow; + myRadius = 5.0f; +} + +DrawingPlane::~DrawingPlane() +{ + terminate(); +} + +void DrawingPlane::initialize() +{ + fbo = new QGLFramebufferObject(128, 128,QGLFramebufferObject::Depth); +} + +void DrawingPlane::terminate() +{ + fbo->bind(); + glEnable(GL_DEPTH_TEST); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glDepthRange(0.1,1.0); + glEnable(GL_LINE_SMOOTH); + SoGLRenderAction a(SbViewportRegion(128,128)); + a.apply(_pcView3D->getSceneManager()->getSceneGraph()); + fbo->release(); + fbo->toImage().save(QString::fromAscii("C:/Temp/DrawingPlane.png")); + delete fbo; +} + +void DrawingPlane::draw () +{return; + if (1/*mustRedraw*/) { + SbVec2s view = _pcView3D->getSize(); + static_cast(_pcView3D->getGLWidget())->makeCurrent(); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0, view[0], 0, view[1], -1, 1); + + // Store GL state + glPushAttrib(GL_ALL_ATTRIB_BITS); + GLfloat depthrange[2]; + glGetFloatv(GL_DEPTH_RANGE, depthrange); + GLdouble projectionmatrix[16]; + glGetDoublev(GL_PROJECTION_MATRIX, projectionmatrix); + + glDepthFunc(GL_ALWAYS); + glDepthMask(GL_TRUE); + glDepthRange(0,0); + glEnable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + glEnable(GL_COLOR_MATERIAL); + glDisable(GL_BLEND); + + glLineWidth(1.0f); + glColor4f(1.0, 1.0, 1.0, 0.0); + glViewport(0, 0, view[0], view[1]); + + glEnable(GL_COLOR_LOGIC_OP); + glLogicOp(GL_XOR); + glDrawBuffer(GL_FRONT); + + + //fbo->drawTexture(QPointF(), fbo->texture()); + + glFlush(); + glLogicOp(GL_COPY); + glDisable(GL_COLOR_LOGIC_OP); + + // Reset original state + glDepthRange(depthrange[0], depthrange[1]); + glMatrixMode(GL_PROJECTION); + glLoadMatrixd(projectionmatrix); + + glPopAttrib(); + glPopMatrix(); + + mustRedraw = false; + } +} + +#include +int DrawingPlane::mouseButtonEvent(const SoMouseButtonEvent * const e, const QPoint& pos) +{ + const int button = e->getButton(); + const SbBool press = e->getState() == SoButtonEvent::DOWN ? TRUE : FALSE; + + if (press) { + switch (button) + { + case SoMouseButtonEvent::BUTTON1: + { + scribbling = true; + lastPoint = pos; + } break; + default: + { + } break; + } + } + // release + else { + switch (button) + { + case SoMouseButtonEvent::BUTTON1: + drawLineTo(pos); + scribbling = false; + return Finish; + default: + { + } break; + } + } + + return Continue; +} + +int DrawingPlane::locationEvent(const SoLocation2Event * const e, const QPoint& pos) +{ + if (scribbling) { + drawLineTo(pos); + + // filter out some points + if (selection.isEmpty()) { + selection << pos; + } + else { + const QPoint& top = selection.last(); + if (abs(top.x()-pos.x()) > 20 || + abs(top.y()-pos.y()) > 20) + selection << pos; + } + + draw(); + } + + return Continue; +} + +int DrawingPlane::keyboardEvent( const SoKeyboardEvent * const e ) +{ + return Continue; +} + +void DrawingPlane::drawLineTo(const QPoint &endPoint) +{ + return; + QPainter painter(fbo); + //QPainter painter(_pcView3D->getGLWidget()); + painter.setPen(QPen(myPenColor, myPenWidth, Qt::SolidLine, Qt::RoundCap, + Qt::RoundJoin)); + //painter.setOpacity(0.5); + //painter.drawLine(lastPoint.x(), fbo->height()-lastPoint.y(), endPoint.x(), fbo->height()-endPoint.y()); + painter.drawLine(lastPoint.x(), lastPoint.y(), endPoint.x(), endPoint.y()); + + //_pcView3D->scheduleRedraw(); + lastPoint = endPoint; +} + //Gui::Document* doc = Gui::Application::Instance->activeDocument(); + //Gui::View3DInventorViewer* view = static_cast(doc->getActiveView())->getViewer(); + ////view->addGraphicsItem(new MyPaintable(view)); + ////view->addGraphicsItem(new Teapots(view)); + //view->addGraphicsItem(new Rubberband(view)); + //.... + //Gui::Document* doc = Gui::Application::Instance->activeDocument(); + //Gui::View3DInventorViewer* view = static_cast(doc->getActiveView())->getViewer(); + //view->clearGraphicsItems(); diff --git a/src/Mod/Sandbox/Gui/Overlay.h b/src/Mod/Sandbox/Gui/Overlay.h new file mode 100644 index 000000000..3127fdd81 --- /dev/null +++ b/src/Mod/Sandbox/Gui/Overlay.h @@ -0,0 +1,64 @@ +/*************************************************************************** + * Copyright (c) 2013 Werner Mayer * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#ifndef SANDBOXGUI_OVERLAY_H +#define SANDBOXGUI_OVERLAY_H + +#include +#include +#include +#include + +class QGLFramebufferObject; + +namespace SandboxGui { +class DrawingPlane : public Gui::BaseMouseSelection +{ +public: + DrawingPlane(); + virtual ~DrawingPlane(); + +protected: + void initialize(); + void terminate(); + virtual int mouseButtonEvent( const SoMouseButtonEvent * const e, const QPoint& pos ); + virtual int locationEvent ( const SoLocation2Event * const e, const QPoint& pos ); + virtual int keyboardEvent ( const SoKeyboardEvent * const e ); + void draw (); + +private: + void drawLineTo(const QPoint &endPoint); + + bool scribbling; + int myPenWidth; + float myRadius; + QColor myPenColor; + QPoint lastPoint; + QList selection; + + QGLFramebufferObject* fbo; +}; + +} // SandboxGui + +#endif // SANDBOXGUI_OVERLAY_H diff --git a/src/Mod/Sandbox/Gui/Workbench.cpp b/src/Mod/Sandbox/Gui/Workbench.cpp index de5753616..b20329b63 100644 --- a/src/Mod/Sandbox/Gui/Workbench.cpp +++ b/src/Mod/Sandbox/Gui/Workbench.cpp @@ -104,7 +104,8 @@ Gui::MenuItem* Workbench::setupMenuBar() const << "Std_ImageNode" << "Sandbox_WidgetShape" << "Sandbox_GDIWidget" - << "Sandbox_RedirectPaint"; + << "Sandbox_RedirectPaint" + << "Std_TestGraphicsView"; Gui::MenuItem* viewer = new Gui::MenuItem; root->insertItem(item, viewer);