diff --git a/Modules/IGT/Rendering/mitkNavigationDataObjectVisualizationFilter.cpp b/Modules/IGT/Rendering/mitkNavigationDataObjectVisualizationFilter.cpp index 413a67888f..930c473485 100644 --- a/Modules/IGT/Rendering/mitkNavigationDataObjectVisualizationFilter.cpp +++ b/Modules/IGT/Rendering/mitkNavigationDataObjectVisualizationFilter.cpp @@ -1,243 +1,256 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkNavigationDataObjectVisualizationFilter.h" #include "mitkDataStorage.h" - +#include mitk::NavigationDataObjectVisualizationFilter::NavigationDataObjectVisualizationFilter() -: NavigationDataToNavigationDataFilter(), -m_RepresentationList(), m_TransformPosition(), m_TransformOrientation(), m_RotationMode(RotationStandard) + : NavigationDataToNavigationDataFilter(), + m_RepresentationVectorMap(), + m_TransformPosition(), + m_TransformOrientation(), + m_RotationMode(RotationStandard) { - } - mitk::NavigationDataObjectVisualizationFilter::~NavigationDataObjectVisualizationFilter() { - m_RepresentationList.clear(); + m_RepresentationVectorMap.clear(); m_OffsetList.clear(); } +mitk::BaseData::Pointer mitk::NavigationDataObjectVisualizationFilter::GetRepresentationObject(unsigned int idx) const +{ + auto iter = m_RepresentationVectorMap.find(idx); + if (iter != m_RepresentationVectorMap.end()) + return iter->second.at(0); + + return nullptr; +} -const mitk::BaseData* mitk::NavigationDataObjectVisualizationFilter::GetRepresentationObject(unsigned int idx) +std::vector mitk::NavigationDataObjectVisualizationFilter::GetAllRepresentationObjects(unsigned int idx) const { - RepresentationPointerMap::const_iterator iter = m_RepresentationList.find(idx); - if (iter != m_RepresentationList.end()) + RepresentationVectorPointerMap::const_iterator iter = m_RepresentationVectorMap.find(idx); + if (iter != m_RepresentationVectorMap.end()) return iter->second; - return nullptr; + std::vector empty; + return empty; } mitk::AffineTransform3D::Pointer mitk::NavigationDataObjectVisualizationFilter::GetOffset(int index) { OffsetPointerMap::const_iterator iter = m_OffsetList.find(index); if (iter != m_OffsetList.end()) return iter->second; return nullptr; } +void mitk::NavigationDataObjectVisualizationFilter::SetRepresentationObject(unsigned int idx, BaseData::Pointer data) +{ + std::vector dataVector; + dataVector.push_back(data); + SetRepresentationObjects(idx, dataVector); +} -void mitk::NavigationDataObjectVisualizationFilter::SetRepresentationObject(unsigned int idx, BaseData* data) +void mitk::NavigationDataObjectVisualizationFilter::SetRepresentationObjects(unsigned int idx, const std::vector &data) { - m_RepresentationList[idx] = RepresentationPointer(data); + m_RepresentationVectorMap[idx] = data; } void mitk::NavigationDataObjectVisualizationFilter::SetOffset(int index, mitk::AffineTransform3D::Pointer offset) { -m_OffsetList[index] = offset; + m_OffsetList[index] = offset; } - void mitk::NavigationDataObjectVisualizationFilter::SetRotationMode(RotationMode r) { m_RotationMode = r; } - void mitk::NavigationDataObjectVisualizationFilter::GenerateData() { /*get each input, lookup the associated BaseData and transfer the data*/ - DataObjectPointerArray inputs = this->GetInputs(); //get all inputs - for (unsigned int index=0; index < inputs.size(); index++) + DataObjectPointerArray inputs = this->GetInputs(); // get all inputs + for (unsigned int index = 0; index < inputs.size(); index++) { - //get the needed variables - const mitk::NavigationData* nd = this->GetInput(index); + // get the needed variables + const mitk::NavigationData *nd = this->GetInput(index); assert(nd); - mitk::NavigationData* output = this->GetOutput(index); + mitk::NavigationData *output = this->GetOutput(index); assert(output); - //check if the data is valid + // check if the data is valid if (!nd->IsDataValid()) { output->SetDataValid(false); continue; } output->Graft(nd); // copy all information from input to output - const mitk::BaseData* data = this->GetRepresentationObject(index); - if (data == nullptr) - { - MITK_WARN << "No BaseData associated with input " << index; - continue; - } - //get the transform from data - mitk::AffineTransform3D::Pointer affineTransform = data->GetGeometry()->GetIndexToWorldTransform(); - if (affineTransform.IsNull()) + const std::vector data = + this->GetAllRepresentationObjects(index); + + for (unsigned int dataIdx = 0; dataIdx < data.size(); dataIdx++) { - MITK_WARN << "AffineTransform IndexToWorldTransform not initialized!"; - continue; - } + if (data.at(dataIdx) == nullptr) + { + MITK_WARN << "No BaseData associated with input " << index; + continue; + } + + // get the transform from data + mitk::AffineTransform3D::Pointer affineTransform = data.at(dataIdx)->GetGeometry()->GetIndexToWorldTransform(); + if (affineTransform.IsNull()) + { + MITK_WARN << "AffineTransform IndexToWorldTransform not initialized!"; + continue; + } - //check for offset - mitk::AffineTransform3D::Pointer offset = this->GetOffset(index); + // check for offset + mitk::AffineTransform3D::Pointer offset = this->GetOffset(index); - //store the current scaling to set it after transformation - mitk::Vector3D spacing = data->GetGeometry()->GetSpacing(); - //clear spacing of data to be able to set it again afterwards - ScalarType scale[] = {1.0, 1.0, 1.0}; - data->GetGeometry()->SetSpacing(scale); + // store the current scaling to set it after transformation + mitk::Vector3D spacing = data.at(dataIdx)->GetGeometry()->GetSpacing(); + // clear spacing of data to be able to set it again afterwards + ScalarType scale[] = {1.0, 1.0, 1.0}; + data.at(dataIdx)->GetGeometry()->SetSpacing(scale); - /*now bring quaternion to affineTransform by using vnl_Quaternion*/ - affineTransform->SetIdentity(); + /*now bring quaternion to affineTransform by using vnl_Quaternion*/ + affineTransform->SetIdentity(); - if (this->GetTransformOrientation(index) == true) - { - mitk::NavigationData::OrientationType orientation = nd->GetOrientation(); + if (this->GetTransformOrientation(index) == true) + { + mitk::NavigationData::OrientationType orientation = nd->GetOrientation(); - /* 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; + /* 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; - //convert quaternion to rotation matrix depending on the rotation mode - if(m_RotationMode == RotationStandard) + // convert quaternion to rotation matrix depending on the rotation mode + if (m_RotationMode == RotationStandard) { - //calculate the transform from the quaternions - static itk::QuaternionRigidTransform::Pointer quatTransform = itk::QuaternionRigidTransform::New(); - // 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(); - mitk::TransferMatrix(quatTransform->GetMatrix(), m); + // calculate the transform from the quaternions + static itk::QuaternionRigidTransform::Pointer quatTransform = + itk::QuaternionRigidTransform::New(); + // 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(); + mitk::TransferMatrix(quatTransform->GetMatrix(), m); } - else if(m_RotationMode == RotationTransposed) + else if (m_RotationMode == RotationTransposed) { - vnl_matrix_fixed rot = orientation.rotation_matrix_transpose(); - for(int i=0; i<3; i++) for (int j=0; j<3; j++) m[i][j] = rot[i][j]; + vnl_matrix_fixed rot = orientation.rotation_matrix_transpose(); + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + m[i][j] = rot[i][j]; } - affineTransform->SetMatrix(m); - - } - if (this->GetTransformPosition(index) == true) - { - ///*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(); - + affineTransform->SetMatrix(m); + } + if (this->GetTransformPosition(index) == true) + { + ///*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(); - //set the transform to data - if(offset.IsNotNull()) //first use offset if there is one. + // set the transform to data + if (offset.IsNotNull()) // first use offset if there is one. { - mitk::AffineTransform3D::Pointer overallTransform = mitk::AffineTransform3D::New(); - overallTransform->SetIdentity(); - overallTransform->Compose(offset); - overallTransform->Compose(affineTransform); - data->GetGeometry()->SetIndexToWorldTransform(overallTransform); + mitk::AffineTransform3D::Pointer overallTransform = mitk::AffineTransform3D::New(); + overallTransform->SetIdentity(); + overallTransform->Compose(offset); + overallTransform->Compose(affineTransform); + data.at(dataIdx)->GetGeometry()->SetIndexToWorldTransform(overallTransform); } - else + else { - data->GetGeometry()->SetIndexToWorldTransform(affineTransform); + data.at(dataIdx)->GetGeometry()->SetIndexToWorldTransform(affineTransform); } - //set the original spacing to keep scaling of the geometrical object - data->GetGeometry()->SetSpacing(spacing); - data->GetGeometry()->Modified(); - data->Modified(); - output->SetDataValid(true); // operation was successful, therefore data of output is valid. + // set the original spacing to keep scaling of the geometrical object + data.at(dataIdx)->GetGeometry()->SetSpacing(spacing); + data.at(dataIdx)->GetGeometry()->Modified(); + data.at(dataIdx)->Modified(); + output->SetDataValid(true); // operation was successful, therefore data of output is valid. + } } } - -void mitk::NavigationDataObjectVisualizationFilter::SetTransformPosition( unsigned int index, bool applyTransform ) +void mitk::NavigationDataObjectVisualizationFilter::SetTransformPosition(unsigned int index, bool applyTransform) { itkDebugMacro("setting TransformPosition for index " << index << " to " << applyTransform); BooleanInputMap::const_iterator it = this->m_TransformPosition.find(index); if ((it != this->m_TransformPosition.end()) && (it->second == applyTransform)) return; this->m_TransformPosition[index] = applyTransform; this->Modified(); } - -bool mitk::NavigationDataObjectVisualizationFilter::GetTransformPosition( unsigned int index ) const +bool mitk::NavigationDataObjectVisualizationFilter::GetTransformPosition(unsigned int index) const { itkDebugMacro("returning TransformPosition for index " << index); BooleanInputMap::const_iterator it = this->m_TransformPosition.find(index); if (it != this->m_TransformPosition.end()) return it->second; else return true; // default to true } - -void mitk::NavigationDataObjectVisualizationFilter::TransformPositionOn( unsigned int index ) +void mitk::NavigationDataObjectVisualizationFilter::TransformPositionOn(unsigned int index) { this->SetTransformPosition(index, true); } - -void mitk::NavigationDataObjectVisualizationFilter::TransformPositionOff( unsigned int index ) +void mitk::NavigationDataObjectVisualizationFilter::TransformPositionOff(unsigned int index) { this->SetTransformPosition(index, false); } - -void mitk::NavigationDataObjectVisualizationFilter::SetTransformOrientation( unsigned int index, bool applyTransform ) +void mitk::NavigationDataObjectVisualizationFilter::SetTransformOrientation(unsigned int index, bool applyTransform) { itkDebugMacro("setting TransformOrientation for index " << index << " to " << applyTransform); BooleanInputMap::const_iterator it = this->m_TransformOrientation.find(index); if ((it != this->m_TransformOrientation.end()) && (it->second == applyTransform)) return; this->m_TransformOrientation[index] = applyTransform; - this->Modified(); \ + this->Modified(); } - -bool mitk::NavigationDataObjectVisualizationFilter::GetTransformOrientation( unsigned int index ) const +bool mitk::NavigationDataObjectVisualizationFilter::GetTransformOrientation(unsigned int index) const { itkDebugMacro("returning TransformOrientation for index " << index); BooleanInputMap::const_iterator it = this->m_TransformOrientation.find(index); if (it != this->m_TransformOrientation.end()) return it->second; else return true; // default to true } - -void mitk::NavigationDataObjectVisualizationFilter::TransformOrientationOn( unsigned int index ) +void mitk::NavigationDataObjectVisualizationFilter::TransformOrientationOn(unsigned int index) { this->SetTransformOrientation(index, true); } - -void mitk::NavigationDataObjectVisualizationFilter::TransformOrientationOff( unsigned int index ) +void mitk::NavigationDataObjectVisualizationFilter::TransformOrientationOff(unsigned int index) { this->SetTransformOrientation(index, false); } diff --git a/Modules/IGT/Rendering/mitkNavigationDataObjectVisualizationFilter.h b/Modules/IGT/Rendering/mitkNavigationDataObjectVisualizationFilter.h index bbfd2df5ba..42871e0337 100644 --- a/Modules/IGT/Rendering/mitkNavigationDataObjectVisualizationFilter.h +++ b/Modules/IGT/Rendering/mitkNavigationDataObjectVisualizationFilter.h @@ -1,153 +1,176 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef MITKNAVIGATIONDATAOBJECTVISUALIZATIONFILTER_H_HEADER_INCLUDED_ #define MITKNAVIGATIONDATAOBJECTVISUALIZATIONFILTER_H_HEADER_INCLUDED_ #include "mitkNavigationDataToNavigationDataFilter.h" #include "mitkNavigationData.h" #include "mitkBaseData.h" namespace mitk { /** * \brief Class that reads NavigationData from input and transfers the information to the geometry of the associated BaseData * * Derived from NavigationDataToNavigationDataFilter * * \ingroup IGT */ class MITKIGT_EXPORT NavigationDataObjectVisualizationFilter : public NavigationDataToNavigationDataFilter { public: mitkClassMacro(NavigationDataObjectVisualizationFilter, NavigationDataToNavigationDataFilter); itkFactorylessNewMacro(Self); itkCloneMacro(Self); /** 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}; /** * \brief Smart Pointer type to a BaseData. */ - typedef BaseData::ConstPointer RepresentationPointer; + typedef BaseData::Pointer RepresentationPointer; /** - * \brief STL map of index to BaseData . Using map to be able to set non continuous indices - */ + * \brief STL map of index to BaseData . Using map to be able to set non continuous indices + */ typedef std::map RepresentationPointerMap; /** - * \brief Size type of an std::vector + * \brief STL vector map of index to BaseData . Using map to be able to set non continuous indices */ - typedef RepresentationPointerMap::size_type RepresentationPointerMapSizeType; + typedef std::map> RepresentationVectorPointerMap; + + /** + * \brief Size type of an std::vector + */ + typedef RepresentationVectorPointerMap::size_type RepresentationPointerMapSizeType; /** * \brief Set the representation object of the input * * \param data The BaseData to be associated to the index * \param index the index with which data will be associated */ - void SetRepresentationObject(unsigned int index, BaseData* data); + void SetRepresentationObject(unsigned int index, BaseData::Pointer data); + /** + * \brief Set the representation objects vector of the input + * + * \param data The BaseData vector to be associated to the index + * \param index the index with which data will be associated + */ + void SetRepresentationObjects(unsigned int index, const std::vector &data); + /** * \brief Get the representation object associated with the index idx * * \param idx the corresponding input number with which the BaseData is associated * \return Returns the desired BaseData if it exists for the given input; Returns nullptr * if no BaseData was found. */ - const BaseData* GetRepresentationObject(unsigned int idx); + BaseData::Pointer GetRepresentationObject(unsigned int idx) const; + + /** + * \brief Get all the representation objects associated with the index idx + * + * \param idx the corresponding input number with which the BaseData is associated + * \return Returns the desired BaseData if it exists for the given input; Returns nullptr + * if no BaseData was found. + */ + std::vector GetAllRepresentationObjects(unsigned int idx) const; virtual void SetTransformPosition(unsigned int index, bool applyTransform); ///< if set to true, the filter will use the position part of the input navigation data at the given index to transform the representation object. If set to false, it will not. If no value is set, it defaults to true. virtual bool GetTransformPosition(unsigned int index) const; ///< returns whether position part of the input navigation data at the given index is used for the transformation of the representation object. virtual void TransformPositionOn(unsigned int index); ///< sets the TransformPosition flag to true for the given index virtual void TransformPositionOff(unsigned int index); ///< sets the TransformPosition flag to false for the given index virtual void SetTransformOrientation(unsigned int index, bool applyTransform); ///< if set to true, the filter will use the orientation part of the input navigation data at the given index to transform the representation object. If set to false, it will not. If no value is set, it defaults to true. virtual bool GetTransformOrientation(unsigned int index) const; ///< returns whether orientation part of the input navigation data at the given index is used for the transformation of the representation object. virtual void TransformOrientationOn(unsigned int index); ///< sets the TransformOrientation flag to true for the given index virtual void TransformOrientationOff(unsigned int index); ///< sets the TransformOrientation flag to false for the given index /** @brief Defines an offset for a representation object. This offset is applied before the object is visualized. * If no offset is given, no offset will be used. To deactivate the offset just set it to nullptr. The offset is deactivated by default. * @param offset The new offset which will be set. Set to nullptr to deactivate the offset. */ void SetOffset(int index, mitk::AffineTransform3D::Pointer offset); /** Sets the rotation mode of this class. See documentation of enum RotationMode for details * on the different modes. * 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 offset of a represenation object. Returns nullptr if there is no offset. */ mitk::AffineTransform3D::Pointer GetOffset(int index); /** *\brief Get the number of added BaseData associated to NavigationData * \return Returns the size of the internal map */ RepresentationPointerMapSizeType GetNumberOfToolRepresentations() const { - return m_RepresentationList.size(); + return m_RepresentationVectorMap.size(); } /* * \brief Transfer the information from the input to the associated BaseData */ void GenerateData() override; protected: typedef std::map BooleanInputMap; typedef std::map OffsetPointerMap; /** * \brief Constructor **/ NavigationDataObjectVisualizationFilter(); /** * \brief Destructor **/ ~NavigationDataObjectVisualizationFilter() override; /** * \brief An array of the BaseData which represent the tools. */ - RepresentationPointerMap m_RepresentationList; + + RepresentationVectorPointerMap m_RepresentationVectorMap; BooleanInputMap m_TransformPosition; ///< if set to true, the filter will use the position part of the input navigation data at the given index for the calculation of the transform. If no entry for the index exists, it defaults to true. BooleanInputMap m_TransformOrientation; ///< if set to true, the filter will use the orientation part of the input navigation data at the given index for the calculation of the transform. If no entry for the index exists, it defaults to true. OffsetPointerMap m_OffsetList; private: RotationMode m_RotationMode; ///< defines the rotation mode Standard or Transposed, Standard is default }; } // namespace mitk #endif /* MITKNAVIGATIONDATAOBJECTVISUALIZATIONFILTER_H_HEADER_INCLUDED_ */ diff --git a/Modules/IGT/Testing/mitkNavigationDataObjectVisualizationFilterTest.cpp b/Modules/IGT/Testing/mitkNavigationDataObjectVisualizationFilterTest.cpp index ef5726e4bc..2163f6531a 100644 --- a/Modules/IGT/Testing/mitkNavigationDataObjectVisualizationFilterTest.cpp +++ b/Modules/IGT/Testing/mitkNavigationDataObjectVisualizationFilterTest.cpp @@ -1,433 +1,458 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkNavigationDataObjectVisualizationFilter.h" #include "mitkNavigationData.h" #include "mitkTestingMacros.h" #include #include #include #include #include "mitkSurface.h" /**Documentation * test for the class "NavigationDataObjectVisualizationFilter". */ class mitkNavigationDataObjectVisualizationFilterTestSuite : public mitk::TestFixture { // List of Tests CPPUNIT_TEST_SUITE(mitkNavigationDataObjectVisualizationFilterTestSuite); //Constructor MITK_TEST(TestInitialize); MITK_TEST(TestInput); MITK_TEST(TestOutput); MITK_TEST(TestRepresentationObjects); MITK_TEST(TestTransforms); MITK_TEST(TestMessWithRepresentationObjects); MITK_TEST(TestThirdInput); MITK_TEST(TestSetTransformPosition); MITK_TEST(TestSetTransformOrientation); MITK_TEST(TestConvenienceSetTransformOrientation); MITK_TEST(TestUpdateOrientation); CPPUNIT_TEST_SUITE_END(); // Used Variables private: mitk::NavigationDataObjectVisualizationFilter::Pointer myFilter; mitk::NavigationData::PositionType initialPos1, initialPos2; mitk::NavigationData::OrientationType initialOri1; mitk::NavigationData::OrientationType initialOri2; mitk::ScalarType initialError1; mitk::ScalarType initialError2; bool initialValid1; bool initialValid2; mitk::NavigationData::Pointer nd1; mitk::NavigationData::Pointer nd2; // Test setting BaseData - mitk::Surface::Pointer mitkToolData1 ; - - mitk::Surface::Pointer mitkToolData2 ; + mitk::Surface::Pointer mitkToolData1; + std::vector mitkToolVectorData1; + mitk::Surface::Pointer mitkToolData2; + std::vector mitkToolVectorData2; //dummy for test; will not be set but used to test find - mitk::Surface::Pointer mitkToolDataDummy ; + mitk::Surface::Pointer mitkToolDataDummy; + std::vector mitkToolVectorDataDummy; //and the Dummy NavigationData for this mitk::NavigationData::OrientationType initialOriDummy; mitk::NavigationData::PositionType initialPosDummy; mitk::ScalarType initialErrorDummy; bool initialValidDummy; mitk::NavigationData::Pointer ndDummy ; mitk::NavigationData* output; mitk::AffineTransform3D::Pointer affineTransform1; mitk::AffineTransform3D::OutputVectorType offset1; mitk::AffineTransform3D::Pointer affineTransform2; mitk::AffineTransform3D::OutputVectorType offset2; mitk::AffineTransform3D::MatrixType::InternalMatrixType m1; mitk::AffineTransform3D::MatrixType::InternalMatrixType m2; public: // Set up for variables void setUp() override { // -------------- Setup for Filter --------------------------- /* create helper objects: navigation data with position as origin, zero quaternion, zero error and data valid */ myFilter = mitk::NavigationDataObjectVisualizationFilter::New(); mitk::FillVector3D(initialPos1, 1.1, 2.2, 3.3); mitk::FillVector3D(initialPos2, 5.0, 6.0, 7.0); mitk::FillVector4D(initialOri1, 0.1, 0.2, 0.3, 0.4); mitk::FillVector4D(initialOri2,0.5, 0.6, 0.7, 0.8); initialError1=0.0; initialError2=5.0; initialValid1 = true; initialValid2 = true; //Set Navigation Data nd1 = mitk::NavigationData::New(); nd1->SetPosition(initialPos1); nd1->SetOrientation(initialOri1); nd1->SetPositionAccuracy(initialError1); nd1->SetDataValid(initialValid1); nd2 = mitk::NavigationData::New(); nd2->SetPosition(initialPos2); nd2->SetOrientation(initialOri2); nd2->SetPositionAccuracy(initialError2); nd2->SetDataValid(initialValid2); //Set Input myFilter->SetInput(nd1); myFilter->SetInput(1, nd2); output = myFilter->GetOutput(); // -------------------------- Setup for TestData ---------------------- // Test setting BaseData mitkToolData1 = mitk::Surface::New(); mitkToolData2 = mitk::Surface::New(); + // Test setting BaseData vectors + mitkToolVectorData1.push_back(mitkToolData1.GetPointer()); + mitkToolVectorData2.push_back(mitkToolData2.GetPointer()); + //dummy for test; will not be set but used to test find mitkToolDataDummy = mitk::Surface::New(); + mitkToolVectorDataDummy.push_back(mitkToolDataDummy.GetPointer()); //and the Dummy NavigationData for this mitk::FillVector3D(initialPosDummy, 8.8, 9.9, 10.10); mitk::FillVector4D(initialOriDummy,1.1, 2.2, 3.3, 4.4); initialErrorDummy=10.0; initialValidDummy=true; ndDummy = mitk::NavigationData::New(); ndDummy->SetPosition(initialPosDummy); ndDummy->SetOrientation(initialOriDummy); ndDummy->SetPositionAccuracy(initialErrorDummy); ndDummy->SetDataValid(initialValidDummy); //now we have ndDummy and mitkToolDataDummy to test with } void tearDown() override { } // Test functions void TestInitialize(){ // first test: did this work? CPPUNIT_ASSERT_MESSAGE("Testing instantiation", myFilter.IsNotNull()); } void TestInput(){ //testing the input CPPUNIT_ASSERT_MESSAGE("Testing Set-/GetInput() input 1 without index",myFilter->GetInput() == nd1); CPPUNIT_ASSERT_MESSAGE("Testing Set-/GetInput() input 1", myFilter->GetInput(0) == nd1); CPPUNIT_ASSERT_MESSAGE( "Testing Set-/GetInput() input 2", myFilter->GetInput(1) == nd2); CPPUNIT_ASSERT_MESSAGE("Testing GetNumberOfToolRepresentations()", myFilter->GetNumberOfToolRepresentations() == 0); } void TestOutput(){ //testing getting the output CPPUNIT_ASSERT_MESSAGE("Testing GetOutput()", output != nullptr); CPPUNIT_ASSERT_MESSAGE("Testing GetOutput() == GetOutput()", output == myFilter->GetOutput()); CPPUNIT_ASSERT_MESSAGE("Testing GetOutput() != GetOutput(1)", output != myFilter->GetOutput(1)); } void TestRepresentationObjects(){ //setting nodes - myFilter->SetRepresentationObject(0, mitkToolData1); + myFilter->SetRepresentationObject(0, mitkToolData1.GetPointer()); CPPUNIT_ASSERT_MESSAGE( "Testing SetRepresentationObject()/GetRepresentationObject() node 1", myFilter->GetRepresentationObject(0) == mitkToolData1); CPPUNIT_ASSERT_MESSAGE("Testing GetNumberOfToolRepresentations() after adding first tool", myFilter->GetNumberOfToolRepresentations() == 1); - myFilter->SetRepresentationObject(1, mitkToolData2); + myFilter->SetRepresentationObject(1, mitkToolData2.GetPointer()); CPPUNIT_ASSERT_MESSAGE( "Testing SetRepresentationObject() node 2", myFilter->GetRepresentationObject(1) == mitkToolData2); CPPUNIT_ASSERT_MESSAGE( "Testing GetNumberOfToolRepresentations() after adding second tool", myFilter->GetNumberOfToolRepresentations() == 2); //getting nodes CPPUNIT_ASSERT_MESSAGE("Testing GetRepresentationObject() node 1", myFilter->GetRepresentationObject(0) == mitkToolData1); CPPUNIT_ASSERT_MESSAGE( "Testing GetRepresentationObject() != Dummy node", myFilter->GetRepresentationObject(0) != mitkToolDataDummy); CPPUNIT_ASSERT_MESSAGE( "Testing GetRepresentationObject() node 2", myFilter->GetRepresentationObject(1) == mitkToolData2); CPPUNIT_ASSERT_MESSAGE( "Testing GetRepresentationObject() != Dummy node", myFilter->GetRepresentationObject(1) != mitkToolDataDummy); CPPUNIT_ASSERT_MESSAGE("Testing GetRepresentationObject() with out of range parameter", myFilter->GetRepresentationObject(111) == nullptr); } + void TestAllRepresentationObjects() + { + // setting nodes + myFilter->SetRepresentationObjects(0, mitkToolVectorData1); + CPPUNIT_ASSERT_MESSAGE("Testing SetRepresentationObject()/GetRepresentationObject() node 1", myFilter->GetAllRepresentationObjects(0) == mitkToolVectorData1); + CPPUNIT_ASSERT_MESSAGE("Testing GetNumberOfToolRepresentations() after adding first tool", myFilter->GetNumberOfToolRepresentations() == 1); + + myFilter->SetRepresentationObjects(1, mitkToolVectorData2); + CPPUNIT_ASSERT_MESSAGE("Testing SetRepresentationObject() node 2", myFilter->GetAllRepresentationObjects(1) == mitkToolVectorData2); + CPPUNIT_ASSERT_MESSAGE("Testing GetNumberOfToolRepresentations() after adding second tool", myFilter->GetNumberOfToolRepresentations() == 2); + // getting nodes + CPPUNIT_ASSERT_MESSAGE("Testing GetRepresentationObject() node 1", myFilter->GetAllRepresentationObjects(0) == mitkToolVectorData1); + CPPUNIT_ASSERT_MESSAGE("Testing GetRepresentationObject() != Dummy node", myFilter->GetAllRepresentationObjects(0) != mitkToolVectorDataDummy); + CPPUNIT_ASSERT_MESSAGE("Testing GetRepresentationObject() node 2", myFilter->GetAllRepresentationObjects(1) == mitkToolVectorData2); + CPPUNIT_ASSERT_MESSAGE("Testing GetRepresentationObject() != Dummy node", myFilter->GetAllRepresentationObjects(1) != mitkToolVectorDataDummy); + CPPUNIT_ASSERT_MESSAGE("Testing GetRepresentationObject() with out of range parameter", myFilter->GetAllRepresentationObjects(111).empty() == true); + } + void TestTransforms(){ - myFilter->SetRepresentationObject(0, mitkToolData1); - myFilter->SetRepresentationObject(1, mitkToolData2); + myFilter->SetRepresentationObject(0, mitkToolData1.GetPointer()); + myFilter->SetRepresentationObject(1, mitkToolData2.GetPointer()); //Process myFilter->Update(); affineTransform1 = mitkToolData1->GetGeometry()->GetIndexToWorldTransform(); offset1 = affineTransform1->GetOffset(); affineTransform2 = mitkToolData2->GetGeometry()->GetIndexToWorldTransform(); offset2 = affineTransform2->GetOffset(); m1 = affineTransform1->GetMatrix().GetVnlMatrix(); m2 = affineTransform2->GetMatrix().GetVnlMatrix(); //now check it there are data connected to the nodes with the according orientation and offsets CPPUNIT_ASSERT_MESSAGE("Testing Offset position 1", offset1.GetVnlVector()==initialPos1.GetVnlVector()); CPPUNIT_ASSERT_MESSAGE("Testing Offset position 2", offset2.GetVnlVector()==initialPos2.GetVnlVector()); MITK_TEST_OUTPUT( << "\n initOrient1="<GetVnlMatrix():\n "<< m1); MITK_TEST_OUTPUT( << "\n initOrient2=" << initialOri2 << " affineTransform2->GetVnlMatrix():\n " << m2); } void TestMessWithRepresentationObjects(){ - myFilter->SetRepresentationObject(0, mitkToolData1); - myFilter->SetRepresentationObject(1, mitkToolData2); + myFilter->SetRepresentationObject(0, mitkToolData1.GetPointer()); + myFilter->SetRepresentationObject(1, mitkToolData2.GetPointer()); //Process myFilter->Update(); affineTransform1 = mitkToolData1->GetGeometry()->GetIndexToWorldTransform(); offset1 = affineTransform1->GetOffset(); affineTransform2 = mitkToolData2->GetGeometry()->GetIndexToWorldTransform(); offset2 = affineTransform2->GetOffset(); m1 = affineTransform1->GetMatrix().GetVnlMatrix(); m2 = affineTransform2->GetMatrix().GetVnlMatrix(); //messing with SetRepresentationObject //setting nodes - myFilter->SetRepresentationObject(0, mitkToolData2); + myFilter->SetRepresentationObject(0, mitkToolData2.GetPointer()); CPPUNIT_ASSERT_MESSAGE("Twisting mitkToolData by using SetRepresentationObject() NavigationData 1 with ToolData 2", myFilter->GetRepresentationObject(0) == mitkToolData2); CPPUNIT_ASSERT_MESSAGE( "Testing GetNumberOfToolRepresentations() == 1", myFilter->GetNumberOfToolRepresentations() == 2); - myFilter->SetRepresentationObject(1, mitkToolData1); + myFilter->SetRepresentationObject(1, mitkToolData1.GetPointer()); CPPUNIT_ASSERT_MESSAGE("Twisting mitkToolData by using SetRepresentationObject() NavigationData 2 with ToolData 1", myFilter->GetRepresentationObject(1) == mitkToolData1); CPPUNIT_ASSERT_MESSAGE( "Testing GetNumberOfToolRepresentations() == 2", myFilter->GetNumberOfToolRepresentations() == 2); //getting nodes CPPUNIT_ASSERT_MESSAGE("Testing switched BaseData of NavigationData 1 ", myFilter->GetRepresentationObject(0) == mitkToolData2); CPPUNIT_ASSERT_MESSAGE("Testing GetRepresentationObject() != Dummy node", myFilter->GetRepresentationObject(0) != mitkToolDataDummy); CPPUNIT_ASSERT_MESSAGE("Testing switched BaseData NavigationData 2", myFilter->GetRepresentationObject(1) == mitkToolData1); CPPUNIT_ASSERT_MESSAGE("Testing GetRepresentationObject() != Dummy node", myFilter->GetRepresentationObject(1) != mitkToolDataDummy); //processing update through pipeline myFilter->Update(); //now check it there are data connected to the nodes with the according orientation and offsets mitk::AffineTransform3D::Pointer affineTransform1Second = mitkToolData1->GetGeometry()->GetIndexToWorldTransform(); CPPUNIT_ASSERT_MESSAGE( "Testing affineTransform1 after second update", affineTransform1 == affineTransform1Second); mitk::AffineTransform3D::OutputVectorType offset1Second = affineTransform1->GetOffset(); CPPUNIT_ASSERT_MESSAGE( "Testing offset1 after second update", offset1 == offset1Second); CPPUNIT_ASSERT_MESSAGE("Testing offset1 equals first update", offset1Second.GetVnlVector()==offset1.GetVnlVector()); mitk::AffineTransform3D::Pointer affineTransform2Second = mitkToolData2->GetGeometry()->GetIndexToWorldTransform(); CPPUNIT_ASSERT_MESSAGE("Testing affineTransform2 after second update", affineTransform2 == affineTransform2Second); mitk::AffineTransform3D::OutputVectorType offset2Second = affineTransform2->GetOffset(); CPPUNIT_ASSERT_MESSAGE("Testing offset2 after second update", offset2 == offset2Second); CPPUNIT_ASSERT_MESSAGE("Testing offset2 equals first update", offset2Second.GetVnlVector()==offset2.GetVnlVector()); mitk::AffineTransform3D::MatrixType::InternalMatrixType m1Second= affineTransform1Second->GetMatrix().GetVnlMatrix(); MITK_TEST_OUTPUT( <<"\n after second update initOrient1="<GetVnlMatrix():\n "<< m1Second); mitk::AffineTransform3D::MatrixType::InternalMatrixType m2Second= affineTransform2Second->GetMatrix().GetVnlMatrix(); MITK_TEST_OUTPUT( << "\n after second update initOrient2="<GetVnlMatrix():\n "<< m2Second); } void TestThirdInput(){ - myFilter->SetRepresentationObject(0, mitkToolData1); - myFilter->SetRepresentationObject(1, mitkToolData2); + myFilter->SetRepresentationObject(0, mitkToolData1.GetPointer()); + myFilter->SetRepresentationObject(1, mitkToolData2.GetPointer()); //Process myFilter->Update(); //testing adding a third input myFilter->SetInput(2,ndDummy); CPPUNIT_ASSERT_MESSAGE("Adding new input and testing GetNumberOfInputs == 3", myFilter->GetNumberOfInputs() == 3); CPPUNIT_ASSERT_MESSAGE("testing GetNumberOfOutputs == 3", myFilter->GetNumberOfOutputs() == 3); CPPUNIT_ASSERT_MESSAGE("Testing Input == newly added input", myFilter->GetInput(2) == ndDummy); CPPUNIT_ASSERT_MESSAGE("Testing GetOutput(2) != nullptr", myFilter->GetOutput(2) != nullptr); CPPUNIT_ASSERT_MESSAGE( "Testing GetOutput(2) != GetOutput(1)", myFilter->GetOutput(2) != myFilter->GetOutput(1)); - myFilter->SetRepresentationObject(2, mitkToolDataDummy); + myFilter->SetRepresentationObject(2, mitkToolDataDummy.GetPointer()); CPPUNIT_ASSERT_MESSAGE("Testing GetNumberOfToolRepresentations() after adding latest tool", myFilter->GetNumberOfToolRepresentations() == 3); CPPUNIT_ASSERT_MESSAGE("Testing Set-/GetRepresentationObject() equals was set", myFilter->GetRepresentationObject(2) == mitkToolDataDummy); //last time processing update through pipeline myFilter->Update(); //now check for the new values mitk::AffineTransform3D::Pointer affineTransformDummy = mitkToolDataDummy->GetGeometry()->GetIndexToWorldTransform(); mitk::AffineTransform3D::OutputVectorType offsetDummy = affineTransformDummy->GetOffset(); CPPUNIT_ASSERT_MESSAGE("Testing Offset latest added tool", offsetDummy.GetVnlVector()==initialPosDummy.GetVnlVector()); mitk::AffineTransform3D::MatrixType::InternalMatrixType m1Latest= affineTransformDummy->GetMatrix().GetVnlMatrix(); MITK_TEST_OUTPUT( << "\n latest initOrient="<GetVnlMatrix():\n "<< m1Latest); mitk::Surface::Pointer anotherSurface = mitk::Surface::New(); - myFilter->SetRepresentationObject(0, anotherSurface); + myFilter->SetRepresentationObject(0, anotherSurface.GetPointer()); CPPUNIT_ASSERT_MESSAGE("Overwriting BaseData index 0", myFilter->GetRepresentationObject(0) == anotherSurface); } void TestSetTransformPosition(){ // test Set/GetTransformPosition() myFilter->SetTransformPosition(0,true); CPPUNIT_ASSERT_MESSAGE("test Set/GetTransformPosition(0,true)", myFilter->GetTransformPosition(0)==true); myFilter->SetTransformPosition(1,true); CPPUNIT_ASSERT_MESSAGE("test Set/GetTransformPosition(1,true)", myFilter->GetTransformPosition(1)==true); myFilter->SetTransformPosition(2,true); CPPUNIT_ASSERT_MESSAGE("test Set/GetTransformPosition(2,true)", myFilter->GetTransformPosition(2)==true); myFilter->SetTransformPosition(3,true); CPPUNIT_ASSERT_MESSAGE("test Set/GetTransformPosition(3,true)", myFilter->GetTransformPosition(3)==true); myFilter->SetTransformPosition(0,false); CPPUNIT_ASSERT_MESSAGE("test Set/GetTransformPosition(0,false)", myFilter->GetTransformPosition(0)==false); myFilter->SetTransformPosition(1,false); CPPUNIT_ASSERT_MESSAGE("test Set/GetTransformPosition(1,false)", myFilter->GetTransformPosition(1)==false); myFilter->SetTransformPosition(2,false); CPPUNIT_ASSERT_MESSAGE("test Set/GetTransformPosition(2,false)", myFilter->GetTransformPosition(2)==false); myFilter->SetTransformPosition(3,false); CPPUNIT_ASSERT_MESSAGE("test Set/GetTransformPosition(3,false)", myFilter->GetTransformPosition(3)==false); } void TestSetTransformOrientation(){ // test Set/GetTransformOrientation() myFilter->SetTransformOrientation(0,true); CPPUNIT_ASSERT_MESSAGE("test Set/GetTransformOrientation(0,true)", myFilter->GetTransformOrientation(0)==true); myFilter->SetTransformOrientation(1,true); CPPUNIT_ASSERT_MESSAGE("test Set/GetTransformOrientation(1,true)", myFilter->GetTransformOrientation(1)==true); myFilter->SetTransformOrientation(2,true); CPPUNIT_ASSERT_MESSAGE("test Set/GetTransformOrientation(2,true)", myFilter->GetTransformOrientation(2)==true); myFilter->SetTransformOrientation(3,true); CPPUNIT_ASSERT_MESSAGE("test Set/GetTransformOrientation(3,true)", myFilter->GetTransformOrientation(3)==true); myFilter->SetTransformOrientation(0,false); CPPUNIT_ASSERT_MESSAGE("test Set/GetTransformOrientation(0,false)", myFilter->GetTransformOrientation(0)==false); myFilter->SetTransformOrientation(1,false); CPPUNIT_ASSERT_MESSAGE("test Set/GetTransformOrientation(1,false)", myFilter->GetTransformOrientation(1)==false); myFilter->SetTransformOrientation(2,false); CPPUNIT_ASSERT_MESSAGE("test Set/GetTransformOrientation(2,false)", myFilter->GetTransformOrientation(2)==false); myFilter->SetTransformOrientation(3,false); CPPUNIT_ASSERT_MESSAGE("test Set/GetTransformOrientation(3,false)", myFilter->GetTransformOrientation(3)==false); } void TestConvenienceSetTransformOrientation(){ // test the convenience methods to set/getTransformOrientation/Position myFilter->TransformOrientationOn(0); CPPUNIT_ASSERT_MESSAGE("test TransformOrientationOn()", myFilter->GetTransformOrientation(0)==true); myFilter->TransformOrientationOff(0); CPPUNIT_ASSERT_MESSAGE("test TransformOrientationOff()", myFilter->GetTransformOrientation(0)==false); myFilter->TransformOrientationOff(1); CPPUNIT_ASSERT_MESSAGE("test TransformOrientationOff()", myFilter->GetTransformOrientation(1)==false); myFilter->TransformOrientationOn(1); CPPUNIT_ASSERT_MESSAGE("test TransformOrientationOn()", myFilter->GetTransformOrientation(1)==true); myFilter->TransformOrientationOn(2); CPPUNIT_ASSERT_MESSAGE("test TransformOrientationOn()", myFilter->GetTransformOrientation(2)==true); myFilter->TransformOrientationOff(2); CPPUNIT_ASSERT_MESSAGE("test TransformOrientationOff()", myFilter->GetTransformOrientation(2)==false); myFilter->TransformOrientationOn(3); CPPUNIT_ASSERT_MESSAGE("test TransformOrientationOn()", myFilter->GetTransformOrientation(3)==true); myFilter->TransformOrientationOff(3); CPPUNIT_ASSERT_MESSAGE("test TransformOrientationOff()", myFilter->GetTransformOrientation(3)==false); myFilter->TransformPositionOn(0); CPPUNIT_ASSERT_MESSAGE("test TransformPositionOn()", myFilter->GetTransformPosition(0)==true); myFilter->TransformPositionOff(0); CPPUNIT_ASSERT_MESSAGE("test TransformPositionOff()", myFilter->GetTransformPosition(0)==false); myFilter->TransformPositionOff(1); CPPUNIT_ASSERT_MESSAGE("test TransformPositionOff()", myFilter->GetTransformPosition(1)==false); myFilter->TransformPositionOn(1); CPPUNIT_ASSERT_MESSAGE("test TransformPositionOn()", myFilter->GetTransformPosition(1)==true); myFilter->TransformPositionOn(2); CPPUNIT_ASSERT_MESSAGE("test TransformPositionOn()", myFilter->GetTransformPosition(2)==true); myFilter->TransformPositionOff(2); CPPUNIT_ASSERT_MESSAGE("test TransformPositionOff()", myFilter->GetTransformPosition(2)==false); myFilter->TransformPositionOn(3); CPPUNIT_ASSERT_MESSAGE("test TransformPositionOn()", myFilter->GetTransformPosition(3)==true); myFilter->TransformPositionOff(3); CPPUNIT_ASSERT_MESSAGE("test TransformPositionOff()", myFilter->GetTransformPosition(3)==false); } void TestUpdateOrientation(){ // update position and orientation mitk::NavigationData::PositionType updatedPos1, updatedPos2, zero; mitk::FillVector3D(updatedPos1, 3.2, 1.5, 2.8); mitk::FillVector3D(updatedPos2, 4.3, 5.2, 6.0); mitk::FillVector3D(zero, 0.0, 0.0, 0.0); mitk::NavigationData::OrientationType updatedOri1(0.7, 0.5, 0.1, 0.4); mitk::NavigationData::OrientationType updatedOri2(0.2, 0.7, 0.6, 0.1); updatedOri1.normalize(); updatedOri2.normalize(); nd1->SetPosition(updatedPos1); nd1->SetOrientation(updatedOri1); nd2->SetPosition(updatedPos2); nd2->SetOrientation(updatedOri2); - myFilter->SetRepresentationObject(0,mitkToolData1); - myFilter->SetRepresentationObject(1,mitkToolData2); + myFilter->SetRepresentationObject(0, mitkToolData1.GetPointer()); + myFilter->SetRepresentationObject(1, mitkToolData2.GetPointer()); myFilter->TransformPositionOn(0); myFilter->TransformOrientationOff(0); myFilter->TransformPositionOff(1); myFilter->TransformOrientationOn(1); myFilter->Update(); // test positions and orientations mitk::AffineTransform3D::Pointer updatedAffineTransform1 = mitkToolData1->GetGeometry()->GetIndexToWorldTransform(); mitk::AffineTransform3D::OutputVectorType updatedOffset1 = updatedAffineTransform1->GetOffset(); CPPUNIT_ASSERT_MESSAGE("Testing updated position 1", mitk::Equal(updatedOffset1.GetVnlVector(),updatedPos1.GetVnlVector())); mitk::AffineTransform3D::Pointer updatedAffineTransform2 = mitkToolData2->GetGeometry()->GetIndexToWorldTransform(); mitk::AffineTransform3D::OutputVectorType updatedOffset2 = updatedAffineTransform2->GetOffset(); CPPUNIT_ASSERT_MESSAGE( "Testing updated position 2", mitk::Equal(updatedOffset2.GetVnlVector(),zero.GetVnlVector())); mitk::AffineTransform3D::Pointer identityTransform = mitk::AffineTransform3D::New(); identityTransform->SetIdentity(); mitk::AffineTransform3D::MatrixType identityMatrix = identityTransform->GetMatrix(); mitk::AffineTransform3D::MatrixType uM1 = updatedAffineTransform1->GetMatrix(); CPPUNIT_ASSERT_MESSAGE( "Testing updated orientation 1", mitk::MatrixEqualElementWise(uM1, identityMatrix)); mitk::AffineTransform3D::MatrixType::InternalMatrixType uM2 = updatedAffineTransform2->GetMatrix().GetVnlMatrix(); mitk::AffineTransform3D::MatrixType::InternalMatrixType updatedOriTransform2 = updatedOri2.rotation_matrix_transpose().transpose(); CPPUNIT_ASSERT_MESSAGE("Testing updated orientation 2", mitk::MatrixEqualElementWise(uM2,updatedOriTransform2)); // Test that the second RepresentationObject is updated properly even when // the first RepresentationObject is invalid nd2->Modified(); myFilter->SetRepresentationObject(0, nullptr); mitkToolData2->GetGeometry()->SetIdentity(); myFilter->Update(); CPPUNIT_ASSERT_MESSAGE( "Test that the second repr object is updated correctly when the first repr object is invalid", mitk::MatrixEqualElementWise(mitkToolData2->GetGeometry()->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix(), updatedOri2.rotation_matrix_transpose().transpose())); } };//end class mitkNavigationDataObjectVisualizationFilterTestSuite MITK_TEST_SUITE_REGISTRATION(mitkNavigationDataObjectVisualizationFilter) diff --git a/Modules/IGT/Tutorial/mitkIGTTutorialStep2.cpp b/Modules/IGT/Tutorial/mitkIGTTutorialStep2.cpp index dd74393157..60b968ecfb 100644 --- a/Modules/IGT/Tutorial/mitkIGTTutorialStep2.cpp +++ b/Modules/IGT/Tutorial/mitkIGTTutorialStep2.cpp @@ -1,179 +1,179 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include #include #include #include #include #include #include #include #include #include //The next line starts a snippet to display this code in the documentation. If you don't revise the documentation, don't remove it! //! [What we will do] //************************************************************************* // What we will do... //************************************************************************* // This tutorial shows how to compose navigation datas. Therefore we render two objects. //The first object is a cone that is tracked. The second object is a cylinder at a fixed position //relative to the cone. At the end of the tracking, the cylinder is moved to its new relative position //according to the last output of the tracking device. //In addition to IGT tutorial step 1, the objects are added to a datastorage. Furthermore, a renderwindow //is used for visual output. //! [What we will do] int main(int, char**) { //************************************************************************* // Set up Render Window and Tracking Device //************************************************************************* //! [Render Window] //General code rendering the data in a renderwindow. See MITK Tutorial Step1 for more details. mitk::StandaloneDataStorage::Pointer dataStorage = mitk::StandaloneDataStorage::New(); mitk::RenderWindow::Pointer renderWindow = mitk::RenderWindow::New(); mitk::DataNode::Pointer dataNode = mitk::DataNode::New(); //Here, we want a 3D renderwindow renderWindow->GetRenderer()->SetMapperID(mitk::BaseRenderer::Standard3D); renderWindow->GetVtkRenderWindow()->SetSize(500, 500); renderWindow->GetRenderer()->Resize(500, 500); //Connect datastorage and renderwindow renderWindow->GetRenderer()->SetDataStorage(dataStorage); //! [Render Window] //! [Setup Tracking Device] //Virtual tracking device to generate random positions mitk::VirtualTrackingDevice::Pointer tracker = mitk::VirtualTrackingDevice::New(); //Bounds (within the random numbers are generated) must be set before the tools are added double bound = 10.0; mitk::ScalarType bounds[] = { -bound, bound, -bound, bound, -bound, bound }; tracker->SetBounds(bounds); tracker->AddTool("tool1"); //Tracking device source to get the data mitk::TrackingDeviceSource::Pointer source = mitk::TrackingDeviceSource::New(); source->SetTrackingDevice(tracker); source->Connect(); //! [Setup Tracking Device] //************************************************************************* // Create Objects //************************************************************************* //! [Moving Object] //Cone representation for rendering of the moving object mitk::Cone::Pointer cone = mitk::Cone::New(); dataNode->SetData(cone); dataNode->SetName("My tracked object"); dataNode->SetColor(0.0, 1.0, 1.0); dataStorage->Add(dataNode); //Filter for rendering the cone at correct postion and orientation mitk::NavigationDataObjectVisualizationFilter::Pointer visualizer = mitk::NavigationDataObjectVisualizationFilter::New(); visualizer->SetInput(0, source->GetOutput()); - visualizer->SetRepresentationObject(0, cone); + visualizer->SetRepresentationObject(0, cone.GetPointer()); //! [Moving Object] //! [Fixed Object] //Cylinder representation for rendering of the fixed object mitk::DataNode::Pointer cylinderNode = mitk::DataNode::New(); mitk::Cylinder::Pointer cylinder = mitk::Cylinder::New(); cylinderNode->SetData(cylinder); cylinderNode->SetName("My fixed object"); cylinderNode->SetColor(1.0, 0.0, 0.0); dataStorage->Add(cylinderNode); //Define a rotation and a translation for the fixed object mitk::Matrix3D rotationMatrix; rotationMatrix.SetIdentity(); double alpha = 0.3; rotationMatrix[1][1] = cos(alpha); rotationMatrix[1][2] = -sin(alpha); rotationMatrix[2][1] = sin(alpha); rotationMatrix[2][2] = cos(alpha); mitk::Vector3D offset; offset.Fill(5.0); //Add rotation and translation to affine transform mitk::AffineTransform3D::Pointer affineTransform3D = mitk::AffineTransform3D::New(); affineTransform3D->SetOffset(offset); affineTransform3D->SetMatrix(rotationMatrix); //apply rotation and translation mitk::NavigationData::Pointer fixedNavigationData = mitk::NavigationData::New(affineTransform3D); cylinder->GetGeometry()->SetIndexToWorldTransform(fixedNavigationData->GetAffineTransform3D()); //! [Fixed Object] //************************************************************************* // The Tracking loop //************************************************************************* //! [Initialize views] // Global reinit with the bounds of the virtual tracking device auto timeGeometry = dataStorage->ComputeBoundingGeometry3D(dataStorage->GetAll()); mitk::BaseGeometry::Pointer geometry = timeGeometry->GetGeometryForTimeStep(0); geometry->SetBounds(bounds); mitk::RenderingManager::GetInstance()->InitializeViews(geometry); source->StartTracking(); //! [Initialize views] //! [Tracking] //Generate and render 75 time steps to move the tracked object for (int i = 0; i < 75; ++i) { //Update the cone position visualizer->Update(); //Update rendering renderWindow->GetVtkRenderWindow()->Render(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); MITK_INFO << "Position " << source->GetOutput()->GetPosition(); //Slight delay for the random numbers itksys::SystemTools::Delay(100); } //Stop the tracking device and disconnect it //The tracking is done, now we want to move the fixed object to its correct relative position regarding the tracked object. source->StopTracking(); source->Disconnect(); //! [Tracking] //************************************************************************* // Final Transform //************************************************************************* //! [Calculate Transform] //Now the tracking is finished and we can use the transformation to move //the fixed object to its correct position relative to the new position //of the moving/tracked object. Therefore, we compose the navigation datas. fixedNavigationData->Compose(source->GetOutput(), false); //Update the transformation matrix of the cylinder cylinder->GetGeometry()->SetIndexToWorldTransform(fixedNavigationData->GetAffineTransform3D()); //Update the rendering renderWindow->GetVtkRenderWindow()->Render(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); //Wait a little before closing the renderwindow itksys::SystemTools::Delay(2000); //! [Calculate Transform] } diff --git a/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkNavigationDataPlayerView.cpp b/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkNavigationDataPlayerView.cpp index 034b7b6183..84d45f917c 100644 --- a/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkNavigationDataPlayerView.cpp +++ b/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkNavigationDataPlayerView.cpp @@ -1,236 +1,236 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ // Qmitk #include "QmitkNavigationDataPlayerView.h" // QT #include #include //mitk #include #include #include #include #include #include // VTK #include const std::string QmitkNavigationDataPlayerView::VIEW_ID = "org.mitk.views.navigationdataplayer"; QmitkNavigationDataPlayerView::QmitkNavigationDataPlayerView() : m_Controls( nullptr ) { } QmitkNavigationDataPlayerView::~QmitkNavigationDataPlayerView() { } void QmitkNavigationDataPlayerView::CreateQtPartControl( QWidget *parent ) { // build up qt view, unless already done if ( !m_Controls ) { // create GUI widgets from the Qt Designer's .ui file m_Controls = new Ui::QmitkNavigationDataPlayerViewControls; m_Controls->setupUi( parent ); this->CreateConnections(); // make deselected Player invisible m_Controls->m_TimedWidget->setVisible(false); } } void QmitkNavigationDataPlayerView::SetFocus() { if ( m_Controls ) { m_Controls->m_grpbxControls->setFocus(); } } void QmitkNavigationDataPlayerView::CreateConnections() { connect( m_Controls->m_RdbSequential, SIGNAL(released()), this, SLOT(OnSelectPlayer()) ); connect( m_Controls->m_RdbTimeBased, SIGNAL(released()), this, SLOT(OnSelectPlayer()) ); connect( m_Controls->m_BtnOpenFile, SIGNAL(released()), this, SLOT(OnOpenFile()) ); connect( m_Controls->m_ChkDisplay, SIGNAL(released()), this, SLOT(OnSetDisplay()) ); connect( m_Controls->m_chkRepeat, SIGNAL(stateChanged(int)), this, SLOT(OnSetRepeat(int)) ); connect( m_Controls->m_ChkMicroservice, SIGNAL(released()), this, SLOT(OnSetMicroservice()) ); connect( m_Controls->m_SequentialWidget, SIGNAL(SignalUpdate()), this, SLOT(OnUpdate()) ); connect( m_Controls->m_TimedWidget, SIGNAL(SignalUpdate()), this, SLOT(OnUpdate()) ); this->SetInteractionComponentsEnabledState(false); } void QmitkNavigationDataPlayerView::OnOpenFile() { mitk::NavigationDataReaderInterface::Pointer reader = nullptr; QString filter = tr("NavigationData File (*.csv *.xml)"); QString fileName = QFileDialog::getOpenFileName(nullptr, tr("Open NavigationData Set"), "", filter); if ( fileName.isNull() ) { return; } // user pressed cancel try { m_Data = dynamic_cast (mitk::IOUtil::Load(fileName.toStdString())[0].GetPointer()); } catch ( const mitk::Exception &e ) { MITK_WARN("NavigationDataPlayerView") << "could not open file " << fileName.toStdString(); QMessageBox::critical(nullptr, "Error Reading File", "The file '" + fileName +"' could not be read.\n" + e.GetDescription() ); return; } if (m_Controls->m_ChkConvertToPointSet->isChecked()) m_Data->ConvertNavigationDataToPointSet(); // Update Labels m_Controls->m_LblFilePath->setText(fileName); m_Controls->m_LblFrames->setText(QString::number(m_Data->Size())); m_Controls->m_LblTools->setText(QString::number(m_Data->GetNumberOfTools())); // Initialize Widgets and create Player this->OnSelectPlayer(); this->SetInteractionComponentsEnabledState(true); } void QmitkNavigationDataPlayerView::OnSelectPlayer() { if (m_Controls->m_RdbSequential->isChecked()) { m_Controls->m_SequentialWidget->setVisible(true); m_Controls->m_TimedWidget->setVisible(false); mitk::NavigationDataSequentialPlayer::Pointer seqPlayer = mitk::NavigationDataSequentialPlayer::New(); seqPlayer->SetNavigationDataSet(m_Data); m_Controls->m_SequentialWidget->SetPlayer(seqPlayer); m_Player = seqPlayer; } else { m_Controls->m_SequentialWidget->setVisible(false); m_Controls->m_TimedWidget->setVisible(true); mitk::NavigationDataPlayer::Pointer timedPlayer = mitk::NavigationDataPlayer::New(); timedPlayer->SetNavigationDataSet(m_Data); m_Controls->m_TimedWidget->SetPlayer(timedPlayer); m_Player = timedPlayer; } this->ConfigurePlayer(); // SetupRenderingPipeline this->OnSetDisplay(); } void QmitkNavigationDataPlayerView::ConfigurePlayer() { // set repeat mode according to the checkbox m_Player->SetRepeat( m_Controls->m_chkRepeat->isChecked() ); } void QmitkNavigationDataPlayerView::OnSetRepeat(int checkState) { m_Player->SetRepeat(checkState != 0); } void QmitkNavigationDataPlayerView::OnSetMicroservice(){ if(m_Controls->m_ChkMicroservice->isChecked()) { m_ToolStorage = mitk::NavigationToolStorage::New(); for (itk::ProcessObject::DataObjectPointerArraySizeType i = 0; i < m_Player->GetNumberOfIndexedOutputs(); i++) { mitk::NavigationTool::Pointer currentDummyTool = mitk::NavigationTool::New(); mitk::VirtualTrackingTool::Pointer dummyTool = mitk::VirtualTrackingTool::New(); std::stringstream name; name << "Virtual Tool " << i; dummyTool->SetToolName(name.str()); currentDummyTool->SetDataNode(m_RenderingNodes.at(i)); currentDummyTool->SetIdentifier(name.str()); m_ToolStorage->AddTool(currentDummyTool); } m_ToolStorage->SetName("NavigationDataPlayer Tool Storage"); m_Player->SetToolMetaDataCollection(m_ToolStorage); m_Player->RegisterAsMicroservice(); m_ToolStorage->SetSourceID(m_Player->GetMicroserviceID()); //DEPRECATED / not needed anymore because NavigationDataSource now holds a member of its tool storage. Only left for backward compatibility. m_ToolStorage->RegisterAsMicroservice(); } else { if (m_ToolStorage.IsNotNull()) m_ToolStorage->UnRegisterMicroservice(); m_ToolStorage = nullptr; m_Player->UnRegisterMicroservice(); } } void QmitkNavigationDataPlayerView::OnUpdate(){ if (m_VisFilter.IsNotNull()) { m_VisFilter->Update(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkNavigationDataPlayerView::OnSetDisplay(){ DestroyPipeline(); if ( (m_Controls->m_ChkDisplay->isChecked()) && ( m_Player.IsNotNull() )) { CreatePipeline(); } } void QmitkNavigationDataPlayerView::CreatePipeline(){ m_VisFilter = mitk::NavigationDataObjectVisualizationFilter::New(); m_VisFilter->ConnectTo(m_Player); for (unsigned int i = 0 ; i < m_Player->GetNumberOfIndexedOutputs(); i++ ) { mitk::DataNode::Pointer node = mitk::DataNode::New(); QString name = "Recorded Tool " + QString::number(i + 1); node->SetName(name.toStdString()); //create small sphere and use it as surface mitk::Surface::Pointer mySphere = mitk::Surface::New(); vtkSmartPointer vtkData = vtkSmartPointer::New(); vtkData->SetRadius(5.0f); vtkData->SetCenter(0.0, 0.0, 0.0); vtkData->Update(); mySphere->SetVtkPolyData(vtkData->GetOutput()); node->SetData(mySphere); - m_VisFilter->SetRepresentationObject(i, mySphere); + m_VisFilter->SetRepresentationObject(i, mySphere.GetPointer()); // Add Node to DataStorageand to local list of Nodes GetDataStorage()->Add(node); m_RenderingNodes.push_back(node); } m_VisFilter->Update(); mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(GetDataStorage()); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkNavigationDataPlayerView::DestroyPipeline(){ m_VisFilter = nullptr; for (unsigned int i = 0; i < m_RenderingNodes.size(); i++){ this->GetDataStorage()->Remove(m_RenderingNodes[i]); } m_RenderingNodes.clear(); } void QmitkNavigationDataPlayerView::SetInteractionComponentsEnabledState(bool isActive){ m_Controls->m_grpbxSettings->setEnabled(isActive); m_Controls->m_grpbxControls->setEnabled(isActive); }