diff --git a/Modules/US/USNavigation/Filter/mitkNeedleProjectionFilter.cpp b/Modules/US/USNavigation/Filter/mitkNeedleProjectionFilter.cpp index ba4897ef7f..7d43ea6c10 100644 --- a/Modules/US/USNavigation/Filter/mitkNeedleProjectionFilter.cpp +++ b/Modules/US/USNavigation/Filter/mitkNeedleProjectionFilter.cpp @@ -1,184 +1,190 @@ /*=================================================================== 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" // VTK #include mitk::NeedleProjectionFilter::NeedleProjectionFilter() : m_Projection(mitk::PointSet::New()), m_OriginalPoints(mitk::PointSet::New()), - m_SelectedInput(-1) + m_SelectedInput(-1), + m_ShowToolAxis(false) { // Tool Coordinates:x axis is chosen as default axis when no axis is specified MITK_DEBUG << "Constructor called"; - mitk::Point3D point; - point.SetElement(0, 1 * 400); - point.SetElement(1, 0 * 400); - point.SetElement(2, 0 * 400); - m_OriginalPoints->InsertPoint(point); - - mitk::Point3D point1; - point1.SetElement(0, 0 * 400); - point1.SetElement(1, 0 * 400); - point1.SetElement(2, 0 * 400); - m_OriginalPoints->InsertPoint(point1); - - mitk::Point3D point2; - point2.SetElement(0, -1 * 400); - point2.SetElement(1, 0 * 400); - point2.SetElement(2, 0 * 400); - m_OriginalPoints->InsertPoint(point2); + mitk::Point3D toolAxis; + mitk::FillVector3D(toolAxis, 1, 0, 0); + 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::SetToolAxisForFilter(mitk::Point3D point) +void mitk::NeedleProjectionFilter::InitializeOriginalPoints(mitk::Point3D toolAxis, bool showToolAxis) { - m_startPoint.SetElement(0, point.GetElement(0) * 400); - m_startPoint.SetElement(1, point.GetElement(1) * 400); - m_startPoint.SetElement(2, point.GetElement(2) * 400); - m_OriginalPoints->SetPoint(0, m_startPoint); + 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); - m_endPoint.SetElement(0, point.GetElement(0) * -400); - m_endPoint.SetElement(1, point.GetElement(1) * -400); - m_endPoint.SetElement(2, point.GetElement(2) * -400); - m_OriginalPoints->SetPoint(1, m_endPoint); + mitk::Point3D toolOrigin; + toolOrigin.SetElement(0, 0); + toolOrigin.SetElement(1, 0); + toolOrigin.SetElement(2, 0); + m_OriginalPoints->InsertPoint(toolOrigin); + + if (showToolAxis) + { + 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::SetToolAxisForFilter(mitk::Point3D point) +{ + InitializeOriginalPoints(point, 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)); - m_Projection->SetPoint(2, m_OriginalPoints->GetPoint(2)); - //m_Projection->SetPoint(2, m_OriginalPoints->GetPoint(2)); + 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(1)[0], m_OriginalPoints->GetPoint(1)[1], m_OriginalPoints->GetPoint(1)[2]}; - double p2[3] = {m_OriginalPoints->GetPoint(2)[0], m_OriginalPoints->GetPoint(2)[1], m_OriginalPoints->GetPoint(2)[2]}; + 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(2, 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/US/USNavigation/Filter/mitkNeedleProjectionFilter.h index 14b3cb1913..17bc1b40e0 100644 --- a/Modules/US/USNavigation/Filter/mitkNeedleProjectionFilter.h +++ b/Modules/US/USNavigation/Filter/mitkNeedleProjectionFilter.h @@ -1,89 +1,96 @@ /*=================================================================== 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 // 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 */ class MITKUSNAVIGATION_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; - - mitk::Point3D m_startPoint; - mitk::Point3D m_endPoint; + bool m_ShowToolAxis; 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