diff --git a/Modules/IGT/IGTFilters/mitkNavigationDataObjectVisualizationFilter.cpp b/Modules/IGT/IGTFilters/mitkNavigationDataObjectVisualizationFilter.cpp index 6532ae6fbd..cf6487bfe6 100644 --- a/Modules/IGT/IGTFilters/mitkNavigationDataObjectVisualizationFilter.cpp +++ b/Modules/IGT/IGTFilters/mitkNavigationDataObjectVisualizationFilter.cpp @@ -1,251 +1,265 @@ /*=================================================================== 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 "mitkNavigationDataObjectVisualizationFilter.h" #include "mitkDataStorage.h" mitk::NavigationDataObjectVisualizationFilter::NavigationDataObjectVisualizationFilter() : NavigationDataToNavigationDataFilter(), -m_RepresentationList(), m_TransformPosition(), m_TransformOrientation() +m_RepresentationList(), m_TransformPosition(), m_TransformOrientation(), m_RotationMode(RotationStandard) { } mitk::NavigationDataObjectVisualizationFilter::~NavigationDataObjectVisualizationFilter() { m_RepresentationList.clear(); m_OffsetList.clear(); } const mitk::BaseData* mitk::NavigationDataObjectVisualizationFilter::GetRepresentationObject(unsigned int idx) { //if (idx >= this->GetNumberOfInputs()) // return NULL; //const NavigationData* nd = this->GetInput(idx); //if (nd == NULL) // return NULL; RepresentationPointerMap::const_iterator iter = m_RepresentationList.find(idx); if (iter != m_RepresentationList.end()) return iter->second; return NULL; } 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 NULL; } void mitk::NavigationDataObjectVisualizationFilter::SetRepresentationObject(unsigned int idx, BaseData* data) { //if (idx >= this->GetNumberOfInputs()) // return false; //const NavigationData* nd = this->GetInput(idx); //if (nd == NULL || data == NULL) // return false; m_RepresentationList[idx] = RepresentationPointer(data); //std::pair returnEl; //pair for returning the result //returnEl = m_RepresentationList.insert( RepresentationPointerMap::value_type(nd, data) ); //insert the given elements //return returnEl.second; // return if insert was successful } void mitk::NavigationDataObjectVisualizationFilter::SetOffset(int index, mitk::AffineTransform3D::Pointer 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++) { //get the needed variables const mitk::NavigationData* nd = this->GetInput(index); assert(nd); mitk::NavigationData* output = this->GetOutput(index); assert(output); //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 == NULL) { itkWarningMacro("NavigationDataObjectVisualizationFilter: Wrong/No BaseData associated with input."); return; } //get the transform from data mitk::AffineTransform3D::Pointer affineTransform = data->GetGeometry()->GetIndexToWorldTransform(); if (affineTransform.IsNull()) { //replace with mitk standard output itkWarningMacro("NavigationDataObjectVisualizationFilter: AffineTransform IndexToWorldTransform not initialized!"); return; } //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 float scale[] = {1.0, 1.0, 1.0}; data->GetGeometry()->SetSpacing(scale); /*now bring quaternion to affineTransform by using vnl_Quaternion*/ affineTransform->SetIdentity(); if (this->GetTransformOrientation(index) == true) { - //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); - 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]; + + //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); + } + 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]; + } 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.Set_vnl_vector(nd->GetPosition().Get_vnl_vector()); affineTransform->SetOffset(pos); } affineTransform->Modified(); //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); } else { data->GetGeometry()->SetIndexToWorldTransform(affineTransform); } //set the original spacing to keep scaling of the geometrical object data->GetGeometry()->SetSpacing(spacing); data->GetGeometry()->TransferItkToVtkTransform(); // update VTK Transform for rendering too data->GetGeometry()->Modified(); data->Modified(); output->SetDataValid(true); // operation was successful, therefore data of output is valid. } } 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 { 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 ) { this->SetTransformPosition(index, true); } void mitk::NavigationDataObjectVisualizationFilter::TransformPositionOff( unsigned int index ) { this->SetTransformPosition(index, false); } 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(); \ } 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 ) { this->SetTransformOrientation(index, true); } void mitk::NavigationDataObjectVisualizationFilter::TransformOrientationOff( unsigned int index ) { this->SetTransformOrientation(index, false); } diff --git a/Modules/IGT/IGTFilters/mitkNavigationDataObjectVisualizationFilter.h b/Modules/IGT/IGTFilters/mitkNavigationDataObjectVisualizationFilter.h index 6fc80ff9e0..cfd4bdcfad 100644 --- a/Modules/IGT/IGTFilters/mitkNavigationDataObjectVisualizationFilter.h +++ b/Modules/IGT/IGTFilters/mitkNavigationDataObjectVisualizationFilter.h @@ -1,129 +1,146 @@ /*=================================================================== 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 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); itkNewMacro(Self); + /** Defines the rotation modes of the input data of this filter + * which results in different interpretations of quaternions. + * - Standard: normal representation, rawdata from the device is not changed + * - Transposed: the rotation is stored transposed, which is standard in VNL + * ndiStandard is default + * use SetRotationMode to change the mode. + */ + enum RotationMode {RotationStandard, RotationTransposed}; + /** * \brief Smart Pointer type to a BaseData. */ typedef BaseData::ConstPointer RepresentationPointer; /** * \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 */ typedef RepresentationPointerMap::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); /** * \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 NULL * if no BaseData was found. */ const BaseData* GetRepresentationObject(unsigned int idx); 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 NULL. */ 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. + */ + virtual void SetRotationMode(RotationMode r); + /** @return Returns the offset of a represenation object. Returns NULL 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(); } /* * \brief Transfer the information from the input to the associated BaseData */ virtual void GenerateData(); protected: typedef std::map BooleanInputMap; typedef std::map OffsetPointerMap; /** * \brief Constructor **/ NavigationDataObjectVisualizationFilter(); /** * \brief Destructor **/ ~NavigationDataObjectVisualizationFilter(); /** * \brief An array of the BaseData which represent the tools. */ RepresentationPointerMap m_RepresentationList; 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_ */