24 #include "qglviewer.h"
26 #include "keyFrameInterpolator.h"
28 #if QT_VERSION >= 0x040000
29 # include <QtAlgorithms>
31 # include <QApplication>
34 # include <QMessageBox>
35 # include <QPushButton>
36 # include <QTabWidget>
37 # include <QTextStream>
38 # include <QMouseEvent>
44 # include <qapplication.h>
45 # include <qfileinfo.h>
46 # include <qdatetime.h>
47 # include <qmessagebox.h>
48 # include <qpushbutton.h>
49 # include <qtabwidget.h>
50 # include <qtextstream.h>
53 # include <qtextedit.h>
54 # include <qkeysequence.h>
57 # define KeyboardModifierMask KeyButtonMask
63 using namespace qglviewer;
66 #if QT_VERSION >= 0x040000
67 QList<QGLViewer*> QGLViewer::QGLViewerPool_;
69 QPtrList<QGLViewer> QGLViewer::QGLViewerPool_;
96 void QGLViewer::defaultConstructor()
109 #if QT_VERSION >= 0x040000
110 int poolIndex = QGLViewer::QGLViewerPool_.indexOf(NULL);
111 setFocusPolicy(Qt::StrongFocus);
113 int poolIndex = QGLViewer::QGLViewerPool_.findRef(NULL);
114 setFocusPolicy(QWidget::StrongFocus);
118 QGLViewer::QGLViewerPool_.replace(poolIndex,
this);
120 QGLViewer::QGLViewerPool_.append(
this);
125 setDefaultShortcuts();
126 setDefaultMouseBindings();
128 setSnapshotFileName(tr(
"snapshot",
"Default snapshot file name"));
129 initializeSnapshotFormats();
130 setSnapshotCounter(0);
131 setSnapshotQuality(95);
136 fpsString_ = tr(
"%1Hz",
"Frames per seconds, in Hertz").arg(
"?");
142 manipulatedFrame_ = NULL;
143 manipulatedFrameIsACamera_ =
false;
144 mouseGrabberIsAManipulatedFrame_ =
false;
145 mouseGrabberIsAManipulatedCameraFrame_ =
false;
146 displayMessage_ =
false;
147 connect(&messageTimer_, SIGNAL(timeout()), SLOT(hideMessage()));
148 #if QT_VERSION >= 0x040000
149 messageTimer_.setSingleShot(
true);
152 setMouseGrabber(NULL);
156 setStateFileName(
".qglviewer.xml");
159 setAxisIsDrawn(
false);
160 setGridIsDrawn(
false);
161 setFPSIsDisplayed(
false);
162 setCameraIsEdited(
false);
163 setTextIsEnabled(
true);
164 setStereoDisplay(
false);
165 setFullScreen(
false);
167 animationTimerId_ = 0;
169 setAnimationPeriod(40);
171 selectBuffer_ = NULL;
172 setSelectBufferSize(4*1000);
173 setSelectRegionWidth(3);
174 setSelectRegionHeight(3);
177 bufferTextureId_ = 0;
178 bufferTextureMaxU_ = 0.0;
179 bufferTextureMaxV_ = 0.0;
180 bufferTextureWidth_ = 0;
181 bufferTextureHeight_ = 0;
182 previousBufferTextureFormat_ = 0;
183 previousBufferTextureInternalFormat_ = 0;
185 #if QT_VERSION >= 0x040000
186 setAttribute(Qt::WA_NoSystemBackground);
192 #if QT_VERSION >= 0x040000
200 QGLViewer::QGLViewer(QWidget* parent,
const QGLWidget* shareWidget, Qt::WFlags flags)
201 : QGLWidget(parent, shareWidget, flags)
202 { defaultConstructor(); }
209 QGLViewer::QGLViewer(QGLContext *context, QWidget* parent,
const QGLWidget* shareWidget, Qt::WFlags flags)
210 : QGLWidget(context, parent, shareWidget, flags)
211 { defaultConstructor(); }
217 QGLViewer::QGLViewer(
const QGLFormat& format, QWidget* parent,
const QGLWidget* shareWidget, Qt::WFlags flags)
218 : QGLWidget(format, parent, shareWidget, flags)
219 { defaultConstructor(); }
233 #if QT_VERSION >= 0x040000
234 QGLViewer::QGLViewerPool_.replace(QGLViewer::QGLViewerPool_.indexOf(
this), NULL);
236 QGLViewer::QGLViewerPool_.replace(QGLViewer::QGLViewerPool_.findRef(
this), NULL);
240 delete[] selectBuffer_;
244 helpWidget()->close();
250 static QString QGLViewerVersionString()
252 return QString::number((QGLVIEWER_VERSION & 0xff0000) >> 16) +
"." +
253 QString::number((QGLVIEWER_VERSION & 0x00ff00) >> 8) +
"." +
254 QString::number(QGLVIEWER_VERSION & 0x0000ff);
257 static int convertToKeyboardModifiers(
int state)
259 #if QT_VERSION < 0x040000
262 if (state & Qt::MODIFIER_MASK)
264 if (state & Qt::CTRL) { state &= ~Qt::CTRL; state |= Qt::ControlButton; }
265 if (state & Qt::SHIFT) { state &= ~Qt::SHIFT; state |= Qt::ShiftButton; }
266 if (state & Qt::ALT) { state &= ~Qt::ALT; state |= Qt::AltButton; }
267 # if QT_VERSION >= 0x030100
268 if (state & Qt::META) { state &= ~Qt::META; state |= Qt::MetaButton; }
275 static QtKeyboardModifiers convertKeyboardModifiers(QtKeyboardModifiers modifiers)
277 #if QT_VERSION < 0x040000
278 return QtKeyboardModifiers(convertToKeyboardModifiers(modifiers));
284 static int convertToShortModifier(
int state)
288 #if QT_VERSION < 0x040000
289 if (state & Qt::KeyButtonMask)
291 if (state & Qt::ControlButton) { state &= ~Qt::ControlButton; state |= Qt::CTRL; }
292 if (state & Qt::ShiftButton) { state &= ~Qt::ShiftButton; state |= Qt::SHIFT; }
293 if (state & Qt::AltButton) { state &= ~Qt::AltButton; state |= Qt::ALT; }
294 # if QT_VERSION >= 0x030100
295 if (state & Qt::MetaButton) { state &= ~Qt::MetaButton; state |= Qt::META; }
323 qWarning(
"Internal debug: initializeGL() is called in QGLViewer constructor.");
326 glEnable(GL_LIGHTING);
327 glEnable(GL_DEPTH_TEST);
328 glEnable(GL_COLOR_MATERIAL);
331 setForegroundColor(QColor(180, 180, 180));
332 setBackgroundColor(QColor(51, 51, 51));
335 if (format().stereo())
337 glDrawBuffer(GL_BACK_RIGHT);
338 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
339 glDrawBuffer(GL_BACK_LEFT);
340 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
343 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
350 QTimer::singleShot( 100,
this, SLOT(delayedFullScreen()) );
364 if (displaysInStereo())
366 for (
int view=1; view>=0; --view)
371 if (camera()->frame()->isManipulated())
383 if (camera()->frame()->isManipulated())
391 Q_EMIT drawFinished(
true);
407 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
410 camera()->loadProjectionMatrix();
412 camera()->loadModelViewMatrix();
430 glMatrixMode(GL_MODELVIEW);
432 camera()->loadModelViewMatrix();
436 glPushAttrib(GL_ALL_ATTRIB_BITS);
439 glDisable(GL_TEXTURE_1D);
440 glDisable(GL_TEXTURE_2D);
441 #ifdef GL_TEXTURE_3D // OpenGL 1.2 Only...
442 glDisable(GL_TEXTURE_3D);
445 glDisable(GL_TEXTURE_GEN_Q);
446 glDisable(GL_TEXTURE_GEN_R);
447 glDisable(GL_TEXTURE_GEN_S);
448 glDisable(GL_TEXTURE_GEN_T);
450 #ifdef GL_RESCALE_NORMAL // OpenGL 1.2 Only...
451 glEnable(GL_RESCALE_NORMAL);
454 glDisable(GL_COLOR_MATERIAL);
455 qglColor(foregroundColor());
457 if (cameraIsEdited())
458 camera()->drawAllPaths();
463 if (gridIsDrawn()) { glLineWidth(1.0); drawGrid(camera()->sceneRadius()); }
464 if (axisIsDrawn()) { glLineWidth(2.0); drawAxis(camera()->sceneRadius()); }
467 const unsigned int maxCounter = 20;
468 if (++fpsCounter_ == maxCounter)
470 f_p_s_ = 1000.0 * maxCounter / fpsTime_.restart();
471 fpsString_ = tr(
"%1Hz",
"Frames per seconds, in Hertz").arg(f_p_s_, 0,
'f', ((f_p_s_ < 10.0)?1:0));
477 color[0] = foregroundColor().red() / 255.0;
478 color[1] = foregroundColor().green() / 255.0;
479 color[2] = foregroundColor().blue() / 255.0;
481 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color);
482 glDisable(GL_LIGHTING);
483 glDisable(GL_DEPTH_TEST);
485 if (FPSIsDisplayed()) displayFPS();
486 if (displayMessage_) drawText(10, height()-10, message_);
504 glDrawBuffer(GL_BACK_LEFT);
506 glDrawBuffer(GL_BACK_RIGHT);
509 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
511 camera()->loadProjectionMatrixStereo(leftBuffer);
513 camera()->loadModelViewMatrixStereo(leftBuffer);
539 cameraIsEdited_ = edit;
542 previousCameraZClippingCoefficient_ = camera()->zClippingCoefficient();
544 camera()->setZClippingCoefficient(5.0);
547 camera()->setZClippingCoefficient(previousCameraZClippingCoefficient_);
549 Q_EMIT cameraIsEditedChanged(edit);
556 void QGLViewer::setDefaultShortcuts()
559 setShortcut(DRAW_AXIS, Qt::Key_A);
560 setShortcut(DRAW_GRID, Qt::Key_G);
561 setShortcut(DISPLAY_FPS, Qt::Key_F);
562 setShortcut(ENABLE_TEXT, Qt::SHIFT+Qt::Key_Question);
563 setShortcut(EXIT_VIEWER, Qt::Key_Escape);
564 setShortcut(SAVE_SCREENSHOT, Qt::CTRL+Qt::Key_S);
565 setShortcut(CAMERA_MODE, Qt::Key_Space);
566 setShortcut(FULL_SCREEN, Qt::ALT+Qt::Key_Return);
567 setShortcut(STEREO, Qt::Key_S);
568 setShortcut(ANIMATION, Qt::Key_Return);
569 setShortcut(HELP, Qt::Key_H);
570 setShortcut(EDIT_CAMERA, Qt::Key_C);
571 setShortcut(MOVE_CAMERA_LEFT, Qt::Key_Left);
572 setShortcut(MOVE_CAMERA_RIGHT,Qt::Key_Right);
573 setShortcut(MOVE_CAMERA_UP, Qt::Key_Up);
574 setShortcut(MOVE_CAMERA_DOWN, Qt::Key_Down);
575 setShortcut(INCREASE_FLYSPEED,Qt::Key_Plus);
576 setShortcut(DECREASE_FLYSPEED,Qt::Key_Minus);
577 setShortcut(SNAPSHOT_TO_CLIPBOARD,Qt::CTRL+Qt::Key_C);
579 keyboardActionDescription_[DISPLAY_FPS] = tr(
"Toggles the display of the FPS",
"DISPLAY_FPS action description");
580 keyboardActionDescription_[SAVE_SCREENSHOT] = tr(
"Saves a screenshot",
"SAVE_SCREENSHOT action description");
581 keyboardActionDescription_[FULL_SCREEN] = tr(
"Toggles full screen display",
"FULL_SCREEN action description");
582 keyboardActionDescription_[DRAW_AXIS] = tr(
"Toggles the display of the world axis",
"DRAW_AXIS action description");
583 keyboardActionDescription_[DRAW_GRID] = tr(
"Toggles the display of the XY grid",
"DRAW_GRID action description");
584 keyboardActionDescription_[CAMERA_MODE] = tr(
"Changes camera mode (revolve or fly)",
"CAMERA_MODE action description");
585 keyboardActionDescription_[STEREO] = tr(
"Toggles stereo display",
"STEREO action description");
586 keyboardActionDescription_[HELP] = tr(
"Opens this help window",
"HELP action description");
587 keyboardActionDescription_[ANIMATION] = tr(
"Starts/stops the animation",
"ANIMATION action description");
588 keyboardActionDescription_[EDIT_CAMERA] = tr(
"Toggles camera paths display",
"EDIT_CAMERA action description");
589 keyboardActionDescription_[ENABLE_TEXT] = tr(
"Toggles the display of the text",
"ENABLE_TEXT action description");
590 keyboardActionDescription_[EXIT_VIEWER] = tr(
"Exits program",
"EXIT_VIEWER action description");
591 keyboardActionDescription_[MOVE_CAMERA_LEFT] = tr(
"Moves camera left",
"MOVE_CAMERA_LEFT action description");
592 keyboardActionDescription_[MOVE_CAMERA_RIGHT] = tr(
"Moves camera right",
"MOVE_CAMERA_RIGHT action description");
593 keyboardActionDescription_[MOVE_CAMERA_UP] = tr(
"Moves camera up",
"MOVE_CAMERA_UP action description");
594 keyboardActionDescription_[MOVE_CAMERA_DOWN] = tr(
"Moves camera down",
"MOVE_CAMERA_DOWN action description");
595 keyboardActionDescription_[INCREASE_FLYSPEED] = tr(
"Increases fly speed",
"INCREASE_FLYSPEED action description");
596 keyboardActionDescription_[DECREASE_FLYSPEED] = tr(
"Decreases fly speed",
"DECREASE_FLYSPEED action description");
597 keyboardActionDescription_[SNAPSHOT_TO_CLIPBOARD] = tr(
"Copies a snapshot to clipboard",
"SNAPSHOT_TO_CLIPBOARD action description");
600 setPathKey(Qt::Key_F1, 1);
601 setPathKey(Qt::Key_F2, 2);
602 setPathKey(Qt::Key_F3, 3);
603 setPathKey(Qt::Key_F4, 4);
604 setPathKey(Qt::Key_F5, 5);
605 setPathKey(Qt::Key_F6, 6);
606 setPathKey(Qt::Key_F7, 7);
607 setPathKey(Qt::Key_F8, 8);
608 setPathKey(Qt::Key_F9, 9);
609 setPathKey(Qt::Key_F10, 10);
610 setPathKey(Qt::Key_F11, 11);
611 setPathKey(Qt::Key_F12, 12);
613 #if QT_VERSION >= 0x040000
614 setAddKeyFrameKeyboardModifiers(Qt::AltModifier);
615 setPlayPathKeyboardModifiers(Qt::NoModifier);
617 setAddKeyFrameKeyboardModifiers(Qt::AltButton);
618 setPlayPathKeyboardModifiers(Qt::NoButton);
623 void QGLViewer::setDefaultMouseBindings()
625 #if QT_VERSION >= 0x040000
626 const QtKeyboardModifiers cameraKeyboardModifiers = Qt::NoModifier;
627 const QtKeyboardModifiers frameKeyboardModifiers = Qt::ControlModifier;
629 const QtKeyboardModifiers cameraKeyboardModifiers = Qt::NoButton;
630 const QtKeyboardModifiers frameKeyboardModifiers = Qt::ControlButton;
633 for (
int handler=0; handler<2; ++handler)
635 MouseHandler mh = (MouseHandler)(handler);
636 QtKeyboardModifiers modifiers = (mh == FRAME) ? frameKeyboardModifiers : cameraKeyboardModifiers;
638 setMouseBinding(modifiers | Qt::LeftButton, mh, ROTATE);
639 setMouseBinding(modifiers | Qt::MidButton, mh, ZOOM);
640 setMouseBinding(modifiers | Qt::RightButton, mh, TRANSLATE);
642 setMouseBinding(modifiers | Qt::LeftButton | Qt::MidButton, mh, SCREEN_ROTATE);
645 setWheelBinding(modifiers, mh, ZOOM);
648 #if QT_VERSION >= 0x040000
650 setMouseBinding(Qt::ShiftModifier | Qt::MidButton, CAMERA, ZOOM_ON_REGION);
652 setMouseBinding(Qt::ShiftModifier | Qt::LeftButton, SELECT);
654 setMouseBinding(Qt::ShiftButton | Qt::MidButton, CAMERA, ZOOM_ON_REGION);
655 setMouseBinding(Qt::ShiftButton | Qt::LeftButton, SELECT);
659 setMouseBinding(Qt::LeftButton, ALIGN_CAMERA,
true);
660 setMouseBinding(Qt::MidButton, SHOW_ENTIRE_SCENE,
true);
661 setMouseBinding(Qt::RightButton, CENTER_SCENE,
true);
663 setMouseBinding(frameKeyboardModifiers | Qt::LeftButton, ALIGN_FRAME,
true);
664 setMouseBinding(frameKeyboardModifiers | Qt::RightButton, CENTER_FRAME,
true);
667 setMouseBinding(Qt::LeftButton, RAP_FROM_PIXEL,
true, Qt::RightButton);
668 setMouseBinding(Qt::RightButton, RAP_IS_CENTER,
true, Qt::LeftButton);
669 setMouseBinding(Qt::LeftButton, ZOOM_ON_PIXEL,
true, Qt::MidButton);
670 setMouseBinding(Qt::RightButton, ZOOM_TO_FIT,
true, Qt::MidButton);
676 # if QT_VERSION >= 0x040000
677 const QtKeyboardModifiers macKeyboardModifiers = Qt::AltModifier;
679 const QtKeyboardModifiers macKeyboardModifiers = Qt::AltButton;
682 setMouseBinding(macKeyboardModifiers | Qt::LeftButton, CAMERA, TRANSLATE);
683 setMouseBinding(macKeyboardModifiers | Qt::LeftButton, CENTER_SCENE,
true);
684 setMouseBinding(frameKeyboardModifiers | macKeyboardModifiers | Qt::LeftButton, CENTER_FRAME,
true);
685 setMouseBinding(frameKeyboardModifiers | macKeyboardModifiers | Qt::LeftButton, FRAME, TRANSLATE);
689 setMouseBinding(Qt::MetaModifier | Qt::RightButton, RAP_FROM_PIXEL,
true, Qt::LeftButton);
690 setMouseBinding(Qt::ShiftModifier | Qt::MetaModifier | Qt::RightButton, RAP_IS_CENTER,
true, Qt::LeftButton);
692 setMouseBinding(Qt::MetaModifier | Qt::RightButton, ZOOM_ON_PIXEL,
false);
693 setMouseBinding(Qt::ShiftModifier | Qt::MetaModifier | Qt::RightButton, ZOOM_TO_FIT,
false);
723 disconnect(this->camera()->frame(), SIGNAL(manipulated()),
this, SLOT(updateGL()));
724 disconnect(this->camera()->frame(), SIGNAL(spun()),
this, SLOT(updateGL()));
727 connect(camera->
frame(), SIGNAL(manipulated()), SLOT(updateGL()));
728 connect(camera->
frame(), SIGNAL(spun()), SLOT(updateGL()));
730 connectAllCameraKFIInterpolatedSignals(
false);
732 connectAllCameraKFIInterpolatedSignals();
737 void QGLViewer::connectAllCameraKFIInterpolatedSignals(
bool connection)
739 for (QMap<int, KeyFrameInterpolator*>::ConstIterator it = camera()->kfi_.begin(), end=camera()->kfi_.end(); it != end; ++it)
742 connect(camera()->keyFrameInterpolator(it.key()), SIGNAL(interpolated()), SLOT(updateGL()));
744 disconnect(camera()->keyFrameInterpolator(it.key()), SIGNAL(interpolated()),
this, SLOT(updateGL()));
748 connect(camera()->interpolationKfi_, SIGNAL(interpolated()), SLOT(updateGL()));
750 disconnect(camera()->interpolationKfi_, SIGNAL(interpolated()),
this, SLOT(updateGL()));
771 static GLUquadric* quadric = gluNewQuadric();
773 const float length = sceneRadius() / 5.0 * scale;
776 glGetBooleanv(light, &lightIsOn);
785 glGetLightfv(light, GL_DIFFUSE, color);
789 glGetLightfv(light, GL_POSITION, pos);
793 glTranslatef(pos[0]/pos[3], pos[1]/pos[3], pos[2]/pos[3]);
796 glGetLightfv(light, GL_SPOT_CUTOFF, &cutOff);
800 glGetLightfv(light, GL_SPOT_DIRECTION, dir);
803 gluCylinder(quadric, 0.0, 0.7 * length * sin(cutOff * M_PI / 180.0), 0.7 * length * cos(cutOff * M_PI / 180.0), 12, 1);
806 gluSphere(quadric, 0.2*length, 10, 10);
811 Vec dir(pos[0], pos[1], pos[2]);
813 Frame fr=
Frame(camera()->cameraCoordinatesOf(4.0 * length * camera()->frame()->inverseTransformOf(dir)),
815 glMultMatrixd(fr.
matrix());
868 if (!textIsEnabled())
871 #if QT_VERSION < QGLVIEWER_QT_VERSION_WITHOUT_GLUT
872 const GLfloat font_scale = 119.05f - 33.33f;
874 startScreenCoordinatesSystem();
877 glPushAttrib(GL_ALL_ATTRIB_BITS);
878 glDisable(GL_LIGHTING);
879 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
881 glDisable(GL_DEPTH_TEST);
882 glEnable(GL_LINE_SMOOTH);
885 glTranslatef((GLfloat)x, (GLfloat)y, 0.0);
886 const GLfloat scale = ((fnt.pixelSize()>0)?fnt.pixelSize():fnt.pointSize()) / font_scale;
887 glScalef(scale, -scale, scale);
889 for (uint i=0; i<text.length(); ++i)
890 glutStrokeCharacter(GLUT_STROKE_ROMAN, text.at(i));
894 stopScreenCoordinatesSystem();
897 # if QT_VERSION < 0x030300 && defined Q_OS_UNIX
900 newFont.setFamily(
"fixed");
901 newFont.setRawMode(
true);
902 newFont.setPixelSize(10);
903 newFont.setFixedPitch(
true);
904 # if QT_VERSION >= 0x030200
905 newFont.setStyleStrategy(QFont::OpenGLCompatible);
907 newFont.setStyleHint(QFont::AnyStyle, QFont::PreferBitmap);
908 renderText(x, y, text, newFont);
910 if (tileRegion_ != NULL) {
911 renderText((x-tileRegion_->xMin) * width() / (tileRegion_->xMax - tileRegion_->xMin),
912 (y-tileRegion_->yMin) * height() / (tileRegion_->yMax - tileRegion_->yMin), text, scaledFont(fnt));
914 renderText(x, y, text, fnt);
1001 displayMessage_ =
true;
1002 #if QT_VERSION >= 0x040000
1004 messageTimer_.start(delay);
1006 if (messageTimer_.isActive())
1007 messageTimer_.changeInterval(delay);
1009 messageTimer_.start(delay,
true);
1011 if (textIsEnabled() && updateGLOK_)
1015 void QGLViewer::hideMessage()
1017 displayMessage_ =
false;
1018 if (textIsEnabled())
1032 void QGLViewer::displayFPS()
1034 drawText(10,
int(1.5*((QApplication::font().pixelSize()>0)?QApplication::font().pixelSize():QApplication::font().pointSize())), fpsString_);
1070 glMatrixMode(GL_PROJECTION);
1073 if (tileRegion_ != NULL)
1075 glOrtho(tileRegion_->xMin, tileRegion_->xMax, tileRegion_->yMin, tileRegion_->yMax, 0.0, -1.0);
1077 glOrtho(tileRegion_->xMin, tileRegion_->xMax, tileRegion_->yMax, tileRegion_->yMin, 0.0, -1.0);
1080 glOrtho(0, width(), 0, height(), 0.0, -1.0);
1082 glOrtho(0, width(), height(), 0, 0.0, -1.0);
1084 glMatrixMode(GL_MODELVIEW);
1095 glMatrixMode(GL_PROJECTION);
1098 glMatrixMode(GL_MODELVIEW);
1107 if (animationIsStarted())
1117 animationTimerId_ = startTimer(animationPeriod());
1118 animationStarted_ =
true;
1124 animationStarted_ =
false;
1125 if (animationTimerId_ != 0)
1126 killTimer(animationTimerId_);
1165 QGLWidget::closeEvent(e);
1180 Q_EMIT pointSelected(event);
1181 select(event->pos());
1236 beginSelection(point);
1238 endSelection(point);
1239 postSelection(point);
1259 glSelectBuffer(selectBufferSize(), selectBuffer());
1260 glRenderMode(GL_SELECT);
1264 glMatrixMode(GL_PROJECTION);
1266 static GLint viewport[4];
1267 camera()->getViewport(viewport);
1268 gluPickMatrix(point.x(), point.y(), selectRegionWidth(), selectRegionHeight(), viewport);
1272 camera()->loadProjectionMatrix(
false);
1274 camera()->loadModelViewMatrix();
1321 GLint nbHits = glRenderMode(GL_RENDER);
1324 setSelectedName(-1);
1331 GLuint zMin = (selectBuffer())[1];
1332 setSelectedName((selectBuffer())[3]);
1333 for (
int i=1; i<nbHits; ++i)
1334 if ((selectBuffer())[4*i+1] < zMin)
1336 zMin = (selectBuffer())[4*i+1];
1337 setSelectedName((selectBuffer())[4*i+3]);
1348 delete[] selectBuffer_;
1349 selectBufferSize_ = size;
1350 selectBuffer_ =
new GLuint[selectBufferSize()];
1353 void QGLViewer::performClickAction(ClickAction ca,
const QMouseEvent*
const e)
1360 case NO_CLICK_ACTION :
1362 case ZOOM_ON_PIXEL :
1363 camera()->interpolateToZoomOnPixel(e->pos());
1366 camera()->interpolateToFitScene();
1372 case RAP_FROM_PIXEL :
1373 if (camera()->setRevolveAroundPointFromPixel(e->pos()))
1375 setVisualHintsMask(1);
1379 case RAP_IS_CENTER :
1380 camera()->setRevolveAroundPoint(sceneCenter());
1381 setVisualHintsMask(1);
1385 if (manipulatedFrame())
1386 manipulatedFrame()->projectOnLine(camera()->position(), camera()->viewDirection());
1389 camera()->centerScene();
1391 case SHOW_ENTIRE_SCENE :
1392 camera()->showEntireScene();
1395 if (manipulatedFrame())
1396 manipulatedFrame()->alignWithFrame(camera()->frame());
1399 camera()->frame()->alignWithFrame(NULL,
true);
1424 ClickActionPrivate cap;
1425 cap.doubleClick =
false;
1426 #if QT_VERSION >= 0x040000
1427 cap.modifiers = e->modifiers();
1428 cap.button = e->button();
1429 cap.buttonsBefore = (QtMouseButtons)(e->buttons() & ~(e->button()));
1431 cap.modifiers = (QtKeyboardModifiers)(e->state() & Qt::KeyboardModifierMask);
1432 cap.button = (QtMouseButtons)((e->stateAfter() & Qt::MouseButtonMask) & (~(e->state() & Qt::MouseButtonMask)));
1433 cap.buttonsBefore = (QtMouseButtons)(e->state() & Qt::MouseButtonMask);
1436 if (clickBinding_.contains(cap))
1437 performClickAction(clickBinding_[cap], e);
1441 if (mouseGrabberIsAManipulatedFrame_)
1443 for (QMap<int, MouseActionPrivate>::ConstIterator it=mouseBinding_.begin(), end=mouseBinding_.end(); it!=end; ++it)
1444 #
if QT_VERSION >= 0x040000
1445 if ((it.value().handler == FRAME) && ((it.key() & Qt::MouseButtonMask) == e->buttons()))
1447 if ((it.data().handler == FRAME) && ((it.key() & Qt::MouseButtonMask) == (e->stateAfter() & Qt::MouseButtonMask)))
1451 if (mouseGrabberIsAManipulatedCameraFrame_)
1453 mf->ManipulatedFrame::startAction(it.value().action, it.value().withConstraint);
1454 mf->ManipulatedFrame::mousePressEvent(e, camera());
1458 mf->
startAction(it.value().action, it.value().withConstraint);
1465 mouseGrabber()->mousePressEvent(e, camera());
1471 #if QT_VERSION >= 0x040000
1472 const int state = e->modifiers() | e->buttons();
1474 const int state = e->stateAfter();
1477 if (mouseBinding_.contains(state))
1479 MouseActionPrivate map = mouseBinding_[state];
1480 switch (map.handler)
1483 camera()->frame()->startAction(map.action, map.withConstraint);
1484 camera()->frame()->mousePressEvent(e, camera());
1487 if (manipulatedFrame())
1489 if (manipulatedFrameIsACamera_)
1491 manipulatedFrame()->ManipulatedFrame::startAction(map.action, map.withConstraint);
1492 manipulatedFrame()->ManipulatedFrame::mousePressEvent(e, camera());
1496 manipulatedFrame()->startAction(map.action, map.withConstraint);
1497 manipulatedFrame()->mousePressEvent(e, camera());
1502 if (map.action == SCREEN_ROTATE)
1506 #if QT_VERSION >= 0x030000
1556 mouseGrabber()->checkIfGrabsMouse(e->x(), e->y(), camera());
1557 if (mouseGrabber()->grabsMouse())
1558 if (mouseGrabberIsAManipulatedCameraFrame_)
1559 (
dynamic_cast<ManipulatedFrame*
>(mouseGrabber()))->ManipulatedFrame::mouseMoveEvent(e, camera());
1561 mouseGrabber()->mouseMoveEvent(e, camera());
1563 setMouseGrabber(NULL);
1567 if (!mouseGrabber())
1570 if (camera()->frame()->isManipulated())
1572 camera()->frame()->mouseMoveEvent(e, camera());
1574 if (camera()->frame()->action_ == ZOOM_ON_REGION)
1578 if ((manipulatedFrame()) && (manipulatedFrame()->isManipulated()))
1579 if (manipulatedFrameIsACamera_)
1580 manipulatedFrame()->ManipulatedFrame::mouseMoveEvent(e, camera());
1582 manipulatedFrame()->mouseMoveEvent(e, camera());
1584 if (hasMouseTracking())
1586 #if QT_VERSION >= 0x040000
1597 setMouseGrabber(mg);
1599 if (mouseGrabber() == mg)
1619 if (mouseGrabberIsAManipulatedCameraFrame_)
1620 (
dynamic_cast<ManipulatedFrame*
>(mouseGrabber()))->ManipulatedFrame::mouseReleaseEvent(e, camera());
1622 mouseGrabber()->mouseReleaseEvent(e, camera());
1623 mouseGrabber()->checkIfGrabsMouse(e->x(), e->y(), camera());
1624 if (!(mouseGrabber()->grabsMouse()))
1625 setMouseGrabber(NULL);
1630 if (camera()->frame()->isManipulated())
1634 camera()->frame()->mouseReleaseEvent(e, camera());
1640 if ((manipulatedFrame()) && (manipulatedFrame()->isManipulated()))
1643 if (manipulatedFrameIsACamera_)
1644 manipulatedFrame()->ManipulatedFrame::mouseReleaseEvent(e, camera());
1646 manipulatedFrame()->mouseReleaseEvent(e, camera());
1650 #if QT_VERSION >= 0x030000
1668 if (mouseGrabberIsAManipulatedFrame_)
1670 for (QMap<QtKeyboardModifiers, MouseActionPrivate>::ConstIterator it=wheelBinding_.begin(), end=wheelBinding_.end(); it!=end; ++it)
1671 if (it.value().handler == FRAME)
1674 if (mouseGrabberIsAManipulatedCameraFrame_)
1676 mf->ManipulatedFrame::startAction(it.value().action, it.value().withConstraint);
1677 mf->ManipulatedFrame::wheelEvent(e, camera());
1681 mf->
startAction(it.value().action, it.value().withConstraint);
1688 mouseGrabber()->wheelEvent(e, camera());
1694 #if QT_VERSION >= 0x040000
1695 const QtKeyboardModifiers modifiers = e->modifiers();
1697 const QtKeyboardModifiers modifiers = e->state();
1699 if (wheelBinding_.contains(modifiers))
1701 MouseActionPrivate map = wheelBinding_[modifiers];
1702 switch (map.handler)
1705 camera()->frame()->startAction(map.action, map.withConstraint);
1706 camera()->frame()->wheelEvent(e, camera());
1709 if (manipulatedFrame()) {
1710 if (manipulatedFrameIsACamera_)
1712 manipulatedFrame()->ManipulatedFrame::startAction(map.action, map.withConstraint);
1713 manipulatedFrame()->ManipulatedFrame::wheelEvent(e, camera());
1717 manipulatedFrame()->startAction(map.action, map.withConstraint);
1718 manipulatedFrame()->wheelEvent(e, camera());
1724 #if QT_VERSION >= 0x030000
1738 ClickActionPrivate cap;
1739 cap.doubleClick =
true;
1740 #if QT_VERSION >= 0x040000
1741 cap.modifiers = e->modifiers();
1742 cap.button = e->button();
1743 cap.buttonsBefore = (QtMouseButtons)(e->buttons() & ~(e->button()));
1745 cap.modifiers = (QtKeyboardModifiers)(e->state() & Qt::KeyboardModifierMask);
1746 cap.button = (QtMouseButtons)((e->stateAfter() & Qt::MouseButtonMask) & (~(e->state() & Qt::MouseButtonMask)));
1747 cap.buttonsBefore = (QtMouseButtons)(e->state() & Qt::MouseButtonMask);
1749 if (clickBinding_.contains(cap))
1750 performClickAction(clickBinding_[cap], e);
1753 mouseGrabber()->mouseDoubleClickEvent(e, camera());
1754 #if QT_VERSION >= 0x030000
1766 if (format().stereo())
1769 if (!displaysInStereo())
1771 glDrawBuffer(GL_BACK_LEFT);
1772 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1773 glDrawBuffer(GL_BACK_RIGHT);
1774 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1777 Q_EMIT stereoChanged(stereo_);
1784 QMessageBox::warning(
this, tr(
"Stereo not supported",
"Message box window title"), tr(
"Stereo is not supported on this display."));
1795 fullScreen_ = fullScreen;
1801 QWidget* tlw = topLevelWidget();
1805 prevPos_ = topLevelWidget()->pos();
1806 tlw->showFullScreen();
1812 tlw->move(prevPos_);
1824 if (!mouseGrabberIsEnabled(mouseGrabber))
1827 mouseGrabber_ = mouseGrabber;
1829 mouseGrabberIsAManipulatedFrame_ = (
dynamic_cast<ManipulatedFrame*
>(mouseGrabber) != NULL);
1830 mouseGrabberIsAManipulatedCameraFrame_ = ((
dynamic_cast<ManipulatedCameraFrame*
>(mouseGrabber) != NULL) &&
1831 (mouseGrabber != camera()->frame()));
1832 Q_EMIT mouseGrabberChanged(mouseGrabber);
1839 disabledMouseGrabbers_.remove(reinterpret_cast<size_t>(mouseGrabber));
1841 disabledMouseGrabbers_[
reinterpret_cast<size_t>(mouseGrabber)];
1844 static QString keyboardModifiersString(QtKeyboardModifiers m,
bool noButton=
false)
1846 #if QT_VERSION >= 0x040000
1847 if (noButton && (m==Qt::NoModifier))
1849 if (noButton && (m==Qt::NoButton))
1851 return QGLViewer::tr(
"(no button)");
1853 QString keySequence =
"";
1855 #if QT_VERSION >= 0x040000
1856 if (m & Qt::ControlModifier) keySequence +=
"Ctrl+";
1857 if (m & Qt::AltModifier) keySequence +=
"Alt+";
1858 if (m & Qt::ShiftModifier) keySequence +=
"Shift+";
1859 if (m & Qt::MetaModifier) keySequence +=
"Meta+";
1861 if (m & Qt::ControlButton) keySequence +=
"Ctrl+";
1862 if (m & Qt::AltButton) keySequence +=
"Alt+";
1863 if (m & Qt::ShiftButton) keySequence +=
"Shift+";
1864 # if QT_VERSION >= 0x030000
1865 if (m & Qt::MetaButton) keySequence +=
"Meta+";
1869 if (keySequence.length() > 0)
1870 #
if QT_VERSION >= 0x040000
1871 return QKeySequence(keySequence+
"X").toString(QKeySequence::NativeText).replace(
"X",
"");
1873 return QString(QKeySequence(keySequence+
"X")).replace(
"X",
"");
1879 static QString mouseButtonsString(QtMouseButtons b)
1882 bool addAmpersand =
false;
1883 if (b & Qt::LeftButton) { result += QGLViewer::tr(
"Left",
"left mouse button"); addAmpersand=
true; }
1884 if (b & Qt::MidButton) {
if (addAmpersand) result +=
" & "; result += QGLViewer::tr(
"Middle",
"middle mouse button"); addAmpersand=
true; }
1885 if (b & Qt::RightButton) {
if (addAmpersand) result +=
" & "; result += QGLViewer::tr(
"Right",
"right mouse button"); }
1893 case QGLViewer::NO_MOUSE_ACTION :
return QString::null;
1894 case QGLViewer::ROTATE :
return QGLViewer::tr(
"Rotates",
"ROTATE mouse action");
1895 case QGLViewer::ZOOM :
return QGLViewer::tr(
"Zooms",
"ZOOM mouse action");
1896 case QGLViewer::TRANSLATE :
return QGLViewer::tr(
"Translates",
"TRANSLATE mouse action");
1897 case QGLViewer::MOVE_FORWARD :
return QGLViewer::tr(
"Moves forward",
"MOVE_FORWARD mouse action");
1898 case QGLViewer::LOOK_AROUND :
return QGLViewer::tr(
"Looks around",
"LOOK_AROUND mouse action");
1899 case QGLViewer::MOVE_BACKWARD :
return QGLViewer::tr(
"Moves backward",
"MOVE_BACKWARD mouse action");
1900 case QGLViewer::SCREEN_ROTATE :
return QGLViewer::tr(
"Rotates in screen plane",
"SCREEN_ROTATE mouse action");
1901 case QGLViewer::ROLL :
return QGLViewer::tr(
"Rolls",
"ROLL mouse action");
1902 case QGLViewer::DRIVE :
return QGLViewer::tr(
"Drives",
"DRIVE mouse action");
1903 case QGLViewer::SCREEN_TRANSLATE :
return QGLViewer::tr(
"Horizontally/Vertically translates",
"SCREEN_TRANSLATE mouse action");
1904 case QGLViewer::ZOOM_ON_REGION :
return QGLViewer::tr(
"Zooms on region for",
"ZOOM_ON_REGION mouse action");
1906 return QString::null;
1913 case QGLViewer::NO_CLICK_ACTION :
return QString::null;
1914 case QGLViewer::ZOOM_ON_PIXEL :
return QGLViewer::tr(
"Zooms on pixel",
"ZOOM_ON_PIXEL click action");
1915 case QGLViewer::ZOOM_TO_FIT :
return QGLViewer::tr(
"Zooms to fit scene",
"ZOOM_TO_FIT click action");
1916 case QGLViewer::SELECT :
return QGLViewer::tr(
"Selects",
"SELECT click action");
1917 case QGLViewer::RAP_FROM_PIXEL :
return QGLViewer::tr(
"Sets revolve around point",
"RAP_FROM_PIXEL click action");
1918 case QGLViewer::RAP_IS_CENTER :
return QGLViewer::tr(
"Resets revolve around point",
"RAP_IS_CENTER click action");
1919 case QGLViewer::CENTER_FRAME :
return QGLViewer::tr(
"Centers frame",
"CENTER_FRAME click action");
1920 case QGLViewer::CENTER_SCENE :
return QGLViewer::tr(
"Centers scene",
"CENTER_SCENE click action");
1921 case QGLViewer::SHOW_ENTIRE_SCENE :
return QGLViewer::tr(
"Shows entire scene",
"SHOW_ENTIRE_SCENE click action");
1922 case QGLViewer::ALIGN_FRAME :
return QGLViewer::tr(
"Aligns frame",
"ALIGN_FRAME click action");
1923 case QGLViewer::ALIGN_CAMERA :
return QGLViewer::tr(
"Aligns camera",
"ALIGN_CAMERA click action");
1925 return QString::null;
1928 QString QGLViewer::formatClickActionPrivate(ClickActionPrivate cap)
1930 bool buttonsBefore = cap.buttonsBefore != Qt::NoButton;
1931 return tr(
"%1%2%3%4%5%6",
"Modifier / button or wheel / double click / with / button / pressed")
1932 .arg(keyboardModifiersString(cap.modifiers))
1933 .arg(mouseButtonsString(cap.button)+(cap.button == Qt::NoButton ? tr(
"Wheel",
"Mouse wheel") :
""))
1934 .arg(cap.doubleClick ? tr(
" double click",
"Suffix after mouse button") :
"")
1935 .arg(buttonsBefore ? tr(
" with ",
"As in : Left button with Ctrl pressed") :
"")
1936 .arg(buttonsBefore ? mouseButtonsString(cap.buttonsBefore) :
"")
1937 .arg(buttonsBefore ? tr(
" pressed",
"As in : Left button with Ctrl pressed") :
"");
1976 ClickActionPrivate cap;
1977 cap.modifiers = QtKeyboardModifiers(convertToKeyboardModifiers(state) & Qt::KeyboardModifierMask);
1978 cap.button = QtMouseButtons(state & Qt::MouseButtonMask);
1979 cap.doubleClick = doubleClick;
1980 cap.buttonsBefore = buttonsBefore;
1982 if (description.isEmpty())
1983 mouseDescription_.remove(cap);
1985 mouseDescription_[cap] = description;
1988 static QString tableLine(
const QString& left,
const QString& right)
1990 static bool even =
false;
1991 const QString tdtd(
"</b></td><td>");
1992 const QString tdtr(
"</td></tr>\n");
1994 QString res(
"<tr bgcolor=\"");
1997 res +=
"#eeeeff\">";
1999 res +=
"#ffffff\">";
2000 res +=
"<td><b>" + left + tdtd + right + tdtr;
2017 QString text(
"<center><table border=\"1\" cellspacing=\"0\" cellpadding=\"4\">\n");
2018 const QString trtd(
"<tr><td>");
2019 const QString tdtr(
"</td></tr>\n");
2020 const QString tdtd(
"</td><td>");
2022 text += QString(
"<tr bgcolor=\"#aaaacc\"><th align=\"center\">%1</th><th align=\"center\">%2</th></tr>\n").
2023 arg(tr(
"Button(s)",
"Buttons column header in help window mouse tab")).arg(tr(
"Description",
"Description column header in help window mouse tab"));
2025 QMap<ClickActionPrivate, QString> mouseBinding;
2028 for (QMap<ClickActionPrivate, QString>::ConstIterator itm=mouseDescription_.begin(), endm=mouseDescription_.end(); itm!=endm; ++itm)
2029 mouseBinding[itm.key()] = itm.value();
2031 for (QMap<ClickActionPrivate, QString>::ConstIterator it=mouseBinding.begin(), end=mouseBinding.end(); it != end; ++it)
2034 if (it.value().isNull())
2037 text += tableLine(formatClickActionPrivate(it.key()), it.value());
2041 if (!mouseBinding.isEmpty())
2043 mouseBinding.clear();
2044 text += QString(
"<tr bgcolor=\"#aaaacc\"><td colspan=2>%1</td></tr>\n").arg(tr(
"Standard mouse bindings",
"In help window mouse tab"));
2050 for (QMap<QtKeyboardModifiers, MouseActionPrivate>::ConstIterator itw=wheelBinding_.begin(), endw=wheelBinding_.end(); itw != endw; ++itw)
2052 ClickActionPrivate cap;
2053 cap.doubleClick =
false;
2054 cap.modifiers = itw.key();
2055 cap.button = Qt::NoButton;
2056 cap.buttonsBefore = Qt::NoButton;
2058 QString text = mouseActionString(itw.value().action);
2062 switch (itw.value().handler)
2064 case CAMERA: text +=
" " + tr(
"camera",
"Suffix after action");
break;
2065 case FRAME: text +=
" " + tr(
"manipulated frame",
"Suffix after action");
break;
2067 if (!(itw.value().withConstraint))
2071 mouseBinding[cap] = text;
2074 for (QMap<int, MouseActionPrivate>::ConstIterator itmb=mouseBinding_.begin(), endmb=mouseBinding_.end();
2075 itmb != endmb; ++itmb)
2077 ClickActionPrivate cap;
2078 cap.doubleClick =
false;
2079 cap.modifiers = QtKeyboardModifiers(itmb.key() & Qt::KeyboardModifierMask);
2080 cap.button = QtMouseButtons(itmb.key() & Qt::MouseButtonMask);
2081 cap.buttonsBefore = Qt::NoButton;
2083 QString text = mouseActionString(itmb.value().action);
2087 switch (itmb.value().handler)
2089 case CAMERA: text +=
" " + tr(
"camera",
"Suffix after action");
break;
2090 case FRAME: text +=
" " + tr(
"manipulated frame",
"Suffix after action");
break;
2092 if (!(itmb.value().withConstraint))
2095 mouseBinding[cap] = text;
2098 for (QMap<ClickActionPrivate, ClickAction>::ConstIterator itcb=clickBinding_.begin(), endcb=clickBinding_.end(); itcb!=endcb; ++itcb)
2099 mouseBinding[itcb.key()] = clickActionString(itcb.value());
2101 for (QMap<ClickActionPrivate, QString>::ConstIterator it2=mouseBinding.begin(), end2=mouseBinding.end(); it2 != end2; ++it2)
2103 if (it2.value().isNull())
2106 text += tableLine(formatClickActionPrivate(it2.key()), it2.value());
2109 text +=
"</table></center>";
2130 #if QT_VERSION >= 0x030000
2132 key = convertToKeyboardModifiers(key);
2134 if (description.isEmpty())
2135 keyDescription_.remove(key);
2137 keyDescription_[key] = description;
2140 static QString keyString(
int key)
2142 #if QT_VERSION >= 0x030000
2143 return QString(QKeySequence(convertToShortModifier(key)));
2146 return QString(QKeySequence(key));
2150 QString QGLViewer::cameraPathKeysString()
const
2152 if (pathIndex_.isEmpty())
2153 return QString::null;
2155 #if QT_VERSION >= 0x040000 || QT_VERSION < 0x030000
2158 QValueVector<int> keys;
2160 keys.reserve(pathIndex_.count());
2161 for (QMap<Qt::Key, int>::ConstIterator i = pathIndex_.begin(), endi=pathIndex_.end(); i != endi; ++i)
2162 keys.push_back(i.key());
2163 #if QT_VERSION >= 0x040000
2166 # if QT_VERSION >= 0x030000
2169 sort(keys.begin(), keys.end());
2173 #if QT_VERSION >= 0x040000 || QT_VERSION < 0x030000
2174 QVector<int>::const_iterator it = keys.begin(), end = keys.end();
2176 QValueVector<int>::const_iterator it = keys.begin(), end = keys.end();
2178 QString res = keyString(*it);
2180 const int maxDisplayedKeys = 6;
2181 int nbDisplayedKeys = 0;
2182 int previousKey = (*it);
2185 while ((it != end) && (nbDisplayedKeys < maxDisplayedKeys-1))
2190 if ((*it) == previousKey + 1)
2194 res +=
", " + keyString(*it);
2199 if ((*it) == previousKey + 1)
2203 res +=
", " + keyString(previousKey);
2204 res +=
", " + keyString(*it);
2205 nbDisplayedKeys += 2;
2210 if ((*it) != previousKey + 1)
2212 res +=
".." + keyString(previousKey);
2213 res +=
", " + keyString(*it);
2214 nbDisplayedKeys += 2;
2224 res +=
", " + keyString(previousKey);
2226 res +=
".." + keyString(previousKey);
2243 QString text(
"<center><table border=\"1\" cellspacing=\"0\" cellpadding=\"4\">\n");
2244 text += QString(
"<tr bgcolor=\"#aaaacc\"><th align=\"center\">%1</th><th align=\"center\">%2</th></tr>\n").
2245 arg(QGLViewer::tr(
"Key(s)",
"Keys column header in help window mouse tab")).arg(QGLViewer::tr(
"Description",
"Description column header in help window mouse tab"));
2247 QMap<int, QString> keyDescription;
2250 for (QMap<int, QString>::ConstIterator kd=keyDescription_.begin(), kdend=keyDescription_.end(); kd!=kdend; ++kd)
2251 keyDescription[kd.key()] = kd.value();
2254 for (QMap<int, QString>::ConstIterator kb=keyDescription.begin(), endb=keyDescription.end(); kb!=endb; ++kb)
2255 text += tableLine(keyString(kb.key()), kb.value());
2259 if (!keyDescription.isEmpty())
2261 keyDescription.clear();
2262 text += QString(
"<tr bgcolor=\"#aaaacc\"><td colspan=2>%1</td></tr>\n").arg(QGLViewer::tr(
"Standard viewer keys",
"In help window keys tab"));
2267 for (QMap<KeyboardAction, int>::ConstIterator it=keyboardBinding_.begin(), end=keyboardBinding_.end(); it != end; ++it)
2268 if ((it.value() != 0) && ((!cameraIsInRevolveMode()) || ((it.key() != INCREASE_FLYSPEED) && (it.key() != DECREASE_FLYSPEED))))
2269 keyDescription[it.value()] = keyboardActionDescription_[it.key()];
2272 for (QMap<int, QString>::ConstIterator kb2=keyDescription.begin(), endb2=keyDescription.end(); kb2!=endb2; ++kb2)
2273 text += tableLine(keyString(kb2.key()), kb2.value());
2277 const QString cpks = cameraPathKeysString();
2280 text +=
"<tr bgcolor=\"#ccccff\"><td colspan=2>\n";
2281 text += QGLViewer::tr(
"Camera paths are controlled using %1 (noted <i>Fx</i> below):",
"Help window key tab camera keys").arg(cpks) +
"</td></tr>\n";
2282 text += tableLine(keyboardModifiersString(playPathKeyboardModifiers()) +
"<i>" + QGLViewer::tr(
"Fx",
"Generic function key (F1..F12)") +
"</i>",
2283 QGLViewer::tr(
"Plays path (or resets saved position)"));
2284 text += tableLine(keyboardModifiersString(addKeyFrameKeyboardModifiers()) +
"<i>" + QGLViewer::tr(
"Fx",
"Generic function key (F1..F12)") +
"</i>",
2285 QGLViewer::tr(
"Adds a key frame to path (or defines a position)"));
2286 text += tableLine(keyboardModifiersString(addKeyFrameKeyboardModifiers()) +
"<i>" + QGLViewer::tr(
"Fx",
"Generic function key (F1..F12)") +
"</i>+<i>" + QGLViewer::tr(
"Fx",
"Generic function key (F1..F12)") +
"</i>",
2287 QGLViewer::tr(
"Deletes path (or saved position)"));
2289 text +=
"</table></center>";
2297 #if QT_VERSION >= 0x040000
2298 helpWidget()->setCurrentIndex(3);
2300 helpWidget()->setCurrentPage(3);
2316 Q_EMIT helpRequired();
2318 bool resize =
false;
2322 static QString label[] = {tr(
"&Help",
"Help window tab title"), tr(
"&Keyboard",
"Help window tab title"), tr(
"&Mouse",
"Help window tab title"), tr(
"&About",
"Help window about title")};
2327 helpWidget_ =
new QTabWidget(NULL);
2328 #if QT_VERSION >= 0x040000
2329 helpWidget()->setWindowTitle(tr(
"Help",
"Help window title"));
2331 helpWidget()->setCaption(tr(
"Help",
"Help window title"));
2335 for (
int i=0; i<4; ++i)
2337 QTextEdit* tab =
new QTextEdit(NULL);
2338 #if QT_VERSION >= 0x030000
2339 tab->setReadOnly(
true);
2342 #if QT_VERSION >= 0x040000
2343 helpWidget()->insertTab(i, tab, label[i]);
2345 # include "qglviewer-icon.xpm"
2346 QPixmap pixmap(qglviewer_icon);
2347 tab->document()->addResource(QTextDocument::ImageResource,
2348 QUrl(
"mydata://qglviewer-icon.xpm"), QVariant(pixmap));
2351 tab->setTextFormat(Qt::RichText);
2352 helpWidget()->insertTab(tab, label[i]);
2358 #if QT_VERSION < 0x030000
2359 const int currentPageIndex = helpWidget()->currentPageIndex();
2362 for (
int i=0; i<4; ++i)
2367 case 0 : text = helpString();
break;
2368 case 1 : text = keyboardString();
break;
2369 case 2 : text = mouseString();
break;
2370 case 3 : text = QString(
"<center><br><img src=\"mydata://qglviewer-icon.xpm\">") + tr(
2371 "<h1>libQGLViewer</h1>"
2372 "<h3>Version %1</h3><br>"
2373 "A versatile 3D viewer based on OpenGL and Qt<br>"
2374 "Copyright 2002-%2 Gilles Debunne<br>"
2375 "<code>%3</code>").arg(QGLViewerVersionString()).arg(
"2010").arg(
"http://www.libqglviewer.com") +
2376 QString(
"</center>");
2381 #if QT_VERSION >= 0x040000
2382 QTextEdit* textEdit = (QTextEdit*)(helpWidget()->widget(i));
2383 textEdit->setHtml(text);
2385 # if QT_VERSION < 0x030000
2386 helpWidget()->setCurrentPage(i);
2387 QTextEdit* textEdit = (QTextEdit*)(helpWidget()->currentPage());
2389 QTextEdit* textEdit = (QTextEdit*)(helpWidget()->page(i));
2391 textEdit->setText(text);
2394 #if QT_VERSION < 0x040000
2395 if (resize && (textEdit->heightForWidth(width) > height))
2396 height = textEdit->heightForWidth(width);
2398 if (resize && (textEdit->height() > height))
2399 height = textEdit->height();
2403 #if QT_VERSION < 0x030000
2404 helpWidget()->setCurrentPage(currentPageIndex);
2408 helpWidget()->resize(width, height+40);
2409 helpWidget()->show();
2410 helpWidget()->raise();
2447 const Qt::Key key = Qt::Key(e->key());
2448 #if QT_VERSION >= 0x040000
2449 const QtKeyboardModifiers modifiers = e->modifiers();
2451 const QtKeyboardModifiers modifiers = (QtKeyboardModifiers)(e->state() & Qt::KeyboardModifierMask);
2454 QMap<KeyboardAction, int>::ConstIterator it=keyboardBinding_.begin(), end=keyboardBinding_.end();
2455 while ((it != end) && (it.value() != (key | modifiers)))
2459 handleKeyboardAction(it.key());
2461 if (pathIndex_.contains(Qt::Key(key)))
2464 int index = pathIndex_[Qt::Key(key)];
2466 static QTime doublePress;
2468 if (modifiers == playPathKeyboardModifiers())
2470 int elapsed = doublePress.restart();
2471 if ((elapsed < 250) && (index==previousPathId_))
2472 camera()->resetPath(index);
2476 if (index != previousPathId_)
2482 camera()->playPath(index);
2484 previousPathId_ = index;
2486 else if (modifiers == addKeyFrameKeyboardModifiers())
2488 int elapsed = doublePress.restart();
2489 if ((elapsed < 250) && (index==previousPathId_))
2491 if (camera()->keyFrameInterpolator(index))
2493 disconnect(camera()->keyFrameInterpolator(index), SIGNAL(interpolated()),
this, SLOT(updateGL()));
2494 if (camera()->keyFrameInterpolator(index)->numberOfKeyFrames() > 1)
2495 displayMessage(tr(
"Path %1 deleted",
"Feedback message").arg(index));
2497 displayMessage(tr(
"Position %1 deleted",
"Feedback message").arg(index));
2498 camera()->deletePath(index);
2503 bool nullBefore = (camera()->keyFrameInterpolator(index) == NULL);
2504 camera()->addKeyFrameToPath(index);
2506 connect(camera()->keyFrameInterpolator(index), SIGNAL(interpolated()), SLOT(updateGL()));
2507 int nbKF = camera()->keyFrameInterpolator(index)->numberOfKeyFrames();
2509 displayMessage(tr(
"Path %1, position %2 added",
"Feedback message").arg(index).arg(nbKF));
2511 displayMessage(tr(
"Position %1 saved",
"Feedback message").arg(index));
2513 previousPathId_ = index;
2521 void QGLViewer::handleKeyboardAction(KeyboardAction
id)
2525 case DRAW_AXIS : toggleAxisIsDrawn();
break;
2526 case DRAW_GRID : toggleGridIsDrawn();
break;
2527 case DISPLAY_FPS : toggleFPSIsDisplayed();
break;
2528 case ENABLE_TEXT : toggleTextIsEnabled();
break;
2529 case EXIT_VIEWER : saveStateToFileForAllViewers(); qApp->closeAllWindows();
break;
2530 case SAVE_SCREENSHOT : saveSnapshot(
false,
false);
break;
2531 case FULL_SCREEN : toggleFullScreen();
break;
2532 case STEREO : toggleStereoDisplay();
break;
2533 case ANIMATION : toggleAnimation();
break;
2534 case HELP : help();
break;
2535 case EDIT_CAMERA : toggleCameraIsEdited();
break;
2536 case SNAPSHOT_TO_CLIPBOARD : snapshotToClipboard();
break;
2539 displayMessage(cameraIsInRevolveMode()?tr(
"Camera in revolve around mode",
"Feedback message"):tr(
"Camera in fly mode",
"Feedback message"));
2542 case MOVE_CAMERA_LEFT :
2543 camera()->frame()->translate(camera()->frame()->inverseTransformOf(
Vec(-10.0*camera()->flySpeed(), 0.0, 0.0)));
2546 case MOVE_CAMERA_RIGHT :
2547 camera()->frame()->translate(camera()->frame()->inverseTransformOf(
Vec( 10.0*camera()->flySpeed(), 0.0, 0.0)));
2550 case MOVE_CAMERA_UP :
2551 camera()->frame()->translate(camera()->frame()->inverseTransformOf(
Vec(0.0, 10.0*camera()->flySpeed(), 0.0)));
2554 case MOVE_CAMERA_DOWN :
2555 camera()->frame()->translate(camera()->frame()->inverseTransformOf(
Vec(0.0, -10.0*camera()->flySpeed(), 0.0)));
2559 case INCREASE_FLYSPEED : camera()->setFlySpeed(camera()->flySpeed() * 1.5);
break;
2560 case DECREASE_FLYSPEED : camera()->setFlySpeed(camera()->flySpeed() / 1.5);
break;
2570 QGLWidget::resizeGL(width, height);
2571 glViewport( 0, 0, GLint(width), GLint(height) );
2572 camera()->setScreenWidthAndHeight(this->width(), this->height());
2598 keyboardBinding_[action] = convertToKeyboardModifiers(key);
2618 if (keyboardBinding_.contains(action))
2619 return convertToShortModifier(keyboardBinding_[action]);
2625 void QGLViewer::setKeyboardAccelerator(KeyboardAction action,
int key)
2627 qWarning(
"setKeyboardAccelerator is deprecated. Use setShortcut instead.");
2628 setShortcut(action, key);
2631 int QGLViewer::keyboardAccelerator(KeyboardAction action)
const
2633 qWarning(
"keyboardAccelerator is deprecated. Use shortcut instead.");
2634 return shortcut(action);
2657 for (QMap<Qt::Key, int>::ConstIterator it = pathIndex_.begin(), end=pathIndex_.end(); it != end; ++it)
2658 if (it.value() == index)
2677 pathIndex_.remove(Qt::Key(-key));
2679 pathIndex_[Qt::Key(key)] = index;
2685 playPathKeyboardModifiers_ = convertKeyboardModifiers(modifiers);
2691 addKeyFrameKeyboardModifiers_ = convertKeyboardModifiers(modifiers);
2709 return addKeyFrameKeyboardModifiers_;
2726 return playPathKeyboardModifiers_;
2731 QtKeyboardModifiers QGLViewer::addKeyFrameStateKey()
const
2733 qWarning(
"addKeyFrameStateKey has been renamed addKeyFrameKeyboardModifiers");
2734 return addKeyFrameKeyboardModifiers(); }
2736 QtKeyboardModifiers QGLViewer::playPathStateKey()
const
2738 qWarning(
"playPathStateKey has been renamed playPathKeyboardModifiers");
2739 return playPathKeyboardModifiers();
2742 void QGLViewer::setAddKeyFrameStateKey(
int buttonState)
2744 qWarning(
"setAddKeyFrameStateKey has been renamed setAddKeyFrameKeyboardModifiers");
2745 setAddKeyFrameKeyboardModifiers(QtKeyboardModifiers(buttonState & Qt::KeyboardModifierMask));
2748 void QGLViewer::setPlayPathStateKey(
int buttonState)
2750 qWarning(
"setPlayPathStateKey has been renamed setPlayPathKeyboardModifiers");
2751 setPlayPathKeyboardModifiers(QtKeyboardModifiers(buttonState & Qt::KeyboardModifierMask));
2754 Qt::Key QGLViewer::keyFrameKey(
int index)
const
2756 qWarning(
"keyFrameKey has been renamed pathKey.");
2757 return pathKey(index);
2760 QtKeyboardModifiers QGLViewer::playKeyFramePathStateKey()
const
2762 qWarning(
"playKeyFramePathStateKey has been renamed playPathKeyboardModifiers.");
2763 return playPathKeyboardModifiers();
2766 void QGLViewer::setKeyFrameKey(
int index,
int key)
2768 qWarning(
"setKeyFrameKey is deprecated, use setPathKey instead, with swapped parameters.");
2769 setPathKey(key, index);
2772 void QGLViewer::setPlayKeyFramePathStateKey(
int buttonState)
2774 qWarning(
"setPlayKeyFramePathStateKey has been renamed setPlayPathKeyboardModifiers.");
2775 setPlayPathKeyboardModifiers(QtKeyboardModifiers(buttonState & Qt::KeyboardModifierMask));
2825 QMap<int, MouseActionPrivate> newMouseBinding;
2826 QMap<QtKeyboardModifiers, MouseActionPrivate> newWheelBinding;
2827 QMap<ClickActionPrivate, ClickAction> newClickBinding_;
2829 QMap<int, MouseActionPrivate>::Iterator mit;
2830 QMap<QtKeyboardModifiers, MouseActionPrivate>::Iterator wit;
2833 for (mit = mouseBinding_.begin(); mit != mouseBinding_.end(); ++mit)
2834 if ((mit.value().handler != handler) || (mit.value().action == ZOOM_ON_REGION))
2835 newMouseBinding[mit.key()] = mit.value();
2837 for (wit = wheelBinding_.begin(); wit != wheelBinding_.end(); ++wit)
2838 if (wit.value().handler != handler)
2839 newWheelBinding[wit.key()] = wit.value();
2842 modifiers = convertKeyboardModifiers(modifiers);
2843 for (mit = mouseBinding_.begin(); mit != mouseBinding_.end(); ++mit)
2844 if ((mit.value().handler == handler) && (mit.value().action != ZOOM_ON_REGION))
2846 int newState = modifiers | (mit.key() & Qt::MouseButtonMask);
2847 newMouseBinding[newState] = mit.value();
2850 for (wit = wheelBinding_.begin(); wit != wheelBinding_.end(); ++wit)
2851 if (wit.value().handler == handler)
2853 QtKeyboardModifiers newState = modifiers;
2854 newWheelBinding[newState] = wit.value();
2858 for (QMap<ClickActionPrivate, ClickAction>::ConstIterator cb=clickBinding_.begin(), end=clickBinding_.end(); cb != end; ++cb)
2859 if (((handler==CAMERA) && ((cb.value() == CENTER_SCENE) || (cb.value() == ALIGN_CAMERA))) ||
2860 ((handler==FRAME) && ((cb.value() == CENTER_FRAME) || (cb.value() == ALIGN_FRAME))))
2862 ClickActionPrivate cap;
2863 cap.modifiers = modifiers;
2864 cap.button = cb.key().button;
2865 cap.doubleClick = cb.key().doubleClick;
2866 cap.buttonsBefore = cb.key().buttonsBefore;
2867 newClickBinding_[cap] = cb.value();
2870 newClickBinding_[cb.key()] = cb.value();
2872 mouseBinding_ = newMouseBinding;
2873 wheelBinding_ = newWheelBinding;
2874 clickBinding_ = newClickBinding_;
2879 void QGLViewer::setHandlerStateKey(MouseHandler handler,
int buttonState)
2881 qWarning(
"setHandlerStateKey has been renamed setHandlerKeyboardModifiers");
2882 setHandlerKeyboardModifiers(handler, QtKeyboardModifiers(buttonState & Qt::KeyboardModifierMask));
2885 void QGLViewer::setMouseStateKey(MouseHandler handler,
int buttonState)
2887 qWarning(
"setMouseStateKey has been renamed setHandlerKeyboardModifiers.");
2888 setHandlerKeyboardModifiers(handler, QtKeyboardModifiers(buttonState & Qt::KeyboardModifierMask));
2925 if ((handler == FRAME) && ((action == MOVE_FORWARD) || (action == MOVE_BACKWARD) ||
2926 (action == ROLL) || (action == LOOK_AROUND) ||
2927 (action == ZOOM_ON_REGION)))
2929 #if QT_VERSION >= 0x040000
2930 qWarning(
"Cannot bind %s to FRAME", mouseActionString(action).toLatin1().constData());
2932 qWarning(
"Cannot bind %s to FRAME", mouseActionString(action).latin1());
2936 if ((state & Qt::MouseButtonMask) == 0)
2937 qWarning(
"No mouse button specified in setMouseBinding");
2940 MouseActionPrivate map;
2941 map.handler = handler;
2942 map.action = action;
2943 map.withConstraint = withConstraint;
2944 state = convertToKeyboardModifiers(state);
2946 mouseBinding_.remove(state);
2948 if (action != NO_MOUSE_ACTION)
2949 mouseBinding_.insert(state, map);
2951 ClickActionPrivate cap;
2952 cap.modifiers = QtKeyboardModifiers(state & Qt::KeyboardModifierMask);
2953 cap.button = QtMouseButtons(state & Qt::MouseButtonMask);
2954 cap.doubleClick =
false;
2955 cap.buttonsBefore = Qt::NoButton;
2956 clickBinding_.remove(cap);
2980 if ((buttonsBefore != Qt::NoButton) && !doubleClick)
2981 qWarning(
"Buttons before is only meaningful when doubleClick is true in setMouseBinding().");
2983 if ((state & Qt::MouseButtonMask) == 0)
2984 qWarning(
"No mouse button specified in setMouseBinding");
2987 ClickActionPrivate cap;
2988 state = convertToKeyboardModifiers(state);
2989 cap.modifiers = QtKeyboardModifiers(state & Qt::KeyboardModifierMask);
2990 cap.button = QtMouseButtons(state & Qt::MouseButtonMask);
2991 cap.doubleClick = doubleClick;
2992 cap.buttonsBefore = buttonsBefore;
2993 clickBinding_.remove(cap);
2996 if (action != NO_CLICK_ACTION)
2997 clickBinding_.insert(cap, action);
2999 if ((!doubleClick) && (buttonsBefore == Qt::NoButton))
3000 mouseBinding_.remove(state);
3017 if ((action != ZOOM) && (action != MOVE_FORWARD) && (action != MOVE_BACKWARD) && (action != NO_MOUSE_ACTION))
3018 #if QT_VERSION >= 0x040000
3019 qWarning(
"Cannot bind %s to wheel", mouseActionString(action).toLatin1().constData());
3021 qWarning(
"Cannot bind %s to wheel", + mouseActionString(action).latin1());
3024 if ((handler == FRAME) && (action != ZOOM) && (action != NO_MOUSE_ACTION))
3025 #if QT_VERSION >= 0x040000
3026 qWarning(
"Cannot bind %s to FRAME wheel", mouseActionString(action).toLatin1().constData());
3028 qWarning(
"Cannot bind %s to FRAME wheel", mouseActionString(action).latin1());
3032 MouseActionPrivate map;
3033 map.handler = handler;
3034 map.action = action;
3035 map.withConstraint = withConstraint;
3036 modifiers = convertKeyboardModifiers(modifiers);
3037 wheelBinding_.remove(modifiers);
3039 if (action != NO_MOUSE_ACTION)
3040 wheelBinding_.insert(modifiers, map);
3057 state = convertToKeyboardModifiers(state);
3058 if (mouseBinding_.contains(state))
3059 return mouseBinding_[state].action;
3061 return NO_MOUSE_ACTION;
3076 state = convertToKeyboardModifiers(state);
3077 if (mouseBinding_.contains(state))
3078 return mouseBinding_[state].handler;
3102 for (QMap<int, MouseActionPrivate>::ConstIterator it=mouseBinding_.begin(), end=mouseBinding_.end(); it != end; ++it)
3103 if ( (it.value().handler == handler) && (it.value().action == action) && (it.value().withConstraint == withConstraint) )
3106 return Qt::NoButton;
3116 modifiers = convertKeyboardModifiers(modifiers);
3117 if (wheelBinding_.contains(modifiers))
3118 return wheelBinding_[modifiers].action;
3120 return NO_MOUSE_ACTION;
3126 modifiers = convertKeyboardModifiers(modifiers);
3127 if (wheelBinding_.contains(modifiers))
3128 return wheelBinding_[modifiers].handler;
3139 for (QMap<QtKeyboardModifiers, MouseActionPrivate>::ConstIterator it=wheelBinding_.begin(), end=wheelBinding_.end(); it!=end; ++it)
3140 if ( (it.value().handler == handler) && (it.value().action == action) && (it.value().withConstraint == withConstraint) )
3149 ClickActionPrivate cap;
3150 cap.modifiers = QtKeyboardModifiers(convertToKeyboardModifiers(state) & Qt::KeyboardModifierMask);
3151 cap.button = QtMouseButtons(state & Qt::MouseButtonMask);
3152 cap.doubleClick = doubleClick;
3153 cap.buttonsBefore = buttonsBefore;
3154 if (clickBinding_.contains(cap))
3155 return clickBinding_[cap];
3157 return NO_CLICK_ACTION;
3167 for (QMap<ClickActionPrivate, ClickAction>::ConstIterator it=clickBinding_.begin(), end=clickBinding_.end(); it != end; ++it)
3168 if (it.value() == ca)
3170 state = it.key().modifiers | it.key().button;
3171 doubleClick = it.key().doubleClick;
3172 buttonsBefore = it.key().buttonsBefore;
3176 state = Qt::NoButton;
3182 bool QGLViewer::cameraIsInRevolveMode()
const
3185 return mouseButtonState(CAMERA, ROTATE) != Qt::NoButton;
3203 bool revolveMode = cameraIsInRevolveMode();
3206 bs = mouseButtonState(CAMERA, ROTATE);
3208 bs = mouseButtonState(CAMERA, MOVE_FORWARD);
3209 QtKeyboardModifiers modifiers = QtKeyboardModifiers(bs & Qt::KeyboardModifierMask);
3214 camera()->frame()->updateFlyUpVector();
3215 camera()->frame()->stopSpinning();
3217 setMouseBinding(modifiers | Qt::LeftButton, CAMERA, MOVE_FORWARD);
3218 setMouseBinding(modifiers | Qt::MidButton, CAMERA, LOOK_AROUND);
3219 setMouseBinding(modifiers | Qt::RightButton, CAMERA, MOVE_BACKWARD);
3221 setMouseBinding(modifiers | Qt::LeftButton | Qt::MidButton, CAMERA, ROLL);
3224 setMouseBinding(Qt::LeftButton, NO_CLICK_ACTION,
true);
3225 setMouseBinding(Qt::MidButton, NO_CLICK_ACTION,
true);
3226 setMouseBinding(Qt::RightButton, NO_CLICK_ACTION,
true);
3228 setWheelBinding(modifiers, CAMERA, MOVE_FORWARD);
3233 setMouseBinding(modifiers | Qt::LeftButton, CAMERA, ROTATE);
3234 setMouseBinding(modifiers | Qt::MidButton, CAMERA, ZOOM);
3235 setMouseBinding(modifiers | Qt::RightButton, CAMERA, TRANSLATE);
3237 setMouseBinding(modifiers | Qt::LeftButton | Qt::MidButton, CAMERA, SCREEN_ROTATE);
3240 setMouseBinding(Qt::LeftButton, ALIGN_CAMERA,
true);
3241 setMouseBinding(Qt::MidButton, SHOW_ENTIRE_SCENE,
true);
3242 setMouseBinding(Qt::RightButton, CENTER_SCENE,
true);
3244 setWheelBinding(modifiers, CAMERA, ZOOM);
3265 if (manipulatedFrame())
3267 manipulatedFrame()->stopSpinning();
3269 if (manipulatedFrame() != camera()->frame())
3271 disconnect(manipulatedFrame(), SIGNAL(manipulated()),
this, SLOT(updateGL()));
3272 disconnect(manipulatedFrame(), SIGNAL(spun()),
this, SLOT(updateGL()));
3276 manipulatedFrame_ = frame;
3278 manipulatedFrameIsACamera_ = ((manipulatedFrame() != camera()->frame()) &&
3279 (dynamic_cast<ManipulatedCameraFrame*>(manipulatedFrame()) != NULL));
3281 if (manipulatedFrame())
3284 if (manipulatedFrame() != camera()->frame())
3286 connect(manipulatedFrame(), SIGNAL(manipulated()), SLOT(updateGL()));
3287 connect(manipulatedFrame(), SIGNAL(spun()), SLOT(updateGL()));
3314 if (visualHint_ & 1)
3316 const float size = 15.0;
3317 Vec proj = camera()->projectedCoordinatesOf(camera()->revolveAroundPoint());
3318 startScreenCoordinatesSystem();
3319 glDisable(GL_LIGHTING);
3320 glDisable(GL_DEPTH_TEST);
3323 glVertex2f(proj.x - size, proj.y);
3324 glVertex2f(proj.x + size, proj.y);
3325 glVertex2f(proj.x, proj.y - size);
3326 glVertex2f(proj.x, proj.y + size);
3328 glEnable(GL_DEPTH_TEST);
3329 stopScreenCoordinatesSystem();
3338 if (camera()->frame()->action_ == SCREEN_ROTATE)
3340 mf = camera()->frame();
3341 pnt = camera()->revolveAroundPoint();
3343 if (manipulatedFrame() && (manipulatedFrame()->action_ == SCREEN_ROTATE))
3345 mf = manipulatedFrame();
3348 pnt = manipulatedFrame()->position();
3353 pnt = camera()->projectedCoordinatesOf(pnt);
3354 startScreenCoordinatesSystem();
3355 glDisable(GL_LIGHTING);
3356 glDisable(GL_DEPTH_TEST);
3359 glVertex2f(pnt.x, pnt.y);
3360 glVertex2f(mf->prevPos_.x(), mf->prevPos_.y());
3362 glEnable(GL_DEPTH_TEST);
3363 stopScreenCoordinatesSystem();
3367 if (camera()->frame()->action_ == ZOOM_ON_REGION)
3369 startScreenCoordinatesSystem();
3370 glDisable(GL_LIGHTING);
3371 glDisable(GL_DEPTH_TEST);
3373 glBegin(GL_LINE_LOOP);
3374 glVertex2i(camera()->frame()->pressPos_.x(), camera()->frame()->pressPos_.y());
3375 glVertex2i(camera()->frame()->prevPos_.x(), camera()->frame()->pressPos_.y());
3376 glVertex2i(camera()->frame()->prevPos_.x(), camera()->frame()->prevPos_.y());
3377 glVertex2i(camera()->frame()->pressPos_.x(), camera()->frame()->prevPos_.y());
3379 glEnable(GL_DEPTH_TEST);
3380 stopScreenCoordinatesSystem();
3389 visualHint_ = visualHint_ | mask;
3390 QTimer::singleShot(delay,
this, SLOT(resetVisualHints()));
3415 static GLUquadric* quadric = gluNewQuadric();
3418 radius = 0.05 * length;
3420 const float head = 2.5*(radius / length) + 0.1;
3421 const float coneRadiusCoef = 4.0 - 5.0 * head;
3423 gluCylinder(quadric, radius, radius, length * (1.0 - head/coneRadiusCoef), nbSubdivisions, 1);
3424 glTranslatef(0.0, 0.0, length * (1.0 - head));
3425 gluCylinder(quadric, coneRadiusCoef * radius, 0.0, head * length, nbSubdivisions, 1);
3426 glTranslatef(0.0, 0.0, -length * (1.0 - head));
3436 glTranslatef(from[0],from[1],from[2]);
3437 const Vec dir = to-from;
3463 const float charWidth = length / 40.0;
3464 const float charHeight = length / 30.0;
3465 const float charShift = 1.04 * length;
3467 GLboolean lighting, colorMaterial;
3468 glGetBooleanv(GL_LIGHTING, &lighting);
3469 glGetBooleanv(GL_COLOR_MATERIAL, &colorMaterial);
3471 glDisable(GL_LIGHTING);
3475 glVertex3f(charShift, charWidth, -charHeight);
3476 glVertex3f(charShift, -charWidth, charHeight);
3477 glVertex3f(charShift, -charWidth, -charHeight);
3478 glVertex3f(charShift, charWidth, charHeight);
3480 glVertex3f( charWidth, charShift, charHeight);
3481 glVertex3f(0.0, charShift, 0.0);
3482 glVertex3f(-charWidth, charShift, charHeight);
3483 glVertex3f(0.0, charShift, 0.0);
3484 glVertex3f(0.0, charShift, 0.0);
3485 glVertex3f(0.0, charShift, -charHeight);
3487 glVertex3f(-charWidth, charHeight, charShift);
3488 glVertex3f( charWidth, charHeight, charShift);
3489 glVertex3f( charWidth, charHeight, charShift);
3490 glVertex3f(-charWidth, -charHeight, charShift);
3491 glVertex3f(-charWidth, -charHeight, charShift);
3492 glVertex3f( charWidth, -charHeight, charShift);
3495 glEnable(GL_LIGHTING);
3496 glDisable(GL_COLOR_MATERIAL);
3499 color[0] = 0.7f; color[1] = 0.7f; color[2] = 1.0f; color[3] = 1.0f;
3500 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color);
3503 color[0] = 1.0f; color[1] = 0.7f; color[2] = 0.7f; color[3] = 1.0f;
3504 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color);
3506 glRotatef(90.0, 0.0, 1.0, 0.0);
3510 color[0] = 0.7f; color[1] = 1.0f; color[2] = 0.7f; color[3] = 1.0f;
3511 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color);
3513 glRotatef(-90.0, 1.0, 0.0, 0.0);
3518 glEnable(GL_COLOR_MATERIAL);
3520 glDisable(GL_LIGHTING);
3532 glGetBooleanv(GL_LIGHTING, &lighting);
3534 glDisable(GL_LIGHTING);
3537 for (
int i=0; i<=nbSubdivisions; ++i)
3539 const float pos = size*(2.0*i/nbSubdivisions-1.0);
3540 glVertex2f(pos, -size);
3541 glVertex2f(pos, +size);
3542 glVertex2f(-size, pos);
3543 glVertex2f( size, pos);
3548 glEnable(GL_LIGHTING);
3556 void QGLViewer::saveStateToFileForAllViewers()
3558 #if QT_VERSION >= 0x040000
3563 for (
QGLViewer* viewer; (viewer = it.current()) != 0; ++it)
3590 QString name = stateFileName_;
3595 #if QT_VERSION >= 0x040000
3596 if (fi.suffix().isEmpty())
3598 if (fi.extension(
false).isEmpty())
3602 #if QT_VERSION >= 0x040000
3603 name = fi.absolutePath() +
'/' + fi.completeBaseName() + QString::number(
QGLViewer::QGLViewerIndex(
this)) +
"." + fi.suffix();
3605 # if QT_VERSION >= 0x030000
3606 name = fi.dirPath() +
'/' + fi.baseName(
true) + QString::number(
QGLViewer::QGLViewerIndex(
this)) +
"." + fi.extension(
false);
3625 QString name = stateFileName();
3630 QFileInfo fileInfo(name);
3632 if (fileInfo.isDir())
3634 QMessageBox::warning(
this, tr(
"Save to file error",
"Message box window title"), tr(
"State file name (%1) references a directory instead of a file.").arg(name));
3638 #if QT_VERSION >= 0x040000
3639 const QString dirName = fileInfo.absolutePath();
3641 const QString dirName = fileInfo.dirPath();
3643 if (!QFileInfo(dirName).exists())
3646 #if QT_VERSION >= 0x040000
3647 if (!(dir.mkdir(dirName)))
3649 if (!(dir.mkdir(dirName,
true)))
3652 QMessageBox::warning(
this, tr(
"Save to file error",
"Message box window title"), tr(
"Unable to create directory %1").arg(dirName));
3659 #if QT_VERSION >= 0x040000
3660 if (f.open(QIODevice::WriteOnly))
3662 if (f.open(IO_WriteOnly))
3665 QTextStream out(&f);
3666 QDomDocument doc(
"QGLVIEWER");
3667 doc.appendChild(domElement(
"QGLViewer", doc));
3673 #if QT_VERSION < 0x030200
3674 QMessageBox::warning(
this, tr(
"Save to file error",
"Message box window title"), tr(
"Unable to save to file %1").arg(name));
3676 QMessageBox::warning(
this, tr(
"Save to file error",
"Message box window title"), tr(
"Unable to save to file %1").arg(name) +
":\n" + f.errorString());
3702 QString name = stateFileName();
3707 QFileInfo fileInfo(name);
3709 if (!fileInfo.isFile())
3713 if (!fileInfo.isReadable())
3715 QMessageBox::warning(
this, tr(
"Problem in state restoration",
"Message box window title"), tr(
"File %1 is not readable.").arg(name));
3721 #if QT_VERSION >= 0x040000
3722 if (f.open(QIODevice::ReadOnly) ==
true)
3724 if (f.open(IO_ReadOnly) ==
true)
3730 QDomElement main = doc.documentElement();
3731 initFromDOMElement(main);
3735 #if QT_VERSION < 0x030200
3736 QMessageBox::warning(
this, tr(
"Open file error",
"Message box window title"), tr(
"Unable to open file %1").arg(name));
3738 QMessageBox::warning(
this, tr(
"Open file error",
"Message box window title"), tr(
"Unable to open file %1").arg(name) +
":\n" + f.errorString());
3780 QDomElement de = document.createElement(name);
3781 de.setAttribute(
"version", QGLViewerVersionString());
3783 QDomElement stateNode = document.createElement(
"State");
3785 stateNode.appendChild(DomUtils::QColorDomElement(foregroundColor(),
"foregroundColor", document));
3786 stateNode.appendChild(DomUtils::QColorDomElement(backgroundColor(),
"backgroundColor", document));
3787 stateNode.setAttribute(
"stereo", (displaysInStereo()?
"true":
"false"));
3788 stateNode.setAttribute(
"cameraMode", (cameraIsInRevolveMode()?
"revolve":
"fly"));
3789 de.appendChild(stateNode);
3791 QDomElement displayNode = document.createElement(
"Display");
3792 displayNode.setAttribute(
"axisIsDrawn", (axisIsDrawn()?
"true":
"false"));
3793 displayNode.setAttribute(
"gridIsDrawn", (gridIsDrawn()?
"true":
"false"));
3794 displayNode.setAttribute(
"FPSIsDisplayed", (FPSIsDisplayed()?
"true":
"false"));
3795 displayNode.setAttribute(
"cameraIsEdited", (cameraIsEdited()?
"true":
"false"));
3797 de.appendChild(displayNode);
3799 QDomElement geometryNode = document.createElement(
"Geometry");
3800 geometryNode.setAttribute(
"fullScreen", (isFullScreen()?
"true":
"false"));
3803 geometryNode.setAttribute(
"prevPosX", QString::number(prevPos_.x()));
3804 geometryNode.setAttribute(
"prevPosY", QString::number(prevPos_.y()));
3808 QWidget* tlw = topLevelWidget();
3809 geometryNode.setAttribute(
"width", QString::number(tlw->width()));
3810 geometryNode.setAttribute(
"height", QString::number(tlw->height()));
3811 geometryNode.setAttribute(
"posX", QString::number(tlw->pos().x()));
3812 geometryNode.setAttribute(
"posY", QString::number(tlw->pos().y()));
3814 de.appendChild(geometryNode);
3817 if (cameraIsEdited())
3818 camera()->setZClippingCoefficient(previousCameraZClippingCoefficient_);
3819 de.appendChild(camera()->domElement(
"Camera", document));
3820 if (cameraIsEdited())
3822 camera()->setZClippingCoefficient(5.0);
3824 if (manipulatedFrame())
3825 de.appendChild(manipulatedFrame()->domElement(
"ManipulatedFrame", document));
3866 const QString version = element.attribute(
"version");
3868 if (version[0] !=
'2')
3870 #if QT_VERSION >= 0x040000
3871 qWarning(
"State file created using QGLViewer version %s may not be correctly read.", version.toLatin1().constData());
3873 qWarning(
"State file created using QGLViewer version %s may not be correctly read.", version.latin1());
3876 QDomElement child=element.firstChild().toElement();
3877 bool tmpCameraIsEdited = cameraIsEdited();
3878 while (!child.isNull())
3880 if (child.tagName() ==
"State")
3884 setStereoDisplay(DomUtils::boolFromDom(child,
"stereo",
false));
3885 if ((child.attribute(
"cameraMode",
"revolve") ==
"fly") && (cameraIsInRevolveMode()))
3888 QDomElement ch=child.firstChild().toElement();
3889 while (!ch.isNull())
3891 if (ch.tagName() ==
"foregroundColor")
3892 setForegroundColor(DomUtils::QColorFromDom(ch));
3893 if (ch.tagName() ==
"backgroundColor")
3894 setBackgroundColor(DomUtils::QColorFromDom(ch));
3895 ch = ch.nextSibling().toElement();
3899 if (child.tagName() ==
"Display")
3902 setAxisIsDrawn(DomUtils::boolFromDom(child,
"axisIsDrawn",
false));
3903 setGridIsDrawn(DomUtils::boolFromDom(child,
"gridIsDrawn",
false));
3904 setFPSIsDisplayed(DomUtils::boolFromDom(child,
"FPSIsDisplayed",
false));
3906 tmpCameraIsEdited = DomUtils::boolFromDom(child,
"cameraIsEdited",
false);
3910 if (child.tagName() ==
"Geometry")
3912 setFullScreen(DomUtils::boolFromDom(child,
"fullScreen",
false));
3916 prevPos_.setX(DomUtils::intFromDom(child,
"prevPosX", 0));
3917 prevPos_.setY(DomUtils::intFromDom(child,
"prevPosY", 0));
3921 int width = DomUtils::intFromDom(child,
"width", 600);
3922 int height = DomUtils::intFromDom(child,
"height", 400);
3923 topLevelWidget()->resize(width, height);
3924 camera()->setScreenWidthAndHeight(this->width(), this->height());
3927 pos.setX(DomUtils::intFromDom(child,
"posX", 0));
3928 pos.setY(DomUtils::intFromDom(child,
"posY", 0));
3929 topLevelWidget()->move(pos);
3933 if (child.tagName() ==
"Camera")
3935 connectAllCameraKFIInterpolatedSignals(
false);
3936 camera()->initFromDOMElement(child);
3937 connectAllCameraKFIInterpolatedSignals();
3940 if ((child.tagName() ==
"ManipulatedFrame") && (manipulatedFrame()))
3941 manipulatedFrame()->initFromDOMElement(child);
3943 child = child.nextSibling().toElement();
3950 cameraIsEdited_ = tmpCameraIsEdited;
3951 if (cameraIsEdited_)
3953 previousCameraZClippingCoefficient_ = camera()->zClippingCoefficient();
3955 camera()->setZClippingCoefficient(5.0);
3964 if (!fileName.isEmpty())
3965 setStateFileName(fileName);
3967 qWarning(
"saveToFile() is deprecated, use saveStateToFile() instead.");
3975 if (!fileName.isEmpty())
3976 setStateFileName(fileName);
3978 qWarning(
"restoreFromFile() is deprecated, use restoreStateFromFile() instead.");
3979 return restoreStateFromFile();
4043 while (h < height())
4048 if ((w != bufferTextureWidth_) || (h != bufferTextureHeight_))
4050 bufferTextureWidth_ = w;
4051 bufferTextureHeight_ = h;
4052 bufferTextureMaxU_ = width() / float(bufferTextureWidth_);
4053 bufferTextureMaxV_ = height() / float(bufferTextureHeight_);
4057 if (bufferTextureId() == 0)
4059 glGenTextures(1, &bufferTextureId_);
4060 glBindTexture(GL_TEXTURE_2D, bufferTextureId_);
4061 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4062 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4066 glBindTexture(GL_TEXTURE_2D, bufferTextureId_);
4068 if ((format != previousBufferTextureFormat_) ||
4069 (internalFormat != previousBufferTextureInternalFormat_))
4071 previousBufferTextureFormat_ = format;
4072 previousBufferTextureInternalFormat_ = internalFormat;
4078 if (format == GL_NONE)
4079 format = internalFormat;
4081 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, bufferTextureWidth_, bufferTextureHeight_, 0, format, GL_UNSIGNED_BYTE, NULL);
4084 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, width(), height());
4095 if (glIsTexture(bufferTextureId_))
4096 return bufferTextureId_;