diff --git a/CMake/BuildConfigurations/mitkNavigationModules.cmake b/CMake/BuildConfigurations/mitkNavigationModules.cmake
index ee7b528cc9..456c1c877c 100644
--- a/CMake/BuildConfigurations/mitkNavigationModules.cmake
+++ b/CMake/BuildConfigurations/mitkNavigationModules.cmake
@@ -1,37 +1,38 @@
message(STATUS "Configuring MITK Navigation Modules Build")
set(MITK_CONFIG_PACKAGES
ACVD
Qt5
BLUEBERRY
)
# Enable open cv and open igt link, which is a necessary configuration
set(MITK_USE_OpenCV ON CACHE BOOL "MITK Use OpenCV Library" FORCE)
set(MITK_USE_OpenIGTLink ON CACHE BOOL "MITK Use OpenIGTLink Library" FORCE)
# Enable default plugins and the navigation modules
set(MITK_CONFIG_PLUGINS
org.mitk.gui.qt.datamanager
org.mitk.gui.qt.stdmultiwidgeteditor
org.mitk.gui.qt.dicom
org.mitk.gui.qt.imagenavigator
org.mitk.gui.qt.measurementtoolbox
org.mitk.gui.qt.properties
org.mitk.gui.qt.segmentation
org.mitk.gui.qt.volumevisualization
org.mitk.planarfigure
org.mitk.gui.qt.moviemaker
org.mitk.gui.qt.pointsetinteraction
org.mitk.gui.qt.registration
org.mitk.gui.qt.remeshing
org.mitk.gui.qt.viewnavigator
org.mitk.gui.qt.imagecropper
org.mitk.gui.qt.igtexamples
org.mitk.gui.qt.igttracking
org.mitk.gui.qt.igtlplugin
+ org.mitk.gui.qt.openigtlink
org.mitk.gui.qt.ultrasound
org.mitk.gui.qt.toftutorial
org.mitk.gui.qt.tofutil
)
diff --git a/CMake/MITK.vcxproj.user.in b/CMake/MITK.vcxproj.user.in
index 48fc5df678..7d974043e4 100644
--- a/CMake/MITK.vcxproj.user.in
+++ b/CMake/MITK.vcxproj.user.in
@@ -1,15 +1,28 @@
PATH=@MITK_RUNTIME_PATH_REL@;@CUSTOM_RUNTIME_PATH@;@CMAKE_RUNTIME_OUTPUT_DIRECTORY@\@VS_BUILD_TYPE_REL@;@CMAKE_RUNTIME_OUTPUT_DIRECTORY@\plugins\@VS_BUILD_TYPE_REL@;%PATH%
WindowsLocalDebugger
PATH=@MITK_RUNTIME_PATH_RELDEB@;@CUSTOM_RUNTIME_PATH@;@CMAKE_RUNTIME_OUTPUT_DIRECTORY@\@VS_BUILD_TYPE_RELDEB@;@CMAKE_RUNTIME_OUTPUT_DIRECTORY@\plugins\@VS_BUILD_TYPE_RELDEB@;%PATH%
WindowsLocalDebugger
PATH=@MITK_RUNTIME_PATH_DEB@;@CUSTOM_RUNTIME_PATH@;@CMAKE_RUNTIME_OUTPUT_DIRECTORY@\@VS_BUILD_TYPE_DEB@;@CMAKE_RUNTIME_OUTPUT_DIRECTORY@\plugins\@VS_BUILD_TYPE_DEB@;%PATH%
WindowsLocalDebugger
+
+
+ PATH=@MITK_RUNTIME_PATH_REL@;@CUSTOM_RUNTIME_PATH@;@CMAKE_RUNTIME_OUTPUT_DIRECTORY@\@VS_BUILD_TYPE_REL@;@CMAKE_RUNTIME_OUTPUT_DIRECTORY@\plugins\@VS_BUILD_TYPE_REL@;%PATH%
+ WindowsLocalDebugger
+
+
+ PATH=@MITK_RUNTIME_PATH_RELDEB@;@CUSTOM_RUNTIME_PATH@;@CMAKE_RUNTIME_OUTPUT_DIRECTORY@\@VS_BUILD_TYPE_RELDEB@;@CMAKE_RUNTIME_OUTPUT_DIRECTORY@\plugins\@VS_BUILD_TYPE_RELDEB@;%PATH%
+ WindowsLocalDebugger
+
+
+ PATH=@MITK_RUNTIME_PATH_DEB@;@CUSTOM_RUNTIME_PATH@;@CMAKE_RUNTIME_OUTPUT_DIRECTORY@\@VS_BUILD_TYPE_DEB@;@CMAKE_RUNTIME_OUTPUT_DIRECTORY@\plugins\@VS_BUILD_TYPE_DEB@;%PATH%
+ WindowsLocalDebugger
+
\ No newline at end of file
diff --git a/Modules/US/USNavigation/Filter/mitkNavigationDataPassThroughFilter.cpp b/Modules/IGT/Algorithms/mitkNavigationDataPassThroughFilter.cpp
similarity index 100%
rename from Modules/US/USNavigation/Filter/mitkNavigationDataPassThroughFilter.cpp
rename to Modules/IGT/Algorithms/mitkNavigationDataPassThroughFilter.cpp
diff --git a/Modules/US/USNavigation/Filter/mitkNavigationDataPassThroughFilter.h b/Modules/IGT/Algorithms/mitkNavigationDataPassThroughFilter.h
similarity index 91%
rename from Modules/US/USNavigation/Filter/mitkNavigationDataPassThroughFilter.h
rename to Modules/IGT/Algorithms/mitkNavigationDataPassThroughFilter.h
index da5563a0c3..42579317f2 100644
--- a/Modules/US/USNavigation/Filter/mitkNavigationDataPassThroughFilter.h
+++ b/Modules/IGT/Algorithms/mitkNavigationDataPassThroughFilter.h
@@ -1,52 +1,52 @@
/*===================================================================
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 NAVIGATIONDATAPASSTHROUGHFILTER_H
#define NAVIGATIONDATAPASSTHROUGHFILTER_H
#include "mitkNavigationDataToNavigationDataFilter.h"
-#include "MitkUSNavigationExports.h"
+#include "MitkIGTExports.h"
namespace mitk {
/**
* \brief Basis for filters that want to leave the navigation data untouched.
*
* Subclasses can call the mitk::NavigationDataToNavigationDataFilter::GenerateData()
* method in their own GenerateData() implementation to pass through navigation data
* from all inputs to the outputs.
*/
-class MITKUSNAVIGATION_EXPORT NavigationDataPassThroughFilter : public NavigationDataToNavigationDataFilter
+class MITKIGT_EXPORT NavigationDataPassThroughFilter : public NavigationDataToNavigationDataFilter
{
public:
mitkClassMacro(NavigationDataPassThroughFilter, NavigationDataToNavigationDataFilter)
itkNewMacro(Self)
protected:
NavigationDataPassThroughFilter();
virtual ~NavigationDataPassThroughFilter();
/**
* \brief Passes navigation data from all inputs to all outputs.
* If a subclass wants to implement its own version of the GenerateData()
* method it should call this method inside its implementation.
*/
virtual void GenerateData() override;
};
} // namespace mitk
#endif // NAVIGATIONDATAPASSTHROUGHFILTER_H
diff --git a/Modules/US/USNavigation/Filter/mitkNeedleProjectionFilter.cpp b/Modules/IGT/Algorithms/mitkNeedleProjectionFilter.cpp
similarity index 75%
rename from Modules/US/USNavigation/Filter/mitkNeedleProjectionFilter.cpp
rename to Modules/IGT/Algorithms/mitkNeedleProjectionFilter.cpp
index 4b4065d024..6854335767 100644
--- a/Modules/US/USNavigation/Filter/mitkNeedleProjectionFilter.cpp
+++ b/Modules/IGT/Algorithms/mitkNeedleProjectionFilter.cpp
@@ -1,169 +1,198 @@
/*===================================================================
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.
===================================================================*/
// MITK
#include "mitkNeedleProjectionFilter.h"
#include
-#include "mitkUSCombinedModality.h"
+// Vermutung - wird nicht benötigt: #include "mitkUSCombinedModality.h"
// VTK
#include
-
-
mitk::NeedleProjectionFilter::NeedleProjectionFilter()
: m_Projection(mitk::PointSet::New()),
m_OriginalPoints(mitk::PointSet::New()),
+ m_ShowToolAxis(false),
m_SelectedInput(-1)
{
// Tool Coordinates:x axis is chosen as default axis when no axis is specified
- for (int i = 0; i < 2; i++)
+
+ MITK_DEBUG << "Constructor called";
+
+ mitk::Point3D toolAxis;
+ mitk::FillVector3D(toolAxis, 1, 0, 0);
+ m_ToolAxis = toolAxis;
+ InitializeOriginalPoints(toolAxis, m_ShowToolAxis);
+
+ MITK_DEBUG << "orginal point 0 set constructor" << m_OriginalPoints->GetPoint(0);
+ MITK_DEBUG << "orginal point 1 set constructor" << m_OriginalPoints->GetPoint(1);
+}
+
+void mitk::NeedleProjectionFilter::InitializeOriginalPoints(mitk::Point3D toolAxis, bool showToolAxis)
+{
+ m_OriginalPoints = mitk::PointSet::New();
+
+ mitk::Point3D projectionPoint;
+ projectionPoint.SetElement(0, toolAxis.GetElement(0) * 400);
+ projectionPoint.SetElement(1, toolAxis.GetElement(1) * 400);
+ projectionPoint.SetElement(2, toolAxis.GetElement(2) * 400);
+ m_OriginalPoints->InsertPoint(projectionPoint);
+
+ mitk::Point3D toolOrigin;
+ toolOrigin.SetElement(0, 0);
+ toolOrigin.SetElement(1, 0);
+ toolOrigin.SetElement(2, 0);
+ m_OriginalPoints->InsertPoint(toolOrigin);
+
+ if (showToolAxis)
{
- mitk::Point3D point;
- point.SetElement(0, i * 400);
- point.SetElement(1, 0);
- point.SetElement(2, 0);
- m_OriginalPoints->InsertPoint(i, point);
+ mitk::Point3D axisPoint;
+ axisPoint.SetElement(0, toolAxis.GetElement(0) * -400);
+ axisPoint.SetElement(1, toolAxis.GetElement(1) * -400);
+ axisPoint.SetElement(2, toolAxis.GetElement(2) * -400);
+ m_OriginalPoints->InsertPoint(axisPoint);
}
+
+}
+
+void mitk::NeedleProjectionFilter::ShowToolAxis(bool enabled)
+{
+ m_ShowToolAxis = enabled;
+ InitializeOriginalPoints(m_ToolAxis,m_ShowToolAxis);
}
void mitk::NeedleProjectionFilter::SetToolAxisForFilter(mitk::Point3D point)
{
- // Tool Coordinates: First point - Tip of Needle, Second Point - 40 cm distance from needle
- mitk::Point3D originPoint;
- originPoint.SetElement(0, 0);
- originPoint.SetElement(1, 0);
- originPoint.SetElement(2, 0);
- m_OriginalPoints->SetPoint(0, originPoint);
-
- mitk::Point3D endPoint;
- endPoint.SetElement(0, point.GetElement(0) * 400);
- endPoint.SetElement(1, point.GetElement(1) * 400);
- endPoint.SetElement(2, point.GetElement(2) * 400);
- MITK_INFO << "Tool axis in project filter:";
- MITK_INFO << endPoint;
- m_OriginalPoints->SetPoint(1, endPoint);
+ m_ToolAxis = point;
+ InitializeOriginalPoints(m_ToolAxis, m_ShowToolAxis);
+
+ MITK_DEBUG << "orginal point 1 set mutator" << m_OriginalPoints->GetPoint(1);
+ MITK_DEBUG << "orginal point 0 set mutator" << m_OriginalPoints->GetPoint(0);
}
mitk::NeedleProjectionFilter::~NeedleProjectionFilter()
{
}
void mitk::NeedleProjectionFilter::SelectInput(int i)
{
if (i < 0) mitkThrow() << "Negative Input selected in NeedleProjectionFilter";
if (! (static_cast(i) < this->GetInputs().size())) mitkThrow() << "Selected input index is larger than actual number of inputs in NeedleProjectionFilter";
m_SelectedInput = i;
}
void mitk::NeedleProjectionFilter::GenerateData()
{
// copy the navigation data from the inputs to the outputs
mitk::NavigationDataPassThroughFilter::GenerateData();
// If no reference has been set yet, warn and abort
if (m_SelectedInput == -1)
{
MITK_INFO << "No input has been selected in NeedleProjection Filter. Only forwarding NavigationData...";
return;
}
// Cancel, if selected tool is currently not being tracked
if (! GetInput(m_SelectedInput)->IsDataValid()) return;
// Outputs have been updated, now to calculate the Projection
// 1) Generate Pseudo-Geometry for Input
mitk::AffineTransform3D::Pointer refTrans = this->NavigationDataToTransform(this->GetInput(m_SelectedInput));
mitk::Geometry3D::Pointer refGeom = this->TransformToGeometry(refTrans);
+
// 2) Transform Original Pointset
m_OriginalPoints->SetGeometry(refGeom);
// Update Projection (We do not clone, since we want to keep properties alive)
m_Projection->SetPoint(0, m_OriginalPoints->GetPoint(0));
m_Projection->SetPoint(1, m_OriginalPoints->GetPoint(1));
+ if (m_ShowToolAxis) { m_Projection->SetPoint(2, m_OriginalPoints->GetPoint(2)); }
+
// 3a) If no target Plane has been set, then leave it at that
if (this->m_TargetPlane.IsNull())
return;
// 3b) else, calculate intersection with plane
mitk::PlaneGeometry::Pointer plane = mitk::PlaneGeometry::New();
plane->SetIndexToWorldTransform(m_TargetPlane);
//plane->TransferItkToVtkTransform(); //included in SetIndexToWorldTransform
double t;
double x[3];
// Points that define the needle vector
double p1[3] = {m_OriginalPoints->GetPoint(0)[0], m_OriginalPoints->GetPoint(0)[1], m_OriginalPoints->GetPoint(0)[2]};
double p2[3] = {m_OriginalPoints->GetPoint(1)[0], m_OriginalPoints->GetPoint(1)[1], m_OriginalPoints->GetPoint(1)[2]};
// Center of image plane and it's normal
double center[3] = {plane->GetCenter()[0], plane->GetCenter()[1], plane->GetCenter()[2]};
double normal[3] = {plane->GetNormal()[0], plane->GetNormal()[1], plane->GetNormal()[2]};
vtkPlane::IntersectWithLine(p1, p2, normal, center, t, x);
// change (cut) needle path only if the needle points to the image plane;
// otherwise the needle path direction would be changed pointing to the image plane
if ( t >= 0 )
{
// Convert vtk to itk
mitk::Point3D intersection;
intersection[0] = x[0];
intersection[1] = x[1];
intersection[2] = x[2];
// Replace distant point with image intersection
- m_Projection->SetPoint(1, intersection);
+ m_Projection->SetPoint(0, intersection);
+
}
}
mitk::AffineTransform3D::Pointer mitk::NeedleProjectionFilter::NavigationDataToTransform(const mitk::NavigationData * nd)
{
mitk::AffineTransform3D::Pointer affineTransform = mitk::AffineTransform3D::New();
affineTransform->SetIdentity();
//calculate the transform from the quaternions
static itk::QuaternionRigidTransform::Pointer quatTransform = itk::QuaternionRigidTransform::New();
mitk::NavigationData::OrientationType orientation = nd->GetOrientation();
// convert mitk::ScalarType quaternion to double quaternion because of itk bug
vnl_quaternion doubleQuaternion(orientation.x(), orientation.y(), orientation.z(), orientation.r());
quatTransform->SetIdentity();
quatTransform->SetRotation(doubleQuaternion);
quatTransform->Modified();
/* because of an itk bug, the transform can not be calculated with float data type.
To use it in the mitk geometry classes, it has to be transfered to mitk::ScalarType which is float */
static AffineTransform3D::MatrixType m;
mitk::TransferMatrix(quatTransform->GetMatrix(), m);
affineTransform->SetMatrix(m);
/*set the offset by convert from itkPoint to itkVector and setting offset of transform*/
mitk::Vector3D pos;
pos.SetVnlVector(nd->GetPosition().GetVnlVector());
affineTransform->SetOffset(pos);
affineTransform->Modified();
return affineTransform;
}
mitk::Geometry3D::Pointer mitk::NeedleProjectionFilter::TransformToGeometry(mitk::AffineTransform3D::Pointer transform){
mitk::Geometry3D::Pointer g3d = mitk::Geometry3D::New();
mitk::ScalarType scale[] = {1.0, 1.0, 1.0};
g3d->SetSpacing(scale);
g3d->SetIndexToWorldTransform(transform);
//g3d->TransferItkToVtkTransform(); // update VTK Transform for rendering too //included in SetIndexToWorldTransform
g3d->Modified();
return g3d;
}
diff --git a/Modules/US/USNavigation/Filter/mitkNeedleProjectionFilter.h b/Modules/IGT/Algorithms/mitkNeedleProjectionFilter.h
similarity index 78%
rename from Modules/US/USNavigation/Filter/mitkNeedleProjectionFilter.h
rename to Modules/IGT/Algorithms/mitkNeedleProjectionFilter.h
index 1b03ffd6ea..845a2a9b48 100644
--- a/Modules/US/USNavigation/Filter/mitkNeedleProjectionFilter.h
+++ b/Modules/IGT/Algorithms/mitkNeedleProjectionFilter.h
@@ -1,86 +1,97 @@
/*===================================================================
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 NEEDLEPROJECTIONFILTER_H_INCLUDED
#define NEEDLEPROJECTIONFILTER_H_INCLUDED
-#include
+#include "MitkIGTExports.h"
// MITK
#include
#include
#include
#include
namespace mitk {
/**
* \brief This filter projects a needle's path onto a plane.
*
* To use it, hook it up to a NavigationDataStream,
* select an input and set an AffineTransform 3D that represents the target plane.
* You can then call GetProjection to retrieve a pointset that represents the projected path.
* You may change the PointSet's properties, these changes will not be overwritten.
* If no Input is selected, the target Pointset will not update
* If no Target Plane is selected, The projection line will always be 40 cm long
* Any points you add to the pointSet will be overwritten during the next Update.
* The point with index zero is the Tip of the Needle.
* The Point with index one is the projection onto the plane.
*
* Projection will happen onto an extension of the plane as well - the filter does not regard boundaries
* This Filter currently only supports projection of one needle. Extension to multiple needles / planes should be easy.
*
- * \ingroup US
+ * \ingroup IGT
*/
- class MITKUSNAVIGATION_EXPORT NeedleProjectionFilter : public NavigationDataPassThroughFilter
+ class MITKIGT_EXPORT NeedleProjectionFilter : public NavigationDataPassThroughFilter
{
public:
mitkClassMacro(NeedleProjectionFilter, NavigationDataPassThroughFilter);
itkNewMacro(Self);
virtual void SelectInput(int i);
itkGetMacro(TargetPlane, mitk::AffineTransform3D::Pointer);
itkSetMacro(TargetPlane, mitk::AffineTransform3D::Pointer);
itkGetMacro(Projection, mitk::PointSet::Pointer);
+ /** Sets the tool axis for this filter. The default tool axis is along the x-axis in
+ * tool coordinates. */
void SetToolAxisForFilter(mitk::Point3D point);
+ /** Sets whether the tool axis should be visualized. This is required if no surface is available.
+ * If disabled only the projection and not the axis is shown. It's disabled by default. */
+ void ShowToolAxis(bool enabled);
protected:
NeedleProjectionFilter();
virtual ~NeedleProjectionFilter();
virtual void GenerateData() override;
mitk::AffineTransform3D::Pointer m_TargetPlane;
mitk::PointSet::Pointer m_Projection;
mitk::PointSet::Pointer m_OriginalPoints;
+ bool m_ShowToolAxis;
+ mitk::Point3D m_ToolAxis;
int m_SelectedInput;
+ /** Internal method for initialization of the projection / tool axis representation
+ * by the point set m_OriginalPoints. */
+ void InitializeOriginalPoints(mitk::Point3D toolAxis, bool showToolAxis);
+
/**
* \brief Creates an Affine Transformation from a Navigation Data Object.
*/
mitk::AffineTransform3D::Pointer NavigationDataToTransform(const mitk::NavigationData * nd);
/**
* \brief Creates an Geometry 3D Object from an AffineTransformation.
*/
mitk::Geometry3D::Pointer TransformToGeometry(mitk::AffineTransform3D::Pointer transform);
};
} // namespace mitk
#endif
diff --git a/Modules/IGT/Common/mitkTrackingTypes.h b/Modules/IGT/Common/mitkTrackingTypes.h
index 7cf0a0250b..dbb7c5db5e 100644
--- a/Modules/IGT/Common/mitkTrackingTypes.h
+++ b/Modules/IGT/Common/mitkTrackingTypes.h
@@ -1,93 +1,94 @@
/*===================================================================
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 MITKTRACKINGTYPES_H_HEADER_INCLUDED_
#define MITKTRACKINGTYPES_H_HEADER_INCLUDED_
#include
#include
#include
namespace mitk
{
typedef std::string TrackingDeviceType;
/**
* /brief This structure defines key variables of a device model and type.
+ * Line is (usually) identical with the TrackingDeviceName and can be used to compare TrackingDevices (string).
* It is specifically used to find out which models belong to which vendor, and what volume
* to use for a specific Model. Leaving VolumeModelLocation set to null will instruct the Generator
* to generate a field to the best of his ability. HardwareCode stands for a hexadecimal string,
* that represents the tracking volume. "X" stands for "hardwarecode is not known" or "tracking device has
* no hardware code". For NDI devices it is used in the SetVolume() Method in mitkNDITrackingDevice.cpp.
* The Pyramid Volume has the hardwarecode "4", but it is not supported yet.
*/
struct TrackingDeviceData {
TrackingDeviceType Line;
std::string Model;
std::string VolumeModelLocation;
std::string HardwareCode;
};
/**Documentation
* \brief Error codes of NDI tracking devices
*/
enum OperationMode
{
ToolTracking6D,
ToolTracking5D,
MarkerTracking3D,
HybridTracking
};
/**Documentation
* \brief activation rate of IR illuminator for NDI Polaris tracking device
*/
enum IlluminationActivationRate
{
Hz20 = 20,
Hz30 = 30,
Hz60 = 60
};
/**Documentation
* \brief Data transfer mode for NDI tracking devices
*/
enum DataTransferMode
{
TX = 0,
BX = 1
};
/**Documentation
* \brief Query mode for NDI tracking devices
*/
enum PHSRQueryType
{
ALL = 0x00,
FREED = 0x01,
OCCUPIED = 0x02,
INITIALIZED = 0x03,
ENABLED = 0x04
};
typedef itk::Point MarkerPointType;
typedef std::vector MarkerPointContainerType;
/** definition of colors for IGT */
static mitk::Color IGTColor_WARNING = mitk::ColorProperty::New(1.0f, 0.0f, 0.0f)->GetColor();
static mitk::Color IGTColor_VALID = mitk::ColorProperty::New(0.0f, 1.0f, 0.0f)->GetColor();
} // namespace mitk
#endif /* MITKTRACKINGTYPES_H_HEADER_INCLUDED_ */
diff --git a/Modules/IGT/DataManagement/mitkNavigationTool.cpp b/Modules/IGT/DataManagement/mitkNavigationTool.cpp
index 02e48810a0..1763aeecfe 100644
--- a/Modules/IGT/DataManagement/mitkNavigationTool.cpp
+++ b/Modules/IGT/DataManagement/mitkNavigationTool.cpp
@@ -1,134 +1,336 @@
/*===================================================================
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 "mitkNavigationTool.h"
#include "mitkIGTException.h"
#include "mitkNavigationData.h"
#include "Poco/File.h"
#include "mitkUnspecifiedTrackingTypeInformation.h"
+#include "mitkInternalTrackingTool.h"
+
+#include "vtkSphereSource.h"
+#include "vtkConeSource.h"
+#include "vtkLineSource.h"
+#include "vtkCylinderSource.h"
+#include "vtkTransformPolyDataFilter.h"
+#include
+#include "mitkTextAnnotation3D.h"
+#include "mitkManualPlacementAnnotationRenderer.h"
+#include "mitkBaseRenderer.h"
mitk::NavigationTool::NavigationTool() : m_Identifier("None"),
- m_Type(mitk::NavigationTool::Unknown),
- m_CalibrationFile("none"),
- m_SerialNumber(""),
- m_TrackingDeviceType(mitk::UnspecifiedTrackingTypeInformation::GetTrackingDeviceName()),
- m_ToolRegistrationLandmarks(mitk::PointSet::New()),
- m_ToolCalibrationLandmarks(mitk::PointSet::New()),
- m_ToolTipOrientation(mitk::Quaternion(0,0,0,1))
- {
- m_ToolTipPosition[0] = 0;
- m_ToolTipPosition[1] = 0;
- m_ToolTipPosition[2] = 0;
+m_Type(mitk::NavigationTool::Unknown),
+m_CalibrationFile("none"),
+m_SerialNumber(""),
+m_TrackingDeviceType(mitk::UnspecifiedTrackingTypeInformation::GetTrackingDeviceName()),
+m_ToolRegistrationLandmarks(mitk::PointSet::New()),
+m_ToolCalibrationLandmarks(mitk::PointSet::New()),
+m_ToolTipOrientation(mitk::Quaternion(0, 0, 0, 1))
+{
+ m_ToolTipPosition[0] = 0;
+ m_ToolTipPosition[1] = 0;
+ m_ToolTipPosition[2] = 0;
- m_ToolAxis[0] = 1;
- m_ToolAxis[1] = 0;
- m_ToolAxis[2] = 0;
- }
+ m_ToolAxis[0] = 1;
+ m_ToolAxis[1] = 0;
+ m_ToolAxis[2] = 0;
-mitk::NavigationTool::~NavigationTool()
- {
+ SetDefaultSurface();
+}
+
+itk::LightObject::Pointer mitk::NavigationTool::InternalClone() const
+{
+ Self::Pointer tool = new Self(*this);
+ tool->UnRegister();
+ return tool.GetPointer();
+}
+mitk::NavigationTool::NavigationTool(const NavigationTool &other)
+ : Superclass()
+{
+ this->m_Identifier = other.m_Identifier;
+ this->m_Type = other.m_Type;
+ if (other.m_DataNode.IsNotNull())
+ {
+ this->m_DataNode = other.m_DataNode->Clone();
+ this->m_DataNode->SetName(other.m_DataNode->GetName());
+ if (other.m_DataNode->GetData())
+ {
+ this->m_DataNode->SetData(dynamic_cast(other.m_DataNode->GetData()->Clone().GetPointer()));
+ }
}
+ if (other.m_SpatialObject.IsNotNull())
+ this->m_SpatialObject = other.m_SpatialObject->Clone();
+ this->m_CalibrationFile = other.m_CalibrationFile;
+ this->m_SerialNumber = other.m_SerialNumber;
+ this->m_TrackingDeviceType = other.m_TrackingDeviceType;
+ if (other.m_ToolRegistrationLandmarks.IsNotNull())
+ this->m_ToolRegistrationLandmarks = other.m_ToolRegistrationLandmarks->Clone();
+ if (other.m_ToolCalibrationLandmarks.IsNotNull())
+ this->m_ToolCalibrationLandmarks = other.m_ToolCalibrationLandmarks->Clone();
+ this->m_ToolTipPosition = other.m_ToolTipPosition;
+ this->m_ToolTipOrientation = other.m_ToolTipOrientation;
+ this->m_ToolAxis = other.m_ToolAxis;
+}
+
+mitk::NavigationTool::~NavigationTool()
+{
+}
+
mitk::AffineTransform3D::Pointer mitk::NavigationTool::GetToolTipTransform()
- {
- mitk::NavigationData::Pointer returnValue = mitk::NavigationData::New();
- returnValue->SetPosition(this->m_ToolTipPosition);
- returnValue->SetOrientation(this->m_ToolTipOrientation);
- return returnValue->GetAffineTransform3D();
- }
-
-void mitk::NavigationTool::Graft( const DataObject *data )
+{
+ mitk::NavigationData::Pointer returnValue = mitk::NavigationData::New();
+ returnValue->SetPosition(this->m_ToolTipPosition);
+ returnValue->SetOrientation(this->m_ToolTipOrientation);
+ return returnValue->GetAffineTransform3D();
+}
+
+void mitk::NavigationTool::Graft(const DataObject *data)
{
// Attempt to cast data to an NavigationData
const Self* nd;
try
{
- nd = dynamic_cast( data );
+ nd = dynamic_cast(data);
}
- catch( ... )
+ catch (...)
{
mitkThrowException(mitk::IGTException) << "mitk::NavigationData::Graft cannot cast "
<< typeid(data).name() << " to "
- << typeid(const Self *).name() ;
+ << typeid(const Self *).name();
}
if (!nd)
{
// pointer could not be cast back down
mitkThrowException(mitk::IGTException) << "mitk::NavigationData::Graft cannot cast "
<< typeid(data).name() << " to "
- << typeid(const Self *).name() ;
+ << typeid(const Self *).name();
}
// Now copy anything that is needed
m_Identifier = nd->GetIdentifier();
m_Type = nd->GetType();
m_DataNode->SetName(nd->GetDataNode()->GetName());
m_DataNode->SetData(nd->GetDataNode()->GetData());
m_SpatialObject = nd->GetSpatialObject();
- m_TrackingTool = nd->GetTrackingTool();
m_CalibrationFile = nd->GetCalibrationFile();
m_SerialNumber = nd->GetSerialNumber();
m_TrackingDeviceType = nd->GetTrackingDeviceType();
m_ToolRegistrationLandmarks = nd->GetToolRegistrationLandmarks();
m_ToolCalibrationLandmarks = nd->GetToolCalibrationLandmarks();
m_ToolTipPosition = nd->GetToolTipPosition();
m_ToolTipOrientation = nd->GetToolTipOrientation();
m_ToolAxis = nd->GetToolAxis();
-
}
bool mitk::NavigationTool::IsToolTipSet()
- {
- if( (m_ToolTipPosition[0] == 0) &&
+{
+ if ((m_ToolTipPosition[0] == 0) &&
(m_ToolTipPosition[1] == 0) &&
(m_ToolTipPosition[2] == 0) &&
(m_ToolTipOrientation.x() == 0) &&
(m_ToolTipOrientation.y() == 0) &&
(m_ToolTipOrientation.z() == 0) &&
(m_ToolTipOrientation.r() == 1))
- return false;
+ return false;
else return true;
- }
+}
void mitk::NavigationTool::SetCalibrationFile(const std::string filename)
- {
+{
//check if file does exist:
- if (filename=="")
- {
+ if (filename == "")
+ {
m_CalibrationFile = "none";
- }
+ }
else
- {
+ {
Poco::File myFile(filename);
if (myFile.exists())
m_CalibrationFile = filename;
else
m_CalibrationFile = "none";
- }
}
+}
std::string mitk::NavigationTool::GetToolName()
- {
- if (this->m_DataNode.IsNull()) {return "";}
- else {return m_DataNode->GetName();}
- }
+{
+ if (this->m_DataNode.IsNull()) { return ""; }
+ else { return m_DataNode->GetName(); }
+}
mitk::Surface::Pointer mitk::NavigationTool::GetToolSurface()
- {
- if (this->m_DataNode.IsNull()) {return nullptr;}
- else if (this->m_DataNode->GetData() == nullptr) {return nullptr;}
- else {return dynamic_cast(m_DataNode->GetData());}
- }
+{
+ if (this->m_DataNode.IsNull()) { return nullptr; }
+ else if (this->m_DataNode->GetData() == nullptr) { return nullptr; }
+ else { return dynamic_cast(m_DataNode->GetData()); }
+}
+
+void mitk::NavigationTool::SetDefaultSurface()
+{
+ if (m_DataNode.IsNull())
+ m_DataNode = mitk::DataNode::New();
+
+ mitk::Surface::Pointer mySphere = mitk::Surface::New();
+
+ double axisLength = 5.;
+
+ vtkSphereSource *vtkSphere = vtkSphereSource::New();
+ vtkConeSource *vtkCone = vtkConeSource::New();
+ vtkCylinderSource *vtkCylinder = vtkCylinderSource::New();
+ vtkPolyData* axis = vtkPolyData::New();
+ vtkLineSource *vtkLine = vtkLineSource::New();
+ vtkLineSource *vtkLine2 = vtkLineSource::New();
+ vtkLineSource *vtkLine3 = vtkLineSource::New();
+
+ vtkAppendPolyData* appendPolyData = vtkAppendPolyData::New();
+ vtkPolyData* surface = vtkPolyData::New();
+
+ //Y-Axis (start with y, cause cylinder is oriented in y by vtk default...)
+ vtkCone->SetDirection(0, 1, 0);
+ vtkCone->SetHeight(1.0);
+ vtkCone->SetRadius(0.4f);
+ vtkCone->SetResolution(16);
+ vtkCone->SetCenter(0.0, axisLength, 0.0);
+ vtkCone->Update();
+
+ vtkCylinder->SetRadius(0.05);
+ vtkCylinder->SetHeight(axisLength);
+ vtkCylinder->SetCenter(0.0, 0.5*axisLength, 0.0);
+ vtkCylinder->Update();
+
+ appendPolyData->AddInputData(vtkCone->GetOutput());
+ appendPolyData->AddInputData(vtkCylinder->GetOutput());
+ appendPolyData->Update();
+ axis->DeepCopy(appendPolyData->GetOutput());
+
+ //y symbol
+ vtkLine->SetPoint1(-0.5, axisLength + 2., 0.0);
+ vtkLine->SetPoint2(0.0, axisLength + 1.5, 0.0);
+ vtkLine->Update();
+
+ vtkLine2->SetPoint1(0.5, axisLength + 2., 0.0);
+ vtkLine2->SetPoint2(-0.5, axisLength + 1., 0.0);
+ vtkLine2->Update();
+
+ appendPolyData->AddInputData(vtkLine->GetOutput());
+ appendPolyData->AddInputData(vtkLine2->GetOutput());
+ appendPolyData->AddInputData(axis);
+ appendPolyData->Update();
+ surface->DeepCopy(appendPolyData->GetOutput());
+
+ //X-axis
+ vtkTransform *XTransform = vtkTransform::New();
+ XTransform->RotateZ(-90);
+ vtkTransformPolyDataFilter *TrafoFilter = vtkTransformPolyDataFilter::New();
+ TrafoFilter->SetTransform(XTransform);
+ TrafoFilter->SetInputData(axis);
+ TrafoFilter->Update();
+
+ //x symbol
+ vtkLine->SetPoint1(axisLength + 2., -0.5, 0.0);
+ vtkLine->SetPoint2(axisLength + 1., 0.5, 0.0);
+ vtkLine->Update();
+
+ vtkLine2->SetPoint1(axisLength + 2., 0.5, 0.0);
+ vtkLine2->SetPoint2(axisLength + 1., -0.5, 0.0);
+ vtkLine2->Update();
+
+ appendPolyData->AddInputData(vtkLine->GetOutput());
+ appendPolyData->AddInputData(vtkLine2->GetOutput());
+ appendPolyData->AddInputData(TrafoFilter->GetOutput());
+ appendPolyData->AddInputData(surface);
+ appendPolyData->Update();
+ surface->DeepCopy(appendPolyData->GetOutput());
+
+ //Z-axis
+ vtkTransform *ZTransform = vtkTransform::New();
+ ZTransform->RotateX(90);
+ TrafoFilter->SetTransform(ZTransform);
+ TrafoFilter->SetInputData(axis);
+ TrafoFilter->Update();
+
+ //z symbol
+ vtkLine->SetPoint1(-0.5, 0.0, axisLength + 2.);
+ vtkLine->SetPoint2(0.5, 0.0, axisLength + 2.);
+ vtkLine->Update();
+
+ vtkLine2->SetPoint1(-0.5, 0.0, axisLength + 2.);
+ vtkLine2->SetPoint2(0.5, 0.0, axisLength + 1.);
+ vtkLine2->Update();
+
+ vtkLine3->SetPoint1(0.5, 0.0, axisLength + 1.);
+ vtkLine3->SetPoint2(-0.5, 0.0, axisLength + 1.);
+ vtkLine3->Update();
+
+ appendPolyData->AddInputData(vtkLine->GetOutput());
+ appendPolyData->AddInputData(vtkLine2->GetOutput());
+ appendPolyData->AddInputData(vtkLine3->GetOutput());
+ appendPolyData->AddInputData(TrafoFilter->GetOutput());
+ appendPolyData->AddInputData(surface);
+ appendPolyData->Update();
+ surface->DeepCopy(appendPolyData->GetOutput());
+
+ //Center
+ vtkSphere->SetRadius(0.5f);
+ vtkSphere->SetCenter(0.0, 0.0, 0.0);
+ vtkSphere->Update();
+
+ appendPolyData->AddInputData(vtkSphere->GetOutput());
+ appendPolyData->AddInputData(surface);
+ appendPolyData->Update();
+ surface->DeepCopy(appendPolyData->GetOutput());
+
+ //Scale
+ vtkTransform *ScaleTransform = vtkTransform::New();
+ ScaleTransform->Scale(20., 20., 20.);
+
+ TrafoFilter->SetTransform(ScaleTransform);
+ TrafoFilter->SetInputData(surface);
+ TrafoFilter->Update();
+
+ mySphere->SetVtkPolyData(TrafoFilter->GetOutput());
+
+ vtkCone->Delete();
+ vtkSphere->Delete();
+ vtkLine->Delete();
+ vtkLine2->Delete();
+ vtkLine3->Delete();
+ vtkCylinder->Delete();
+ ZTransform->Delete();
+ XTransform->Delete();
+ ScaleTransform->Delete();
+ TrafoFilter->Delete();
+ appendPolyData->Delete();
+ surface->Delete();
+
+ this->GetDataNode()->SetData(mySphere);
+}
+
+std::string mitk::NavigationTool::GetStringWithAllToolInformation() const
+{
+ std::stringstream _info;
+ _info << " Identifier: " << this->m_Identifier << "\n"
+ << " NavigationToolType: " << m_Type << "\n"
+ << " Calibration file: " << m_CalibrationFile << "\n"
+ << " Serial number: " << m_SerialNumber << "\n"
+ << " TrackingDeviceType: " << m_TrackingDeviceType << "\n"
+ << " ToolTip Position: " << m_ToolTipPosition << "\n"
+ << " ToolTip Orientation: " << m_ToolTipOrientation << "\n"
+ << " ToolTip Axis: " << m_ToolAxis;
+
+ return _info.str();
+}
\ No newline at end of file
diff --git a/Modules/IGT/DataManagement/mitkNavigationTool.h b/Modules/IGT/DataManagement/mitkNavigationTool.h
index 04ce577314..d77d3ea8de 100644
--- a/Modules/IGT/DataManagement/mitkNavigationTool.h
+++ b/Modules/IGT/DataManagement/mitkNavigationTool.h
@@ -1,206 +1,212 @@
/*===================================================================
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 NAVIGATIONTOOL_H_INCLUDED
#define NAVIGATIONTOOL_H_INCLUDED
//itk headers
#include
#include
#include
//mitk headers
#include
#include
#include
#include
#include
#include
#include
namespace mitk {
/**Documentation
* \brief An object of this class represents a navigation tool in the view of the software.
* A few informations like an identifier, a toolname, a surface and a itk spatial
* object are stored in such an object. The classes NavigationToolReader and
* are availiable to write/read tools to/from the harddisc. If you need a collection
* of navigation tools the class NavigationToolStorage could be used.
*
* \ingroup IGT
*/
class MITKIGT_EXPORT NavigationTool : public itk::DataObject
{
public:
mitkClassMacroItkParent(NavigationTool,itk::DataObject);
itkFactorylessNewMacro(Self)
itkCloneMacro(Self)
enum NavigationToolType {Instrument, Fiducial, Skinmarker, Unknown};
//## getter and setter ##
//NavigationToolType:
itkGetConstMacro(Type,NavigationToolType);
itkSetMacro(Type,NavigationToolType);
//Identifier:
itkGetConstMacro(Identifier,std::string);
itkSetMacro(Identifier,std::string);
//Datatreenode:
itkGetConstMacro(DataNode,mitk::DataNode::Pointer);
itkSetMacro(DataNode,mitk::DataNode::Pointer);
//SpatialObject:
itkGetConstMacro(SpatialObject,itk::SpatialObject<3>::Pointer);
itkSetMacro(SpatialObject,itk::SpatialObject<3>::Pointer);
- //TrackingTool:
- itkGetConstMacro(TrackingTool,mitk::TrackingTool::Pointer);
- itkSetMacro(TrackingTool,mitk::TrackingTool::Pointer);
-
//CalibrationFile:
itkGetConstMacro(CalibrationFile,std::string);
void SetCalibrationFile(const std::string filename);
//Tool tip definition:
itkGetConstMacro(ToolTipPosition,mitk::Point3D);
itkSetMacro(ToolTipPosition,mitk::Point3D);
itkGetConstMacro(ToolTipOrientation,mitk::Quaternion);
itkSetMacro(ToolTipOrientation,mitk::Quaternion);
//Tool Axis definition:
//default tool axis is along x axis, the tool axis must be normalized
itkGetConstMacro(ToolAxis, mitk::Point3D);
itkSetMacro(ToolAxis, mitk::Point3D);
/** @return Returns the tooltip as transform object. */
mitk::AffineTransform3D::Pointer GetToolTipTransform();
/** @return Returns true if a tooltip is set, false if not. */
bool IsToolTipSet();
//Tool Landmarks:
/** For overview, here are descriptons of the two types of tool landmarks:
*
* tool calibration landmarks: These landmarks may be used clearly define the tools pose only by
* using landmarks in the tool coordinate system. E.g., two landmarks for a 5DoF tool and three
* landmarks for a 6DoF tool. These landmarks may be used, e.g., for a point based registration
* of a tool from image space to tracking space.
*
* tool registration landmarks: These landmarks are designed for representing defined landmarks
* on a tools surface. The number of these landmarks might exeed the number of tool calibration
* landmarks for reasons of redundancy and averaging. They are used for, e.g., manually registering
* the pose of a tool by visual markers in a CT scan. If you would use these landmarks to do a
* point based registration from image space to tracking space later, you might overweight the
* tool because of two many landmarks compared to other markers.
*
* @return Returns the tool registration landmarks which represent markers / special points on a
* tool that can be used for registration. The landmarks should be given in tool coordinates.
* If there are no landmarks defined for this tool the method returns an empty point set.
*/
itkGetConstMacro(ToolRegistrationLandmarks,mitk::PointSet::Pointer);
/** @brief Sets the tool registration landmarks which represent markers / special points on a
* tool that can be used for registration. The landmarks should be given in tool coordinates.
*/
itkSetMacro(ToolRegistrationLandmarks,mitk::PointSet::Pointer);
/** @return Returns the tool calibration landmarks for calibration of the defined points in the
* tool coordinate system, e.g. 2 landmarks for a 5DoF tool and 3 landmarks for a 6DoF tool.
*/
itkGetConstMacro(ToolCalibrationLandmarks,mitk::PointSet::Pointer);
/** @brief Sets the tool calibration landmarks for calibration of defined points in the
* tool coordinate system, e.g. 2 landmarks for a 5DoF tool and 3 landmarks for a 6DoF tool.
*/
itkSetMacro(ToolCalibrationLandmarks,mitk::PointSet::Pointer);
//SerialNumber:
itkGetConstMacro(SerialNumber,std::string);
itkSetMacro(SerialNumber,std::string);
//TrackingDeviceType:
itkGetConstMacro(TrackingDeviceType,mitk::TrackingDeviceType);
itkSetMacro(TrackingDeviceType,mitk::TrackingDeviceType);
//ToolName (only getter):
/** @return Returns the name of this navigation tool. Returns an empty string if there is
* no name (for example because the data node has not been set yet).
*
* Note: There is no setter for the name,
* because the name of the corresponding data node is used as tool name. So if you
* want to modify the name of this navigation tool only get the data node and modify
* its name.
*/
std::string GetToolName();
//ToolSurface (only getter):
/** @return Returns the surface of this navigation tool. Returns nullptr if there is
* no surface (for example because the data node has not been set yet).
*
* Note: There is no setter for the surface,
* because the surface is the data of the corresponding data node. So if you
* want to set a new surface only get the data node and modify its data.
*/
mitk::Surface::Pointer GetToolSurface();
/**
* \brief Graft the data and information from one NavigationTool to another.
*
* Copies the content of data into this object.
* This is a convenience method to setup a second NavigationTool object with all the meta
* information of another NavigationTool object.
* Note that this method is different than just using two
* SmartPointers to the same NavigationTool object since separate DataObjects are
* still maintained.
*/
virtual void Graft(const DataObject *data) override;
+
+
+ /**
+ * Return all relevant information as string, e.g. to display all tool information
+ */
+ std::string GetStringWithAllToolInformation() const;
+
+
+ void SetDefaultSurface();
+
//#######################
protected:
NavigationTool();
+ NavigationTool(const NavigationTool &other);
~NavigationTool();
+ virtual itk::LightObject::Pointer InternalClone() const override;
//## data structure of a navigation tool object ##
std::string m_Identifier;
NavigationToolType m_Type;
/** @brief This DataNode holds a toolname and a tool surface */
mitk::DataNode::Pointer m_DataNode;
/** @brief This member variable holds a mathamatical description of the tool */
itk::SpatialObject<3>::Pointer m_SpatialObject;
- /** @brief This member variable holds a pointer to the corresponding tracking tool in the hardware. */
- mitk::TrackingTool::Pointer m_TrackingTool;
/** @brief The path to the calibration file of the tool. */
std::string m_CalibrationFile;
/** @brief A unique serial number of the tool which is needed to identify the tool correctly. This is very important
* in case of the NDI Aurora System. */
std::string m_SerialNumber;
/** @brief This member holds the tracking device type of the tool. */
mitk::TrackingDeviceType m_TrackingDeviceType;
/** @brief Holds landmarks for tool registration. */
mitk::PointSet::Pointer m_ToolRegistrationLandmarks;
/** @brief Holds landmarks for calibration of the defined points in the tool coordinate system,
* e.g. 2 landmarks for a 5DoF tool and 3 landmarks for a 6DoF tool.
*/
mitk::PointSet::Pointer m_ToolCalibrationLandmarks;
/** @brief Holds the position of the tool tip. */
mitk::Point3D m_ToolTipPosition;
/** @brief Holds the orientation of the tool tip. */
mitk::Quaternion m_ToolTipOrientation;
/** @brief Holds the axis of the tool. */
mitk::Point3D m_ToolAxis;
//#################################################
};
} // namespace mitk
#endif //NAVIGATIONTOOL
diff --git a/Modules/IGT/DataManagement/mitkNavigationToolStorage.cpp b/Modules/IGT/DataManagement/mitkNavigationToolStorage.cpp
index 399d800e5c..85b8e27465 100644
--- a/Modules/IGT/DataManagement/mitkNavigationToolStorage.cpp
+++ b/Modules/IGT/DataManagement/mitkNavigationToolStorage.cpp
@@ -1,219 +1,239 @@
/*===================================================================
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 "mitkNavigationToolStorage.h"
//Microservices
#include
#include
#include
const std::string mitk::NavigationToolStorage::US_INTERFACE_NAME = "org.mitk.services.NavigationToolStorage"; // Name of the interface
const std::string mitk::NavigationToolStorage::US_PROPKEY_SOURCE_ID = US_INTERFACE_NAME + ".sourceID";
const std::string mitk::NavigationToolStorage::US_PROPKEY_STORAGE_NAME = US_INTERFACE_NAME + ".name";
mitk::NavigationToolStorage::NavigationToolStorage()
: m_ToolCollection(std::vector()),
m_DataStorage(nullptr),
- m_storageLocked(false)
- {
+ m_storageLocked(false)
+{
this->SetName("ToolStorage (no name given)");
- }
+}
-mitk::NavigationToolStorage::NavigationToolStorage(mitk::DataStorage::Pointer ds) : m_storageLocked(false)
- {
+mitk::NavigationToolStorage::NavigationToolStorage(mitk::DataStorage::Pointer ds)
+ : m_storageLocked(false)
+{
m_ToolCollection = std::vector();
this->m_DataStorage = ds;
- }
+ this->SetName("Tool Storage (no name given)");
+}
void mitk::NavigationToolStorage::SetName(std::string n)
- {
+{
m_Name = n;
- m_props[ US_PROPKEY_STORAGE_NAME ] = m_Name;
- }
+ m_props[US_PROPKEY_STORAGE_NAME] = m_Name;
+}
- void mitk::NavigationToolStorage::UpdateMicroservice()
- {
- if (m_ServiceRegistration) {m_ServiceRegistration.SetProperties(m_props);}
- }
+std::string mitk::NavigationToolStorage::GetName() const
+{
+ return m_Name;
+}
+void mitk::NavigationToolStorage::UpdateMicroservice()
+{
+ if (m_ServiceRegistration) { m_ServiceRegistration.SetProperties(m_props); }
+}
mitk::NavigationToolStorage::~NavigationToolStorage()
- {
+{
if (m_DataStorage.IsNotNull()) //remove all nodes from the data storage
- {
- for(std::vector::iterator it = m_ToolCollection.begin(); it != m_ToolCollection.end(); it++)
- m_DataStorage->Remove((*it)->GetDataNode());
- }
+ {
+ for (std::vector::iterator it = m_ToolCollection.begin(); it != m_ToolCollection.end(); it++)
+ m_DataStorage->Remove((*it)->GetDataNode());
}
+}
-
-void mitk::NavigationToolStorage::RegisterAsMicroservice(std::string sourceID){
-
- if ( sourceID.empty() ) mitkThrow() << "Empty or null string passed to NavigationToolStorage::registerAsMicroservice().";
-
+void mitk::NavigationToolStorage::RegisterAsMicroservice(){
// Get Context
us::ModuleContext* context = us::GetModuleContext();
// Define ServiceProps
- m_props[ US_PROPKEY_SOURCE_ID ] = sourceID;
m_ServiceRegistration = context->RegisterService(this, m_props);
+ //Tell all widgets, that there is a new toolStorage registered, e.g. the old one might have changed.
+ UpdateMicroservice();
}
-
void mitk::NavigationToolStorage::UnRegisterMicroservice(){
- if ( ! m_ServiceRegistration )
+ if (!m_ServiceRegistration)
{
MITK_WARN("NavigationToolStorage")
- << "Cannot unregister microservice as it wasn't registered before.";
+ << "Cannot unregister microservice as it wasn't registered before.";
return;
}
m_ServiceRegistration.Unregister();
m_ServiceRegistration = 0;
}
-
bool mitk::NavigationToolStorage::DeleteTool(int number)
+{
+ if (m_storageLocked)
{
- if (m_storageLocked)
- {
- MITK_WARN << "Storage is locked, cannot modify it!";
- return false;
- }
-
- else if ((unsigned int)number > m_ToolCollection.size())
- {
- MITK_WARN << "Tool no " << number << "doesn't exist, can't delete it!";
- return false;
- }
- std::vector::iterator it = m_ToolCollection.begin() + number;
- if(m_DataStorage.IsNotNull())
- m_DataStorage->Remove((*it)->GetDataNode());
- m_ToolCollection.erase(it);
+ MITK_WARN << "Storage is locked, cannot modify it!";
+ return false;
+ }
- return true;
+ else if ((unsigned int)number > m_ToolCollection.size())
+ {
+ MITK_WARN << "Tool no " << number << "doesn't exist, can't delete it!";
+ return false;
}
+ std::vector::iterator it = m_ToolCollection.begin() + number;
+ if (m_DataStorage.IsNotNull())
+ m_DataStorage->Remove((*it)->GetDataNode());
+ m_ToolCollection.erase(it);
+
+ //This line is important so that other widgets can get a notice that the toolStorage has changed!
+ this->UpdateMicroservice();
+ return true;
+}
bool mitk::NavigationToolStorage::DeleteAllTools()
+{
+ if (m_storageLocked)
{
- if (m_storageLocked)
- {
MITK_WARN << "Storage is locked, cannot modify it!";
return false;
- }
+ }
- while(m_ToolCollection.size() > 0) if (!DeleteTool(0)) return false;
+ while (m_ToolCollection.size() > 0) if (!DeleteTool(0)) return false;
return true;
- }
+}
bool mitk::NavigationToolStorage::AddTool(mitk::NavigationTool::Pointer tool)
- {
+{
if (m_storageLocked)
- {
+ {
MITK_WARN << "Storage is locked, cannot modify it!";
return false;
- }
+ }
else if (GetTool(tool->GetIdentifier()).IsNotNull())
- {
+ {
MITK_WARN << "Tool ID already exists in storage, can't add!";
return false;
- }
+ }
else
- {
+ {
m_ToolCollection.push_back(tool);
- if(m_DataStorage.IsNotNull())
- {
+ if (m_DataStorage.IsNotNull())
+ {
if (!m_DataStorage->Exists(tool->GetDataNode()))
m_DataStorage->Add(tool->GetDataNode());
- }
- return true;
}
+ //This line is important so that other widgets can get a notice that the toolStorage has changed!
+ this->UpdateMicroservice();
+ return true;
}
+}
mitk::NavigationTool::Pointer mitk::NavigationToolStorage::GetTool(int number)
- {
+{
return m_ToolCollection.at(number);
- }
+}
mitk::NavigationTool::Pointer mitk::NavigationToolStorage::GetTool(std::string identifier)
- {
- for (int i=0; iGetIdentifier())==identifier) return GetTool(i);
+{
+ for (unsigned int i = 0; i < GetToolCount(); i++) if ((GetTool(i)->GetIdentifier()) == identifier) return GetTool(i);
return nullptr;
- }
+}
mitk::NavigationTool::Pointer mitk::NavigationToolStorage::GetToolByName(std::string name)
- {
- for (int i=0; iGetToolName())==name) return GetTool(i);
+{
+ for (unsigned int i = 0; i < GetToolCount(); i++) if ((GetTool(i)->GetToolName()) == name) return GetTool(i);
return nullptr;
- }
+}
-int mitk::NavigationToolStorage::GetToolCount()
- {
+unsigned int mitk::NavigationToolStorage::GetToolCount()
+{
return m_ToolCollection.size();
- }
+}
bool mitk::NavigationToolStorage::isEmpty()
- {
+{
return m_ToolCollection.empty();
- }
+}
void mitk::NavigationToolStorage::LockStorage()
- {
+{
m_storageLocked = true;
- }
+}
void mitk::NavigationToolStorage::UnLockStorage()
- {
+{
m_storageLocked = false;
- }
+}
bool mitk::NavigationToolStorage::isLocked()
- {
+{
return m_storageLocked;
- }
+}
bool mitk::NavigationToolStorage::AssignToolNumber(std::string identifier1, int number2)
- {
+{
if (this->GetTool(identifier1).IsNull())
- {
+ {
MITK_WARN << "Identifier does not exist, cannot assign new number";
return false;
- }
+ }
if ((number2 >= static_cast(m_ToolCollection.size())) || (number2 < 0))
- {
+ {
MITK_WARN << "Invalid number, cannot assign new number";
return false;
- }
+ }
mitk::NavigationTool::Pointer tool2 = m_ToolCollection.at(number2);
int number1 = -1;
for(int i = 0; i(m_ToolCollection.size()); i++)
- {
- if (m_ToolCollection.at(i)->GetIdentifier() == identifier1) {number1=i;}
- }
+ {
+ if (m_ToolCollection.at(i)->GetIdentifier() == identifier1) { number1 = i; }
+ }
m_ToolCollection[number2] = m_ToolCollection.at(number1);
m_ToolCollection[number1] = tool2;
MITK_DEBUG << "Swapped tool " << number2 << " with tool " << number1;
+ //This line is important so that other widgets can get a notice that the toolStorage has changed!
+ this->UpdateMicroservice();
+
return true;
}
+
+void mitk::NavigationToolStorage::SetSourceID(std::string _id)
+{
+ m_SourceID = _id;
+ m_props[US_PROPKEY_SOURCE_ID] = m_SourceID;
+}
+
+/** @return Returns the name of this storage. */
+std::string mitk::NavigationToolStorage::GetSourceID() const
+{
+ return m_SourceID;
+}
diff --git a/Modules/IGT/DataManagement/mitkNavigationToolStorage.h b/Modules/IGT/DataManagement/mitkNavigationToolStorage.h
index 80785a3c98..74fcbef42b 100644
--- a/Modules/IGT/DataManagement/mitkNavigationToolStorage.h
+++ b/Modules/IGT/DataManagement/mitkNavigationToolStorage.h
@@ -1,186 +1,201 @@
/*===================================================================
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 NAVIGATIONTOOLSTORAGE_H_INCLUDED
#define NAVIGATIONTOOLSTORAGE_H_INCLUDED
//itk headers
#include
//mitk headers
#include
#include
#include "mitkNavigationTool.h"
#include
// Microservices
#include
#include
#include
namespace mitk {
/**Documentation
* \brief An object of this class represents a collection of navigation tools.
* You may add/delete navigation tools or store/load the whole collection
* to/from the harddisc by using the class NavigationToolStorageSerializer
* and NavigationToolStorageDeserializer.
*
* \ingroup IGT
*/
class MITKIGT_EXPORT NavigationToolStorage : public itk::Object
{
public:
mitkClassMacroItkParent(NavigationToolStorage,itk::Object);
/** @brief Constructs a NavigationToolStorage without reference to a DataStorage. The Data Nodes of tools have to be added and removed to a data storage outside this class.
* Normaly the other constructor should be used.
*/
itkFactorylessNewMacro(Self)
itkCloneMacro(Self)
/** @brief Constructs a NavigationToolStorage with reference to a DataStorage. The Data Nodes of tools are added and removed automatically to this data storage. */
mitkNewMacro1Param(Self,mitk::DataStorage::Pointer);
/**
*\brief Registers this object as a Microservice, making it available to every module and/or plugin.
* To unregister, call UnregisterMicroservice(). Make sure to pass the id of the Device that this tool is connected to.
*/
- virtual void RegisterAsMicroservice(std::string sourceID);
+ virtual void RegisterAsMicroservice();
/**
*\brief Registers this object as a Microservice, making it available to every module and/or plugin.
*/
virtual void UnRegisterMicroservice();
/**
*\brief Returns the id that this device is registered with. The id will only be valid, if the
* NavigationDataSource has been registered using RegisterAsMicroservice().
*/
std::string GetMicroserviceID();
/**
*\brief These constants are used in conjunction with Microservices
*/
- static const std::string US_INTERFACE_NAME; // Name of the interface
- static const std::string US_PROPKEY_SOURCE_ID; // ID of the device this ToolStorage is associated with
- static const std::string US_PROPKEY_STORAGE_NAME; // name of the storage
+ // Name of the interface
+ static const std::string US_INTERFACE_NAME;
+ // ID of the NavigationDataSource this ToolStorage is associated with. Can be empty ("") and changed with SetSourceID().
+ static const std::string US_PROPKEY_SOURCE_ID;
+ // name of the storage
+ static const std::string US_PROPKEY_STORAGE_NAME;
/**
* @brief Adds a tool to the storage. Be sure that the tool has a unique
* identifier which is not already part of this storage.
* @return Returns true if the tool was added to the storage, false if not
* (false can be returned if the identifier already exists in this storage
* for example).
*/
bool AddTool(mitk::NavigationTool::Pointer tool);
/**
* @return Returns the tracking tool at the position "number"
* in the storage. Returns nullptr if there is no
* tracking tool at this position.
*/
mitk::NavigationTool::Pointer GetTool(int number);
/**
* @return Returns the tracking tool with the given identifier.
* Returns nullptr if there is no
* tracking tool with this identifier in the storage.
*/
mitk::NavigationTool::Pointer GetTool(std::string identifier);
/**
* @return Returns the tracking tool with the given name.
* Returns nullptr if there is no
* tracking tool with this name in the storage.
*/
mitk::NavigationTool::Pointer GetToolByName(std::string name);
/** Assigns the given number to the tool with the given identifier. This means the tool is swapped with another tool in the internal tool vector.
* @return Returns true if the assignment was successfull. Returns false if assignment is not possible, e.g. because the identifier does not exist or if the given number is not available.
**/
bool AssignToolNumber(std::string identifier1, int number2);
/**
* @brief Deletes a tool from the collection.
* Warning, this method operates on the data storage and is not thread save. Calling it from outside the main thread may cause crashes.
*/
bool DeleteTool(int number);
/**
* @brief Deletes all tools from the collection.
* Warning, this method operates on the data storage and is not thread save. Calling it from outside the main thread may cause crashes.
*/
bool DeleteAllTools();
/**
* @return Returns the number of tools stored in the storage.
*/
- int GetToolCount();
+ unsigned int GetToolCount();
/**
* @return Returns true if the storage is empty, false if not.
*/
bool isEmpty();
/**
* @return Returns the corresponding data storage if one is set to this NavigationToolStorage.
* Returns nullptr if none is set.
*/
itkGetMacro(DataStorage,mitk::DataStorage::Pointer);
/** Sets the name of this storage. The name should be understandable for the user.
* Something like "NDI Aurora Tool Storage". If a storage is loaded from the harddisk
* the name might be the filename.
*/
void SetName(std::string);
/** @return Returns the name of this storage. */
- itkGetConstMacro(Name,std::string);
+ std::string GetName() const;
+
+ /** Sets the name of this storage. The name should be understandable for the user.
+ * Something like "NDI Aurora Tool Storage". If a storage is loaded from the harddisk
+ * the name might be the filename.
+ * @warning: if your microservice is already registered, you need to call UpdateMicroservice after changing the ID.
+ * This can't be done inside this functions, as we might use different threads.
+ */
+ void SetSourceID(std::string);
+
+ /** @return Returns the name of this storage. */
+ std::string GetSourceID() const;
/** Locks the storage. A logged storage may not be modified.
* If a method tries to modify the storage anyway a waring message is given.
* The storage is unlocked by default. A Storage might be locked when a
* tracking device is active and needs the storage to stay consistent.
*/
void LockStorage();
/** Unlocks the storage again. */
void UnLockStorage();
/** @return Returns true if the storage is locked at the moment, false if not. */
bool isLocked();
/** Sets the properties which causes the microservice to emit an update signal. */
void UpdateMicroservice();
protected:
NavigationToolStorage();
NavigationToolStorage(mitk::DataStorage::Pointer);
~NavigationToolStorage();
std::vector m_ToolCollection;
mitk::DataStorage::Pointer m_DataStorage;
std::string m_Name;
+ std::string m_SourceID;
bool m_storageLocked;
private:
us::ServiceRegistration m_ServiceRegistration;
us::ServiceProperties m_props;
};
} // namespace mitk
MITK_DECLARE_SERVICE_INTERFACE(mitk::NavigationToolStorage, "org.mitk.services.NavigationToolStorage")
#endif //NAVIGATIONTOOLSTORAGE
diff --git a/Modules/IGT/DataManagement/mitkTrackingDeviceSource.cpp b/Modules/IGT/DataManagement/mitkTrackingDeviceSource.cpp
index ee1298389b..40d33caa07 100644
--- a/Modules/IGT/DataManagement/mitkTrackingDeviceSource.cpp
+++ b/Modules/IGT/DataManagement/mitkTrackingDeviceSource.cpp
@@ -1,213 +1,216 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkTrackingDeviceSource.h"
#include "mitkTrackingDevice.h"
#include "mitkTrackingTool.h"
#include "mitkIGTTimeStamp.h"
#include "mitkIGTException.h"
+#include "mitkIGTHardwareException.h"
mitk::TrackingDeviceSource::TrackingDeviceSource()
: mitk::NavigationDataSource(), m_TrackingDevice(nullptr)
{
}
mitk::TrackingDeviceSource::~TrackingDeviceSource()
{
if (m_TrackingDevice.IsNotNull())
{
if (m_TrackingDevice->GetState() == mitk::TrackingDevice::Tracking)
{
this->StopTracking();
}
if (m_TrackingDevice->GetState() == mitk::TrackingDevice::Ready)
{
this->Disconnect();
}
m_TrackingDevice = nullptr;
}
}
void mitk::TrackingDeviceSource::GenerateData()
{
if (m_IsFrozen) {return;} //no update at all if device is frozen
else if (m_TrackingDevice.IsNull()) {return;}
if (m_TrackingDevice->GetToolCount() < 1)
return;
if (this->GetNumberOfIndexedOutputs() != m_TrackingDevice->GetToolCount()) // mismatch between tools and outputs. What should we do? Were tools added to the tracking device after SetTrackingDevice() was called?
{
//check this: TODO:
////this might happen if a tool is plugged into an aurora during tracking.
//this->CreateOutputs();
std::stringstream ss;
ss << "mitk::TrackingDeviceSource: not enough outputs available for all tools. "
<< this->GetNumberOfOutputs() << " outputs available, but "
<< m_TrackingDevice->GetToolCount() << " tools available in the tracking device.";
throw std::out_of_range(ss.str());
}
/* update outputs with tracking data from tools */
unsigned int toolCount = m_TrackingDevice->GetToolCount();
for (unsigned int i = 0; i < toolCount; ++i)
{
mitk::NavigationData* nd = this->GetOutput(i);
assert(nd);
mitk::TrackingTool* t = m_TrackingDevice->GetTool(i);
assert(t);
if ((t->IsEnabled() == false) || (t->IsDataValid() == false))
{
nd->SetDataValid(false);
continue;
}
nd->SetDataValid(true);
mitk::NavigationData::PositionType p;
t->GetPosition(p);
nd->SetPosition(p);
mitk::NavigationData::OrientationType o;
t->GetOrientation(o);
nd->SetOrientation(o);
nd->SetOrientationAccuracy(t->GetTrackingError());
nd->SetPositionAccuracy(t->GetTrackingError());
nd->SetIGTTimeStamp(t->GetIGTTimeStamp());
//for backward compatibility: check if the timestamp was set, if not create a default timestamp
if (nd->GetIGTTimeStamp()==0) nd->SetIGTTimeStamp(mitk::IGTTimeStamp::GetInstance()->GetElapsed());
}
}
void mitk::TrackingDeviceSource::SetTrackingDevice( mitk::TrackingDevice* td )
{
MITK_DEBUG << "Setting TrackingDevice to " << td;
if (this->m_TrackingDevice.GetPointer() != td)
{
this->m_TrackingDevice = td;
this->CreateOutputs();
std::stringstream name; // create a human readable name for the source
name << td->GetData().Model << " Tracking Source";
this->SetName(name.str());
}
}
void mitk::TrackingDeviceSource::CreateOutputs(){
//if outputs are set then delete them
if (this->GetNumberOfOutputs() > 0)
{
for (int numOP = this->GetNumberOfOutputs() -1; numOP >= 0; numOP--)
this->RemoveOutput(numOP);
this->Modified();
}
//fill the outputs if a valid tracking device is set
if (m_TrackingDevice.IsNull())
return;
this->SetNumberOfIndexedOutputs(m_TrackingDevice->GetToolCount()); // create outputs for all tools
unsigned int numberOfOutputs = this->GetNumberOfIndexedOutputs();
MITK_DEBUG << "Number of tools at start of method CreateOutputs(): " << m_TrackingDevice->GetToolCount();
MITK_DEBUG << "Number of outputs at start of method CreateOutputs(): " << numberOfOutputs;
for (unsigned int idx = 0; idx < m_TrackingDevice->GetToolCount(); ++idx)
{
if (this->GetOutput(idx) == nullptr)
{
DataObjectPointer newOutput = this->MakeOutput(idx);
static_cast(newOutput.GetPointer())->SetName(m_TrackingDevice->GetTool(idx)->GetToolName()); // set NavigationData name to ToolName
this->SetNthOutput(idx, newOutput);
this->Modified();
}
}
}
void mitk::TrackingDeviceSource::Connect()
{
if (m_TrackingDevice.IsNull())
throw std::invalid_argument("mitk::TrackingDeviceSource: No tracking device set");
if (this->IsConnected())
return;
- try {m_TrackingDevice->OpenConnection();}
+ try
+ {
+ //Try to open the connection. If it didn't work (fals is returned from OpenConnection by the tracking device), throw an exception.
+ if (!m_TrackingDevice->OpenConnection())
+ {
+ mitkThrowException(mitk::IGTHardwareException) << "Could not open connection.";
+ }
+ }
catch (mitk::IGTException &e)
{
throw std::runtime_error(std::string("mitk::TrackingDeviceSource: Could not open connection to tracking device. Error: ") + e.GetDescription());
}
-
- /* NDI Aurora needs a connection to discover tools that are connected to it.
- Therefore we need to create outputs for these tools now */
- //if (m_TrackingDevice->GetType() == mitk::NDIAurora)
- //this->CreateOutputs();
}
void mitk::TrackingDeviceSource::StartTracking()
{
if (m_TrackingDevice.IsNull())
throw std::invalid_argument("mitk::TrackingDeviceSource: No tracking device set");
if (m_TrackingDevice->GetState() == mitk::TrackingDevice::Tracking)
return;
if (m_TrackingDevice->StartTracking() == false)
throw std::runtime_error("mitk::TrackingDeviceSource: Could not start tracking");
}
void mitk::TrackingDeviceSource::Disconnect()
{
if (m_TrackingDevice.IsNull())
throw std::invalid_argument("mitk::TrackingDeviceSource: No tracking device set");
if (m_TrackingDevice->CloseConnection() == false)
throw std::runtime_error("mitk::TrackingDeviceSource: Could not close connection to tracking device");
}
void mitk::TrackingDeviceSource::StopTracking()
{
if (m_TrackingDevice.IsNull())
throw std::invalid_argument("mitk::TrackingDeviceSource: No tracking device set");
if (m_TrackingDevice->StopTracking() == false)
throw std::runtime_error("mitk::TrackingDeviceSource: Could not stop tracking");
}
void mitk::TrackingDeviceSource::UpdateOutputInformation()
{
if(this->GetTrackingDevice()->GetToolCount() != this->GetNumberOfIndexedOutputs())
this->CreateOutputs();
this->Modified(); // make sure that we need to be updated
Superclass::UpdateOutputInformation();
}
//unsigned int mitk::TrackingDeviceSource::GetToolCount()
//{
// if (m_TrackingDevice)
// return m_TrackingDevice->GetToolCount();
// return 0;
//}
bool mitk::TrackingDeviceSource::IsConnected()
{
if (m_TrackingDevice.IsNull())
return false;
return (m_TrackingDevice->GetState() == mitk::TrackingDevice::Ready) || (m_TrackingDevice->GetState() == mitk::TrackingDevice::Tracking);
}
bool mitk::TrackingDeviceSource::IsTracking()
{
if (m_TrackingDevice.IsNull())
return false;
return m_TrackingDevice->GetState() == mitk::TrackingDevice::Tracking;
}
diff --git a/Modules/IGT/DataManagement/mitkTrackingDeviceSourceConfigurator.cpp b/Modules/IGT/DataManagement/mitkTrackingDeviceSourceConfigurator.cpp
index dec53c3505..43d5eb3dd2 100644
--- a/Modules/IGT/DataManagement/mitkTrackingDeviceSourceConfigurator.cpp
+++ b/Modules/IGT/DataManagement/mitkTrackingDeviceSourceConfigurator.cpp
@@ -1,175 +1,175 @@
/*===================================================================
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 "mitkTrackingDeviceSourceConfigurator.h"
#include "mitkNDITrackingDevice.h"
#include "mitkClaronTrackingDevice.h"
#include "mitkOptitrackTrackingDevice.h"
#include "mitkOpenIGTLinkTrackingDevice.h"
#include "mitkVirtualTrackingDevice.h"
#include
#include
#include
#include
#include
#include
#include
mitk::TrackingDeviceSourceConfigurator::TrackingDeviceSourceConfigurator(mitk::NavigationToolStorage::Pointer NavigationTools, mitk::TrackingDevice::Pointer TrackingDevice)
{
//make a copy of the navigation tool storage because we will modify the storage
if (NavigationTools.IsNotNull())
{
m_NavigationTools = mitk::NavigationToolStorage::New();
- for (int i=0; iGetToolCount(); i++)
+ for (unsigned int i=0; iGetToolCount(); i++)
{
m_NavigationTools->AddTool(NavigationTools->GetTool(i));
}
}
m_TrackingDevice = TrackingDevice;
m_ToolCorrespondencesInToolStorage = std::vector();
m_ErrorMessage = "";
}
mitk::NavigationToolStorage::Pointer mitk::TrackingDeviceSourceConfigurator::GetUpdatedNavigationToolStorage()
{
return m_NavigationTools;
}
mitk::TrackingDeviceSourceConfigurator::~TrackingDeviceSourceConfigurator()
{
}
bool mitk::TrackingDeviceSourceConfigurator::IsCreateTrackingDeviceSourcePossible()
{
if (m_NavigationTools.IsNull())
{
m_ErrorMessage = "NavigationToolStorage is nullptr!";
return false;
}
else if (m_TrackingDevice.IsNull())
{
m_ErrorMessage = "TrackingDevice is nullptr!";
return false;
}
else
{
- for (int i=0; iGetToolCount(); i++)
+ for (unsigned int i=0; iGetToolCount(); i++)
{
if (m_NavigationTools->GetTool(i)->GetTrackingDeviceType() != m_TrackingDevice->GetType())
{
m_ErrorMessage = "At least one tool is not of the same type like the tracking device.";
return false;
}
}
//TODO in case of Aurora: check if the tools are automatically detected by comparing the serial number
return true;
}
}
mitk::TrackingDeviceSource::Pointer mitk::TrackingDeviceSourceConfigurator::CreateTrackingDeviceSource()
{
mitk::NavigationDataObjectVisualizationFilter::Pointer dummy; //this dummy is lost directly after creating the device
return this->CreateTrackingDeviceSource(dummy);
}
mitk::TrackingDeviceSource::Pointer mitk::TrackingDeviceSourceConfigurator::CreateTrackingDeviceSource(mitk::NavigationDataObjectVisualizationFilter::Pointer &visualizationFilter)
{
if (!this->IsCreateTrackingDeviceSourcePossible()) {MITK_WARN << "Cannot create tracking decive: " << m_ErrorMessage; return nullptr;}
mitk::TrackingDeviceSource::Pointer returnValue;
us::ModuleContext* context = us::GetModuleContext();
std::vector > refs = context->GetServiceReferences();
if (refs.empty())
{
MITK_ERROR << "No tracking device service found!";
}
mitk::TrackingDeviceTypeCollection* deviceTypeCollection = context->GetService(refs.front());
//create tracking device source
returnValue = deviceTypeCollection->GetTrackingDeviceTypeInformation(m_TrackingDevice->GetType())->
CreateTrackingDeviceSource(m_TrackingDevice,m_NavigationTools, &m_ErrorMessage, &m_ToolCorrespondencesInToolStorage);
//TODO: insert other tracking systems?
if (returnValue.IsNull()) {MITK_WARN << "Cannot create tracking decive: " << m_ErrorMessage; return nullptr;}
//create visualization filter
visualizationFilter = CreateNavigationDataObjectVisualizationFilter(returnValue,m_NavigationTools);
if (visualizationFilter.IsNull()) {MITK_WARN << "Cannot create tracking decive: " << m_ErrorMessage; return nullptr;}
return returnValue;
}
std::string mitk::TrackingDeviceSourceConfigurator::GetErrorMessage()
{
return this->m_ErrorMessage;
}
//############################ internal help methods ########################################
mitk::NavigationDataObjectVisualizationFilter::Pointer mitk::TrackingDeviceSourceConfigurator::CreateNavigationDataObjectVisualizationFilter(mitk::TrackingDeviceSource::Pointer trackingDeviceSource, mitk::NavigationToolStorage::Pointer navigationTools)
{
mitk::NavigationDataObjectVisualizationFilter::Pointer returnValue = mitk::NavigationDataObjectVisualizationFilter::New();
for (unsigned int i=0; iGetNumberOfIndexedOutputs(); i++)
{
// Note: If all tools have the same name only the first tool will always be returned and
// the others won't be updated during rendering.This could potentially lead to inconstencies
mitk::NavigationTool::Pointer currentTool = navigationTools->GetToolByName(trackingDeviceSource->GetOutput(i)->GetName());
if (currentTool.IsNull())
{
this->m_ErrorMessage = "Error: did not find corresponding tool in tracking device after initialization.";
return nullptr;
}
returnValue->SetInput(i,trackingDeviceSource->GetOutput(i));
returnValue->SetRepresentationObject(i,currentTool->GetDataNode()->GetData());
}
return returnValue;
}
int mitk::TrackingDeviceSourceConfigurator::GetToolNumberInToolStorage(unsigned int outputID)
{
if (outputID < m_ToolCorrespondencesInToolStorage.size()) return m_ToolCorrespondencesInToolStorage.at(outputID);
else return -1;
}
std::string mitk::TrackingDeviceSourceConfigurator::GetToolIdentifierInToolStorage(unsigned int outputID)
{
if (outputID < m_ToolCorrespondencesInToolStorage.size()) return m_NavigationTools->GetTool(m_ToolCorrespondencesInToolStorage.at(outputID))->GetIdentifier();
else return "";
}
std::vector mitk::TrackingDeviceSourceConfigurator::GetToolNumbersInToolStorage()
{
return m_ToolCorrespondencesInToolStorage;
}
std::vector mitk::TrackingDeviceSourceConfigurator::GetToolIdentifiersInToolStorage()
{
std::vector returnValue = std::vector();
for (unsigned int i=0; iGetTool(m_ToolCorrespondencesInToolStorage.at(i))->GetIdentifier());}
return returnValue;
}
diff --git a/Modules/IGT/IO/mitkNavigationToolStorageSerializer.cpp b/Modules/IGT/IO/mitkNavigationToolStorageSerializer.cpp
index 1d4b2cf7d3..236db1c301 100644
--- a/Modules/IGT/IO/mitkNavigationToolStorageSerializer.cpp
+++ b/Modules/IGT/IO/mitkNavigationToolStorageSerializer.cpp
@@ -1,99 +1,99 @@
/*===================================================================
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.
===================================================================*/
//Poco headers
#include
#include
#include
#include "mitkNavigationToolStorageSerializer.h"
#include "mitkNavigationToolWriter.h"
#include "mitkIGTException.h"
#include "mitkIGTIOException.h"
#include
#include
#include
#include
mitk::NavigationToolStorageSerializer::NavigationToolStorageSerializer()
{
//create temp directory
m_tempDirectory = mitk::IOUtil::CreateTemporaryDirectory("NavigationToolStorageSerializerTmp_XXXXXX",mitk::IOUtil::GetProgramPath());
}
mitk::NavigationToolStorageSerializer::~NavigationToolStorageSerializer()
{
//remove temp directory
Poco::File myFile(m_tempDirectory);
try
{
if (myFile.exists()) myFile.remove(true);
}
catch(...)
{
MITK_ERROR << "Can't remove temp directory " << m_tempDirectory << "!";
}
}
bool mitk::NavigationToolStorageSerializer::Serialize(std::string filename, mitk::NavigationToolStorage::Pointer storage)
{
//save every tool to temp directory
mitk::NavigationToolWriter::Pointer myToolWriter = mitk::NavigationToolWriter::New();
- for(int i=0; iGetToolCount();i++)
+ for(unsigned int i=0; iGetToolCount();i++)
{
std::string tempFileName = m_tempDirectory + Poco::Path::separator() + "NavigationTool" + convertIntToString(i) + ".tool";
if (!myToolWriter->DoWrite(tempFileName,storage->GetTool(i)))
{
mitkThrowException(mitk::IGTIOException) << "Could not write tool to tempory directory: " << tempFileName;
}
}
//add all files to zip archive
std::ofstream file( filename.c_str(), std::ios::binary | std::ios::out);
if (!file.good()) //test if the zip archive is ready for writing
{
//first: clean up
- for (int i=0; iGetToolCount();i++)
+ for (unsigned int i=0; iGetToolCount();i++)
{
std::string tempFileName = m_tempDirectory + Poco::Path::separator() + "NavigationTool" + convertIntToString(i) + ".tool";
std::remove(tempFileName.c_str());
}
//then: throw an exception
mitkThrowException(mitk::IGTIOException) << "Could not open a file for writing: " << filename;
}
Poco::Zip::Compress zipper( file, true );
- for (int i=0; iGetToolCount();i++)
+ for (unsigned int i=0; iGetToolCount();i++)
{
std::string fileName = m_tempDirectory + Poco::Path::separator() + "NavigationTool" + convertIntToString(i) + ".tool";
zipper.addFile(fileName,myToolWriter->GetFileWithoutPath(fileName));
std::remove(fileName.c_str()); //delete file
}
zipper.close();
file.close();
return true;
}
std::string mitk::NavigationToolStorageSerializer::convertIntToString(int i)
{
std::string s;
std::stringstream out;
out << i;
s = out.str();
return s;
}
diff --git a/Modules/IGT/TrackingDevices/mitkInternalTrackingTool.cpp b/Modules/IGT/TrackingDevices/mitkInternalTrackingTool.cpp
index d9676fca30..128eabfc47 100644
--- a/Modules/IGT/TrackingDevices/mitkInternalTrackingTool.cpp
+++ b/Modules/IGT/TrackingDevices/mitkInternalTrackingTool.cpp
@@ -1,270 +1,279 @@
/*===================================================================
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 "mitkInternalTrackingTool.h"
#include
typedef itk::MutexLockHolder MutexLockHolder;
mitk::InternalTrackingTool::InternalTrackingTool()
: TrackingTool(),
m_TrackingError(0.0f),
m_Enabled(true),
m_DataValid(false),
m_ToolTipSet(false)
{
m_Position[0] = 0.0f;
m_Position[1] = 0.0f;
m_Position[2] = 0.0f;
m_Orientation[0] = 0.0f;
m_Orientation[1] = 0.0f;
m_Orientation[2] = 0.0f;
m_Orientation[3] = 0.0f;
// this should not be necessary as the tools bring their own tooltip transformation
m_ToolTip[0] = 0.0f;
m_ToolTip[1] = 0.0f;
m_ToolTip[2] = 0.0f;
m_ToolTipRotation[0] = 0.0f;
m_ToolTipRotation[1] = 0.0f;
m_ToolTipRotation[2] = 0.0f;
m_ToolTipRotation[3] = 1.0f;
}
mitk::InternalTrackingTool::~InternalTrackingTool()
{
}
void mitk::InternalTrackingTool::PrintSelf(std::ostream& os, itk::Indent indent) const
{
Superclass::PrintSelf(os, indent);
os << indent << "Position: " << m_Position << std::endl;
os << indent << "Orientation: " << m_Orientation << std::endl;
os << indent << "TrackingError: " << m_TrackingError << std::endl;
os << indent << "Enabled: " << m_Enabled << std::endl;
os << indent << "DataValid: " << m_DataValid << std::endl;
os << indent << "ToolTip: " << m_ToolTip << std::endl;
os << indent << "ToolTipRotation: " << m_ToolTipRotation << std::endl;
os << indent << "ToolTipSet: " << m_ToolTipSet << std::endl;
}
void mitk::InternalTrackingTool::SetToolName(const char* _arg)
{
itkDebugMacro("setting m_ToolName to " << _arg);
MutexLockHolder lock(*m_MyMutex); // lock and unlock the mutex
if ( _arg && (_arg == this->m_ToolName) )
{
return;
}
if (_arg)
{
this->m_ToolName= _arg;
}
else
{
this->m_ToolName= "";
}
this->Modified();
}
void mitk::InternalTrackingTool::SetToolName( const std::string _arg )
{
this->SetToolName(_arg.c_str());
}
void mitk::InternalTrackingTool::GetPosition(mitk::Point3D& position) const
{
MutexLockHolder lock(*m_MyMutex); // lock and unlock the mutex
if (m_ToolTipSet)
{
// Compute the position of tool tip in the coordinate frame of the
// tracking device: Rotate the position of the tip into the tracking
// device coordinate frame then add to the position of the tracking
// sensor
vnl_vector pos_vnl = m_Position.GetVnlVector() + m_Orientation.rotate( m_ToolTip.GetVnlVector() ) ;
position[0] = pos_vnl[0];
position[1] = pos_vnl[1];
position[2] = pos_vnl[2];
}
else
{
position[0] = m_Position[0];
position[1] = m_Position[1];
position[2] = m_Position[2];
}
this->Modified();
}
void mitk::InternalTrackingTool::SetPosition(mitk::Point3D position)
{
itkDebugMacro("setting m_Position to " << position);
MutexLockHolder lock(*m_MyMutex); // lock and unlock the mutex
m_Position = position;
this->Modified();
}
void mitk::InternalTrackingTool::GetOrientation(mitk::Quaternion& orientation) const
{
MutexLockHolder lock(*m_MyMutex); // lock and unlock the mutex
if (m_ToolTipSet)
{
// Compute the orientation of the tool tip in the coordinate frame of
// the tracking device.
//
// * m_Orientation is the orientation of the sensor relative to the transmitter
// * m_ToolTipRotation is the orientation of the tool tip relative to the sensor
orientation = m_Orientation * m_ToolTipRotation;
}
else
{
orientation = m_Orientation;
}
}
void mitk::InternalTrackingTool::SetToolTip(mitk::Point3D toolTipPosition,
mitk::Quaternion orientation,
mitk::ScalarType eps)
{
if ( !Equal(m_ToolTip, toolTipPosition, eps) ||
!Equal(m_ToolTipRotation, orientation, eps) )
{
if( (toolTipPosition[0] == 0) &&
(toolTipPosition[1] == 0) &&
(toolTipPosition[2] == 0) &&
(orientation.x() == 0) &&
(orientation.y() == 0) &&
(orientation.z() == 0) &&
(orientation.r() == 1))
{
m_ToolTipSet = false;
}
else
{
m_ToolTipSet = true;
}
m_ToolTip = toolTipPosition;
m_ToolTipRotation = orientation;
this->Modified();
}
}
+mitk::Point3D mitk::InternalTrackingTool::GetToolTip() const
+{
+ return m_ToolTip;
+}
+mitk::Quaternion mitk::InternalTrackingTool::GetToolTipOrientation() const
+{
+ return m_ToolTipRotation;
+}
+
void mitk::InternalTrackingTool::SetOrientation(mitk::Quaternion orientation)
{
itkDebugMacro("setting m_Orientation to " << orientation);
MutexLockHolder lock(*m_MyMutex); // lock and unlock the mutex
m_Orientation = orientation;
this->Modified();
}
void mitk::InternalTrackingTool::SetTrackingError(float error)
{
itkDebugMacro("setting m_TrackingError to " << error);
MutexLockHolder lock(*m_MyMutex); // lock and unlock the mutex
if (error == m_TrackingError)
{
return;
}
m_TrackingError = error;
this->Modified();
}
float mitk::InternalTrackingTool::GetTrackingError() const
{
MutexLockHolder lock(*m_MyMutex); // lock and unlock the mutex
float r = m_TrackingError;
return r;
}
bool mitk::InternalTrackingTool::Enable()
{
MutexLockHolder lock(*m_MyMutex); // lock and unlock the mutex
if (m_Enabled == false)
{
this->m_Enabled = true;
this->Modified();
}
return true;
}
bool mitk::InternalTrackingTool::Disable()
{
MutexLockHolder lock(*m_MyMutex); // lock and unlock the mutex
if (m_Enabled == true)
{
this->m_Enabled = false;
this->Modified();
}
return true;
}
bool mitk::InternalTrackingTool::IsEnabled() const
{
MutexLockHolder lock(*m_MyMutex); // lock and unlock the mutex
return m_Enabled;
}
bool mitk::InternalTrackingTool::IsTooltipSet() const
{
MutexLockHolder lock(*m_MyMutex); // lock and unlock the mutex
return m_ToolTipSet;
}
bool mitk::InternalTrackingTool::IsDataValid() const
{
MutexLockHolder lock(*m_MyMutex); // lock and unlock the mutex
return m_DataValid;
}
void mitk::InternalTrackingTool::SetDataValid(bool _arg)
{
itkDebugMacro("setting m_DataValid to " << _arg);
if (this->m_DataValid != _arg)
{
MutexLockHolder lock(*m_MyMutex); // lock and unlock the mutex
this->m_DataValid = _arg;
this->Modified();
}
}
void mitk::InternalTrackingTool::SetErrorMessage(const char* _arg)
{
itkDebugMacro("setting m_ErrorMessage to " << _arg);
MutexLockHolder lock(*m_MyMutex); // lock and unlock the mutex
if ((_arg == nullptr) || (_arg == this->m_ErrorMessage))
return;
if (_arg != nullptr)
this->m_ErrorMessage = _arg;
else
this->m_ErrorMessage = "";
this->Modified();
}
diff --git a/Modules/IGT/TrackingDevices/mitkInternalTrackingTool.h b/Modules/IGT/TrackingDevices/mitkInternalTrackingTool.h
index de952cf0b8..d0a34cc476 100644
--- a/Modules/IGT/TrackingDevices/mitkInternalTrackingTool.h
+++ b/Modules/IGT/TrackingDevices/mitkInternalTrackingTool.h
@@ -1,80 +1,82 @@
/*===================================================================
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 MITKINTERNALTRACKINGTOOL_H_HEADER_INCLUDED_
#define MITKINTERNALTRACKINGTOOL_H_HEADER_INCLUDED_
#include
#include
#include
#include
namespace mitk {
/**Documentation
* \brief implements TrackingTool interface
*
* This class is a complete TrackingTool implementation. It can either be used directly by
* TrackingDevices, or be subclassed for more specific implementations.
* mitk::MicroBirdTrackingDevice uses this class to manage its tools. Other tracking devices
* uses specialized versions of this class (e.g. mitk::NDITrackingTool)
*
* \ingroup IGT
*/
class MITKIGT_EXPORT InternalTrackingTool : public TrackingTool
{
friend class MicroBirdTrackingDevice; // Add all TrackingDevice subclasses that use InternalTrackingDevice directly
public:
mitkClassMacro(InternalTrackingTool, TrackingTool);
virtual void PrintSelf(std::ostream& os, itk::Indent indent) const override;
virtual void GetPosition(Point3D& position) const override; ///< returns the current position of the tool as an array of three floats (in the tracking device coordinate system)
virtual void GetOrientation(Quaternion& orientation) const override; ///< returns the current orientation of the tool as a quaternion (in the tracking device coordinate system)
virtual bool Enable() override; ///< enablea the tool, so that it will be tracked. Returns true if enabling was successfull
virtual bool Disable() override; ///< disables the tool, so that it will not be tracked anymore. Returns true if disabling was successfull
virtual bool IsEnabled() const override; ///< returns whether the tool is enabled or disabled
virtual bool IsDataValid() const override; ///< returns true if the current position data is valid (no error during tracking, tracking error below threshold, ...)
virtual float GetTrackingError() const override; ///< return one value that corresponds to the overall tracking error. The dimension of this value is specific to each tracking device
virtual bool IsTooltipSet() const; ///< returns true if a tooltip is set, false if not
virtual void SetToolName(const std::string _arg); ///< Sets the name of the tool
virtual void SetToolName(const char* _arg); ///< Sets the name of the tool
virtual void SetPosition(Point3D position); ///< sets the position
virtual void SetOrientation(Quaternion orientation); ///< sets the orientation as a quaternion
virtual void SetTrackingError(float error); ///< sets the tracking error
virtual void SetDataValid(bool _arg); ///< sets if the tracking data (position & Orientation) is valid
virtual void SetErrorMessage(const char* _arg); ///< sets the error message
virtual void SetToolTip(Point3D toolTipPosition, Quaternion orientation = Quaternion(0,0,0,1), ScalarType eps=0.0) override; ///< defines a tool tip for this tool in tool coordinates. GetPosition() and GetOrientation() return the data of the tool tip if it is defined. By default no tooltip is defined.
+ Point3D GetToolTip() const; //Returns the tool tip in tool coordinates, which where set by SetToolTip
+ Quaternion GetToolTipOrientation() const;//Returns the tool tip orientation in tool coordinates, which where set by SetToolTip
protected:
itkFactorylessNewMacro(Self)
itkCloneMacro(Self)
InternalTrackingTool();
virtual ~InternalTrackingTool();
Point3D m_Position; ///< holds the position of the tool
Quaternion m_Orientation; ///< holds the orientation of the tool
float m_TrackingError; ///< holds the tracking error of the tool
bool m_Enabled; ///< if true, tool is enabled and should receive tracking updates from the tracking device
bool m_DataValid; ///< if true, data in m_Position and m_Orientation is valid, e.g. true tracking data
Point3D m_ToolTip;
Quaternion m_ToolTipRotation;
bool m_ToolTipSet;
};
} // namespace mitk
#endif /* MITKINTERNALTRACKINGTOOL_H_HEADER_INCLUDED_ */
diff --git a/Modules/IGT/TrackingDevices/mitkMicronTrackerTypeInformation.cpp b/Modules/IGT/TrackingDevices/mitkMicronTrackerTypeInformation.cpp
index eb75123bf4..3edfdf7dcd 100644
--- a/Modules/IGT/TrackingDevices/mitkMicronTrackerTypeInformation.cpp
+++ b/Modules/IGT/TrackingDevices/mitkMicronTrackerTypeInformation.cpp
@@ -1,70 +1,70 @@
/*===================================================================
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 "mitkMicronTrackerTypeInformation.h"
#include "mitkClaronTrackingDevice.h"
namespace mitk
{
std::string MicronTrackerTypeInformation::GetTrackingDeviceName()
{
return "Claron Micron";
}
TrackingDeviceData MicronTrackerTypeInformation::GetDeviceDataMicronTrackerH40()
{
TrackingDeviceData data = { MicronTrackerTypeInformation::GetTrackingDeviceName(), "Micron Tracker H40", "ClaronMicron.stl", "X" };
return data;
}
MicronTrackerTypeInformation::MicronTrackerTypeInformation()
{
m_DeviceName = MicronTrackerTypeInformation::GetTrackingDeviceName();
m_TrackingDeviceData.push_back(GetDeviceDataMicronTrackerH40());
}
MicronTrackerTypeInformation::~MicronTrackerTypeInformation()
{
}
mitk::TrackingDeviceSource::Pointer MicronTrackerTypeInformation::CreateTrackingDeviceSource(
mitk::TrackingDevice::Pointer trackingDevice,
mitk::NavigationToolStorage::Pointer navigationTools,
std::string* errorMessage,
std::vector* toolCorrespondencesInToolStorage)
{
mitk::TrackingDeviceSource::Pointer returnValue = mitk::TrackingDeviceSource::New();
mitk::ClaronTrackingDevice::Pointer thisDevice = dynamic_cast(trackingDevice.GetPointer());
*toolCorrespondencesInToolStorage = std::vector();
//add the tools to the tracking device
- for (int i = 0; i < navigationTools->GetToolCount(); i++)
+ for (unsigned int i = 0; i < navigationTools->GetToolCount(); i++)
{
mitk::NavigationTool::Pointer thisNavigationTool = navigationTools->GetTool(i);
toolCorrespondencesInToolStorage->push_back(i);
bool toolAddSuccess = thisDevice->AddTool(thisNavigationTool->GetToolName().c_str(), thisNavigationTool->GetCalibrationFile().c_str());
if (!toolAddSuccess)
{
//todo error handling
errorMessage->append("Can't add tool, is the toolfile valid?");
return nullptr;
}
thisDevice->GetTool(i)->SetToolTip(thisNavigationTool->GetToolTipPosition(), thisNavigationTool->GetToolTipOrientation());
}
returnValue->SetTrackingDevice(thisDevice);
return returnValue;
}
}
diff --git a/Modules/IGT/TrackingDevices/mitkNDIAuroraTypeInformation.cpp b/Modules/IGT/TrackingDevices/mitkNDIAuroraTypeInformation.cpp
index 16ce24fc58..77b0e70b23 100644
--- a/Modules/IGT/TrackingDevices/mitkNDIAuroraTypeInformation.cpp
+++ b/Modules/IGT/TrackingDevices/mitkNDIAuroraTypeInformation.cpp
@@ -1,149 +1,153 @@
/*===================================================================
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 "mitkNDIAuroraTypeInformation.h"
#include "mitkIGTHardwareException.h"
#include "mitkNDITrackingDevice.h"
namespace mitk
{
std::string NDIAuroraTypeInformation::GetTrackingDeviceName()
{
return "NDI Aurora";
}
TrackingDeviceData NDIAuroraTypeInformation::GetDeviceDataAuroraCompact()
{
TrackingDeviceData data = { NDIAuroraTypeInformation::GetTrackingDeviceName(), "Aurora Compact", "NDIAuroraCompactFG_Dome.stl", "A" };
return data;
}
TrackingDeviceData NDIAuroraTypeInformation::GetDeviceDataAuroraPlanarCube()
{
TrackingDeviceData data = { NDIAuroraTypeInformation::GetTrackingDeviceName(), "Aurora Planar (Cube)", "NDIAurora.stl", "9" };
return data;
}
TrackingDeviceData NDIAuroraTypeInformation::GetDeviceDataAuroraPlanarDome()
{
TrackingDeviceData data = { NDIAuroraTypeInformation::GetTrackingDeviceName(), "Aurora Planar (Dome)", "NDIAuroraPlanarFG_Dome.stl", "A" };
return data;
}
TrackingDeviceData NDIAuroraTypeInformation::GetDeviceDataAuroraTabletop()
{
TrackingDeviceData data = { NDIAuroraTypeInformation::GetTrackingDeviceName(), "Aurora Tabletop", "NDIAuroraTabletopFG_Dome.stl", "A" };
return data;
}
NDIAuroraTypeInformation::NDIAuroraTypeInformation()
{
m_DeviceName = NDIAuroraTypeInformation::GetTrackingDeviceName();
m_TrackingDeviceData.push_back(GetDeviceDataAuroraCompact());
m_TrackingDeviceData.push_back(GetDeviceDataAuroraPlanarCube());
m_TrackingDeviceData.push_back(GetDeviceDataAuroraPlanarDome());
m_TrackingDeviceData.push_back(GetDeviceDataAuroraTabletop());
}
NDIAuroraTypeInformation::~NDIAuroraTypeInformation()
{
}
mitk::TrackingDeviceSource::Pointer NDIAuroraTypeInformation::CreateTrackingDeviceSource(
mitk::TrackingDevice::Pointer trackingDevice,
mitk::NavigationToolStorage::Pointer navigationTools,
std::string* errorMessage,
std::vector* toolCorrespondencesInToolStorage)
{
MITK_DEBUG << "Creating Aurora tracking device.";
mitk::TrackingDeviceSource::Pointer returnValue = mitk::TrackingDeviceSource::New();
mitk::NDITrackingDevice::Pointer thisDevice = dynamic_cast(trackingDevice.GetPointer());
try
{
//connect to aurora to dectect tools automatically
thisDevice->OpenConnection();
}
catch (mitk::IGTHardwareException& e)
{
errorMessage->append("Hardware error on opening the connection (");
errorMessage->append(e.GetDescription());
errorMessage->append(")");
return nullptr;
}
catch (mitk::IGTException& e)
{
errorMessage->append("Error on opening the connection (");
errorMessage->append(e.GetDescription());
errorMessage->append(")");
return nullptr;
}
//now search for automatically detected tools in the tool storage and save them
mitk::NavigationToolStorage::Pointer newToolStorageInRightOrder = mitk::NavigationToolStorage::New();
- std::vector alreadyFoundTools = std::vector();
+ std::vector alreadyFoundTools = std::vector();
*toolCorrespondencesInToolStorage = std::vector();
for (unsigned int i = 0; i < thisDevice->GetToolCount(); i++)
{
bool toolFound = false;
- for (int j = 0; j < navigationTools->GetToolCount(); j++)
+ for (unsigned int j = 0; j < navigationTools->GetToolCount(); j++)
{
//check if the serial number is the same to identify the tool
if ((dynamic_cast(thisDevice->GetTool(i)))->GetSerialNumber() == navigationTools->GetTool(j)->GetSerialNumber())
{
//check if this tool was already added to make sure that every tool is only added once (in case of same serial numbers)
bool toolAlreadyAdded = false;
- for (unsigned int k = 0; k < alreadyFoundTools.size(); k++) if (alreadyFoundTools.at(k) == j) toolAlreadyAdded = true;
+ for (unsigned int k = 0; k < alreadyFoundTools.size(); k++)
+ {
+ if (alreadyFoundTools.at(k) == j)
+ {
+ toolAlreadyAdded = true;
+ }
+ }
if (!toolAlreadyAdded)
{
//add tool in right order
newToolStorageInRightOrder->AddTool(navigationTools->GetTool(j));
toolCorrespondencesInToolStorage->push_back(j);
//adapt name of tool
dynamic_cast(thisDevice->GetTool(i))->SetToolName(navigationTools->GetTool(j)->GetToolName());
//set tip of tool
dynamic_cast(thisDevice->GetTool(i))->SetToolTip(navigationTools->GetTool(j)->GetToolTipPosition(), navigationTools->GetTool(j)->GetToolTipOrientation());
//rember that this tool was already found
alreadyFoundTools.push_back(j);
toolFound = true;
break;
}
}
}
if (!toolFound)
{
errorMessage->append("Error: did not find every automatically detected tool in the loaded tool storage: aborting initialization.");
return nullptr;
}
}
- //delete all tools from the tool storage
- navigationTools->DeleteAllTools();
-
- //and add only the detected tools in the right order
- for (int i = 0; i < newToolStorageInRightOrder->GetToolCount(); i++)
+ //And resort them (this was done in TrackingToolBoxWorker before).
+ for (unsigned int i = 0; i < newToolStorageInRightOrder->GetToolCount(); i++)
{
- navigationTools->AddTool(newToolStorageInRightOrder->GetTool(i));
+ navigationTools->AssignToolNumber(newToolStorageInRightOrder->GetTool(i)->GetIdentifier(), i);
}
+
returnValue->SetTrackingDevice(thisDevice);
MITK_DEBUG << "Number of tools of created tracking device: " << thisDevice->GetToolCount();
MITK_DEBUG << "Number of outputs of created source: " << returnValue->GetNumberOfOutputs();
return returnValue;
}
}
diff --git a/Modules/IGT/TrackingDevices/mitkNDIPolarisTypeInformation.cpp b/Modules/IGT/TrackingDevices/mitkNDIPolarisTypeInformation.cpp
index 2fd22e6bd0..025f26d535 100644
--- a/Modules/IGT/TrackingDevices/mitkNDIPolarisTypeInformation.cpp
+++ b/Modules/IGT/TrackingDevices/mitkNDIPolarisTypeInformation.cpp
@@ -1,90 +1,90 @@
/*===================================================================
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 "mitkNDIPolarisTypeInformation.h"
#include "mitkNDITrackingDevice.h"
namespace mitk
{
std::string NDIPolarisTypeInformation::GetTrackingDeviceName()
{
return "NDI Polaris"; ///< Polaris: optical Tracker from NDI;
}
TrackingDeviceData NDIPolarisTypeInformation::GetDeviceDataPolarisOldModel()
{
TrackingDeviceData data = { NDIPolarisTypeInformation::GetTrackingDeviceName(), "Polaris (Old Model)", "NDIPolarisOldModel.stl", "0" };
return data;
}
TrackingDeviceData NDIPolarisTypeInformation::GetDeviceDataPolarisSpectra()
{
//full hardware code of polaris spectra: 5-240000-153200-095000+057200+039800+056946+024303+029773+999999+99999924
TrackingDeviceData data = { NDIPolarisTypeInformation::GetTrackingDeviceName(), "Polaris Spectra", "NDIPolarisSpectra.stl", "5-2" };
return data;
}
TrackingDeviceData NDIPolarisTypeInformation::GetDeviceDataSpectraExtendedPyramid()
{
//full hardware code of polaris spectra (extended pyramid): 5-300000-153200-095000+057200+039800+056946+024303+029773+999999+07350024
TrackingDeviceData data = { NDIPolarisTypeInformation::GetTrackingDeviceName(), "Polaris Spectra (Extended Pyramid)", "NDIPolarisSpectraExtendedPyramid.stl", "5-3" };
return data;
}
TrackingDeviceData NDIPolarisTypeInformation::GetDeviceDataPolarisVicra()
{
TrackingDeviceData data = { NDIPolarisTypeInformation::GetTrackingDeviceName(), "Polaris Vicra", "NDIPolarisVicra.stl", "7" };
return data;
}
NDIPolarisTypeInformation::NDIPolarisTypeInformation()
{
m_DeviceName = NDIPolarisTypeInformation::GetTrackingDeviceName();
m_TrackingDeviceData.push_back(GetDeviceDataPolarisOldModel());
m_TrackingDeviceData.push_back(GetDeviceDataSpectraExtendedPyramid());
m_TrackingDeviceData.push_back(GetDeviceDataPolarisSpectra());
m_TrackingDeviceData.push_back(GetDeviceDataPolarisVicra());
}
NDIPolarisTypeInformation::~NDIPolarisTypeInformation()
{
}
mitk::TrackingDeviceSource::Pointer NDIPolarisTypeInformation::CreateTrackingDeviceSource(
mitk::TrackingDevice::Pointer trackingDevice,
mitk::NavigationToolStorage::Pointer navigationTools,
std::string* errorMessage,
std::vector* toolCorrespondencesInToolStorage)
{
mitk::TrackingDeviceSource::Pointer returnValue = mitk::TrackingDeviceSource::New();
mitk::NDITrackingDevice::Pointer thisDevice = dynamic_cast(trackingDevice.GetPointer());
*toolCorrespondencesInToolStorage = std::vector();
//add the tools to the tracking device
- for (int i = 0; i < navigationTools->GetToolCount(); i++)
+ for (unsigned int i = 0; i < navigationTools->GetToolCount(); i++)
{
mitk::NavigationTool::Pointer thisNavigationTool = navigationTools->GetTool(i);
toolCorrespondencesInToolStorage->push_back(i);
bool toolAddSuccess = thisDevice->AddTool(thisNavigationTool->GetToolName().c_str(), thisNavigationTool->GetCalibrationFile().c_str());
if (!toolAddSuccess)
{
//todo: error handling
errorMessage->append("Can't add tool, is the SROM-file valid?");
return nullptr;
}
thisDevice->GetTool(i)->SetToolTip(thisNavigationTool->GetToolTipPosition(), thisNavigationTool->GetToolTipOrientation());
}
returnValue->SetTrackingDevice(thisDevice);
return returnValue;
}
}
diff --git a/Modules/IGT/TrackingDevices/mitkNDITrackingDevice.cpp b/Modules/IGT/TrackingDevices/mitkNDITrackingDevice.cpp
index 04a190ddaa..9f3e895a38 100644
--- a/Modules/IGT/TrackingDevices/mitkNDITrackingDevice.cpp
+++ b/Modules/IGT/TrackingDevices/mitkNDITrackingDevice.cpp
@@ -1,1335 +1,1314 @@
/*===================================================================
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 "mitkNDITrackingDevice.h"
#include "mitkIGTTimeStamp.h"
#include "mitkIGTHardwareException.h"
#include
#include
#include
#include
#include
#include
// vtk
#include
typedef itk::MutexLockHolder MutexLockHolder;
-
const unsigned char CR = 0xD; // == '\r' - carriage return
const unsigned char LF = 0xA; // == '\n' - line feed
-
mitk::NDITrackingDevice::NDITrackingDevice() :
-TrackingDevice(),m_DeviceName(""), m_PortNumber(mitk::SerialCommunication::COM5), m_BaudRate(mitk::SerialCommunication::BaudRate9600),
+TrackingDevice(), m_DeviceName(""), m_PortNumber(mitk::SerialCommunication::COM5), m_BaudRate(mitk::SerialCommunication::BaudRate9600),
m_DataBits(mitk::SerialCommunication::DataBits8), m_Parity(mitk::SerialCommunication::None), m_StopBits(mitk::SerialCommunication::StopBits1),
m_HardwareHandshake(mitk::SerialCommunication::HardwareHandshakeOff),
m_IlluminationActivationRate(Hz20), m_DataTransferMode(TX), m_6DTools(), m_ToolsMutex(nullptr),
m_SerialCommunication(nullptr), m_SerialCommunicationMutex(nullptr), m_DeviceProtocol(nullptr),
m_MultiThreader(nullptr), m_ThreadID(0), m_OperationMode(ToolTracking6D), m_MarkerPointsMutex(nullptr), m_MarkerPoints()
{
m_Data = mitk::UnspecifiedTrackingTypeInformation::GetDeviceDataUnspecified();
m_6DTools.clear();
m_SerialCommunicationMutex = itk::FastMutexLock::New();
m_DeviceProtocol = NDIProtocol::New();
m_DeviceProtocol->SetTrackingDevice(this);
m_DeviceProtocol->UseCRCOn();
m_MultiThreader = itk::MultiThreader::New();
m_ToolsMutex = itk::FastMutexLock::New();
m_MarkerPointsMutex = itk::FastMutexLock::New();
m_MarkerPoints.reserve(50); // a maximum of 50 marker positions can be reported by the tracking device
}
-
bool mitk::NDITrackingDevice::UpdateTool(mitk::TrackingTool* tool)
{
if (this->GetState() != Setup)
{
mitk::NDIPassiveTool* ndiTool = dynamic_cast(tool);
if (ndiTool == nullptr)
return false;
std::string portHandle = ndiTool->GetPortHandle();
//return false if the SROM Data has not been set
if (ndiTool->GetSROMData() == nullptr)
return false;
NDIErrorCode returnvalue;
returnvalue = m_DeviceProtocol->PVWR(&portHandle, ndiTool->GetSROMData(), ndiTool->GetSROMDataLength());
if (returnvalue != NDIOKAY)
return false;
returnvalue = m_DeviceProtocol->PINIT(&portHandle);
if (returnvalue != NDIOKAY)
return false;
returnvalue = m_DeviceProtocol->PENA(&portHandle, ndiTool->GetTrackingPriority()); // Enable tool
if (returnvalue != NDIOKAY)
return false;
return true;
}
else
{
return false;
}
}
void mitk::NDITrackingDevice::SetRotationMode(RotationMode r)
{
m_RotationMode = r;
}
mitk::NDITrackingDevice::~NDITrackingDevice()
{
/* stop tracking and disconnect from tracking device */
if (GetState() == Tracking)
{
this->StopTracking();
}
if (GetState() == Ready)
{
this->CloseConnection();
}
/* cleanup tracking thread */
if ((m_ThreadID != 0) && (m_MultiThreader.IsNotNull()))
{
m_MultiThreader->TerminateThread(m_ThreadID);
}
m_MultiThreader = nullptr;
/* free serial communication interface */
if (m_SerialCommunication.IsNotNull())
{
m_SerialCommunication->ClearReceiveBuffer();
m_SerialCommunication->ClearSendBuffer();
m_SerialCommunication->CloseConnection();
m_SerialCommunication = nullptr;
}
}
-
void mitk::NDITrackingDevice::SetPortNumber(const PortNumber _arg)
{
if (this->GetState() != Setup)
return;
itkDebugMacro("setting PortNumber to " << _arg);
if (this->m_PortNumber != _arg)
{
this->m_PortNumber = _arg;
this->Modified();
}
}
-
void mitk::NDITrackingDevice::SetDeviceName(std::string _arg)
{
if (this->GetState() != Setup)
return;
itkDebugMacro("setting eviceName to " << _arg);
if (this->m_DeviceName != _arg)
{
this->m_DeviceName = _arg;
this->Modified();
}
}
-
void mitk::NDITrackingDevice::SetBaudRate(const BaudRate _arg)
{
if (this->GetState() != Setup)
return;
itkDebugMacro("setting BaudRate to " << _arg);
if (this->m_BaudRate != _arg)
{
this->m_BaudRate = _arg;
this->Modified();
}
}
-
void mitk::NDITrackingDevice::SetDataBits(const DataBits _arg)
{
if (this->GetState() != Setup)
return;
itkDebugMacro("setting DataBits to " << _arg);
if (this->m_DataBits != _arg)
{
this->m_DataBits = _arg;
this->Modified();
}
}
-
void mitk::NDITrackingDevice::SetParity(const Parity _arg)
{
if (this->GetState() != Setup)
return;
itkDebugMacro("setting Parity to " << _arg);
if (this->m_Parity != _arg)
{
this->m_Parity = _arg;
this->Modified();
}
}
-
void mitk::NDITrackingDevice::SetStopBits(const StopBits _arg)
{
if (this->GetState() != Setup)
return;
itkDebugMacro("setting StopBits to " << _arg);
if (this->m_StopBits != _arg)
{
this->m_StopBits = _arg;
this->Modified();
}
}
-
void mitk::NDITrackingDevice::SetHardwareHandshake(const HardwareHandshake _arg)
{
if (this->GetState() != Setup)
return;
itkDebugMacro("setting HardwareHandshake to " << _arg);
if (this->m_HardwareHandshake != _arg)
{
this->m_HardwareHandshake = _arg;
this->Modified();
}
}
-
void mitk::NDITrackingDevice::SetIlluminationActivationRate(const IlluminationActivationRate _arg)
{
if (this->GetState() == Tracking)
return;
itkDebugMacro("setting IlluminationActivationRate to " << _arg);
if (this->m_IlluminationActivationRate != _arg)
{
this->m_IlluminationActivationRate = _arg;
this->Modified();
if (this->GetState() == Ready) // if the connection to the tracking system is established, send the new rate to the tracking device too
m_DeviceProtocol->IRATE(this->m_IlluminationActivationRate);
}
}
-
void mitk::NDITrackingDevice::SetDataTransferMode(const DataTransferMode _arg)
{
itkDebugMacro("setting DataTransferMode to " << _arg);
if (this->m_DataTransferMode != _arg)
{
this->m_DataTransferMode = _arg;
this->Modified();
}
}
-
mitk::NDIErrorCode mitk::NDITrackingDevice::Send(const std::string* input, bool addCRC)
{
if (input == nullptr)
return SERIALSENDERROR;
std::string message;
if (addCRC == true)
message = *input + CalcCRC(input) + std::string(1, CR);
else
message = *input + std::string(1, CR);
//unsigned int messageLength = message.length() + 1; // +1 for CR
// Clear send buffer
this->ClearSendBuffer();
// Send the date to the device
MutexLockHolder lock(*m_SerialCommunicationMutex); // lock and unlock the mutex
long returnvalue = m_SerialCommunication->Send(message);
if (returnvalue == 0)
return SERIALSENDERROR;
else
return NDIOKAY;
}
-
mitk::NDIErrorCode mitk::NDITrackingDevice::Receive(std::string* answer, unsigned int numberOfBytes)
{
if (answer == nullptr)
return SERIALRECEIVEERROR;
MutexLockHolder lock(*m_SerialCommunicationMutex); // lock and unlock the mutex
long returnvalue = m_SerialCommunication->Receive(*answer, numberOfBytes); // never read more bytes than the device has send, the function will block until enough bytes are send...
if (returnvalue == 0)
return SERIALRECEIVEERROR;
else
return NDIOKAY;
}
-
mitk::NDIErrorCode mitk::NDITrackingDevice::ReceiveByte(char* answer)
{
if (answer == nullptr)
return SERIALRECEIVEERROR;
std::string m;
MutexLockHolder lock(*m_SerialCommunicationMutex); // lock and unlock the mutex
long returnvalue = m_SerialCommunication->Receive(m, 1);
- if ((returnvalue == 0) ||(m.size() != 1))
+ if ((returnvalue == 0) || (m.size() != 1))
return SERIALRECEIVEERROR;
*answer = m.at(0);
return NDIOKAY;
}
-
mitk::NDIErrorCode mitk::NDITrackingDevice::ReceiveLine(std::string* answer)
{
if (answer == nullptr)
return SERIALRECEIVEERROR;
std::string m;
MutexLockHolder lock(*m_SerialCommunicationMutex); // lock and unlock the mutex
do
{
long returnvalue = m_SerialCommunication->Receive(m, 1);
- if ((returnvalue == 0) ||(m.size() != 1))
+ if ((returnvalue == 0) || (m.size() != 1))
return SERIALRECEIVEERROR;
*answer += m;
} while (m.at(0) != LF);
return NDIOKAY;
}
-
void mitk::NDITrackingDevice::ClearSendBuffer()
{
MutexLockHolder lock(*m_SerialCommunicationMutex); // lock and unlock the mutex
m_SerialCommunication->ClearSendBuffer();
}
-
void mitk::NDITrackingDevice::ClearReceiveBuffer()
{
MutexLockHolder lock(*m_SerialCommunicationMutex); // lock and unlock the mutex
m_SerialCommunication->ClearReceiveBuffer();
}
-
const std::string mitk::NDITrackingDevice::CalcCRC(const std::string* input)
{
-
if (input == nullptr)
return "";
/* the crc16 calculation code is taken from the NDI API guide example code section */
- static int oddparity[16] = {0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0};
+ static int oddparity[16] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 };
unsigned int data; // copy of the input string's current character
unsigned int crcValue = 0; // the crc value is stored here
unsigned int* puCRC16 = &crcValue; // the algorithm uses a pointer to crcValue, so it's easier to provide that than to change the algorithm
for (unsigned int i = 0; i < input->length(); i++)
{
data = (*input)[i];
- data = (data ^ (*(puCRC16) & 0xff)) & 0xff;
+ data = (data ^ (*(puCRC16)& 0xff)) & 0xff;
*puCRC16 >>= 8;
if (oddparity[data & 0x0f] ^ oddparity[data >> 4])
{
*(puCRC16) ^= 0xc001;
}
data <<= 6;
*puCRC16 ^= data;
data <<= 1;
*puCRC16 ^= data;
}
// crcValue contains now the CRC16 value. Convert it to a string and return it
char returnvalue[13];
- sprintf(returnvalue,"%04X", crcValue); // 4 hexadecimal digit with uppercase format
+ sprintf(returnvalue, "%04X", crcValue); // 4 hexadecimal digit with uppercase format
return std::string(returnvalue);
}
bool mitk::NDITrackingDevice::OpenConnection()
{
-
//this->m_ModeMutex->Lock();
if (this->GetState() != Setup)
- {mitkThrowException(mitk::IGTException) << "Can only try to open the connection if in setup mode";}
+ {
+ mitkThrowException(mitk::IGTException) << "Can only try to open the connection if in setup mode";
+ }
m_SerialCommunication = mitk::SerialCommunication::New();
/* init local com port to standard com settings for a NDI tracking device:
9600 baud, 8 data bits, no parity, 1 stop bit, no hardware handshake */
if (m_DeviceName.empty())
m_SerialCommunication->SetPortNumber(m_PortNumber);
else
m_SerialCommunication->SetDeviceName(m_DeviceName);
m_SerialCommunication->SetBaudRate(mitk::SerialCommunication::BaudRate9600);
m_SerialCommunication->SetDataBits(mitk::SerialCommunication::DataBits8);
m_SerialCommunication->SetParity(mitk::SerialCommunication::None);
m_SerialCommunication->SetStopBits(mitk::SerialCommunication::StopBits1);
m_SerialCommunication->SetSendTimeout(5000);
m_SerialCommunication->SetReceiveTimeout(5000);
if (m_SerialCommunication->OpenConnection() == 0) // 0 == ERROR_VALUE
{
m_SerialCommunication->CloseConnection();
m_SerialCommunication = nullptr;
mitkThrowException(mitk::IGTHardwareException) << "Can not open serial port";
}
/* Reset Tracking device by sending a serial break for 500ms */
m_SerialCommunication->SendBreak(400);
/* Read answer from tracking device (RESETBE6F) */
static const std::string reset("RESETBE6F\r");
std::string answer = "";
this->Receive(&answer, reset.length()); // read answer (should be RESETBE6F)
this->ClearReceiveBuffer(); // flush the receive buffer of all remaining data (carriage return, strings other than reset
if (reset.compare(answer) != 0) // check for RESETBE6F
{
if (m_SerialCommunication.IsNotNull())
{
m_SerialCommunication->CloseConnection();
m_SerialCommunication = nullptr;
}
mitkThrowException(mitk::IGTHardwareException) << "Hardware Reset of tracking device did not work";
}
/* Now the tracking device isSetData reset, start initialization */
NDIErrorCode returnvalue;
/* set device com settings to new values and wait for the device to change them */
returnvalue = m_DeviceProtocol->COMM(m_BaudRate, m_DataBits, m_Parity, m_StopBits, m_HardwareHandshake);
if (returnvalue != NDIOKAY)
- {mitkThrowException(mitk::IGTHardwareException) << "Could not set comm settings in trackingdevice";}
+ {
+ mitkThrowException(mitk::IGTHardwareException) << "Could not set comm settings in trackingdevice";
+ }
//after changing COMM wait at least 100ms according to NDI Api documentation page 31
itksys::SystemTools::Delay(500);
/* now change local com settings accordingly */
m_SerialCommunication->CloseConnection();
m_SerialCommunication->SetBaudRate(m_BaudRate);
m_SerialCommunication->SetDataBits(m_DataBits);
m_SerialCommunication->SetParity(m_Parity);
m_SerialCommunication->SetStopBits(m_StopBits);
m_SerialCommunication->SetHardwareHandshake(m_HardwareHandshake);
m_SerialCommunication->SetSendTimeout(5000);
m_SerialCommunication->SetReceiveTimeout(5000);
m_SerialCommunication->OpenConnection();
-
/* initialize the tracking device */
returnvalue = m_DeviceProtocol->INIT();
if (returnvalue != NDIOKAY)
- {mitkThrowException(mitk::IGTHardwareException) << "Could not initialize the tracking device";}
+ {
+ mitkThrowException(mitk::IGTHardwareException) << "Could not initialize the tracking device";
+ }
if (this->GetType() == mitk::UnspecifiedTrackingTypeInformation::GetTrackingDeviceName()) // if the type of tracking device is not specified, try to query the connected device
{
mitk::TrackingDeviceType deviceType;
returnvalue = m_DeviceProtocol->VER(deviceType);
if ((returnvalue != NDIOKAY) || (deviceType == mitk::UnspecifiedTrackingTypeInformation::GetTrackingDeviceName()))
- {mitkThrowException(mitk::IGTHardwareException) << "Could not determine tracking device type. Please set manually and try again.";}
+ {
+ mitkThrowException(mitk::IGTHardwareException) << "Could not determine tracking device type. Please set manually and try again.";
+ }
this->SetType(deviceType);
}
/**** Optional Polaris specific code, Work in progress
// start diagnostic mode
returnvalue = m_DeviceProtocol->DSTART();
if (returnvalue != NDIOKAY)
{
this->SetErrorMessage("Could not start diagnostic mode");
return false;
}
else // we are in diagnostic mode
{
// initialize extensive IR checking
returnvalue = m_DeviceProtocol->IRINIT();
if (returnvalue != NDIOKAY)
{
this->SetErrorMessage("Could not initialize intense infrared light checking");
return false;
}
bool intenseIR = false;
returnvalue = m_DeviceProtocol->IRCHK(&intenseIR);
if (returnvalue != NDIOKAY)
{
this->SetErrorMessage("Could not execute intense infrared light checking");
return false;
}
if (intenseIR == true)
// do something - warn the user, raise exception, write to protocol or similar
std::cout << "Warning: Intense infrared light detected. Accurate tracking will probably not be possible.\n";
// stop diagnictic mode
returnvalue = m_DeviceProtocol->DSTOP();
if (returnvalue != NDIOKAY)
{
this->SetErrorMessage("Could not stop diagnostic mode");
return false;
}
}
*** end of optional polaris code ***/
/**
* now add tools to the tracking system
**/
/* First, check if the tracking device has port handles that need to be freed and free them */
returnvalue = FreePortHandles();
// non-critical, therefore no error handling
/**
* POLARIS: initialize the tools that were added manually
**/
{
-
MutexLockHolder toolsMutexLockHolder(*m_ToolsMutex); // lock and unlock the mutex
std::string portHandle;
auto endIt = m_6DTools.end();
- for(auto it = m_6DTools.begin(); it != endIt; ++it)
+ for (auto it = m_6DTools.begin(); it != endIt; ++it)
{
/* get a port handle for the tool */
returnvalue = m_DeviceProtocol->PHRQ(&portHandle);
if (returnvalue == NDIOKAY)
{
(*it)->SetPortHandle(portHandle.c_str());
/* now write the SROM file of the tool to the tracking system using PVWR */
- if (this->m_Data.Line == mitk::NDIPolarisTypeInformation::GetTrackingDeviceName())
+ if (this->m_Data.Line == mitk::NDIPolarisTypeInformation::GetTrackingDeviceName())
{
returnvalue = m_DeviceProtocol->PVWR(&portHandle, (*it)->GetSROMData(), (*it)->GetSROMDataLength());
if (returnvalue != NDIOKAY)
- {mitkThrowException(mitk::IGTHardwareException) << (std::string("Could not write SROM file for tool '") + (*it)->GetToolName() + std::string("' to tracking device")).c_str();}
+ {
+ mitkThrowException(mitk::IGTHardwareException) << (std::string("Could not write SROM file for tool '") + (*it)->GetToolName() + std::string("' to tracking device")).c_str();
+ }
returnvalue = m_DeviceProtocol->PINIT(&portHandle);
if (returnvalue != NDIOKAY)
- {mitkThrowException(mitk::IGTHardwareException) << (std::string("Could not initialize tool '") + (*it)->GetToolName()).c_str();}
+ {
+ mitkThrowException(mitk::IGTHardwareException) << (std::string("Could not initialize tool '") + (*it)->GetToolName()).c_str();
+ }
if ((*it)->IsEnabled() == true)
{
returnvalue = m_DeviceProtocol->PENA(&portHandle, (*it)->GetTrackingPriority()); // Enable tool
if (returnvalue != NDIOKAY)
{
mitkThrowException(mitk::IGTHardwareException) << (std::string("Could not enable port '") + portHandle +
- std::string("' for tool '")+ (*it)->GetToolName() + std::string("'")).c_str();
+ std::string("' for tool '") + (*it)->GetToolName() + std::string("'")).c_str();
}
}
}
}
}
} // end of toolsmutexlockholder scope
/* check for wired tools and add them too */
if (this->DiscoverWiredTools() == false) // query the tracking device for wired tools and add them to our tool list
return false; // \TODO: could we continue anyways?
-
/*POLARIS: set the illuminator activation rate */
if (this->m_Data.Line == mitk::NDIPolarisTypeInformation::GetTrackingDeviceName())
{
returnvalue = m_DeviceProtocol->IRATE(this->m_IlluminationActivationRate);
if (returnvalue != NDIOKAY)
- {mitkThrowException(mitk::IGTHardwareException) << "Could not set the illuminator activation rate";}
+ {
+ mitkThrowException(mitk::IGTHardwareException) << "Could not set the illuminator activation rate";
+ }
}
/* finish - now all tools should be added, initialized and enabled, so that tracking can be started */
this->SetState(Ready);
try
{
SetVolume(this->m_Data);
}
catch (mitk::IGTHardwareException e)
{
- MITK_WARN<PHSR(OCCUPIED, &portHandle);
if (returnvalue != NDIOKAY)
- {mitkThrowException(mitk::IGTHardwareException) << "Could not obtain a list of port handles that are connected";}
+ {
+ mitkThrowException(mitk::IGTHardwareException) << "Could not obtain a list of port handles that are connected";
+ }
/* if there are port handles that need to be initialized, initialize them. Furthermore instantiate tools for each handle that has no tool yet. */
std::string ph;
for (unsigned int i = 0; i < portHandle.size(); i += 2)
{
ph = portHandle.substr(i, 2);
mitk::NDIPassiveTool* pt = this->GetInternalTool(ph);
- if ( pt == nullptr) // if we don't have a tool, something is wrong. Tools should be discovered first by calling DiscoverWiredTools()
+ if (pt == nullptr) // if we don't have a tool, something is wrong. Tools should be discovered first by calling DiscoverWiredTools()
continue;
if (pt->GetSROMData() == nullptr)
continue;
returnvalue = m_DeviceProtocol->PVWR(&ph, pt->GetSROMData(), pt->GetSROMDataLength());
if (returnvalue != NDIOKAY)
- {mitkThrowException(mitk::IGTHardwareException) << (std::string("Could not write SROM file for tool '") + pt->GetToolName() + std::string("' to tracking device")).c_str();}
+ {
+ mitkThrowException(mitk::IGTHardwareException) << (std::string("Could not write SROM file for tool '") + pt->GetToolName() + std::string("' to tracking device")).c_str();
+ }
returnvalue = m_DeviceProtocol->PINIT(&ph);
if (returnvalue != NDIOKAY)
- {mitkThrowException(mitk::IGTHardwareException) << (std::string("Could not initialize tool '") + pt->GetToolName()).c_str();}
+ {
+ mitkThrowException(mitk::IGTHardwareException) << (std::string("Could not initialize tool '") + pt->GetToolName()).c_str();
+ }
if (pt->IsEnabled() == true)
{
returnvalue = m_DeviceProtocol->PENA(&ph, pt->GetTrackingPriority()); // Enable tool
if (returnvalue != NDIOKAY)
{
mitkThrowException(mitk::IGTHardwareException) << (std::string("Could not enable port '") + portHandle +
- std::string("' for tool '")+ pt->GetToolName() + std::string("'")).c_str();
+ std::string("' for tool '") + pt->GetToolName() + std::string("'")).c_str();
}
}
}
return true;
}
-
mitk::TrackingDeviceType mitk::NDITrackingDevice::TestConnection()
{
if (this->GetState() != Setup)
{
return mitk::UnspecifiedTrackingTypeInformation::GetTrackingDeviceName();
}
m_SerialCommunication = mitk::SerialCommunication::New();
//m_DeviceProtocol = mitk::NDIProtocol::New();
//m_DeviceProtocol->SetTrackingDevice(this);
//m_DeviceProtocol->UseCRCOn();
/* init local com port to standard com settings for a NDI tracking device:
9600 baud, 8 data bits, no parity, 1 stop bit, no hardware handshake
*/
if (m_DeviceName.empty())
m_SerialCommunication->SetPortNumber(m_PortNumber);
else
m_SerialCommunication->SetDeviceName(m_DeviceName);
m_SerialCommunication->SetBaudRate(mitk::SerialCommunication::BaudRate9600);
m_SerialCommunication->SetDataBits(mitk::SerialCommunication::DataBits8);
m_SerialCommunication->SetParity(mitk::SerialCommunication::None);
m_SerialCommunication->SetStopBits(mitk::SerialCommunication::StopBits1);
m_SerialCommunication->SetSendTimeout(5000);
m_SerialCommunication->SetReceiveTimeout(5000);
if (m_SerialCommunication->OpenConnection() == 0) // error
{
m_SerialCommunication = nullptr;
return mitk::UnspecifiedTrackingTypeInformation::GetTrackingDeviceName();
}
/* Reset Tracking device by sending a serial break for 500ms */
m_SerialCommunication->SendBreak(400);
/* Read answer from tracking device (RESETBE6F) */
static const std::string reset("RESETBE6F\r");
std::string answer = "";
this->Receive(&answer, reset.length()); // read answer (should be RESETBE6F)
this->ClearReceiveBuffer(); // flush the receive buffer of all remaining data (carriage return, strings other than reset
if (reset.compare(answer) != 0) // check for RESETBE6F
{
m_SerialCommunication->CloseConnection();
m_SerialCommunication = nullptr;
mitkThrowException(mitk::IGTHardwareException) << "Hardware Reset of tracking device did not work";
}
/* Now the tracking device is reset, start initialization */
NDIErrorCode returnvalue;
/* initialize the tracking device */
//returnvalue = m_DeviceProtocol->INIT();
//if (returnvalue != NDIOKAY)
//{
// this->SetErrorMessage("Could not initialize the tracking device");
// return mitk::TrackingSystemNotSpecified;
//}
-
- mitk::TrackingDeviceType deviceType;
- returnvalue = m_DeviceProtocol->VER(deviceType);
- if ((returnvalue != NDIOKAY) || (deviceType == mitk::UnspecifiedTrackingTypeInformation::GetTrackingDeviceName()))
- {
- m_SerialCommunication = nullptr;
- return mitk::UnspecifiedTrackingTypeInformation::GetTrackingDeviceName();
- }
+ mitk::TrackingDeviceType deviceType;
+ returnvalue = m_DeviceProtocol->VER(deviceType);
+ if ((returnvalue != NDIOKAY) || (deviceType == mitk::UnspecifiedTrackingTypeInformation::GetTrackingDeviceName()))
+ {
m_SerialCommunication = nullptr;
- return deviceType;
+ return mitk::UnspecifiedTrackingTypeInformation::GetTrackingDeviceName();
+ }
+ m_SerialCommunication = nullptr;
+ return deviceType;
}
-
bool mitk::NDITrackingDevice::CloseConnection()
{
if (this->GetState() != Setup)
{
//init before closing to force the field generator from aurora to switch itself off
m_DeviceProtocol->INIT();
/* close the serial connection */
m_SerialCommunication->CloseConnection();
/* invalidate all tools */
this->InvalidateAll();
/* return to setup mode */
this->SetState(Setup);
m_SerialCommunication = nullptr;
}
return true;
}
-
ITK_THREAD_RETURN_TYPE mitk::NDITrackingDevice::ThreadStartTracking(void* pInfoStruct)
{
/* extract this pointer from Thread Info structure */
struct itk::MultiThreader::ThreadInfoStruct * pInfo = (struct itk::MultiThreader::ThreadInfoStruct*)pInfoStruct;
if (pInfo == nullptr)
{
return ITK_THREAD_RETURN_VALUE;
}
if (pInfo->UserData == nullptr)
{
return ITK_THREAD_RETURN_VALUE;
}
NDITrackingDevice *trackingDevice = (NDITrackingDevice*)pInfo->UserData;
if (trackingDevice != nullptr)
{
if (trackingDevice->GetOperationMode() == ToolTracking6D)
trackingDevice->TrackTools(); // call TrackTools() from the original object
else if (trackingDevice->GetOperationMode() == MarkerTracking3D)
trackingDevice->TrackMarkerPositions(); // call TrackMarkerPositions() from the original object
else if (trackingDevice->GetOperationMode() == ToolTracking5D)
trackingDevice->TrackMarkerPositions(); // call TrackMarkerPositions() from the original object
else if (trackingDevice->GetOperationMode() == HybridTracking)
{
trackingDevice->TrackToolsAndMarkers();
}
}
trackingDevice->m_ThreadID = 0; // erase thread id, now that this thread will end.
return ITK_THREAD_RETURN_VALUE;
}
-
bool mitk::NDITrackingDevice::StartTracking()
{
if (this->GetState() != Ready)
return false;
this->SetState(Tracking); // go to mode Tracking
this->m_StopTrackingMutex->Lock(); // update the local copy of m_StopTracking
this->m_StopTracking = false;
this->m_StopTrackingMutex->Unlock();
m_ThreadID = m_MultiThreader->SpawnThread(this->ThreadStartTracking, this); // start a new thread that executes the TrackTools() method
mitk::IGTTimeStamp::GetInstance()->Start(this);
return true;
}
-
void mitk::NDITrackingDevice::TrackTools()
{
/* lock the TrackingFinishedMutex to signal that the execution rights are now transfered to the tracking thread */
MutexLockHolder trackingFinishedLockHolder(*m_TrackingFinishedMutex); // keep lock until end of scope
if (this->GetState() != Tracking)
return;
NDIErrorCode returnvalue;
returnvalue = m_DeviceProtocol->TSTART();
if (returnvalue != NDIOKAY)
return;
-
-
bool localStopTracking; // Because m_StopTracking is used by two threads, access has to be guarded by a mutex. To minimize thread locking, a local copy is used here
this->m_StopTrackingMutex->Lock(); // update the local copy of m_StopTracking
localStopTracking = this->m_StopTracking;
this->m_StopTrackingMutex->Unlock();
while ((this->GetState() == Tracking) && (localStopTracking == false))
{
if (this->m_DataTransferMode == TX)
{
returnvalue = this->m_DeviceProtocol->TX();
if (!((returnvalue == NDIOKAY) || (returnvalue == NDICRCERROR) || (returnvalue == NDICRCDOESNOTMATCH))) // right now, do not stop on crc errors
break;
}
else
{
returnvalue = this->m_DeviceProtocol->BX();
if (returnvalue != NDIOKAY)
break;
}
/* Update the local copy of m_StopTracking */
this->m_StopTrackingMutex->Lock();
localStopTracking = m_StopTracking;
this->m_StopTrackingMutex->Unlock();
}
/* StopTracking was called, thus the mode should be changed back to Ready now that the tracking loop has ended. */
returnvalue = m_DeviceProtocol->TSTOP();
if (returnvalue != NDIOKAY)
- {mitkThrowException(mitk::IGTHardwareException) << "An error occured while tracking tools.";}
+ {
+ mitkThrowException(mitk::IGTHardwareException) << "An error occured while tracking tools.";
+ }
return; // returning from this function (and ThreadStartTracking()) this will end the thread and transfer control back to main thread by releasing trackingFinishedLockHolder
}
-
void mitk::NDITrackingDevice::TrackMarkerPositions()
{
MutexLockHolder trackingFinishedLockHolder(*m_TrackingFinishedMutex); // keep lock until end of scope
if (m_OperationMode == ToolTracking6D)
return;
if (this->GetState() != Tracking)
return;
NDIErrorCode returnvalue;
returnvalue = m_DeviceProtocol->DSTART(); // Start Diagnostic Mode
if (returnvalue != NDIOKAY)
return;
bool localStopTracking; // Because m_StopTracking is used by two threads, access has to be guarded by a mutex. To minimize thread locking, a local copy is used here
this->m_StopTrackingMutex->Lock(); // update the local copy of m_StopTracking
localStopTracking = this->m_StopTracking;
this->m_StopTrackingMutex->Unlock();
while ((this->GetState() == Tracking) && (localStopTracking == false))
{
m_MarkerPointsMutex->Lock(); // lock points data structure
returnvalue = this->m_DeviceProtocol->POS3D(&m_MarkerPoints); // update points data structure with new position data from tracking device
m_MarkerPointsMutex->Unlock();
if (!((returnvalue == NDIOKAY) || (returnvalue == NDICRCERROR) || (returnvalue == NDICRCDOESNOTMATCH))) // right now, do not stop on crc errors
{
std::cout << "Error in POS3D: could not read data. Possibly no markers present." << std::endl;
}
/* Update the local copy of m_StopTracking */
this->m_StopTrackingMutex->Lock();
localStopTracking = m_StopTracking;
this->m_StopTrackingMutex->Unlock();
itksys::SystemTools::Delay(1);
}
/* StopTracking was called, thus the mode should be changed back to Ready now that the tracking loop has ended. */
returnvalue = m_DeviceProtocol->DSTOP();
if (returnvalue != NDIOKAY)
return; // how can this thread tell the application, that an error has occured?
this->SetState(Ready);
return; // returning from this function (and ThreadStartTracking()) this will end the thread
}
-
void mitk::NDITrackingDevice::TrackToolsAndMarkers()
{
-
MutexLockHolder trackingFinishedLockHolder(*m_TrackingFinishedMutex); // keep lock until end of scope
if (m_OperationMode != HybridTracking)
return;
NDIErrorCode returnvalue;
returnvalue = m_DeviceProtocol->TSTART(); // Start Diagnostic Mode
if (returnvalue != NDIOKAY)
return;
bool localStopTracking; // Because m_StopTracking is used by two threads, access has to be guarded by a mutex. To minimize thread locking, a local copy is used here
this->m_StopTrackingMutex->Lock(); // update the local copy of m_StopTracking
localStopTracking = this->m_StopTracking;
this->m_StopTrackingMutex->Unlock();
while ((this->GetState() == Tracking) && (localStopTracking == false))
{
m_MarkerPointsMutex->Lock(); // lock points data structure
returnvalue = this->m_DeviceProtocol->TX(true, &m_MarkerPoints); // update points data structure with new position data from tracking device
m_MarkerPointsMutex->Unlock();
if (!((returnvalue == NDIOKAY) || (returnvalue == NDICRCERROR) || (returnvalue == NDICRCDOESNOTMATCH))) // right now, do not stop on crc errors
{
std::cout << "Error in TX: could not read data. Possibly no markers present." << std::endl;
}
/* Update the local copy of m_StopTracking */
this->m_StopTrackingMutex->Lock();
localStopTracking = m_StopTracking;
this->m_StopTrackingMutex->Unlock();
}
/* StopTracking was called, thus the mode should be changed back to Ready now that the tracking loop has ended. */
returnvalue = m_DeviceProtocol->TSTOP();
if (returnvalue != NDIOKAY)
return; // how can this thread tell the application, that an error has occurred?
this->SetState(Ready);
return; // returning from this function (and ThreadStartTracking()) this will end the thread
}
-
mitk::TrackingTool* mitk::NDITrackingDevice::GetTool(unsigned int toolNumber) const
{
MutexLockHolder toolsMutexLockHolder(*m_ToolsMutex); // lock and unlock the mutex
if (toolNumber < m_6DTools.size())
return m_6DTools.at(toolNumber);
return nullptr;
}
-
mitk::TrackingTool* mitk::NDITrackingDevice::GetToolByName(std::string name) const
{
MutexLockHolder toolsMutexLockHolder(*m_ToolsMutex); // lock and unlock the mutex
auto end = m_6DTools.end();
for (auto iterator = m_6DTools.begin(); iterator != end; ++iterator)
if (name.compare((*iterator)->GetToolName()) == 0)
return *iterator;
return nullptr;
}
-
mitk::NDIPassiveTool* mitk::NDITrackingDevice::GetInternalTool(std::string portHandle)
{
MutexLockHolder toolsMutexLockHolder(*m_ToolsMutex); // lock and unlock the mutex
auto end = m_6DTools.end();
for (auto iterator = m_6DTools.begin(); iterator != end; ++iterator)
if (portHandle.compare((*iterator)->GetPortHandle()) == 0)
return *iterator;
return nullptr;
}
-
unsigned int mitk::NDITrackingDevice::GetToolCount() const
{
MutexLockHolder toolsMutexLockHolder(*m_ToolsMutex); // lock and unlock the mutex
return m_6DTools.size();
}
-
bool mitk::NDITrackingDevice::Beep(unsigned char count)
{
if (this->GetState() != Setup)
{
return (m_DeviceProtocol->BEEP(count) == NDIOKAY);
}
else
{
return false;
}
}
-mitk::TrackingTool* mitk::NDITrackingDevice::AddTool( const char* toolName, const char* fileName, TrackingPriority p /*= NDIPassiveTool::Dynamic*/ )
+mitk::TrackingTool* mitk::NDITrackingDevice::AddTool(const char* toolName, const char* fileName, TrackingPriority p /*= NDIPassiveTool::Dynamic*/)
{
mitk::NDIPassiveTool::Pointer t = mitk::NDIPassiveTool::New();
if (t->LoadSROMFile(fileName) == false)
return nullptr;
t->SetToolName(toolName);
t->SetTrackingPriority(p);
if (this->InternalAddTool(t) == false)
return nullptr;
return t.GetPointer();
}
-
bool mitk::NDITrackingDevice::InternalAddTool(mitk::NDIPassiveTool* tool)
{
if (tool == nullptr)
return false;
NDIPassiveTool::Pointer p = tool;
/* if the connection to the tracking device is already established, add the new tool to the device now */
if (this->GetState() == Ready)
{
/* get a port handle for the tool */
std::string newPortHandle;
NDIErrorCode returnvalue;
returnvalue = m_DeviceProtocol->PHRQ(&newPortHandle);
if (returnvalue == NDIOKAY)
{
p->SetPortHandle(newPortHandle.c_str());
/* now write the SROM file of the tool to the tracking system using PVWR */
returnvalue = m_DeviceProtocol->PVWR(&newPortHandle, p->GetSROMData(), p->GetSROMDataLength());
if (returnvalue != NDIOKAY)
- {mitkThrowException(mitk::IGTHardwareException) << (std::string("Could not write SROM file for tool '") + p->GetToolName() + std::string("' to tracking device")).c_str();}
+ {
+ mitkThrowException(mitk::IGTHardwareException) << (std::string("Could not write SROM file for tool '") + p->GetToolName() + std::string("' to tracking device")).c_str();
+ }
/* initialize the port handle */
returnvalue = m_DeviceProtocol->PINIT(&newPortHandle);
if (returnvalue != NDIOKAY)
- {
- mitkThrowException(mitk::IGTHardwareException) << (std::string("Could not initialize port '") + newPortHandle +
- std::string("' for tool '")+ p->GetToolName() + std::string("'")).c_str();
- }
+ {
+ mitkThrowException(mitk::IGTHardwareException) << (std::string("Could not initialize port '") + newPortHandle +
+ std::string("' for tool '") + p->GetToolName() + std::string("'")).c_str();
+ }
/* enable the port handle */
if (p->IsEnabled() == true)
{
returnvalue = m_DeviceProtocol->PENA(&newPortHandle, p->GetTrackingPriority()); // Enable tool
if (returnvalue != NDIOKAY)
{
mitkThrowException(mitk::IGTHardwareException) << (std::string("Could not enable port '") + newPortHandle +
- std::string("' for tool '")+ p->GetToolName() + std::string("'")).c_str();
+ std::string("' for tool '") + p->GetToolName() + std::string("'")).c_str();
}
}
}
/* now that the tool is added to the device, add it to list too */
m_ToolsMutex->Lock();
this->m_6DTools.push_back(p);
m_ToolsMutex->Unlock();
this->Modified();
return true;
}
else if (this->GetState() == Setup)
{
/* In Setup mode, we only add it to the list, so that OpenConnection() can add it later */
m_ToolsMutex->Lock();
this->m_6DTools.push_back(p);
m_ToolsMutex->Unlock();
this->Modified();
return true;
}
else // in Tracking mode, no tools can be added
return false;
}
-
bool mitk::NDITrackingDevice::RemoveTool(mitk::TrackingTool* tool)
{
mitk::NDIPassiveTool* ndiTool = dynamic_cast(tool);
if (ndiTool == nullptr)
return false;
std::string portHandle = ndiTool->GetPortHandle();
/* a valid portHandle has length 2. If a valid handle exists, the tool is already added to the tracking device, so we have to remove it there
if the connection to the tracking device has already been established.
*/
if ((portHandle.length() == 2) && (this->GetState() == Ready)) // do not remove a tool in tracking mode
{
NDIErrorCode returnvalue;
returnvalue = m_DeviceProtocol->PHF(&portHandle);
if (returnvalue != NDIOKAY)
return false;
/* Now that the tool is removed from the tracking device, remove it from our tool list too */
MutexLockHolder toolsMutexLockHolder(*m_ToolsMutex); // lock and unlock the mutex (scope is inside the if-block
auto end = m_6DTools.end();
for (auto iterator = m_6DTools.begin(); iterator != end; ++iterator)
{
if (iterator->GetPointer() == ndiTool)
{
m_6DTools.erase(iterator);
this->Modified();
return true;
}
}
return false;
}
else if (this->GetState() == Setup) // in Setup Mode, we are not connected to the tracking device, so we can just remove the tool from the tool list
{
MutexLockHolder toolsMutexLockHolder(*m_ToolsMutex); // lock and unlock the mutex
auto end = m_6DTools.end();
for (auto iterator = m_6DTools.begin(); iterator != end; ++iterator)
{
if ((*iterator).GetPointer() == ndiTool)
{
m_6DTools.erase(iterator);
this->Modified();
return true;
}
}
return false;
}
return false;
}
-
void mitk::NDITrackingDevice::InvalidateAll()
{
MutexLockHolder toolsMutexLockHolder(*m_ToolsMutex); // lock and unlock the mutex
auto end = m_6DTools.end();
for (auto iterator = m_6DTools.begin(); iterator != end; ++iterator)
(*iterator)->SetDataValid(false);
}
-
bool mitk::NDITrackingDevice::SetOperationMode(OperationMode mode)
{
if (GetState() == Tracking)
return false;
m_OperationMode = mode;
return true;
}
-
mitk::OperationMode mitk::NDITrackingDevice::GetOperationMode()
{
return m_OperationMode;
}
-
bool mitk::NDITrackingDevice::GetMarkerPositions(MarkerPointContainerType* markerpositions)
{
m_MarkerPointsMutex->Lock();
*markerpositions = m_MarkerPoints; // copy the internal vector to the one provided
m_MarkerPointsMutex->Unlock();
- return (markerpositions->size() != 0) ;
+ return (markerpositions->size() != 0);
}
-
bool mitk::NDITrackingDevice::DiscoverWiredTools()
{
/* First, check for disconnected tools and remove them */
this->FreePortHandles();
/* check for new tools, add and initialize them */
NDIErrorCode returnvalue;
std::string portHandle;
returnvalue = m_DeviceProtocol->PHSR(OCCUPIED, &portHandle);
if (returnvalue != NDIOKAY)
- {mitkThrowException(mitk::IGTHardwareException) << "Could not obtain a list of port handles that are connected";}
+ {
+ mitkThrowException(mitk::IGTHardwareException) << "Could not obtain a list of port handles that are connected";
+ }
/* if there are port handles that need to be initialized, initialize them. Furthermore instantiate tools for each handle that has no tool yet. */
std::string ph;
/* we need to remember the ports which are occupied to be able to readout the serial numbers of the connected tools later */
std::vector occupiedPorts = std::vector();
int numberOfToolsAtStart = this->GetToolCount(); //also remember the number of tools at start to identify the automatically detected tools later
for (unsigned int i = 0; i < portHandle.size(); i += 2)
{
ph = portHandle.substr(i, 2);
if (this->GetInternalTool(ph) != nullptr) // if we already have a tool with this handle
continue; // then skip the initialization
//instantiate an object for each tool that is connected
mitk::NDIPassiveTool::Pointer newTool = mitk::NDIPassiveTool::New();
newTool->SetPortHandle(ph.c_str());
newTool->SetTrackingPriority(mitk::NDIPassiveTool::Dynamic);
//set a name for identification
newTool->SetToolName((std::string("Port ") + ph).c_str());
returnvalue = m_DeviceProtocol->PINIT(&ph);
if (returnvalue != NDIINITIALIZATIONFAILED) //if the initialization failed (AURORA) it can not be enabled. A srom file will have to be specified manually first. Still return true to be able to continue
{
if (returnvalue != NDIOKAY)
{
mitkThrowException(mitk::IGTHardwareException) << (std::string("Could not initialize port '") + ph +
- std::string("' for tool '")+ newTool->GetToolName() + std::string("'")).c_str();
+ std::string("' for tool '") + newTool->GetToolName() + std::string("'")).c_str();
}
/* enable the port handle */
returnvalue = m_DeviceProtocol->PENA(&ph, newTool->GetTrackingPriority()); // Enable tool
if (returnvalue != NDIOKAY)
{
mitkThrowException(mitk::IGTHardwareException) << (std::string("Could not enable port '") + ph +
- std::string("' for tool '")+ newTool->GetToolName() + std::string("'")).c_str();
+ std::string("' for tool '") + newTool->GetToolName() + std::string("'")).c_str();
}
}
//we have to temporarily unlock m_ModeMutex here to avoid a deadlock with another lock inside InternalAddTool()
if (this->InternalAddTool(newTool) == false)
- {mitkThrowException(mitk::IGTException) << "Error while adding new tool";}
+ {
+ mitkThrowException(mitk::IGTException) << "Error while adding new tool";
+ }
else occupiedPorts.push_back(i);
}
-
// after initialization readout serial numbers of automatically detected tools
for (unsigned int i = 0; i < occupiedPorts.size(); i++)
- {
+ {
ph = portHandle.substr(occupiedPorts.at(i), 2);
std::string portInfo;
NDIErrorCode returnvaluePort = m_DeviceProtocol->PHINF(ph, &portInfo);
- if ((returnvaluePort==NDIOKAY) && (portInfo.size()>31)) dynamic_cast(this->GetTool(i+numberOfToolsAtStart))->SetSerialNumber(portInfo.substr(23,8));
+ if ((returnvaluePort == NDIOKAY) && (portInfo.size()>31)) dynamic_cast(this->GetTool(i + numberOfToolsAtStart))->SetSerialNumber(portInfo.substr(23, 8));
itksys::SystemTools::Delay(10);
- }
+ }
return true;
}
-
mitk::NDIErrorCode mitk::NDITrackingDevice::FreePortHandles()
{
/* first search for port handles that need to be freed: e.g. because of a reset of the tracking system */
NDIErrorCode returnvalue = NDIOKAY;
std::string portHandle;
returnvalue = m_DeviceProtocol->PHSR(FREED, &portHandle);
if (returnvalue != NDIOKAY)
- {mitkThrowException(mitk::IGTHardwareException) << "Could not obtain a list of port handles that need to be freed";}
+ {
+ mitkThrowException(mitk::IGTHardwareException) << "Could not obtain a list of port handles that need to be freed";
+ }
/* if there are port handles that need to be freed, free them */
if (portHandle.empty() == true)
return returnvalue;
std::string ph;
for (unsigned int i = 0; i < portHandle.size(); i += 2)
{
ph = portHandle.substr(i, 2);
mitk::NDIPassiveTool* t = this->GetInternalTool(ph);
if (t != nullptr) // if we have a tool for the port handle that needs to be freed
{
if (this->RemoveTool(t) == false) // remove it (this will free the port too)
returnvalue = NDIERROR;
}
else // we don't have a tool, the port handle exists only in the tracking device
{
returnvalue = m_DeviceProtocol->PHF(&ph); // free it there
// What to do if port handle could not be freed? This seems to be a non critical error
if (returnvalue != NDIOKAY)
- {mitkThrowException(mitk::IGTHardwareException) << "Could not free all port handles";}
+ {
+ mitkThrowException(mitk::IGTHardwareException) << "Could not free all port handles";
+ }
}
}
return returnvalue;
}
-
int mitk::NDITrackingDevice::GetMajorFirmwareRevisionNumber()
{
std::string revision;
- if (m_DeviceProtocol->APIREV(&revision) != mitk::NDIOKAY || revision.empty() || (revision.size() != 9) )
+ if (m_DeviceProtocol->APIREV(&revision) != mitk::NDIOKAY || revision.empty() || (revision.size() != 9))
{
MITK_ERROR << "Could not receive firmware revision number!";
return 0;
}
- const std::string majrevno = revision.substr(2,3); //cut out "004" from "D.004.001"
+ const std::string majrevno = revision.substr(2, 3); //cut out "004" from "D.004.001"
return std::atoi(majrevno.c_str());
}
const char* mitk::NDITrackingDevice::GetFirmwareRevisionNumber()
{
static std::string revision;
- if (m_DeviceProtocol->APIREV(&revision) != mitk::NDIOKAY || revision.empty() || (revision.size() != 9) )
+ if (m_DeviceProtocol->APIREV(&revision) != mitk::NDIOKAY || revision.empty() || (revision.size() != 9))
{
MITK_ERROR << "Could not receive firmware revision number!";
revision = "";
return revision.c_str();
}
return revision.c_str();
}
bool mitk::NDITrackingDevice::AutoDetectToolsAvailable()
{
if (this->GetType() == mitk::NDIAuroraTypeInformation::GetTrackingDeviceName()) { return true; }
else { return false; }
}
+bool mitk::NDITrackingDevice::AddSingleToolIsAvailable()
+{
+ //For Aurora, only AutoDetecion or loading of toolStorage should be used. It is not possible to add a single tool.
+ if (this->GetType() == mitk::NDIAuroraTypeInformation::GetTrackingDeviceName()) { return false; }
+ //For Polaris, a single tool can be added, there is no autoDetection.
+ else { return true; }
+}
+
mitk::NavigationToolStorage::Pointer mitk::NDITrackingDevice::AutoDetectTools()
{
mitk::NavigationToolStorage::Pointer autoDetectedStorage = mitk::NavigationToolStorage::New();
if (this->GetType() == mitk::NDIAuroraTypeInformation::GetTrackingDeviceName())
{
try
{
this->OpenConnection();
this->StartTracking();
}
catch (mitk::Exception& e)
{
MITK_WARN << "Warning, can not auto-detect tools! (" << e.GetDescription() << ")";
return autoDetectedStorage;
}
for (unsigned int i = 0; i < this->GetToolCount(); i++)
{
//create a navigation tool with sphere as surface
std::stringstream toolname;
toolname << "AutoDetectedTool" << i;
mitk::NavigationTool::Pointer newTool = mitk::NavigationTool::New();
newTool->SetSerialNumber(dynamic_cast(this->GetTool(i))->GetSerialNumber());
newTool->SetIdentifier(toolname.str());
newTool->SetTrackingDeviceType(mitk::NDIAuroraTypeInformation::GetTrackingDeviceName());
- mitk::DataNode::Pointer newNode = mitk::DataNode::New();
- mitk::Surface::Pointer mySphere = mitk::Surface::New();
- vtkSphereSource *vtkData = vtkSphereSource::New();
- vtkData->SetRadius(3.0f);
- vtkData->SetCenter(0.0, 0.0, 0.0);
- vtkData->Update();
- mySphere->SetVtkPolyData(vtkData->GetOutput());
- vtkData->Delete();
- newNode->SetData(mySphere);
- newNode->SetName(toolname.str());
- newTool->SetDataNode(newNode);
+ newTool->GetDataNode()->SetName(toolname.str());
autoDetectedStorage->AddTool(newTool);
}
this->StopTracking();
this->CloseConnection();
}
return autoDetectedStorage;
}
bool mitk::NDITrackingDevice::GetSupportedVolumes(unsigned int* numberOfVolumes, mitk::NDITrackingDevice::NDITrackingVolumeContainerType* volumes, mitk::NDITrackingDevice::TrackingVolumeDimensionType* volumesDimensions)
{
if (numberOfVolumes == nullptr || volumes == nullptr || volumesDimensions == nullptr)
return false;
static std::string info;
if (m_DeviceProtocol->SFLIST(&info) != mitk::NDIOKAY || info.empty())
{
MITK_ERROR << "Could not receive tracking volume information of tracking system!";
return false;
}
/*info contains the following:
(+n times:)
*/
- (*numberOfVolumes) = (unsigned int) std::atoi(info.substr(0,1).c_str());
+ (*numberOfVolumes) = (unsigned int)std::atoi(info.substr(0, 1).c_str());
- for (unsigned int i=0; i<(*numberOfVolumes); i++)
+ for (unsigned int i = 0; i < (*numberOfVolumes); i++)
{
//e.g. for cube: "9-025000+025000-025000+025000-055000-005000+000000+000000+000000+00000011"
//for dome: "A+005000+048000+005000+066000+000000+000000+000000+000000+000000+00000011"
std::string::size_type offset, end;
- offset = (i*73)+1;
- end = 73+(i*73);
+ offset = (i * 73) + 1;
+ end = 73 + (i * 73);
std::string currentVolume = info.substr(offset, end);//i=0: from 1 to 73 characters; i=1: from 75 to 148 char;
// if i>0 then we have a return statement infront
- if (i>0)
+ if (i > 0)
currentVolume = currentVolume.substr(1, currentVolume.size());
if (currentVolume.compare(0, 1, NDIPolarisTypeInformation::GetDeviceDataPolarisOldModel().HardwareCode) == 0)
volumes->push_back(NDIPolarisTypeInformation::GetDeviceDataPolarisOldModel().Model);
if (currentVolume.compare(0, 3, NDIPolarisTypeInformation::GetDeviceDataPolarisSpectra().HardwareCode) == 0)
volumes->push_back(NDIPolarisTypeInformation::GetDeviceDataPolarisSpectra().Model);
if (currentVolume.compare(1, 3, NDIPolarisTypeInformation::GetDeviceDataSpectraExtendedPyramid().HardwareCode) == 0)
{
- currentVolume = currentVolume.substr(1,currentVolume.size());
+ currentVolume = currentVolume.substr(1, currentVolume.size());
volumes->push_back(NDIPolarisTypeInformation::GetDeviceDataSpectraExtendedPyramid().Model);
}
if (currentVolume.compare(0, 1, NDIPolarisTypeInformation::GetDeviceDataPolarisVicra().HardwareCode) == 0)
volumes->push_back(NDIPolarisTypeInformation::GetDeviceDataPolarisVicra().Model);
else if (currentVolume.compare(0, 1, mitk::NDIAuroraTypeInformation::GetDeviceDataAuroraPlanarCube().HardwareCode) == 0)
volumes->push_back(mitk::NDIAuroraTypeInformation::GetDeviceDataAuroraPlanarCube().Model);//alias cube
else if (currentVolume.compare(0, 1, mitk::NDIAuroraTypeInformation::GetDeviceDataAuroraPlanarDome().HardwareCode) == 0)
volumes->push_back(mitk::NDIAuroraTypeInformation::GetDeviceDataAuroraPlanarDome().Model);
//fill volumesDimensions
for (unsigned int index = 0; index < 10; index++)
{
std::string::size_type offD, endD;
- offD = 1+(index*7); //7 digits per dimension and the first is the type of volume
- endD = offD+7;
+ offD = 1 + (index * 7); //7 digits per dimension and the first is the type of volume
+ endD = offD + 7;
int dimension = std::atoi(currentVolume.substr(offD, endD).c_str());
dimension /= 100; //given in mm. 7 digits are xxxx.xx according to NDI //strange, the last two digits (11) also for the metal flag get read also...
volumesDimensions->push_back(dimension);
}
}
return true;
}
bool mitk::NDITrackingDevice::SetVolume(mitk::TrackingDeviceData volume)
{
if (m_DeviceProtocol->VSEL(volume) != mitk::NDIOKAY)
{
mitkThrowException(mitk::IGTHardwareException) << "Could not set volume!";
}
return true;
-}
-
+}
\ No newline at end of file
diff --git a/Modules/IGT/TrackingDevices/mitkNDITrackingDevice.h b/Modules/IGT/TrackingDevices/mitkNDITrackingDevice.h
index 9895aa12fe..e7dcfd2226 100644
--- a/Modules/IGT/TrackingDevices/mitkNDITrackingDevice.h
+++ b/Modules/IGT/TrackingDevices/mitkNDITrackingDevice.h
@@ -1,331 +1,334 @@
/*===================================================================
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 MITKNDITRACKINGDEVICE_H_HEADER_INCLUDED_C1C2FCD2
#define MITKNDITRACKINGDEVICE_H_HEADER_INCLUDED_C1C2FCD2
#include "mitkTrackingDevice.h"
#include
#include
#include "itkFastMutexLock.h"
#include
#include "mitkNDIProtocol.h"
#include "mitkNDIPassiveTool.h"
#include "mitkSerialCommunication.h"
namespace mitk
{
class NDIProtocol;
/** Documentation
* \brief superclass for specific NDI tracking Devices that use serial communication.
*
* implements the TrackingDevice interface for NDI tracking devices (POLARIS, AURORA)
*
* \ingroup IGT
*/
class MITKIGT_EXPORT NDITrackingDevice : public TrackingDevice
{
friend class NDIProtocol;
public:
typedef std::vector Tool6DContainerType; ///< List of 6D tools of the correct type for this tracking device
typedef mitk::TrackingDeviceType NDITrackingDeviceType; ///< This enumeration includes the two types of NDI tracking devices (Polaris, Aurora).
typedef mitk::SerialCommunication::PortNumber PortNumber; ///< Port number of the serial connection
typedef mitk::SerialCommunication::BaudRate BaudRate; ///< Baud rate of the serial connection
typedef mitk::SerialCommunication::DataBits DataBits; ///< Number of data bits used in the serial connection
typedef mitk::SerialCommunication::Parity Parity; ///< Parity mode used in the serial connection
typedef mitk::SerialCommunication::StopBits StopBits; ///< Number of stop bits used in the serial connection
typedef mitk::SerialCommunication::HardwareHandshake HardwareHandshake; ///< Hardware handshake mode of the serial connection
typedef mitk::NDIPassiveTool::TrackingPriority TrackingPriority; ///< Tracking priority used for tracking a tool
mitkClassMacro(NDITrackingDevice, TrackingDevice);
itkFactorylessNewMacro(Self)
itkCloneMacro(Self)
/**
* \brief Set the type of the NDI Tracking Device because it can not jet handle this itself
*/
//itkSetMacro(Type, TrackingDeviceType);
/**
* \brief initialize the connection to the tracking device
*
* OpenConnection() establishes the connection to the tracking device by:
* - initializing the serial port with the given parameters (port number, baud rate, ...)
* - connection to the tracking device
* - initializing the device
* - initializing all manually added passive tools (user supplied srom file)
* - initializing active tools that are connected to the tracking device
* @throw mitk::IGTHardwareException Throws an exception if there are errors while connecting to the device.
* @throw mitk::IGTException Throws a normal IGT exception if an error occures which is not related to the hardware.
*/
virtual bool OpenConnection() override;
/**
* \brief Closes the connection
*
* CloseConnection() resets the tracking device, invalidates all tools and then closes the serial port.
*/
virtual bool CloseConnection() override;
/** @throw mitk::IGTHardwareException Throws an exception if there are errors while connecting to the device. */
bool InitializeWiredTools();
/** Sets the rotation mode of this class. See documentation of enum RotationMode for details
* on the different modes.
*/
virtual void SetRotationMode(RotationMode r) override;
/**
* \brief TestConnection() tries to connect to a NDI tracking device on the current port/device and returns which device it has found
*
* TestConnection() tries to connect to a NDI tracking device on the current port/device.
* \return It returns the type of the device that answers at the port/device. Throws an exception if no device is available on that port.
* @throw mitk::IGTHardwareException Throws an exception if there are errors while connecting to the device.
*/
virtual mitk::TrackingDeviceType TestConnection();
/**
* \brief retrieves all wired tools from the tracking device
*
* This method queries the tracking device for all wired tools, initializes them and creates TrackingTool representation objects
* for them
* \return True if the method was executed successful.
* @throw mitk::IGTHardwareException Throws an exception if there are errors while connecting to the device.
* @throw mitk::IGTException Throws a normal IGT exception if an error occures which is not related to the hardware.
*/
bool DiscoverWiredTools();
/**
* \brief Start the tracking.
*
* A new thread is created, which continuously reads the position and orientation information of each tool and stores them inside the tools.
* Depending on the current operation mode (see SetOperationMode()), either the 6D tools (ToolTracking6D), 5D tools (ToolTracking5D),
* 3D marker positions (MarkerTracking3D) or both 6D tools and 3D markers (HybridTracking) are updated.
* Call StopTracking() to stop the tracking thread.
*/
virtual bool StartTracking() override;
/**
* \brief return the tool with index toolNumber
*/
virtual TrackingTool* GetTool(unsigned int toolNumber) const override;
virtual mitk::TrackingTool* GetToolByName(std::string name) const override;
/**
* \brief return current number of tools
*/
virtual unsigned int GetToolCount() const override;
/**
* \brief Create a passive 6D tool with toolName and fileName and add it to the list of tools
*
* This method will create a new NDIPassiveTool object, load the SROM file fileName,
* set the tool name toolName and the tracking priority p and then add
* it to the list of tools. It returns a pointer of type mitk::TrackingTool to the tool
* that can be used to read tracking data from it.
* This is the only way to add tools to NDITrackingDevice.
* @throw mitk::IGTHardwareException Throws an exception if there are errors while adding the tool.
*
* \warning adding tools is not possible in tracking mode, only in setup and ready.
*/
mitk::TrackingTool* AddTool(const char* toolName, const char* fileName, TrackingPriority p = NDIPassiveTool::Dynamic);
/**
* \brief Remove a passive 6D tool from the list of tracked tools.
*
* \warning removing tools is not possible in tracking mode, only in setup and ready modes.
*/
virtual bool RemoveTool(TrackingTool* tool);
/**
* \brief reloads the srom file and reinitializes the tool
*/
virtual bool UpdateTool(mitk::TrackingTool* tool);
virtual void SetPortNumber(const PortNumber _arg); ///< set port number for serial communication
itkGetConstMacro(PortNumber, PortNumber); ///< returns the port number for serial communication
virtual void SetDeviceName(std::string _arg); ///< set device name (e.g. COM1, /dev/ttyUSB0). If this is set, PortNumber will be ignored
itkGetStringMacro(DeviceName); ///< returns the device name for serial communication
virtual void SetBaudRate(const BaudRate _arg); ///< set baud rate for serial communication
itkGetConstMacro(BaudRate, BaudRate); ///< returns the baud rate for serial communication
virtual void SetDataBits(const DataBits _arg); ///< set number of data bits
itkGetConstMacro(DataBits, DataBits); ///< returns the data bits for serial communication
virtual void SetParity(const Parity _arg); ///< set parity mode
itkGetConstMacro(Parity, Parity); ///< returns the parity mode
virtual void SetStopBits(const StopBits _arg); ///< set number of stop bits
itkGetConstMacro(StopBits, StopBits); ///< returns the number of stop bits
virtual void SetHardwareHandshake(const HardwareHandshake _arg); ///< set use hardware handshake for serial communication
itkGetConstMacro(HardwareHandshake, HardwareHandshake); ///< returns the hardware handshake setting
virtual void SetIlluminationActivationRate(const IlluminationActivationRate _arg); ///< set activation rate of IR illumator for polaris
itkGetConstMacro(IlluminationActivationRate, IlluminationActivationRate); ///< returns the activation rate of IR illumator for polaris
virtual void SetDataTransferMode(const DataTransferMode _arg); ///< set data transfer mode to text (TX) or binary (BX). \warning: only TX is supportet at the moment
itkGetConstMacro(DataTransferMode, DataTransferMode); ///< returns the data transfer mode
virtual bool Beep(unsigned char count); ///< Beep the tracking device 1 to 9 times
NDIErrorCode GetErrorCode(const std::string* input); ///< returns the error code for a string that contains an error code in hexadecimal format
virtual bool SetOperationMode(OperationMode mode); ///< set operation mode to 6D tool tracking, 3D marker tracking or 6D&3D hybrid tracking (see OperationMode)
virtual OperationMode GetOperationMode(); ///< get current operation mode
/**
* \brief Get 3D marker positions (operation mode must be set to MarkerTracking3D or HybridTracking)
*/
virtual bool GetMarkerPositions(MarkerPointContainerType* markerpositions);
/**
* \brief Get major revision number from tracking device
* should not be called directly after starting to track
**/
virtual int GetMajorFirmwareRevisionNumber();
/**
* \brief Get revision number from tracking device as string
* should not be called directly after starting to track
**/
virtual const char* GetFirmwareRevisionNumber();
/** @return Returns true if this device can autodetects its tools. */
virtual bool AutoDetectToolsAvailable();
+ /** @return Returns true if it is possible to add a single tool. True for Polaris, false for Aurora.*/
+ virtual bool AddSingleToolIsAvailable();
+
/** Autodetects tools from this device and returns them as a navigation tool storage.
* @return Returns the detected tools. Returns an empty storage if no tools are present
* or if detection is not possible
*/
virtual mitk::NavigationToolStorage::Pointer AutoDetectTools();
protected:
typedef std::vector NDITrackingVolumeContainerType; ///< vector of tracking volumes
typedef std::vector TrackingVolumeDimensionType; ///< List of the supported tracking volume dimensions.
/**
* \brief Get number of supported tracking volumes, a vector containing the supported volumes and
* a vector containing the signed dimensions in mm. For each volume 10 boundaries are stored in the order of
* the supported volumes (see AURORA API GUIDE: SFLIST p.54).
**/
virtual bool GetSupportedVolumes(unsigned int* numberOfVolumes, NDITrackingVolumeContainerType* volumes, TrackingVolumeDimensionType* volumesDimensions);
/**
* \brief Sets the desired tracking volume. Returns true if the volume type could be set. It is set in the OpenConnection() Method and sets the tracking volume out of m_Data.
* @throw mitk::IGTHardwareException Throws an IGT hardware exception if the volume could not be set.
**/
virtual bool SetVolume(mitk::TrackingDeviceData volume);
/**
* \brief Add a passive 6D tool to the list of tracked tools. This method is used by AddTool
* @throw mitk::IGTHardwareException Throws an exception if there are errors while adding the tool.
* \warning adding tools is not possible in tracking mode, only in setup and ready.
*/
virtual bool InternalAddTool(NDIPassiveTool* tool);
/* Methods for NDIProtocol friend class */
virtual void InvalidateAll(); ///< invalidate all tools
NDIPassiveTool* GetInternalTool(std::string portHandle); ///< returns the tool object that has been assigned the port handle or nullptr if no tool can be found
/**
* \brief free all port handles that need to be freed
*
* This method retrieves a list of all port handles that need to be freed (e.g. tool got disconnected)
* and frees the handles at the tracking device and it removes the tools from the internal tool list
* \warning This method can remove TrackingTools from the tool list! After calling this method, GetTool(i) could return
* a different tool, because tool indices could have changed.
* @throw mitk::IGTHardwareException Throws an exception if there are errors while communicating with the device.
* \return returns NDIOKAY if everything was sucessfull, returns an error code otherwise
*/
NDIErrorCode FreePortHandles();
NDIErrorCode Send(const std::string* message, bool addCRC = true); ///< Send message to tracking device
NDIErrorCode Receive(std::string* answer, unsigned int numberOfBytes); ///< receive numberOfBytes bytes from tracking device
NDIErrorCode ReceiveByte(char* answer); ///< lightweight receive function, that reads just one byte
NDIErrorCode ReceiveLine(std::string* answer); ///< receive characters until the first LF (The LF is included in the answer string)
void ClearSendBuffer(); ///< empty send buffer of serial communication interface
void ClearReceiveBuffer(); ///< empty receive buffer of serial communication interface
const std::string CalcCRC(const std::string* input); ///< returns the CRC16 for input as a std::string
public:
/**
* \brief TrackTools() continuously polls serial interface for new 6d tool positions until StopTracking is called.
*
* Continuously tracks the 6D position of all tools until StopTracking() is called.
* This function is executed by the tracking thread (through StartTracking() and ThreadStartTracking()).
* It should not be called directly.
* @throw mitk::IGTHardwareException Throws an exception if there are errors while tracking the tools.
*/
virtual void TrackTools();
/**
* \brief continuously polls serial interface for new 3D marker positions until StopTracking is called.
*
* Continuously tracks the 3D position of all markers until StopTracking() is called.
* This function is executed by the tracking thread (through StartTracking() and ThreadStartTracking()).
* It should not be called directly.
*/
virtual void TrackMarkerPositions();
/**
* \brief continuously polls serial interface for new 3D marker positions and 6D tool positions until StopTracking is called.
*
* Continuously tracks the 3D position of all markers and the 6D position of all tools until StopTracking() is called.
* This function is executed by the tracking thread (through StartTracking() and ThreadStartTracking()).
* It should not be called directly.
*/
virtual void TrackToolsAndMarkers();
/**
* \brief static start method for the tracking thread.
*/
static ITK_THREAD_RETURN_TYPE ThreadStartTracking(void* data);
protected:
NDITrackingDevice(); ///< Constructor
virtual ~NDITrackingDevice(); ///< Destructor
std::string m_DeviceName;///< Device Name
PortNumber m_PortNumber; ///< COM Port Number
BaudRate m_BaudRate; ///< COM Port Baud Rate
DataBits m_DataBits; ///< Number of Data Bits per token
Parity m_Parity; ///< Parity mode for communication
StopBits m_StopBits; ///< number of stop bits per token
HardwareHandshake m_HardwareHandshake; ///< use hardware handshake for serial port connection
///< which tracking volume is currently used (if device supports multiple volumes) (\warning This parameter is not used yet)
IlluminationActivationRate m_IlluminationActivationRate; ///< update rate of IR illuminator for Polaris
DataTransferMode m_DataTransferMode; ///< use TX (text) or BX (binary) (\warning currently, only TX mode is supported)
Tool6DContainerType m_6DTools; ///< list of 6D tools
itk::FastMutexLock::Pointer m_ToolsMutex; ///< mutex for coordinated access of tool container
mitk::SerialCommunication::Pointer m_SerialCommunication; ///< serial communication interface
itk::FastMutexLock::Pointer m_SerialCommunicationMutex; ///< mutex for coordinated access of serial communication interface
NDIProtocol::Pointer m_DeviceProtocol; ///< create and parse NDI protocol strings
itk::MultiThreader::Pointer m_MultiThreader; ///< creates tracking thread that continuously polls serial interface for new tracking data
int m_ThreadID; ///< ID of tracking thread
OperationMode m_OperationMode; ///< tracking mode (6D tool tracking, 3D marker tracking,...)
itk::FastMutexLock::Pointer m_MarkerPointsMutex; ///< mutex for marker point data container
MarkerPointContainerType m_MarkerPoints; ///< container for markers (3D point tracking mode)
};
} // namespace mitk
#endif /* MITKNDITRACKINGDEVICE_H_HEADER_INCLUDED_C1C2FCD2 */
diff --git a/Modules/IGT/TrackingDevices/mitkNPOptitrackTrackingTypeInformation.cpp b/Modules/IGT/TrackingDevices/mitkNPOptitrackTrackingTypeInformation.cpp
index e16418f2ed..7b56482453 100644
--- a/Modules/IGT/TrackingDevices/mitkNPOptitrackTrackingTypeInformation.cpp
+++ b/Modules/IGT/TrackingDevices/mitkNPOptitrackTrackingTypeInformation.cpp
@@ -1,75 +1,75 @@
/*===================================================================
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 "mitkNPOptitrackTrackingTypeInformation.h"
#include "mitkOptitrackTrackingDevice.h"
namespace mitk
{
std::string NPOptitrackTrackingTypeInformation::GetTrackingDeviceName()
{
return "NP Optitrack";
}
TrackingDeviceData NPOptitrackTrackingTypeInformation::GetDeviceDataNPOptitrack()
{
TrackingDeviceData data = { NPOptitrackTrackingTypeInformation::GetTrackingDeviceName(), "Optitrack", "cube", "X" };
return data;
}
NPOptitrackTrackingTypeInformation::NPOptitrackTrackingTypeInformation()
{
m_DeviceName = NPOptitrackTrackingTypeInformation::GetTrackingDeviceName();
m_TrackingDeviceData.push_back(GetDeviceDataNPOptitrack());
}
NPOptitrackTrackingTypeInformation::~NPOptitrackTrackingTypeInformation()
{
}
TrackingDeviceSource::Pointer NPOptitrackTrackingTypeInformation::CreateTrackingDeviceSource(
TrackingDevice::Pointer trackingDevice,
NavigationToolStorage::Pointer navigationTools,
std::string* errorMessage,
std::vector* toolCorrespondencesInToolStorage)
{
mitk::TrackingDeviceSource::Pointer returnValue = mitk::TrackingDeviceSource::New();
mitk::OptitrackTrackingDevice::Pointer thisDevice = dynamic_cast(trackingDevice.GetPointer());
*toolCorrespondencesInToolStorage = std::vector();
//OpenConnection with Optitrack
thisDevice->OpenConnection();
//add the tools to the tracking device
- for (int i = 0; i < navigationTools->GetToolCount(); i++)
+ for (unsigned int i = 0; i < navigationTools->GetToolCount(); i++)
{
mitk::NavigationTool::Pointer thisNavigationTool = navigationTools->GetTool(i);
toolCorrespondencesInToolStorage->push_back(i);
bool toolAddSuccess = thisDevice->AddToolByDefinitionFile(thisNavigationTool->GetCalibrationFile());
thisDevice->GetOptitrackTool(i)->SetToolName(thisNavigationTool->GetToolName().c_str());
if (!toolAddSuccess)
{
//todo error handling
errorMessage->append("Can't add tool, is the toolfile valid?");
return nullptr;
}
//thisDevice->GetTool(i)->SetToolTip(thisNavigationTool->GetToolTipPosition(),thisNavigationTool->GetToolTipOrientation());
}
returnValue->SetTrackingDevice(thisDevice);
return returnValue;
}
}
diff --git a/Modules/IGT/TrackingDevices/mitkOpenIGTLinkTrackingDevice.cpp b/Modules/IGT/TrackingDevices/mitkOpenIGTLinkTrackingDevice.cpp
index 954ec5487f..0ea2bd84e4 100644
--- a/Modules/IGT/TrackingDevices/mitkOpenIGTLinkTrackingDevice.cpp
+++ b/Modules/IGT/TrackingDevices/mitkOpenIGTLinkTrackingDevice.cpp
@@ -1,524 +1,508 @@
/*===================================================================
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 "mitkOpenIGTLinkTrackingDevice.h"
#include "mitkOpenIGTLinkTrackingTool.h"
#include "mitkIGTConfig.h"
#include "mitkIGTTimeStamp.h"
#include "mitkIGTHardwareException.h"
#include "mitkTrackingTypes.h"
#include
#include
#include
#include
#include
#include
//sleep headers
#include
#include
typedef itk::MutexLockHolder MutexLockHolder;
mitk::OpenIGTLinkTrackingDevice::OpenIGTLinkTrackingDevice() : mitk::TrackingDevice(), m_UpdateRate(60)
{
//set the type of this tracking device
this->m_Data = mitk::OpenIGTLinkTypeInformation::GetDeviceDataOpenIGTLinkTrackingDeviceConnection();
m_OpenIGTLinkClient = mitk::IGTLClient::New(true);
m_OpenIGTLinkClient->SetName("OpenIGTLink Tracking Device");
m_OpenIGTLinkClient->EnableNoBufferingMode(false);
m_IGTLDeviceSource = mitk::IGTLTrackingDataDeviceSource::New();
m_IGTLDeviceSource->SetIGTLDevice(m_OpenIGTLinkClient);
}
mitk::OpenIGTLinkTrackingDevice::~OpenIGTLinkTrackingDevice()
{
}
int mitk::OpenIGTLinkTrackingDevice::GetPortNumber()
{
return m_OpenIGTLinkClient->GetPortNumber();
}
bool mitk::OpenIGTLinkTrackingDevice::AutoDetectToolsAvailable()
{
return true;
}
mitk::NavigationToolStorage::Pointer mitk::OpenIGTLinkTrackingDevice::AutoDetectTools()
{
mitk::NavigationToolStorage::Pointer returnValue = mitk::NavigationToolStorage::New();
if (m_OpenIGTLinkClient->GetPortNumber() == -1)
{
MITK_WARN << "Connection not initialized, aborting (invalid port number).";
return mitk::NavigationToolStorage::New();
}
//open connection
try
{
m_IGTLDeviceSource->Connect();
m_IGTLDeviceSource->StartCommunication();
}
catch (std::runtime_error &e)
{
MITK_WARN << "AutoDetection: Open IGT Link device retruned an error while trying to connect: " << e.what();
return mitk::NavigationToolStorage::New();
}
//get a message to find out type
m_IGTLDeviceSource->SettrackingDataType(mitk::IGTLTrackingDataDeviceSource::UNKNOWN);
mitk::IGTLMessage::Pointer receivedMessage = ReceiveMessage(100);
const char* msgType = receivedMessage->GetIGTLMessageType();
if (std::string(msgType).empty())
{
MITK_INFO << "Did not receive a message. Do you have to start the stream manually at the server?";
MITK_INFO << "Waiting for 10 seconds ...";
receivedMessage = ReceiveMessage(10000);
msgType = receivedMessage->GetIGTLMessageType();
}
MITK_INFO << "################# got message type: " << msgType;
mitk::OpenIGTLinkTrackingDevice::TrackingMessageType type = GetMessageTypeFromString(msgType);
switch (type)
{
case UNKNOWN:
m_IGTLDeviceSource->SettrackingDataType(mitk::IGTLTrackingDataDeviceSource::UNKNOWN);
break;
case TDATA:
m_IGTLDeviceSource->SettrackingDataType(mitk::IGTLTrackingDataDeviceSource::TDATA);
break;
case QTDATA:
m_IGTLDeviceSource->SettrackingDataType(mitk::IGTLTrackingDataDeviceSource::QTDATA);
break;
case TRANSFORM:
m_IGTLDeviceSource->SettrackingDataType(mitk::IGTLTrackingDataDeviceSource::TRANSFORM);
break;
}
returnValue = DiscoverToolsAndConvertToNavigationTools(type);
//close connection
try
{
m_IGTLDeviceSource->StopCommunication();
m_IGTLDeviceSource->Disconnect();
}
catch (std::runtime_error &e)
{
MITK_WARN << "AutoDetection: Open IGT Link device retruned an error while trying to disconnect: " << e.what();
return mitk::NavigationToolStorage::New();
}
return returnValue;
}
mitk::NavigationToolStorage::Pointer mitk::OpenIGTLinkTrackingDevice::DiscoverToolsAndConvertToNavigationTools(mitk::OpenIGTLinkTrackingDevice::TrackingMessageType type, int NumberOfMessagesToWait)
{
MITK_INFO << "Start discovering tools by " << type << " messages";
mitk::NavigationToolStorage::Pointer returnValue = mitk::NavigationToolStorage::New();
std::map toolNameMap;
for (int j = 0; jUpdate();
switch (type)
{
case TRANSFORM:
{
igtl::TransformMessage::Pointer msg = dynamic_cast(m_IGTLDeviceSource->GetOutput()->GetMessage().GetPointer());
if (msg == nullptr || msg.IsNull()) { MITK_INFO << "Received message is invalid / null. Skipping.."; continue; }
int count = toolNameMap[msg->GetDeviceName()];
if (count == 0) { toolNameMap[msg->GetDeviceName()] = 1; }
else { toolNameMap[msg->GetDeviceName()]++; }
}
break;
case TDATA:
{
igtl::TrackingDataMessage::Pointer msg = dynamic_cast(m_IGTLDeviceSource->GetOutput()->GetMessage().GetPointer());
if (msg == nullptr || msg.IsNull()) { MITK_INFO << "Received message is invalid / null. Skipping.."; continue; }
for (int k = 0; k < msg->GetNumberOfTrackingDataElements(); k++)
{
igtl::TrackingDataElement::Pointer tde;
msg->GetTrackingDataElement(k, tde);
if (tde.IsNotNull())
{
int count = toolNameMap[tde->GetName()];
if (count == 0) { toolNameMap[tde->GetName()] = 1; }
else { toolNameMap[tde->GetName()]++; }
}
}
}
break;
default:
MITK_WARN << "Only TRANSFORM and TDATA is currently supported, skipping!";
break;
}
}
int i = 0;
for (std::map::iterator it = toolNameMap.begin(); it != toolNameMap.end(); ++it)
{
MITK_INFO << "Found tool: " << it->first;
std::stringstream name;
name << it->first;
std::stringstream identifier;
identifier << "AutoDetectedTool-" << i;
i++;
mitk::NavigationTool::Pointer newTool = ConstructDefaultOpenIGTLinkTool(name.str(), identifier.str());
returnValue->AddTool(newTool);
}
return returnValue;
}
std::string mitk::OpenIGTLinkTrackingDevice::GetHostname()
{
return m_OpenIGTLinkClient->GetHostname();
}
void mitk::OpenIGTLinkTrackingDevice::SetPortNumber(int portNumber)
{
m_OpenIGTLinkClient->SetPortNumber(portNumber);
}
void mitk::OpenIGTLinkTrackingDevice::SetHostname(std::string hostname)
{
m_OpenIGTLinkClient->SetHostname(hostname);
}
bool mitk::OpenIGTLinkTrackingDevice::IsDeviceInstalled()
{
return true;
}
mitk::TrackingTool* mitk::OpenIGTLinkTrackingDevice::AddTool(const char*, const char*)
{
mitk::OpenIGTLinkTrackingTool::Pointer t;// = mitk::OpenIGTLinkTrackingTool::New();
//TODO: Implement
if (this->InternalAddTool(t) == false)
return nullptr;
return t.GetPointer();
}
bool mitk::OpenIGTLinkTrackingDevice::InternalAddTool(OpenIGTLinkTrackingTool::Pointer tool)
{
m_AllTools.push_back(tool);
return true;
}
bool mitk::OpenIGTLinkTrackingDevice::DiscoverTools(int waitingTime)
{
if (m_OpenIGTLinkClient->GetPortNumber() == -1)
{
MITK_WARN << "Connection not initialized, aborting (invalid port number).";
return false;
}
try
{
m_IGTLDeviceSource->Connect();
m_IGTLDeviceSource->StartCommunication();
}
catch (std::runtime_error &e)
{
MITK_WARN << "Open IGT Link device retruned an error while trying to connect: " << e.what();
return false;
}
mitk::IGTLMessage::Pointer receivedMessage = ReceiveMessage(waitingTime);
//check the tracking stream for the number and type of tools
//igtl::MessageBase::Pointer receivedMessage = m_OpenIGTLinkClient->GetNextMessage();
if (receivedMessage.IsNull())
{
MITK_WARN << "No message was received. Is there really a server?";
return false;
}
else if (!receivedMessage->IsDataValid())
{
MITK_WARN << "Received invalid message.";
return false;
}
const char* msgType = receivedMessage->GetIGTLMessageType();
mitk::OpenIGTLinkTrackingDevice::TrackingMessageType type = GetMessageTypeFromString(msgType);
mitk::NavigationToolStorage::Pointer foundTools = this->DiscoverToolsAndConvertToNavigationTools(type);
if (foundTools.IsNull() || (foundTools->GetToolCount() == 0)) { return false; }
- for (int i = 0; i < foundTools->GetToolCount(); i++) { AddNewToolForName(foundTools->GetTool(i)->GetToolName(), i); }
+ for (unsigned int i = 0; i < foundTools->GetToolCount(); i++) { AddNewToolForName(foundTools->GetTool(i)->GetToolName(), i); }
MITK_INFO << "Found tools: " << foundTools->GetToolCount();
return true;
}
mitk::IGTLMessage::Pointer mitk::OpenIGTLinkTrackingDevice::ReceiveMessage(int waitingTime)
{
mitk::IGTLMessage::Pointer receivedMessage;
//send a message to the server: start tracking stream
mitk::IGTLMessageFactory::Pointer msgFactory = m_OpenIGTLinkClient->GetMessageFactory();
std::string message[2] = {"STT_QTDATA","STT_TDATA"};
for (int i = 0; i < 2; i++)
{
igtl::MessageBase::Pointer sttMsg = msgFactory->CreateInstance(message[i]);
//TODO: Fix this to dynamically get this from GUI
((igtl::StartTrackingDataMessage*)sttMsg.GetPointer())->SetResolution(m_UpdateRate);
m_OpenIGTLinkClient->SendMessage(mitk::IGTLMessage::New(sttMsg));
}
std::chrono::high_resolution_clock::time_point time = std::chrono::high_resolution_clock::now();
std::chrono::milliseconds d = std::chrono::milliseconds(waitingTime);
while (!(receivedMessage.IsNotNull() && receivedMessage->IsDataValid()))
{
m_IGTLDeviceSource->Update();
receivedMessage = m_IGTLDeviceSource->GetOutput();
if ((time + d) < std::chrono::high_resolution_clock::now())
break;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
return receivedMessage;
}
void mitk::OpenIGTLinkTrackingDevice::AddNewToolForName(std::string name, int i)
{
mitk::OpenIGTLinkTrackingTool::Pointer newTool = mitk::OpenIGTLinkTrackingTool::New();
if (name == "") //if no name was given create a default name
{
std::stringstream defaultName;
defaultName << "OpenIGTLinkTool#" << i;
name = defaultName.str();
}
MITK_INFO << "Added tool " << name << " to tracking device.";
newTool->SetToolName(name);
InternalAddTool(newTool);
}
mitk::NavigationTool::Pointer mitk::OpenIGTLinkTrackingDevice::ConstructDefaultOpenIGTLinkTool(std::string name, std::string identifier)
{
- mitk::DataNode::Pointer newNode = mitk::DataNode::New();
-
- newNode->SetName(name);
-
- mitk::Surface::Pointer myCone = mitk::Surface::New();
- vtkConeSource *vtkData = vtkConeSource::New();
- vtkData->SetAngle(5.0);
- vtkData->SetResolution(50);
- vtkData->SetHeight(6.0f);
- vtkData->SetRadius(2.0f);
- vtkData->SetCenter(0.0, 0.0, 0.0);
- vtkData->Update();
- myCone->SetVtkPolyData(vtkData->GetOutput());
- vtkData->Delete();
- newNode->SetData(myCone);
-
mitk::NavigationTool::Pointer newTool = mitk::NavigationTool::New();
- newTool->SetDataNode(newNode);
+ newTool->GetDataNode()->SetName(name);
newTool->SetIdentifier(identifier);
newTool->SetTrackingDeviceType(mitk::OpenIGTLinkTypeInformation::GetDeviceDataOpenIGTLinkTrackingDeviceConnection().Line);
return newTool;
}
void mitk::OpenIGTLinkTrackingDevice::UpdateTools()
{
if (this->GetState() != Tracking)
{
MITK_ERROR << "Method was called in the wrong state, something went wrong!";
return;
}
m_IGTLMsgToNavDataFilter->Update();
for (std::size_t j = 0; j < m_IGTLMsgToNavDataFilter->GetNumberOfIndexedOutputs(); ++j)
{
mitk::NavigationData::Pointer currentNavData = m_IGTLMsgToNavDataFilter->GetOutput(j);
const char* name = currentNavData->GetName();
for (std::size_t i = 0; i < m_AllTools.size(); i++)
{
if (strcmp(m_AllTools.at(i)->GetToolName(), name) == 0)
{
m_AllTools.at(i)->SetDataValid(currentNavData->IsDataValid());
m_AllTools.at(i)->SetPosition(currentNavData->GetPosition());
m_AllTools.at(i)->SetOrientation(currentNavData->GetOrientation());
m_AllTools.at(i)->SetIGTTimeStamp(currentNavData->GetIGTTimeStamp());
}
}
}
}
bool mitk::OpenIGTLinkTrackingDevice::StartTracking()
{
//check tracking state
if (this->GetState() != Ready)
{
MITK_WARN << "Cannot start tracking, device is not ready!";
return false;
}
try
{
m_IGTLDeviceSource->StartCommunication();
//send a message to the server: start tracking stream
mitk::IGTLMessageFactory::Pointer msgFactory = m_OpenIGTLinkClient->GetMessageFactory();
std::string message = "STT_TDATA";
//m_OpenIGTLinkClient->SendMessage(msgFactory->CreateInstance(message));
}
catch (std::runtime_error &e)
{
MITK_WARN << "Open IGT Link device retruned an error while starting communication: " << e.what();
return false;
}
//create internal igtl pipeline
m_IGTLMsgToNavDataFilter = mitk::IGTLMessageToNavigationDataFilter::New();
m_IGTLMsgToNavDataFilter->SetNumberOfExpectedOutputs(this->GetToolCount());
m_IGTLMsgToNavDataFilter->ConnectTo(m_IGTLDeviceSource);
//connect itk events
typedef itk::SimpleMemberCommand< mitk::OpenIGTLinkTrackingDevice > CurCommandType;
CurCommandType::Pointer messageReceivedCommand = CurCommandType::New();
messageReceivedCommand->SetCallbackFunction(this, &mitk::OpenIGTLinkTrackingDevice::UpdateTools);
m_MessageReceivedObserverTag = m_OpenIGTLinkClient->AddObserver(mitk::MessageReceivedEvent(), messageReceivedCommand);
m_OpenIGTLinkClient->EnableNoBufferingMode(true);
this->SetState(Tracking);
return true;
}
bool mitk::OpenIGTLinkTrackingDevice::StopTracking()
{
//check tracking state
if (this->GetState() != Tracking)
{
MITK_WARN << "Cannot open connection, device is already connected!";
return false;
}
m_OpenIGTLinkClient->RemoveObserver(m_MessageReceivedObserverTag); //disconnect itk events
try
{
m_IGTLDeviceSource->StopCommunication();
}
catch (std::runtime_error &e)
{
MITK_WARN << "Open IGT Link device retruned an error while stopping communication: " << e.what();
return false;
}
m_OpenIGTLinkClient->EnableNoBufferingMode(false);
this->SetState(Ready);
return true;
}
unsigned int mitk::OpenIGTLinkTrackingDevice::GetToolCount() const
{
return (unsigned int)this->m_AllTools.size();
}
mitk::TrackingTool* mitk::OpenIGTLinkTrackingDevice::GetTool(unsigned int toolNumber) const
{
if (toolNumber >= this->GetToolCount())
return nullptr;
else
return this->m_AllTools[toolNumber];
}
bool mitk::OpenIGTLinkTrackingDevice::OpenConnection()
{
//check tracking state
if (this->GetState() != Setup)
{
MITK_WARN << "Cannot open connection, device is already connected!";
return false;
}
try
{
m_IGTLDeviceSource->Connect();
}
catch (std::runtime_error &e)
{
MITK_WARN << "Open IGT Link device retruned an error while trying to connect: " << e.what();
return false;
}
this->SetState(Ready);
return true;
}
bool mitk::OpenIGTLinkTrackingDevice::CloseConnection()
{
//check tracking state
if (this->GetState() != Ready)
{
MITK_WARN << "Cannot close connection, device is in the wrong state!";
return false;
}
try
{
m_IGTLDeviceSource->Disconnect();
}
catch (std::runtime_error &e)
{
MITK_WARN << "Open IGT Link device retruned an error while trying to disconnect: " << e.what();
return false;
}
this->SetState(Setup);
return true;
}
std::vector mitk::OpenIGTLinkTrackingDevice::GetAllTools()
{
return this->m_AllTools;
}
mitk::OpenIGTLinkTrackingDevice::TrackingMessageType mitk::OpenIGTLinkTrackingDevice::GetMessageTypeFromString(const char* messageTypeString)
{
if (strcmp(messageTypeString, "TDATA") == 0)
{
return mitk::OpenIGTLinkTrackingDevice::TrackingMessageType::TDATA;
}
else if (strcmp(messageTypeString, "QTDATA") == 0)
{
return mitk::OpenIGTLinkTrackingDevice::TrackingMessageType::QTDATA;
}
else if (strcmp(messageTypeString, "TRANSFORM") == 0)
{
return mitk::OpenIGTLinkTrackingDevice::TrackingMessageType::TRANSFORM;
}
else
{
return mitk::OpenIGTLinkTrackingDevice::TrackingMessageType::UNKNOWN;
}
}
diff --git a/Modules/IGT/TrackingDevices/mitkOpenIGTLinkTypeInformation.cpp b/Modules/IGT/TrackingDevices/mitkOpenIGTLinkTypeInformation.cpp
index 428e1e043c..aacdeea343 100644
--- a/Modules/IGT/TrackingDevices/mitkOpenIGTLinkTypeInformation.cpp
+++ b/Modules/IGT/TrackingDevices/mitkOpenIGTLinkTypeInformation.cpp
@@ -1,60 +1,60 @@
/*===================================================================
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 "mitkOpenIGTLinkTypeInformation.h"
#include "mitkOpenIGTLinkTrackingDevice.h"
namespace mitk
{
std::string OpenIGTLinkTypeInformation::GetTrackingDeviceName()
{
return "Open IGT Link Connection";
}
TrackingDeviceData OpenIGTLinkTypeInformation::GetDeviceDataOpenIGTLinkTrackingDeviceConnection(){
TrackingDeviceData data = { OpenIGTLinkTypeInformation::GetTrackingDeviceName(), "OpenIGTLink Tracking Device", "cube", "X" };
return data;
}
OpenIGTLinkTypeInformation::OpenIGTLinkTypeInformation()
{
m_DeviceName = OpenIGTLinkTypeInformation::GetTrackingDeviceName();
m_TrackingDeviceData.push_back(GetDeviceDataOpenIGTLinkTrackingDeviceConnection());
}
OpenIGTLinkTypeInformation::~OpenIGTLinkTypeInformation()
{
}
mitk::TrackingDeviceSource::Pointer OpenIGTLinkTypeInformation::CreateTrackingDeviceSource(
mitk::TrackingDevice::Pointer trackingDevice,
mitk::NavigationToolStorage::Pointer navigationTools,
std::string* errorMessage,
std::vector* /*toolCorrespondencesInToolStorage*/)
{
mitk::TrackingDeviceSource::Pointer returnValue = mitk::TrackingDeviceSource::New();
mitk::OpenIGTLinkTrackingDevice::Pointer thisDevice = dynamic_cast(trackingDevice.GetPointer());
thisDevice->DiscoverTools();
- if (static_cast(thisDevice->GetToolCount()) != navigationTools->GetToolCount())
+ if (thisDevice->GetToolCount() != navigationTools->GetToolCount())
{
errorMessage->append("The number of tools in the connected device differs from the tool storage, cannot add tools.");
return nullptr;
}
returnValue->SetTrackingDevice(thisDevice);
return returnValue;
}
}
diff --git a/Modules/IGT/TrackingDevices/mitkPolhemusInterface.cpp b/Modules/IGT/TrackingDevices/mitkPolhemusInterface.cpp
index 7e4af215c8..b7b8f0cf85 100644
--- a/Modules/IGT/TrackingDevices/mitkPolhemusInterface.cpp
+++ b/Modules/IGT/TrackingDevices/mitkPolhemusInterface.cpp
@@ -1,207 +1,469 @@
/*===================================================================
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
#define _USE_MATH_DEFINES
#include
#include
BYTE MotionBuf[0x1FA400];
mitk::PolhemusInterface::PolhemusInterface() : m_continousTracking(false)
{
- m_pdiDev = new CPDIdev();
-
+ m_pdiDev = new CPDIdev();
+ m_numberOfTools = 0;
}
mitk::PolhemusInterface::~PolhemusInterface()
{
- delete m_pdiDev;
+ delete m_pdiDev;
}
bool mitk::PolhemusInterface::InitializeDevice()
{
m_pdiDev->ResetTracker();
m_pdiDev->ResetSAlignment(-1);
m_pdiDev->Trace(TRUE, 7);
m_continousTracking = false;
return true;
}
bool mitk::PolhemusInterface::SetupDevice()
{
m_pdiDev->SetPnoBuffer(MotionBuf, 0x1FA400);
m_pdiDev->SetMetric(true); //use cm instead of inches
m_pdiDev->StartPipeExport();
CPDImdat pdiMDat;
pdiMDat.Empty();
pdiMDat.Append(PDI_MODATA_FRAMECOUNT);
pdiMDat.Append(PDI_MODATA_POS);
pdiMDat.Append(PDI_MODATA_ORI);
m_pdiDev->SetSDataList(-1, pdiMDat);
CPDIbiterr cBE;
m_pdiDev->GetBITErrs(cBE);
- if (!(cBE.IsClear())) {m_pdiDev->ClearBITErrs();}
-
- if (this->m_HemisphereTrackingEnabled) { m_pdiDev->SetSHemiTrack(-1); }
- else { m_pdiDev->SetSHemisphere(-1, { (float)2.54,0,0 }); }
+ if (!(cBE.IsClear())) { m_pdiDev->ClearBITErrs(); }
return true;
}
bool mitk::PolhemusInterface::StartTracking()
{
- LPCTSTR szWindowClass = _T("PDIconsoleWinClass");
- HINSTANCE hInst = GetModuleHandle(0);
- HWND hwnd = CreateWindowEx(
- WS_EX_NOACTIVATE,//WS_EX_STATICEDGE, //
- szWindowClass,
- _T("MyWindowName"),
- WS_POPUP,
- 0, 0, 1, 1,
- HWND_MESSAGE,
- 0,
- hInst,
- 0);
-
m_continousTracking = true;
- return m_pdiDev->StartContPno(hwnd);
+ return m_pdiDev->StartContPno(0);
}
bool mitk::PolhemusInterface::StopTracking()
{
m_continousTracking = false;
+ m_pdiDev->StopContPno();
return true;
}
+bool mitk::PolhemusInterface::OpenConnection()
+{
+ bool returnValue;
+ //Initialize, and if it is not successful, return false.
+ if (!InitializeDevice())
+ {
+ returnValue = false;
+ }
+ //Connect
+ else if (m_pdiDev->CnxReady())
+ {
+ returnValue = true;
+ }
+ //If it is not successful, search for connections.
+ else
+ {
+ CPDIser pdiSer;
+ m_pdiDev->SetSerialIF(&pdiSer);
+
+ ePiCommType eType = m_pdiDev->DiscoverCnx();
+ switch (eType)
+ {
+ case PI_CNX_USB:
+ MITK_INFO << "USB Connection: " << m_pdiDev->GetLastResultStr();
+ break;
+ case PI_CNX_SERIAL:
+ MITK_INFO << "Serial Connection: " << m_pdiDev->GetLastResultStr();
+ break;
+ default:
+ MITK_INFO << "DiscoverCnx result: " << m_pdiDev->GetLastResultStr();
+ break;
+ }
+
+ //Setup device
+ if (!SetupDevice())
+ {
+ returnValue = false;
+ }
+ else
+ {
+ returnValue = m_pdiDev->CnxReady();
+ }
+ }
+ return returnValue;
+}
+
bool mitk::PolhemusInterface::Connect()
{
- if (!InitializeDevice()) { return false; }
+ bool returnValue = OpenConnection();
- if (m_pdiDev->CnxReady()) { return true; }
- CPDIser pdiSer;
- m_pdiDev->SetSerialIF(&pdiSer);
+ if (!returnValue)
+ {
+ return returnValue;
+ }
+
+ m_numberOfTools = this->GetNumberOfTools();
+
+ //Get the tracking data to find out which tools are available.
+ std::vector _trackingData = GetFrame();
+
+ //if we have more/less tools than before, reset all data.
+ //check with toolStorage changes is nto enough, 'cause a sensor could just have been unplugged.
+ if (m_ToolPorts.size() != _trackingData.size())
+ {
+ m_ToolPorts.clear();
+ m_Hemispheres.clear();
+ m_HemisphereTracking.clear();
+ }
- ePiCommType eType = m_pdiDev->DiscoverCnx();
- switch (eType)
+ //if we have the same number of tools as before, check if they are still the same.
+ if (m_ToolPorts.size() == _trackingData.size())
{
- case PI_CNX_USB:
- MITK_INFO << "USB Connection: " << m_pdiDev->GetLastResultStr();
- break;
- case PI_CNX_SERIAL:
- MITK_INFO << "Serial Connection: " << m_pdiDev->GetLastResultStr();
- break;
- default:
- MITK_INFO << "DiscoverCnx result: " << m_pdiDev->GetLastResultStr();
- break;
+ for (int i = 0; i < _trackingData.size(); ++i)
+ {
+ //if they are not the same, clear hemispheres and toolNames and break.
+ if (m_ToolPorts[i] != _trackingData.at(i).id)
+ {
+ m_ToolPorts.clear();
+ m_Hemispheres.clear();
+ m_HemisphereTracking.clear();
+ break;
+ }
+ }
}
- if (!SetupDevice()) { return false; }
+ //if we don't have old tool names or if the old ones don't match any more, assign them again.
+ if (m_ToolPorts.size() == 0)
+ {
+ for (int i = 0; i < _trackingData.size(); ++i)
+ {
+ m_ToolPorts.push_back(_trackingData.at(i).id);
+ }
+ //and reset the hemisphere parameters
+ m_Hemispheres.clear();
+ m_HemisphereTracking.clear();
+ mitk::Vector3D temp;
+ mitk::FillVector3D(temp, 1, 0, 0);
+ m_Hemispheres.assign(m_numberOfTools, temp);
+ m_HemisphereTracking.assign(m_numberOfTools, false);
+ }
- return m_pdiDev->CnxReady();
+ return returnValue;
}
bool mitk::PolhemusInterface::Disconnect()
{
+ bool returnValue = true;
+ //If Tracking is running, stop tracking first
if (m_continousTracking)
{
- m_continousTracking = false;
- if (!m_pdiDev->Disconnect()) return false;
+ this->StopTracking();
}
- return true;
+
+ returnValue = m_pdiDev->Disconnect();
+ MITK_INFO << "Disconnect: " << m_pdiDev->GetLastResultStr();
+ return returnValue;
+}
+
+std::vector mitk::PolhemusInterface::AutoDetectTools()
+{
+ OpenConnection();
+ std::vector frame = GetSingleFrame();
+ m_pdiDev->Disconnect();
+ return frame;
+}
+
+unsigned int mitk::PolhemusInterface::GetNumberOfTools()
+{
+ std::vector _trackingData = GetFrame();
+ return _trackingData.size();
+}
+
+std::vector mitk::PolhemusInterface::GetFrame()
+{
+ if (m_continousTracking)
+ return this->GetLastFrame();
+ else
+ return this->GetSingleFrame();
}
std::vector mitk::PolhemusInterface::GetLastFrame()
{
PBYTE pBuf;
DWORD dwSize;
//read one frame
- if (!m_pdiDev->LastPnoPtr(pBuf, dwSize)) {MITK_WARN << m_pdiDev->GetLastResultStr();}
+ if (!m_pdiDev->LastPnoPtr(pBuf, dwSize)) { MITK_WARN << m_pdiDev->GetLastResultStr(); }
std::vector returnValue = ParsePolhemusRawData(pBuf, dwSize);
- if (returnValue.empty()) { MITK_WARN << "Cannot parse data / no tools present"; }
+ if (returnValue.empty())
+ {
+ MITK_WARN << "Cannot parse data / no tools present";
+ }
return returnValue;
}
-unsigned int mitk::PolhemusInterface::GetNumberOfTools()
-{
- if (m_continousTracking) return GetLastFrame().size();
- else return GetSingleFrame().size();
-}
-
std::vector mitk::PolhemusInterface::GetSingleFrame()
{
if (m_continousTracking)
{
- MITK_WARN << "Cannot get tool count when continously tracking";
+ MITK_WARN << "Cannot get a single frame when continuous tracking is on!";
return std::vector();
}
PBYTE pBuf;
DWORD dwSize;
//read one frame
if (!m_pdiDev->ReadSinglePnoBuf(pBuf, dwSize)) {
MITK_WARN << m_pdiDev->GetLastResultStr();
return std::vector();
}
return ParsePolhemusRawData(pBuf, dwSize);
}
std::vector mitk::PolhemusInterface::ParsePolhemusRawData(PBYTE pBuf, DWORD dwSize)
{
std::vector returnValue;
DWORD i = 0;
- while (i eulerQuat(rollAngle, elevationAngle, azimuthAngle);
currentTrackingData.rot = eulerQuat;
returnValue.push_back(currentTrackingData);
i += shSize;
}
return returnValue;
}
+
+void mitk::PolhemusInterface::SetHemisphereTrackingEnabled(bool _HeisphereTrackingEnabeled, int _tool)
+{
+ //only if connection is ready!
+ if (!this->m_pdiDev->CnxReady())
+ return;
+
+ if (m_Hemispheres.empty())
+ {
+ MITK_ERROR << "No Hemispheres. This should never happen when connected. Check your code!";
+ }
+
+ //HemisphereTracking is switched on by SetSHemiTrack(-1). "-1" means for all sensors.
+ //To switch heisphere tracking of, you need to set a hemisphere vector e.g. by calling SetSHemisphere(-1, { (float)1,0,0 })
+ if (_HeisphereTrackingEnabeled)
+ {
+ m_pdiDev->SetSHemiTrack(_tool);
+ if (_tool != -1)
+ {
+ m_HemisphereTracking.at(GetToolIndex(_tool)) = true;
+ }
+ else
+ {
+ m_HemisphereTracking.assign(m_numberOfTools, true);
+ }
+ }
+
+ //switch HemiTracking OFF
+ else
+ {
+ //Get Tool Position. ToDo, this should not be the tool tip but the sensor position. Any chance, to get that from Polhemus interface?!
+ std::vector _position = GetFrame();
+
+ for (int index : GetToolIterator(_tool))
+ {
+ //Scalar product between mitk::point and mitk::vector
+ double _scalarProduct = _position.at(index).pos.GetVectorFromOrigin() * m_Hemispheres.at(index);
+ //if scalar product is negative, then the tool is in the opposite sphere then when we started to track.
+ //Hence, we have to set the inverted hemisphere.
+ //For default (1|0|0) this means, if x is negative, we have to set (-1|0|0). But we want to keep it generic if user sets different hemisphere...
+ if (_scalarProduct < 0)
+ {
+ m_Hemispheres.at(index) = -1. * m_Hemispheres.at(index);
+ }
+ else if (_scalarProduct == 0)
+ MITK_ERROR << "Something went wrong. Hemisphere or Position should not be zero.";
+
+ SetHemisphere(m_ToolPorts[index], m_Hemispheres.at(index));
+ }
+ }
+}
+
+void mitk::PolhemusInterface::ToggleHemisphere(int _tool)
+{
+ //only if connection is ready!
+ if (!this->m_pdiDev->CnxReady())
+ return;
+
+ //toggle.
+ for (int index : GetToolIterator(_tool))
+ {
+ if (m_HemisphereTracking.at(index))
+ {
+ SetHemisphereTrackingEnabled(false, m_ToolPorts[index]);
+ this->SetHemisphere(m_ToolPorts[index], -1.*m_Hemispheres.at(index));
+ SetHemisphereTrackingEnabled(true, m_ToolPorts[index]);
+ }
+ else
+ {
+ this->SetHemisphere(m_ToolPorts[index], -1.*m_Hemispheres.at(index));
+ }
+ }
+}
+
+void mitk::PolhemusInterface::AdjustHemisphere(int _tool)
+{
+ //only if connection is ready!
+ if (!this->m_pdiDev->CnxReady())
+ return;
+
+ mitk::Vector3D _hemisphere;
+ mitk::FillVector3D(_hemisphere, 1, 0, 0);
+
+ for (int index : GetToolIterator(_tool))
+ {
+ if (m_HemisphereTracking.at(index))
+ {
+ SetHemisphereTrackingEnabled(false, m_ToolPorts[index]);
+ this->SetHemisphere(m_ToolPorts[index], _hemisphere);
+ SetHemisphereTrackingEnabled(true, m_ToolPorts[index]);
+ }
+ else
+ {
+ this->SetHemisphere(m_ToolPorts[index], _hemisphere);
+ }
+ }
+}
+
+void mitk::PolhemusInterface::SetHemisphere(int _tool, mitk::Vector3D _hemisphere)
+{
+ //only if connection is ready!
+ if (!this->m_pdiDev->CnxReady())
+ return;
+
+ m_pdiDev->SetSHemisphere(_tool, { (float)_hemisphere[0], (float)_hemisphere[1], (float)_hemisphere[2] });
+
+ for (int index : GetToolIterator(_tool))
+ {
+ if (_hemisphere.GetNorm() != 0)
+ {
+ m_HemisphereTracking.at(index) = false;
+ m_Hemispheres.at(index) = _hemisphere;
+ }
+ else
+ {
+ m_HemisphereTracking.at(index) = true;
+ //don't set the Hemisphere to (0|0|0), as we want to remember the old one.
+ }
+ }
+}
+
+mitk::Vector3D mitk::PolhemusInterface::GetHemisphere(int _tool)
+{
+ if (_tool == -1)
+ {
+ MITK_WARN << "Can't return hemisphere for all tools. Returning Hemisphere of first tool " << m_ToolPorts[0];
+ return m_Hemispheres.at(0);
+ }
+ return m_Hemispheres.at(GetToolIndex(_tool));
+}
+
+bool mitk::PolhemusInterface::GetHemisphereTrackingEnabled(int _tool)
+{
+ //if tool is -1, this means "All Tools". We return true if HemiTracking is enabled for all tools, and false if it is off for at least one tool.
+ if (_tool == -1)
+ {
+ bool _returnValue = true;
+ for (bool currentValue : m_HemisphereTracking)
+ _returnValue = _returnValue && currentValue;
+ return _returnValue;
+ }
+ else
+ return m_HemisphereTracking.at(GetToolIndex(_tool));
+}
+
+std::vector mitk::PolhemusInterface::GetToolPorts()
+{
+ return m_ToolPorts;
+}
+
+int mitk::PolhemusInterface::GetToolIndex(int _tool)
+{
+ if (_tool == -1)
+ return -1;
+ else
+ return std::find(m_ToolPorts.begin(), m_ToolPorts.end(), _tool) - m_ToolPorts.begin();
+}
+
+std::vector mitk::PolhemusInterface::GetToolIterator(int _tool)
+{
+ std::vector _iterator;
+ if (_tool == -1)
+ {
+ for (int i = 0; i < static_cast(m_numberOfTools); ++i)
+ _iterator.push_back(i);
+ }
+ else
+ {
+ _iterator.push_back(GetToolIndex(_tool));
+ }
+ return _iterator;
+}
+
+void mitk::PolhemusInterface::PrintStatus()
+{
+ MITK_INFO << "Polhemus status: " << this->m_pdiDev->CnxReady();
+}
\ No newline at end of file
diff --git a/Modules/IGT/TrackingDevices/mitkPolhemusInterface.h b/Modules/IGT/TrackingDevices/mitkPolhemusInterface.h
index 28eea88760..4123d66038 100644
--- a/Modules/IGT/TrackingDevices/mitkPolhemusInterface.h
+++ b/Modules/IGT/TrackingDevices/mitkPolhemusInterface.h
@@ -1,117 +1,174 @@
/*===================================================================
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 MITKPolhemusINTERFACE_H_HEADER_INCLUDED_
#define MITKPolhemusINTERFACE_H_HEADER_INCLUDED_
-
#include
#include
#include
#include "mitkCommon.h"
#include
#include
#include
#include
#include
#include
class CPDIdev;
namespace mitk
{
-
/** Documentation:
* \brief An object of this class represents the interface to Polhemus trackers.
+ * All variables with the name "tool" start with index 1, which is the station number of Polhemus.
+ * Make sure to call functions in this class with parameter "1" if you want to loop over all tools.
+ * If you need to access an array (e.g. m_Hemisphere), you need to use "_tool -1" and adapt your index for loops...
* \ingroup IGT
*/
class MITKIGT_EXPORT PolhemusInterface : public itk::Object
{
public:
- mitkClassMacroItkParent(PolhemusInterface,itk::Object);
+ mitkClassMacroItkParent(PolhemusInterface, itk::Object);
itkFactorylessNewMacro(Self);
itkCloneMacro(Self);
struct trackingData
{
mitk::Point3D pos;
mitk::Quaternion rot;
BYTE id;
};
/**
* \brief Opens the connection to the device and makes it ready to track tools.
* \return Returns true if there is a connection to the device and the device is ready to track tools, false if not.
*/
bool StartTracking();
/**
* \brief Clears all resources. After this method have been called the system isn't ready to track any longer.
* \return Returns true if the operation was succesful, false if not.
*/
bool StopTracking();
bool Connect();
bool Disconnect();
+ /** @return Returns the number of tools. Returns 0 if no information is avialable.*/
+ unsigned int GetNumberOfTools();
+
+ /** Enables/disables hemisphere tracking for all stations/tools. */
+ void SetHemisphereTrackingEnabled(bool _HeisphereTrackingEnabeled, int _tool = -1);
+
+ /** Toggles the current hemisphere. Parameter _tool describes, for which tool the hemisphere should change. Default -1 toggles all tools.
+ Index starts at "1" for the first tool (i.e. station number of Polhemus). Not 0!
+ */
+ void ToggleHemisphere(int _tool = -1);
+
+ /** Convenient method to print the status of the tracking device (true/false) if connection is established. For debugging...*/
+ void PrintStatus();
+
+ /** Sets the Hemisphere of tool _tool to the vector _hemisphere. "-1" sets all tools.
+ Index starts at "1" for the first tool (i.e. station number of Polhemus). Not 0!
+ */
+ void SetHemisphere(int _tool, mitk::Vector3D _hemisphere);
+
+ /** Get the Hemisphere for _tool as mitk vector. -1 ("all tools") returns hemisphere of first tool.
+ Index starts at "1" for the first tool (i.e. station number of Polhemus). Not 0!
+ */
+ mitk::Vector3D GetHemisphere(int _tool);
+
+ /** Get the ports on which tools are connected. Returns empty vector if device is not connected!
+ */
+ std::vector GetToolPorts();
+
+ /** Is Hemisphere Tracking Enabled for this tool?
+ * if tool is -1, this means "All Tools". We return true if HemiTracking is enabled for all tools, and false if it is off for at least one tool.*/
+ bool GetHemisphereTrackingEnabled(int _tool);
+
+ /** Adjust the Hemisphere for this tool. User needs to make sure, that the tool is located in hemisphere (1|0|0) when calling this function.
+ In contrast to SetHemisphere(1,0,0), this method restores the original HemisphereTracking settings at the end. */
+ void AdjustHemisphere(int _tool);
+
/** @return Returns a single frame. Only works if the tracking device is not in continous tracking mode. Returns an empty vector in case of an error.*/
std::vector GetSingleFrame();
+ /** @return Returns a single frame with all tools, which could be auto detected.*/
+ std::vector AutoDetectTools();
+
/** @return Returns the last frame when the tracking device is in continous tracking mode. Returns an empty vector in case of an error.*/
std::vector GetLastFrame();
- /** @return Returns the number of tools. Returns 0 if no information is avialable.*/
- unsigned int GetNumberOfTools();
-
- /** Enables/disables hemisphere tracking for all sensors. */
- itkSetMacro(HemisphereTrackingEnabled, bool);
-
protected:
/**
* \brief standard constructor
*/
PolhemusInterface();
/**
* \brief standard destructor
*/
~PolhemusInterface();
- /** Polhemus liberty/patriot tracker object*/
+ /** Polhemus liberty/patriot tracker object*/
CPDIdev* m_pdiDev;
-
- /** Parses polhemus raw data to a collection of tracking data of single tools. */
- std::vector ParsePolhemusRawData(PBYTE pBuf, DWORD dwSize);
-
- unsigned int m_numberOfTools;
- bool m_continousTracking;
+ /** Parses polhemus raw data to a collection of tracking data of single tools. */
+ std::vector ParsePolhemusRawData(PBYTE pBuf, DWORD dwSize);
bool InitializeDevice();
bool SetupDevice();
- bool m_HemisphereTrackingEnabled;
+ //returns the index in the arrays of tool _tool. Eg. sensor 3 (_tool = 3) is the second tool --> index 1 in m_Hemispheres etc.
+ int GetToolIndex(int _tool);
+
+ /** @brief Convenient method to get a frame from the tracking device.
+ * @return Returns a single OR the last frame depending on m_continuousTracking.
+ * @warning Don't use this function if you use different threads. You need to make sure, that you are still in the right mode! */
+ std::vector GetFrame();
+ private:
+ //returns vector with tool index as only element if tool != -1, else returns vector from 0 to numberOfTools
+ std::vector GetToolIterator(int _tool);
+ //helper method to open connection
+ bool OpenConnection();
+
+
+ private:
+ //Stores the hemispheres for all sensors. Default is (1|0|0).
+ std::vector m_Hemispheres;
+
+ //Stores, if hemisphereTracking is on for this Sensor.
+ std::vector m_HemisphereTracking;
+
+ //This vector stores the order of tools, which are available.
+ //E.g. only Sensor 1 and 3 are attached, then this vector maps the first tool (0) to Polhemus identifier 1 and the second tool (1) to Polhemus 3.
+ std::vector m_ToolPorts;
+
+ unsigned int m_numberOfTools;
+
+ bool m_continousTracking;
};
}//mitk
#endif
diff --git a/Modules/IGT/TrackingDevices/mitkPolhemusTool.cpp b/Modules/IGT/TrackingDevices/mitkPolhemusTool.cpp
index dfa34e5769..5131f608ae 100644
--- a/Modules/IGT/TrackingDevices/mitkPolhemusTool.cpp
+++ b/Modules/IGT/TrackingDevices/mitkPolhemusTool.cpp
@@ -1,25 +1,35 @@
/*===================================================================
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 "mitkPolhemusTool.h"
mitk::PolhemusTool::PolhemusTool() :InternalTrackingTool()
{
}
mitk::PolhemusTool::~PolhemusTool(void)
{
}
+
+void mitk::PolhemusTool::SetToolPort(int _ToolPort)
+{
+ this->m_ToolPort = _ToolPort;
+}
+
+int mitk::PolhemusTool::GetToolPort()
+{
+ return this->m_ToolPort;
+}
diff --git a/Modules/IGT/TrackingDevices/mitkPolhemusTool.h b/Modules/IGT/TrackingDevices/mitkPolhemusTool.h
index 0d16bebb10..1f23d2ece5 100644
--- a/Modules/IGT/TrackingDevices/mitkPolhemusTool.h
+++ b/Modules/IGT/TrackingDevices/mitkPolhemusTool.h
@@ -1,46 +1,60 @@
/*===================================================================
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 MITKPolhemusTOOL_H_HEADER_INCLUDED_
#define MITKPolhemusTOOL_H_HEADER_INCLUDED_
#include
#include
#include
namespace mitk
{
class PolhemusTrackingDevice;
/** Documentation:
* \brief An object of this class represents a tool of a Polhemus tracking device.
* A tool has to be added to a tracking device which will then
* continuously update the tool coordinates.
* \ingroup IGT
*/
class MITKIGT_EXPORT PolhemusTool : public InternalTrackingTool
{
public:
friend class PolhemusTrackingDevice;
mitkClassMacro(PolhemusTool, InternalTrackingTool);
+ /**
+ * \brief Sets the port of the tool. (e.g. 1 for port "SENS 1" etc.)
+ */
+ virtual void SetToolPort(int _ToolPort);
+
+ /**
+ * \brief Sets the port of the tool. (e.g. 1 for port "SENS 1" etc.)
+ */
+ virtual int GetToolPort();
+
protected:
itkFactorylessNewMacro(Self)
itkCloneMacro(Self)
PolhemusTool();
virtual ~PolhemusTool();
+
+ //This is the port, on which the tool is connected. It is identical with the "ToolIdentifier" set on NavigationDataTools.
+ //If tool is connected on port "SENS 2", the m_ToolPort is 2 etc.
+ int m_ToolPort;
};
}//mitk
#endif // MITKPolhemusTOOL_H_HEADER_INCLUDED_
diff --git a/Modules/IGT/TrackingDevices/mitkPolhemusTrackerTypeInformation.cpp b/Modules/IGT/TrackingDevices/mitkPolhemusTrackerTypeInformation.cpp
index a4e7bed526..4efd7f2596 100644
--- a/Modules/IGT/TrackingDevices/mitkPolhemusTrackerTypeInformation.cpp
+++ b/Modules/IGT/TrackingDevices/mitkPolhemusTrackerTypeInformation.cpp
@@ -1,70 +1,70 @@
/*===================================================================
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 "mitkPolhemusTrackerTypeInformation.h"
#include "mitkPolhemusTrackingDevice.h"
namespace mitk
{
std::string PolhemusTrackerTypeInformation::GetTrackingDeviceName()
{
return "Polhemus tracker";
}
TrackingDeviceData PolhemusTrackerTypeInformation::GetDeviceDataPolhemusTrackerLiberty()
{
TrackingDeviceData data = { PolhemusTrackerTypeInformation::GetTrackingDeviceName(), "Polhemus Liberty Tracker", "cube", "X" };
return data;
}
PolhemusTrackerTypeInformation::PolhemusTrackerTypeInformation()
{
m_DeviceName = PolhemusTrackerTypeInformation::GetTrackingDeviceName();
m_TrackingDeviceData.push_back(GetDeviceDataPolhemusTrackerLiberty());
}
PolhemusTrackerTypeInformation::~PolhemusTrackerTypeInformation()
{
}
mitk::TrackingDeviceSource::Pointer PolhemusTrackerTypeInformation::CreateTrackingDeviceSource(
mitk::TrackingDevice::Pointer trackingDevice,
mitk::NavigationToolStorage::Pointer navigationTools,
std::string* errorMessage,
std::vector* toolCorrespondencesInToolStorage)
{
mitk::TrackingDeviceSource::Pointer returnValue = mitk::TrackingDeviceSource::New();
mitk::PolhemusTrackingDevice::Pointer thisDevice = dynamic_cast(trackingDevice.GetPointer());
*toolCorrespondencesInToolStorage = std::vector();
//add the tools to the tracking device
for (int i = 0; i < navigationTools->GetToolCount(); i++)
{
mitk::NavigationTool::Pointer thisNavigationTool = navigationTools->GetTool(i);
toolCorrespondencesInToolStorage->push_back(i);
- bool toolAddSuccess = thisDevice->AddTool(thisNavigationTool->GetToolName().c_str());
+ bool toolAddSuccess = thisDevice->AddTool(thisNavigationTool->GetToolName().c_str(), std::stoi(thisNavigationTool->GetIdentifier()));
if (!toolAddSuccess)
{
//todo error handling
errorMessage->append("Can't add tool, is the toolfile valid?");
return NULL;
}
thisDevice->GetTool(i)->SetToolTip(thisNavigationTool->GetToolTipPosition(), thisNavigationTool->GetToolTipOrientation());
}
returnValue->SetTrackingDevice(thisDevice);
return returnValue;
}
}
diff --git a/Modules/IGT/TrackingDevices/mitkPolhemusTrackingDevice.cpp b/Modules/IGT/TrackingDevices/mitkPolhemusTrackingDevice.cpp
index 98bd67f4f7..7121391bfe 100644
--- a/Modules/IGT/TrackingDevices/mitkPolhemusTrackingDevice.cpp
+++ b/Modules/IGT/TrackingDevices/mitkPolhemusTrackingDevice.cpp
@@ -1,250 +1,317 @@
/*===================================================================
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 "mitkPolhemusTrackingDevice.h"
#include "mitkPolhemusTool.h"
#include "mitkIGTConfig.h"
#include "mitkIGTTimeStamp.h"
#include "mitkIGTHardwareException.h"
#include
#include
#include
#include "mitkPolhemusTrackerTypeInformation.h"
-#include
typedef itk::MutexLockHolder MutexLockHolder;
-
-mitk::PolhemusTrackingDevice::PolhemusTrackingDevice(): mitk::TrackingDevice()
+mitk::PolhemusTrackingDevice::PolhemusTrackingDevice() : mitk::TrackingDevice()
{
//set the type of this tracking device
this->m_Data = mitk::PolhemusTrackerTypeInformation::GetDeviceDataPolhemusTrackerLiberty();
this->m_MultiThreader = itk::MultiThreader::New();
m_ThreadID = 0;
m_Device = mitk::PolhemusInterface::New();
}
mitk::PolhemusTrackingDevice::~PolhemusTrackingDevice()
{
}
bool mitk::PolhemusTrackingDevice::IsDeviceInstalled()
{
return true;
}
-mitk::TrackingTool* mitk::PolhemusTrackingDevice::AddTool( const char* toolName)
+mitk::TrackingTool* mitk::PolhemusTrackingDevice::AddTool(const char* toolName, int toolPort)
{
+ //Only add tool if port isn't already used.
+ for (auto _tool : m_AllTools)
+ {
+ if (_tool->GetToolPort() == toolPort)
+ {
+ MITK_DEBUG << "There is already a tool connected to this port. Returning existing tool";
+ return _tool;
+ }
+ }
+
mitk::PolhemusTool::Pointer t = mitk::PolhemusTool::New();
t->SetToolName(toolName);
+ t->SetToolPort(toolPort);
if (this->InternalAddTool(t) == false)
return nullptr;
return t.GetPointer();
}
bool mitk::PolhemusTrackingDevice::InternalAddTool(PolhemusTool::Pointer tool)
{
m_AllTools.push_back(tool);
return true;
}
bool mitk::PolhemusTrackingDevice::StartTracking()
{
bool success = m_Device->StartTracking();
if (success)
{
mitk::IGTTimeStamp::GetInstance()->Start(this);
this->SetState(Tracking);
+ this->m_StopTrackingMutex->Lock();
+ this->m_StopTracking = false;
+ this->m_StopTrackingMutex->Unlock();
m_ThreadID = m_MultiThreader->SpawnThread(this->ThreadStartTracking, this); // start a new thread that executes the TrackTools() method
return true;
}
else
{
this->SetState(Ready);
mitkThrowException(mitk::IGTHardwareException) << "Error while trying to start the device!";
}
return success;
}
bool mitk::PolhemusTrackingDevice::StopTracking()
{
+ m_Device->StopTracking();
return Superclass::StopTracking();
}
-
unsigned int mitk::PolhemusTrackingDevice::GetToolCount() const
{
return (unsigned int)this->m_AllTools.size();
}
-
mitk::TrackingTool* mitk::PolhemusTrackingDevice::GetTool(unsigned int toolNumber) const
{
- if ( toolNumber >= this->GetToolCount())
+ if (toolNumber >= this->GetToolCount())
return nullptr;
else
return this->m_AllTools[toolNumber];
}
-
bool mitk::PolhemusTrackingDevice::OpenConnection()
{
//reset everything
- if (m_Device.IsNull()) {m_Device = mitk::PolhemusInterface::New();}
- m_Device->SetHemisphereTrackingEnabled(m_HemisphereTrackingEnabled);
- m_Device->Connect();
+ if (m_Device.IsNull()) { m_Device = mitk::PolhemusInterface::New(); }
+ if (!m_Device->Connect()) //Connect the device, if it fails, throw an error.
+ {
+ MITK_ERROR << "Cannot connect Polhemus device!";
+ CloseConnection();
+ return false;
+ }
+
+ //Ready must be set here, 'cause if tools don't match we need to be able to disconnect.
this->SetState(Ready);
+
+ //check if connected ports of Polhemus matches the tools in the toolStorage.
+ std::vector toolPorts = m_Device->GetToolPorts();
+
+ //first, check size.
+ if (this->GetToolCount() != toolPorts.size())
+ {
+ MITK_ERROR << "Cannot connect device, number of tools in toolstorage doesn't match the number of tools connected to Polhemus device!";
+ CloseConnection();
+ return false;
+ }
+
+ //second, check if toolStorage identifier is included in this port.
+ for (auto _tool : m_AllTools)
+ {
+ if (std::find(toolPorts.begin(), toolPorts.end(), _tool->GetToolPort()) == toolPorts.end())
+ {
+ MITK_ERROR << "Cannot connect device, tool " << _tool->GetToolPort() << " is not connected to its port.";
+ CloseConnection();
+ return false;
+ }
+ else
+ {
+ //erase this port to avoid that two tools want to connect to the same port.
+ toolPorts.erase(std::find(toolPorts.begin(), toolPorts.end(), _tool->GetToolPort()));
+ }
+ }
+
+ m_Device->SetHemisphereTrackingEnabled(m_HemisphereTrackingEnabled);
+
return true;
}
bool mitk::PolhemusTrackingDevice::CloseConnection()
{
bool returnValue = true;
if (this->GetState() == Setup)
return true;
returnValue = m_Device->Disconnect();
this->SetState(Setup);
return returnValue;
}
-
mitk::PolhemusInterface* mitk::PolhemusTrackingDevice::GetDevice()
{
return m_Device;
}
-
std::vector mitk::PolhemusTrackingDevice::GetAllTools()
{
return this->m_AllTools;
}
-
void mitk::PolhemusTrackingDevice::TrackTools()
{
try
{
/* lock the TrackingFinishedMutex to signal that the execution rights are now transfered to the tracking thread */
MutexLockHolder trackingFinishedLockHolder(*m_TrackingFinishedMutex); // keep lock until end of scope
bool localStopTracking; // Because m_StopTracking is used by two threads, access has to be guarded by a mutex. To minimize thread locking, a local copy is used here
this->m_StopTrackingMutex->Lock(); // update the local copy of m_StopTracking
localStopTracking = this->m_StopTracking;
this->m_StopTrackingMutex->Unlock();
Sleep(100);//Wait a bit until the tracker is ready...
while ((this->GetState() == Tracking) && (localStopTracking == false))
{
std::vector lastData = this->GetDevice()->GetLastFrame();
if (lastData.size() != m_AllTools.size())
{
- MITK_WARN << "Tool count is corrupt. Aborting!";
+ MITK_WARN << "Tool count is corrupt. Hardware gives " << lastData.size() << " tools, MITK expects " << m_AllTools.size() << " tools. Aborting!";
}
else
{
std::vector allTools = this->GetAllTools();
for (int i = 0; i < allTools.size(); i++)
{
mitk::PolhemusTool::Pointer currentTool = allTools.at(i);
currentTool->SetDataValid(true);
currentTool->SetPosition(lastData.at(i).pos);
currentTool->SetOrientation(lastData.at(i).rot);
currentTool->SetIGTTimeStamp(mitk::IGTTimeStamp::GetInstance()->GetElapsed());
}
}
/* Update the local copy of m_StopTracking */
this->m_StopTrackingMutex->Lock();
localStopTracking = m_StopTracking;
this->m_StopTrackingMutex->Unlock();
}
}
- catch(...)
+ catch (...)
{
this->StopTracking();
mitkThrowException(mitk::IGTHardwareException) << "Error while trying to track tools. Thread stopped.";
}
}
ITK_THREAD_RETURN_TYPE mitk::PolhemusTrackingDevice::ThreadStartTracking(void* pInfoStruct)
{
/* extract this pointer from Thread Info structure */
struct itk::MultiThreader::ThreadInfoStruct * pInfo = (struct itk::MultiThreader::ThreadInfoStruct*)pInfoStruct;
if (pInfo == nullptr)
{
return ITK_THREAD_RETURN_VALUE;
}
if (pInfo->UserData == nullptr)
{
return ITK_THREAD_RETURN_VALUE;
}
PolhemusTrackingDevice *trackingDevice = (PolhemusTrackingDevice*)pInfo->UserData;
if (trackingDevice != nullptr)
trackingDevice->TrackTools();
return ITK_THREAD_RETURN_VALUE;
}
bool mitk::PolhemusTrackingDevice::AutoDetectToolsAvailable()
{
return true;
}
mitk::NavigationToolStorage::Pointer mitk::PolhemusTrackingDevice::AutoDetectTools()
{
- this->OpenConnection();
- std::vector singeFrameData = this->m_Device->GetSingleFrame();
+ std::vector singeFrameData = this->m_Device->AutoDetectTools();
MITK_INFO << "Found " << singeFrameData.size() << " tools.";
- this->CloseConnection();
mitk::NavigationToolStorage::Pointer returnValue = mitk::NavigationToolStorage::New();
for each (mitk::PolhemusInterface::trackingData t in singeFrameData)
{
+ mitk::NavigationTool::Pointer newTool = mitk::NavigationTool::New();
- mitk::DataNode::Pointer newNode = mitk::DataNode::New();
std::stringstream name;
name << "Sensor-" << ((int)t.id);
- newNode->SetName(name.str());
-
- mitk::Surface::Pointer myCone = mitk::Surface::New();
- vtkConeSource *vtkData = vtkConeSource::New();
- vtkData->SetAngle(5.0);
- vtkData->SetResolution(50);
- vtkData->SetHeight(6.0f);
- vtkData->SetRadius(2.0f);
- vtkData->SetCenter(0.0, 0.0, 0.0);
- vtkData->Update();
- myCone->SetVtkPolyData(vtkData->GetOutput());
- vtkData->Delete();
- newNode->SetData(myCone);
-
- mitk::NavigationTool::Pointer newTool = mitk::NavigationTool::New();
- newTool->SetDataNode(newNode);
+ newTool->GetDataNode()->SetName(name.str());
+ //The identifier defines, which plug is used (e.g. "Sens 2" --> 2).
std::stringstream identifier;
- identifier << "AutoDetectedTool-" << ((int)t.id);
+ identifier << ((int)t.id);
newTool->SetIdentifier(identifier.str());
newTool->SetTrackingDeviceType(mitk::PolhemusTrackerTypeInformation::GetDeviceDataPolhemusTrackerLiberty().Line);
returnValue->AddTool(newTool);
}
return returnValue;
+}
+
+void mitk::PolhemusTrackingDevice::SetHemisphereTrackingEnabled(bool _HemisphereTrackingEnabled)
+{
+ //We need to remember if HemisphereTracking is switch on for this reason:
+ /* m_Device->SetHemi works only if the device is connected. However, GUI can also change if it is not connected.
+ In this case, we remember it in the m_HemisphereTrackingEnabled variable. And when connecting, we know, which
+ status is wanted from the user by GUI.
+ */
+ m_HemisphereTrackingEnabled = _HemisphereTrackingEnabled;
+ this->m_Device->SetHemisphereTrackingEnabled(_HemisphereTrackingEnabled);
+}
+void mitk::PolhemusTrackingDevice::ToggleHemisphere(int _tool)
+{
+ this->m_Device->ToggleHemisphere(_tool);
}
+
+void mitk::PolhemusTrackingDevice::SetHemisphere(int _tool, mitk::Vector3D _hemisphere)
+{
+ //If you set a hemisphere vector which is unequal (0|0|0), this means, that there is no hemisphere tracking any more
+ //disable the option, so that it can be reactivated... Also if it is just a single tool.
+ if (_hemisphere.GetNorm() != 0)
+ m_HemisphereTrackingEnabled = false;
+
+ this->m_Device->SetHemisphere(_tool, _hemisphere);
+}
+
+mitk::Vector3D mitk::PolhemusTrackingDevice::GetHemisphere(int _tool)
+{
+ return this->m_Device->GetHemisphere(_tool);
+}
+
+bool mitk::PolhemusTrackingDevice::GetHemisphereTrackingEnabled(int _tool)
+{
+ return this->m_Device->GetHemisphereTrackingEnabled(_tool);
+}
+
+void mitk::PolhemusTrackingDevice::AdjustHemisphere(int _tool)
+{
+ return this->m_Device->AdjustHemisphere(_tool);
+}
\ No newline at end of file
diff --git a/Modules/IGT/TrackingDevices/mitkPolhemusTrackingDevice.h b/Modules/IGT/TrackingDevices/mitkPolhemusTrackingDevice.h
index 0d02827f2f..1d50ec8f75 100644
--- a/Modules/IGT/TrackingDevices/mitkPolhemusTrackingDevice.h
+++ b/Modules/IGT/TrackingDevices/mitkPolhemusTrackingDevice.h
@@ -1,145 +1,165 @@
/*===================================================================
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 MITKPolhemusTRACKINGDEVICE_H_HEADER_INCLUDED_
#define MITKPolhemusTRACKINGDEVICE_H_HEADER_INCLUDED_
#include
#include
#include
#include
#include
namespace mitk
{
/** Documentation:
* \brief An object of this class represents Polhemus tracking device. You can add tools to this
* device, then open the connection and start tracking. The tracking device will then
* continuously update the tool coordinates.
+ * The tools which are used by Polhemus need to be connected to the correct port.
+ * The port of the tool is stored as m_ToolPort in PolhemusTool AND as identifier in the NavigationTool (ToolStorage).
* \ingroup IGT
*/
class MITKIGT_EXPORT PolhemusTrackingDevice : public TrackingDevice
{
public:
mitkClassMacro(PolhemusTrackingDevice, TrackingDevice);
itkFactorylessNewMacro(Self)
itkCloneMacro(Self)
/**
* \brief Starts the tracking.
* \return Returns true if the tracking is started. Throws an exception if an error occures.
* @throw mitk::IGTHardwareException Throws an exception if there is an error during start tracking.
*/
virtual bool StartTracking() override;
/**
* \brief Stops the tracking.
* \return Returns true if the tracking is stopped.
*/
virtual bool StopTracking() override;
/**
* \brief Opens the connection to the device. This have to be done before the tracking is started.
* @throw mitk::IGTHardwareException Throws an exception if there is an error during open connection.
*/
virtual bool OpenConnection() override;
/**
* \brief Closes the connection and clears all resources.
*/
virtual bool CloseConnection() override;
/**
* \return Returns the number of tools which have been added to the device.
*/
virtual unsigned int GetToolCount() const override;
/**
* \param toolNumber The number of the tool which should be given back.
* \return Returns the tool which the number "toolNumber". Returns NULL, if there is
* no tool with this number.
*/
TrackingTool* GetTool(unsigned int toolNumber) const override;
/**
* \brief Create a new Polhemus tool with toolName and add it to the list of tools
*
* This method will create a new PolhemusTool object,
* set the tool name toolName and then add it to the list of tools.
* It returns a pointer of type mitk::TrackingTool to the tool
* that can be used to read tracking data from it.
* This is the only way to add tools to PolhemusTrackingDevice.
*
* \warning adding tools is not possible in tracking mode, only in setup and ready.
*/
- mitk::TrackingTool* AddTool(const char* toolName);
+ mitk::TrackingTool* AddTool(const char* toolName, int toolPort);
+
+
bool IsDeviceInstalled();
/** @return Returns true if this device can autodetects its tools. */
virtual bool AutoDetectToolsAvailable();
/** Autodetects tools from this device and returns them as a navigation tool storage.
* @return Returns the detected tools. Returns an empty storage if no tools are present
* or if detection is not possible
*/
virtual mitk::NavigationToolStorage::Pointer AutoDetectTools();
/** Enables/disables hemisphere tracking for all sensors. */
- itkSetMacro(HemisphereTrackingEnabled, bool);
+ void SetHemisphereTrackingEnabled(bool _HemisphereTrackingEnabled);
+
+ /** Is Hemisphere Tracking Enabled for this tool? */
+ bool GetHemisphereTrackingEnabled(int _tool);
+
+ /** Toggles the current hemisphere. Parameter _tool describes, for which tool the hemisphere should change. Default -1 toggles all tools.*/
+ void ToggleHemisphere(int _tool = -1);
+
+ /** Sets the Hemisphere of tool _tool to the vector _hemisphere */
+ void SetHemisphere(int _tool, mitk::Vector3D _hemisphere);
+
+ /** Get the Hemisphere for _tool as mitk vector */
+ mitk::Vector3D GetHemisphere(int _tool);
+
+ /** Adjust the Hemisphere for this tool. User needs to make sure, that the tool is located in hemisphere (1|0|0) when calling this function.
+ In contrast to SetHemisphere(1,0,0), this method restores the original HemisphereTracking settings at the end. */
+ void AdjustHemisphere(int _tool);
protected:
PolhemusTrackingDevice();
~PolhemusTrackingDevice();
/**
* \brief Adds a tool to the tracking device.
*
* \param tool The tool which will be added.
* \return Returns true if the tool has been added, false otherwise.
*/
bool InternalAddTool(PolhemusTool::Pointer tool);
/**
* \brief This method tracks tools as long as the variable m_Mode is set to "Tracking".
* Tracking tools means grabbing frames from the camera an updating the tools.
* @throw mitk::IGTHardwareException Throws an exception if there is an error during tracking of tools.
*/
void TrackTools();
/**
* \return Returns all tools of the tracking device.
*/
std::vector GetAllTools();
/**
* \return Gives back the device which is represented by an object of the class PolhemusInterface.
*/
PolhemusInterface* GetDevice();
static ITK_THREAD_RETURN_TYPE ThreadStartTracking(void* data);
std::vector m_AllTools; ///< vector holding all tools
PolhemusInterface::Pointer m_Device; ///< represents the interface to the tracking hardware
itk::MultiThreader::Pointer m_MultiThreader;
int m_ThreadID;
bool m_HemisphereTrackingEnabled;
};
}//mitk
#endif /* MITKPolhemusTRACKINGDEVICE_H_HEADER_INCLUDED_ */
diff --git a/Modules/IGT/TrackingDevices/mitkTrackingDevice.cpp b/Modules/IGT/TrackingDevices/mitkTrackingDevice.cpp
index 8393c21d4f..f3585d0ee1 100644
--- a/Modules/IGT/TrackingDevices/mitkTrackingDevice.cpp
+++ b/Modules/IGT/TrackingDevices/mitkTrackingDevice.cpp
@@ -1,148 +1,157 @@
/*===================================================================
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 "mitkTrackingDevice.h"
#include "mitkIGTTimeStamp.h"
#include "mitkTrackingTool.h"
#include
#include
#include
#include "mitkUnspecifiedTrackingTypeInformation.h"
#include "mitkTrackingDeviceTypeCollection.h"
typedef itk::MutexLockHolder MutexLockHolder;
mitk::TrackingDevice::TrackingDevice() :
m_State(mitk::TrackingDevice::Setup),
m_Data(mitk::UnspecifiedTrackingTypeInformation::GetDeviceDataUnspecified()),
m_StopTracking(false),
m_RotationMode(mitk::TrackingDevice::RotationStandard)
{
m_StopTrackingMutex = itk::FastMutexLock::New();
m_StateMutex = itk::FastMutexLock::New();
m_TrackingFinishedMutex = itk::FastMutexLock::New();
}
mitk::TrackingDevice::~TrackingDevice()
{
}
bool mitk::TrackingDevice::IsDeviceInstalled()
{
return true;
//this is the default for all tracking device
//If a device needs installation please reimplement
//this method in the subclass.
}
bool mitk::TrackingDevice::AutoDetectToolsAvailable()
{
return false;
}
+bool mitk::TrackingDevice::AddSingleToolIsAvailable()
+{
+ return true;
+}
+
mitk::NavigationToolStorage::Pointer mitk::TrackingDevice::AutoDetectTools()
{
return mitk::NavigationToolStorage::New();
}
mitk::TrackingDevice::TrackingDeviceState mitk::TrackingDevice::GetState() const
{
MutexLockHolder lock(*m_StateMutex);
return m_State;
}
void mitk::TrackingDevice::SetState( TrackingDeviceState state )
{
itkDebugMacro("setting m_State to " << state);
MutexLockHolder lock(*m_StateMutex); // lock and unlock the mutex
if (m_State == state)
{
return;
}
m_State = state;
this->Modified();
}
void mitk::TrackingDevice::SetRotationMode(RotationMode)
{
MITK_WARN << "Rotation mode switching is not implemented for this device. Leaving it at mitk::TrackingDevice::RotationStandard";
}
mitk::TrackingDeviceType mitk::TrackingDevice::GetType() const{
return m_Data.Line;
}
void mitk::TrackingDevice::SetType(mitk::TrackingDeviceType deviceType){
us::ModuleContext* context = us::GetModuleContext();
std::vector > refs = context->GetServiceReferences();
if (refs.empty())
{
MITK_ERROR << "No tracking device service found!";
}
mitk::TrackingDeviceTypeCollection* deviceTypeCollection = context->GetService(refs.front());
m_Data = deviceTypeCollection->GetFirstCompatibleDeviceDataForLine(deviceType);
}
mitk::TrackingDeviceData mitk::TrackingDevice::GetData() const{
return m_Data;
}
void mitk::TrackingDevice::SetData(mitk::TrackingDeviceData data){
m_Data = data;
}
bool mitk::TrackingDevice::StopTracking()
{
if (this->GetState() == Tracking) // Only if the object is in the correct state
{
m_StopTrackingMutex->Lock(); // m_StopTracking is used by two threads, so we have to ensure correct thread handling
m_StopTracking = true;
m_StopTrackingMutex->Unlock();
//we have to wait here that the other thread recognizes the STOP-command and executes it
m_TrackingFinishedMutex->Lock();
mitk::IGTTimeStamp::GetInstance()->Stop(this); // notify realtime clock
// StopTracking was called, thus the mode should be changed back
// to Ready now that the tracking loop has ended.
this->SetState(Ready);
m_TrackingFinishedMutex->Unlock();
}
return true;
}
mitk::TrackingTool* mitk::TrackingDevice::GetToolByName( std::string name ) const
{
unsigned int toolCount = this->GetToolCount();
for (unsigned int i = 0; i < toolCount; ++i)
if (name == this->GetTool(i)->GetToolName())
return this->GetTool(i);
return nullptr;
}
+std::string mitk::TrackingDevice::GetTrackingDeviceName()
+{
+ return this->GetData().Line;
+}
diff --git a/Modules/IGT/TrackingDevices/mitkTrackingDevice.h b/Modules/IGT/TrackingDevices/mitkTrackingDevice.h
index 1cadb52701..c731ee7419 100644
--- a/Modules/IGT/TrackingDevices/mitkTrackingDevice.h
+++ b/Modules/IGT/TrackingDevices/mitkTrackingDevice.h
@@ -1,199 +1,209 @@
/*===================================================================
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 MITKTRACKINGDEVICE_H_HEADER_INCLUDED_C1C2FCD2
#define MITKTRACKINGDEVICE_H_HEADER_INCLUDED_C1C2FCD2
#include
#include "itkObject.h"
#include "mitkCommon.h"
#include "mitkTrackingTypes.h"
#include "itkFastMutexLock.h"
#include "mitkNavigationToolStorage.h"
namespace mitk {
class TrackingTool; // interface for a tool that can be tracked by the TrackingDevice
/**Documentation
* \brief Interface for all Tracking Devices
*
* Defines the methods that are common for all tracking devices.
*
* \ingroup IGT
*/
class MITKIGT_EXPORT TrackingDevice : public itk::Object
{
public:
mitkClassMacroItkParent(TrackingDevice, itk::Object);
/** Defines the rotation modes of this tracking device which results in different representations
* of quaternions.
*
* - Standard: normal representation, rawdata from the device is not changed (DEFAULT)
*
* - Transposed: the rotation is stored transposed, which is (by mistake!) expected by some older MITK classes due
* to an ambigious method naming in VNL.
*
* CAUTION: The rotation mode can only be changed for backward compatibility of old WRONG code.
* PLEASE DO NOT CHANGE THE ROTATION MODE UNLESS YOU ARE KNOWING EXACTLY WHAT YOU ARE DOING!
*
* use SetRotationMode to change the mode.
*/
enum RotationMode {RotationStandard, RotationTransposed};
enum TrackingDeviceState {Setup, Ready, Tracking}; ///< Type for state variable. The trackingdevice is always in one of these states
/**
* \brief Opens a connection to the device
*
* This may only be called if there is currently no connection to the device.
* If OpenConnection() is successful, the object will change from Setup state to Ready state
*/
virtual bool OpenConnection() = 0;
/**
* \brief Closes the connection to the device
*
* This may only be called if there is currently a connection to the device, but tracking is
* not running (e.g. object is in Ready state)
*/
virtual bool CloseConnection() = 0; ///< Closes the connection with the device
/**
* \brief start retrieving tracking data from the device.
*
* This may only be called after the connection to the device has been established
* with a call to OpenConnection() (E.g. object is in Ready mode). This will change the
* object state from Ready to Tracking
*/
virtual bool StartTracking() = 0;
/**
* \brief stop retrieving tracking data from the device.
* stop retrieving tracking data from the device.
* This may only be called after StartTracking was called
* (e.g. the object is in Tracking mode).
* This will change the object state from Tracking to Ready.
*/
virtual bool StopTracking();
/**
* \brief Return tool with index toolNumber
*
* tools are numbered from 0 to GetToolCount() - 1.
*/
virtual TrackingTool* GetTool(unsigned int toolNumber) const = 0;
/**
* \brief Returns the tool with the given tool name
*
* Note: subclasses can and should implement optimized versions of this method
* \return the given tool or nullptr if no tool with that name exists
*/
virtual mitk::TrackingTool* GetToolByName(std::string name) const;
/**
* \brief Returns number of tracking tools
*/
virtual unsigned int GetToolCount() const = 0;
/** Sets the rotation mode of this class. See documentation of enum RotationMode for details
* on the different modes. This method has to be implemented in a deriving class to become
* functional / if different rotation modes should be supported.
* CAUTION: The rotation mode can only be changed for backward compatibility of old WRONG code.
* PLEASE DO NOT CHANGE THE ROTATION MODE UNLESS YOU ARE KNOWING EXACTLY WHAT YOU ARE DOING!
*/
virtual void SetRotationMode(RotationMode r);
/** @return Returns the rotation mode of this class. See documentation of enum
* RotationMode for details on the different modes.
*/
itkGetConstMacro(RotationMode,RotationMode);
/**
* \brief return current object state (Setup, Ready or Tracking)
*/
TrackingDeviceState GetState() const;
/**
- * \brief Deprecated! Use the more specific getDeviceData instead. return device type identifier
+ * \brief Deprecated! Use the more specific getData or GetTrackingDeviceName instead. return device type identifier
*/
TrackingDeviceType GetType() const;
/**
* \brief Deprecated! Use the more specific setDeviceData instead. set device type
*/
void SetType(TrackingDeviceType type);
+ /**
+ * \brief Convenient Method to get the Name of the Tracking Device.
+ * This is identical with GetData().Line and can be used to compare with TrackingDeviceTypeInformation::GetTrackingDeviceName()
+ * to check if you have a specific device.
+ */
+ std::string GetTrackingDeviceName();
+
/**
* \brief return device data
*/
TrackingDeviceData GetData() const;
/**
* \brief set device type
*/
void SetData(TrackingDeviceData data);
/**
* @return Returns true if the device is installed on this system an can be used.
* Installed means activated in MITK, in some cases this means the MITK
* installation / build has to know the installation path of the device
* libraries on this system. This path is usually given as cmake variable
* during the build configuration in devellopers mode. If the device should
* be available for end users with an installer the libraries can be included
* into the installer or the installer has to be adapted such that it asks
* for the path.
* Returns fals if the device is not installed. It cannot be used on this build
* in this case.
*
* Note that some tracking systems communicate via a standard interface (e.g., serial
* port) and don't need any library or installation. These devices are always "installed".
*/
virtual bool IsDeviceInstalled();
/** @return Returns true if this device can autodetects its tools. */
virtual bool AutoDetectToolsAvailable();
+ /** @return Returns true if it is possible to add a single tool. Default return is true.*/
+ virtual bool AddSingleToolIsAvailable();
+
/** Autodetects tools from this device and returns them as a navigation tool storage.
* @return Returns the detected tools. Returns an empty storage if no tools are present
* or if detection is not possible
*/
virtual mitk::NavigationToolStorage::Pointer AutoDetectTools();
private:
TrackingDeviceState m_State; ///< current object state (Setup, Ready or Tracking)
protected:
/**
* \brief change object state
*/
void SetState(TrackingDeviceState state);
TrackingDevice();
virtual ~TrackingDevice();
TrackingDeviceData m_Data; ///< current device Data
bool m_StopTracking; ///< signal stop to tracking thread
itk::FastMutexLock::Pointer m_StopTrackingMutex; ///< mutex to control access to m_StopTracking
itk::FastMutexLock::Pointer m_TrackingFinishedMutex; ///< mutex to manage control flow of StopTracking()
itk::FastMutexLock::Pointer m_StateMutex; ///< mutex to control access to m_State
RotationMode m_RotationMode; ///< defines the rotation mode Standard or Transposed, Standard is default
};
} // namespace mitk
#endif /* MITKTRACKINGDEVICE_H_HEADER_INCLUDED_C1C2FCD2 */
diff --git a/Modules/IGT/TrackingDevices/mitkVirtualTrackerTypeInformation.cpp b/Modules/IGT/TrackingDevices/mitkVirtualTrackerTypeInformation.cpp
index 2bcc5fa600..eae7f126b7 100644
--- a/Modules/IGT/TrackingDevices/mitkVirtualTrackerTypeInformation.cpp
+++ b/Modules/IGT/TrackingDevices/mitkVirtualTrackerTypeInformation.cpp
@@ -1,70 +1,70 @@
/*===================================================================
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 "mitkVirtualTrackerTypeInformation.h"
#include "mitkVirtualTrackingDevice.h"
namespace mitk
{
std::string VirtualTrackerTypeInformation::GetTrackingDeviceName()
{
return "Virtual Tracker";
}
TrackingDeviceData VirtualTrackerTypeInformation::GetDeviceDataVirtualTracker()
{
TrackingDeviceData data = { VirtualTrackerTypeInformation::GetTrackingDeviceName(), "Virtual Tracker", "cube", "X" };
return data;
}
VirtualTrackerTypeInformation::VirtualTrackerTypeInformation()
{
m_DeviceName = VirtualTrackerTypeInformation::GetTrackingDeviceName();
m_TrackingDeviceData.push_back(GetDeviceDataVirtualTracker());
}
VirtualTrackerTypeInformation::~VirtualTrackerTypeInformation()
{
}
mitk::TrackingDeviceSource::Pointer VirtualTrackerTypeInformation::CreateTrackingDeviceSource(
mitk::TrackingDevice::Pointer trackingDevice,
mitk::NavigationToolStorage::Pointer navigationTools,
std::string* errorMessage,
std::vector* toolCorrespondencesInToolStorage)
{
mitk::TrackingDeviceSource::Pointer returnValue = mitk::TrackingDeviceSource::New();
mitk::VirtualTrackingDevice::Pointer thisDevice = dynamic_cast(trackingDevice.GetPointer());
*toolCorrespondencesInToolStorage = std::vector();
//add the tools to the tracking device
- for (int i = 0; i < navigationTools->GetToolCount(); i++)
+ for (unsigned int i = 0; i < navigationTools->GetToolCount(); i++)
{
mitk::NavigationTool::Pointer thisNavigationTool = navigationTools->GetTool(i);
toolCorrespondencesInToolStorage->push_back(i);
bool toolAddSuccess = thisDevice->AddTool(thisNavigationTool->GetToolName().c_str());
if (!toolAddSuccess)
{
//todo error handling
errorMessage->append("Can't add tool, is the toolfile valid?");
return nullptr;
}
}
returnValue->SetTrackingDevice(thisDevice);
return returnValue;
}
}
diff --git a/Modules/IGT/files.cmake b/Modules/IGT/files.cmake
index 8d9ec0bc9e..f9b80c1194 100644
--- a/Modules/IGT/files.cmake
+++ b/Modules/IGT/files.cmake
@@ -1,113 +1,115 @@
set(CPP_FILES
TestingHelper/mitkNavigationToolStorageTestHelper.cpp
Algorithms/mitkNavigationDataDelayFilter.cpp
Algorithms/mitkNavigationDataDisplacementFilter.cpp
Algorithms/mitkNavigationDataEvaluationFilter.cpp
Algorithms/mitkNavigationDataLandmarkTransformFilter.cpp
+ Algorithms/mitkNavigationDataPassThroughFilter.cpp
Algorithms/mitkNavigationDataReferenceTransformFilter.cpp
Algorithms/mitkNavigationDataSmoothingFilter.cpp
Algorithms/mitkNavigationDataToMessageFilter.cpp
Algorithms/mitkNavigationDataToNavigationDataFilter.cpp
Algorithms/mitkNavigationDataToPointSetFilter.cpp
Algorithms/mitkNavigationDataTransformFilter.cpp
Algorithms/mitkNavigationDataToIGTLMessageFilter.cpp
Algorithms/mitkIGTLMessageToNavigationDataFilter.cpp
+ Algorithms/mitkNeedleProjectionFilter.cpp
Algorithms/mitkPivotCalibration.cpp
Common/mitkIGTTimeStamp.cpp
Common/mitkSerialCommunication.cpp
DataManagement/mitkNavigationDataSource.cpp
DataManagement/mitkNavigationTool.cpp
DataManagement/mitkNavigationToolStorage.cpp
DataManagement/mitkTrackingDeviceSourceConfigurator.cpp
DataManagement/mitkTrackingDeviceSource.cpp
DataManagement/mitkTrackingDeviceTypeCollection.cpp
ExceptionHandling/mitkIGTException.cpp
ExceptionHandling/mitkIGTHardwareException.cpp
ExceptionHandling/mitkIGTIOException.cpp
IO/mitkNavigationDataPlayer.cpp
IO/mitkNavigationDataPlayerBase.cpp
IO/mitkNavigationDataRecorder.cpp
IO/mitkNavigationDataRecorderDeprecated.cpp
IO/mitkNavigationDataSequentialPlayer.cpp
IO/mitkNavigationToolReader.cpp
IO/mitkNavigationToolStorageSerializer.cpp
IO/mitkNavigationToolStorageDeserializer.cpp
IO/mitkNavigationToolWriter.cpp
IO/mitkNavigationDataReaderInterface.cpp
Rendering/mitkCameraVisualization.cpp
Rendering/mitkNavigationDataObjectVisualizationFilter.cpp
Rendering/mitkNavigationDataSliceVisualization.cpp
TrackingDevices/mitkClaronTool.cpp
TrackingDevices/mitkClaronTrackingDevice.cpp
TrackingDevices/mitkInternalTrackingTool.cpp
TrackingDevices/mitkNDIPassiveTool.cpp
TrackingDevices/mitkNDIProtocol.cpp
TrackingDevices/mitkNDITrackingDevice.cpp
TrackingDevices/mitkTrackingDevice.cpp
TrackingDevices/mitkTrackingTool.cpp
TrackingDevices/mitkTrackingVolumeGenerator.cpp
TrackingDevices/mitkVirtualTrackingDevice.cpp
TrackingDevices/mitkVirtualTrackingTool.cpp
TrackingDevices/mitkOptitrackErrorMessages.cpp
TrackingDevices/mitkOptitrackTrackingDevice.cpp
TrackingDevices/mitkOptitrackTrackingTool.cpp
TrackingDevices/mitkOpenIGTLinkTrackingDevice.cpp
TrackingDevices/mitkOpenIGTLinkTrackingTool.cpp
TrackingDevices/mitkNDIAuroraTypeInformation.cpp
TrackingDevices/mitkNDIPolarisTypeInformation.cpp
TrackingDevices/mitkNPOptitrackTrackingTypeInformation.cpp
TrackingDevices/mitkVirtualTrackerTypeInformation.cpp
TrackingDevices/mitkMicronTrackerTypeInformation.cpp
TrackingDevices/mitkOpenIGTLinkTypeInformation.cpp
TrackingDevices/mitkUnspecifiedTrackingTypeInformation.cpp
# TrackingDevices/mitkPolhemusTrackingDevice.cpp
# TrackingDevices/mitkPolhemusTool.cpp
# TrackingDevices/mitkPolhemusTrackerTypeInformation.cpp
)
set(H_FILES
DataManagement/mitkTrackingDeviceTypeInformation.h
Common/mitkTrackingTypes.h
)
set(RESOURCE_FILES
ClaronMicron.stl
IntuitiveDaVinci.stl
NDIAurora.stl
NDIAurora_Dome.stl
NDIAuroraCompactFG_Dome.stl
NDIAuroraPlanarFG_Dome.stl
NDIAuroraTabletopFG_Dome.stl
NDIAuroraTabletopFG_Prototype_Dome.stl
NDIPolarisOldModel.stl
NDIPolarisSpectra.stl
NDIPolarisSpectraExtendedPyramid.stl
NDIPolarisVicra.stl
)
if(MITK_USE_MICRON_TRACKER)
set(CPP_FILES ${CPP_FILES} TrackingDevices/mitkClaronInterface.cpp)
else()
set(CPP_FILES ${CPP_FILES} TrackingDevices/mitkClaronInterfaceStub.cpp)
endif(MITK_USE_MICRON_TRACKER)
if(MITK_USE_MICROBIRD_TRACKER)
set(CPP_FILES ${CPP_FILES} TrackingDevices/mitkMicroBirdTrackingDevice.cpp)
endif(MITK_USE_MICROBIRD_TRACKER)
if(MITK_USE_POLHEMUS_TRACKER)
set(CPP_FILES ${CPP_FILES}
TrackingDevices/mitkPolhemusInterface.cpp
TrackingDevices/mitkPolhemusTrackingDevice.cpp
TrackingDevices/mitkPolhemusTool.cpp
TrackingDevices/mitkPolhemusTrackerTypeInformation.cpp
)
endif(MITK_USE_POLHEMUS_TRACKER)
diff --git a/Modules/IGTUI/Qmitk/QmitkAbstractTrackingDeviceWidget.cpp b/Modules/IGTUI/Qmitk/QmitkAbstractTrackingDeviceWidget.cpp
index d337d2d393..f84d1676a5 100644
--- a/Modules/IGTUI/Qmitk/QmitkAbstractTrackingDeviceWidget.cpp
+++ b/Modules/IGTUI/Qmitk/QmitkAbstractTrackingDeviceWidget.cpp
@@ -1,77 +1,77 @@
/*===================================================================
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 "QmitkAbstractTrackingDeviceWidget.h"
#include
QmitkAbstractTrackingDeviceWidget::QmitkAbstractTrackingDeviceWidget(QWidget* parent, Qt::WindowFlags f)
: QWidget(parent, f)
, m_TestConnectionWorker(nullptr)
, m_TestConnectionWorkerThread(nullptr)
, m_ErrorMessage("")
, isInitialized(false)
{
}
void QmitkAbstractTrackingDeviceWidget::InitializeSuperclassWidget()
{
m_TestConnectionWorkerThread = new QThread();
m_TestConnectionWorker = new QmitkTrackingDeviceConfigurationWidgetConnectionWorker();
CreateConnections();
m_ErrorMessage = "";
isInitialized = true;
}
QmitkAbstractTrackingDeviceWidget::~QmitkAbstractTrackingDeviceWidget(){
if (m_TestConnectionWorker) delete m_TestConnectionWorker;
if (m_TestConnectionWorkerThread) delete m_TestConnectionWorkerThread;
}
void QmitkAbstractTrackingDeviceWidget::TestConnectionFinished(bool connected, QString output)
{
m_TestConnectionWorkerThread->quit();
AddOutput(output.toStdString());
MITK_INFO << "Test connection: " << connected;
this->setEnabled(true);
}
void QmitkAbstractTrackingDeviceWidget::TestConnection()
{
this->setEnabled(false);
//construct a tracking device:
- mitk::TrackingDevice::Pointer testTrackingDevice = ConstructTrackingDevice();
+ mitk::TrackingDevice::Pointer testTrackingDevice = GetTrackingDevice();
m_TestConnectionWorker->SetTrackingDevice(testTrackingDevice);
m_TestConnectionWorkerThread->start();
}
void QmitkAbstractTrackingDeviceWidget::CreateConnections() {
connect(m_TestConnectionWorker, SIGNAL(ConnectionTested(bool, QString)), this, SLOT(TestConnectionFinished(bool, QString)));
connect(m_TestConnectionWorkerThread, SIGNAL(started()), m_TestConnectionWorker, SLOT(TestConnectionThreadFunc()));
//move the worker to the thread
m_TestConnectionWorker->moveToThread(m_TestConnectionWorkerThread);
}
QmitkAbstractTrackingDeviceWidget* QmitkAbstractTrackingDeviceWidget::CloneForQt(QWidget* parent) const
{
QmitkAbstractTrackingDeviceWidget* clonedWidget = this->Clone(parent);
if (!clonedWidget->IsInitialized())
MITK_ERROR << "Your cloned widget is not initialized!";
clonedWidget->create();
return clonedWidget;
}
diff --git a/Modules/IGTUI/Qmitk/QmitkAbstractTrackingDeviceWidget.h b/Modules/IGTUI/Qmitk/QmitkAbstractTrackingDeviceWidget.h
index 2948a8c06c..74f1aeaec6 100644
--- a/Modules/IGTUI/Qmitk/QmitkAbstractTrackingDeviceWidget.h
+++ b/Modules/IGTUI/Qmitk/QmitkAbstractTrackingDeviceWidget.h
@@ -1,143 +1,175 @@
/*===================================================================
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 QmitkAbstractTrackingDeviceWidget_H
#define QmitkAbstractTrackingDeviceWidget_H
#include
#include "MitkIGTUIExports.h"
#include "mitkTrackingDevice.h"
#include
#include "QmitkTrackingDeviceConfigurationWidgetConnectionWorker.h"
//itk headers
/** Documentation:
* \brief Abstract class to configure a tracking device.
* Inherited widgets should be registered in the Microservice (TrackingDeviceCollectionWidget),
* If done so, they will be included in the QmitkTrackingDeviceConfigurationWidget of the Tracking Toolbox.
*
- * - Each implementation of this class must have a method to construct a tracking Device (ConstructTrackingDevice).
+ * - Each implementation of this class must have a method to get a TrackingDevice
+ * - Each implementation handles itself, if a new TrackingDevice needs to be constructed.
+ * Attention: In former MITK versions, there was no pure virtual GetTrackingDevice function but a pure virtual ConstructTrackingDevice function.
+ * You can simply rename these, but you should give it a thought, if each time "Construct" was called, a new device needs to be constructed,
+ * or if you can store your TrackingDevice in a member variable and return this. Up to you.
* - Please create the UI elements in a function like CreateQtPartControl (e.g. see QmitkVitrualTrackerWidget).
* - You might want to use own buttons etc., please connect them in a private CreateConnections (e.g. see QmitkVitrualTrackerWidget).
* - Due to initialization of qt during autoloading of the IGT module, you constructor should be as slim as possible and only contain a call
* of the QmitkAbstractTrackingDeviceWidget constructor and simple variable initialization.
* - For the initialization, you must write an Iniltialize() function, which must include a call of InitializeSuperclassWidget() and should contain
* calls of your private CreateConnections / CreateQtPartControl (if you implemented these).
* - For integration into the TrackingToolbox, a clone function is needed. Here, a new widget should be created, Initialize() needs to be called,
* and all settings of your widget should be copied.
*
* You can Load and Store previous settings of your GUI elements (e.g. see QmitkNDIPolarisWidget).
* Also, you can add an output textbox to your widget to display information about your device status. It's optional, see e.g. QmitkNDIAuroraWidget.
* Some Devices need the information if drivers are installed on your computer. If this is necessary for your device to avoid crashes,
* please override IsDeviceInstalled. The default return value is true otherwise.
*
* \ingroup IGTUI
*/
class MITKIGTUI_EXPORT QmitkAbstractTrackingDeviceWidget : public QWidget
{
Q_OBJECT
public:
static const std::string VIEW_ID;
QmitkAbstractTrackingDeviceWidget(QWidget* parent = 0, Qt::WindowFlags f = 0);
~QmitkAbstractTrackingDeviceWidget() override;
/**
* \brief Return pointer to copy of the object.
* Internally use of QmitkUSAbstractCustomWidget::Clone() with additionaly
* setting an internal flag that the object was really cloned.
*/
QmitkAbstractTrackingDeviceWidget* CloneForQt(QWidget* parent = 0) const;
/**
* \brief Subclass must implement this method to return a pointer to a copy of the object.
* Please don't forget to call InitializeSuperclassWidget(), CreateQtPartControl and optionally CreateConnections during this function.
*/
virtual void Initialize() = 0;
bool IsInitialized() const { return isInitialized; }
signals:
void ConnectionTested(bool connected, QString output);
protected slots:
void TestConnectionFinished(bool connected, QString output);
/* @brief This method is called when the user presses the button "test connection". The method will then create a temporary tracking device,
* try to open a connection and start tracking. The user can see the result of the connection test on the small output window.
*/
void TestConnection();
private:
/// \brief Creation of the connections. You might implement the same function again in your inherited widget.
void CreateConnections();
protected:
PERSISTENCE_GET_SERVICE_METHOD_MACRO
void InitializeSuperclassWidget();
QmitkTrackingDeviceConfigurationWidgetConnectionWorker* m_TestConnectionWorker;
QThread* m_TestConnectionWorkerThread;
/**
* \brief Subclass must implement this method to return a pointer to a copy of the object.
* Please don't forget to call Initialize() during this function and copy all of your settings.
*/
virtual QmitkAbstractTrackingDeviceWidget* Clone(QWidget* parent = 0) const = 0;
public:
/**
* \brief Optional method to add output to a small screen in the trackingToolbox (see QmitkNDIPolarisWidget)
*/
virtual void ResetOutput() {}
/**
* \brief Optional method to add output to a small screen in the trackingToolbox (see QmitkNDIPolarisWidget)
*/
virtual void AddOutput(std::string) {}
- virtual mitk::TrackingDevice::Pointer ConstructTrackingDevice() = 0;
+ virtual mitk::TrackingDevice::Pointer GetTrackingDevice() = 0;
/**
* \brief Optional method to store and load settings of your widget (see QmitkNDIPolarisWidget)
*/
virtual void StoreUISettings() {}
/**
* \brief Optional method to store and load settings of your widget (see QmitkNDIPolarisWidget)
*/
virtual void LoadUISettings() {}
/**
* \brief Optional method to investigate if drivers etc for your device are installed.
* The default value is "true" as most devices don't need this information.
* Others however migth crash, and for these you might implement this function (see QmitkMicronTrackerWidget)
*/
virtual bool IsDeviceInstalled() { return true; }
+ /**
+ * \brief This function is called, when in the TrackingToolboxView "Connect" was clicked and the device is successful connected.
+ * Can e.g. be used to activate options of a tracking device only when it is connected.
+ */
+ virtual void OnConnected(bool) {}
+ /**
+ * \brief This function is called, when in the TrackingToolboxView "Disconnect" was clicked and the device is successful disconnected.
+ * Can e.g. be used to activate/disactivate options of a tracking device.
+ */
+ virtual void OnDisconnected(bool) {}
+
+ /**
+ * \brief This function is called, when in the TrackingToolboxView "Start Tracking" was clicked and the device successfully started tracking.
+ * Can e.g. be used to activate options of a tracking device only when tracking is started.
+ */
+ virtual void OnStartTracking(bool) {}
+ /**
+ * \brief This function is called, when in the TrackingToolboxView "Stop Tracking" was clicked and the device successful stopped tracking.
+ * Can e.g. be used to activate/disactivate options when device is not tracking.
+ */
+ virtual void OnStopTracking(bool) {}
+ /**
+ * \brief This function is called, when anything in the ToolStorage changed, e.g. AddTool or EditTool.
+ * ServiceListener is connected in the QmitkMITKIGTTrackingToolboxView.
+ */
+ virtual void OnToolStorageChanged() {}
+
+
std::string m_ErrorMessage; ///< current problem description
private:
/**
* \warning Don't touch this variable if you don't know what you are doing!
*/
bool isInitialized;
};
#endif
diff --git a/Modules/IGTUI/Qmitk/QmitkIGTConnectionWidget.cpp b/Modules/IGTUI/Qmitk/QmitkIGTConnectionWidget.cpp
index d86c9516d2..099873b754 100644
--- a/Modules/IGTUI/Qmitk/QmitkIGTConnectionWidget.cpp
+++ b/Modules/IGTUI/Qmitk/QmitkIGTConnectionWidget.cpp
@@ -1,215 +1,215 @@
/*===================================================================
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 "QmitkIGTConnectionWidget.h"
#include "QmitkTrackingDeviceConfigurationWidget.h"
#include "mitkClaronTrackingDevice.h"
#include "mitkNDITrackingDevice.h"
#include "mitkOptitrackTrackingDevice.h"
#include "mitkNavigationToolStorageDeserializer.h"
#include "mitkTrackingDeviceSourceConfigurator.h"
#include "QmitkIGTCommonHelper.h"
#include
#include
const std::string QmitkIGTConnectionWidget::VIEW_ID = "org.mitk.views.igtconnectionwidget";
QmitkIGTConnectionWidget::QmitkIGTConnectionWidget(QWidget* parent, Qt::WindowFlags f)
: QWidget(parent, f)
{
m_Controls = nullptr;
CreateQtPartControl(this);
CreateConnections();
m_TrackingDevice = nullptr;
m_TrackingDeviceSource = nullptr;
m_NavigationToolStorage = nullptr;
m_DataStorage = nullptr;
m_ErrorMessage = "";
}
QmitkIGTConnectionWidget::~QmitkIGTConnectionWidget()
{
}
void QmitkIGTConnectionWidget::CreateQtPartControl(QWidget *parent)
{
if (!m_Controls)
{
// create GUI widgets
m_Controls = new Ui::QmitkIGTConnectionWidgetControls;
m_Controls->setupUi(parent);
}
}
void QmitkIGTConnectionWidget::CreateConnections()
{
if ( m_Controls )
{
connect( (QObject*)(m_Controls->connectButton), SIGNAL(clicked()), this, SLOT(OnConnect()) );
}
}
void QmitkIGTConnectionWidget::OnConnect()
{
if (m_Controls->connectButton->isChecked()) // Load tools and connect tracking device
{
m_Controls->connectButton->setChecked(false);
// create TrackingDevice
m_TrackingDevice = m_Controls->trackingDeviceConfigurationWidget->GetTrackingDevice();
if (m_TrackingDevice.IsNotNull())
{
QString fileName = QFileDialog::getOpenFileName(nullptr,tr("Open Navigation tool storage"), QmitkIGTCommonHelper::GetLastFileLoadPath(), tr("Toolfile (*.tfl)"));
QmitkIGTCommonHelper::SetLastFileLoadPathByFileName(fileName);
if (LoadToolfile(fileName))
{
// Create TrackingDeviceSource and add tools
mitk::TrackingDeviceSourceConfigurator::Pointer myTrackingDeviceSourceFactory =
mitk::TrackingDeviceSourceConfigurator::New(this->m_NavigationToolStorage,m_TrackingDevice);
m_TrackingDeviceSource = myTrackingDeviceSourceFactory->CreateTrackingDeviceSource();
m_TrackingDeviceSource->Connect();
m_TrackingDeviceSource->StartTracking();
// change button text
m_Controls->connectButton->setText("Disconnect");
m_Controls->connectButton->setChecked(true);
// disable configuration widget
m_Controls->trackingDeviceConfigurationWidget->setEnabled(false);
// emit connected signal
emit TrackingDeviceConnected();
}
else
{
QString error(m_ErrorMessage.c_str());
QMessageBox::warning(nullptr,"Warning",error);
// reset button to unchecked
m_Controls->connectButton->setChecked(false);
// remove tool nodes from DataStorage
this->RemoveToolNodes();
// reset NavigationToolStorage
m_NavigationToolStorage = nullptr;
}
}
else
{
// reset button to unchecked
m_Controls->connectButton->setChecked(false);
MITK_ERROR<<"Could not create TrackingDevice";
}
}
else // Disconnect tracking device
{
// disconnect TrackingDeviceSource
if (m_TrackingDeviceSource.IsNotNull())
{
m_TrackingDeviceSource->StopTracking();
m_TrackingDeviceSource->Disconnect();
}
// remove tool nodes from DataStorage
this->RemoveToolNodes();
// reset members
m_NavigationToolStorage = nullptr;
m_TrackingDevice = nullptr;
m_TrackingDeviceSource = nullptr;
// change button text
m_Controls->connectButton->setText("Connect");
// enable configuration widget
m_Controls->trackingDeviceConfigurationWidget->setEnabled(true);
// emit disconnected signal
emit TrackingDeviceDisconnected();
}
}
bool QmitkIGTConnectionWidget::LoadToolfile(QString qFilename)
{
if (m_DataStorage.IsNotNull())
{
std::string filename = qFilename.toStdString();
mitk::NavigationToolStorageDeserializer::Pointer myDeserializer = mitk::NavigationToolStorageDeserializer::New(this->m_DataStorage);
mitk::NavigationToolStorage::Pointer tempStorage = myDeserializer->Deserialize(filename);
m_NavigationToolStorage = tempStorage;
if (tempStorage.IsNull())
{
m_ErrorMessage = myDeserializer->GetErrorMessage();
return false;
}
// check if there are tools in the storage
mitk::TrackingDeviceType lastDevice;
if (tempStorage->GetToolCount()>0)
{
lastDevice = tempStorage->GetTool(0)->GetTrackingDeviceType();
}
else
{
m_ErrorMessage = "Error: Didn't find a tool in the storage. Do you want to navigate without even an instrument?";
return false;
}
//check if all tools are from the same device
- for (int i=1; iGetToolCount(); i++)
+ for (unsigned int i=1; iGetToolCount(); i++)
{
if (lastDevice!=tempStorage->GetTool(i)->GetTrackingDeviceType())
{
m_ErrorMessage = "Error: Toolfile contains tools of different tracking devices which is not acceptable for this application.";
return false;
}
else lastDevice = tempStorage->GetTool(i)->GetTrackingDeviceType();
}
// check if tracking device typ of tools corresponds with chosen tracking device
if (m_TrackingDevice->GetType()!=tempStorage->GetTool(0)->GetTrackingDeviceType())
{
m_ErrorMessage = "Tools are not compliant with this tracking device. Please use correct toolfile for specified device.";
return false;
}
m_NavigationToolStorage = tempStorage;
return true;
}
else
{
m_ErrorMessage = "Error: No DataStorage available! Make sure the widget is initialized with a DataStorage";
return false;
}
}
void QmitkIGTConnectionWidget::RemoveToolNodes()
{
- for (int i=0; iGetToolCount(); i++)
+ for (unsigned int i=0; iGetToolCount(); i++)
{
mitk::DataNode::Pointer currentNode = m_NavigationToolStorage->GetTool(i)->GetDataNode();
if (currentNode.IsNotNull())
{
m_DataStorage->Remove(currentNode);
}
}
}
mitk::TrackingDeviceSource::Pointer QmitkIGTConnectionWidget::GetTrackingDeviceSource()
{
return m_TrackingDeviceSource;
}
void QmitkIGTConnectionWidget::SetDataStorage( mitk::DataStorage::Pointer dataStorage )
{
m_DataStorage = dataStorage;
}
mitk::NavigationToolStorage::Pointer QmitkIGTConnectionWidget::GetNavigationToolStorage()
{
return m_NavigationToolStorage;
}
diff --git a/Modules/IGTUI/Qmitk/QmitkInteractiveTransformationWidget.cpp b/Modules/IGTUI/Qmitk/QmitkInteractiveTransformationWidget.cpp
index ce2de57c70..f994bf2fdc 100644
--- a/Modules/IGTUI/Qmitk/QmitkInteractiveTransformationWidget.cpp
+++ b/Modules/IGTUI/Qmitk/QmitkInteractiveTransformationWidget.cpp
@@ -1,287 +1,300 @@
/*===================================================================
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 "QmitkInteractiveTransformationWidget.h"
// mitk includes
#include "mitkRenderingManager.h"
+#include "mitkBaseRenderer.h"
#include "mitkNavigationData.h"
// vtk includes
#include "vtkMatrix4x4.h"
#include "vtkLinearTransform.h"
const std::string QmitkInteractiveTransformationWidget::VIEW_ID = "org.mitk.views.interactivetransformationwidget";
QmitkInteractiveTransformationWidget::QmitkInteractiveTransformationWidget(QWidget* parent, Qt::WindowFlags f)
-: QWidget(parent, f), m_Controls(nullptr), m_Geometry(nullptr), m_ResetGeometry(nullptr)
+ : QDialog(parent, f), m_Controls(nullptr), m_Geometry(nullptr)
{
CreateQtPartControl(this);
CreateConnections();
- m_TranslationVector.Fill(0.0f);
- m_RotateSliderPos.Fill(0.0f);
+
+ m_ResetGeometry = mitk::Geometry3D::New();
+
+
+ this->setWindowTitle("Edit Tool Tip and Tool Orientation");
}
QmitkInteractiveTransformationWidget::~QmitkInteractiveTransformationWidget()
{
}
void QmitkInteractiveTransformationWidget::CreateQtPartControl(QWidget *parent)
{
if (!m_Controls)
{
// create GUI widgets
m_Controls = new Ui::QmitkInteractiveTransformationWidgetControls;
m_Controls->setupUi(parent);
}
}
void QmitkInteractiveTransformationWidget::CreateConnections()
{
- if ( m_Controls )
+ if (m_Controls)
{
// translations
- connect( (QObject*)(m_Controls->m_XTransSlider), SIGNAL(valueChanged(int)), this, SLOT(OnXTranslationValueChanged(int)) );
- connect( (QObject*)(m_Controls->m_XTransSpinBox), SIGNAL(valueChanged(int)), this, SLOT(OnXTranslationValueChanged(int)) );
- connect( (QObject*)(m_Controls->m_YTransSlider), SIGNAL(valueChanged(int)), this, SLOT(OnYTranslationValueChanged(int)) );
- connect( (QObject*)(m_Controls->m_YTransSpinBox), SIGNAL(valueChanged(int)), this, SLOT(OnYTranslationValueChanged(int)) );
- connect( (QObject*)(m_Controls->m_ZTransSlider), SIGNAL(valueChanged(int)), this, SLOT(OnZTranslationValueChanged(int)) );
- connect( (QObject*)(m_Controls->m_ZTransSpinBox), SIGNAL(valueChanged(int)), this, SLOT(OnZTranslationValueChanged(int)) );
+ connect(m_Controls->m_XTransSpinBox, static_cast(&QDoubleSpinBox::valueChanged), this, &QmitkInteractiveTransformationWidget::OnXTranslationValueChanged);
+ connect(m_Controls->m_XTransSlider, &QSlider::valueChanged, this, &QmitkInteractiveTransformationWidget::OnXTranslationValueChanged);
+
+ connect(m_Controls->m_YTransSpinBox, static_cast(&QDoubleSpinBox::valueChanged), this, &QmitkInteractiveTransformationWidget::OnYTranslationValueChanged);
+ connect(m_Controls->m_YTransSlider, &QSlider::valueChanged, this, &QmitkInteractiveTransformationWidget::OnYTranslationValueChanged);
+
+ connect(m_Controls->m_ZTransSpinBox, static_cast(&QDoubleSpinBox::valueChanged), this, &QmitkInteractiveTransformationWidget::OnZTranslationValueChanged);
+ connect(m_Controls->m_ZTransSlider, &QSlider::valueChanged, this, &QmitkInteractiveTransformationWidget::OnZTranslationValueChanged);
// rotations
- connect( (QObject*)(m_Controls->m_XRotSlider), SIGNAL(valueChanged(int)), this, SLOT(OnXRotationValueChanged(int)) );
- connect( (QObject*)(m_Controls->m_XRotSpinBox), SIGNAL(valueChanged(int)), this, SLOT(OnXRotationValueChanged(int)) );
- connect( (QObject*)(m_Controls->m_YRotSlider), SIGNAL(valueChanged(int)), this, SLOT(OnYRotationValueChanged(int)) );
- connect( (QObject*)(m_Controls->m_YRotSpinBox), SIGNAL(valueChanged(int)), this, SLOT(OnYRotationValueChanged(int)) );
- connect( (QObject*)(m_Controls->m_ZRotSlider), SIGNAL(valueChanged(int)), this, SLOT(OnZRotationValueChanged(int)) );
- connect( (QObject*)(m_Controls->m_ZRotSpinBox), SIGNAL(valueChanged(int)), this, SLOT(OnZRotationValueChanged(int)) );
-
- connect( (QObject*)(m_Controls->m_ResetPB), SIGNAL(clicked()), this, SLOT(OnResetGeometry()) );
- connect( (QObject*)(m_Controls->m_UseManipulatedToolTipPB), SIGNAL(clicked()), this, SLOT(OnApplyManipulatedToolTip()) );
+ connect(m_Controls->m_XRotSpinBox, static_cast(&QDoubleSpinBox::valueChanged), this, &QmitkInteractiveTransformationWidget::OnXRotationValueChanged);
+ connect(m_Controls->m_XRotSlider, &QSlider::valueChanged, this, &QmitkInteractiveTransformationWidget::OnXRotationValueChanged);
+
+ connect(m_Controls->m_YRotSpinBox, static_cast(&QDoubleSpinBox::valueChanged), this, &QmitkInteractiveTransformationWidget::OnYRotationValueChanged);
+ connect(m_Controls->m_YRotSlider, &QSlider::valueChanged, this, &QmitkInteractiveTransformationWidget::OnYRotationValueChanged);
+
+ connect(m_Controls->m_ZRotSpinBox, static_cast(&QDoubleSpinBox::valueChanged), this, &QmitkInteractiveTransformationWidget::OnZRotationValueChanged);
+ connect(m_Controls->m_ZRotSlider, &QSlider::valueChanged, this, &QmitkInteractiveTransformationWidget::OnZRotationValueChanged);
+
+ connect((QObject*)(m_Controls->m_ResetPB), SIGNAL(clicked()), this, SLOT(OnResetGeometryToIdentity()));
+ connect((QObject*)(m_Controls->m_RevertChanges), SIGNAL(clicked()), this, SLOT(OnRevertChanges()));
+ connect((QObject*)(m_Controls->m_UseManipulatedToolTipPB), SIGNAL(clicked()), this, SLOT(OnApplyManipulatedToolTip()));
+ connect((QObject*)(m_Controls->m_Cancel), SIGNAL(clicked()), this, SLOT(OnCancel()));
}
}
-void QmitkInteractiveTransformationWidget::SetGeometry( mitk::BaseGeometry::Pointer geometry, mitk::BaseGeometry::Pointer defaultValues )
+void QmitkInteractiveTransformationWidget::SetToolToEdit(const mitk::NavigationTool::Pointer _tool)
{
- m_Geometry = geometry;
- m_ResetGeometry = geometry->Clone();
-
- //set default values
- if (defaultValues.IsNotNull())
- {
- //first: some conversion
- mitk::NavigationData::Pointer transformConversionHelper = mitk::NavigationData::New(defaultValues->GetIndexToWorldTransform());
- double eulerAlphaDegrees = transformConversionHelper->GetOrientation().rotation_euler_angles()[0] / vnl_math::pi * 180;
- double eulerBetaDegrees = transformConversionHelper->GetOrientation().rotation_euler_angles()[1] / vnl_math::pi * 180;
- double eulerGammaDegrees = transformConversionHelper->GetOrientation().rotation_euler_angles()[2] / vnl_math::pi * 180;
-
- //set translation
- OnXTranslationValueChanged(defaultValues->GetIndexToWorldTransform()->GetOffset()[0]);
- OnYTranslationValueChanged(defaultValues->GetIndexToWorldTransform()->GetOffset()[1]);
- OnZTranslationValueChanged(defaultValues->GetIndexToWorldTransform()->GetOffset()[2]);
-
- //set rotation
- OnXRotationValueChanged(eulerAlphaDegrees);
- OnYRotationValueChanged(eulerBetaDegrees);
- OnZRotationValueChanged(eulerGammaDegrees);
- }
- else
- {
- //reset everything
- OnXTranslationValueChanged(0);
- OnYTranslationValueChanged(0);
- OnZTranslationValueChanged(0);
- OnXRotationValueChanged(0);
- OnYRotationValueChanged(0);
- OnZRotationValueChanged(0);
- }
+ //If there is already a tool, remove it's node first.
+ if (m_ToolToEdit)
+ mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget4"))->GetDataStorage()
+ ->Remove(m_ToolToEdit->GetDataNode());
+
+ m_ToolToEdit = _tool->Clone();
+ mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget4"))->GetDataStorage()
+ ->Add(m_ToolToEdit->GetDataNode());
+ m_ToolToEdit->GetDataNode()->SetName("Tool Tip to be edited");
+
+ //change color to red
+ m_ToolToEdit->GetDataNode()->SetProperty("color", mitk::ColorProperty::New(1, 0, 0));
+
+ //use the set-fuction via vtk matrix, 'cause this garantees a deep copy and not just sharing a pointer.
+ m_Geometry = m_ToolToEdit->GetDataNode()->GetData()->GetGeometry();
+ m_ResetGeometry->SetIndexToWorldTransformByVtkMatrix(m_Geometry->GetVtkMatrix()); //Remember the original values to be able to reset and abort everything
}
-mitk::BaseGeometry::Pointer QmitkInteractiveTransformationWidget::GetGeometry()
+void QmitkInteractiveTransformationWidget::SetDefaultOffset(const mitk::Point3D _defaultValues)
{
- return m_Geometry;
+ m_Geometry->SetOrigin(_defaultValues);
+ m_ResetGeometry->SetOrigin(_defaultValues); //Remember the original values to be able to reset and abort everything
+ SetValuesToGUI(m_Geometry->GetIndexToWorldTransform());
}
+void QmitkInteractiveTransformationWidget::SetDefaultRotation(const mitk::Quaternion _defaultValues)
+{
+ // Conversion to navigation data / transform
+ mitk::NavigationData::Pointer rotationTransform = mitk::NavigationData::New(m_Geometry->GetIndexToWorldTransform());
+ rotationTransform->SetOrientation(_defaultValues);
+ m_Geometry->SetIndexToWorldTransform(rotationTransform->GetAffineTransform3D());
+ //For ResetGeometry, use the set-fuction via vtk matrix, 'cause this garantees a deep copy and not just sharing a pointer.
+ m_ResetGeometry->SetIndexToWorldTransformByVtkMatrix(m_Geometry->GetVtkMatrix()); //Remember the original values to be able to reset and abort everything
+ SetValuesToGUI(m_Geometry->GetIndexToWorldTransform());
+}
+void QmitkInteractiveTransformationWidget::SetValuesToGUI(const mitk::AffineTransform3D::Pointer _defaultValues)
+{
+ //Set toolTip values in gui
+ m_Controls->m_XTransSlider->setValue(_defaultValues->GetOffset()[0]);
+ m_Controls->m_YTransSlider->setValue(_defaultValues->GetOffset()[1]);
+ m_Controls->m_ZTransSlider->setValue(_defaultValues->GetOffset()[2]);
-/////////////////////////////////////////////////////////////////////////////////////////////
-// Section to allow interactive positioning of the moving surface
-/////////////////////////////////////////////////////////////////////////////////////////////
+ //first: some conversion
+ mitk::NavigationData::Pointer transformConversionHelper = mitk::NavigationData::New(_defaultValues);
+ double eulerAlphaDegrees = transformConversionHelper->GetOrientation().rotation_euler_angles()[0] / vnl_math::pi * 180;
+ double eulerBetaDegrees = transformConversionHelper->GetOrientation().rotation_euler_angles()[1] / vnl_math::pi * 180;
+ double eulerGammaDegrees = transformConversionHelper->GetOrientation().rotation_euler_angles()[2] / vnl_math::pi * 180;
-void QmitkInteractiveTransformationWidget::OnXTranslationValueChanged( int v )
-{
- mitk::Vector3D translationParams;
- translationParams[0] = v;
- translationParams[1] = m_Controls->m_YTransSlider->value();
- translationParams[2] = m_Controls->m_ZTransSlider->value();
- SetSliderX(v);
- this->Translate(translationParams);
-}
+ m_Controls->m_XRotSpinBox->setValue(eulerAlphaDegrees);
+ m_Controls->m_YRotSpinBox->setValue(eulerBetaDegrees);
+ m_Controls->m_ZRotSpinBox->setValue(eulerGammaDegrees);
-void QmitkInteractiveTransformationWidget::SetSliderX(int v)
-{
- m_Controls->m_XTransSlider->setValue(v);
- m_Controls->m_XTransSpinBox->setValue(v);
+ //Update view
+ mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
-void QmitkInteractiveTransformationWidget::OnYTranslationValueChanged( int v )
+void QmitkInteractiveTransformationWidget::SetSynchronizedVauesToSliderAndSpinbox(QDoubleSpinBox* _spinbox, QSlider* _slider, double _value)
{
- mitk::Vector3D translationParams;
- translationParams[0] = m_Controls->m_XTransSlider->value();
- translationParams[1] = v;
- translationParams[2] = m_Controls->m_ZTransSlider->value();
- SetSliderY(v);
- this->Translate(translationParams);
+//block signals to avoid loop between slider and spinbox. Unblock at the end of the function!
+ _spinbox->blockSignals(true);
+ _slider->blockSignals(true);
+ _spinbox->setValue(_value);
+ _slider->setValue(_value);
+//unblock signals. See above, don't remove this line. Unblock at the end of the function!
+ _spinbox->blockSignals(false);//
+ _slider->blockSignals(false);//
}
-void QmitkInteractiveTransformationWidget::SetSliderY(int v)
+void QmitkInteractiveTransformationWidget::OnXTranslationValueChanged(double v)
{
- m_Controls->m_YTransSlider->setValue(v);
- m_Controls->m_YTransSpinBox->setValue(v);
-}
+ //Set values to member variable
+ mitk::Point3D translationParams = m_Geometry->GetOrigin();
+ translationParams[0] = v;
+ m_Geometry->SetOrigin(translationParams);
+
+ SetSynchronizedVauesToSliderAndSpinbox(m_Controls->m_XTransSpinBox, m_Controls->m_XTransSlider, v);
+
+ //Update view
+ mitk::RenderingManager::GetInstance()->RequestUpdateAll();
-void QmitkInteractiveTransformationWidget::OnZTranslationValueChanged( int v )
-{
- mitk::Vector3D translationParams;
- translationParams[0] = m_Controls->m_XTransSlider->value();
- translationParams[1] = m_Controls->m_YTransSlider->value();
- translationParams[2] = v;
- SetSliderZ(v);
- this->Translate(translationParams);
}
-void QmitkInteractiveTransformationWidget::SetSliderZ(int v)
+void QmitkInteractiveTransformationWidget::OnYTranslationValueChanged(double v)
{
- m_Controls->m_ZTransSlider->setValue(v);
- m_Controls->m_ZTransSpinBox->setValue(v);
+ //Set values to member variable
+ mitk::Point3D translationParams = m_Geometry->GetOrigin();
+ translationParams[1] = v;
+ m_Geometry->SetOrigin(translationParams);
+
+ SetSynchronizedVauesToSliderAndSpinbox(m_Controls->m_YTransSpinBox, m_Controls->m_YTransSlider, v);
+
+ //Update view
+ mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
-void QmitkInteractiveTransformationWidget::Translate( mitk::Vector3D translateVector)
+void QmitkInteractiveTransformationWidget::OnZTranslationValueChanged(double v)
{
- mitk::Vector3D translateVec;
-
- // transform the translation vector
- translateVec[0] = translateVector[0] - m_TranslationVector[0];
- translateVec[1] = translateVector[1] - m_TranslationVector[1];
- translateVec[2] = translateVector[2] - m_TranslationVector[2];
+ //Set values to member variable
+ mitk::Point3D translationParams = m_Geometry->GetOrigin();
+ translationParams[2] = v;
+ m_Geometry->SetOrigin(translationParams);
- // set the new translation vector to member variable
- m_TranslationVector[0] = translateVector[0];
- m_TranslationVector[1] = translateVector[1];
- m_TranslationVector[2] = translateVector[2];
+ SetSynchronizedVauesToSliderAndSpinbox(m_Controls->m_ZTransSpinBox, m_Controls->m_ZTransSlider, v);
- m_Geometry->Translate( translateVec );
- qApp->processEvents();
+ //Update view
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
-void QmitkInteractiveTransformationWidget::OnXRotationValueChanged( int v )
+void QmitkInteractiveTransformationWidget::OnXRotationValueChanged(double v)
{
mitk::Vector3D rotationParams;
rotationParams[0] = v;
- rotationParams[1] = m_Controls->m_YRotSlider->value();
- rotationParams[2] = m_Controls->m_ZRotSlider->value();
+ rotationParams[1] = m_Controls->m_YRotSpinBox->value();
+ rotationParams[2] = m_Controls->m_ZRotSpinBox->value();
- m_Controls->m_XRotSlider->setValue(v);
- m_Controls->m_XRotSpinBox->setValue(v);
+ SetSynchronizedVauesToSliderAndSpinbox(m_Controls->m_XRotSpinBox, m_Controls->m_XRotSlider, v);
this->Rotate(rotationParams);
}
-void QmitkInteractiveTransformationWidget::OnYRotationValueChanged( int v )
+void QmitkInteractiveTransformationWidget::OnYRotationValueChanged(double v)
{
mitk::Vector3D rotationParams;
- rotationParams[0] = m_Controls->m_XRotSlider->value();
+ rotationParams[0] = m_Controls->m_XRotSpinBox->value();
rotationParams[1] = v;
- rotationParams[2] = m_Controls->m_ZRotSlider->value();
+ rotationParams[2] = m_Controls->m_ZRotSpinBox->value();
- m_Controls->m_YRotSlider->setValue(v);
- m_Controls->m_YRotSpinBox->setValue(v);
+ SetSynchronizedVauesToSliderAndSpinbox(m_Controls->m_YRotSpinBox, m_Controls->m_YRotSlider, v);
this->Rotate(rotationParams);
}
-void QmitkInteractiveTransformationWidget::OnZRotationValueChanged( int v )
+void QmitkInteractiveTransformationWidget::OnZRotationValueChanged(double v)
{
mitk::Vector3D rotationParams;
- rotationParams[0]=m_Controls->m_XRotSlider->value();
- rotationParams[1]=m_Controls->m_YRotSlider->value();
- rotationParams[2]=v;
- m_Controls->m_ZRotSlider->setValue(v);
- m_Controls->m_ZRotSpinBox->setValue(v);
+ rotationParams[0] = m_Controls->m_XRotSpinBox->value();
+ rotationParams[1] = m_Controls->m_YRotSpinBox->value();
+ rotationParams[2] = v;
+
+ SetSynchronizedVauesToSliderAndSpinbox(m_Controls->m_ZRotSpinBox, m_Controls->m_ZRotSlider, v);
this->Rotate(rotationParams);
}
void QmitkInteractiveTransformationWidget::Rotate(mitk::Vector3D rotateVector)
{
//0: from degrees to radians
double radianX = rotateVector[0] * vnl_math::pi / 180;
double radianY = rotateVector[1] * vnl_math::pi / 180;
double radianZ = rotateVector[2] * vnl_math::pi / 180;
//1: from euler angles to quaternion
- mitk::Quaternion rotation(radianX,radianY,radianZ);
+ mitk::Quaternion rotation(radianX, radianY, radianZ);
//2: Conversion to navigation data / transform
- mitk::NavigationData::Pointer rotationTransform = mitk::NavigationData::New();
+ mitk::NavigationData::Pointer rotationTransform = mitk::NavigationData::New(m_Geometry->GetIndexToWorldTransform());
rotationTransform->SetOrientation(rotation);
- //3: Apply transform
+ m_Geometry->SetIndexToWorldTransform(rotationTransform->GetAffineTransform3D());
- //also remember old transform, but without rotation, because rotation is completely stored in the sliders
- mitk::NavigationData::Pointer oldTransform = mitk::NavigationData::New(m_Geometry->GetIndexToWorldTransform());
- mitk::Quaternion identity(0,0,0,1);
- oldTransform->SetOrientation(identity);
+ mitk::RenderingManager::GetInstance()->RequestUpdateAll();
+}
- //compose old transform with the new one
- rotationTransform->Compose(oldTransform);
+void QmitkInteractiveTransformationWidget::OnResetGeometryToIdentity()
+{
+ // reset the input to its initial state.
+ m_Geometry->SetIdentity();
- //and apply it...
- m_Geometry->SetIndexToWorldTransform(rotationTransform->GetAffineTransform3D());
- qApp->processEvents();
+ //Update Sliders
+ this->SetValuesToGUI(m_Geometry->GetIndexToWorldTransform());
+ //Refresh view
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
-void QmitkInteractiveTransformationWidget::OnResetGeometry()
+void QmitkInteractiveTransformationWidget::OnRevertChanges()
{
- m_Controls->m_XRotSlider->setValue(0);
- m_Controls->m_YRotSlider->setValue(0);
- m_Controls->m_ZRotSlider->setValue(0);
- m_Controls->m_XRotSpinBox->setValue(0);
- m_Controls->m_YRotSpinBox->setValue(0);
- m_Controls->m_ZRotSpinBox->setValue(0);
-
- m_Controls->m_XTransSlider->setValue(0);
- m_Controls->m_YTransSlider->setValue(0);
- m_Controls->m_ZTransSlider->setValue(0);
- m_Controls->m_XTransSpinBox->setValue(0);
- m_Controls->m_YTransSpinBox->setValue(0);
- m_Controls->m_ZTransSpinBox->setValue(0);
- qApp->processEvents();
-
// reset the input to its initial state.
- m_Geometry->SetIdentity();
- m_Geometry->Compose(m_ResetGeometry->GetVtkTransform()->GetMatrix());
+ m_Geometry->SetIndexToWorldTransformByVtkMatrix(m_ResetGeometry->GetVtkMatrix());
+
+ //Update Sliders
+ this->SetValuesToGUI(m_Geometry->GetIndexToWorldTransform());
+ //Refresh view
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkInteractiveTransformationWidget::OnApplyManipulatedToolTip()
{
- emit ApplyManipulatedToolTip();
+ mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget4"))->GetDataStorage()
+ ->Remove(m_ToolToEdit->GetDataNode());
+
+ mitk::AffineTransform3D::Pointer toolTip = m_Geometry->GetIndexToWorldTransform();
+ emit EditToolTipFinished(toolTip);
+ this->close();
+}
+
+void QmitkInteractiveTransformationWidget::reject()
+{
+ OnCancel();
}
+
+void QmitkInteractiveTransformationWidget::OnCancel()
+{
+ QDialog::reject();
+
+ mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget4"))->GetDataStorage()
+ ->Remove(m_ToolToEdit->GetDataNode());
+
+ emit EditToolTipFinished(nullptr);
+}
\ No newline at end of file
diff --git a/Modules/IGTUI/Qmitk/QmitkInteractiveTransformationWidget.h b/Modules/IGTUI/Qmitk/QmitkInteractiveTransformationWidget.h
index f4a93e5f95..bbab6d819d 100644
--- a/Modules/IGTUI/Qmitk/QmitkInteractiveTransformationWidget.h
+++ b/Modules/IGTUI/Qmitk/QmitkInteractiveTransformationWidget.h
@@ -1,94 +1,102 @@
/*===================================================================
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 QmitkInteractiveTransformationWidget_H
#define QmitkInteractiveTransformationWidget_H
//QT headers
-#include
+#include
//Mitk headers
#include "MitkIGTUIExports.h"
#include "mitkVector.h"
#include "mitkGeometry3D.h"
+#include "mitkNavigationTool.h"
//ui header
#include "ui_QmitkInteractiveTransformationWidgetControls.h"
/** Documentation:
* \brief An object of this class offers an UI to create a widget to access the advance tool creation options.
*
*
* \ingroup IGTUI
*/
-class MITKIGTUI_EXPORT QmitkInteractiveTransformationWidget : public QWidget
+class MITKIGTUI_EXPORT QmitkInteractiveTransformationWidget : public QDialog
{
Q_OBJECT
public:
static const std::string VIEW_ID;
QmitkInteractiveTransformationWidget(QWidget* parent = nullptr, Qt::WindowFlags f = nullptr);
~QmitkInteractiveTransformationWidget() override;
- /** Sets the geometry which will be modified by this widget. Default values may be
- * provided by the second variable. These values will be applied to the geometry
- * in the beginning and the UI will also hold these values.
+ /** This tool will be copied to m_ToolToEdit. It will not be changed.
+ To apply any changes made by this widget, you will need to connect to the signal
+ EditToolTipFinished(mitk::AffineTransform3D::Pointer toolTip) and set this transfrom
+ as calibrated tool tip.
+ We do not directly modify the tool to allow to cancel/exit this widget without doing
+ any harm.
*/
- void SetGeometry(mitk::BaseGeometry::Pointer geometry, mitk::BaseGeometry::Pointer defaultValues = nullptr);
+ void SetToolToEdit(const mitk::NavigationTool::Pointer _tool);
- mitk::BaseGeometry::Pointer GetGeometry();
+ /** The sliders and spinboxes will be set to these values.
+ When clicking "Revert Changes", sliders will be reseted to these values.
+ */
+ void SetDefaultOffset(const mitk::Point3D _defaultValues);
+ void SetDefaultRotation(const mitk::Quaternion _defaultValues);
protected slots:
- void OnZTranslationValueChanged( int v );
- void OnYTranslationValueChanged( int v );
- void OnXTranslationValueChanged( int v );
- void OnZRotationValueChanged( int v );
- void OnYRotationValueChanged( int v );
- void OnXRotationValueChanged( int v );
- void OnResetGeometry();
+ void OnZTranslationValueChanged( double v );
+ void OnYTranslationValueChanged(double v);
+ void OnXTranslationValueChanged(double v);
+ void OnZRotationValueChanged(double v);
+ void OnYRotationValueChanged(double v);
+ void OnXRotationValueChanged(double v);
+ void OnResetGeometryToIdentity();
+ void OnRevertChanges();
void OnApplyManipulatedToolTip();
+ void OnCancel();
signals:
- void ApplyManipulatedToolTip();
+ void EditToolTipFinished(mitk::AffineTransform3D::Pointer toolTip);
protected:
+ void reject();
+
virtual void CreateConnections();
virtual void CreateQtPartControl(QWidget *parent);
- void SetSliderX(int v);
- void SetSliderY(int v);
- void SetSliderZ(int v);
-
- /*! \brief Method performs the translation.
- \params translateVector New translation to be combine with geometry. */
- void Translate( mitk::Vector3D translateVector);
-
/*! \brief Method performs the rotation.
\params rotateVector New rotation to be combined with geometry. */
void Rotate(mitk::Vector3D rotateVector);
// Member variables
Ui::QmitkInteractiveTransformationWidgetControls* m_Controls;
- mitk::BaseGeometry::Pointer m_Geometry; ///< \brief Initial geometry that is manipulated
- mitk::BaseGeometry::Pointer m_ResetGeometry; ///< \brief Lifeline to reset to the initial geometry
- mitk::Vector3D m_TranslationVector; ///< \brief Accumulated translation vector
- mitk::Vector3D m_RotateSliderPos; ///< \brief Accumulated rotation vector (holds degree around x,y,z direction)
+ mitk::NavigationTool::Pointer m_ToolToEdit; ///< \brief this mamber holds a copy of the tool that should be edited for visualization
+ mitk::BaseGeometry::Pointer m_Geometry; ///< \brief The geometry that is manipulated
+ mitk::BaseGeometry::Pointer m_ResetGeometry; ///< \brief Lifeline to reset to the original geometry
+
+private:
+ void SetValuesToGUI(const mitk::AffineTransform3D::Pointer _defaultValues);
+ void SetSynchronizedVauesToSliderAndSpinbox(QDoubleSpinBox* _spinbox, QSlider* _slider, double _value);
+
};
#endif // QmitkInteractiveTransformationWidget_H
diff --git a/Modules/IGTUI/Qmitk/QmitkInteractiveTransformationWidgetControls.ui b/Modules/IGTUI/Qmitk/QmitkInteractiveTransformationWidgetControls.ui
index 62f0938a91..6daf485458 100644
--- a/Modules/IGTUI/Qmitk/QmitkInteractiveTransformationWidgetControls.ui
+++ b/Modules/IGTUI/Qmitk/QmitkInteractiveTransformationWidgetControls.ui
@@ -1,433 +1,463 @@