diff --git a/Plugins/org.mitk.gui.qt.matchpoint.visualizer/documentation/UserManual/Manual.dox b/Plugins/org.mitk.gui.qt.matchpoint.visualizer/documentation/UserManual/Manual.dox index 0c1aedd4f0..ede511a3e5 100644 --- a/Plugins/org.mitk.gui.qt.matchpoint.visualizer/documentation/UserManual/Manual.dox +++ b/Plugins/org.mitk.gui.qt.matchpoint.visualizer/documentation/UserManual/Manual.dox @@ -1,86 +1,88 @@ /** \page org_mitk_views_matchpoint_visualizer The MatchPoint Registration Visualizer View \imageMacro{map_vis_icon_doc.svg, "Icon of the Registration Visualizer",3} \tableofcontents \section MAP_VIS_Introduction Introduction This view is in development to offer the user a way to visualize MatchPoint registrations (so the transformation/deformation field they represent) in a MITK scene. -Currently only a simple grid visualization and glyph visualization is implemented.\n +Currently, a simple grid visualization and glyph visualization is implemented.\n \remark This is an experimental version and work in progress. So please excuse errors or usage issues and report them at https://phabricator.mitk.org. \section MAP_VIS_Usage Usage \imageMacro{map_view_visualizer_example.png, "Example screenshot showing the main elements of the view used to visualize a registration.", 14} The view has following steps/sections:\n\n -(1) Registration slot: Shows the currently selected registration whose visualization settings should be altered. Click to change.\n\n +(1) Registration slot: Shows the currently selected registration which is visualized and whose visualization settings should be altered. Click to change.\n\n -(2) Registration information: General information of the selected registration.\n\n +(2) Registration information: General information on the selected registration.\n\n (3) Update visual settings: By clicking the button the current settings will be accepted and the visualization of the registration will be updated accordingly.\n\n (4) Mapping direction: Allows to select the mapping direction that should be visualized (more details see below \ref MAP_VIS_Direction).\n\n (5) Visualization style: Select how the registration should be visualized. Currently two options are available.: - Grid: Visualize as a wire frame grid that is deformed by the registration. The magnitude of deformation can be encoded in the grid color (cf style example "a)" below). - Glyph: Visualize as a cloud of arrows that follow the deformation vectors of the registrations. The magnitude of deformation can be encoded in the glyph color (cf style example "f)" below). More details can be found in the settings and style section below. \imageMacro{map_view_visualizer_style_example.png, "Example of the appearance of different style settings: a) grid style; b) grid with no color interpolation; c) grid in unicolor; d) grid with different grid frequency (frequency=1); e) grid also showing start grid (in gray); f) glyph style.", 14} \section MAP_VIS_Settings_vis Visualization settings \imageMacro{map_view_visualizer_vis_settings.png, "Visualization settings offered by view.", 8} (6) Color style: The following color styles are available: - uni color: everything painted in the selected color (cf style example "c)"). Click on the color button to change the used color. - vector magnitode: the color is depending on the respective vector magnitude of the deformation field (cf style example "a)" and "b)"). See (7) for instructions to change the used color encoding for the magnitude. (7) Color coding settings: One can change the color and associated vector length (in mm) for 4 classes of magnitude (negligible, small, medium and large). The color is encoded accordingly.\n\n (8) Interpolate colors: By default activated, the colors between to magnitude classes (see (7)) will be linear interpolated (e.g. with the settings given in the example shifts of 5 mm will be yellow, 10 mm will be orange and >=15 mm will be red). If interpolation is deactivated the color of one class is used till a next higher class is reached. Cf style example "a)" and "b)", in "b)" no red color can be seen because no shift was 15 mm or greater (magnitude class "large"). \section MAP_VIS_Settings_grid Grid settings \imageMacro{map_view_visualizer_grid_settings.png, "Grid settings offered by view.", 8} These are only available for style "grid".\n\n -(9) Grid frequency: Allows to control how spares the grid frame should be. One can also achieve something similar with changing the FOV spacing (see below), but using the frequency allows for a sparse frame and still having a high resolution in the frame deformation. The latter one would loose if just using a low FOV spacing. Style example "a)" and "d)" illustrate different frequency settings and there effect.\n\n +(9) Grid frequency: Allows to control how spares the grid frame should be. With a frequency n only each n-th element of the frame will be visualized, so the visual grid has n-times the spacing of the FOV. One can also achieve something similar with just changing the FOV spacing (see below), but using the frequency allows for a sparse frame and still having a high resolution in the frame deformation. The latter one would loose if just using a low FOV spacing. Style example "a)" and "d)" illustrate different frequency settings and there effect.\n\n (10) Start grid: If activated also the start grid of the registration will (for the chosen direction) will be visible. This is another grid specific possibility to illustrate the amount of deformation (cf style example "e)").\n\n (11) Start grid color: Select the color that should be used for the start grid. Click on the color button to change the used color. \section MAP_VIS_Settings_FOV Field of view (FOV) settings -\imageMacro{map_view_visualizer_grid_settings.png, "FOV settings offered by view.", 8} +\imageMacro{map_view_visualizer_FOV_settings.png, "FOV settings offered by view.", 8} The field of view defines the area of space (grid) that should be used for the visualization of the registration.\n\n (12) Size: Size of the FOV in mm.\n\n (13) Origin: Origin of the FOV in mm.\n\n (14) Spacing: Spacing of the FOV in mm. This directly impact the visualization's level of detail. IMPORTANT: Please be careful with setting small spacings, as it can lead to computational very expensive visualizations.\n\n (15) Orientation: Orientation matrix of the FOV (only readable).\n\n (16) FOV Reference slot: Select an image that should be used to define the geometric properties of the FOV. By default (and available) the target image used to determine the registration will be used. Click slot to change the FOV reference.\n\n (17) Relevant FOV reference properties: One can select which properties of the reference image will be used to specify the FOV.\n\n \section MAP_VIS_Direction Information regarding the directions Registrations can have two supported directions (direct and inverse). The direct kernel maps from the moving space into the target space, so this is the direction that "naively" people assume when they think about registrations. But practically it is only used to map continuous data like point sets. The inverse kernel maps from the target space into the moving space and is used to map images by so called inverse mapping. The effect is most obvious in the glyph style, where the glyphs points from the mapped space to the point in the moving space. -\section MAP_VIS_image_source Grid settings +\section MAP_VIS_used_data Data reference The data visible in the visualization styles images is part of the Patient 1 of the DIR_validation_data data set. For further information: https://www.creatis.insa-lyon.fr/rio/dir_validation_data -------------- + By downloading this data, you agreeing to follow these guidelines. When using any of the data provided for publications, please make reference to: The institution from which they were obtained: the Léon Bérard Cancer Center & CREATIS lab, Lyon, France. The article containing the description of this data: J. Vandemeulebroucke, S. Rit, J. Kybic, P. Clarysse, and D. Sarrut. Spatiotemporal motion estimation for respiratory-correlated imaging of the lungs. In Med Phys, 2011, 38(1), 166-178. pdf + --------------- */ \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.matchpoint.visualizer/src/internal/QmitkMatchPointRegistrationVisualizer.cpp b/Plugins/org.mitk.gui.qt.matchpoint.visualizer/src/internal/QmitkMatchPointRegistrationVisualizer.cpp index b264d54c9f..49fdf85bc0 100644 --- a/Plugins/org.mitk.gui.qt.matchpoint.visualizer/src/internal/QmitkMatchPointRegistrationVisualizer.cpp +++ b/Plugins/org.mitk.gui.qt.matchpoint.visualizer/src/internal/QmitkMatchPointRegistrationVisualizer.cpp @@ -1,795 +1,798 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "org_mitk_gui_qt_matchpoint_visualizer_Activator.h" // Blueberry #include #include // Mitk #include #include #include #include #include #include #include #include "mitkRegVisDirectionProperty.h" #include "mitkRegVisStyleProperty.h" #include "mitkRegVisColorStyleProperty.h" #include "mitkRegVisPropertyTags.h" #include "mitkRegVisHelper.h" #include "mitkMatchPointPropertyTags.h" #include "mitkRegistrationHelper.h" // Qmitk #include "QmitkMatchPointRegistrationVisualizer.h" // Qt #include #include const std::string QmitkMatchPointRegistrationVisualizer::VIEW_ID = "org.mitk.views.matchpoint.visualizer"; QmitkMatchPointRegistrationVisualizer::QmitkMatchPointRegistrationVisualizer() : m_Parent(nullptr), m_internalUpdateGuard(false), m_spSelectedFOVRefNode(nullptr), m_spSelectedRegNode(nullptr) { } void QmitkMatchPointRegistrationVisualizer::SetFocus() { } void QmitkMatchPointRegistrationVisualizer::CreateConnections() { connect(m_Controls->registrationNodeSelector, &QmitkAbstractNodeSelectionWidget::CurrentSelectionChanged, this, &QmitkMatchPointRegistrationVisualizer::OnNodeSelectionChanged); connect(m_Controls->fovReferenceNodeSelector, &QmitkAbstractNodeSelectionWidget::CurrentSelectionChanged, this, &QmitkMatchPointRegistrationVisualizer::OnNodeSelectionChanged); connect(m_Controls->m_pbStyleGrid, SIGNAL(clicked()), this, SLOT(OnStyleButtonPushed())); connect(m_Controls->m_pbStyleGlyph, SIGNAL(clicked()), this, SLOT(OnStyleButtonPushed())); connect(m_Controls->m_pbStylePoints, SIGNAL(clicked()), this, SLOT(OnStyleButtonPushed())); connect(m_Controls->m_comboDirection, SIGNAL(currentIndexChanged(int)), this, SLOT(OnDirectionChanged(int))); connect(m_Controls->m_pbUpdateViz, SIGNAL(clicked()), this, SLOT(OnUpdateBtnPushed())); connect(m_Controls->radioColorUni, SIGNAL(toggled(bool)), m_Controls->btnUniColor, SLOT(setEnabled(bool))); connect(m_Controls->radioColorVecMag, SIGNAL(toggled(bool)), m_Controls->groupColorCoding, SLOT(setEnabled(bool))); connect(m_Controls->m_pbStyleGrid, SIGNAL(toggled(bool)), m_Controls->tabGrid, SLOT(setEnabled(bool))); connect(m_Controls->cbVevMagInterlolate, SIGNAL(toggled(bool)), this, SLOT(OnColorInterpolationChecked(bool))); connect(m_Controls->m_checkUseRefSize, SIGNAL(clicked()), this, SLOT(TransferFOVRefGeometry())); connect(m_Controls->m_checkUseRefSpacing, SIGNAL(clicked()), this, SLOT(TransferFOVRefGeometry())); connect(m_Controls->m_checkUseRefOrigin, SIGNAL(clicked()), this, SLOT(TransferFOVRefGeometry())); connect(m_Controls->m_checkUseRefOrientation, SIGNAL(clicked()), this, SLOT(TransferFOVRefGeometry())); } void QmitkMatchPointRegistrationVisualizer::Error(QString msg) { mitk::StatusBar::GetInstance()->DisplayErrorText(msg.toLatin1()); MITK_ERROR << msg.toStdString().c_str(); } void QmitkMatchPointRegistrationVisualizer::CreateQtPartControl(QWidget* parent) { m_Controls = new Ui::MatchPointRegVisControls; // create GUI widgets from the Qt Designer's .ui file m_Controls->setupUi(parent); m_Parent = parent; this->m_Controls->registrationNodeSelector->SetDataStorage(this->GetDataStorage()); this->m_Controls->registrationNodeSelector->SetSelectionIsOptional(false); this->m_Controls->fovReferenceNodeSelector->SetDataStorage(this->GetDataStorage()); this->m_Controls->fovReferenceNodeSelector->SetSelectionIsOptional(false); m_Controls->registrationNodeSelector->SetInvalidInfo("Select registration."); m_Controls->registrationNodeSelector->SetPopUpTitel("Select registration."); m_Controls->registrationNodeSelector->SetPopUpHint("Select the registration object whose registration visualization should be edited."); m_Controls->fovReferenceNodeSelector->SetInvalidInfo("Select a FOV reference image."); m_Controls->fovReferenceNodeSelector->SetPopUpTitel("Select a FOV reference image."); m_Controls->fovReferenceNodeSelector->SetPopUpHint("Select the the image that should be used to define the field of view (FOV) for the registration visualization. The visualization will use the image geometry (size, orientation, spacing...)."); this->ConfigureNodePredicates(); this->m_Controls->btnVecMagColorSmall->setDisplayColorName(false); this->m_Controls->btnVecMagColorMedium->setDisplayColorName(false); this->m_Controls->btnVecMagColorLarge->setDisplayColorName(false); this->m_Controls->btnVecMagColorNeg->setDisplayColorName(false); this->m_Controls->btnUniColor->setDisplayColorName(false); this->m_Controls->btnStartGridColor->setDisplayColorName(false); this->CreateConnections(); this->m_Controls->radioColorUni->setChecked(false); this->m_Controls->radioColorVecMag->setChecked(true); this->CheckInputs(); this->LoadStateFromNode(); this->ConfigureVisualizationControls(); + + //deactivate because currently not an implemented style + this->m_Controls->m_pbStylePoints->setVisible(false); } void QmitkMatchPointRegistrationVisualizer::ConfigureNodePredicates() { m_Controls->registrationNodeSelector->SetNodePredicate(mitk::MITKRegistrationHelper::RegNodePredicate()); auto geometryCheck = [](const mitk::DataNode * node) { return node->GetData() && node->GetData()->GetGeometry(); }; mitk::NodePredicateFunction::Pointer hasGeometry = mitk::NodePredicateFunction::New(geometryCheck); auto nodePredicate = mitk::NodePredicateAnd::New(mitk::MITKRegistrationHelper::ImageNodePredicate().GetPointer(), hasGeometry.GetPointer()); m_Controls->fovReferenceNodeSelector->SetNodePredicate(nodePredicate.GetPointer()); } mitk::MAPRegistrationWrapper* QmitkMatchPointRegistrationVisualizer::GetCurrentRegistration() { mitk::MAPRegistrationWrapper* result = nullptr; if (this->m_spSelectedRegNode.IsNotNull()) { result = dynamic_cast(this->m_spSelectedRegNode->GetData()); assert(result); } return result; } mitk::DataNode::Pointer QmitkMatchPointRegistrationVisualizer::GetSelectedRegNode() const { return m_Controls->registrationNodeSelector->GetSelectedNode(); } mitk::DataNode::Pointer QmitkMatchPointRegistrationVisualizer::GetRefNodeOfReg(bool target) const { mitk::DataNode::Pointer spResult = nullptr; if (this->m_spSelectedRegNode.IsNotNull() && m_spSelectedRegNode->GetData()) { std::string nodeName; mitk::BaseProperty* uidProp; if (target) { uidProp = m_spSelectedRegNode->GetData()->GetProperty(mitk::Prop_RegAlgTargetData); } else { uidProp = m_spSelectedRegNode->GetData()->GetProperty(mitk::Prop_RegAlgMovingData); } if (uidProp) { //search for the target node mitk::NodePredicateDataProperty::Pointer predicate = mitk::NodePredicateDataProperty::New(mitk::Prop_UID, uidProp); spResult = this->GetDataStorage()->GetNode(predicate); } } return spResult; } mitk::DataNode::Pointer QmitkMatchPointRegistrationVisualizer::GetSelectedDataNode() { return m_Controls->fovReferenceNodeSelector->GetSelectedNode(); } void QmitkMatchPointRegistrationVisualizer::CheckInputs() { this->m_spSelectedRegNode = this->GetSelectedRegNode(); this->InitRegNode(); this->m_spSelectedFOVRefNode = this->GetSelectedDataNode(); } void QmitkMatchPointRegistrationVisualizer::ConfigureVisualizationControls() { if (!m_internalUpdateGuard) { m_internalUpdateGuard = true; m_Controls->groupViz->setVisible(this->m_spSelectedRegNode.IsNotNull()); m_Controls->m_pbUpdateViz->setEnabled(this->m_spSelectedRegNode.IsNotNull()); m_Controls->m_boxSettings->setEnabled(this->m_spSelectedRegNode.IsNotNull()); m_Controls->m_boxStyles->setEnabled(this->m_spSelectedRegNode.IsNotNull()); this->ActualizeRegInfo(this->GetCurrentRegistration()); this->m_Controls->m_checkUseRefSize->setEnabled(this->m_spSelectedRegNode.IsNotNull() && this->m_spSelectedFOVRefNode.IsNotNull()); this->m_Controls->m_checkUseRefOrigin->setEnabled(this->m_spSelectedRegNode.IsNotNull() && this->m_spSelectedFOVRefNode.IsNotNull()); this->m_Controls->m_checkUseRefSpacing->setEnabled(this->m_spSelectedRegNode.IsNotNull() && this->m_spSelectedFOVRefNode.IsNotNull()); m_internalUpdateGuard = false; } } void QmitkMatchPointRegistrationVisualizer::StoreStateInNode() { if (this->m_spSelectedRegNode.IsNotNull()) { //general this->m_spSelectedRegNode->SetProperty(mitk::nodeProp_RegVisDirection, mitk::RegVisDirectionProperty::New(this->m_Controls->m_comboDirection->currentIndex())); this->m_spSelectedRegNode->SetBoolProperty(mitk::nodeProp_RegVisGrid, this->m_Controls->m_pbStyleGrid->isChecked()); this->m_spSelectedRegNode->SetBoolProperty(mitk::nodeProp_RegVisGlyph, this->m_Controls->m_pbStyleGlyph->isChecked()); this->m_spSelectedRegNode->SetBoolProperty(mitk::nodeProp_RegVisPoints, this->m_Controls->m_pbStylePoints->isChecked()); //Visualization if (this->m_Controls->radioColorUni->isChecked()) { this->m_spSelectedRegNode->SetProperty(mitk::nodeProp_RegVisColorStyle, mitk::RegVisColorStyleProperty::New(0)); } else { this->m_spSelectedRegNode->SetProperty(mitk::nodeProp_RegVisColorStyle, mitk::RegVisColorStyleProperty::New(1)); } float tmpColor[3]; tmpColor[0] = this->m_Controls->btnUniColor->color().redF(); tmpColor[1] = this->m_Controls->btnUniColor->color().greenF(); tmpColor[2] = this->m_Controls->btnUniColor->color().blueF(); this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisColorUni, mitk::ColorProperty::New(tmpColor), nullptr, true); tmpColor[0] = this->m_Controls->btnVecMagColorNeg->color().redF(); tmpColor[1] = this->m_Controls->btnVecMagColorNeg->color().greenF(); tmpColor[2] = this->m_Controls->btnVecMagColorNeg->color().blueF(); this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisColor1Value, mitk::ColorProperty::New(tmpColor), nullptr, true); tmpColor[0] = this->m_Controls->btnVecMagColorSmall->color().redF(); tmpColor[1] = this->m_Controls->btnVecMagColorSmall->color().greenF(); tmpColor[2] = this->m_Controls->btnVecMagColorSmall->color().blueF(); this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisColor2Value, mitk::ColorProperty::New(tmpColor), nullptr, true); this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisColor2Magnitude, mitk::DoubleProperty::New(this->m_Controls->sbVecMagSmall->value()), nullptr, true); tmpColor[0] = this->m_Controls->btnVecMagColorMedium->color().redF(); tmpColor[1] = this->m_Controls->btnVecMagColorMedium->color().greenF(); tmpColor[2] = this->m_Controls->btnVecMagColorMedium->color().blueF(); this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisColor3Value, mitk::ColorProperty::New(tmpColor), nullptr, true); this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisColor3Magnitude, mitk::DoubleProperty::New(this->m_Controls->sbVecMagMedium->value()), nullptr, true); tmpColor[0] = this->m_Controls->btnVecMagColorLarge->color().redF(); tmpColor[1] = this->m_Controls->btnVecMagColorLarge->color().greenF(); tmpColor[2] = this->m_Controls->btnVecMagColorLarge->color().blueF(); this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisColor4Value, mitk::ColorProperty::New(tmpColor), nullptr, true); this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisColor4Magnitude, mitk::DoubleProperty::New(this->m_Controls->sbVecMagLarge->value()), nullptr, true); this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisColorInterpolate, mitk::BoolProperty::New(this->m_Controls->cbVevMagInterlolate->isChecked()), nullptr, true); //Grid Settings this->m_spSelectedRegNode->SetIntProperty(mitk::nodeProp_RegVisGridFrequence, this->m_Controls->m_sbGridFrequency->value()); this->m_spSelectedRegNode->SetBoolProperty(mitk::nodeProp_RegVisGridShowStart, this->m_Controls->m_groupShowStartGrid->isChecked()); tmpColor[0] = this->m_Controls->btnStartGridColor->color().redF(); tmpColor[1] = this->m_Controls->btnStartGridColor->color().greenF(); tmpColor[2] = this->m_Controls->btnStartGridColor->color().blueF(); this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisGridStartColor, mitk::ColorProperty::New(tmpColor), nullptr, true); //FOV mitk::Vector3D value; value[0] = this->m_Controls->m_sbFOVSizeX->value(); value[1] = this->m_Controls->m_sbFOVSizeY->value(); value[2] = this->m_Controls->m_sbFOVSizeZ->value(); this->m_spSelectedRegNode->SetProperty(mitk::nodeProp_RegVisFOVSize, mitk::Vector3DProperty::New(value)); value[0] = this->m_Controls->m_sbGridSpX->value(); value[1] = this->m_Controls->m_sbGridSpY->value(); value[2] = this->m_Controls->m_sbGridSpZ->value(); this->m_spSelectedRegNode->SetProperty(mitk::nodeProp_RegVisFOVSpacing, mitk::Vector3DProperty::New(value)); mitk::Point3D origin; origin[0] = this->m_Controls->m_sbFOVOriginX->value(); origin[1] = this->m_Controls->m_sbFOVOriginY->value(); origin[2] = this->m_Controls->m_sbFOVOriginZ->value(); this->m_spSelectedRegNode->SetProperty(mitk::nodeProp_RegVisFOVOrigin, mitk::Point3dProperty::New(origin)); mitk::Vector3D orientationRow1; mitk::Vector3D orientationRow2; mitk::Vector3D orientationRow3; orientationRow1.SetVnlVector(m_FOVRefOrientation.GetVnlMatrix().get_row(0)); orientationRow2.SetVnlVector(m_FOVRefOrientation.GetVnlMatrix().get_row(1)); orientationRow3.SetVnlVector(m_FOVRefOrientation.GetVnlMatrix().get_row(2)); this->m_spSelectedRegNode->SetProperty(mitk::nodeProp_RegVisFOVOrientation1, mitk::Vector3DProperty::New(orientationRow1)); this->m_spSelectedRegNode->SetProperty(mitk::nodeProp_RegVisFOVOrientation2, mitk::Vector3DProperty::New(orientationRow2)); this->m_spSelectedRegNode->SetProperty(mitk::nodeProp_RegVisFOVOrientation3, mitk::Vector3DProperty::New(orientationRow3)); } } void QmitkMatchPointRegistrationVisualizer::LoadStateFromNode() { if (this->m_spSelectedRegNode.IsNotNull()) { mitk::RegVisDirectionProperty* directionProp = nullptr; if (this->m_spSelectedRegNode->GetProperty(directionProp, mitk::nodeProp_RegVisDirection)) { this->m_Controls->m_comboDirection->setCurrentIndex(directionProp->GetValueAsId()); } else { this->Error(QStringLiteral("Cannot configure plugin controlls correctly. Node property ") + QString( mitk::nodeProp_RegVisDirection) + QStringLiteral(" has not the assumed type.")); } bool styleActive = false; if (this->m_spSelectedRegNode->GetBoolProperty(mitk::nodeProp_RegVisGrid, styleActive)) { this->m_Controls->m_pbStyleGrid->setChecked(styleActive); this->m_Controls->tabGrid->setEnabled(styleActive); } else { this->Error(QStringLiteral("Cannot configure plugin controlls correctly. Node property ") + QString( mitk::nodeProp_RegVisGrid) + QStringLiteral(" has not the assumed type.")); } if (this->m_spSelectedRegNode->GetBoolProperty(mitk::nodeProp_RegVisGlyph, styleActive)) { this->m_Controls->m_pbStyleGlyph->setChecked(styleActive); } else { this->Error(QStringLiteral("Cannot configure plugin controlls correctly. Node property ") + QString( mitk::nodeProp_RegVisGlyph) + QStringLiteral(" has not the assumed type.")); } if (this->m_spSelectedRegNode->GetBoolProperty(mitk::nodeProp_RegVisPoints, styleActive)) { this->m_Controls->m_pbStylePoints->setChecked(styleActive); } else { this->Error(QStringLiteral("Cannot configure plugin controlls correctly. Node property ") + QString( mitk::nodeProp_RegVisPoints) + QStringLiteral(" has not the assumed type.")); } /////////////////////////////////////////////////////// //visualization mitk::RegVisColorStyleProperty* colorStyleProp = nullptr; if (this->m_spSelectedRegNode->GetProperty(colorStyleProp, mitk::nodeProp_RegVisColorStyle)) { this->m_Controls->radioColorUni->setChecked(colorStyleProp->GetValueAsId() == 0); this->m_Controls->radioColorVecMag->setChecked(colorStyleProp->GetValueAsId() == 1); } else { this->Error(QStringLiteral("Cannot configure plugin controlls correctly. Node property ") + QString( mitk::nodeProp_RegVisColorStyle) + QStringLiteral(" has not the assumed type.")); } QColor tmpColor; float colorUni[3] = { 0.0, 0.0, 0.0 }; this->m_spSelectedRegNode->GetColor(colorUni, nullptr, mitk::nodeProp_RegVisColorUni); tmpColor.setRgbF(colorUni[0], colorUni[1], colorUni[2]); this->m_Controls->btnUniColor->setColor(tmpColor); float color1[3] = { 0.0, 0.0, 0.0 }; this->m_spSelectedRegNode->GetColor(color1, nullptr, mitk::nodeProp_RegVisColor1Value); tmpColor.setRgbF(color1[0], color1[1], color1[2]); this->m_Controls->btnVecMagColorNeg->setColor(tmpColor); float color2[3] = { 0.25, 0.25, 0.25 }; this->m_spSelectedRegNode->GetColor(color2, nullptr, mitk::nodeProp_RegVisColor2Value); tmpColor.setRgbF(color2[0], color2[1], color2[2]); this->m_Controls->btnVecMagColorSmall->setColor(tmpColor); float color3[3] = { 0.5, 0.5, 0.5 }; this->m_spSelectedRegNode->GetColor(color3, nullptr, mitk::nodeProp_RegVisColor3Value); tmpColor.setRgbF(color3[0], color3[1], color3[2]); this->m_Controls->btnVecMagColorMedium->setColor(tmpColor); float color4[3] = { 1.0, 1.0, 1.0 }; this->m_spSelectedRegNode->GetColor(color4, nullptr, mitk::nodeProp_RegVisColor4Value); tmpColor.setRgbF(color4[0], color4[1], color4[2]); this->m_Controls->btnVecMagColorLarge->setColor(tmpColor); double mag2 = 0; this->m_spSelectedRegNode->GetPropertyValue(mitk::nodeProp_RegVisColor2Magnitude, mag2); double mag3 = 0; this->m_spSelectedRegNode->GetPropertyValue(mitk::nodeProp_RegVisColor3Magnitude, mag3); double mag4 = 0; this->m_spSelectedRegNode->GetPropertyValue(mitk::nodeProp_RegVisColor4Magnitude, mag4); bool interpolate = true; this->m_spSelectedRegNode->GetBoolProperty(mitk::nodeProp_RegVisColorInterpolate, interpolate); this->m_Controls->sbVecMagSmall->setValue(mag2); this->m_Controls->sbVecMagMedium->setValue(mag3); this->m_Controls->sbVecMagLarge->setValue(mag4); this->m_Controls->cbVevMagInterlolate->setChecked(interpolate); /////////////////////////////////////////////////////// //Grid general bool showStart = false; if (this->m_spSelectedRegNode->GetBoolProperty(mitk::nodeProp_RegVisGridShowStart, showStart)) { this->m_Controls->m_groupShowStartGrid->setChecked(showStart); } else { this->Error(QStringLiteral("Cannot configure plugin controlls correctly. Node property ") + QString( mitk::nodeProp_RegVisGridShowStart) + QStringLiteral(" is not correctly defined.")); } int gridFrequ = 5; if (this->m_spSelectedRegNode->GetIntProperty(mitk::nodeProp_RegVisGridFrequence, gridFrequ)) { this->m_Controls->m_sbGridFrequency->setValue(gridFrequ); } else { this->Error(QStringLiteral("Cannot configure plugin controlls correctly. Node property ") + QString( mitk::nodeProp_RegVisGridFrequence) + QStringLiteral(" is not correctly defined.")); } float colorStart[3] = { 0.0, 0.0, 0.0 }; this->m_spSelectedRegNode->GetColor(colorStart, nullptr, mitk::nodeProp_RegVisGridStartColor); tmpColor.setRgbF(colorStart[0], colorStart[1], colorStart[2]); this->m_Controls->btnStartGridColor->setColor(tmpColor); /////////////////////////////////////////////////////// //FOV mitk::Vector3DProperty* valueProp = nullptr; if (this->m_spSelectedRegNode->GetProperty(valueProp, mitk::nodeProp_RegVisFOVSize)) { this->m_Controls->m_sbFOVSizeX->setValue(valueProp->GetValue()[0]); this->m_Controls->m_sbFOVSizeY->setValue(valueProp->GetValue()[1]); this->m_Controls->m_sbFOVSizeZ->setValue(valueProp->GetValue()[2]); } else { this->Error(QStringLiteral("Cannot configure plugin controlls correctly. Node property ") + QString( mitk::nodeProp_RegVisFOVSize) + QStringLiteral(" is not correctly defined.")); } if (this->m_spSelectedRegNode->GetProperty(valueProp, mitk::nodeProp_RegVisFOVSpacing)) { this->m_Controls->m_sbGridSpX->setValue(valueProp->GetValue()[0]); this->m_Controls->m_sbGridSpY->setValue(valueProp->GetValue()[1]); this->m_Controls->m_sbGridSpZ->setValue(valueProp->GetValue()[2]); } else { this->Error(QStringLiteral("Cannot configure plugin controlls correctly. Node property ") + QString( mitk::nodeProp_RegVisFOVSpacing) + QStringLiteral(" is not correctly defined.")); } mitk::Point3dProperty* originProp = nullptr; if (this->m_spSelectedRegNode->GetProperty(originProp, mitk::nodeProp_RegVisFOVOrigin)) { this->m_Controls->m_sbFOVOriginX->setValue(originProp->GetValue()[0]); this->m_Controls->m_sbFOVOriginY->setValue(originProp->GetValue()[1]); this->m_Controls->m_sbFOVOriginZ->setValue(originProp->GetValue()[2]); } else { this->Error(QStringLiteral("Cannot configure plugin controlls correctly. Node property ") + QString( mitk::nodeProp_RegVisFOVOrigin) + QStringLiteral(" is not correctly defined.")); } mitk::Vector3DProperty* orientationProp1; mitk::Vector3DProperty* orientationProp2; mitk::Vector3DProperty* orientationProp3; if (this->m_spSelectedRegNode->GetProperty(orientationProp1, mitk::nodeProp_RegVisFOVOrientation1) && this->m_spSelectedRegNode->GetProperty(orientationProp2, mitk::nodeProp_RegVisFOVOrientation2) && this->m_spSelectedRegNode->GetProperty(orientationProp3, mitk::nodeProp_RegVisFOVOrientation3)) { this->m_Controls->m_sbFOVOriginX->setValue(originProp->GetValue()[0]); this->m_Controls->m_sbFOVOriginY->setValue(originProp->GetValue()[1]); this->m_Controls->m_sbFOVOriginZ->setValue(originProp->GetValue()[2]); m_FOVRefOrientation.GetVnlMatrix().set_row(0, orientationProp1->GetValue().GetVnlVector()); m_FOVRefOrientation.GetVnlMatrix().set_row(1, orientationProp2->GetValue().GetVnlVector()); m_FOVRefOrientation.GetVnlMatrix().set_row(2, orientationProp3->GetValue().GetVnlVector()); } else { m_FOVRefOrientation.SetIdentity(); this->Error(QStringLiteral("Cannot configure plugin controlls correctly. One of the node propertiesy ") + QString(mitk::nodeProp_RegVisFOVOrientation1) + QString(mitk::nodeProp_RegVisFOVOrientation2) + QString(mitk::nodeProp_RegVisFOVOrientation3) + QStringLiteral(" is not correctly defined.")); } this->UpdateOrientationMatrixWidget(); } } void QmitkMatchPointRegistrationVisualizer::CheckAndSetDefaultFOVRef() { //check if node has a default reference node. mitk::DataNode::Pointer defaultRef = this->GetRefNodeOfReg( this->m_Controls->m_comboDirection->currentIndex() == 1); //direction value 1 = show inverse mapping -> we need the target image used for the registration. //if there is a default node and no m_spSelectedFOVRefNode is set -> set default node and transfer values if (defaultRef.IsNotNull() && this->m_spSelectedFOVRefNode.IsNull()) { //there is a default ref and no ref lock -> select default ref and transfer its values this->m_spSelectedFOVRefNode = defaultRef; QmitkSingleNodeSelectionWidget::NodeList selection({ defaultRef }); this->m_Controls->fovReferenceNodeSelector->SetCurrentSelection(selection); this->m_Controls->m_checkUseRefSize->setChecked(true); this->m_Controls->m_checkUseRefOrigin->setChecked(true); this->m_Controls->m_checkUseRefSpacing->setChecked(true); this->m_Controls->m_checkUseRefOrientation->setChecked(true); } if (this->m_spSelectedFOVRefNode.IsNotNull()) { //auto transfere values this->TransferFOVRefGeometry(); } } void QmitkMatchPointRegistrationVisualizer::OnNodeSelectionChanged(QList /*nodes*/) { this->CheckInputs(); this->LoadStateFromNode(); this->CheckAndSetDefaultFOVRef(); this->ConfigureVisualizationControls(); } void QmitkMatchPointRegistrationVisualizer::ActualizeRegInfo(mitk::MAPRegistrationWrapper* currentReg) { std::stringstream descriptionString; m_Controls->m_teRegInfo->clear(); if (currentReg) { descriptionString << "Moving dimension: " << currentReg->GetMovingDimensions() << "
"; descriptionString << "Target dimension: " << currentReg->GetTargetDimensions() << "
"; descriptionString << "Limited moving representation: " << currentReg->HasLimitedMovingRepresentation() << "
"; descriptionString << "Limited target representation: " << currentReg->HasLimitedTargetRepresentation() << "
"; mitk::MAPRegistrationWrapper::TagMapType tagMap = currentReg->GetTags(); descriptionString << "
Tags:
"; for (mitk::MAPRegistrationWrapper::TagMapType::const_iterator pos = tagMap.begin(); pos != tagMap.end(); ++pos) { descriptionString << pos->first << " : " << pos->second << "
"; } } else { descriptionString << "no registration selected!"; } m_Controls->m_teRegInfo->insertHtml(QString::fromStdString(descriptionString.str())); } void QmitkMatchPointRegistrationVisualizer::OnDirectionChanged(int) { this->CheckAndSetDefaultFOVRef(); this->ConfigureVisualizationControls(); } void QmitkMatchPointRegistrationVisualizer::OnUpdateBtnPushed() { this->StoreStateInNode(); mitk::Geometry3D::Pointer gridDesc; unsigned int gridFrequ = 5; mitk::GetGridGeometryFromNode(this->m_spSelectedRegNode, gridDesc, gridFrequ); this->GetCurrentRegistration()->SetGeometry(gridDesc); mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); } void QmitkMatchPointRegistrationVisualizer::OnStyleButtonPushed() { } void QmitkMatchPointRegistrationVisualizer::OnColorInterpolationChecked(bool checked) { if (checked) { this->m_Controls->labelVecMagSmall->setText(QStringLiteral("=")); this->m_Controls->labelVecMagMedium->setText(QStringLiteral("=")); this->m_Controls->labelVecMagLarge->setText(QStringLiteral("=")); } else { this->m_Controls->labelVecMagSmall->setText(QStringLiteral(">")); this->m_Controls->labelVecMagMedium->setText(QStringLiteral(">")); this->m_Controls->labelVecMagLarge->setText(QStringLiteral(">")); } } mitk::ScalarType QmitkMatchPointRegistrationVisualizer::GetSaveSpacing(mitk::ScalarType gridRes, mitk::ScalarType spacing, unsigned int maxGridRes) const { mitk::ScalarType newSpacing = spacing; mitk::ScalarType scaling = gridRes / maxGridRes; if (scaling > 1.0) { newSpacing = spacing * scaling; } return newSpacing; } void QmitkMatchPointRegistrationVisualizer::TransferFOVRefGeometry() { if (this->m_spSelectedFOVRefNode.IsNotNull()) { assert(this->m_spSelectedFOVRefNode->GetData()); assert(this->m_spSelectedFOVRefNode->GetData()->GetGeometry()); mitk::BaseGeometry* gridRef = this->m_spSelectedFOVRefNode->GetData()->GetGeometry(); mitk::Vector3D spacing = gridRef->GetSpacing(); mitk::Point3D origin = gridRef->GetOrigin(); mitk::Geometry3D::BoundsArrayType bounds = gridRef->GetBounds(); mitk::AffineTransform3D::ConstPointer fovTransform = gridRef->GetIndexToWorldTransform(); if (this->m_Controls->m_checkUseRefSize->isChecked()) { this->m_Controls->m_sbFOVSizeX->setValue((bounds[1] - bounds[0])*spacing[0]); this->m_Controls->m_sbFOVSizeY->setValue((bounds[3] - bounds[2])*spacing[1]); this->m_Controls->m_sbFOVSizeZ->setValue((bounds[5] - bounds[4])*spacing[2]); } if (this->m_Controls->m_checkUseRefSpacing->isChecked()) { this->m_Controls->m_sbGridSpX->setValue(GetSaveSpacing((bounds[1] - bounds[0]), spacing[0], 20)); this->m_Controls->m_sbGridSpY->setValue(GetSaveSpacing((bounds[3] - bounds[2]), spacing[1], 20)); this->m_Controls->m_sbGridSpZ->setValue(GetSaveSpacing((bounds[5] - bounds[4]), spacing[2], 20)); } if (this->m_Controls->m_checkUseRefOrigin->isChecked()) { this->m_Controls->m_sbFOVOriginX->setValue(origin[0]); this->m_Controls->m_sbFOVOriginY->setValue(origin[1]); this->m_Controls->m_sbFOVOriginZ->setValue(origin[2]); } if (this->m_Controls->m_checkUseRefOrientation->isChecked()) { this->m_FOVRefOrientation = fovTransform->GetMatrix(); this->UpdateOrientationMatrixWidget(); } } } void QmitkMatchPointRegistrationVisualizer::UpdateOrientationMatrixWidget() { for (unsigned int r = 0; r < 3; ++r) { for (unsigned int c = 0; c < 3; ++c) { this->m_Controls->m_tableOrientation->item(r, c)->setText(QString::number(this->m_FOVRefOrientation.GetVnlMatrix().get(r, c))); } } } void QmitkMatchPointRegistrationVisualizer::InitRegNode() { if (this->m_spSelectedRegNode.IsNotNull()) { this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisGrid, mitk::BoolProperty::New(true)); this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisGlyph, mitk::BoolProperty::New(false)); this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisPoints, mitk::BoolProperty::New(false)); this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisDirection, mitk::RegVisDirectionProperty::New()); this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisColorStyle, mitk::RegVisColorStyleProperty::New(1)); this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisColorUni, mitk::ColorProperty::New(0, 0.5, 0)); this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisGridFrequence, mitk::IntProperty::New(3)); this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisGridShowStart, mitk::BoolProperty::New(false)); this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisGridStartColor, mitk::ColorProperty::New(0.5, 0, 0)); this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisFOVSize, mitk::Vector3DProperty::New(mitk::Vector3D(100.0))); this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisFOVSpacing, mitk::Vector3DProperty::New(mitk::Vector3D(5.0))); this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisColor1Value, mitk::ColorProperty::New(0, 0, 0.5)); this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisColor2Value, mitk::ColorProperty::New(0, 0.7, 0)); this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisColor2Magnitude, mitk::DoubleProperty::New(1)); this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisColor3Value, mitk::ColorProperty::New(1, 1, 0)); this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisColor3Magnitude, mitk::DoubleProperty::New(5)); this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisColor4Value, mitk::ColorProperty::New(1, 0, 0)); this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisColor4Magnitude, mitk::DoubleProperty::New(15)); this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisColorInterpolate, mitk::BoolProperty::New(true)); mitk::Point3D origin; origin.Fill(0.0); this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisFOVOrigin, mitk::Point3dProperty::New(mitk::Point3D(origin))); mitk::Vector3D vec(0.0); vec.SetElement(0, 1.0); this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisFOVOrientation1, mitk::Vector3DProperty::New(vec)); vec.Fill(0.0); vec.SetElement(1, 1.0); this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisFOVOrientation2, mitk::Vector3DProperty::New(vec)); vec.Fill(0.0); vec.SetElement(2, 1.0); this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisFOVOrientation3, mitk::Vector3DProperty::New(vec)); } }