ATLAS Offline Software
Loading...
Searching...
No Matches
VP1ExaminerViewer.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5
6
8// //
9// Implementation of class VP1ExaminerViewer //
10// //
11// Author: Thomas H. Kittelmann (Thomas.Kittelmann@cern.ch) //
12// Initial version: March 2008 //
13// //
14// Major updates: //
15// Sep 2013, Riccardo-Maria BIANCHI rbianchi@cern.ch //
16// Sep 2017, Riccardo-Maria BIANCHI rbianchi@cern.ch //
17// //
19
22#include "VP1Base/VP1Msg.h"
25#include "VP1Base/VP1QtUtils.h"
27#include "VP1Base/VP1Settings.h"
32
33#include <Inventor/nodes/SoSphere.h>
34#include <Inventor/nodes/SoGroup.h>
35#include <Inventor/nodes/SoPerspectiveCamera.h>
36#include <Inventor/nodes/SoSeparator.h>
37#include <Inventor/Qt/widgets/SoQtPopupMenu.h>
38#include <Inventor/events/SoKeyboardEvent.h>
39#include <Inventor/events/SoMouseButtonEvent.h>
40#include <Inventor/nodes/SoEnvironment.h>
41#include <Inventor/actions/SoSearchAction.h>
42#include <Inventor/nodekits/SoBaseKit.h>
43#include <Inventor/SoSceneManager.h>
44
45#include <QBuffer>
46#include <QByteArray>
47#include <QMenu>
48#include <QCursor>
49#include <QColorDialog>
50#include <QFileDialog>
51#include <QInputDialog>
52#include <QPushButton>
53#include <QGLFormat>
54
55// Has to be after qt headers because qt uses its own glext.
56#include "VP1HEPVis/gl2ps.h"
57
58#include <map>
59#include <iostream>
60#include <typeinfo>
61
62//TODO: Statustips.
63//TODO: windows menu button should launch the menu (in correct mode?).
64//TODO: detectorviewbuttons (+others) in menu so hidden control modes has access to everything!
65//TODO: preserve spinning when going to next event (or when tour returns).
66
67//____________________________________________________________________
69
70public:
71 Imp (const Imp&) = delete;
72 Imp& operator= (const Imp&) = delete;
73
75: theclass(tc),
82 popup_menu(0),
127 tourLoopsForever(false),
130 isantialias(false),
133 button_home(0),
136 button_seek(0),
138 sphere(0),
141 movieFrameFileNamePrefix("vp1_frame"),
143{
144 VP1Msg::messageVerbose("VP1ExaminerViewer::Imp() constructor");
145 signalcatcher->m_d = this; init();
146
147 // TEST
148 // With this command, Coin does not clear the pixel-buffer,
149 // so the previous (or background) image
150 // is not removed before the new rendering.
151 // theclass->setClearBeforeRender(FALSE, TRUE);
152 // theclass->setClearBeforeRender(FALSE, FALSE);
153 // theclass->setClearBeforeOverlayRender(FALSE);
154}
155
157 {
158 VP1Msg::messageVerbose("VP1ExaminerViewer::~Imp() destructor");
160 actualSceneGraph->unref();
161 if (environmentNode)
162 environmentNode->unref();
164 customtoureditor->deleteLater();
166 customstereoeditor->deleteLater();
167 delete popup_menu;
168 delete signalcatcher;
169 if (sphere)
170 sphere->unref();
171 }
172
173
174
176 QString toString(const REGION& r) {
177 switch (r) {
178 case VERTEX: return "VERTEX";
179 case INDET: return "INDET";
180 case FORWARDREGION: return "FORWARDREGION";
181 case CALO: return "CALO";
182 case MUON: return "MUON";
183 default: return "Unknown(ERROR)";
184 }
185 }
186
188
189 enum VIEW { ASIDE, CSIDE, BARREL };
190 std::map<QPushButton*,std::pair<REGION,VIEW> > detectorbuttons;
191 QPushButton *takeTourButton; // * JFB
192
195
196
197 QPushButton * addNewButton(QString text,QString tooltip,REGION region ,VIEW view,QWidget * tempparent, QString iconname="");
198 void init();
199 void detectorZoomButtonClicked(std::pair<REGION,VIEW>);
200 void takeTourButtonClicked(); // * JFB
201 void grabFocus();
202
203
205 SoEnvironment * environmentNode;
206
207
208
209
210 bool ensureMenuInit();
215 QMenu * popup_menu;
259 // stereo view
262// QList<QAction*> popup_stereo_offset_actions;
263// QList<QAction*> popup_stereo_type_actions;
264// QList<QAction*> popup_stereo_anaglyph_actions;
265// QList<QAction*> popup_stereo_anaglyph_actions_camera;
266// QMenu * stereo_set_anaglyph_menu;
267// QMenu * stereo_set_stereo_camera_view_menu;
268// QAction* popup_stereo_offset_value_action;
269// QAction* popup_stereo_offset_value_action_camera;
270// QAction* popup_stereo_balance_value_action_camera;
271
272
274 if (environmentNode) {
275 int al = theclass->ambientLight();
276 environmentNode->ambientIntensity = (al==0?0.0f:(al==100?1.0f:al/100.0f));
277 }
278 }
279
280
286 bool updateAnimationSequence();//Returns false if nothing is to be animated (i.e. no regions selected)
289 QPushButton * button_interact;
290 QPushButton * button_examine;
291 QPushButton * button_home;
292 QPushButton * button_sethome;
293 QPushButton * button_viewall;
294 QPushButton * button_seek;
295 QPushButton * button_togglecamera;
296 SoSphere * sphere;
297 SoSphere * getRegionSphere(REGION,bool perspective);
298
300
301 float rotZWheelMotion(float value, float oldvalue);
302 float rotXWheelMotion(float value, float oldvalue);
303 void rotateCamera(SoCamera * cam,const SbVec3f & aroundaxis,const float delta);
304 static int drawStyleToInt(SoQtViewer::DrawStyle);
305 static SoQtViewer::DrawStyle intToDrawStyle(int);
306
307
310 popup_ambientLightAction->setText("Change ambient &light [current "+QString::number(ambientLightPercentage)+"%]");
311 }
313
314
316
318
319 void aboutToShowMenu(QMenu *);
320
322 QString lastSVGFile;
323 QString lastEPSFile;
326
328 public:
329 StoredView(const QByteArray& camState, bool camPerspective, QPixmap snapShot, const QString& name)
331 StoredView(QByteArray persistifiedState);
332 const QString& name() const { return m_name; }
333 const QByteArray& camState() const { return m_camState; }
335 QPixmap snapShot() const { return m_snapShot; }
336 QByteArray persistifiedState() const;
337 QIcon icon() const {
338 if (m_cachedIcon.isNull())
339 m_cachedIcon = QIcon(m_snapShot);
340 return m_cachedIcon;
341 }
342 bool isValid() { return !m_name.isEmpty()&&!m_camState.isEmpty()&&!m_snapShot.isNull(); }
343
344
345 private:
346 QByteArray m_camState;
348 QPixmap m_snapShot;//FIXME: Update this whenever we have just "restored view"
349 QString m_name;
350 mutable QIcon m_cachedIcon;
351 };
352
353 bool fitsCurrentCamType(const StoredView& sv) { return sv.camStateIsPerspective()==theclass->currentCamIsPerspective(); }
354
355 QList<StoredView> storedViews;
358 viewmenu_deleteview->setEnabled(!storedViews.isEmpty());
360 viewmenu_restoreview->setEnabled(!storedViews.isEmpty());
362 viewmenu_zoomtoview->setEnabled(!storedViews.isEmpty());
363 }
364 QList<QAction*> storeViewActions;
365 QList<QAction*> restoreViewActions;
366 QList<QAction*> deleteViewActions;
367 QList<QAction*> zoomToViewActions;
369 const bool perspective(theclass->currentCamIsPerspective());
370 int i(1);
371 while (true) {
372 QString n = QString(perspective?"Perspective":"Orthographic")+"View"+QString::number(i++);
373 bool ok(true);
374 for(const StoredView & sv : storedViews) {
375 if (sv.name()==n) {
376 ok = false;
377 break;
378 }
379 }
380 if (ok)
381 return n;
382 }
383 }
384
386 // For persistification, etc. of draw styles (possibly move to util class) //
388 static QList<SoQtViewer::DrawStyle> getAllViewerDrawStyles();
389 static int viewerDrawStyleToInt( SoQtViewer::DrawStyle );//Returns -1 if unknown.
390 static SoQtViewer::DrawStyle intToViewerDrawStyle( int );//Return VIEW_AS_IS if unknown;
391 static QString viewerDrawStyle2PrettyString( SoQtViewer::DrawStyle );//Returns "" if unknown.
392 // Stereo view
393 static QList<SoQtViewer::StereoType> getAllStereoViewTypes();
394 static int viewerStereoTypeToInt( SoQtViewer::StereoType );//Returns -1 if unknown.
395 static SoQtViewer::StereoType intToViewerStereoType( int );//Return STEREO_NONE if unknown;
396 static QString viewerStereoType2PrettyString( SoQtViewer::StereoType );//Returns "" if unknown.
397
398
399
400};
401
402
403
404
405//____________________________________________________________________
407{
408 VP1Msg::messageVerbose("persistifiedState()");
409
410 // ===> Setup stream writing to a byteArray:
411 QByteArray byteArray;
412 QBuffer buffer(&byteArray);
413 buffer.open(QIODevice::WriteOnly);
414 QDataStream out(&buffer);
415
416 // ===> Write Data:
417 out << (qint32)0;//version
418 out << m_name;
419 out << m_camState;
420 out << m_camPerspective;
421 out << m_snapShot;
422
423 // ===> Finish up:
424 buffer.close();
425 return byteArray;
426}
427
428//____________________________________________________________________
430: m_camPerspective(true)
431{
432 VP1Msg::messageVerbose("StoredView()");
433
434 // ===> Setup stream for getting the contents of the byteArray:
435 QBuffer buffer(&persistifiedState);
436 buffer.open(QIODevice::ReadOnly);
437 QDataStream state(&buffer);
438 // ===> Check version and pass on state info to base class:
439 qint32 version;
440 state >> version;
441 if (version!=0) {
442 VP1Msg::messageDebug("VP1ExaminerViewer Warning: "
443 "Attempt to depersistify stored view ignored due to bad version!");
444 return;
445 }
446 // ===> Decode the state info:
447 state >> m_name;
448 state >> m_camState;
449 state >> m_camPerspective;
450 state >> m_snapShot;
451 if (!buffer.atEnd())
452 m_name = "";//To make isValid() return false;
453 // ===> Finish up:
454 buffer.close();
455}
456
457
458
459//____________________________________________________________________
463
464// N.B.
465// this code has been taken and adapted from CMSSW:
466// http://cmssw.cvs.cern.ch/cgi-bin/cmssw.cgi/CMSSW/ISpy/Client/src/ISpy3DView.cc?view=co
467//
468void debugCameraClipPlanes(void * data, const SbVec2f & nearfar)
469{
470 SoCamera *camera = ((VP1ExaminerViewer *) data)->getCamera();
471 SoNode *scenegraph = ((VP1ExaminerViewer *) data)->getSceneGraph();
472
473 SbVec3f pos = camera->position.getValue();
474
475 SoSearchAction action;
476 SbBool oldsearch = SoBaseKit::isSearchingChildren();
477 SoBaseKit::setSearchingChildren(TRUE);
478
479 action.setSearchingAll(true);
480 action.setType(SoCamera::getClassTypeId());
481 action.setInterest(SoSearchAction::ALL);
482 action.apply(scenegraph);
483
484 SoBaseKit::setSearchingChildren(oldsearch);
485
486 SoPathList &cameras = action.getPaths();
487
488 for (int i = 0, e = cameras.getLength(); i != e; ++i) {
489 auto* tail = cameras[i]->getTail();
490 std::cerr << "Camera #" << i << " = " << (void *) tail << "(" << typeid(*tail).name() << ")\n";
491 }
492
493 std::cerr << "Calculated clip-planes. Near: " << nearfar[0] << ". Far: " << nearfar[1] << "\n"
494 << "Current camera clip-planes. Near: " << camera->nearDistance.getValue() << ", Far: " << camera->farDistance.getValue() << "\n"
495 << "Camera ptr: " << (void *) camera << "\n"
496 << "Camera name: " << camera->getName() << "\n"
497 << "Camera type: " << typeid(*camera).name() << "\n"
498 << "Camera position:(" << pos[0] << ", " << pos[1] << ", " << pos[2] << ")\n"
499 << "Number of cameras in the scene: " << cameras.getLength() << "\n"
500 << "Focal distance: " << camera->focalDistance.getValue() << std::endl;
501}
502
503//____________________________________________________________________
507
508// N.B.
509// this code has been taken and adapted from CMSSW:
510// http://cmssw.cvs.cern.ch/cgi-bin/cmssw.cgi/CMSSW/ISpy/Client/src/ISpy3DView.cc?view=co
511//
512SbVec2f fixedDistanceClipPlanesCB(void * data, const SbVec2f & nearfar)
513{
514 SoCamera *camera = ((VP1ExaminerViewer *) data)->getCamera();
515 if (0) debugCameraClipPlanes(data, nearfar);
516
517 if (camera->nearDistance.getValue() != nearfar[0])
518 camera->nearDistance = nearfar[0];
519 if (camera->farDistance.getValue() != nearfar[1])
520 camera->farDistance = nearfar[1];
521
522 return nearfar;
523}
524
525//____________________________________________________________________
528 const char * name,
529 SbBool embed,
530 SoQtFullViewer::BuildFlag flag,
531 SoQtViewer::Type type)
532: SoQtExaminerViewer(parent,(name?name:"VP1ExaminerViewer"),embed,flag,type,false/*delay createViewerButtons call*/),
533 m_d(new Imp(this,detectorViewButtons))
534{
535 VP1Msg::messageDebug("VP1ExaminerViewer::VP1ExaminerViewer()");
536 // Explicitly trigger the construction of viewer decorations.
537 QWidget * widget = buildWidget(getParentWidget());
538 if (rightWheelLabel)
539 rightWheelLabel->setVisible(false);//it will be shown again by the first setCameraType call
540 setBaseWidget(widget);
541 setLeftWheelString("Rotz");
542 m_d->rotationMode=Imp::ZROT;
543// setRightWheelString("Zoom");
544 setRightWheelString("Zoom test");
545 leftWheel->setMinimumHeight(20);
546 rightWheel->setMinimumHeight(20);
547
548
549 /* set the clipping strategy and fix the clipping
550 *
551 * N.B.
552 * this code has been taken and adapted from CMSSW:
553 * http://cmssw.cvs.cern.ch/cgi-bin/cmssw.cgi/CMSSW/ISpy/Client/src/ISpy3DView.cc?view=co
554 */
555 setAutoClippingStrategy(CONSTANT_NEAR_PLANE, 0.9, fixedDistanceClipPlanesCB, this);
556
557 // Let's build this now, otherwise there will be problems with making the connections later:
558 m_d->customtoureditor = new VP1CustomTourEditor(this);
559 QObject::connect(&(m_d->animationSequencer),SIGNAL(clipVolumePercentOfATLAS(double)),m_d->customtoureditor,SLOT(setClipVolumePercentOfATLAS(double)));
560 VP1Controller::setCustomTourEditor(m_d->customtoureditor);
561 m_d->customtoureditor->disableObjectWhenTourNotAvailable(m_d->customtour_execute);
562 if (m_d->customtoureditorState!=QByteArray()) {
563 m_d->customtoureditor->setState(m_d->customtoureditorState);
564 m_d->customtoureditorState = QByteArray();
565 }
566
567 // test Ric
568 VP1Msg::messageVerbose("is stereo: " + QString(isStereoViewing()) + " - offset: " + QString::number(getStereoOffsetSlot()) + " - type: " + QString::number(getStereoType()) );
569}
570
571
572// stereographic view methods
574 VP1Msg::messageDebug("VP1ExaminerViewer::setStereoOffsetSlot() - offset: " + QString::number(offset));
575 SoQtExaminerViewer::setStereoOffset(offset);
576}
578 return SoQtExaminerViewer::getStereoOffset();
579}
580SbBool VP1ExaminerViewer::setStereoTypeSlot(SoQtViewer::StereoType type) {
581 VP1Msg::messageDebug("VP1ExaminerViewer::setStereoTypeSlot() - type: " + QString::number(type));
582 return SoQtExaminerViewer::setStereoType(type);
583}
584SoQtViewer::StereoType VP1ExaminerViewer::getStereoTypeSlot(void) const {
585 return SoQtExaminerViewer::getStereoType();
586}
587void VP1ExaminerViewer::setAnaglyphStereoColorMasksSlot(const SbBool left[3], const SbBool right[3]) {
588 SoQtExaminerViewer::setAnaglyphStereoColorMasks(left, right);
589}
590void VP1ExaminerViewer::getAnaglyphStereoColorMasksSlot(SbBool left[3], SbBool right[3]) {
591 SoQtExaminerViewer::getAnaglyphStereoColorMasks(left, right);
592}
593
594
595
596
597//____________________________________________________________________
598int VP1ExaminerViewer::Imp::drawStyleToInt(SoQtViewer::DrawStyle ds) {
599 switch (ds) {
600 case VIEW_AS_IS: return 0;
601 case VIEW_HIDDEN_LINE: return 1;
602 case VIEW_NO_TEXTURE: return 2;
603 case VIEW_LOW_COMPLEXITY: return 3;
604 case VIEW_LINE: return 4;
605 case VIEW_POINT: return 5;
606 case VIEW_BBOX: return 6;
607 case VIEW_LOW_RES_LINE: return 7;
608 case VIEW_LOW_RES_POINT: return 8;
609 case VIEW_SAME_AS_STILL: return 9;
610 case VIEW_WIREFRAME_OVERLAY : return 10;
611 default:
612 VP1Msg::messageDebug("VP1ExaminerViewer::Imp::drawStyleToInt ERROR: Unknown draw style");
613 return 0;
614 }
615}
616
617//____________________________________________________________________
618SoQtViewer::DrawStyle VP1ExaminerViewer::Imp::intToDrawStyle(int i) {
619 switch (i) {
620 case 0: return SoQtViewer::VIEW_AS_IS;
621 case 1: return SoQtViewer::VIEW_HIDDEN_LINE;
622 case 2: return SoQtViewer::VIEW_NO_TEXTURE;
623 case 3: return SoQtViewer::VIEW_LOW_COMPLEXITY;
624 case 4: return SoQtViewer::VIEW_LINE;
625 case 5: return SoQtViewer::VIEW_POINT;
626 case 6: return SoQtViewer::VIEW_BBOX;
627 case 7: return SoQtViewer::VIEW_LOW_RES_LINE;
628 case 8: return SoQtViewer::VIEW_LOW_RES_POINT;
629 case 9: return SoQtViewer::VIEW_SAME_AS_STILL;
630 case 10: return SoQtViewer::VIEW_WIREFRAME_OVERLAY;
631 default:
632 VP1Msg::messageDebug("VP1ExaminerViewer::Imp::intToDrawStyle ERROR: int out of range "+str(i));
633 return SoQtViewer::VIEW_AS_IS;
634 }
635}
636
637//____________________________________________________________________
639{
640 VP1Msg::messageVerbose("VP1ExaminerViewer::saveState");
641
642 // ===> Setup stream writing to a byteArray:
643 QByteArray byteArray;
644 QBuffer buffer(&byteArray);
645 buffer.open(QIODevice::WriteOnly);
646 QDataStream out(&buffer);
647
648 // ===> Write Data:
649 //Version:
650 out << (qint32)6; //version
651
652 //Background color:
653 QColor bgdcol(VP1QtInventorUtils::sbcol2qcol(getBackgroundColor()));
654 out << bgdcol;
655 VP1Msg::messageVerbose("saveState background color = "+str(bgdcol));
656
657 //Render buffer:
658 int ibuffer(0);
659 if (getBufferingType()==BUFFER_SINGLE)
660 ibuffer=1;
661 else if (getBufferingType()==BUFFER_INTERACTIVE)
662 ibuffer=2;
663 out << ibuffer;
664 VP1Msg::messageVerbose("saveState Render Buffer = ("+str(ibuffer)+")");
665
666 //Camera type and parameters:
667 bool isperspective(currentCamIsPerspective());
668 out << isperspective;
669 out << currentCameraState();
670 VP1Msg::messageVerbose("saveState camera type = "+str(isperspective?"Perspective":"Orthographic"));
671
672 //Misc:
673 const bool isdeco(isDecoration()), isheadlight(isHeadlight()),isviewing(isViewing());
674 out << isdeco;
675 out << isheadlight;
676 out << isviewing;
677 out << m_d->decorationMenuRemoved;
678 VP1Msg::messageVerbose("saveState (deco,headlight,viewing,nodecomenu) = ("
679 +str(isdeco)+", "+str(isheadlight)+", "+str(isviewing)+", "+str(m_d->decorationMenuRemoved)+")");
680
681 //Antialiasing state:
682 out << m_d->isantialias;//version 6+
683 VP1Msg::messageVerbose("saveState (isantialis)) = ("+str(m_d->isantialias)+")");
684 //OLD (up to version 5):
685 // SbBool smoothing; int numPasses;
686 // getAntialiasing(smoothing, numPasses);
687 // out << smoothing;
688 // out << numPasses;
689 // VP1Msg::messageVerbose("saveState (smoothing,numPasses)) = ("+str(smoothing)+", "+str(numPasses)+")");
690
691 //Draw style:
692 int idrawstyle_still = Imp::drawStyleToInt(getDrawStyle(STILL));
693 int idrawstyle_interactive = Imp::drawStyleToInt(getDrawStyle(INTERACTIVE));
694 out << idrawstyle_still;
695 out << idrawstyle_interactive;
696 VP1Msg::messageVerbose("saveState DrawStyle (still,interactive)) = ("+str(idrawstyle_still)+", "+str(idrawstyle_interactive)+")");
697
698 //Transparency type:
699 int itransp = VP1QtInventorUtils::transparencyTypeToInt(getTransparencyType());
700 out << itransp;
701 VP1Msg::messageVerbose("saveState Transparency Type = ("+str(itransp)+")");
702
704 // Added for version 1 //
706
707 m_d->ensureMenuInit();
708 out << m_d->popup_tourReturnToStartAction->isChecked();
709 out << m_d->popup_tourStartEachEvent->isChecked();
710
711 qint32 ispeed(0);//medium
712 if (m_d->popup_tourSpeedVerySlow->isChecked()) ispeed = -2;
713 else if (m_d->popup_tourSpeedSlow->isChecked()) ispeed = -1;
714 else if (m_d->popup_tourSpeedFast->isChecked()) ispeed = 1;
715 else if (m_d->popup_tourSpeedVeryFast->isChecked()) ispeed = 2;
716 out << ispeed;
717
718 out << m_d->popup_tourPartsVertex->isChecked();
719 out << m_d->popup_tourPartsInDet->isChecked();
720 out << m_d->popup_tourPartsCalo->isChecked();
721 out << m_d->popup_tourPartsMuon->isChecked();
722
723 qint32 iloop(1);
724 if (m_d->popup_tourLoopTwice->isChecked()) iloop = 2;
725 else if (m_d->popup_tourLoopThrice->isChecked()) iloop = 3;
726 else if (m_d->popup_tourLoopForever->isChecked()) iloop = 999;
727 out << iloop;
728
730 // Added for version 2 //
732 out << m_d->resetCamera_isPerspective;
733 out << m_d->resetCamera_state;
734
736 // Added for version 3 //
738
739 QList<QByteArray> persistifiedViews;
740 for(const Imp::StoredView & sv : m_d->storedViews){
741 persistifiedViews << sv.persistifiedState();
742 }
743 out << persistifiedViews;
744
746 // Added for version 4 //
748
749 out << m_d->ambientLightPercentage;
750
752 // Added for version 5 //
754
755 out << (m_d->customtoureditor ? m_d->customtoureditor->state() : QByteArray());
756
757 // ===> Finish up:
758 buffer.close();
759 return byteArray;
760
761}
762
763
764//____________________________________________________________________
765void VP1ExaminerViewer::restoreFromState(QByteArray ba_state)
766{
767 VP1Msg::messageVerbose("VP1ExaminerViewer::restoreFromState");
768
769 // ===> Setup stream for getting the contents of the byteArray:
770 QBuffer buffer(&ba_state);
771 buffer.open(QIODevice::ReadOnly);
772 QDataStream state(&buffer);
773 // ===> Check version and pass on state info to base class:
774 qint32 version;
775 state >> version;
776 if (version<0||version>6) {
777 VP1Msg::messageDebug("VP1ExaminerViewer Warning: Input state data is in wrong format - ignoring!");
778 return;
779 }
780 // ===> Decode the state info:
781
782 //Background color:
783 QColor bgdcol;
784 state >> bgdcol;
785 if (bgdcol.isValid())
786 setBackgroundColor(VP1QtInventorUtils::qcol2sbcol(bgdcol));
787 VP1Msg::messageVerbose("restoreState background color = "+str(bgdcol));
788
789 //Render buffer:
790 int ibuffer;
791 state >> ibuffer;
792 if (ibuffer==1) setBufferingType(BUFFER_SINGLE);
793 else if (ibuffer==2) setBufferingType(BUFFER_INTERACTIVE);
794 else setBufferingType(BUFFER_DOUBLE);
795 VP1Msg::messageVerbose("restoreState Render Buffer = ("+str(ibuffer)+")");
796
797 //camtype and camera parameters:
798 bool isperspective;
799 state >> isperspective;
800 if (isperspective != currentCamIsPerspective())
802 QByteArray ba_cam;
803 state>>ba_cam;
804 if (getCamera()&&ba_cam!=QByteArray())
805 VP1QtInventorUtils::deserializeSoCameraParameters(ba_cam,*(getCamera()));//Fixme: Check return value?
806 VP1Msg::messageVerbose("restoreState camera type = "+str(isperspective?"Perspective":"Orthographic"));
807
808 //misc:
809 bool isdeco, isheadlight, isviewing, decoremoved;
810 state >> isdeco; if (isdeco!=isDecoration()) setDecoration(isdeco);
811 state >> isheadlight; if (isheadlight!=isHeadlight()) setHeadlight(isheadlight);
812 state >> isviewing; if (isviewing!=isViewing()) setViewing(isviewing);
813 state >> decoremoved; if (decoremoved) removeDecorationMenuOption();
814 VP1Msg::messageVerbose("saveState (deco,headlight,viewing,nodecomenu) = ("
815 +str(isdeco)+", "+str(isheadlight)+", "+str(isviewing)+", "+str(decoremoved)+")");
816
817 //Antialiasing state:
818 if (version<=5) {
819 SbBool smoothing; int numPasses;
820 state >> smoothing;
821 state >> numPasses;
822 m_d->isantialias=smoothing;
823 }
824 if (version>=6) {
825 state >> m_d->isantialias;
826 }
827 setAntiAlias(m_d->isantialias);
828 VP1Msg::messageVerbose("restoreState (isantialias)) = ("+str(m_d->isantialias)+")");
829 // getAntialiasing(current_smoothing, current_numPasses);
830 // state >> smoothing;
831 // state >> numPasses;
832 // if (numPasses<9999&&(current_smoothing!=smoothing||current_numPasses!=numPasses))
833 // setAntialiasing(smoothing,numPasses);
834 // VP1Msg::messageVerbose("restoreState (smoothing,numPasses)) = ("+str(smoothing)+", "+str(numPasses)+")");
835
836 //Draw style:
837 int idrawstyle_still, idrawstyle_interactive;
838 state >> idrawstyle_still;
839 state >> idrawstyle_interactive;
840 setDrawStyle(STILL,Imp::intToDrawStyle(idrawstyle_still));
841 setDrawStyle(INTERACTIVE,Imp::intToDrawStyle(idrawstyle_interactive));
842 VP1Msg::messageVerbose("restoreState DrawStyle (still,interactive)) = ("+str(idrawstyle_still)+", "+str(idrawstyle_interactive)+")");
843
844 //Transparency type:
845 int itransp;
846 state >> itransp;
848 VP1Msg::messageVerbose("restoreState Transparency Type = ("+str(itransp)+")");
849
850 if (version>=1) {
851
852 m_d->ensureMenuInit();
853 bool b;
854 state >> b; m_d->popup_tourReturnToStartAction->setChecked(b);
855 state >> b; m_d->popup_tourStartEachEvent->setChecked(b);
856
857 qint32 ispeed;
858 state >> ispeed;
859 if (ispeed==-2) m_d->popup_tourSpeedVerySlow->setChecked(true);
860 else if (ispeed==-1) m_d->popup_tourSpeedSlow->setChecked(true);
861 else if (ispeed==1) m_d->popup_tourSpeedFast->setChecked(true);
862 else if (ispeed==2) m_d->popup_tourSpeedVeryFast->setChecked(true);
863
864 state >> b; m_d->popup_tourPartsVertex->setChecked(b);
865 state >> b; m_d->popup_tourPartsInDet->setChecked(b);
866 state >> b; m_d->popup_tourPartsCalo->setChecked(b);
867 state >> b; m_d->popup_tourPartsMuon->setChecked(b);
868
869 qint32 iloop;
870 state >> iloop;
871 if (iloop==2) m_d->popup_tourLoopTwice->setChecked(true);
872 else if (iloop==3) m_d->popup_tourLoopThrice->setChecked(true);
873 else if (iloop==999) m_d->popup_tourLoopForever->setChecked(true);
874
875 }
876
877 if (version>=2) {
878 state >> m_d->resetCamera_isPerspective;
879 state >> m_d->resetCamera_state;
880 if (m_d->popup_resetCameraAction) {
881 bool v(m_d->resetCamera_state!=QByteArray());
882 if (m_d->popup_resetCameraAction->isVisible()!=v)
883 m_d->popup_resetCameraAction->setVisible(v);
884 }
885 }
886 if (version>=3) {
887 m_d->storedViews.clear();
888 QList<QByteArray> persistifiedViews;
889 state >> persistifiedViews;
890 for(const QByteArray& ba_pv : persistifiedViews) {
891 Imp::StoredView sv(ba_pv);
892 if (sv.isValid())
893 m_d->storedViews << sv;
894 }
895 m_d->storedViewsChanged();
896 }
897
898 if (version>=4)
899 state >> m_d->ambientLightPercentage;
900
901 if (version>=5) {
902 QByteArray ba;
903 state >> ba;
904 if (ba!=QByteArray()) {
905 if (!m_d->customtoureditor)
906 m_d->customtoureditorState = std::move(ba);
907 else
908 m_d->customtoureditor->setState(ba);
909 }
910 }
911
912 m_d->updateEnvironmentNode();
913 m_d->updateAmbientLightText();
914
915 // ===> Finish up:
916 buffer.close();
917}
918
919
920//____________________________________________________________________
922{
923#if SOQT_MAJOR_VERSION <= 1 && SOQT_MINOR_VERSION <= 4 && SOQT_MICRO_VERSION <= 1
924 //Fix bug in SoQt, in which the menu does not get deleted (reported and fixed upstream after SoQt 1.4.1)
925 delete prefmenu;
926#endif
927 delete m_d;
928 SoQtExaminerViewer::setSceneGraph(0);
929}
930
931//____________________________________________________________________
932void VP1ExaminerViewer::createViewerButtons(QWidget * parent, SbPList * buttonlist)
933{
934 VP1Msg::messageVerbose("VP1ExaminerViewer::createViewerButtons");
935
936 SoQtExaminerViewer::createViewerButtons(parent,buttonlist);
937 //buttonlist holds void pointers to pushbuttons
938
939 if (buttonlist->getLength()==7) {
940 //Get pointers:
941 m_d->button_interact = static_cast<QPushButton*>(buttonlist->get(0));
942 m_d->button_examine = static_cast<QPushButton*>(buttonlist->get(1));
943 m_d->button_home = static_cast<QPushButton*>(buttonlist->get(2));
944 m_d->button_sethome = static_cast<QPushButton*>(buttonlist->get(3));
945 m_d->button_viewall = static_cast<QPushButton*>(buttonlist->get(4));
946 m_d->button_seek = static_cast<QPushButton*>(buttonlist->get(5));
947 m_d->button_togglecamera = static_cast<QPushButton*>(buttonlist->get(6));
948 //Other stuff? Connections? Change pixmaps?
949 m_d->button_interact->setToolTip("Pick mode (ESC/M toggles). Use this in order to select objects.");
950 m_d->button_examine->setToolTip("Navigation mode (ESC/M toggles). Use to ROTATE (left click), ZOOM (wheel or SHIFT+CTRL+left click) or PAN (middle click or SHIFT+left click or CTRL+left click).");
951 m_d->button_home->setToolTip("Change view to home view");
952 m_d->button_sethome->setToolTip("Store current view as new home");
953 m_d->button_viewall->setToolTip("View all objects currently displayed (V)");
954 m_d->button_seek->setToolTip("Seek to point (S). Sets cameras rotation centre to the clicked point and zooms towards it.");
955 m_d->button_togglecamera->setToolTip("Toggle (C) camera between perspective (P) and orthographic (O) mode.");
956 //These are just confusing anyway:
957 m_d->button_home->setVisible(false);
958 m_d->button_sethome->setVisible(false);
959 } else {
960 VP1Msg::message("VP1ExaminerViewer::createViewerButtons ERROR: Did not get list of exactly 7 buttons from base.");
961 }
962}
963
964//____________________________________________________________________
965QPushButton * VP1ExaminerViewer::Imp::addNewButton(QString text,QString tooltip,REGION region ,VIEW view,QWidget * tempparent, QString iconname)
966{
967 VP1Msg::messageVerbose("VP1ExaminerViewer::Imp::addNewButton()");
968
969 QPushButton * button = new QPushButton(tempparent);
970 if (iconname.isEmpty()) {
971 button->setText(text);
972 } else {
973 button->setIcon( QIcon(iconname) );
974 }
975 button->setToolTip(tooltip);
976 detectorbuttons[button] = std::make_pair(region,view);
977 button->setFocusPolicy(Qt::NoFocus);
978 // button->setIconSize(QSize(24, 24));
979 // button->setFixedSize(30, );
980 QObject::connect(button,SIGNAL(clicked()),signalcatcher,SLOT(catchSignal()));
981 theclass->addAppPushButton(button);
982 return button;
983}
984
985//____________________________________________________________________
987{
988 VP1Msg::messageVerbose("VP1ExaminerViewer::Imp::updateAnimationSequence()");
989 animationSequencer.sequence().clearAllFrames();
991
992 //Speed:
993 double steptime=3;//seconds (fixme. Also, fix number of loops... Also, calculate total time and display in speed menu...
994 if (popup_tourSpeedVerySlow->isChecked())
995 steptime *= 3;
996 else if (popup_tourSpeedSlow->isChecked())
997 steptime *= 1.5;
998 else if (popup_tourSpeedFast->isChecked())
999 steptime /= 1.5;
1000 else if (popup_tourSpeedVeryFast->isChecked())
1001 steptime /= 3;
1002
1003 //cycles:
1005 int nloops(1);//define number of loops
1006 if (popup_tourLoopTwice->isChecked())
1007 nloops = 2;
1008 else if (popup_tourLoopThrice->isChecked())
1009 nloops = 3;
1010
1011 int nregions(0);
1013 double firstfact(action_movieenabled->isChecked()?0.0:0.25);
1015 bool first(true);
1016 for (int iloop = 0; iloop < nloops; ++iloop) {
1017 if (popup_tourPartsMuon->isChecked()) {
1019 if (first||latestRegion!=region)
1020 animationSequencer.sequence().addFrame(region, SbVec3f(sin(6*M_PI/6), 0,cos(6*M_PI/6)), (first?firstfact:1.0)*steptime);
1021 animationSequencer.sequence().addFrame(region, SbVec3f(sin(10*M_PI/6), 0,cos(10*M_PI/6)), steptime);
1022 animationSequencer.sequence().addFrame(region, SbVec3f(sin(2*M_PI/6), 0,cos(2*M_PI/6)), steptime);
1023 animationSequencer.sequence().addFrame(region, SbVec3f(sin(6*M_PI/6), 0,cos(6*M_PI/6)), steptime);
1024 latestRegion=region;
1025 if (first)
1026 firstRegion = region;
1027 first=false;
1028 if (iloop==0)
1029 ++nregions;
1030 }
1031 if (popup_tourPartsCalo->isChecked()) {
1033 if (first||latestRegion!=region)
1034 animationSequencer.sequence().addFrame(region, SbVec3f(sin(6*M_PI/6), 0,cos(6*M_PI/6)), (first?firstfact:1.0)*steptime);
1035 animationSequencer.sequence().addFrame(region, SbVec3f(sin(10*M_PI/6), 0,cos(10*M_PI/6)), steptime);
1036 animationSequencer.sequence().addFrame(region, SbVec3f(sin(2*M_PI/6), 0,cos(2*M_PI/6)), steptime);
1037 animationSequencer.sequence().addFrame(region, SbVec3f(sin(6*M_PI/6), 0,cos(6*M_PI/6)), steptime);
1038 latestRegion=region;
1039 if (first)
1040 firstRegion = region;
1041 first=false;
1042 if (iloop==0)
1043 ++nregions;
1044 }
1045 if (popup_tourPartsInDet->isChecked()) {
1047 if (first||latestRegion!=region)
1048 animationSequencer.sequence().addFrame(region, SbVec3f(sin(6*M_PI/6), 0,cos(6*M_PI/6)), (first?firstfact:1.0)*steptime);
1049 animationSequencer.sequence().addFrame(region, SbVec3f(sin(10*M_PI/6), 0,cos(10*M_PI/6)), steptime);
1050 animationSequencer.sequence().addFrame(region, SbVec3f(sin(2*M_PI/6), 0,cos(2*M_PI/6)), steptime);
1051 animationSequencer.sequence().addFrame(region, SbVec3f(sin(6*M_PI/6), 0,cos(6*M_PI/6)), steptime);
1052 latestRegion=region;
1053 if (first)
1054 firstRegion = region;
1055 first=false;
1056 if (iloop==0)
1057 ++nregions;
1058 }
1059 if (popup_tourPartsVertex->isChecked()) {
1061 if (first||latestRegion!=region)
1062 animationSequencer.sequence().addFrame(region, SbVec3f(sin(6*M_PI/6), 0,cos(6*M_PI/6)), (first?firstfact:1.0)*steptime);
1063 animationSequencer.sequence().addFrame(region, SbVec3f(sin(10*M_PI/6), 0,cos(10*M_PI/6)), steptime);
1064 animationSequencer.sequence().addFrame(region, SbVec3f(sin(2*M_PI/6), 0,cos(2*M_PI/6)), steptime);
1065 animationSequencer.sequence().addFrame(region, SbVec3f(sin(6*M_PI/6), 0,cos(6*M_PI/6)), steptime);
1066 latestRegion=region;
1067 if (first)
1068 firstRegion = region;
1069 first=false;
1070 if (iloop==0)
1071 ++nregions;
1072 }
1073 if (first)//Apparently nothing was enabled
1074 return false;
1075 }
1076 if (tourLoopsForever && nregions==1)
1078
1079 if (!tourLoopsForever&&latestRegion!=firstRegion)
1080 animationSequencer.sequence().addFrame(firstRegion, SbVec3f(sin(6*M_PI/6), 0,cos(6*M_PI/6)), steptime);
1081 if (firstfact>0.0&&!tourLoopsForever)
1082 animationSequencer.sequence().addFrame(theclass->currentCameraState(),firstfact*steptime);
1083
1084 return true;
1085}
1086
1087
1088//____________________________________________________________________
1090{
1091 VP1Msg::messageVerbose("VP1ExaminerViewer::Imp::init");
1092 QWidget * tempparent = new QWidget();//Use this as temporary parent to
1093 //avoid the buttons temporarily
1094 //showing up as individual top
1095 //widgets.
1096 tempparent->setVisible(false);
1097 if (detectorViewButtons) {
1098 // addNewButton("VA","View vertex region from positive Z axis",VERTEX,ASIDE,tempparent);
1099 // addNewButton("VC","View vertex region from negative Z axis",VERTEX,CSIDE,tempparent);
1100
1101 addNewButton("IA","View inner detector from positive Z axis",INDET,ASIDE,tempparent);
1102 addNewButton("IC","View inner detector from negative Z axis",INDET,CSIDE,tempparent);
1103
1104 addNewButton("CA","View calorimeters from positive Z axis",CALO,ASIDE,tempparent);
1105 addNewButton("CC","View calorimeters from negative Z axis",CALO,CSIDE,tempparent);
1106
1107 addNewButton("MA","View muon spectrometer from positive Z axis",MUON,ASIDE,tempparent);
1108 addNewButton("MC","View muon spectrometer from negative Z axis",MUON,CSIDE,tempparent);
1109
1110 addNewButton("FA","View forward region from positive Z axis",FORWARDREGION,ASIDE,tempparent);
1111 addNewButton("FC","View forward region from negative Z axis",FORWARDREGION,CSIDE,tempparent);
1112
1113 addNewButton("MB","View muon spectrometer from barrel",MUON,BARREL,tempparent, ":icons/icons/rphi.png");
1114
1115 // This one is special:
1116 //addNewButton("XT", "Execute a tour of the detector",INDET, true, tempparent);
1117 {
1118 QPushButton *button = new QPushButton(tempparent);
1119 button->setText("XT");
1120 button->setToolTip("Execute a tour of the detector (configure in context menu)");
1121 button->setFocusPolicy(Qt::NoFocus);
1122 takeTourButton=button;
1123 QObject::connect(button,SIGNAL(clicked()), signalcatcher, SLOT(catchSignal()));
1124 theclass->addAppPushButton(button);
1125 QObject::connect(&animationSequencer,SIGNAL(animationFinishedSuccessfully()),signalcatcher,SLOT(catchSignal()));
1126 }
1127 }
1128 QWidget * w_spacer = new QWidget(tempparent);
1129 QSizePolicy sp_spacer(w_spacer->sizePolicy());
1130 unsigned vertStretch = 99999;
1131 sp_spacer.setVerticalStretch(vertStretch);
1132 w_spacer->setSizePolicy(sp_spacer);
1133 theclass->addAppPushButton(w_spacer);
1134
1135 tempparent->deleteLater();
1136}
1137
1138//____________________________________________________________________
1140{
1141 if (!sender())
1142 return;
1143 if (sender()==&(m_d->animationSequencer)) {
1144 if (m_d->tourLoopsForever)
1145 m_d->animationSequencer.startAnimating(m_d->tourLoopsForeverSkipFirstFrame);
1146 return;
1147 }
1148 QPushButton* button = dynamic_cast<QPushButton*>(sender());
1149 if (button) {
1150 if (m_d->detectorbuttons.find(button)!=m_d->detectorbuttons.end())
1151 m_d->detectorZoomButtonClicked(m_d->detectorbuttons.find(button)->second);
1152 else if (button==m_d->takeTourButton)
1153 m_d->takeTourButtonClicked();
1154 return;
1155 }
1156 QMenu* menu = dynamic_cast<QMenu*>(sender());
1157 if (menu) {
1158 m_d->aboutToShowMenu(menu);
1159 return;
1160 }
1161 VP1Msg::messageDebug("VP1ExaminerViewer_SignalCatcher::catchSignal ERROR: Received unknown signal");
1162}
1163
1164//____________________________________________________________________
1166{
1167 VP1Msg::messageVerbose("VP1ExaminerViewer::startTour()");
1168 if (m_d->detectorViewButtons)
1169 m_d->takeTourButtonClicked();
1170}
1171
1172//____________________________________________________________________
1174{
1175 VP1Msg::messageVerbose("VP1ExaminerViewer::startTourEachEvent()");
1176 return m_d->popup_tourStartEachEvent ? m_d->popup_tourStartEachEvent->isChecked() : false;
1177}
1178
1179//____________________________________________________________________
1180SoSphere * VP1ExaminerViewer::Imp::getRegionSphere(REGION region,bool perspective)
1181{
1182 if (!sphere) {
1183 sphere = new SoSphere;
1184 sphere->ref();
1185 }
1186 double r(30);
1187 switch (region) {
1188 case VERTEX:
1189 VP1Msg::messageVerbose("set sphere dimensions for vertex");
1190 //r = perspective ? 0.5 : 0.5;
1191 r=0.5;
1192 break;
1193 case INDET:
1194 VP1Msg::messageVerbose("set sphere dimensions for indet");
1195 r = perspective ? 13 : 7;
1196 break;
1197 case CALO:
1198 VP1Msg::messageVerbose("set sphere dimensions for calo");
1199 r = perspective ? 35 : 27;
1200 break;
1201 case FORWARDREGION:
1202 VP1Msg::messageVerbose("set sphere dimensions for forward region");
1203 //r = perspective ? 600 : 600;
1204 r=600;
1205 break;
1206 case MUON:
1207 default:
1208 VP1Msg::messageVerbose("set sphere dimensions for muon");
1209 r = perspective ? 95 : 73;
1210 break;
1211 }
1212 sphere->radius = r * 1000.0;
1213 return sphere;
1214}
1215
1216//____________________________________________________________________
1218{
1219 VP1Msg::messageVerbose("VP1ExaminerViewer::Imp::grabFocus()");
1220 QWidget * w = theclass->getGLWidget();
1221 if (w)
1222 w->setFocus(Qt::OtherFocusReason);
1223}
1224
1225//____________________________________________________________________
1227{
1228 VP1Msg::messageVerbose("VP1ExaminerViewer::Imp::applyMovieSettingsToAnimationSequencer()");
1229
1230 //Movie pars:
1231 if (action_movieenabled->isChecked()) {
1232 int width = action_moviewidth->data().toInt();
1233 int height = action_movieheight->data().toInt();
1234 int fps = action_moviefps->data().toInt();
1235 QString outdir = action_movieoutdir->data().toString();
1236 QDir().mkpath(outdir);
1237 animationSequencer.setMovie(true);
1238 animationSequencer.setMovieParameters(outdir,movieFrameFileNamePrefix,fps,width,height);
1239 } else {
1240 animationSequencer.setMovie(false);
1241 }
1242}
1243
1244//____________________________________________________________________
1246{
1247 VP1Msg::messageVerbose("startCustomTour begin.");
1248
1249 if (!m_d->customtoureditor||!m_d->customtoureditor->tourAvailable())
1250 return;
1251
1252 m_d->grabFocus();
1253 if (isAnimating())
1254 stopAnimating();
1255 bool jump(m_d->action_movieenabled->isChecked());
1256 if (currentCamIsPerspective()!=m_d->customtoureditor->tourIsPerspective()) {
1258 jump = true;
1259 }
1260 m_d->animationSequencer.sequence().clearAllFrames();
1261 m_d->customtoureditor->addTourToAnimationSequencer(m_d->animationSequencer,jump);
1262 m_d->applyMovieSettingsToAnimationSequencer();
1263 //Start animation:
1264 m_d->animationSequencer.startAnimating();
1265}
1266
1267//____________________________________________________________________
1269 VP1Msg::messageVerbose("takeTourButtonClicked begin.");
1270 grabFocus();
1271 if (theclass->isAnimating())
1272 theclass->stopAnimating();
1275 //animationSequencer
1276 animationSequencer.startAnimating();
1277 } else {
1278 VP1Msg::messageDebug("Aborting tour since no detector parts enabled.");
1279 }
1280 VP1Msg::messageVerbose("takeTourButtonClicked end.");
1281}
1282
1283//____________________________________________________________________
1285{
1286 grabFocus();
1287
1288 VP1Msg::messageVerbose("detectorZoomButtonClicked region = "+toString(p.first)+", from "+QString((std::to_string(p.second) +" Z axis").c_str()));
1289
1290 SoNode * rootnode = theclass->getSceneGraph();
1291 if (!rootnode) {
1292 VP1Msg::messageDebug("VP1ExaminerViewer::Imp::detectorZoomButtonClicked WARNING: No scenegraph set. Ignoring.");
1293 return;
1294 }
1295 if ( ! ( rootnode->getTypeId().isDerivedFrom(SoGroup::getClassTypeId())) ) {
1296 VP1Msg::messageDebug("VP1ExaminerViewer::Imp::detectorZoomButtonClicked WARNING: Root node does not derive from SoGroup. Ignoring.");
1297 return;
1298 }
1299 if (theclass->currentCamIsPerspective()) {
1300 //Fix for bad camera (fixme: this doesn't really work... Perhaps let all detector buttons reset camera?):
1301 theclass->toggleCameraType();
1302 theclass->toggleCameraType();
1303 }
1304 SoCamera * camera = theclass->getCamera();
1305 if (!camera) {
1306 VP1Msg::messageDebug("VP1ExaminerViewer::Imp::detectorZoomButtonClicked WARNING: Could not get camera. Ignoring.");
1307 return;
1308 }
1309 rootnode->ref();
1310 camera->ref();
1311
1312 SoGroup * root = static_cast<SoGroup*>(rootnode);
1313
1314 //Get region:
1315 SoSphere * regionsphere = getRegionSphere(p.first,
1316 theclass->currentCamIsPerspective());
1317 //Get direction:
1318 int zDir=0;
1319 int xDir=0;
1320 switch (p.second){
1321 case ASIDE:
1322 {
1323 zDir=-1;
1325 theclass->setLeftWheelString("Rotz");
1326 break;
1327 }
1328 case CSIDE:
1329 {
1330 zDir=1;
1332 theclass->setLeftWheelString("Rotz");
1333 break;
1334 }
1335 case BARREL:
1336 {
1337 xDir=1;
1339 theclass->setLeftWheelString("Rotx");
1340 }
1341 }
1342 SbVec3f lookat(xDir,0,zDir), upvec(0,1,0);
1343
1344 bool notifyenabled = root->enableNotify(false);
1345
1346 root->insertChild(regionsphere,0);
1347 VP1Msg::messageVerbose("detectorZoomButtonClicked Initiating zoom.");
1348 if (theclass->isAnimating())
1349 theclass->stopAnimating();
1350 camera->unrefNoDelete();//Must be done before we start the zoom (to avoid an abort)
1351 // if (resetCamera_state!=QByteArray())
1352 // VP1CameraHelper::animatedZoomToCameraState( camera,root,resetCamera_state,1.0, true );
1353 // else
1354 VP1CameraHelper::animatedZoomToSubTree(camera,root,regionsphere,1.0,100.0,100.0,0.1,lookat,upvec);
1355
1356 root->removeChild(regionsphere);
1357 if (notifyenabled) {
1358 root->enableNotify(true);
1359 root->touch();
1360 }
1361
1362 rootnode->unrefNoDelete();
1363
1364 VP1Msg::messageVerbose("detectorZoomButtonClicked end.");
1365}
1366
1367
1368
1369//____________________________________________________________________
1371{
1372 //We don't actually use this popupmenu.
1373
1374 // SoQtExaminerViewer::buildPopupMenu();
1375}
1376
1377//____________________________________________________________________
1379{
1380
1381 VP1Msg::messageVerbose("VP1ExaminerViewer::removeDecorationMenuOption()");
1382 if (m_d->decorationMenuRemoved || !prefmenu)
1383 return;
1384 m_d->decorationMenuRemoved = true;
1385 int id = prefmenu->getMenuItem("decoration");
1386 if (id!=-1)
1387 prefmenu->removeMenuItem(id);
1388
1389}
1390
1391//____________________________________________________________________
1392SbBool VP1ExaminerViewer::processSoEvent(const SoEvent * const evt )
1393{
1394// VP1Msg::messageDebug("VP1ExaminerViewer::processSoEvent()");
1395// std::cout << "event type: " << evt->getClassTypeId().getName() << " - " << evt->getTypeId().getName() << std::endl;
1396
1397 if (evt->getTypeId().isDerivedFrom(SoKeyboardEvent::getClassTypeId())) {
1398 //We want to add a few shortcuts:
1399 // "A": View all
1400 // "P": Perspective camera
1401 // "O": Orthogonal camera
1402 // "C": Toggle camera mode
1403 // "M": Toggle view/selection mode.
1404 // If "Q" then we do NOT pass it on to the base class (because that closes the top window!!)
1405
1406 m_d->grabFocus(); //probably redundant since we got the event, but can't hurt.
1407
1408 if (SO_KEY_PRESS_EVENT(evt,SoKeyboardEvent::V)) {
1409 viewAll();
1410 return true;//eat event
1411 }
1412 if (SO_KEY_PRESS_EVENT(evt,SoKeyboardEvent::Q))
1413 return false;//do not eat event, but do not pass through to base.
1414 if (SO_KEY_PRESS_EVENT(evt,SoKeyboardEvent::C)) {
1416 return true;//eat event
1417 }
1418 if (SO_KEY_PRESS_EVENT(evt,SoKeyboardEvent::P)) {
1421 return true;//eat event
1422 }
1423 if (SO_KEY_PRESS_EVENT(evt,SoKeyboardEvent::O)) {
1426 return true;//eat event
1427 }
1428 if (SO_KEY_PRESS_EVENT(evt,SoKeyboardEvent::M)) {
1429 setViewing(!isViewing());
1430 return true;//eat event
1431 }
1432 if (SO_KEY_PRESS_EVENT(evt,SoKeyboardEvent::A)) {
1434 m_d->grabFocus();//Needed since the GL calls triggered when setting antialiasing makes us loose focus (we obviusly just had it).
1435 return true;//eat event
1436 }
1437
1438 //NB: We could emit keypressed signal when keyboardevent and base
1439 // class does not eat event.
1440
1441 } else if (evt->getTypeId().isDerivedFrom(SoMouseButtonEvent::getClassTypeId())) {
1442 m_d->grabFocus();//Any click grabs focus:
1443 if (isViewing()) {//In viewing mode we open a popup menu on right clicks:
1444 const SoMouseButtonEvent * ev_mouse = static_cast<const SoMouseButtonEvent*>(evt);
1445 if ((ev_mouse->getButton() == SoMouseButtonEvent::BUTTON2/*right click*/)) {
1446 if (ev_mouse->getState() == SoButtonEvent::DOWN) {
1447 showPopupMenu();
1448 }
1449 return true;//eat all right-clicks in viewing mode.
1450 }
1451 }
1452 }
1453
1454 return SoQtExaminerViewer::processSoEvent(evt);//pass event through
1455}
1456
1457//____________________________________________________________________
1459{
1460 VP1Msg::messageVerbose("VP1ExaminerViewer::viewAll()");
1461 m_d->grabFocus();
1463 //Fix for bad camera:
1466 //Fixme: Instead make a reset camera followed by a 0 second "zoom" to correct orientation?
1467 }
1468 SoQtExaminerViewer::viewAll();
1469
1470}
1471
1472//____________________________________________________________________
1474{
1475 VP1Msg::messageVerbose("VP1ExaminerViewer::toggleCameraType()");
1476 m_d->grabFocus();
1477 SoQtExaminerViewer::toggleCameraType();
1478}
1479
1480//____________________________________________________________________
1482{
1483 VP1Msg::messageVerbose("VP1ExaminerViewer::setCameraType()");
1484 m_d->grabFocus();
1485 if (rightWheelLabel)
1486 rightWheelLabel->setUpdatesEnabled(false);
1487 SoQtExaminerViewer::setCameraType(type);
1488 setRightWheelString("Zoom");
1489 if (rightWheelLabel) {
1490 rightWheelLabel->setVisible(true);
1491 rightWheelLabel->setUpdatesEnabled(true);
1492 }
1493
1494 // get default stereo values and set them as starting point for the stereo editor
1495 if (getCamera()) {
1496 stereo_offset_camera = getCamera()->getStereoAdjustment();
1497 stereo_parallax_camera = getCamera()->getBalanceAdjustment();
1498 stereo_offset_viewer = getStereoOffset();
1499 }
1500}
1501
1502//____________________________________________________________________
1504{
1505 VP1Msg::messageVerbose("VP1ExaminerViewer::setSeekMode()");
1506 m_d->grabFocus();
1507 SoQtExaminerViewer::setSeekMode(enable);
1508}
1509
1510//____________________________________________________________________
1512{
1513 VP1Msg::messageVerbose("VP1ExaminerViewer::setViewing()");
1514 m_d->grabFocus();
1515 SoQtExaminerViewer::setViewing(enable);
1516}
1517
1518//____________________________________________________________________
1520{
1521 VP1Msg::messageVerbose("VP1ExaminerViewer::bottomWheelFinish()");
1522 m_d->grabFocus();
1523 SoQtExaminerViewer::bottomWheelFinish();
1524}
1525
1526//____________________________________________________________________
1528{
1529 VP1Msg::messageVerbose("VP1ExaminerViewer::bottomWheelMotion()");
1530 m_d->grabFocus();
1531 SoQtExaminerViewer::bottomWheelMotion(val);
1532}
1533
1534//____________________________________________________________________
1536{
1537 VP1Msg::messageVerbose("VP1ExaminerViewer::bottomWheelStart()");
1538 m_d->grabFocus();
1539 SoQtExaminerViewer::bottomWheelStart();
1540}
1541
1542//____________________________________________________________________
1544{
1545 m_d->grabFocus();
1546 SoQtExaminerViewer::leftWheelFinish();
1547}
1548
1549//____________________________________________________________________
1551{
1552 m_d->grabFocus();
1553
1554 if (isAnimating())
1555 stopAnimating();
1556
1557 float newval = 0.0;
1558 if (m_d->rotationMode==Imp::XROT)
1559 newval = m_d->rotXWheelMotion(val, getLeftWheelValue());
1560 else
1561 newval = m_d->rotZWheelMotion(val, getLeftWheelValue());
1562
1563 SoQtFullViewer::leftWheelMotion(newval);//NB: We bypass SoQtExaminerViewer implementation
1564}
1565
1566//____________________________________________________________________
1568{
1569 m_d->grabFocus();
1570 SoQtExaminerViewer::leftWheelStart();
1571}
1572
1573//____________________________________________________________________
1575{
1576 m_d->grabFocus();
1577 SoQtExaminerViewer::rightWheelFinish();
1578}
1579
1580//____________________________________________________________________
1582{
1583 m_d->grabFocus();
1584 SoQtExaminerViewer::rightWheelMotion(val);
1585}
1586
1587//____________________________________________________________________
1589{
1590 m_d->grabFocus();
1591 SoQtExaminerViewer::rightWheelStart();
1592}
1593
1594//____________________________________________________________________
1595float VP1ExaminerViewer::Imp::rotZWheelMotion(float value, float oldvalue)
1596{
1597 SoCamera * cam = theclass->getCamera();
1598 if (!cam)
1599 return 0.0f; // can happen for empty scenegraph
1600
1601 cam->ref();
1602 rotateCamera(cam, SbVec3f(0, 0, -1), value - oldvalue);
1603 cam->unrefNoDelete();
1604 return value;
1605}
1606
1607//____________________________________________________________________
1608float VP1ExaminerViewer::Imp::rotXWheelMotion(float value, float oldvalue)
1609{
1610 SoCamera * cam = theclass->getCamera();
1611 if (!cam)
1612 return 0.0f; // can happen for empty scenegraph
1613
1614 cam->ref();
1615 rotateCamera(cam, SbVec3f(-1, 0, 0), value - oldvalue);
1616 cam->unrefNoDelete();
1617 return value;
1618}
1619
1620//____________________________________________________________________
1622 const SbVec3f & aroundaxis,
1623 const float delta)
1624{
1625 const SbVec3f DEFAULTDIRECTION(0, 0, -1);
1626 const SbRotation currentorientation = cam->orientation.getValue();
1627
1628 SbVec3f currentdir;
1629 currentorientation.multVec(DEFAULTDIRECTION, currentdir);
1630
1631 const SbVec3f focalpoint = cam->position.getValue() +
1632 cam->focalDistance.getValue() * currentdir;
1633
1634 // set new orientation
1635 cam->orientation = SbRotation(aroundaxis, delta) * currentorientation;
1636
1637 SbVec3f newdir;
1638 cam->orientation.getValue().multVec(DEFAULTDIRECTION, newdir);
1639 cam->position = focalpoint - cam->focalDistance.getValue() * newdir;
1640}
1641
1642//____________________________________________________________________
1643void VP1ExaminerViewer::setBufferingType(SoQtViewer::BufferType bt)
1644{
1645 SoQtExaminerViewer::setBufferingType(bt);
1646}
1647
1648//____________________________________________________________________
1649void VP1ExaminerViewer::setAntialiasing(SbBool smoothing, int numPasses)
1650{
1651 VP1Msg::messageDebug("VP1ExaminerViewer::setAntialiasing()");
1652
1653 SoQtExaminerViewer::setAntialiasing(smoothing, numPasses); // Needed for offscreen rendering (i.e. snapshots).
1654
1655
1656 // --- OLD AA method ---
1657 // QGLWidget* qglw = (QGLWidget*)getGLWidget();
1658 // QGLFormat fmt = qglw->format();
1659 // fmt.setSampleBuffers(smoothing);
1660 // fmt.setSamples(numPasses);
1661 // qglw->setFormat(fmt); // note: this is supposedly deprecated..
1662 // qglw->makeCurrent();
1663
1664 // if(smoothing && numPasses > 1)
1665 // glEnable(GL_MULTISAMPLE);
1666 // else
1667 // glDisable(GL_MULTISAMPLE);
1668
1669 bool printWarning = false;
1670 const char* env_aa;
1671 #ifndef BUILDVP1LIGHT
1672 env_aa = std::getenv("VP1_ADVANCED_ANTIALIASING");
1673 #else
1674 bool antialiasingIsOn = VP1QtUtils::expertSettingIsOn("general","ExpertSettings/VP1_ADVANCED_ANTIALIASING");
1675 if(antialiasingIsOn){
1676 env_aa = "1";
1677 } else {
1678 env_aa = "0";
1679 }
1680 #endif
1681 if (env_aa != NULL) {
1682 std::string env_aa_string( env_aa );
1683 if(env_aa_string == "1") {
1684
1685 // print a warning message, on the first time
1686 if ( ! std::getenv("VP1_ADVANCED_ANTIALIASING_PRINTMSG")) {
1687 VP1Msg::messageWarningRed("You switched ON advanced anti-aliasing. That's very good, but please notice that this method DOES NOT WORK on LXPLUS machines, currently, because of their old graphics drivers! If you are on LXPLUS, this will likely freeze VP1... If that's the case, please restart VP1 without the '-advanced-aa' flag.");
1688 }
1689 ::setenv("VP1_ADVANCED_ANTIALIASING_PRINTMSG", "1", 1/*override present value*/); // TODO: move to Qt settings
1690
1691 // --- NEW AA method (26Sep2017) --- it works, but not on LXPLUS!!
1692 if (smoothing) {
1693 VP1Msg::message("VP1ExaminerViewer: turning AA on.");
1694
1695 VP1Msg::message("Sep 2017: AA is now done using a new technique so please let hn-atlas-vp1-help@cern.ch know of any problems.");
1696 //FIXME - remove above messages at some point? EJWM.
1697
1698 if (getGLRenderAction()->isSmoothing() != smoothing)
1699 getGLRenderAction()->setSmoothing(smoothing); // --> quite ugly outcome!
1700
1701 int buffers = 4;
1702 #if SOQT_MAJOR_VERSION > 1 || (SOQT_MAJOR_VERSION == 1 && SOQT_MINOR_VERSION >= 5)
1703 if (getSampleBuffers() != buffers)
1704 setSampleBuffers(buffers);
1705 #else
1706 if (buffers > 1)
1707 VP1Msg::message("Multisampling is not supported by SoQT < 1.5, this anti-aliasing mode is disabled");
1708 #endif
1709 }
1710 else {
1711 VP1Msg::message("VP1ExaminerViewer: turning AA off.");
1712 getGLRenderAction()->setSmoothing(smoothing);
1713 setSampleBuffers(0);
1714 }
1715 }
1716 else {
1717 printWarning = true;
1718 }
1719 }
1720 else {
1721 printWarning = true;
1722 }
1723
1724 if (printWarning) {
1725 VP1Msg::messageWarningRed("Anti-aliasing is using low-quality mode only, because of problems with the graphic drivers installed on LXPLUS machines. If you are not running VP1 on LXPLUS machine (for example, if you are running it on a custom SLC6 machine), you can start VP1 again using the command-line flag '-advanced-aa'.");
1726 }
1727
1728 m_d->isantialias=smoothing;
1729}
1730
1731//____________________________________________________________________
1732void VP1ExaminerViewer::setTransparencyType(SoGLRenderAction::TransparencyType t)
1733{
1734 SoQtExaminerViewer::setTransparencyType(t);
1735}
1736
1737//____________________________________________________________________
1738void VP1ExaminerViewer::setDrawStyle(SoQtViewer::DrawType t, SoQtViewer::DrawStyle s)
1739{
1740 SoQtExaminerViewer::setDrawStyle(t,s);
1741}
1742
1743//____________________________________________________________________
1745{
1746 return m_d->isantialias;
1747 // SbBool smoothing; int numPasses;
1748 // getAntialiasing(smoothing, numPasses);
1749 // return smoothing&&numPasses>1;
1750}
1751
1752//____________________________________________________________________
1754{
1755 m_d->isantialias=b;
1756 b ? setAntialiasing(true,4) : setAntialiasing(false,1);
1757 std::cout << "antiAliasing set." << std::endl;
1758}
1759
1760//____________________________________________________________________
1762{
1763 VP1Msg::messageVerbose("VP1ExaminerViewer::resetCamera()");
1764 if (m_d->resetCamera_state==QByteArray())
1765 return;
1766 if (isAnimating())
1767 stopAnimating();
1768 if (m_d->resetCamera_isPerspective != (currentCamIsPerspective()))
1770 if (getCamera()&&m_d->resetCamera_state!=QByteArray())
1771 VP1QtInventorUtils::deserializeSoCameraParameters(m_d->resetCamera_state,*(getCamera()));//Fixme: Check return value?
1772}
1773
1774
1775//____________________________________________________________________
1777{
1778 return getCameraType() == SoPerspectiveCamera::getClassTypeId();
1779}
1780
1781//____________________________________________________________________
1783{
1784 SoCamera * cam(getCamera());
1785 return cam ? VP1QtInventorUtils::serializeSoCameraParameters(*cam) : QByteArray();
1786}
1787
1788//____________________________________________________________________
1789QPixmap VP1ExaminerViewer::getSnapShotFromCamState(bool camStateIsPerspective, QByteArray camState,
1790 int width, int height, bool transp )
1791{
1792 SoCamera * cam = getCamera();
1793 if (!cam)
1794 return QPixmap();
1795 bool notifyenabled = cam->enableNotify(false);
1796
1797 bool currentPersp(currentCamIsPerspective());
1798 QByteArray currentState(currentCameraState());
1799 if (currentPersp!=camStateIsPerspective)
1802 QPixmap pm = VP1QtInventorUtils::renderToPixmap(this, width, height,transp);
1803 if (currentPersp!=camStateIsPerspective)
1805 VP1QtInventorUtils::deserializeSoCameraParameters(currentState,*(getCamera()));
1806
1807 if (notifyenabled) {
1808 cam->enableNotify(true);
1809 //We don't touch since we know that we didn't actually change anything: cam->touch();
1810 }
1811 return pm;
1812}
1813
1814//____________________________________________________________________
1816{
1817 if (m_d->resetCamera_state!=QByteArray())
1818 return;
1819 //Camera type and parameters:
1820 m_d->resetCamera_isPerspective = (currentCamIsPerspective());
1821 m_d->resetCamera_state = currentCameraState();
1822
1823 if (m_d->popup_resetCameraAction&&!m_d->popup_resetCameraAction->isVisible())
1824 m_d->popup_resetCameraAction->setVisible(true);
1825}
1826
1827//____________________________________________________________________
1829{
1830 VP1Msg::messageVerbose("VP1ExaminerViewer::Imp::updateMovieMenuVisuals()");
1831
1833 int width = action_moviewidth->data().toInt();
1834 int height = action_movieheight->data().toInt();
1835 int fps = action_moviefps->data().toInt();
1836 QString outdir = action_movieoutdir->data().toString();
1837 action_moviewidth->setText("Change output &width [current: "+QString::number(width)+"]");
1838 action_movieheight->setText("Change output &height [current: "+QString::number(height)+"]");
1839 action_moviefps->setText("Change output &FPS [current: "+QString::number(fps)+"]");
1840 action_movieoutdir->setText("Change output &dir [current: "+outdir+"]");
1841
1842 bool c(action_movieenabled->isChecked());
1843 action_moviewidth->setEnabled(c);
1844 action_movieheight->setEnabled(c);
1845 action_moviefps->setEnabled(c);
1846 action_movieoutdir->setEnabled(c);
1847
1848}
1849
1850//____________________________________________________________________
1852{
1853 if (popup_menu)
1854 return true;
1855 QWidget * w = theclass->getWidget();
1856 if (!w)
1857 return false;
1858 popup_menu = new QMenu (w);
1859
1860 popup_bgdColAction = popup_menu->addAction("&Background Colour");
1861 popup_antiAliasAction = popup_menu->addAction("&Anti aliasing [A]");
1862 popup_resetCameraAction = popup_menu->addAction("&Reset camera");
1863
1864 if (detectorViewButtons) {
1865 //Tour - base
1866 QMenu * tourmenu = popup_menu->addMenu("&Tour");
1867 popup_tourStartEachEvent = tourmenu->addAction("Start tour on new event");
1868 popup_tourStartEachEvent->setCheckable(true);
1869 popup_tourReturnToStartAction = tourmenu->addAction("Tour ends at &original view");
1870 popup_tourReturnToStartAction->setCheckable(true);
1871 popup_tourReturnToStartAction->setVisible(false);//Until functionality actually implemented
1872 QMenu * tourspeedmenu = tourmenu->addMenu("&Speed");
1873 QMenu * tourpartsmenu = tourmenu->addMenu("&Parts");
1874 QMenu * tourloopmenu = tourmenu->addMenu("&Looping");
1875 popup_tourExecute = tourmenu->addAction("E&xecute");
1876
1877 //Tour - speed:
1878 popup_tourSpeedVerySlow = tourspeedmenu->addAction("Very s&low");
1879 popup_tourSpeedSlow = tourspeedmenu->addAction("&Slow");
1880 popup_tourSpeedMedium = tourspeedmenu->addAction("&Medium");
1881 popup_tourSpeedFast = tourspeedmenu->addAction("&Fast");
1882 popup_tourSpeedVeryFast = tourspeedmenu->addAction("Very f&ast");
1883 popup_tourSpeedVerySlow->setCheckable(true);
1884 popup_tourSpeedSlow->setCheckable(true);
1885 popup_tourSpeedMedium->setCheckable(true);
1886 popup_tourSpeedFast->setCheckable(true);
1887 popup_tourSpeedVeryFast->setCheckable(true);
1888 QActionGroup * tour_speed_group = new QActionGroup(tourspeedmenu);
1889 tour_speed_group->addAction(popup_tourSpeedVerySlow);
1890 tour_speed_group->addAction(popup_tourSpeedSlow);
1891 tour_speed_group->addAction(popup_tourSpeedMedium);
1892 tour_speed_group->addAction(popup_tourSpeedFast);
1893 tour_speed_group->addAction(popup_tourSpeedVeryFast);
1894 popup_tourSpeedMedium->setChecked(true);
1895
1896 //Tour - parts:
1897 popup_tourPartsVertex = tourpartsmenu->addAction("&Vertex region");
1898 popup_tourPartsInDet = tourpartsmenu->addAction("&Inner Detector");
1899 popup_tourPartsCalo = tourpartsmenu->addAction("&Calorimeters");
1900 popup_tourPartsMuon = tourpartsmenu->addAction("&Muon systems");
1901 popup_tourPartsVertex->setCheckable(true);
1902 popup_tourPartsInDet->setCheckable(true);
1903 popup_tourPartsCalo->setCheckable(true);
1904 popup_tourPartsMuon->setCheckable(true);
1905 popup_tourPartsInDet->setChecked(true);
1906 popup_tourPartsMuon->setChecked(true);
1907
1908 //Tour - Looping:
1909 popup_tourLoopOnce = tourloopmenu->addAction("&Once");
1910 popup_tourLoopTwice = tourloopmenu->addAction("&Twice");
1911 popup_tourLoopThrice = tourloopmenu->addAction("T&hrice");
1912 popup_tourLoopForever = tourloopmenu->addAction("&Indefinitely");
1913 popup_tourLoopOnce->setCheckable(true);
1914 popup_tourLoopTwice->setCheckable(true);
1915 popup_tourLoopThrice->setCheckable(true);
1916 popup_tourLoopForever->setCheckable(true);
1917 QActionGroup * tour_loop_group = new QActionGroup(tourloopmenu);
1918 tour_loop_group->addAction(popup_tourLoopOnce);
1919 tour_loop_group->addAction(popup_tourLoopTwice);
1920 tour_loop_group->addAction(popup_tourLoopThrice);
1921 tour_loop_group->addAction(popup_tourLoopForever);
1922 popup_tourLoopOnce->setChecked(true);
1923
1924 }
1925
1926 QMenu * advancedmenu = popup_menu->addMenu("&More");
1927
1928 popup_hidedecorationsaction = advancedmenu->addAction("Hide &controls");
1929 popup_headLightAction = advancedmenu->addAction("&Headlight");
1930 popup_ambientLightAction = advancedmenu->addAction("dummy");
1931 popup_dumpSceneAction = advancedmenu->addAction("Dump &scene to file");
1932 popup_dumpSceneVRMLAction = advancedmenu->addAction("Dump &scene to VRML file");
1933 popup_toSVGAction = advancedmenu->addAction("Produce SV&G image");
1934 popup_toEPSAction = advancedmenu->addAction("Produce &EPS image");
1935
1936 if (detectorViewButtons) {
1937 //Custom views:
1938 QMenu * viewsmenu = advancedmenu->addMenu("Stored &views");
1939 viewmenu_zoomtoview = viewsmenu->addMenu("Animated &zoom to view");
1940 viewmenu_restoreview = viewsmenu->addMenu("&Restore view");
1941 viewmenu_storecurrentview = viewsmenu->addMenu("Store &current view");
1942 viewmenu_deleteview = viewsmenu->addMenu("&Delete view");
1943 QObject::connect(viewmenu_storecurrentview,SIGNAL(aboutToShow()),signalcatcher,SLOT(catchSignal()));
1944 QObject::connect(viewmenu_deleteview,SIGNAL(aboutToShow()),signalcatcher,SLOT(catchSignal()));
1945 QObject::connect(viewmenu_restoreview,SIGNAL(aboutToShow()),signalcatcher,SLOT(catchSignal()));
1946 QObject::connect(viewmenu_zoomtoview,SIGNAL(aboutToShow()),signalcatcher,SLOT(catchSignal()));
1948 }
1949
1950 if (detectorViewButtons) {
1951 //Custom tour:
1952 QMenu * customtourmenu = advancedmenu->addMenu("Custom &tour");
1953 customtour_launcheditor = customtourmenu->addAction("Launch &editor");
1954 customtour_execute = customtourmenu->addAction("E&xecute");
1955 customtour_execute->setEnabled(false);
1956
1957 //Movies:
1958 QMenu * moviesmenu = advancedmenu->addMenu("&Movie settings");
1959 action_movieenabled = moviesmenu->addAction("&Enable movie output when executing tours (one image file per frame)");
1960 action_movieenabled->setCheckable(true);
1961 action_movieenabled->setChecked(false);
1962 action_moviewidth = moviesmenu->addAction("dummy");
1963 action_moviewidth->setData(1024);
1964 action_movieheight = moviesmenu->addAction("dummy");
1965 action_movieheight->setData(768);
1966 action_moviefps = moviesmenu->addAction("dummy");
1967 action_moviefps->setData(24);
1968 action_movieoutdir = moviesmenu->addAction("dummy");
1969 QString username=VP1QtUtils::environmentVariableValue("USER");
1970 action_movieoutdir->setData(username.isEmpty() ? "/tmp/vp1frames" : "/tmp/"+username+"/vp1frames");
1971 action_moviefadetocurrentview = moviesmenu->addAction("Fade last frame to current view (1s)");
1973 }
1974
1975
1977 popup_headLightAction->setCheckable(true);
1978 popup_antiAliasAction->setCheckable(true);
1979 popup_hidedecorationsaction->setCheckable(true);
1980
1981
1982 //Draw styles sub menu:
1983 QMenu * drawstylemenu = advancedmenu->addMenu("&Draw styles");
1984
1985 QMenu * drawstyle_still_menu = drawstylemenu->addMenu("&Still draw style");
1986 QMenu * drawstyle_interactive_menu = drawstylemenu->addMenu("&Interactive draw style");
1987 QMenu * drawstyle_transptype_menu = drawstylemenu->addMenu("&Transparency Type");
1988
1989 //Drawstyles sub menus:
1990 QActionGroup * ds_still_group = new QActionGroup(drawstyle_still_menu);
1991 QActionGroup * ds_interactive_group = new QActionGroup(drawstyle_interactive_menu);
1992 for(SoQtViewer::DrawStyle ds : getAllViewerDrawStyles()) {
1993 int ids = viewerDrawStyleToInt(ds);
1994 QString pretty = viewerDrawStyle2PrettyString(ds);
1995 if (ds!=SoQtViewer::VIEW_SAME_AS_STILL) {
1996 //still menu:
1997 QAction * act = drawstyle_still_menu->addAction(pretty);
1998 act->setData(ids);
2000 ds_still_group->addAction(act);
2001 act->setCheckable(true);
2002 }
2003 if (ds!=SoQtViewer::VIEW_AS_IS) {
2004 //interactive menu:
2005 QAction * act = drawstyle_interactive_menu->addAction(pretty);
2006 act->setData(ids);
2008 ds_interactive_group->addAction(act);
2009 act->setCheckable(true);
2010 }
2011 }
2012
2013 //Transparency type sub menu:
2014 QActionGroup * transptype_group = new QActionGroup(drawstyle_transptype_menu);
2015 for(SoGLRenderAction::TransparencyType type : VP1QtInventorUtils::getAllTransparencyTypes()) {
2016 QAction * act = drawstyle_transptype_menu->addAction(VP1QtInventorUtils::transparencyType2PrettyString(type));
2019 transptype_group->addAction(act);
2020 act->setCheckable(true);
2021 }
2022
2023
2024 //Stereo view sub menu:
2025 QMenu * stereoviewmenu_main = advancedmenu->addMenu("&Stereographic view");
2026 stereo_launcheditor = stereoviewmenu_main->addAction("Launch &editor");
2027
2028 // focal length submenu
2029 popup_focal_value_action = advancedmenu->addAction("dummy"); // dummy text replaced here below
2030 SoCamera *camera = theclass->getCamera();
2031 float default_focal_camera = camera->focalDistance.getValue();
2032 popup_focal_value_action->setData(default_focal_camera);
2033 popup_focal_value_action->setText("Change camera FOCAL LENGTH [current: "+QString::number(default_focal_camera)+"]");
2034
2035 // N.B.!! --> all the actions and menus here below are not needed anymore,
2036 // because we implemented the new stereo editor
2037
2038// QMenu * stereoviewmenu = stereoviewmenu_main->addMenu("stereo menu - viewer");
2039// QMenu * stereoviewmenu_camera = stereoviewmenu_main->addMenu("stereo menu - camera");
2040
2041
2042// // STEREO settings - SoQtViewer version
2043//
2044// QMenu * stereo_set_offset_menu = stereoviewmenu->addMenu("Set stereo &Offset");
2045// popup_stereo_offset_value_action = stereoviewmenu->addAction("dummy"); // dummy text replaced here below
2046// QMenu * stereo_set_type_menu = stereoviewmenu->addMenu("Set &Stereo type");
2047// stereo_set_anaglyph_menu = stereoviewmenu->addMenu("Set &Anaglyph settings");
2048
2049
2050// // build the Stereo Offset submenu
2051// QActionGroup * stereo_set_offset_group = new QActionGroup(stereo_set_offset_menu);
2052//
2053// QList<float> offset_values;
2054// offset_values << 0 << 1000.00 << 5000.00 << 10000.00 << 20000.00;
2055//
2056// for(float value : offset_values) {
2057// QAction * act = stereo_set_offset_menu->addAction(QString::number(value));
2058// act->setData(QString::number(value));
2059// popup_stereo_offset_actions << act;
2060// stereo_set_offset_group->addAction(act);
2061// act->setCheckable(true);
2062// }
2063//
2064//
2065//
2066// // an action to change the let the user change the stereo offset by entering a double
2067// float default_offset = 0.1;
2068// popup_stereo_offset_value_action->setData(default_offset);
2069// popup_stereo_offset_value_action->setText("Change STEREO offset [current: "+QString::number(default_offset)+"]");
2070//
2071//
2072// // build the Stereo Type submenu
2073// QActionGroup * stereo_set_type_group = new QActionGroup(stereoviewmenu);
2074//
2075// QList<SoQtViewer::StereoType> stereo_type_values;
2076// stereo_type_values << SoQtViewer::STEREO_NONE << SoQtViewer::STEREO_ANAGLYPH;
2077//
2078// for(SoQtViewer::StereoType value : getAllStereoViewTypes() ) {
2079// QAction * act = stereo_set_type_menu->addAction(viewerStereoType2PrettyString(value));
2080// act->setData( viewerStereoTypeToInt(value) );
2081// popup_stereo_type_actions << act;
2082// stereo_set_type_group->addAction(act);
2083// act->setCheckable(true);
2084// }
2085//
2086//
2087// // build the Anaglyph settings submenu
2088// QActionGroup * stereo_set_anaglyph_group = new QActionGroup(stereoviewmenu);
2089//
2090// QList<SoQtViewer::StereoType> stereo_type_values;
2091// stereo_type_values << SoQtViewer::STEREO_NONE << SoQtViewer::STEREO_ANAGLYPH;
2092//
2093// QStringList options;
2094// options << "Standard Red-Cyan view" << "Left-eye only" << "Right-eye only";
2095//
2096// for(QString value : options ) {
2097// QAction * act = stereo_set_anaglyph_menu->addAction(value);
2098// act->setData( value );
2099// popup_stereo_anaglyph_actions << act;
2100// stereo_set_anaglyph_group->addAction(act);
2101// act->setCheckable(true);
2102// }
2103
2104
2105
2106
2107 // STEREO settings - Camera version
2108
2109// // offset submenu
2110// popup_stereo_offset_value_action_camera = stereoviewmenu_camera->addAction("dummy"); // dummy text replaced here below
2111// // an action to change the let the user change the stereo offset by entering a double
2112// float default_offset_camera = 0.1;
2113// popup_stereo_offset_value_action_camera->setData(default_offset_camera);
2114// popup_stereo_offset_value_action_camera->setText("Change STEREO offset [current: "+QString::number(default_offset_camera)+"]");
2115//
2116// // balance submenu
2117// popup_stereo_balance_value_action_camera = stereoviewmenu_camera->addAction("dummy"); // dummy text replaced here below
2118// // an action to change the let the user change the stereo offset by entering a double
2119// float default_balance_camera = 1.0;
2120// popup_stereo_balance_value_action_camera->setData(default_balance_camera);
2121// popup_stereo_balance_value_action_camera->setText("Change STEREO balance [current: "+QString::number(default_balance_camera)+"]");
2122//
2123
2124
2125
2126// // stereo camera view settings submenu
2127// stereo_set_stereo_camera_view_menu = stereoviewmenu_camera->addMenu("Set Stereo &Camera view settings");
2128// QActionGroup * stereo_set_stereo_camera_view_group = new QActionGroup(stereoviewmenu_camera);
2129//
2130// QStringList options_camera;
2131// options_camera << "Standard view" << "Left-eye view" << "Right-eye view";
2132//
2133// for(QString value : options_camera ) {
2134// QAction * act = stereo_set_stereo_camera_view_menu->addAction(value);
2135// act->setData( value );
2136// popup_stereo_anaglyph_actions_camera << act;
2137// stereo_set_stereo_camera_view_group->addAction(act);
2138// act->setCheckable(true);
2139// }
2140
2141
2142
2143 return true;
2144
2145}
2146
2147//____________________________________________________________________
2149{
2150 VP1Msg::messageVerbose("aboutToShowMenu()");
2151
2154 storeViewActions.clear();
2155 QString fs = firstAvailableStoredViewName();
2156 QAction * act = viewmenu_storecurrentview->addAction("Store as "+fs);
2157 act->setData(fs);
2158 storeViewActions << act;
2159 if (!storedViews.isEmpty()) {
2160 viewmenu_storecurrentview->addSeparator();
2161 for(const StoredView & sv : storedViews) {
2162 act = viewmenu_storecurrentview->addAction("Overwrite "+sv.name());
2163 act->setIcon(sv.icon());
2164 if (!fitsCurrentCamType(sv)) {
2165 act->setEnabled(false);
2166 } else {
2167 act->setData(sv.name());
2168 storeViewActions << act;
2169 }
2170 }
2171 }
2172 return;
2173
2174 }
2176 viewmenu_zoomtoview->clear();
2177 zoomToViewActions.clear();
2178 for(const StoredView & sv : storedViews) {
2179 QAction * act = viewmenu_zoomtoview->addAction(sv.name());
2180 act->setIcon(sv.icon());
2181 if (!fitsCurrentCamType(sv)) {
2182 act->setEnabled(false);
2183 } else {
2184 act->setData(sv.name());
2185 zoomToViewActions << act;
2186 }
2187 }
2188 return;
2189 }
2191 viewmenu_restoreview->clear();
2192 restoreViewActions.clear();
2193 for(const StoredView & sv : storedViews) {
2194 QAction * act = viewmenu_restoreview->addAction(sv.name());
2195 act->setIcon(sv.icon());
2196 act->setData(sv.name());
2197 restoreViewActions << act;
2198 }
2199 return;
2200 }
2202 viewmenu_deleteview->clear();
2203 deleteViewActions.clear();
2204 for(const StoredView & sv : storedViews) {
2205 QAction * act = viewmenu_deleteview->addAction(sv.name());
2206 act->setIcon(sv.icon());
2207 act->setData(sv.name());
2208 deleteViewActions << act;
2209 }
2210 return;
2211 }
2212 VP1Msg::messageDebug("VP1ExaminerViewer::Imp::aboutToShowMenu ERROR: Unknown menu");
2213}
2214
2215//____________________________________________________________________
2217{
2218 VP1Msg::messageVerbose("updatePopupMenuStates()");
2219
2221 return;
2222 popup_headLightAction->setChecked(theclass->isHeadlight());
2223 popup_antiAliasAction->setChecked(theclass->isAntiAlias());
2224 popup_hidedecorationsaction->setChecked(! theclass->isDecoration());
2225
2226 int idrawstyle_still = viewerDrawStyleToInt(theclass->getDrawStyle(SoQtViewer::STILL));
2227 for (QAction * act : popup_drawstyle_still_actions) {
2228 if (act->data().toInt() == idrawstyle_still) {
2229 act->setChecked(true);
2230 break;
2231 }
2232 }
2233
2234 int idrawstyle_interactive = viewerDrawStyleToInt(theclass->getDrawStyle(SoQtViewer::INTERACTIVE));
2235 for (QAction * act : popup_drawstyle_interactive_actions) {
2236 if (act->data().toInt() == idrawstyle_interactive) {
2237 act->setChecked(true);
2238 break;
2239 }
2240 }
2241
2242 int itransptype = VP1QtInventorUtils::transparencyTypeToInt(theclass->getTransparencyType());
2243 for (QAction * act : popup_transptype_actions) {
2244 if (act->data().toInt() == itransptype) {
2245 act->setChecked(true);
2246 break;
2247 }
2248 }
2249
2250 popup_resetCameraAction->setVisible(resetCamera_state!=QByteArray());
2251
2252}
2253
2254//____________________________________________________________________
2256{
2257 VP1Msg::messageVerbose("VP1ExaminerViewer::dumpSceneToFile()");
2258
2259 SoNode * rootnode = getSceneGraph();
2260 if (!rootnode)
2261 return;
2262
2263 QWidget * w = getWidget();
2264 if (!w)
2265 return;
2266
2267 if(filename.isEmpty()) {
2268 if (isAnimating())
2269 stopAnimating();
2270 filename = QFileDialog::getSaveFileName(w, "Select output file",
2271 (m_d->lastDumpFile.isEmpty()?VP1Settings::defaultFileSelectDirectory():m_d->lastDumpFile),
2272 "Inventor files (*.iv)",0,QFileDialog::DontResolveSymlinks);
2273 if(filename.isEmpty())
2274 return;
2275 if (!filename.endsWith(".iv"))
2276 filename += ".iv";
2277 m_d->lastDumpFile=filename;
2278 }
2279
2280 SoGroup * standardisedRoot(0);
2281 if ( rootnode->getTypeId().isDerivedFrom(SoGroup::getClassTypeId()))
2282 standardisedRoot = VP1HEPVisUtils::convertToStandardScene(static_cast<SoGroup*>(rootnode));
2283
2284 if (standardisedRoot&&VP1QtInventorUtils::writeGraphToFile(standardisedRoot, filename))
2285 VP1Msg::messageDebug("VP1ExaminerViewer: Dumped scene to file "+filename);
2286 else
2287 VP1Msg::messageDebug("VP1ExaminerViewer: Error: Problems dumping scene to file "+filename);
2288
2289}
2290
2292 VP1Msg::messageVerbose("VP1ExaminerViewer::dumpSceneToVRMLFile()");
2293
2294 SoNode * rootnode = getSceneGraph();
2295 if (!rootnode)
2296 return;
2297
2298 QWidget * w = getWidget();
2299 if (!w)
2300 return;
2301
2302 if(filename.isEmpty()) {
2303 if (isAnimating())
2304 stopAnimating();
2305 filename = QFileDialog::getSaveFileName(w, "Select output file",
2306 (m_d->lastDumpFile.isEmpty()?VP1Settings::defaultFileSelectDirectory():m_d->lastDumpFile),
2307 "VRML2.0/X3D files (*.wrl)",0,QFileDialog::DontResolveSymlinks);
2308 if(filename.isEmpty())
2309 return;
2310 if (!filename.endsWith(".wrl"))
2311 filename += ".wrl";
2312 m_d->lastDumpFile=filename;
2313 }
2314
2315 SoGroup * standardisedRoot(0);
2316 if ( rootnode->getTypeId().isDerivedFrom(SoGroup::getClassTypeId()))
2317 standardisedRoot = VP1HEPVisUtils::convertToStandardScene(static_cast<SoGroup*>(rootnode));
2318
2319 if (standardisedRoot&&VP1QtInventorUtils::writeGraphToVRMLFile(standardisedRoot, filename))
2320 VP1Msg::messageDebug("VP1ExaminerViewer: Dumped scene to VRML file "+filename);
2321 else
2322 VP1Msg::messageDebug("VP1ExaminerViewer: Error: Problems dumping scene to VRML file "+filename);
2323
2324}
2325
2326//____________________________________________________________________
2328{
2329 QWidget * w = getWidget();
2330 if (!w)
2331 return;
2332 if(filename.isEmpty()) {
2333 if (isAnimating())
2334 stopAnimating();
2335 filename = QFileDialog::getSaveFileName(w, "Select output file",
2336 (m_d->lastSVGFile.isEmpty()?VP1Settings::defaultFileSelectDirectory():m_d->lastSVGFile),
2337 "Scalable Vector Graphics files (*.svg)",0,QFileDialog::DontResolveSymlinks);
2338 if(filename.isEmpty())
2339 return;
2340 if (!filename.endsWith(".svg"))
2341 filename += ".svg";
2342 m_d->lastSVGFile=filename;
2343 }
2344
2345 VP1Msg::messageVerbose("Attempting to produce svg output: "+filename);
2346
2347 //The following code contributed by Laurent Duflot:
2348
2350
2351 // want to render from above the SceneGraph so we get what the camera sees
2352 SoNode *rootA = static_cast<SoNode*>(SoQtRenderArea::getSceneGraph());
2353 if (!rootA ) return;
2354 SoNode *cam = static_cast<SoNode*>(this->getCamera());
2355 if ( ! cam ) return;
2356 SoSearchAction search;
2357 search.setNode(cam);
2358 search.apply(rootA);
2359 assert(search.getPath());
2360 SoNode* hiddenRoot =
2361 static_cast<SoFullPath *>(search.getPath())->getNodeFromTail(1);
2362
2363 const SbViewportRegion& vpRegion = getViewportRegion();
2364 SoGL2PSAction* action = new SoGL2PSAction(vpRegion);
2365 action->setFileName(filename.toStdString().c_str());
2366 action->setFileFormat(SoGL2PSAction::SVG);
2367 action->enableFileWriting();
2368 action->apply(hiddenRoot);
2369 action->disableFileWriting();
2370 delete action;
2371
2372}
2373
2374//____________________________________________________________________
2376{
2377 QWidget * w = getWidget();
2378 if (!w)
2379 return;
2380 if(filename.isEmpty()) {
2381 if (isAnimating())
2382 stopAnimating();
2383 filename = QFileDialog::getSaveFileName(w, "Select output file",
2384 (m_d->lastEPSFile.isEmpty()?VP1Settings::defaultFileSelectDirectory():m_d->lastEPSFile),
2385 "Encapsulated Postscript files (*.eps)",0,QFileDialog::DontResolveSymlinks);
2386 if(filename.isEmpty())
2387 return;
2388 if (!filename.endsWith(".eps"))
2389 filename += ".eps";
2390 m_d->lastEPSFile=filename;
2391 }
2392
2393 VP1Msg::messageVerbose("Attempting to produce eps output: "+filename);
2394
2395 //The following code contributed by Laurent Duflot:
2396
2397 // first method : direct calls to gl2ps
2398 if (FILE *output = fopen (filename.toStdString().c_str(), "w"))
2399 {
2400 int buffsize = 0, state = GL2PS_OVERFLOW;
2401 while (state == GL2PS_OVERFLOW)
2402 {
2403 buffsize += 1024*1024;
2404 gl2psBeginPage ("VP1"/*fixme: should contain run/evt number*/, "VP1", NULL,
2407 | GL2PS_SILENT
2410 | 0,
2411 GL_RGBA, 0, NULL,0, 0, 0,
2412 buffsize, output, NULL);
2413 actualRedraw();
2414 state = gl2psEndPage();
2415 }
2416 fclose (output);
2417 }
2418}
2419
2420//____________________________________________________________________
2422{
2423 VP1Msg::messageVerbose("setAmbientLight()");
2424
2425 a = std::max(0,std::min(100,a));
2426 if (m_d->ambientLightPercentage==a)
2427 return;
2428 m_d->ambientLightPercentage = a;
2429 m_d->updateAmbientLightText();
2430 m_d->updateEnvironmentNode();
2431}
2432
2433//____________________________________________________________________
2435{
2436 return m_d->ambientLightPercentage;
2437}
2438
2439//____________________________________________________________________
2441{
2442 VP1Msg::messageVerbose("VP1ExaminerViewer: Showing popup menu.");
2443 if (!m_d->ensureMenuInit())
2444 return;
2445 m_d->updatePopupMenuStates();
2446
2447 //Execute
2448 QAction * selAct = m_d->popup_menu->exec(QCursor::pos());
2449
2450 //Act on selection:
2451 if (!selAct) {
2452 VP1Msg::messageVerbose(" => No selection.");
2453 return;
2454 }
2455 if ( selAct == m_d->popup_bgdColAction ) {
2456 VP1Msg::messageVerbose("VP1ExaminerViewer::showPopupMenu Change background colour.");
2457 if (isAnimating())
2458 stopAnimating();
2459 QColor oldcol = VP1QtInventorUtils::sbcol2qcol(getBackgroundColor());
2460 QColor col = QColorDialog::getColor(oldcol, getWidget());
2461 if (col!=oldcol)
2462 setBackgroundColor(VP1QtInventorUtils::qcol2sbcol(col));
2463 return;
2464 }
2465 if ( selAct == m_d->popup_ambientLightAction ) {
2466 VP1Msg::messageVerbose("VP1ExaminerViewer::showPopupMenu ambient light editor triggered");
2467 bool ok;
2468 // int newamb = QInputDialog::getInteger(getWidget(), "Change ambient light",
2469 int newamb = QInputDialog::getInt(getWidget(), "Change ambient light",
2470 "New ambient light percentage:",
2471 ambientLight(),0,100,1,&ok);
2472 if (ok)
2473 setAmbientLight(newamb);
2474 return;
2475 }
2476 if ( selAct == m_d->popup_headLightAction ) {
2477 VP1Msg::messageVerbose("VP1ExaminerViewer::showPopupMenu head light changed to "+VP1Msg::str(m_d->popup_headLightAction->isChecked()));
2478 setHeadlight(m_d->popup_headLightAction->isChecked());
2479 return;
2480 }
2481 if ( selAct == m_d->popup_hidedecorationsaction ) {
2482 VP1Msg::messageVerbose("VP1ExaminerViewer::showPopupMenu hide controls changed to "+VP1Msg::str(m_d->popup_hidedecorationsaction->isChecked()));
2483 setDecoration(! m_d->popup_hidedecorationsaction->isChecked());
2484 return;
2485 }
2486 if ( selAct == m_d->popup_antiAliasAction ) {
2487 VP1Msg::messageVerbose("VP1ExaminerViewer::showPopupMenu anti aliasing changed to "+VP1Msg::str(m_d->popup_antiAliasAction->isChecked()));
2488 setAntiAlias(m_d->popup_antiAliasAction->isChecked());
2489 m_d->grabFocus();//Needed since the GL calls triggered when setting antialiasing makes us loose focus (we obviusly just had it).
2490 VP1Msg::messageVerbose("Anti-aliasing, done.");
2491 return;
2492 }
2493 if ( selAct == m_d->popup_dumpSceneAction ) {
2494 VP1Msg::messageVerbose("VP1ExaminerViewer::showPopupMenu Dump scene to an *.iv (OpenInventor) file");
2496 return;
2497 }
2498 if ( selAct == m_d->popup_dumpSceneVRMLAction ) {
2499 VP1Msg::messageVerbose("VP1ExaminerViewer::showPopupMenu Dump scene to a *.wrl (VRML) file");
2501 return;
2502 }
2503
2504 if ( selAct == m_d->popup_toSVGAction ) {
2505 VP1Msg::messageVerbose("VP1ExaminerViewer::showPopupMenu Produce SVG image");
2507 return;
2508 }
2509
2510 if ( selAct == m_d->popup_toEPSAction ) {
2511 VP1Msg::messageVerbose("VP1ExaminerViewer::showPopupMenu Produce EPS image");
2513 return;
2514 }
2515
2516 if ( selAct == m_d->popup_resetCameraAction ) {
2517 VP1Msg::messageVerbose("VP1ExaminerViewer::showPopupMenu Reset camera");
2518 resetCamera();
2519 return;
2520 }
2521 if (m_d->popup_drawstyle_still_actions.contains(selAct)) {
2522 SoQtViewer::DrawStyle ds = Imp::intToViewerDrawStyle(selAct->data().toInt());
2523 if (VP1Msg::verbose())
2524 VP1Msg::messageVerbose("VP1ExaminerViewer::showPopupMenu still draw style selected: "
2526 if (ds!=getDrawStyle(STILL))
2527 setDrawStyle(STILL,ds);
2528 return;
2529 }
2530 if (m_d->popup_drawstyle_interactive_actions.contains(selAct)) {
2531 SoQtViewer::DrawStyle ds = Imp::intToViewerDrawStyle(selAct->data().toInt());
2532 if (VP1Msg::verbose())
2533 VP1Msg::messageVerbose("VP1ExaminerViewer::showPopupMenu interactive draw style selected: "
2535 if (ds!=getDrawStyle(INTERACTIVE))
2536 setDrawStyle(INTERACTIVE,ds);
2537 return;
2538 }
2539 if (m_d->popup_transptype_actions.contains(selAct)) {
2540 SoGLRenderAction::TransparencyType type = VP1QtInventorUtils::intToTransparencyType(selAct->data().toInt());
2541 if (VP1Msg::verbose())
2542 VP1Msg::messageVerbose("VP1ExaminerViewer::showPopupMenu transparency type selected: "
2545 return;
2546 }
2547
2548 if (m_d->storeViewActions.contains(selAct)) {
2549 QString name = selAct->data().toString();
2550 VP1Msg::messageVerbose("Storing current view as "+name);
2551
2552 bool camPerspective = currentCamIsPerspective();
2553 QByteArray camState = currentCameraState();
2554 QPixmap snapShot = VP1QtInventorUtils::renderToPixmap(this, 40, 40,false);
2555
2556 Imp::StoredView sv(camState, camPerspective, snapShot, name);
2557 //Remove old stored views with that name (if any)
2558 int i(0);
2559 bool replaced(false);
2560 for(const Imp::StoredView & oldsv : m_d->storedViews) {
2561 if (oldsv.name()==name) {
2562 m_d->storedViews.replace(i,sv);
2563 replaced = true;
2564 break;
2565 }
2566 ++i;
2567 }
2568 if (!replaced)
2569 m_d->storedViews << sv;
2570 m_d->storedViewsChanged();
2571 return;
2572 }
2573
2574 if (m_d->zoomToViewActions.contains(selAct)) {
2575 QString name = selAct->data().toString();
2576 SoGroup * root = dynamic_cast<SoGroup*>(getSceneGraph());
2577 SoCamera * camera = getCamera();
2578 if (root&&camera) {
2579 for(const Imp::StoredView & sv : m_d->storedViews) {
2580 if (sv.name()==name) {
2581 if (isAnimating())
2582 stopAnimating();
2583 VP1CameraHelper::animatedZoomToCameraState( camera,root,sv.camState(),1.5, 100.0, 100.0, true );
2584 break;
2585 }
2586 }
2587 } else {
2588 VP1Msg::messageDebug("VP1CameraHelper Error: Attempting to zoom"
2589 " to stored view, but can't get root and camera pointers");
2590 }
2591 return;
2592 }
2593
2594
2595
2596 if (m_d->restoreViewActions.contains(selAct)) {
2597 QString name = selAct->data().toString();
2598 SoGroup * root = dynamic_cast<SoGroup*>(getSceneGraph());
2599 SoCamera * camera = getCamera();
2600 if (root&&camera) {
2601 for(const Imp::StoredView & sv : m_d->storedViews) {
2602 if (sv.name()==name) {
2603 if (!m_d->fitsCurrentCamType(sv))
2605 if (isAnimating())
2606 stopAnimating();
2607 QByteArray ba = sv.camState();
2609 break;
2610 }
2611 }
2612 } else {
2613 VP1Msg::messageDebug("VP1CameraHelper Error: Attempting to zoom"
2614 " to stored view, but can't get root and camera pointers");
2615 }
2616 return;
2617
2618 }
2619
2620 if (m_d->deleteViewActions.contains(selAct)) {
2621 QString name = selAct->data().toString();
2622 int i(0);
2623 for(const Imp::StoredView & sv : m_d->storedViews) {
2624 if (sv.name()==name) {
2625 m_d->storedViews.removeAt(i);
2626 break;
2627 }
2628 ++i;
2629 }
2630 m_d->storedViewsChanged();
2631 return;
2632 }
2633
2634 if (selAct==m_d->customtour_launcheditor) {
2635 VP1Msg::messageVerbose("VP1ExaminerViewer::showPopupMenu Launch custom tour editor.");
2636 if (!m_d->customtoureditor) {
2637 m_d->customtoureditor = new VP1CustomTourEditor(this);
2638 QObject::connect(&(m_d->animationSequencer),SIGNAL(clipVolumePercentOfATLAS(double)),m_d->customtoureditor,SLOT(setClipVolumePercentOfATLAS(double)));
2639 VP1Controller::setCustomTourEditor(m_d->customtoureditor);
2640 m_d->customtoureditor->disableObjectWhenTourNotAvailable(m_d->customtour_execute);
2641 if (m_d->customtoureditorState!=QByteArray()) {
2642 m_d->customtoureditor->setState(m_d->customtoureditorState);
2643 m_d->customtoureditorState = QByteArray();
2644 }
2645 }
2646 m_d->customtoureditor->show();
2647 //Fixme: deal with minimised state!
2648 return;
2649 }
2650
2651 if (selAct==m_d->customtour_execute) {
2652 VP1Msg::messageVerbose("VP1ExaminerViewer::showPopupMenu Execute custom tour.");
2654 return;
2655 }
2656
2657 if (selAct==m_d->action_movieenabled) {
2658 VP1Msg::messageVerbose("VP1ExaminerViewer::showPopupMenu movie enabled changed.");
2659 m_d->updateMovieMenuVisuals();
2660 return;
2661 }
2662 if (selAct==m_d->action_moviewidth) {
2663 int old = m_d->action_moviewidth->data().toInt();
2664 bool ok;
2665 // int newwidth = QInputDialog::getInteger(getWidget(), "Change movie width",
2666 int newwidth = QInputDialog::getInt(getWidget(), "Change movie width",
2667 "New movie width:", old,1,4000,1,&ok);
2668 if (ok&&old!=newwidth) {
2669 VP1Msg::messageVerbose("VP1ExaminerViewer::showPopupMenu changed movie width to "+VP1Msg::str(newwidth));
2670 m_d->action_moviewidth->setData(newwidth);
2671 m_d->updateMovieMenuVisuals();
2672 }
2673 return;
2674 }
2675 if (selAct==m_d->action_movieheight) {
2676 int old = m_d->action_movieheight->data().toInt();
2677 bool ok;
2678 // int newheight = QInputDialog::getInteger(getWidget(), "Change movie height",
2679 int newheight = QInputDialog::getInt(getWidget(), "Change movie height",
2680 "New movie height:", old,1,4000,1,&ok);
2681 if (ok&&old!=newheight) {
2682 VP1Msg::messageVerbose("VP1ExaminerViewer::showPopupMenu changed movie height to "+VP1Msg::str(newheight));
2683 m_d->action_movieheight->setData(newheight);
2684 m_d->updateMovieMenuVisuals();
2685 }
2686 return;
2687 }
2688 if (selAct==m_d->action_moviefps) {
2689 int old = m_d->action_moviefps->data().toInt();
2690 bool ok;
2691 // int newfps = QInputDialog::getInteger(getWidget(), "Change movie FPS",
2692 int newfps = QInputDialog::getInt(getWidget(), "Change movie FPS",
2693 "New movie frames per second:", old,1,4000,1,&ok);
2694 if (ok&&old!=newfps) {
2695 VP1Msg::messageVerbose("VP1ExaminerViewer::showPopupMenu changed movie fps to "+VP1Msg::str(newfps));
2696 m_d->action_moviefps->setData(newfps);
2697 m_d->updateMovieMenuVisuals();
2698 }
2699 return;
2700 }
2701 if (selAct==m_d->action_movieoutdir) {
2702 QString old = m_d->action_movieoutdir->data().toString();
2703 QString newoutdir = QFileDialog::getExistingDirectory ( getWidget(), "Select movie frame output directory",old);
2704 if (!newoutdir.isEmpty()&&old!=newoutdir) {
2705 VP1Msg::messageVerbose("VP1ExaminerViewer::showPopupMenu changed movie outdir to "+VP1Msg::str(newoutdir));
2706 m_d->action_movieoutdir->setData(newoutdir);
2707 m_d->updateMovieMenuVisuals();
2708 }
2709 return;
2710 }
2711 if (selAct==m_d->action_moviefadetocurrentview) {
2713 return;
2714 }
2715
2716 if (selAct==m_d->popup_tourReturnToStartAction
2717 ||selAct==m_d->popup_tourStartEachEvent
2718 ||selAct==m_d->popup_tourSpeedVerySlow
2719 ||selAct==m_d->popup_tourSpeedSlow
2720 ||selAct==m_d->popup_tourSpeedMedium
2721 ||selAct==m_d->popup_tourSpeedFast
2722 ||selAct==m_d->popup_tourSpeedVeryFast
2723 ||selAct==m_d->popup_tourPartsVertex
2724 ||selAct==m_d->popup_tourPartsInDet
2725 ||selAct==m_d->popup_tourPartsCalo
2726 ||selAct==m_d->popup_tourPartsMuon
2727 ||selAct==m_d->popup_tourLoopOnce
2728 ||selAct==m_d->popup_tourLoopTwice
2729 ||selAct==m_d->popup_tourLoopThrice
2730 ||selAct==m_d->popup_tourLoopForever) {
2731 VP1Msg::messageVerbose("VP1ExaminerViewer::showPopupMenu tour setting changed.");
2732 return;
2733 }
2734 if (selAct==m_d->popup_tourExecute) {
2735 VP1Msg::messageVerbose("VP1ExaminerViewer::showPopupMenu Tour Execute selected => starting tour.");
2736 startTour();
2737 return;
2738 }
2739
2740
2741 // stereo view actions
2742
2743
2744 if (selAct==m_d->stereo_launcheditor) {
2745 VP1Msg::messageVerbose("VP1ExaminerViewer::showPopupMenu Launch custom STEREO editor.");
2746 if (!m_d->customstereoeditor) {
2747 m_d->customstereoeditor = new VP1CustomStereoEditor(this);
2748// m_d->customstereoeditor->disableObjectWhenTourNotAvailable(m_d->customtour_execute);
2749// if (m_d->customstereoeditorState!=QByteArray()) { //TODO: implement save stereo settings
2750// m_d->customstereoeditor->setState(m_d->customstereoeditorState);
2751// m_d->customstereoeditorState = QByteArray();
2752// }
2753 }
2754 m_d->customstereoeditor->show();
2755 //Fixme: deal with minimised state!
2756 return;
2757 }
2758
2759// N.B.!! --> those separate actions below are not needed anymore,
2760// because we introduced the stereo editor window
2761
2762// if (m_d->popup_stereo_offset_actions.contains(selAct)) {
2763//
2765// float old = m_d->stereo_offset_value; //->data().toFloat();
2766//
2767// // new value
2768// float offset = selAct->data().toFloat();
2769//
2770// int newoffset = offset;
2771// if (old != newoffset) {
2772// VP1Msg::messageVerbose("VP1ExaminerViewer::showPopupMenu stereo offset selected: "
2773// +VP1Msg::str(newoffset));
2774// m_d->stereo_offset_value = newoffset;
2775// }
2776//
2777// setStereoOffsetSlot(offset);
2778// return;
2779// }
2780//
2781// if (selAct==m_d->popup_stereo_offset_value_action) {
2782//
2783// float old = m_d->popup_stereo_offset_value_action->data().toFloat();
2784// bool ok;
2785// int newoffset = QInputDialog::getDouble(getWidget(), "Change stereo OFFSET - 0.1 is the standard offset between left and right eye",
2786// "New stereo offset: ", old,0.1,4000,1,&ok);
2787// if (ok && old != newoffset) {
2788// VP1Msg::messageVerbose("VP1ExaminerViewer::showPopupMenu changed stereo offset to "+VP1Msg::str(newoffset));
2789// m_d->popup_stereo_offset_value_action->setData(newoffset);
2790// setStereoOffsetSlot(newoffset);
2791// m_d->popup_stereo_offset_value_action->setText("Change STEREO offset [current: "+QString::number(newoffset)+"]");
2792// }
2793// return;
2794// }
2795//
2796 if (selAct==m_d->popup_focal_value_action) {
2797
2798 // float old = m_d->popup_focal_value_action->data().toFloat();
2799 bool ok;
2800 SoPerspectiveCamera * camera = dynamic_cast<SoPerspectiveCamera*>(getCamera());
2801 if (! (camera==NULL) ) {
2802 float current_value = camera->focalDistance.getValue();
2803 int newfocal = QInputDialog::getDouble(getWidget(),
2804 "Change focal length", // title
2805 "New focal length: ", // label
2806 current_value, // initial value
2807 0.1, // min value
2808 2147483647, // max value
2809 1, // decimals
2810 &ok);
2811 if (ok && current_value != newfocal) {
2812 VP1Msg::messageVerbose("VP1ExaminerViewer::showPopupMenu changed focal length to "+VP1Msg::str(newfocal));
2813 m_d->popup_focal_value_action->setData(newfocal);
2814 // SoCamera *camera = getCamera();
2815 camera->focalDistance.setValue(newfocal);
2816 // camera->heightAngle.setValue(newfocal);
2817 m_d->popup_focal_value_action->setText("Change FOCAL LENGTH value [current: "+QString::number(newfocal)+"]");
2818 }
2819 } else {
2820 VP1Msg::message("Warning! No 'camera'...");
2821 }
2822 return;
2823 }
2824//
2825//
2826// if (m_d->popup_stereo_type_actions.contains(selAct)) {
2827//
2828// SoQtViewer::StereoType type = m_d->intToViewerStereoType(selAct->data().toInt());
2829//
2830// if (VP1Msg::verbose())
2831// VP1Msg::messageVerbose("VP1ExaminerViewer::showPopupMenu stereo type selected: "
2832// +m_d->viewerStereoType2PrettyString(type));
2833//
2834// setStereoTypeSlot(type);
2835//
2836// // enable the relevant menus
2837// if (type == SoQtViewer::STEREO_ANAGLYPH) {
2838// m_d->stereo_set_anaglyph_menu->setEnabled(true);
2839// } else {
2840// m_d->stereo_set_anaglyph_menu->setEnabled(false);
2841// }
2842//
2843//
2844// return;
2845// }
2846// if (m_d->popup_stereo_anaglyph_actions.contains(selAct)) {
2847//
2848// QString type = selAct->data().toString();
2849//
2850// if (VP1Msg::verbose())
2851// VP1Msg::messageVerbose("VP1ExaminerViewer::showPopupMenu stereo anaglyph selected: "
2852// +type);
2853//
2854// // default values for normal Anaglyph red-cyan view
2855// SbBool leftFilter[3] = {true, false, false};
2856// SbBool rightFilter[3] = {false, true, true};
2857//
2858// if (type.contains("Left-eye")) {
2859// SbBool leftFilter[3] = {true, true, true};
2860// SbBool rightFilter[3] = {false, false, false};
2861// setAnaglyphStereoColorMasksSlot(leftFilter, rightFilter);
2862// }
2863// else if (type.contains("Right-eye")) {
2864// SbBool leftFilter[3] = {false, false, false};
2865// SbBool rightFilter[3] = {true, true, true};
2866// setAnaglyphStereoColorMasksSlot(leftFilter, rightFilter);
2867// }
2868// else {
2869// setAnaglyphStereoColorMasksSlot(leftFilter, rightFilter);
2870// }
2871// return;
2872// }
2873//
2874//
2875// // STEREO - Camera
2876// if (selAct==m_d->popup_stereo_offset_value_action_camera) {
2877//
2878// float old = m_d->popup_stereo_offset_value_action_camera->data().toFloat();
2879// bool ok;
2880// float newoffset = QInputDialog::getDouble(getWidget(), "Change stereo OFFSET (Camera) - 0.1 is the standard offset between left and right eye",
2881// "New stereo offset: ", old,0.1,4000,1,&ok);
2882// if (ok && old != newoffset) {
2883// VP1Msg::messageVerbose("VP1ExaminerViewer::showPopupMenu changed CAMERA stereo offset to "+VP1Msg::str(newoffset));
2884// m_d->popup_stereo_offset_value_action_camera->setData(newoffset);
2885//
2886// SoCamera *camera = getCamera();
2887// camera->setStereoAdjustment(newoffset);
2889// m_d->popup_stereo_offset_value_action_camera->setText("Change CAMERA STEREO offset [current: "+QString::number(newoffset)+"]");
2890// }
2891// return;
2892// }
2893// if (selAct==m_d->popup_stereo_balance_value_action_camera) {
2894//
2895// float old = m_d->popup_stereo_balance_value_action_camera->data().toFloat();
2896// bool ok;
2897// float newoffset = QInputDialog::getDouble(getWidget(), "Change stereo OFFSET (Camera) - 0.1 is the standard offset between left and right eye",
2898// "New stereo offset: ", old,0.1,4000,1,&ok);
2899// if (ok && old != newoffset) {
2900// VP1Msg::messageVerbose("VP1ExaminerViewer::showPopupMenu changed CAMERA stereo offset to "+VP1Msg::str(newoffset));
2901// m_d->popup_stereo_balance_value_action_camera->setData(newoffset);
2902//
2903// SoCamera *camera = getCamera();
2904// camera->setBalanceAdjustment(newoffset);
2906// m_d->popup_stereo_balance_value_action_camera->setText("Change CAMERA STEREO balance [current: "+QString::number(newoffset)+"]");
2907// }
2908// return;
2909// }
2910//
2911//
2912// if (m_d->popup_stereo_anaglyph_actions_camera.contains(selAct)) {
2913//
2914// QString type = selAct->data().toString();
2915//
2916// if (VP1Msg::verbose())
2917// VP1Msg::messageVerbose("VP1ExaminerViewer::showPopupMenu CAMERA stereo view mode selected: "
2918// +type);
2919//
2920// SoCamera *camera = getCamera();
2921//
2922// if (type.contains("Left-eye")) {
2923// camera->setStereoMode(SoCamera::LEFT_VIEW);
2924// }
2925// else if (type.contains("Right-eye")) {
2926// camera->setStereoMode(SoCamera::RIGHT_VIEW);
2927// }
2928// else {
2929// camera->setStereoMode(SoCamera::MONOSCOPIC);
2930// }
2931// return;
2932// }
2933
2934
2935
2936
2937 // default
2938 VP1Msg::messageDebug("VP1ExaminerViewer::showPopupMenu ERROR: Unknown selected item!");
2939 return;
2940
2941}
2942
2943
2944//____________________________________________________________________
2946{
2947 VP1Msg::messageVerbose("VP1ExaminerViewer::launchStereoEditor()");
2948
2949 if (!m_d->customstereoeditor) {
2950 m_d->customstereoeditor = new VP1CustomStereoEditor(this);
2951 // m_d->customstereoeditor->disableObjectWhenTourNotAvailable(m_d->customtour_execute);
2952 // if (m_d->customstereoeditorState!=QByteArray()) { //TODO: implement save stereo settings
2953 // m_d->customstereoeditor->setState(m_d->customstereoeditorState);
2954 // m_d->customstereoeditorState = QByteArray();
2955 // }
2956 }
2957 m_d->customstereoeditor->show();
2958 //Fixme: deal with minimised state!
2959 return;
2960}
2961
2962
2963//____________________________________________________________________
2965{
2966 VP1Msg::messageVerbose("getAllStereoViewTypes()");
2967 QList<SoQtViewer::StereoType> l;
2968
2969 // for the moment we only use these two
2970 l << SoQtViewer::STEREO_NONE; //Use monoscopic rendering.
2971 l<< SoQtViewer::STEREO_ANAGLYPH; //Render stereo by superimposing two images of the same scene, but with different color filters over the left and right view (or "eye").
2972 //This is a way of rendering stereo which works on any display, using color-filter glasses. Such glasses are usually cheap and easy to come by.
2973 //See also: setAnaglyphStereoColorMasks()
2974
2975 // test
2976 l << SoQtViewer::STEREO_QUADBUFFER; //Render stereo by using OpenGL quad-buffers. This is the most common interface for stereo rendering for more expensive hardware devices, such as shutter glasses and polarized glasses.
2977 //The well known Crystal Eyes glasses are commonly used with this type of stereo display.
2978 l << SoQtViewer::STEREO_INTERLEAVED_ROWS; //Interleaving / interlacing rows from the left and right eye is another stereo rendering method requiring special hardware. One example of a provider of shutter glasses working with interleaved glasses is VRex:
2979 //http://www.vrex.com/
2980 l << SoQtViewer::STEREO_INTERLEAVED_COLUMNS; //Same basic technique as SoQtViewer::STEREO_INTERLEAVED_ROWS, only it is vertical lines that are interleaved / interlaced, instead of horizontal lines.
2981
2982 return l;
2983}
2984//____________________________________________________________________
2986{
2987 VP1Msg::messageVerbose("viewerStereoType2PrettyString() - "+QString::number(ds) );
2988 switch (ds) {
2989 case SoQtViewer::STEREO_NONE: return "NO Stereo";
2990 case SoQtViewer::STEREO_ANAGLYPH: return "Anaglyph Stereo (Red-Cyan 3D mode)";
2991 case SoQtViewer::STEREO_QUADBUFFER: return "QUADBUFFER";
2992 case SoQtViewer::STEREO_INTERLEAVED_ROWS: return "INTERLEAVED_ROWS";
2993 case SoQtViewer::STEREO_INTERLEAVED_COLUMNS: return "INTERLEAVED_COLUMNS";
2994 default:
2995 VP1Msg::messageDebug("VP1ExaminerViewer::Imp::viewerStereoType2PrettyString ERROR: Unknown viewer draw style");
2996 return "x";
2997 }
2998}
2999//____________________________________________________________________
3001{
3002 switch (ds) {
3003 case SoQtViewer::STEREO_NONE: return 0;
3004 case SoQtViewer::STEREO_ANAGLYPH: return 1;
3005 case SoQtViewer::STEREO_QUADBUFFER: return 2;
3006 case SoQtViewer::STEREO_INTERLEAVED_ROWS: return 3;
3007 case SoQtViewer::STEREO_INTERLEAVED_COLUMNS: return 4;
3008 default:
3009 VP1Msg::messageDebug("VP1ExaminerViewer::Imp::viewerStereoTypeToInt ERROR: Unknown viewer draw style");
3010 return -1;
3011 }
3012}
3013//____________________________________________________________________
3015{
3016 VP1Msg::messageVerbose("intToViewerStereoType() - "+QString::number(i) );
3017 switch (i) {
3018 case 0: return SoQtViewer::STEREO_NONE;
3019 case 1: return SoQtViewer::STEREO_ANAGLYPH;
3020 case 2: return SoQtViewer::STEREO_QUADBUFFER;
3021 case 3: return SoQtViewer::STEREO_INTERLEAVED_ROWS;
3022 case 4: return SoQtViewer::STEREO_INTERLEAVED_COLUMNS;
3023 default:
3024 VP1Msg::messageDebug("VP1ExaminerViewer::Imp::intToViewerStereoType ERROR: int out of range "+VP1Msg::str(i));
3025 return SoQtViewer::STEREO_NONE;
3026 }
3027}
3028
3029
3030
3031
3032//____________________________________________________________________
3034{
3035 VP1Msg::messageVerbose("getAllViewerDrawStyles()");
3036
3037 QList<SoQtViewer::DrawStyle> l;
3038 l << SoQtViewer::VIEW_SAME_AS_STILL
3039 << SoQtViewer::VIEW_AS_IS
3040 << SoQtViewer::VIEW_HIDDEN_LINE
3041 << SoQtViewer::VIEW_NO_TEXTURE
3042 << SoQtViewer::VIEW_LOW_COMPLEXITY
3043 << SoQtViewer::VIEW_LINE
3044 << SoQtViewer::VIEW_POINT
3045 << SoQtViewer::VIEW_BBOX
3046 << SoQtViewer::VIEW_LOW_RES_LINE
3047 << SoQtViewer::VIEW_LOW_RES_POINT
3048 << SoQtViewer::VIEW_WIREFRAME_OVERLAY;
3049 return l;
3050}
3051
3052//____________________________________________________________________
3054{
3055 switch (ds) {
3056 case SoQtViewer::VIEW_AS_IS: return 0;
3057 case SoQtViewer::VIEW_HIDDEN_LINE: return 1;
3058 case SoQtViewer::VIEW_NO_TEXTURE: return 2;
3059 case SoQtViewer::VIEW_LOW_COMPLEXITY: return 3;
3060 case SoQtViewer::VIEW_LINE: return 4;
3061 case SoQtViewer::VIEW_POINT: return 5;
3062 case SoQtViewer::VIEW_BBOX: return 6;
3063 case SoQtViewer::VIEW_LOW_RES_LINE: return 7;
3064 case SoQtViewer::VIEW_LOW_RES_POINT: return 8;
3065 case SoQtViewer::VIEW_SAME_AS_STILL: return 9;
3066 case SoQtViewer::VIEW_WIREFRAME_OVERLAY: return 10;
3067 default:
3068 VP1Msg::messageDebug("VP1ExaminerViewer::Imp::viewerDrawStyleToInt ERROR: Unknown viewer draw style");
3069 return -1;
3070 }
3071}
3072
3073//____________________________________________________________________
3075{
3076 switch (i) {
3077 case 0: return SoQtViewer::VIEW_AS_IS;
3078 case 1: return SoQtViewer::VIEW_HIDDEN_LINE;
3079 case 2: return SoQtViewer::VIEW_NO_TEXTURE;
3080 case 3: return SoQtViewer::VIEW_LOW_COMPLEXITY;
3081 case 4: return SoQtViewer::VIEW_LINE;
3082 case 5: return SoQtViewer::VIEW_POINT;
3083 case 6: return SoQtViewer::VIEW_BBOX;
3084 case 7: return SoQtViewer::VIEW_LOW_RES_LINE;
3085 case 8: return SoQtViewer::VIEW_LOW_RES_POINT;
3086 case 9: return SoQtViewer::VIEW_SAME_AS_STILL;
3087 case 10: return SoQtViewer::VIEW_WIREFRAME_OVERLAY;
3088 default:
3089 VP1Msg::messageDebug("VP1ExaminerViewer::Imp::intToViewerDrawStyle ERROR: int out of range "+VP1Msg::str(i));
3090 return SoQtViewer::VIEW_AS_IS;
3091 }
3092}
3093
3094//____________________________________________________________________
3096{
3097 switch (ds) {
3098 case SoQtViewer::VIEW_AS_IS: return "As is";
3099 case SoQtViewer::VIEW_HIDDEN_LINE: return "Hidden line";
3100 case SoQtViewer::VIEW_NO_TEXTURE: return "No texture";
3101 case SoQtViewer::VIEW_LOW_COMPLEXITY: return "Low complexity";
3102 case SoQtViewer::VIEW_LINE: return "Line";
3103 case SoQtViewer::VIEW_POINT: return "Point";
3104 case SoQtViewer::VIEW_BBOX: return "Bounding boxes";
3105 case SoQtViewer::VIEW_LOW_RES_LINE: return "Low resolution lines";
3106 case SoQtViewer::VIEW_LOW_RES_POINT: return "Low resolution points";
3107 case SoQtViewer::VIEW_SAME_AS_STILL: return "Same as still";
3108 case SoQtViewer::VIEW_WIREFRAME_OVERLAY: return "Wireframe overlay";
3109 default:
3110 VP1Msg::messageDebug("VP1ExaminerViewer::Imp::viewerDrawStyleToInt ERROR: Unknown viewer draw style");
3111 return "";
3112 }
3113}
3114
3115//____________________________________________________________________
3117{
3118 VP1Msg::messageVerbose("VP1ExaminerViewer::setSceneGraph()");
3119
3120 if (!m_d->actualSceneGraph) {
3121 m_d->actualSceneGraph = new SoGroup;
3122 m_d->actualSceneGraph->ref();
3123 if (!m_d->environmentNode) {
3124 m_d->environmentNode = new SoEnvironment;
3125 m_d->environmentNode->ref();
3126 }
3127 m_d->updateEnvironmentNode();
3128 m_d->actualSceneGraph->addChild(m_d->environmentNode);
3129 SoQtExaminerViewer::setSceneGraph(m_d->actualSceneGraph);
3130 }
3131 while(m_d->actualSceneGraph->getNumChildren()>1)
3132 m_d->actualSceneGraph->removeChild(1);
3133
3134 if (n)
3135 m_d->actualSceneGraph->addChild(n);
3136}
3137
3138//____________________________________________________________________
3140{
3141 return (m_d->actualSceneGraph && m_d->actualSceneGraph->getNumChildren()>1) ? m_d->actualSceneGraph->getChild(1) : 0;
3142}
3143
3144//____________________________________________________________________
3146{
3147 if (!m_d->ensureMenuInit())
3148 return;
3149 QString lastfile, nextfile;
3150 QString outdir = m_d->action_movieoutdir->data().toString();
3152 m_d->movieFrameFileNamePrefix,
3153 lastfile, nextfile );
3154
3155 QImage img0(lastfile);
3156
3157 if (lastfile.isEmpty()||img0.isNull()) {
3158 VP1Msg::messageDebug("VP1ExaminerViewer ERROR: No previous image found!");
3159 return;
3160 }
3161 if (nextfile.isEmpty())
3162 return;
3163
3164 QImage img1 = VP1QtInventorUtils::renderToImage(this, img0.width(),img0.height(),false/*transp*/);
3165 if (img1.isNull())
3166 return;
3167
3168 int nTransitionFrames = std::max(1,static_cast<int>(m_d->action_moviefps->data().toInt()*time_seconds+0.5));
3169 VP1Msg::messageDebug("VP1ExaminerViewer Creating "+VP1Msg::str(nTransitionFrames)+" transition frames");
3170
3171 for (int i = 0; i < nTransitionFrames; ++i) {
3172 double fadefact((i+1.0)/(nTransitionFrames+1.0));//Should not be 0.0 or 1.0
3173 QString dummy, filename;
3174 VP1CameraHelper::getLastAndNextFrameFileNames( outdir, m_d->movieFrameFileNamePrefix,dummy,filename );
3175 QImage img = VP1QtUtils::fadeImage(img0, img1, fadefact );
3176 if (img.isNull()) {
3177 VP1Msg::messageDebug("VP1ExaminerViewer ERROR: Problems creating image!");
3178 } else {
3179 if (!img.save(filename))
3180 VP1Msg::messageDebug("VP1ExaminerViewer ERROR: Could not save image file "+filename);
3181 }
3182 }
3183
3184 QString dummy, filename;
3185 VP1CameraHelper::getLastAndNextFrameFileNames( outdir, m_d->movieFrameFileNamePrefix,dummy,filename );
3186 if (!img1.save(filename))
3187 VP1Msg::messageDebug("VP1ExaminerViewer ERROR: Could not save image file "+filename);
3188
3189}
#define M_PI
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
static Double_t a
static Double_t fs
static Double_t tc
static Double_t al
const double width
void debugCameraClipPlanes(void *data, const SbVec2f &nearfar)
tune the camera clipping planes
SbVec2f fixedDistanceClipPlanesCB(void *data, const SbVec2f &nearfar)
set the clipping strategy and fix the clipping
SoGL2PSAction inherits Inventor/SoGLRenderAction.
static void initClass()
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
static VP1CameraHelper * animatedZoomToSubTree(SoCamera *camera, SoGroup *sceneroot, SoNode *subtreeroot, double duration_in_secs=1.0, double clipVolPercent=100.0, double lastClipVolPercent=100.0, double slack=1.0, const SbVec3f &lookat=SbVec3f(999, 999, 999), const SbVec3f &upvec=SbVec3f(999, 999, 999), bool varySpeed=true, bool forceCircular=false)
static void getLastAndNextFrameFileNames(const QString &outputdir, const QString &prefix, QString &lastOfExistingFiles, QString &nextAvailableFile)
static VP1CameraHelper * animatedZoomToCameraState(SoCamera *camera, SoGroup *sceneroot, const QByteArray &camstate, double duration_in_secs=1.0, double clipVolPercent=100.0, double lastClipVolPercent=100.0, bool varySpeed=true, bool forceCircular=false)
static void setCustomTourEditor(VP1CustomTourEditor *editor)
const QByteArray & camState() const
StoredView(const QByteArray &camState, bool camPerspective, QPixmap snapShot, const QString &name)
QPushButton * addNewButton(QString text, QString tooltip, REGION region, VIEW view, QWidget *tempparent, QString iconname="")
VP1CustomTourEditor * customtoureditor
Imp(VP1ExaminerViewer *tc, bool dvb)
static QList< SoQtViewer::StereoType > getAllStereoViewTypes()
std::map< QPushButton *, std::pair< REGION, VIEW > > detectorbuttons
QString toString(const REGION &r)
QList< QAction * > restoreViewActions
QList< QAction * > deleteViewActions
Imp & operator=(const Imp &)=delete
SoSphere * getRegionSphere(REGION, bool perspective)
static QString viewerDrawStyle2PrettyString(SoQtViewer::DrawStyle)
float rotXWheelMotion(float value, float oldvalue)
static QString viewerStereoType2PrettyString(SoQtViewer::StereoType)
float rotZWheelMotion(float value, float oldvalue)
QList< QAction * > storeViewActions
VP1ExaminerViewer * theclass
static int viewerDrawStyleToInt(SoQtViewer::DrawStyle)
QList< StoredView > storedViews
Imp(const Imp &)=delete
static SoQtViewer::DrawStyle intToViewerDrawStyle(int)
VP1ExaminerViewer_SignalCatcher * signalcatcher
VP1CustomStereoEditor * customstereoeditor
bool fitsCurrentCamType(const StoredView &sv)
QList< QAction * > zoomToViewActions
void detectorZoomButtonClicked(std::pair< REGION, VIEW >)
void rotateCamera(SoCamera *cam, const SbVec3f &aroundaxis, const float delta)
static SoQtViewer::StereoType intToViewerStereoType(int)
ROTATIONMODE rotationMode
Which mode is left wheel in?
QList< QAction * > popup_drawstyle_still_actions
AnimationSequencer animationSequencer
static int viewerStereoTypeToInt(SoQtViewer::StereoType)
static int drawStyleToInt(SoQtViewer::DrawStyle)
static QList< SoQtViewer::DrawStyle > getAllViewerDrawStyles()
QList< QAction * > popup_drawstyle_interactive_actions
QList< QAction * > popup_transptype_actions
static SoQtViewer::DrawStyle intToDrawStyle(int)
virtual void leftWheelFinish()
void fadeLastRecordedFrameToCurrent(double time_seconds)
QByteArray currentCameraState() const
void dumpSceneToVRMLFile(QString filename="")
virtual void setAntialiasing(SbBool smoothing, int numPasses)
virtual void bottomWheelStart()
VP1ExaminerViewer(QWidget *parent=0, bool detectorViewButtons=true, const char *name=0, SbBool embed=TRUE, SoQtFullViewer::BuildFlag flag=BUILD_ALL, SoQtViewer::Type type=BROWSER)
SoQtViewer::StereoType getStereoTypeSlot(void) const
virtual void setSceneGraph(SoNode *)
virtual void createViewerButtons(QWidget *parent, SbPList *buttonlist)
void setStereoOffsetSlot(float offset)
virtual QByteArray saveState()
virtual void setBufferingType(SoQtViewer::BufferType)
virtual SbBool processSoEvent(const SoEvent *const event)
virtual void removeDecorationMenuOption()
virtual void setDrawStyle(SoQtViewer::DrawType, SoQtViewer::DrawStyle)
void setAnaglyphStereoColorMasksSlot(const SbBool left[3], const SbBool right[3])
virtual void toggleCameraType()
void produceSVGImage(QString filename="")
virtual void buildPopupMenu()
virtual void rightWheelFinish()
QPixmap getSnapShotFromCamState(bool camStateIsPerspective, QByteArray camState, int width, int height, bool transp=false)
SbBool setStereoTypeSlot(SoQtViewer::StereoType type)
virtual void setViewing(SbBool enable)
void getAnaglyphStereoColorMasksSlot(SbBool left[3], SbBool right[3])
virtual void rightWheelStart()
virtual void setTransparencyType(SoGLRenderAction::TransparencyType)
virtual void showPopupMenu()
bool currentCamIsPerspective() const
friend class VP1ExaminerViewer_SignalCatcher
virtual void restoreFromState(QByteArray)
virtual void leftWheelMotion(float val)
virtual void leftWheelStart()
virtual void setSeekMode(SbBool enable)
void dumpSceneToFile(QString filename="")
virtual void bottomWheelMotion(float val)
virtual void rightWheelMotion(float val)
bool startTourEachEvent() const
virtual void bottomWheelFinish()
virtual void setCameraType(SoType type)
virtual SoNode * getSceneGraph()
void produceEPSImage(QString filename="")
static SoGroup * convertToStandardScene(SoGroup *)
static void messageVerbose(const QString &)
Definition VP1Msg.cxx:84
static bool verbose()
Definition VP1Msg.h:31
static void messageDebug(const QString &)
Definition VP1Msg.cxx:39
static void message(const QString &, IVP1System *sys=0)
Definition VP1Msg.cxx:30
static void messageWarningRed(const QString &str, IVP1System *sys=0)
Definition VP1Msg.cxx:57
static bool writeGraphToVRMLFile(SoNode *root, const QString &filename)
static QList< SoGLRenderAction::TransparencyType > getAllTransparencyTypes()
static QPixmap renderToPixmap(VP1ExaminerViewer *ra, int pixels_x, int pixels_y, bool transparent_background=false, double actualRenderedSizeFact=1.0)
static SoGLRenderAction::TransparencyType intToTransparencyType(int)
static QColor sbcol2qcol(const SbColor &)
static QByteArray serializeSoCameraParameters(const SoCamera &)
static bool writeGraphToFile(SoNode *root, const QString &filename)
static SbColor qcol2sbcol(const QColor &)
static QString transparencyType2PrettyString(SoGLRenderAction::TransparencyType)
static bool deserializeSoCameraParameters(QByteArray &, SoCamera &)
static QImage renderToImage(VP1ExaminerViewer *ra, int pixels_x, int pixels_y, bool transparent_background=false, double actualRenderedSizeFact=1.0)
static int transparencyTypeToInt(SoGLRenderAction::TransparencyType)
static QImage fadeImage(QImage img0, QImage img1, double fadefact)
static QString environmentVariableValue(const QString &name)
static bool expertSettingIsOn(const QString &type, const QString &name)
static QString defaultFileSelectDirectory()
static QString str(const QString &s)
Definition VP1String.h:49
make the sidebar many part of the config
Definition hcg.cxx:552
std::string tail(std::string s, const std::string &pattern)
tail of a string
GL2PSDLL_API GLint gl2psBeginPage(const char *title, const char *producer, GLint viewport[4], GLint format, GLint sort, GLint options, GLint colormode, GLint colorsize, GL2PSrgba *colormap, GLint nr, GLint ng, GLint nb, GLint buffersize, FILE *stream, const char *filename)
Definition gl2ps.cxx:5584
GL2PSDLL_API GLint gl2psEndPage(void)
Definition gl2ps.cxx:5751
#define GL2PS_BSP_SORT
Definition gl2ps.h:105
#define GL2PS_OCCLUSION_CULL
Definition gl2ps.h:124
#define GL2PS_SILENT
Definition gl2ps.h:122
#define GL2PS_OVERFLOW
Definition gl2ps.h:114
#define GL2PS_BEST_ROOT
Definition gl2ps.h:123
#define GL2PS_DRAW_BACKGROUND
Definition gl2ps.h:120
#define GL2PS_EPS
Definition gl2ps.h:95
#define GL2PS_USE_CURRENT_VIEWPORT
Definition gl2ps.h:129
int r
Definition globals.cxx:22
void search(TDirectory *td, const std::string &s, std::string cwd, node *n)
recursive directory search for TH1 and TH2 and TProfiles
Definition hcg.cxx:739