59#include <qpushbutton.h>
62#include <qimagewriter.h>
65#include <qtreewidget.h>
66#include <qapplication.h>
67#include <qmessagebox.h>
68#include <qfiledialog.h>
70#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
71 #include <qelapsedtimer.h>
73#if (QT_VERSION < QT_VERSION_CHECK(5, 10, 0))
74 #include "qdesktopwidget.h"
78#include <qcolordialog.h>
85#include <qmainwindow.h>
86#include <qtablewidget.h>
87#include <qheaderview.h>
88#include <qscrollarea.h>
94#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
97#include <QOpenGLContext>
101#include "moc_G4OpenGLQtViewer.cpp"
117#if QT_VERSION < 0x060000
120 ResizeWindow(glWidget->devicePixelRatio()*
fVP.GetWindowSizeHintX(),glWidget->devicePixelRatio()*
fVP.GetWindowSizeHintY());
133 if (UI == NULL)
return;
142 bool isTabbedView =
false;
152 QObject::connect(
fUiQt->GetViewerTabWidget(),
153 SIGNAL(currentChanged(
int)),
155 SLOT(currentTabActivated(
int)));
157#if QT_VERSION < 0x060000
159 createViewerPropertiesWidget();
163 createSceneTreeWidget();
170 QWidget *glDialogWidget = getParentWidget();
171 if (glDialogWidget == NULL) {
174 glWidget->setParent(glDialogWidget);
175 QHBoxLayout *mainLayout =
new QHBoxLayout();
177 mainLayout->setContentsMargins(0,0,0,0);
178 mainLayout->setSpacing(0);
180 if (
fGLWidget->inherits(
"QMainWindow")) {
183 glDialogWidget->setLayout(mainLayout);
187#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
188 G4int offset = QGuiApplication::primaryScreen()->availableGeometry().height()
189 - QGuiApplication::screenAt(QPoint(20,20))->availableGeometry().height();
192 - QApplication::desktop()->availableGeometry().height();
195 G4int YPos=
fVP.GetWindowAbsoluteLocationHintY(QGuiApplication::primaryScreen()->availableGeometry().height());
196 if (
fVP.GetWindowAbsoluteLocationHintY(QGuiApplication::primaryScreen()->availableGeometry().height())<
offset) {
200 glDialogWidget->move(
fVP.GetWindowAbsoluteLocationHintX(QGuiApplication::primaryScreen()->availableGeometry().width()),YPos);
201 glDialogWidget->show();
223 ,fLastPickPoint(-1,-1)
226 ,fHoldKeyEvent(false)
227 ,fHoldMoveEvent(false)
228 ,fHoldRotateEvent(false)
232 ,fMovieTempFolderPath(
"")
234 ,fParameterFileName(
"ppmtompeg_encode_parameter_file.par")
235 ,fMovieParametersDialog(NULL)
236 ,fRecordingStep(WAIT)
238 ,fNbMaxFramesPerSec(100)
239 ,fNbMaxAnglePerSec(360)
240 ,fLaunchSpinDelay(100)
241 ,fUISceneTreeWidget(NULL)
242 ,fUIViewerPropertiesWidget(NULL)
243 ,fUIPickInfosWidget(NULL)
246 ,fControlKeyPress(false)
247 ,fShiftKeyPress(false)
249 ,fCheckSceneTreeComponentSignalLock(false)
250 ,fViewerPropertiesTableWidgetIsInit(false)
251 ,fSceneTreeComponentTreeWidget(NULL)
252 ,fSceneTreeWidget(NULL)
253 ,fPVRootNodeCreate(false)
257 ,fTouchableVolumes(
"Touchables")
258 ,fShortcutsDialog(NULL)
259 ,fViewerPropertiesTableWidget(NULL)
260 ,fPickInfosWidget(NULL)
261 ,fPickInfosScrollArea(NULL)
262 ,fTreeWidgetInfosIgnoredCommands(0)
263 ,fSceneTreeDepthSlider(NULL)
265 ,fModelShortNameItem(NULL)
266 ,fMaxPOindexInserted(-1)
268 ,fTreeIconClosed(NULL)
269 ,fLastExportSliderValue(80)
270 ,fLastHighlightColor(
G4Color(0,0,0,0))
271 ,fLastHighlightName(0)
275 if (QCoreApplication::instance () == NULL) {
280 fLastPos3 = QPoint(-1,-1);
281 fLastPos2 = QPoint(-1,-1);
282 fLastPos1 = QPoint(-1,-1);
284 initMovieParameters();
286#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0))
287 fLastEventTime =
new QTime();
289 fLastEventTime =
new QElapsedTimer();
292 fFileSavePath = QDir::currentPath();
295 QList<QByteArray> formats = QImageWriter::supportedImageFormats ();
296 for (
int i = 0; i < formats.size(); ++i) {
300 const char *
const icon1[]={
358 const char *
const icon2[]={
451 const char *
const search[] = {
463 "OOOOOOOOOOOOOOOOOOO",
464 "OOOOOOOOOOOOOOOOOOO",
465 "OOOOOOOo. .oOOOOOO",
468 "OOOOO. XOOOOX .OOOO",
471 "OOOOO. XOOOOo .OOOO",
475 "OOOOOOOOOOOOO. XOO",
476 "OOOOOOOOOOOOOO. XOO",
477 "OOOOOOOOOOOOOOOoOOO",
478 "OOOOOOOOOOOOOOOOOOO",
479 "OOOOOOOOOOOOOOOOOOO",
480 "OOOOOOOOOOOOOOOOOOO",
481 "OOOOOOOOOOOOOOOOOOO"
484 fSearchIcon =
new QPixmap(search);
485 fTreeIconOpen =
new QPixmap(icon1);
486 fTreeIconClosed =
new QPixmap(icon2);
501 if (fSceneTreeWidget != NULL) {
502 if (fSceneTreeWidget->layout() != NULL) {
503 while ((wItem = fSceneTreeWidget->layout()->takeAt(0)) != 0) {
504 delete wItem->widget();
511 delete fTreeIconOpen;
512 delete fTreeIconClosed;
514#if QT_VERSION < 0x060000
515 G4cout <<removeTempFolder().toStdString().c_str() <<
G4endl;
521#if QT_VERSION < 0x060000
526 if (!qGLW)
return false;
527 return qGLW->isValid();
534void G4OpenGLQtViewer::createPopupMenu() {
536 fContextMenu =
new QMenu(
"All");
538 QMenu *mMouseAction = fContextMenu->addMenu(
"&Mouse actions");
539 fMouseRotateAction = mMouseAction->addAction(
"Rotate",
this, [
this](){ this->toggleMouseAction(1); });
540 fMouseMoveAction = mMouseAction->addAction(
"Move",
this, [
this](){ this->toggleMouseAction(2); });
541 fMousePickAction = mMouseAction->addAction(
"Pick",
this, [
this](){ this->toggleMouseAction(3); });
542 fMouseZoomOutAction = mMouseAction->addAction(
"Zoom out",
this, [
this](){ this->toggleMouseAction(4); });
543 fMouseZoomInAction = mMouseAction->addAction(
"Zoom in",
this, [
this](){ this->toggleMouseAction(5); });
544 QAction *shortcutsAction = mMouseAction->addAction(
"Show shortcuts");
546 fMouseRotateAction->setCheckable(
true);
547 fMouseMoveAction->setCheckable(
true);
548 fMousePickAction->setCheckable(
true);
549 fMouseZoomOutAction->setCheckable(
true);
550 fMouseZoomInAction->setCheckable(
true);
551 shortcutsAction->setCheckable(
false);
553 QObject::connect(shortcutsAction,
554 SIGNAL(triggered(
bool)),
556 SLOT(showShortcuts()));
559 QMenu *mStyle = fContextMenu->addMenu(
"&Style");
561 QMenu *mProjection = mStyle->addMenu(
"&Projection");
564 fProjectionOrtho = mProjection->addAction(
"Orthographic",
this, [
this](){ this->toggleProjection(
true); });
565 fProjectionPerspective = mProjection->addAction(
"Perspective",
this, [
this](){ this->toggleProjection(
false); });
567 QMenu *mDrawing = mStyle->addMenu(
"&Drawing");
568 fDrawingWireframe = mDrawing->addAction(
"Wireframe",
this, [
this](){ this->toggleSurfaceAction(1); });
569 fDrawingLineRemoval = mDrawing->addAction(
"Hidden line removal",
this, [
this](){ this->toggleSurfaceAction(2); });
570 fDrawingSurfaceRemoval = mDrawing->addAction(
"Hidden Surface removal",
this, [
this](){ this->toggleSurfaceAction(3); });
571 fDrawingLineSurfaceRemoval = mDrawing->addAction(
"Hidden line and surface removal",
this, [
this](){ this->toggleSurfaceAction(4); });
573 fDrawingWireframe->setCheckable(
true);
574 fDrawingLineRemoval->setCheckable(
true);
575 fDrawingSurfaceRemoval->setCheckable(
true);
576 fDrawingLineSurfaceRemoval->setCheckable(
true);
580 QAction *backgroundColorChooser ;
582 backgroundColorChooser = mStyle->addAction(
"Background color");
583 QObject ::connect(backgroundColorChooser,
586 SLOT(actionChangeBackgroundColor()));
590 QAction *textColorChooser ;
592 textColorChooser = mStyle->addAction(
"Text color");
593 QObject ::connect(textColorChooser,
596 SLOT(actionChangeTextColor()));
600 QAction *defaultColorChooser ;
602 defaultColorChooser = mStyle->addAction(
"Default color");
603 QObject ::connect(defaultColorChooser,
606 SLOT(actionChangeDefaultColor()));
610 QMenu *mActions = fContextMenu->addMenu(
"&Actions");
611 QAction *createEPS = mActions->addAction(
"Save as ...");
612 QObject ::connect(createEPS,
615 SLOT(actionSaveImage()));
618 QAction *movieParameters = mActions->addAction(
"Save as movie...");
619 QObject ::connect(movieParameters,
622 SLOT(actionMovieParameters()));
628 QMenu *mSpecial = fContextMenu->addMenu(
"S&pecial");
629 QMenu *mTransparency = mSpecial->addMenu(
"Transparency");
630 QAction *transparencyOn = mTransparency->addAction(
"On");
631 QAction *transparencyOff = mTransparency->addAction(
"Off");
634 createRadioAction(transparencyOn,transparencyOff,SLOT(toggleTransparency(
bool)),2);
636 createRadioAction(transparencyOn,transparencyOff,SLOT(toggleTransparency(
bool)),1);
642 QMenu *mAntialiasing = mSpecial->addMenu(
"Antialiasing");
643 QAction *antialiasingOn = mAntialiasing->addAction(
"On");
644 QAction *antialiasingOff = mAntialiasing->addAction(
"Off");
647 createRadioAction(antialiasingOn,antialiasingOff,SLOT(toggleAntialiasing(
bool)),2);
649 createRadioAction(antialiasingOn,antialiasingOff,SLOT(toggleAntialiasing(
bool)),1);
651 mAntialiasing->clear();
654 QMenu *mHaloing = mSpecial->addMenu(
"Haloing");
655 QAction *haloingOn = mHaloing->addAction(
"On");
656 QAction *haloingOff = mHaloing->addAction(
"Off");
658 createRadioAction(haloingOn,haloingOff,SLOT(toggleHaloing(
bool)),2);
660 createRadioAction(haloingOn,haloingOff,SLOT(toggleHaloing(
bool)),1);
665 QMenu *mAux = mSpecial->addMenu(
"Auxiliary edges");
666 QAction *auxOn = mAux->addAction(
"On");
667 QAction *auxOff = mAux->addAction(
"Off");
668 if (!
fVP.IsAuxEdgeVisible()) {
669 createRadioAction(auxOn,auxOff,SLOT(toggleAux(
bool)),2);
671 createRadioAction(auxOn,auxOff,SLOT(toggleAux(
bool)),1);
675 QMenu *mHiddenMarkers = mSpecial->addMenu(
"Hidden markers");
676 QAction *hiddenMarkersOn = mHiddenMarkers->addAction(
"On");
677 QAction *hiddenMarkersOff = mHiddenMarkers->addAction(
"Off");
678 if (
fVP.IsMarkerNotHidden()) {
679 createRadioAction(hiddenMarkersOn,hiddenMarkersOff,SLOT(toggleHiddenMarkers(
bool)),2);
681 createRadioAction(hiddenMarkersOn,hiddenMarkersOff,SLOT(toggleHiddenMarkers(
bool)),1);
686 QMenu *mFullScreen = mSpecial->addMenu(
"&Full screen");
687 fFullScreenOn = mFullScreen->addAction(
"On");
688 fFullScreenOff = mFullScreen->addAction(
"Off");
689 createRadioAction(fFullScreenOn,fFullScreenOff,SLOT(toggleFullScreen(
bool)),2);
698 G4cerr <<
"Visualization window not defined, please choose one before" <<
G4endl;
705 if ( fContextMenu ) {
707 fContextMenu->exec( e->globalPos() );
723void G4OpenGLQtViewer::createRadioAction(QAction *action1,QAction *action2,
const std::string& method,
unsigned int nCheck) {
725 action1->setCheckable(
true);
726 action2->setCheckable(
true);
729 action1->setChecked (
true);
731 action2->setChecked (
true);
733 QObject ::connect(action1, SIGNAL(triggered(
bool)),action2, SLOT(toggle()));
734 QObject ::connect(action2, SIGNAL(triggered(
bool)),action1, SLOT(toggle()));
736 QObject ::connect(action1, SIGNAL(toggled(
bool)),
this, method.c_str());
745void G4OpenGLQtViewer::showShortcuts() {
748 text =
"========= Mouse Shortcuts =========\n";
750 if (
fUiQt->IsIconRotateSelected()) {
751 text +=
"Click and move mouse to rotate volume \n";
752 text +=
"ALT + Click and move mouse to rotate volume (Toggle View/Theta-Phi Direction) \n";
753 text +=
"CTRL + Click and move mouse to zoom in/out \n";
754 text +=
"SHIFT + Click and move mouse to change camera point of view \n";
755 }
else if (
fUiQt->IsIconMoveSelected()) {
756 text +=
"Move camera point of view with mouse \n";
757 }
else if (
fUiQt->IsIconPickSelected()) {
758 text +=
"Click and pick \n";
761 text +=
"Click and move mouse to rotate volume \n";
762 text +=
"ALT + Click and move mouse to rotate volume (Toggle View/Theta-Phi Direction) \n";
763 text +=
"CTRL + Click and zoom mouse to zoom in/out \n";
764 text +=
"SHIFT + Click and zoommove camera point of view \n";
766 text +=
"========= Move Shortcuts ========= \n";
767 text +=
"Press left/right arrows to move volume left/right \n";
768 text +=
"Press up/down arrows to move volume up/down \n";
769 text +=
"Press '+'/'-' to move volume toward/forward \n";
771 text +=
"========= Rotation (Theta/Phi) Shortcuts ========= \n";
772 text +=
"Press SHIFT + left/right arrows to rotate volume left/right \n";
773 text +=
"Press SHIFT + up/down arrows to rotate volume up/down \n";
775 text +=
"========= Rotation (View Direction) Shortcuts ========= \n";
776 text +=
"Press ALT + left/right to rotate volume around vertical direction \n";
777 text +=
"Press ALT + up/down to rotate volume around horizontal direction \n";
779 text +=
"========= Zoom View ========= \n";
780 text +=
"Press CTRL + '+'/'-' to zoom into volume \n";
782 text +=
"========= Misc ========= \n";
783 text +=
"Press ALT +/- to slow/speed rotation/move \n";
784 text +=
"Press H to reset view \n";
785 text +=
"Press Esc to exit FullScreen \n";
787 text +=
"========= Video ========= \n";
788 text +=
"In video mode : \n";
789 text +=
" Press SPACE to Start/Pause video recording \n";
790 text +=
" Press RETURN to Stop video recording \n";
795 if ( fShortcutsDialog == NULL) {
796 fShortcutsDialog =
new QDialog();
797 fShortcutsDialogInfos =
new QTextEdit() ;
798 QVBoxLayout *mainLayout =
new QVBoxLayout;
799 mainLayout->addWidget(fShortcutsDialogInfos);
800 fShortcutsDialog->setLayout(mainLayout);
801 fShortcutsDialog->setWindowTitle(tr(
"Shortcuts"));
804 fShortcutsDialogInfos->setPlainText(text.data());
805 fShortcutsDialog->show();
816void G4OpenGLQtViewer::toggleMouseAction(
int aAction) {
819 fUiQt->SetIconRotateSelected();
820 }
else if (aAction == 2) {
821 fUiQt->SetIconMoveSelected();
822 }
else if (aAction == 3) {
824 }
else if (aAction == 4) {
825 fUiQt->SetIconZoomOutSelected();
826 }
else if (aAction == 5) {
827 fUiQt->SetIconZoomInSelected();
845void G4OpenGLQtViewer::toggleSurfaceAction(
int aAction) {
852 }
else if (aAction ==2) {
855 }
else if (aAction ==3) {
858 }
else if (aAction ==4) {
861 fVP.SetDrawingStyle(d_style);
878void G4OpenGLQtViewer::toggleProjection(
bool check) {
881 fVP.SetOrthogonalProjection ();
883 fVP.SetPerspectiveProjection();
894void G4OpenGLQtViewer::toggleTransparency(
bool check) {
910void G4OpenGLQtViewer::toggleAntialiasing(
bool check) {
914 glDisable (GL_LINE_SMOOTH);
915 glDisable (GL_POLYGON_SMOOTH);
918 glEnable (GL_LINE_SMOOTH);
919 glHint (GL_LINE_SMOOTH_HINT, GL_NICEST);
920 glEnable (GL_POLYGON_SMOOTH);
921 glHint (GL_POLYGON_SMOOTH_HINT, GL_NICEST);
933void G4OpenGLQtViewer::toggleHaloing(
bool check) {
949void G4OpenGLQtViewer::toggleAux(
bool check) {
951 fVP.SetAuxEdgeVisible(
true);
953 fVP.SetAuxEdgeVisible(
false);
961void G4OpenGLQtViewer::togglePicking() {
964 fUiQt->TogglePickSelection();
969 if (!
fVP.IsPicking()) {
970 UI->
ApplyCommand(std::string(
"/vis/viewer/set/picking true"));
972 UI->
ApplyCommand(std::string(
"/vis/viewer/set/picking false"));
983void G4OpenGLQtViewer::toggleHiddenMarkers(
bool check) {
985 fVP.SetMarkerHidden();
987 fVP.SetMarkerNotHidden();
997void G4OpenGLQtViewer::toggleFullScreen(
bool check) {
998 if (check !=
fGLWidget->isFullScreen()) {
1005 if (fMovieTempFolderPath ==
"") {
1013 QString filePath =fMovieTempFolderPath+fileName;
1016#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
1017 image = qGLW->grabFrameBuffer();
1019 image = qGLW->grabFramebuffer();
1023 res = image.save(filePath,0);
1026 setRecordingInfos(
"Can't save tmp file "+filePath);
1030 setRecordingInfos(
"File "+fileName+
" saved");
1036void G4OpenGLQtViewer::actionSaveImage() {
1044 qFilename = QFileDialog::getSaveFileName (
fGLWidget,
1051 std::string
name = qFilename.toStdString().c_str();
1058 fFileSavePath = QFileInfo(qFilename).path();
1060 std::string format = selectedFormat->toLower().toStdString().c_str();
1065 std::string filename =
name;
1066 std::string extension =
"";
1067 if (
name.find_last_of(
".") != std::string::npos) {
1068 filename =
name.substr(0,
name.find_last_of(
".") + 1);
1069 extension =
name.substr(
name.find_last_of(
".") + 1);
1074 filename+=
"."+ extension;
1080 G4OpenGLQtExportDialog* exportDialog=
new G4OpenGLQtExportDialog(
fGLWidget,format.c_str(),
fGLWidget->height(),
fGLWidget->width());
1081 if( exportDialog->exec()) {
1106void G4OpenGLQtViewer::actionChangeBackgroundColor() {
1113 const QColor color =
1114 QColorDialog::getColor(Qt::black,
1116 " Get background color and transparency",
1117 QColorDialog::ShowAlphaChannel);
1118 if (color.isValid()) {
1119 G4Colour colour(((
G4double)color.red())/255,
1123 fVP.SetBackgroundColour(colour);
1130void G4OpenGLQtViewer::actionChangeTextColor() {
1131 const QColor& color =
1132 QColorDialog::getColor(Qt::yellow,
1134 " Get text color and transparency",
1135 QColorDialog::ShowAlphaChannel);
1136 if (color.isValid()) {
1137 G4Colour colour(((
G4double)color.red())/255,
1142 fVP.SetDefaultTextColour(colour);
1149void G4OpenGLQtViewer::actionChangeDefaultColor() {
1150 const QColor& color =
1151 QColorDialog::getColor(Qt::white,
1153 " Get default color and transparency",
1154 QColorDialog::ShowAlphaChannel);
1155 if (color.isValid()) {
1156 G4Colour colour(((
G4double)color.red())/255,
1161 fVP.SetDefaultColour(colour);
1169void G4OpenGLQtViewer::actionMovieParameters() {
1170 showMovieParametersDialog();
1174void G4OpenGLQtViewer::showMovieParametersDialog() {
1175 if (!fMovieParametersDialog) {
1176 fMovieParametersDialog=
new G4OpenGLQtMovieDialog(
this,
fGLWidget);
1178 fMovieParametersDialog->checkEncoderSwParameters();
1179 fMovieParametersDialog->checkSaveFileNameParameters();
1180 fMovieParametersDialog->checkTempFolderParameters();
1182 setRecordingInfos(
"ppmtompeg is needed to encode in video format. It is available here: http://netpbm.sourceforge.net ");
1185 fMovieParametersDialog->show();
1208 if (evnt->button() == Qt::RightButton) {
1211 if ((evnt->button() & Qt::LeftButton) && (! (evnt->modifiers() & Qt::ControlModifier ))){
1214 fLastPos1 = evnt->pos();
1215 fLastPos2 = fLastPos1;
1216 fLastPos3 = fLastPos2;
1217 fLastEventTime->start();
1218 if (
fUiQt != NULL) {
1220 if (
fUiQt->IsIconZoomInSelected()) {
1223 float deltaX = ((float)
getWinWidth()/2-evnt->pos().x());
1224 float deltaY = ((float)
getWinHeight()/2-evnt->pos().y());
1231 fVP.IncrementPan(-deltaX*coefTrans,deltaY*coefTrans,0);
1232 fVP.SetZoomFactor(1.5 *
fVP.GetZoomFactor());
1236 }
else if (
fUiQt->IsIconZoomOutSelected()) {
1240 fVP.SetZoomFactor(0.75 *
fVP.GetZoomFactor());
1243 }
else if (
fUiQt->IsIconRotateSelected() ) {
1245 if (fShiftKeyPress) {
1246 fGLWidget->setCursor(QCursor(Qt::SizeAllCursor));
1249 fGLWidget->setCursor(QCursor(Qt::ClosedHandCursor));
1251 }
else if (
fUiQt->IsIconMoveSelected()) {
1252 fGLWidget->setCursor(QCursor(Qt::SizeAllCursor));
1253 }
else if (
fUiQt->IsIconPickSelected()) {
1254 fGLWidget->setCursor(QCursor(Qt::PointingHandCursor));
1264#if QT_VERSION < 0x060000
1267 if (qGLW) qGLW->makeCurrent();}
1271 glGetIntegerv(GL_VIEWPORT, viewport);
1274 double factorX = ((double)viewport[2]/
fGLWidget->width());
1275 double factorY = ((double)viewport[3]/
fGLWidget->height());
1276 fSpinningDelay = (int)fLastEventTime->elapsed();
1277 QPoint delta = (fLastPos3-fLastPos1)*factorX;
1280 fGLWidget->setCursor(QCursor(Qt::ArrowCursor));
1282 if (
fVP.IsPicking()){
1283 if ((delta.x() != 0) || (delta.y() != 0) || (evnt->button() & Qt::RightButton)) {
1288 }
else if (fSpinningDelay < fLaunchSpinDelay ) {
1289 if ((delta.x() == 0) && (delta.y() == 0)) {
1294#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0))
1297 QElapsedTimer lastMoveTime;
1299 lastMoveTime.start();
1301 float correctionFactor = 5;
1303 if ( lastMoveTime.elapsed() >= (
int)(1000/fNbMaxFramesPerSec)) {
1304 float lTime = 1000.0f/lastMoveTime.elapsed();
1305 if (((((
float)delta.x())/correctionFactor)*lTime > fNbMaxAnglePerSec) ||
1306 ((((
float)delta.x())/correctionFactor)*lTime < -fNbMaxAnglePerSec) ) {
1307 correctionFactor = (float)delta.x()*(lTime/fNbMaxAnglePerSec);
1308 if (delta.x() <0 ) {
1309 correctionFactor = -correctionFactor;
1312 if (((((
float)delta.y())/correctionFactor)*lTime > fNbMaxAnglePerSec) ||
1313 ((((
float)delta.y())/correctionFactor)*lTime < -fNbMaxAnglePerSec) ) {
1314 correctionFactor = (float)delta.y()*(lTime/fNbMaxAnglePerSec);
1315 if (delta.y() <0 ) {
1316 correctionFactor = -correctionFactor;
1327 lastMoveTime.start();
1329 bool rotate =
false;
1332 if (
fUiQt != NULL) {
1333 if (
fUiQt->IsIconRotateSelected()) {
1335 }
else if (
fUiQt->IsIconMoveSelected()) {
1348 rotateQtScene(((
float)delta.x())/correctionFactor,((
float)delta.y())/correctionFactor);
1349 }
else if (fAltKeyPress) {
1350 rotateQtSceneToggle(((
float)delta.x())/correctionFactor,((
float)delta.y())/correctionFactor);
1354 moveScene(-((
float)delta.x())/correctionFactor,-((
float)delta.y())/correctionFactor,0,
true);
1381 Qt::MouseButtons mButtons = evnt->buttons();
1389 fLastPos3 = fLastPos2;
1390 fLastPos2 = fLastPos1;
1392#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
1393 fLastPos1 = QPoint(evnt->x(), evnt->y());
1395 fLastPos1 = QPoint(evnt->position().x(), evnt->position().y());
1398 int deltaX = fLastPos2.x()-fLastPos1.x();
1399 int deltaY = fLastPos2.y()-fLastPos1.y();
1402 if (
fUiQt != NULL) {
1403 if (
fUiQt->IsIconMoveSelected()) {
1408 if (mButtons & Qt::LeftButton) {
1411 }
else if (fAltKeyPress) {
1413 }
else if (fShiftKeyPress) {
1414 moveScene(-(
float)deltaX, -(
float)deltaY, 0,
true);
1415 }
else if (fControlKeyPress) {
1416 fVP.SetZoomFactor(
fVP.GetZoomFactor()*(1+((
float)deltaY)));
1420 if (mButtons & Qt::LeftButton) {
1421 moveScene(-(
float)deltaX,-(
float)deltaY,0,
true);
1425 fLastEventTime->start();
1440 fHoldMoveEvent =
true;
1443 GLdouble coefDepth = 0;
1445 if (
fVP.GetFieldHalfAngle() == 0.0) {
1454 if (radius <= 0.) radius = 1.;
1455 const G4double cameraDistance =
fVP.GetCameraDistance(radius);
1465 fVP.IncrementPan(-dx*coefTrans,dy*coefTrans,dz*coefDepth);
1471 fHoldMoveEvent =
false;
1482 if (fHoldRotateEvent)
1484 fHoldRotateEvent =
true;
1490 fHoldRotateEvent =
false;
1500 if (fHoldRotateEvent)
1502 fHoldRotateEvent =
true;
1508 fHoldRotateEvent =
false;
1531void G4OpenGLQtViewer::rescaleImage(
1553#if (QT_VERSION < QT_VERSION_CHECK(5, 15, 0))
1554 double delta = evnt->delta();
1556 double delta = evnt->angleDelta().y();
1559 ZoomFromMouseWheel(delta, evnt->modifiers() & Qt::ShiftModifier, evnt->position().x(), evnt->position().y());
1570 fHoldKeyEvent =
true;
1575 if ((fNoKeyPress) || (evnt->modifiers() == Qt::KeypadModifier )) {
1576 if (evnt->key() == Qt::Key_Down) {
1579 else if (evnt->key() == Qt::Key_Up) {
1582 if (evnt->key() == Qt::Key_Left) {
1585 else if (evnt->key() == Qt::Key_Right) {
1588 if (evnt->key() == Qt::Key_Minus) {
1591 else if (evnt->key() == Qt::Key_Plus) {
1595 if (evnt->key() == Qt::Key_Escape) {
1596 toggleFullScreen(
false);
1605 if ((evnt->key() == Qt::Key_Return) || (evnt->key() == Qt::Key_Enter)){
1608 if (evnt->key() == Qt::Key_Space){
1613 if (evnt->key() == Qt::Key_H){
1620 if (fShiftKeyPress) {
1621 fGLWidget->setCursor(QCursor(Qt::SizeAllCursor));
1623 if (evnt->key() == Qt::Key_Down) {
1626 else if (evnt->key() == Qt::Key_Up) {
1629 if (evnt->key() == Qt::Key_Left) {
1632 else if (evnt->key() == Qt::Key_Right) {
1635 if (evnt->key() == Qt::Key_Plus) {
1642 if ((fAltKeyPress)) {
1643 fGLWidget->setCursor(QCursor(Qt::ClosedHandCursor));
1645 if (evnt->key() == Qt::Key_Down) {
1648 else if (evnt->key() == Qt::Key_Up) {
1651 if (evnt->key() == Qt::Key_Left) {
1654 else if (evnt->key() == Qt::Key_Right) {
1659 if (evnt->key() == Qt::Key_Plus) {
1663 else if (evnt->key() == Qt::Key_Minus) {
1670 if ((fControlKeyPress)) {
1671 if (evnt->key() == Qt::Key_Plus) {
1672 fVP.SetZoomFactor(
fVP.GetZoomFactor()*(1+fDeltaZoom));
1675 else if (evnt->key() == Qt::Key_Minus) {
1676 fVP.SetZoomFactor(
fVP.GetZoomFactor()*(1-fDeltaZoom));
1681 fHoldKeyEvent =
false;
1687 fGLWidget->setCursor(QCursor(Qt::ArrowCursor));
1695 fAltKeyPress =
false;
1696 fShiftKeyPress =
false;
1697 fControlKeyPress =
false;
1699 if (modifier & Qt::AltModifier ) {
1700 fAltKeyPress =
true;
1701 fNoKeyPress =
false;
1703 if (modifier & Qt::ShiftModifier ) {
1704 fShiftKeyPress =
true;
1705 fNoKeyPress =
false;
1707 if (modifier & Qt::ControlModifier ) {
1708 fControlKeyPress =
true;
1709 fNoKeyPress =
false;
1719 if (!fMovieParametersDialog) {
1720 showMovieParametersDialog();
1722 setRecordingStatus(STOP);
1726 if (!(fMovieParametersDialog->checkEncoderSwParameters())) {
1727 setRecordingStatus(BAD_ENCODER);
1728 }
else if (!(fMovieParametersDialog->checkSaveFileNameParameters())) {
1729 setRecordingStatus(BAD_OUTPUT);
1733 setRecordingInfos(
"No frame to encode.");
1742 if (!fMovieParametersDialog) {
1743 showMovieParametersDialog();
1746 fMovieParametersDialog->checkEncoderSwParameters();
1747 fMovieParametersDialog->checkSaveFileNameParameters();
1749 if (fRecordingStep == STOP) {
1750 setRecordingStatus(SAVE);
1763 if ( fRecordingStep == WAIT) {
1766 showMovieParametersDialog();
1767 setRecordingInfos(
"You should specified the temp folder in order to make movie");
1771 QString tmp = removeTempFolder();
1773 setRecordingInfos(tmp);
1776 tmp = createTempFolder();
1778 setRecordingInfos(
"Can't create temp folder."+tmp);
1784 if (fRecordingStep == WAIT) {
1785 setRecordingStatus(START);
1786 }
else if (fRecordingStep == START) {
1787 setRecordingStatus(PAUSE);
1788 }
else if (fRecordingStep == PAUSE) {
1789 setRecordingStatus(CONTINUE);
1790 }
else if (fRecordingStep == CONTINUE) {
1791 setRecordingStatus(PAUSE);
1795void G4OpenGLQtViewer::setRecordingStatus(RECORDING_STEP step) {
1797 fRecordingStep = step;
1804 QString txtStatus =
"";
1805 if (fRecordingStep == WAIT) {
1806 txtStatus =
"Waiting to start...";
1808 }
else if (fRecordingStep == START) {
1809 txtStatus =
"Start Recording...";
1810 }
else if (fRecordingStep == PAUSE) {
1811 txtStatus =
"Pause Recording...";
1812 }
else if (fRecordingStep == CONTINUE) {
1813 txtStatus =
"Continue Recording...";
1814 }
else if (fRecordingStep == STOP) {
1815 txtStatus =
"Stop Recording...";
1816 }
else if (fRecordingStep == READY_TO_ENCODE) {
1817 txtStatus =
"Ready to Encode...";
1818 }
else if (fRecordingStep == ENCODING) {
1819 txtStatus =
"Encoding...";
1820 }
else if (fRecordingStep == FAILED) {
1821 txtStatus =
"Failed to encode...";
1822 }
else if ((fRecordingStep == BAD_ENCODER)
1823 || (fRecordingStep == BAD_OUTPUT)
1824 || (fRecordingStep == BAD_TMP)) {
1825 txtStatus =
"Correct above errors first";
1826 }
else if (fRecordingStep == SUCCESS) {
1827 txtStatus =
"File encoded successfully";
1831 if (fMovieParametersDialog) {
1832 fMovieParametersDialog->setRecordingStatus(txtStatus);
1836 setRecordingInfos(
"");
1840void G4OpenGLQtViewer::setRecordingInfos(
const QString& txt) {
1841 if (fMovieParametersDialog) {
1850void G4OpenGLQtViewer::initMovieParameters() {
1854 fProcess =
new QProcess();
1856 QObject ::connect(fProcess,SIGNAL(finished (
int)),
1857 this,SLOT(processLookForFinished()));
1858 fProcess->setProcessChannelMode(QProcess::MergedChannels);
1859#if (QT_VERSION < QT_VERSION_CHECK(5, 15, 0))
1860 fProcess->start (
"which ppmtompeg");
1862 fProcess->start (
"which ppmtompeg", QStringList());
1869 return fEncoderPath;
1879 return "ppmtompeg is needed to encode in video format. It is available here: http://netpbm.sourceforge.net ";
1882 path = QDir::cleanPath(path);
1883 QFileInfo *f =
new QFileInfo(path);
1885 return "File does not exist";
1886 }
else if (f->isDir()) {
1887 return "This is a directory";
1888 }
else if (!f->isExecutable()) {
1889 return "File exist but is not executable";
1890 }
else if (!f->isFile()) {
1891 return "This is not a file";
1893 fEncoderPath = path;
1895 if (fRecordingStep == BAD_ENCODER) {
1896 setRecordingStatus(STOP);
1903 if ((fRecordingStep == START) || (fRecordingStep == CONTINUE)) {
1910 if (fRecordingStep == PAUSE) {
1917 if (fRecordingStep == ENCODING) {
1924 if (fRecordingStep == WAIT) {
1931 if (fRecordingStep == STOP) {
1938 if (fRecordingStep == FAILED) {
1945 if (fRecordingStep == SUCCESS) {
1952 if (fRecordingStep == BAD_ENCODER) {
1958 if (fRecordingStep == BAD_TMP) {
1964 if (fRecordingStep == BAD_OUTPUT) {
1971 fRecordingStep = BAD_ENCODER;
1975 fRecordingStep = BAD_TMP;
1979 fRecordingStep = BAD_OUTPUT;
1984 fRecordingStep = WAIT;
1990 if (fRecordingStep == READY_TO_ENCODE) {
1997 setRecordingStatus(WAIT);
2007 return "Path does not exist";
2009 path = QDir::cleanPath(path);
2010 QFileInfo *d =
new QFileInfo(path);
2012 return "Path does not exist";
2013 }
else if (!d->isDir()) {
2014 return "This is not a directory";
2015 }
else if (!d->isReadable()) {
2016 return path +
" is read protected";
2017 }
else if (!d->isWritable()) {
2018 return path +
" is write protected";
2021 if (fRecordingStep == BAD_TMP) {
2022 setRecordingStatus(WAIT);
2024 fTempFolderPath = path;
2031 return fTempFolderPath;
2041 return "Path does not exist";
2044 QFileInfo *file =
new QFileInfo(path);
2045 QDir dir = file->dir();
2046 path = QDir::cleanPath(path);
2047 if (file->exists()) {
2048 return "File already exist, please choose a new one";
2049 }
else if (!dir.exists()) {
2050 return "Dir does not exist";
2051 }
else if (!dir.isReadable()) {
2052 return path +
" is read protected";
2055 if (fRecordingStep == BAD_OUTPUT) {
2056 setRecordingStatus(STOP);
2058 fSaveFileName = path;
2065 return fSaveFileName ;
2072QString G4OpenGLQtViewer::createTempFolder() {
2073 fMovieTempFolderPath =
"";
2079 QString sep = QString(QDir::separator());
2080 QString path = sep+
"QtMovie_"+QDateTime::currentDateTime ().toString(
"dd-MM-yyyy_hh-mm-ss")+sep;
2081 QDir *d =
new QDir(QDir::cleanPath(fTempFolderPath));
2083 if (d->exists(path)) {
2084 return "Folder "+path+
" already exists.Please remove it first";
2086 if (d->mkdir(fTempFolderPath+path)) {
2087 fMovieTempFolderPath = fTempFolderPath+path;
2090 return "Can't create "+fTempFolderPath+path;
2095QString G4OpenGLQtViewer::removeTempFolder() {
2097 if (fMovieTempFolderPath ==
"") {
2100 QDir *d =
new QDir(QDir::cleanPath(fMovieTempFolderPath));
2105 d->setFilter( QDir::Files );
2106 QStringList subDirList = d->entryList();
2109 for (QStringList::ConstIterator it = subDirList.begin() ;(it != subDirList.end()) ; it++) {
2110 const QString currentFile = *it;
2111 if (!d->remove(currentFile)) {
2113 QString file = fMovieTempFolderPath+currentFile;
2114 error +=
"Removing file failed : "+file;
2119 if (d->rmdir(fMovieTempFolderPath)) {
2120 fMovieTempFolderPath =
"";
2123 return "Dir "+fMovieTempFolderPath+
" should be empty, but could not remove it";
2127 return "Could not remove "+fMovieTempFolderPath+
" because of the following errors :"+error;
2144 bool increaseFileNumber =
true;
2146 if (name.size() != name.substr(name.find_last_of(
".") + 1).size()) {
2147 increaseFileNumber =
false;
2152 if ((width !=-1) && (height != -1)) {
2162#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
2163 image = qGLW->grabFrameBuffer();
2165 image = qGLW->grabFramebuffer();
2185 fp = fopen (QString(fMovieTempFolderPath+fParameterFileName).toStdString().c_str(),
"w");
2188 setRecordingInfos(
"Generation of parameter file failed");
2192 fprintf (fp,
"# Pattern affects speed, quality and compression. See the User's Guide\n");
2193 fprintf (fp,
"# for more info.\n");
2195 fprintf (fp,
"PATTERN I\n");
2198 fprintf (fp,
"# You must specify the type of the input files. The choices are:\n");
2199 fprintf (fp,
"# YUV, PPM, JMOVIE, Y, JPEG, PNM\n");
2200 fprintf (fp,
"# (must be upper case)\n");
2202 fprintf (fp,
"BASE_FILE_FORMAT PPM\n");
2205 fprintf (fp,
"# If you are using YUV, there are different supported file formats.\n");
2206 fprintf (fp,
"# EYUV or UCB are the same as previous versions of this encoder.\n");
2207 fprintf (fp,
"# (All the Y's, then U's then V's, in 4:2:0 subsampling.)\n");
2208 fprintf (fp,
"# Other formats, such as Abekas, Phillips, or a general format are\n");
2209 fprintf (fp,
"# permissible, the general format is a string of Y's, U's, and V's\n");
2210 fprintf (fp,
"# to specify the file order.\n");
2212 fprintf (fp,
"INPUT_FORMAT UCB\n");
2214 fprintf (fp,
"# the conversion statement\n");
2216 fprintf (fp,
"# Each occurrence of '*' will be replaced by the input file\n");
2218 fprintf (fp,
"# e.g., if you have a bunch of GIF files, then this might be:\n");
2219 fprintf (fp,
"# INPUT_CONVERT giftoppm *\n");
2221 fprintf (fp,
"# e.g., if you have a bunch of files like a.Y a.U a.V, etc., then:\n");
2222 fprintf (fp,
"# INPUT_CONVERT cat *.Y *.U *.V\n");
2224 fprintf (fp,
"# e.g., if you are grabbing from laser disc you might have something like\n");
2225 fprintf (fp,
"# INPUT_CONVERT goto frame *; grabppm\n");
2226 fprintf (fp,
"# 'INPUT_CONVERT *' means the files are already in the base file format\n");
2228 fprintf (fp,
"INPUT_CONVERT * \n");
2230 fprintf (fp,
"# number of frames in a GOP.\n");
2232 fprintf (fp,
"# since each GOP must have at least one I-frame, the encoder will find the\n");
2233 fprintf (fp,
"# the first I-frame after GOP_SIZE frames to start the next GOP\n");
2235 fprintf (fp,
"# later, will add more flexible GOP signalling\n");
2237 fprintf (fp,
"GOP_SIZE 1\n");
2239 fprintf (fp,
"# number of slices in a frame\n");
2241 fprintf (fp,
"# 1 is a good number. another possibility is the number of macroblock rows\n");
2242 fprintf (fp,
"# (which is the height divided by 16)\n");
2244 fprintf (fp,
"SLICES_PER_FRAME 1\n");
2245 fprintf (fp,
"PIXEL HALF");
2247 fprintf (fp,
"# directory to get all input files from (makes this file easier to read)\n");
2248 fprintf (fp,
"INPUT_DIR %s\n",fMovieTempFolderPath.toStdString().c_str());
2250 fprintf (fp,
"# There are a bunch of ways to specify the input files.\n");
2251 fprintf (fp,
"# from a simple one-per-line listing, to the following \n");
2252 fprintf (fp,
"# way of numbering them. See the manual for more information.\n");
2253 fprintf (fp,
"INPUT\n");
2254 fprintf (fp,
"# '*' is replaced by the numbers 01, 02, 03, 04\n");
2255 fprintf (fp,
"# if I instead do [01-11], it would be 01, 02, ..., 09, 10, 11\n");
2256 fprintf (fp,
"# if I instead do [1-11], it would be 1, 2, 3, ..., 9, 10, 11\n");
2257 fprintf (fp,
"# if I instead do [1-11+3], it would be 1, 4, 7, 10\n");
2258 fprintf (fp,
"# the program assumes none of your input files has a name ending in ']'\n");
2259 fprintf (fp,
"# if you do, too bad!!!\n");
2263 fprintf (fp,
"# can have more files here if you want...there is no limit on the number\n");
2264 fprintf (fp,
"# of files\n");
2265 fprintf (fp,
"END_INPUT\n");
2269 fprintf (fp,
"# Many of the remaining options have to do with the motion search and qscale\n");
2271 fprintf (fp,
"# FULL or HALF -- must be upper case\n");
2272 fprintf (fp,
"# Should be FULL for computer generated images\n");
2273 fprintf (fp,
"PIXEL FULL\n");
2275 fprintf (fp,
"# means +/- this many pixels for both P and B frame searches\n");
2276 fprintf (fp,
"# specify two numbers if you wish to serc different ranges in the two.\n");
2277 fprintf (fp,
"RANGE 10\n");
2279 fprintf (fp,
"# The two search algorithm parameters below mostly affect speed,\n");
2280 fprintf (fp,
"# with some affect on compression and almost none on quality.\n");
2282 fprintf (fp,
"# this must be one of {EXHAUSTIVE, SUBSAMPLE, LOGARITHMIC}\n");
2283 fprintf (fp,
"PSEARCH_ALG LOGARITHMIC\n");
2285 fprintf (fp,
"# this must be one of {SIMPLE, CROSS2, EXHAUSTIVE}\n");
2287 fprintf (fp,
"# note that EXHAUSTIVE is really, really, really slow\n");
2289 fprintf (fp,
"BSEARCH_ALG SIMPLE\n");
2292 fprintf (fp,
"# these specify the q-scale for I, P, and B frames\n");
2293 fprintf (fp,
"# (values must be between 1 and 31)\n");
2294 fprintf (fp,
"# These are the Qscale values for the entire frame in variable bit-rate\n");
2295 fprintf (fp,
"# mode, and starting points (but not important) for constant bit rate\n");
2298 fprintf (fp,
"# Qscale (Quantization scale) affects quality and compression,\n");
2299 fprintf (fp,
"# but has very little effect on speed.\n");
2301 fprintf (fp,
"IQSCALE 4\n");
2302 fprintf (fp,
"PQSCALE 5\n");
2303 fprintf (fp,
"BQSCALE 12\n");
2305 fprintf (fp,
"# this must be ORIGINAL or DECODED\n");
2306 fprintf (fp,
"REFERENCE_FRAME ORIGINAL\n");
2308 fprintf (fp,
"# for parallel parameters see parallel.param in the examples subdirectory\n");
2310 fprintf (fp,
"# if you want constant bit-rate mode, specify it as follows (number is bits/sec):\n");
2311 fprintf (fp,
"#BIT_RATE 1000000\n");
2313 fprintf (fp,
"# To specify the buffer size (327680 is default, measused in bits, for 16bit words)\n");
2314 fprintf (fp,
"BUFFER_SIZE 327680\n");
2316 fprintf (fp,
"# The frame rate is the number of frames/second (legal values:\n");
2317 fprintf (fp,
"# 23.976, 24, 25, 29.97, 30, 50 ,59.94, 60\n");
2318 fprintf (fp,
"FRAME_RATE 30\n");
2320 fprintf (fp,
"# There are many more options, see the users manual for examples....\n");
2321 fprintf (fp,
"# ASPECT_RATIO, USER_DATA, GAMMA, IQTABLE, etc.\n");
2326 setRecordingInfos(
"Parameter file "+fParameterFileName+
" generated in "+fMovieTempFolderPath);
2327 setRecordingStatus(READY_TO_ENCODE);
2334 setRecordingStatus(ENCODING);
2336 fProcess =
new QProcess();
2337 QObject ::connect(fProcess,SIGNAL(finished (
int,QProcess::ExitStatus)),
2338 this,SLOT(processEncodeFinished()));
2339 QObject ::connect(fProcess,SIGNAL(readyReadStandardOutput ()),
2340 this,SLOT(processEncodeStdout()));
2341#if (QT_VERSION < QT_VERSION_CHECK(5, 10, 0))
2342 fProcess->setReadChannelMode(QProcess::MergedChannels);
2344 fProcess->setProcessChannelMode(QProcess::MergedChannels);
2346 fProcess->start (fEncoderPath, QStringList(fMovieTempFolderPath+fParameterFileName));
2352void G4OpenGLQtViewer::processEncodeStdout()
2354 QString tmp = fProcess->readAllStandardOutput ().data();
2355 auto start = tmp.lastIndexOf(
"ESTIMATED TIME");
2356 tmp = tmp.mid(start,tmp.indexOf(
"\n",start)-start);
2357 setRecordingInfos(tmp);
2361void G4OpenGLQtViewer::processEncodeFinished()
2365 txt = getProcessErrorMsg();
2367 setRecordingStatus(SUCCESS);
2369 setRecordingStatus(FAILED);
2375void G4OpenGLQtViewer::processLookForFinished()
2378 QString txt = getProcessErrorMsg();
2382 fEncoderPath = QString(fProcess->readAllStandardOutput ().data()).trimmed();
2384 if (fEncoderPath.contains(
" ")) {
2386 }
else if (!fEncoderPath.contains(
"ppmtompeg")) {
2396QString G4OpenGLQtViewer::getProcessErrorMsg()
2399 if (fProcess->exitCode() != 0) {
2400 switch (fProcess->error()) {
2401 case QProcess::FailedToStart:
2402 txt =
"The process failed to start. Either the invoked program is missing, or you may have insufficient permissions to invoke the program.\n";
2404 case QProcess::Crashed:
2405 txt =
"The process crashed some time after starting successfully.\n";
2407 case QProcess::Timedout:
2408 txt =
"The last waitFor...() function timed out. The state of QProcess is unchanged, and you can try calling waitFor...() again.\n";
2410 case QProcess::WriteError:
2411 txt =
"An error occurred when attempting to write to the process. For example, the process may not be running, or it may have closed its input channel.\n";
2413 case QProcess::ReadError:
2414 txt =
"An error occurred when attempting to read from the process. For example, the process may not be running.\n";
2416 case QProcess::UnknownError:
2417 txt =
"An unknown error occurred. This is the default return value of error().\n";
2427QWidget *G4OpenGLQtViewer::getParentWidget()
2433 QDialog* dialog = NULL;
2437 QWidgetList wl = QApplication::allWidgets();
2438 QWidget *widget = NULL;
2439 for (
int i=0; i < wl.size(); i++) {
2441 if ((found==
false) && (widget->inherits(
"QMainWindow"))) {
2442 dialog =
new QDialog(widget,Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint);
2448 dialog =
new QDialog();
2451 dialog=
new QDialog();
2461void G4OpenGLQtViewer::createSceneTreeWidget() {
2462 fUISceneTreeWidget =
fUiQt->GetSceneTreeWidget();
2464 if (!fUISceneTreeWidget) {
2469 QLayoutItem * wItem;
2471 if (fUISceneTreeWidget->layout()->count() ) {
2472 for(
int idx = 0; idx < fUISceneTreeWidget->layout()->count(); idx++){
2473 wItem = fUISceneTreeWidget->layout()->itemAt(idx);
2474 if (fSceneTreeWidget) {
2475 if(
dynamic_cast<QWidget *
>(wItem->widget())) {
2476 if (wItem->widget()->windowTitle() == fSceneTreeWidget->windowTitle()) {
2477 wItem->widget()->show();
2480 wItem->widget()->hide();
2491 fSceneTreeWidget =
new QWidget();
2492 QVBoxLayout* layoutSceneTree =
new QVBoxLayout();
2493 fSceneTreeWidget->setStyleSheet (
"padding: 0px ");
2495 fSceneTreeWidget->setLayout(layoutSceneTree);
2496 fSceneTreeWidget->layout()->setContentsMargins(5,5,5,5);
2497 fSceneTreeWidget->setWindowTitle(QString(
GetName().data()));
2499 if (fUISceneTreeWidget != NULL) {
2504 if (
dynamic_cast<G4OpenGLStoredQtViewer*
> (
this)) {
2505 createSceneTreeComponent();
2511void G4OpenGLQtViewer::createSceneTreeComponent(){
2513 QLayout* vLayout = fSceneTreeWidget->layout();
2516 QWidget* coutButtonWidget =
new QWidget();
2517 QHBoxLayout* layoutCoutTBButtons =
new QHBoxLayout();
2519 fFilterOutput =
new QLineEdit();
2520 fFilterOutput->setToolTip(
"Filter output by...");
2521 fFilterOutput->setStyleSheet (
"padding: 0px ");
2523 QPixmap* searchIcon =
fUiQt->getSearchIcon();
2524 fFilterOutput->addAction(*searchIcon,QLineEdit::TrailingPosition);
2525 fFilterOutput->setStyleSheet (
"border-radius:7px;");
2526 layoutCoutTBButtons->addWidget(fFilterOutput);
2528 coutButtonWidget->setLayout(layoutCoutTBButtons);
2529 vLayout->addWidget(coutButtonWidget);
2532 vLayout->setContentsMargins(0,0,0,0);
2535 fSceneTreeComponentTreeWidget =
new QTreeWidget();
2536 fSceneTreeComponentTreeWidget->setSelectionMode(QAbstractItemView::SingleSelection);
2537 fSceneTreeComponentTreeWidget->setHeaderLabel (
"Scene tree : "+QString(
GetName().data()));
2538 fSceneTreeComponentTreeWidget->setColumnHidden (1,
true);
2539 fSceneTreeComponentTreeWidget->setColumnHidden (2,
true);
2540 fSceneTreeComponentTreeWidget->setColumnHidden (3,
true);
2545 vLayout->addWidget(fSceneTreeComponentTreeWidget);
2547 connect(fSceneTreeComponentTreeWidget,SIGNAL(itemChanged(QTreeWidgetItem*,
int)),SLOT(sceneTreeComponentItemChanged(QTreeWidgetItem*,
int)));
2548 connect(fSceneTreeComponentTreeWidget,SIGNAL(itemSelectionChanged ()),SLOT(sceneTreeComponentSelected()));
2549 connect(fSceneTreeComponentTreeWidget,SIGNAL(itemDoubleClicked ( QTreeWidgetItem*,
int)),SLOT(changeColorAndTransparency( QTreeWidgetItem*,
int)));
2553 QWidget *helpWidget =
new QWidget();
2554 QHBoxLayout *helpLayout =
new QHBoxLayout();
2556 QWidget* depthWidget =
new QWidget();
2557 QWidget *showBox =
new QWidget(depthWidget);
2558 QHBoxLayout *showBoxLayout =
new QHBoxLayout();
2561 showBoxLayout->setContentsMargins(5,5,5,5);
2563 QLabel *zero =
new QLabel();
2564 zero->setText(
"Show all");
2565 QLabel *one =
new QLabel();
2566 one->setText(
"Hide all");
2567 fSceneTreeDepthSlider =
new QSlider ( Qt::Horizontal);
2568 fSceneTreeDepthSlider->setMaximum (1000);
2569 fSceneTreeDepthSlider->setMinimum (0);
2570 fSceneTreeDepthSlider->setTickPosition(QSlider::TicksAbove);
2572 fSceneTreeDepthSlider->setMinimumWidth (40);
2574 showBoxLayout->addWidget(zero);
2575 showBoxLayout->addWidget(fSceneTreeDepthSlider);
2576 showBoxLayout->addWidget(one);
2578 showBox->setLayout(showBoxLayout);
2580 helpLayout->addWidget(showBox);
2581 helpWidget->setLayout(helpLayout);
2582 helpLayout->setContentsMargins(0,0,0,0);
2584 vLayout->addWidget(helpWidget);
2586 connect( fSceneTreeDepthSlider, SIGNAL( valueChanged(
int) ),
this, SLOT( changeDepthInSceneTree(
int) ) );
2587 connect( fFilterOutput, SIGNAL( textEdited (
const QString &) ),
this, SLOT(changeSearchSelection()));
2588 fTreeItemModels.clear();
2590 fPVRootNodeCreate =
false;
2592 fMaxPOindexInserted = -1;
2598void G4OpenGLQtViewer::createViewerPropertiesWidget() {
2601 fUIViewerPropertiesWidget =
fUiQt->GetViewerPropertiesWidget();
2603 if (!fUIViewerPropertiesWidget) {
2608 QLayoutItem * wItem;
2609 if (fUIViewerPropertiesWidget->layout()->count()) {
2610 while ((wItem = fUIViewerPropertiesWidget->layout()->takeAt(0)) != 0) {
2611 delete wItem->widget();
2617 QGroupBox *groupBox =
new QGroupBox();
2618 groupBox->setTitle(
GetName().data());
2619 QVBoxLayout *vbox =
new QVBoxLayout;
2622 fViewerPropertiesTableWidget =
new QTableWidget();
2624 QSizePolicy vPolicy = fViewerPropertiesTableWidget->sizePolicy();
2625 vPolicy.setVerticalStretch(4);
2627 vbox->addWidget(fViewerPropertiesTableWidget);
2628 groupBox->setLayout(vbox);
2629 fUIViewerPropertiesWidget->layout()->addWidget(groupBox);
2631 connect(fViewerPropertiesTableWidget, SIGNAL(itemChanged(QTableWidgetItem*)),
this, SLOT(tableWidgetViewerSetItemChanged(QTableWidgetItem *)));
2635 QDialog* dial =
static_cast<QDialog*
> (fUIViewerPropertiesWidget->parent());
2638 dial->setWindowTitle(QString(
"Viewer properties - ")+
GetName());
2643void G4OpenGLQtViewer::createPickInfosWidget(){
2646 fUIPickInfosWidget =
fUiQt->GetPickInfosWidget();
2648 if (!fUIPickInfosWidget) {
2653 QLayoutItem * wItem;
2654 if (fUIPickInfosWidget->layout()->count()) {
2655 while ((wItem = fUIPickInfosWidget->layout()->takeAt(0)) != 0) {
2656 delete wItem->widget();
2661 QGroupBox *groupBox =
new QGroupBox(
"");
2662 QVBoxLayout *vbox =
new QVBoxLayout;
2665 QWidget *pickingInfoWidget =
new QWidget();
2666 QHBoxLayout *pickingInfoLayout =
new QHBoxLayout();
2668 pickingInfoWidget->setStyleSheet (
"padding-left: 0px; border:0px;");
2669 pickingInfoWidget->setLayout(pickingInfoLayout);
2671 vbox->addWidget(pickingInfoWidget);
2674 fPickInfosScrollArea =
new QScrollArea();
2675 fPickInfosScrollArea->setWidgetResizable(
true);
2678 fPickInfosWidget =
new QWidget();
2679 fPickInfosWidget->setStyleSheet (
"padding: 0px ");
2681 QVBoxLayout* vLayout =
new QVBoxLayout();
2682 fPickInfosWidget->setLayout (vLayout);
2683 fPickInfosScrollArea->setWidget(fPickInfosWidget);
2685 QSizePolicy vPolicy = fPickInfosWidget->sizePolicy();
2686 vPolicy.setVerticalStretch(4);
2687 vbox->addWidget(fPickInfosScrollArea);
2688 pickingInfoLayout->setContentsMargins(0,0,0,0);
2689 vLayout->setContentsMargins(0,0,0,0);
2690 vbox->setContentsMargins(1,1,1,1);
2692 groupBox->setLayout(vbox);
2693 fUIPickInfosWidget->layout()->addWidget(groupBox);
2701void G4OpenGLQtViewer::setCheckComponent(QTreeWidgetItem* item,
bool check)
2705 const PVPath& fullPath = fTreeItemModels[item->data(0,Qt::UserRole).toInt()];
2707 if (fullPath.size() > 0) {
2714 item->setCheckState(0,Qt::Checked);
2716 item->setCheckState(0,Qt::Unchecked);
2718 updatePositivePoIndexSceneTreeWidgetQuickMap(item->data(0,Qt::UserRole).toInt(),item);
2719 int nChildCount = item->childCount();
2720 for (
int i = 0; i < nChildCount; i++) {
2721 setCheckComponent(item->child(i),check);
2726#if QT_VERSION < 0x060000
2729static void transform_point(GLdouble out[4],
const GLdouble model[16],
const GLdouble in[4])
2731#define M(row,col) model[col*4+row]
2733 M(0, 0) * in[0] +
M(0, 1) * in[1] +
M(0, 2) * in[2] +
M(0, 3) * in[3];
2735 M(1, 0) * in[0] +
M(1, 1) * in[1] +
M(1, 2) * in[2] +
M(1, 3) * in[3];
2737 M(2, 0) * in[0] +
M(2, 1) * in[1] +
M(2, 2) * in[2] +
M(2, 3) * in[3];
2739 M(3, 0) * in[0] +
M(3, 1) * in[1] +
M(3, 2) * in[2] +
M(3, 3) * in[3];
2742inline GLint project_point(GLdouble objx, GLdouble objy, GLdouble objz,
2743 const GLdouble model[16],
const GLdouble proj[16],
2744 const GLint viewport[4],
2745 GLdouble * winx, GLdouble * winy, GLdouble * winz)
2747 GLdouble in[4], out[4];
2753 transform_point(out, model, in);
2754 transform_point(in, proj, out);
2763 *winx = viewport[0] + (1 + in[0]) * viewport[2] / 2;
2764 *winy = viewport[1] + (1 + in[1]) * viewport[3] / 2;
2766 *winz = (1 + in[2]) / 2;
2769static void render_text(QOpenGLWidget& widget,
2770 double world_x,
double world_y,
double world_z,
2771 double offset_x,
double offset_y,
2773 const QColor& color,
2776 GLdouble model[4][4];
2777 glGetDoublev(GL_MODELVIEW_MATRIX, &model[0][0]);
2778 GLdouble proj[4][4];
2779 glGetDoublev(GL_PROJECTION_MATRIX, &proj[0][0]);
2781 glGetIntegerv(GL_VIEWPORT, &view[0]);
2783 GLdouble textPosX = 0, textPosY = 0, textPosZ = 0;
2784 project_point(world_x, world_y, world_z,
2785 &model[0][0], &proj[0][0], &view[0],
2786 &textPosX, &textPosY, &textPosZ);
2788 textPosX /= GLdouble(widget.devicePixelRatio());
2789 textPosY /= GLdouble(widget.devicePixelRatio());
2791 textPosY = GLdouble(widget.height()) - textPosY;
2793 textPosX += offset_x;
2794 textPosY += offset_y;
2796 GLboolean GL_BLEND_enabled = glIsEnabled(GL_BLEND);
2798 QPainter painter(&widget);
2799 painter.setPen(color);
2800 painter.setFont(font);
2801 painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
2802 painter.drawText(textPosX, textPosY, text);
2805 if(GL_BLEND_enabled==GL_TRUE) {
2806 ::glEnable(GL_BLEND);
2807 ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2831 QFont font = QFont();
2832 font.setPointSizeF(size);
2839 const char* textCString = textString.c_str();
2842 QFontMetrics f(font);
2843 G4double span = f.boundingRect(textCString).width();
2858#if QT_VERSION < 0x060000
2867 xmove *= fudgeFactor;
2868 ymove *= fudgeFactor;
2876 QColor color((
int)(c.
GetRed()*255),
2883 font,color,textCString);
2900 const QString& modelShortName = getModelShortName(model);
2902 if (modelShortName ==
"") {
2906 if (fSceneTreeComponentTreeWidget == NULL) {
2907 createSceneTreeComponent();
2911 if (fSceneTreeComponentTreeWidget == NULL) {
2915 fSceneTreeComponentTreeWidget->blockSignals(
true);
2919 if (!fPVRootNodeCreate) {
2922 fModelShortNameItem = createTreeWidgetItem(pPVModel->
GetFullPVPath(),
2930 fPVRootNodeCreate =
true;
2933 bool added = parseAndInsertInSceneTree(fModelShortNameItem,pPVModel,0,modelShortName,0,currentPOIndex);
2937 fSceneTreeComponentTreeWidget->blockSignals(
false);
2946QTreeWidgetItem* G4OpenGLQtViewer::createTreeWidgetItem(
2947 const PVPath& fullPath
2948 ,
const QString& name
2951 ,
const QString& logicalName
2952 ,Qt::CheckState state
2953 ,QTreeWidgetItem * parentTreeNode
2958 if (fullPath.size() > fSceneTreeDepth) {
2959 fSceneTreeDepth = (
unsigned int)fullPath.size();
2961 if (fSceneTreeDepthSlider) {
2962 fSceneTreeDepthSlider->setTickInterval(1000/(fSceneTreeDepth+1));
2965 QTreeWidgetItem * newItem = NULL;
2966 if (parentTreeNode == NULL) {
2967 newItem =
new QTreeWidgetItem();
2968 fSceneTreeComponentTreeWidget->addTopLevelItem(newItem);
2970 newItem =
new QTreeWidgetItem(parentTreeNode);
2971 fSceneTreeComponentTreeWidget->addTopLevelItem(parentTreeNode);
2975 newItem->setText(0,name);
2976 newItem->setData(1,Qt::UserRole,copyNb);
2977 newItem->setText(2,QString::number(POIndex));
2978 newItem->setData(0, Qt::UserRole, POIndex);
2979 newItem->setText(3,logicalName);
2980 newItem->setFlags(newItem->flags()|Qt::ItemIsUserCheckable);
2981 newItem->setCheckState(0,state);
2982 newItem->setExpanded(
true);
2983 updatePositivePoIndexSceneTreeWidgetQuickMap(POIndex,newItem);
2985 changeQColorForTreeWidgetItem(newItem,QColor((
int)(color.
GetRed()*255),
2991 if ((state == Qt::Unchecked) && (POIndex == -1)) {
2992 newItem->setForeground (0, QBrush( Qt::gray) );
2995 newItem->setToolTip (0,QString(
2996 "This node exists in the geometry but has not been\n")+
2997 "drawn, perhaps because it has been set invisible. It \n"+
2998 "cannot be made visible with a click on the button.\n"+
2999 "To see it, change the visibility, for example, with \n"+
3000 "/vis/geometry/set/visibility " + logicalName +
" 0 true\n"+
3001 "and rebuild the view with /vis/viewer/rebuild.\n"+
3002 "Click here will only show/hide all child components");
3005 newItem->setToolTip (0,QString(
"double-click to change the color"));
3011 state = Qt::Unchecked;
3012 newItem->setCheckState(0,state);
3013 updatePositivePoIndexSceneTreeWidgetQuickMap(POIndex,newItem);
3016 fTreeItemModels.insert(std::pair <int, PVPath > (POIndex,fullPath) );
3020 changeOpenCloseVisibleHiddenSelectedColorSceneTreeElement(newItem);
3037bool G4OpenGLQtViewer::parseAndInsertInSceneTree(
3038 QTreeWidgetItem * parentItem
3040 ,
unsigned int fullPathIndex
3041 ,
const QString& parentRoot
3042 ,
unsigned int currentIndexInTreeSceneHandler
3043 ,
int currentPVPOIndex
3046 if (parentItem == NULL) {
3052 std::ostringstream oss;
3053 oss << fullPath.at(fullPathIndex).GetCopyNo();
3054 std::string currentPVName = G4String(fullPath.at(fullPathIndex).GetPhysicalVolume()->GetName()+
" ["+oss.str()+
"]").data();
3056 int currentPVCopyNb = fullPath.at(fullPathIndex).GetCopyNo();
3066 QTreeWidgetItem* subItem = NULL;
3067 QList<QTreeWidgetItem *> parentItemList;
3075 if ((currentIndexInTreeSceneHandler == (fullPath.size()-1)) && ((color.
GetAlpha() == 1.))) {
3077 QString lookForString = QString(currentPVName.c_str());
3078 for (
int i = 0;i < parentItem->childCount(); i++ ) {
3079 if (parentItem->child(i)->text(0) == lookForString) {
3080 parentItemList.push_back(parentItem->child(i));
3085 for (
int i = 0; i < parentItemList.size(); ++i) {
3086 const std::string& parentItemName = parentItemList.at(i)->text(0).toStdString();
3087 int parentItemCopyNb = parentItemList.at(i)->data(1,Qt::UserRole).toInt();
3088 int parentItemPOIndex = parentItemList.at(i)->data(0,Qt::UserRole).toInt();
3096 if (((parentRoot == fTouchableVolumes) && (currentPVCopyNb == parentItemCopyNb)
3097 && (currentPVName == parentItemName)) ||
3099 ((parentRoot != fTouchableVolumes) && (currentPVCopyNb == parentItemCopyNb)
3101 && (currentPVName == parentItemName) && (currentPVPOIndex == parentItemPOIndex) )) {
3104 bool sameTransform =
true;
3105 if (parentItemPOIndex >= 0) {
3106 const PVPath& fullPathTmp = fTreeItemModels[parentItemPOIndex];
3107 if (fullPathTmp.size() > 0) {
3108 if (fullPathTmp.at(fullPathTmp.size()-1).GetTransform () == pPVModel->
GetTransformation ()) {
3109 sameTransform =
true;
3111 sameTransform =
false;
3117 if (sameTransform ==
true) {
3124 if (currentIndexInTreeSceneHandler == (fullPath.size()-1)) {
3126 parentItemList.at(i)->setText(2,QString::number(currentPVPOIndex));
3127 parentItemList.at(i)->setData(0, Qt::UserRole,currentPVPOIndex);
3129 fTreeItemModels.insert(std::pair <int, PVPath >(currentPVPOIndex,fullPath) );
3133 parentItemList.at(i)->setFont (0,f);
3136 parentItemList.at(i)->setForeground (0,QBrush());
3139 parentItemList.at(i)->setToolTip (0,
"");
3141 changeQColorForTreeWidgetItem(parentItemList.at(i),QColor((
int)(color.
GetRed()*255),
3148 parentItemList.at(i)->setCheckState(0,Qt::Checked);
3149 updatePositivePoIndexSceneTreeWidgetQuickMap(currentPVPOIndex,parentItemList.at(i));
3153 subItem = parentItemList.at(i);
3157 }
else if (currentIndexInTreeSceneHandler < (fullPath.size()-1)) {
3158 subItem = parentItemList.at(i);
3165 if (currentIndexInTreeSceneHandler == (fullPath.size()-1)) {
3166 createTreeWidgetItem(fullPath,
3167 QString(currentPVName.c_str()),
3170 QString(fullPath.at(fullPathIndex).GetPhysicalVolume()->GetLogicalVolume()->GetName().data()),
3175 if (currentPVPOIndex > fMaxPOindexInserted) {
3176 fMaxPOindexInserted = currentPVPOIndex;
3182 if (subItem == NULL) {
3184 if (currentIndexInTreeSceneHandler < (fullPath.size()-1)) {
3185 subItem = createTreeWidgetItem(fullPath,
3186 QString(currentPVName.c_str()),
3189 QString(fullPath.at(fullPathIndex).GetPhysicalVolume()->GetLogicalVolume()->GetName().data()),
3196 return parseAndInsertInSceneTree(subItem,pPVModel,fullPathIndex+1,parentRoot,currentIndexInTreeSceneHandler+1,currentPVPOIndex);
3202void G4OpenGLQtViewer::changeOpenCloseVisibleHiddenSelectedColorSceneTreeElement(
3203 QTreeWidgetItem* subItem
3207 QTreeWidgetItem* oldItem = NULL;
3209 QTreeWidgetItem* foundItem = getOldTreeWidgetItem(subItem->data(0,Qt::UserRole).toInt());
3211 if (foundItem != NULL) {
3212 if (isSameSceneTreeElement(foundItem,subItem)) {
3213 oldItem = foundItem;
3216 if (foundItem == NULL) {
3219 std::map <int, QTreeWidgetItem*>::const_iterator i;
3220 i = fOldPositivePoIndexSceneTreeWidgetQuickMap.cbegin();
3221 while (i != fOldPositivePoIndexSceneTreeWidgetQuickMap.cend()) {
3222 if (isSameSceneTreeElement(i->second,subItem)) {
3223 oldItem = i->second;
3224 i = fOldPositivePoIndexSceneTreeWidgetQuickMap.cend();
3230 if (oldItem == NULL) {
3232 while (a < fOldNullPoIndexSceneTreeWidgetQuickVector.size()) {
3233 if (isSameSceneTreeElement(fOldNullPoIndexSceneTreeWidgetQuickVector[a],subItem)) {
3234 oldItem = fOldNullPoIndexSceneTreeWidgetQuickVector[a];
3235 a = fOldNullPoIndexSceneTreeWidgetQuickVector.size();
3244 if (oldItem != NULL) {
3245 subItem->setFlags(oldItem->flags());
3246 subItem->setCheckState(0,oldItem->checkState(0));
3247 subItem->setSelected(oldItem->isSelected());
3248 subItem->setExpanded(oldItem->isExpanded ());
3253 std::map <int, QTreeWidgetItem* >::iterator it;
3256 int oldPOIndex = oldItem->data(0,Qt::UserRole).toInt();
3257 it = fOldPositivePoIndexSceneTreeWidgetQuickMap.find(oldPOIndex);
3261 std::map <int, QColor >::iterator itVis;
3262 itVis = fOldVisAttrColorMap.find(oldPOIndex);
3264 QColor oldVisAttrColor;
3265 const QColor& newVisAttrColor = subItem->data(2,Qt::UserRole).value<QColor>();
3267 bool visAttrChange =
false;
3269 if (itVis != fOldVisAttrColorMap.end()) {
3270 oldVisAttrColor = itVis->second;
3271 if (oldVisAttrColor != newVisAttrColor) {
3272 visAttrChange =
true;
3275 visAttrChange =
true;
3278 if (visAttrChange) {
3279 fOldVisAttrColorMap.insert(std::pair <int, QColor > (subItem->data(0,Qt::UserRole).toInt(),newVisAttrColor) );
3283 if (it != fOldPositivePoIndexSceneTreeWidgetQuickMap.end()) {
3284 color = (it->second)->data(2,Qt::UserRole).value<QColor>();
3286 color = oldItem->data(2,Qt::UserRole).value<QColor>();
3288 changeQColorForTreeWidgetItem(subItem,color);
3300bool G4OpenGLQtViewer::isSameSceneTreeElement(
3301 QTreeWidgetItem* parentOldItem
3302 ,QTreeWidgetItem* parentNewItem
3308 int newCpNumber = -1;
3309 int oldCpNumber = -1;
3311 bool firstWhile =
true;
3313 while ((parentOldItem != NULL) && (parentNewItem != NULL)) {
3317 oldPO = parentOldItem->data(0,Qt::UserRole).toInt();
3318 newPO = parentNewItem->data(0,Qt::UserRole).toInt();
3324 const PVPath& oldFullPath = fOldTreeItemModels[oldPO];
3325 const PVPath& newFullPath = fTreeItemModels[newPO];
3326 if ((oldFullPath.size() > 0) &&
3327 (newFullPath.size() > 0)) {
3328 if (oldFullPath.size() != newFullPath.size()) {
3331 if (oldFullPath.at(oldFullPath.size()-1).GetTransform () == newFullPath.at(newFullPath.size()-1).GetTransform ()) {
3332 newCpNumber = newFullPath.at(newFullPath.size()-1).GetCopyNo();
3333 oldCpNumber = oldFullPath.at(oldFullPath.size()-1).GetCopyNo();
3342 if (oldCpNumber == -1) {
3343 oldCpNumber = parentOldItem->data(1,Qt::UserRole).toInt();
3345 if (newCpNumber == -1) {
3346 newCpNumber = parentNewItem->data(1,Qt::UserRole).toInt();
3348 if ((oldCpNumber != newCpNumber) ||
3350 (parentOldItem->text(0) != parentNewItem->text(0)) ) {
3353 }
else if ((parentOldItem->text(0) != parentNewItem->text(0)) ||
3354 (parentOldItem->text(3) != parentNewItem->text(3))) {
3357 parentOldItem = parentOldItem->parent();
3358 parentNewItem = parentNewItem->parent();
3369 ,
const std::string& modelDescription
3373 QString modelShortName = getModelShortName(model);
3378 const G4Text& g4Text =
dynamic_cast<const G4Text&
>(visible);
3381 catch (
const std::bad_cast&) {
3388 if (g4Marker.
GetInfo() !=
"") {
3389 modelShortName = g4Marker.
GetInfo();
3392 catch (
const std::bad_cast&) {}
3394 if (modelShortName ==
"") {
3398 if (fSceneTreeComponentTreeWidget == NULL) {
3399 createSceneTreeComponent();
3403 if (fSceneTreeComponentTreeWidget == NULL) {
3407 fSceneTreeComponentTreeWidget->blockSignals(
true);
3411 QList<QTreeWidgetItem *> resItem;
3412 resItem = fSceneTreeComponentTreeWidget->findItems (modelShortName, Qt::MatchExactly, 0 );
3413 QTreeWidgetItem * currentItem = NULL;
3414 const PVPath tmpFullPath;
3416 if (resItem.empty()) {
3417 currentItem = createTreeWidgetItem(tmpFullPath,
3426 currentItem = resItem.first();
3430 const QList<QTreeWidgetItem *>&
3431 resItems = fSceneTreeComponentTreeWidget->findItems (QString(modelDescription.c_str()), Qt::MatchFixedString| Qt::MatchCaseSensitive|Qt::MatchRecursive, 0 );
3433 bool alreadyPresent =
false;
3434 for (
int i = 0; i < resItems.size(); ++i) {
3435 if (currentPOIndex == resItems.at(i)->data(0,Qt::UserRole).toInt()) {
3436 alreadyPresent =
true;
3439 if (!alreadyPresent) {
3440 createTreeWidgetItem(tmpFullPath,
3449 fSceneTreeComponentTreeWidget->blockSignals(
false);
3457QString G4OpenGLQtViewer::getModelShortName(
const G4String& model) {
3459 QString modelShortName = model.data();
3460 if (modelShortName.mid(0,modelShortName.indexOf(
" ")) ==
"G4PhysicalVolumeModel") {
3461 modelShortName = fTouchableVolumes;
3463 if (modelShortName.mid(0,2) ==
"G4") {
3464 modelShortName = modelShortName.mid(2);
3466 if (modelShortName.indexOf(
"Model") != -1) {
3467 modelShortName = modelShortName.mid(0,modelShortName.indexOf(
"Model"));
3470 return modelShortName;
3478 if (fSceneTreeComponentTreeWidget == NULL) {
3484 if (fLastSceneTreeWidgetAskForIterator != fLastSceneTreeWidgetAskForIteratorEnd) {
3485 fLastSceneTreeWidgetAskForIterator++;
3487 QTreeWidgetItem* item = getTreeWidgetItem(POindex);
3490 if ( item->checkState(0) == Qt::Checked) {
3498bool G4OpenGLQtViewer::parseAndCheckVisibility(QTreeWidgetItem * treeNode,
int POindex){
3499 bool isFound =
false;
3500 for (
int i = 0; i < treeNode->childCount() ; ++i) {
3502 if (treeNode->child(i)->data(0,Qt::UserRole).toInt() == POindex) {
3503 if (treeNode->child(i)->checkState(0) == Qt::Checked) {
3507 isFound = parseAndCheckVisibility(treeNode->child(i),POindex);
3516std::string G4OpenGLQtViewer::parseSceneTreeAndSaveState(){
3517 std::string commandLine =
"";
3518 for (
int b=0;b<fSceneTreeComponentTreeWidget->topLevelItemCount();b++) {
3519 commandLine += parseSceneTreeElementAndSaveState(fSceneTreeComponentTreeWidget->topLevelItem(b),1)+
"\n";
3521 if (commandLine !=
"") {
3522 commandLine = std::string(
"# Disable auto refresh and quieten vis messages whilst scene and\n") +
3523 "# trajectories are established:\n" +
3524 "/vis/viewer/set/autoRefresh false\n" +
3525 "/vis/verbose errors" +
3527 "# Re-establish auto refreshing and verbosity:\n" +
3528 "/vis/viewer/set/autoRefresh true\n" +
3529 "/vis/verbose confirmations\n";
3535std::string G4OpenGLQtViewer::parseSceneTreeElementAndSaveState(QTreeWidgetItem* item,
unsigned int level){
3537 std::string str( level,
' ' );
3538 std::string commandLine =
"\n#"+ str +
"PV Name: " + item->text(0).toStdString();
3540 if (item->text(3) !=
"") {
3541 commandLine +=
" LV Name: "+item->text(3).toStdString()+
"\n";
3543 commandLine +=
"/vis/geometry/set/visibility " + item->text(3).toStdString() +
" ! ";
3544 if (item->checkState(0) == Qt::Checked) {
3547 if (item->checkState(0) == Qt::Unchecked) {
3553 const QColor& c = item->data(2,Qt::UserRole).value<QColor>();
3554 std::stringstream red;
3555 red << ((double)c.red())/255;
3556 std::stringstream green;
3557 green << (double)c.green()/255;
3558 std::stringstream blue;
3559 blue << ((double)c.blue())/255;
3560 std::stringstream
alpha;
3561 alpha << ((double)c.alpha())/255;
3563 commandLine +=
"/vis/geometry/set/colour " + item->text(3).toStdString() +
" ! " + red.str() +
" " + green.str() +
" " + blue.str() +
" " +
alpha.str()+
"\n";
3566 commandLine +=
"\n";
3570 for (
int b=0;b< item->childCount();b++) {
3571 commandLine += parseSceneTreeElementAndSaveState(item->child(b),level+1);
3578void G4OpenGLQtViewer::sceneTreeComponentItemChanged(QTreeWidgetItem* item,
int) {
3580 if (fCheckSceneTreeComponentSignalLock ==
false) {
3581 fCheckSceneTreeComponentSignalLock =
true;
3583 if (item->checkState(0) == Qt::Checked) {
3586 setCheckComponent(item,checked);
3589 fCheckSceneTreeComponentSignalLock =
false;
3594void G4OpenGLQtViewer::sceneTreeComponentSelected() {
3597void G4OpenGLQtViewer::changeDepthInSceneTree (
int val){
3600 if (fSceneTreeComponentTreeWidget == NULL) {
3611 double depth = 1 + ((double)val)/1000 * ((
double)fSceneTreeDepth+1);
3614 fCheckSceneTreeComponentSignalLock =
true;
3617 G4bool currentAutoRefresh =
fVP.IsAutoRefresh();
3618 fVP.SetAutoRefresh(
false);
3620 for (
int b=0;b<fSceneTreeComponentTreeWidget->topLevelItemCount();b++) {
3621 changeDepthOnSceneTreeItem(depth,1.,fSceneTreeComponentTreeWidget->topLevelItem(b));
3625 fVP.SetAutoRefresh(currentAutoRefresh);
3629 fCheckSceneTreeComponentSignalLock =
false;
3634void G4OpenGLQtViewer::changeColorAndTransparency(QTreeWidgetItem* item,
int) {
3639 const QColor& old = QColor(item->data(2,Qt::UserRole).value<QColor>());
3641 const QColor& color = QColorDialog::getColor(old,
3642 fSceneTreeComponentTreeWidget,
3643 " Get color and transparency",
3644 QColorDialog::ShowAlphaChannel);
3646 if (color.isValid()) {
3648 changeColorAndTransparency(item->data(0,Qt::UserRole).toInt(),
3649 G4Colour (((
G4double)color.red())/255,
3655 changeQColorForTreeWidgetItem(item,color);
3660void G4OpenGLQtViewer::changeColorAndTransparency(GLuint index,
G4Color ) {
3664 if (iPO >= 0 && fTreeItemModels.find(iPO) != fTreeItemModels.end()) {
3665 const PVPath& fullPath = fTreeItemModels[iPO];
3667 if (fullPath.size()) {
3676 QTreeWidgetItem* item = getTreeWidgetItem(poIndex);
3680 const QColor& color = item->data(2,Qt::UserRole).value<QColor>();
3692const std::vector<G4ModelingParameters::VisAttributesModifier>*
3695 static std::vector<G4ModelingParameters::VisAttributesModifier>
3696 privateVisAttributesModifiers;
3698 privateVisAttributesModifiers.clear();
3751 return &privateVisAttributesModifiers;
3755void G4OpenGLQtViewer::changeSearchSelection()
3757 const QString& searchText = fFilterOutput->text();
3758 if (fSceneTreeComponentTreeWidget == NULL) {
3763 for (
int a=0; a<fSceneTreeComponentTreeWidget->topLevelItemCount(); a++) {
3764 fSceneTreeComponentTreeWidget->topLevelItem(a)->setExpanded(
false);
3765 fSceneTreeComponentTreeWidget->topLevelItem(a)->setSelected(
false);
3766 clearSceneTreeSelection(fSceneTreeComponentTreeWidget->topLevelItem(a));
3769 QList<QTreeWidgetItem *> itemList = fSceneTreeComponentTreeWidget->findItems (searchText,Qt::MatchContains | Qt::MatchRecursive,0);
3771 for (
int i = 0; i < itemList.size(); ++i) {
3772 QTreeWidgetItem* expandParentItem = itemList.at(i);
3773 while (expandParentItem->parent() != NULL) {
3774 expandParentItem->parent()->setExpanded(
true);
3775 expandParentItem = expandParentItem->parent();
3777 itemList.at(i)->setSelected(
true);
3783void G4OpenGLQtViewer::clearSceneTreeSelection(QTreeWidgetItem* item) {
3784 for (
int a=0; a<item->childCount(); a++) {
3785 item->child(a)->setSelected(
false);
3786 item->child(a)->setExpanded(
false);
3787 clearSceneTreeSelection(item->child(a));
3793bool G4OpenGLQtViewer::isPVVolume(QTreeWidgetItem* item) {
3794 QTreeWidgetItem* sParent = item;
3795 while (sParent->parent() != NULL) {
3796 sParent = sParent->parent();
3798 if (sParent->text(0) != fTouchableVolumes) {
3802 if (item->text(0) == fTouchableVolumes) {
3809void G4OpenGLQtViewer::changeDepthOnSceneTreeItem(
3811 ,
double currentDepth
3812 ,QTreeWidgetItem* item
3814 double transparencyLevel = 0.;
3819 if (isPVVolume(item)) {
3820 if ((lookForDepth-currentDepth) < 0) {
3821 item->setCheckState(0,Qt::Checked);
3822 updatePositivePoIndexSceneTreeWidgetQuickMap(item->data(0,Qt::UserRole).toInt(),item);
3823 transparencyLevel = 1;
3824 }
else if ((lookForDepth-currentDepth) > 1 ){
3825 item->setCheckState(0,Qt::Unchecked);
3826 updatePositivePoIndexSceneTreeWidgetQuickMap(item->data(0,Qt::UserRole).toInt(),item);
3827 transparencyLevel = 0;
3829 item->setCheckState(0,Qt::Checked);
3830 updatePositivePoIndexSceneTreeWidgetQuickMap(item->data(0,Qt::UserRole).toInt(),item);
3831 transparencyLevel = 1-(lookForDepth-currentDepth);
3835 if (item->data(0,Qt::UserRole).toInt() >= 0) {
3848 if (((color.
GetAlpha()-transparencyLevel) > 0.000001) ||
3849 ((color.
GetAlpha()-transparencyLevel) < -0.000001)) {
3850 if ((item->text(3) !=
"")) {
3856 changeQColorForTreeWidgetItem(item,QColor((
int)(color.
GetRed()*255),
3859 (
int)(transparencyLevel*255)));
3864 for (
int b=0;b< item->childCount();b++) {
3865 changeDepthOnSceneTreeItem(lookForDepth,currentDepth+1,item->child(b));
3873 if (fSceneTreeComponentTreeWidget) {
3875 if (fSceneTreeComponentTreeWidget->topLevelItemCount () > 0) {
3877 fPVRootNodeCreate =
false;
3880 fOldPositivePoIndexSceneTreeWidgetQuickMap.clear();
3881 fOldNullPoIndexSceneTreeWidgetQuickVector.clear();
3882 fOldTreeItemModels.clear();
3885 for (
int b =0; b <fSceneTreeComponentTreeWidget->topLevelItemCount();b++) {
3894 int poIndex = fSceneTreeComponentTreeWidget->topLevelItem(b)->data(0,Qt::UserRole).toInt();
3895 if (poIndex != -1) {
3896 fOldPositivePoIndexSceneTreeWidgetQuickMap.insert(std::pair <int, QTreeWidgetItem*> (poIndex,cloneWidgetItem(fSceneTreeComponentTreeWidget->topLevelItem(b))));
3898 fOldNullPoIndexSceneTreeWidgetQuickVector.push_back(cloneWidgetItem(fSceneTreeComponentTreeWidget->topLevelItem(b)));
3902 cloneSceneTree(fSceneTreeComponentTreeWidget->topLevelItem(b));
3906 fOldTreeItemModels.insert(fTreeItemModels.begin(), fTreeItemModels.end());
3909 int tmp2 = fSceneTreeComponentTreeWidget->topLevelItemCount();
3911 delete fSceneTreeComponentTreeWidget->takeTopLevelItem (0);
3912 tmp2 = fSceneTreeComponentTreeWidget->topLevelItemCount();
3914 fPositivePoIndexSceneTreeWidgetQuickMap.clear();
3917 fOldLastSceneTreeWidgetAskForIterator = fOldPositivePoIndexSceneTreeWidgetQuickMap.begin();
3918 fOldLastSceneTreeWidgetAskForIteratorEnd = fOldPositivePoIndexSceneTreeWidgetQuickMap.end();
3919 fSceneTreeDepth = 1;
3920 fModelShortNameItem = NULL;
3921 fMaxPOindexInserted = -1;
3934QTreeWidgetItem * G4OpenGLQtViewer::cloneWidgetItem(QTreeWidgetItem* item) {
3936 QTreeWidgetItem* cloneItem =
new QTreeWidgetItem();
3940 cloneItem->setText(0,item->text(0));
3941 cloneItem->setData(1,Qt::UserRole,item->data(1,Qt::UserRole).toInt());
3942 cloneItem->setText(2,item->text(2));
3943 cloneItem->setData(0, Qt::UserRole,item->data(0,Qt::UserRole).toInt());
3944 cloneItem->setText(3,item->text(3));
3945 cloneItem->setFlags(item->flags());
3946 cloneItem->setToolTip(0,item->toolTip(0));
3947 cloneItem->setCheckState(0,item->checkState(0));
3948 cloneItem->setSelected(item->isSelected());
3949 cloneItem->setExpanded(item->isExpanded ());
3951 cloneItem->setData(2,Qt::UserRole,item->data(2,Qt::UserRole).value<QColor>());
3960void G4OpenGLQtViewer::cloneSceneTree(
3961 QTreeWidgetItem* rootItem
3964 for (
int b=0;b< rootItem->childCount();b++) {
3966 QTreeWidgetItem *child = rootItem->child(b);
3969 int poIndex = child->data(0,Qt::UserRole).toInt();
3970 if (poIndex != -1) {
3971 fOldPositivePoIndexSceneTreeWidgetQuickMap.insert(std::pair <int, QTreeWidgetItem*> (poIndex,cloneWidgetItem(child)));
3973 fOldNullPoIndexSceneTreeWidgetQuickVector.push_back(cloneWidgetItem(child));
3975 cloneSceneTree(child);
3983 void G4OpenGLQtViewer::updatePositivePoIndexSceneTreeWidgetQuickMap(
int POindex,QTreeWidgetItem* item) {
3986 std::map <int, QTreeWidgetItem*>::iterator i;
3987 i = fPositivePoIndexSceneTreeWidgetQuickMap.find(POindex);
3989 if (i == fPositivePoIndexSceneTreeWidgetQuickMap.end()) {
3990 fPositivePoIndexSceneTreeWidgetQuickMap.insert(std::pair <int, QTreeWidgetItem*> (POindex,item) );
3991 fLastSceneTreeWidgetAskForIterator = fPositivePoIndexSceneTreeWidgetQuickMap.end();
3992 fLastSceneTreeWidgetAskForIteratorEnd = fPositivePoIndexSceneTreeWidgetQuickMap.end();
4000void G4OpenGLQtViewer::changeQColorForTreeWidgetItem(QTreeWidgetItem* item,
const QColor& qc) {
4002 int POIndex = item->data(0,Qt::UserRole).toInt();
4003 updatePositivePoIndexSceneTreeWidgetQuickMap(POIndex,item );
4005 QPixmap pixmap = QPixmap(QSize(16, 16));
4006 if (item->data(0,Qt::UserRole).toInt() != -1) {
4009 pixmap.fill (QColor(255,255,255,255));
4011 QPainter painter(&pixmap);
4012 painter.setPen(Qt::black);
4013 painter.drawRect(0,0,15,15);
4015 item->setIcon(0,pixmap);
4016 item->setData(2,Qt::UserRole,qc);
4025QTreeWidgetItem* G4OpenGLQtViewer::getTreeWidgetItem(
int POindex){
4028 if (POindex == -1) {
4032 if (fPositivePoIndexSceneTreeWidgetQuickMap.size() == 0){
4036 if (fLastSceneTreeWidgetAskForIterator != fLastSceneTreeWidgetAskForIteratorEnd) {
4037 if (POindex == fLastSceneTreeWidgetAskForIterator->first) {
4038 if (fLastSceneTreeWidgetAskForIterator->second != NULL) {
4039 return fLastSceneTreeWidgetAskForIterator->second;
4045 fLastSceneTreeWidgetAskForIterator = fPositivePoIndexSceneTreeWidgetQuickMap.find(POindex);
4046 fLastSceneTreeWidgetAskForIteratorEnd = fPositivePoIndexSceneTreeWidgetQuickMap.end();
4048 if (fLastSceneTreeWidgetAskForIterator != fPositivePoIndexSceneTreeWidgetQuickMap.end()) {
4049 return fLastSceneTreeWidgetAskForIterator->second;
4058QTreeWidgetItem* G4OpenGLQtViewer::getOldTreeWidgetItem(
int POindex){
4062 if (POindex == -1) {
4066 if (fOldPositivePoIndexSceneTreeWidgetQuickMap.size() == 0){
4072 if (fOldLastSceneTreeWidgetAskForIterator != fOldLastSceneTreeWidgetAskForIteratorEnd) {
4073 fOldLastSceneTreeWidgetAskForIterator++;
4076 if (fOldLastSceneTreeWidgetAskForIterator != fOldPositivePoIndexSceneTreeWidgetQuickMap.end()) {
4077 if (POindex == fOldLastSceneTreeWidgetAskForIterator->first) {
4078 if (fOldLastSceneTreeWidgetAskForIterator->second != NULL) {
4079 return fOldLastSceneTreeWidgetAskForIterator->second;
4085 fOldLastSceneTreeWidgetAskForIterator = fOldPositivePoIndexSceneTreeWidgetQuickMap.find(POindex);
4086 fOldLastSceneTreeWidgetAskForIteratorEnd = fOldPositivePoIndexSceneTreeWidgetQuickMap.end();
4088 if (fOldLastSceneTreeWidgetAskForIterator != fOldPositivePoIndexSceneTreeWidgetQuickMap.end()) {
4089 return fOldLastSceneTreeWidgetAskForIterator->second;
4102 if (fUISceneTreeWidget == NULL) {
4105 if (fSceneTreeComponentTreeWidget == NULL) {
4110 fSceneTreeComponentTreeWidget->sortItems (0, Qt::AscendingOrder );
4128 d_style =
fVP.GetDrawingStyle();
4132 if (
fUiQt)
fUiQt->SetIconWireframeSelected();
4134 fDrawingWireframe->setChecked(
true);
4135 fDrawingLineRemoval->setChecked(
false);
4136 fDrawingSurfaceRemoval->setChecked(
false);
4137 fDrawingLineSurfaceRemoval->setChecked(
false);
4142 fDrawingLineRemoval->setChecked(
true);
4143 fDrawingWireframe->setChecked(
false);
4144 fDrawingSurfaceRemoval->setChecked(
false);
4145 fDrawingLineSurfaceRemoval->setChecked(
false);
4150 fDrawingSurfaceRemoval->setChecked(
true);
4151 fDrawingWireframe->setChecked(
false);
4152 fDrawingLineRemoval->setChecked(
false);
4153 fDrawingLineSurfaceRemoval->setChecked(
false);
4158 fDrawingLineSurfaceRemoval->setChecked(
true);
4159 fDrawingWireframe->setChecked(
false);
4160 fDrawingLineRemoval->setChecked(
false);
4161 fDrawingSurfaceRemoval->setChecked(
false);
4162 fDrawingLineSurfaceRemoval->setChecked(
false);
4172 fProjectionOrtho->setChecked(
true);
4173 fProjectionPerspective->setChecked(
false);
4176 if (
fUiQt)
fUiQt->SetIconPerspectiveSelected();
4178 fProjectionPerspective->setChecked(
true);
4179 fProjectionOrtho->setChecked(
false);
4185 if (
fUiQt && fContextMenu) {
4186 if (
fUiQt->IsIconPickSelected()) {
4187 fMousePickAction->setChecked(
true);
4189 fMousePickAction->setChecked(
false);
4191 if (
fUiQt->IsIconZoomOutSelected()) {
4192 fMouseZoomOutAction->setChecked(
true);
4193 fMouseZoomInAction->setChecked(
false);
4194 fMouseRotateAction->setChecked(
false);
4195 fMouseMoveAction->setChecked(
false);
4196 }
else if (
fUiQt->IsIconZoomInSelected()) {
4197 fMouseZoomInAction->setChecked(
true);
4198 fMouseZoomOutAction->setChecked(
false);
4199 fMouseRotateAction->setChecked(
false);
4200 fMouseMoveAction->setChecked(
false);
4201 }
else if (
fUiQt->IsIconRotateSelected()) {
4202 fMouseRotateAction->setChecked(
true);
4203 fMouseZoomOutAction->setChecked(
false);
4204 fMouseZoomInAction->setChecked(
false);
4205 fMouseMoveAction->setChecked(
false);
4206 }
else if (
fUiQt->IsIconMoveSelected()) {
4207 fMouseMoveAction->setChecked(
true);
4208 fMouseZoomOutAction->setChecked(
false);
4209 fMouseZoomInAction->setChecked(
false);
4210 fMouseRotateAction->setChecked(
false);
4221 if (!fSceneTreeWidget) {
4222 createSceneTreeWidget();
4238 if (!fViewerPropertiesTableWidget) {
4239 createViewerPropertiesWidget();
4241 int treeWidgetInfosIgnoredCommands = 0;
4251 if ((path->
GetCommandEntry()-fTreeWidgetInfosIgnoredCommands) != fViewerPropertiesTableWidget->rowCount()) {
4252 fViewerPropertiesTableWidget->clear();
4255 fViewerPropertiesTableWidget->blockSignals(
true);
4258 fViewerPropertiesTableWidget->setColumnCount (2);
4259 fViewerPropertiesTableWidget->setRowCount (path->
GetCommandEntry()-fTreeWidgetInfosIgnoredCommands);
4260 fViewerPropertiesTableWidget->setHorizontalHeaderLabels(QStringList() << tr(
"Property")
4262 fViewerPropertiesTableWidget->verticalHeader()->setVisible(
false);
4263 fViewerPropertiesTableWidget->setAlternatingRowColors (
true);
4271 QString params =
"";
4274 if (
fVP.IsAutoRefresh()) {
4280 if (
fVP.IsAuxEdgeVisible()) {
4286 params = QString().number(
fVP.GetBackgroundColour().GetRed()) +
" "+
4287 QString().number(
fVP.GetBackgroundColour().GetGreen()) +
" "+
4288 QString().number(
fVP.GetBackgroundColour().GetBlue()) +
" "+
4289 QString().number(
fVP.GetBackgroundColour().GetAlpha());
4292 params = QString().number(
fVP. IsCulling ());
4297 params =
"intersection";
4301 params = QString().number(
fVP.GetDefaultVisAttributes()->GetColor().GetRed()) +
" "+
4302 QString().number(
fVP.GetDefaultVisAttributes()->GetColor().GetGreen()) +
" "+
4303 QString().number(
fVP.GetDefaultVisAttributes()->GetColor().GetBlue()) +
" "+
4304 QString().number(
fVP.GetDefaultVisAttributes()->GetColor().GetAlpha());
4307 params = QString().number(
fVP.GetDefaultTextVisAttributes()->GetColor().GetRed()) +
" "+
4308 QString().number(
fVP.GetDefaultTextVisAttributes()->GetColor().GetGreen()) +
" "+
4309 QString().number(
fVP.GetDefaultTextVisAttributes()->GetColor().GetBlue()) +
" "+
4310 QString().number(
fVP.GetDefaultTextVisAttributes()->GetColor().GetAlpha());
4320 params = QString().number(
fVP.GetExplodeFactor()) +
" " + QString(
G4String(
G4BestUnit(
fVP.GetExplodeFactor(),
"Length")).data());
4322 }
else if(commandTmp->
GetCommandName() ==
"globalLineWidthScale") {
4323 params = QString().number(
fVP.GetGlobalLineWidthScale());
4326 params = QString().number(
fVP.GetGlobalMarkerScale());
4338 if (
fVP.IsMarkerNotHidden()) {
4345 if (
fVP.GetLightsMoveWithCamera()) {
4353 params = QString().number(direction.
theta()/CLHEP::degree)+
" "+ QString().number(direction.
phi()/CLHEP::degree)+
" deg";
4360 params = QString().number(
fVP.GetLightpointDirection().x()) +
" "+
4361 QString().number(
fVP.GetLightpointDirection().y()) +
" "+
4362 QString().number(
fVP.GetLightpointDirection().z());
4364 }
else if(commandTmp->
GetCommandName() ==
"lineSegmentsPerCircle") {
4365 params = QString().number(
fVP.GetNoOfSides());
4368 if (
fVP.IsPicking()) {
4375 if (
fVP.GetFieldHalfAngle() == 0.) {
4376 params =
"orthogonal";
4378 params = QString(
"perspective ") + QString().number(
fVP.GetFieldHalfAngle()/CLHEP::degree) +
" deg";
4383 params =
"constrainUpDirection";
4385 params =
"freeRotation";
4389 if (
fVP.IsSection()) {
4390 params = QString(
"on ") +
4392 QString().number(
fVP.GetSectionPlane().normal().x())
4393 +
" " + QString().number(
fVP.GetSectionPlane().normal().y())
4394 +
" " + QString().number(
fVP.GetSectionPlane().normal().z());
4401 params =
"wireframe";
4416 params = QString().number(up.
theta()/CLHEP::degree)+
" "+ QString().number(up.
phi()/CLHEP::degree)+
" deg";
4424 params = QString().number(up.
x())+
" "+ QString().number(up.
y())+
" "+QString().number(up.
z())+
" ";
4429 params = QString().number(direction.
theta()/CLHEP::degree)+
" "+ QString().number(direction.
phi()/CLHEP::degree)+
" deg";
4437 params = QString().number(direction.
x())+
" "+ QString().number(direction.
y())+
" "+QString().number(direction.
z());
4467 QTableWidgetItem *nameItem;
4468 QTableWidgetItem *paramItem;
4471 QList<QTableWidgetItem *> list = fViewerPropertiesTableWidget->findItems (commandTmp->
GetCommandName().data(),Qt::MatchExactly);
4472 if (list.size() == 1) {
4473 nameItem = list.first();
4474 paramItem = fViewerPropertiesTableWidget->item(nameItem->row(),1);
4477 nameItem =
new QTableWidgetItem();
4478 paramItem =
new QTableWidgetItem();
4479 fViewerPropertiesTableWidget->setItem(a-treeWidgetInfosIgnoredCommands, 0, nameItem);
4480 fViewerPropertiesTableWidget->setItem(a-treeWidgetInfosIgnoredCommands, 1, paramItem);
4485 for(
G4int i_thGuidance=0; i_thGuidance < n_guidanceEntry; i_thGuidance++ ) {
4486 guidance += QString((
char*)(commandTmp->
GetGuidanceLine(i_thGuidance)).data()) +
"\n";
4489 nameItem->setToolTip(guidance);
4490 paramItem->setToolTip(GetCommandParameterList(commandTmp));
4492 fViewerPropertiesTableWidget->setRowHeight(a-treeWidgetInfosIgnoredCommands,15);
4497 paramItem->setText(params);
4499 nameItem->setFlags(Qt::NoItemFlags);
4500 nameItem->setForeground(QBrush());
4503 treeWidgetInfosIgnoredCommands++;
4507 for (
int i=0; i<treeWidgetInfosIgnoredCommands; i++) {
4508 fViewerPropertiesTableWidget->removeRow (fViewerPropertiesTableWidget->rowCount() - 1);
4512 if (!fViewerPropertiesTableWidgetIsInit) {
4513 fViewerPropertiesTableWidgetIsInit =
true;
4515 fViewerPropertiesTableWidget->resizeColumnsToContents();
4517 int x = fViewerPropertiesTableWidget->horizontalHeader()->length();
4518 int y = fViewerPropertiesTableWidget->verticalHeader()->length()+ fViewerPropertiesTableWidget->horizontalHeader()->sizeHint().height() + 2;
4524 QDialog* dial =
static_cast<QDialog*
> (fUIViewerPropertiesWidget->parent());
4526 dial->resize(x+56,y+46);
4529 fViewerPropertiesTableWidget->blockSignals(
false);
4531 fTreeWidgetInfosIgnoredCommands = treeWidgetInfosIgnoredCommands;
4539 fLastPickPoint = QPoint(aX,aY);
4545 if (!fPickInfosWidget) {
4546 createPickInfosWidget();
4549#if QT_VERSION < 0x060000
4552 if (qGLW) qGLW->makeCurrent();}
4555 const std::vector < G4OpenGLViewerPickMap* > & pickMapVector =
GetPickDetails(aX,aY);
4558 if (fPickInfosWidget) {
4559 QLayoutItem * wItem;
4560 if (fPickInfosWidget->layout()->count()) {
4561 while ((wItem = fPickInfosWidget->layout()->takeAt(0)) != 0) {
4562 delete wItem->widget();
4568 if (!fPickInfosWidget) {
4569 createPickInfosWidget();
4574 G4int nPickedObjectsWithAttributes = 0;
4575 for (
unsigned int a=0; a< pickMapVector.size(); a++) {
4576 const auto& pickMap = pickMapVector[a];
4578 std::ostringstream label;
4579 std::ostringstream content;
4580 std::string txt = pickMap->getAttributes()[0].data();
4581 if (pickMapVector[a]->getAttributes().size()) {
4582 ++nPickedObjectsWithAttributes;
4584 std::size_t pos1 = txt.find(
':');
4585 std::string storeKey = txt.substr(0,pos1);
4587 if (storeKey ==
"G4PhysicalVolumeModel") {
4590 std::size_t pos2 = txt.find(
':',pos1+1);
4591 std::size_t pos3 = txt.find(
'\n',pos2+1);
4592 label << txt.substr(pos2+1,pos3-pos2-1);
4594 }
else if (storeKey ==
"G4TrajectoriesModel") {
4596 label <<
"Trajectory:";
4597 std::size_t pos2 = txt.find(
':',pos1+1);
4598 std::size_t pos3 = txt.find(
'\n',pos2+1);
4599 label <<
" Run:" << txt.substr(pos2+1,pos3-pos2-1);
4600 std::size_t pos4 = txt.find(
':',pos3+1);
4601 std::size_t pos5 = txt.find(
'\n',pos4+1);
4602 label <<
", Event:" << txt.substr(pos4+1,pos5-pos4-1);
4606 label <<
"Hit number:" << a <<
", PickName: " << pickMap->getPickName();
4611 content << pickMap->print().data();
4612 G4int thisPickName = pickMap->getPickName();
4613 while (++a < pickMapVector.size()) {
4614 const auto& a_pickMap = pickMapVector[a];
4615 if (a_pickMap->getPickName() == thisPickName) {
4616 content << a_pickMap->print().data();
4623 QPushButton* pickCoutButton =
new QPushButton(label.str().c_str());
4624 pickCoutButton->setStyleSheet (
"text-align: left; padding: 1px; border: 0px;");
4625 pickCoutButton->setIcon(*fTreeIconClosed);
4626 fPickInfosWidget->layout()->addWidget(pickCoutButton);
4631 newStr = QStringList(QString(content.str().c_str()).trimmed());
4633 QTextEdit* ed =
new QTextEdit();
4634 ed->setReadOnly(
true);
4635 fPickInfosWidget->layout()->addWidget(ed);
4636 ed->setVisible((
false));
4637 ed->append(newStr.join(
""));
4639 int tmp = fPickInfosWidget->layout()->count()-1;
4640 connect(pickCoutButton, &QPushButton::clicked , [
this, tmp](){ this->toggleSceneTreeComponentPickingCout(tmp);});
4646 QLabel * pushUp =
new QLabel(
"");
4647 QSizePolicy vPolicy = QSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum);
4648 vPolicy.setVerticalStretch(10);
4649 pushUp->setSizePolicy(vPolicy);
4650 fPickInfosWidget->layout()->addWidget(pushUp);
4655 changeColorAndTransparency(fLastHighlightName,fLastHighlightColor);
4657 if (pickMapVector.size() > 0 ) {
4659 fLastHighlightName = pickMapVector[0]->getPickName();
4662 changeColorAndTransparency(fLastHighlightName,
G4Color(1,1,1,1));
4666 QDialog* dial =
static_cast<QDialog*
> (fUIPickInfosWidget->parent());
4669 std::ostringstream oss;
4670 if (nPickedObjectsWithAttributes == 0) {
4672 }
else if (nPickedObjectsWithAttributes == 1) {
4675 oss << nPickedObjectsWithAttributes <<
" objects";
4677 oss <<
" selected - " <<
GetName();
4678 dial->setWindowTitle(oss.str().c_str());
4681 fPickInfosScrollArea->setVisible(
true);
4686void G4OpenGLQtViewer::toggleSceneTreeComponentPickingCout(
int pickItem) {
4691 for (
int a=0; a<fPickInfosWidget->layout()->count(); a++) {
4692 w = fPickInfosWidget->layout()->itemAt(a)->widget();
4693 QTextEdit* ed =
dynamic_cast<QTextEdit*
>(w);
4694 QPushButton* button;
4696 if (a == pickItem) {
4697 w->setVisible(!w->isVisible());
4699 w->setVisible(
false);
4702 button =
dynamic_cast<QPushButton*
>(fPickInfosWidget->layout()->itemAt(a-1)->widget());
4704 if (button->isVisible()) {
4705 button->setIcon(*fTreeIconOpen);
4707 button->setIcon(*fTreeIconClosed);
4716void G4OpenGLQtViewer::currentTabActivated(
int currentTab) {
4717 if (
fUiQt->GetViewerTabWidget()->tabText(currentTab) ==
GetName().data()) {
4718 createViewerPropertiesWidget();
4723void G4OpenGLQtViewer::tableWidgetViewerSetItemChanged(QTableWidgetItem * item) {
4726 QTableWidgetItem* previous = fViewerPropertiesTableWidget->item(fViewerPropertiesTableWidget->row(item),0);
4728 fViewerPropertiesTableWidget->blockSignals(
true);
4730 + previous->text().toStdString()
4732 + item->text().toStdString()).c_str());
4733 fViewerPropertiesTableWidget->blockSignals(
false);
4743 if (
GetName() !=
fUiQt->GetViewerTabWidget()->tabText(
fUiQt->GetViewerTabWidget()->currentIndex()).toStdString().c_str()) {
4757QString G4OpenGLQtViewer::GetCommandParameterList (
4764 if( n_parameterEntry > 0 ) {
4769 for(
G4int i_thParameter=0; i_thParameter<n_parameterEntry; i_thParameter++ ) {
4771 txt +=
"\nParameter : " + QString((
char*)(param->
GetParameterName()).data()) +
"\n";
4774 txt +=
" Parameter type : " + QString(QChar(param->
GetParameterType())) +
"\n";
4776 txt +=
" Omittable : True\n";
4778 txt +=
" Omittable : False\n";
4781 txt +=
" Default value : taken from the current value\n";
4783 txt +=
" Default value : " + QString((
char*)(param->
GetDefaultValue()).data())+
"\n";
4786 txt +=
" Parameter range : " + QString((
char*)(param->
GetParameterRange()).data())+
"\n";
4796#ifdef G4MULTITHREADED
4801 G4bool visSubThreadEstablished =
false;
4802 G4bool qObjectsSwitched =
false;
4812 if (qGLWidget ==
nullptr)
return;
4815 qGLWidget->doneCurrent();
4818 fQGLContextMainThread = QThread::currentThread();
4825 if (qGLWidget ==
nullptr)
return;
4834 if(qGLWidget->context()) qGLWidget->context()->moveToThread(fQGLContextVisSubThread);
4838 qObjectsSwitched =
true;
4847 if (qGLWidget ==
nullptr)
return;
4850 fQGLContextVisSubThread = QThread::currentThread();
4855 visSubThreadEstablished =
true;
4866 qGLWidget->makeCurrent();
4873 if (qGLWidget ==
nullptr)
return;
4876 qGLWidget->doneCurrent();
4879 if(qGLWidget->context()) qGLWidget->context()->moveToThread(fQGLContextMainThread);
4886 if (qGLWidget ==
nullptr)
return;
4888 qGLWidget->makeCurrent();
4890 visSubThreadEstablished =
false;
4891 qObjectsSwitched =
false;
G4TemplateAutoLock< G4Mutex > G4AutoLock
G4ThreadLocal T * G4GeomSplitter< T >::offset
QOpenGLWidget G4QGLWidgetType
HepGeom::Point3D< G4double > G4Point3D
#define G4CONDITION_INITIALIZER
#define G4MUTEX_INITIALIZER
#define G4CONDITIONWAITLAMBDA(cond, mutex, lambda)
#define G4CONDITIONBROADCAST(cond)
HepGeom::Vector3D< G4double > G4Vector3D
G4GLOB_DLL std::ostream G4cerr
G4GLOB_DLL std::ostream G4cout
G4double GetAlpha() const
G4double GetGreen() const
void setRecordingInfos(QString)
void G4MouseReleaseEvent(QMouseEvent *evnt)
virtual G4bool ReadyToDraw()
void rotateQtSceneToggle(float, float)
void G4MouseMoveEvent(QMouseEvent *event)
void G4keyPressEvent(QKeyEvent *event)
void updateViewerPropertiesTableWidget()
void addNonPVSceneTreeElement(const G4String &model, int currentPVPOIndex, const std::string &modelDescription, const G4Visible &visible)
void displayRecordingStatus()
QString getSaveFileName()
void G4MousePressEvent(QMouseEvent *event)
void G4wheelEvent(QWheelEvent *event)
void G4MouseDoubleClickEvent()
void updateSceneTreeWidget()
G4OpenGLQtViewer(G4OpenGLSceneHandler &scene)
bool isTouchableVisible(int POindex)
void moveScene(float, float, float, bool)
void G4manageContextMenuEvent(QContextMenuEvent *e)
QString getTempFolderPath()
G4bool GetWindowSize(unsigned int &a_w, unsigned int &a_h)
void rotateQtScene(float, float)
bool exportImage(std::string name="", int width=-1, int height=-1)
void updateToolbarAndMouseContextMenu()
void updateKeyModifierState(const Qt::KeyboardModifiers &)
void G4keyReleaseEvent(QKeyEvent *event)
virtual void CreateMainWindow(G4QGLWidgetType *, const QString &)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
G4Colour getColorForPoIndex(int poIndex)
void updatePickInfosWidget(int, int)
virtual ~G4OpenGLQtViewer()
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
void DrawText(const G4Text &)
QString setEncoderPath(QString path)
G4bool GetRenderAreaSize(unsigned int &a_w, unsigned int &a_h)
bool generateMpegEncoderParameters()
virtual void updateQWidget()=0
QString setSaveFileName(QString path)
void addPVSceneTreeElement(const G4String &model, G4PhysicalVolumeModel *pPVModel, int currentPVPOIndex)
const std::vector< G4ModelingParameters::VisAttributesModifier > * GetPrivateVisAttributesModifiers() const
QString setTempFolderPath(QString path)
void displaySceneTreeComponent()
std::vector< std::string > fExportImageFormatVector
friend class G4OpenGLSceneHandler
void rotateSceneToggle(G4double dx, G4double dy)
unsigned int getWinHeight() const
std::string fExportImageFormat
void ResizeWindow(unsigned int, unsigned int)
unsigned int getWinWidth() const
std::string fDefaultExportImageFormat
bool setExportFilename(G4String name, G4bool inc=true)
G4OpenGLViewer(G4OpenGLSceneHandler &scene)
void addExportImageFormat(std::string format)
G4bool antialiasing_enabled
virtual void DrawText(const G4Text &)
void setExportSize(G4int, G4int)
void rotateScene(G4double dx, G4double dy)
G4bool transparency_enabled
virtual bool exportImage(std::string name="", int width=-1, int height=-1)
std::string getRealPrintFilename()
G4double GetSceneNearWidth()
const std::vector< G4OpenGLViewerPickMap * > & GetPickDetails(GLdouble x, GLdouble y)
const G4Transform3D & GetTransformation() const
const std::vector< G4PhysicalVolumeNodeID > & GetFullPVPath() const
static G4Qt * getInstance()
G4double GetYOffset() const
G4double GetXOffset() const
G4int GetCommandEntry() const
G4UIcommand * GetCommand(G4int i)
G4UIcommandTree * FindCommandTree(const char *commandPath)
std::size_t GetParameterEntries() const
const G4String & GetGuidanceLine(G4int i) const
G4UIparameter * GetParameter(G4int i) const
std::size_t GetGuidanceEntries() const
const G4String & GetCommandName() const
G4UIcommandTree * GetTree() const
G4int ApplyCommand(const char *aCommand)
G4UIsession * GetG4UIWindow() const
static G4UImanager * GetUIpointer()
const G4String & GetParameterCandidates() const
const G4String & GetParameterGuidance() const
G4bool IsOmittable() const
const G4String & GetParameterRange() const
G4bool GetCurrentAsDefault() const
char GetParameterType() const
const G4String & GetParameterName() const
const G4String & GetDefaultValue() const
G4Interactor GetMainInteractor()
G4Point3D GetPosition() const
const G4String & GetName() const
virtual void DoneWithMasterThread()
G4VSceneHandler & fSceneHandler
void SetNeedKernelVisit(G4bool need)
virtual void SwitchToMasterThread()
virtual void SwitchToVisSubThread()
G4VViewer(G4VSceneHandler &, G4int id, const G4String &name="")
void ZoomFromMouseWheel(G4double delta, G4bool shift=false, G4double xPos=0, G4double yPos=0)
virtual void MovingToVisSubThread()
virtual void DoneWithVisSubThread()
virtual const G4String & GetInfo() const
const char * name(G4int ptype)