diff --git a/Plugins/org.mitk.gui.qt.igt.app.echotrack/CMakeLists.txt b/Plugins/org.mitk.gui.qt.igt.app.echotrack/CMakeLists.txt
index 53b8a44ceb..28dfd3d235 100644
--- a/Plugins/org.mitk.gui.qt.igt.app.echotrack/CMakeLists.txt
+++ b/Plugins/org.mitk.gui.qt.igt.app.echotrack/CMakeLists.txt
@@ -1,16 +1,16 @@
-project(org_mitk_gui_qt_igtappechotrack)
+project(org_mitk_gui_qt_igt_app_echotrack)
-MACRO_CREATE_MITK_CTK_PLUGIN(
+mitk_create_plugin(
EXPORT_DIRECTIVE IGTAPPECHOTRACK_EXPORT
EXPORTED_INCLUDE_SUFFIXES src
PACKAGE_DEPENDS CTK Poco
MODULE_DEPENDS MitkUSUI MitkUSNavigation MitkIGTUI MitkSceneSerialization MitkContourModel
)
#usFunctionAddResources(TARGET ${PLUGIN_TARGET}
# MODULE_NAME liborg_mitk_gui_qt_usnavigation
# WORKING_DIRECTORY resources
# FILES Interactions/USPointMarkInteractions.xml
# Interactions/USZoneInteractions.xml
# Interactions/USZoneInteractionsHold.xml
#)
diff --git a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/NavigationStepWidgets/QmitkUSNavigationStepCombinedModality.ui b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/NavigationStepWidgets/QmitkUSNavigationStepCombinedModality.ui
index a65c698b89..e7f25ad991 100644
--- a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/NavigationStepWidgets/QmitkUSNavigationStepCombinedModality.ui
+++ b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/NavigationStepWidgets/QmitkUSNavigationStepCombinedModality.ui
@@ -1,398 +1,398 @@
QmitkUSNavigationStepCombinedModality
0
0
286
339
0
300
Form
-
Available Combined Modalities
- Qt::AlignCenter
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
-
0
0
0
0
-
-
Create New Combined Modality
:/USNavigation/plus.png:/USNavigation/plus.png
-
false
Delete Selected Combined Modality
:/USNavigation/minus.png:/USNavigation/minus.png
-
false
Edit Selected Combined Modality
:/USNavigation/preferences.png:/USNavigation/preferences.png
-
false
Disconnect Selected Combined Modality
:/USNavigation/process-stop.png:/USNavigation/process-stop.png
-
Qt::Horizontal
40
20
-
Qt::Horizontal
40
20
-
false
Activate Selected Combined Modality
:/USNavigation/accept.png:/USNavigation/accept.png
-
Qt::Vertical
QSizePolicy::Fixed
20
13
-
8
<html><head/><body><p>Select a Combined Modality from the list above or create a new one first. A calibration file must be loaded if the Combined Modality isn't calibrated already. Calibrations can be managed by hitting the <span style=" text-decoration: underline;">Edit</span> button above.</p><p>You can proceed by hitting the <span style=" text-decoration: underline;">Next</span> button.</p></body></html>
true
-
Qt::Vertical
QSizePolicy::Fixed
20
13
-
-
-
false
Calibration
-
true
Selected device is not calibrated.
Qt::AlignCenter
true
-
0
0
0
0
&Load Calibration
:/USNavigation/document-open.png:/USNavigation/document-open.png
QmitkUSCombinedModalityCreationWidget
QWidget
src/internal/Widgets/QmitkUSCombinedModalityCreationWidget.h
1
QmitkServiceListWidget
QWidget
1
QmitkUSCombinedModalityEditWidget
QWidget
src/internal/Widgets/QmitkUSCombinedModalityEditWidget.h
1
calibrationLoadButton
clicked()
QmitkUSNavigationStepCombinedModality
OnLoadCalibration()
142
268
142
149
combinedModalityCreateButton
clicked()
QmitkUSNavigationStepCombinedModality
OnCombinedModalityCreateNewButtonClicked()
52
73
142
149
combinedModalityDeleteButton
clicked()
QmitkUSNavigationStepCombinedModality
OnDeleteButtonClicked()
112
73
142
149
combinedModalityDistconnectButton
clicked()
QmitkUSNavigationStepCombinedModality
OnDisconnectButtonClicked()
232
73
142
149
combinedModalitEditButton
clicked()
QmitkUSNavigationStepCombinedModality
OnCombinedModalityEditButtonClicked()
172
73
142
149
combinedModalityActivateButton
clicked()
QmitkUSNavigationStepCombinedModality
OnActivateButtonClicked()
235
60
142
149
OnCombinedModalityCreateNewButtonClicked()
OnDeleteButtonClicked()
OnLoadCalibration()
OnDisconnectButtonClicked()
OnCombinedModalityEditButtonClicked()
OnActivateButtonClicked()
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 8ae75aadd8..ce0c46942d 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,266 +1,267 @@
/*===================================================================
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 "usModuleRegistry.h"
#include
QmitkUSNavigationStepPunctuationIntervention::QmitkUSNavigationStepPunctuationIntervention(QWidget *parent) :
QmitkUSAbstractNavigationStep(parent),
m_NeedleProjectionFilter(mitk::NeedleProjectionFilter::New()),
ui(new Ui::QmitkUSNavigationStepPunctuationIntervention),
m_SphereSource(vtkSmartPointer::New()),
m_OBBTree(vtkSmartPointer::New()),
m_IntersectPoints(vtkSmartPointer::New())
{
ui->setupUi(this);
connect(ui->m_AddNewAblationZone, SIGNAL(clicked()), this, SLOT(OnAddAblationZoneClicked()));
connect(ui->m_EnableAblationMarking, SIGNAL(clicked()), this, SLOT(OnEnableAblationZoneMarkingClicked()));
connect(ui->m_AblationZoneSizeSlider, SIGNAL(valueChanged(int)), this, SLOT(OnAblationZoneSizeSliderChanged(int)));
+ ui->m_AblationZonesBox->setVisible(false);
}
void QmitkUSNavigationStepPunctuationIntervention::OnEnableAblationZoneMarkingClicked()
{
if(ui->m_EnableAblationMarking->isChecked())
- ui->m_AblationZonesBox->setEnabled(true);
+ ui->m_AblationZonesBox->setVisible(true);
else
- ui->m_AblationZonesBox->setEnabled(false);
+ ui->m_AblationZonesBox->setVisible(false);
}
void QmitkUSNavigationStepPunctuationIntervention::OnAblationZoneSizeSliderChanged(int size)
{
int id = ui->m_AblationZonesList->currentRow();
if (id!=-1) {emit AblationZoneChanged(id,size);}
}
void QmitkUSNavigationStepPunctuationIntervention::OnAddAblationZoneClicked()
{
QListWidgetItem* newItem = new QListWidgetItem("Ablation Zone (initial size: " + QString::number(ui->m_AblationZoneSizeSlider->value()) + " mm)", ui->m_AblationZonesList);
newItem->setSelected(true);
emit AddAblationZoneClicked(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 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);
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));
// add zones to the widgets for risk structures
for (mitk::DataStorage::SetOfObjects::ConstIterator it = m_ZoneNodes->Begin();
it != m_ZoneNodes->End(); ++it)
{
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::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);
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()
{
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)
{
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->riskStructuresRangeGroupBox->setEnabled(valid);
}
void QmitkUSNavigationStepPunctuationIntervention::UpdateCriticalStructures(mitk::NavigationData::Pointer needle, mitk::PointSet::Pointer path)
{
// update the distances for the risk structures widget
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, NULL);
if (m_IntersectPoints->GetNumberOfPoints() > 0) {return true;}
else {return false;}
}
diff --git a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/NavigationStepWidgets/QmitkUSNavigationStepPunctuationIntervention.ui b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/NavigationStepWidgets/QmitkUSNavigationStepPunctuationIntervention.ui
index 110fb6de85..a3b454f70a 100644
--- a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/NavigationStepWidgets/QmitkUSNavigationStepPunctuationIntervention.ui
+++ b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/NavigationStepWidgets/QmitkUSNavigationStepPunctuationIntervention.ui
@@ -1,222 +1,222 @@
QmitkUSNavigationStepPunctuationIntervention
0
0
317
- 337
+ 393
Form
-
background-color: #ff7878; margin-right: 1em; margin-left: 1em;
border: 1px solid grey
Body marker is not inside the tracking volume.
Qt::AlignCenter
true
-
-
Distance Needle to US plane:
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
<not available>
-
Distances to Critical Structures
-
-
Enable Manual Ablation Zone Marking
-
- false
+ true
Ablation Zones
-
-
-
-
Size:
-
Qt::Vertical
20
40
-
-
100
10
Qt::Horizontal
QSlider::TicksBelow
10
-
-
0 cm
-
Qt::Horizontal
40
20
-
10 cm
-
-
Qt::Horizontal
40
20
-
Add New Ablation Zone
-
Qt::Vertical
20
40
QmitkUSNavigationZoneDistancesWidget
QWidget
src/internal/Widgets/QmitkUSNavigationZoneDistancesWidget.h
1
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 1bbdb96558..b1380808ff 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,260 +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"
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,
QmitkUSAbstractNavigationStep::DATANAME_BASENODE);
ui->zonesWidget->SetDataStorage(this->GetDataStorage(), USNavigationMarkerPlacement::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));
}
}
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/NavigationStepWidgets/QmitkUSNavigationStepZoneMarking.h b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/NavigationStepWidgets/QmitkUSNavigationStepZoneMarking.h
index 46eb1eb34b..6bdf3ded4e 100644
--- a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/NavigationStepWidgets/QmitkUSNavigationStepZoneMarking.h
+++ b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/NavigationStepWidgets/QmitkUSNavigationStepZoneMarking.h
@@ -1,132 +1,134 @@
/*===================================================================
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 QMITKUSNAVIGATIONSTEPZONEMARKING_H
#define QMITKUSNAVIGATIONSTEPZONEMARKING_H
#include "QmitkUSAbstractNavigationStep.h"
namespace itk {
template class SmartPointer;
}
namespace mitk {
class NodeDisplacementFilter;
class NavigationDataSource;
}
namespace Ui {
class QmitkUSNavigationStepZoneMarking;
}
/**
* \brief Navigation step for marking risk structures.
* The user can add risk structures by interacting with the render windows. The
* risk structures are organized in an embedded table view.
*
* The risk structures are stored under DATANAME_BASENODE -> DATANAME_ZONES.
*
* This step is ready for the next step directly after activating. All actions
* to be done in this step are optional.
*/
class QmitkUSNavigationStepZoneMarking : public QmitkUSAbstractNavigationStep
{
Q_OBJECT
protected slots:
void OnFreeze(bool freezed);
/**
* \brief Triggered when a risk zone was added.
* Adds the zone to a member variable and to the node displacement filter.
*/
void OnZoneAdded();
/**
* \brief Triggered when a risk zone was removed.
* Removes the zone from a member variable and from the node displacement
* filter.
*/
void OnZoneRemoved();
+ void OnShowListClicked(int state);
+
public:
explicit QmitkUSNavigationStepZoneMarking(QWidget *parent = 0);
~QmitkUSNavigationStepZoneMarking();
/**
* \brief Initialization of the data storage nodes.
* \return always true
*/
virtual bool OnStartStep();
/**
* \brief Resets widget and filter and removes nodes from the data storage.
* \return always true
*/
virtual bool OnStopStep();
/**
* \brief There is nothing to be done.
* \return always true
*/
virtual bool OnFinishStep();
/**
* \brief Selects input for the node displacement filter and emits "ReadyForNextStep" signal.
* The input selection cannot be done earlier.
* \return
*/
virtual bool OnActivateStep();
virtual bool OnDeactivateStep();
/**
* \brief Updates just the tracking validity status.
*/
virtual void OnUpdate();
/**
* The property "settings.interaction-concept" is used.
*/
virtual void OnSettingsChanged(const itk::SmartPointer settingsNode);
virtual QString GetTitle();
/**
* @return a node displacement filter for the zone surfaces
*/
virtual FilterVector GetFilter();
protected:
virtual void OnSetCombinedModality();
void UpdateReferenceSensorName();
itk::SmartPointer m_NavigationDataSource;
itk::SmartPointer m_ZoneDisplacementFilter;
std::vector > m_ZoneNodes;
std::string m_StateMachineFilename;
std::string m_ReferenceSensorName;
unsigned int m_ReferenceSensorIndex;
bool m_CurrentlyAddingZone;
private:
Ui::QmitkUSNavigationStepZoneMarking *ui;
};
#endif // QMITKUSNAVIGATIONSTEPZONEMARKING_H
diff --git a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/NavigationStepWidgets/QmitkUSNavigationStepZoneMarking.ui b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/NavigationStepWidgets/QmitkUSNavigationStepZoneMarking.ui
index 8606d16885..d510c7a755 100644
--- a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/NavigationStepWidgets/QmitkUSNavigationStepZoneMarking.ui
+++ b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/NavigationStepWidgets/QmitkUSNavigationStepZoneMarking.ui
@@ -1,127 +1,147 @@
QmitkUSNavigationStepZoneMarking
0
0
400
395
Form
-
background-color: #ff7878; margin-right: 1em; margin-left: 1em;
border: 1px solid grey
Body marker is not inside the tracking volume.
Qt::AlignCenter
true
-
You can mark critical structures by navigating to them using the ultrasound probe and freezing the image.
true
-
-
false
<!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:7.8pt; font-weight:400; font-style:normal;">
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Now you can add a critical structure by clicking on its center in the ultrasound image, moving the mouse until the arc radius is as desired and clicking again then.</p></body></html>
true
-
Qt::Vertical
QSizePolicy::Fixed
20
20
-
-
+
+
+ Show critical structure list
+
+
+
+ -
+
0
0
Critical Structures
Qt::AlignCenter
-
0
0
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
QmitkUSZoneManagementWidget
QWidget
src/internal/Widgets/QmitkUSZoneManagementWidget.h
1
QmitkUSNavigationFreezeButton
QPushButton
src/internal/Widgets/QmitkUSNavigationFreezeButton.h
diff --git a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/QmitkUSNavigationPerspective.cpp b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/QmitkUSNavigationPerspective.cpp
index 70ba385845..aa06b99bf9 100644
--- a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/QmitkUSNavigationPerspective.cpp
+++ b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/QmitkUSNavigationPerspective.cpp
@@ -1,42 +1,31 @@
/*===================================================================
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 "QmitkUSNavigationPerspective.h"
QmitkUSNavigationPerspective::QmitkUSNavigationPerspective()
{
}
void QmitkUSNavigationPerspective::CreateInitialLayout (berry::IPageLayout::Pointer layout)
{
// place navigation plugin on the right side (not closable)
layout->AddStandaloneView("org.mitk.views.usmarkerplacement", false, berry::IPageLayout::RIGHT, 0.75f, layout->GetEditorArea());
// place tracking toolbox and ultrasound support on the left into a folder
// layout (closeable)
layout->AddStandaloneView("org.mitk.views.ultrasoundsupport", false, berry::IPageLayout::LEFT, 0.3f, layout->GetEditorArea());
layout->AddStandaloneView("org.mitk.views.mitkigttrackingtoolbox", false, berry::IPageLayout::BOTTOM, 0.9f, "org.mitk.views.ultrasoundsupport");
-
- /*
- berry::IFolderLayout::Pointer leftFolder = layout->CreateFolder("left", berry::IPageLayout::LEFT, 0.3f, layout->GetEditorArea());
-
- leftFolder->AddStandaloneView("org.mitk.views.ultrasoundsupport", false, berry::IPageLayout::LEFT, 0.8f, layout->GetEditorArea());
- leftFolder->AddView("org.mitk.views.mitkigttrackingtoolbox");
- leftFolder->AddView("org.mitk.views.ultrasoundsupport");
-
- layout->GetViewLayout("org.mitk.views.mitkigttrackingtoolbox")->SetCloseable(false);
- layout->GetViewLayout("org.mitk.views.ultrasoundsupport")->SetCloseable(false);
- */
}
diff --git a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/SettingsWidgets/QmitkUSNavigationCombinedSettingsWidget.ui b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/SettingsWidgets/QmitkUSNavigationCombinedSettingsWidget.ui
index a17a457684..a390e4d978 100644
--- a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/SettingsWidgets/QmitkUSNavigationCombinedSettingsWidget.ui
+++ b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/SettingsWidgets/QmitkUSNavigationCombinedSettingsWidget.ui
@@ -1,256 +1,256 @@
QmitkUSNavigationCombinedSettingsWidget
0
0
400
546
Form
-
Global
QFormLayout::AllNonFixedFieldsGrow
-
Application
-
0
0
-
- Punction
+ Puncture
-
Marker Placement
-
Interaction Concept
-
0
0
-
Click, Move and Click
-
Qt::Horizontal
-
Experiment Mode
-
Enable Experiment Mode
-
Results Path
-
-
Qt::Horizontal
-
Needle Name
-
Reference Name
-
true
-
true
-
Punction
QFormLayout::AllNonFixedFieldsGrow
-
Marker Placement
QFormLayout::ExpandingFieldsGrow
-
Tumour Segmentation
-
0
0
-
Simple Segmentation
-
Security Distance (cm)
-
0.500000000000000
2.000000000000000
-
Number of Targets
-
1
4
3
-
Planning
-
Use Planning Step
true
ctkDirectoryButton
QWidget
1
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/USNavigationMarkerPlacement.cpp
index dc8e87a8f6..d29e530f93 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/USNavigationMarkerPlacement.cpp
@@ -1,713 +1,737 @@
/*===================================================================
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 "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"
// scene serialization
#include
#include
#include
#include
#include
const std::string USNavigationMarkerPlacement::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";
USNavigationMarkerPlacement::USNavigationMarkerPlacement()
: m_UpdateTimer(new QTimer(this)),
m_ImageAndNavigationDataLoggingTimer(new QTimer(this)),
m_StdMultiWidget(0),
m_ReinitAlreadyDone(false),
m_IsExperimentRunning(false),
m_NavigationStepTimer(mitk::USNavigationStepTimer::New()),
m_ExperimentLogging(mitk::USNavigationExperimentLogging::New()),
m_AblationZonesDisplacementFilter(mitk::NodeDisplacementFilter::New()),
m_IconRunning(QPixmap(":/USNavigation/record.png")),
m_IconNotRunning(QPixmap(":/USNavigation/record-gray.png")),
m_USImageLoggingFilter(mitk::USImageLoggingFilter::New()),
m_NavigationDataRecorder(mitk::NavigationDataRecorder::New()),
m_SceneNumber(1),
m_WarnOverlay(mitk::TextAnnotation2D::New()),
m_ListenerDeviceChanged(this, &USNavigationMarkerPlacement::OnCombinedModalityPropertyChanged),
m_NeedleIndex(0),
m_MarkerIndex(1),
ui(new Ui::USNavigationMarkerPlacement)
{
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()
{
- // make sure that the experiment got finished before destructing the object
- if (m_IsExperimentRunning)
- {
- this->OnFinishExperiment();
- }
// remove listener for ultrasound device changes
if (m_CombinedModality.IsNotNull() && m_CombinedModality->GetUltrasoundDevice().IsNotNull())
{
m_CombinedModality->GetUltrasoundDevice()->RemovePropertyChangedListener(m_ListenerDeviceChanged);
}
- delete ui;
+
+ // 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)
{
if ((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)
{
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)
{
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->startExperimentButton, SIGNAL(clicked()), this, SLOT(OnStartExperiment()));
connect(ui->finishExperimentButton, SIGNAL(clicked()), this, SLOT(OnFinishExperiment()));
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 &)
{
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()
{
this->ReinitOnImage();
}
void USNavigationMarkerPlacement::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();
if (m_StdMultiWidget)
{
m_StdMultiWidget->DisableStandardLevelWindow();
m_StdMultiWidget->changeLayoutTo2DUpAnd3DDown();
}
}
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::OnResetStandardLayout()
+{
+ MITK_INFO << "Resetting Layout";
+ //reset render windows
+ mitk::DataNode::Pointer widget1 = this->GetDataStorage()->GetNamedNode("stdmulti.widget1.plane");
+ if (widget1.IsNotNull()) { widget1->SetVisibility(true); }
+ mitk::DataNode::Pointer widget3 = this->GetDataStorage()->GetNamedNode("stdmulti.widget3.plane");
+ if (widget3.IsNotNull()) { widget3->SetVisibility(true); }
+ m_StdMultiWidget->changeLayoutToDefault();
+}
+
+void USNavigationMarkerPlacement::OnChangeLayoutClicked()
+{
+ if (ui->m_enableNavigationLayout->isChecked()) OnEnableNavigationLayout();
+ else OnResetStandardLayout();
+}
+
void USNavigationMarkerPlacement::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 (int 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()
{
// 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()
{
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::SaveBaseData(
m_NavigationDataRecorder->GetNavigationDataSet(),
(QString(m_ExperimentResultsSubDirectory + QDir::separator() + "navigation-data.xml").toStdString().c_str()));
mitk::IOUtil::SaveBaseData(
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 = 0;
// reset scene number for next experiment
m_SceneNumber = 1;
this->WaitCursorOff();
MITK_INFO("USNavigationLogging") << "Finished!";
}
void USNavigationMarkerPlacement::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();
// TODO check for correct connection
// for (unsigned int n = 0; n < navigationDataSource->GetNumberOfIndexedOutputs(); ++n)
// {
// m_NavigationDataRecorder->AddNavigationData(navigationDataSource->GetOutput(n));
// }
// 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)
{
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 == "Punction")
- {
- 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);
+ 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 << "Results Directory: " << m_ResultsDirectory.toStdString();
}
void USNavigationMarkerPlacement::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 (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::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()
{
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)
{
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()
{
// 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
}
diff --git a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/Widgets/QmitkUSNavigationProcessWidget.cpp b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/Widgets/QmitkUSNavigationProcessWidget.cpp
index 9e0cb4d3bf..5da2076cf7 100644
--- a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/Widgets/QmitkUSNavigationProcessWidget.cpp
+++ b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/Widgets/QmitkUSNavigationProcessWidget.cpp
@@ -1,556 +1,556 @@
/*===================================================================
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 "QmitkUSNavigationProcessWidget.h"
#include "ui_QmitkUSNavigationProcessWidget.h"
#include "../NavigationStepWidgets/QmitkUSAbstractNavigationStep.h"
#include "../SettingsWidgets/QmitkUSNavigationAbstractSettingsWidget.h"
#include "mitkDataNode.h"
#include "mitkNavigationDataToNavigationDataFilter.h"
#include
#include
#include
QmitkUSNavigationProcessWidget::QmitkUSNavigationProcessWidget(QWidget* parent) :
QWidget(parent),
m_SettingsWidget(0),
m_BaseNode(mitk::DataNode::New()), m_CurrentTabIndex(0), m_CurrentMaxStep(0),
m_ImageAlreadySetToNode(false),
m_ReadySignalMapper(new QSignalMapper(this)), m_NoLongerReadySignalMapper(new QSignalMapper(this)),
m_StdMultiWidget(0),
m_UsePlanningStepWidget(false),
ui(new Ui::QmitkUSNavigationProcessWidget)
{
m_Parent = parent;
ui->setupUi(this);
// remove the default page
- ui->stepsToolBox->removeItem(0);
+ ui->stepsToolBox->setCurrentIndex(1);// ->removeItem(0);
//set shortcuts
QShortcut *nextShortcut = new QShortcut(QKeySequence("F10"), parent);
QShortcut *prevShortcut = new QShortcut(QKeySequence("F11"), parent);
connect(nextShortcut, SIGNAL(activated()), this, SLOT(OnNextButtonClicked()));
connect(prevShortcut, SIGNAL(activated()), this, SLOT(OnPreviousButtonClicked()));
//connect other slots
connect( ui->restartStepButton, SIGNAL(clicked()), this, SLOT(OnRestartStepButtonClicked()) );
connect( ui->previousButton, SIGNAL(clicked()), this, SLOT(OnPreviousButtonClicked()) );
connect( ui->nextButton, SIGNAL(clicked()), this, SLOT(OnNextButtonClicked()) );
connect( ui->stepsToolBox, SIGNAL(currentChanged(int)), this, SLOT(OnTabChanged(int)) );
connect (ui->settingsButton, SIGNAL(clicked()), this, SLOT(OnSettingsButtonClicked()) );
connect( m_ReadySignalMapper, SIGNAL(mapped(int)), this, SLOT(OnStepReady(int)) );
connect( m_NoLongerReadySignalMapper, SIGNAL(mapped(int)), this, SLOT(OnStepNoLongerReady(int)) );
ui->settingsFrameWidget->setHidden(true);
}
QmitkUSNavigationProcessWidget::~QmitkUSNavigationProcessWidget()
{
ui->stepsToolBox->blockSignals(true);
for ( NavigationStepVector::iterator it = m_NavigationSteps.begin();
it != m_NavigationSteps.end(); ++it )
{
if ( (*it)->GetNavigationStepState() > QmitkUSAbstractNavigationStep::State_Stopped ) { (*it)->StopStep(); }
delete *it;
}
m_NavigationSteps.clear();
if ( m_SettingsNode.IsNotNull() && m_DataStorage.IsNotNull() )
{
m_DataStorage->Remove(m_SettingsNode);
}
delete ui;
}
void QmitkUSNavigationProcessWidget::EnableInteraction(bool enable)
{
if (enable)
{
ui->restartStepButton->setEnabled(true);
ui->previousButton->setEnabled(true);
ui->nextButton->setEnabled(true);
ui->stepsToolBox->setEnabled(true);
}
else
{
ui->restartStepButton->setEnabled(false);
ui->previousButton->setEnabled(false);
ui->nextButton->setEnabled(false);
ui->stepsToolBox->setEnabled(false);
}
}
void QmitkUSNavigationProcessWidget::SetDataStorage(itk::SmartPointer dataStorage)
{
m_DataStorage = dataStorage;
if ( dataStorage.IsNull() )
{
mitkThrow() << "Data Storage must not be null for QmitkUSNavigationProcessWidget.";
}
// test if base node is already in the data storage and add it if not
m_BaseNode = dataStorage->GetNamedNode(QmitkUSAbstractNavigationStep::DATANAME_BASENODE);
if ( m_BaseNode.IsNull() )
{
m_BaseNode = mitk::DataNode::New();
m_BaseNode->SetName(QmitkUSAbstractNavigationStep::DATANAME_BASENODE);
dataStorage->Add(m_BaseNode);
}
// base node and image stream node may be the same node
if ( strcmp(QmitkUSAbstractNavigationStep::DATANAME_BASENODE, QmitkUSAbstractNavigationStep::DATANAME_IMAGESTREAM) != 0)
{
m_ImageStreamNode = dataStorage->GetNamedNode(QmitkUSAbstractNavigationStep::DATANAME_IMAGESTREAM);
if (m_ImageStreamNode.IsNull())
{
// Create Node for US Stream
m_ImageStreamNode = mitk::DataNode::New();
m_ImageStreamNode->SetName(QmitkUSAbstractNavigationStep::DATANAME_IMAGESTREAM);
dataStorage->Add(m_ImageStreamNode);
}
}
else
{
m_ImageStreamNode = m_BaseNode;
}
m_SettingsNode =
dataStorage->GetNamedDerivedNode(QmitkUSAbstractNavigationStep::DATANAME_SETTINGS, m_BaseNode);
if ( m_SettingsNode.IsNull() )
{
m_SettingsNode = mitk::DataNode::New();
m_SettingsNode->SetName(QmitkUSAbstractNavigationStep::DATANAME_SETTINGS);
dataStorage->Add(m_SettingsNode, m_BaseNode);
}
if (m_SettingsWidget) { m_SettingsWidget->SetSettingsNode(m_SettingsNode); }
}
void QmitkUSNavigationProcessWidget::SetSettingsWidget(QmitkUSNavigationAbstractSettingsWidget* settingsWidget)
{
// disconnect slots to settings widget if there was a widget before
if ( m_SettingsWidget )
{
disconnect( ui->settingsSaveButton, SIGNAL(clicked()), m_SettingsWidget, SLOT(OnSave()) );
disconnect( ui->settingsCancelButton, SIGNAL(clicked()), m_SettingsWidget, SLOT(OnCancel()) );
disconnect (m_SettingsWidget, SIGNAL(Saved()), this, SLOT(OnSettingsWidgetReturned()) );
disconnect (m_SettingsWidget, SIGNAL(Canceled()), this, SLOT(OnSettingsWidgetReturned()) );
disconnect (m_SettingsWidget, SIGNAL(SettingsChanged(itk::SmartPointer)), this, SLOT(OnSettingsChanged(itk::SmartPointer)) );
ui->settingsWidget->removeWidget(m_SettingsWidget);
}
m_SettingsWidget = settingsWidget;
if ( m_SettingsWidget )
{
m_SettingsWidget->LoadSettings();
connect( ui->settingsSaveButton, SIGNAL(clicked()), m_SettingsWidget, SLOT(OnSave()) );
connect( ui->settingsCancelButton, SIGNAL(clicked()), m_SettingsWidget, SLOT(OnCancel()) );
connect (m_SettingsWidget, SIGNAL(Saved()), this, SLOT(OnSettingsWidgetReturned()) );
connect (m_SettingsWidget, SIGNAL(Canceled()), this, SLOT(OnSettingsWidgetReturned()) );
connect (m_SettingsWidget, SIGNAL(SettingsChanged(itk::SmartPointer)), this, SLOT(OnSettingsChanged(itk::SmartPointer)) );
if ( m_SettingsNode.IsNotNull() ) { m_SettingsWidget->SetSettingsNode(m_SettingsNode, true); }
ui->settingsWidget->addWidget(m_SettingsWidget);
}
ui->settingsButton->setEnabled(m_SettingsWidget != 0);
}
void QmitkUSNavigationProcessWidget::SetNavigationSteps(NavigationStepVector navigationSteps)
{
disconnect( this, SLOT(OnTabChanged(int)) );
for ( int n = ui->stepsToolBox->count()-1; n >= 0; --n )
{
- ui->stepsToolBox->removeItem(n);
+ //ui->stepsToolBox->removeItem(n);
}
connect( ui->stepsToolBox, SIGNAL(currentChanged(int)), this, SLOT(OnTabChanged(int)) );
m_NavigationSteps.clear();
m_NavigationSteps = navigationSteps;
this->InitializeNavigationStepWidgets();
// notify all navigation step widgets about the current settings
for (NavigationStepIterator it = m_NavigationSteps.begin(); it != m_NavigationSteps.end(); ++it)
{
(*it)->OnSettingsChanged(m_SettingsNode);
}
}
void QmitkUSNavigationProcessWidget::ResetNavigationProcess()
{
MITK_INFO("QmitkUSNavigationProcessWidget") << "Resetting navigation process.";
ui->stepsToolBox->blockSignals(true);
for ( int n = 0; n <= m_CurrentMaxStep; ++n )
{
m_NavigationSteps.at(n)->StopStep();
- if ( n > 0 ) { ui->stepsToolBox->setItemEnabled(n, false); }
+ //if ( n > 0 ) { ui->stepsToolBox->setItemEnabled(n, false); }
}
ui->stepsToolBox->blockSignals(false);
m_CurrentMaxStep = 0;
ui->stepsToolBox->setCurrentIndex(0);
if ( m_NavigationSteps.size() > 0 )
{
m_NavigationSteps.at(0)->ActivateStep();
}
this->UpdatePrevNextButtons();
}
void QmitkUSNavigationProcessWidget::UpdateNavigationProgress()
{
if ( m_CombinedModality.IsNotNull() && !m_CombinedModality->GetIsFreezed() )
{
m_CombinedModality->Modified();
m_CombinedModality->Update();
if ( m_LastNavigationDataFilter.IsNotNull() ) { m_LastNavigationDataFilter->Update(); }
mitk::Image::Pointer image = m_CombinedModality->GetOutput();
// make sure that always the current image is set to the data node
if ( image.IsNotNull() && m_ImageStreamNode->GetData() != image.GetPointer() && image->IsInitialized() )
{
m_ImageStreamNode->SetData(image);
m_ImageAlreadySetToNode = true;
}
}
if ( m_CurrentTabIndex > 0 && static_cast(m_CurrentTabIndex) < m_NavigationSteps.size() )
{
m_NavigationSteps.at(m_CurrentTabIndex)->Update();
}
}
void QmitkUSNavigationProcessWidget::OnNextButtonClicked()
{
if (m_CombinedModality.IsNotNull() && m_CombinedModality->GetIsFreezed()) {return;} //no moving through steps when the modality is NULL or frozen
int currentIndex = ui->stepsToolBox->currentIndex();
if (currentIndex >= m_CurrentMaxStep)
{
MITK_WARN << "Next button clicked though no next tab widget is available.";
return;
}
ui->stepsToolBox->setCurrentIndex(++currentIndex);
this->UpdatePrevNextButtons();
}
void QmitkUSNavigationProcessWidget::OnPreviousButtonClicked()
{
if (m_CombinedModality.IsNotNull() && m_CombinedModality->GetIsFreezed()) {return;} //no moving through steps when the modality is NULL or frozen
int currentIndex = ui->stepsToolBox->currentIndex();
if (currentIndex <= 0)
{
MITK_WARN << "Previous button clicked though no previous tab widget is available.";
return;
}
ui->stepsToolBox->setCurrentIndex(--currentIndex);
this->UpdatePrevNextButtons();
}
void QmitkUSNavigationProcessWidget::OnRestartStepButtonClicked()
{
MITK_INFO("QmitkUSNavigationProcessWidget") << "Restarting step "
<< m_CurrentTabIndex << " (" << m_NavigationSteps.at(m_CurrentTabIndex)->GetTitle().toStdString() << ").";
m_NavigationSteps.at(ui->stepsToolBox->currentIndex())->RestartStep();
m_NavigationSteps.at(ui->stepsToolBox->currentIndex())->ActivateStep();
}
void QmitkUSNavigationProcessWidget::OnTabChanged(int index)
{
if ( index < 0 || index >= static_cast(m_NavigationSteps.size()) )
{
return;
}
else if ( m_CurrentTabIndex == index )
{
// just activate the step if it is the same step againg
m_NavigationSteps.at(index)->ActivateStep();
return;
}
MITK_INFO("QmitkUSNavigationProcessWidget") << "Activating navigation step "
<< index << " (" << m_NavigationSteps.at(index)->GetTitle().toStdString() <<").";
if (index > m_CurrentTabIndex)
{
this->UpdateFilterPipeline();
// finish all previous steps to make sure that all data is valid
for (int n = m_CurrentTabIndex; n < index; ++n)
{
m_NavigationSteps.at(n)->FinishStep();
}
}
// deactivate the previously active step
if ( m_CurrentTabIndex > 0 && m_NavigationSteps.size() > static_cast(m_CurrentTabIndex) )
{
m_NavigationSteps.at(m_CurrentTabIndex)->DeactivateStep();
}
// start step of the current tab if it wasn't started before
if ( m_NavigationSteps.at(index)->GetNavigationStepState() == QmitkUSAbstractNavigationStep::State_Stopped )
{
m_NavigationSteps.at(index)->StartStep();
}
m_NavigationSteps.at(index)->ActivateStep();
if (static_cast(index) < m_NavigationSteps.size())
ui->restartStepButton->setEnabled(m_NavigationSteps.at(index)->GetIsRestartable());
this->UpdatePrevNextButtons();
m_CurrentTabIndex = index;
emit SignalActiveNavigationStepChanged(index);
}
void QmitkUSNavigationProcessWidget::OnSettingsButtonClicked()
{
this->SetSettingsWidgetVisible(true);
}
void QmitkUSNavigationProcessWidget::OnSettingsWidgetReturned()
{
this->SetSettingsWidgetVisible(false);
}
void QmitkUSNavigationProcessWidget::OnSettingsNodeChanged(itk::SmartPointer dataNode)
{
if ( m_SettingsWidget ) m_SettingsWidget->SetSettingsNode(dataNode);
}
void QmitkUSNavigationProcessWidget::OnStepReady(int index)
{
if (m_CurrentMaxStep <= index)
{
m_CurrentMaxStep = index + 1;
this->UpdatePrevNextButtons();
for (int n = 0; n <= m_CurrentMaxStep; ++n)
{
- ui->stepsToolBox->setItemEnabled(n, true);
+ //ui->stepsToolBox->setItemEnabled(n, true);
}
}
emit SignalNavigationStepFinished(index, true);
}
void QmitkUSNavigationProcessWidget::OnStepNoLongerReady(int index)
{
if (m_CurrentMaxStep > index)
{
m_CurrentMaxStep = index;
this->UpdatePrevNextButtons();
this->UpdateFilterPipeline();
for (int n = m_CurrentMaxStep+1; n < ui->stepsToolBox->count(); ++n)
{
- ui->stepsToolBox->setItemEnabled(n, false);
+ //ui->stepsToolBox->setItemEnabled(n, false);
m_NavigationSteps.at(n)->StopStep();
}
}
emit SignalNavigationStepFinished(index, false);
}
void QmitkUSNavigationProcessWidget::OnCombinedModalityChanged(itk::SmartPointer combinedModality)
{
m_CombinedModality = combinedModality;
m_ImageAlreadySetToNode = false;
if ( combinedModality.IsNotNull() )
{
if ( combinedModality->GetNavigationDataSource().IsNull() )
{
MITK_WARN << "There is no navigation data source set for the given combined modality.";
return;
}
this->UpdateFilterPipeline();
}
for (NavigationStepIterator it = m_NavigationSteps.begin(); it != m_NavigationSteps.end(); ++it)
{
(*it)->SetCombinedModality(combinedModality);
}
emit SignalCombinedModalityChanged(combinedModality);
}
void QmitkUSNavigationProcessWidget::OnSettingsChanged(const mitk::DataNode::Pointer dataNode)
{
static bool methodEntered = false;
if ( methodEntered )
{
MITK_WARN("QmitkUSNavigationProcessWidget") << "Ignoring recursive call to 'OnSettingsChanged()'. "
<< "Make sure to no emit 'SignalSettingsNodeChanged' in an 'OnSettingsChanged()' method.";
return;
}
methodEntered = true;
std::string application;
if ( dataNode->GetStringProperty("settings.application", application) )
{
QString applicationQString = QString::fromStdString(application);
if ( applicationQString != ui->titleLabel->text() )
{
ui->titleLabel->setText(applicationQString);
}
}
// notify all navigation step widgets about the changed settings
for (NavigationStepIterator it = m_NavigationSteps.begin(); it != m_NavigationSteps.end(); ++it)
{
(*it)->OnSettingsChanged(dataNode);
}
emit SignalSettingsChanged(dataNode);
methodEntered = false;
}
void QmitkUSNavigationProcessWidget::InitializeNavigationStepWidgets()
{
// do not listen for steps tool box signal during insertion of items into tool box
disconnect( ui->stepsToolBox, SIGNAL(currentChanged(int)), this, SLOT(OnTabChanged(int)) );
m_CurrentMaxStep = 0;
mitk::DataStorage::Pointer dataStorage = m_DataStorage;
for (unsigned int n = 0; n < m_NavigationSteps.size(); ++n)
{
QmitkUSAbstractNavigationStep* curNavigationStep = m_NavigationSteps.at(n);
curNavigationStep->SetDataStorage(dataStorage);
connect( curNavigationStep, SIGNAL(SignalReadyForNextStep()), m_ReadySignalMapper, SLOT(map()));
connect( curNavigationStep, SIGNAL(SignalNoLongerReadyForNextStep()), m_NoLongerReadySignalMapper, SLOT(map()) );
connect( curNavigationStep, SIGNAL(SignalCombinedModalityChanged(itk::SmartPointer)), this, SLOT(OnCombinedModalityChanged(itk::SmartPointer)) );
connect( curNavigationStep, SIGNAL(SignalIntermediateResult(const itk::SmartPointer)), this, SIGNAL(SignalIntermediateResult(const itk::SmartPointer)) );
connect( curNavigationStep, SIGNAL(SignalSettingsNodeChanged(itk::SmartPointer)), this, SLOT(OnSettingsNodeChanged(itk::SmartPointer)) );
m_ReadySignalMapper->setMapping(curNavigationStep, n);
m_NoLongerReadySignalMapper->setMapping(curNavigationStep, n);
- ui->stepsToolBox->insertItem(n, curNavigationStep, QString("Step ") + QString::number(n+1) + ": " + curNavigationStep->GetTitle());
- if ( n > 0 ) { ui->stepsToolBox->setItemEnabled(n, false); }
+ ui->stepsToolBox->insertWidget(n, curNavigationStep);
+ //if ( n > 0 ) { ui->stepsToolBox->get(n, false); }
}
ui->restartStepButton->setEnabled(m_NavigationSteps.at(0)->GetIsRestartable());
ui->stepsToolBox->setCurrentIndex(0);
// activate the first navigation step widgets
if ( ! m_NavigationSteps.empty() ) { m_NavigationSteps.at(0)->ActivateStep(); }
// after filling the steps tool box the signal is interesting again
connect( ui->stepsToolBox, SIGNAL(currentChanged(int)), this, SLOT(OnTabChanged(int)) );
this->UpdateFilterPipeline();
}
void QmitkUSNavigationProcessWidget::UpdatePrevNextButtons()
{
int currentIndex = ui->stepsToolBox->currentIndex();
ui->previousButton->setEnabled(currentIndex > 0);
ui->nextButton->setEnabled(currentIndex < m_CurrentMaxStep);
}
void QmitkUSNavigationProcessWidget::UpdateFilterPipeline()
{
if ( m_CombinedModality.IsNull() ) { return; }
std::vector filterList;
mitk::NavigationDataSource::Pointer navigationDataSource = m_CombinedModality->GetNavigationDataSource();
for (unsigned int n = 0; n <= m_CurrentMaxStep && n < m_NavigationSteps.size(); ++n)
{
QmitkUSAbstractNavigationStep::FilterVector filter = m_NavigationSteps.at(n)->GetFilter();
if ( ! filter.empty() ) { filterList.insert(filterList.end(), filter.begin(), filter.end()); }
}
if ( ! filterList.empty() )
{
for (unsigned int n = 0; n < navigationDataSource->GetNumberOfOutputs(); ++n)
{
filterList.at(0)->SetInput(n, navigationDataSource->GetOutput(n));
}
for (std::vector::iterator it = filterList.begin()+1;
it != filterList.end(); ++it)
{
std::vector::iterator prevIt = it-1;
for (unsigned int n = 0; n < (*prevIt)->GetNumberOfOutputs(); ++n)
{
(*it)->SetInput(n, (*prevIt)->GetOutput(n));
}
}
m_LastNavigationDataFilter = filterList.at(filterList.size()-1);
}
else
{
m_LastNavigationDataFilter = navigationDataSource.GetPointer();
}
}
void QmitkUSNavigationProcessWidget::SetSettingsWidgetVisible(bool visible)
{
ui->settingsFrameWidget->setVisible(visible);
ui->stepsToolBox->setHidden(visible);
ui->settingsButton->setHidden(visible);
ui->restartStepButton->setHidden(visible);
ui->previousButton->setHidden(visible);
ui->nextButton->setHidden(visible);
}
void QmitkUSNavigationProcessWidget::FinishCurrentNavigationStep()
{
int currentIndex = ui->stepsToolBox->currentIndex();
QmitkUSAbstractNavigationStep* curNavigationStep = m_NavigationSteps.at(currentIndex);
curNavigationStep->FinishStep();
}
diff --git a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/Widgets/QmitkUSNavigationProcessWidget.ui b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/Widgets/QmitkUSNavigationProcessWidget.ui
index dc61a9bfeb..5526f413c9 100644
--- a/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/Widgets/QmitkUSNavigationProcessWidget.ui
+++ b/Plugins/org.mitk.gui.qt.igt.app.echotrack/src/internal/Widgets/QmitkUSNavigationProcessWidget.ui
@@ -1,213 +1,203 @@
QmitkUSNavigationProcessWidget
0
0
- 400
+ 465
757
Form
-
font-size: 10pt;
font-weight: bold;
- Qt::AlignCenter
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
-
-
+
0
-
-
-
- 0
- 0
- 378
- 300
-
-
-
- No navigation step widgets loaded.
-
+
+
-
-
false
Open Preferences
Preferences
:/USNavigation/preferences.png:/USNavigation/preferences.png
-
false
false
Restart the Current Step
&Restart Step
:/USNavigation/restart.png:/USNavigation/restart.png
-
Qt::Horizontal
40
20
-
false
Go to Previous Step
&Prev
:/USNavigation/go-previous.png:/USNavigation/go-previous.png
-
false
Go to Next Step
&Next
:/USNavigation/go-next.png:/USNavigation/go-next.png
-
-
<!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:7.8pt; font-weight:400; font-style:normal;">
-<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">Settings</span></p></body></html>
+</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:400; font-style:normal;">
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600;">Settings</span></p></body></html>
-
-
Qt::Vertical
20
40
-
-
Save
:/USNavigation/document-save.png:/USNavigation/document-save.png
-
Cancel
:/USNavigation/restart.png:/USNavigation/restart.png
OnNextButtonClicked()
OnPreviousButtonClicked()
OnRestartStepButtonClicked()
OnTabChanged(int)
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 e7baba9e85..f8a17098f1 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 "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(QmitkUSNavigationPerspective, context)
// create a combined modality persitence 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_mbi_gui_qt_usnavigation, mitk::org_mbi_gui_qt_usnavigation_Activator)
+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/src/internal/QmitkMITKIGTTrackingToolboxView.cpp b/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkMITKIGTTrackingToolboxView.cpp
index f0476ee894..308aac7508 100644
--- a/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkMITKIGTTrackingToolboxView.cpp
+++ b/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkMITKIGTTrackingToolboxView.cpp
@@ -1,1482 +1,1481 @@
/*===================================================================
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 "QmitkMITKIGTTrackingToolboxView.h"
#include "QmitkTrackingDeviceConfigurationWidget.h"
#include "QmitkStdMultiWidget.h"
// Qt
#include
#include
#include
// MITK
#include
#include
#include
#include
#include
#include
#include
-#include
+//#include
#include
#include
#include
#include
#include
#include "mitkNDIAuroraTypeInformation.h"
// vtk
#include
//for exceptions
#include
#include
//for Microservice
#include "mitkPluginActivator.h"
#include
#include
#include "usServiceReference.h"
const std::string QmitkMITKIGTTrackingToolboxView::VIEW_ID = "org.mitk.views.mitkigttrackingtoolbox";
QmitkMITKIGTTrackingToolboxView::QmitkMITKIGTTrackingToolboxView()
: QmitkFunctionality()
, m_Controls(nullptr)
, m_MultiWidget(nullptr)
, m_DeviceTypeCollection(nullptr)
{
m_TrackingLoggingTimer = new QTimer(this);
m_TrackingRenderTimer = new QTimer(this);
m_TimeoutTimer = new QTimer(this);
m_tracking = false;
m_connected = false;
m_logging = false;
m_loggedFrames = 0;
m_SimpleModeEnabled = false;
//create filename for autosaving of tool storage
QString loggingPathWithoutFilename = QString(mitk::LoggingBackend::GetLogFile().c_str());
if (!loggingPathWithoutFilename.isEmpty()) //if there already is a path for the MITK logging file use this one
{
//extract path from path+filename (if someone knows a better way to do this feel free to change it)
int lengthOfFilename = QFileInfo(QString::fromStdString(mitk::LoggingBackend::GetLogFile())).fileName().size();
loggingPathWithoutFilename.resize(loggingPathWithoutFilename.size() - lengthOfFilename);
m_AutoSaveFilename = loggingPathWithoutFilename + "TrackingToolboxAutoSave.IGTToolStorage";
}
else //if not: use a temporary path from IOUtil
{
m_AutoSaveFilename = QString(mitk::IOUtil::GetTempPath().c_str()) + "TrackingToolboxAutoSave.IGTToolStorage";
}
MITK_INFO("IGT Tracking Toolbox") << "Filename for auto saving of IGT ToolStorages: " << m_AutoSaveFilename.toStdString();
//! [Thread 1]
//initialize worker thread
m_WorkerThread = new QThread();
m_Worker = new QmitkMITKIGTTrackingToolboxViewWorker();
//! [Thread 1]
ctkPluginContext* pluginContext = mitk::PluginActivator::GetContext();
if (pluginContext)
{
QString interfaceName = QString::fromStdString(us_service_interface_iid());
QList serviceReference = pluginContext->getServiceReferences(interfaceName);
if (serviceReference.size() > 0)
{
m_DeviceTypeServiceReference = serviceReference.at(0);
const ctkServiceReference& r = serviceReference.at(0);
m_DeviceTypeCollection = pluginContext->getService(r);
}
else
{
MITK_INFO << "No Tracking Device Collection!";
}
}
}
QmitkMITKIGTTrackingToolboxView::~QmitkMITKIGTTrackingToolboxView()
{
this->StoreUISettings();
m_TrackingLoggingTimer->stop();
m_TrackingRenderTimer->stop();
m_TimeoutTimer->stop();
delete m_TrackingLoggingTimer;
delete m_TrackingRenderTimer;
delete m_TimeoutTimer;
try
{
//! [Thread 2]
// wait for thread to finish
m_WorkerThread->terminate();
m_WorkerThread->wait();
//clean up worker thread
if (m_WorkerThread) { delete m_WorkerThread; }
if (m_Worker) { delete m_Worker; }
//! [Thread 2]
//remove the tracking volume
this->GetDataStorage()->Remove(m_TrackingVolumeNode);
//unregister microservices
if (m_toolStorage) { m_toolStorage->UnRegisterMicroservice(); }
if (m_TrackingDeviceSource) { m_TrackingDeviceSource->UnRegisterMicroservice(); }
if (m_IGTLMessageProvider.IsNotNull()){ m_IGTLMessageProvider->UnRegisterMicroservice(); }
}
catch (std::exception& e) { MITK_WARN << "Unexpected exception during clean up of tracking toolbox view: " << e.what(); }
catch (...) { MITK_WARN << "Unexpected unknown error during clean up of tracking toolbox view!"; }
//store tool storage and UI settings for persistence
this->AutoSaveToolStorage();
this->StoreUISettings();
m_DeviceTypeCollection = nullptr;
mitk::PluginActivator::GetContext()->ungetService(m_DeviceTypeServiceReference);
}
void QmitkMITKIGTTrackingToolboxView::CreateQtPartControl(QWidget *parent)
{
// build up qt view, unless already done
if (!m_Controls)
{
// create GUI widgets from the Qt Designer's .ui file
m_Controls = new Ui::QmitkMITKIGTTrackingToolboxViewControls;
m_Controls->setupUi(parent);
//create connections
connect(m_Controls->m_LoadTools, SIGNAL(clicked()), this, SLOT(OnLoadTools()));
connect(m_Controls->m_ConnectDisconnectButton, SIGNAL(clicked()), this, SLOT(OnConnectDisconnect()));
connect(m_Controls->m_StartStopTrackingButton, SIGNAL(clicked()), this, SLOT(OnStartStopTracking()));
connect(m_Controls->m_ConnectSimpleMode, SIGNAL(clicked()), this, SLOT(OnConnectDisconnect()));
connect(m_Controls->m_StartTrackingSimpleMode, SIGNAL(clicked()), this, SLOT(OnStartStopTracking()));
connect(m_Controls->m_FreezeUnfreezeTrackingButton, SIGNAL(clicked()), this, SLOT(OnFreezeUnfreezeTracking()));
connect(m_TrackingLoggingTimer, SIGNAL(timeout()), this, SLOT(UpdateLoggingTrackingTimer()));
connect(m_TrackingRenderTimer, SIGNAL(timeout()), this, SLOT(UpdateRenderTrackingTimer()));
connect(m_TimeoutTimer, SIGNAL(timeout()), this, SLOT(OnTimeOut()));
connect(m_Controls->m_ChooseFile, SIGNAL(clicked()), this, SLOT(OnChooseFileClicked()));
connect(m_Controls->m_StartLogging, SIGNAL(clicked()), this, SLOT(StartLogging()));
connect(m_Controls->m_StopLogging, SIGNAL(clicked()), this, SLOT(StopLogging()));
connect(m_Controls->m_VolumeSelectionBox, SIGNAL(currentIndexChanged(QString)), this, SLOT(OnTrackingVolumeChanged(QString)));
connect(m_Controls->m_ShowTrackingVolume, SIGNAL(clicked()), this, SLOT(OnShowTrackingVolumeChanged()));
connect(m_Controls->m_AutoDetectTools, SIGNAL(clicked()), this, SLOT(OnAutoDetectTools()));
connect(m_Controls->m_ResetTools, SIGNAL(clicked()), this, SLOT(OnResetTools()));
connect(m_Controls->m_AddSingleTool, SIGNAL(clicked()), this, SLOT(OnAddSingleTool()));
connect(m_Controls->m_NavigationToolCreationWidget, SIGNAL(NavigationToolFinished()), this, SLOT(OnAddSingleToolFinished()));
connect(m_Controls->m_NavigationToolCreationWidget, SIGNAL(Canceled()), this, SLOT(OnAddSingleToolCanceled()));
connect(m_Controls->m_csvFormat, SIGNAL(clicked()), this, SLOT(OnToggleFileExtension()));
connect(m_Controls->m_xmlFormat, SIGNAL(clicked()), this, SLOT(OnToggleFileExtension()));
connect(m_Controls->m_UseDifferentUpdateRates, SIGNAL(clicked()), this, SLOT(OnToggleDifferentUpdateRates()));
connect(m_Controls->m_RenderUpdateRate, SIGNAL(valueChanged(int)), this, SLOT(OnChangeRenderUpdateRate()));
connect(m_Controls->m_DisableAllTimers, SIGNAL(stateChanged(int)), this, SLOT(EnableDisableTimerButtons(int)));
connect(m_Controls->m_advancedUI, SIGNAL(clicked()), this, SLOT(OnToggleAdvancedSimpleMode()));
connect(m_Controls->m_simpleUI, SIGNAL(clicked()), this, SLOT(OnToggleAdvancedSimpleMode()));
//connections for the tracking device configuration widget
connect(m_Controls->m_configurationWidget, SIGNAL(TrackingDeviceSelectionChanged()), this, SLOT(OnTrackingDeviceChanged()));
//! [Thread 3]
//connect worker thread
connect(m_Worker, SIGNAL(AutoDetectToolsFinished(bool, QString)), this, SLOT(OnAutoDetectToolsFinished(bool, QString)));
connect(m_Worker, SIGNAL(ConnectDeviceFinished(bool, QString)), this, SLOT(OnConnectFinished(bool, QString)));
connect(m_Worker, SIGNAL(StartTrackingFinished(bool, QString)), this, SLOT(OnStartTrackingFinished(bool, QString)));
connect(m_Worker, SIGNAL(StopTrackingFinished(bool, QString)), this, SLOT(OnStopTrackingFinished(bool, QString)));
connect(m_Worker, SIGNAL(DisconnectDeviceFinished(bool, QString)), this, SLOT(OnDisconnectFinished(bool, QString)));
connect(m_WorkerThread, SIGNAL(started()), m_Worker, SLOT(ThreadFunc()));
//move the worker to the thread
m_Worker->moveToThread(m_WorkerThread);
//! [Thread 3]
//initialize widgets
m_Controls->m_TrackingToolsStatusWidget->SetShowPositions(true);
m_Controls->m_TrackingToolsStatusWidget->SetTextAlignment(Qt::AlignLeft);
m_Controls->m_simpleWidget->setVisible(false);
//initialize tracking volume node
m_TrackingVolumeNode = mitk::DataNode::New();
m_TrackingVolumeNode->SetName("TrackingVolume");
m_TrackingVolumeNode->SetBoolProperty("Backface Culling", true);
mitk::Color red;
red.SetRed(1);
m_TrackingVolumeNode->SetColor(red);
//initialize buttons
m_Controls->m_AutoDetectTools->setVisible(false); //only visible if tracking device is Aurora
m_Controls->m_StartStopTrackingButton->setEnabled(false);
m_Controls->m_StartTrackingSimpleMode->setEnabled(false);
m_Controls->m_FreezeUnfreezeTrackingButton->setEnabled(false);
//initialize warning labels
m_Controls->m_renderWarningLabel->setVisible(false);
m_Controls->m_TrackingFrozenLabel->setVisible(false);
//Update List of available models for selected tool.
std::vector Compatibles;
if ((m_Controls == NULL) || //check all these stuff for NULL, latterly this causes crashes from time to time
(m_Controls->m_configurationWidget == NULL) ||
(m_Controls->m_configurationWidget->GetTrackingDevice().IsNull()))
{
MITK_ERROR << "Couldn't get current tracking device or an object is NULL, something went wrong!";
return;
}
else
{
Compatibles = m_DeviceTypeCollection->GetDeviceDataForLine(m_Controls->m_configurationWidget->GetTrackingDevice()->GetType());
}
m_Controls->m_VolumeSelectionBox->clear();
for (std::size_t i = 0; i < Compatibles.size(); i++)
{
m_Controls->m_VolumeSelectionBox->addItem(Compatibles[i].Model.c_str());
}
//initialize tool storage
m_toolStorage = mitk::NavigationToolStorage::New(GetDataStorage());
m_toolStorage->SetName("TrackingToolbox Default Storage");
m_toolStorage->RegisterAsMicroservice("no tracking device");
//set home directory as default path for logfile
m_Controls->m_LoggingFileName->setText(QDir::toNativeSeparators(QDir::homePath()) + QDir::separator() + "logfile.csv");
//tracking device may be changed already by the persistence of the
//QmitkTrackingDeciveConfigurationWidget
this->OnTrackingDeviceChanged();
this->LoadUISettings();
//add tracking volume node only to data storage
this->GetDataStorage()->Add(m_TrackingVolumeNode);
if (!m_Controls->m_ShowTrackingVolume->isChecked()) m_TrackingVolumeNode->SetOpacity(0.0);
else m_TrackingVolumeNode->SetOpacity(0.25);
//Update List of available models for selected tool.
m_Controls->m_VolumeSelectionBox->clear();
for (std::size_t i = 0; i < Compatibles.size(); i++)
{
m_Controls->m_VolumeSelectionBox->addItem(Compatibles[i].Model.c_str());
}
}
}
void QmitkMITKIGTTrackingToolboxView::StdMultiWidgetAvailable(QmitkStdMultiWidget &stdMultiWidget)
{
m_MultiWidget = &stdMultiWidget;
}
void QmitkMITKIGTTrackingToolboxView::StdMultiWidgetNotAvailable()
{
m_MultiWidget = NULL;
}
void QmitkMITKIGTTrackingToolboxView::OnLoadTools()
{
//read in filename
QString filename = QFileDialog::getOpenFileName(NULL, tr("Open Tool Storage"), "/", tr("Tool Storage Files (*.IGTToolStorage)"));
if (filename.isNull()) return;
//read tool storage from disk
std::string errorMessage = "";
mitk::NavigationToolStorageDeserializer::Pointer myDeserializer = mitk::NavigationToolStorageDeserializer::New(GetDataStorage());
// try-catch block for exceptions
try
{
this->ReplaceCurrentToolStorage(myDeserializer->Deserialize(filename.toStdString()), filename.toStdString());
}
catch (mitk::IGTException)
{
std::string errormessage = "Error during loading the tool storage file. Please only load tool storage files created with the NavigationToolManager view.";
QMessageBox::warning(NULL, "Tool Storage Loading Error", errormessage.c_str());
return;
}
if (m_toolStorage->isEmpty())
{
errorMessage = myDeserializer->GetErrorMessage();
MessageBox(errorMessage);
return;
}
//update label
UpdateToolStorageLabel(filename);
//update tool preview
m_Controls->m_TrackingToolsStatusWidget->RemoveStatusLabels();
m_Controls->m_TrackingToolsStatusWidget->PreShowTools(m_toolStorage);
//save filename for persistent storage
m_ToolStorageFilename = filename;
}
void QmitkMITKIGTTrackingToolboxView::OnResetTools()
{
this->ReplaceCurrentToolStorage(mitk::NavigationToolStorage::New(GetDataStorage()), "TrackingToolbox Default Storage");
m_Controls->m_TrackingToolsStatusWidget->RemoveStatusLabels();
QString toolLabel = QString("");
m_Controls->m_toolLabel->setText(toolLabel);
m_ToolStorageFilename = "";
}
void QmitkMITKIGTTrackingToolboxView::OnStartStopTracking()
{
if (!m_connected)
{
MITK_WARN << "Can't start tracking if no device is connected. Aborting";
return;
}
if (m_tracking) { OnStopTracking(); }
else { OnStartTracking(); }
}
void QmitkMITKIGTTrackingToolboxView::OnFreezeUnfreezeTracking()
{
if (m_Controls->m_FreezeUnfreezeTrackingButton->text() == "Freeze Tracking")
{
m_TrackingDeviceSource->Freeze();
m_Controls->m_FreezeUnfreezeTrackingButton->setText("Unfreeze Tracking");
m_Controls->m_TrackingFrozenLabel->setVisible(true);
}
else if (m_Controls->m_FreezeUnfreezeTrackingButton->text() == "Unfreeze Tracking")
{
m_TrackingDeviceSource->UnFreeze();
m_Controls->m_FreezeUnfreezeTrackingButton->setText("Freeze Tracking");
m_Controls->m_TrackingFrozenLabel->setVisible(false);
}
}
void QmitkMITKIGTTrackingToolboxView::OnConnectDisconnect()
{
if (m_connected) { OnDisconnect(); }
else { OnConnect(); }
}
void QmitkMITKIGTTrackingToolboxView::OnConnect()
{
MITK_INFO << "Connect Clicked";
//check if everything is ready to start tracking
if (this->m_toolStorage.IsNull())
{
MessageBox("Error: No Tools Loaded Yet!");
return;
}
else if (this->m_toolStorage->GetToolCount() == 0)
{
MessageBox("Error: No Way To Track Without Tools!");
return;
}
//parse tracking device data
mitk::TrackingDeviceData data = mitk::UnspecifiedTrackingTypeInformation::GetDeviceDataUnspecified();
QString qstr = m_Controls->m_VolumeSelectionBox->currentText();
if ((!qstr.isNull()) || (!qstr.isEmpty())) {
std::string str = qstr.toStdString();
data = m_DeviceTypeCollection->GetDeviceDataByName(str); //Data will be set later, after device generation
}
//! [Thread 4]
//initialize worker thread
m_Worker->SetWorkerMethod(QmitkMITKIGTTrackingToolboxViewWorker::eConnectDevice);
m_Worker->SetTrackingDevice(this->m_Controls->m_configurationWidget->GetTrackingDevice());
m_Worker->SetInverseMode(m_Controls->m_InverseMode->isChecked());
m_Worker->SetNavigationToolStorage(this->m_toolStorage);
m_Worker->SetTrackingDeviceData(data);
//start worker thread
m_WorkerThread->start();
//! [Thread 4]
//disable buttons
this->m_Controls->m_MainWidget->setEnabled(false);
}
void QmitkMITKIGTTrackingToolboxView::EnableDisableTimerButtons(int enable)
{
bool enableBool = enable;
m_Controls->m_UpdateRateOptionsGroupBox->setEnabled(!enableBool);
m_Controls->m_renderWarningLabel->setVisible(enableBool);
}
void QmitkMITKIGTTrackingToolboxView::OnConnectFinished(bool success, QString errorMessage)
{
m_WorkerThread->quit();
m_WorkerThread->wait();
//enable buttons
this->m_Controls->m_MainWidget->setEnabled(true);
if (!success)
{
MITK_WARN << errorMessage.toStdString();
MessageBox(errorMessage.toStdString());
return;
}
//! [Thread 6]
//get data from worker thread
m_TrackingDeviceSource = m_Worker->GetTrackingDeviceSource();
m_TrackingDeviceData = m_Worker->GetTrackingDeviceData();
m_ToolVisualizationFilter = m_Worker->GetToolVisualizationFilter();
//! [Thread 6]
//enable/disable Buttons
DisableOptionsButtons();
DisableTrackingConfigurationButtons();
m_Controls->m_TrackingControlLabel->setText("Status: connected");
m_Controls->m_ConnectDisconnectButton->setText("Disconnect");
m_Controls->m_ConnectSimpleMode->setText("Disconnect");
m_Controls->m_StartStopTrackingButton->setEnabled(true);
m_Controls->m_StartTrackingSimpleMode->setEnabled(true);
m_connected = true;
}
void QmitkMITKIGTTrackingToolboxView::OnDisconnect()
{
m_Worker->SetWorkerMethod(QmitkMITKIGTTrackingToolboxViewWorker::eDisconnectDevice);
m_WorkerThread->start();
m_Controls->m_MainWidget->setEnabled(false);
}
void QmitkMITKIGTTrackingToolboxView::OnDisconnectFinished(bool success, QString errorMessage)
{
m_WorkerThread->quit();
m_WorkerThread->wait();
m_Controls->m_MainWidget->setEnabled(true);
if (!success)
{
MITK_WARN << errorMessage.toStdString();
MessageBox(errorMessage.toStdString());
return;
}
//enable/disable Buttons
m_Controls->m_StartStopTrackingButton->setEnabled(false);
m_Controls->m_StartTrackingSimpleMode->setEnabled(false);
EnableOptionsButtons();
EnableTrackingConfigurationButtons();
m_Controls->m_TrackingControlLabel->setText("Status: disconnected");
m_Controls->m_ConnectDisconnectButton->setText("Connect");
m_Controls->m_ConnectSimpleMode->setText("Connect");
m_Controls->m_FreezeUnfreezeTrackingButton->setText("Freeze Tracking");
m_Controls->m_TrackingFrozenLabel->setVisible(false);
m_connected = false;
}
void QmitkMITKIGTTrackingToolboxView::OnStartTracking()
{
//show tracking volume
this->OnTrackingVolumeChanged(m_Controls->m_VolumeSelectionBox->currentText());
//Reset the view to a defined start. Do it here and not in OnStartTrackingFinished, to give other tracking devices the chance to reset the view to a different direction.
this->GlobalReinit();
m_Worker->SetWorkerMethod(QmitkMITKIGTTrackingToolboxViewWorker::eStartTracking);
m_WorkerThread->start();
this->m_Controls->m_MainWidget->setEnabled(false);
}
void QmitkMITKIGTTrackingToolboxView::OnStartTrackingFinished(bool success, QString errorMessage)
{
//! [Thread 5]
m_WorkerThread->quit();
m_WorkerThread->wait();
//! [Thread 5]
this->m_Controls->m_MainWidget->setEnabled(true);
if (!success)
{
MessageBox(errorMessage.toStdString());
MITK_WARN << errorMessage.toStdString();
return;
}
if (!(m_Controls->m_DisableAllTimers->isChecked()))
{
if (m_Controls->m_UseDifferentUpdateRates->isChecked())
{
if (m_Controls->m_RenderUpdateRate->value() != 0)
m_TrackingRenderTimer->start(1000 / (m_Controls->m_RenderUpdateRate->value()));
m_TrackingLoggingTimer->start(1000 / (m_Controls->m_LogUpdateRate->value()));
}
else
{
m_TrackingRenderTimer->start(1000 / (m_Controls->m_UpdateRate->value()));
m_TrackingLoggingTimer->start(1000 / (m_Controls->m_UpdateRate->value()));
}
}
m_Controls->m_TrackingControlLabel->setText("Status: tracking");
//connect the tool visualization widget
for (std::size_t i = 0; i < m_TrackingDeviceSource->GetNumberOfOutputs(); i++)
{
m_Controls->m_TrackingToolsStatusWidget->AddNavigationData(m_TrackingDeviceSource->GetOutput(i));
}
m_Controls->m_TrackingToolsStatusWidget->ShowStatusLabels();
if (m_Controls->m_ShowToolQuaternions->isChecked()) { m_Controls->m_TrackingToolsStatusWidget->SetShowQuaternions(true); }
else { m_Controls->m_TrackingToolsStatusWidget->SetShowQuaternions(false); }
//if activated enable open IGT link microservice
if (m_Controls->m_EnableOpenIGTLinkMicroService->isChecked())
{
//create convertion filter
m_IGTLConversionFilter = mitk::NavigationDataToIGTLMessageFilter::New();
m_IGTLConversionFilter->SetName("IGT Tracking Toolbox");
m_IGTLConversionFilter->ConnectTo(m_ToolVisualizationFilter);
m_IGTLConversionFilter->SetOperationMode(mitk::NavigationDataToIGTLMessageFilter::ModeSendTDataMsg);
m_IGTLConversionFilter->RegisterAsMicroservice();
//create server and message provider
m_IGTLServer = mitk::IGTLServer::New(false);
m_IGTLServer->SetName("Tracking Toolbox IGTL Server");
m_IGTLMessageProvider = mitk::IGTLMessageProvider::New();
m_IGTLMessageProvider->SetIGTLDevice(m_IGTLServer);
m_IGTLMessageProvider->RegisterAsMicroservice();
}
m_tracking = true;
m_Controls->m_ConnectDisconnectButton->setEnabled(false);
m_Controls->m_StartStopTrackingButton->setText("Stop Tracking");
m_Controls->m_StartTrackingSimpleMode->setText("Stop\nTracking");
m_Controls->m_FreezeUnfreezeTrackingButton->setEnabled(true);
}
void QmitkMITKIGTTrackingToolboxView::OnStopTracking()
{
if (!m_tracking) return;
m_TrackingRenderTimer->stop();
m_TrackingLoggingTimer->stop();
m_Worker->SetWorkerMethod(QmitkMITKIGTTrackingToolboxViewWorker::eStopTracking);
m_WorkerThread->start();
m_Controls->m_MainWidget->setEnabled(false);
}
void QmitkMITKIGTTrackingToolboxView::OnStopTrackingFinished(bool success, QString errorMessage)
{
m_WorkerThread->quit();
m_WorkerThread->wait();
m_Controls->m_MainWidget->setEnabled(true);
if (!success)
{
MessageBox(errorMessage.toStdString());
MITK_WARN << errorMessage.toStdString();
return;
}
m_Controls->m_TrackingControlLabel->setText("Status: connected");
if (m_logging) StopLogging();
m_Controls->m_TrackingToolsStatusWidget->RemoveStatusLabels();
m_Controls->m_TrackingToolsStatusWidget->PreShowTools(m_toolStorage);
m_tracking = false;
m_Controls->m_StartStopTrackingButton->setText("Start Tracking");
m_Controls->m_StartTrackingSimpleMode->setText("Start\nTracking");
m_Controls->m_ConnectDisconnectButton->setEnabled(true);
m_Controls->m_FreezeUnfreezeTrackingButton->setEnabled(false);
//unregister open IGT link micro service
if (m_Controls->m_EnableOpenIGTLinkMicroService->isChecked())
{
m_IGTLConversionFilter->UnRegisterMicroservice();
m_IGTLMessageProvider->UnRegisterMicroservice();
}
}
void QmitkMITKIGTTrackingToolboxView::OnTrackingDeviceChanged()
{
mitk::TrackingDeviceType Type;
if (m_Controls->m_configurationWidget->GetTrackingDevice().IsNotNull())
{
Type = m_Controls->m_configurationWidget->GetTrackingDevice()->GetType();
//enable controls because device is valid
m_Controls->m_TrackingToolsGoupBox->setEnabled(true);
m_Controls->m_TrackingControlsGroupBox->setEnabled(true);
}
else
{
Type = mitk::UnspecifiedTrackingTypeInformation::GetTrackingDeviceName();
MessageBox("Error: This tracking device is not included in this project. Please make sure that the device is installed and activated in your MITK build.");
m_Controls->m_TrackingToolsGoupBox->setEnabled(false);
m_Controls->m_TrackingControlsGroupBox->setEnabled(false);
return;
}
// Code to enable/disable device specific buttons
if (m_Controls->m_configurationWidget->GetTrackingDevice()->AutoDetectToolsAvailable())
{ m_Controls->m_AutoDetectTools->setVisible(true); }
else
{ m_Controls->m_AutoDetectTools->setVisible(false); }
if (Type == mitk::NDIAuroraTypeInformation::GetTrackingDeviceName()) //Aurora
{ m_Controls->m_AddSingleTool->setEnabled(false);}
else //other trackers
{ m_Controls->m_AddSingleTool->setEnabled(true); }
// Code to select appropriate tracking volume for current type
std::vector Compatibles = m_DeviceTypeCollection->GetDeviceDataForLine(Type);
m_Controls->m_VolumeSelectionBox->clear();
for (std::size_t i = 0; i < Compatibles.size(); i++)
{
m_Controls->m_VolumeSelectionBox->addItem(Compatibles[i].Model.c_str());
}
}
void QmitkMITKIGTTrackingToolboxView::OnTrackingVolumeChanged(QString qstr)
{
if (qstr.isNull()) return;
if (qstr.isEmpty()) return;
mitk::TrackingVolumeGenerator::Pointer volumeGenerator = mitk::TrackingVolumeGenerator::New();
std::string str = qstr.toStdString();
mitk::TrackingDeviceData data = m_DeviceTypeCollection->GetDeviceDataByName(str);
m_TrackingDeviceData = data;
volumeGenerator->SetTrackingDeviceData(data);
volumeGenerator->Update();
mitk::Surface::Pointer volumeSurface = volumeGenerator->GetOutput();
m_TrackingVolumeNode->SetData(volumeSurface);
if (!m_Controls->m_ShowTrackingVolume->isChecked()) m_TrackingVolumeNode->SetOpacity(0.0);
else m_TrackingVolumeNode->SetOpacity(0.25);
GlobalReinit();
}
void QmitkMITKIGTTrackingToolboxView::OnShowTrackingVolumeChanged()
{
if (m_Controls->m_ShowTrackingVolume->isChecked())
{
OnTrackingVolumeChanged(m_Controls->m_VolumeSelectionBox->currentText());
m_TrackingVolumeNode->SetOpacity(0.25);
}
else
{
m_TrackingVolumeNode->SetOpacity(0.0);
}
}
void QmitkMITKIGTTrackingToolboxView::OnAutoDetectTools()
{
if (m_Controls->m_configurationWidget->GetTrackingDevice()->AutoDetectToolsAvailable())
{
DisableTrackingConfigurationButtons();
m_Worker->SetWorkerMethod(QmitkMITKIGTTrackingToolboxViewWorker::eAutoDetectTools);
m_Worker->SetTrackingDevice(m_Controls->m_configurationWidget->GetTrackingDevice().GetPointer());
m_Worker->SetDataStorage(this->GetDataStorage());
m_WorkerThread->start();
m_TimeoutTimer->start(5000);
//disable controls until worker thread is finished
this->m_Controls->m_MainWidget->setEnabled(false);
}
}
void QmitkMITKIGTTrackingToolboxView::OnAutoDetectToolsFinished(bool success, QString errorMessage)
{
m_TimeoutTimer->stop();
m_WorkerThread->quit();
m_WorkerThread->wait();
//enable controls again
this->m_Controls->m_MainWidget->setEnabled(true);
EnableTrackingConfigurationButtons();
if (!success)
{
MITK_WARN << errorMessage.toStdString();
MessageBox(errorMessage.toStdString());
EnableTrackingConfigurationButtons();
return;
}
mitk::NavigationToolStorage::Pointer autoDetectedStorage = m_Worker->GetNavigationToolStorage();
//save detected tools
this->ReplaceCurrentToolStorage(autoDetectedStorage, "Autodetected NDI Aurora Storage");
//auto save the new storage to hard disc (for persistence)
AutoSaveToolStorage();
//update label
QString toolLabel = QString("Loaded Tools: ") + QString::number(m_toolStorage->GetToolCount()) + " Tools (Auto Detected)";
m_Controls->m_toolLabel->setText(toolLabel);
//update tool preview
m_Controls->m_TrackingToolsStatusWidget->RemoveStatusLabels();
m_Controls->m_TrackingToolsStatusWidget->PreShowTools(m_toolStorage);
EnableTrackingConfigurationButtons();
//print a logging message about the detected tools
switch (m_toolStorage->GetToolCount())
{
case 0:
MITK_INFO("IGT Tracking Toolbox") << "Found no tools. Empty ToolStorage was autosaved to " << m_ToolStorageFilename.toStdString();
break;
case 1:
MITK_INFO("IGT Tracking Toolbox") << "Found one tool. ToolStorage was autosaved to " << m_ToolStorageFilename.toStdString();
break;
default:
MITK_INFO("IGT Tracking Toolbox") << "Found " << m_toolStorage->GetToolCount() << " tools. ToolStorage was autosaved to " << m_ToolStorageFilename.toStdString();
}
}
void QmitkMITKIGTTrackingToolboxView::MessageBox(std::string s)
{
QMessageBox msgBox;
msgBox.setText(s.c_str());
msgBox.exec();
}
void QmitkMITKIGTTrackingToolboxView::UpdateRenderTrackingTimer()
{
//update filter
m_ToolVisualizationFilter->Update();
MITK_DEBUG << "Number of outputs ToolVisualizationFilter: " << m_ToolVisualizationFilter->GetNumberOfIndexedOutputs();
MITK_DEBUG << "Number of inputs ToolVisualizationFilter: " << m_ToolVisualizationFilter->GetNumberOfIndexedInputs();
//update tool colors to show tool status
for (unsigned int i = 0; i < m_ToolVisualizationFilter->GetNumberOfIndexedOutputs(); i++)
{
mitk::NavigationData::Pointer currentTool = m_ToolVisualizationFilter->GetOutput(i);
if (currentTool->IsDataValid())
{
this->m_toolStorage->GetTool(i)->GetDataNode()->SetColor(mitk::IGTColor_VALID);
}
else
{
this->m_toolStorage->GetTool(i)->GetDataNode()->SetColor(mitk::IGTColor_WARNING);
}
}
//refresh view and status widget
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
m_Controls->m_TrackingToolsStatusWidget->Refresh();
//code to better isolate bug 17713, could be removed when bug 17713 is fixed
static int i = 0;
static mitk::Point3D lastPositionTool1 = m_ToolVisualizationFilter->GetOutput(0)->GetPosition();
static itk::TimeStamp lastTimeStamp = m_ToolVisualizationFilter->GetOutput(0)->GetTimeStamp();
i++;
//every 20 frames: check if tracking is frozen
if (i > 20)
{
i = 0;
if (m_ToolVisualizationFilter->GetOutput(0)->IsDataValid())
{
if (mitk::Equal(lastPositionTool1, m_ToolVisualizationFilter->GetOutput(0)->GetPosition(), 0.000000001, false)
&& m_Controls->m_configurationWidget->GetTrackingDevice()->GetType() != "Da Vinci")
{
MITK_WARN << "Seems as tracking (of at least tool 1) is frozen which means that bug 17713 occurred. Restart tracking might help.";
//display further information to find the bug
MITK_WARN << "Timestamp of current navigation data: " << m_ToolVisualizationFilter->GetOutput(0)->GetTimeStamp();
MITK_WARN << "Timestamp of last navigation data (which holds the same values): " << lastTimeStamp;
}
lastPositionTool1 = m_ToolVisualizationFilter->GetOutput(0)->GetPosition();
lastTimeStamp = m_ToolVisualizationFilter->GetOutput(0)->GetTimeStamp();
}
}
}
void QmitkMITKIGTTrackingToolboxView::UpdateLoggingTrackingTimer()
{
//update logging
if (m_logging)
{
this->m_loggingFilter->Update();
m_loggedFrames = this->m_loggingFilter->GetNumberOfRecordedSteps();
this->m_Controls->m_LoggedFramesLabel->setText("Logged Frames: " + QString::number(m_loggedFrames));
//check if logging stopped automatically
if ((m_loggedFrames > 1) && (!m_loggingFilter->GetRecording())){ StopLogging(); }
}
//refresh status widget
m_Controls->m_TrackingToolsStatusWidget->Refresh();
}
void QmitkMITKIGTTrackingToolboxView::OnChooseFileClicked()
{
QDir currentPath = QFileInfo(m_Controls->m_LoggingFileName->text()).dir();
// if no path was selected (QDir would select current working dir then) or the
// selected path does not exist -> use home directory
if (currentPath == QDir() || !currentPath.exists())
{
currentPath = QDir(QDir::homePath());
}
QString filename = QFileDialog::getSaveFileName(NULL, tr("Choose Logging File"), currentPath.absolutePath(), "*.*");
if (filename == "") return;
this->m_Controls->m_LoggingFileName->setText(filename);
this->OnToggleFileExtension();
}
// bug-16470: toggle file extension after clicking on radio button
void QmitkMITKIGTTrackingToolboxView::OnToggleFileExtension()
{
QString currentInputText = this->m_Controls->m_LoggingFileName->text();
QString currentFile = QFileInfo(currentInputText).baseName();
QDir currentPath = QFileInfo(currentInputText).dir();
if (currentFile.isEmpty())
{
currentFile = "logfile";
}
// Setting currentPath to default home path when currentPath is empty or it does not exist
if (currentPath == QDir() || !currentPath.exists())
{
currentPath = QDir::homePath();
}
// check if csv radio button is clicked
if (this->m_Controls->m_csvFormat->isChecked())
{
// you needn't add a seperator to the input text when currentpath is the rootpath
if (currentPath.isRoot())
{
this->m_Controls->m_LoggingFileName->setText(QDir::toNativeSeparators(currentPath.absolutePath()) + currentFile + ".csv");
}
else
{
this->m_Controls->m_LoggingFileName->setText(QDir::toNativeSeparators(currentPath.absolutePath()) + QDir::separator() + currentFile + ".csv");
}
}
// check if xml radio button is clicked
else if (this->m_Controls->m_xmlFormat->isChecked())
{
// you needn't add a seperator to the input text when currentpath is the rootpath
if (currentPath.isRoot())
{
this->m_Controls->m_LoggingFileName->setText(QDir::toNativeSeparators(currentPath.absolutePath()) + currentFile + ".xml");
}
else
{
this->m_Controls->m_LoggingFileName->setText(QDir::toNativeSeparators(currentPath.absolutePath()) + QDir::separator() + currentFile + ".xml");
}
}
}
void QmitkMITKIGTTrackingToolboxView::OnToggleAdvancedSimpleMode()
{
if (m_SimpleModeEnabled)
{
m_Controls->m_simpleWidget->setVisible(false);
m_Controls->m_MainWidget->setVisible(true);
m_Controls->m_simpleUI->setChecked(false);
m_SimpleModeEnabled = false;
}
else
{
m_Controls->m_simpleWidget->setVisible(true);
m_Controls->m_MainWidget->setVisible(false);
m_SimpleModeEnabled = true;
}
}
void QmitkMITKIGTTrackingToolboxView::OnToggleDifferentUpdateRates()
{
if (m_Controls->m_UseDifferentUpdateRates->isChecked())
{
if (m_Controls->m_RenderUpdateRate->value() == 0)
m_Controls->m_renderWarningLabel->setVisible(true);
else
m_Controls->m_renderWarningLabel->setVisible(false);
m_Controls->m_UpdateRate->setEnabled(false);
m_Controls->m_OptionsUpdateRateLabel->setEnabled(false);
m_Controls->m_RenderUpdateRate->setEnabled(true);
m_Controls->m_OptionsRenderUpdateRateLabel->setEnabled(true);
m_Controls->m_LogUpdateRate->setEnabled(true);
m_Controls->m_OptionsLogUpdateRateLabel->setEnabled(true);
}
else
{
m_Controls->m_renderWarningLabel->setVisible(false);
m_Controls->m_UpdateRate->setEnabled(true);
m_Controls->m_OptionsUpdateRateLabel->setEnabled(true);
m_Controls->m_RenderUpdateRate->setEnabled(false);
m_Controls->m_OptionsRenderUpdateRateLabel->setEnabled(false);
m_Controls->m_LogUpdateRate->setEnabled(false);
m_Controls->m_OptionsLogUpdateRateLabel->setEnabled(false);
}
}
void QmitkMITKIGTTrackingToolboxView::OnChangeRenderUpdateRate()
{
if (m_Controls->m_RenderUpdateRate->value() == 0)
m_Controls->m_renderWarningLabel->setVisible(true);
else
m_Controls->m_renderWarningLabel->setVisible(false);
}
void QmitkMITKIGTTrackingToolboxView::StartLogging()
{
if (m_ToolVisualizationFilter.IsNull())
{
MessageBox("Cannot activate logging without a connected device. Configure and connect a tracking device first.");
return;
}
if (!m_logging)
{
//initialize logging filter
m_loggingFilter = mitk::NavigationDataRecorder::New();
m_loggingFilter->ConnectTo(m_ToolVisualizationFilter);
if (m_Controls->m_LoggingLimit->isChecked()){ m_loggingFilter->SetRecordCountLimit(m_Controls->m_LoggedFramesLimit->value()); }
//start filter with try-catch block for exceptions
try
{
m_loggingFilter->StartRecording();
}
catch (mitk::IGTException)
{
std::string errormessage = "Error during start recording. Recorder already started recording?";
QMessageBox::warning(NULL, "IGTPlayer: Error", errormessage.c_str());
m_loggingFilter->StopRecording();
return;
}
//update labels / logging variables
this->m_Controls->m_LoggingLabel->setText("Logging ON");
this->m_Controls->m_LoggedFramesLabel->setText("Logged Frames: 0");
m_loggedFrames = 0;
m_logging = true;
DisableLoggingButtons();
}
}
void QmitkMITKIGTTrackingToolboxView::StopLogging()
{
if (m_logging)
{
//stop logging
m_loggingFilter->StopRecording();
m_logging = false;
//update GUI
this->m_Controls->m_LoggingLabel->setText("Logging OFF");
EnableLoggingButtons();
//write the results to a file
if (m_Controls->m_csvFormat->isChecked())
{
mitk::IOUtil::SaveBaseData(m_loggingFilter->GetNavigationDataSet(), this->m_Controls->m_LoggingFileName->text().toStdString());
}
else if (m_Controls->m_xmlFormat->isChecked())
{
mitk::IOUtil::SaveBaseData(m_loggingFilter->GetNavigationDataSet(), this->m_Controls->m_LoggingFileName->text().toStdString());
}
}
}
void QmitkMITKIGTTrackingToolboxView::OnAddSingleTool()
{
QString Identifier = "Tool#";
QString Name = "NewTool";
if (m_toolStorage.IsNotNull()) {
Identifier += QString::number(m_toolStorage->GetToolCount());
Name += QString::number(m_toolStorage->GetToolCount());
}
else {
Identifier += "0";
Name += "0";
}
m_Controls->m_NavigationToolCreationWidget->Initialize(GetDataStorage(), Identifier.toStdString(), Name.toStdString());
m_Controls->m_NavigationToolCreationWidget->SetTrackingDeviceType(m_Controls->m_configurationWidget->GetTrackingDevice()->GetType(), false);
m_Controls->m_TrackingToolsWidget->setCurrentIndex(1);
//disable tracking volume during tool editing
lastTrackingVolumeState = m_Controls->m_ShowTrackingVolume->isChecked();
if (lastTrackingVolumeState) m_Controls->m_ShowTrackingVolume->click();
GlobalReinit();
}
void QmitkMITKIGTTrackingToolboxView::OnAddSingleToolFinished()
{
m_Controls->m_TrackingToolsWidget->setCurrentIndex(0);
if (this->m_toolStorage.IsNull())
{
//this shouldn't happen!
MITK_WARN << "No ToolStorage available, cannot add tool, aborting!";
return;
}
m_toolStorage->AddTool(m_Controls->m_NavigationToolCreationWidget->GetCreatedTool());
m_Controls->m_TrackingToolsStatusWidget->PreShowTools(m_toolStorage);
m_Controls->m_toolLabel->setText("");
//auto save current storage for persistence
MITK_INFO << "Auto saving manually added tools for persistence.";
AutoSaveToolStorage();
//enable tracking volume again
if (lastTrackingVolumeState) m_Controls->m_ShowTrackingVolume->click();
GlobalReinit();
}
void QmitkMITKIGTTrackingToolboxView::OnAddSingleToolCanceled()
{
m_Controls->m_TrackingToolsWidget->setCurrentIndex(0);
//enable tracking volume again
if (lastTrackingVolumeState) m_Controls->m_ShowTrackingVolume->click();
GlobalReinit();
}
void QmitkMITKIGTTrackingToolboxView::GlobalReinit()
{
// get all nodes that have not set "includeInBoundingBox" to false
mitk::NodePredicateNot::Pointer pred = mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("includeInBoundingBox", mitk::BoolProperty::New(false)));
mitk::DataStorage::SetOfObjects::ConstPointer rs = this->GetDataStorage()->GetSubset(pred);
// calculate bounding geometry of these nodes
mitk::TimeGeometry::Pointer bounds = this->GetDataStorage()->ComputeBoundingGeometry3D(rs, "visible");
// initialize the views to the bounding geometry
mitk::RenderingManager::GetInstance()->InitializeViews(bounds);
}
void QmitkMITKIGTTrackingToolboxView::DisableLoggingButtons()
{
m_Controls->m_StartLogging->setEnabled(false);
m_Controls->m_LoggingFileName->setEnabled(false);
m_Controls->m_ChooseFile->setEnabled(false);
m_Controls->m_LoggingLimit->setEnabled(false);
m_Controls->m_LoggedFramesLimit->setEnabled(false);
m_Controls->m_csvFormat->setEnabled(false);
m_Controls->m_xmlFormat->setEnabled(false);
m_Controls->m_StopLogging->setEnabled(true);
}
void QmitkMITKIGTTrackingToolboxView::EnableLoggingButtons()
{
m_Controls->m_StartLogging->setEnabled(true);
m_Controls->m_LoggingFileName->setEnabled(true);
m_Controls->m_ChooseFile->setEnabled(true);
m_Controls->m_LoggingLimit->setEnabled(true);
m_Controls->m_LoggedFramesLimit->setEnabled(true);
m_Controls->m_csvFormat->setEnabled(true);
m_Controls->m_xmlFormat->setEnabled(true);
m_Controls->m_StopLogging->setEnabled(false);
}
void QmitkMITKIGTTrackingToolboxView::DisableOptionsButtons()
{
m_Controls->m_ShowTrackingVolume->setEnabled(false);
m_Controls->m_UseDifferentUpdateRates->setEnabled(false);
m_Controls->m_UpdateRate->setEnabled(false);
m_Controls->m_OptionsUpdateRateLabel->setEnabled(false);
m_Controls->m_RenderUpdateRate->setEnabled(false);
m_Controls->m_OptionsRenderUpdateRateLabel->setEnabled(false);
m_Controls->m_LogUpdateRate->setEnabled(false);
m_Controls->m_OptionsLogUpdateRateLabel->setEnabled(false);
m_Controls->m_DisableAllTimers->setEnabled(false);
m_Controls->m_OtherOptionsGroupBox->setEnabled(false);
}
void QmitkMITKIGTTrackingToolboxView::EnableOptionsButtons()
{
m_Controls->m_ShowTrackingVolume->setEnabled(true);
m_Controls->m_UseDifferentUpdateRates->setEnabled(true);
m_Controls->m_DisableAllTimers->setEnabled(true);
m_Controls->m_OtherOptionsGroupBox->setEnabled(true);
OnToggleDifferentUpdateRates();
}
void QmitkMITKIGTTrackingToolboxView::EnableTrackingControls()
{
m_Controls->m_TrackingControlsGroupBox->setEnabled(true);
}
void QmitkMITKIGTTrackingToolboxView::DisableTrackingControls()
{
m_Controls->m_TrackingControlsGroupBox->setEnabled(false);
}
void QmitkMITKIGTTrackingToolboxView::EnableTrackingConfigurationButtons()
{
m_Controls->m_AutoDetectTools->setEnabled(true);
if (m_Controls->m_configurationWidget->GetTrackingDevice()->GetType() != mitk::NDIAuroraTypeInformation::GetTrackingDeviceName()) m_Controls->m_AddSingleTool->setEnabled(true);
m_Controls->m_LoadTools->setEnabled(true);
m_Controls->m_ResetTools->setEnabled(true);
}
void QmitkMITKIGTTrackingToolboxView::DisableTrackingConfigurationButtons()
{
m_Controls->m_AutoDetectTools->setEnabled(false);
if (m_Controls->m_configurationWidget->GetTrackingDevice()->GetType() != mitk::NDIAuroraTypeInformation::GetTrackingDeviceName()) m_Controls->m_AddSingleTool->setEnabled(false);
m_Controls->m_LoadTools->setEnabled(false);
m_Controls->m_ResetTools->setEnabled(false);
}
void QmitkMITKIGTTrackingToolboxView::ReplaceCurrentToolStorage(mitk::NavigationToolStorage::Pointer newStorage, std::string newStorageName)
{
//first: get rid of the old one
//don't reset if there is no tool storage. BugFix #17793
if (m_toolStorage.IsNotNull()){
m_toolStorage->UnLockStorage(); //only to be sure...
m_toolStorage->UnRegisterMicroservice();
m_toolStorage = nullptr;
}
//now: replace by the new one
m_toolStorage = newStorage;
m_toolStorage->SetName(newStorageName);
m_toolStorage->RegisterAsMicroservice("no tracking device");
}
void QmitkMITKIGTTrackingToolboxView::OnTimeOut()
{
m_WorkerThread->terminate();
m_WorkerThread->wait();
m_TimeoutTimer->stop();
}
//! [StoreUISettings]
void QmitkMITKIGTTrackingToolboxView::StoreUISettings()
{
// persistence service does not directly work in plugins for now
// -> using QSettings
QSettings settings;
settings.beginGroup(QString::fromStdString(VIEW_ID));
MITK_INFO << "Store UI settings";
// set the values of some widgets and attrbutes to the QSettings
settings.setValue("ShowTrackingVolume", QVariant(m_Controls->m_ShowTrackingVolume->isChecked()));
settings.setValue("toolStorageFilename", QVariant(m_ToolStorageFilename));
settings.setValue("VolumeSelectionBox", QVariant(m_Controls->m_VolumeSelectionBox->currentIndex()));
settings.setValue("SimpleModeEnabled", QVariant(m_SimpleModeEnabled));
settings.endGroup();
}
//! [StoreUISettings]
//! [LoadUISettings]
void QmitkMITKIGTTrackingToolboxView::LoadUISettings()
{
// persistence service does not directly work in plugins for now
// -> using QSettings
QSettings settings;
settings.beginGroup(QString::fromStdString(VIEW_ID));
// set some widgets and attributes by the values from the QSettings
m_Controls->m_ShowTrackingVolume->setChecked(settings.value("ShowTrackingVolume", true).toBool());
m_Controls->m_VolumeSelectionBox->setCurrentIndex(settings.value("VolumeSelectionBox", 0).toInt());
m_ToolStorageFilename = settings.value("toolStorageFilename", QVariant("")).toString();
if (settings.value("SimpleModeEnabled", false).toBool()) { this->OnToggleAdvancedSimpleMode(); }
settings.endGroup();
//! [LoadUISettings]
//! [LoadToolStorage]
// try to deserialize the tool storage from the given tool storage file name
if (!m_ToolStorageFilename.isEmpty())
{
// try-catch block for exceptions
try
{
mitk::NavigationToolStorageDeserializer::Pointer myDeserializer = mitk::NavigationToolStorageDeserializer::New(GetDataStorage());
m_toolStorage->UnRegisterMicroservice();
m_toolStorage = myDeserializer->Deserialize(m_ToolStorageFilename.toStdString());
m_toolStorage->RegisterAsMicroservice("no tracking device");
//update label
UpdateToolStorageLabel(m_ToolStorageFilename);
//update tool preview
m_Controls->m_TrackingToolsStatusWidget->RemoveStatusLabels();
m_Controls->m_TrackingToolsStatusWidget->PreShowTools(m_toolStorage);
}
catch (mitk::IGTException)
{
MITK_WARN("QmitkMITKIGTTrackingToolBoxView") << "Error during restoring tools. Problems with file (" << m_ToolStorageFilename.toStdString() << "), please check the file?";
this->OnResetTools(); //if there where errors reset the tool storage to avoid problems later on
}
}
//! [LoadToolStorage]
}
void QmitkMITKIGTTrackingToolboxView::UpdateToolStorageLabel(QString pathOfLoadedStorage)
{
QFileInfo myPath(pathOfLoadedStorage); //use this to seperate filename from path
QString toolLabel = myPath.fileName();
if (toolLabel.size() > 45) //if the tool storage name is to long trimm the string
{
toolLabel.resize(40);
toolLabel += "[...]";
}
m_Controls->m_toolLabel->setText(toolLabel);
}
void QmitkMITKIGTTrackingToolboxView::AutoSaveToolStorage()
{
m_ToolStorageFilename = m_AutoSaveFilename;
mitk::NavigationToolStorageSerializer::Pointer mySerializer = mitk::NavigationToolStorageSerializer::New();
mySerializer->Serialize(m_ToolStorageFilename.toStdString(), m_toolStorage);
}
void QmitkMITKIGTTrackingToolboxViewWorker::SetWorkerMethod(WorkerMethod w)
{
m_WorkerMethod = w;
}
void QmitkMITKIGTTrackingToolboxViewWorker::SetTrackingDevice(mitk::TrackingDevice::Pointer t)
{
m_TrackingDevice = t;
}
void QmitkMITKIGTTrackingToolboxViewWorker::SetDataStorage(mitk::DataStorage::Pointer d)
{
m_DataStorage = d;
}
void QmitkMITKIGTTrackingToolboxViewWorker::SetInverseMode(bool mode)
{
m_InverseMode = mode;
}
void QmitkMITKIGTTrackingToolboxViewWorker::SetTrackingDeviceData(mitk::TrackingDeviceData d)
{
m_TrackingDeviceData = d;
}
void QmitkMITKIGTTrackingToolboxViewWorker::SetNavigationToolStorage(mitk::NavigationToolStorage::Pointer n)
{
m_NavigationToolStorage = n;
}
//! [Thread 7]
void QmitkMITKIGTTrackingToolboxViewWorker::ThreadFunc()
{
switch (m_WorkerMethod)
{
case eAutoDetectTools:
this->AutoDetectTools();
break;
case eConnectDevice:
this->ConnectDevice();
break;
case eStartTracking:
this->StartTracking();
break;
case eStopTracking:
this->StopTracking();
break;
case eDisconnectDevice:
this->DisconnectDevice();
break;
default:
MITK_WARN << "Undefined worker method was set ... something went wrong!";
break;
}
}
//! [Thread 7]
void QmitkMITKIGTTrackingToolboxViewWorker::AutoDetectTools()
{
- mitk::ProgressBar::GetInstance()->AddStepsToDo(2);
+ //mitk::ProgressBar::GetInstance()->AddStepsToDo(2);
mitk::NavigationToolStorage::Pointer autoDetectedStorage = mitk::NavigationToolStorage::New(m_DataStorage);
try
{
mitk::NavigationToolStorage::Pointer tempStorage = m_TrackingDevice->AutoDetectTools();
- mitk::ProgressBar::GetInstance()->Progress();
+ //mitk::ProgressBar::GetInstance()->Progress();
for (int i = 0; i < tempStorage->GetToolCount(); i++) { autoDetectedStorage->AddTool(tempStorage->GetTool(i)); }
}
catch (mitk::Exception& e)
{
MITK_WARN << e.GetDescription();
- mitk::ProgressBar::GetInstance()->Progress(2);
+ //mitk::ProgressBar::GetInstance()->Reset();
emit AutoDetectToolsFinished(false, e.GetDescription());
return;
}
m_NavigationToolStorage = autoDetectedStorage;
- mitk::ProgressBar::GetInstance()->Progress();
+ //::ProgressBar::GetInstance()->Progress();
emit AutoDetectToolsFinished(true, "");
- mitk::ProgressBar::GetInstance()->Progress(2);
}
void QmitkMITKIGTTrackingToolboxViewWorker::ConnectDevice()
{
std::string message = "";
- mitk::ProgressBar::GetInstance()->AddStepsToDo(10);
+ //mitk::ProgressBar::GetInstance()->AddStepsToDo(4);
//build the IGT pipeline
mitk::TrackingDevice::Pointer trackingDevice = m_TrackingDevice;
trackingDevice->SetData(m_TrackingDeviceData);
//set device to rotation mode transposed becaus we are working with VNL style quaternions
if (m_InverseMode)
{
trackingDevice->SetRotationMode(mitk::TrackingDevice::RotationTransposed);
}
//Get Tracking Volume Data
mitk::TrackingDeviceData data = m_TrackingDeviceData;
- mitk::ProgressBar::GetInstance()->Progress();
+ //mitk::ProgressBar::GetInstance()->Progress();
//Create Navigation Data Source with the factory class
mitk::TrackingDeviceSourceConfigurator::Pointer myTrackingDeviceSourceFactory = mitk::TrackingDeviceSourceConfigurator::New(m_NavigationToolStorage, trackingDevice);
m_TrackingDeviceSource = myTrackingDeviceSourceFactory->CreateTrackingDeviceSource(m_ToolVisualizationFilter);
- mitk::ProgressBar::GetInstance()->Progress();
+ //mitk::ProgressBar::GetInstance()->Progress();
if (m_TrackingDeviceSource.IsNull())
{
message = std::string("Cannot connect to device: ") + myTrackingDeviceSourceFactory->GetErrorMessage();
emit ConnectDeviceFinished(false, QString(message.c_str()));
return;
}
//set filter to rotation mode transposed becaus we are working with VNL style quaternions
if (m_InverseMode)
m_ToolVisualizationFilter->SetRotationMode(mitk::NavigationDataObjectVisualizationFilter::RotationTransposed);
//First check if the created object is valid
if (m_TrackingDeviceSource.IsNull())
{
message = myTrackingDeviceSourceFactory->GetErrorMessage();
emit ConnectDeviceFinished(false, QString(message.c_str()));
return;
}
MITK_INFO << "Number of tools: " << m_TrackingDeviceSource->GetNumberOfOutputs();
- mitk::ProgressBar::GetInstance()->Progress();
+ //mitk::ProgressBar::GetInstance()->Progress();
//The tools are maybe reordered after initialization, e.g. in case of auto-detected tools of NDI Aurora
mitk::NavigationToolStorage::Pointer toolsInNewOrder = myTrackingDeviceSourceFactory->GetUpdatedNavigationToolStorage();
if ((toolsInNewOrder.IsNotNull()) && (toolsInNewOrder->GetToolCount() > 0))
{
//so delete the old tools in wrong order and add them in the right order
//we cannot simply replace the tool storage because the new storage is
//not correctly initialized with the right data storage
/*
m_NavigationToolStorage->DeleteAllTools();
for (int i=0; i < toolsInNewOrder->GetToolCount(); i++) {m_NavigationToolStorage->AddTool(toolsInNewOrder->GetTool(i));}
This was replaced and thereby fixed Bug 18318 DeleteAllTools() is not Threadsafe!
*/
for (int i = 0; i < toolsInNewOrder->GetToolCount(); i++)
{
m_NavigationToolStorage->AssignToolNumber(toolsInNewOrder->GetTool(i)->GetIdentifier(), i);
}
}
- mitk::ProgressBar::GetInstance()->Progress();
+ //mitk::ProgressBar::GetInstance()->Progress();
//connect to device
try
{
m_TrackingDeviceSource->Connect();
- mitk::ProgressBar::GetInstance()->Progress();
+ //mitk::ProgressBar::GetInstance()->Reset();
//Microservice registration:
m_TrackingDeviceSource->RegisterAsMicroservice();
m_NavigationToolStorage->UnRegisterMicroservice();
m_NavigationToolStorage->RegisterAsMicroservice(m_TrackingDeviceSource->GetMicroserviceID());
m_NavigationToolStorage->LockStorage();
}
catch (...) //todo: change to mitk::IGTException
{
message = "Error on connecting the tracking device.";
emit ConnectDeviceFinished(false, QString(message.c_str()));
return;
}
emit ConnectDeviceFinished(true, QString(message.c_str()));
- mitk::ProgressBar::GetInstance()->Progress(10);
+ //mitk::ProgressBar::GetInstance()->Reset();
}
void QmitkMITKIGTTrackingToolboxViewWorker::StartTracking()
{
QString errorMessage = "";
try
{
m_TrackingDeviceSource->StartTracking();
}
catch (...) //todo: change to mitk::IGTException
{
errorMessage += "Error while starting the tracking device!";
emit StartTrackingFinished(false, errorMessage);
return;
}
//remember the original colors of the tools
m_OriginalColors = std::map();
for (int i = 0; i < this->m_NavigationToolStorage->GetToolCount(); i++)
{
mitk::DataNode::Pointer currentToolNode = m_NavigationToolStorage->GetTool(i)->GetDataNode();
float c[3];
currentToolNode->GetColor(c);
mitk::Color color;
color.SetRed(c[0]);
color.SetGreen(c[1]);
color.SetBlue(c[2]);
m_OriginalColors[currentToolNode] = color;
}
emit StartTrackingFinished(true, errorMessage);
}
void QmitkMITKIGTTrackingToolboxViewWorker::StopTracking()
{
//stop tracking
try
{
m_TrackingDeviceSource->StopTracking();
}
catch (mitk::Exception& e)
{
emit StopTrackingFinished(false, e.GetDescription());
}
//restore the original colors of the tools
for (int i = 0; i < this->m_NavigationToolStorage->GetToolCount(); i++)
{
mitk::DataNode::Pointer currentToolNode = m_NavigationToolStorage->GetTool(i)->GetDataNode();
if (m_OriginalColors.find(currentToolNode) == m_OriginalColors.end())
{
MITK_WARN << "Cannot restore original color of tool " << m_NavigationToolStorage->GetTool(i)->GetToolName();
}
else
{
currentToolNode->SetColor(m_OriginalColors[currentToolNode]);
}
}
//emit signal
emit StopTrackingFinished(true, "");
}
void QmitkMITKIGTTrackingToolboxViewWorker::DisconnectDevice()
{
try
{
if (m_TrackingDeviceSource->IsTracking()) { m_TrackingDeviceSource->StopTracking(); }
m_TrackingDeviceSource->Disconnect();
m_TrackingDeviceSource->UnRegisterMicroservice();
m_NavigationToolStorage->UnLockStorage();
}
catch (mitk::Exception& e)
{
emit DisconnectDeviceFinished(false, e.GetDescription());
}
emit DisconnectDeviceFinished(true, "");
}
\ No newline at end of file
diff --git a/Plugins/org.mitk.gui.qt.ultrasound/src/internal/UltrasoundSupport.cpp b/Plugins/org.mitk.gui.qt.ultrasound/src/internal/UltrasoundSupport.cpp
index 25cbd1abec..fe5cae6035 100644
--- a/Plugins/org.mitk.gui.qt.ultrasound/src/internal/UltrasoundSupport.cpp
+++ b/Plugins/org.mitk.gui.qt.ultrasound/src/internal/UltrasoundSupport.cpp
@@ -1,500 +1,499 @@
/*===================================================================
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
// Qmitk
#include "UltrasoundSupport.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"
const std::string UltrasoundSupport::VIEW_ID = "org.mitk.views.ultrasoundsupport";
void UltrasoundSupport::SetFocus()
{
}
void UltrasoundSupport::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;
// Create Node for US Stream
if (m_Node.IsNull())
{
m_Node = mitk::DataNode::New();
m_Node->SetName("US Support 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);
m_OldGeometry = dynamic_cast(dummyImage->GetGeometry());
}
m_Controls.tabWidget->setTabEnabled(1, false);
}
void UltrasoundSupport::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()
{
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::UpdateImage()
{
//Update device
m_Device->Modified();
m_Device->Update();
//Only update the view if the image is shown
if (m_Controls.m_ShowImageStream->isChecked())
{
//Update data node
mitk::Image::Pointer curOutput = m_Device->GetOutput();
if (curOutput->IsEmpty())
{
m_Node->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->SetData(randomImage);
curOutput->SetGeometry(randomImage->GetGeometry());
}
else
{
m_Node->SetName("US Support Viewing Stream");
m_Node->SetData(curOutput);
}
// if the geometry changed: reinitialize the ultrasound image
if ((m_OldGeometry.IsNotNull()) &&
(curOutput->GetGeometry() != NULL) &&
(!mitk::Equal(m_OldGeometry.GetPointer(), curOutput->GetGeometry(), 0.0001, false))
)
{
mitk::IRenderWindowPart* renderWindow = this->GetRenderWindowPart();
if ((renderWindow != NULL) && (curOutput->GetTimeGeometry()->IsValid()) && (m_Controls.m_ShowImageStream->isChecked()))
{
renderWindow->GetRenderingManager()->InitializeViews(
curOutput->GetGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true);
renderWindow->GetRenderingManager()->RequestUpdateAll();
}
m_CurrentImageWidth = curOutput->GetDimension(0);
m_CurrentImageHeight = curOutput->GetDimension(1);
m_OldGeometry = dynamic_cast(curOutput->GetGeometry());
}
}
//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()
{
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()
{
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()
{
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()
{
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()
{
//clean up and stop timer
StopTimers();
this->RemoveControlWidgets();
this->GetDataStorage()->Remove(m_Node);
m_Node->ReleaseData();
//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);
//show node if the option is enabled
if (m_Controls.m_ShowImageStream->isChecked())
{
this->GetDataStorage()->Add(m_Node);
}
//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);
}
}
void UltrasoundSupport::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()
{
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);
m_Controls.m_ToolBoxControlWidgets->addItem(m_ControlBModeWidget, "B Mode Controls");
if (!m_Device->GetControlInterfaceBMode())
{
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);
m_Controls.m_ToolBoxControlWidgets->addItem(m_ControlDopplerWidget, "Doppler Controls");
if (!m_Device->GetControlInterfaceDoppler())
{
m_Controls.m_ToolBoxControlWidgets->setItemEnabled(m_Controls.m_ToolBoxControlWidgets->count() - 1, false);
}
ctkPluginContext* pluginContext = mitk::PluginActivator::GetContext();
if (pluginContext)
{
std::string filter = "(ork.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()
{
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)
{
if (m_Device.IsNull() || event.getType() != 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;
m_Node->GetLevelWindow(levelWindow);
levelWindow.SetAuto(m_Image, true, true);
m_Node->SetLevelWindow(levelWindow);
}
}
UltrasoundSupport::UltrasoundSupport()
: m_ControlCustomWidget(0), m_ControlBModeWidget(0),
m_ControlProbesWidget(0), m_ImageAlreadySetToNode(false),
m_CurrentImageWidth(0), m_CurrentImageHeight(0)
{
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()
{
try
{
+ StoreUISettings();
StopTimers();
// Get all active devicesand deactivate them to prevent freeze
std::vector devices = this->m_Controls.m_ActiveVideoDevices->GetAllServices();
for (int i = 0; i < devices.size(); i++)
{
mitk::USDevice::Pointer device = devices[i];
if (device.IsNotNull() && device->GetIsActive())
{
device->Deactivate();
device->Disconnect();
}
}
-
- StoreUISettings();
}
catch (std::exception &e)
{
MITK_ERROR << "Exception during call of destructor! Message: " << e.what();
}
}
void UltrasoundSupport::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()
{
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()
{
m_UpdateTimer->start();
if (m_Controls.m_Update2DView->isChecked()) { m_RenderingTimer2d->start(); }
if (m_Controls.m_Update3DView->isChecked()) { m_RenderingTimer3d->start(); }
}
void UltrasoundSupport::StopTimers()
{
m_UpdateTimer->stop();
m_RenderingTimer2d->stop();
m_RenderingTimer3d->stop();
}
void UltrasoundSupport::SetTimerIntervals(int intervalPipeline, int interval2D, int interval3D)
{
m_UpdateTimer->setInterval(intervalPipeline);
m_RenderingTimer2d->setInterval(interval2D);
m_RenderingTimer3d->setInterval(interval3D);
}