From 58417b9a5d73e7a8958bd777d623654430a44956 Mon Sep 17 00:00:00 2001 From: Charles PIGNEROL <> Date: Tue, 8 Apr 2025 15:44:04 +0200 Subject: [PATCH] Version 8.7.0. QtVtkViewPointToolBar and QtVtkViewPointToolButton classes: manage VTK viewpoints via a Qt button bar. --- cmake/version.cmake | 2 +- src/CMakeLists.txt | 1 + src/QtVtk/CMakeLists.txt | 7 +- src/QtVtk/QtVTKPrintHelper.cpp | 47 +- src/QtVtk/QtVtk.qrc | 29 ++ src/QtVtk/QtVtkViewDefinitionDialog.cpp | 179 ++++++++ src/QtVtk/QtVtkViewDefinitionPanel.cpp | 356 ++++++++++++++++ src/QtVtk/QtVtkViewPointToolBar.cpp | 266 ++++++++++++ src/QtVtk/QtVtkViewPointToolButton.cpp | 403 ++++++++++++++++++ src/QtVtk/cmake/QtVtkConfig.cmake.in | 2 +- src/QtVtk/images/.viewpoint_15svg.svg | 88 ++++ src/QtVtk/images/add_viewpoint.png | Bin 0 -> 886 bytes src/QtVtk/images/add_viewpoint.svg | 89 ++++ src/QtVtk/images/export_viewpoints.png | Bin 0 -> 2143 bytes src/QtVtk/images/import_viewpoints.png | Bin 0 -> 2310 bytes src/QtVtk/images/remove_viewpoint.png | Bin 0 -> 1065 bytes src/QtVtk/images/remove_viewpoint.svg | 86 ++++ src/QtVtk/images/remove_viewpoints.png | Bin 0 -> 1762 bytes src/QtVtk/images/remove_viewpoints.svg | 177 ++++++++ src/QtVtk/images/viewpoint_01.png | Bin 0 -> 893 bytes src/QtVtk/images/viewpoint_01.svg | 88 ++++ src/QtVtk/images/viewpoint_02.png | Bin 0 -> 1011 bytes src/QtVtk/images/viewpoint_02.svg | 87 ++++ src/QtVtk/images/viewpoint_03.png | Bin 0 -> 1013 bytes src/QtVtk/images/viewpoint_03.svg | 87 ++++ src/QtVtk/images/viewpoint_04.png | Bin 0 -> 956 bytes src/QtVtk/images/viewpoint_04.svg | 87 ++++ src/QtVtk/images/viewpoint_05.png | Bin 0 -> 949 bytes src/QtVtk/images/viewpoint_05.svg | 87 ++++ src/QtVtk/images/viewpoint_06.png | Bin 0 -> 1069 bytes src/QtVtk/images/viewpoint_06.svg | 87 ++++ src/QtVtk/images/viewpoint_07.png | Bin 0 -> 937 bytes src/QtVtk/images/viewpoint_07.svg | 87 ++++ src/QtVtk/images/viewpoint_08.png | Bin 0 -> 1090 bytes src/QtVtk/images/viewpoint_08.svg | 87 ++++ src/QtVtk/images/viewpoint_09.png | Bin 0 -> 1065 bytes src/QtVtk/images/viewpoint_09.svg | 87 ++++ src/QtVtk/images/viewpoint_10.png | Bin 0 -> 1158 bytes src/QtVtk/images/viewpoint_10.svg | 88 ++++ src/QtVtk/images/viewpoint_11.png | Bin 0 -> 989 bytes src/QtVtk/images/viewpoint_11.svg | 88 ++++ src/QtVtk/images/viewpoint_12.png | Bin 0 -> 1078 bytes src/QtVtk/images/viewpoint_12.svg | 88 ++++ src/QtVtk/images/viewpoint_13.png | Bin 0 -> 1094 bytes src/QtVtk/images/viewpoint_13.svg | 88 ++++ src/QtVtk/images/viewpoint_14.png | Bin 0 -> 1052 bytes src/QtVtk/images/viewpoint_14.svg | 88 ++++ src/QtVtk/images/viewpoint_15.png | Bin 0 -> 1054 bytes src/QtVtk/images/viewpoint_15.svg | 88 ++++ src/QtVtk/images/viewpoint_16.png | Bin 0 -> 1163 bytes src/QtVtk/images/viewpoint_16.svg | 88 ++++ src/QtVtk/images/viewpoint_17.png | Bin 0 -> 1037 bytes src/QtVtk/images/viewpoint_17.svg | 88 ++++ src/QtVtk/images/viewpoint_18.png | Bin 0 -> 1196 bytes src/QtVtk/images/viewpoint_18.svg | 88 ++++ src/QtVtk/images/viewpoint_19.png | Bin 0 -> 1169 bytes src/QtVtk/images/viewpoint_19.svg | 88 ++++ src/QtVtk/images/viewpoint_20.png | Bin 0 -> 1302 bytes src/QtVtk/images/viewpoint_20.svg | 88 ++++ .../public/QtVtk/QtVtkViewDefinitionDialog.h | 121 ++++++ .../public/QtVtk/QtVtkViewDefinitionPanel.h | 199 +++++++++ .../public/QtVtk/QtVtkViewPointToolBar.h | 84 ++++ .../public/QtVtk/QtVtkViewPointToolButton.h | 124 ++++++ src/viewpoint/CMakeLists.txt | 18 + src/viewpoint/QtViewPointWindow.cpp | 289 +++++++++++++ src/viewpoint/QtViewPointWindow.h | 58 +++ src/viewpoint/viewpoint.cpp | 40 ++ versions.txt | 7 + 68 files changed, 4375 insertions(+), 49 deletions(-) create mode 100644 src/QtVtk/QtVtk.qrc create mode 100644 src/QtVtk/QtVtkViewDefinitionDialog.cpp create mode 100644 src/QtVtk/QtVtkViewDefinitionPanel.cpp create mode 100644 src/QtVtk/QtVtkViewPointToolBar.cpp create mode 100644 src/QtVtk/QtVtkViewPointToolButton.cpp create mode 100644 src/QtVtk/images/.viewpoint_15svg.svg create mode 100644 src/QtVtk/images/add_viewpoint.png create mode 100644 src/QtVtk/images/add_viewpoint.svg create mode 100644 src/QtVtk/images/export_viewpoints.png create mode 100644 src/QtVtk/images/import_viewpoints.png create mode 100644 src/QtVtk/images/remove_viewpoint.png create mode 100644 src/QtVtk/images/remove_viewpoint.svg create mode 100644 src/QtVtk/images/remove_viewpoints.png create mode 100644 src/QtVtk/images/remove_viewpoints.svg create mode 100644 src/QtVtk/images/viewpoint_01.png create mode 100644 src/QtVtk/images/viewpoint_01.svg create mode 100644 src/QtVtk/images/viewpoint_02.png create mode 100644 src/QtVtk/images/viewpoint_02.svg create mode 100644 src/QtVtk/images/viewpoint_03.png create mode 100644 src/QtVtk/images/viewpoint_03.svg create mode 100644 src/QtVtk/images/viewpoint_04.png create mode 100644 src/QtVtk/images/viewpoint_04.svg create mode 100644 src/QtVtk/images/viewpoint_05.png create mode 100644 src/QtVtk/images/viewpoint_05.svg create mode 100644 src/QtVtk/images/viewpoint_06.png create mode 100644 src/QtVtk/images/viewpoint_06.svg create mode 100644 src/QtVtk/images/viewpoint_07.png create mode 100644 src/QtVtk/images/viewpoint_07.svg create mode 100644 src/QtVtk/images/viewpoint_08.png create mode 100644 src/QtVtk/images/viewpoint_08.svg create mode 100644 src/QtVtk/images/viewpoint_09.png create mode 100644 src/QtVtk/images/viewpoint_09.svg create mode 100644 src/QtVtk/images/viewpoint_10.png create mode 100644 src/QtVtk/images/viewpoint_10.svg create mode 100644 src/QtVtk/images/viewpoint_11.png create mode 100644 src/QtVtk/images/viewpoint_11.svg create mode 100644 src/QtVtk/images/viewpoint_12.png create mode 100644 src/QtVtk/images/viewpoint_12.svg create mode 100644 src/QtVtk/images/viewpoint_13.png create mode 100644 src/QtVtk/images/viewpoint_13.svg create mode 100644 src/QtVtk/images/viewpoint_14.png create mode 100644 src/QtVtk/images/viewpoint_14.svg create mode 100644 src/QtVtk/images/viewpoint_15.png create mode 100644 src/QtVtk/images/viewpoint_15.svg create mode 100644 src/QtVtk/images/viewpoint_16.png create mode 100644 src/QtVtk/images/viewpoint_16.svg create mode 100644 src/QtVtk/images/viewpoint_17.png create mode 100644 src/QtVtk/images/viewpoint_17.svg create mode 100644 src/QtVtk/images/viewpoint_18.png create mode 100644 src/QtVtk/images/viewpoint_18.svg create mode 100644 src/QtVtk/images/viewpoint_19.png create mode 100644 src/QtVtk/images/viewpoint_19.svg create mode 100644 src/QtVtk/images/viewpoint_20.png create mode 100644 src/QtVtk/images/viewpoint_20.svg create mode 100644 src/QtVtk/public/QtVtk/QtVtkViewDefinitionDialog.h create mode 100644 src/QtVtk/public/QtVtk/QtVtkViewDefinitionPanel.h create mode 100644 src/QtVtk/public/QtVtk/QtVtkViewPointToolBar.h create mode 100644 src/QtVtk/public/QtVtk/QtVtkViewPointToolButton.h create mode 100644 src/viewpoint/CMakeLists.txt create mode 100644 src/viewpoint/QtViewPointWindow.cpp create mode 100644 src/viewpoint/QtViewPointWindow.h create mode 100644 src/viewpoint/viewpoint.cpp diff --git a/cmake/version.cmake b/cmake/version.cmake index e6b3c37..c491e7e 100644 --- a/cmake/version.cmake +++ b/cmake/version.cmake @@ -3,7 +3,7 @@ # set (QT_VTK_MAJOR_VERSION "8") -set (QT_VTK_MINOR_VERSION "6") +set (QT_VTK_MINOR_VERSION "7") set (QT_VTK_RELEASE_VERSION "0") set (QT_VTK_VERSION ${QT_VTK_MAJOR_VERSION}.${QT_VTK_MINOR_VERSION}.${QT_VTK_RELEASE_VERSION}) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2e293ec..98d396f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,3 +1,4 @@ add_subdirectory (QtVtk) +add_subdirectory (viewpoint) diff --git a/src/QtVtk/CMakeLists.txt b/src/QtVtk/CMakeLists.txt index 0f4cee2..87e07f5 100644 --- a/src/QtVtk/CMakeLists.txt +++ b/src/QtVtk/CMakeLists.txt @@ -10,20 +10,21 @@ include (${GUIToolkitsVariables_CMAKE_DIR}/workarounds.cmake) find_package (VtkContrib 5 REQUIRED) include (${CMAKE_SOURCE_DIR}/cmake/qtvtk_common.cmake) # Après VtkContrib qui positionne les variables VTK_7, VTK_8 et VTK_9 -find_package (QtUtil 6 REQUIRED) +find_package (PrefsQt 6 REQUIRED) find_package(Qt${QT_MAJOR}Core NO_CMAKE_SYSTEM_PATH) # In order to enable moc ... if (VTK_9) find_package (VTK COMPONENTS GUISupportQt IOExportGL2PS FiltersExtraction) endif (VTK_9) file (GLOB HEADERS public/${CURRENT_PACKAGE_NAME}/*.h) -file (GLOB CPP_SOURCES *.cpp) +file (GLOB CPP_SOURCES *.cpp *.qrc) # On ajoute les en-têtes aux sources. C'est utile pour cmake dans certains cas, # par exemple lorsqu'ils doivent être pré-processés (moc, ...). add_library (QtVtk ${CPP_SOURCES} ${HEADERS}) set (ALL_TARGETS QtVtk) set_property (TARGET QtVtk PROPERTY AUTOMOC ON) +set_property (TARGET QtVtk PROPERTY AUTORCC ON) set_property (TARGET QtVtk PROPERTY VERSION ${QT_VTK_VERSION}) set_property (TARGET QtVtk PROPERTY SOVERSION ${QT_VTK_MAJOR_VERSION}) # Rem : en Qt v 4.* on utilise -DUSE_QT_WEBKIT @@ -51,7 +52,7 @@ endif(VTK_9) target_compile_definitions (QtVtk PUBLIC ${QT_VTK_PUBLIC_FLAGS}) target_compile_definitions (QtVtk PRIVATE ${QT_VTK_PRIVATE_FLAGS} ${QT_VTK_PRIVATE_HELP_FLAGS}) target_compile_options (QtVtk PRIVATE ${SHARED_CFLAGS}) # Requested by Qt ... -target_link_libraries (QtVtk PUBLIC QtUtil::QtUtil VtkContrib::VtkContrib) +target_link_libraries (QtVtk PUBLIC PrefsQt::PrefsQt VtkContrib::VtkContrib) # Etre capable une fois installée de retrouver vtk*, ... : # (Rem : en son absence on a Set runtime path of "/tmp/pignerol/install/lib/libQtVtk.so.5.0.0" to "") ... diff --git a/src/QtVtk/QtVTKPrintHelper.cpp b/src/QtVtk/QtVTKPrintHelper.cpp index 5ea1bdf..7248cec 100644 --- a/src/QtVtk/QtVTKPrintHelper.cpp +++ b/src/QtVtk/QtVTKPrintHelper.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -142,47 +143,6 @@ QtVTKPrintHelper::PrinterStatus QtVTKPrintHelper::print (vtkRenderWindow& window } // QtVTKPrintHelper::print -/** - * @return La première extension du filtre Qt reçu en argument (format NOM (*.ext1 *.ext2 ... *.extn). - */ -static string getFirstExtension (const string& filter) // v 7.4.0 -{ - UTF8String prepared (filter); - prepared.replace (string ("("), string (" "), true); // => nom *.ext1) - prepared.replace (string ("*"), string (""), true); // => nom .ext1) - prepared.replace (string (")"), string (""), true); // => nom *.ext1 - istringstream stream (prepared.utf8 ( )); - string name, ext; - stream >> name >> ext; - - - if ((false == stream.fail ( )) && (false == stream.bad ( ))) - return ext; - - return string ( ); -} // getFirstExtension - - -/** - * @param Nom de fichier proposé - * @param Filtre Qt utilisé lors du choix du fichier - * @return Le nom de fichier avec extension. Si le nom proposé n'en n'a pas alors la première du filtre est ajoutée. - */ -static string completeFileName (const string& path, const string& filter) // v 7.4.0 -{ - File file (path); - if (0 != file.getExtension ( ).length ( )) - return path; - - // Le fichier n'a pas d'extension, on rajoute la première du filtre - const string ext = getFirstExtension (filter); - UTF8String newPath (charset); - newPath << path << ext; - - return newPath.utf8 ( ); -} // completeFileName - - QtVTKPrintHelper::PrinterStatus QtVTKPrintHelper::printToFile (vtkRenderWindow& window, QWidget* top) { QPrinter printer; @@ -219,8 +179,7 @@ QtVTKPrintHelper::PrinterStatus QtVTKPrintHelper::printToFile (vtkRenderWindow& if (1 != fileList.size ( )) throw Exception ("Erreur, la liste de fichiers d'impression ne contient pas qu'un fichier."); -// string fileName (fileList [0].toStdString ( )); - string fileName (completeFileName (fileList [0].toStdString ( ), dialog.selectedNameFilter ( ).toStdString ( ))); // v 7.4.0 + string fileName (QtFileDialogUtilities::completeFileName (fileList [0].toStdString ( ), dialog.selectedNameFilter ( ).toStdString ( ))); // v 7.4.0 File file (fileName); if (false == file.isWritable ( )) @@ -277,7 +236,7 @@ QtVTKPrintHelper::PrinterStatus QtVTKPrintHelper::printTo4kFile (vtkRenderWindow if (1 != fileList.size ( )) throw Exception ("Erreur, la liste de fichiers d'impression ne contient pas qu'un fichier."); - const string fileName (completeFileName (fileList [0].toStdString ( ), dialog.selectedNameFilter ( ).toStdString ( ))); + const string fileName (QtFileDialogUtilities::completeFileName (fileList [0].toStdString ( ), dialog.selectedNameFilter ( ).toStdString ( ))); File file (fileName); if (false == file.isWritable ( )) { diff --git a/src/QtVtk/QtVtk.qrc b/src/QtVtk/QtVtk.qrc new file mode 100644 index 0000000..e7edcdb --- /dev/null +++ b/src/QtVtk/QtVtk.qrc @@ -0,0 +1,29 @@ + + + images/add_viewpoint.png + images/remove_viewpoint.png + images/remove_viewpoints.png + images/export_viewpoints.png + images/import_viewpoints.png + images/viewpoint_01.png + images/viewpoint_02.png + images/viewpoint_03.png + images/viewpoint_04.png + images/viewpoint_05.png + images/viewpoint_06.png + images/viewpoint_07.png + images/viewpoint_08.png + images/viewpoint_09.png + images/viewpoint_10.png + images/viewpoint_11.png + images/viewpoint_12.png + images/viewpoint_13.png + images/viewpoint_14.png + images/viewpoint_15.png + images/viewpoint_16.png + images/viewpoint_17.png + images/viewpoint_18.png + images/viewpoint_19.png + images/viewpoint_20.png + + diff --git a/src/QtVtk/QtVtkViewDefinitionDialog.cpp b/src/QtVtk/QtVtkViewDefinitionDialog.cpp new file mode 100644 index 0000000..2b5d980 --- /dev/null +++ b/src/QtVtk/QtVtkViewDefinitionDialog.cpp @@ -0,0 +1,179 @@ +#include "QtVtk/QtVtkViewDefinitionDialog.h" +#include +#include +#include + +#include + +#include + +#include +#include + + +USING_STD +USING_UTIL + +static const Charset charset ("àéèùô"); +USE_ENCODING_AUTODETECTION + +/** + * Aide pour positionner un widget au centre de "son parent". + * Utile depuis le passage à Qt 5 : une boite de dialogue modale ayant un parent est positionnée au centre du parent, ce qui est très bien, mais si on la + * déplace le parent suit le mouvement ... Donc pas moyen de voir ce qu'il y a dessous la boite de dialogue. + * => créer la boite de dialogue sans parent, et utiliser cette macro juste au moment de l'afficher. + */ +#ifndef QTVTK_CENTER_DIALOG +#define LEM_CENTER_DIALOG(dlg,parent) \ +if ((0 != dlg) && (0 != parent)) \ +{ \ + QRect pfg = parent->frameGeometry ( ); \ + QSize sz = dlg->size ( ); \ + dlg->move (pfg.x ( ) + (pfg.width ( ) - sz.width ( )) / 2, \ + pfg.y ( ) + (pfg.height ( ) - sz.height ( )) / 2); \ +} +#endif // LEM_CENTER_DIALOG + + +QtVtkViewDefinitionDialog::QtVtkViewDefinitionDialog ( + QWidget* parent, const string& title, bool modal, const UTF8String& name, const UTF8String& comment, + double position [3], double focal [3], double viewUp [3], double roll, + vtkRenderer* renderer, const string& helpURL, const string& helpTag) + : QDialog (0, true == modal ? (Qt::WindowFlags)(QtConfiguration::modalDialogWFlags | Qt::WindowStaysOnTopHint) : (Qt::WindowFlags)(QtConfiguration::amodalDialogWFlags | Qt::WindowStaysOnTopHint)), _viewDefinitionPanel (0), _closurePanel (0) +{ + setModal (modal); + setWindowTitle (QSTR (title)); + + // Creation de l'ihm : + QVBoxLayout* layout = new QVBoxLayout (this); + layout->setMargin (QtConfiguration::margin); + layout->setSizeConstraint (QLayout::SetMinimumSize); + QtGroupBox* frame = new QtGroupBox (QSTR ("Paramètres de la vue"), this, "frame"); + QVBoxLayout* frameLayout = new QVBoxLayout (frame); + layout->addWidget (frame); + frame->setLayout (frameLayout); + frame->setMargin (QtConfiguration::margin); + frame->setSpacing (QtConfiguration::spacing); + _viewDefinitionPanel = new QtVtkViewDefinitionPanel (frame, title, name, comment, position, focal, viewUp, roll, renderer); + _viewDefinitionPanel->adjustSize ( ); + frameLayout->addWidget (_viewDefinitionPanel); + + layout->addWidget (new QLabel (" ", this)); + _closurePanel = new QtDlgClosurePanel (this, true, "Appliquer", "Fermer", "Annuler",helpURL, helpTag); + layout->addWidget (_closurePanel); + _closurePanel->setMinimumSize (_closurePanel->sizeHint ( )); + + // Par defaut le bouton OK est artificellement clique par QDialog quand l'utilisateur fait return dans un champ de texte => on inhibe ce comportement par defaut : + _closurePanel->getApplyButton ( )->setAutoDefault (false); + _closurePanel->getApplyButton ( )->setDefault (false); + _closurePanel->getCloseButton ( )->setAutoDefault (false); + _closurePanel->getCloseButton ( )->setDefault (false); + _closurePanel->getCancelButton ( )->setAutoDefault (false); + _closurePanel->getCancelButton ( )->setDefault (false); + connect (_closurePanel->getApplyButton ( ), SIGNAL(clicked ( )), this, SLOT(apply ( ))); + connect (_closurePanel->getCloseButton ( ), SIGNAL(clicked ( )), this, SLOT(close ( ))); + connect (_closurePanel->getCancelButton ( ), SIGNAL(clicked ( )), this, SLOT(reject ( ))); + + layout->activate ( ); + setMinimumSize (layout->sizeHint ( )); + LEM_CENTER_DIALOG (this, parent) +} // QtVtkViewDefinitionDialog::QtVtkViewDefinitionDialog + + +QtVtkViewDefinitionDialog::QtVtkViewDefinitionDialog (const QtVtkViewDefinitionDialog&) +{ + assert (0 && "QtVtkViewDefinitionDialog copy constructor is forbidden."); +} // QtVtkViewDefinitionDialog::QtVtkViewDefinitionDialog (const QtVtkViewDefinitionDialog&) + + +QtVtkViewDefinitionDialog& QtVtkViewDefinitionDialog::operator = (const QtVtkViewDefinitionDialog&) +{ + assert (0 && "QtVtkViewDefinitionDialog assignment operator is forbidden."); + return *this; +} // QtVtkViewDefinitionDialog::operator = + + +QtVtkViewDefinitionDialog::~QtVtkViewDefinitionDialog ( ) +{ +} // QtVtkViewDefinitionDialog::~QtVtkViewDefinitionDialog + + +UTF8String QtVtkViewDefinitionDialog::getName ( ) const +{ + assert ((0 != _viewDefinitionPanel) && "QtVtkViewDefinitionDialog::getName : null view definition panel."); + return _viewDefinitionPanel->getName ( ); +} // QtVtkViewDefinitionDialog::getName + + +UTF8String QtVtkViewDefinitionDialog::getComment ( ) const +{ + assert ((0 != _viewDefinitionPanel) && "QtVtkViewDefinitionDialog::getComment : null view definition panel."); + return _viewDefinitionPanel->getComment ( ); +} // QtVtkViewDefinitionDialog::getComment + + +void QtVtkViewDefinitionDialog::getPosition (double coords [3]) const +{ + assert ((0 != _viewDefinitionPanel) && "QtVtkViewDefinitionDialog::getPosition : null view definition panel."); + _viewDefinitionPanel->getPosition (coords); +} // QtVtkViewDefinitionDialog::getPosition + + +void QtVtkViewDefinitionDialog::getFocalPoint (double coords [3]) const +{ + assert ((0 != _viewDefinitionPanel) && "QtVtkViewDefinitionDialog::getFocalPoint : null view definition panel."); + _viewDefinitionPanel->getFocalPoint (coords); +} // QtVtkViewDefinitionDialog::getFocalPoint + + +void QtVtkViewDefinitionDialog::getViewUp (double direction [3]) const +{ + assert ((0 != _viewDefinitionPanel) && "QtVtkViewDefinitionDialog::getViewUp : null view definition panel."); + _viewDefinitionPanel->getViewUp (direction); +} // QtVtkViewDefinitionDialog::getViewUp + + +double QtVtkViewDefinitionDialog::getRoll ( ) const +{ + assert ((0 != _viewDefinitionPanel) && "QtVtkViewDefinitionDialog::getRoll : null view definition panel."); + return _viewDefinitionPanel->getRoll ( ); +} // QtVtkViewDefinitionDialog::getRoll + + +QPushButton* QtVtkViewDefinitionDialog::getApplyButton ( ) const +{ + assert ((0 != _closurePanel) && "QtVtkViewDefinitionDialog::getApplyButton : null closure panel."); + return _closurePanel->getApplyButton ( ); +} // QtVtkViewDefinitionDialog::getApplyButton + + +QPushButton* QtVtkViewDefinitionDialog::getCancelButton ( ) const +{ + assert ((0 != _closurePanel) && "QtVtkViewDefinitionDialog::getCancelButton : null closure panel."); + return _closurePanel->getCancelButton ( ); +} // QtVtkViewDefinitionDialog::getCancelButton + + +void QtVtkViewDefinitionDialog::apply ( ) +{ + assert ((0 != _viewDefinitionPanel) && "QtVtkViewDefinitionDialog::apply : null view definition panel."); + _viewDefinitionPanel->apply ( ); +} // QtVtkViewDefinitionDialog::apply + + +void QtVtkViewDefinitionDialog::close ( ) +{ + QDialog::accept ( ); + emit applied (this); +} // QtVtkViewDefinitionDialog::close + + +void QtVtkViewDefinitionDialog::reject ( ) +{ + assert ((0 != _viewDefinitionPanel) && "QtVtkViewDefinitionDialog::reject : null view definition panel."); + _viewDefinitionPanel->reset ( ); + QDialog::reject ( ); + emit canceled (this); +} // QtVtkViewDefinitionDialog::reject + + diff --git a/src/QtVtk/QtVtkViewDefinitionPanel.cpp b/src/QtVtk/QtVtkViewDefinitionPanel.cpp new file mode 100644 index 0000000..bec84f1 --- /dev/null +++ b/src/QtVtk/QtVtkViewDefinitionPanel.cpp @@ -0,0 +1,356 @@ +#include "QtVtk/QtVtkViewDefinitionPanel.h" + +#include +#include +#include +#include +#include + +#include +#include // FLT_MAX +#include // FLT_MAX sous Linux ... + +#include +#include +#include +#include +#include + +#include +#include + + +USING_STD +USING_UTIL + +static const Charset charset ("àéèùô"); +USE_ENCODING_AUTODETECTION + + +// =========================================================================== +// QtVtkViewDefinitionPanel +// =========================================================================== + + + +QtVtkViewDefinitionPanel::QtVtkViewDefinitionPanel (QWidget* parent, const string& appTitle, const UTF8String& name, const UTF8String& comment, + double position [3], double focal [3], double viewUp [3],double roll, vtkRenderer* renderer) + : QWidget (parent), _appTitle (appTitle), _positionPanel (0), _focalPanel (0), _rollTextField (0), _renderer (renderer), _modified (false), _updated (true) +{ + for (int i = 0; i < 3; i++) + { + _initialPosition [i] = _position [i] = position [i]; + _initialFocal [i] = _focal [i] = focal [i]; + _initialViewUp [i] = _viewUp [i] = viewUp [i]; + } // for (int i = 0; i < 3; i++) + _initialRoll = _roll = roll; + + // Creation de l'ihm : + QVBoxLayout* layout = new QVBoxLayout (this); + layout->setSpacing (QtConfiguration::spacing); + layout->setMargin (QtConfiguration::margin); + layout->setSizeConstraint (QLayout::SetMinimumSize); + + // Nom / Commentaire : + QtGroupBox* nameGroupBox = new QtGroupBox ("", this); + QGridLayout* nameLayout = new QGridLayout (nameGroupBox); + nameGroupBox->setLayout (nameLayout); + nameGroupBox->setSpacing (QtConfiguration::spacing); + nameGroupBox->setMargin (QtConfiguration::margin); + nameLayout->setSizeConstraint (QLayout::SetMinimumSize); + QLabel* label = new QLabel ("Nom :", nameGroupBox); + nameLayout->addWidget (label, 0, 0); + _nameTextField = new QtTextField (nameGroupBox); + _nameTextField->setText (UTF8TOQSTRING (name)); + connect (_nameTextField, SIGNAL (returnPressed ( )), this, SLOT (viewFieldValidatedCallback ( ))); + connect (_nameTextField, SIGNAL (textChanged (const QString&)), this, SLOT (viewFieldModifiedCallback (const QString&))); + nameLayout->addWidget (_nameTextField, 0, 1); + label = new QLabel ("Commentaire :", nameGroupBox); + nameLayout->addWidget (label, 1, 0); + _commentTextField = new QtTextField (nameGroupBox); + _commentTextField->setText (UTF8TOQSTRING (comment)); + connect (_commentTextField, SIGNAL (returnPressed ( )), this, SLOT (viewFieldValidatedCallback ( ))); + connect (_commentTextField, SIGNAL (textChanged (const QString&)), this, SLOT (viewFieldModifiedCallback (const QString&))); + nameLayout->addWidget (_commentTextField, 1, 1); + nameGroupBox->adjustSize ( ); + layout->addWidget (nameGroupBox); + + // Position : + _positionPanel = new Qt3DDataPanel (this, "Position", true, "x : ", "y : ", "z : ", position [0], -DBL_MAX, DBL_MAX, position [1], -DBL_MAX, DBL_MAX, position [2], -DBL_MAX, DBL_MAX, false); + connect (_positionPanel->getXTextField ( ), SIGNAL (returnPressed ( )), this, SLOT (viewFieldValidatedCallback ( ))); + connect (_positionPanel->getYTextField ( ), SIGNAL (returnPressed ( )), this, SLOT (viewFieldValidatedCallback ( ))); + connect (_positionPanel->getZTextField ( ), SIGNAL (returnPressed ( )), this, SLOT (viewFieldValidatedCallback ( ))); + connect (_positionPanel->getXTextField ( ), SIGNAL (textChanged (const QString&)), this, SLOT (viewFieldModifiedCallback (const QString&))); + connect (_positionPanel->getYTextField ( ), SIGNAL (textChanged (const QString&)), this, SLOT (viewFieldModifiedCallback (const QString&))); + connect (_positionPanel->getZTextField ( ), SIGNAL (textChanged (const QString&)), this, SLOT (viewFieldModifiedCallback (const QString&))); + layout->addWidget (_positionPanel); + + // Focale : + _focalPanel = new Qt3DDataPanel (this, "Focale", true, "x : ", "y : ", "z : ", focal [0], -DBL_MAX, DBL_MAX, focal [1], -DBL_MAX, DBL_MAX, focal [2], -DBL_MAX, DBL_MAX, false); + connect (_focalPanel->getXTextField ( ), SIGNAL (returnPressed ( )), this, SLOT (viewFieldValidatedCallback ( ))); + connect (_focalPanel->getYTextField ( ), SIGNAL (returnPressed ( )), this, SLOT (viewFieldValidatedCallback ( ))); + connect (_focalPanel->getZTextField ( ), SIGNAL (returnPressed ( )), this, SLOT (viewFieldValidatedCallback ( ))); + connect (_focalPanel->getXTextField ( ), SIGNAL (textChanged (const QString&)), this, SLOT (viewFieldModifiedCallback (const QString&))); + connect (_focalPanel->getYTextField ( ), SIGNAL (textChanged (const QString&)), this, SLOT (viewFieldModifiedCallback (const QString&))); + connect (_focalPanel->getZTextField ( ), SIGNAL (textChanged (const QString&)), this, SLOT (viewFieldModifiedCallback (const QString&))); + layout->addWidget (_focalPanel); + + // Haut : + _viewUpPanel = new Qt3DDataPanel (this, "Direction vers le haut", true, "dx : ", "dy : ", "dz : ", viewUp [0], -DBL_MAX, DBL_MAX, viewUp [1], -DBL_MAX, DBL_MAX, viewUp [2], -DBL_MAX, DBL_MAX, false); + connect (_viewUpPanel->getXTextField ( ), SIGNAL (returnPressed ( )), this, SLOT (viewFieldValidatedCallback ( ))); + connect (_viewUpPanel->getYTextField ( ), SIGNAL (returnPressed ( )), this, SLOT (viewFieldValidatedCallback ( ))); + connect (_viewUpPanel->getZTextField ( ), SIGNAL (returnPressed ( )), this, SLOT (viewFieldValidatedCallback ( ))); + connect (_viewUpPanel->getXTextField ( ), SIGNAL (textChanged (const QString&)), this, SLOT (viewFieldModifiedCallback (const QString&))); + connect (_viewUpPanel->getYTextField ( ), SIGNAL (textChanged (const QString&)), this, SLOT (viewFieldModifiedCallback (const QString&))); + connect (_viewUpPanel->getZTextField ( ), SIGNAL (textChanged (const QString&)), this, SLOT (viewFieldModifiedCallback (const QString&))); + layout->addWidget (_viewUpPanel); + + // Roulis : + QtGroupBox* rollGroupBox = new QtGroupBox ("Roulis", this); + QHBoxLayout* rollLayout = new QHBoxLayout (rollGroupBox); + rollGroupBox->setLayout (rollLayout); + rollGroupBox->setSpacing (QtConfiguration::spacing); + rollGroupBox->setMargin (QtConfiguration::margin); + rollLayout->setSizeConstraint (QLayout::SetMinimumSize); + label = new QLabel ("Angle :", rollGroupBox); + label->setFixedSize (label->sizeHint ( )); + rollLayout->addWidget (label); + _rollTextField = new QtTextField (rollGroupBox); + _rollTextField->setVisibleColumns (4); + _rollTextField->setMaxLength (4); + _rollTextField->setFixedSize (_rollTextField->sizeHint ( )); + _rollTextField->setMaximumSize (_rollTextField->sizeHint ( )); + _rollTextField->setText (QString::number (roll)); + _rollTextField->setValidator (new QDoubleValidator (-360., 360., 4, _rollTextField)); + connect (_rollTextField, SIGNAL (returnPressed ( )), this, SLOT (viewFieldValidatedCallback ( ))); + connect (_rollTextField, SIGNAL (textChanged (const QString&)), this, SLOT (viewFieldModifiedCallback (const QString&))); + rollLayout->addWidget (_rollTextField); + label = new QLabel (QSTR ("(Domaine : -360 à 360 degrés)"), rollGroupBox); + label->setMinimumSize (label->sizeHint ( )); + rollLayout->addWidget (label); + rollGroupBox->adjustSize ( ); + layout->addWidget (rollGroupBox); + + layout->activate ( ); + setMinimumSize (layout->sizeHint ( )); +} // QtVtkViewDefinitionPanel::QtVtkViewDefinitionPanel + + +QtVtkViewDefinitionPanel::QtVtkViewDefinitionPanel (const QtVtkViewDefinitionPanel&) +{ + assert (0 && "QtVtkViewDefinitionPanel copy constructor is forbidden."); +} // QtVtkViewDefinitionPanel::QtVtkViewDefinitionPanel (const QtVtkViewDefinitionPanel&) + + +QtVtkViewDefinitionPanel& QtVtkViewDefinitionPanel::operator = (const QtVtkViewDefinitionPanel&) +{ + assert (0 && "QtVtkViewDefinitionPanel assignment operator is forbidden."); + return *this; +} // QtVtkViewDefinitionPanel::operator = + + +QtVtkViewDefinitionPanel::~QtVtkViewDefinitionPanel ( ) +{ +} // QtVtkViewDefinitionPanel::~QtVtkViewDefinitionPanel + + +void QtVtkViewDefinitionPanel::setPosition (double coords [3]) +{ + assert ((0 != _positionPanel) && "QtVtkViewDefinitionPanel::setPosition : null position panel."); + _positionPanel->setX (coords [0]); + _positionPanel->setY (coords [1]); + _positionPanel->setZ (coords [2]); + _updated = false; +} // QtVtkViewDefinitionPanel::setPosition + + +void QtVtkViewDefinitionPanel::setFocalPoint (double coords [3]) +{ + assert ((0 != _focalPanel) && "QtVtkViewDefinitionPanel::setFocalPoint : null focal panel."); + _focalPanel->setX (coords [0]); + _focalPanel->setY (coords [1]); + _focalPanel->setZ (coords [2]); + _updated = false; +} // QtVtkViewDefinitionPanel::setFocalPoint + + +void QtVtkViewDefinitionPanel::setViewUp (double coords [3]) +{ + assert ((0 != _focalPanel) && "QtVtkViewDefinitionPanel::setViewUp : null view up panel."); + _viewUpPanel->setX (coords [0]); + _viewUpPanel->setY (coords [1]); + _viewUpPanel->setZ (coords [2]); + _updated = false; +} // QtVtkViewDefinitionPanel::setViewUp + + +void QtVtkViewDefinitionPanel::setRoll (double roll) +{ + assert ((0 != _rollTextField) && "QtVtkViewDefinitionPanel::setRoll : null roll text field."); + _rollTextField->setText (QString::number (roll)); + _updated = false; +} // QtVtkViewDefinitionPanel::setRoll + + +void QtVtkViewDefinitionPanel::updateData ( ) +{ + bool modified = false; + int i = 0; + + double param3D [3]; + getPosition (param3D); + for (i = 0; i < 3; i++) + { + if (param3D [i] != _position [i]) + { + _position [i] = param3D [i]; + modified = true; + } // if (param3D [i] != _position [i]) + } // for (i = 0; i < 3; i++) + + getFocalPoint (param3D); + for (i = 0; i < 3; i++) + { + if (param3D [i] != _focal [i]) + { + _focal [i] = param3D [i]; + modified = true; + } // if (param3D [i] != _focal [i]) + } // for (i = 0; i < 3; i++) + + getViewUp (param3D); + for (i = 0; i < 3; i++) + { + if (param3D [i] != _viewUp [i]) + { + _viewUp [i] = param3D [i]; + modified = true; + } // if (param3D [i] != _focal [i]) + } // for (i = 0; i < 3; i++) + + if (_roll != getRoll ( )) + { + _roll = getRoll ( ); + modified = true; + } // if (_roll != getRoll ( )) + + if (false == modified) + return; + + setModified (true); + setUpdated (false); +} // QtVtkViewDefinitionPanel::updateData + + +UTF8String QtVtkViewDefinitionPanel::getName ( ) const +{ + assert ((0 != _nameTextField) && "QtVtkViewDefinitionPanel::getName : null name textfield."); + return QtUnicodeHelper::qstringToUTF8String (_nameTextField->text ( )); +} // QtVtkViewDefinitionPanel::getName + + +UTF8String QtVtkViewDefinitionPanel::getComment ( ) const +{ + assert ((0 != _commentTextField) && "QtVtkViewDefinitionPanel::getComment : null comment textfield."); + return QtUnicodeHelper::qstringToUTF8String (_commentTextField->text ( )); +} // QtVtkViewDefinitionPanel::getComment + + +void QtVtkViewDefinitionPanel::getPosition (double coords [3]) const +{ + assert ((0 != _positionPanel) && "QtVtkViewDefinitionPanel::getPosition : null position panel."); + coords [0] = _positionPanel->getX ( ); + coords [1] = _positionPanel->getY ( ); + coords [2] = _positionPanel->getZ ( ); +} // QtVtkViewDefinitionPanel::getPosition + + +void QtVtkViewDefinitionPanel::getFocalPoint (double coords [3]) const +{ + assert ((0 != _focalPanel) && "QtVtkViewDefinitionPanel::getFocalPoint : null focal panel."); + coords [0] = _focalPanel->getX ( ); + coords [1] = _focalPanel->getY ( ); + coords [2] = _focalPanel->getZ ( ); +} // QtVtkViewDefinitionPanel::getFocalPoint + + +void QtVtkViewDefinitionPanel::getViewUp (double direction [3]) const +{ + assert ((0 != _viewUpPanel) && "QtVtkViewDefinitionPanel::getViewUp : null view up panel."); + direction [0] = _viewUpPanel->getX ( ); + direction [1] = _viewUpPanel->getY ( ); + direction [2] = _viewUpPanel->getZ ( ); +} // QtVtkViewDefinitionPanel::getViewUp + + +double QtVtkViewDefinitionPanel::getRoll ( ) const +{ + assert ((0 != _rollTextField) && "QtVtkViewDefinitionPanel::getRoll : null roll text field."); + bool ok = true; + return _rollTextField->text ( ).toDouble (&ok); +} // QtVtkViewDefinitionPanel::getRoll + + +void QtVtkViewDefinitionPanel::apply ( ) +{ + if (true == isUpdated ( )) + return; + QtAutoWaitingCursor waitingCursor (true); + updateData ( ); + + vtkCamera* camera = 0 == _renderer ? 0 : _renderer->GetActiveCamera ( ); + if ((0 == _renderer) || (0 == camera)) + return; + + double position [3] = { 0., 0., 0. }; + double focal [3] = { 0., 0., 0. }; + double viewUp [3] = { 0., 0., 0. }; + double roll = getRoll ( ); + getPosition (position); + getFocalPoint (focal); + getViewUp (viewUp); + camera->SetPosition (position); + camera->SetFocalPoint (focal); + camera->SetViewUp (viewUp); + camera->SetRoll (roll); + // ResetCameraClippingRange : en son absence il y a de bonnes chances + // que certains objets ne soient plus affiches bien qu'ils devraient etre + // visibles. + _renderer->ResetCameraClippingRange ( ); + if (0 != _renderer->GetRenderWindow ( )) + _renderer->GetRenderWindow ( )->Render ( ); + + setUpdated (true); +} // QtVtkViewDefinitionPanel::apply + + +void QtVtkViewDefinitionPanel::reset ( ) +{ + if (false == isModified ( )) + return; + + setPosition (_initialPosition); + setFocalPoint (_initialFocal); + setViewUp (_initialViewUp); + setRoll (_initialRoll); + apply ( ); + setModified (false); +} // QtVtkViewDefinitionPanel::reset + + +void QtVtkViewDefinitionPanel::viewFieldModifiedCallback (const QString&) +{ +// setModified (true); + setUpdated (false); +} // QtVtkViewDefinitionPanel::viewFieldModifiedCallback + + +void QtVtkViewDefinitionPanel::viewFieldValidatedCallback ( ) +{ + updateData ( ); + + if (false == isUpdated ( )) + apply ( ); +} // QtVtkViewDefinitionPanel::viewFieldModifiedCallback + + diff --git a/src/QtVtk/QtVtkViewPointToolBar.cpp b/src/QtVtk/QtVtkViewPointToolBar.cpp new file mode 100644 index 0000000..9898626 --- /dev/null +++ b/src/QtVtk/QtVtkViewPointToolBar.cpp @@ -0,0 +1,266 @@ +#include "QtVtk/QtVtkViewPointToolBar.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + + +using namespace std; +using namespace TkUtil; +using namespace Preferences; + +static const Charset charset ("àéèùô"); +USE_ENCODING_AUTODETECTION + + + + +QtVtkViewPointToolBar::QtVtkViewPointToolBar (QWidget* parent, vtkCamera& camera, vtkRenderer* renderer) + : QToolBar (parent), _viewPointButtons ( ), _nextButton (1), _camera (&camera), _renderer (renderer) +{ + _camera->Register (0); + if (0 != _renderer) + _renderer->Register (0); + + QAction* action = new QAction (QIcon(":/images/add_viewpoint.png"), "+", this); + connect (action, SIGNAL (triggered ( )), this, SLOT (newViewPointCallback ( ))); + QToolButton* button = new QToolButton (this); + button->setText ("+"); + button->setDefaultAction (action); + addWidget (button); + action = new QAction (QIcon(":/images/remove_viewpoints.png"), "Réinitialiser", this); + connect (action, SIGNAL (triggered ( )), this, SLOT (initializeCallback ( ))); + button = new QToolButton (this); + button->setDefaultAction (action); + addWidget (button); + action = new QAction (QIcon(":/images/export_viewpoints.png"), "Exporter ...", this); + connect (action, SIGNAL (triggered ( )), this, SLOT (exportViewPointsCallback ( ))); + button = new QToolButton (this); + button->setDefaultAction (action); + addWidget (button); + action = new QAction (QIcon(":/images/import_viewpoints.png"), "Importer ...", this); + connect (action, SIGNAL (triggered ( )), this, SLOT (importViewPointsCallback ( ))); + button = new QToolButton (this); + button->setDefaultAction (action); + addWidget (button); +} // QtVtkViewPointToolBar::QtVtkViewPointToolBar + + +QtVtkViewPointToolBar::QtVtkViewPointToolBar (const QtVtkViewPointToolBar& tb) + : QToolBar ( ), _camera (0), _renderer (0) +{ + assert (0 && "QtVtkViewPointToolBar copy constructor is not allowed."); +} // QtVtkViewPointToolBar::QtVtkViewPointToolBar + + +QtVtkViewPointToolBar& QtVtkViewPointToolBar::operator = (const QtVtkViewPointToolBar&) +{ + assert (0 && "QtVtkViewPointToolBar assignment operator is not allowed."); + return *this; +} // QtVtkViewPointToolBar::QtVtkViewPointToolBar + + +QtVtkViewPointToolBar::~QtVtkViewPointToolBar ( ) +{ + if (0 != _camera) + _camera->UnRegister (0); + _camera = 0; + if (0 != _renderer) + _renderer->UnRegister (0); + _renderer = 0; +} // QtVtkViewPointToolBar::~QtVtkViewPointToolBar + + +void QtVtkViewPointToolBar::addViewPoint (const QtVtkViewPointToolButton::VtkViewPoint& viewPoint) +{ + assert (0 != _camera); + UTF8String name (charset); + name << "Vue_" << _nextButton; + UTF8String icon (charset); + icon << ":/images/viewpoint_" << TkUtil::setw (2) << _nextButton << ".png"; + QtVtkViewPointToolButton* tb = new QtVtkViewPointToolButton (this, icon.utf8 ( ), viewPoint, *_camera, _renderer); + addWidget (tb); + _viewPointButtons.push_back (tb); + _nextButton++; +} // QtVtkViewPointToolBar::addViewPoint + + +void QtVtkViewPointToolBar::removeViewPoint (QtVtkViewPointToolButton& viewPointButton) +{ + for (vector::iterator ittb = _viewPointButtons.begin ( ); _viewPointButtons.end ( ) != ittb; ittb++) + { + if (&viewPointButton == *ittb) + { +// _nextButton--; // NON, tant qu'on ne supporte pas les trous dans la numérotation ! +if (2 == _nextButton) _nextButton--; // => En attendant ;) + _viewPointButtons.erase (ittb); + viewPointButton.deleteLater ( ); + return; + } // if (&viewPointButton == *ittb) + } // for (vector::iterator ittb = _viewPointButtons.begin ( ); _viewPointButtons.end ( ) != ittb; ittb++) + + UTF8String error (charset); + error << "La barre d'outils \"Points de vue\" ne contient pas le point de vue \"" << viewPointButton.getViewPoint ( ).name << "\" : impossibilité de l'enlever."; + throw Exception (error); +} // QtVtkViewPointToolBar::removeViewPoint + + +void QtVtkViewPointToolBar::newViewPointCallback ( ) +{ + assert (0 != _camera); + UTF8String name (charset); + name << "Vue_" << _nextButton; + UTF8String icon (charset); + icon << ":/images/viewpoint_" << TkUtil::setw (2) << _nextButton << ".png"; + QtVtkViewPointToolButton* tb = new QtVtkViewPointToolButton (this, icon.utf8 ( ), name.utf8 ( ), *_camera, _renderer); + addWidget (tb); + _viewPointButtons.push_back (tb); + _nextButton++; +} // QtVtkViewPointToolBar::newViewPointCallback + + +void QtVtkViewPointToolBar::initializeCallback ( ) +{ + vector buttons = _viewPointButtons; + _nextButton = 1; + _viewPointButtons.clear ( ); + for (vector::iterator ittb = buttons.begin ( ); buttons.end ( ) != ittb; ittb++) + (*ittb)->deleteLater ( ); +} // QtVtkViewPointToolBar::initializeCallback + + +void QtVtkViewPointToolBar::exportViewPointsCallback ( ) +{ + if (true == _viewPointButtons.empty ( )) + { + QtMessageBox::displayErrorMessage (this, "Exportation des points de vue", UTF8String ("Absence de point de vue à exporter.", charset)); + return; + } // if (true == _viewPointButtons.empty ( )) + + static QString lastDir (Process::getCurrentDirectory ( ).c_str ( )); + UTF8String formats (charset); + formats << "XML (*.xml);;"; + QFileDialog dialog (this, "Exporter les points de vue", lastDir, UTF8TOQSTRING (formats)); + dialog.setOption (QFileDialog::DontUseNativeDialog); + dialog.setFileMode (QFileDialog::AnyFile); + dialog.setAcceptMode (QFileDialog::AcceptSave); + + if (QDialog::Accepted == dialog.exec ( )) + { + QtAutoWaitingCursor cursor (true); + + QStringList fileList = dialog.selectedFiles ( ); + if (1 != fileList.size ( )) + throw Exception ("Erreur, la liste de fichiers d'exportation de points de vue ne contient pas qu'un fichier."); + + string fileName (QtFileDialogUtilities::completeFileName (fileList [0].toStdString ( ), dialog.selectedNameFilter ( ).toStdString ( ))); + File file (fileName); + + if (false == file.isWritable ( )) + { + cursor.hide ( ); + UTF8String message (charset); + message << "Exportation des points de vue impossible dans le fichier \n" << file.getFullFileName ( ) << " :" << "\n" + << " absence de droits en écriture."; + QtMessageBox::displayErrorMessage (this, "Exportation des points de vue", message); + return; + } // if (false == file.isWritable ( )) + + lastDir = file.getPath ( ).getFullFileName ( ).c_str ( ); + + try + { + unique_ptr
mainSection (new Section (UTF8String ("QtVtk", charset), UTF8String ("Définitions de points de vue pour applications 3D", charset))); + for (vector::const_iterator ittb = _viewPointButtons.begin ( ); _viewPointButtons.end ( ) != ittb; ittb++) + { + Section* viewPointSection = QtVtkViewPointToolButton::viewPointToSection ((*ittb)->getViewPoint ( )); + mainSection->addSection (viewPointSection); + } + XMLLoader::save (*mainSection, file.getFullFileName ( ).c_str ( )); + } + catch (const Exception& exc) + { + UTF8String message (charset); + message << "Exportation des points de vue impossible dans le fichier \n" << file.getFullFileName ( ) << " :" << "\n" << exc.getFullMessage ( ); + QtMessageBox::displayErrorMessage (this, "Exportation de points de vue", message); + } + catch (...) + { + UTF8String message (charset); + message << "Exportation des points de vue impossible dans le fichier \n" << file.getFullFileName ( ) << " :" << " erreur non documentée."; + QtMessageBox::displayErrorMessage (this, "Exportation de points de vue", message); + } + } // if (QDialog::Accepted == dialog.exec ( )) + +} // QtVtkViewPointToolBar::exportViewPointsCallback + + +void QtVtkViewPointToolBar::importViewPointsCallback ( ) +{ + static QString lastDir (Process::getCurrentDirectory ( ).c_str ( )); + UTF8String formats (charset); + formats << "XML (*.xml);;"; + QFileDialog dialog (this, "Importer des points de vue", lastDir, UTF8TOQSTRING (formats)); + dialog.setOption (QFileDialog::DontUseNativeDialog); + dialog.setFileMode (QFileDialog::ExistingFile); + dialog.setAcceptMode (QFileDialog::AcceptOpen); + + if (QDialog::Accepted == dialog.exec ( )) + { + QtAutoWaitingCursor cursor (true); + + QStringList fileList = dialog.selectedFiles ( ); + if (0 == fileList.size ( )) + throw Exception ("Erreur, la liste de fichiers importés de point de vue ne contient pas qu'un fichier."); + + string fileName (QtFileDialogUtilities::completeFileName (fileList [0].toStdString ( ), dialog.selectedNameFilter ( ).toStdString ( ))); + File file (fileName); + + if (false == file.isReadable ( )) + { + cursor.hide ( ); + UTF8String message (charset); + message << "Import de points de vue impossible depuis le fichier \n" << file.getFullFileName ( ) << " :" << "\n" + << " absence de droits en lecture."; + QtMessageBox::displayErrorMessage (this, "Import de points de vue", message); + return; + } // if (false == file.isReadable ( )) + + lastDir = file.getPath ( ).getFullFileName ( ).c_str ( ); + + try + { + unique_ptr
mainSection (new Section (UTF8String ("QtVtk", charset), UTF8String ("Définitions de points de vue pour applications 3D", charset))); + mainSection.reset (XMLLoader::load (file.getFullFileName ( ).c_str ( ))); + const vector viewPoints = mainSection->getSections ( ); + for (vector::const_iterator itvp = viewPoints.begin ( ); viewPoints.end ( ) != itvp; itvp++) + { + addViewPoint (QtVtkViewPointToolButton::sectionToViewPoint (**itvp)); + } // for (vector::const_iterator itvp = viewPoints.begin ( ); viewPoints.end ( ) != itvp; itvp++) + } + catch (const Exception& exc) + { + UTF8String message (charset); + message << "Importation de points de vue impossible depuis le fichier \n" << file.getFullFileName ( ) << " :" << "\n" << exc.getFullMessage ( ); + QtMessageBox::displayErrorMessage (this, "Importation de points de vue", message); + } + catch (...) + { + UTF8String message (charset); + message << "Importation de points de vue impossible depuis le fichier \n" << file.getFullFileName ( ) << " :" << " erreur non documentée."; + QtMessageBox::displayErrorMessage (this, "Importation de points de vue", message); + } + } // if (QDialog::Accepted == dialog.exec ( )) +} // QtVtkViewPointToolBar::importViewPointsCallback diff --git a/src/QtVtk/QtVtkViewPointToolButton.cpp b/src/QtVtk/QtVtkViewPointToolButton.cpp new file mode 100644 index 0000000..1ddd498 --- /dev/null +++ b/src/QtVtk/QtVtkViewPointToolButton.cpp @@ -0,0 +1,403 @@ +#include "QtVtk/QtVtkViewPointToolButton.h" +#include "QtVtk/QtVtkViewDefinitionDialog.h" +#include "QtVtk/QtVtkViewPointToolBar.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +using namespace TkUtil; +using namespace Preferences; +using namespace std; + +static const Charset charset ("àéèùô"); +USE_ENCODING_AUTODETECTION + + +// ====================================================================================================================================== +// LA STRUCTURE QtVtkViewPointToolButton::VtkViewPoint +// ====================================================================================================================================== + +QtVtkViewPointToolButton::VtkViewPoint::VtkViewPoint ( ) + : name ( ), comment ( ), roll (0.) +{ + memset (position, 0, 3 * sizeof (double)); + memset (focalPoint, 0, 3 * sizeof (double)); + memset (viewUp, 0, 3 * sizeof (double)); +} // VtkViewPoint::VtkViewPoint + + +QtVtkViewPointToolButton::VtkViewPoint::VtkViewPoint (const QtVtkViewPointToolButton::VtkViewPoint& vp) + : name (vp.name), comment (vp.comment), roll (vp.roll) +{ + memcpy (position, vp.position, 3 * sizeof (double)); + memcpy (focalPoint, vp.focalPoint, 3 * sizeof (double)); + memcpy (viewUp, vp.viewUp, 3 * sizeof (double)); +} // VtkViewPoint::VtkViewPoint + + +QtVtkViewPointToolButton::VtkViewPoint& QtVtkViewPointToolButton::VtkViewPoint::operator = (const QtVtkViewPointToolButton::VtkViewPoint& vp) +{ + name = vp.name; + comment = vp.comment; + roll = vp.roll; + memcpy (position, vp.position, 3 * sizeof (double)); + memcpy (focalPoint, vp.focalPoint, 3 * sizeof (double)); + memcpy (viewUp, vp.viewUp, 3 * sizeof (double)); + + return *this; +} // VtkViewPoint::operator = + + +QtVtkViewPointToolButton::VtkViewPoint& QtVtkViewPointToolButton::VtkViewPoint::operator = (const vtkCamera& camera) +{ + roll = ((vtkCamera&)camera).GetRoll ( ); + memcpy (position, ((vtkCamera&)camera).GetPosition ( ), 3 * sizeof (double)); + memcpy (focalPoint, ((vtkCamera&)camera).GetFocalPoint ( ), 3 * sizeof (double)); + memcpy (viewUp, ((vtkCamera&)camera).GetViewUp ( ), 3 * sizeof (double)); + + return *this; +} // VtkViewPoint::operator = + + +QtVtkViewPointToolButton::VtkViewPoint::~VtkViewPoint ( ) +{ +} // VtkViewPoint::~VtkViewPoint + + +// ====================================================================================================================================== +// LA CLASSE QtVtkViewPointToolButton +// ====================================================================================================================================== + +Section* QtVtkViewPointToolButton::viewPointToSection (const QtVtkViewPointToolButton::VtkViewPoint& vp) +{ + Section* section = new Section (vp.name, vp.comment); + DoubleTripletNamedValue* position = new DoubleTripletNamedValue (UTF8String ("position", charset), vp.position [0], vp.position [1], vp.position [2]); + DoubleTripletNamedValue* focalPoint = new DoubleTripletNamedValue (UTF8String ("focalPoint", charset), vp.focalPoint [0], vp.focalPoint [1], vp.focalPoint [2]); + DoubleTripletNamedValue* viewUp = new DoubleTripletNamedValue (UTF8String ("viewUp", charset), vp.viewUp [0], vp.viewUp [1], vp.viewUp [2]); + DoubleNamedValue* roll = new DoubleNamedValue (UTF8String ("roll", charset), vp.roll); + section->addNamedValue (position); + section->addNamedValue (focalPoint); + section->addNamedValue (viewUp); + section->addNamedValue (roll); + + return section; +} // QtVtkViewPointToolButton::viewPointToSection + + +QtVtkViewPointToolButton::VtkViewPoint QtVtkViewPointToolButton::sectionToViewPoint (const Section& section) +{ + QtVtkViewPointToolButton::VtkViewPoint vp; + + vp.name = section.getName ( ); + vp.comment = section.getComment ( ); + try + { + DoubleTripletNamedValue* pos = dynamic_cast(&(section.getNamedValue (UTF8String ("position", charset)))); + if (0 != pos) + { + vp.position [0] = pos->getX ( ); + vp.position [1] = pos->getY ( ); + vp.position [2] = pos->getZ ( ); + } // if (0 != pos) + } + catch (...) + { + } + + try + { + DoubleTripletNamedValue* fp = dynamic_cast(&(section.getNamedValue (UTF8String ("focalPoint", charset)))); + if (0 != fp) + { + vp.focalPoint [0] = fp->getX ( ); + vp.focalPoint [1] = fp->getY ( ); + vp.focalPoint [2] = fp->getZ ( ); + } // if (0 != fp) + } + catch (...) + { + } + + try + { + DoubleTripletNamedValue* vu = dynamic_cast(&(section.getNamedValue (UTF8String ("viewUp", charset)))); + if (0 != vu) + { + vp.viewUp [0] = vu->getX ( ); + vp.viewUp [1] = vu->getY ( ); + vp.viewUp [2] = vu->getZ ( ); + } // if (0 != vu) + } + catch (...) + { + } + + try + { + DoubleNamedValue* r = dynamic_cast(&(section.getNamedValue (UTF8String ("roll", charset)))); + if (0 != r) + vp.roll = r->getValue ( ); + } + catch (...) + { + } + + return vp; +} // QtVtkViewPointToolButton::sectionToViewPoint + + +QtVtkViewPointToolButton::QtVtkViewPointToolButton (QWidget* parent, const std::string& icon, const TkUtil::UTF8String& name, vtkCamera& camera, vtkRenderer* renderer) + : QToolButton (parent), _viewPoint ( ), _camera (&camera), _renderer (renderer) +{ + setText (UTF8TOQSTRING (name)); + setIcon (QIcon (icon.c_str ( ))); + _viewPoint.name = name; + _viewPoint = *_camera; + setToolButtonStyle (Qt::ToolButtonIconOnly); + setPopupMode (QToolButton::MenuButtonPopup); + _camera->Register (0); + if (0 != _renderer) + _renderer->Register (0); + + QMenu* menu = new QMenu (this); + QAction* action = new QAction ("Appliquer", this); + connect (action, SIGNAL (triggered ( )), this, SLOT (applyViewPointCallback ( ))); + menu->addAction (action); + action = new QAction ("Modifier ...", this); + connect (action, SIGNAL (triggered ( )), this, SLOT (editViewPointCallback ( ))); + menu->addAction (action); + action = new QAction ("Supprimer ...", this); + connect (action, SIGNAL (triggered ( )), this, SLOT (removeViewPointCallback ( ))); + menu->addAction (action); + action = new QAction ("Exporter ...", this); + connect (action, SIGNAL (triggered ( )), this, SLOT (exportViewPointCallback ( ))); + menu->addAction (action); + setMenu (menu); +} // QtVtkViewPointToolButton::QtVtkViewPointToolButton + + +QtVtkViewPointToolButton::QtVtkViewPointToolButton (QWidget* parent, const string& icon, const QtVtkViewPointToolButton::VtkViewPoint& viewPoint, vtkCamera& camera, vtkRenderer* renderer) + : QToolButton (parent), _viewPoint (viewPoint), _camera (&camera), _renderer (renderer) +{ + setText (UTF8TOQSTRING (_viewPoint.name)); + setToolTip (UTF8TOQSTRING (_viewPoint.comment)); + setIcon (QIcon (icon.c_str ( ))); + setToolButtonStyle (Qt::ToolButtonIconOnly); + setPopupMode (QToolButton::MenuButtonPopup); + _camera->Register (0); + if (0 != _renderer) + _renderer->Register (0); + + QMenu* menu = new QMenu (this); + QAction* action = new QAction ("Appliquer", this); + connect (action, SIGNAL (triggered ( )), this, SLOT (applyViewPointCallback ( ))); + menu->addAction (action); + action = new QAction ("Modifier ...", this); + connect (action, SIGNAL (triggered ( )), this, SLOT (editViewPointCallback ( ))); + menu->addAction (action); + action = new QAction ("Supprimer ...", this); + connect (action, SIGNAL (triggered ( )), this, SLOT (removeViewPointCallback ( ))); + menu->addAction (action); + action = new QAction ("Exporter ...", this); + connect (action, SIGNAL (triggered ( )), this, SLOT (exportViewPointCallback ( ))); + menu->addAction (action); + setMenu (menu); +} // QtVtkViewPointToolButton::QtVtkViewPointToolButton + + +QtVtkViewPointToolButton::QtVtkViewPointToolButton (const QtVtkViewPointToolButton& tb) + : QToolButton ( ), _viewPoint ( ), _camera (0), _renderer (0) +{ + assert (0 && "QtVtkViewPointToolButton copy constructor is not allowed."); +} // QtVtkViewPointToolButton::QtVtkViewPointToolButton + + +QtVtkViewPointToolButton& QtVtkViewPointToolButton::operator = (const QtVtkViewPointToolButton&) +{ + assert (0 && "QtVtkViewPointToolButton assignment operator is not allowed."); + return *this; +} // QtVtkViewPointToolButton::QtVtkViewPointToolButton + + +QtVtkViewPointToolButton::~QtVtkViewPointToolButton ( ) +{ + if (0 != _camera) + _camera->UnRegister (0); + _camera = 0; + if (0 != _renderer) + _renderer->UnRegister (0); + _renderer = 0; +} // QtVtkViewPointToolButton::~QtVtkViewPointToolButton + + +const QtVtkViewPointToolButton::VtkViewPoint& QtVtkViewPointToolButton::getViewPoint ( ) const +{ + return _viewPoint; +} // QtVtkViewPointToolButton::getViewPoint + + +void QtVtkViewPointToolButton::setViewPoint (const QtVtkViewPointToolButton::VtkViewPoint& vp) +{ + _viewPoint = vp; + setText (UTF8TOQSTRING (_viewPoint.name)); + setToolTip (UTF8TOQSTRING (_viewPoint.comment)); + applyViewPointCallback ( ); +} // QtVtkViewPointToolButton::setViewPoint + + +void QtVtkViewPointToolButton::applyViewPointCallback ( ) +{ + assert (0 != _camera && "QtVtkViewPointToolButton::applyViewPointCallback : null camera"); + _camera->SetPosition (_viewPoint.position); + _camera->SetFocalPoint (_viewPoint.focalPoint); + _camera->SetViewUp (_viewPoint.viewUp); + _camera->SetRoll (_viewPoint.roll); + + if (0 != _renderer) + { + _renderer->ResetCameraClippingRange ( ); + if (0 != _renderer->GetRenderWindow ( )) + _renderer->GetRenderWindow ( )->Render ( ); + } // if (0 != _renderer) +} // QtVtkViewPointToolButton::applyViewPointCallback + + +void QtVtkViewPointToolButton::editViewPointCallback ( ) +{ + assert (0 != _camera && "QtVtkViewPointToolButton::editViewPointCallback : null camera"); + + try + { + UTF8String dlgTitle (charset); + dlgTitle << "Paramètres de définition de la vue."; + + QtVtkViewPointToolButton::VtkViewPoint vp = getViewPoint ( ); + QtVtkViewDefinitionDialog viewDialog (this, dlgTitle.utf8 ( ).c_str ( ), true, vp.name, vp.comment, vp.position, vp.focalPoint, vp.viewUp, vp.roll, _renderer); + int retVal = viewDialog.exec ( ); + + if (0 == retVal) + { + applyViewPointCallback ( ); // Annule d'éventuelles modifications effectuées par la boite de dialogue. + return; + } + + vp.name = viewDialog.getName ( ); + vp.comment = viewDialog.getComment ( ); + viewDialog.getPosition (vp.position); + viewDialog.getFocalPoint (vp.focalPoint); + viewDialog.getViewUp (vp.viewUp); + vp.roll = viewDialog.getRoll ( ); + + UTF8String message (charset); + message << "Paramètres de la vues modifiés. " + << "Position de la caméra : " + << vp.position [0] << ", " << vp.position [1] << ", " << vp.position [2] + << ". Position de la focale : " + << vp.focalPoint [0] << ", " << vp.focalPoint [1] << ", " << vp.focalPoint [2] + << ". Direction vers le haut : " + << vp.viewUp [0] << ", " << vp.viewUp [1] << ", " << vp.viewUp [2] + << " Roulis : " << vp.roll << " degrés."; + cout << message << endl; + setViewPoint (vp); + } + catch (const Exception& exc) + { + UTF8String message (charset); + message << "Modification du point de vue impossible :" << "\n" << exc.getFullMessage ( ); + QtMessageBox::displayErrorMessage (this, "Modification de point de vue", message); + } + catch (...) + { + UTF8String message (charset); + message << "Modification du point de vue impossible : erreur non renseignée."; + QtMessageBox::displayErrorMessage (this, "Modification de point de vue", message); + } +} // QtVtkViewPointToolButton::editViewPointCallback + + +void QtVtkViewPointToolButton::removeViewPointCallback ( ) +{ + try + { + QtVtkViewPointToolBar* toolbar = dynamic_cast(parentWidget ( )); + if (0 != toolbar) + toolbar->removeViewPoint (*this); + else + deleteLater ( ); + } + catch (...) + { + } +} // QtVtkViewPointToolButton::removeViewPointCallback + + +void QtVtkViewPointToolButton::exportViewPointCallback ( ) +{ + static QString lastDir (Process::getCurrentDirectory ( ).c_str ( )); + UTF8String formats (charset); + formats << "XML (*.xml);;"; + QFileDialog dialog (this, "Exporter le point de vue", lastDir, UTF8TOQSTRING (formats)); + dialog.setOption (QFileDialog::DontUseNativeDialog); + dialog.setFileMode (QFileDialog::AnyFile); + dialog.setAcceptMode (QFileDialog::AcceptSave); + + if (QDialog::Accepted == dialog.exec ( )) + { + QtAutoWaitingCursor cursor (true); + + QStringList fileList = dialog.selectedFiles ( ); + if (1 != fileList.size ( )) + throw Exception ("Erreur, la liste de fichiers d'export de point de vue ne contient pas qu'un fichier."); + + string fileName (QtFileDialogUtilities::completeFileName (fileList [0].toStdString ( ), dialog.selectedNameFilter ( ).toStdString ( ))); + File file (fileName); + + if (false == file.isWritable ( )) + { + cursor.hide ( ); + UTF8String message (charset); + message << "Exportation du point de vue impossible dans le fichier \n" << file.getFullFileName ( ) << " :" << "\n" + << " absence de droits en écriture."; + QtMessageBox::displayErrorMessage (this, "Export de point de vue", message); + return; + } // if (false == file.isWritable ( )) + + lastDir = file.getPath ( ).getFullFileName ( ).c_str ( ); + + try + { + unique_ptr
mainSection (new Section (UTF8String ("QtVtk", charset), UTF8String ("Définitions de points de vue pour applications 3D", charset))); + Section* viewPointSection = QtVtkViewPointToolButton::viewPointToSection (getViewPoint ( )); + mainSection->addSection (viewPointSection); + XMLLoader::save (*mainSection, file.getFullFileName ( ).c_str ( )); + } + catch (const Exception& exc) + { + UTF8String message (charset); + message << "Exportation du point de vue impossible dans le fichier \n" << file.getFullFileName ( ) << " :" << "\n" << exc.getFullMessage ( ); + QtMessageBox::displayErrorMessage (this, "Exportation de point de vue", message); + } + catch (...) + { + UTF8String message (charset); + message << "Exportation du point de vue impossible dans le fichier \n" << file.getFullFileName ( ) << " :" << " erreur non documentée."; + QtMessageBox::displayErrorMessage (this, "Exportation de point de vue", message); + } + } // if (QDialog::Accepted == dialog.exec ( )) +} // QtVtkViewPointToolButton::exportViewPointCallback + + diff --git a/src/QtVtk/cmake/QtVtkConfig.cmake.in b/src/QtVtk/cmake/QtVtkConfig.cmake.in index 2c4dc79..473817e 100644 --- a/src/QtVtk/cmake/QtVtkConfig.cmake.in +++ b/src/QtVtk/cmake/QtVtkConfig.cmake.in @@ -1,6 +1,6 @@ include(CMakeFindDependencyMacro) find_dependency (VtkContrib) -find_dependency (QtUtil) +find_dependency (PrefsQt) @PACKAGE_INIT@ diff --git a/src/QtVtk/images/.viewpoint_15svg.svg b/src/QtVtk/images/.viewpoint_15svg.svg new file mode 100644 index 0000000..77a2970 --- /dev/null +++ b/src/QtVtk/images/.viewpoint_15svg.svg @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + 15 + + diff --git a/src/QtVtk/images/add_viewpoint.png b/src/QtVtk/images/add_viewpoint.png new file mode 100644 index 0000000000000000000000000000000000000000..8818ba800b0871efadd5ce027d629b4460e4c6de GIT binary patch literal 886 zcmV-+1Bv{JP)4kqkr(A_96(P;zblsdI<OnmCkD}-yDj1X+QE3Sj7h5S*Ep2SpB*tzst4+qk9*e{ci73~ z&3kWN_M6=h1VIo4K@bE%5ClOGq-rzn%sYujS~8Abz*G1R&*I9Auh+CX%r)Wz+?{Va z`MLvd;z#tMGv9Rb)4|ox(=$QOF}fbiJE2t;w-OBy#SFzfd6BIpb{^2oQxUT+=0MHb zv9d^&7pukBuJbVmV{VzG`+GLrpKkUkh*=*K*Q{O3k21ND=&!{Ms9i%bPgLkSPxq^u zWh&BXK(xPc@r$NnmhIzo9bxUg=~uN3$r}*25S?3k0~SujV`a9Sqy>!>D|d2uy86K8DrD0bi5?%sYu>{$~);cVBS>xL-#0G zePM}Dn}r62zK@&g{HPT@HLp)&@)BY0D)9IGL(%8R_>JrsUK?TX0^@Hn+mAo%o!O`X z!?-nJCL0P&%s&(z#q9~>F44#|yMAK$dThrZ3(v^<(_lU0*|C#wj#qHVVgR| zLtBF=?_#jd@wIrS=JlsIb%_|!;zRLBgTYH^@C<#U6iZy}$6?H*dWjTvfxYRz`Hjx9 zr$}c}^;71}%gLtE1Z3q)ypTN1$qIW<@EOW);}FWp<6cGzPlByfN-MkDQ!$^E*zq&% z1FBnHqQ9pcCZI4w^dX*J`tMA{ynd2H1;##R_8@-CD#M17PXLs!A)31U9sjn>eMPP~ zs``~$d)oCZTRIJZ=#~0KPsa5B&JD*|a~Qp;7LZg-Tg*c>YtsrNwKM(0T;Zo@cS$5j zuiwJ}9+2I$aMQU>^=|LOmYj3R#Tw19cLzZb1VIo4K@bE%5Cn7n12Qiq;XG^sYXATM M07*qoM6N<$f{a?GQUCw| literal 0 HcmV?d00001 diff --git a/src/QtVtk/images/add_viewpoint.svg b/src/QtVtk/images/add_viewpoint.svg new file mode 100644 index 0000000..46ede54 --- /dev/null +++ b/src/QtVtk/images/add_viewpoint.svg @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/QtVtk/images/export_viewpoints.png b/src/QtVtk/images/export_viewpoints.png new file mode 100644 index 0000000000000000000000000000000000000000..7d2f07d77fc1797b7583446ce0972317eb87bc6d GIT binary patch literal 2143 zcmV-l2%z_gP)wpk~DypcWiYoq35pcNH2>bvz{CGmC z2ok_+z+fdhy9tQ@!Lk5+$16!Y2OI)=8#i>Y|G8JGt!p+fNU3?|rrzdz-~S2i9b3KL zr{d`CyUm@^NpiO_qaVJ*;6MIsoc;p%p<6#SHuasr(WkfXr(?^mybGbwItWC#dgV`a zeX5)KhQ<=YcY%k!S!Zk$LcrwYg5F%vv@yn}mZzC`@Bx{O`gyeJdjXK_`f(IsQ_D6s zw`>O>otBYOaa3iQU`>QTU=0KBzR8xYoisGmk;y3DOWH?Uhtk?oNA3C=?u-nhD$A(K zGLcAxwzloWXYQdWQYY{g;BUa9715Bp)}ScM%uipTd-uVd+IqGpZ@T8rMZX5D6n zhx$Qtv?Uw`&^pRkj(~xWgS=b&!gfw@aX`KRi;Hn?f6xa&S63J8^k;jwK>duqRlB+P z7<02@2m!lyKMUmwV0NzO+2mrJYyEEkuyMl+2;oftFC%7m-H|*60?dwaccd49eS1Ic zg}*lkATj{d*Voh2(_wIl%wN?ThSjdeXn=;pwcEI?rnXlU5T=k|R=7slOT zkCVI*f(=bET3cHY0+J7dmB<0)2p}M^me87*rzGPiSy{DlBd=BD*R4unR#G7{8C>J@ zBtUkqW%LpEmSO!QxKadg>MxIcrE-Ab0K4Fw$h!snsK{5&0a~w~9N>43d$qdlG0x=6 z79e-j-5gK}@?HhV*5OEARBjb;&H;7=AI0eB)j5&Z1u9DbOabg2;8yGeD205H5H2x! zQNY;&Xv<)B-LH%QZgpPB>*M3;{v`{5*^wc_;~jlF@+L927+mSQIv_g*3f0bJDl_^{ z=T@W(NA)o{AX5~W7xJYD;G28}1PD6v$4Dj_v%^mcc{4(%7%JufJqdaxU#ivpk*Dah zKyh*9?>z_jNrHuB%bDwLHg=4q+>MZ?uyqm?LXcdNDmMCsbzaD)B-NI@;Z`?z&H+{q z_}6%X_}ofGtnZgR!1Wss9Lam>!}BU&vre~I%$yX!?WHS0(vbLHesq|m_$TkSS#d&Y<_Fn7h=mf_p zfZ37thas;)d|c$q7Qi5n@U{wk(#V&+6~?MfB#YOInj4(Ytg%A=5+utai5m-+k zP#kI`5}~PiBP}iMwsDmufXG<}og83C{_4B^D5;MS=?6f%H1b9)fd&Gh7=d7|StrXf zQsWsQ-rGk!ViP6B84hI(3S^zCI91 z0_hLw*!nfX;W_}8mlm0ykF&5a$NJh@qS2;GJHR;yIL-OJpWViHU;Vn-*Xrsj=gytW z>;K4+Bl`FF*87F#=4Or`KhC8~mpFU&EHg7REX)qFxotlHb@h$NvP3eOK$c~TINSv< zIS05Uysv)wSyVNDFGd^>d=H^y2Ag@cEEGxDGgu~ixRYfJ0O68HYI+kUb zbUJMkHr@{qtkK1=iKA2j0A2)o$L|e9$?QUi9lq9iS&{R|f82GoLx^nY<7JMV9l($+DayfbIZQaTLIKm1UVs zM*D@@&H;ja@)gMez(rkzGk?AGI&B?0X=#1RqXQHN0rDMSMLzdfQ4~~F)d&X)9bhCu z>nZ96=g$Hf&H`srsfWD&>mM;Wao3XosxE-6JE2g3a5#*bPUl@OJT{7=CrWW-)R=?#FFE z@bs9Rj-LVJsno+W7vDIA5Q1HMzFyu*^WJzh#LTV& z!MrIDtf|rY`zP;L0MMobz?nDC|D1*SX$~HKxrn?F0#zSfBdAa)#EBCpibxvHa1udP zRa1aqK@!Y$Kq>Gm0B9n-5A^=M_Ycvj$$PZ4K1m`m!>z%$%|<6ro}{C_!6cFUYE@_V z3NSf2$=KK!v$M0rXOm1#|I)m+va-U;>I!r5^{idHE-%o;!hejzaXT`l2msm=c^K#& z9T|v@jtmqvP*v5my&vLMb;HBMT)upn)zwwf=`{boKk6se1lohsmT>xi0WWAoTPCCW z`5E9o@KdzMQy&E`pgGVB5_``&0J)+1VRXGTVUI^b6Fx# zc6F@b^Cuny=mAcxEVOteJD@^|CICB^2$bLY>M^=I*Mc(*zP>`ZVv{@tP6MaTpFhvw z!JUZdzXn5FxHCLZ0zyi|w9sVD;s13v=B z8d17Rp~#`cd$29h6kxXrufvl=AK={2Px1Yqp5xrel^$TI5hG(z4{*|VJsY>9>;M2V znKS|?gqr~z?Bh6Z--BEE)epbq305P^m8m9Bg-(@z=@~!!-AjDu$7cb~;6zxgNN88^ zPWJcr^Wl#kqdfZ>!gdU+ltQ?dYp8IItMKr(D`Z?S!auEKc^R;W*atXJ2Oi$rOLxZ_ zMlQVx&`-=L2u*?@B|Nt-Y=@DlklXsEw1$I6Km_9z!_=ytT)f*ERsN3sV*F#eAOW@jGa#RFf`HJW&wH zHW~h%|#M2x;@eBZVVLIAiAIn;t3V)W7$1dlq9RjLEkfmsg)Bf?t zcCv5RR<6D^(dY3Z98g_y3dKC8X)>8ivU$hD96s?3ww|Iq@gl;=2aOc6j-V~VZ=I0L z7cvM@14>8^^0wVlHv&%cDd}Ec&60H-P+ecM*%YQ}lAc@O;FI3~1jfWm*t!-2oV2|8 z3|4{-s1VY<1TM~L@mgrq!b zmCaJXeg!aj%1B@X&v5U5`=?hu<{7V2Cjy|T7cfneTt=h+@F74@)+T+g%06%nhGgid zEqgwI@#z%*x;Y6>_*eEjkq!XR^#W$uWHDc0`|iV7r5vW7U6zon3$AAVM?_W~=l}Wd zSH0@6pI?6p*aE#!#4t=Y_wKd3)zU+WL zpE=m3j$xEo%oo_SeK!E5%tYW*Syejlvn-?5EXj_%SRMUgSvLG#!2Pu?i^8JLBYPhO zprp-KRsc_S<-j!?{_l9z5xFfo2?{|fJ&$3Symws}wy9&4^~NoTMN4sHbl;0(O*z1s zqq?rMnA6$1V-H4tt~v9T6e4jPqndUOY55}8-kt*IRk-G#YNZ4Edbi_gOs7*=w#|l3 z_had~CX8#`Xjvv)E~?#Oyj&f9<)1NX2lVw)OphZF%+JnaS%Qt5w~@W|O3cw*+NjlU z4{NJ+$i;~H50R??E@VX|fC9srE|JpXNQ^6FBl$!oI9bHg7RbAYqXYg(3K(O|=t zP5`X3E`0!18yN*49*8PGTGoFbe4uxK>5ZhvQl3;%PJyAJ$H`4zWqxj&l5Vo?fxRFE zdU|}xAsLUS2BW$UwuykwiJ8iAgb|h15Vi^kLAj`r$)qV6CTlyo0Oy;X|6xH8Dj+Ie z$gk_{LLe$%h?@<`uzEZ|L2zNut?~p~zUVcN zDA5zK6~2>vi&Dt}yyN{3F@NI%mSqKG8V$*MfWm-y)$lfTdHvRmr?z_Tp}qqg<=3xY z#WV$dyY{&cwXtn$Ng-JuWGz@VICUh*<#$9>pMt zIDo6|Dp{}Y3;$#z4!Arv_Qp^$d7CFb`%NbArZ_b86s5&91#Lb8WW11!0u`mJwjSQs zll{kNW#2OrC8zp8|gpqSRgD54pIW55UEbKy!CiZcw1GAIaw4x*w95y6Ek6;TvK zM1uqogNV2gaWjjVWHUHAVI~hX42B6&P(+Q14-DE}5xb6y?vhHSJ5`BYUAORla5w$9 z=X`%%?(I|xG#ZUYqtR$I8earv3!D%zqwd9vz!ZTq0_9;9s1d+Xv_B2 zEKm_fkrUYh&bXvP2-z#&>FO&j@M9Q-41q>Z2$8M?&y^PeTVQvX1(gY*=<=?@k%thO zysLr8LWo@6p#o|j!OdcZpp1N$S`(VCL0>UKP)+^|lcDk-xD{py%E~+B+7nu#eL74n zz}#xfJLC%C3Y9}93+_VQ&*Pjk9`X*kLTKVAG5Pfq%y|Wi&H_~d=ZcrSgMjfTtJ;Q# zuvJX@1kMXA9EAFRVRGJ|tFe{OFj#Gnde_KK85u%Sz!GQ`*fs=p{ZM}z*Q$uQJb-ly zEHOyQ=pk4F{Q~E0nEw{)?kuJ3mzc|o3DyfoFjxqgk)TC7n39gMJV0`#S1d>f3Hqds znF=Q__?_t(0C|w)1)fh+}@dn@*LN58;G`RMP&2M1(6PR>}fG0?V3|+|;K)w*J zvUwDF_vjaB_z3j_P}2geiP|&|R&%}p@`d0p?;WiI8(%i`vkK)asz}&W4w3W4z4zPbQnXU_uwL510_KSWu({hF%4gAAUOQ7#2b={Bd2) zW$uU7I2L*6v*Fu98zy!FyMS_0;Ffzqn90M2 z-13707oWoS|3TSJV5RrFu@6BYk*1_$xco62_V+?n4{!vi_L(D|A&BQ@hK(Ty`0g20 zw30cyOUE!*yh0c$kDP?tz=E%sGaexbB$CkOYSJEn{RNs^=@86iu%QQDyXB?8cXCt> zVM#T#KZfUF$~!0*LNnB)p`#e`4$6e!-SCPb@2VYb2vN$rdWa?j735vL6gLEw + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/QtVtk/images/remove_viewpoints.png b/src/QtVtk/images/remove_viewpoints.png new file mode 100644 index 0000000000000000000000000000000000000000..5647296d93c34d089cc131a3addd880585c936c7 GIT binary patch literal 1762 zcmV<81|9i{P)6ie zV>F@$6hEk85pRH~K}7DsU@|cx%Gd;jF$TN9P`0(FYuCpQ?Pzz*x}L7A>(bx1W$$_S zK2OiyKL2wdL4pJc5+q2_8xSlPjEqvR;ewUX=+z?##t5zmPIT7G~L5rX`+B05rx?@7zi}#bV0^Vo^rw2}jYeHWUf0YYR!hFiPJ*an8oCKR$; zHDs%WG!^r$p!6Ip`W&vimk_%mX81!+vp<|zFu^#|Za}*U&7{kVO#&@slY)N_WlmUq z5XQU!q=)ktk|NY(2^&-cbAU0x!SIuwyum+RCX;@+u^}25%0co?^%tw4`ZP4023%1X zJ-P_;{2`|zJQIvB+dtjO9F>y+66jr)2knFtZdiW^3f=&wUUL!Mr2i^^$Z3N=yEehO z$SnRDUK1E9;In@m*xeUNs{a6P?3wYSL@ms6gX0p^7BYTm=aovmnIp9w#eY``50}E= z2b_UBD&n(4%n;59`e+~{YdF<;DavtJiQ^+~o0#ELTF>8Rd5c60vq1!r$K@bZ0&Qe* z&`vn%f%gtW$(z6oi}TDBY!#$ND9JJ@Pr;jRU&yKG+63nkv-mZ1rra-> z=mn=hTNtnd7}RN}_%y+}6b$9FR{;~M1cnB)(|w%5UN<(KhgZVs7E==h4-1A^yDG5Z zgH5=NL;9Os8Kh_~p9tQrf_Y!T*m+^h(eozwLykl6t2GlkhMau%s)aPQktBf@vC$NA z4m88cJuv!NLWi8Fn-DSx`9sbZ zxLcx4%JcA!2V8Bw%-@9xz9kqe{w3B33>EQdvje-QmgI)Da7)jOA0hfB)fiNf_DT@AA|c|g{*<5np`(_L!fmO z)Ii?*&~K`##^Twb*Pzt7Y;SOos-sL%7AFK7FTmpMFtb>Y+veLB`i23!2=VO^rzSWT zgP{_3C}2X3z|bIewjO7Q*Mm)s@LD+C;?RV^v-)5Y##62`rpZNr&7)MX{x4Wi3KOPx z)iKUYaFzv!m=bo#$pE#G<`=)!6moVq!SY=&YBiA3S=U&Z5Wy26TZe0Y=2og0OBxPp z$mS<*H`S*%LUSYh+e(NRmo_+rFLdPqKSUb3dVs*g%uH&p-u7#GF=!`Ld*Q<)F#CP5 z-+_fUwt`uLoeJ~iW(+W%FpF=$?dMSHFi38z!Ct!}4&Kv6h%yFITi;RqfwS<$Rv5Lc z0p?nZ&2fexv!0=+T=dsMmY#yy8zFV3sm9{jAx;ovy5QF~a6eDxCPIkob0$oK`RCzG z8@N5tpi92y*fhqzsEQhd$pTj z@$p&=5u^)tbys{)zY@W2!N9Jo6C_BGAVGoz39c>w0S4w0Yu@Bwy8r+H07*qoM6N<$ Ef>qu&rvLx| literal 0 HcmV?d00001 diff --git a/src/QtVtk/images/remove_viewpoints.svg b/src/QtVtk/images/remove_viewpoints.svg new file mode 100644 index 0000000..bc9286a --- /dev/null +++ b/src/QtVtk/images/remove_viewpoints.svg @@ -0,0 +1,177 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/QtVtk/images/viewpoint_01.png b/src/QtVtk/images/viewpoint_01.png new file mode 100644 index 0000000000000000000000000000000000000000..79670ad80714d60e9306125e5e70df9c3ad0c25e GIT binary patch literal 893 zcmV-@1A_dCP)VW86XJ^1|B=jx)R-e7FJb+X2K1G z#|iHc_7jetZ5wMJck0=4@RjX&;O)S5<8hc9K8NPe5fG z3~ZjF<2aqKDXuEQ2Er-AKEfM>E%hfLd8K;r=T*ft*Pf(fFH1LN8{Y+mmh$!bU%$1! z1cXMCW9btxvnn1r#oA-6-lmwUs5b!gy3tQw~6Ir&#by$P7=&o%+)RK?$Po?zw2Qa)|w{Vp(za78}jwqeT>4z=^)M(%r; z6+h6pRh6nJAOYI*pW-I$TE&6Ybl;2bF>B(BNWjVbr}%Y@hdyWh5x&`t_4sYJBb)PI z%uHdV{Fa=DPk*NO1V>7o-ibXpQ|%iCB*1XC!~Gf9K13fzzrgGGHrqMQQTH}@dp39d zLkSNYWcfinh2nuN~+| zl5WkJ3cpl&C9Z7U>Bmf7o&9W&2X_9%)rV=>gPz>Nl71K1h09VLH=2IxrO%MuM#C-T z{>U_aKhi(V=zDkzrS#)1N|RUd$x(U^vuqIeD`sn+cdd97dzF77?kaXU^Jg7iQvQFS zSGvn;(Q8!RuiwW2?lS*-cVTW+KHJ-5xOXomEy~w>6h%=KMNt$*Q4~c{v{3vDUHBiv T0YK8H00000NkvXXu0mjf$!(_6 literal 0 HcmV?d00001 diff --git a/src/QtVtk/images/viewpoint_01.svg b/src/QtVtk/images/viewpoint_01.svg new file mode 100644 index 0000000..e9f117f --- /dev/null +++ b/src/QtVtk/images/viewpoint_01.svg @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + 1 + + diff --git a/src/QtVtk/images/viewpoint_02.png b/src/QtVtk/images/viewpoint_02.png new file mode 100644 index 0000000000000000000000000000000000000000..aee9824ee635f15c876bd4cc32f4e0dabb3ea824 GIT binary patch literal 1011 zcmVLcT~v7kVgqPzs`=hkEHD2qKB{AxMe} z8Y;|u8-g^V3q3el1m%qwlvFY$Ek$a~#>`1)&X~^X;ry*()R}Y6oHJ*H{e{ip|37=L zy?$%2z1RQ$Cy_`b5{X12kw_#Gi9{k%R%YSWYCAC!wH3BsgD0^WPvOD}&o^Od^nV~e z#GTc3r@GvPmFU8Am{DDKsz)Q2KSSGJv~8vN{%Si^05OSZA?6Wd+|N-*u9IA_DR}%O zEj=t~H?guJZX{kNb`mFv$l58Qi+HFsy8|!g#Sd+Vf_H-JdTITRi|;M3mXi2Sa1h6c zABbPF0Gz)6ZgDnyXOcU5W&nn^O~GRWG#{e%4b{tvI7NI)+(Fb2xqlV$`H&ziDcol6 zwUNc2krjhndxYi7NjPPFru{#UE+5+v>lIt!!0K>E5k>fOVbLDaq)*GqH1Wf;;;nzUriWSIP=8mc-k0M^a4`ElURd{fVdf-U=mj2l_CZoDQ(VT z`0Y;~{+78r`Tir!#qVV@9`lKwY~?$NDaDQNf4_1ozV-kMwo<JBR<(&h>T;kVk<<}F_O0&~{TX|M{dyWUU zF>M>3Mv49uM9e1kW#Tsy7mUGH9Roe3iS7$N>tX&brgqAgx|%YHJg37=*~?E5n~CXT zx0zc}obZE#EZxP--PFE{rm_2wXO!s0bZp1f$YB|do~tu8s|uU;_!ZRcLBq)Xw)FAR zem3@VY$ZA}KgNq_8umIoQae?g?cD2UU+vyt)dA-0VDiUUSP^L%qg8=pc&|WPQQXv1 zULd!Knp^VM2M1~YnT|mYe}K2qQ=HB7j{ezvy_bbMXxJoQyNfK%=O + + + + + + + + + + + + + + + + + + + 2 + + diff --git a/src/QtVtk/images/viewpoint_03.png b/src/QtVtk/images/viewpoint_03.png new file mode 100644 index 0000000000000000000000000000000000000000..7150ed7830b6630c52c4de4f8057a6550bcb1030 GIT binary patch literal 1013 zcmVjq|#8CG^4Sk=p~_tuzS$uq0pDElrKRy2z{w6QVNTR zkSL>v@}V0+L1cCTL5(s6GfWwRN@_$$D{1DO@iME2v&++QoY^yT&YXGpf8qadHvhf$ z`u+Ag|MlN{lSm{Ii9{liNF)-8L?V%>DKl|JqmvknLY?C`VJW`GgE*tk*BiG?al(lA za7|;=X)KrHHEhK)v^6%J#xaHIk1_vG=5MF{mPRL(gJ>nrCl(MhMj2}YrS+78Ey2CV znA6RImyNHgh(*K)#BW4YjV@v}F@nXd?}@Vb%CSFK6I^_ldEYSg#@g!{Ht}qQ;J=9< zi9JNI;&>-9J%7x@(38KW1t5 z;NnlJiher&pnVgQuB)xSQ4=p!R7X>e`2|W{`36O)FX z-@9;R;;XCTm7`qP&CHE7Ut52jrzD;_u@2;+xMK7MR9D54L!A2yQ=T-oRS`F3r60t7 z`OfKktF{LGuPTl(?*M0SQ2X6xG!vg^Vb;5hL*(J>4Iw$0%ffIBdu4x+1x zvxuXa3AYVBzqqotq7U@*%r4q?DL-XiRBy!t5M7x8j|@GxcvWqLe_vwp4kquw!gJN&w5(Tdb;DT4hA*yA-t!MSXJy4susvVg(yPN0 zzOSFUZR`dzec zQ+}m3#LcKV(K + + + + + + + + + + + + + + + + + + + 3 + + diff --git a/src/QtVtk/images/viewpoint_04.png b/src/QtVtk/images/viewpoint_04.png new file mode 100644 index 0000000000000000000000000000000000000000..ec35b439f05eadd3432607e6941dc1f84b07e929 GIT binary patch literal 956 zcmV;t14I0YP)HAfhOUNMA&$ii)OIsziE$*cvJ=6%*5>)o7YcY%)Ham8NOjTh8uAoi7aRo^xi- z|MxpT&dlr*i9{liNF)-8L?V$$BoaxL<+!riMdYHk%;VSK0ep>zv9!$hTd*`ZVZ^(* zwz}n1m&?(GZ_$Cq>XuVI8aVec+J2?&J6dk3c0m;;oJM9VnZWkI{l{53%<4`49jOSf z6ZU7@kiJkG5xwzA>2*~Gup=D`j0k|`R!B#X148t`zB}^ zqV+`!Cl#TQFi038{8*X+nHO@4KP45@Tzr(4ZJd66d2|&_csnclE<$hd283EN1BDwf zI~Dhgv0{McPL)qZxG5|6!|eAG3^>+an)unNc;!zn8fN(yEV`~ddQT!OB^)CBL1@Vy zE5U&A4f8i(b}H^X!m@)jJgt1G2(M+uK04!A2?k8OnXUmRrDBrS!<_xGbXS|<8p1ST zM>2oU$AHX7F78&i0YnyJFY&Pmfe`xn4vcxxHG&8)r^ zKj56Xt}J9X_&hGaGt}%%p}M0fjFE?*k8t;wtmGf~bG#c{B+30p@)%&9q}ttBOPGEB?^s^CjR7Y|C-}5j3L* zA7qc^ditpAVR9r{QWwiKJ{jT3Vfqh{*@#cg5zPuw$}|X>&BZi+EXt(J;D=& zF2b4;`qnZ2%?aTLrdZcc<34Oqkp)xL89$%T_S3$HGq&S4`CrWc3F>gKWQOTNTXoB+ z94qmxl|1cE3uo@GD2pw;xjPbxL?V$$Boc{4 eB9Tbs|IJ^81Zj2bT2`O{0000 + + + + + + + + + + + + + + + + + + + 4 + + diff --git a/src/QtVtk/images/viewpoint_05.png b/src/QtVtk/images/viewpoint_05.png new file mode 100644 index 0000000000000000000000000000000000000000..d7ad90c43e0ba5d95d7e2a6d1cb7c4315322dad4 GIT binary patch literal 949 zcmV;m14{gfP)K*Of?6slf-T}grHXD`h;G`AA})$z z1*1q2chZG*A-FOY5lh>M))ZpFrj`~f|eV@rCPj@P2UXC>`Ijazi$nN+LE8QN$|2fYBCme_m`r;pz*Xo}~RW9dD~# zDy9wimAG;4RSLPc<`;iaD$aAu@3imZ(g(BAIVaNwoG4ShT5?0h8!$5!Pma+x#P!=O zPb$i7zV8Wc{tRjAz zGGU-d1HQ~&`0)`Q+ruT_%Rg_d%0T?I2~QN94yza5eqv{K!aqMr*FoxcV-xBY>ZX3_ z2H0QlyB!OS%QB7A3!Dvh4AO&j&{bQ{Ek<0t#U#ZP=Fft(; zig*kjC!Q(2c5eIZqDO-dPjb^C8a_pL*<}?^)DWA99-?pR#m5=q7h*5*I?=kw+Ko(n zS8&sEj+c(od<3tdrHn$Vm5J4Sb&T#qT-GN)yUQ_}tDZ(Yg?;jGh&wCW&hoJaZ^(Zi z*n%r7+s^V(D?hJ4MlT+g?d+~9?vy{;+brMgt|}TV|LjgA5{X12kw_#Gi9{liNX*B- X=;#`OT&!d500000NkvXXu0mjfhceG! literal 0 HcmV?d00001 diff --git a/src/QtVtk/images/viewpoint_05.svg b/src/QtVtk/images/viewpoint_05.svg new file mode 100644 index 0000000..e9d5849 --- /dev/null +++ b/src/QtVtk/images/viewpoint_05.svg @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + 5 + + diff --git a/src/QtVtk/images/viewpoint_06.png b/src/QtVtk/images/viewpoint_06.png new file mode 100644 index 0000000000000000000000000000000000000000..8ac38f1f6a2121c0e2d4ef050ef0deddfe522ca9 GIT binary patch literal 1069 zcmV+|1k(G7P) zK~#90?b&OHlywxx@z3s>t|@j|DJ@jQOO_Xkf|MW%x@b_Z3JSXrly9OJ`XVJTq(~AA zvIvPHC<-DX2qISl#j*_(O%QBXyP4&6)iQQ>*2|t=%p*;^>(1=%jI+i63(t$0|C!%& zerL`z=l?uIB9TZW5{X12kw_#GiA18TOu*b~C(#$R71po8B7B3Va7l&FH)I*(pF(_u zJF1&bb-595VjGsCp}Of*k1>p2!puLIxr52~RXd@65F?3c#0+Be05$5!HIfUOg2&G= zrIk5r4Bf7XTZl&D6cGi-Zenr&v^tmP%@-a=f;WO$Cz-yL%NA6|$AE}uh_jjD(?oM- zyghqwW9eEa$CCTAX8{V2rr@zoCLdw?E2`TS@o;9ci&#xu-fev@@nq?Gxz&A}@6i=q zTz7)WTNrUydA$`S8i-?A0bVGBUM;zUr5B)kS3J_j#DiSD(uL`YSdy7PKnx$eUi-X( zneW~eub<|cRwis_*qwvV>%2r$R)E*aqt~%w@CE4J6%QU~+&;!Ur@UPe7ZDv<0Ujc* zCEg`|CXNz2iB-h7(ltBZD{le*)fK0hev~UVD9>&)CKQai=L?E)CYuE3)>?_1OViA) zuS@~Dcg6h&Y1m8cG6V05m|bAFd~QR)ft1)l9k{CU{Z$%`#~hPHR`HrfWS+k;q> zwfA>@#GJbX)|H@FM`!E6TD(2@w3XS-)HlkHx|(u1Jzv5%W%mF<+}6wbRH8Fmf4Vfy z+}i#bKh(vtX2!NqyGm)7S~-aiGK0Sn^Yi=ps3C48_GD{65u-}eYrBeEdvW7mw{iDw zMsJsYq*h-^mwgbUh|L8Pp@V2Ec>OCetACogmwPvTGI(o0Q+F}^6U?iKrT!Cj#3Eu- zw&^)cY$cYLwgKv)S5L>c1)G+$EZ$2)3szuknGFm@IwrC4N9OHfWRv{tE;gF~7u4fX zY>|ILJhQs#TsWrSCHemcmSO;x&VP?u`FZ^z8gZ}6&+Z|^4f5aiN*8{14+(~=-t0~! n5{X12kw_#Gi9{liNc6_vIH3lLAZj!b00000NkvXXu0mjf + + + + + + + + + + + + + + + + + + + 6 + + diff --git a/src/QtVtk/images/viewpoint_07.png b/src/QtVtk/images/viewpoint_07.png new file mode 100644 index 0000000000000000000000000000000000000000..aca24d7cbee4e5830f6f6bfa1c724b29a0f2e3fd GIT binary patch literal 937 zcmV;a16KTrP)@J2-HX5JLT3n?l{ zEQUxoUWtVe1g)T=vK5Kq66QpThT+W3ttQ)^nfmMEJkd7he9p6T&Xe$a!;ix`{J!7c z_w#+ezvugVoopfQ`7O#_RoWY4Tqp z_Tu4U!zq^guoDN+f#zbvDUK#?evP(2X*)#glSKzqXTlR1&G zm!A@T#Pu2dZKmPVY*VLRCv2Vh+ZaAV*ICXTWvG+U&oZuEE5aZlWE|_W`5bE@`Kx^O zFEx4sFHO;UnzipL?p_gA5pJJnbf@AEXZM-BJ-_(r<8wd0!w02r6CM+jR zqzTxR(WXQ)m^}frtKx-mRt|FOHpO?4uqhQkMQF)pGtr(;{OqdO@i%u4v*H^TKT=zr zmn0lY6R;<{&1C1o6EM3fo*Ut&0h-=Wzp4o9r``N2*q2kgtDArsRdJ5BL)`F%+MhPV z`>FU7<({6E5vgI9D`z zp9Y`8wFuZA{95(ZCHqh12cAWVR@8M{5*O)=rn(qBk!qUp^ zCm*cN{{A`P*b_g7BMxPPxM6KlVR@er?FeP)zxZ0%^CdT z(|Z59{C<+I%7mY~$d-Ouj!}9GE2}1{GQ!?eeDA{ijNd{sae3k2kMmd`S07Y#E?dk;$K?9a=8%>T#Nn zp%WP&uC8b%SMk*^v>#z<51x_#Y;r}>h!?S6`3-SfvEkH@)p%3+|A7uHFE*U|P*U#K zd(e$1)VFsR$~xt%y-jhwyHJ)Wws%J&kw_#Gi9{liNF)-8L}v33{KA%^AXYkv00000 LNkvXXu0mjf + + + + + + + + + + + + + + + + + + + 7 + + diff --git a/src/QtVtk/images/viewpoint_08.png b/src/QtVtk/images/viewpoint_08.png new file mode 100644 index 0000000000000000000000000000000000000000..3327ddfcca70ad20957c94e219b83d51f71bac22 GIT binary patch literal 1090 zcmV-I1ikx-P)rJBY}YW5f!gik1H8qh;~=vO9P=xa=U!-*DD-1FxmeL_M)4Cwe=v zocNmP$o@M{+)&)+!6r(-pX`8qSsUDTlnJ|Oepc>RWRTnpVJG9i^Sc9ndu@ZavKSot(eWsfmhM zmx+6!hx*Yu2h6N&??`KP;=4x0OUJo%FXO&o*z{`E71;@H&3-TLp?+fSc}rz;LuM3s zX9XH?=P))l(sng-+Bo-T8Xhz7Q4v##6Itmp!qGr{l8yfR#q1q@v;Ps$V^kcYc@Jl= zG_bqPm`&`?gsvuDC)$WzL?^M7IHQ=Y(u%=xK-aZm&Q2QJshh9=Q4u4EJBR~a_5neB zKujubtF(Ub9q?D#euT@{VIR)vt~bL9h;PC&v|<+);3wsi-E_>x4B~Evyivdd2a33< zfBdqahkjt$D2~62#n@k^u~?FgbUQJooBFxA&Cuk^_Bxgf-iUv^gO&{pTZx-6v`W!` ziyM>8@gQ#LrQMHNo97ES;K_j%y{D4}n`zvve9G*@bgW2B&CT_eUfQ)~Z9b}Ovt!!8 z2>-ss%^MlD5%*zKH3}=O0mpLB-7X?s>PnSgS-+ZN`-m!5=1#2I$0K`b-%e=}K1KB1 zRv}^paVQ(zw|ZzZDR(G(xR~A2t9={oUptwP&F^Gf2^?kEjTGYMh zgTdk*T(XJbOO?}at%)JTjl_FdI^0j}%)Ry={G0TyvO z(s3c5ZKHJ)BiAbD?gE>$e?Rq@i#5u*drED)bLyCgr + + + + + + + + + + + + + + + + + + + 8 + + diff --git a/src/QtVtk/images/viewpoint_09.png b/src/QtVtk/images/viewpoint_09.png new file mode 100644 index 0000000000000000000000000000000000000000..0c96001823a7b1a598f619abeb10179f709095bf GIT binary patch literal 1065 zcmV+^1lIeBP)!F)N%f9i#kHS`QgSJ!BD~4^bFJNkzT%5Cx(SCH9aM zDku?AK?D{_L>Up8&|l3cQF0_5wJ0&PWYjcf<_@N-hkM1tI5YRmpF4Mg{e=zp-o4J+ z`?vNwd+l>Bi9{liNF)-8L?V$$Boc{1WioEA_9S|vw!;2v@Fc#+Q@EtU;|*Ktoe#wO zxTCt$sV+C-b!^8{jIZu=sz*JSKg*22nX!{83#&b$oJ1ori?mA(j(|iO96Q#Nz(>?0mi`KHH84uLd(uG5rS`?jBqn{UYj!uQQ@|5uXr0 zXMS7NH=m~_P&j#E0J3dcu(*>cN147x^|B&XmqZqb1zq|cBu{Ttu{$1g`19W^Ji|M^2x$6prK%K-a8zxQ)gmT)9%^vm$QGr1|wZ zY?{jZY@gRZ@m;gxmD60)%H(etIe&0s$BKamplen!2T{Hb;sluH5+GYB`S42&z)|WQ97}ceJY^f}sy9GWf@3XLD zaBqR$+VAb$upP(HZQ#pfKuur?LNNorA{G*JiF>g{F#}GPE;wC208Zqv86by`^U$|6 z?ct{n(1gDR;4mJ`l*4R0L%cwIQTqNyd0!pxRBpvTJH+grjNFX-F{0dTM&=7Z&0EB$ zScEyK!*AF?O*8RF$*?7dvxE7@%*#K)Yb~t9u`O7Oy@NYOuS8QOBj%O2@3?(%R=c^t zqFs#Jg{LvD!a{o@R+Yr>FK(J;?MKkr+CS0l!N;x4YN2kEVyVk9X2pnGh|W>~7U#dN z@LJ!5|9O^WElk))?aOGan4}Adn~3$r2ceioG!Qe16`753W4_ftN81$?+RF?7u8q6) zaPbbsS88sv#t%`4m zXH<7OL&sFSr1<~9Qe0Zy=?o3EiuHN}HerG4*6tx?j^b*sG_ + + + + + + + + + + + + + + + + + + + 9 + + diff --git a/src/QtVtk/images/viewpoint_10.png b/src/QtVtk/images/viewpoint_10.png new file mode 100644 index 0000000000000000000000000000000000000000..b43eef628bd2df7ed0fe82da4ddf235e3bc84f3a GIT binary patch literal 1158 zcmV;11bO?3P)xOuwJwWiwIxDdN3j%5~3(E zLkzO$LP8}%(#6D_s0h5(lr?Ay+EvH;M0s z|K5A8bBIJDkw_#Gi9{liNF)-8Tr#HNx@tR7%w>HzR}N3$Q#^>leK_|&iaIPt1J+_z zb=|2ha}<)WT_Gt$s_RbmsAKwaW;Rp5m2q>c?NBcXLkZIfQwRep&<`QMn|z=l@IVVw zjxc+LzN?BbfH0S^gs`5llhBm38!EiUSi(Dm7D7ncNx~XJZTI8yFBO7Mw44v=#Kg#HiCdVsNwow_(UxGS3G>E;U*mw_jzR!p~N~|`sNI?36$I9qBlQT4B zyCQ@6FG78eH^;K=YQ`_Zeua%0vPnQk>T~}xx|-zJp0broSVnyJ3wM0Vtnb2XiJB0N>&!OfIA8>}x!4>iCe{!ro8+)oGsGPs3Tx zti!9w_wu4WS_nOr=zh3xHF>VTmT)G~+?%owzxY0&yLKY5?l4mu8T78g7my`AO2BkN zd!oI&ME~PS-%-M_3;Xh$dKUPBHXhzfT_aY=_DvENr`qyV0#+9F4JS_-Cun6}lJoMVI2kXgg?EZ3LI4xgd zV&S~0m6c6wZl`&J!taL775esXrFk|R4^qF2fuG + + + + + + + + + + + + + + + + + + + 10 + + diff --git a/src/QtVtk/images/viewpoint_11.png b/src/QtVtk/images/viewpoint_11.png new file mode 100644 index 0000000000000000000000000000000000000000..dfbedc75d8cf19bcec344d94401db90d96c4daba GIT binary patch literal 989 zcmV<310wv1P)X)ny#V@z+tu)|AFF6zy(PhnhxiV*Ud{bnk;A3bLNepgpl?LwitBfhb~- zU^0B5NhwH_DA|oE$ttq2J5X_~B{hS{W1%~9ZdVVE=;3TTH*-6`Zmu_69IlJs=X-sx z@9+EjUEk|>h(schNF)-8L?V$$Boc{C7z=S%(oWh(}Hca9KDq_udtwprhQa3m+50cN2;@_e6>HPj0~7WsLC5VT|5KAG%}gO zcfU|pJelT>Ze~4ij9HPB0jYjcVJt>S4UrlsUw7#~RF7@W7HqHMiw4%N&t^sAd&;aU zDp?7RK)Cn%ZPcT+isRGS^)QbeWcDehwJ9Mh5)Obl<7=)3J7@596R&PyUKg|XD3BFN z2VmyJn61aNH}Jzu_CCtW_nH2^5vt9k190=iPtly>o!dBaJB_XAmOYpu`2d`o_$f~O z#v_MWa+2=1(1@!q`y%`AgmV`2$KUJ__MfKxPk!oUa5Fw0>B@uykm|{~8RNkDK{otI z#}v~0umxudDH0CA&_|?JUB8{LF7Q$}oqb&Fzz$?eQ6?OKngjG-9-AMRu&0-e=jk~~ z-+Fvru9c)8fj`K6fCo$0oE>E233g59+-|&q-^c1fUI4=CoKEf*wUUrqOza?)mtx@o z+>$eJW;Vute<> z!?k^Hk9^=s2R3yv>l9TTSTxQH9`*=qD^WMn3+8}qkx`7(!-s0x=wF7p*?!jmuXVA1 zkn~R3?}q6TefzhPZej1wG=EFYAv`3fV*4*s=h|oT*U^xuHx*=o?1GQT2H=13N6BQ_ z)ZUNXSdpwdm1PCK#9GWq*q218m3ZM5i9{liNF)-8L?V$$BogsAg-d5*D_ysl00000 LNkvXXu0mjfXn)g= literal 0 HcmV?d00001 diff --git a/src/QtVtk/images/viewpoint_11.svg b/src/QtVtk/images/viewpoint_11.svg new file mode 100644 index 0000000..b0d61fd --- /dev/null +++ b/src/QtVtk/images/viewpoint_11.svg @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + 11 + + diff --git a/src/QtVtk/images/viewpoint_12.png b/src/QtVtk/images/viewpoint_12.png new file mode 100644 index 0000000000000000000000000000000000000000..c4f88143b3e29da82fa5a51225faf4148c926382 GIT binary patch literal 1078 zcmV-61j+k}P)J%o;e%qXKfg|M9P1EGr$GV&|ol{7Ftk-VEapOuq=HP@Jy zXZj{a&Z(`xrA{m^GCV7D%jh1+j7Flm|k zWJOp^I9o9EO~Ol624E{;0ih|=e+OZ8W}eqebuWF=yYt0a@y-=m|6=k+2G6Qx0EQ59 znf8P#0x+S>_w9vwP89WzAW13@Kyg+)mFNB=jD1<{v!a>+l$~oyX0FUO=v>q{=Zmvq z_2o1xTE0|eT`^FVU?_Zc;c}+?(f&`}jOPclXEf`dWYH$Z9cIK*{mY7)X2A6=u#oNKu=k*>LQa)F>ZstRhzX6K$xGI=kcNd9IQ_Ova<6U3y(8;zv`;ZS_B|WCY&kE zv99#{sv? z-H**3%lsHM;M`T-I>_2VFL_+@9qE4wx40& zNe{ZF-q)?nnJNPiMiF*rES#v>syU7kIeeE*BYBO({H*u&Xfk z7-4+n>m(bibNuKPUOYhaA*{e%efP2C31A(k zAeX<<%)Lr@OxY*W_kXkOcYe%saV0*-mELu#rpN1Wu@pr;oUcN6YU#Q?-3ar6l^u*d z%;2?{R%3@to&xVzsFxJAKUDd_lP~RRT1w|bn3%RZx_G05_N(MSlD;?WM(?H~Kby~v zGixtRoAHE9#db3@(v8>TtE9!#EkUc);ce0Y+!BA3+%8S+c6^Gq#+oy*v|$&PV@!i> wX$ZsA?eZ0gL?V$$Boc{4B9TZW5~-Mf0Vme}xwk36*Z=?k07*qoM6N<$f=iMC + + + + + + + + + + + + + + + + + + + 12 + + diff --git a/src/QtVtk/images/viewpoint_13.png b/src/QtVtk/images/viewpoint_13.png new file mode 100644 index 0000000000000000000000000000000000000000..439b1505127d24e507a38e5b2db22d65146e59b6 GIT binary patch literal 1094 zcmV-M1iAZ(P)7_Ro6hsz@AYnn|jY5T8h<0IJME?+^ zf&_`QA~GV%tVG&2k~Om=Q!A}a+lXzWaKv0^b=%X$JGSr4uFmZI*-brPI1KNZ_j%6q z{N{PjpLd8vB9TZW5{X12kw_#GiPVi7FmtejC}zk2j+MdVXu<;+F@R(LuNZ^nXvRj& z8r*OOm$?!VK9`6xa&W^LJjQV28fIjf{V5aY4|YIR5JnOj2y^qFL(8+teM>IT9Js%e z>)V*K&cIbgxRNlRu!8Uk;Tu9rzTH&9b|&Es!q0?I)J_sM6DFMBKKF8xe7dy-Ug~Cg zmKi%3J-4>`_D*6+AHkn%^Get*P2GEnaF}p_a6Hw2oG_=iZEh;Lv%LjKx8}gIQ%wGq zDXZ0|D#DU{ke?8qB|O{@0p<}_5~daP4C&!)Dhm z|Kt(Kq^>8GFF;A(52k!gO7)K-mn&a@;;LAhWx`R$J*xIqQBwhCrhKK={m#XeC0|?> zFPurLqTxNY+gH?7fW>(~oyo6$j@+i|1t_kH#qEqg!l)IhtBP6)5N;u~=KVZZ_+75C zwgRN9VnYX0erNnvl~qNh0)$ryI|)sMpYrx62u~)HVu1jM>LWn9?e1n#D`OAn-)^&F z0gm*sjJ{7;(EHw8d;JAC*AAYbVK4rW9L!Lk)8IY08Mopg$?5M-G!h;uy7zb;#xLTB zcJ69o)?tpmjs}D>3~M?GuFCs4Q@B^iHPz?W?g+g7Ba^>o=m%I>NzkQjuLzU1H^u3CVu^mKNfs*~mZvV#ju#bfVQnFkF0n5NyYLad!(WnDUlVb!WHo?Y__%P) z%v!=7O0Gy>on-ZI?90-z9`B;-!Z!WpyvO0HHFtlk1kVJk`SX zf5^Tjd2g64Gq#JB>>S={W%hoCH%c~7nNn7l0;Bc3Cf}f7nY^@_CQ0}+i2#?yA0 + + + + + + + + + + + + + + + + + + + 13 + + diff --git a/src/QtVtk/images/viewpoint_14.png b/src/QtVtk/images/viewpoint_14.png new file mode 100644 index 0000000000000000000000000000000000000000..2b3a419ec7730e3a714925121a76f44e1699c332 GIT binary patch literal 1052 zcmV+%1mpXOP)Q(rNw{b76gv{ac6b)bTMO2)6VStdEM#H`NCo5edjsP zdCu=V=Y5~|9U_rPBoc{4B9TZW5{X12myH{7bG?Hoq+t}tO5q9Y!UJd?#j*cUv|t5# z@d_5yH=O#iP*#K!c8k_P1ClMX^ZL|&?pnek@=cTpf_;;AanX@Uv2cV zB8(+0B6Jcq5%v@Ma&3N`jSV}lW_=NB*;o<592#th&IRW;T z7GU75(vvUDikF6%`!ln*(b!h|ye|bkmXOLjo>7AUt8)FGBy27&Kp0OZQ@#L&S#fWg zsYjUnsN}PvS^>gb!T{kAp{cY0gG;KLd|_6+cs83A)8AKNU6F7l7#i>zuEc|+G9%dE zQTv!JSl-C~iM)9?OLj2jFylLwkrhdo!jIuLY#`NBhW(6Whi^ysB=*i`&01#lF=dPD zs?AEbK)8W$hH#Q_P2TwuTOf0=_AM|{+jD`%$C-G*Fx6&484w!qDy~8&sdSkguT5tB zQnaOb`#N@C&-CRuBKu&5HV<_YTwtr98FC6XX{PXyDILibCumV@(Gc3y!_ad#i&l!ZrbKkp3 zog{T^82cJHeV(-k**J#uHmt{qDxH;k5e!e4D4~nB+|%B`vScoFJ-^X$faWh`7o@4& zStgMIA1S?;m!b`au_<>hw<=8^FgR3Q9A~kmpXW|<><|ObU{B?Kic(7{{1-nZZiA57 zR@rJF9pa&HX!#ba)p#c;2ta0RN5lmQffB1{L?^)dM{jT1%R znLX}1$5VZ5KTo<__Pt@b#nr!+bUW`Ir|m16KE++~Dz^VJ6I^;t{sN}eHJVXmuIz+& z%L?$n_@m?s+0@>SchFJaa7LF7e2$fvROeXgLbGHl&qyQ^i9{liNF)-8L?V$$E&Ksk WuT!oih_2=U0000 + + + + + + + + + + + + + + + + + + + 14 + + diff --git a/src/QtVtk/images/viewpoint_15.png b/src/QtVtk/images/viewpoint_15.png new file mode 100644 index 0000000000000000000000000000000000000000..1710c1952aff50fec51027928930f5d5b4bf7cd7 GIT binary patch literal 1054 zcmV+(1mXLMP)BU z(hCXOjS-Q(V+IwzM6sr3XseipnTlxgvR)$xr`gKv~FV3ZH+Fd&V(`Kz9Sdt2t3fkwZ~{%uEws& zq>30RxgKwpShEe|E_`_pnO()xgcga72Vx$XeHS0jy@rSLkDb8#fmi<^vy~&u=-N@n z9F-Cl5<-!2>j1G=mxxV|er|)g>EzBPXTR9!2rN3q)FVt=sy40&3kfF(8wk%6mQ*Of zEW(r`W5mU=r{5~Q`1Cjyc)6DuzcGCsO|3&Iz(_*+l9*DV0OLykHZN{0xm@`I6uRR6 zEY}=l;$w#174;CHXF+9)FLcFAXA)OT{>UKvih6c}{Sf9>pQ9NMHL-I7Z{E#x5hSkIQYW-T}p2v8tPC$7xxsvTn0t0s0%~2`lpV7|89Z zjR5Jf8GVwDZAZeit;=_H(#wANEn#}5&PaGtJnys(G%;bhn06&xuQQ6~Y4asG2Mi>lAF z{S?m}q~kQ*?O20cIgxb|Ak5bHV0EzX_^40l>8-4eGgy0!7rQvLkJBr#rRq}q7}Q;$ z#Ksav5H|L|2|{k&;I8kVdUyb7P3RDmK2l#z2 z;o0Kz7JDMh238(m;(nUias3c4xUeAztILdgBL7T=J8&m%$3%&H&Pbf_723({EuJon zr)L|cCZ7+S<+%f_KS%Zr$$P_WnYCT2WZQV}Fs-{7wGnqIuVcI9xm@3C@>Q7B&}!<) z49SAOkO=U<_@iW)#MAm(Hh=*M + + + + + + + + + + + + + + + + + + + 15 + + diff --git a/src/QtVtk/images/viewpoint_16.png b/src/QtVtk/images/viewpoint_16.png new file mode 100644 index 0000000000000000000000000000000000000000..015176279db35f1e649d6510ab3f59d8c9f3c27e GIT binary patch literal 1163 zcmV;61a$j}P)E&SVTo6(t|xDlu?LD zNv9rCij*G04D6~@N{NuAn99MtV@S^NI>&R4tB2X*oN; zca-UiUB9k~24W_$fcTL3m1xSwlp6Lko>)tqC8A^;B9>Q=Jyq^wHc`l8E)aW(?Zn^NZ^tf=DU7Aidbt3lV{`E28Acyu%tGDM z6)~4ML3~TRK|EKR0C6vIKJ)*WxV_ANC-K7Napyj{a`EL|@lG4#k27{1eW%r@_F{q! zM6P6eRP_QxFJedLyQbrQt{69vLZNyA%Ddw6Ja_D4*z@Y&6*UR)K<3v<+*bV@Epxh7 ze0f(aKVR&Mk)NyIx}qil8Z*CdYMZ0bc$Eu-h8_R1;8Pmk@HM-UnHFZF9=Jz&nyyPx$u4ErA#A6-f z3OnoD0hPv<3p{#&A-}6_wOOqI(K{@dR;mW}8B6%IpPVVu=99x?g~cV@ES1 zx8g6w2Q$>?6o``Vz3?)*)#Of+YbUoI58^Ny@KTBYi8{=G75+HJBO95zn|-S>vMlG$ zsOc0qmHC|}`gY>8^wNs(B883JbF|L}YxgpG8@<24tj;p;Q-u=Ma0uhkM6R_HpS{`V z@S;e$R&x8RI~di{+|JUSH1;9C4l8i*N)h!EV5g!0)t*vW)fc`d_vE!tzx52S?ql;g z&NkvB6sn1=mjD|u8zYIE$epj?GcNl)NUp8;wcnStv~?|y^H_6~H=EhNn{%&YOBZtQ zjGC?iLx_`^@3R%`gNP%U{oRhX!n)ed??2mkW(R|JVKHv4Q^64POU9xS0hW~6`c;Ts znE9R|=3VlMDa22it(h3nF|Orq3hh@f{Ku2rw~PK;Fh~8mw?h$8<*1-~2!xY6;*AaY$W#kTb z5_1bJzhHE6yQ!5WO{{Mxze@4FVZO@T{;TAt^VtEWZKvONc*tc3=*DD_ORve7VMLE+ za~&D4SnwuA0sa?%l=N0??e+N76_%(sBD3%_7U3$d$!|>h>z;deB9TZW5{X12kw_#G diA16n{sF_&Fc-*a-Rb}U002ovPDHLkV1h|QH2eSn literal 0 HcmV?d00001 diff --git a/src/QtVtk/images/viewpoint_16.svg b/src/QtVtk/images/viewpoint_16.svg new file mode 100644 index 0000000..f17f29b --- /dev/null +++ b/src/QtVtk/images/viewpoint_16.svg @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + 16 + + diff --git a/src/QtVtk/images/viewpoint_17.png b/src/QtVtk/images/viewpoint_17.png new file mode 100644 index 0000000000000000000000000000000000000000..aa0615af439d91f2b440d52b64f7557ae4c8d33b GIT binary patch literal 1037 zcmV+o1oHcdP)Zrq4l8y!R`J6`^!<;b39GRW zuV7JQ!)YwHOGMZ!5oKy)!)Y8%+|x?Y{L zB3Bf|B+2u5ha@#yaYb7BAh`qO&4ewur%In4PA z(nl?XWrR?s+*zUTjuHBnmX$;M7Uom9klg)pWnbW-v&`*g-a7Tkim;5(L)b}pmaz5` z1eigXGeYS|?c@n1ufOwek39I|ax&1-&%$4s-^Ik1ECrZED1Id7R4>4Yc5{U9Q#&t} z)J>yMs9u25tXPrfhGWclQubMqnE>||*;zcau5W2=gD=gB7yn4IqIs+A))kov@K$Q$ z;NR;Coue0^G%J>#X66y5tueZ+$U=ZHop3g_v33{%c4aF-aaL?R$GlU_d{1pzk%<6n z(*AvfYlacvP<;d_E}ssvp^V$ zj&;2pKgqxg*fCtoItdUi!}9dxb#ep4x6A!dbTcyG%mB|FqH_ZIE^I<~jmAbZ35Mlq zzd^#>^6k#A%x0q7`#Wt1nev%rqMKafpoa`%Gy-f-`|YgI?n)K+0p&_>pz~)I9_I3o zaCgl^EfZXg0)$zF{~O!$!q9ajC8_0dVyz-vTcC;7Rh(R zeD(JJmE>D_{{$@un7j-38}h~Kzsq!geJ0 + + + + + + + + + + + + + + + + + + + 17 + + diff --git a/src/QtVtk/images/viewpoint_18.png b/src/QtVtk/images/viewpoint_18.png new file mode 100644 index 0000000000000000000000000000000000000000..a7e6b1da60f4dc967190921016f78e0f7978a412 GIT binary patch literal 1196 zcmV;d1XKHoP)&2L^+|U@#aA27|$1Fc=Jmym1?FN1>hYGH(v&vVfO>4&X5$GKX{j ztEdFF0-Zn$u&S``6qePvN%#^sDGLkhPT{D8+oRBEL(>VUSyO0-W{E5YSqahzQsF~? zAviyPBhV@EXdG@Gg618}T~$a4$QqDsAp1d1gY>Jm(ue&#Wg7z#txbY_2eM&$TjxzT zc)bk??3;w;HZ-x{@{y8_gVd+mj=q;YcyCp_k${Fj zVA)|PZVEF2B_Nj8Um73*`;^`wNKpoP1xP~aY}dxiz;XO1z*`lM*l_azEO~|;t3o>n zS#hu=mxpMR$H1CM7h5*)i|Ujm$H(pmN^+aB8Q5PACu<C?vVoBh<4z>~#rx(W_G1RL9-`W%#PV|HsrpjTiqh^=&=_q<9AKw6dT zEXe$%%sHN0`TJQb_KraPZ&2MvZl}#42>_5LZ42xHIRNr5$ayvPHOP&rHcoGT5}>!P zNqBe=s(vKcX)|yFERgkDzdsj(af!LR$l*6leoJ2C9JF zz-HhH;4R#1@E7j(n!=@U=Fi4Y!?3;sR>ff8AW#eVS?mL?0WT^&8>B9S{B96O>1ZcH zrz1b#_K3g-KSSLqC^`bH^P8?*6L3-Ky^=+zP3asQjz8~AVno;w2-y}+x$O*2I~ ze

