diff --git a/Plugins/org.mitk.gui.qt.igt.app.echotrack/files.cmake b/Plugins/org.mitk.gui.qt.igt.app.echotrack/files.cmake index 4bdeb204d5..54901bd4e4 100644 --- a/Plugins/org.mitk.gui.qt.igt.app.echotrack/files.cmake +++ b/Plugins/org.mitk.gui.qt.igt.app.echotrack/files.cmake @@ -1,137 +1,137 @@ set(SRC_CPP_FILES ) set(INTERNAL_CPP_FILES org_mbi_gui_qt_usnavigation_Activator.cpp #USNavigation.cpp //not functional anymore. Delete code? - UltrasoundCalibration.cpp - USNavigationMarkerPlacement.cpp + QmitkUltrasoundCalibration.cpp + QmitkUSNavigationMarkerPlacement.cpp QmitkUSNavigationPerspective.cpp mitkUSTargetPlacementQualityCalculator.cpp QmitkUSZonesDataModel.cpp QmitkUSNavigationCalibrationsDataModel.cpp QmitkUSZoneManagementColorDialogDelegate.cpp QmitkUSNavigationCalibrationRemoveDelegate.cpp QmitkUSNavigationCalibrationUpdateDepthDelegate.cpp Interactors/mitkUSZonesInteractor.cpp Interactors/mitkUSPointMarkInteractor.cpp Widgets/QmitkUSCombinedModalityCreationWidget.cpp Widgets/QmitkUSCombinedModalityEditWidget.cpp Widgets/QmitkUSNavigationFreezeButton.cpp Widgets/QmitkUSNavigationProcessWidget.cpp Widgets/QmitkUSNavigationZoneDistancesWidget.cpp Widgets/QmitkUSZoneManagementWidget.cpp Widgets/QmitkZoneProgressBar.cpp NavigationStepWidgets/QmitkUSAbstractNavigationStep.cpp NavigationStepWidgets/QmitkUSNavigationStepCombinedModality.cpp NavigationStepWidgets/QmitkUSNavigationStepTumourSelection.cpp NavigationStepWidgets/QmitkUSNavigationStepZoneMarking.cpp NavigationStepWidgets/QmitkUSNavigationStepPlacementPlanning.cpp NavigationStepWidgets/QmitkUSNavigationStepMarkerIntervention.cpp NavigationStepWidgets/QmitkUSNavigationStepPunctuationIntervention.cpp SettingsWidgets/QmitkUSNavigationCombinedSettingsWidget.cpp SettingsWidgets/QmitkUSNavigationAbstractSettingsWidget.cpp Filter/mitkUSNavigationTargetOcclusionFilter.cpp Filter/mitkUSNavigationTargetUpdateFilter.cpp Filter/mitkUSNavigationTargetIntersectionFilter.cpp IO/mitkUSNavigationCombinedModalityPersistence.cpp IO/mitkUSNavigationLoggingBackend.cpp IO/mitkUSNavigationExperimentLogging.cpp IO/mitkUSNavigationStepTimer.cpp ) set(UI_FILES #src/internal/USNavigationControls.ui //not functional anymore. Delete code? - src/internal/UltrasoundCalibrationControls.ui - src/internal/USNavigationMarkerPlacement.ui + src/internal/QmitkUltrasoundCalibrationControls.ui + src/internal/QmitkUSNavigationMarkerPlacement.ui src/internal/Widgets/QmitkUSCombinedModalityCreationWidget.ui src/internal/Widgets/QmitkUSCombinedModalityEditWidget.ui src/internal/Widgets/QmitkUSNavigationProcessWidget.ui src/internal/Widgets/QmitkUSZoneManagementWidget.ui src/internal/NavigationStepWidgets/QmitkUSAbstractNavigationStep.ui src/internal/NavigationStepWidgets/QmitkUSNavigationStepCombinedModality.ui src/internal/NavigationStepWidgets/QmitkUSNavigationStepTumourSelection.ui src/internal/NavigationStepWidgets/QmitkUSNavigationStepZoneMarking.ui src/internal/NavigationStepWidgets/QmitkUSNavigationStepPlacementPlanning.ui src/internal/NavigationStepWidgets/QmitkUSNavigationStepMarkerIntervention.ui src/internal/NavigationStepWidgets/QmitkUSNavigationStepPunctuationIntervention.ui src/internal/SettingsWidgets/QmitkUSNavigationCombinedSettingsWidget.ui ) set(MOC_H_FILES src/internal/org_mbi_gui_qt_usnavigation_Activator.h #src/internal/USNavigation.h //not functional anymore. Delete code? - src/internal/UltrasoundCalibration.h - src/internal/USNavigationMarkerPlacement.h + src/internal/QmitkUltrasoundCalibration.h + src/internal/QmitkUSNavigationMarkerPlacement.h src/internal/QmitkUSZonesDataModel.h src/internal/QmitkUSNavigationCalibrationsDataModel.h src/internal/QmitkUSZoneManagementColorDialogDelegate.h src/internal/QmitkUSNavigationCalibrationRemoveDelegate.h src/internal/QmitkUSNavigationCalibrationUpdateDepthDelegate.h src/internal/QmitkUSNavigationPerspective.h src/internal/Widgets/QmitkUSCombinedModalityCreationWidget.h src/internal/Widgets/QmitkUSCombinedModalityEditWidget.h src/internal/Widgets/QmitkUSNavigationFreezeButton.h src/internal/Widgets/QmitkUSNavigationProcessWidget.h src/internal/Widgets/QmitkUSNavigationZoneDistancesWidget.h src/internal/Widgets/QmitkUSZoneManagementWidget.h src/internal/Widgets/QmitkZoneProgressBar.h src/internal/NavigationStepWidgets/QmitkUSAbstractNavigationStep.h src/internal/NavigationStepWidgets/QmitkUSNavigationStepCombinedModality.h src/internal/NavigationStepWidgets/QmitkUSNavigationStepTumourSelection.h src/internal/NavigationStepWidgets/QmitkUSNavigationStepZoneMarking.h src/internal/NavigationStepWidgets/QmitkUSNavigationStepPlacementPlanning.h src/internal/NavigationStepWidgets/QmitkUSNavigationStepMarkerIntervention.h src/internal/NavigationStepWidgets/QmitkUSNavigationStepPunctuationIntervention.h src/internal/SettingsWidgets/QmitkUSNavigationCombinedSettingsWidget.h src/internal/SettingsWidgets/QmitkUSNavigationAbstractSettingsWidget.h ) # list of resource files which can be used by the plug-in # system without loading the plug-ins shared library, # for example the icon used in the menu and tabs for the # plug-in views in the workbench set(CACHED_RESOURCE_FILES # resources/icon.xpm //not functional anymore. Delete code? resources/icon2.xpm resources/icon_US_calibration.svg plugin.xml ) # list of Qt .qrc files which contain additional resources # specific to this plugin set(QRC_FILES resources/USNavigation.qrc ) set(CPP_FILES ) foreach(file ${SRC_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/${file}) endforeach(file ${SRC_CPP_FILES}) foreach(file ${INTERNAL_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/internal/${file}) endforeach(file ${INTERNAL_CPP_FILES}) set(RESOURCE_FILES Interactions/USPointMarkInteractions.xml Interactions/USZoneInteractions.xml Interactions/USZoneInteractionsHold.xml ) diff --git a/Plugins/org.mitk.gui.qt.igt.app.echotrack/plugin.xml b/Plugins/org.mitk.gui.qt.igt.app.echotrack/plugin.xml index e45f93a534..3e385bffbd 100644 --- a/Plugins/org.mitk.gui.qt.igt.app.echotrack/plugin.xml +++ b/Plugins/org.mitk.gui.qt.igt.app.echotrack/plugin.xml @@ -1,26 +1,26 @@ diff --git a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/NavigationStepWidgets/QmitkUSNavigationStepMarkerIntervention.cpp b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/NavigationStepWidgets/QmitkUSNavigationStepMarkerIntervention.cpp index 61c7b2e42d..3c6f6514df 100644 --- a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/NavigationStepWidgets/QmitkUSNavigationStepMarkerIntervention.cpp +++ b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/NavigationStepWidgets/QmitkUSNavigationStepMarkerIntervention.cpp @@ -1,1017 +1,1017 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkUSNavigationStepMarkerIntervention.h" #include "ui_QmitkUSNavigationStepMarkerIntervention.h" #include "mitkBaseRenderer.h" #include "mitkContourModel.h" #include "mitkNeedleProjectionFilter.h" #include "mitkNodeDisplacementFilter.h" #include "mitkSurface.h" #include "mitkTextAnnotation2D.h" #include #include #include "../Filter/mitkUSNavigationTargetIntersectionFilter.h" #include "../Filter/mitkUSNavigationTargetOcclusionFilter.h" #include "../Filter/mitkUSNavigationTargetUpdateFilter.h" -#include "../USNavigationMarkerPlacement.h" +#include "../QmitkUSNavigationMarkerPlacement.h" #include "../Widgets/QmitkZoneProgressBar.h" #include "../mitkUSTargetPlacementQualityCalculator.h" #include "../Interactors/mitkUSPointMarkInteractor.h" #include "usModuleRegistry.h" #include "mitkLookupTable.h" #include "mitkLookupTableProperty.h" #include "mitkSurface.h" // VTK #include "vtkCellLocator.h" #include "vtkDataSet.h" #include "vtkDoubleArray.h" #include "vtkFloatArray.h" #include "vtkIdList.h" #include "vtkLinearTransform.h" #include "vtkLookupTable.h" #include "vtkMath.h" #include "vtkOBBTree.h" #include "vtkPointData.h" #include "vtkPointData.h" #include "vtkPolyData.h" #include "vtkSelectEnclosedPoints.h" #include "vtkSmartPointer.h" #include "vtkSphereSource.h" #include "vtkTransformPolyDataFilter.h" #include "vtkWarpScalar.h" QmitkUSNavigationStepMarkerIntervention::QmitkUSNavigationStepMarkerIntervention(QWidget *parent) : QmitkUSAbstractNavigationStep(parent), m_NumberOfTargets(0), m_PlannedTargetsNodes(), m_ReachedTargetsNodes(), m_TargetProgressBar(new QmitkZoneProgressBar(QString::fromStdString("Target: %1 mm"), 200, 0, this)), m_PlannedTargetProgressBar(nullptr), m_CurrentTargetIndex(0), m_CurrentTargetReached(false), m_ShowPlanningColors(false), m_PointMarkInteractor(mitk::USPointMarkInteractor::New()), m_TargetNode(nullptr), m_TargetColorLookupTableProperty(nullptr), m_TargetSurface(nullptr), m_NeedleProjectionFilter(mitk::NeedleProjectionFilter::New()), m_NodeDisplacementFilter(mitk::NodeDisplacementFilter::New()), m_TargetUpdateFilter(mitk::USNavigationTargetUpdateFilter::New()), m_TargetOcclusionFilter(mitk::USNavigationTargetOcclusionFilter::New()), m_TargetIntersectionFilter(mitk::USNavigationTargetIntersectionFilter::New()), m_PlacementQualityCalculator(mitk::USTargetPlacementQualityCalculator::New()), m_TargetStructureWarnOverlay(mitk::TextAnnotation2D::New()), m_ReferenceSensorName(), m_NeedleSensorName(), m_ReferenceSensorIndex(1), m_NeedleSensorIndex(0), m_ListenerTargetCoordinatesChanged(this, &QmitkUSNavigationStepMarkerIntervention::UpdateTargetCoordinates), ui(new Ui::QmitkUSNavigationStepMarkerIntervention) { m_ActiveTargetColor[0] = 1; m_ActiveTargetColor[1] = 1; m_ActiveTargetColor[2] = 0; m_InactiveTargetColor[0] = 1; m_InactiveTargetColor[1] = 1; m_InactiveTargetColor[2] = 0.5; m_ReachedTargetColor[0] = 0.6; m_ReachedTargetColor[1] = 1; m_ReachedTargetColor[2] = 0.6; ui->setupUi(this); connect(ui->freezeImageButton, SIGNAL(SignalFreezed(bool)), this, SLOT(OnFreeze(bool))); connect(ui->backToLastTargetButton, SIGNAL(clicked()), this, SLOT(OnBackToLastTargetClicked())); connect(ui->targetReachedButton, SIGNAL(clicked()), this, SLOT(OnTargetLeft())); connect(this, SIGNAL(TargetReached(int)), this, SLOT(OnTargetReached())); connect(this, SIGNAL(TargetLeft(int)), this, SLOT(OnTargetLeft())); connect(ui->riskStructuresRangeWidget, SIGNAL(SignalZoneViolated(const mitk::DataNode *, mitk::Point3D)), this, SLOT(OnRiskZoneViolated(const mitk::DataNode *, mitk::Point3D))); m_PointMarkInteractor->CoordinatesChangedEvent.AddListener(m_ListenerTargetCoordinatesChanged); this->GenerateTargetColorLookupTable(); m_TargetProgressBar->SetTextFormatInvalid("Target is not on Needle Path"); ui->targetStructuresRangeLayout->addWidget(m_TargetProgressBar); m_TargetUpdateFilter->SetScalarArrayIdentifier("USNavigation::ReachedTargetScores"); } QmitkUSNavigationStepMarkerIntervention::~QmitkUSNavigationStepMarkerIntervention() { mitk::DataStorage::Pointer dataStorage = this->GetDataStorage(false); if (dataStorage.IsNotNull()) { // remove the node for the needle path mitk::DataNode::Pointer node = this->GetNamedDerivedNode("Needle Path", QmitkUSAbstractNavigationStep::DATANAME_BASENODE); if (node.IsNotNull()) { dataStorage->Remove(node); } } delete ui; m_PointMarkInteractor->CoordinatesChangedEvent.RemoveListener(m_ListenerTargetCoordinatesChanged); } bool QmitkUSNavigationStepMarkerIntervention::OnStartStep() { m_NeedleProjectionFilter->SelectInput(m_NeedleSensorIndex); // create node for Needle Projection mitk::DataNode::Pointer node = this->GetNamedDerivedNodeAndCreate("Needle Path", QmitkUSAbstractNavigationStep::DATANAME_BASENODE); node->SetData(m_NeedleProjectionFilter->GetProjection()); node->SetBoolProperty("show contour", true); // initialize warning overlay (and do not display it, yet) m_TargetStructureWarnOverlay->SetText("Warning: Needle is Inside the Target Structure."); m_TargetStructureWarnOverlay->SetVisibility(false); // set position and font size for the text overlay mitk::Point2D overlayPosition; overlayPosition.SetElement(0, 10.0f); overlayPosition.SetElement(1, 10.0f); m_TargetStructureWarnOverlay->SetPosition2D(overlayPosition); m_TargetStructureWarnOverlay->SetFontSize(18); // overlay should be red mitk::Color color; color[0] = 1; color[1] = 0; color[2] = 0; m_TargetStructureWarnOverlay->SetColor(color); mitk::ManualPlacementAnnotationRenderer::AddAnnotation(m_TargetStructureWarnOverlay.GetPointer(), "stdmulti.widget4"); return true; } bool QmitkUSNavigationStepMarkerIntervention::OnStopStep() { mitk::DataStorage::Pointer dataStorage = this->GetDataStorage(); // remove all reached nodes from the data storage for (QVector>::iterator it = m_ReachedTargetsNodes.begin(); it != m_ReachedTargetsNodes.end(); ++it) { dataStorage->Remove(*it); } m_ReachedTargetsNodes.clear(); m_CurrentTargetIndex = 0; // reset button states ui->freezeImageButton->setEnabled(false); ui->backToLastTargetButton->setEnabled(false); ui->targetReachedButton->setEnabled(true); // make sure that it is unfreezed after stopping the step ui->freezeImageButton->Unfreeze(); // remove base node for reached targets from the data storage mitk::DataNode::Pointer reachedTargetsNode = this->GetNamedDerivedNode( - QmitkUSAbstractNavigationStep::DATANAME_BASENODE, USNavigationMarkerPlacement::DATANAME_REACHED_TARGETS); + QmitkUSAbstractNavigationStep::DATANAME_BASENODE, QmitkUSNavigationMarkerPlacement::DATANAME_REACHED_TARGETS); if (reachedTargetsNode.IsNotNull()) { dataStorage->Remove(reachedTargetsNode); } return true; } bool QmitkUSNavigationStepMarkerIntervention::OnFinishStep() { return true; } bool QmitkUSNavigationStepMarkerIntervention::OnActivateStep() { this->ClearZones(); // clear risk zones before adding new ones // get target node from data storage and make sure that it contains data - m_TargetNode = this->GetNamedDerivedNode(USNavigationMarkerPlacement::DATANAME_TARGETSURFACE, - USNavigationMarkerPlacement::DATANAME_TUMOUR); + m_TargetNode = this->GetNamedDerivedNode(QmitkUSNavigationMarkerPlacement::DATANAME_TARGETSURFACE, + QmitkUSNavigationMarkerPlacement::DATANAME_TUMOUR); if (m_TargetNode.IsNull() || m_TargetNode->GetData() == 0) { - mitkThrow() << "Target node (" << USNavigationMarkerPlacement::DATANAME_TARGETSURFACE << ") must not be null."; + mitkThrow() << "Target node (" << QmitkUSNavigationMarkerPlacement::DATANAME_TARGETSURFACE << ") must not be null."; } // get target data and make sure that it is a surface m_TargetSurface = dynamic_cast(m_TargetNode->GetData()); if (m_TargetSurface.IsNull()) { - mitkThrow() << "Target node (" << USNavigationMarkerPlacement::DATANAME_TARGETSURFACE + mitkThrow() << "Target node (" << QmitkUSNavigationMarkerPlacement::DATANAME_TARGETSURFACE << ") data must be of type mitk::Surface"; } // delete progress bars for reinitializing them again afterwards if (m_PlannedTargetProgressBar) { ui->targetStructuresRangeLayout->removeWidget(m_PlannedTargetProgressBar); delete m_PlannedTargetProgressBar; m_PlannedTargetProgressBar = 0; } m_NodeDisplacementFilter->SelectInput(m_ReferenceSensorIndex); this->UpdateTargetProgressDisplay(); - mitk::DataNode::Pointer tumourNode = this->GetNamedDerivedNode(USNavigationMarkerPlacement::DATANAME_TUMOUR, + mitk::DataNode::Pointer tumourNode = this->GetNamedDerivedNode(QmitkUSNavigationMarkerPlacement::DATANAME_TUMOUR, QmitkUSAbstractNavigationStep::DATANAME_BASENODE); if (tumourNode.IsNotNull()) { // do not show tumour node during intervention (target surface is shown) tumourNode->SetBoolProperty("visible", false); // add tumour as a risk structure ui->riskStructuresRangeWidget->AddZone(tumourNode); } // set target structure for target update filter m_TargetUpdateFilter->SetTargetStructure(m_TargetNode); m_TargetOcclusionFilter->SetTargetStructure(m_TargetNode); // set lookup table of tumour node m_TargetNode->SetProperty("LookupTable", m_TargetColorLookupTableProperty); // - mitk::DataNode::Pointer targetsBaseNode = this->GetNamedDerivedNode(USNavigationMarkerPlacement::DATANAME_TARGETS, + mitk::DataNode::Pointer targetsBaseNode = this->GetNamedDerivedNode(QmitkUSNavigationMarkerPlacement::DATANAME_TARGETS, QmitkUSAbstractNavigationStep::DATANAME_BASENODE); mitk::DataStorage::SetOfObjects::ConstPointer plannedTargetNodes; if (targetsBaseNode.IsNotNull()) { plannedTargetNodes = this->GetDataStorage()->GetDerivations(targetsBaseNode); } if (plannedTargetNodes.IsNotNull() && plannedTargetNodes->Size() > 0) { for (mitk::DataStorage::SetOfObjects::ConstIterator it = plannedTargetNodes->Begin(); it != plannedTargetNodes->End(); ++it) { m_PlannedTargetsNodes.push_back(it->Value()); } m_PlannedTargetProgressBar = new QmitkZoneProgressBar(QString::fromStdString("Planned Target"), 200, 0); ui->targetStructuresRangeLayout->addWidget(m_PlannedTargetProgressBar); } // add progress bars for risk zone nodes - mitk::DataNode::Pointer zonesBaseNode = this->GetNamedDerivedNode(USNavigationMarkerPlacement::DATANAME_ZONES, + mitk::DataNode::Pointer zonesBaseNode = this->GetNamedDerivedNode(QmitkUSNavigationMarkerPlacement::DATANAME_ZONES, QmitkUSAbstractNavigationStep::DATANAME_BASENODE); // only add progress bars if the base node for zones was created if (zonesBaseNode.IsNotNull()) { mitk::DataStorage::SetOfObjects::ConstPointer zoneNodes = this->GetDataStorage()->GetDerivations(zonesBaseNode); for (mitk::DataStorage::SetOfObjects::ConstIterator it = zoneNodes->Begin(); it != zoneNodes->End(); ++it) { ui->riskStructuresRangeWidget->AddZone(it->Value()); } m_TargetOcclusionFilter->SelectStartPositionInput(m_NeedleSensorIndex); m_TargetOcclusionFilter->SetObstacleStructures(zoneNodes); } return true; } bool QmitkUSNavigationStepMarkerIntervention::OnDeactivateStep() { ui->freezeImageButton->Unfreeze(); return true; } void QmitkUSNavigationStepMarkerIntervention::OnUpdate() { // get navigation data source and make sure that it is not null mitk::NavigationDataSource::Pointer navigationDataSource = this->GetCombinedModality()->GetNavigationDataSource(); if (navigationDataSource.IsNull()) { MITK_ERROR("QmitkUSAbstractNavigationStep") ("QmitkUSNavigationStepMarkerIntervention") << "Navigation Data Source of Combined Modality must not be null."; mitkThrow() << "Navigation Data Source of Combined Modality must not be null."; } ui->riskStructuresRangeWidget->UpdateDistancesToNeedlePosition(navigationDataSource->GetOutput(m_NeedleSensorIndex)); this->UpdateBodyMarkerStatus(navigationDataSource->GetOutput(m_ReferenceSensorIndex)); this->UpdateTargetColors(); this->UpdateTargetScore(); this->UpdateTargetViolationStatus(); } void QmitkUSNavigationStepMarkerIntervention::OnSettingsChanged(const itk::SmartPointer settingsNode) { if (settingsNode.IsNull()) { return; } int numberOfTargets; if (settingsNode->GetIntProperty("settings.number-of-targets", numberOfTargets)) { m_NumberOfTargets = numberOfTargets; m_TargetUpdateFilter->SetNumberOfTargets(numberOfTargets); m_PlacementQualityCalculator->SetOptimalAngle(m_TargetUpdateFilter->GetOptimalAngle()); } std::string referenceSensorName; if (settingsNode->GetStringProperty("settings.reference-name-selected", referenceSensorName)) { m_ReferenceSensorName = referenceSensorName; } std::string needleSensorName; if (settingsNode->GetStringProperty("settings.needle-name-selected", needleSensorName)) { m_NeedleSensorName = needleSensorName; } this->UpdateSensorsNames(); } QString QmitkUSNavigationStepMarkerIntervention::GetTitle() { return "Computer-assisted Intervention"; } bool QmitkUSNavigationStepMarkerIntervention::GetIsRestartable() { return true; } QmitkUSAbstractNavigationStep::FilterVector QmitkUSNavigationStepMarkerIntervention::GetFilter() { FilterVector filter; filter.push_back(m_NeedleProjectionFilter.GetPointer()); filter.push_back(m_NodeDisplacementFilter.GetPointer()); filter.push_back(m_TargetOcclusionFilter.GetPointer()); return filter; } void QmitkUSNavigationStepMarkerIntervention::OnSetCombinedModality() { mitk::USCombinedModality::Pointer combinedModality = this->GetCombinedModality(false); if (combinedModality.IsNotNull()) { mitk::AffineTransform3D::Pointer calibration = combinedModality->GetCalibration(); if (calibration.IsNotNull()) { m_NeedleProjectionFilter->SetTargetPlane(calibration); } } ui->freezeImageButton->SetCombinedModality(combinedModality, m_ReferenceSensorIndex); this->UpdateSensorsNames(); } void QmitkUSNavigationStepMarkerIntervention::OnTargetReached() { m_CurrentTargetReached = true; } void QmitkUSNavigationStepMarkerIntervention::OnTargetLeft() { m_CurrentTargetReached = false; m_CurrentTargetIndex++; if (m_CurrentTargetIndex >= 0 && static_cast(m_CurrentTargetIndex) >= m_NumberOfTargets) { ui->targetReachedButton->setDisabled(true); } ui->backToLastTargetButton->setEnabled(true); ui->freezeImageButton->setEnabled(true); this->UpdateTargetProgressDisplay(); if (m_ReachedTargetsNodes.size() < m_CurrentTargetIndex) { mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetName( (QString("Target ") + QString("%1").arg(m_CurrentTargetIndex, 2, 10, QLatin1Char('0'))).toStdString()); this->GetDataStorage()->Add( node, - this->GetNamedDerivedNodeAndCreate(USNavigationMarkerPlacement::DATANAME_REACHED_TARGETS, + this->GetNamedDerivedNodeAndCreate(QmitkUSNavigationMarkerPlacement::DATANAME_REACHED_TARGETS, QmitkUSAbstractNavigationStep::DATANAME_BASENODE)); m_ReachedTargetsNodes.push_back(node); } mitk::DataNode::Pointer node = m_ReachedTargetsNodes.at(m_CurrentTargetIndex - 1); mitk::Surface::Pointer zone = mitk::Surface::New(); // create a vtk sphere with given radius vtkSphereSource *vtkData = vtkSphereSource::New(); vtkData->SetRadius(5); vtkData->SetCenter(0, 0, 0); vtkData->Update(); zone->SetVtkPolyData(vtkData->GetOutput()); vtkData->Delete(); // set vtk sphere and origin to data node node->SetData(zone); node->GetData()->GetGeometry()->SetOrigin( this->GetCombinedModality()->GetNavigationDataSource()->GetOutput(m_NeedleSensorIndex)->GetPosition()); node->SetColor(0.2, 0.9, 0.2); this->UpdateTargetCoordinates(node); } void QmitkUSNavigationStepMarkerIntervention::OnBackToLastTargetClicked() { if (m_CurrentTargetIndex < 1) { MITK_WARN << "Cannot go back to last target as there is no last target."; return; } m_CurrentTargetIndex--; if (m_ReachedTargetsNodes.size() > m_CurrentTargetIndex) { this->GetDataStorage()->Remove(m_ReachedTargetsNodes.last()); MITK_INFO("QmitkUSAbstractNavigationStep") ("QmitkUSNavigationStepMarkerIntervention") << "Removed Target " << m_ReachedTargetsNodes.size(); m_ReachedTargetsNodes.pop_back(); } if (m_CurrentTargetIndex == 0) { ui->backToLastTargetButton->setDisabled(true); } if (m_CurrentTargetIndex >= 0 && static_cast(m_CurrentTargetIndex) < m_NumberOfTargets) { ui->targetReachedButton->setEnabled(true); } ui->freezeImageButton->setEnabled(false); ui->freezeImageButton->Unfreeze(); this->UpdateTargetProgressDisplay(); m_TargetUpdateFilter->RemovePositionOfTarget(m_CurrentTargetIndex); } void QmitkUSNavigationStepMarkerIntervention::OnFreeze(bool freezed) { if (freezed) { this->GetCombinedModality()->SetIsFreezed(true); // load state machine and event config for data interactor m_PointMarkInteractor->LoadStateMachine("USPointMarkInteractions.xml", us::ModuleRegistry::GetModule("MitkUS")); m_PointMarkInteractor->SetEventConfig("globalConfig.xml"); if (m_CurrentTargetIndex < 1) { mitkThrow() << "Current target index has to be greater zero when freeze button is clicked."; } if (m_ReachedTargetsNodes.size() < m_CurrentTargetIndex) { mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetName( (QString("Target ") + QString("%1").arg(m_CurrentTargetIndex, 2, 10, QLatin1Char('0'))).toStdString()); this->GetDataStorage()->Add( node, - this->GetNamedDerivedNodeAndCreate(USNavigationMarkerPlacement::DATANAME_REACHED_TARGETS, + this->GetNamedDerivedNodeAndCreate(QmitkUSNavigationMarkerPlacement::DATANAME_REACHED_TARGETS, QmitkUSAbstractNavigationStep::DATANAME_BASENODE)); m_ReachedTargetsNodes.push_back(node); } m_PointMarkInteractor->SetDataNode(m_ReachedTargetsNodes.last()); } else { m_PointMarkInteractor->SetDataNode(0); this->GetCombinedModality()->SetIsFreezed(false); } } void QmitkUSNavigationStepMarkerIntervention::OnShowPlanningView(bool show) { m_ShowPlanningColors = show; } void QmitkUSNavigationStepMarkerIntervention::OnRiskZoneViolated(const mitk::DataNode *node, mitk::Point3D position) { MITK_INFO << "Risk zone (" << node->GetName() << ") violated at position " << position << "."; } void QmitkUSNavigationStepMarkerIntervention::ClearZones() { ui->riskStructuresRangeWidget->ClearZones(); // remove all reached target nodes from the data storage and clear the list mitk::DataStorage::Pointer dataStorage = this->GetDataStorage(); for (QVector::iterator it = m_ReachedTargetsNodes.begin(); it != m_ReachedTargetsNodes.end(); ++it) { if (it->IsNotNull()) { dataStorage->Remove(*it); } } m_ReachedTargetsNodes.clear(); } void QmitkUSNavigationStepMarkerIntervention::UpdateTargetCoordinates(mitk::DataNode *dataNode) { m_NodeDisplacementFilter->ResetNodes(); for (QVector>::iterator it = m_ReachedTargetsNodes.begin(); it != m_ReachedTargetsNodes.end(); ++it) { if (it->IsNotNull() && (*it)->GetData() != 0) { m_NodeDisplacementFilter->AddNode(*it); } } mitk::BaseData *baseData = dataNode->GetData(); if (!baseData) { mitkThrow() << "Data of the data node must not be null."; } mitk::BaseGeometry::Pointer geometry = baseData->GetGeometry(); if (geometry.IsNull()) { mitkThrow() << "Geometry of the data node must not be null."; } m_TargetUpdateFilter->SetControlNode(m_CurrentTargetIndex - 1, dataNode); if (m_PlannedTargetsNodes.size() > m_CurrentTargetIndex - 1) { m_PlannedTargetsNodes.at(m_CurrentTargetIndex - 1)->SetVisibility(false); } MITK_INFO("QmitkUSAbstractNavigationStep") ("QmitkUSNavigationStepMarkerIntervention") << "Target " << m_CurrentTargetIndex << " reached at position " << geometry->GetOrigin(); this->CalculateTargetPlacementQuality(); } void QmitkUSNavigationStepMarkerIntervention::UpdateBodyMarkerStatus(mitk::NavigationData::Pointer bodyMarker) { if (bodyMarker.IsNull()) { MITK_ERROR("QmitkUSAbstractNavigationStep") ("QmitkUSNavigationStepMarkerIntervention") << "Current Navigation Data for body marker of Combined Modality must not be null."; mitkThrow() << "Current Navigation Data for body marker of Combined Modality must not be null."; } bool valid = bodyMarker->IsDataValid(); // update body marker status label if (valid) { ui->bodyMarkerTrackingStatusLabel->setStyleSheet( "background-color: #8bff8b; margin-right: 1em; margin-left: 1em; border: 1px solid grey"); ui->bodyMarkerTrackingStatusLabel->setText("Body marker is inside the tracking volume."); } else { ui->bodyMarkerTrackingStatusLabel->setStyleSheet( "background-color: #ff7878; margin-right: 1em; margin-left: 1em; border: 1px solid grey"); ui->bodyMarkerTrackingStatusLabel->setText("Body marker is not inside the tracking volume."); } ui->targetStructuresRangeGroupBox->setEnabled(valid); ui->riskStructuresRangeGroupBox->setEnabled(valid); } void QmitkUSNavigationStepMarkerIntervention::GenerateTargetColorLookupTable() { vtkSmartPointer lookupTable = vtkSmartPointer::New(); lookupTable->SetHueRange(0.0, 0.33); lookupTable->SetSaturationRange(1.0, 1.0); lookupTable->SetValueRange(1.0, 1.0); lookupTable->SetTableRange(0.0, 1.0); lookupTable->Build(); mitk::LookupTable::Pointer lut = mitk::LookupTable::New(); lut->SetVtkLookupTable(lookupTable); m_TargetColorLookupTableProperty = mitk::LookupTableProperty::New(lut); } void QmitkUSNavigationStepMarkerIntervention::UpdateTargetColors() { if (m_TargetNode.IsNull()) { return; } m_TargetNode->SetColor(1, 1, 1); mitk::BaseData *targetNodeData = m_TargetNode->GetData(); if (targetNodeData == 0) { return; } mitk::Surface::Pointer targetNodeSurface = dynamic_cast(targetNodeData); vtkSmartPointer targetNodeSurfaceVtk = targetNodeSurface->GetVtkPolyData(); vtkPointData *targetPointData = targetNodeSurface->GetVtkPolyData()->GetPointData(); vtkFloatArray *scalars = dynamic_cast(targetPointData->GetScalars("USNavigation::Occlusion")); vtkFloatArray *targetScoreScalars; if (m_ShowPlanningColors) { targetScoreScalars = dynamic_cast(targetPointData->GetScalars("USNavigation::PlanningScalars")); } else { targetScoreScalars = dynamic_cast(targetPointData->GetScalars("USNavigation::ReachedTargetScores")); } if (!scalars || !targetScoreScalars) { return; } unsigned int numberOfTupels = scalars->GetNumberOfTuples(); vtkSmartPointer colors = vtkSmartPointer::New(); colors->SetNumberOfComponents(1); colors->SetNumberOfTuples(numberOfTupels); colors->SetName("Colors"); double color, intersection, markerScore; for (unsigned int n = 0; n < numberOfTupels; n++) { scalars->GetTuple(n, &intersection); targetScoreScalars->GetTuple(n, &markerScore); if (intersection > 0) { color = 0; } else { color = markerScore; } colors->SetTuple(n, &color); } if (numberOfTupels > 0) { targetNodeSurfaceVtk->GetPointData()->SetScalars(colors); targetNodeSurfaceVtk->GetPointData()->Update(); } } void QmitkUSNavigationStepMarkerIntervention::UpdateTargetScore() { if (m_NeedleProjectionFilter->GetProjection()->GetSize() != 2) { return; } vtkSmartPointer targetSurfaceVtk = m_TargetSurface->GetVtkPolyData(); m_TargetIntersectionFilter->SetTargetSurface(m_TargetSurface); m_TargetIntersectionFilter->SetLine(m_NeedleProjectionFilter->GetProjection()); m_TargetIntersectionFilter->CalculateIntersection(); if (m_TargetIntersectionFilter->GetIsIntersecting()) { vtkFloatArray *scalars = dynamic_cast(targetSurfaceVtk->GetPointData()->GetScalars("USNavigation::ReachedTargetScores")); double score; scalars->GetTuple(m_TargetIntersectionFilter->GetIntersectionNearestSurfacePointId(), &score); double color[3]; m_TargetColorLookupTableProperty->GetLookupTable()->GetVtkLookupTable()->GetColor(score, color); float colorF[3]; colorF[0] = color[0]; colorF[1] = color[1]; colorF[2] = color[2]; m_TargetProgressBar->SetColor(colorF); m_TargetProgressBar->SetBorderColor(colorF); m_TargetProgressBar->setValue(m_TargetIntersectionFilter->GetDistanceToIntersection()); if (m_PlannedTargetProgressBar) { vtkFloatArray *scalars = dynamic_cast(targetSurfaceVtk->GetPointData()->GetScalars("USNavigation::PlanningScalars")); if (scalars) { double score; scalars->GetTuple(m_TargetIntersectionFilter->GetIntersectionNearestSurfacePointId(), &score); double color[3]; m_TargetColorLookupTableProperty->GetLookupTable()->GetVtkLookupTable()->GetColor(score, color); float colorF[3]; colorF[0] = color[0]; colorF[1] = color[1]; colorF[2] = color[2]; m_PlannedTargetProgressBar->SetColor(colorF); m_PlannedTargetProgressBar->SetBorderColor(colorF); m_PlannedTargetProgressBar->SetTextFormatValid("Planned Target: %1 mm"); mitk::Point3D intersectionPoint = m_TargetIntersectionFilter->GetIntersectionPoint(); mitk::ScalarType minDistance = -1; for (QVector>::iterator it = m_PlannedTargetsNodes.begin(); it != m_PlannedTargetsNodes.end(); ++it) { mitk::ScalarType distance = intersectionPoint.EuclideanDistanceTo((*it)->GetData()->GetGeometry()->GetOrigin()); if (minDistance < 0 || distance < minDistance) { minDistance = distance; } } m_PlannedTargetProgressBar->setValue(minDistance); } } } else { m_TargetProgressBar->setValueInvalid(); } } void QmitkUSNavigationStepMarkerIntervention::UpdateTargetProgressDisplay() { QString description; if (m_CurrentTargetIndex >= static_cast(m_NumberOfTargets)) { description = "All Targets Reached"; if (m_TargetProgressBar) { m_TargetProgressBar->hide(); } } else { description = QString("Distance to Target ") + QString::number(m_CurrentTargetIndex + 1) + QString(" of ") + QString::number(m_NumberOfTargets); if (m_TargetProgressBar) { m_TargetProgressBar->show(); } } ui->targetStructuresRangeGroupBox->setTitle(description); } void QmitkUSNavigationStepMarkerIntervention::UpdatePlannedTargetProgressDisplay() { // make sure that the needle projection consists of two points if (m_NeedleProjectionFilter->GetProjection()->GetSize() != 2) { return; } vtkSmartPointer targetSurfaceVtk = m_TargetSurface->GetVtkPolyData(); m_TargetIntersectionFilter->SetTargetSurface(m_TargetSurface); m_TargetIntersectionFilter->SetLine(m_NeedleProjectionFilter->GetProjection()); m_TargetIntersectionFilter->CalculateIntersection(); // update target progress bar according to the color of the intersection // point on the target surface and the distance to the intersection if (m_TargetIntersectionFilter->GetIsIntersecting()) { vtkFloatArray *scalars = dynamic_cast(targetSurfaceVtk->GetPointData()->GetScalars("Colors")); double score; scalars->GetTuple(m_TargetIntersectionFilter->GetIntersectionNearestSurfacePointId(), &score); double color[3]; m_TargetColorLookupTableProperty->GetLookupTable()->GetVtkLookupTable()->GetColor(score, color); float colorF[3]; colorF[0] = color[0]; colorF[1] = color[1]; colorF[2] = color[2]; m_TargetProgressBar->SetColor(colorF); m_TargetProgressBar->SetBorderColor(colorF); m_TargetProgressBar->setValue(m_TargetIntersectionFilter->GetDistanceToIntersection()); } else { float red[3] = {0.6f, 0.0f, 0.0f}; m_TargetProgressBar->SetBorderColor(red); m_TargetProgressBar->setValueInvalid(); } } void QmitkUSNavigationStepMarkerIntervention::UpdateTargetViolationStatus() { // transform vtk polydata according to mitk geometry vtkSmartPointer transformFilter = vtkSmartPointer::New(); transformFilter->SetInputData(0, m_TargetSurface->GetVtkPolyData()); transformFilter->SetTransform(m_TargetSurface->GetGeometry()->GetVtkTransform()); transformFilter->Update(); vtkSmartPointer enclosedPoints = vtkSmartPointer::New(); enclosedPoints->Initialize(transformFilter->GetOutput()); mitk::Point3D needleTip = m_NeedleProjectionFilter->GetProjection()->GetPoint(0); // show warning if the needle tip is inside the target surface if (enclosedPoints->IsInsideSurface(needleTip[0], needleTip[1], needleTip[2])) { if (!m_TargetStructureWarnOverlay->IsVisible(NULL)) { m_TargetStructureWarnOverlay->SetVisibility(true); mitk::DataNode::Pointer targetViolationResult = mitk::DataNode::New(); targetViolationResult->SetName("TargetViolation"); targetViolationResult->SetProperty("USNavigation::TargetViolationPoint", mitk::Point3dProperty::New(needleTip)); emit SignalIntermediateResult(targetViolationResult); } MITK_INFO("QmitkUSAbstractNavigationStep") ("QmitkUSNavigationStepMarkerIntervention") << "Target surface violated at " << needleTip << "."; } else { m_TargetStructureWarnOverlay->SetVisibility(false); } } void QmitkUSNavigationStepMarkerIntervention::CalculateTargetPlacementQuality() { // clear quality display if there aren't all targets reached if (m_ReachedTargetsNodes.size() != static_cast(m_NumberOfTargets)) { ui->placementQualityGroupBox->setEnabled(false); ui->angleDifferenceValue->setText(""); ui->centersOfMassValue->setText(""); return; } ui->placementQualityGroupBox->setEnabled(true); mitk::Surface::Pointer targetSurface = dynamic_cast(m_TargetNode->GetData()); if (targetSurface.IsNull()) { mitkThrow() << "Target surface must not be null."; } m_PlacementQualityCalculator->SetTargetSurface(targetSurface); mitk::PointSet::Pointer targetPointSet = mitk::PointSet::New(); // copy the origins of all reached target nodes into a point set // for the quality calculator mitk::PointSet::PointIdentifier n = 0; for (QVector>::iterator it = m_ReachedTargetsNodes.begin(); it != m_ReachedTargetsNodes.end(); ++it) { targetPointSet->InsertPoint(n++, (*it)->GetData()->GetGeometry()->GetOrigin()); } m_PlacementQualityCalculator->SetTargetPoints(targetPointSet); m_PlacementQualityCalculator->Update(); double centersOfMassDistance = m_PlacementQualityCalculator->GetCentersOfMassDistance(); ui->centersOfMassValue->setText(QString::number(centersOfMassDistance, 103, 2) + " mm"); double meanAnglesDifference = m_PlacementQualityCalculator->GetMeanAngleDifference(); ui->angleDifferenceValue->setText(QString::number(meanAnglesDifference, 103, 2) + QString::fromLatin1(" °")); // create an intermediate result of the placement quality mitk::DataNode::Pointer placementQualityResult = mitk::DataNode::New(); placementQualityResult->SetName("PlacementQuality"); placementQualityResult->SetFloatProperty("USNavigation::CentersOfMassDistance", centersOfMassDistance); placementQualityResult->SetFloatProperty("USNavigation::MeanAngleDifference", meanAnglesDifference); placementQualityResult->SetProperty( "USNavigation::AngleDifferences", mitk::GenericProperty::New(m_PlacementQualityCalculator->GetAngleDifferences())); if (m_PlannedTargetsNodes.size() == static_cast(m_NumberOfTargets)) { mitk::VnlVector reachedPlannedDifferences; double reachedPlannedDifferencesSum = 0; double reachedPlannedDifferencesMax = 0; reachedPlannedDifferences.set_size(m_NumberOfTargets); // get sum and maximum of the planning / reality differences for (unsigned int n = 0; n < m_NumberOfTargets; ++n) { mitk::ScalarType distance = m_PlannedTargetsNodes.at(n)->GetData()->GetGeometry()->GetOrigin().EuclideanDistanceTo( m_ReachedTargetsNodes.at(n)->GetData()->GetGeometry()->GetOrigin()); reachedPlannedDifferences.put(n, distance); reachedPlannedDifferencesSum += distance; if (distance > reachedPlannedDifferencesMax) { reachedPlannedDifferencesMax = distance; } } // add distances between planning and reality to the quality intermediate result placementQualityResult->SetProperty("USNavigation::PlanningRealityDistances", mitk::GenericProperty::New(reachedPlannedDifferences)); placementQualityResult->SetProperty( "USNavigation::MeanPlanningRealityDistance", mitk::DoubleProperty::New(reachedPlannedDifferencesSum / static_cast(m_NumberOfTargets))); placementQualityResult->SetProperty("USNavigation::MaximumPlanningRealityDistance", mitk::DoubleProperty::New(reachedPlannedDifferencesMax)); } emit SignalIntermediateResult(placementQualityResult); } void QmitkUSNavigationStepMarkerIntervention::UpdateSensorsNames() { mitk::USCombinedModality::Pointer combinedModality = this->GetCombinedModality(false); if (combinedModality.IsNull()) { return; } mitk::NavigationDataSource::Pointer navigationDataSource = combinedModality->GetNavigationDataSource(); if (navigationDataSource.IsNull()) { return; } if (!m_NeedleSensorName.empty()) { try { m_NeedleSensorIndex = navigationDataSource->GetOutputIndex(m_NeedleSensorName); } catch (const std::exception &e) { MITK_WARN("QmitkUSAbstractNavigationStep") ("QmitkUSNavigationStepPlacementPlanning") << "Cannot get index for needle sensor name: " << e.what(); } } if (this->GetNavigationStepState() >= QmitkUSAbstractNavigationStep::State_Active) { m_NeedleProjectionFilter->SelectInput(m_NeedleSensorIndex); } if (!m_ReferenceSensorName.empty()) { try { m_ReferenceSensorIndex = navigationDataSource->GetOutputIndex(m_ReferenceSensorName); } catch (const std::exception &e) { MITK_WARN("QmitkUSAbstractNavigationStep") ("QmitkUSNavigationStepPlacementPlanning") << "Cannot get index for reference sensor name: " << e.what(); } } if (this->GetNavigationStepState() >= QmitkUSAbstractNavigationStep::State_Active) { m_NodeDisplacementFilter->SelectInput(m_ReferenceSensorIndex); } ui->freezeImageButton->SetCombinedModality(combinedModality, m_ReferenceSensorIndex); } diff --git a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/NavigationStepWidgets/QmitkUSNavigationStepPlacementPlanning.cpp b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/NavigationStepWidgets/QmitkUSNavigationStepPlacementPlanning.cpp index ed25fa6f63..4554922d1d 100644 --- a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/NavigationStepWidgets/QmitkUSNavigationStepPlacementPlanning.cpp +++ b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/NavigationStepWidgets/QmitkUSNavigationStepPlacementPlanning.cpp @@ -1,817 +1,817 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkUSNavigationStepPlacementPlanning.h" #include "ui_QmitkUSNavigationStepPlacementPlanning.h" #include "../Interactors/mitkUSPointMarkInteractor.h" #include "../mitkUSTargetPlacementQualityCalculator.h" #include "mitkNeedleProjectionFilter.h" #include "mitkNodeDisplacementFilter.h" #include "usModuleRegistry.h" #include "../Filter/mitkUSNavigationTargetIntersectionFilter.h" #include "../Filter/mitkUSNavigationTargetUpdateFilter.h" -#include "../USNavigationMarkerPlacement.h" +#include "../QmitkUSNavigationMarkerPlacement.h" #include "mitkLookupTableProperty.h" #include "mitkSurface.h" #include #include "mitkLayoutAnnotationRenderer.h" #include "mitkTextAnnotation3D.h" #include "vtkFloatArray.h" #include "vtkLookupTable.h" #include "vtkPointData.h" #include "vtkPolyData.h" #include "vtkSmartPointer.h" #include "vtkLineSource.h" #include "vtkSphereSource.h" #include "vtkCenterOfMass.h" #include "vtkLinearTransform.h" #include "vtkPoints.h" #include "vtkTransformPolyDataFilter.h" #include "vtkUnstructuredGrid.h" #include "vtkMath.h" QmitkUSNavigationStepPlacementPlanning::QmitkUSNavigationStepPlacementPlanning(QWidget *parent) : QmitkUSAbstractNavigationStep(parent), m_NumberOfTargets(0), m_CurrentTargetIndex(0), m_BodyMarkerValid(false), m_PointMarkInteractor(mitk::USPointMarkInteractor::New()), m_TargetUpdateFilter(mitk::USNavigationTargetUpdateFilter::New()), m_NodeDisplacementFilter(mitk::NodeDisplacementFilter::New()), m_NeedleProjectionFilter(mitk::NeedleProjectionFilter::New()), m_TargetIntersectionFilter(mitk::USNavigationTargetIntersectionFilter::New()), m_PlacementQualityCalculator(mitk::USTargetPlacementQualityCalculator::New()), m_ReferenceSensorIndex(1), m_NeedleSensorIndex(0), m_ListenerTargetCoordinatesChanged(this, &QmitkUSNavigationStepPlacementPlanning::UpdateTargetCoordinates), ui(new Ui::QmitkUSNavigationStepPlacementPlanning) { ui->setupUi(this); connect(ui->freezeImageButton, SIGNAL(SignalFreezed(bool)), this, SLOT(OnFreeze(bool))); m_TargetUpdateFilter->SetScalarArrayIdentifier("USNavigation::PlanningPlacement"); this->GenerateTargetColorLookupTable(); } QmitkUSNavigationStepPlacementPlanning::~QmitkUSNavigationStepPlacementPlanning() { delete ui; } bool QmitkUSNavigationStepPlacementPlanning::OnStartStep() { // create node for needle projection mitk::DataNode::Pointer node = this->GetNamedDerivedNodeAndCreate("Needle Path", QmitkUSAbstractNavigationStep::DATANAME_BASENODE); node->SetData(m_NeedleProjectionFilter->GetProjection()); node->SetBoolProperty("show contour", true); // make sure that the targets node exist in the data storage - this->GetNamedDerivedNodeAndCreate(USNavigationMarkerPlacement::DATANAME_TARGETS, + this->GetNamedDerivedNodeAndCreate(QmitkUSNavigationMarkerPlacement::DATANAME_TARGETS, QmitkUSAbstractNavigationStep::DATANAME_BASENODE); - this->GetNamedDerivedNodeAndCreate(USNavigationMarkerPlacement::DATANAME_TARGETS_PATHS, + this->GetNamedDerivedNodeAndCreate(QmitkUSNavigationMarkerPlacement::DATANAME_TARGETS_PATHS, QmitkUSAbstractNavigationStep::DATANAME_BASENODE); // listen to event of point mark interactor m_PointMarkInteractor->CoordinatesChangedEvent.AddListener(m_ListenerTargetCoordinatesChanged); return true; } bool QmitkUSNavigationStepPlacementPlanning::OnStopStep() { // remove listener to event of point mark interactor m_PointMarkInteractor->CoordinatesChangedEvent.RemoveListener(m_ListenerTargetCoordinatesChanged); m_CurrentTargetIndex = 0; m_TargetUpdateFilter->Reset(); m_NodeDisplacementFilter->ResetNodes(); // remove the planned target nodes from the data storage mitk::DataStorage::Pointer dataStorage = this->GetDataStorage(); for (QVector>::iterator it = m_PlannedTargetNodes.begin(); it != m_PlannedTargetNodes.end(); ++it) { dataStorage->Remove(*it); } m_PlannedTargetNodes.clear(); // remove the planned target path nodes from the data storage for (QVector>::iterator it = m_PlannedNeedlePaths.begin(); it != m_PlannedNeedlePaths.end(); ++it) { dataStorage->Remove(*it); } m_PlannedNeedlePaths.clear(); // remove the targets node from the data storage - mitk::DataNode::Pointer targetsNode = this->GetNamedDerivedNode(USNavigationMarkerPlacement::DATANAME_TARGETS, + mitk::DataNode::Pointer targetsNode = this->GetNamedDerivedNode(QmitkUSNavigationMarkerPlacement::DATANAME_TARGETS, QmitkUSAbstractNavigationStep::DATANAME_BASENODE); if (targetsNode.IsNotNull()) { dataStorage->Remove(targetsNode); } // remove the target paths node from the data storage mitk::DataNode::Pointer targetPathsNode = this->GetNamedDerivedNode( - USNavigationMarkerPlacement::DATANAME_TARGETS_PATHS, QmitkUSAbstractNavigationStep::DATANAME_BASENODE); + QmitkUSNavigationMarkerPlacement::DATANAME_TARGETS_PATHS, QmitkUSAbstractNavigationStep::DATANAME_BASENODE); if (targetPathsNode.IsNotNull()) { dataStorage->Remove(targetPathsNode); } // make sure that the image is no longer freezed after stopping ui->freezeImageButton->Unfreeze(); return true; } bool QmitkUSNavigationStepPlacementPlanning::OnRestartStep() { this->OnStopStep(); this->OnStartStep(); return true; } bool QmitkUSNavigationStepPlacementPlanning::OnFinishStep() { // create scalars showing the planned positions on the target surface if (!m_PlannedTargetNodes.isEmpty()) { mitk::USNavigationTargetUpdateFilter::Pointer planningSurfaceFilter = mitk::USNavigationTargetUpdateFilter::New(); planningSurfaceFilter->SetOptimalAngle(0); planningSurfaceFilter->SetScalarArrayIdentifier("USNavigation::PlanningScalars"); planningSurfaceFilter->SetUseMaximumScore(true); planningSurfaceFilter->SetTargetStructure(m_TargetNode); unsigned int n = 0; for (QVector>::iterator it = m_PlannedTargetNodes.begin(); it != m_PlannedTargetNodes.end(); ++it) { bool isSurfaceEmpty; if (((*it)->GetBoolProperty("surface_empty", isSurfaceEmpty)) && isSurfaceEmpty) { // remove node from data storage if it is not fully planned this->GetDataStorage()->Remove(*it); } else { // set origin to filter for coloring target surface (good // positions are positions near to the origin) planningSurfaceFilter->SetControlNode(n, *it); } n++; } } // make sure that the image is no longer freezed after finishing ui->freezeImageButton->Unfreeze(); return true; } bool QmitkUSNavigationStepPlacementPlanning::OnActivateStep() { emit SignalReadyForNextStep(); m_NodeDisplacementFilter->SelectInput(m_ReferenceSensorIndex); m_NeedleProjectionFilter->SelectInput(m_NeedleSensorIndex); if (m_PlannedTargetNodes.empty()) { m_CurrentTargetIndex = 0; } else { m_CurrentTargetIndex = m_PlannedTargetNodes.size() - 1; } - m_TargetNode = this->GetNamedDerivedNode(USNavigationMarkerPlacement::DATANAME_TARGETSURFACE, - USNavigationMarkerPlacement::DATANAME_TUMOUR); + m_TargetNode = this->GetNamedDerivedNode(QmitkUSNavigationMarkerPlacement::DATANAME_TARGETSURFACE, + QmitkUSNavigationMarkerPlacement::DATANAME_TUMOUR); m_TargetNode->SetBoolProperty("visible", true); // set lookup table of tumour node m_TargetNode->SetProperty("LookupTable", m_TargetColorLookupTableProperty); m_TargetUpdateFilter->SetTargetStructure(m_TargetNode); for (QVector>::iterator it = m_PlannedTargetNodes.begin(); it != m_PlannedTargetNodes.end(); ++it) { (*it)->SetBoolProperty("visible", true); } this->UpdateTargetDescriptions(); // m_TargetUpdateFilter->UpdateTargetScores(); return true; } bool QmitkUSNavigationStepPlacementPlanning::OnDeactivateStep() { ui->freezeImageButton->Unfreeze(); return true; } void QmitkUSNavigationStepPlacementPlanning::OnUpdate() { this->UpdateTargetColors(); // get navigation data source and make sure that it is not null mitk::NavigationDataSource::Pointer navigationDataSource = this->GetCombinedModality()->GetNavigationDataSource(); if (navigationDataSource.IsNull()) { MITK_ERROR("QmitkUSAbstractNavigationStep") ("QmitkUSNavigationStepPunctuationIntervention") << "Navigation Data Source of Combined Modality must not be null."; mitkThrow() << "Navigation Data Source of Combined Modality must not be null."; } navigationDataSource->Update(); this->UpdateBodyMarkerStatus(navigationDataSource->GetOutput(m_ReferenceSensorIndex)); ui->freezeImageButton->setEnabled(m_BodyMarkerValid); mitk::PointSet::Pointer needleProjectionPointSet = m_NeedleProjectionFilter->GetProjection(); if (needleProjectionPointSet->GetSize() == 2) { m_TargetIntersectionFilter->SetTargetSurface(dynamic_cast(m_TargetNode->GetData())); m_TargetIntersectionFilter->SetLine(needleProjectionPointSet); m_TargetIntersectionFilter->CalculateIntersection(); if (m_TargetIntersectionFilter->GetIsIntersecting()) { // only enable button if body marker is in the tracking volume, too ui->placeTargetButton->setEnabled(m_BodyMarkerValid); ui->placeTargetButton->setToolTip(""); if (m_PlannedTargetNodes.size() == m_NumberOfTargets - 1) { mitk::PointSet::Pointer targetPointSet = mitk::PointSet::New(); mitk::PointSet::PointIdentifier n = 0; for (QVector>::iterator it = m_PlannedTargetNodes.begin(); it != m_PlannedTargetNodes.end(); ++it) { targetPointSet->InsertPoint(n++, (*it)->GetData()->GetGeometry()->GetOrigin()); } targetPointSet->InsertPoint(n, m_TargetIntersectionFilter->GetIntersectionPoint()); this->CalculatePlanningQuality(dynamic_cast(m_TargetNode->GetData()), targetPointSet); } } else { ui->placeTargetButton->setEnabled(false); ui->placeTargetButton->setToolTip( "Target cannot be placed as the needle path is not intersecting the target surface."); // no not show planning quality if not all nodes are planned for now // and there is no needle path intersection if (m_PlannedTargetNodes.size() < m_NumberOfTargets) { ui->angleDifferenceValue->setText(""); ui->centersOfMassValue->setText(""); } } } } void QmitkUSNavigationStepPlacementPlanning::OnSettingsChanged(const itk::SmartPointer settingsNode) { int numberOfTargets; if (settingsNode->GetIntProperty("settings.number-of-targets", numberOfTargets)) { m_NumberOfTargets = numberOfTargets; m_TargetUpdateFilter->SetNumberOfTargets(numberOfTargets); m_PlacementQualityCalculator->SetOptimalAngle(m_TargetUpdateFilter->GetOptimalAngle()); } std::string referenceSensorName; if (settingsNode->GetStringProperty("settings.reference-name-selected", referenceSensorName)) { m_ReferenceSensorName = referenceSensorName; } std::string needleSensorName; if (settingsNode->GetStringProperty("settings.needle-name-selected", needleSensorName)) { m_NeedleSensorName = needleSensorName; } this->UpdateSensorsNames(); } QString QmitkUSNavigationStepPlacementPlanning::GetTitle() { return "Placement Planning"; } QmitkUSAbstractNavigationStep::FilterVector QmitkUSNavigationStepPlacementPlanning::GetFilter() { FilterVector filterVector; filterVector.push_back(m_NodeDisplacementFilter.GetPointer()); filterVector.push_back(m_NeedleProjectionFilter.GetPointer()); return filterVector; } void QmitkUSNavigationStepPlacementPlanning::OnSetCombinedModality() { mitk::USCombinedModality::Pointer combinedModality = this->GetCombinedModality(false); if (combinedModality.IsNotNull()) { mitk::AffineTransform3D::Pointer calibration = combinedModality->GetCalibration(); if (calibration.IsNotNull()) { m_NeedleProjectionFilter->SetTargetPlane(calibration); } } ui->freezeImageButton->SetCombinedModality(combinedModality, m_ReferenceSensorIndex); this->UpdateSensorsNames(); } void QmitkUSNavigationStepPlacementPlanning::OnFreeze(bool freeze) { if (freeze) this->GetCombinedModality()->SetIsFreezed(true); if (freeze) { // load state machine and event config for data interactor m_PointMarkInteractor->LoadStateMachine("USPointMarkInteractions.xml", us::ModuleRegistry::GetModule("MitkUS")); m_PointMarkInteractor->SetEventConfig("globalConfig.xml"); this->CreateTargetNodesIfNecessary(); m_PointMarkInteractor->SetDataNode(m_PlannedTargetNodes.at(m_CurrentTargetIndex)); } else { m_PointMarkInteractor->SetDataNode(0); } if (!freeze) this->GetCombinedModality()->SetIsFreezed(false); } void QmitkUSNavigationStepPlacementPlanning::OnPlaceTargetButtonClicked() { this->CreateTargetNodesIfNecessary(); mitk::DataNode::Pointer currentNode = m_PlannedTargetNodes.at(m_CurrentTargetIndex); currentNode->SetData(this->CreateSphere(5)); currentNode->SetBoolProperty("surface_empty", false); mitk::PointSet::Pointer needleProjection = m_NeedleProjectionFilter->GetProjection(); m_TargetIntersectionFilter->SetTargetSurface(dynamic_cast(m_TargetNode->GetData())); m_TargetIntersectionFilter->SetLine(m_NeedleProjectionFilter->GetProjection()); m_TargetIntersectionFilter->CalculateIntersection(); mitk::Point3D intersectionPoint = m_TargetIntersectionFilter->GetIntersectionPoint(); currentNode->GetData()->GetGeometry()->SetOrigin(intersectionPoint); m_TargetUpdateFilter->SetControlNode(m_CurrentTargetIndex, currentNode); mitk::PointSet::Pointer plannedPath = mitk::PointSet::New(); m_PlannedNeedlePaths.at(m_CurrentTargetIndex)->SetData(plannedPath); plannedPath->SetPoint(0, needleProjection->GetPoint(0)); plannedPath->SetPoint(1, intersectionPoint); if (m_CurrentTargetIndex < m_NumberOfTargets - 1) { this->OnGoToNextTarget(); } else { this->UpdateTargetDescriptions(); } this->ReinitNodeDisplacementFilter(); MITK_INFO("QmitkUSAbstractNavigationStep") ("QmitkUSNavigationStepPlacementPlanning") << "Target " << m_CurrentTargetIndex + 1 << " planned at position " << intersectionPoint << "."; } void QmitkUSNavigationStepPlacementPlanning::OnGoToPreviousTarget() { if (m_CurrentTargetIndex < 1) { mitkThrow() << "Cannot go to previous target as current target is first target."; } m_CurrentTargetIndex--; this->UpdateTargetDescriptions(); } void QmitkUSNavigationStepPlacementPlanning::OnGoToNextTarget() { m_CurrentTargetIndex++; this->UpdateTargetDescriptions(); } void QmitkUSNavigationStepPlacementPlanning::OnRemoveCurrentTargetClicked() { if (m_CurrentTargetIndex >= m_PlannedTargetNodes.size()) { MITK_WARN << "Cannot remove current target as there aren't as much planned target nodes."; return; } this->GetDataStorage()->Remove(m_PlannedTargetNodes.at(m_CurrentTargetIndex)); m_PlannedTargetNodes.remove(m_CurrentTargetIndex); this->GetDataStorage()->Remove(m_PlannedNeedlePaths.at(m_CurrentTargetIndex)); m_PlannedNeedlePaths.remove(m_CurrentTargetIndex); this->ReinitNodeDisplacementFilter(); for (int n = 0; n < m_PlannedTargetNodes.size(); ++n) { // set name of the target node according to its new index m_PlannedTargetNodes.at(n)->SetName( QString("Target %1").arg(n + 1, m_NumberOfTargets / 10 + 1, 10, QLatin1Char('0')).toStdString()); m_PlannedNeedlePaths.at(n)->SetName( QString("Target Path %1").arg(n + 1, m_NumberOfTargets / 10 + 1, 10, QLatin1Char('0')).toStdString()); } m_TargetUpdateFilter->RemovePositionOfTarget(m_CurrentTargetIndex); m_CurrentTargetIndex = m_PlannedTargetNodes.size(); this->UpdateTargetDescriptions(); MITK_INFO("QmitkUSAbstractNavigationStep") ("QmitkUSNavigationStepPlacementPlanning") << "Planned target " << m_CurrentTargetIndex + 1 << " removed."; } void QmitkUSNavigationStepPlacementPlanning::CreateTargetNodesIfNecessary() { mitk::DataStorage::Pointer dataStorage = this->GetDataStorage(); while (m_PlannedTargetNodes.size() <= m_CurrentTargetIndex) { QString targetNumber = QString("%1").arg(m_PlannedTargetNodes.size() + 1, m_NumberOfTargets / 10 + 1, 10, QLatin1Char('0')); mitk::DataNode::Pointer targetNode = this->GetNamedDerivedNodeAndCreate( - (QString("Target ") + targetNumber).toStdString().c_str(), USNavigationMarkerPlacement::DATANAME_TARGETS); + (QString("Target ") + targetNumber).toStdString().c_str(), QmitkUSNavigationMarkerPlacement::DATANAME_TARGETS); targetNode->SetOpacity(0.5); targetNode->SetBoolProperty("surface_empty", true); targetNode->SetData(mitk::Surface::New()); m_PlannedTargetNodes.push_back(targetNode); mitk::DataNode::Pointer targetPathNode = this->GetNamedDerivedNodeAndCreate((QString("Target Path ") + targetNumber).toStdString().c_str(), - USNavigationMarkerPlacement::DATANAME_TARGETS_PATHS); + QmitkUSNavigationMarkerPlacement::DATANAME_TARGETS_PATHS); targetPathNode->SetOpacity(0.5); targetPathNode->SetColor(1, 1, 1); targetPathNode->SetColor(1, 1, 1, nullptr, "contourcolor"); targetPathNode->SetBoolProperty("show contour", true); m_PlannedNeedlePaths.push_back(targetPathNode); mitk::Surface::Pointer pathSurface = mitk::Surface::New(); targetPathNode->SetData(pathSurface); } } void QmitkUSNavigationStepPlacementPlanning::UpdateTargetCoordinates(mitk::DataNode *dataNode) { bool surfaceEmpty; if (dataNode->GetBoolProperty("surface_empty", surfaceEmpty) && surfaceEmpty) { mitk::Point3D origin = dataNode->GetData()->GetGeometry()->GetOrigin(); dataNode->SetData(this->CreateSphere(5)); dataNode->SetBoolProperty("surface_empty", false); dataNode->GetData()->GetGeometry()->SetOrigin(origin); } this->ReinitNodeDisplacementFilter(); mitk::BaseData *baseData = dataNode->GetData(); if (!baseData) { mitkThrow() << "Data of the data node must not be null."; } mitk::BaseGeometry::Pointer geometry = baseData->GetGeometry(); if (geometry.IsNull()) { mitkThrow() << "Geometry of the data node must not be null."; } m_TargetUpdateFilter->SetControlNode(m_CurrentTargetIndex, dataNode); MITK_INFO("QmitkUSAbstractNavigationStep") ("QmitkUSNavigationStepPlacementPlanning") << "Target " << m_CurrentTargetIndex + 1 << " planned at position " << geometry->GetOrigin() << "."; if (ui->freezeImageButton->isChecked()) { ui->freezeImageButton->Unfreeze(); if (m_CurrentTargetIndex < m_NumberOfTargets - 1) { this->OnGoToNextTarget(); } } this->UpdateTargetDescriptions(); } void QmitkUSNavigationStepPlacementPlanning::UpdateTargetColors() { if (m_TargetNode.IsNull()) { return; } m_TargetNode->SetColor(1, 1, 1); mitk::BaseData *targetNodeData = m_TargetNode->GetData(); if (targetNodeData == 0) { return; } mitk::Surface::Pointer targetNodeSurface = dynamic_cast(targetNodeData); vtkSmartPointer targetNodeSurfaceVtk = targetNodeSurface->GetVtkPolyData(); vtkFloatArray *targetScoreScalars = dynamic_cast( targetNodeSurface->GetVtkPolyData()->GetPointData()->GetScalars("USNavigation::PlanningPlacement")); if (!targetScoreScalars) { return; } unsigned int numberOfTupels = targetScoreScalars->GetNumberOfTuples(); vtkSmartPointer colors = vtkSmartPointer::New(); colors->SetNumberOfComponents(1); colors->SetNumberOfTuples(numberOfTupels); colors->SetName("Colors"); double markerScore; for (unsigned int n = 0; n < numberOfTupels; n++) { targetScoreScalars->GetTuple(n, &markerScore); colors->SetTuple(n, &markerScore); } if (numberOfTupels > 0) { targetNodeSurfaceVtk->GetPointData()->SetScalars(colors); targetNodeSurfaceVtk->GetPointData()->Update(); } } void QmitkUSNavigationStepPlacementPlanning::UpdateTargetDescriptions() { ui->previousButton->setEnabled(m_CurrentTargetIndex > 0); ui->nextButton->setEnabled(m_CurrentTargetIndex + 1 < m_PlannedTargetNodes.size()); ui->removeButton->setEnabled(m_PlannedTargetNodes.size() > 0); ui->currentTargetLabel->setText( QString("Planning Target %1 of %2").arg(m_CurrentTargetIndex + 1).arg(m_NumberOfTargets)); ui->removeButton->setEnabled(m_CurrentTargetIndex < m_PlannedTargetNodes.size()); this->CalculatePlanningQuality(); } void QmitkUSNavigationStepPlacementPlanning::GenerateTargetColorLookupTable() { vtkSmartPointer lookupTable = vtkSmartPointer::New(); lookupTable->SetHueRange(0.0, 0.27); lookupTable->SetSaturationRange(1.0, 1.0); lookupTable->SetValueRange(1.0, 1.0); lookupTable->SetTableRange(0.0, 1.0); lookupTable->Build(); mitk::LookupTable::Pointer lut = mitk::LookupTable::New(); lut->SetVtkLookupTable(lookupTable); m_TargetColorLookupTableProperty = mitk::LookupTableProperty::New(lut); } void QmitkUSNavigationStepPlacementPlanning::ReinitNodeDisplacementFilter() { m_NodeDisplacementFilter->ResetNodes(); for (QVector>::iterator it = m_PlannedTargetNodes.begin(); it != m_PlannedTargetNodes.end(); ++it) { if (it->IsNotNull() && (*it)->GetData() != 0) { m_NodeDisplacementFilter->AddNode(*it); } } for (QVector>::iterator it = m_PlannedNeedlePaths.begin(); it != m_PlannedNeedlePaths.end(); ++it) { if (it->IsNotNull() && (*it)->GetData() != 0) { m_NodeDisplacementFilter->AddNode(*it); } } } void QmitkUSNavigationStepPlacementPlanning::CalculatePlanningQuality() { if (m_PlannedTargetNodes.size() != m_NumberOfTargets) { ui->angleDifferenceLabel->setEnabled(false); ui->centersOfMassLabel->setEnabled(false); ui->allTargetsPlannedLabel->setEnabled(false); ui->angleDifferenceValue->setText(""); ui->centersOfMassValue->setText(""); return; } ui->angleDifferenceLabel->setEnabled(true); ui->centersOfMassLabel->setEnabled(true); ui->allTargetsPlannedLabel->setEnabled(true); mitk::PointSet::Pointer targetPointSet = mitk::PointSet::New(); mitk::PointSet::PointIdentifier n = 0; for (QVector>::iterator it = m_PlannedTargetNodes.begin(); it != m_PlannedTargetNodes.end(); ++it) { targetPointSet->InsertPoint(n++, (*it)->GetData()->GetGeometry()->GetOrigin()); } mitk::DataNode::Pointer planningQualityResult = this->CalculatePlanningQuality(dynamic_cast(m_TargetNode->GetData()), targetPointSet); emit SignalIntermediateResult(planningQualityResult); } mitk::DataNode::Pointer QmitkUSNavigationStepPlacementPlanning::CalculatePlanningQuality( mitk::Surface::Pointer targetSurface, mitk::PointSet::Pointer targetPoints) { if (targetSurface.IsNull()) { mitkThrow() << "Target surface must not be null."; } m_PlacementQualityCalculator->SetTargetSurface(targetSurface); m_PlacementQualityCalculator->SetTargetPoints(targetPoints); m_PlacementQualityCalculator->Update(); mitk::DataNode::Pointer planningQualityResult = mitk::DataNode::New(); planningQualityResult->SetName("PlanningQuality"); double centersOfMassDistance = m_PlacementQualityCalculator->GetCentersOfMassDistance(); ui->centersOfMassValue->setText(QString::number(centersOfMassDistance, 103, 2) + " mm"); planningQualityResult->SetFloatProperty("USNavigation::CentersOfMassDistance", centersOfMassDistance); if (m_PlannedTargetNodes.size() > 1) { double meanAnglesDifference = m_PlacementQualityCalculator->GetMeanAngleDifference(); ui->angleDifferenceValue->setText(QString::number(meanAnglesDifference, 103, 2) + QString::fromLatin1(" °")); planningQualityResult->SetFloatProperty("USNavigation::MeanAngleDifference", meanAnglesDifference); planningQualityResult->SetProperty( "USNavigation::AngleDifferences", mitk::GenericProperty::New(m_PlacementQualityCalculator->GetAngleDifferences())); } else { ui->angleDifferenceValue->setText("not valid for one point"); } return planningQualityResult; } itk::SmartPointer QmitkUSNavigationStepPlacementPlanning::CreateSphere(float) { mitk::Surface::Pointer surface = mitk::Surface::New(); // create a vtk sphere with fixed radius vtkSphereSource *vtkData = vtkSphereSource::New(); vtkData->SetRadius(5); vtkData->SetCenter(0, 0, 0); vtkData->Update(); surface->SetVtkPolyData(vtkData->GetOutput()); vtkData->Delete(); return surface; } void QmitkUSNavigationStepPlacementPlanning::UpdateBodyMarkerStatus(mitk::NavigationData::Pointer bodyMarker) { if (bodyMarker.IsNull()) { MITK_ERROR("QmitkUSAbstractNavigationStep") ("QmitkUSNavigationStepPunctuationIntervention") << "Current Navigation Data for body marker of Combined Modality must not be null."; mitkThrow() << "Current Navigation Data for body marker of Combined Modality must not be null."; } m_BodyMarkerValid = bodyMarker->IsDataValid(); // update body marker status label if (m_BodyMarkerValid) { ui->bodyMarkerTrackingStatusLabel->setStyleSheet( "background-color: #8bff8b; margin-right: 1em; margin-left: 1em; border: 1px solid grey"); ui->bodyMarkerTrackingStatusLabel->setText("Body marker is inside the tracking volume."); } else { ui->bodyMarkerTrackingStatusLabel->setStyleSheet( "background-color: #ff7878; margin-right: 1em; margin-left: 1em; border: 1px solid grey"); ui->bodyMarkerTrackingStatusLabel->setText("Body marker is not inside the tracking volume."); } } void QmitkUSNavigationStepPlacementPlanning::UpdateSensorsNames() { mitk::USCombinedModality::Pointer combinedModality = this->GetCombinedModality(false); if (combinedModality.IsNull()) { return; } mitk::NavigationDataSource::Pointer navigationDataSource = combinedModality->GetNavigationDataSource(); if (navigationDataSource.IsNull()) { return; } if (!m_NeedleSensorName.empty()) { try { m_NeedleSensorIndex = navigationDataSource->GetOutputIndex(m_NeedleSensorName); } catch (const std::exception &e) { MITK_WARN("QmitkUSAbstractNavigationStep") ("QmitkUSNavigationStepPlacementPlanning") << "Cannot get index for needle sensor name: " << e.what(); } } if (this->GetNavigationStepState() >= QmitkUSAbstractNavigationStep::State_Active) { m_NeedleProjectionFilter->SelectInput(m_NeedleSensorIndex); } if (!m_ReferenceSensorName.empty()) { try { m_ReferenceSensorIndex = navigationDataSource->GetOutputIndex(m_ReferenceSensorName); } catch (const std::exception &e) { MITK_WARN("QmitkUSAbstractNavigationStep") ("QmitkUSNavigationStepPlacementPlanning") << "Cannot get index for reference sensor name: " << e.what(); } } if (this->GetNavigationStepState() >= QmitkUSAbstractNavigationStep::State_Active) { m_NodeDisplacementFilter->SelectInput(m_ReferenceSensorIndex); } ui->freezeImageButton->SetCombinedModality(combinedModality, m_ReferenceSensorIndex); } diff --git a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/NavigationStepWidgets/QmitkUSNavigationStepPunctuationIntervention.cpp b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/NavigationStepWidgets/QmitkUSNavigationStepPunctuationIntervention.cpp index 1e0fcbba77..1fdbbb5ded 100644 --- a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/NavigationStepWidgets/QmitkUSNavigationStepPunctuationIntervention.cpp +++ b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/NavigationStepWidgets/QmitkUSNavigationStepPunctuationIntervention.cpp @@ -1,283 +1,283 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkUSNavigationStepPunctuationIntervention.h" #include "ui_QmitkUSNavigationStepPunctuationIntervention.h" #include "mitkNeedleProjectionFilter.h" #include "../Widgets/QmitkZoneProgressBar.h" -#include "../USNavigationMarkerPlacement.h" +#include "../QmitkUSNavigationMarkerPlacement.h" #include "usModuleRegistry.h" #include QmitkUSNavigationStepPunctuationIntervention::QmitkUSNavigationStepPunctuationIntervention(QWidget *parent) : QmitkUSAbstractNavigationStep(parent), m_Ui(new Ui::QmitkUSNavigationStepPunctuationIntervention), m_ZoneNodes(nullptr), m_NeedleProjectionFilter(mitk::NeedleProjectionFilter::New()), m_NeedleNavigationTool(mitk::NavigationTool::New()), m_OldColors(), m_SphereSource(vtkSmartPointer::New()), m_OBBTree(vtkSmartPointer::New()), m_IntersectPoints(vtkSmartPointer::New()) { m_Ui->setupUi(this); connect(m_Ui->m_AddNewAblationZone, SIGNAL(clicked()), this, SLOT(OnAddAblationZoneClicked())); connect(m_Ui->m_ShowToolAxisN, SIGNAL(stateChanged(int)), this, SLOT(OnShowToolAxisEnabled(int))); connect(m_Ui->m_EnableAblationMarking, SIGNAL(clicked()), this, SLOT(OnEnableAblationZoneMarkingClicked())); connect(m_Ui->m_AblationZoneSizeSlider, SIGNAL(valueChanged(int)), this, SLOT(OnAblationZoneSizeSliderChanged(int))); m_Ui->m_AblationZonesBox->setVisible(false); } void QmitkUSNavigationStepPunctuationIntervention::SetNeedleMetaData(mitk::NavigationTool::Pointer needleNavigationTool) { this->m_NeedleNavigationTool = needleNavigationTool; } void QmitkUSNavigationStepPunctuationIntervention::OnEnableAblationZoneMarkingClicked() { if(m_Ui->m_EnableAblationMarking->isChecked()) m_Ui->m_AblationZonesBox->setVisible(true); else m_Ui->m_AblationZonesBox->setVisible(false); } void QmitkUSNavigationStepPunctuationIntervention::OnAblationZoneSizeSliderChanged(int size) { int id = m_Ui->m_AblationZonesList->currentRow(); if (id!=-1) {emit AblationZoneChanged(id,size);} }// void QmitkUSNavigationStepPunctuationIntervention::OnAddAblationZoneClicked() { QListWidgetItem* newItem = new QListWidgetItem("Ablation Zone (initial size: " + QString::number(m_Ui->m_AblationZoneSizeSlider->value()) + " mm)", m_Ui->m_AblationZonesList); newItem->setSelected(true); emit AddAblationZoneClicked(m_Ui->m_AblationZoneSizeSlider->value()); } QmitkUSNavigationStepPunctuationIntervention::~QmitkUSNavigationStepPunctuationIntervention() { mitk::DataStorage::Pointer dataStorage = this->GetDataStorage(false); if ( dataStorage.IsNotNull() ) { // remove needle path from data storage if it is there mitk::DataNode::Pointer node = this->GetNamedDerivedNode ("Needle Path", QmitkUSAbstractNavigationStep::DATANAME_BASENODE); if ( node.IsNotNull() ) { dataStorage->Remove(node); } } delete m_Ui; } bool QmitkUSNavigationStepPunctuationIntervention::OnStartStep() { // create node for Needle Projection mitk::DataNode::Pointer node = this->GetNamedDerivedNodeAndCreate ("Needle Path", QmitkUSAbstractNavigationStep::DATANAME_BASENODE); node->SetData(m_NeedleProjectionFilter->GetProjection()); node->SetBoolProperty("show contour", true); m_NeedleProjectionFilter->SetToolAxisForFilter(m_NeedleNavigationTool->GetToolAxis()); return true; } bool QmitkUSNavigationStepPunctuationIntervention::OnRestartStep() { return this->OnActivateStep(); } bool QmitkUSNavigationStepPunctuationIntervention::OnFinishStep() { mitk::DataNode::Pointer finishPunctionResult = mitk::DataNode::New(); finishPunctionResult->SetName("PunctionResult"); mitk::Point3D needlePos = m_NeedleProjectionFilter->GetOutput(0)->GetPosition(); mitk::Quaternion needleRot = m_NeedleProjectionFilter->GetOutput(0)->GetOrientation(); finishPunctionResult->SetProperty("USNavigation::TipPositionEnd", mitk::Point3dProperty::New(needlePos)); MITK_INFO("USNavigationLogging") << "Instrument tip at end: " <ClearZones(); mitk::DataStorage::Pointer dataStorage = this->GetDataStorage(); // add progress bars for risk zone nodes - m_ZoneNodes = dataStorage->GetDerivations(dataStorage->GetNamedNode(USNavigationMarkerPlacement::DATANAME_ZONES)); + m_ZoneNodes = dataStorage->GetDerivations(dataStorage->GetNamedNode(QmitkUSNavigationMarkerPlacement::DATANAME_ZONES)); // add zones to the widgets for risk structures for (mitk::DataStorage::SetOfObjects::ConstIterator it = m_ZoneNodes->Begin(); it != m_ZoneNodes->End(); ++it) { m_Ui->riskStructuresRangeWidget->AddZone(it->Value()); float rgb[3]; it->Value()->GetColor(rgb); mitk::Color color; color.SetRed(rgb[0]); color.SetGreen(rgb[1]); color.SetBlue(rgb[2]); m_OldColors[it->Value()] = color; } m_NeedleProjectionFilter->SelectInput(0); return true; } void QmitkUSNavigationStepPunctuationIntervention::OnShowToolAxisEnabled(int enabled) { if (enabled == 0) { m_NeedleProjectionFilter->ShowToolAxis(false); } else { m_NeedleProjectionFilter->ShowToolAxis(true); } } void QmitkUSNavigationStepPunctuationIntervention::OnUpdate() { // get navigation data source and make sure that it is not null mitk::NavigationDataSource::Pointer navigationDataSource = this->GetCombinedModality()->GetNavigationDataSource(); if ( navigationDataSource.IsNull() ) { MITK_ERROR("QmitkUSAbstractNavigationStep")("QmitkUSNavigationStepPunctuationIntervention") << "Navigation Data Source of Combined Modality must not be null."; mitkThrow() << "Navigation Data Source of Combined Modality must not be null."; } // update body marker this->UpdateBodyMarkerStatus(navigationDataSource->GetOutput(1)); // update critical structures this->UpdateCriticalStructures(navigationDataSource->GetOutput(0),m_NeedleProjectionFilter->GetProjection()); //Update Distance to US image mitk::Point3D point1 = m_NeedleProjectionFilter->GetProjection()->GetPoint(0); mitk::Point3D point2 = m_NeedleProjectionFilter->GetProjection()->GetPoint(1); double distance = point1.EuclideanDistanceTo(point2); m_Ui->m_DistanceToUSPlane->setText(QString::number(distance) + " mm"); } void QmitkUSNavigationStepPunctuationIntervention::OnSettingsChanged(const itk::SmartPointer settingsNode) { if ( settingsNode.IsNull() ) { return; } } QString QmitkUSNavigationStepPunctuationIntervention::GetTitle() { return "Computer-assisted Intervention"; } bool QmitkUSNavigationStepPunctuationIntervention::GetIsRestartable() { return false; } QmitkUSNavigationStepPunctuationIntervention::FilterVector QmitkUSNavigationStepPunctuationIntervention::GetFilter() { return FilterVector(1, m_NeedleProjectionFilter.GetPointer()); } void QmitkUSNavigationStepPunctuationIntervention::OnSetCombinedModality() { mitk::USCombinedModality::Pointer combinedModality = this->GetCombinedModality(false); if ( combinedModality.IsNotNull() ) { // set calibration of the combined modality to the needle projection filter mitk::AffineTransform3D::Pointer calibration = combinedModality->GetCalibration(); if ( calibration.IsNotNull() ) { m_NeedleProjectionFilter->SetTargetPlane(calibration); } } } void QmitkUSNavigationStepPunctuationIntervention::ClearZones() { m_Ui->riskStructuresRangeWidget->ClearZones(); } void QmitkUSNavigationStepPunctuationIntervention::UpdateBodyMarkerStatus(mitk::NavigationData::Pointer bodyMarker) { if ( bodyMarker.IsNull() ) { MITK_ERROR("QmitkUSAbstractNavigationStep")("QmitkUSNavigationStepPunctuationIntervention") << "Current Navigation Data for body marker of Combined Modality must not be null."; mitkThrow() << "Current Navigation Data for body marker of Combined Modality must not be null."; } bool valid = bodyMarker->IsDataValid(); // update body marker status label if (valid) { m_Ui->bodyMarkerTrackingStatusLabel->setStyleSheet( "background-color: #8bff8b; margin-right: 1em; margin-left: 1em; border: 1px solid grey"); m_Ui->bodyMarkerTrackingStatusLabel->setText("Body marker is inside the tracking volume."); } else { m_Ui->bodyMarkerTrackingStatusLabel->setStyleSheet( "background-color: #ff7878; margin-right: 1em; margin-left: 1em; border: 1px solid grey"); m_Ui->bodyMarkerTrackingStatusLabel->setText("Body marker is not inside the tracking volume."); } m_Ui->riskStructuresRangeGroupBox->setEnabled(valid); } void QmitkUSNavigationStepPunctuationIntervention::UpdateCriticalStructures(mitk::NavigationData::Pointer needle, mitk::PointSet::Pointer path) { // update the distances for the risk structures widget m_Ui->riskStructuresRangeWidget->UpdateDistancesToNeedlePosition(needle); //iterate through all zones for (mitk::DataStorage::SetOfObjects::ConstIterator it = m_ZoneNodes->Begin(); it != m_ZoneNodes->End(); ++it) { mitk::DataNode::Pointer currentNode = it->Value(); //get center point and radius float radius = -1; mitk::Point3D center; currentNode->GetFloatProperty("zone.size", radius); center = currentNode->GetData()->GetGeometry()->GetIndexToWorldTransform()->GetTranslation(); mitk::Point3D point0 = path->GetPoint(0); mitk::Point3D point1 = path->GetPoint(1); if (CheckSphereLineIntersection(center,radius,point0,point1)) {currentNode->SetColor(mitk::IGTColor_WARNING);} else {currentNode->SetColor(m_OldColors[currentNode]);} } } bool QmitkUSNavigationStepPunctuationIntervention::CheckSphereLineIntersection(mitk::Point3D& sphereOrigin, float& sphereRadius, mitk::Point3D& lineStart, mitk::Point3D& lineEnd) { double center[3] = {sphereOrigin[0],sphereOrigin[1],sphereOrigin[2]}; m_SphereSource->SetCenter(center); m_SphereSource->SetRadius(sphereRadius); m_SphereSource->Update(); m_OBBTree->SetDataSet(m_SphereSource->GetOutput()); m_OBBTree->BuildLocator(); double lineP0[3] = {lineStart[0], lineStart[1], lineStart[2]}; double lineP1[3] = {lineEnd[0], lineEnd[1], lineEnd[2]}; m_OBBTree->IntersectWithLine(lineP0, lineP1, m_IntersectPoints, nullptr); if (m_IntersectPoints->GetNumberOfPoints() > 0) {return true;} else {return false;} } diff --git a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/NavigationStepWidgets/QmitkUSNavigationStepTumourSelection.cpp b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/NavigationStepWidgets/QmitkUSNavigationStepTumourSelection.cpp index 26fc7f79a9..bd6d29d4c9 100644 --- a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/NavigationStepWidgets/QmitkUSNavigationStepTumourSelection.cpp +++ b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/NavigationStepWidgets/QmitkUSNavigationStepTumourSelection.cpp @@ -1,428 +1,428 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkUSNavigationStepTumourSelection.h" #include "ui_QmitkUSNavigationStepTumourSelection.h" #include "usModuleRegistry.h" #include "mitkDataNode.h" #include "mitkSurface.h" #include "mitkUSCombinedModality.h" #include "../Interactors/mitkUSZonesInteractor.h" #include "mitkNodeDisplacementFilter.h" #include "QmitkUSNavigationStepCombinedModality.h" -#include "../USNavigationMarkerPlacement.h" +#include "../QmitkUSNavigationMarkerPlacement.h" #include "mitkIOUtil.h" #include "vtkSmartPointer.h" #include "vtkDoubleArray.h" #include "vtkPolyData.h" #include "vtkPointData.h" #include "vtkWarpScalar.h" QmitkUSNavigationStepTumourSelection::QmitkUSNavigationStepTumourSelection(QWidget* parent) : QmitkUSAbstractNavigationStep(parent), m_targetSelectionOptional(false), m_SecurityDistance(0), m_Interactor(mitk::USZonesInteractor::New()), m_NodeDisplacementFilter(mitk::NodeDisplacementFilter::New()), m_StateMachineFilename("USZoneInteractions.xml"), m_ReferenceSensorIndex(1), m_ListenerChangeNode(this, &QmitkUSNavigationStepTumourSelection::TumourNodeChanged), ui(new Ui::QmitkUSNavigationStepTumourSelection) { ui->setupUi(this); connect(ui->freezeImageButton, SIGNAL(SignalFreezed(bool)), this, SLOT(OnFreeze(bool))); connect(ui->tumourSizeSlider, SIGNAL(valueChanged(int)), this, SLOT(OnTumourSizeChanged(int))); connect(ui->deleteTumourButton, SIGNAL(clicked()), this, SLOT(OnDeleteButtonClicked())); m_SphereColor = mitk::Color(); //default color: green m_SphereColor[0] = 0; m_SphereColor[1] = 255; m_SphereColor[2] = 0; } void QmitkUSNavigationStepTumourSelection::SetTumorColor(mitk::Color c) { m_SphereColor = c; } void QmitkUSNavigationStepTumourSelection::SetTargetSelectionOptional(bool t) { m_targetSelectionOptional = t; } QmitkUSNavigationStepTumourSelection::~QmitkUSNavigationStepTumourSelection() { delete ui; } bool QmitkUSNavigationStepTumourSelection::OnStartStep() { m_TumourNode = this->GetNamedDerivedNodeAndCreate( - USNavigationMarkerPlacement::DATANAME_TUMOUR, + QmitkUSNavigationMarkerPlacement::DATANAME_TUMOUR, QmitkUSAbstractNavigationStep::DATANAME_BASENODE); m_TumourNode->SetColor(m_SphereColor[0], m_SphereColor[1], m_SphereColor[2]); // load state machine and event config for data interactor m_Interactor->LoadStateMachine(m_StateMachineFilename, us::ModuleRegistry::GetModule("MitkUS")); m_Interactor->SetEventConfig("globalConfig.xml"); this->GetDataStorage()->ChangedNodeEvent.AddListener(m_ListenerChangeNode); m_TargetSurfaceNode = this->GetNamedDerivedNodeAndCreate( - USNavigationMarkerPlacement::DATANAME_TARGETSURFACE, - USNavigationMarkerPlacement::DATANAME_TUMOUR); + QmitkUSNavigationMarkerPlacement::DATANAME_TARGETSURFACE, + QmitkUSNavigationMarkerPlacement::DATANAME_TUMOUR); // do not show the surface until this is requested m_TargetSurfaceNode->SetBoolProperty("visible", false); // make sure that scalars will be renderer on the surface m_TargetSurfaceNode->SetBoolProperty("scalar visibility", true); m_TargetSurfaceNode->SetBoolProperty("color mode", true); m_TargetSurfaceNode->SetBoolProperty("Backface Culling", true); return true; } bool QmitkUSNavigationStepTumourSelection::OnStopStep() { // make sure that imaging isn't freezed anymore ui->freezeImageButton->Unfreeze(); m_NodeDisplacementFilter->ResetNodes(); mitk::DataStorage::Pointer dataStorage = this->GetDataStorage(false); if (dataStorage.IsNotNull()) { // remove target surface node from data storage, if available there if (m_TargetSurfaceNode.IsNotNull()) { dataStorage->Remove(m_TargetSurfaceNode); } dataStorage->ChangedNodeEvent.RemoveListener(m_ListenerChangeNode); dataStorage->Remove(m_TumourNode); m_TumourNode = 0; } MITK_INFO("QmitkUSAbstractNavigationStep")("QmitkUSNavigationStepTumourSelection") << "Removing tumour."; return true; } bool QmitkUSNavigationStepTumourSelection::OnRestartStep() { ui->tumourSizeExplanationLabel->setEnabled(false); ui->tumourSizeLabel->setEnabled(false); ui->tumourSizeSlider->setEnabled(false); ui->deleteTumourButton->setEnabled(false); ui->tumourSizeSlider->blockSignals(true); ui->tumourSizeSlider->setValue(0); ui->tumourSizeSlider->blockSignals(false); emit SignalNoLongerReadyForNextStep(); return QmitkUSAbstractNavigationStep::OnRestartStep(); } bool QmitkUSNavigationStepTumourSelection::OnFinishStep() { // make sure that the surface has the right extent (in case the // tumor size was changed since the initial surface creation) m_TargetSurfaceNode->SetData(this->CreateTargetSurface()); return true; } bool QmitkUSNavigationStepTumourSelection::OnActivateStep() { m_Interactor = mitk::USZonesInteractor::New(); m_Interactor->LoadStateMachine(m_StateMachineFilename, us::ModuleRegistry::GetModule("MitkUS")); m_Interactor->SetEventConfig("globalConfig.xml"); m_NodeDisplacementFilter->SelectInput(m_ReferenceSensorIndex); //target selection is optional if (m_targetSelectionOptional) { emit SignalReadyForNextStep(); } return true; } bool QmitkUSNavigationStepTumourSelection::OnDeactivateStep() { m_Interactor->SetDataNode(0); bool value; if (m_TumourNode.IsNotNull() && !(m_TumourNode->GetBoolProperty("zone.created", value) && value)) { m_TumourNode->SetData(0); } // make sure that imaging isn't freezed anymore ui->freezeImageButton->Unfreeze(); return true; } void QmitkUSNavigationStepTumourSelection::OnUpdate() { if (m_NavigationDataSource.IsNull()) { return; } m_NavigationDataSource->Update(); bool valid = m_NavigationDataSource->GetOutput(m_ReferenceSensorIndex)->IsDataValid(); if (valid) { ui->bodyMarkerTrackingStatusLabel->setStyleSheet( "background-color: #8bff8b; margin-right: 1em; margin-left: 1em; border: 1px solid grey"); ui->bodyMarkerTrackingStatusLabel->setText("Body marker is inside the tracking volume."); } else { ui->bodyMarkerTrackingStatusLabel->setStyleSheet( "background-color: #ff7878; margin-right: 1em; margin-left: 1em; border: 1px solid grey"); ui->bodyMarkerTrackingStatusLabel->setText("Body marker is not inside the tracking volume."); } ui->freezeImageButton->setEnabled(valid); bool created; if (m_TumourNode.IsNull() || !m_TumourNode->GetBoolProperty("zone.created", created) || !created) { ui->tumourSearchExplanationLabel->setEnabled(valid); } } void QmitkUSNavigationStepTumourSelection::OnSettingsChanged(const itk::SmartPointer settingsNode) { if (settingsNode.IsNull()) { return; } float securityDistance; if (settingsNode->GetFloatProperty("settings.security-distance", securityDistance)) { m_SecurityDistance = securityDistance; } std::string stateMachineFilename; if (settingsNode->GetStringProperty("settings.interaction-concept", stateMachineFilename) && stateMachineFilename != m_StateMachineFilename) { m_StateMachineFilename = stateMachineFilename; m_Interactor->LoadStateMachine(stateMachineFilename, us::ModuleRegistry::GetModule("MitkUS")); } std::string referenceSensorName; if (settingsNode->GetStringProperty("settings.reference-name-selected", referenceSensorName)) { m_ReferenceSensorName = referenceSensorName; } this->UpdateReferenceSensorName(); } QString QmitkUSNavigationStepTumourSelection::GetTitle() { return "Localisation of Tumour Position"; } QmitkUSAbstractNavigationStep::FilterVector QmitkUSNavigationStepTumourSelection::GetFilter() { return FilterVector(1, m_NodeDisplacementFilter.GetPointer()); } void QmitkUSNavigationStepTumourSelection::OnFreeze(bool freezed) { if (freezed) this->GetCombinedModality()->SetIsFreezed(true); ui->tumourSelectionExplanation1Label->setEnabled(freezed); ui->tumourSelectionExplanation2Label->setEnabled(freezed); if (freezed) { if (!m_TumourNode->GetData()) { // load state machine and event config for data interactor m_Interactor->LoadStateMachine(m_StateMachineFilename, us::ModuleRegistry::GetModule("MitkUS")); m_Interactor->SetEventConfig("globalConfig.xml"); m_Interactor->SetDataNode(m_TumourNode); // feed reference pose to node displacement filter m_NodeDisplacementFilter->SetInitialReferencePose(this->GetCombinedModality()->GetNavigationDataSource()->GetOutput(m_ReferenceSensorIndex)->Clone()); } } else { bool value; if (m_TumourNode->GetBoolProperty("zone.created", value) && value) { ui->freezeImageButton->setEnabled(false); ui->tumourSearchExplanationLabel->setEnabled(false); } } if (!freezed) this->GetCombinedModality()->SetIsFreezed(false); } void QmitkUSNavigationStepTumourSelection::OnSetCombinedModality() { mitk::USCombinedModality::Pointer combinedModality = this->GetCombinedModality(false); if (combinedModality.IsNotNull()) { m_NavigationDataSource = combinedModality->GetNavigationDataSource(); } else { m_NavigationDataSource = 0; } ui->freezeImageButton->SetCombinedModality(combinedModality, m_ReferenceSensorIndex); this->UpdateReferenceSensorName(); } void QmitkUSNavigationStepTumourSelection::OnTumourSizeChanged(int size) { m_TumourNode->SetFloatProperty("zone.size", static_cast(size)); mitk::USZonesInteractor::UpdateSurface(m_TumourNode); MITK_INFO("QmitkUSAbstractNavigationStep")("QmitkUSNavigationStepTumourSelection") << "Changing tumour radius to " << size << "."; } void QmitkUSNavigationStepTumourSelection::OnDeleteButtonClicked() { this->OnRestartStep(); } void QmitkUSNavigationStepTumourSelection::TumourNodeChanged(const mitk::DataNode* dataNode) { // only changes of tumour node are of interest if (dataNode != m_TumourNode) { return; } float size; dataNode->GetFloatProperty("zone.size", size); ui->tumourSizeSlider->setValue(static_cast(size)); bool created; if (dataNode->GetBoolProperty("zone.created", created) && created) { if (ui->freezeImageButton->isChecked()) { m_NodeDisplacementFilter->AddNode(const_cast(dataNode)); m_TargetSurfaceNode->SetData(this->CreateTargetSurface()); m_NodeDisplacementFilter->AddNode(m_TargetSurfaceNode); MITK_INFO("QmitkUSAbstractNavigationStep")("QmitkUSNavigationStepTumourSelection") << "Tumour created with center " << dataNode->GetData()->GetGeometry()->GetOrigin() << " and radius " << size << "."; mitk::DataNode::Pointer tumourResultNode = mitk::DataNode::New(); tumourResultNode->SetName("TumourResult"); tumourResultNode->SetProperty("USNavigation::TumourCenter", mitk::Point3dProperty::New(dataNode->GetData()->GetGeometry()->GetOrigin())); tumourResultNode->SetProperty("USNavigation::TumourRadius", mitk::DoubleProperty::New(size)); emit SignalIntermediateResult(tumourResultNode); ui->freezeImageButton->Unfreeze(); } ui->tumourSearchExplanationLabel->setEnabled(false); ui->tumourSizeExplanationLabel->setEnabled(true); ui->tumourSizeLabel->setEnabled(true); ui->tumourSizeSlider->setEnabled(true); ui->deleteTumourButton->setEnabled(true); emit SignalReadyForNextStep(); } } mitk::Surface::Pointer QmitkUSNavigationStepTumourSelection::CreateTargetSurface() { mitk::Surface::Pointer tumourSurface = dynamic_cast(m_TumourNode->GetData()); if (tumourSurface.IsNull()) { MITK_WARN << "No target selected, cannot create surface!"; return mitk::Surface::New(); //return a empty surface in this case... } // make a deep copy of the tumour surface polydata vtkSmartPointer tumourSurfaceVtk = vtkSmartPointer::New(); tumourSurfaceVtk->DeepCopy(tumourSurface->GetVtkPolyData()); // create scalars for moving every point the same size onto its normal vector vtkSmartPointer scalars = vtkSmartPointer::New(); int numberOfPoints = tumourSurfaceVtk->GetNumberOfPoints(); scalars->SetNumberOfTuples(numberOfPoints); // set scalars for warp filter for (vtkIdType i = 0; i < numberOfPoints; ++i) { scalars->SetTuple1(i, m_SecurityDistance * 10); } tumourSurfaceVtk->GetPointData()->SetScalars(scalars); vtkSmartPointer warpScalar = vtkSmartPointer::New(); warpScalar->SetInputData(tumourSurfaceVtk); warpScalar->SetScaleFactor(1); // use the scalars themselves warpScalar->Update(); vtkSmartPointer targetSurfaceVtk = warpScalar->GetPolyDataOutput(); // set the moved points to the deep copied tumour surface; this is // necessary as setting the targetSurfaceVtk as polydata for the // targetSurface would result in flat shading for the surface (seems // to be a bug in MITK or VTK) tumourSurfaceVtk->SetPoints(targetSurfaceVtk->GetPoints()); mitk::Surface::Pointer targetSurface = mitk::Surface::New(); targetSurface->SetVtkPolyData(tumourSurfaceVtk); targetSurface->GetGeometry()->SetOrigin(tumourSurface->GetGeometry()->GetOrigin()); return targetSurface; } itk::SmartPointer QmitkUSNavigationStepTumourSelection::GetTumourNodeDisplacementFilter() { return m_NodeDisplacementFilter; } void QmitkUSNavigationStepTumourSelection::UpdateReferenceSensorName() { if (m_NavigationDataSource.IsNull()) { return; } if (!m_ReferenceSensorName.empty()) { try { m_ReferenceSensorIndex = m_NavigationDataSource->GetOutputIndex(m_ReferenceSensorName); } catch (const std::exception &e) { MITK_WARN("QmitkUSAbstractNavigationStep")("QmitkUSNavigationStepTumourSelection") << "Cannot get index for reference sensor name: " << e.what(); } } if (this->GetNavigationStepState() >= QmitkUSAbstractNavigationStep::State_Active) { m_NodeDisplacementFilter->SelectInput(m_ReferenceSensorIndex); } ui->freezeImageButton->SetCombinedModality(this->GetCombinedModality(false), m_ReferenceSensorIndex); } diff --git a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/NavigationStepWidgets/QmitkUSNavigationStepZoneMarking.cpp b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/NavigationStepWidgets/QmitkUSNavigationStepZoneMarking.cpp index b1380808ff..ffe7a26b38 100644 --- a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/NavigationStepWidgets/QmitkUSNavigationStepZoneMarking.cpp +++ b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/NavigationStepWidgets/QmitkUSNavigationStepZoneMarking.cpp @@ -1,269 +1,269 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkUSNavigationStepZoneMarking.h" #include "ui_QmitkUSNavigationStepZoneMarking.h" #include "mitkNodeDisplacementFilter.h" -#include "../USNavigationMarkerPlacement.h" +#include "../QmitkUSNavigationMarkerPlacement.h" QmitkUSNavigationStepZoneMarking::QmitkUSNavigationStepZoneMarking(QWidget *parent) : QmitkUSAbstractNavigationStep(parent), m_ZoneDisplacementFilter(mitk::NodeDisplacementFilter::New()), m_ReferenceSensorIndex(1), m_CurrentlyAddingZone(false), ui(new Ui::QmitkUSNavigationStepZoneMarking) { ui->setupUi(this); connect( ui->freezeButton, SIGNAL(SignalFreezed(bool)), this, SLOT(OnFreeze(bool)) ); connect( ui->zonesWidget, SIGNAL(ZoneAdded()), this, SLOT(OnZoneAdded()) ); connect( ui->zonesWidget, SIGNAL(ZoneRemoved()), this, SLOT(OnZoneRemoved()) ); connect(ui->showStructureList, SIGNAL(stateChanged(int)), this, SLOT(OnShowListClicked(int))); ui->zonesLabel->setVisible(false); ui->zonesWidget->setVisible(false); } void QmitkUSNavigationStepZoneMarking::OnShowListClicked(int state) { ui->zonesLabel->setVisible(state); ui->zonesWidget->setVisible(state); } QmitkUSNavigationStepZoneMarking::~QmitkUSNavigationStepZoneMarking() { delete ui; } bool QmitkUSNavigationStepZoneMarking::OnStartStep() { - this->GetNamedDerivedNodeAndCreate(USNavigationMarkerPlacement::DATANAME_ZONES, + this->GetNamedDerivedNodeAndCreate(QmitkUSNavigationMarkerPlacement::DATANAME_ZONES, QmitkUSAbstractNavigationStep::DATANAME_BASENODE); - ui->zonesWidget->SetDataStorage(this->GetDataStorage(), USNavigationMarkerPlacement::DATANAME_ZONES); + ui->zonesWidget->SetDataStorage(this->GetDataStorage(), QmitkUSNavigationMarkerPlacement::DATANAME_ZONES); return true; } bool QmitkUSNavigationStepZoneMarking::OnStopStep() { m_ZoneDisplacementFilter->ResetNodes(); ui->zonesWidget->OnResetZones(); m_ZoneNodes.clear(); // remove zone nodes from the data storage mitk::DataStorage::Pointer dataStorage = this->GetDataStorage(false); if ( dataStorage.IsNotNull() ) { mitk::DataNode::Pointer baseNode = dataStorage->GetNamedNode(QmitkUSAbstractNavigationStep::DATANAME_BASENODE); if ( baseNode.IsNotNull() ) { - dataStorage->Remove(dataStorage->GetNamedDerivedNode(USNavigationMarkerPlacement::DATANAME_ZONES, baseNode)); + dataStorage->Remove(dataStorage->GetNamedDerivedNode(QmitkUSNavigationMarkerPlacement::DATANAME_ZONES, baseNode)); } } return true; } bool QmitkUSNavigationStepZoneMarking::OnFinishStep() { return true; } bool QmitkUSNavigationStepZoneMarking::OnActivateStep() { m_ZoneDisplacementFilter->SelectInput(m_ReferenceSensorIndex); emit SignalReadyForNextStep(); return true; } bool QmitkUSNavigationStepZoneMarking::OnDeactivateStep() { ui->freezeButton->Unfreeze(); return true; } void QmitkUSNavigationStepZoneMarking::OnUpdate() { if (m_NavigationDataSource.IsNull()) { return; } m_NavigationDataSource->Update(); bool valid = m_NavigationDataSource->GetOutput(m_ReferenceSensorIndex)->IsDataValid(); if (valid) { ui->bodyMarkerTrackingStatusLabel->setStyleSheet( "background-color: #8bff8b; margin-right: 1em; margin-left: 1em; border: 1px solid grey"); ui->bodyMarkerTrackingStatusLabel->setText("Body marker is inside the tracking volume."); } else { ui->bodyMarkerTrackingStatusLabel->setStyleSheet( "background-color: #ff7878; margin-right: 1em; margin-left: 1em; border: 1px solid grey"); ui->bodyMarkerTrackingStatusLabel->setText("Body marker is not inside the tracking volume."); } ui->freezeButton->setEnabled(valid); } void QmitkUSNavigationStepZoneMarking::OnSettingsChanged(const itk::SmartPointer settingsNode) { if ( settingsNode.IsNull() ) { return; } std::string stateMachineFilename; if ( settingsNode->GetStringProperty("settings.interaction-concept", stateMachineFilename) && stateMachineFilename != m_StateMachineFilename ) { m_StateMachineFilename = stateMachineFilename; ui->zonesWidget->SetStateMachineFilename(stateMachineFilename); } std::string referenceSensorName; if ( settingsNode->GetStringProperty("settings.reference-name-selected", referenceSensorName) ) { m_ReferenceSensorName = referenceSensorName; } this->UpdateReferenceSensorName(); } QString QmitkUSNavigationStepZoneMarking::GetTitle() { return "Critical Structures"; } QmitkUSAbstractNavigationStep::FilterVector QmitkUSNavigationStepZoneMarking::GetFilter() { return FilterVector(1, m_ZoneDisplacementFilter.GetPointer()); } void QmitkUSNavigationStepZoneMarking::OnFreeze(bool freezed) { if (freezed) this->GetCombinedModality()->SetIsFreezed(true); ui->zoneAddingExplanationLabel->setEnabled(freezed); if ( freezed ) { m_CurrentlyAddingZone = true; ui->zonesWidget->OnStartAddingZone(); // feed reference pose to node displacement filter m_ZoneDisplacementFilter->SetInitialReferencePose(this->GetCombinedModality()->GetNavigationDataSource()->GetOutput(m_ReferenceSensorIndex)->Clone()); } else if ( m_CurrentlyAddingZone ) { m_CurrentlyAddingZone = false; ui->zonesWidget->OnAbortAddingZone(); } if (!freezed) this->GetCombinedModality()->SetIsFreezed(false); } void QmitkUSNavigationStepZoneMarking::OnZoneAdded() { m_CurrentlyAddingZone = false; ui->freezeButton->Unfreeze(); ui->zoneAddingExplanationLabel->setEnabled(ui->freezeButton->isChecked()); mitk::DataStorage::SetOfObjects::ConstPointer zoneNodesSet = ui->zonesWidget->GetZoneNodes(); for (mitk::DataStorage::SetOfObjects::ConstIterator it = zoneNodesSet->Begin(); it != zoneNodesSet->End(); ++it) { // add all zones to zone filter which aren't added until now if ( std::find(m_ZoneNodes.begin(), m_ZoneNodes.end(), it->Value()) == m_ZoneNodes.end() ) { // logging center point and radius float radius = -1; it->Value()->GetFloatProperty("zone.size", radius); MITK_INFO("QmitkUSNavigationStepZoneMarking")("QmitkUSAbstractNavigationStep") << "Risk zone (" << it->Value()->GetName() << ") added with center " << it->Value()->GetData()->GetGeometry()->GetOrigin() << " and radius " << radius << "."; m_ZoneNodes.push_back(it->Value()); m_ZoneDisplacementFilter->AddNode(it->Value()); } } } void QmitkUSNavigationStepZoneMarking::OnZoneRemoved() { mitk::DataStorage::SetOfObjects::ConstPointer zoneNodesSet = ui->zonesWidget->GetZoneNodes(); for ( int n = m_ZoneNodes.size() - 1; n >= 0; --n ) { bool found = false; // test if the node can be found in the set of zone nodes for (mitk::DataStorage::SetOfObjects::ConstIterator itSet = zoneNodesSet->Begin(); itSet != zoneNodesSet->End(); ++itSet) { if ( m_ZoneNodes.at(n) == itSet->Value() ) { found = true; break; } } if ( ! found ) { MITK_INFO("QmitkUSNavigationStepZoneMarking")("QmitkUSAbstractNavigationStep") << "Risk zone (" << m_ZoneNodes.at(n)->GetName() << ") removed."; m_ZoneNodes.erase(m_ZoneNodes.begin()+n); m_ZoneDisplacementFilter->RemoveNode(n); } } } void QmitkUSNavigationStepZoneMarking::OnSetCombinedModality() { mitk::USCombinedModality::Pointer combinedModality = this->GetCombinedModality(false); if (combinedModality.IsNotNull()) { m_NavigationDataSource = combinedModality->GetNavigationDataSource(); } ui->freezeButton->SetCombinedModality(combinedModality, m_ReferenceSensorIndex); this->UpdateReferenceSensorName(); } void QmitkUSNavigationStepZoneMarking::UpdateReferenceSensorName() { if ( m_NavigationDataSource.IsNull() ) { return; } if ( ! m_ReferenceSensorName.empty() ) { try { m_ReferenceSensorIndex = m_NavigationDataSource->GetOutputIndex(m_ReferenceSensorName); } catch ( const std::exception &e ) { MITK_WARN("QmitkUSAbstractNavigationStep")("QmitkUSNavigationStepZoneMarking") << "Cannot get index for reference sensor name: " << e.what(); } } if ( this->GetNavigationStepState() >= QmitkUSAbstractNavigationStep::State_Active ) { m_ZoneDisplacementFilter->SelectInput(m_ReferenceSensorIndex); } ui->freezeButton->SetCombinedModality(this->GetCombinedModality(false), m_ReferenceSensorIndex); } diff --git a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/USNavigationMarkerPlacement.cpp b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/QmitkUSNavigationMarkerPlacement.cpp similarity index 92% rename from Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/USNavigationMarkerPlacement.cpp rename to Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/QmitkUSNavigationMarkerPlacement.cpp index 61500be8af..843a7144dd 100644 --- a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/USNavigationMarkerPlacement.cpp +++ b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/QmitkUSNavigationMarkerPlacement.cpp @@ -1,875 +1,875 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ -#include "USNavigationMarkerPlacement.h" -#include "ui_USNavigationMarkerPlacement.h" +#include "QmitkUSNavigationMarkerPlacement.h" +#include "ui_QmitkUSNavigationMarkerPlacement.h" #include "NavigationStepWidgets/QmitkUSNavigationStepCombinedModality.h" #include "NavigationStepWidgets/QmitkUSNavigationStepMarkerIntervention.h" #include "NavigationStepWidgets/QmitkUSNavigationStepPlacementPlanning.h" #include "NavigationStepWidgets/QmitkUSNavigationStepPunctuationIntervention.h" #include "NavigationStepWidgets/QmitkUSNavigationStepTumourSelection.h" #include "NavigationStepWidgets/QmitkUSNavigationStepZoneMarking.h" #include "SettingsWidgets/QmitkUSNavigationCombinedSettingsWidget.h" #include "mitkIRenderingManager.h" #include "mitkNodeDisplacementFilter.h" #include "mitkUSCombinedModality.h" #include #include "IO/mitkUSNavigationExperimentLogging.h" #include "IO/mitkUSNavigationStepTimer.h" #include #include #include #include #include #include #include "QmitkRenderWindow.h" #include "QmitkStdMultiWidget.h" #include "QmitkStdMultiWidgetEditor.h" #include "mitkLayoutAnnotationRenderer.h" #include "mitkCameraController.h" // scene serialization #include #include #include #include #include -const std::string USNavigationMarkerPlacement::VIEW_ID = "org.mitk.views.usmarkerplacement"; +const std::string QmitkUSNavigationMarkerPlacement::VIEW_ID = "org.mitk.views.usmarkerplacement"; -const char *USNavigationMarkerPlacement::DATANAME_TUMOUR = "Tumour"; -const char *USNavigationMarkerPlacement::DATANAME_TARGETSURFACE = "Target Surface"; -const char *USNavigationMarkerPlacement::DATANAME_ZONES = "Zones"; -const char *USNavigationMarkerPlacement::DATANAME_TARGETS = "Targets"; -const char *USNavigationMarkerPlacement::DATANAME_TARGETS_PATHS = "Target Paths"; -const char *USNavigationMarkerPlacement::DATANAME_REACHED_TARGETS = "Reached Targets"; +const char *QmitkUSNavigationMarkerPlacement::DATANAME_TUMOUR = "Tumour"; +const char *QmitkUSNavigationMarkerPlacement::DATANAME_TARGETSURFACE = "Target Surface"; +const char *QmitkUSNavigationMarkerPlacement::DATANAME_ZONES = "Zones"; +const char *QmitkUSNavigationMarkerPlacement::DATANAME_TARGETS = "Targets"; +const char *QmitkUSNavigationMarkerPlacement::DATANAME_TARGETS_PATHS = "Target Paths"; +const char *QmitkUSNavigationMarkerPlacement::DATANAME_REACHED_TARGETS = "Reached Targets"; -USNavigationMarkerPlacement::USNavigationMarkerPlacement() +QmitkUSNavigationMarkerPlacement::QmitkUSNavigationMarkerPlacement() : m_Parent(nullptr), m_NavigationSteps(), m_UpdateTimer(new QTimer(this)), m_ImageAndNavigationDataLoggingTimer(new QTimer(this)), m_StdMultiWidget(nullptr), m_CombinedModality(nullptr), m_ReinitAlreadyDone(false), m_IsExperimentRunning(false), m_CurrentApplicationName(), m_NavigationStepTimer(mitk::USNavigationStepTimer::New()), m_ExperimentLogging(mitk::USNavigationExperimentLogging::New()), m_IconRunning(QPixmap(":/USNavigation/record.png")), m_IconNotRunning(QPixmap(":/USNavigation/record-gray.png")), m_ResultsDirectory(), m_ExperimentName(), m_ExperimentResultsSubDirectory(), m_NavigationStepNames(), m_LoggingBackend(), m_USImageLoggingFilter(mitk::USImageLoggingFilter::New()), m_NavigationDataRecorder(mitk::NavigationDataRecorder::New()), m_TargetNodeDisplacementFilter(nullptr), m_AblationZonesDisplacementFilter(mitk::NodeDisplacementFilter::New()), m_AblationZonesVector(), m_NeedleIndex(0), m_MarkerIndex(1), m_SceneNumber(1), m_WarnOverlay(mitk::TextAnnotation2D::New()), m_NavigationDataSource(nullptr), m_CurrentStorage(nullptr), - m_ListenerDeviceChanged(this, &USNavigationMarkerPlacement::OnCombinedModalityPropertyChanged), - ui(new Ui::USNavigationMarkerPlacement) + m_ListenerDeviceChanged(this, &QmitkUSNavigationMarkerPlacement::OnCombinedModalityPropertyChanged), + ui(new Ui::QmitkUSNavigationMarkerPlacement ) { connect(m_UpdateTimer, SIGNAL(timeout()), this, SLOT(OnTimeout())); connect( m_ImageAndNavigationDataLoggingTimer, SIGNAL(timeout()), this, SLOT(OnImageAndNavigationDataLoggingTimeout())); // scale running (and not running) icon the specific height m_IconRunning = m_IconRunning.scaledToHeight(20, Qt::SmoothTransformation); m_IconNotRunning = m_IconNotRunning.scaledToHeight(20, Qt::SmoothTransformation); // set prefix for experiment logging (only keys with this prefix are taken // into consideration m_ExperimentLogging->SetKeyPrefix("USNavigation::"); m_UpdateTimer->start(33); // every 33 Milliseconds = 30 Frames/Second } -USNavigationMarkerPlacement::~USNavigationMarkerPlacement() +QmitkUSNavigationMarkerPlacement::~QmitkUSNavigationMarkerPlacement() { // remove listener for ultrasound device changes if (m_CombinedModality.IsNotNull() && m_CombinedModality->GetUltrasoundDevice().IsNotNull()) { m_CombinedModality->GetUltrasoundDevice()->RemovePropertyChangedListener(m_ListenerDeviceChanged); } // remove listener for ultrasound device changes if (m_CombinedModality.IsNotNull() && m_CombinedModality->GetUltrasoundDevice().IsNotNull()) { m_CombinedModality->GetUltrasoundDevice()->RemovePropertyChangedListener(m_ListenerDeviceChanged); } delete ui; } -void USNavigationMarkerPlacement::OnChangeAblationZone(int id, int newSize) +void QmitkUSNavigationMarkerPlacement::OnChangeAblationZone(int id, int newSize) { if ((static_cast(m_AblationZonesVector.size()) < id) || (id < 0)) { return; } MITK_INFO << "Ablation Zone " << id << " changed, new size: " << newSize; // create a vtk sphere with given radius vtkSphereSource *vtkData = vtkSphereSource::New(); vtkData->SetRadius(newSize / 2); vtkData->SetCenter(0, 0, 0); vtkData->SetPhiResolution(20); vtkData->SetThetaResolution(20); vtkData->Update(); mitk::Surface::Pointer zoneSurface = dynamic_cast(m_AblationZonesVector.at(id)->GetData()); zoneSurface->SetVtkPolyData(vtkData->GetOutput()); vtkData->Delete(); } -void USNavigationMarkerPlacement::OnAddAblationZone(int size) +void QmitkUSNavigationMarkerPlacement::OnAddAblationZone(int size) { m_AblationZonesDisplacementFilter->SetInitialReferencePose( m_CombinedModality->GetNavigationDataSource()->GetOutput(m_MarkerIndex)); mitk::DataNode::Pointer NewAblationZone = mitk::DataNode::New(); mitk::Point3D origin = m_CombinedModality->GetNavigationDataSource()->GetOutput(m_NeedleIndex)->GetPosition(); MITK_INFO("USNavigationLogging") << "Ablation Zone Added, initial size: " << size << ", origin: " << origin; mitk::Surface::Pointer zone = mitk::Surface::New(); // create a vtk sphere with given radius vtkSphereSource *vtkData = vtkSphereSource::New(); vtkData->SetRadius(size / 2); vtkData->SetCenter(0, 0, 0); vtkData->SetPhiResolution(20); vtkData->SetThetaResolution(20); vtkData->Update(); zone->SetVtkPolyData(vtkData->GetOutput()); vtkData->Delete(); // set vtk sphere and origin to data node (origin must be set // again, because of the new sphere set as data) NewAblationZone->SetData(zone); NewAblationZone->GetData()->GetGeometry()->SetOrigin(origin); mitk::Color SphereColor = mitk::Color(); // default color SphereColor[0] = 102; SphereColor[1] = 0; SphereColor[2] = 204; NewAblationZone->SetColor(SphereColor); NewAblationZone->SetOpacity(0.3); // set name of zone std::stringstream name; name << "Ablation Zone" << m_AblationZonesVector.size(); NewAblationZone->SetName(name.str()); // add zone to filter m_AblationZonesDisplacementFilter->AddNode(NewAblationZone); m_AblationZonesVector.push_back(NewAblationZone); this->GetDataStorage()->Add(NewAblationZone); } -void USNavigationMarkerPlacement::CreateQtPartControl(QWidget *parent) +void QmitkUSNavigationMarkerPlacement::CreateQtPartControl(QWidget *parent) { m_Parent = parent; ui->setupUi(parent); connect(ui->navigationProcessWidget, SIGNAL(SignalCombinedModalityChanged(itk::SmartPointer)), this, SLOT(OnCombinedModalityChanged(itk::SmartPointer))); connect(ui->navigationProcessWidget, SIGNAL(SignalSettingsChanged(itk::SmartPointer)), this, SLOT(OnSettingsChanged(itk::SmartPointer))); connect(ui->navigationProcessWidget, SIGNAL(SignalActiveNavigationStepChanged(int)), this, SLOT(OnActiveNavigationStepChanged(int))); connect(ui->navigationProcessWidget, SIGNAL(SignalActiveNavigationStepChangeRequested(int)), this, SLOT(OnNextNavigationStepInitialization(int))); connect(ui->startExperimentButton, SIGNAL(clicked()), this, SLOT(OnStartExperiment())); connect(ui->finishExperimentButton, SIGNAL(clicked()), this, SLOT(OnFinishExperiment())); connect(ui->m_enableNavigationLayout, SIGNAL(clicked()), this, SLOT(OnChangeLayoutClicked())); connect(ui->m_RenderWindowSelection, SIGNAL(valueChanged(int)), this, SLOT(OnRenderWindowSelection())); connect(ui->m_RefreshView, SIGNAL(clicked()), this, SLOT(OnRefreshView())); connect(ui->navigationProcessWidget, SIGNAL(SignalIntermediateResult(const itk::SmartPointer)), this, SLOT(OnIntermediateResultProduced(const itk::SmartPointer))); ui->navigationProcessWidget->SetDataStorage(this->GetDataStorage()); // indicate that no experiment is running at start ui->runningLabel->setPixmap(m_IconNotRunning); ui->navigationProcessWidget->SetSettingsWidget(new QmitkUSNavigationCombinedSettingsWidget(m_Parent)); } -void USNavigationMarkerPlacement::OnCombinedModalityPropertyChanged(const std::string &key, const std::string &) +void QmitkUSNavigationMarkerPlacement::OnCombinedModalityPropertyChanged(const std::string &key, const std::string &) { if (key == mitk::USDevice::GetPropertyKeys().US_PROPKEY_BMODE_DEPTH) { m_ReinitAlreadyDone = false; this->ReinitOnImage(); if (m_CombinedModality.IsNotNull() && !m_CombinedModality->GetIsCalibratedForCurrentStatus()) { mitk::LayoutAnnotationRenderer::AddAnnotation( m_WarnOverlay.GetPointer(), "stdmulti.widget1", mitk::LayoutAnnotationRenderer::TopLeft); MITK_WARN << "No calibration available for the selected ultrasound image depth."; } } } -void USNavigationMarkerPlacement::SetFocus() +void QmitkUSNavigationMarkerPlacement::SetFocus() { this->ReinitOnImage(); } -void USNavigationMarkerPlacement::OnTimeout() +void QmitkUSNavigationMarkerPlacement::OnTimeout() { if (!m_StdMultiWidget) { // try to get the standard multi widget if it couldn't be got before mitk::IRenderWindowPart *renderWindow = this->GetRenderWindowPart(); QmitkStdMultiWidgetEditor *multiWidgetEditor = dynamic_cast(renderWindow); // if there is a standard multi widget now, disable the level window and // change the layout to 2D up and 3d down if (multiWidgetEditor) { m_StdMultiWidget = multiWidgetEditor->GetStdMultiWidget(); SetTwoWindowView(); } this->CreateOverlays(); } if (m_CombinedModality.IsNotNull() && !this->m_CombinedModality->GetIsFreezed()) // if the combined modality is freezed: do nothing { ui->navigationProcessWidget->UpdateNavigationProgress(); m_AblationZonesDisplacementFilter->Update(); // update the 3D window only every fourth time to speed up the rendering (at least in 2D) this->RequestRenderWindowUpdate(mitk::RenderingManager::REQUEST_UPDATE_2DWINDOWS); // make sure that a reinit was performed on the image this->ReinitOnImage(); } } -void USNavigationMarkerPlacement::OnEnableNavigationLayout() +void QmitkUSNavigationMarkerPlacement::OnEnableNavigationLayout() { MITK_INFO << "Navigation Layout"; // try to get the standard multi widget if it couldn't be got before mitk::IRenderWindowPart *renderWindow = this->GetRenderWindowPart(); QmitkStdMultiWidgetEditor *multiWidgetEditor = dynamic_cast(renderWindow); // if there is a standard multi widget now, disable the level window and // change the layout to 2D up and 3d down if (multiWidgetEditor) { m_StdMultiWidget = multiWidgetEditor->GetStdMultiWidget(); SetTwoWindowView(); } } -void USNavigationMarkerPlacement::OnRenderWindowSelection() +void QmitkUSNavigationMarkerPlacement::OnRenderWindowSelection() { SetTwoWindowView(); } -void USNavigationMarkerPlacement::OnRefreshView() +void QmitkUSNavigationMarkerPlacement::OnRefreshView() { if (!ui->m_enableNavigationLayout->isChecked()) OnResetStandardLayout(); else { //Reinit the US Image Stream (this might be broken if there was a global reinit somewhere...) try { mitk::RenderingManager::GetInstance()->InitializeViews(//Reinit this->GetDataStorage()//GetDataStorage ->GetNamedNode("US Support Viewing Stream")->GetData()->GetTimeGeometry());//GetNode } catch (...) { MITK_DEBUG << "No reinit possible"; } SetTwoWindowView(); } } -void USNavigationMarkerPlacement::SetTwoWindowView() +void QmitkUSNavigationMarkerPlacement::SetTwoWindowView() { if (m_StdMultiWidget) { m_StdMultiWidget->DisableStandardLevelWindow(); int i, j, k; switch (this->ui->m_RenderWindowSelection->value()) { case 1: mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget4"))->GetCameraController()->SetViewToCaudal(); i = 2; j = 3; //other windows k = 1; break; case 2: mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget4"))->GetCameraController()->SetViewToSinister(); i = 1; j = 3; k = 2; break; case 3: mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget4"))->GetCameraController()->SetViewToAnterior(); i = 2; j = 1; k = 3; break; default: return; } m_StdMultiWidget->changeLayoutTo2DUpAnd3DDown(k); ////Crosshair invisible in 3D view this->GetDataStorage()->GetNamedNode("stdmulti.widget" + std::to_string(i) + ".plane")-> SetBoolProperty("visible", false, mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget4"))); this->GetDataStorage()->GetNamedNode("stdmulti.widget" + std::to_string(j) + ".plane")-> SetBoolProperty("visible", false, mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget4"))); this->GetDataStorage()->GetNamedNode("stdmulti.widget" + std::to_string(k) + ".plane")-> SetBoolProperty("visible", true, mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget4"))); this->GetDataStorage()->GetNamedNode("stdmulti.widget" + std::to_string(i) + ".plane")-> SetIntProperty("Crosshair.Gap Size", 0); this->GetDataStorage()->GetNamedNode("stdmulti.widget" + std::to_string(j) + ".plane")-> SetIntProperty("Crosshair.Gap Size", 0); } } -void USNavigationMarkerPlacement::OnResetStandardLayout() +void QmitkUSNavigationMarkerPlacement::OnResetStandardLayout() { //reset render windows mitk::DataNode::Pointer widget1 = this->GetDataStorage()->GetNamedNode("stdmulti.widget1.plane"); if (widget1.IsNotNull()) { widget1->SetVisibility(true); } mitk::DataNode::Pointer widget2 = this->GetDataStorage()->GetNamedNode("stdmulti.widget2.plane"); if (widget2.IsNotNull()) { widget2->SetVisibility(true); } mitk::DataNode::Pointer widget3 = this->GetDataStorage()->GetNamedNode("stdmulti.widget3.plane"); if (widget3.IsNotNull()) { widget3->SetVisibility(true); } m_StdMultiWidget->changeLayoutToDefault(); } -void USNavigationMarkerPlacement::OnChangeLayoutClicked() +void QmitkUSNavigationMarkerPlacement::OnChangeLayoutClicked() { if (ui->m_enableNavigationLayout->isChecked()) OnEnableNavigationLayout(); else OnResetStandardLayout(); } -void USNavigationMarkerPlacement::OnImageAndNavigationDataLoggingTimeout() +void QmitkUSNavigationMarkerPlacement::OnImageAndNavigationDataLoggingTimeout() { // update filter for logging navigation data and ultrasound images if (m_CombinedModality.IsNotNull()) { m_NavigationDataRecorder->Update(); // get last messages for logging filer and store them std::vector messages = m_LoggingBackend.GetNavigationMessages(); std::string composedMessage = ""; for (std::size_t i = 0; i < messages.size(); i++) { composedMessage += messages.at(i); } m_USImageLoggingFilter->AddMessageToCurrentImage(composedMessage); m_LoggingBackend.ClearNavigationMessages(); // update logging filter m_USImageLoggingFilter->Update(); } } -void USNavigationMarkerPlacement::OnStartExperiment() +void QmitkUSNavigationMarkerPlacement::OnStartExperiment() { // get name for the experiment by a QInputDialog bool ok; if (m_ExperimentName.isEmpty()) { // default: current date m_ExperimentName = QString::number(QDateTime::currentDateTime().date().year()) + "_" + QString::number(QDateTime::currentDateTime().date().month()) + "_" + QString::number(QDateTime::currentDateTime().date().day()) + "_experiment_" + QString::number(QDateTime::currentDateTime().time().hour()) + "." + QString::number(QDateTime::currentDateTime().time().minute()); } m_ExperimentName = QInputDialog::getText( m_Parent, QString("Experiment Name"), QString("Name of the Experiment"), QLineEdit::Normal, m_ExperimentName, &ok); MITK_INFO("USNavigationLogging") << "Experiment started: " << m_ExperimentName.toStdString(); if (ok && !m_ExperimentName.isEmpty()) { // display error message and call the function recursivly if a directory // with the given name already exists QDir experimentResultsDir(m_ResultsDirectory + QDir::separator() + m_ExperimentName); if (experimentResultsDir.exists()) { QMessageBox::critical( m_Parent, "Results Directory Exists", "The result directory already exists.\nPlease choose an other name."); this->OnStartExperiment(); } else { QDir(m_ResultsDirectory).mkdir(m_ExperimentName); m_ExperimentResultsSubDirectory = m_ResultsDirectory + QDir::separator() + m_ExperimentName; // experiment is running now ui->runningLabel->setPixmap(m_IconRunning); ui->navigationProcessWidget->EnableInteraction(true); // (re)start timer for navigation step durations m_NavigationStepTimer->Reset(); m_NavigationStepTimer->SetOutputFileName( QString(m_ExperimentResultsSubDirectory + QDir::separator() + QString("durations.cvs")).toStdString()); m_NavigationStepTimer->SetActiveIndex(0, m_NavigationSteps.at(0)->GetTitle().toStdString()); ui->finishExperimentButton->setEnabled(true); ui->startExperimentButton->setDisabled(true); // initialize and register logging backend QString loggingFilename = m_ExperimentResultsSubDirectory + QDir::separator() + "logging.txt"; m_LoggingBackend.SetOutputFileName(loggingFilename.toStdString()); mbilog::RegisterBackend(&m_LoggingBackend); // initialize and start navigation data recorder form xml recording m_NavigationDataRecorder->StartRecording(); m_IsExperimentRunning = true; m_ImageAndNavigationDataLoggingTimer->start(1000); // (re)start experiment logging and set output file name m_ExperimentLogging->Reset(); m_ExperimentLogging->SetFileName( QString(m_ExperimentResultsSubDirectory + QDir::separator() + "experiment-logging.xml").toStdString()); } } } -void USNavigationMarkerPlacement::OnFinishExperiment() +void QmitkUSNavigationMarkerPlacement::OnFinishExperiment() { this->WaitCursorOn(); MITK_INFO("USNavigationLogging") << "Experiment finished!"; MITK_INFO("USNavigationLogging") << "Position/Orientation of needle tip: " << (dynamic_cast(m_CombinedModality->GetTrackingDevice()->GetOutput(0)))->GetPosition(); MITK_INFO("USNavigationLogging") << "Position of target: " << m_TargetNodeDisplacementFilter->GetRawDisplacementNavigationData(0)->GetPosition(); MITK_INFO("USNavigationLogging") << "Total duration: " << m_NavigationStepTimer->GetTotalDuration(); ui->navigationProcessWidget->FinishCurrentNavigationStep(); m_ImageAndNavigationDataLoggingTimer->stop(); ui->runningLabel->setPixmap(m_IconNotRunning); ui->navigationProcessWidget->EnableInteraction(false); m_NavigationStepTimer->Stop(); // make sure that the navigation process will be start from beginning at the // next experiment ui->navigationProcessWidget->ResetNavigationProcess(); ui->finishExperimentButton->setDisabled(true); ui->startExperimentButton->setEnabled(true); MITK_INFO("USNavigationLogging") << "Writing logging data to " << m_ExperimentResultsSubDirectory.toStdString(); // save ultrasound images to the file system QDir(m_ExperimentResultsSubDirectory).mkdir("ImageStream"); m_USImageLoggingFilter->Update(); m_USImageLoggingFilter->SetImageFilesExtension(".jpg"); m_USImageLoggingFilter->SaveImages( QString(m_ExperimentResultsSubDirectory + QDir::separator() + "ImageStream" + QDir::separator()).toStdString()); m_USImageLoggingFilter = mitk::USImageLoggingFilter::New(); m_NavigationDataRecorder->StopRecording(); // Write data to csv and xml file mitk::IOUtil::Save( m_NavigationDataRecorder->GetNavigationDataSet(), (QString(m_ExperimentResultsSubDirectory + QDir::separator() + "navigation-data.xml").toStdString().c_str())); mitk::IOUtil::Save( m_NavigationDataRecorder->GetNavigationDataSet(), (QString(m_ExperimentResultsSubDirectory + QDir::separator() + "navigation-data.csv").toStdString().c_str())); // write logged navigation data messages to separate file std::stringstream csvNavigationMessagesFilename; csvNavigationMessagesFilename << m_ExperimentResultsSubDirectory.toStdString() << QDir::separator().toLatin1() << "CSVNavigationMessagesLogFile.csv"; MITK_INFO("USNavigationLogging") << "Writing logged navigation messages to separate csv file: " << csvNavigationMessagesFilename.str(); m_LoggingBackend.WriteCSVFileWithNavigationMessages(csvNavigationMessagesFilename.str()); mbilog::UnregisterBackend(&m_LoggingBackend); m_IsExperimentRunning = false; m_ImageAndNavigationDataLoggingTimer->stop(); m_CombinedModality = nullptr; // reset scene number for next experiment m_SceneNumber = 1; this->WaitCursorOff(); MITK_INFO("USNavigationLogging") << "Finished!"; } -void USNavigationMarkerPlacement::OnCombinedModalityChanged( +void QmitkUSNavigationMarkerPlacement::OnCombinedModalityChanged( itk::SmartPointer combinedModality) { // remove old listener for ultrasound device changes if (m_CombinedModality.IsNotNull() && m_CombinedModality->GetUltrasoundDevice().IsNotNull()) { m_CombinedModality->GetUltrasoundDevice()->RemovePropertyChangedListener(m_ListenerDeviceChanged); } m_CombinedModality = combinedModality; m_ReinitAlreadyDone = false; // add a listener for ultrasound device changes if (m_CombinedModality.IsNotNull() && m_CombinedModality->GetUltrasoundDevice().IsNotNull()) { m_CombinedModality->GetUltrasoundDevice()->AddPropertyChangedListener(m_ListenerDeviceChanged); } // update navigation data recorder for using the new combined modality mitk::NavigationDataSource::Pointer navigationDataSource = combinedModality->GetNavigationDataSource(); m_NavigationDataRecorder->ConnectTo(navigationDataSource); m_NavigationDataRecorder->ResetRecording(); // update ultrasound image logging filter for using the new combined modality mitk::USDevice::Pointer ultrasoundImageSource = combinedModality->GetUltrasoundDevice(); for (unsigned int n = 0; n < ultrasoundImageSource->GetNumberOfIndexedOutputs(); ++n) { m_USImageLoggingFilter->SetInput(n, ultrasoundImageSource->GetOutput(n)); } // update ablation zone filter for using the new combined modality for (unsigned int n = 0; n < navigationDataSource->GetNumberOfIndexedOutputs(); ++n) { m_AblationZonesDisplacementFilter->SetInput(n, navigationDataSource->GetOutput(n)); } m_AblationZonesDisplacementFilter->SelectInput(m_MarkerIndex); // make sure that a reinit is done for the new images this->ReinitOnImage(); } -void USNavigationMarkerPlacement::OnSettingsChanged(itk::SmartPointer settings) +void QmitkUSNavigationMarkerPlacement::OnSettingsChanged(itk::SmartPointer settings) { std::string applicationName; if (!settings->GetStringProperty("settings.application", applicationName)) { // set default application if the string property is not available applicationName = "Marker Placement"; } // create navigation step widgets according to the selected application if (applicationName != m_CurrentApplicationName) { m_CurrentApplicationName = applicationName; QmitkUSNavigationProcessWidget::NavigationStepVector navigationSteps; if (applicationName == "Puncture") { QmitkUSNavigationStepCombinedModality* stepCombinedModality = new QmitkUSNavigationStepCombinedModality(m_Parent); QmitkUSNavigationStepTumourSelection* stepTumourSelection = new QmitkUSNavigationStepTumourSelection(m_Parent); stepTumourSelection->SetTargetSelectionOptional(true); m_TargetNodeDisplacementFilter = stepTumourSelection->GetTumourNodeDisplacementFilter(); QmitkUSNavigationStepZoneMarking* stepZoneMarking = new QmitkUSNavigationStepZoneMarking(m_Parent); QmitkUSNavigationStepPunctuationIntervention* stepIntervention = new QmitkUSNavigationStepPunctuationIntervention(m_Parent); connect(stepIntervention, SIGNAL(AddAblationZoneClicked(int)), this, SLOT(OnAddAblationZone(int))); connect(stepIntervention, SIGNAL(AblationZoneChanged(int, int)), this, SLOT(OnChangeAblationZone(int, int))); m_NavigationStepNames = std::vector(); navigationSteps.push_back(stepCombinedModality); m_NavigationStepNames.push_back("Combined Modality Initialization"); navigationSteps.push_back(stepTumourSelection); m_NavigationStepNames.push_back("Target Selection"); navigationSteps.push_back(stepZoneMarking); m_NavigationStepNames.push_back("Critical Structure Marking"); navigationSteps.push_back(stepIntervention); m_NavigationStepNames.push_back("Intervention"); } else if (applicationName == "Marker Placement") { QmitkUSNavigationStepCombinedModality *stepCombinedModality = new QmitkUSNavigationStepCombinedModality(m_Parent); QmitkUSNavigationStepTumourSelection *stepTumourSelection = new QmitkUSNavigationStepTumourSelection(m_Parent); m_TargetNodeDisplacementFilter = stepTumourSelection->GetTumourNodeDisplacementFilter(); QmitkUSNavigationStepZoneMarking *stepZoneMarking = new QmitkUSNavigationStepZoneMarking(m_Parent); QmitkUSNavigationStepPlacementPlanning *stepPlacementPlanning = new QmitkUSNavigationStepPlacementPlanning(m_Parent); QmitkUSNavigationStepMarkerIntervention *stepMarkerIntervention = new QmitkUSNavigationStepMarkerIntervention(m_Parent); m_NavigationStepNames = std::vector(); navigationSteps.push_back(stepCombinedModality); m_NavigationStepNames.push_back("Combined Modality Initialization"); navigationSteps.push_back(stepTumourSelection); m_NavigationStepNames.push_back("Target Selection"); navigationSteps.push_back(stepZoneMarking); m_NavigationStepNames.push_back("Critical Structure Marking"); navigationSteps.push_back(stepPlacementPlanning); m_NavigationStepNames.push_back("Placement Planning"); navigationSteps.push_back(stepMarkerIntervention); m_NavigationStepNames.push_back("Marker Intervention"); } // set navigation step widgets to the process widget ui->navigationProcessWidget->SetNavigationSteps(navigationSteps); for (QmitkUSNavigationProcessWidget::NavigationStepIterator it = m_NavigationSteps.begin(); it != m_NavigationSteps.end(); ++it) { delete *it; } m_NavigationSteps.clear(); m_NavigationSteps = navigationSteps; } // initialize gui according to the experiment mode setting bool experimentMode = false; settings->GetBoolProperty("settings.experiment-mode", experimentMode); ui->startExperimentButton->setVisible(experimentMode); ui->finishExperimentButton->setVisible(experimentMode); ui->runningLabel->setVisible(experimentMode); if (experimentMode && !m_IsExperimentRunning) { ui->navigationProcessWidget->ResetNavigationProcess(); ui->navigationProcessWidget->EnableInteraction(false); ui->runningLabel->setPixmap(m_IconNotRunning); } else if (!experimentMode) { if (m_IsExperimentRunning) { this->OnFinishExperiment(); } ui->navigationProcessWidget->EnableInteraction(true); } // get the results directory from the settings and use home directory if // there is no results directory configured std::string resultsDirectory; if (settings->GetStringProperty("settings.experiment-results-directory", resultsDirectory)) { m_ResultsDirectory = QString::fromStdString(resultsDirectory); } else { m_ResultsDirectory = QDir::homePath(); } // make sure that the results directory exists QDir resultsDirectoryQDir = QDir(m_ResultsDirectory); if (!resultsDirectoryQDir.exists()) { resultsDirectoryQDir.mkpath(m_ResultsDirectory); } MITK_INFO("USNavigation") << "Results Directory: " << m_ResultsDirectory.toStdString(); } -void USNavigationMarkerPlacement::OnActiveNavigationStepChanged(int index) +void QmitkUSNavigationMarkerPlacement::OnActiveNavigationStepChanged(int index) { // update navigation step timer each time the active navigation step changes m_NavigationStepTimer->SetActiveIndex(index, m_NavigationSteps.at(index)->GetTitle().toStdString()); if (static_cast(m_NavigationStepNames.size()) <= index) { MITK_INFO("USNavigationLogging") << "Someting went wrong: unknown navigation step!"; } else { MITK_INFO("USNavigationLogging") << "Navigation step finished/changed, next step: " << this->m_NavigationStepNames.at(index).toStdString() << "; duration until now: " << m_NavigationStepTimer->GetTotalDuration(); } } -void USNavigationMarkerPlacement::OnNextNavigationStepInitialization(int index) +void QmitkUSNavigationMarkerPlacement::OnNextNavigationStepInitialization(int index) { MITK_DEBUG << "Next Step: " << m_NavigationSteps.at(index)->GetTitle().toStdString(); if (m_NavigationSteps.at(index)->GetTitle().toStdString() == "Computer-assisted Intervention") { QmitkUSNavigationStepPunctuationIntervention* navigationStepPunctuationIntervention = static_cast(m_NavigationSteps.at(index)); if (navigationStepPunctuationIntervention != nullptr) { if (m_CurrentStorage.IsNull()) { this->UpdateToolStorage(); } if (m_CurrentStorage.IsNull() || (m_CurrentStorage->GetTool(m_NeedleIndex).IsNull())) { MITK_WARN << "Found null pointer when setting the tool axis, aborting"; } else { navigationStepPunctuationIntervention->SetNeedleMetaData(m_CurrentStorage->GetTool(m_NeedleIndex)); MITK_DEBUG << "Needle axis vector: " << m_CurrentStorage->GetTool(m_NeedleIndex)->GetToolAxis(); } } } } -void USNavigationMarkerPlacement::OnIntermediateResultProduced(const itk::SmartPointer resultsNode) +void QmitkUSNavigationMarkerPlacement::OnIntermediateResultProduced(const itk::SmartPointer resultsNode) { // intermediate results only matter during an experiment if (!m_IsExperimentRunning) { return; } this->WaitCursorOn(); // set results node to the experiment logging (for saving contents to the // file system) m_ExperimentLogging->SetResult(resultsNode); std::string resultsName; if (!resultsNode->GetName(resultsName)) { MITK_WARN << "Could not get name of current results node."; return; } // save the mitk scene std::string scenefile = QString(m_ExperimentResultsSubDirectory + QDir::separator() + QString("Scene %1 - ").arg(m_SceneNumber++, 2, 10, QChar('0')) + QString::fromStdString(resultsName).replace(":", "_") + ".mitk") .toStdString(); MITK_INFO << "Saving Scene File: " << scenefile; mitk::SceneIO::Pointer sceneIO = mitk::SceneIO::New(); mitk::NodePredicateNot::Pointer isNotHelperObject = mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object", mitk::BoolProperty::New(true))); mitk::DataStorage::SetOfObjects::ConstPointer nodesToBeSaved = this->GetDataStorage()->GetSubset(isNotHelperObject); this->Convert2DImagesTo3D(nodesToBeSaved); sceneIO->SaveScene(nodesToBeSaved, this->GetDataStorage(), scenefile); this->WaitCursorOff(); } -void USNavigationMarkerPlacement::ReinitOnImage() +void QmitkUSNavigationMarkerPlacement::ReinitOnImage() { if (!m_ReinitAlreadyDone && m_CombinedModality.IsNotNull()) { // make sure that the output is already calibrated correctly // (if the zoom level was changed recently) m_CombinedModality->Modified(); m_CombinedModality->Update(); mitk::Image::Pointer image = m_CombinedModality->GetOutput(); if (image.IsNotNull() && image->IsInitialized()) { // make a reinit on the ultrasound image mitk::IRenderWindowPart *renderWindow = this->GetRenderWindowPart(); if (renderWindow != NULL && image->GetTimeGeometry()->IsValid()) { renderWindow->GetRenderingManager()->InitializeViews( image->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true); renderWindow->GetRenderingManager()->RequestUpdateAll(); } this->RequestRenderWindowUpdate(); m_ReinitAlreadyDone = true; } } } -void USNavigationMarkerPlacement::Convert2DImagesTo3D(mitk::DataStorage::SetOfObjects::ConstPointer nodes) +void QmitkUSNavigationMarkerPlacement::Convert2DImagesTo3D(mitk::DataStorage::SetOfObjects::ConstPointer nodes) { for (mitk::DataStorage::SetOfObjects::ConstIterator it = nodes->Begin(); it != nodes->End(); ++it) { if (it->Value()->GetData() && strcmp(it->Value()->GetData()->GetNameOfClass(), "Image") == 0) { // convert image to 3d image if it is 2d at the moment mitk::Image::Pointer image = dynamic_cast(it->Value()->GetData()); if (image.IsNotNull() && image->GetDimension() == 2 && !image->GetGeometry()->Is2DConvertable()) { mitk::Convert2Dto3DImageFilter::Pointer convert2DTo3DImageFilter = mitk::Convert2Dto3DImageFilter::New(); convert2DTo3DImageFilter->SetInput(image); convert2DTo3DImageFilter->Update(); it->Value()->SetData(convert2DTo3DImageFilter->GetOutput()); } } } } -void USNavigationMarkerPlacement::CreateOverlays() +void QmitkUSNavigationMarkerPlacement::CreateOverlays() { // initialize warning overlay (and do not display it, yet) m_WarnOverlay->SetText("Warning: No calibration available for current depth."); // set position and font size for the text overlay // (nonesense postition as a layouter is used, but it ignored // the overlay without setting a position here) mitk::Point2D overlayPosition; overlayPosition.SetElement(0, -50.0f); overlayPosition.SetElement(1, -50.0f); m_WarnOverlay->SetPosition2D(overlayPosition); m_WarnOverlay->SetFontSize(22); m_WarnOverlay->SetColor(1, 0, 0); // overlay should be red } -void USNavigationMarkerPlacement::UpdateToolStorage() +void QmitkUSNavigationMarkerPlacement::UpdateToolStorage() { if (m_NavigationDataSource.IsNull()) { m_NavigationDataSource = m_CombinedModality->GetNavigationDataSource(); } if (m_NavigationDataSource.IsNull()) { MITK_WARN << "Found an invalid navigation data source object!"; } us::ModuleContext* context = us::GetModuleContext(); std::string id = m_NavigationDataSource->US_PROPKEY_ID; std::string filter = "(" + mitk::NavigationToolStorage::US_PROPKEY_SOURCE_ID + "=" + id + ")"; // Get Storage std::vector > refs = context->GetServiceReferences(); m_CurrentStorage = context->GetService(refs.front()); if (m_CurrentStorage.IsNull()) { MITK_WARN << "Found an invalid storage object!"; } else if (m_CurrentStorage->GetToolCount() != m_NavigationDataSource->GetNumberOfOutputs()) //there is something wrong with the storage { MITK_WARN << "Found a tool storage, but it has not the same number of tools like the NavigationDataSource. This storage won't be used because it isn't the right one."; m_CurrentStorage = NULL; } } diff --git a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/USNavigationMarkerPlacement.h b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/QmitkUSNavigationMarkerPlacement.h similarity index 92% rename from Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/USNavigationMarkerPlacement.h rename to Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/QmitkUSNavigationMarkerPlacement.h index 6dd2b585ea..e4e4634543 100644 --- a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/USNavigationMarkerPlacement.h +++ b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/QmitkUSNavigationMarkerPlacement.h @@ -1,216 +1,216 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ -#ifndef USNAVIGATIONMARKERPLACEMENT_H -#define USNAVIGATIONMARKERPLACEMENT_H +#ifndef QmitkUSNAVIGATIONMARKERPLACEMENT_H +#define QmitkUSNAVIGATIONMARKERPLACEMENT_H #include #include "IO/mitkUSNavigationLoggingBackend.h" #include "Widgets/QmitkUSNavigationProcessWidget.h" #include "mitkNavigationDataRecorder.h" #include "mitkNodeDisplacementFilter.h" #include "mitkUSImageLoggingFilter.h" #include #include #include #include namespace itk { template class SmartPointer; } namespace mitk { class USNavigationStepTimer; class USNavigationExperimentLogging; } namespace Ui { - class USNavigationMarkerPlacement; + class QmitkUSNavigationMarkerPlacement; } class QmitkUSAbstractNavigationStep; class QmitkUSNavigationStepPunctuationIntervention; class QmitkStdMultiWidget; class QTimer; class QSignalMapper; /** * \brief View for navigated marker placement using the combined modality. * This view utilizes the QmitkUSNavigationProcessWidget to do the navigation * process. It can be switched between widgets for marker placement and widgets * for punctuation. * * An experiment mode allows for logging results, durations and the ultrasound * images. */ -class USNavigationMarkerPlacement : public QmitkAbstractView +class QmitkUSNavigationMarkerPlacement : public QmitkAbstractView { Q_OBJECT protected slots: /** * \brief Called periodically to update the rendering. * The standard multi widget is changed to fit the navigation process once it * is available and a reinit on the ultrasound image is done for a new image * node. */ void OnTimeout(); /** * \brief Called periodically during an experiment for logging the ultrasound images. */ void OnImageAndNavigationDataLoggingTimeout(); /** * \brief Initializes anything neccessary for an experiment. * The user is asked for a directory for storing the results and the logging * is started. */ void OnStartExperiment(); /** * \brief Stops logging and saves everything to the file system. */ void OnFinishExperiment(); void OnCombinedModalityChanged(itk::SmartPointer); /** * \brief Switches the navigation step widgets if the navigation application was changed. */ void OnSettingsChanged(itk::SmartPointer); /** * \brief Updates the timer for the navigation steps durations every time the active navigation step changes. */ void OnActiveNavigationStepChanged(int); /** Initializes the next navigation step */ void OnNextNavigationStepInitialization(int); /** * \brief The data node is given to the experiment logging and scene is saved to the file system. */ void OnIntermediateResultProduced(const itk::SmartPointer); void OnAddAblationZone(int size); void OnEnableNavigationLayout(); void OnResetStandardLayout(); void OnChangeLayoutClicked(); void OnChangeAblationZone(int id, int newSize); void OnRenderWindowSelection(); void OnRefreshView(); public: static const char *DATANAME_TUMOUR; static const char *DATANAME_TARGETSURFACE; static const char *DATANAME_ZONES; static const char *DATANAME_TARGETS; static const char *DATANAME_TARGETS_PATHS; static const char *DATANAME_REACHED_TARGETS; - explicit USNavigationMarkerPlacement(); - ~USNavigationMarkerPlacement(); + explicit QmitkUSNavigationMarkerPlacement(); + ~QmitkUSNavigationMarkerPlacement(); virtual void CreateQtPartControl(QWidget *parent); static const std::string VIEW_ID; void OnCombinedModalityPropertyChanged(const std::string &, const std::string &); protected: /** * \brief A reinit on the ultrasound image is performed every time the view gets the focus. */ virtual void SetFocus(); /** * \brief Helper function which performs a reinit on the ultrasound image. */ void ReinitOnImage(); /** * \brief Sets the multiwidget to two windows, axial on top and 3D render window on the bottom. */ virtual void SetTwoWindowView(); /** * \brief Helper function for being able to serialize the 2d ultrasound image. */ void Convert2DImagesTo3D(mitk::DataStorage::SetOfObjects::ConstPointer nodes); void UpdateToolStorage(); void CreateOverlays(); QWidget *m_Parent; QmitkUSNavigationProcessWidget::NavigationStepVector m_NavigationSteps; QTimer *m_UpdateTimer; QTimer *m_ImageAndNavigationDataLoggingTimer; QmitkStdMultiWidget *m_StdMultiWidget; itk::SmartPointer m_CombinedModality; bool m_ReinitAlreadyDone; bool m_IsExperimentRunning; std::string m_CurrentApplicationName; itk::SmartPointer m_NavigationStepTimer; itk::SmartPointer m_ExperimentLogging; QPixmap m_IconRunning; QPixmap m_IconNotRunning; QString m_ResultsDirectory; QString m_ExperimentName; QString m_ExperimentResultsSubDirectory; std::vector m_NavigationStepNames; // stores the names of the navigation steps which are currently used (for logging purposes) mitk::USNavigationLoggingBackend m_LoggingBackend; mitk::USImageLoggingFilter::Pointer m_USImageLoggingFilter; mitk::NavigationDataRecorder::Pointer m_NavigationDataRecorder; // records navigation data files mitk::NodeDisplacementFilter::Pointer m_TargetNodeDisplacementFilter; mitk::NodeDisplacementFilter::Pointer m_AblationZonesDisplacementFilter; std::vector m_AblationZonesVector; int m_NeedleIndex; int m_MarkerIndex; int m_SceneNumber; itk::SmartPointer m_WarnOverlay; //To get tool storage mitk::NavigationDataSource::Pointer m_NavigationDataSource; mitk::NavigationToolStorage::Pointer m_CurrentStorage; private: - mitk::MessageDelegate2 m_ListenerDeviceChanged; + mitk::MessageDelegate2 m_ListenerDeviceChanged; - Ui::USNavigationMarkerPlacement *ui; + Ui::QmitkUSNavigationMarkerPlacement *ui; }; #endif // USNAVIGATIONMARKERPLACEMENT_H diff --git a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/USNavigationMarkerPlacement.ui b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/QmitkUSNavigationMarkerPlacement.ui similarity index 95% copy from Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/USNavigationMarkerPlacement.ui copy to Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/QmitkUSNavigationMarkerPlacement.ui index a181fe0767..ceb1ffc701 100644 --- a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/USNavigationMarkerPlacement.ui +++ b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/QmitkUSNavigationMarkerPlacement.ui @@ -1,123 +1,123 @@ - USNavigationMarkerPlacement - + QmitkUSNavigationMarkerPlacement + 0 0 - 400 + 443 146 Form 0 0 0 0 0 Qt::Horizontal Enable Navigation Render Window Layout with RenderWindow true 1 3 Refresh view Start New Experiment false Finish Experiment 20 20 QmitkUSNavigationProcessWidget QWidget
src/internal/Widgets/QmitkUSNavigationProcessWidget.h
1
OnStartExperiment() OnFinishExperiment()
diff --git a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/UltrasoundCalibration.cpp b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/QmitkUltrasoundCalibration.cpp similarity index 93% rename from Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/UltrasoundCalibration.cpp rename to Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/QmitkUltrasoundCalibration.cpp index 33db213e37..40fb72b2ab 100644 --- a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/UltrasoundCalibration.cpp +++ b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/QmitkUltrasoundCalibration.cpp @@ -1,1140 +1,1140 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ // Blueberry #include #include // Qmitk -#include "UltrasoundCalibration.h" +#include "QmitkUltrasoundCalibration.h" #include // Qt #include #include #include #include // MITK #include //#include #include #include #include #include #include #include "mitkIRenderingManager.h" // us #include //VTK #include #include #include #include #include #include #include "internal/org_mbi_gui_qt_usnavigation_Activator.h" //sleep headers #include #include -const std::string UltrasoundCalibration::VIEW_ID = "org.mitk.views.ultrasoundcalibration"; +const std::string QmitkUltrasoundCalibration::VIEW_ID = "org.mitk.views.ultrasoundcalibration"; -UltrasoundCalibration::UltrasoundCalibration() : -m_USDeviceChanged(this, &UltrasoundCalibration::OnUSDepthChanged) +QmitkUltrasoundCalibration::QmitkUltrasoundCalibration() : +m_USDeviceChanged(this, &QmitkUltrasoundCalibration::OnUSDepthChanged) { ctkPluginContext* pluginContext = mitk::PluginActivator::GetContext(); if (pluginContext) { // to be notified about service event of an USDevice pluginContext->connectServiceListener(this, "OnDeciveServiceEvent", QString::fromStdString("(" + us::ServiceConstants::OBJECTCLASS() + "=" + us_service_interface_iid() + ")")); } } -UltrasoundCalibration::~UltrasoundCalibration() +QmitkUltrasoundCalibration::~QmitkUltrasoundCalibration() { m_Controls.m_CombinedModalityManagerWidget->blockSignals(true); mitk::USCombinedModality::Pointer combinedModality; combinedModality = m_Controls.m_CombinedModalityManagerWidget->GetSelectedCombinedModality(); if (combinedModality.IsNotNull()) { combinedModality->GetUltrasoundDevice()->RemovePropertyChangedListener(m_USDeviceChanged); } m_Timer->stop(); // Sleep(500); //This might be problematic... seems like sometimes some ressources are still in use at calling time. this->OnStopCalibrationProcess(); this->OnStopPlusCalibration(); /*mitk::DataNode::Pointer node = this->GetDataStorage()->GetNamedNode("Tool Calibration Points"); if (node.IsNotNull())this->GetDataStorage()->Remove(node); node = this->GetDataStorage()->GetNamedNode("Image Calibration Points"); if (node.IsNotNull())this->GetDataStorage()->Remove(node); node = this->GetDataStorage()->GetNamedNode("US Image Stream"); if (node.IsNotNull())this->GetDataStorage()->Remove(node);*/ mitk::DataNode::Pointer node = this->GetDataStorage()->GetNamedNode("Needle Path"); if (node.IsNotNull())this->GetDataStorage()->Remove(node); this->GetDataStorage()->Remove(m_VerificationReferencePointsDataNode); delete m_Timer; } -void UltrasoundCalibration::SetFocus() +void QmitkUltrasoundCalibration::SetFocus() { m_Controls.m_ToolBox->setFocus(); } -void UltrasoundCalibration::CreateQtPartControl(QWidget *parent) +void QmitkUltrasoundCalibration::CreateQtPartControl(QWidget *parent) { // create GUI widgets from the Qt Designer's .ui file m_Controls.setupUi(parent); m_Controls.m_CombinedModalityManagerWidget->SetCalibrationLoadedNecessary(false); m_Timer = new QTimer(this); m_StreamingTimer = new QTimer(this); m_Controls.m_SpacingBtnFreeze->setEnabled(true); m_Controls.m_SpacingAddPoint->setEnabled(false); m_Controls.m_CalculateSpacing->setEnabled(false); m_SpacingPointsCount = 0; m_SpacingPoints = mitk::PointSet::New(); m_SpacingNode = mitk::DataNode::New(); m_SpacingNode->SetName("Spacing Points"); m_SpacingNode->SetData(this->m_SpacingPoints); this->GetDataStorage()->Add(m_SpacingNode); // Pointset for Calibration Points m_CalibPointsTool = mitk::PointSet::New(); // Pointset for Worldpoints m_CalibPointsImage = mitk::PointSet::New(); m_CalibPointsCount = 0; // Evaluation Pointsets (Non-Visualized) m_EvalPointsImage = mitk::PointSet::New(); m_EvalPointsTool = mitk::PointSet::New(); m_EvalPointsProjected = mitk::PointSet::New(); // Neelde Projection Filter m_NeedleProjectionFilter = mitk::NeedleProjectionFilter::New(); // Tracking Status Widgets m_Controls.m_CalibTrackingStatus->ShowStatusLabels(); m_Controls.m_EvalTrackingStatus->ShowStatusLabels(); m_OverrideSpacing = false; // General & Device Selection connect(m_Timer, SIGNAL(timeout()), this, SLOT(Update())); //connect(m_Controls.m_ToolBox, SIGNAL(currentChanged(int)), this, SLOT(OnTabSwitch(int))); // Calibration connect(m_Controls.m_CalibBtnFreeze, SIGNAL(clicked()), this, SLOT(SwitchFreeze())); // Freeze connect(m_Controls.m_CalibBtnAddPoint, SIGNAL(clicked()), this, SLOT(OnAddCalibPoint())); // Tracking & Image Points (Calibration) connect(m_Controls.m_CalibBtnCalibrate, SIGNAL(clicked()), this, SLOT(OnCalibration())); // Perform Calibration // Evaluation connect(m_Controls.m_EvalBtnStep1, SIGNAL(clicked()), this, SLOT(OnAddEvalProjectedPoint())); // Needle Projection connect(m_Controls.m_EvalBtnStep2, SIGNAL(clicked()), this, SLOT(SwitchFreeze())); // Freeze connect(m_Controls.m_EvalBtnStep3, SIGNAL(clicked()), this, SLOT(OnAddEvalTargetPoint())); // Tracking & Image Points (Evaluation) connect(m_Controls.m_EvalBtnSave, SIGNAL(clicked()), this, SLOT(OnSaveEvaluation())); // Save Evaluation Results connect(m_Controls.m_CalibBtnSaveCalibration, SIGNAL(clicked()), this, SLOT(OnSaveCalibration())); // Save Evaluation Results connect(m_Controls.m_BtnReset, SIGNAL(clicked()), this, SLOT(OnReset())); // Reset Pointsets // PLUS Calibration connect(m_Controls.m_GetCalibrationFromPLUS, SIGNAL(clicked()), this, SLOT(OnGetPlusCalibration())); connect(m_Controls.m_StartStreaming, SIGNAL(clicked()), this, SLOT(OnStartStreaming())); connect(m_StreamingTimer, SIGNAL(timeout()), this, SLOT(OnStreamingTimerTimeout())); connect(m_Controls.m_StopPlusCalibration, SIGNAL(clicked()), this, SLOT(OnStopPlusCalibration())); connect(m_Controls.m_SavePlusCalibration, SIGNAL(clicked()), this, SLOT(OnSaveCalibration())); connect(this, SIGNAL(NewConnectionSignal()), this, SLOT(OnNewConnection())); //Determine Spacing for Calibration of USVideoDevice connect(m_Controls.m_SpacingBtnFreeze, SIGNAL(clicked()), this, SLOT(OnFreezeClicked())); connect(m_Controls.m_SpacingAddPoint, SIGNAL(clicked()), this, SLOT(OnAddSpacingPoint())); connect(m_Controls.m_CalculateSpacing, SIGNAL(clicked()), this, SLOT(OnCalculateSpacing())); //connect( m_Controls.m_CombinedModalityManagerWidget, SIGNAL(SignalCombinedModalitySelected(mitk::USCombinedModality::Pointer)), // this, SLOT(OnSelectDevice(mitk::USCombinedModality::Pointer)) ); connect(m_Controls.m_CombinedModalityManagerWidget, SIGNAL(SignalReadyForNextStep()), this, SLOT(OnDeviceSelected())); connect(m_Controls.m_CombinedModalityManagerWidget, SIGNAL(SignalNoLongerReadyForNextStep()), this, SLOT(OnDeviceDeselected())); connect(m_Controls.m_StartCalibrationButton, SIGNAL(clicked()), this, SLOT(OnStartCalibrationProcess())); connect(m_Controls.m_StartPlusCalibrationButton, SIGNAL(clicked()), this, SLOT(OnStartPlusCalibration())); connect(m_Controls.m_CalibBtnRestartCalibration, SIGNAL(clicked()), this, SLOT(OnReset())); connect(m_Controls.m_CalibBtnStopCalibration, SIGNAL(clicked()), this, SLOT(OnStopCalibrationProcess())); connect(m_Controls.m_AddReferencePoints, SIGNAL(clicked()), this, SLOT(OnAddCurrentTipPositionToReferencePoints())); connect(m_Controls.m_AddCurrentPointerTipForVerification, SIGNAL(clicked()), this, SLOT(OnAddCurrentTipPositionForVerification())); connect(m_Controls.m_StartVerification, SIGNAL(clicked()), this, SLOT(OnStartVerification())); //initialize data storage combo box m_Controls.m_ReferencePointsComboBox->SetDataStorage(this->GetDataStorage()); m_Controls.m_ReferencePointsComboBox->SetAutoSelectNewItems(true); m_Controls.m_ReferencePointsComboBox->SetPredicate(mitk::NodePredicateDataType::New("PointSet")); //initialize point list widget if (m_VerificationReferencePoints.IsNull()) { m_VerificationReferencePoints = mitk::PointSet::New(); } if (m_VerificationReferencePointsDataNode.IsNull()) { m_VerificationReferencePointsDataNode = mitk::DataNode::New(); m_VerificationReferencePointsDataNode->SetName("US Verification Reference Points"); m_VerificationReferencePointsDataNode->SetData(m_VerificationReferencePoints); this->GetDataStorage()->Add(m_VerificationReferencePointsDataNode); } m_Controls.m_ReferencePointsPointListWidget->SetPointSetNode(m_VerificationReferencePointsDataNode); m_Controls.m_ToolBox->setCurrentIndex(0); } -void UltrasoundCalibration::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*source*/, +void QmitkUltrasoundCalibration::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*source*/, const QList& /*nodes*/) { } -void UltrasoundCalibration::OnTabSwitch(int index) +void QmitkUltrasoundCalibration::OnTabSwitch(int index) { switch (index) { case 0: if (m_Controls.m_ToolBox->isItemEnabled(1) || m_Controls.m_ToolBox->isItemEnabled(2)) { this->OnStopCalibrationProcess(); } break; default: ; } } -//void UltrasoundCalibration::OnSelectDevice(mitk::USCombinedModality::Pointer combinedModality) -void UltrasoundCalibration::OnDeviceSelected() +//void QmitkUltrasoundCalibration::OnSelectDevice(mitk::USCombinedModality::Pointer combinedModality) +void QmitkUltrasoundCalibration::OnDeviceSelected() { mitk::USCombinedModality::Pointer combinedModality; combinedModality = m_Controls.m_CombinedModalityManagerWidget->GetSelectedCombinedModality(); if (combinedModality.IsNotNull()) { //m_Tracker = m_CombinedModality->GetNavigationDataSource(); // Construct Pipeline //this->m_NeedleProjectionFilter->SetInput(0, m_Tracker->GetOutput(0)); combinedModality->GetUltrasoundDevice()->AddPropertyChangedListener(m_USDeviceChanged); m_Controls.m_StartCalibrationButton->setEnabled(true); m_Controls.m_StartPlusCalibrationButton->setEnabled(true); m_Controls.m_ToolBox->setItemEnabled(1, true); m_Controls.m_ToolBox->setItemEnabled(2, true); } } -void UltrasoundCalibration::OnDeviceDeselected() +void QmitkUltrasoundCalibration::OnDeviceDeselected() { mitk::USCombinedModality::Pointer combinedModality; combinedModality = m_Controls.m_CombinedModalityManagerWidget->GetSelectedCombinedModality(); if (combinedModality.IsNotNull()) { combinedModality->GetUltrasoundDevice()->RemovePropertyChangedListener(m_USDeviceChanged); } m_Controls.m_StartCalibrationButton->setEnabled(false); m_Controls.m_StartPlusCalibrationButton->setEnabled(false); m_Controls.m_ToolBox->setCurrentIndex(0); m_Controls.m_ToolBox->setItemEnabled(1, false); m_Controls.m_ToolBox->setItemEnabled(2, false); } -void UltrasoundCalibration::OnAddCurrentTipPositionToReferencePoints() +void QmitkUltrasoundCalibration::OnAddCurrentTipPositionToReferencePoints() { if (m_Controls.m_VerificationPointerChoser->GetSelectedNavigationDataSource().IsNull() || (m_Controls.m_VerificationPointerChoser->GetSelectedToolID() == -1)) { MITK_WARN << "No tool selected, aborting"; return; } mitk::NavigationData::Pointer currentPointerData = m_Controls.m_VerificationPointerChoser->GetSelectedNavigationDataSource()->GetOutput(m_Controls.m_VerificationPointerChoser->GetSelectedToolID()); mitk::Point3D currentTipPosition = currentPointerData->GetPosition(); m_VerificationReferencePoints->InsertPoint(m_VerificationReferencePoints->GetSize(), currentTipPosition); } -void UltrasoundCalibration::OnStartVerification() +void QmitkUltrasoundCalibration::OnStartVerification() { m_currentPoint = 0; mitk::PointSet::Pointer selectedPointSet = dynamic_cast(m_Controls.m_ReferencePointsComboBox->GetSelectedNode()->GetData()); m_Controls.m_CurrentPointLabel->setText("Point " + QString::number(m_currentPoint) + " of " + QString::number(selectedPointSet->GetSize())); m_allErrors = std::vector(); m_allReferencePoints = std::vector(); for (int i = 0; i < selectedPointSet->GetSize(); i++) { m_allReferencePoints.push_back(selectedPointSet->GetPoint(i)); } } -void UltrasoundCalibration::OnAddCurrentTipPositionForVerification() +void QmitkUltrasoundCalibration::OnAddCurrentTipPositionForVerification() { if (m_currentPoint == -1) { MITK_WARN << "Cannot add point"; return; } if (m_Controls.m_VerificationPointerChoser->GetSelectedNavigationDataSource().IsNull() || (m_Controls.m_VerificationPointerChoser->GetSelectedToolID() == -1)) { MITK_WARN << "No tool selected, aborting"; return; } mitk::NavigationData::Pointer currentPointerData = m_Controls.m_VerificationPointerChoser->GetSelectedNavigationDataSource()->GetOutput(m_Controls.m_VerificationPointerChoser->GetSelectedToolID()); mitk::Point3D currentTipPosition = currentPointerData->GetPosition(); double currentError = m_allReferencePoints.at(m_currentPoint).EuclideanDistanceTo(currentTipPosition); MITK_INFO << "Current Error: " << currentError << " mm"; m_allErrors.push_back(currentError); if (++m_currentPoint < static_cast(m_allReferencePoints.size())) { m_Controls.m_CurrentPointLabel->setText("Point " + QString::number(m_currentPoint) + " of " + QString::number(m_allReferencePoints.size())); } else { m_currentPoint = -1; double meanError = 0; for (std::size_t i = 0; i < m_allErrors.size(); ++i) { meanError += m_allErrors[i]; } meanError /= m_allErrors.size(); QString result = "Finished verification! \n Verification of " + QString::number(m_allErrors.size()) + " points, mean error: " + QString::number(meanError) + " mm"; m_Controls.m_ResultsTextEdit->setText(result); MITK_INFO << result.toStdString(); } } -void UltrasoundCalibration::OnStartCalibrationProcess() +void QmitkUltrasoundCalibration::OnStartCalibrationProcess() { // US Image Stream m_Node = mitk::DataNode::New(); m_Node->SetName("US Calibration Viewing Stream"); //create a dummy image (gray values 0..255) for correct initialization of level window, etc. mitk::Image::Pointer dummyImage = mitk::ImageGenerator::GenerateRandomImage(100, 100, 1, 1, 1, 1, 1, 255, 0); m_Node->SetData(dummyImage); this->GetDataStorage()->Add(m_Node); // data node for calibration point set m_CalibNode = mitk::DataNode::New(); m_CalibNode->SetName("Tool Calibration Points"); m_CalibNode->SetData(this->m_CalibPointsImage); this->GetDataStorage()->Add(m_CalibNode); // data node for world point set m_WorldNode = mitk::DataNode::New(); m_WorldNode->SetName("Image Calibration Points"); m_WorldNode->SetData(this->m_CalibPointsTool); this->GetDataStorage()->Add(m_WorldNode); m_CombinedModality = m_Controls.m_CombinedModalityManagerWidget->GetSelectedCombinedModality(); if (m_CombinedModality.IsNull()) { return; } m_Tracker = m_CombinedModality->GetNavigationDataSource(); //QString curDepth = service.getProperty(QString::fromStdString(mitk::USDevice::US_PROPKEY_BMODE_DEPTH)).toString(); // Construct Pipeline this->m_NeedleProjectionFilter->SetInput(0, m_Tracker->GetOutput(0)); QApplication::setOverrideCursor(Qt::WaitCursor); // make sure that the combined modality is in connected state before using it if (m_CombinedModality->GetDeviceState() < mitk::USDevice::State_Connected) { m_CombinedModality->Connect(); } if (m_CombinedModality->GetDeviceState() < mitk::USDevice::State_Activated) { m_CombinedModality->Activate(); } QApplication::restoreOverrideCursor(); this->SwitchFreeze(); // Todo: Maybe display this elsewhere this->ShowNeedlePath(); // Switch active tab to Calibration page m_Controls.m_ToolBox->setItemEnabled(1, true); m_Controls.m_ToolBox->setCurrentIndex(1); } -void UltrasoundCalibration::OnStartPlusCalibration() +void QmitkUltrasoundCalibration::OnStartPlusCalibration() { if (m_CombinedModality.IsNull()){ m_CombinedModality = m_Controls.m_CombinedModalityManagerWidget->GetSelectedCombinedModality(); if (m_CombinedModality.IsNull()) { return; } //something went wrong, there is no combined modality } //setup server to send UltrasoundImages to PLUS mitk::IGTLServer::Pointer m_USServer = mitk::IGTLServer::New(true); m_USServer->SetName("EchoTrack Image Source"); m_USServer->SetHostname("127.0.0.1"); m_USServer->SetPortNumber(18944); m_USMessageProvider = mitk::IGTLMessageProvider::New(); m_USMessageProvider->SetIGTLDevice(m_USServer); m_USMessageProvider->SetFPS(5); m_USImageToIGTLMessageFilter = mitk::ImageToIGTLMessageFilter::New(); m_USImageToIGTLMessageFilter->ConnectTo(m_CombinedModality->GetUltrasoundDevice()); m_USImageToIGTLMessageFilter->SetName("USImage Filter"); //setup server to send TrackingData to PLUS m_TrackingServer = mitk::IGTLServer::New(true); m_TrackingServer->SetName("EchoTrack Tracking Source"); m_TrackingServer->SetHostname("127.0.0.1"); m_TrackingServer->SetPortNumber(18945); m_TrackingMessageProvider = mitk::IGTLMessageProvider::New(); m_TrackingMessageProvider->SetIGTLDevice(m_TrackingServer); m_TrackingMessageProvider->SetFPS(5); m_TrackingToIGTLMessageFilter = mitk::NavigationDataToIGTLMessageFilter::New(); m_TrackingToIGTLMessageFilter->ConnectTo(m_CombinedModality->GetTrackingDevice()); m_TrackingToIGTLMessageFilter->SetName("Tracker Filter"); - typedef itk::SimpleMemberCommand< UltrasoundCalibration > CurCommandType; + typedef itk::SimpleMemberCommand< QmitkUltrasoundCalibration > CurCommandType; CurCommandType::Pointer newConnectionCommand = CurCommandType::New(); newConnectionCommand->SetCallbackFunction( - this, &UltrasoundCalibration::OnPlusConnected); + this, &QmitkUltrasoundCalibration::OnPlusConnected); this->m_NewConnectionObserverTag = this->m_TrackingServer->AddObserver( mitk::NewClientConnectionEvent(), newConnectionCommand); //Open connections of both servers if (m_USServer->OpenConnection()) { MITK_INFO << "US Server opened its connection successfully"; m_USServer->StartCommunication(); } else { MITK_INFO << "US Server could not open its connection"; } if (m_TrackingServer->OpenConnection()) { MITK_INFO << "Tracking Server opened its connection successfully"; m_TrackingServer->StartCommunication(); } else { MITK_INFO << "Tracking Server could not open its connection"; } if (m_USMessageProvider->IsCommunicating() && m_TrackingMessageProvider->IsCommunicating()) { m_Controls.m_StartPlusCalibrationButton->setEnabled(false); m_Controls.m_GetCalibrationFromPLUS->setEnabled(true); m_Controls.m_StartStreaming->setEnabled(false); m_Controls.m_SavePlusCalibration->setEnabled(false); m_Controls.m_SetupStatus->setStyleSheet("QLabel { color : green; }"); m_Controls.m_SetupStatus->setText("Setup successfull you can now connect PLUS"); } else { m_Controls.m_SetupStatus->setStyleSheet("QLabel { color : red; }"); m_Controls.m_SetupStatus->setText("Something went wrong. Please try again"); } } -void UltrasoundCalibration::OnStopPlusCalibration() +void QmitkUltrasoundCalibration::OnStopPlusCalibration() { //closing all server and clients when PlusCalibration is finished if (m_USMessageProvider.IsNotNull()) { if (m_USMessageProvider->IsStreaming()) { m_USMessageProvider->StopStreamingOfSource(m_USImageToIGTLMessageFilter); } } if (m_TrackingMessageProvider.IsNotNull()) { if (m_TrackingMessageProvider->IsStreaming()) { m_TrackingMessageProvider->StopStreamingOfSource(m_TrackingToIGTLMessageFilter); } } if (m_USServer.IsNotNull()) { m_USServer->CloseConnection(); } if (m_TrackingServer.IsNotNull()) { m_TrackingServer->CloseConnection(); } if (m_TransformClient.IsNotNull()) { m_TransformClient->CloseConnection(); } m_Controls.m_GotCalibrationLabel->setText(""); m_Controls.m_ConnectionStatus->setText(""); m_Controls.m_SetupStatus->setText(""); m_Controls.m_StartPlusCalibrationButton->setEnabled(true); m_StreamingTimer->stop(); delete m_StreamingTimer; } -void UltrasoundCalibration::OnPlusConnected() +void QmitkUltrasoundCalibration::OnPlusConnected() { emit NewConnectionSignal(); } -void UltrasoundCalibration::OnNewConnection() +void QmitkUltrasoundCalibration::OnNewConnection() { m_Controls.m_StartStreaming->setEnabled(true); m_Controls.m_ConnectionStatus->setStyleSheet("QLabel { color : green; }"); m_Controls.m_ConnectionStatus->setText("Connection successfull you can now start streaming"); } -void UltrasoundCalibration::OnStreamingTimerTimeout() +void QmitkUltrasoundCalibration::OnStreamingTimerTimeout() { m_USMessageProvider->Update(); m_TrackingMessageProvider->Update(); } -void UltrasoundCalibration::OnStartStreaming() +void QmitkUltrasoundCalibration::OnStartStreaming() { m_USMessageProvider->StartStreamingOfSource(m_USImageToIGTLMessageFilter, 5); m_TrackingMessageProvider->StartStreamingOfSource(m_TrackingToIGTLMessageFilter, 5); m_Controls.m_StartStreaming->setEnabled(false); m_Controls.m_ConnectionStatus->setText(""); m_StreamingTimer->start((1.0 / 5.0 * 1000.0)); } -void UltrasoundCalibration::OnGetPlusCalibration() +void QmitkUltrasoundCalibration::OnGetPlusCalibration() { m_TransformClient = mitk::IGTLClient::New(true); m_TransformClient->SetHostname("127.0.0.1"); m_TransformClient->SetPortNumber(18946); m_TransformDeviceSource = mitk::IGTLDeviceSource::New(); m_TransformDeviceSource->SetIGTLDevice(m_TransformClient); m_TransformDeviceSource->Connect(); if (m_TransformDeviceSource->IsConnected()) { MITK_INFO << "successfully connected"; m_TransformDeviceSource->StartCommunication(); if (m_TransformDeviceSource->IsCommunicating()) { MITK_INFO << "communication started"; mitk::IGTLMessage::Pointer receivedMessage; bool condition = false; igtl::Matrix4x4 transformPLUS; while (!(receivedMessage.IsNotNull() && receivedMessage->IsDataValid())) { std::this_thread::sleep_for(std::chrono::milliseconds(50)); m_TransformDeviceSource->Update(); receivedMessage = m_TransformDeviceSource->GetOutput(); igtl::TransformMessage::Pointer msg = dynamic_cast(m_TransformDeviceSource->GetOutput()->GetMessage().GetPointer()); if (msg == nullptr || msg.IsNull()) { MITK_INFO << "Received message could not be casted to TransformMessage. Skipping.."; continue; } else { if (std::strcmp(msg->GetDeviceName(), "ImageToTracker") != 0) { MITK_INFO << "Was not Image to Tracker Transform. Skipping..."; continue; } else { msg->GetMatrix(transformPLUS); condition = true; break; } } } if (condition) { this->ProcessPlusCalibration(transformPLUS); } else { m_Controls.m_GotCalibrationLabel->setStyleSheet("QLabel { color : red; }"); m_Controls.m_GotCalibrationLabel->setText("Something went wrong. Please try again"); } } else { MITK_INFO << " no connection"; m_Controls.m_GotCalibrationLabel->setStyleSheet("QLabel { color : red; }"); m_Controls.m_GotCalibrationLabel->setText("Something went wrong. Please try again"); } } else { m_Controls.m_GotCalibrationLabel->setStyleSheet("QLabel { color : red; }"); m_Controls.m_GotCalibrationLabel->setText("Something went wrong. Please try again"); } } -void UltrasoundCalibration::ProcessPlusCalibration(igtl::Matrix4x4& imageToTracker) +void QmitkUltrasoundCalibration::ProcessPlusCalibration(igtl::Matrix4x4& imageToTracker) { mitk::AffineTransform3D::Pointer imageToTrackerTransform = mitk::AffineTransform3D::New(); itk::Matrix rotationFloat = itk::Matrix(); itk::Vector translationFloat = itk::Vector(); rotationFloat[0][0] = imageToTracker[0][0]; rotationFloat[0][1] = imageToTracker[0][1]; rotationFloat[0][2] = imageToTracker[0][2]; rotationFloat[1][0] = imageToTracker[1][0]; rotationFloat[1][1] = imageToTracker[1][1]; rotationFloat[1][2] = imageToTracker[1][2]; rotationFloat[2][0] = imageToTracker[2][0]; rotationFloat[2][1] = imageToTracker[2][1]; rotationFloat[2][2] = imageToTracker[2][2]; translationFloat[0] = imageToTracker[0][3]; translationFloat[1] = imageToTracker[1][3]; translationFloat[2] = imageToTracker[2][3]; imageToTrackerTransform->SetTranslation(translationFloat); imageToTrackerTransform->SetMatrix(rotationFloat); m_CombinedModality->SetCalibration(imageToTrackerTransform); m_Controls.m_ToolBox->setItemEnabled(2, true); m_Controls.m_SavePlusCalibration->setEnabled(true); m_Controls.m_GotCalibrationLabel->setStyleSheet("QLabel { color : green; }"); m_Controls.m_GotCalibrationLabel->setText("Recieved Calibration from PLUS you can now save it"); } -void UltrasoundCalibration::OnStopCalibrationProcess() +void QmitkUltrasoundCalibration::OnStopCalibrationProcess() { this->ClearTemporaryMembers(); m_Timer->stop(); this->GetDataStorage()->Remove(m_Node); m_Node = 0; this->GetDataStorage()->Remove(m_CalibNode); m_CalibNode = 0; this->GetDataStorage()->Remove(m_WorldNode); m_WorldNode = 0; m_Controls.m_ToolBox->setCurrentIndex(0); } -void UltrasoundCalibration::OnDeciveServiceEvent(const ctkServiceEvent event) +void QmitkUltrasoundCalibration::OnDeciveServiceEvent(const ctkServiceEvent event) { if (m_CombinedModality.IsNull() || event.getType() != ctkServiceEvent::MODIFIED) { return; } ctkServiceReference service = event.getServiceReference(); QString curDepth = service.getProperty(QString::fromStdString(mitk::USDevice::GetPropertyKeys().US_PROPKEY_BMODE_DEPTH)).toString(); if (m_CurrentDepth != curDepth) { m_CurrentDepth = curDepth; this->OnReset(); } } -void UltrasoundCalibration::OnAddCalibPoint() +void QmitkUltrasoundCalibration::OnAddCalibPoint() { mitk::Point3D world = this->GetRenderWindowPart()->GetSelectedPosition(); this->m_CalibPointsImage->InsertPoint(m_CalibPointsCount, world); this->m_CalibPointsTool->InsertPoint(m_CalibPointsCount, this->m_FreezePoint); QString text = text.number(m_CalibPointsCount + 1); text = "Point " + text; this->m_Controls.m_CalibPointList->addItem(text); m_CalibPointsCount++; SwitchFreeze(); } -void UltrasoundCalibration::OnCalibration() +void QmitkUltrasoundCalibration::OnCalibration() { // Compute transformation vtkSmartPointer transform = vtkSmartPointer::New(); transform->SetSourceLandmarks(this->ConvertPointSetToVtkPolyData(m_CalibPointsImage)->GetPoints()); transform->SetTargetLandmarks(this->ConvertPointSetToVtkPolyData(m_CalibPointsTool)->GetPoints()); if (m_Controls.m_ScaleTransform->isChecked()) { transform->SetModeToSimilarity(); } //use affine transform else { transform->SetModeToRigidBody(); } //use similarity transform: scaling is not touched transform->Modified(); transform->Update(); // Convert from vtk to itk data types itk::Matrix rotationFloat = itk::Matrix(); itk::Vector translationFloat = itk::Vector(); vtkSmartPointer m = transform->GetMatrix(); rotationFloat[0][0] = m->GetElement(0, 0); rotationFloat[0][1] = m->GetElement(0, 1); rotationFloat[0][2] = m->GetElement(0, 2); rotationFloat[1][0] = m->GetElement(1, 0); rotationFloat[1][1] = m->GetElement(1, 1); rotationFloat[1][2] = m->GetElement(1, 2); rotationFloat[2][0] = m->GetElement(2, 0); rotationFloat[2][1] = m->GetElement(2, 1); rotationFloat[2][2] = m->GetElement(2, 2); translationFloat[0] = m->GetElement(0, 3); translationFloat[1] = m->GetElement(1, 3); translationFloat[2] = m->GetElement(2, 3); mitk::DataNode::Pointer CalibPointsImage = mitk::DataNode::New(); CalibPointsImage->SetName("Calibration Points Image"); CalibPointsImage->SetData(m_CalibPointsImage); this->GetDataStorage()->Add(CalibPointsImage); mitk::DataNode::Pointer CalibPointsTracking = mitk::DataNode::New(); CalibPointsTracking->SetName("Calibration Points Tracking"); CalibPointsTracking->SetData(m_CalibPointsTool); this->GetDataStorage()->Add(CalibPointsTracking); mitk::PointSet::Pointer ImagePointsTransformed = m_CalibPointsImage->Clone(); this->ApplyTransformToPointSet(ImagePointsTransformed, transform); mitk::DataNode::Pointer CalibPointsImageTransformed = mitk::DataNode::New(); CalibPointsImageTransformed->SetName("Calibration Points Image (Transformed)"); CalibPointsImageTransformed->SetData(ImagePointsTransformed); this->GetDataStorage()->Add(CalibPointsImageTransformed); // Set output variable mitk::AffineTransform3D::Pointer oldUSImageTransform = m_Image->GetGeometry()->GetIndexToWorldTransform(); //including spacing! MITK_INFO << "Old US Image transform: " << oldUSImageTransform; mitk::AffineTransform3D::Pointer calibTransform = mitk::AffineTransform3D::New(); calibTransform->SetTranslation(translationFloat); calibTransform->SetMatrix(rotationFloat); MITK_INFO << "Calibration transform: " << calibTransform; m_Transformation = mitk::AffineTransform3D::New(); if (!m_Controls.m_ScaleTransform->isChecked()) { m_Transformation->Compose(oldUSImageTransform); } m_Transformation->Compose(calibTransform); MITK_INFO << "New combined transform: " << m_Transformation; mitk::SlicedGeometry3D::Pointer sliced3d = dynamic_cast (m_Node->GetData()->GetGeometry()); mitk::PlaneGeometry::Pointer plane = const_cast (sliced3d->GetPlaneGeometry(0)); plane->SetIndexToWorldTransform(m_Transformation); // Save to US-Device m_CombinedModality->SetCalibration(m_Transformation); m_Controls.m_ToolBox->setItemEnabled(2, true); // Save to NeedleProjectionFilter m_NeedleProjectionFilter->SetTargetPlane(m_Transformation); // Update Calibration FRE m_CalibrationStatistics = mitk::PointSetDifferenceStatisticsCalculator::New(); mitk::PointSet::Pointer p1 = this->m_CalibPointsTool->Clone(); // We use clones to calculate statistics to avoid concurrency Problems // Create point set with transformed image calibration points for // calculating the difference of image calibration and tool // calibration points in one geometry space mitk::PointSet::Pointer p2 = mitk::PointSet::New(); int n = 0; for (mitk::PointSet::PointsConstIterator it = m_CalibPointsImage->Begin(); it != m_CalibPointsImage->End(); ++it, ++n) { p2->InsertPoint(n, m_Transformation->TransformPoint(it->Value())); } m_CalibrationStatistics->SetPointSets(p1, p2); //QString text = text.number(m_CalibrationStatistics->GetRMS()); QString text = QString::number(ComputeFRE(m_CalibPointsImage, m_CalibPointsTool, transform)); MITK_INFO << "Calibration FRE: " << text.toStdString().c_str(); m_Controls.m_EvalLblCalibrationFRE->setText(text); m_Node->SetStringProperty("Calibration FRE", text.toStdString().c_str()); // Enable Button to save Calibration m_Controls.m_CalibBtnSaveCalibration->setEnabled(true); } -void UltrasoundCalibration::OnAddEvalTargetPoint() +void QmitkUltrasoundCalibration::OnAddEvalTargetPoint() { mitk::Point3D world = this->GetRenderWindowPart()->GetSelectedPosition(); this->m_EvalPointsImage->InsertPoint(m_EvalPointsImage->GetSize(), world); this->m_EvalPointsTool->InsertPoint(m_EvalPointsTool->GetSize(), this->m_FreezePoint); QString text = text.number(this->m_EvalPointsTool->GetSize()); this->m_Controls.m_EvalLblNumTargetPoints->setText(text); // Update FREs // Update Evaluation FRE, but only if it contains more than one point (will crash otherwise) if ((m_EvalPointsProjected->GetSize() > 1) && (m_EvalPointsTool->GetSize() > 1)) { m_EvaluationStatistics = mitk::PointSetDifferenceStatisticsCalculator::New(); m_ProjectionStatistics = mitk::PointSetDifferenceStatisticsCalculator::New(); mitk::PointSet::Pointer p1 = this->m_EvalPointsTool->Clone(); // We use clones to calculate statistics to avoid concurrency Problems mitk::PointSet::Pointer p2 = this->m_EvalPointsImage->Clone(); mitk::PointSet::Pointer p3 = this->m_EvalPointsProjected->Clone(); m_EvaluationStatistics->SetPointSets(p1, p2); m_ProjectionStatistics->SetPointSets(p1, p3); QString evalText = evalText.number(m_EvaluationStatistics->GetRMS()); QString projText = projText.number(m_ProjectionStatistics->GetRMS()); m_Controls.m_EvalLblEvaluationFRE->setText(evalText); m_Controls.m_EvalLblProjectionFRE->setText(projText); } SwitchFreeze(); } -void UltrasoundCalibration::OnAddEvalProjectedPoint() +void QmitkUltrasoundCalibration::OnAddEvalProjectedPoint() { MITK_WARN << "Projection Evaluation may currently be inaccurate."; // TODO: Verify correct Evaluation. Is the Point that is added really current? mitk::Point3D projection = this->m_NeedleProjectionFilter->GetProjection()->GetPoint(1); m_EvalPointsProjected->InsertPoint(m_EvalPointsProjected->GetSize(), projection); QString text = text.number(this->m_EvalPointsProjected->GetSize()); this->m_Controls.m_EvalLblNumProjectionPoints->setText(text); } -void UltrasoundCalibration::OnSaveEvaluation() +void QmitkUltrasoundCalibration::OnSaveEvaluation() { //Filename without suffix QString filename = m_Controls.m_EvalFilePath->text() + "//" + m_Controls.m_EvalFilePrefix->text(); MITK_WARN << "CANNOT SAVE, ABORTING!"; /* not working any more TODO! mitk::PointSetWriter::Pointer psWriter = mitk::PointSetWriter::New(); psWriter->SetInput(0, m_CalibPointsImage); psWriter->SetInput(1, m_CalibPointsTool); psWriter->SetInput(2, m_EvalPointsImage); psWriter->SetInput(3, m_EvalPointsTool); psWriter->SetInput(4, m_EvalPointsProjected); psWriter->SetFileName(filename.toStdString() + ".xml"); psWriter->Write(); */ // TODO: New writer for transformations must be implemented. /* mitk::TransformationFileWriter::Pointer tWriter = mitk::TransformationFileWriter::New(); tWriter->SetInput(0, m_CalibPointsImage); tWriter->SetInput(1, m_CalibPointsTool); tWriter->SetInput(2, m_EvalPointsImage); tWriter->SetInput(3, m_EvalPointsTool); tWriter->SetInput(4, m_EvalPointsProjected); tWriter->SetOutputFilename(filename.toStdString() + ".txt"); tWriter->DoWrite(this->m_Transformation); */ } -void UltrasoundCalibration::OnSaveCalibration() +void QmitkUltrasoundCalibration::OnSaveCalibration() { m_Controls.m_GotCalibrationLabel->setText(""); QString filename = QFileDialog::getSaveFileName(QApplication::activeWindow(), "Save Calibration", "", "Calibration files *.cal"); QFile file(filename); if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) { MITK_WARN << "Cannot open file '" << filename.toStdString() << "' for writing."; return; } std::string calibrationSerialization = m_CombinedModality->SerializeCalibration(); QTextStream outStream(&file); outStream << QString::fromStdString(calibrationSerialization); //save additional information if (m_Controls.m_saveAdditionalCalibrationLog->isChecked()) { mitk::SceneIO::Pointer mySceneIO = mitk::SceneIO::New(); QString filenameScene = filename + "_mitkScene.mitk"; mitk::NodePredicateNot::Pointer isNotHelperObject = mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object", mitk::BoolProperty::New(true))); mitk::DataStorage::SetOfObjects::ConstPointer nodesToBeSaved = this->GetDataStorage()->GetSubset(isNotHelperObject); mySceneIO->SaveScene(nodesToBeSaved, this->GetDataStorage(), filenameScene.toStdString().c_str()); } } -void UltrasoundCalibration::OnReset() +void QmitkUltrasoundCalibration::OnReset() { this->ClearTemporaryMembers(); if (m_Transformation.IsNull()) { m_Transformation = mitk::AffineTransform3D::New(); } m_Transformation->SetIdentity(); if (m_Node.IsNotNull() && (m_Node->GetData() != nullptr) && (m_Node->GetData()->GetGeometry() != nullptr)) { mitk::SlicedGeometry3D::Pointer sliced3d = dynamic_cast (m_Node->GetData()->GetGeometry()); mitk::PlaneGeometry::Pointer plane = const_cast (sliced3d->GetPlaneGeometry(0)); plane->SetIndexToWorldTransform(m_Transformation); } QString text1 = text1.number(this->m_EvalPointsTool->GetSize()); this->m_Controls.m_EvalLblNumTargetPoints->setText(text1); QString text2 = text2.number(this->m_EvalPointsProjected->GetSize()); this->m_Controls.m_EvalLblNumProjectionPoints->setText(text2); } -void UltrasoundCalibration::Update() +void QmitkUltrasoundCalibration::Update() { //QList nodes = this->GetDataManagerSelection(); // if (nodes.empty()) return; // Update Tracking Data std::vector* datas = new std::vector(); datas->push_back(m_Tracker->GetOutput()); m_Controls.m_CalibTrackingStatus->SetNavigationDatas(datas); m_Controls.m_CalibTrackingStatus->Refresh(); m_Controls.m_EvalTrackingStatus->SetNavigationDatas(datas); m_Controls.m_EvalTrackingStatus->Refresh(); // Update US Image m_CombinedModality->Modified(); m_CombinedModality->Update(); mitk::Image::Pointer m_Image = m_CombinedModality->GetOutput(); if (m_Image.IsNotNull() && m_Image->IsInitialized()) { if (m_OverrideSpacing) { m_Image->GetGeometry()->SetSpacing(m_Spacing); } if (m_Image.IsNotNull() && m_Image->IsInitialized()) { m_Node->SetData(m_Image); } } // Update Needle Projection m_NeedleProjectionFilter->Update(); //only update 2d window because it is faster //this->RequestRenderWindowUpdate(mitk::RenderingManager::REQUEST_UPDATE_2DWINDOWS); } -void UltrasoundCalibration::SwitchFreeze() +void QmitkUltrasoundCalibration::SwitchFreeze() { m_Controls.m_CalibBtnAddPoint->setEnabled(false); // generally deactivate // We use the activity state of the timer to determine whether we are currently viewing images if (!m_Timer->isActive()) // Activate Imaging { // if (m_Node) m_Node->ReleaseData(); if (m_CombinedModality.IsNull()){ m_Timer->stop(); return; } m_CombinedModality->Update(); m_Image = m_CombinedModality->GetOutput(); if (m_Image.IsNotNull() && m_Image->IsInitialized()) { m_Node->SetData(m_Image); } std::vector datas; datas.push_back(m_Tracker->GetOutput()); m_Controls.m_CalibTrackingStatus->SetNavigationDatas(&datas); m_Controls.m_CalibTrackingStatus->ShowStatusLabels(); m_Controls.m_CalibTrackingStatus->Refresh(); m_Controls.m_EvalTrackingStatus->SetNavigationDatas(&datas); m_Controls.m_EvalTrackingStatus->ShowStatusLabels(); m_Controls.m_EvalTrackingStatus->Refresh(); int interval = 40; m_Timer->setInterval(interval); m_Timer->start(); m_CombinedModality->SetIsFreezed(false); } else if (this->m_Tracker->GetOutput(0)->IsDataValid()) { //deactivate Imaging m_Timer->stop(); // Remember last tracking coordinates m_FreezePoint = this->m_Tracker->GetOutput(0)->GetPosition(); m_Controls.m_CalibBtnAddPoint->setEnabled(true); // activate only, if valid point is set m_CombinedModality->SetIsFreezed(true); } } -void UltrasoundCalibration::ShowNeedlePath() +void QmitkUltrasoundCalibration::ShowNeedlePath() { // Init Filter this->m_NeedleProjectionFilter->SelectInput(0); // Create Node for Pointset mitk::DataNode::Pointer node = this->GetDataStorage()->GetNamedNode("Needle Path"); if (node.IsNull()) { node = mitk::DataNode::New(); node->SetName("Needle Path"); node->SetData(m_NeedleProjectionFilter->GetProjection()); node->SetBoolProperty("show contour", true); this->GetDataStorage()->Add(node); } } -void UltrasoundCalibration::ClearTemporaryMembers() +void QmitkUltrasoundCalibration::ClearTemporaryMembers() { m_CalibPointsTool->Clear(); m_CalibPointsImage->Clear(); m_CalibPointsCount = 0; m_EvalPointsImage->Clear(); m_EvalPointsTool->Clear(); m_EvalPointsProjected->Clear(); this->m_Controls.m_CalibPointList->clear(); m_SpacingPoints->Clear(); m_Controls.m_SpacingPointsList->clear(); m_SpacingPointsCount = 0; } -vtkSmartPointer UltrasoundCalibration::ConvertPointSetToVtkPolyData(mitk::PointSet::Pointer PointSet) +vtkSmartPointer QmitkUltrasoundCalibration::ConvertPointSetToVtkPolyData(mitk::PointSet::Pointer PointSet) { vtkSmartPointer returnValue = vtkSmartPointer::New(); vtkSmartPointer points = vtkSmartPointer::New(); for (int i = 0; i < PointSet->GetSize(); i++) { double point[3] = { PointSet->GetPoint(i)[0], PointSet->GetPoint(i)[1], PointSet->GetPoint(i)[2] }; points->InsertNextPoint(point); } vtkSmartPointer temp = vtkSmartPointer::New(); temp->SetPoints(points); vtkSmartPointer vertexFilter = vtkSmartPointer::New(); vertexFilter->SetInputData(temp); vertexFilter->Update(); returnValue->ShallowCopy(vertexFilter->GetOutput()); return returnValue; } -double UltrasoundCalibration::ComputeFRE(mitk::PointSet::Pointer imageFiducials, mitk::PointSet::Pointer realWorldFiducials, vtkSmartPointer transform) +double QmitkUltrasoundCalibration::ComputeFRE(mitk::PointSet::Pointer imageFiducials, mitk::PointSet::Pointer realWorldFiducials, vtkSmartPointer transform) { if (imageFiducials->GetSize() != realWorldFiducials->GetSize()) return -1; double FRE = 0; for (int i = 0; i < imageFiducials->GetSize(); ++i) { itk::Point current_image_fiducial_point = imageFiducials->GetPoint(i); if (transform != nullptr) { current_image_fiducial_point = transform->TransformPoint(imageFiducials->GetPoint(i)[0], imageFiducials->GetPoint(i)[1], imageFiducials->GetPoint(i)[2]); } double cur_error_squared = current_image_fiducial_point.SquaredEuclideanDistanceTo(realWorldFiducials->GetPoint(i)); FRE += cur_error_squared; } FRE = sqrt(FRE / (double)imageFiducials->GetSize()); return FRE; } -void UltrasoundCalibration::ApplyTransformToPointSet(mitk::PointSet::Pointer pointSet, vtkSmartPointer transform) +void QmitkUltrasoundCalibration::ApplyTransformToPointSet(mitk::PointSet::Pointer pointSet, vtkSmartPointer transform) { for (int i = 0; i < pointSet->GetSize(); ++i) { itk::Point current_point_transformed = itk::Point(); current_point_transformed = transform->TransformPoint(pointSet->GetPoint(i)[0], pointSet->GetPoint(i)[1], pointSet->GetPoint(i)[2]); pointSet->SetPoint(i, current_point_transformed); } } -void UltrasoundCalibration::OnFreezeClicked() +void QmitkUltrasoundCalibration::OnFreezeClicked() { if (m_CombinedModality->GetIsFreezed()) { //device was already frozen so we need to delete all Spacing points because they need to be collected all at once // no need to check if all four points are already collected, because if thats the case you can no longer click the Freeze Button m_SpacingPoints->Clear(); m_Controls.m_SpacingPointsList->clear(); m_SpacingPointsCount = 0; m_Controls.m_SpacingAddPoint->setEnabled(false); m_CombinedModality->SetIsFreezed(false); } else { m_CombinedModality->SetIsFreezed(true); m_Controls.m_SpacingAddPoint->setEnabled(true); } //SwitchFreeze(); } -void UltrasoundCalibration::OnAddSpacingPoint() +void QmitkUltrasoundCalibration::OnAddSpacingPoint() { mitk::Point3D point = this->GetRenderWindowPart()->GetSelectedPosition(); this->m_SpacingPoints->InsertPoint(m_SpacingPointsCount, point); QString text = text.number(m_SpacingPointsCount + 1); text = "Point " + text; this->m_Controls.m_SpacingPointsList->addItem(text); m_SpacingPointsCount++; if (m_SpacingPointsCount == 4) //now we have all 4 points needed { m_Controls.m_SpacingAddPoint->setEnabled(false); m_Controls.m_CalculateSpacing->setEnabled(true); m_Controls.m_SpacingBtnFreeze->setEnabled(false); } } -void UltrasoundCalibration::OnCalculateSpacing() +void QmitkUltrasoundCalibration::OnCalculateSpacing() { mitk::Point3D horizontalOne = m_SpacingPoints->GetPoint(0); mitk::Point3D horizontalTwo = m_SpacingPoints->GetPoint(1); mitk::Point3D verticalOne = m_SpacingPoints->GetPoint(2); mitk::Point3D verticalTwo = m_SpacingPoints->GetPoint(3); //Get the distances between the points in the image double xDistance = horizontalOne.EuclideanDistanceTo(horizontalTwo); double yDistance = verticalOne.EuclideanDistanceTo(verticalTwo); //Calculate the spacing of the image and fill a vector with it double xSpacing = 30 / xDistance; double ySpacing = 20 / yDistance; m_Spacing[0] = xSpacing; m_Spacing[1] = ySpacing; m_Spacing[2] = 1; MITK_INFO << m_Spacing; //Make sure the new spacing is applied to the USVideoDeviceImages m_OverrideSpacing = true; //Now that the spacing is set clear all stuff and return to Calibration m_SpacingPoints->Clear(); m_Controls.m_SpacingPointsList->clear(); m_SpacingPointsCount = 0; m_CombinedModality->SetIsFreezed(false); } -void UltrasoundCalibration::OnUSDepthChanged(const std::string& key, const std::string&) +void QmitkUltrasoundCalibration::OnUSDepthChanged(const std::string& key, const std::string&) { //whenever depth of USImage is changed the spacing should no longer be overwritten if (key == mitk::USDevice::GetPropertyKeys().US_PROPKEY_BMODE_DEPTH) { m_OverrideSpacing = false; } } diff --git a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/UltrasoundCalibration.h b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/QmitkUltrasoundCalibration.h similarity index 95% rename from Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/UltrasoundCalibration.h rename to Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/QmitkUltrasoundCalibration.h index a387ad3686..7efae7c8ab 100644 --- a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/UltrasoundCalibration.h +++ b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/QmitkUltrasoundCalibration.h @@ -1,348 +1,348 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ -#ifndef UltrasoundCalibration_h -#define UltrasoundCalibration_h +#ifndef QmitkUltrasoundCalibration_h +#define QmitkUltrasoundCalibration_h #include #include //QT //#include //MITK #include #include #include #include #include #include // Microservices -#include "ui_UltrasoundCalibrationControls.h" +#include "ui_QmitkUltrasoundCalibrationControls.h" #include #include #include #include /*! - \brief UltrasoundCalibration + \brief QmitkUltrasoundCalibration \warning This view provides a simple calibration process. \sa QmitkFunctionality \ingroup ${plugin_target}_internal */ -class UltrasoundCalibration : public QmitkAbstractView +class QmitkUltrasoundCalibration : public QmitkAbstractView { // this is needed for all Qt objects that should have a Qt meta-object // (everything that derives from QObject and wants to have signal/slots) Q_OBJECT public: - UltrasoundCalibration(); - ~UltrasoundCalibration(); + QmitkUltrasoundCalibration(); + ~QmitkUltrasoundCalibration(); static const std::string VIEW_ID; virtual void CreateQtPartControl(QWidget *parent); void OnUSDepthChanged(const std::string&, const std::string&); protected slots: /** * \brief Triggered, whenever the user switches Tabs * */ void OnTabSwitch(int index); /** * \brief Triggered, when the user has clicked "select Devices". * */ //void OnSelectDevice(mitk::USCombinedModality::Pointer); void OnDeviceSelected(); void OnDeviceDeselected(); /** * \brief Triggered, when the user clicks "Add Point" * */ void OnAddCalibPoint(); /** * \brief Triggered, when the user clicks "Calibrate" * */ void OnCalibration(); /** * \brief Triggered, when the user clicks "Add Target Points". * * Adds an image point and an tracking point to their respective evaluation pointsets */ void OnAddEvalTargetPoint(); /** * \brief Triggered, when the user clicks "Add Point". * * Adds a projected point to the projected point evaluation set. */ void OnAddEvalProjectedPoint(); /** * \brief Triggered when the user clicks "Save Results" in the Evaluation tab. */ void OnSaveEvaluation(); /** * \brief Triggered when the user clicks "Save Calibration" in the Calibration tab. */ void OnSaveCalibration(); /** * \brief Triggered when the user clicks "Run Next Round". Also used as a reset mechanism. */ void OnReset(); /** * \brief Triggered in regular intervals by a timer, when live view is enabled. * */ void Update(); /** * \brief Freezes or unfreezes the image. */ void SwitchFreeze(); /** * */ void OnStartCalibrationProcess(); /** *\brief Method to use the PLUS-Toolkoit for Calibration of EchoTrack */ void OnStartPlusCalibration(); void OnStopPlusCalibration(); /** *\ brief Starts the Streaming of USImage and Navigation Data when PLUS is connected */ void OnStartStreaming(); void OnNewConnection(); /** \*brief Get the Calibration from the PLUS-Toolkit once Calibration with fCal is done */ void OnGetPlusCalibration(); /** \*brief Convert the recieved igtl::Matrix into an mitk::AffineTransform3D which can be used to calibrate the CombinedModality */ void ProcessPlusCalibration(igtl::Matrix4x4& imageToTracker); void OnStreamingTimerTimeout(); /** * */ void OnStopCalibrationProcess(); void OnAddCurrentTipPositionToReferencePoints(); void OnStartVerification(); void OnAddCurrentTipPositionForVerification(); void OnDeciveServiceEvent(const ctkServiceEvent event); void OnFreezeClicked(); void OnAddSpacingPoint(); void OnCalculateSpacing(); signals: /** * \brief used for thread seperation, the worker thread must not call OnNewConnection directly. * QT signals are thread safe and separate the threads */ void NewConnectionSignal(); protected: virtual void SetFocus(); /// \brief called by QmitkFunctionality when DataManager's selection has changed virtual void OnSelectionChanged(berry::IWorkbenchPart::Pointer source, const QList& nodes); - Ui::UltrasoundCalibrationControls m_Controls; + Ui::QmitkUltrasoundCalibrationControls m_Controls; /** * \brief Internal function that activates display of the needle path. */ void ShowNeedlePath(); /** * \brief Clears all member attributes which are holding intermediate results for the calibration. */ void ClearTemporaryMembers(); void OnPlusConnected(); /** * \brief The combined modality used for imaging and tracking. */ mitk::USCombinedModality::Pointer m_CombinedModality; /** * \brief NavigationDataSource used for tracking data. * This will be gotten by the combined modality. */ mitk::NavigationDataSource::Pointer m_Tracker; QTimer *m_Timer; mitk::DataNode::Pointer m_Node; mitk::DataNode::Pointer m_CalibNode; mitk::DataNode::Pointer m_WorldNode; //IGTL Servers and Devices needed for the communication with PLUS mitk::IGTLServer::Pointer m_USServer; mitk::IGTLMessageProvider::Pointer m_USMessageProvider; mitk::ImageToIGTLMessageFilter::Pointer m_USImageToIGTLMessageFilter; mitk::IGTLServer::Pointer m_TrackingServer; mitk::IGTLMessageProvider::Pointer m_TrackingMessageProvider; mitk::NavigationDataToIGTLMessageFilter::Pointer m_TrackingToIGTLMessageFilter; mitk::IGTLClient::Pointer m_TransformClient; mitk::IGTLDeviceSource::Pointer m_TransformDeviceSource; QTimer *m_StreamingTimer; unsigned long m_NewConnectionObserverTag; // Variables to determine if spacing was calibrated and needs to be applied to the incoming images mitk::Vector3D m_Spacing; bool m_OverrideSpacing; /** * \brief The current Ultrasound Image. */ mitk::Image::Pointer m_Image; /** * \brief Current point when the image was last frozen. */ mitk::Point3D m_FreezePoint; /** * \brief Pointset containing all tool points. */ mitk::PointSet::Pointer m_CalibPointsImage; /** * \brief Pointset containing corresponding points on the image. */ mitk::PointSet::Pointer m_CalibPointsTool; /** * \brief Pointset containing Projected Points (aka "where we thought the needle was gonna land") */ mitk::PointSet::Pointer m_EvalPointsProjected; /** * \brief Pointset containing the evaluated points on the image. */ mitk::PointSet::Pointer m_EvalPointsImage; /** * \brief Pointset containing tracked evaluation points. */ mitk::PointSet::Pointer m_EvalPointsTool; /** * \brief Pointset containing tracked evaluation points. */ mitk::PointSet::Pointer m_VerificationReferencePoints; mitk::DataNode::Pointer m_VerificationReferencePointsDataNode; int m_currentPoint; std::vector m_allReferencePoints; std::vector m_allErrors; /** * \brief Pointset containing points along the needle's prohected path. Only used for visualization. The first point is the needle tip. */ //mitk::PointSet::Pointer m_NeedlePathPoints; /** * \brief Creates a Pointset that projects the needle's path */ mitk::NeedleProjectionFilter::Pointer m_NeedleProjectionFilter; /** * \brief Total number of calibration points set. */ int m_CalibPointsCount; QString m_CurrentDepth; /** * \brief StatisticsRegarding Projection Accuracy. * (Compares m_EvalPointsProjected to m_EvalPointsImage) */ mitk::PointSetDifferenceStatisticsCalculator::Pointer m_ProjectionStatistics; /** * \brief StatisticsRegarding Evaluation Accuracy. * (Compares m_EvalPointsTool to m_EvalPointsImage) */ mitk::PointSetDifferenceStatisticsCalculator::Pointer m_EvaluationStatistics; /** * \brief StatisticsRegarding Calibration Accuracy. * (Compares m_CalibPointsTool to a transformed copy of m_CalibPointsImage). */ mitk::PointSetDifferenceStatisticsCalculator::Pointer m_CalibrationStatistics; /** * \brief Result of the Calibration. */ mitk::AffineTransform3D::Pointer m_Transformation; /** * This method is copied from PointSetModifier which is part of MBI. It should be replaced * by external method call as soon as this functionality will be available in MITK. */ vtkSmartPointer ConvertPointSetToVtkPolyData(mitk::PointSet::Pointer PointSet); double ComputeFRE(mitk::PointSet::Pointer imageFiducials, mitk::PointSet::Pointer realWorldFiducials, vtkSmartPointer transform = nullptr); void ApplyTransformToPointSet(mitk::PointSet::Pointer pointSet, vtkSmartPointer transform); mitk::PointSet::Pointer m_SpacingPoints; mitk::DataNode::Pointer m_SpacingNode; int m_SpacingPointsCount; private: - mitk::MessageDelegate2 m_USDeviceChanged; + mitk::MessageDelegate2 m_USDeviceChanged; }; #endif // UltrasoundCalibration_h diff --git a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/UltrasoundCalibrationControls.ui b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/QmitkUltrasoundCalibrationControls.ui similarity index 99% rename from Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/UltrasoundCalibrationControls.ui rename to Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/QmitkUltrasoundCalibrationControls.ui index 59289dd670..1b4e4a3d7e 100644 --- a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/UltrasoundCalibrationControls.ui +++ b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/QmitkUltrasoundCalibrationControls.ui @@ -1,1163 +1,1163 @@ - UltrasoundCalibrationControls + QmitkUltrasoundCalibrationControls true 0 0 374 923 0 0 QmitkTemplate 0 0 1 0 0 200 57 Config false Start Calibration for Selected Device 0 0 356 824 Spatial Calibration 0 10 351 831 1 Spacing 10 150 281 41 Add Point Qt::Horizontal QSizePolicy::Expanding 40 20 false Freeze 10 10 281 131 <html><head/><body><p>1. Freeze the US-Image.</p><p>2. Mark two points in the US-Image of which you know <br/>they are exactly 30mm apart in horizontal direction.</p><p>3. Marktwo more points in the US-Image of which you <br/>know they are exactly 20mm apart vertical direction.</p><p>4. Now you can click the &quot;Calculate Spacing&quot;-Button. <br/>The spacing is calculated and applied to the US-Image.</p></body></html> Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop 10 200 281 192 20 400 261 23 Calculate Spacing Point Based 10 10 221 16 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600; text-decoration: underline;">Step 1: Collect Points</span></p></body></html> 10 30 261 91 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Slowly move a tracking tool into the image plane of the ultrasound. As soon as it becomes visible, click &quot;freeze&quot; and mark the point on the screen by moving the Crosshair to the pont in the US image (best: click in 2D Axial view).</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Do this with as many points as necessary, then click calibrate to perform calibration.</p></body></html> true 10 120 291 31 75 true <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Tracking Status:</span></p></body></html> false 10 620 301 23 Save Calibration 10 550 291 16 Qt::Horizontal 10 200 301 225 10 450 571 16 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600; text-decoration: underline;">Step 2: Calibrate (perform landmark transformation)</span></p></body></html> 10 160 301 25 Freeze Qt::Horizontal 40 20 false Add Point 10 430 301 21 Qt::Horizontal 10 510 301 23 Calibrate 10 590 584 17 Save additional logging information (MITK scene, etc.) true 10 480 584 17 Activate Scaling during Calibration Transform 10 570 291 16 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600; text-decoration: underline;">Step 3: Save calibration to hard disc</span></p></body></html> 10 680 301 23 Stop Calibration Process 10 710 301 23 Restart Current Calibration 100 120 211 31 0 40 10 650 301 20 Qt::Horizontal PLUS Connection 10 10 301 241 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600; text-decoration: underline;">Step 1: Calibrate using fCal</span></p></body></html> Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">1. Setup the Connection to PLUS</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">2. Start fCal with the EchoTrackCalibration Config file</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">3. Connect fcal to MITK, once it connected successfully you can click the &quot;Start Streaming&quot; Button below</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">4. Now follow the steps in fCal and don't forget to save the Calibration in the end</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">5. Finish fCal</p></body></html> true <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600; text-decoration: underline;">Step 2: Get the calibration back from PLUS</span></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">1. Start a PLUS Server with the configfile you saved in the final step of fCal</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">2. Once the Server connected to MITK click the &quot;Start Streaming&quot; Button below</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">3. Now Click the &quot;Get Calibration from PLUS&quot;Button below</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">4. You can now save the calibration</p></body></html> true 10 270 301 281 false 0 90 299 23 Start Streaming false 0 140 299 23 Get Calibration from PLUS false 0 180 299 23 Save PLUS Calibration 0 220 299 23 Stop Calibration with PLUS false 0 60 291 21 0 120 281 16 false 0 30 301 23 Setup PLUS Connection false 0 10 291 21 0 0 100 30 Evaluation 0 0 311 821 1 Point Based Evaluation 10 130 301 16 Mark the visible needle tip with the crosshair 10 10 301 31 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Bring the needle into the tracking volume, so the projection can be calculated</span></p></body></html> true 10 70 291 31 Push the needle forward until it becomes visible in the Image true 10 150 291 23 Step 3: Add Target Points 10 100 291 23 Step 2: Freeze Image 10 440 291 108 When done, save results Run Next Round Prefix: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Save Results Path: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 10 180 291 247 Control QFormLayout::AllNonFixedFieldsGrow Tracking Status: # Projection Points: # Target Points: 0 Evaluation TRE: 0 Projection TRE: 0 Calibration FRE: 0 0 10 50 291 23 Step 1: Save Needle Projection Reference Device 10 10 281 16 Choose pointer: 10 30 281 50 0 50 10 90 281 366 1 0 0 179 82 Create Reference Current reference points: Add Current Pointer Tip Position Qt::Vertical 20 111 0 0 281 312 Quick Verification Start Verification Current Point: Qt::Horizontal 40 20 <none> Add current pointer tip Result: QmitkToolTrackingStatusWidget QWidget
QmitkToolTrackingStatusWidget.h
1
QmitkUSNavigationStepCombinedModality QWidget
src/internal/NavigationStepWidgets/QmitkUSNavigationStepCombinedModality.h
1
QmitkPointListWidget QWidget
QmitkPointListWidget.h
1
QmitkDataStorageComboBox QComboBox
QmitkDataStorageComboBox.h
QmitkNavigationDataSourceSelectionWidget QWidget
QmitkNavigationDataSourceSelectionWidget.h
1
OnStartCalibrationProcess() OnReset() OnStopCalibrationProcess()
diff --git a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/USNavigationMarkerPlacement.ui b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/USNavigationMarkerPlacement.ui index a181fe0767..4d3ceb49c3 100644 --- a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/USNavigationMarkerPlacement.ui +++ b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/USNavigationMarkerPlacement.ui @@ -1,123 +1,123 @@ - USNavigationMarkerPlacement + QmitkUSNavigationMarkerPlacement 0 0 400 146 Form 0 0 0 0 0 Qt::Horizontal Enable Navigation Render Window Layout with RenderWindow true 1 3 Refresh view Start New Experiment false Finish Experiment 20 20 QmitkUSNavigationProcessWidget QWidget
src/internal/Widgets/QmitkUSNavigationProcessWidget.h
1
OnStartExperiment() OnFinishExperiment()
diff --git a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/org_mbi_gui_qt_usnavigation_Activator.cpp b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/org_mbi_gui_qt_usnavigation_Activator.cpp index fb1eaf8361..d02b7fb363 100644 --- a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/org_mbi_gui_qt_usnavigation_Activator.cpp +++ b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/org_mbi_gui_qt_usnavigation_Activator.cpp @@ -1,67 +1,67 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "org_mbi_gui_qt_usnavigation_Activator.h" #include #include //#include "USNavigation.h" -#include "UltrasoundCalibration.h" -#include "USNavigationMarkerPlacement.h" +#include "QmitkUltrasoundCalibration.h" +#include "QmitkUSNavigationMarkerPlacement.h" #include "QmitkUSNavigationPerspective.h" #include "mitkVirtualTrackingDevice.h" namespace mitk { ctkPluginContext* org_mbi_gui_qt_usnavigation_Activator::m_Context = 0; void org_mbi_gui_qt_usnavigation_Activator::start(ctkPluginContext* context) { m_Context = context; //BERRY_REGISTER_EXTENSION_CLASS(USNavigation, context) - BERRY_REGISTER_EXTENSION_CLASS(UltrasoundCalibration, context) - BERRY_REGISTER_EXTENSION_CLASS(USNavigationMarkerPlacement, context) + BERRY_REGISTER_EXTENSION_CLASS(QmitkUltrasoundCalibration, context) + BERRY_REGISTER_EXTENSION_CLASS(QmitkUSNavigationMarkerPlacement, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkUSNavigationPerspective, context) // create a combined modality persistence object for loading and storing // combined modality objects persistently m_USCombinedModalityPersistence = mitk::USNavigationCombinedModalityPersistence::New(); } void org_mbi_gui_qt_usnavigation_Activator::stop(ctkPluginContext* context) { m_USCombinedModalityPersistence = 0; m_Context = 0; Q_UNUSED(context) } ctkPluginContext *org_mbi_gui_qt_usnavigation_Activator::GetContext() { return m_Context; } } #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) Q_EXPORT_PLUGIN2(org_mitk_gui_qt_igt_app_echotrack, mitk::org_mbi_gui_qt_usnavigation_Activator) #endif // necessary for us::GetModuleContext() in USNavigationCombinedModalityPersistence // (see: https://www.mail-archive.com/mitk-users@lists.sourceforge.net/msg04421.html) US_INITIALIZE_MODULE diff --git a/Plugins/org.mitk.gui.qt.igttracking/files.cmake b/Plugins/org.mitk.gui.qt.igttracking/files.cmake index cbb54f9284..1c2e872a66 100644 --- a/Plugins/org.mitk.gui.qt.igttracking/files.cmake +++ b/Plugins/org.mitk.gui.qt.igttracking/files.cmake @@ -1,59 +1,59 @@ set(SRC_CPP_FILES internal/QmitkMITKIGTTrackingToolboxViewWorker.cpp ) set(INTERNAL_CPP_FILES mitkPluginActivator.cpp QmitkMITKIGTNavigationToolManagerView.cpp QmitkMITKIGTTrackingToolboxView.cpp QmitkNavigationDataPlayerView.cpp - IGTFiducialRegistration.cpp - IGTNavigationToolCalibration.cpp + QmitkIGTFiducialRegistration.cpp + QmitkIGTNavigationToolCalibration.cpp ) set(UI_FILES src/internal/QmitkMITKIGTNavigationToolManagerViewControls.ui src/internal/QmitkMITKIGTTrackingToolboxViewControls.ui src/internal/QmitkNavigationDataPlayerViewControls.ui - src/internal/IGTNavigationToolCalibrationControls.ui - src/internal/IGTFiducialRegistrationControls.ui + src/internal/QmitkIGTNavigationToolCalibrationControls.ui + src/internal/QmitkIGTFiducialRegistrationControls.ui ) set(MOC_H_FILES src/internal/mitkPluginActivator.h src/internal/QmitkMITKIGTNavigationToolManagerView.h src/internal/QmitkMITKIGTTrackingToolboxView.h src/internal/QmitkMITKIGTTrackingToolboxViewWorker.h src/internal/QmitkNavigationDataPlayerView.h - src/internal/IGTNavigationToolCalibration.h - src/internal/IGTFiducialRegistration.h + src/internal/QmitkIGTNavigationToolCalibration.h + src/internal/QmitkIGTFiducialRegistration.h ) # list of resource files which can be used by the plug-in # system without loading the plug-ins shared library, # for example the icon used in the menu and tabs for the # plug-in views in the workbench set(CACHED_RESOURCE_FILES resources/iconTrackingDataPlayer.svg resources/iconTrackingRegistration.svg resources/iconTrackingToolbox.svg resources/iconTrackingToolCalibration.svg resources/iconTrackingToolManager.svg plugin.xml ) # list of Qt .qrc files which contain additional resources # specific to this plugin set(QRC_FILES resources/IGTNavigationToolCalibration.qrc ) set(CPP_FILES ) foreach(file ${SRC_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/${file}) endforeach(file ${SRC_CPP_FILES}) foreach(file ${INTERNAL_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/internal/${file}) endforeach(file ${INTERNAL_CPP_FILES}) \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.igttracking/plugin.xml b/Plugins/org.mitk.gui.qt.igttracking/plugin.xml index 8c413964a5..1e87364e99 100644 --- a/Plugins/org.mitk.gui.qt.igttracking/plugin.xml +++ b/Plugins/org.mitk.gui.qt.igttracking/plugin.xml @@ -1,32 +1,32 @@ diff --git a/Plugins/org.mitk.gui.qt.igttracking/src/internal/IGTFiducialRegistration.cpp b/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkIGTFiducialRegistration.cpp similarity index 84% rename from Plugins/org.mitk.gui.qt.igttracking/src/internal/IGTFiducialRegistration.cpp rename to Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkIGTFiducialRegistration.cpp index 08af548a6b..d32826c240 100644 --- a/Plugins/org.mitk.gui.qt.igttracking/src/internal/IGTFiducialRegistration.cpp +++ b/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkIGTFiducialRegistration.cpp @@ -1,104 +1,104 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ // Blueberry #include #include //Mitk #include #include #include #include #include #include #include // Qmitk -#include "IGTFiducialRegistration.h" +#include "QmitkIGTFiducialRegistration.h" // Qt #include #include #include // MicroServices #include #include #include "usServiceReference.h" -const std::string IGTFiducialRegistration::VIEW_ID = "org.mitk.views.IGTFiducialRegistration"; +const std::string QmitkIGTFiducialRegistration::VIEW_ID = "org.mitk.views.IGTFiducialRegistration"; -void IGTFiducialRegistration::SetFocus() +void QmitkIGTFiducialRegistration::SetFocus() { } -void IGTFiducialRegistration::CreateQtPartControl( QWidget *parent ) +void QmitkIGTFiducialRegistration::CreateQtPartControl( QWidget *parent ) { // create GUI widgets from the Qt Designer's .ui file m_Controls.setupUi( parent ); //Connect signals and slots connect(m_Controls.m_ChooseSelectedPointer, SIGNAL(clicked()), this, SLOT(PointerSelectionChanged())); connect(m_Controls.m_ChooseSelectedImage, SIGNAL(clicked()), this, SLOT(ImageSelectionChanged())); //Initialize Combobox m_Controls.m_DataStorageComboBox->SetDataStorage(this->GetDataStorage()); m_Controls.m_DataStorageComboBox->SetAutoSelectNewItems(false); m_Controls.m_DataStorageComboBox->SetPredicate(mitk::NodePredicateOr::New(mitk::NodePredicateDataType::New("Surface"), mitk::NodePredicateDataType::New("Image"))); //Initialize Fiducial Registration Widget m_Controls.m_FiducialRegistrationWidget->setDataStorage(this->GetDataStorage()); m_Controls.m_FiducialRegistrationWidget->HideStaticRegistrationRadioButton(true); m_Controls.m_FiducialRegistrationWidget->HideContinousRegistrationRadioButton(true); m_Controls.m_FiducialRegistrationWidget->HideUseICPRegistrationCheckbox(true); } -void IGTFiducialRegistration::InitializeRegistration() +void QmitkIGTFiducialRegistration::InitializeRegistration() { foreach(QmitkRenderWindow* renderWindow, this->GetRenderWindowPart()->GetQmitkRenderWindows().values()) { this->m_Controls.m_FiducialRegistrationWidget->AddSliceNavigationController(renderWindow->GetSliceNavigationController()); } } -void IGTFiducialRegistration::PointerSelectionChanged() +void QmitkIGTFiducialRegistration::PointerSelectionChanged() { InitializeRegistration(); int toolID = m_Controls.m_TrackingDeviceSelectionWidget->GetSelectedToolID(); m_TrackingPointer = m_Controls.m_TrackingDeviceSelectionWidget->GetSelectedNavigationDataSource()->GetOutput(toolID); m_Controls.m_FiducialRegistrationWidget->setTrackerNavigationData(m_TrackingPointer); m_Controls.m_PointerLabel->setText(m_Controls.m_TrackingDeviceSelectionWidget->GetSelectedNavigationTool()->GetToolName().c_str()); } -void IGTFiducialRegistration::ImageSelectionChanged() +void QmitkIGTFiducialRegistration::ImageSelectionChanged() { InitializeRegistration(); m_Controls.m_ImageLabel->setText(m_Controls.m_DataStorageComboBox->GetSelectedNode()->GetName().c_str()); m_Controls.m_FiducialRegistrationWidget->setImageNode(m_Controls.m_DataStorageComboBox->GetSelectedNode()); } -IGTFiducialRegistration::IGTFiducialRegistration() +QmitkIGTFiducialRegistration::QmitkIGTFiducialRegistration() { } -IGTFiducialRegistration::~IGTFiducialRegistration() +QmitkIGTFiducialRegistration::~QmitkIGTFiducialRegistration() { } diff --git a/Plugins/org.mitk.gui.qt.igttracking/src/internal/IGTFiducialRegistration.h b/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkIGTFiducialRegistration.h similarity index 80% rename from Plugins/org.mitk.gui.qt.igttracking/src/internal/IGTFiducialRegistration.h rename to Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkIGTFiducialRegistration.h index 732cfefbb4..6b8d731200 100644 --- a/Plugins/org.mitk.gui.qt.igttracking/src/internal/IGTFiducialRegistration.h +++ b/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkIGTFiducialRegistration.h @@ -1,72 +1,72 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ -#ifndef IGTFiducialRegistration_h -#define IGTFiducialRegistration_h +#ifndef QmitkIGTFiducialRegistration_h +#define QmitkIGTFiducialRegistration_h #include #include -#include "ui_IGTFiducialRegistrationControls.h" +#include "ui_QmitkIGTFiducialRegistrationControls.h" #include /*! -\brief IGTFiducialRegistration +\brief QmitkIGTFiducialRegistration \sa QmitkFunctionality \ingroup ${plugin_target}_internal */ -class IGTFiducialRegistration : public QmitkAbstractView +class QmitkIGTFiducialRegistration : public QmitkAbstractView { // this is needed for all Qt objects that should have a Qt meta-object // (everything that derives from QObject and wants to have signal/slots) Q_OBJECT public: virtual void SetFocus() override; static const std::string VIEW_ID; virtual void CreateQtPartControl(QWidget *parent) override; - IGTFiducialRegistration(); - virtual ~IGTFiducialRegistration(); + QmitkIGTFiducialRegistration(); + virtual ~QmitkIGTFiducialRegistration(); public slots: protected slots: void PointerSelectionChanged(); void ImageSelectionChanged(); protected: void InitializeRegistration(); Ui::IGTFiducialRegistrationControls m_Controls; mitk::NavigationData::Pointer m_TrackingPointer; }; #endif // IGTFiducialRegistration_h diff --git a/Plugins/org.mitk.gui.qt.igttracking/src/internal/IGTFiducialRegistrationControls.ui b/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkIGTFiducialRegistrationControls.ui similarity index 100% rename from Plugins/org.mitk.gui.qt.igttracking/src/internal/IGTFiducialRegistrationControls.ui rename to Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkIGTFiducialRegistrationControls.ui diff --git a/Plugins/org.mitk.gui.qt.igttracking/src/internal/IGTNavigationToolCalibration.cpp b/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkIGTNavigationToolCalibration.cpp similarity index 92% rename from Plugins/org.mitk.gui.qt.igttracking/src/internal/IGTNavigationToolCalibration.cpp rename to Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkIGTNavigationToolCalibration.cpp index b063252f4c..3d81291a96 100644 --- a/Plugins/org.mitk.gui.qt.igttracking/src/internal/IGTNavigationToolCalibration.cpp +++ b/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkIGTNavigationToolCalibration.cpp @@ -1,734 +1,734 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include // Blueberry #include #include // Qmitk -#include "IGTNavigationToolCalibration.h" +#include "QmitkIGTNavigationToolCalibration.h" // mitk #include #include #include #include #include #include #include // Qt #include #include //vtk #include -const std::string IGTNavigationToolCalibration::VIEW_ID = "org.mitk.views.igtnavigationtoolcalibration"; +const std::string QmitkIGTNavigationToolCalibration::VIEW_ID = "org.mitk.views.igtnavigationtoolcalibration"; -IGTNavigationToolCalibration::IGTNavigationToolCalibration() +QmitkIGTNavigationToolCalibration::QmitkIGTNavigationToolCalibration() { m_ToolTransformationWidget = new QmitkInteractiveTransformationWidget(); } -IGTNavigationToolCalibration::~IGTNavigationToolCalibration() +QmitkIGTNavigationToolCalibration::~QmitkIGTNavigationToolCalibration() { //The following code is required due to a bug in the point list widget. //If this is removed, MITK crashes when closing the view: m_Controls.m_RegistrationLandmarkWidget->SetPointSetNode(nullptr); m_Controls.m_CalibrationLandmarkWidget->SetPointSetNode(nullptr); //clean up data storage this->GetDataStorage()->Remove(m_ToolTipPointPreview); delete m_ToolTransformationWidget; } -void IGTNavigationToolCalibration::SetFocus() +void QmitkIGTNavigationToolCalibration::SetFocus() { } -void IGTNavigationToolCalibration::OnToolCalibrationMethodChanged(int index) +void QmitkIGTNavigationToolCalibration::OnToolCalibrationMethodChanged(int index) { //if pivot calibration (3) or manual(0) is chosen only calibration pointer is needed if (index == 0 || index == 3) { if (!CheckInitialization(false)) { return; } } else{ if (!CheckInitialization()) { return; } } UpdateManualToolTipCalibrationView(); m_Controls.m_CalibrationMethodsWidget->setCurrentIndex(index); m_IndexCurrentCalibrationMethod = index; } -void IGTNavigationToolCalibration::CreateQtPartControl(QWidget *parent) +void QmitkIGTNavigationToolCalibration::CreateQtPartControl(QWidget *parent) { m_TrackingTimer = new QTimer(this); // create GUI widgets from the Qt Designer's .ui file m_Controls.setupUi(parent); connect(m_Controls.m_SetToolToCalibrate, SIGNAL(clicked()), this, SLOT(SetToolToCalibrate())); connect(m_Controls.m_SetPointer, SIGNAL(clicked()), this, SLOT(SetCalibrationPointer())); connect(m_TrackingTimer, SIGNAL(timeout()), this, SLOT(UpdateTrackingTimer())); connect(m_Controls.m_AddLandmark, SIGNAL(clicked()), this, SLOT(AddLandmark())); connect(m_Controls.m_SaveCalibratedTool, SIGNAL(clicked()), this, SLOT(SaveCalibratedTool())); connect(m_Controls.m_AddPivotPose, SIGNAL(clicked()), this, SLOT(OnAddPivotPose())); connect(m_Controls.m_ComputePivot, SIGNAL(clicked()), this, SLOT(OnComputePivot())); connect(m_Controls.m_UseComputedPivotPoint, SIGNAL(clicked()), this, SLOT(OnUseComputedPivotPoint())); connect(m_Controls.m_StartEditTooltipManually, SIGNAL(clicked()), this, SLOT(OnStartManualToolTipCalibration())); connect(m_Controls.m_GetPositions, SIGNAL(clicked()), this, SLOT(OnGetPositions())); connect(m_Controls.m_ToolAxis_X, SIGNAL(valueChanged(double)), this, SLOT(OnToolAxisSpinboxChanged())); connect(m_Controls.m_ToolAxis_Y, SIGNAL(valueChanged(double)), this, SLOT(OnToolAxisSpinboxChanged())); connect(m_Controls.m_ToolAxis_Z, SIGNAL(valueChanged(double)), this, SLOT(OnToolAxisSpinboxChanged())); connect(m_Controls.m_CalibrateToolAxis, SIGNAL(clicked()), this, SLOT(OnCalibrateToolAxis())); connect((QObject*)(m_ToolTransformationWidget), SIGNAL(EditToolTipFinished(mitk::AffineTransform3D::Pointer)), this, SLOT(OnManualEditToolTipFinished(mitk::AffineTransform3D::Pointer))); connect(m_Controls.m_CalibrationMethodComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(OnToolCalibrationMethodChanged(int))); connect((QObject*)(m_Controls.m_RunCalibrationButton), SIGNAL(clicked()), (QObject*) this, SLOT(OnRunSingleRefToolCalibrationClicked())); connect((QObject*)(m_Controls.m_CollectNavigationDataButton), SIGNAL(clicked()), (QObject*) this, SLOT(OnLoginSingleRefToolNavigationDataClicked())); connect((QObject*)(m_Controls.m_SetNewToolTipPosButton), SIGNAL(clicked()), (QObject*) this, SLOT(OnSetNewToolTipPosButtonClicked())); m_IDToolToCalibrate = -1; m_IDCalibrationPointer = -1; m_IndexCurrentCalibrationMethod = -1; m_OnLoginSingleRefToolNavigationDataClicked = false; m_NumberOfNavigationDataCounter = 0; m_NumberOfNavigationData = -1; //for pivot calibration m_OnAddPivotPoseClicked = false; PivotCount = 0; m_PivotPoses = std::vector(); m_CalibrationLandmarks = mitk::PointSet::New(); m_CalibrationLandmarksNode = mitk::DataNode::New(); m_CalibrationLandmarksNode->SetData(m_CalibrationLandmarks); m_Controls.m_CalibrationLandmarkWidget->SetPointSetNode(m_CalibrationLandmarksNode); m_RegistrationLandmarks = mitk::PointSet::New(); m_RegistrationLandmarksNode = mitk::DataNode::New(); m_RegistrationLandmarksNode->SetData(m_RegistrationLandmarks); m_Controls.m_RegistrationLandmarkWidget->SetPointSetNode(m_RegistrationLandmarksNode); m_ToolSurfaceInToolCoordinatesDataNode = mitk::DataNode::New(); m_ToolSurfaceInToolCoordinatesDataNode->SetName("ToolSurface(ToolCoordinates)"); m_LoggedNavigationDataDifferences = std::vector< mitk::NavigationData::Pointer >(); } -void IGTNavigationToolCalibration::OnRunSingleRefToolCalibrationClicked() +void QmitkIGTNavigationToolCalibration::OnRunSingleRefToolCalibrationClicked() { if (!CheckInitialization()) { return; } mitk::NavigationData::Pointer ToolTipTransform = mitk::NavigationData::New(); if (m_Controls.m_CalibratePosition->isChecked()) { //1: Compute mean translational offset vector m_ResultOffsetVector.Fill(0); for (std::vector::iterator vecIter = m_LoggedNavigationDataOffsets.begin(); vecIter != m_LoggedNavigationDataOffsets.end(); vecIter++) { m_ResultOffsetVector[0] = m_ResultOffsetVector[0] + (*vecIter)[0]; m_ResultOffsetVector[1] = m_ResultOffsetVector[1] + (*vecIter)[1]; m_ResultOffsetVector[2] = m_ResultOffsetVector[2] + (*vecIter)[2]; } m_ResultOffsetVector[0] = m_ResultOffsetVector[0] / m_LoggedNavigationDataOffsets.size(); m_ResultOffsetVector[1] = m_ResultOffsetVector[1] / m_LoggedNavigationDataOffsets.size(); m_ResultOffsetVector[2] = m_ResultOffsetVector[2] / m_LoggedNavigationDataOffsets.size(); this->m_Controls.m_ResultOfCalibration->setText( QString("x: ") + QString(QString::number(m_ResultOffsetVector[0], 103, 3)) + QString("; y: ") + (QString::number(m_ResultOffsetVector[1], 103, 3)) + QString("; z: ") + (QString::number(m_ResultOffsetVector[2], 103, 3))); ToolTipTransform->SetPosition(m_ResultOffsetVector); } if (m_Controls.m_CalibrateOrientation->isChecked()) { //2: Compute mean orientation mitk::Quaternion meanOrientation; std::vector allOrientations = std::vector (); for (std::size_t i = 0; i < m_LoggedNavigationDataDifferences.size(); i++) { allOrientations.push_back(m_LoggedNavigationDataDifferences.at(i)->GetOrientation()); } meanOrientation = mitk::QuaternionAveraging::CalcAverage(allOrientations); this->m_Controls.m_ResultOfCalibrationOrientation->setText( QString("qx: ") + QString(QString::number(meanOrientation.x(), 103, 3)) + QString("; qy: ") + (QString::number(meanOrientation.y(), 103, 3)) + QString("; qz: ") + (QString::number(meanOrientation.z(), 103, 3)) + QString("; qr: ") + (QString::number(meanOrientation.r(), 103, 3))); ToolTipTransform->SetOrientation(meanOrientation); } MITK_INFO << "Computed calibration: "; MITK_INFO << "Translation Vector: " << ToolTipTransform->GetPosition(); MITK_INFO << "Quaternion: (" << ToolTipTransform->GetOrientation() << ")"; MITK_INFO << "Euler Angles [rad]: (" << ToolTipTransform->GetOrientation().rotation_euler_angles() << ")"; MITK_INFO << "Matrix:"; vnl_matrix_fixed rotMatrix = ToolTipTransform->GetOrientation().rotation_matrix_transpose(); MITK_INFO << rotMatrix[0][0] << " " << rotMatrix[0][1] << " " << rotMatrix[0][2] << std::endl; MITK_INFO << rotMatrix[1][0] << " " << rotMatrix[1][1] << " " << rotMatrix[1][2] << std::endl; MITK_INFO << rotMatrix[2][0] << " " << rotMatrix[2][1] << " " << rotMatrix[2][2] << std::endl; //3: write everything into the final tool tip transform and save it as member (it will be written to the tool later on) mitk::NavigationData::Pointer ToolTipInTrackingCoordinates = mitk::NavigationData::New(); ToolTipInTrackingCoordinates->Compose(ToolTipTransform); ToolTipInTrackingCoordinates->Compose(m_NavigationDataSourceOfToolToCalibrate->GetOutput(m_IDToolToCalibrate)); ShowToolTipPreview(ToolTipInTrackingCoordinates); m_Controls.m_SetNewToolTipPosButton->setEnabled(true); m_ComputedToolTipTransformation = ToolTipTransform; } -void IGTNavigationToolCalibration::OnLoginSingleRefToolNavigationDataClicked() +void QmitkIGTNavigationToolCalibration::OnLoginSingleRefToolNavigationDataClicked() { if (!CheckInitialization()) { return; } //reset old data m_LoggedNavigationDataOffsets.clear(); m_LoggedNavigationDataDifferences.clear(); m_OnLoginSingleRefToolNavigationDataClicked = true; m_Controls.m_CollectNavigationDataButton->setEnabled(false); m_NumberOfNavigationData = m_Controls.m_NumberOfNavigationDataToCollect->value(); MITK_INFO << "Collecting " << m_NumberOfNavigationData << " NavigationData ... " << endl; } -void IGTNavigationToolCalibration::LoginSingleRefToolNavigationData() +void QmitkIGTNavigationToolCalibration::LoginSingleRefToolNavigationData() { if (!CheckInitialization()) { return; } if (m_NumberOfNavigationDataCounter < m_NumberOfNavigationData) { //update label text QString labelText = "Collecting Data: " + QString::number(m_NumberOfNavigationDataCounter); m_Controls.m_CollectionStatus->setText(labelText); mitk::NavigationData::Pointer referenceTool = m_NavigationDataSourceOfCalibrationPointer->GetOutput(m_IDCalibrationPointer); mitk::NavigationData::Pointer toolToCalibrate = m_NavigationDataSourceOfToolToCalibrate->GetOutput(m_IDToolToCalibrate); //compute difference: // differenceND = toolToCalibrate^-1 * referenceTool mitk::NavigationData::Pointer differenceND = mitk::NavigationData::New(); differenceND->Compose(referenceTool); differenceND->Compose(toolToCalibrate->GetInverse()); //inverse mode... if (m_Controls.m_InvertQuaternions->isChecked()) { // negate identity matrix to directly show parameters that will set up in NDI 6D Software Architect differenceND = differenceND->GetInverse(); } //save difference in member m_LoggedNavigationDataOffsets.push_back(differenceND->GetPosition()); m_LoggedNavigationDataDifferences.push_back(differenceND); m_NumberOfNavigationDataCounter++; } if (m_NumberOfNavigationDataCounter == m_NumberOfNavigationData) { m_NumberOfNavigationDataCounter = 0; m_OnLoginSingleRefToolNavigationDataClicked = false; m_Controls.m_CollectNavigationDataButton->setEnabled(true); m_Controls.m_RunCalibrationButton->setEnabled(true); MITK_INFO << "Collecting " << m_NumberOfNavigationData << " NavigationData ... Finished" << endl; QString labelText = "Collected " + QString::number(m_NumberOfNavigationData) + " data samples!"; m_Controls.m_CollectionStatus->setText(labelText); } } -void IGTNavigationToolCalibration::OnSetNewToolTipPosButtonClicked() +void QmitkIGTNavigationToolCalibration::OnSetNewToolTipPosButtonClicked() { ApplyToolTipTransform(m_ComputedToolTipTransformation); RemoveToolTipPreview(); } -void IGTNavigationToolCalibration::ClearOldPivot() +void QmitkIGTNavigationToolCalibration::ClearOldPivot() { mitk::NavigationData::Pointer tempND = mitk::NavigationData::New(); this->ApplyToolTipTransform(tempND); UpdateManualToolTipCalibrationView(); //m_ManualToolTipEditWidget->hide(); //TODO this->GetDataStorage()->Remove(m_ToolSurfaceInToolCoordinatesDataNode); } -void IGTNavigationToolCalibration::OnAddPivotPose() +void QmitkIGTNavigationToolCalibration::OnAddPivotPose() { ClearOldPivot(); //When the collect Poses Button is Clicked m_OnAddPivotPoseClicked = true; m_NumberOfNavigationData = m_Controls.m_PosesToCollect->value(); } -void IGTNavigationToolCalibration::AddPivotPose() +void QmitkIGTNavigationToolCalibration::AddPivotPose() { //Save the poses to be used in computation if (PivotCount < m_NumberOfNavigationData) { mitk::NavigationData::Pointer currentPose = mitk::NavigationData::New(); currentPose->Graft(m_Controls.m_SelectionWidget->GetSelectedNavigationDataSource()->GetOutput(m_IDToolToCalibrate)); m_PivotPoses.push_back(currentPose); m_Controls.m_PoseNumber->setText(QString::number(m_PivotPoses.size())); PivotCount++; } if (PivotCount == m_NumberOfNavigationData) { m_OnAddPivotPoseClicked = false; } } -void IGTNavigationToolCalibration::OnComputePivot() +void QmitkIGTNavigationToolCalibration::OnComputePivot() { mitk::PivotCalibration::Pointer myPivotCalibration = mitk::PivotCalibration::New(); for (std::size_t i = 0; i < this->m_PivotPoses.size(); i++) { myPivotCalibration->AddNavigationData(m_PivotPoses.at(i)); } QString resultString; if (myPivotCalibration->ComputePivotResult()) { mitk::NavigationData::Pointer markerTransformationTrackingCoordinates = m_PivotPoses.at(0); //Get computed pivot transfromation in tool coordinates mitk::NavigationData::Pointer ToolTipToTool = mitk::NavigationData::New(); ToolTipToTool->SetPosition(myPivotCalibration->GetResultPivotPoint()); ToolTipToTool->SetOrientation(myPivotCalibration->GetResultPivotRotation()); mitk::NavigationData::Pointer TrackerToTool = mitk::NavigationData::New(); TrackerToTool->SetOrientation(markerTransformationTrackingCoordinates->GetOrientation()); TrackerToTool->SetPosition(markerTransformationTrackingCoordinates->GetPosition()); TrackerToTool->Compose(ToolTipToTool); // Compute pivot point in relation to marker transformation for preview mitk::NavigationData::Pointer ToolTipToTracker = mitk::NavigationData::New(); ToolTipToTracker->Compose(ToolTipToTool); ToolTipToTracker->Compose(markerTransformationTrackingCoordinates); //add the preview node to the data storage ShowToolTipPreview(ToolTipToTracker); //parse result string resultString = QString("Pivot computation succeeded!\n") + QString("RMS Error: ") + QString::number(myPivotCalibration->GetResultRMSError()) + QString("\n") + QString("Pivot Point: ") + QString::number(myPivotCalibration->GetResultPivotPoint()[0]) + ";" + QString::number(myPivotCalibration->GetResultPivotPoint()[1]) + ";" + QString::number(myPivotCalibration->GetResultPivotPoint()[2]) + QString("\n") + QString("Pivot Rotation: ") + QString::number(myPivotCalibration->GetResultPivotRotation()[0]) + ";" + QString::number(myPivotCalibration->GetResultPivotRotation()[1]) + ";" + QString::number(myPivotCalibration->GetResultPivotRotation()[2]) + ";" + QString::number(myPivotCalibration->GetResultPivotRotation()[3]) + QString("\n"); //finally: save results to member variable m_ComputedToolTipTransformation = ToolTipToTool; //enable button to use the computed point with the tool m_Controls.m_UseComputedPivotPoint->setEnabled(true); } else { resultString = "Pivot computation failed!"; } MITK_INFO << resultString.toStdString().c_str(); m_Controls.m_ResultText->setText(resultString); } -void IGTNavigationToolCalibration::UpdatePivotCount() +void QmitkIGTNavigationToolCalibration::UpdatePivotCount() { PivotCount = 0; while (!m_PivotPoses.empty()) { m_PivotPoses.pop_back(); } m_Controls.m_PoseNumber->setText(QString::number(PivotCount)); } -void IGTNavigationToolCalibration::OnUseComputedPivotPoint() +void QmitkIGTNavigationToolCalibration::OnUseComputedPivotPoint() { RemoveToolTipPreview(); QString resultString = QString("Pivoted tool tip transformation was written to the tool ") + m_ToolToCalibrate->GetToolName().c_str(); ApplyToolTipTransform(m_ComputedToolTipTransformation, resultString.toStdString()); m_Controls.m_ResultText->setText(resultString); UpdatePivotCount(); } -void IGTNavigationToolCalibration::ApplyToolTipTransform(mitk::NavigationData::Pointer ToolTipTransformInToolCoordinates, std::string message) +void QmitkIGTNavigationToolCalibration::ApplyToolTipTransform(mitk::NavigationData::Pointer ToolTipTransformInToolCoordinates, std::string message) { if (!CheckInitialization(false)) { return; } //Update tool in tool storage m_ToolToCalibrate->SetToolTipPosition(ToolTipTransformInToolCoordinates->GetPosition()); m_ToolToCalibrate->SetToolTipOrientation(ToolTipTransformInToolCoordinates->GetOrientation()); //And also update tracking device, so the transform is directly used mitk::TrackingDeviceSource::Pointer trackingDeviceSource; try { trackingDeviceSource = dynamic_cast(m_NavigationDataSourceOfToolToCalibrate.GetPointer()); mitk::TrackingTool::Pointer TrackingToolToCalibrate = trackingDeviceSource->GetTrackingDevice()->GetTool(m_IDToolToCalibrate); TrackingToolToCalibrate->SetToolTip(ToolTipTransformInToolCoordinates->GetPosition(), ToolTipTransformInToolCoordinates->GetOrientation()); } catch (std::exception& e) { MITK_ERROR << "Error while trying to set the tool tip to the running tracking device. Aborting! (" << e.what() << ")"; } MITK_INFO << message; } -void IGTNavigationToolCalibration::ShowToolTipPreview(mitk::NavigationData::Pointer ToolTipInTrackingCoordinates) +void QmitkIGTNavigationToolCalibration::ShowToolTipPreview(mitk::NavigationData::Pointer ToolTipInTrackingCoordinates) { if(m_ToolTipPointPreview.IsNull()) { m_ToolTipPointPreview = mitk::DataNode::New(); m_ToolTipPointPreview->SetName("Modified Tool Tip Preview"); mitk::Color blue; blue.SetBlue(1); m_ToolTipPointPreview->SetColor(blue); mitk::Surface::Pointer mySphere = mitk::Surface::New(); vtkSmartPointer vtkData = vtkSmartPointer::New(); vtkData->SetRadius(3.0f); vtkData->SetCenter(0.0, 0.0, 0.0); vtkData->Update(); mySphere->SetVtkPolyData(vtkData->GetOutput()); m_ToolTipPointPreview->SetData(mySphere); this->GetDataStorage()->Add(m_ToolTipPointPreview); } m_ToolTipPointPreview->GetData()->GetGeometry()->SetIndexToWorldTransform(ToolTipInTrackingCoordinates->GetAffineTransform3D()); } -void IGTNavigationToolCalibration::RemoveToolTipPreview() +void QmitkIGTNavigationToolCalibration::RemoveToolTipPreview() { this->GetDataStorage()->Remove(m_ToolTipPointPreview.GetPointer()); } -void IGTNavigationToolCalibration::UpdateManualToolTipCalibrationView() +void QmitkIGTNavigationToolCalibration::UpdateManualToolTipCalibrationView() { if (m_ToolToCalibrate.IsNull()) { return; } //parse human readable transformation data and display it std::stringstream translation; std::stringstream orientation; translation << m_ToolToCalibrate->GetToolTipPosition(); orientation << "Quaternion: (" << m_ToolToCalibrate->GetToolTipOrientation() << ")" << std::endl; orientation << std::endl; orientation << "Euler Angles [rad]: (" << m_ToolToCalibrate->GetToolTipOrientation().rotation_euler_angles() << ")" << std::endl; orientation << std::endl; orientation << "Matrix:" << std::endl; vnl_matrix_fixed rotMatrix = m_ToolToCalibrate->GetToolTipOrientation().rotation_matrix_transpose(); orientation << rotMatrix[0][0] << " " << rotMatrix[0][1] << " " << rotMatrix[0][2] << std::endl; orientation << rotMatrix[1][0] << " " << rotMatrix[1][1] << " " << rotMatrix[1][2] << std::endl; orientation << rotMatrix[2][0] << " " << rotMatrix[2][1] << " " << rotMatrix[2][2] << std::endl; m_Controls.m_ManualCurrentTranslation->setText(translation.str().c_str()); m_Controls.m_ManualCurrentOrientation->setPlainText(orientation.str().c_str()); } -void IGTNavigationToolCalibration::OnStartManualToolTipCalibration() +void QmitkIGTNavigationToolCalibration::OnStartManualToolTipCalibration() { if (!CheckInitialization(false)) { return; } m_ToolTransformationWidget->SetToolToEdit(m_ToolToCalibrate); m_ToolTransformationWidget->SetDefaultOffset(m_ToolToCalibrate->GetToolTipPosition()); m_ToolTransformationWidget->SetDefaultRotation(m_ToolToCalibrate->GetToolTipOrientation()); m_ToolTransformationWidget->open(); } -void IGTNavigationToolCalibration::OnManualEditToolTipFinished(mitk::AffineTransform3D::Pointer toolTip) +void QmitkIGTNavigationToolCalibration::OnManualEditToolTipFinished(mitk::AffineTransform3D::Pointer toolTip) { //This function is called, when the toolTipEdit view is closed. //if user pressed cancle, nullptr is returned. Do nothing. Else, set values. if (toolTip) { mitk::NavigationData::Pointer tempND = mitk::NavigationData::New(toolTip);//Convert to Navigation data for simple transversion to quaternion QString resultString = QString("Manual edited values are written to ") + m_ToolToCalibrate->GetToolName().c_str(); ApplyToolTipTransform(tempND, resultString.toStdString()); m_Controls.m_ResultText->setText(resultString); } UpdateManualToolTipCalibrationView(); } -void IGTNavigationToolCalibration::OnGetPositions() +void QmitkIGTNavigationToolCalibration::OnGetPositions() { if (!CheckInitialization(true)) { return; } //Navigation Data from Tool which should be calibrated if (!m_AxisCalibration_ToolToCalibrate) m_AxisCalibration_ToolToCalibrate = mitk::NavigationData::New(); m_AxisCalibration_ToolToCalibrate->Graft(m_Controls.m_SelectionWidget->GetSelectedNavigationDataSource()->GetOutput(m_IDToolToCalibrate)); //Navigation Data from calibration pointer tool if (!m_AxisCalibration_NavDataCalibratingTool) m_AxisCalibration_NavDataCalibratingTool = mitk::NavigationData::New(); m_AxisCalibration_NavDataCalibratingTool->Graft(m_Controls.m_SelectionWidget->GetSelectedNavigationDataSource()->GetOutput(m_IDCalibrationPointer)); MITK_DEBUG << "Positions for tool axis calibration:"; MITK_DEBUG << " ToolTip: " << m_AxisCalibration_ToolToCalibrate->GetPosition() << ","; MITK_DEBUG << " Rotation: \n" << m_AxisCalibration_ToolToCalibrate->GetRotationMatrix(); MITK_DEBUG << " End of the tool: " << m_AxisCalibration_NavDataCalibratingTool->GetPosition(); QString _label = "Position recorded: " + QString::number(m_AxisCalibration_NavDataCalibratingTool->GetPosition()[0], 'f', 1) + ", " + QString::number(m_AxisCalibration_NavDataCalibratingTool->GetPosition()[1], 'f', 1) + ", " + QString::number(m_AxisCalibration_NavDataCalibratingTool->GetPosition()[2], 'f', 1); m_Controls.m_ToolAxisPositionLabel->setText(_label); } -void IGTNavigationToolCalibration::OnCalibrateToolAxis() +void QmitkIGTNavigationToolCalibration::OnCalibrateToolAxis() { if (!m_AxisCalibration_ToolToCalibrate || !m_AxisCalibration_NavDataCalibratingTool) { MITK_ERROR << "Please record position first."; return; } //Calculate the tool tip //here is an explanation, what is happening here: /* The axis is equal to the (tool tip) minus the (end of the tool) in tool coordinates of the tool which should be calibrated. The tool tip in tool coordinates is zero (definition of the tip). The end of the tool is recorded by the calibration pointer's position and is transformed using the inverse of the tool which should be calibrated. Normalize it. */ m_CalibratedToolAxis = -m_AxisCalibration_ToolToCalibrate->GetInverse()->TransformPoint(m_AxisCalibration_NavDataCalibratingTool->GetPosition()).GetVectorFromOrigin(); MITK_DEBUG << "Tool Endpoint in Tool coordinates: " << m_CalibratedToolAxis; m_CalibratedToolAxis.Normalize(); MITK_DEBUG << "Tool Axis: " << m_CalibratedToolAxis; m_ToolToCalibrate->SetToolAxis(m_CalibratedToolAxis); //Update GUI QString calibratedToolAxisString = "Tool Axis: " + QString::number(m_CalibratedToolAxis.GetElement(0), 'f', 3) + ", " + QString::number(m_CalibratedToolAxis.GetElement(1), 'f', 3) + ", " + QString::number(m_CalibratedToolAxis.GetElement(2), 'f', 3); m_Controls.m_ToolAxisCalibrationLabel->setText(calibratedToolAxisString); //Block QT signals, we don't want to emit SpinboxChanged on the first value to overwrite the next ones m_Controls.m_ToolAxis_X->blockSignals(true); m_Controls.m_ToolAxis_Y->blockSignals(true); m_Controls.m_ToolAxis_Z->blockSignals(true); m_Controls.m_ToolAxis_X->setValue(m_CalibratedToolAxis[0]); m_Controls.m_ToolAxis_Y->setValue(m_CalibratedToolAxis[1]); m_Controls.m_ToolAxis_Z->setValue(m_CalibratedToolAxis[2]); m_Controls.m_ToolAxis_X->blockSignals(false); m_Controls.m_ToolAxis_Y->blockSignals(false); m_Controls.m_ToolAxis_Z->blockSignals(false); } -void IGTNavigationToolCalibration::OnToolAxisSpinboxChanged() +void QmitkIGTNavigationToolCalibration::OnToolAxisSpinboxChanged() { m_CalibratedToolAxis.SetElement(0, m_Controls.m_ToolAxis_X->value()); m_CalibratedToolAxis.SetElement(1, m_Controls.m_ToolAxis_Y->value()); m_CalibratedToolAxis.SetElement(2, m_Controls.m_ToolAxis_Z->value()); m_ToolToCalibrate->SetToolAxis(m_CalibratedToolAxis); MITK_INFO << "Tool axis changed to " << m_CalibratedToolAxis; } -void IGTNavigationToolCalibration::SetToolToCalibrate() +void QmitkIGTNavigationToolCalibration::SetToolToCalibrate() { m_IDToolToCalibrate = m_Controls.m_SelectionWidget->GetSelectedToolID(); if (m_IDToolToCalibrate == -1) //no valid tool to calibrate { m_Controls.m_CalToolLabel->setText(""); m_Controls.m_StatusWidgetToolToCalibrate->RemoveStatusLabels(); m_TrackingTimer->stop(); } else { m_ToolToCalibrate = m_Controls.m_SelectionWidget->GetSelectedNavigationTool(); m_NavigationDataSourceOfToolToCalibrate = m_Controls.m_SelectionWidget->GetSelectedNavigationDataSource(); m_Controls.m_CalToolLabel->setText(m_NavigationDataSourceOfToolToCalibrate->GetOutput(m_IDToolToCalibrate)->GetName()); //initialize widget m_Controls.m_StatusWidgetToolToCalibrate->RemoveStatusLabels(); m_Controls.m_StatusWidgetToolToCalibrate->SetShowPositions(true); m_Controls.m_StatusWidgetToolToCalibrate->SetTextAlignment(Qt::AlignLeft); m_Controls.m_StatusWidgetToolToCalibrate->AddNavigationData(m_NavigationDataSourceOfToolToCalibrate->GetOutput(m_IDToolToCalibrate)); m_Controls.m_StatusWidgetToolToCalibrate->ShowStatusLabels(); //initialize manual tool tip calibration view UpdateManualToolTipCalibrationView(); //save tool surface in tool coordinates for further editing mitk::Surface::Pointer ToolSurface = dynamic_cast(m_ToolToCalibrate->GetDataNode()->GetData())->Clone(); m_ToolSurfaceInToolCoordinatesDataNode->SetData(ToolSurface); m_ToolSurfaceInToolCoordinatesDataNode->GetData()->GetGeometry()->SetIdentity(); //Set the default needle axis m_CalibratedToolAxis = m_ToolToCalibrate->GetToolAxis().GetVectorFromOrigin(); //Block QT signals, we don't want to emit SpinboxChanged on the first value to overwrite the next ones m_Controls.m_ToolAxis_X->blockSignals(true); m_Controls.m_ToolAxis_Y->blockSignals(true); m_Controls.m_ToolAxis_Z->blockSignals(true); m_Controls.m_ToolAxis_X->setValue(m_CalibratedToolAxis[0]); m_Controls.m_ToolAxis_Y->setValue(m_CalibratedToolAxis[1]); m_Controls.m_ToolAxis_Z->setValue(m_CalibratedToolAxis[2]); m_Controls.m_ToolAxis_X->blockSignals(false); m_Controls.m_ToolAxis_Y->blockSignals(false); m_Controls.m_ToolAxis_Z->blockSignals(false); UpdateManualToolTipCalibrationView(); //start updating timer for status widgets, etc. if (!m_TrackingTimer->isActive()) m_TrackingTimer->start(100); } } -void IGTNavigationToolCalibration::SetCalibrationPointer() +void QmitkIGTNavigationToolCalibration::SetCalibrationPointer() { m_IDCalibrationPointer = m_Controls.m_SelectionWidget->GetSelectedToolID(); if (m_IDCalibrationPointer == -1) { m_Controls.m_PointerLabel->setText(""); m_Controls.m_StatusWidgetCalibrationPointer->RemoveStatusLabels(); m_TrackingTimer->stop(); } else { m_NavigationDataSourceOfCalibrationPointer = m_Controls.m_SelectionWidget->GetSelectedNavigationDataSource(); m_Controls.m_PointerLabel->setText(m_NavigationDataSourceOfCalibrationPointer->GetOutput(m_IDCalibrationPointer)->GetName()); //initialize widget m_Controls.m_StatusWidgetCalibrationPointer->RemoveStatusLabels(); m_Controls.m_StatusWidgetCalibrationPointer->SetShowPositions(true); m_Controls.m_StatusWidgetCalibrationPointer->SetTextAlignment(Qt::AlignLeft); m_Controls.m_StatusWidgetCalibrationPointer->AddNavigationData(m_NavigationDataSourceOfCalibrationPointer->GetOutput(m_IDCalibrationPointer)); m_Controls.m_StatusWidgetCalibrationPointer->ShowStatusLabels(); if (!m_TrackingTimer->isActive()) m_TrackingTimer->start(100); } } -void IGTNavigationToolCalibration::UpdateOffsetCoordinates() +void QmitkIGTNavigationToolCalibration::UpdateOffsetCoordinates() { if (m_NavigationDataSourceOfCalibrationPointer.IsNull() || m_NavigationDataSourceOfToolToCalibrate.IsNull()) { return; } mitk::NavigationData::Pointer referenceToolND = m_NavigationDataSourceOfCalibrationPointer->GetOutput(m_IDCalibrationPointer); mitk::NavigationData::Pointer toolToCalibrateND = m_NavigationDataSourceOfToolToCalibrate->GetOutput(m_IDToolToCalibrate); if (referenceToolND->IsDataValid() && toolToCalibrateND->IsDataValid()) { //computation: difference between both tools (in tool coordinates) //differenceND = toolToCalibrateND^-1 * referenceToolND mitk::NavigationData::Pointer differenceND = mitk::NavigationData::New(); differenceND->Compose(referenceToolND); differenceND->Compose(toolToCalibrateND->GetInverse()); //display this orientation in the UI m_Controls.m_OffsetCoordinates->setText( QString("x: ") + QString(QString::number(differenceND->GetPosition()[0], 103, 3)) + QString("; y: ") + (QString::number(differenceND->GetPosition()[1], 103, 3)) + QString("; z: ") + (QString::number(differenceND->GetPosition()[2], 103, 3))); m_Controls.m_OrientationOffsetCoordinates->setText( QString("qx: ") + QString(QString::number(differenceND->GetOrientation().x(), 103, 3)) + QString("; qy: ") + (QString::number(differenceND->GetOrientation().y(), 103, 3)) + QString("; qz: ") + (QString::number(differenceND->GetOrientation().z(), 103, 3)) + QString("; qr: ") + (QString::number(differenceND->GetOrientation().r(), 103, 3))); //also update preview if active if (m_ToolTipPointPreview.IsNotNull()) //NOT WORKING! TODO: fix or remove! { mitk::NavigationData::Pointer ToolTipTransform = mitk::NavigationData::New(); ToolTipTransform->SetPosition(m_ResultOffsetVector); mitk::NavigationData::Pointer ToolTipInTrackingCoordinates = mitk::NavigationData::New(); //maybe store as for better peformance... ToolTipInTrackingCoordinates->Compose(m_NavigationDataSourceOfToolToCalibrate->GetOutput(m_IDToolToCalibrate)); ToolTipInTrackingCoordinates->Compose(ToolTipTransform); m_ToolTipPointPreview->GetData()->GetGeometry()->SetIndexToWorldTransform(ToolTipInTrackingCoordinates->GetAffineTransform3D()); } } } -void IGTNavigationToolCalibration::UpdateTrackingTimer() +void QmitkIGTNavigationToolCalibration::UpdateTrackingTimer() { m_Controls.m_StatusWidgetToolToCalibrate->Refresh(); m_Controls.m_StatusWidgetCalibrationPointer->Refresh(); if (m_OnLoginSingleRefToolNavigationDataClicked) LoginSingleRefToolNavigationData(); if (m_OnAddPivotPoseClicked) AddPivotPose(); // 1 == Single Reference Calibration Method if (m_IndexCurrentCalibrationMethod == 1) UpdateOffsetCoordinates(); } -void IGTNavigationToolCalibration::AddLandmark() +void QmitkIGTNavigationToolCalibration::AddLandmark() { if (!CheckInitialization()) { return; } mitk::NavigationData::Pointer navDataTool = m_NavigationDataSourceOfToolToCalibrate->GetOutput(m_IDToolToCalibrate); mitk::Point3D landmark = m_NavigationDataSourceOfCalibrationPointer->GetOutput(m_IDCalibrationPointer)->GetPosition(); //convert to itk transform itk::Vector translation; for (int k = 0; k < 3; k++) translation[k] = navDataTool->GetPosition()[k]; itk::Matrix rotation; for (int k = 0; k < 3; k++) for (int l = 0; l < 3; l++) rotation[k][l] = navDataTool->GetOrientation().rotation_matrix_transpose()[k][l]; rotation = rotation.GetTranspose(); itk::Vector landmarkItk; landmarkItk[0] = landmark[0]; landmarkItk[1] = landmark[1]; landmarkItk[2] = landmark[2]; //compute landmark in tool coordinates itk::Matrix rotationInverse; for (int k = 0; k < 3; k++) for (int l = 0; l < 3; l++) rotationInverse[k][l] = rotation.GetInverse()[k][l]; landmarkItk = rotationInverse * (landmarkItk - translation); //convert back and add landmark to pointset landmark[0] = landmarkItk[0]; landmark[1] = landmarkItk[1]; landmark[2] = landmarkItk[2]; m_RegistrationLandmarks->InsertPoint(m_RegistrationLandmarks->GetSize(), landmark); } -void IGTNavigationToolCalibration::SaveCalibratedTool() +void QmitkIGTNavigationToolCalibration::SaveCalibratedTool() { if (m_ToolToCalibrate.IsNotNull()) { mitk::NavigationTool::Pointer calibratedTool = m_ToolToCalibrate; calibratedTool->SetToolCalibrationLandmarks(this->m_CalibrationLandmarks); calibratedTool->SetToolRegistrationLandmarks(this->m_RegistrationLandmarks); mitk::NavigationToolWriter::Pointer myWriter = mitk::NavigationToolWriter::New(); std::string filename = QFileDialog::getSaveFileName(nullptr,tr("Save Navigation Tool"), "/", "*.IGTTool").toUtf8().data(); filename.append(".IGTTool"); if (filename == "") return; if (myWriter->DoWrite(filename, calibratedTool)) MITK_INFO << "Saved calibrated tool to file " << filename; else MITK_WARN << "Can't write tool to file " << filename; } else { MITK_ERROR << "Did not find navigation tool storage of calibrated tool, aborting!"; } } -bool IGTNavigationToolCalibration::CheckInitialization(bool CalibrationPointerRequired) +bool QmitkIGTNavigationToolCalibration::CheckInitialization(bool CalibrationPointerRequired) { if ((m_IDToolToCalibrate == -1) || ((CalibrationPointerRequired) && (m_IDCalibrationPointer == -1) ) ) { QMessageBox msgBox; msgBox.setText("Tool to calibrate and/or calibration pointer not initialized, cannot proceed!"); msgBox.exec(); return false; } else { return true; } } diff --git a/Plugins/org.mitk.gui.qt.igttracking/src/internal/IGTNavigationToolCalibration.h b/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkIGTNavigationToolCalibration.h similarity index 94% rename from Plugins/org.mitk.gui.qt.igttracking/src/internal/IGTNavigationToolCalibration.h rename to Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkIGTNavigationToolCalibration.h index 741488fc68..d88cdd940e 100644 --- a/Plugins/org.mitk.gui.qt.igttracking/src/internal/IGTNavigationToolCalibration.h +++ b/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkIGTNavigationToolCalibration.h @@ -1,143 +1,143 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ -#ifndef IGTNavigationToolCalibration_h -#define IGTNavigationToolCalibration_h +#ifndef QmitkIGTNavigationToolCalibration_h +#define QmitkIGTNavigationToolCalibration_h #include #include #include #include "QmitkInteractiveTransformationWidget.h" -#include "ui_IGTNavigationToolCalibrationControls.h" +#include "ui_QmitkIGTNavigationToolCalibrationControls.h" #include //QT headers #include /*! \brief IGTNavigationToolCalibration \warning This class is not yet documented. Use "git blame" and ask the author to provide basic documentation. \ingroup ${plugin_target}_internal */ -class IGTNavigationToolCalibration : public QmitkAbstractView +class QmitkIGTNavigationToolCalibration : public QmitkAbstractView { // this is needed for all Qt objects that should have a Qt meta-object // (everything that derives from QObject and wants to have signal/slots) Q_OBJECT public: - IGTNavigationToolCalibration(); + QmitkIGTNavigationToolCalibration(); - virtual ~IGTNavigationToolCalibration(); + virtual ~QmitkIGTNavigationToolCalibration(); static const std::string VIEW_ID; virtual void CreateQtPartControl(QWidget *parent); protected slots: void OnAddPivotPose(); void OnComputePivot(); void OnUseComputedPivotPoint(); void SetToolToCalibrate(); void SetCalibrationPointer(); void UpdateTrackingTimer(); void AddLandmark(); void SaveCalibratedTool(); void OnToolCalibrationMethodChanged(int index); void OnStartManualToolTipCalibration(); void OnRunSingleRefToolCalibrationClicked(); void OnLoginSingleRefToolNavigationDataClicked(); void OnSetNewToolTipPosButtonClicked(); void OnGetPositions(); void OnCalibrateToolAxis(); void OnToolAxisSpinboxChanged(); void OnManualEditToolTipFinished(mitk::AffineTransform3D::Pointer toolTip); protected: virtual void SetFocus(); void UpdateOffsetCoordinates(); int m_IndexCurrentCalibrationMethod; Ui::IGTNavigationToolCalibrationControls m_Controls; //some general members mitk::NavigationTool::Pointer m_ToolToCalibrate; //<<< tool that will be calibrated int m_IDToolToCalibrate; //<<< id of tool that will be calibrated (of the navigation data source) mitk::NavigationDataSource::Pointer m_NavigationDataSourceOfToolToCalibrate; //<<< navigation data source of the tool that will be calibrated mitk::NavigationDataSource::Pointer m_NavigationDataSourceOfCalibrationPointer; //<<< navigation data source of the calibration pointer mitk::DataNode::Pointer m_ToolSurfaceInToolCoordinatesDataNode; //<<< holds the tool surface in tool coordinates (for preview purposes) int m_IDCalibrationPointer; //<<< id of the calibration pointer (of the corresponding navigation data source) QTimer* m_TrackingTimer; //<<< tracking timer that updates the status widgets void ApplyToolTipTransform(mitk::NavigationData::Pointer ToolTipTransformInToolCoordinates, std::string message = "Tool was updated with the calibrated tool tip!"); //<<< applys the given tool tip transform to the tool to calibrate bool CheckInitialization(bool CalibrationPointerRequired = true); //<<< checks if the tool to calibrate and (if required) the calibration pointer is initialized. Displays a warning and returns false if not. mitk::NavigationData::Pointer m_ComputedToolTipTransformation; //<<< holds the new tooltip transformation after it was computed to write it into the tool later // members and helper methods for pivot tool calibration std::vector m_PivotPoses; void AddPivotPose(); void ClearOldPivot(); void UpdatePivotCount(); bool m_OnAddPivotPoseClicked; int PivotCount; // members and helper methods for manual tool calibration void UpdateManualToolTipCalibrationView(); QmitkInteractiveTransformationWidget* m_ToolTransformationWidget; // members and helper methods for single reference tool calibration void LoginSingleRefToolNavigationData(); std::vector< mitk::Point3D > m_LoggedNavigationDataOffsets; std::vector< mitk::NavigationData::Pointer > m_LoggedNavigationDataDifferences; bool m_OnLoginSingleRefToolNavigationDataClicked; int m_NumberOfNavigationData; int m_NumberOfNavigationDataCounter; mitk::Point3D m_ResultOffsetVector; // members and helper methods for tool tip preview mitk::DataNode::Pointer m_ToolTipPointPreview; //<<< Data node of the tool tip preview void ShowToolTipPreview(mitk::NavigationData::Pointer ToolTipInTrackingCoordinates); //<<< Adds a preview of the tool tip into the data storage void RemoveToolTipPreview(); //<<< Removes the preview // members for the tool landmark calibration mitk::PointSet::Pointer m_CalibrationLandmarks; mitk::DataNode::Pointer m_CalibrationLandmarksNode; mitk::PointSet::Pointer m_RegistrationLandmarks; mitk::DataNode::Pointer m_RegistrationLandmarksNode; //members and helper methods for tool axis calibration mitk::Vector3D m_CalibratedToolAxis; mitk::NavigationData::Pointer m_AxisCalibration_ToolToCalibrate; mitk::NavigationData::Pointer m_AxisCalibration_NavDataCalibratingTool; }; #endif // IGTNavigationToolCalibration_h diff --git a/Plugins/org.mitk.gui.qt.igttracking/src/internal/IGTNavigationToolCalibrationControls.ui b/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkIGTNavigationToolCalibrationControls.ui similarity index 100% rename from Plugins/org.mitk.gui.qt.igttracking/src/internal/IGTNavigationToolCalibrationControls.ui rename to Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkIGTNavigationToolCalibrationControls.ui diff --git a/Plugins/org.mitk.gui.qt.igttracking/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.igttracking/src/internal/mitkPluginActivator.cpp index 757cde3e0e..8fd99a359c 100644 --- a/Plugins/org.mitk.gui.qt.igttracking/src/internal/mitkPluginActivator.cpp +++ b/Plugins/org.mitk.gui.qt.igttracking/src/internal/mitkPluginActivator.cpp @@ -1,58 +1,58 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkPluginActivator.h" #include "QmitkMITKIGTNavigationToolManagerView.h" #include "QmitkMITKIGTTrackingToolboxView.h" #include "QmitkNavigationDataPlayerView.h" -#include "IGTNavigationToolCalibration.h" -#include "IGTFiducialRegistration.h" +#include "QmitkIGTNavigationToolCalibration.h" +#include "QmitkIGTFiducialRegistration.h" //#include //Workaround for bug in persistence module (see bug 16643 for details) //CAN BE REMOVED WHEN THE BUG IS FIXED namespace mitk { ctkPluginContext* PluginActivator::m_Context = 0; void PluginActivator::start(ctkPluginContext* context) { // mitk::PersistenceService::LoadModule(); //Workaround for bug in persistence module (see bug 16643 for details) //CAN BE REMOVED WHEN THE BUG IS FIXED m_Context = context; BERRY_REGISTER_EXTENSION_CLASS(QmitkMITKIGTNavigationToolManagerView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkMITKIGTTrackingToolboxView , context) BERRY_REGISTER_EXTENSION_CLASS(QmitkNavigationDataPlayerView , context) - BERRY_REGISTER_EXTENSION_CLASS(IGTNavigationToolCalibration , context) - BERRY_REGISTER_EXTENSION_CLASS(IGTFiducialRegistration, context) + BERRY_REGISTER_EXTENSION_CLASS(QmitkIGTNavigationToolCalibration , context) + BERRY_REGISTER_EXTENSION_CLASS(QmitkIGTFiducialRegistration, context) } void PluginActivator::stop(ctkPluginContext* context) { m_Context = 0; Q_UNUSED(context) } ctkPluginContext *PluginActivator::GetContext() { return m_Context; } } diff --git a/Plugins/org.mitk.gui.qt.openigtlink/files.cmake b/Plugins/org.mitk.gui.qt.openigtlink/files.cmake index a3fdeecb71..06b5fa76b9 100644 --- a/Plugins/org.mitk.gui.qt.openigtlink/files.cmake +++ b/Plugins/org.mitk.gui.qt.openigtlink/files.cmake @@ -1,42 +1,42 @@ set(SRC_CPP_FILES ) set(INTERNAL_CPP_FILES org_mitk_gui_qt_openigtlink_Activator.cpp - OpenIGTLinkManager.cpp + QmitkOpenIGTLinkManager.cpp ) set(UI_FILES - src/internal/OpenIGTLinkManagerControls.ui + src/internal/QmitkOpenIGTLinkManagerControls.ui ) set(MOC_H_FILES src/internal/org_mitk_gui_qt_openigtlink_Activator.h - src/internal/OpenIGTLinkManager.h + src/internal/QmitkOpenIGTLinkManager.h ) # list of resource files which can be used by the plug-in # system without loading the plug-ins shared library, # for example the icon used in the menu and tabs for the # plug-in views in the workbench set(CACHED_RESOURCE_FILES resources/icon_openigtlink_manager.svg plugin.xml ) # list of Qt .qrc files which contain additional resources # specific to this plugin set(QRC_FILES ) set(CPP_FILES ) foreach(file ${SRC_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/${file}) endforeach(file ${SRC_CPP_FILES}) foreach(file ${INTERNAL_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/internal/${file}) endforeach(file ${INTERNAL_CPP_FILES}) diff --git a/Plugins/org.mitk.gui.qt.openigtlink/plugin.xml b/Plugins/org.mitk.gui.qt.openigtlink/plugin.xml index 5939c6ea0e..74a5b76fef 100644 --- a/Plugins/org.mitk.gui.qt.openigtlink/plugin.xml +++ b/Plugins/org.mitk.gui.qt.openigtlink/plugin.xml @@ -1,12 +1,12 @@ diff --git a/Plugins/org.mitk.gui.qt.openigtlink/src/internal/OpenIGTLinkManager.cpp b/Plugins/org.mitk.gui.qt.openigtlink/src/internal/QmitkOpenIGTLinkManager.cpp similarity index 84% rename from Plugins/org.mitk.gui.qt.openigtlink/src/internal/OpenIGTLinkManager.cpp rename to Plugins/org.mitk.gui.qt.openigtlink/src/internal/QmitkOpenIGTLinkManager.cpp index 238bf79625..3408d06bbd 100644 --- a/Plugins/org.mitk.gui.qt.openigtlink/src/internal/OpenIGTLinkManager.cpp +++ b/Plugins/org.mitk.gui.qt.openigtlink/src/internal/QmitkOpenIGTLinkManager.cpp @@ -1,87 +1,87 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ // Blueberry #include #include // -#include "OpenIGTLinkManager.h" +#include "QmitkOpenIGTLinkManager.h" -const std::string OpenIGTLinkManager::VIEW_ID = +const std::string QmitkOpenIGTLinkManager::VIEW_ID = "org.mitk.views.openigtlinkmanager"; -OpenIGTLinkManager::OpenIGTLinkManager() +QmitkOpenIGTLinkManager::QmitkOpenIGTLinkManager() : QmitkAbstractView() { } -OpenIGTLinkManager::~OpenIGTLinkManager() +QmitkOpenIGTLinkManager::~QmitkOpenIGTLinkManager() { for(unsigned int i=0; i < m_AllSourcesHandledByThisWidget.size(); i++) m_AllSourcesHandledByThisWidget.at(i)->UnRegisterMicroservice(); } -void OpenIGTLinkManager::SetFocus() +void QmitkOpenIGTLinkManager::SetFocus() { } -void OpenIGTLinkManager::CreateQtPartControl( QWidget *parent ) +void QmitkOpenIGTLinkManager::CreateQtPartControl( QWidget *parent ) { // create GUI widgets from the Qt Designer's .ui file m_Controls.setupUi( parent ); // create GUI widgets from the Qt Designer's .ui file // connect( (QObject*)(m_Controls.m_SourceManagerWidget), // SIGNAL(NewSourceAdded(mitk::IGTLDeviceSource::Pointer, std::string)), // this, // SLOT(NewSourceByWidget(mitk::IGTLDeviceSource::Pointer,std::string)) ); connect( (QObject*)(m_Controls.m_SourceListWidget), SIGNAL(IGTLDeviceSourceSelected(mitk::IGTLDeviceSource::Pointer)), this, SLOT(SourceSelected(mitk::IGTLDeviceSource::Pointer)) ); } -void OpenIGTLinkManager::NewSourceByWidget( +void QmitkOpenIGTLinkManager::NewSourceByWidget( mitk::IGTLDeviceSource::Pointer source,std::string /*sourceName*/) { source->RegisterAsMicroservice(/*sourceName*/); m_AllSourcesHandledByThisWidget.push_back(source); } -void OpenIGTLinkManager::SourceSelected( +void QmitkOpenIGTLinkManager::SourceSelected( mitk::IGTLDeviceSource::Pointer source) { if (source.IsNull()) //no source selected { //reset everything return; } m_CurrentIGTLDevice = source->GetIGTLDevice(); this->m_Controls.m_SourceManagerWidget->LoadSource(source); //check if the current selected source is also a message provider mitk::IGTLMessageProvider::Pointer currentMsgProvider = mitk::IGTLMessageProvider::New(); currentMsgProvider = dynamic_cast(source.GetPointer()); if(currentMsgProvider.IsNull()) return; this->m_Controls.m_StreamManagerWidget->LoadSource(currentMsgProvider); } diff --git a/Plugins/org.mitk.gui.qt.openigtlink/src/internal/OpenIGTLinkManager.h b/Plugins/org.mitk.gui.qt.openigtlink/src/internal/QmitkOpenIGTLinkManager.h similarity index 85% rename from Plugins/org.mitk.gui.qt.openigtlink/src/internal/OpenIGTLinkManager.h rename to Plugins/org.mitk.gui.qt.openigtlink/src/internal/QmitkOpenIGTLinkManager.h index 259daf2f09..65989cdbed 100644 --- a/Plugins/org.mitk.gui.qt.openigtlink/src/internal/OpenIGTLinkManager.h +++ b/Plugins/org.mitk.gui.qt.openigtlink/src/internal/QmitkOpenIGTLinkManager.h @@ -1,73 +1,73 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ -#ifndef OpenIGTLinkManager_h -#define OpenIGTLinkManager_h +#ifndef QmitkOpenIGTLinkManager_h +#define QmitkOpenIGTLinkManager_h #include #include -#include "ui_OpenIGTLinkManagerControls.h" +#include "ui_QmitkOpenIGTLinkManagerControls.h" #include "mitkIGTLClient.h" #include "mitkIGTLDeviceSource.h" /** \brief OpenIGTLinkManager \warning This class is not yet documented. Use "git blame" and ask the author to provide basic documentation. \sa QmitkAbstractView \ingroup ${plugin_target}_internal */ -class OpenIGTLinkManager : public QmitkAbstractView +class QmitkOpenIGTLinkManager : public QmitkAbstractView { // this is needed for all Qt objects that should have a Qt meta-object // (everything that derives from QObject and wants to have signal/slots) Q_OBJECT public: static const std::string VIEW_ID; - OpenIGTLinkManager(); - virtual ~OpenIGTLinkManager(); + QmitkOpenIGTLinkManager(); + virtual ~QmitkOpenIGTLinkManager(); public slots: void NewSourceByWidget(mitk::IGTLDeviceSource::Pointer source, std::string); void SourceSelected(mitk::IGTLDeviceSource::Pointer source); protected: virtual void CreateQtPartControl(QWidget *parent) override; virtual void SetFocus() override; void CreatePipeline(); void DestroyPipeline(); - Ui::OpenIGTLinkManagerControls m_Controls; + Ui::QmitkOpenIGTLinkManagerControls m_Controls; /** Someone needs to hold the smart pointers of new sources, otherwise the * objects will be lost although they are listed as microservice. */ std::vector m_AllSourcesHandledByThisWidget; mitk::IGTLDevice::Pointer m_CurrentIGTLDevice; }; #endif // OpenIGTLinkManager_h diff --git a/Plugins/org.mitk.gui.qt.openigtlink/src/internal/OpenIGTLinkManagerControls.ui b/Plugins/org.mitk.gui.qt.openigtlink/src/internal/QmitkOpenIGTLinkManagerControls.ui similarity index 98% rename from Plugins/org.mitk.gui.qt.openigtlink/src/internal/OpenIGTLinkManagerControls.ui rename to Plugins/org.mitk.gui.qt.openigtlink/src/internal/QmitkOpenIGTLinkManagerControls.ui index c112355b49..18f60b31e6 100644 --- a/Plugins/org.mitk.gui.qt.openigtlink/src/internal/OpenIGTLinkManagerControls.ui +++ b/Plugins/org.mitk.gui.qt.openigtlink/src/internal/QmitkOpenIGTLinkManagerControls.ui @@ -1,98 +1,98 @@ - OpenIGTLinkManagerControls + QmitkOpenIGTLinkManagerControls 0 0 668 392 0 0 QmitkTemplate 12 75 true Select OpenIGTLink device source: 12 75 true Manage device: 12 75 true Manage streams of selected device source: QmitkIGTLDeviceSourceSelectionWidget QTextEdit
QmitkIGTLDeviceSourceSelectionWidget.h
QmitkIGTLDeviceSourceManagementWidget QWidget
QmitkIGTLDeviceSourceManagementWidget.h
1
QmitkIGTLStreamingManagementWidget QWidget
QmitkIGTLStreamingManagementWidget.h
1
diff --git a/Plugins/org.mitk.gui.qt.openigtlink/src/internal/org_mitk_gui_qt_openigtlink_Activator.cpp b/Plugins/org.mitk.gui.qt.openigtlink/src/internal/org_mitk_gui_qt_openigtlink_Activator.cpp index b0d7b8304d..e69ad8b572 100644 --- a/Plugins/org.mitk.gui.qt.openigtlink/src/internal/org_mitk_gui_qt_openigtlink_Activator.cpp +++ b/Plugins/org.mitk.gui.qt.openigtlink/src/internal/org_mitk_gui_qt_openigtlink_Activator.cpp @@ -1,32 +1,32 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "org_mitk_gui_qt_openigtlink_Activator.h" -#include "OpenIGTLinkManager.h" +#include "QmitkOpenIGTLinkManager.h" namespace mitk { void org_mitk_gui_qt_openigtlink_Activator::start(ctkPluginContext* context) { - BERRY_REGISTER_EXTENSION_CLASS(OpenIGTLinkManager, context) + BERRY_REGISTER_EXTENSION_CLASS(QmitkOpenIGTLinkManager, context) } void org_mitk_gui_qt_openigtlink_Activator::stop(ctkPluginContext* context) { Q_UNUSED(context) } } diff --git a/Plugins/org.mitk.gui.qt.ultrasound/files.cmake b/Plugins/org.mitk.gui.qt.ultrasound/files.cmake index 0b3bc111a9..9f515ce496 100644 --- a/Plugins/org.mitk.gui.qt.ultrasound/files.cmake +++ b/Plugins/org.mitk.gui.qt.ultrasound/files.cmake @@ -1,43 +1,43 @@ set(SRC_CPP_FILES ) set(INTERNAL_CPP_FILES org_mitk_gui_qt_ultrasound_Activator.cpp - UltrasoundSupport.cpp + QmitkUltrasoundSupport.cpp ) set(UI_FILES - src/internal/UltrasoundSupportControls.ui + src/internal/QmitkUltrasoundSupportControls.ui ) set(MOC_H_FILES src/internal/org_mitk_gui_qt_ultrasound_Activator.h - src/internal/UltrasoundSupport.h + src/internal/QmitkUltrasoundSupport.h ) # list of resource files which can be used by the plug-in # system without loading the plug-ins shared library, # for example the icon used in the menu and tabs for the # plug-in views in the workbench set(CACHED_RESOURCE_FILES resources/icon_ultrasound.svg plugin.xml ) # list of Qt .qrc files which contain additional resources # specific to this plugin set(QRC_FILES ) set(CPP_FILES ) foreach(file ${SRC_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/${file}) endforeach(file ${SRC_CPP_FILES}) foreach(file ${INTERNAL_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/internal/${file}) endforeach(file ${INTERNAL_CPP_FILES}) diff --git a/Plugins/org.mitk.gui.qt.ultrasound/plugin.xml b/Plugins/org.mitk.gui.qt.ultrasound/plugin.xml index 76d4e2c4d1..c7b513827a 100644 --- a/Plugins/org.mitk.gui.qt.ultrasound/plugin.xml +++ b/Plugins/org.mitk.gui.qt.ultrasound/plugin.xml @@ -1,11 +1,11 @@ diff --git a/Plugins/org.mitk.gui.qt.ultrasound/src/internal/UltrasoundSupport.cpp b/Plugins/org.mitk.gui.qt.ultrasound/src/internal/QmitkUltrasoundSupport.cpp similarity index 93% rename from Plugins/org.mitk.gui.qt.ultrasound/src/internal/UltrasoundSupport.cpp rename to Plugins/org.mitk.gui.qt.ultrasound/src/internal/QmitkUltrasoundSupport.cpp index 26af2211b7..1d491333e2 100644 --- a/Plugins/org.mitk.gui.qt.ultrasound/src/internal/UltrasoundSupport.cpp +++ b/Plugins/org.mitk.gui.qt.ultrasound/src/internal/QmitkUltrasoundSupport.cpp @@ -1,697 +1,697 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ // Blueberry #include #include #include //Mitk #include #include #include #include #include #include #include #include "QmitkRegisterClasses.h" #include "QmitkRenderWindow.h" #include #include // Qmitk -#include "UltrasoundSupport.h" +#include "QmitkUltrasoundSupport.h" // Qt #include #include #include // Ultrasound #include "mitkUSDevice.h" #include "QmitkUSAbstractCustomWidget.h" #include #include #include "usServiceReference.h" #include "internal/org_mitk_gui_qt_ultrasound_Activator.h" #include "mitkNodePredicateDataType.h" #include -const std::string UltrasoundSupport::VIEW_ID = "org.mitk.views.ultrasoundsupport"; +const std::string QmitkUltrasoundSupport::VIEW_ID = "org.mitk.views.ultrasoundsupport"; -void UltrasoundSupport::SetFocus() +void QmitkUltrasoundSupport::SetFocus() { } -void UltrasoundSupport::CreateQtPartControl(QWidget *parent) +void QmitkUltrasoundSupport::CreateQtPartControl(QWidget *parent) { //initialize timers m_UpdateTimer = new QTimer(this); m_RenderingTimer2d = new QTimer(this); m_RenderingTimer3d = new QTimer(this); // create GUI widgets from the Qt Designer's .ui file m_Controls.setupUi(parent); //load persistence data before connecting slots (so no slots are called in this phase...) LoadUISettings(); //connect signals and slots... connect(m_Controls.m_DeviceManagerWidget, SIGNAL(NewDeviceButtonClicked()), this, SLOT(OnClickedAddNewDevice())); // Change Widget Visibilities connect(m_Controls.m_DeviceManagerWidget, SIGNAL(NewDeviceButtonClicked()), this->m_Controls.m_NewVideoDeviceWidget, SLOT(CreateNewDevice())); // Init NewDeviceWidget connect(m_Controls.m_ActiveVideoDevices, SIGNAL(ServiceSelectionChanged(us::ServiceReferenceU)), this, SLOT(OnChangedActiveDevice())); connect(m_Controls.m_RunImageTimer, SIGNAL(clicked()), this, SLOT(OnChangedActiveDevice())); connect(m_Controls.m_ShowImageStream, SIGNAL(clicked()), this, SLOT(OnChangedActiveDevice())); connect(m_Controls.m_NewVideoDeviceWidget, SIGNAL(Finished()), this, SLOT(OnNewDeviceWidgetDone())); // After NewDeviceWidget finished editing connect(m_Controls.m_FrameRatePipeline, SIGNAL(valueChanged(int)), this, SLOT(OnChangedFramerateLimit())); connect(m_Controls.m_FrameRate2d, SIGNAL(valueChanged(int)), this, SLOT(OnChangedFramerateLimit())); connect(m_Controls.m_FrameRate3d, SIGNAL(valueChanged(int)), this, SLOT(OnChangedFramerateLimit())); connect(m_Controls.m_FreezeButton, SIGNAL(clicked()), this, SLOT(OnClickedFreezeButton())); connect(m_UpdateTimer, SIGNAL(timeout()), this, SLOT(UpdateImage())); connect(m_RenderingTimer2d, SIGNAL(timeout()), this, SLOT(RenderImage2d())); connect(m_RenderingTimer3d, SIGNAL(timeout()), this, SLOT(RenderImage3d())); connect(m_Controls.m_Update2DView, SIGNAL(clicked()), this, SLOT(StartTimers())); connect(m_Controls.m_Update3DView, SIGNAL(clicked()), this, SLOT(StartTimers())); connect(m_Controls.m_DeviceManagerWidget, SIGNAL(EditDeviceButtonClicked(mitk::USDevice::Pointer)), this, SLOT(OnClickedEditDevice())); //Change Widget Visibilities connect(m_Controls.m_DeviceManagerWidget, SIGNAL(EditDeviceButtonClicked(mitk::USDevice::Pointer)), this->m_Controls.m_NewVideoDeviceWidget, SLOT(EditDevice(mitk::USDevice::Pointer))); // Initializations m_Controls.m_NewVideoDeviceWidget->setVisible(false); std::string filter = "(&(" + us::ServiceConstants::OBJECTCLASS() + "=" + "org.mitk.services.UltrasoundDevice)(" + mitk::USDevice::GetPropertyKeys().US_PROPKEY_ISACTIVE + "=true))"; m_Controls.m_ActiveVideoDevices->Initialize( mitk::USDevice::GetPropertyKeys().US_PROPKEY_LABEL, filter); m_Controls.m_ActiveVideoDevices->SetAutomaticallySelectFirstEntry(true); m_FrameCounterPipeline = 0; m_FrameCounter2d = 0; m_FrameCounter3d = 0; m_Controls.tabWidget->setTabEnabled(1, false); } -void UltrasoundSupport::CreateWindows() +void QmitkUltrasoundSupport::CreateWindows() { auto pausViewer = GetSite()->GetWorkbenchWindow()->GetActivePage()->FindView("org.mitk.views.photoacoustics.pausviewer"); if (pausViewer != nullptr) { m_PausViewerView = dynamic_cast(pausViewer.GetPointer()); m_PausViewerView->SetPADataStorage(m_PADataStorage); m_PausViewerView->SetUSDataStorage(m_USDataStorage); m_PausViewerView->InitWindows(); m_PausViewerView->SetUltrasoundReference(&m_PausViewerView); UpdateLevelWindows(); m_ForceRequestUpdateAll = true; } } -void UltrasoundSupport::InitNewNode() +void QmitkUltrasoundSupport::InitNewNode() { m_Node.push_back(nullptr); auto& Node = m_Node.back(); Node = mitk::DataNode::New(); Node->SetName("No Data received yet ..."); //create a dummy image (gray values 0..255) for correct initialization of level window, etc. mitk::Image::Pointer dummyImage = mitk::ImageGenerator::GenerateRandomImage(100, 100, 1, 1, 1, 1, 1, 255, 0); Node->SetData(dummyImage); m_OldGeometry = dynamic_cast(dummyImage->GetGeometry()); // Add to Control Datastorage this->GetDataStorage()->Add(Node); // Add to Display Datastorage if (m_Node.size() > 1) m_USDataStorage->Add(Node); else if (m_Node.size() == 1) m_PADataStorage->Add(Node); } -void UltrasoundSupport::DestroyLastNode() +void QmitkUltrasoundSupport::DestroyLastNode() { auto& Node = m_Node.back(); // Remove from Control Datastorage this->GetDataStorage()->Remove(Node); // Remove from Display Datastorage if (m_Node.size() > 1) m_USDataStorage->Remove(Node); else if (m_Node.size() == 1) m_PADataStorage->Remove(Node); // clean up Node->ReleaseData(); m_Node.pop_back(); } -void UltrasoundSupport::UpdateLevelWindows() +void QmitkUltrasoundSupport::UpdateLevelWindows() { mitk::LevelWindow levelWindow; if (m_Node.size() > 1) { for (unsigned int index = 0; index < m_AmountOfOutputs; ++index) { m_Node.at(index)->GetLevelWindow(levelWindow); if (!m_curOutput.at(index)->IsEmpty()) //levelWindow.SetWindowBounds(0, 4 * (index+1)); levelWindow.SetToImageRange(m_curOutput.at(index)); m_Node.at(index)->SetLevelWindow(levelWindow); } } else if (m_Node.size() == 1) { m_Node.back()->GetLevelWindow(levelWindow); if (!m_curOutput.at(0)->IsEmpty()) levelWindow.SetToImageRange(m_curOutput.at(0)); m_Node.back()->SetLevelWindow(levelWindow); } } -void UltrasoundSupport::SetColormap(mitk::DataNode::Pointer node, mitk::LookupTable::LookupTableType type) +void QmitkUltrasoundSupport::SetColormap(mitk::DataNode::Pointer node, mitk::LookupTable::LookupTableType type) { // consider removing this, unused for now, and probably forever mitk::LookupTable::Pointer lookupTable = mitk::LookupTable::New(); mitk::LookupTableProperty::Pointer lookupTableProperty = mitk::LookupTableProperty::New(); lookupTable->SetType(type); lookupTableProperty->SetLookupTable(lookupTable); node->SetProperty("LookupTable", lookupTableProperty); mitk::RenderingModeProperty::Pointer renderingMode = dynamic_cast(node->GetProperty("Image Rendering.Mode")); renderingMode->SetValue(mitk::RenderingModeProperty::LOOKUPTABLE_LEVELWINDOW_COLOR); } -void UltrasoundSupport::OnClickedAddNewDevice() +void QmitkUltrasoundSupport::OnClickedAddNewDevice() { m_Controls.m_NewVideoDeviceWidget->setVisible(true); m_Controls.m_DeviceManagerWidget->setVisible(false); m_Controls.m_Headline->setText("Add New Video Device:"); m_Controls.m_WidgetActiveDevices->setVisible(false); } -void UltrasoundSupport::OnClickedEditDevice() +void QmitkUltrasoundSupport::OnClickedEditDevice() { m_Controls.m_NewVideoDeviceWidget->setVisible(true); m_Controls.m_DeviceManagerWidget->setVisible(false); m_Controls.m_WidgetActiveDevices->setVisible(false); m_Controls.m_Headline->setText("Edit Video Device:"); } -void UltrasoundSupport::UpdateAmountOfOutputs() +void QmitkUltrasoundSupport::UpdateAmountOfOutputs() { // Update the amount of Nodes; there should be one Node for every slide that is set. Note that we must check whether the slices are set, // just using the m_Image->dimension(3) will produce nullpointers on slices of the image that were not set bool isSet = true; m_AmountOfOutputs = 0; while (isSet) { isSet = m_Image->IsSliceSet(m_AmountOfOutputs); if (isSet) ++m_AmountOfOutputs; } // correct the amount of Nodes to display data while (m_Node.size() < m_AmountOfOutputs) { InitNewNode(); } while (m_Node.size() > m_AmountOfOutputs) { DestroyLastNode(); } // correct the amount of image outputs that we feed the nodes with while (m_curOutput.size() < m_AmountOfOutputs) { m_curOutput.push_back(mitk::Image::New()); // initialize the slice images as 2d images with the size of m_Images unsigned int* dimOld = m_Image->GetDimensions(); unsigned int dim[2] = { dimOld[0], dimOld[1] }; m_curOutput.back()->Initialize(m_Image->GetPixelType(), 2, dim); } while (m_curOutput.size() > m_AmountOfOutputs) { m_curOutput.pop_back(); } } -void UltrasoundSupport::UpdateImage() +void QmitkUltrasoundSupport::UpdateImage() { if(m_Controls.m_ShowImageStream->isChecked()) { m_Device->Modified(); m_Device->Update(); // Update device m_Image = m_Device->GetOutput(); // get the Image data to display UpdateAmountOfOutputs(); // create as many Nodes and Outputs as there are slices in m_Image if (m_AmountOfOutputs == 0) return; // if there is no image to be displayed, skip the rest of this method for (unsigned int index = 0; index < m_AmountOfOutputs; ++index) { if (m_curOutput.at(index)->GetDimension(0) != m_Image->GetDimension(0) || m_curOutput.at(index)->GetDimension(1) != m_Image->GetDimension(1) || m_curOutput.at(index)->GetDimension(2) != m_Image->GetDimension(2) || m_curOutput.at(index)->GetPixelType() != m_Image->GetPixelType()) { unsigned int* dimOld = m_Image->GetDimensions(); unsigned int dim[2] = { dimOld[0], dimOld[1]}; m_curOutput.at(index)->Initialize(m_Image->GetPixelType(), 2, dim); // if we switched image resolution or type the outputs must be reinitialized! } if (!m_Image->IsEmpty()) { mitk::ImageReadAccessor inputReadAccessor(m_Image, m_Image->GetSliceData(index,0,0,nullptr,mitk::Image::ReferenceMemory)); // just reference the slices, to get a small performance gain m_curOutput.at(index)->SetSlice(inputReadAccessor.GetData()); m_curOutput.at(index)->GetGeometry()->SetIndexToWorldTransform(m_Image->GetSlicedGeometry()->GetIndexToWorldTransform()); // Update the image Output with seperate slices } if (m_curOutput.at(index)->IsEmpty()) { m_Node.at(index)->SetName("No Data received yet ..."); // create a noise image for correct initialization of level window, etc. mitk::Image::Pointer randomImage = mitk::ImageGenerator::GenerateRandomImage(32, 32, 1, 1, 1, 1, 1, 255, 0); m_Node.at(index)->SetData(randomImage); m_curOutput.at(index)->SetGeometry(randomImage->GetGeometry()); } else { char name[30]; sprintf(name, "US Viewing Stream - Image %d", index); m_Node.at(index)->SetName(name); m_Node.at(index)->SetData(m_curOutput.at(index)); // set the name of the Output } } float eps = 0.000001f; // if the geometry changed: reinitialize the ultrasound image. we use the m_curOutput.at(0) to readjust the geometry if (((m_OldGeometry.IsNotNull()) && (m_curOutput.at(0)->GetGeometry() != nullptr)) && ( (abs(m_OldGeometry->GetSpacing()[0] - m_curOutput.at(0)->GetGeometry()->GetSpacing()[0]) > eps )|| (abs(m_OldGeometry->GetSpacing()[1] - m_curOutput.at(0)->GetGeometry()->GetSpacing()[1]) > eps )|| (abs(m_OldGeometry->GetCenter()[0] - m_curOutput.at(0)->GetGeometry()->GetCenter()[0]) > eps) || (abs(m_OldGeometry->GetCenter()[1] - m_curOutput.at(0)->GetGeometry()->GetCenter()[1]) > eps) || m_ForceRequestUpdateAll)) { MITK_INFO << "now"; mitk::IRenderWindowPart* renderWindow = this->GetRenderWindowPart(); if ((renderWindow != nullptr) && (m_curOutput.at(0)->GetTimeGeometry()->IsValid()) && (m_Controls.m_ShowImageStream->isChecked())) { renderWindow->GetRenderingManager()->InitializeViews( m_curOutput.at(0)->GetGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true); renderWindow->GetRenderingManager()->RequestUpdateAll(); } m_CurrentImageWidth = m_curOutput.at(0)->GetDimension(0); m_CurrentImageHeight = m_curOutput.at(0)->GetDimension(1); m_OldGeometry = dynamic_cast(m_curOutput.at(0)->GetGeometry()); UpdateLevelWindows(); m_ForceRequestUpdateAll = false; } } //Update frame counter m_FrameCounterPipeline++; if (m_FrameCounterPipeline >= 10) { // compute framerate of pipeline update int nMilliseconds = m_Clock.restart(); int fps = 10000.0f / (nMilliseconds); m_FPSPipeline = fps; m_FrameCounterPipeline = 0; // display lowest framerate in UI int lowestFPS = m_FPSPipeline; if (m_Controls.m_Update2DView->isChecked() && (m_FPS2d < lowestFPS)) { lowestFPS = m_FPS2d; } if (m_Controls.m_Update3DView->isChecked() && (m_FPS3d < lowestFPS)) { lowestFPS = m_FPS3d; } m_Controls.m_FramerateLabel->setText("Current Framerate: " + QString::number(lowestFPS) + " FPS"); } } -void UltrasoundSupport::RenderImage2d() +void QmitkUltrasoundSupport::RenderImage2d() { if (!m_Controls.m_Update2DView->isChecked()) return; if (m_PausViewerView != nullptr) { auto renderingManager = mitk::RenderingManager::GetInstance(); renderingManager->RequestUpdate(m_PausViewerView->GetPARenderWindow()); renderingManager->RequestUpdate(m_PausViewerView->GetUSRenderWindow()); } else { CreateWindows(); // try to check whether the PausViwer has been opened by now } //mitk::IRenderWindowPart* renderWindow = this->GetRenderWindowPart(); //renderWindow->GetRenderingManager()->RequestUpdate(mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget1"))->GetRenderWindow()); // TODO: figure out how to proceed with the standard display //this->RequestRenderWindowUpdate(mitk::RenderingManager::REQUEST_UPDATE_2DWINDOWS); m_FrameCounter2d++; if (m_FrameCounter2d >= 10) { // compute framerate of 2d render window update int nMilliseconds = m_Clock2d.restart(); int fps = 10000.0f / (nMilliseconds); m_FPS2d = fps; m_FrameCounter2d = 0; } } -void UltrasoundSupport::RenderImage3d() +void QmitkUltrasoundSupport::RenderImage3d() { if (!m_Controls.m_Update3DView->isChecked()) return; this->RequestRenderWindowUpdate(mitk::RenderingManager::REQUEST_UPDATE_3DWINDOWS); m_FrameCounter3d++; if (m_FrameCounter3d >= 10) { // compute framerate of 2d render window update int nMilliseconds = m_Clock3d.restart(); int fps = 10000.0f / (nMilliseconds); m_FPS3d = fps; m_FrameCounter3d = 0; } } -void UltrasoundSupport::OnChangedFramerateLimit() +void QmitkUltrasoundSupport::OnChangedFramerateLimit() { StopTimers(); int intervalPipeline = (1000 / m_Controls.m_FrameRatePipeline->value()); int interval2D = (1000 / m_Controls.m_FrameRate2d->value()); int interval3D = (1000 / m_Controls.m_FrameRate3d->value()); SetTimerIntervals(intervalPipeline, interval2D, interval3D); StartTimers(); } -void UltrasoundSupport::OnClickedFreezeButton() +void QmitkUltrasoundSupport::OnClickedFreezeButton() { if (m_Device.IsNull()) { MITK_WARN("UltrasoundSupport") << "Freeze button clicked though no device is selected."; return; } if (m_Device->GetIsFreezed()) { m_Device->SetIsFreezed(false); m_Controls.m_FreezeButton->setText("Freeze"); } else { m_Device->SetIsFreezed(true); m_Controls.m_FreezeButton->setText("Start Viewing Again"); } } -void UltrasoundSupport::OnChangedActiveDevice() +void QmitkUltrasoundSupport::OnChangedActiveDevice() { //clean up, delete nodes and stop timer StopTimers(); this->RemoveControlWidgets(); for (auto& Node : m_Node) { this->GetDataStorage()->Remove(Node); Node->ReleaseData(); } m_Node.clear(); // disconnect from the PausViewer m_PausViewerView = nullptr; //get current device, abort if it is invalid m_Device = m_Controls.m_ActiveVideoDevices->GetSelectedService(); if (m_Device.IsNull()) { m_Controls.tabWidget->setTabEnabled(1, false); return; } //create the widgets for this device and enable the widget tab this->CreateControlWidgets(); m_Controls.tabWidget->setTabEnabled(1, true); //start timer if (m_Controls.m_RunImageTimer->isChecked()) { int intervalPipeline = (1000 / m_Controls.m_FrameRatePipeline->value()); int interval2D = (1000 / m_Controls.m_FrameRate2d->value()); int interval3D = (1000 / m_Controls.m_FrameRate3d->value()); SetTimerIntervals(intervalPipeline, interval2D, interval3D); StartTimers(); m_Controls.m_TimerWidget->setEnabled(true); } else { m_Controls.m_TimerWidget->setEnabled(false); } // connect to PausViewer and Set it up CreateWindows(); } -void UltrasoundSupport::OnNewDeviceWidgetDone() +void QmitkUltrasoundSupport::OnNewDeviceWidgetDone() { m_Controls.m_NewVideoDeviceWidget->setVisible(false); m_Controls.m_DeviceManagerWidget->setVisible(true); m_Controls.m_Headline->setText("Ultrasound Devices:"); m_Controls.m_WidgetActiveDevices->setVisible(true); } -void UltrasoundSupport::CreateControlWidgets() +void QmitkUltrasoundSupport::CreateControlWidgets() { m_ControlProbesWidget = new QmitkUSControlsProbesWidget(m_Device->GetControlInterfaceProbes(), m_Controls.m_ToolBoxControlWidgets); m_Controls.probesWidgetContainer->addWidget(m_ControlProbesWidget); // create b mode widget for current device m_ControlBModeWidget = new QmitkUSControlsBModeWidget(m_Device->GetControlInterfaceBMode(), m_Controls.m_ToolBoxControlWidgets); if (m_Device->GetControlInterfaceBMode()) { m_Controls.m_ToolBoxControlWidgets->addItem(m_ControlBModeWidget, "B Mode Controls"); //m_Controls.m_ToolBoxControlWidgets->setItemEnabled(m_Controls.m_ToolBoxControlWidgets->count() - 1, false); } // create doppler widget for current device m_ControlDopplerWidget = new QmitkUSControlsDopplerWidget(m_Device->GetControlInterfaceDoppler(), m_Controls.m_ToolBoxControlWidgets); if (m_Device->GetControlInterfaceDoppler()) { m_Controls.m_ToolBoxControlWidgets->addItem(m_ControlDopplerWidget, "Doppler Controls"); //m_Controls.m_ToolBoxControlWidgets->setItemEnabled(m_Controls.m_ToolBoxControlWidgets->count() - 1, false); } ctkPluginContext* pluginContext = mitk::PluginActivator::GetContext(); if (pluginContext) { std::string filter = "(org.mitk.services.UltrasoundCustomWidget.deviceClass=" + m_Device->GetDeviceClass() + ")"; QString interfaceName = QString::fromStdString(us_service_interface_iid()); m_CustomWidgetServiceReference = pluginContext->getServiceReferences(interfaceName, QString::fromStdString(filter)); if (m_CustomWidgetServiceReference.size() > 0) { m_ControlCustomWidget = pluginContext->getService (m_CustomWidgetServiceReference.at(0))->CloneForQt(m_Controls.tab2); m_ControlCustomWidget->SetDevice(m_Device); m_Controls.m_ToolBoxControlWidgets->addItem(m_ControlCustomWidget, "Custom Controls"); } else { m_Controls.m_ToolBoxControlWidgets->addItem(new QWidget(m_Controls.m_ToolBoxControlWidgets), "Custom Controls"); m_Controls.m_ToolBoxControlWidgets->setItemEnabled(m_Controls.m_ToolBoxControlWidgets->count() - 1, false); } } // select first enabled control widget for (int n = 0; n < m_Controls.m_ToolBoxControlWidgets->count(); ++n) { if (m_Controls.m_ToolBoxControlWidgets->isItemEnabled(n)) { m_Controls.m_ToolBoxControlWidgets->setCurrentIndex(n); break; } } } -void UltrasoundSupport::RemoveControlWidgets() +void QmitkUltrasoundSupport::RemoveControlWidgets() { if (!m_ControlProbesWidget) { return; } //widgets do not exist... nothing to do // remove all control widgets from the tool box widget while (m_Controls.m_ToolBoxControlWidgets->count() > 0) { m_Controls.m_ToolBoxControlWidgets->removeItem(0); } // remove probes widget (which is not part of the tool box widget) m_Controls.probesWidgetContainer->removeWidget(m_ControlProbesWidget); delete m_ControlProbesWidget; m_ControlProbesWidget = 0; delete m_ControlBModeWidget; m_ControlBModeWidget = 0; delete m_ControlDopplerWidget; m_ControlDopplerWidget = 0; // delete custom widget if it is present if (m_ControlCustomWidget) { ctkPluginContext* pluginContext = mitk::PluginActivator::GetContext(); delete m_ControlCustomWidget; m_ControlCustomWidget = 0; if (m_CustomWidgetServiceReference.size() > 0) { pluginContext->ungetService(m_CustomWidgetServiceReference.at(0)); } } } -void UltrasoundSupport::OnDeciveServiceEvent(const ctkServiceEvent event) +void QmitkUltrasoundSupport::OnDeciveServiceEvent(const ctkServiceEvent event) { if (m_Device.IsNull() || event.getType() != static_cast(us::ServiceEvent::MODIFIED)) { return; } ctkServiceReference service = event.getServiceReference(); if (m_Device->GetManufacturer() != service.getProperty(QString::fromStdString(mitk::USDevice::GetPropertyKeys().US_PROPKEY_MANUFACTURER)).toString().toStdString() && m_Device->GetName() != service.getProperty(QString::fromStdString(mitk::USDevice::GetPropertyKeys().US_PROPKEY_NAME)).toString().toStdString()) { return; } if (!m_Device->GetIsActive() && m_UpdateTimer->isActive()) { StopTimers(); } if (m_CurrentDynamicRange != service.getProperty(QString::fromStdString(mitk::USDevice::GetPropertyKeys().US_PROPKEY_BMODE_DYNAMIC_RANGE)).toDouble()) { m_CurrentDynamicRange = service.getProperty(QString::fromStdString(mitk::USDevice::GetPropertyKeys().US_PROPKEY_BMODE_DYNAMIC_RANGE)).toDouble(); // update level window for the current dynamic range mitk::LevelWindow levelWindow; for (auto& Node : m_Node) { Node->GetLevelWindow(levelWindow); levelWindow.SetAuto(m_Image, true, true); levelWindow.SetWindowBounds(55, 125,true); Node->SetLevelWindow(levelWindow); } } } -UltrasoundSupport::UltrasoundSupport() +QmitkUltrasoundSupport::QmitkUltrasoundSupport() : m_ControlCustomWidget(0), m_ControlBModeWidget(0), m_ControlProbesWidget(0), m_ImageAlreadySetToNode(false), m_CurrentImageWidth(0), m_CurrentImageHeight(0), m_AmountOfOutputs(0), m_PADataStorage(mitk::StandaloneDataStorage::New()), m_USDataStorage(mitk::StandaloneDataStorage::New()), m_ForceRequestUpdateAll(false) { ctkPluginContext* pluginContext = mitk::PluginActivator::GetContext(); if (pluginContext) { // to be notified about service event of an USDevice pluginContext->connectServiceListener(this, "OnDeciveServiceEvent", QString::fromStdString("(" + us::ServiceConstants::OBJECTCLASS() + "=" + us_service_interface_iid() + ")")); } } -UltrasoundSupport::~UltrasoundSupport() +QmitkUltrasoundSupport::~QmitkUltrasoundSupport() { try { StoreUISettings(); StopTimers(); // Get all active devicesand deactivate them to prevent freeze for (auto device : this->m_Controls.m_ActiveVideoDevices->GetAllServices()) { if (device != nullptr && device->GetIsActive()) { device->Deactivate(); device->Disconnect(); } } } catch (std::exception &e) { MITK_ERROR << "Exception during call of destructor! Message: " << e.what(); } } -void UltrasoundSupport::StoreUISettings() +void QmitkUltrasoundSupport::StoreUISettings() { QSettings settings; settings.beginGroup(QString::fromStdString(VIEW_ID)); settings.setValue("DisplayImage", QVariant(m_Controls.m_ShowImageStream->isChecked())); settings.setValue("RunImageTimer", QVariant(m_Controls.m_RunImageTimer->isChecked())); settings.setValue("Update2DView", QVariant(m_Controls.m_Update2DView->isChecked())); settings.setValue("Update3DView", QVariant(m_Controls.m_Update3DView->isChecked())); settings.setValue("UpdateRatePipeline", QVariant(m_Controls.m_FrameRatePipeline->value())); settings.setValue("UpdateRate2d", QVariant(m_Controls.m_FrameRate2d->value())); settings.setValue("UpdateRate3d", QVariant(m_Controls.m_FrameRate3d->value())); settings.endGroup(); } -void UltrasoundSupport::LoadUISettings() +void QmitkUltrasoundSupport::LoadUISettings() { QSettings settings; settings.beginGroup(QString::fromStdString(VIEW_ID)); m_Controls.m_ShowImageStream->setChecked(settings.value("DisplayImage", true).toBool()); m_Controls.m_RunImageTimer->setChecked(settings.value("RunImageTimer", true).toBool()); m_Controls.m_Update2DView->setChecked(settings.value("Update2DView", true).toBool()); m_Controls.m_Update3DView->setChecked(settings.value("Update3DView", true).toBool()); m_Controls.m_FrameRatePipeline->setValue(settings.value("UpdateRatePipeline", 50).toInt()); m_Controls.m_FrameRate2d->setValue(settings.value("UpdateRate2d", 20).toInt()); m_Controls.m_FrameRate3d->setValue(settings.value("UpdateRate3d", 5).toInt()); settings.endGroup(); } -void UltrasoundSupport::StartTimers() +void QmitkUltrasoundSupport::StartTimers() { m_UpdateTimer->start(); if (m_Controls.m_Update2DView->isChecked()) { m_RenderingTimer2d->start(); } if (m_Controls.m_Update3DView->isChecked()) { m_RenderingTimer3d->start(); } } -void UltrasoundSupport::StopTimers() +void QmitkUltrasoundSupport::StopTimers() { m_UpdateTimer->stop(); m_RenderingTimer2d->stop(); m_RenderingTimer3d->stop(); } -void UltrasoundSupport::SetTimerIntervals(int intervalPipeline, int interval2D, int interval3D) +void QmitkUltrasoundSupport::SetTimerIntervals(int intervalPipeline, int interval2D, int interval3D) { m_UpdateTimer->setInterval(intervalPipeline); m_RenderingTimer2d->setInterval(interval2D); m_RenderingTimer3d->setInterval(interval3D); } diff --git a/Plugins/org.mitk.gui.qt.ultrasound/src/internal/UltrasoundSupport.h b/Plugins/org.mitk.gui.qt.ultrasound/src/internal/QmitkUltrasoundSupport.h similarity index 95% rename from Plugins/org.mitk.gui.qt.ultrasound/src/internal/UltrasoundSupport.h rename to Plugins/org.mitk.gui.qt.ultrasound/src/internal/QmitkUltrasoundSupport.h index e8022bcabb..a404b8851d 100644 --- a/Plugins/org.mitk.gui.qt.ultrasound/src/internal/UltrasoundSupport.h +++ b/Plugins/org.mitk.gui.qt.ultrasound/src/internal/QmitkUltrasoundSupport.h @@ -1,186 +1,186 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ -#ifndef UltrasoundSupport_h -#define UltrasoundSupport_h +#ifndef QmitkUltrasoundSupport_h +#define QmitkUltrasoundSupport_h #include #include #include #include -#include "ui_UltrasoundSupportControls.h" +#include "ui_QmitkUltrasoundSupportControls.h" #include "QmitkUSAbstractCustomWidget.h" #include "QmitkUSControlsBModeWidget.h" #include "QmitkUSControlsDopplerWidget.h" #include "QmitkUSControlsProbesWidget.h" #include #include "QmitkRenderWindow.h" #include #include #include #include #include #include /*! \brief UltrasoundSupport This plugin provides functionality to manage Ultrasound devices, create video devices and to view device images. \ingroup ${plugin_target}_internal */ -class UltrasoundSupport : public QmitkAbstractView +class QmitkUltrasoundSupport : public QmitkAbstractView { // this is needed for all Qt objects that should have a Qt meta-object // (everything that derives from QObject and wants to have signal/slots) Q_OBJECT public: virtual void SetFocus() override; static const std::string VIEW_ID; virtual void CreateQtPartControl(QWidget *parent) override; - UltrasoundSupport(); - virtual ~UltrasoundSupport(); + QmitkUltrasoundSupport(); + virtual ~QmitkUltrasoundSupport(); public slots: /* * \brief This is called when the newDeviceWidget is closed */ void OnNewDeviceWidgetDone(); protected slots: void OnClickedAddNewDevice(); void OnChangedFramerateLimit(); void OnClickedEditDevice(); /* *\brief Called, when the selection in the list of the active devices changes. */ void OnChangedActiveDevice(); void OnClickedFreezeButton(); void OnDeciveServiceEvent(const ctkServiceEvent event); /* * \brief This is the main imaging loop that updates the image and is called regularily during the imaging process */ void UpdateImage(); void RenderImage2d(); void RenderImage3d(); void StartTimers(); void StopTimers(); protected: void CreateControlWidgets(); void RemoveControlWidgets(); void CreateWindows(); QmitkPAUSViewerView* m_PausViewerView; Ui::UltrasoundSupportControls m_Controls; QmitkUSAbstractCustomWidget* m_ControlCustomWidget; QmitkUSControlsBModeWidget* m_ControlBModeWidget; QmitkUSControlsDopplerWidget* m_ControlDopplerWidget; QmitkUSControlsProbesWidget* m_ControlProbesWidget; bool m_ImageAlreadySetToNode; unsigned int m_CurrentImageWidth; unsigned int m_CurrentImageHeight; /** Keeps track of the amount of output Nodes*/ unsigned int m_AmountOfOutputs; mitk::StandaloneDataStorage::Pointer m_PADataStorage; mitk::StandaloneDataStorage::Pointer m_USDataStorage; /** The device that is currently used to aquire images */ mitk::USDevice::Pointer m_Device; void SetTimerIntervals(int intervalPipeline, int interval2D, int interval3D); /** This timer triggers periodic updates to the pipeline */ QTimer* m_UpdateTimer; QTimer* m_RenderingTimer2d; QTimer* m_RenderingTimer3d; /** These clocks are used to compute the framerate in the methods DisplayImage(),RenderImage2d() and RenderImage3d(). */ QTime m_Clock; QTime m_Clock2d; QTime m_Clock3d; /** A counter to comute the framerate. */ int m_FrameCounterPipeline; int m_FrameCounter2d; int m_FrameCounter3d; int m_FPSPipeline, m_FPS2d, m_FPS3d; /** Stores the properties of some QWidgets (and the tool storage file name) to QSettings.*/ void StoreUISettings(); /** Loads the properties of some QWidgets (and the tool storage file name) from QSettings.*/ void LoadUISettings(); /** The nodes that we feed images into.*/ std::vector m_Node; /** Adds a new node to the m_Nodes vector*/ void InitNewNode(); /** Destroys the last node in the m_Nodes vector */ void DestroyLastNode(); /** Checks the amount of slices in the image from the USDevice and creates as many Nodes as there are slices */ void UpdateAmountOfOutputs(); /** This function just checks how many nodes there are currently and sets the laser image to a jet transparent colormap. */ void UpdateLevelWindows(); bool m_ForceRequestUpdateAll; void SetColormap(mitk::DataNode::Pointer node, mitk::LookupTable::LookupTableType type); /** The image that holds all data given by the USDevice.*/ mitk::Image::Pointer m_Image; /** The seperated slices from m_Image */ std::vector m_curOutput; /** The old geometry of m_Image. It is needed to check if the geometry changed (e.g. because * the zoom factor was modified) and the image needs to be reinitialized. */ mitk::SlicedGeometry3D::Pointer m_OldGeometry; QList m_CustomWidgetServiceReference; double m_CurrentDynamicRange; }; #endif // UltrasoundSupport_h diff --git a/Plugins/org.mitk.gui.qt.ultrasound/src/internal/UltrasoundSupportControls.ui b/Plugins/org.mitk.gui.qt.ultrasound/src/internal/QmitkUltrasoundSupportControls.ui similarity index 100% rename from Plugins/org.mitk.gui.qt.ultrasound/src/internal/UltrasoundSupportControls.ui rename to Plugins/org.mitk.gui.qt.ultrasound/src/internal/QmitkUltrasoundSupportControls.ui diff --git a/Plugins/org.mitk.gui.qt.ultrasound/src/internal/org_mitk_gui_qt_ultrasound_Activator.cpp b/Plugins/org.mitk.gui.qt.ultrasound/src/internal/org_mitk_gui_qt_ultrasound_Activator.cpp index 1f2542778e..bd24bbef26 100644 --- a/Plugins/org.mitk.gui.qt.ultrasound/src/internal/org_mitk_gui_qt_ultrasound_Activator.cpp +++ b/Plugins/org.mitk.gui.qt.ultrasound/src/internal/org_mitk_gui_qt_ultrasound_Activator.cpp @@ -1,44 +1,44 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. -All rights reserved. +All rights reserved.#include "QmitkUltrasoundSupport.h" This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "org_mitk_gui_qt_ultrasound_Activator.h" -#include "UltrasoundSupport.h" +#include "QmitkUltrasoundSupport.h" namespace mitk { ctkPluginContext* org_mitk_gui_qt_ultrasound_Activator::m_Context = 0; void org_mitk_gui_qt_ultrasound_Activator::start(ctkPluginContext* context) { m_Context = context; - BERRY_REGISTER_EXTENSION_CLASS(UltrasoundSupport, context) + BERRY_REGISTER_EXTENSION_CLASS(QmitkUltrasoundSupport, context) } void org_mitk_gui_qt_ultrasound_Activator::stop(ctkPluginContext* context) { m_Context = 0; Q_UNUSED(context) } ctkPluginContext *org_mitk_gui_qt_ultrasound_Activator::GetContext() { return m_Context; } }