viewer.cpp

00001 #include "viewer.h"
00002 #include "model.h"
00003 
00004 #include "viewer.moc"
00005 
00006 #include <QGLFormat>
00007 #include <QDomElement>
00008 #include <QShowEvent>
00009 #include <QFileInfo>
00010 #include <QMainWindow>
00011 #include <QPalette>
00012 #include <QApplication>
00013 
00014 #include <cassert>
00015 #include <iostream>
00016 using std::cerr;
00017 using std::endl;
00018 
00019 #ifndef max
00020 int max(int a, int b) { return (a<b)?b:a; }
00021 #endif
00022 
00023 Q_DECLARE_METATYPE(QMenuBar*);
00024 Q_DECLARE_METATYPE(QMenu*);
00025 
00026 Viewer::Viewer( QWidget* parent, const QGLWidget *shareWidget, int idx)
00027   : QGLViewer(parent, shareWidget)
00028   , _model(0)
00029   , animation(false)
00030   , initialized(false)
00031   , lastInitCamera(0)
00032   , _index(idx)
00033   , block_draw(0)
00034   , minFrameInterval(0)
00035   , main_window(0)
00036 {
00037   initObject();
00038 }
00039 
00040 void Viewer::initObject()
00041 {
00042   QVariant mw = qApp->property("MainWindow");
00043   if(mw.canConvert<QObject*>())
00044     main_window = dynamic_cast<QMainWindow*>(mw.value<QObject*>());
00045   setAnimationPeriod(0);
00046   setMouseBinding( Qt::LeftButton, CAMERA, ROTATE );
00047   setMouseBinding( Qt::RightButton, NO_CLICK_ACTION );
00048   setMouseBinding( Qt::SHIFT + Qt::LeftButton, CAMERA, TRANSLATE );
00049   setMouseBinding( Qt::ALT + Qt::LeftButton, SELECT);
00050   setMouseBinding( Qt::SHIFT + Qt::CTRL + Qt::LeftButton, SELECT);
00051   setKeyDescription(Qt::ALT + Qt::CTRL + Qt::Key_F, tr("Fit the entire scene in the screen", "FIT_ENTIRE_SCENE action description"));
00052 #ifdef __APPLE__
00053   setShortcut(SAVE_SCREENSHOT, Qt::CTRL + Qt::Key_P);
00054   setShortcut(SAVE_SCREENSHOT, Qt::CTRL + Qt::ALT + Qt::Key_P);
00055   setShortcut(SAVE_SCREENSHOT, Qt::SHIFT + Qt::CTRL + Qt::ALT + Qt::Key_P);
00056 #else
00057   setShortcut(SAVE_SCREENSHOT, Qt::SHIFT + Qt::Key_Print);
00058 #endif
00059   setShortcut(CAMERA_MODE, 0);
00060   setShortcut(EXIT_VIEWER, 0);
00061   setShortcut(ANIMATION, 0);
00062   setKeyDescription(Qt::Key_Return, "Starts/stops the animation loop");
00063   setContextMenuPolicy(Qt::ActionsContextMenu);
00064   connect(this, SIGNAL(openOpenGLConfig()), mainWindow(), SLOT(configOpenGL()));
00065   connect(this, SIGNAL(modelRecordingStart()), mainWindow(), SLOT(recordModelAnimation()));
00066   connect(this, SIGNAL(modelRecordingStop()), mainWindow(), SLOT(stopRecordModelAnimation()));
00067   connect(this, SIGNAL(cameraRecordingStart()), mainWindow(), SLOT(recordCameraAnimation()));
00068   connect(this, SIGNAL(cameraRecordingStop()), mainWindow(), SLOT(stopRecordCameraAnimation()));
00069   connect(this, SIGNAL(createViewer(const QGLWidget*)), mainWindow(), SLOT(addViewer(const QGLWidget*)));
00070   connect(this, SIGNAL(createViewer(QLayout*, const QGLWidget*)), mainWindow(), SLOT(addViewer(QLayout*, const QGLWidget*)));
00071   connect(this, SIGNAL(createViewer(QWidget*, const QGLWidget*)), mainWindow(), SLOT(addViewer(QWidget*, const QGLWidget*)));
00072   //connect(this, SIGNAL(createViewer()), mainWindow(), SLOT(addViewer()));
00073   //connect(this, SIGNAL(createViewer(QLayout*)), mainWindow(), SLOT(addViewer(QLayout*)));
00074   //connect(this, SIGNAL(createViewer(QWidget*)), mainWindow(), SLOT(addViewer(QWidget*)));
00075 
00076   QVariant args = mainWindow()->property("minFrameInterval");
00077   if(args.isValid())
00078   {
00079     if(args.type() == QVariant::Int)
00080     {
00081       minFrameInterval = args.toInt();
00082     }
00083   }
00084 }
00085 
00086 Viewer::~Viewer()
00087 {
00088   if(_model)
00089   {
00090     _model->finalizeDraw(this);
00091   }
00092   saveStateToFile();
00093 }
00094 
00095 void Viewer::init()
00096 {
00097   QGLViewer::init();
00098   initCamera();
00099   if(_model)
00100   {
00101     _model->initDraw( this );
00102     //showEntireScene();
00103   }
00104 }
00105 
00106 void Viewer::setModel( Model* m )
00107 {
00108   this->_model = m;
00109   if(initialized) this->init();
00110   updateGL();
00111   update();
00112 }
00113 
00114 void Viewer::postDraw()
00115 {
00116   if(_model and !block_draw)
00117     _model->postDraw(this);
00118   QGLViewer::postDraw();
00119 }
00120 
00121 void Viewer::initFromDOMElement(const QDomElement &element )
00122 {
00123   // Restore standard state
00124   QGLViewer::initFromDOMElement(element);
00125 
00126   QGLFormat def = QGLFormat::defaultFormat();
00127 
00128   QDomElement child=element.firstChild().toElement();
00129   while (!child.isNull())
00130   {
00131     if (child.tagName() == "GLFormat")
00132     {
00133       if (child.hasAttribute("alpha"))
00134         def.setAlpha(child.attribute("alpha").toLower() == "yes");
00135       if (child.hasAttribute("depth"))
00136         def.setDepth(child.attribute("depth").toLower() == "yes");
00137       if (child.hasAttribute("rgba"))
00138         def.setRgba(child.attribute("rgba").toLower() == "yes");
00139       if (child.hasAttribute("stereo"))
00140         def.setStereo(child.attribute("stereo").toLower() == "yes");
00141       if (child.hasAttribute("stencil"))
00142         def.setStencil(child.attribute("stencil").toLower() == "yes");
00143       if (child.hasAttribute("doubleBuffer"))
00144         def.setDoubleBuffer(child.attribute("doubleBuffer").toLower() == "yes");
00145       if (child.hasAttribute("sampleBuffers"))
00146         def.setSampleBuffers(child.attribute("sampleBuffers").toLower() == "yes");
00147       if (child.hasAttribute("directRendering"))
00148         def.setDirectRendering(child.attribute("directRendering").toLower() == "yes");
00149       if (child.hasAttribute("hasOverlay"))
00150         def.setOverlay(child.attribute("hasOverlay").toLower() == "yes");
00151       if(def.accum())
00152         if (child.hasAttribute("accumBufferSize"))
00153           def.setAccumBufferSize(child.attribute("accumBufferSize").toInt());
00154       if(def.alpha())
00155         if (child.hasAttribute("alphaBufferSize"))
00156           def.setAlphaBufferSize(child.attribute("alphaBufferSize").toInt());
00157       if(def.depth())
00158         if (child.hasAttribute("depthBufferSize"))
00159           def.setDepthBufferSize(child.attribute("depthBufferSize").toInt());
00160       if(def.sampleBuffers())
00161         if (child.hasAttribute("samples"))
00162           def.setSamples(child.attribute("samples").toInt());
00163       if(def.stencil())
00164         if (child.hasAttribute("stencilBufferSize"))
00165           def.setStencilBufferSize(child.attribute("stencilBufferSize").toInt());
00166       if(def.rgba())
00167       {
00168         if (child.hasAttribute("redBufferSize"))
00169           def.setRedBufferSize(child.attribute("redBufferSize").toInt());
00170         if (child.hasAttribute("greenBufferSize"))
00171           def.setGreenBufferSize(child.attribute("greenBufferSize").toInt());
00172         if (child.hasAttribute("blueBufferSize"))
00173           def.setBlueBufferSize(child.attribute("blueBufferSize").toInt());
00174       }
00175     }
00176     child = child.nextSibling().toElement();
00177   }
00178   QGLFormat::setDefaultFormat(def);
00179 }
00180 
00181 QDomElement Viewer::domElement(const QString & name, QDomDocument &document) const
00182 {
00183   // Creates a custom node for a light
00184   QDomElement de = document.createElement("GLFormat");
00185   QGLFormat def = QGLFormat::defaultFormat();
00186   de.setAttribute("accum", (def.accum()?"yes":"no"));
00187   if(def.accum() && def.accumBufferSize() != -1)
00188     de.setAttribute("accumBufferSize", max(0, def.accumBufferSize()));
00189   de.setAttribute("alpha", (def.alpha()?"yes":"no"));
00190   if(def.alpha() && def.alphaBufferSize() != -1)
00191     de.setAttribute("alphaBufferSize", max(0, def.alphaBufferSize()));
00192   de.setAttribute("depth", (def.depth()?"yes":"no"));
00193   if(def.depth() && def.depthBufferSize() != -1)
00194     de.setAttribute("depthBufferSize", max(0, def.depthBufferSize()));
00195   de.setAttribute("doubleBuffer", (def.doubleBuffer()?"yes":"no"));
00196   de.setAttribute("directRendering", (def.directRendering()?"yes":"no"));
00197   de.setAttribute("hasOverlay", (def.hasOverlay()?"yes":"no"));
00198   de.setAttribute("rgba", (def.rgba()?"yes":"no"));
00199   if(def.rgba())
00200   {
00201     if(def.redBufferSize() != -1)
00202       de.setAttribute("redBufferSize", max(0, def.redBufferSize()));
00203     if(def.greenBufferSize() != -1)
00204       de.setAttribute("greenBufferSize", max(0, def.greenBufferSize()));
00205     if(def.blueBufferSize() != -1)
00206       de.setAttribute("blueBufferSize", max(0, def.blueBufferSize()));
00207   }
00208   de.setAttribute("sampleBuffers", (def.sampleBuffers()?"yes":"no"));
00209   if(def.sampleBuffers() && def.samples() != -1)
00210     de.setAttribute("samples", max(0, def.samples()));
00211   de.setAttribute("stereo", (def.stereo()?"yes":"no"));
00212   de.setAttribute("stencil", (def.stencil()?"yes":"no"));
00213   if(def.stencil() && def.stencilBufferSize() != -1)
00214     de.setAttribute("stencilBufferSize", max(0, def.stencilBufferSize()));
00215 
00216   // Get default state domElement and append custom node
00217   QDomElement res = QGLViewer::domElement(name, document);
00218   res.appendChild(de);
00219   return res;
00220 }
00221 
00222 void Viewer::initFormat()
00223 {
00224   QGLFormat def = QGLFormat::defaultFormat();
00225   QFile file(".qglviewer.xml");
00226   if(file.open(QIODevice::ReadOnly))
00227   {
00228     QDomDocument doc("QGLViewer");
00229     doc.setContent(&file);
00230     file.close();
00231     QDomElement root = doc.firstChildElement("QGLViewer");
00232     QDomElement child = root.firstChildElement("GLFormat");
00233     if(!child.isNull())
00234     {
00235       if (child.hasAttribute("alpha"))
00236         def.setAlpha(child.attribute("alpha").toLower() == "yes");
00237       if (child.hasAttribute("depth"))
00238         def.setDepth(child.attribute("depth").toLower() == "yes");
00239       if (child.hasAttribute("rgba"))
00240         def.setRgba(child.attribute("rgba").toLower() == "yes");
00241       if (child.hasAttribute("stereo"))
00242         def.setStereo(child.attribute("stereo").toLower() == "yes");
00243       if (child.hasAttribute("stencil"))
00244         def.setStencil(child.attribute("stencil").toLower() == "yes");
00245       if (child.hasAttribute("doubleBuffer"))
00246         def.setDoubleBuffer(child.attribute("doubleBuffer").toLower() == "yes");
00247       if (child.hasAttribute("sampleBuffers"))
00248         def.setSampleBuffers(child.attribute("sampleBuffers").toLower() == "yes");
00249       if (child.hasAttribute("directRendering"))
00250         def.setDirectRendering(child.attribute("directRendering").toLower() == "yes");
00251       if (child.hasAttribute("hasOverlay"))
00252         def.setOverlay(child.attribute("hasOverlay").toLower() == "yes");
00253       if(def.accum())
00254         if (child.hasAttribute("accumBufferSize"))
00255           def.setAccumBufferSize(child.attribute("accumBufferSize").toInt());
00256       if(def.alpha())
00257         if (child.hasAttribute("alphaBufferSize"))
00258           def.setAlphaBufferSize(child.attribute("alphaBufferSize").toInt());
00259       if(def.depth())
00260         if (child.hasAttribute("depthBufferSize"))
00261           def.setDepthBufferSize(child.attribute("depthBufferSize").toInt());
00262       if(def.sampleBuffers())
00263         if (child.hasAttribute("samples"))
00264           def.setSamples(child.attribute("samples").toInt());
00265       if(def.stencil())
00266         if (child.hasAttribute("stencilBufferSize"))
00267           def.setStencilBufferSize(child.attribute("stencilBufferSize").toInt());
00268       if(def.rgba())
00269       {
00270         if (child.hasAttribute("redBufferSize"))
00271           def.setRedBufferSize(child.attribute("redBufferSize").toInt());
00272         if (child.hasAttribute("greenBufferSize"))
00273           def.setGreenBufferSize(child.attribute("greenBufferSize").toInt());
00274         if (child.hasAttribute("blueBufferSize"))
00275           def.setBlueBufferSize(child.attribute("blueBufferSize").toInt());
00276       }
00277     }
00278   }
00279   QGLFormat::setDefaultFormat(def);
00280 }
00281 
00282 
00283 void Viewer::showEvent(QShowEvent* event)
00284 {
00285   QGLViewer::showEvent(event);
00286   if(!initialized)
00287   {
00288     restoreStateFromFile();
00289     lastInitCamera = camera();
00290     initialized = true;
00291   }
00292 }
00293 
00294 void Viewer::initCamera()
00295 {
00296   camera()->setType(qglviewer::Camera::ORTHOGRAPHIC);
00297   if(camera() != lastInitCamera)
00298   {
00299     restoreStateFromFile();
00300     lastInitCamera = camera();
00301   }
00302 }
00303 
00304 void Viewer::setStatusMessage(const QString& msg)
00305 {
00306   bool success = parent()->setProperty("statusMessage", msg);
00307   assert(success);
00308 }
00309 
00310 QString Viewer::statusMessage() const
00311 {
00312   QString result = parent()->property("statusMessage").toString();
00313   return result;
00314 }
00315 
00316 QToolBar* Viewer::addToolBar(const QString& title)
00317 {
00318   return mainWindow()->addToolBar(title);
00319 }
00320 
00321 void Viewer::addToolBar(Qt::ToolBarArea area, QToolBar* toolbar)
00322 {
00323   mainWindow()->addToolBar(area, toolbar);
00324 }
00325 
00326 QMainWindow* Viewer::mainWindow()
00327 {
00328   return main_window;
00329 }
00330 
00331 QMenuBar* Viewer::menuBar(bool clear)
00332 {
00333   const char* property_name;
00334   if(clear)
00335   {
00336     property_name = "menuBar";
00337   }
00338   else
00339   {
00340     property_name = "existingMenuBar";
00341   }
00342   QVariant mb = mainWindow()->property(property_name);
00343   if(mb.isValid())
00344   {
00345     QMenuBar* bar = mb.value<QMenuBar*>();
00346     return bar;
00347   }
00348   return 0;
00349 }
00350 
00351 QMenu* Viewer::helpMenu()
00352 {
00353   QVariant hm = mainWindow()->property("helpMenu");
00354   if(hm.isValid())
00355   {
00356     QMenu* menu = hm.value<QMenu*>();
00357     return menu;
00358   }
00359   return 0;
00360 }
00361 
00362 void Viewer::configOpenGL()
00363 {
00364   emit openOpenGLConfig();
00365 }
00366 
00367 void Viewer::updateAll()
00368 {
00369   updateGL();
00370   update();
00371 }
00372 
00373 void Viewer::startRecordingCameraAnimation()
00374 {
00375   emit cameraRecordingStart();
00376 }
00377 
00378 void Viewer::stopRecordingCameraAnimation()
00379 {
00380   emit cameraRecordingStop();
00381 }
00382 
00383 void Viewer::startRecordingModelAnimation()
00384 {
00385   emit modelRecordingStart();
00386 }
00387 
00388 void Viewer::stopRecordingModelAnimation()
00389 {
00390   emit modelRecordingStop();
00391 }
00392 
00393 void Viewer::keyPressEvent(QKeyEvent *e)
00394 {
00395   switch(e->key())
00396   {
00397     case Qt::Key_F:
00398       if(index() < 0 and e->modifiers() == (Qt::AltModifier | Qt::ControlModifier))
00399       {
00400         showEntireScene();
00401         return;
00402       }
00403       break;
00404     default:
00405       break;
00406   }
00407   QGLViewer::keyPressEvent(e);
00408 }
00409 
00410 void Viewer::newViewer(const QGLWidget* shareWidget)
00411 {
00412   emit createViewer(shareWidget);
00413 }
00414 
00415 void Viewer::addViewer(QWidget *w, const QGLWidget* shareWidget)
00416 {
00417   emit createViewer(w, shareWidget);
00418 }
00419 
00420 void Viewer::addViewer(QLayout *l, const QGLWidget* shareWidget)
00421 {
00422   emit createViewer(l, shareWidget);
00423 }
00424 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Fri May 31 15:37:53 2013 for VVE by  doxygen 1.6.3