QkqB^u>hxw&>;X0cwcJ=1ms?o7y+4Z7et--3UDT7 z4*aV>VQn8ox^Q2mFse5#0p9(4x|Sj9^14T7OuGP0^`FW-?{qgpTVPK=EI9|ot-$iI zBleuzrNyV+vta#|J}hf-_x?L^*MkXQ2=_O?7O>7{ew-|V__u)CLi@*IXFnXB0Q()+ z7Tc$9S1Wcid^iYAXQ1>r@E~bl(0`M1l0TF01!@ZF%^cEz8}R423HV?9qofG8w2uPs zliLyXs%0JU4G;ycEwC>IAwqukZiB&KFc=I5gTY`h7z_qO5dH>Sokuzo6v8zC0000< KMNUMnLSTZngcf4} literal 0 HcmV?d00001 diff --git a/src/QtVtk/images/viewpoint_18.svg b/src/QtVtk/images/viewpoint_18.svg new file mode 100644 index 0000000..7b21e15 --- /dev/null +++ b/src/QtVtk/images/viewpoint_18.svg @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + 18 + + diff --git a/src/QtVtk/images/viewpoint_19.png b/src/QtVtk/images/viewpoint_19.png new file mode 100644 index 0000000000000000000000000000000000000000..ece789e91d3a7f5580c432695ca24403d2260849 GIT binary patch literal 1169 zcmV;C1aA9@P)Z5@!wUKd;?uIML(3Uw5FA-lo$kk5G0~3Py~srBn>R0Z(;_1u_8f; zl3tJqO)AUMOu?X148h8@R5WYRvfK>ItEPKRZTj$B+h_0Y-Mx4B>W0oA2Il3QnKS1( zJ9FkPkw_#Gi9{liNF)-8L?V$(#%SEs*+vx795yC=3RdLi^#>XJl*&g%sSXI&rsQT8 zk?Eh3xxcah?DY0+zA!3Y`a6k=Ve6EcS5zVs9F(dbY*{4p2TtZ2cQp2gDIH(F8jn`7 zt3RvmW%?$D9H93+B}7Ff9FR-Z`?f3+sx+p)qf-OJE3kfw@mM*K9iv#hgpqX&S*?|* zsDuL!qakHMON_zA8(?6ne^3ju6`&e(d$4B^Yo>AENA%yVylk_qL-75)+%dv{g0U`y zwN0^Z@(ukgF%VTQ`R2A{!c^v5>BEW!lB-Pnk!$mV6wrSy(hX#G~$ zf0U`48TUO0-@-725){jc00?&y>Wd^&D+sUT>t8hL z4yDFckVz##p)Xe99qdGXUjHsUov-i0?PMA>;q1+Xo!Y#SzCOkLU->4>nWgv;=iAs{ zxfFd47nZ`izF!;iTbk>nDfS}F2A0+__yASQB?(nUDZB+%-8r7EW5WfqD + + + + + + + + + + + + + + + + + + + 19 + + diff --git a/src/QtVtk/images/viewpoint_20.png b/src/QtVtk/images/viewpoint_20.png new file mode 100644 index 0000000000000000000000000000000000000000..5448bae874d37054f9852209efff81829f22eaa2 GIT binary patch literal 1302 zcmV+x1?l>UP)@kXB0zLZO;MHP$rg4};Mkz7o@D8{;F2G12}o=?_v( z#2Ee4NF-Y818EFxtc_KXkl4huB?!jGM=3VdDpIL}wF=V$?XEnIKjtn>XJ=+-VY}<& ze#y=3+;h&o=bSlnXYMR$G#ZUYqtR$I8jVJy(P%CjD}ZZL?SzwgNu0|7o&gR54*^+8 zockX|F7O!81-t>QO07GoWi?h3I3e8sH!75RUz|0)`2vD`~)JlHUZKJa(jSrmVmqu61Lfo zfNTfJ@wN-SZUt{|g96*8pu&We`ygj^;^K{VywDN!Fi1B@AIPMw|2dyAmVx}P^hQBG z0XYCNuKJFETo!E?DuK{=bOP+HOW=VqSbh?UYe{@nNTIrF?||H3Rm8Nc7^K~ngmoTc zbSil_NP(@t0%SnR-i)?8|E_=V&Z>BI0?Ph?l2*v5OjH6gFLXLeo(FPD1<~XpuU4`t z5SPcA+^gi{Ad7AN*$@f^Pk^&3HkxpC9~3;r#a}CAj|!s0MYdhZx;$*tK~5{3O*8%B z^|K4!SrxDRWmQE{3vs?z#PcR7>Nw^iTdR&P$pJ7XfKG=lAh*UbzX!QMO$Hp!hh2BV z`h8G%9I~GvKve`xfMf%=sFTkevNYftb#l^YkbZSsVe4BKZ2q8B0nLlxs}gu&D-`!a z;U4DxwkZv&d`*xm9kR=93*<(hG3u1gz)WB0=-h9CSncyExVsX>coyCU}dbEVRN-AkbTDk!P}`mi=;K+FWlZNLs?P!C44i_(AD5!s}zZ`gnSMDX1yxa%OS`X2gr0!7TMXMPUL&AukS*{xRjSTl^{dP$rg}|IBd&po2GkQ#!+;4q0<>VQF^>ZEz$L(DFkZUQE_@xxH^h7* zeK`WPzrxohoT~>u1SVny7!Xxpm$<4lnjX+a#FH zSl{a zz + + + + + + + + + + + + + + + + + + + 20 + + diff --git a/src/QtVtk/public/QtVtk/QtVtkViewDefinitionDialog.h b/src/QtVtk/public/QtVtk/QtVtkViewDefinitionDialog.h new file mode 100644 index 0000000..69ff397 --- /dev/null +++ b/src/QtVtk/public/QtVtk/QtVtkViewDefinitionDialog.h @@ -0,0 +1,121 @@ +#ifndef QT_VTK_VIEW_DEFINITION_DIALOG_H +#define QT_VTK_VIEW_DEFINITION_DIALOG_H + +#include "QtVtk/QtVtkViewDefinitionPanel.h" +#include + +#include + +#include + + +/** + * Boite de dialogue Qt permettant la saisie des paramètres de définition d'un point de vue. + * Cette boite de dialogue peut piloter, optionnellement, une caméra VTK. La caméra est mise à jour avec les derniers paramètres saisis lorsque + * l'utilisateur effectue un retour chariot dans un champ numérique. + */ +class QtVtkViewDefinitionDialog : public QDialog +{ + Q_OBJECT + + public : + + /** Constructeur. + * @param widget parent. Ne doit pas être nul. + * @param titre de la boite de dialogue. + * @param caractère modal de la boite de dialogue. + * @param Eventuel nom du point de vue + * @param Eventuel commentaire associé au point de vue + * @param position initiale (x, y, z) de la caméra. + * @param focale initiale (x, y, z) de la caméra. + * @param direction vers le haut de la caméra + * @param roulis (angle de la caméra par rapport à sa direction (axe position-focale)). En degrés. + * @param Renderer utilisant la caméra à piloter si non nul (GetActiveCamera sur le renderer est utilisé). + * @param URL de l'aide + * @param Balise de l'aide + */ + QtVtkViewDefinitionDialog (QWidget* parent, const IN_STD string& title, bool modal, const TkUtil::UTF8String& name, const TkUtil::UTF8String& comment, + double position [3], double focal [3], double viewUp [3], double roll, vtkRenderer* renderer, + const IN_STD string& helpURL ="", const IN_STD string& helpTag = ""); + + /** Destructeur. */ + virtual ~QtVtkViewDefinitionDialog ( ); + + /** @return l'éventuel nom du point de vue. */ + virtual TkUtil::UTF8String getName ( ) const; + + /** @return l'éventuel commentaire associé au point de vue. */ + virtual TkUtil::UTF8String getComment ( ) const; + + /** @param les coordonnées de la caméra, en retour. */ + virtual void getPosition (double coords [3]) const; + + /** @param la position de la focale la caméra, en retour. */ + virtual void getFocalPoint (double coords [3]) const; + + /** @param la direction vers le haut de la caméra, en retour. */ + virtual void getViewUp (double direction [3]) const; + + /** @return le roulis de la caméra. */ + virtual double getRoll ( ) const; + + /** @return le bouton "Appliquer" de la boite de dialogue. */ + virtual QPushButton* getApplyButton ( ) const; + + /** @return le bouton "Annuler" de la boite de dialogue. */ + virtual QPushButton* getCancelButton ( ) const; + + + public slots : + + /** Appelé quand l'utilisateur appuie sur le bouton "Appliquer". + */ + virtual void apply ( ); + + /** Appelé quand l'utilisateur appuie sur le bouton "Fermer". + * Invoque Dialog::accept. + * Envoie le signal "applied" avec en argument cette instance. + */ + virtual void close ( ); + + /** Appelé quand l'utilisateur appuie sur le bouton "Annuler". + * Invoque Dialog::reject. + * Envoie le signal "canceled" avec en argument cette instance. + */ + virtual void reject ( ); + + + signals : + + /** Envoyé lorsque le bouton "Appliquer" est cliqué. + * @param l'instance siège de l'évènement. + */ + void applied (QtVtkViewDefinitionDialog* dialog); + + /** Envoyé lorsque le bouton "Annuler" est cliqué. + * @param l'instance siège de l'évènement. + */ + void canceled (QtVtkViewDefinitionDialog* dialog); + + + protected : + + + private : + + /** Constructeur de copie. Interdit. */ + QtVtkViewDefinitionDialog (const QtVtkViewDefinitionDialog&); + + /** Opérateur de copie. Interdit. */ + QtVtkViewDefinitionDialog& operator = (const QtVtkViewDefinitionDialog&); + + /** Le panneau de paramétrage de l'opération d'extraction. */ + QtVtkViewDefinitionPanel* _viewDefinitionPanel; + + /** Le panneau proposant "Appliquer" et "Annuler". */ + QtDlgClosurePanel* _closurePanel; +}; // class QtVtkViewDefinitionDialog + + + +#endif // QT_VTK_VIEW_DEFINITION_DIALOG_H diff --git a/src/QtVtk/public/QtVtk/QtVtkViewDefinitionPanel.h b/src/QtVtk/public/QtVtk/QtVtkViewDefinitionPanel.h new file mode 100644 index 0000000..673d9ca --- /dev/null +++ b/src/QtVtk/public/QtVtk/QtVtkViewDefinitionPanel.h @@ -0,0 +1,199 @@ +#ifndef QT_VTK_VIEW_DEFINITION_PANEL_H +#define QT_VTK_VIEW_DEFINITION_PANEL_H + +#include +#include +#include +#include + +#include + +#include + +#include + + +/** + * Panneau Qt permettant de définir interactivement la vue d'un théâtre. Cette vue est définie par l'emplacement et la focale de la caméra. + * Ce panneau peut piloter, optionnellement, une caméra VTK. La caméra est mise à jour avec les derniers paramètres saisis lorsque + * l'utilisateur effectue un retour chariot dans un champ numérique. + */ +class QtVtkViewDefinitionPanel : public QWidget +{ + Q_OBJECT + + public : + + /** Constructeur. + * @param widget parent. Ne doit pas être nul. + * @param titre de l'application (pour les messages d'erreur). + * @param Eventuel nom du point de vue + * @param Eventuel commentaire associé au point de vue + * @param position initiale (x, y, z) de la caméra. + * @param focale initiale (x, y, z) de la caméra. + * @param direction vers le haut (dx, dy, dz) de la caméra. + * @param roulis (angle de la caméra par rapport à sa direction (axe position-focale)). En degrés. + * @param Renderer utilisant la caméra à piloter si non nul (GetActiveCamera sur le renderer est utilisé). + */ + QtVtkViewDefinitionPanel (QWidget* parent, const IN_STD string& appTitle, const TkUtil::UTF8String& name, const TkUtil::UTF8String& comment, + double position [3], double focal [3], double viewUp [3], double roll, vtkRenderer* renderer); + + /** Destructeur. */ + virtual ~QtVtkViewDefinitionPanel ( ); + + /** @return l'éventuel nom du point de vue. */ + virtual TkUtil::UTF8String getName ( ) const; + + /** @return l'éventuel commentaire associé au point de vue. */ + virtual TkUtil::UTF8String getComment ( ) const; + + /** @param les coordonnées de la caméra, en retour. */ + virtual void getPosition (double coords [3]) const; + + /** @param la position de la focale la caméra, en retour. */ + virtual void getFocalPoint (double coords [3]) const; + + /** @param direction vers le haut (dx, dy, dz) de la caméra, en retour. */ + virtual void getViewUp (double direction [3]) const; + + /** @return le roulis de la caméra. */ + virtual double getRoll ( ) const; + + /** Applique les modification à l'éventuelle caméra. Affecte true à _updated. */ + virtual void apply ( ); + + /** Restaure les paramètres initiaux, aussi bien au niveau du panneau qu'au niveau de la caméra éventuellement pilotée. + */ + virtual void reset ( ); + + /** @return true si les paramètres ont été modifiés depuis le constructeur, sinon retourne false. */ + virtual bool isModified ( ) const + { return _modified; } + + + protected : + + + /** + * @param Nouvelle coordonnées de la caméra. + */ + virtual void setPosition (double coords [3]); + + /** + * @param Nouvelle coordonnées de la focale de la caméra. + */ + virtual void setFocalPoint (double coords [3]); + + /** + * @param Nouvelle direction haute de la caméra. + */ + virtual void setViewUp (double direction [3]); + + /** + * @param Nouveau roulis de la caméra. + */ + virtual void setRoll (double roll); + + /** + * Affecte le caractère "modifié" (depuis sa construction) à cette instance. + */ + virtual void setModified (bool modified) + { _modified = modified; } + + /** @return true si les paramètres n'ont pas été modifiés depuis la dernière mise à jour de la caméra, sinon retourne false. */ + virtual bool isUpdated ( ) const + { return _updated; } + + /** + * @param Mise à jour du caractère "caméra mis à jour". + */ + virtual void setUpdated (bool updated) + { _updated = updated; } + + /** + * Met à jour les paramètres au regard des valeurs dans le panneau. + * Appelle setModified (true) et setUpdated (false) si l'un d'entre-eux est modifié. + */ + virtual void updateData ( ); + + + protected slots : + + /** Appelé quand l'utilisateur modifie un champ dans le panneau. + * @param Nouveau texte. + * Affecte setUpdated (false). + */ + virtual void viewFieldModifiedCallback (const QString&); + + /** Appelé quand l'utilisateur valide la saisie d'un champ dans le panneau. Appelle apply. + * Affecte true à _modified si un paramètre est changé. + */ + virtual void viewFieldValidatedCallback ( ); + + + private : + + /** Constructeur de copie. Interdit. */ + QtVtkViewDefinitionPanel (const QtVtkViewDefinitionPanel&); + + /** Opérateur de copie. Interdit. */ + QtVtkViewDefinitionPanel& operator = (const QtVtkViewDefinitionPanel&); + + /** Le titre de l'application. */ + IN_STD string _appTitle; + + /** Le champ de définition du nom. */ + QtTextField* _nameTextField; + + /** Le champ de définition du commentaire. */ + QtTextField* _commentTextField; + + /** La position de la caméra. */ + Qt3DDataPanel* _positionPanel; + + /** La position de la focale de la caméra. */ + Qt3DDataPanel* _focalPanel; + + /** La direction vers le haut de la caméra. */ + Qt3DDataPanel* _viewUpPanel; + + /** Le champ de définition du roulis. */ + QtTextField* _rollTextField; + + /** Le renderer utilisant la caméra pilotée. */ + vtkRenderer* _renderer; + + /** La position initiale. */ + double _initialPosition [3]; + + /** La position initiale de la focale. */ + double _initialFocal [3]; + + /** La direction vers le haut initiale. */ + double _initialViewUp [3]; + + /** La valeur initiale du roulis. */ + double _initialRoll; + + /** La dernière position. */ + double _position [3]; + + /** La dernière position de la focale. */ + double _focal [3]; + + /** La direction vers le haut. */ + double _viewUp [3]; + + /** La dernère valeur du roulis. */ + double _roll; + + /** Les paramètres ont ils été modifiés par l'utilisateur ? */ + bool _modified; + + /** La vue est-elle à jour par rapport aux paramètres ? */ + bool _updated; +}; // class QtVtkViewDefinitionPanel + + + +#endif // QT_VTK_VIEW_DEFINITION_PANEL_H diff --git a/src/QtVtk/public/QtVtk/QtVtkViewPointToolBar.h b/src/QtVtk/public/QtVtk/QtVtkViewPointToolBar.h new file mode 100644 index 0000000..04d7ee7 --- /dev/null +++ b/src/QtVtk/public/QtVtk/QtVtkViewPointToolBar.h @@ -0,0 +1,84 @@ +#ifndef QT_VTK_VIEWPOINT_TOOL_BAR_H +#define QT_VTK_VIEWPOINT_TOOL_BAR_H + +#include +#include + +#include + + +/** + * @brief Barre de boutons à menu permettant de gérer un point de vue dans une fenêtre VTK et d'assurer la persistance de ce point de vue. + * @since 8.7.0 + */ +class QtVtkViewPointToolBar : public QToolBar +{ + Q_OBJECT + + public : + + /** + * @param Parent + * @param Camera VTK associée aux points de vue + * @param Eventuel gestionnaire de rendu (pour forcer les opération d'actualisation de la vue). + */ + QtVtkViewPointToolBar (QWidget* parent, vtkCamera& camera, vtkRenderer* renderer); + + /** + * Destructeur. RAS. + */ + virtual ~QtVtkViewPointToolBar ( ); + + /** + * Ajoute le point de vue transmis en argument à la barre de boutons. + */ + virtual void addViewPoint (const QtVtkViewPointToolButton::VtkViewPoint& viewPoint); + + /** + * Enlève le point de vue dont une référence sur le bouton est transmise en argument. + */ + virtual void removeViewPoint (QtVtkViewPointToolButton& viewPointButton); + + + protected slots : + + /** + * Ajoute le point de vue aux points de vue existants. + */ + virtual void newViewPointCallback ( ); + + /** + * Réinitialise (supprime tous les points de vue. + */ + virtual void initializeCallback ( ); + + /** + * Exporte les points de vue dans un fichier. + */ + virtual void exportViewPointsCallback ( ); + + /** + * Importe les points de vue depusi un fichier. + */ + virtual void importViewPointsCallback ( ); + + + private : + + QtVtkViewPointToolBar (const QtVtkViewPointToolBar&); + QtVtkViewPointToolBar& operator = (const QtVtkViewPointToolBar&); + + /** Points de vue gérés. */ + std::vector _viewPointButtons; + + /** Indice du prochain bouton créé. */ + size_t _nextButton; + + /** Camera VTK associée. */ + vtkCamera* _camera; + + /** Gestionnaire de rendu (pour forcer les opération d'actualisation de la vue). */ + vtkRenderer* _renderer; +}; // class QtVtkViewPointToolBar + +#endif // QT_VTK_VIEWPOINT_TOOL_BAR_H diff --git a/src/QtVtk/public/QtVtk/QtVtkViewPointToolButton.h b/src/QtVtk/public/QtVtk/QtVtkViewPointToolButton.h new file mode 100644 index 0000000..8a8e224 --- /dev/null +++ b/src/QtVtk/public/QtVtk/QtVtkViewPointToolButton.h @@ -0,0 +1,124 @@ +#ifndef QT_VTK_VIEWPOINT_TOOL_BUTTON_H +#define QT_VTK_VIEWPOINT_TOOL_BUTTON_H + +#include +#include +#include +#include +#include + + +/** + * @brief Bouton à menu permettant de gérer un point de vue dans une fenêtre VTK et d'assurer la persistance de ce point de vue. + * @since 8.7.0 + */ +class QtVtkViewPointToolButton : public QToolButton +{ + Q_OBJECT + + public : + + /** + * La définition d'un point de vue. + */ + struct VtkViewPoint + { + VtkViewPoint ( ); + VtkViewPoint (const VtkViewPoint& vp); + VtkViewPoint& operator = (const VtkViewPoint& vp); + VtkViewPoint& operator = (const vtkCamera&); + ~VtkViewPoint ( ); + + /** Nom de la vue et commentaire associé. */ + TkUtil::UTF8String name, comment; + + /** Position de l'observateur. */ + double position [3]; + + /** Point focal. */ + double focalPoint [3]; + + /** Direction vers le haut. */ + double viewUp [3]; + + /** Roulis (rotation autour de l'axe de visée). */ + double roll; + }; // struct VtkViewPoint + + static Preferences::Section* viewPointToSection (const VtkViewPoint& viewpoint); + static VtkViewPoint sectionToViewPoint (const Preferences::Section& section); + + + /** + * @param Parent + * @param Icône du bouton + * @param Nom du point de vue + * @param Camera VTK associée au point de vue + * @param Eventuel gestionnaire de rendu (pour forcer les opération d'actualisation de la vue). + */ + QtVtkViewPointToolButton (QWidget* parent, const std::string& icon, const TkUtil::UTF8String& name, vtkCamera& camera, vtkRenderer* renderer); + + /** + * @param Parent + * @param Icône du bouton + * @param Définition du point de vue + * @param Camera VTK associée au point de vue + * @param Eventuel gestionnaire de rendu (pour forcer les opération d'actualisation de la vue). + */ + QtVtkViewPointToolButton (QWidget* parent, const std::string& icon, const VtkViewPoint& viewPoint, vtkCamera& camera, vtkRenderer* renderer); + + /** + * Destructeur. RAS. + */ + virtual ~QtVtkViewPointToolButton ( ); + + /** + * @return La description du point de vue + */ + virtual const VtkViewPoint& getViewPoint ( ) const; + + /** + * @param Nouveau point de vue. Modifie également la vue graphique. + */ + virtual void setViewPoint (const VtkViewPoint& vp); + + + protected slots : + + /** + * Modifie la vue conformément aux paramétrage de ce point de vue. + */ + virtual void applyViewPointCallback ( ); + + /** + * Affiche une boite de dialogue de modification du point de vue. + */ + virtual void editViewPointCallback ( ); + + /** + * Supprime la vue (et le bouton). + */ + virtual void removeViewPointCallback ( ); + + /** + * Exporte le point de vue dans un fichier. + */ + virtual void exportViewPointCallback ( ); + + + private : + + QtVtkViewPointToolButton (const QtVtkViewPointToolButton&); + QtVtkViewPointToolButton& operator = (const QtVtkViewPointToolButton&); + + /** Le point de vue. */ + VtkViewPoint _viewPoint; + + /** Camera VTK associée. */ + vtkCamera* _camera; + + /** Gestionnaire de rendu (pour forcer les opération d'actualisation de la vue). */ + vtkRenderer* _renderer; +}; // class QtVtkViewPointToolButton + +#endif // QT_VTK_VIEWPOINT_TOOL_BUTTON_H diff --git a/src/viewpoint/CMakeLists.txt b/src/viewpoint/CMakeLists.txt new file mode 100644 index 0000000..4fa2264 --- /dev/null +++ b/src/viewpoint/CMakeLists.txt @@ -0,0 +1,18 @@ +find_package (GUIToolkitsVariables) + +include (${CMAKE_SOURCE_DIR}/cmake/version.cmake) +include (${GUIToolkitsVariables_CMAKE_DIR}/common.cmake) +include (${GUIToolkitsVariables_CMAKE_DIR}/common_qt.cmake) +include (${GUIToolkitsVariables_CMAKE_DIR}/workarounds.cmake) + +add_executable (viewpoint viewpoint.cpp QtViewPointWindow.cpp) +set_property (TARGET viewpoint PROPERTY AUTOMOC ON) + +set (ALL_TARGETS viewpoint) + +foreach (exe ${ALL_TARGETS}) + target_include_directories (${exe} PRIVATE ../QtVtk/public ${CMAKE_CURRENT_SOURCE_DIR}) + target_compile_options (${exe} PRIVATE ${SHARED_CFLAGS}) + target_link_libraries (${exe} PRIVATE QtVtk) + set_target_properties (${exe} PROPERTIES INSTALL_RPATH_USE_LINK_PATH 1 INSTALL_RPATH ${CMAKE_PACKAGE_RPATH_DIR}) +endforeach ( ) diff --git a/src/viewpoint/QtViewPointWindow.cpp b/src/viewpoint/QtViewPointWindow.cpp new file mode 100644 index 0000000..28dbb85 --- /dev/null +++ b/src/viewpoint/QtViewPointWindow.cpp @@ -0,0 +1,289 @@ +#include "QtViewPointWindow.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +using namespace TkUtil; +using namespace std; + +static const TkUtil::Charset charset ("àéèùô"); + +USE_ENCODING_AUTODETECTION + + +QtViewPointWindow::QtViewPointWindow ( ) + : QMainWindow ( ), _graphicWindow (0), _renderer (0), _renderWindow (0), _actors ( ), _surfaces ( ) +{ + createGui ( ); + createMenu ( ); +} // QtViewPointWindow::QtViewPointWindow + + +void QtViewPointWindow::createGui ( ) +{ + _graphicWindow = new QtVtkGraphicWidget (this); + _graphicWindow->setAttribute (Qt::WA_TranslucentBackground, true); // Bonne gestion transparence + setCentralWidget (_graphicWindow); + _renderer = vtkRenderer::New ( ); + _renderWindow = vtkRenderWindow::New ( ); + _renderWindow->Render ( ); // Pour bonne gestion transparence + _renderWindow->SetAlphaBitPlanes (1); // Bonne gestion transparence + _renderWindow->SetMultiSamples (0); // Bonne gestion transparence + _renderer->SetUseDepthPeeling (true); // Bonne gestion transparence + _renderer->SetBackground (1., 1., 1.); // Blanc +//_renderer->SetBackground (0., 0., 0.); // Noir + _renderWindow->AddRenderer (_renderer); + vtkRenderer* trihedronRenderer = vtkRenderer::New ( ); + trihedronRenderer->InteractiveOff ( ); + trihedronRenderer->SetViewport (0, 0, 0.2, 0.2); + trihedronRenderer->SetLayer (1); + vtkTrihedronCommand* trihedronCommand = vtkTrihedronCommand::New ( ); + _renderer->AddObserver (vtkCommand::StartEvent, trihedronCommand); + trihedronCommand->SetRenderer (trihedronRenderer); + vtkTrihedron* trihedron = vtkTrihedron::New ( ); + trihedron->PickableOff ( ); + trihedronRenderer->AddActor (trihedron); + _renderWindow->SetNumberOfLayers (2); + _renderWindow->AddRenderer (trihedronRenderer); + _graphicWindow->SetRenderWindow (_renderWindow); + vtkInteractorStyleSwitch* interactorStyle = vtkInteractorStyleSwitch::New ( ); + _graphicWindow->GetInteractor ( )->SetInteractorStyle (interactorStyle); + _graphicWindow->GetInteractor ( )->SetRenderWindow (_renderWindow); + _graphicWindow->setMinimumSize (800, 600); + _graphicWindow->resize (800, 600); +} // QtViewPointWindow::createGui + + +void QtViewPointWindow::createMenu ( ) +{ + addToolBar (Qt::TopToolBarArea, new QtVtkViewPointToolBar (this, *_renderer->GetActiveCamera ( ), _renderer)); + QMenuBar* menubar = menuBar ( ); + + QMenu* fileMenu = new QMenu ("&Fichier", menubar); + menubar->addMenu (fileMenu); + fileMenu->setToolTipsVisible (true); + QAction* action = new QAction ("Im&primer ...", this); + connect (action, SIGNAL (triggered( )), this, SLOT(printCallback ( ))); + fileMenu->addAction (action); + action = new QAction ("Im&primer dans un fichier ...", this); + connect (action, SIGNAL (triggered( )), this, SLOT(printToFileCallback ( ))); + fileMenu->addAction (action); + fileMenu->addSeparator ( ); + action = new QAction ("&Quitter", this); + connect (action, SIGNAL (triggered ( )), this, SLOT (quitCallback ( ))); + fileMenu->addAction (action); + + QMenu* objectMenu = new QMenu ("&Objets", menubar); + menubar->addMenu (objectMenu); + objectMenu->setToolTipsVisible (true); + action = new QAction ("S&upprimer", this); + connect (action, SIGNAL (triggered ( )), this, SLOT (removeObjectsCallback ( ))); + objectMenu->addAction (action); + action = new QAction (QSTR ("Sp&hère ..."), this); + connect (action, SIGNAL (triggered ( )), this, SLOT (sphereCallback ( ))); + objectMenu->addAction (action); + action = new QAction ("C&ylindre ...", this); + connect (action, SIGNAL (triggered ( )), this, SLOT (cylinderCallback ( ))); + objectMenu->addAction (action); +} // QtViewPointWindow::createMenu + + +void QtViewPointWindow::printCallback ( ) +{ + try + { + raise ( ); // Eviter qu'une fenêtre recouvre celle-ci + CHECK_NULL_PTR_ERROR (_renderWindow) + QtVTKPrintHelper::PrinterStatus status = QtVTKPrintHelper::print (*_renderWindow, this); + } + catch (const Exception& e) + { + QtMessageBox::displayErrorMessage (this, windowTitle ( ).toStdString ( ), e.getFullMessage ( )); + } + catch (...) + { + QtMessageBox::displayErrorMessage (this, windowTitle ( ).toStdString ( ), "Erreur non documentée"); + } +} // QtViewPointWindow::printCallback + + +void QtViewPointWindow::printToFileCallback ( ) +{ + try + { + raise ( ); // Eviter qu'une fen^etre recouvre celle-ci + CHECK_NULL_PTR_ERROR (_renderWindow) + QtVTKPrintHelper::PrinterStatus status = QtVTKPrintHelper::printToFile (*_renderWindow, this); + } + catch (const Exception& e) + { + QtMessageBox::displayErrorMessage (this, windowTitle ( ).toStdString ( ), e.getFullMessage ( )); + } + catch (...) + { + QtMessageBox::displayErrorMessage (this, windowTitle ( ).toStdString ( ), "Erreur non documentée"); + } +} // QtViewPointWindow::printToFileCallback + + +void QtViewPointWindow::quitCallback ( ) +{ + QApplication::exit (0); +} // QtViewPointWindow::quitCallback + + +void QtViewPointWindow::removeObjectsCallback ( ) +{ + try + { + CHECK_NULL_PTR_ERROR (_renderer) + CHECK_NULL_PTR_ERROR (_renderWindow) + for (vector::iterator it = _actors.begin ( ); + _actors.end ( ) != it; it++) + { + _renderer->RemoveActor (*it); + (*it)->Delete ( ); + } + for (vector::iterator itpd = _surfaces.begin ( ); + _surfaces.end ( ) != itpd; itpd++) + (*itpd)->Delete ( ); + + _actors.clear ( ); + _surfaces.clear ( ); + } + catch (const Exception& e) + { + QtMessageBox::displayErrorMessage (this, windowTitle ( ).toStdString ( ), e.getFullMessage ( )); + } + catch (...) + { + QtMessageBox::displayErrorMessage (this, windowTitle ( ).toStdString ( ), "Erreur non documentée"); + } +} // QtViewPointWindow::removeObjectsCallback + + +void QtViewPointWindow::sphereCallback ( ) +{ + try + { + CHECK_NULL_PTR_ERROR (_renderer) + CHECK_NULL_PTR_ERROR (_renderWindow) + // Mériterait une boite de dialogue dédiée : + double x = 0., y = 0., z = 0., radius = 1.; + QtCoordinatesDialog coordsDialog (this, "Centre de la sphère", "X :", "Y :", "Z :", x, y, z, false, true, true, true); + if (QDialog::Rejected == coordsDialog.exec ( )) + return; + coordsDialog.getCoordinates (x, y, z); + bool ok = true; + radius = QInputDialog::getDouble (this, QSTR ("Rayon de la sphère"), "Rayon :", radius, 0., 9.99E9, 10, &ok); + if (false == ok) + return; + vtkSphereSource* sphere = vtkSphereSource::New ( ); + sphere->SetCenter (x, y, z); + sphere->SetThetaResolution (360 / 4); + sphere->SetPhiResolution (360 / 4); + sphere->SetRadius (radius); + vtkPolyDataMapper* mapper = vtkPolyDataMapper::New ( ); + vtkActor* actor = vtkActor::New ( ); + mapper->SetInputConnection (sphere->GetOutputPort ( )); + actor->SetMapper (mapper); + _renderer->AddActor (actor); + _renderer->ResetCamera ( ); + _renderWindow->Render ( ); + _actors.push_back (actor); + vtkPolyData* surface = sphere->GetOutput ( ); + sphere->Update ( ); + surface->Register (0); + _surfaces.push_back (surface); + mapper->Delete ( ); mapper = 0; + sphere->Delete ( ); sphere = 0; + } + catch (const Exception& e) + { + QtMessageBox::displayErrorMessage (this, windowTitle ( ).toStdString ( ), e.getFullMessage ( )); + } + catch (...) + { + QtMessageBox::displayErrorMessage (this, windowTitle ( ).toStdString ( ), "Erreur non documentée"); + } +} // QtViewPointWindow::sphereCallback + + +void QtViewPointWindow::cylinderCallback ( ) +{ + try + { + CHECK_NULL_PTR_ERROR (_renderer) + CHECK_NULL_PTR_ERROR (_renderWindow) + // Mériterait une boite de dialogue dédiée : + double x = 0., y = 0., z = 0., radius = 1., height = 1; + QtCoordinatesDialog coordsDialog (this, "Centre du cylindre", "X :", "Y :", "Z :", x, y, z, false, true, true, true); + if (QDialog::Rejected == coordsDialog.exec ( )) + return; + coordsDialog.getCoordinates (x, y, z); + bool ok = true; + height = QInputDialog::getDouble (this, "Hauteur du cylindre", "Hauteur :", height, 0., 9.99E9, 10, &ok); + if (false == ok) + return; + radius = QInputDialog::getDouble (this, "Rayon du cylindre", "Rayon :", radius, 0., 9.99E9, 10, &ok); + if (false == ok) + return; + vtkCylinderSource* cylinder = vtkCylinderSource::New ( ); + cylinder->SetCenter (x, y, z); + cylinder->SetResolution (360); + cylinder->SetHeight (height); + cylinder->SetRadius (radius); + cylinder->CappingOff ( ); + // Par défaut le cylindre est le long de l'axe des Y, on le veut le long des X : + vtkTransformFilter* filter = vtkTransformFilter::New ( ); + vtkTransform* transform = vtkTransform::New ( ); + transform->RotateZ (90.); + filter->SetTransform (transform); + filter->SetInputData (cylinder->GetOutput ( )); + cylinder->Update ( ); + vtkPolyDataMapper* mapper = vtkPolyDataMapper::New ( ); + vtkActor* actor = vtkActor::New ( ); + mapper->SetInputConnection (filter->GetOutputPort ( )); + actor->SetMapper (mapper); + _renderer->AddActor (actor); + _renderer->ResetCamera ( ); + _renderWindow->Render ( ); + _actors.push_back (actor); + vtkPolyData* surface = filter->GetPolyDataOutput ( ); + surface->Register (0); + _surfaces.push_back (surface); + mapper->Delete ( ); mapper = 0; + cylinder->Delete ( ); cylinder = 0; + } + catch (const Exception& e) + { + QtMessageBox::displayErrorMessage (this, windowTitle ( ).toStdString ( ), e.getFullMessage ( )); + } + catch (...) + { + QtMessageBox::displayErrorMessage (this, windowTitle ( ).toStdString ( ), "Erreur non documentée"); + } +} // QtViewPointWindow::cylinderCallback diff --git a/src/viewpoint/QtViewPointWindow.h b/src/viewpoint/QtViewPointWindow.h new file mode 100644 index 0000000..fd3c459 --- /dev/null +++ b/src/viewpoint/QtViewPointWindow.h @@ -0,0 +1,58 @@ +#include + +#include +#include + +#include +#include +#include +#include + +#include + + +class QtViewPointWindow : public QMainWindow +{ + Q_OBJECT + + public : + + QtViewPointWindow ( ); + + ~QtViewPointWindow ( ) + { } + + + protected : + + void createGui ( ); + void createMenu ( ); + + + protected slots : + + + virtual void printCallback ( ); + virtual void printToFileCallback ( ); + virtual void quitCallback ( ); + virtual void removeObjectsCallback ( ); + virtual void sphereCallback ( ); + virtual void cylinderCallback ( ); + + + private : + + QtViewPointWindow (const QtViewPointWindow&) + : QMainWindow ( ) + { } + QtViewPointWindow& operator = (const QtViewPointWindow&) + { return *this; } + + QtVtkGraphicWidget* _graphicWindow; + vtkRenderer* _renderer; + vtkRenderWindow* _renderWindow; + std::vector _actors; + std::vector _surfaces; +}; // class QtViewPointWindow + + diff --git a/src/viewpoint/viewpoint.cpp b/src/viewpoint/viewpoint.cpp new file mode 100644 index 0000000..2237bdd --- /dev/null +++ b/src/viewpoint/viewpoint.cpp @@ -0,0 +1,40 @@ +/** + * Petite application test mettant en scène une chambre d'expérience avec des + * pointages laser. + */ +#include "QtViewPointWindow.h" +#include + +#include +#include + +#include + +#include + + +using namespace TkUtil; +using namespace std; + + +int main (int argc, char* argv[]) +{ + try + { + QApplication* application = new QApplication (argc, argv); + QtVtk::initialize ( ); + QtViewPointWindow* mainWindow = new QtViewPointWindow ( ); + mainWindow->show ( ); + return application->exec ( ); + } + catch (const Exception& e) + { + cerr << "ERREUR : " << e.getFullMessage ( ) << endl; + return -1; + } + catch (...) + { + cerr << "ERREUR non documentée." << endl; + return -2; + } +} // main diff --git a/versions.txt b/versions.txt index a9e821f..33dbacf 100644 --- a/versions.txt +++ b/versions.txt @@ -1,5 +1,12 @@ A FAIRE : tester le vtkIntersectionPolyDataFilter de VTK 7, voir si de base il propose les services attendus (Inner, ...). +Version 8.7.0 : 08/04/25 +=============== + +Classes QtVtkViewPointToolBar et QtVtkViewPointToolButton. +Ce projet dépend maintenant de PrefsQt v 6.x. + + Version 8.6.0 : 22/11/24 ===============