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
00073
00074
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
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
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
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
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