diff --git a/Modules/IGT/IGTFilters/mitkNavigationDataObjectVisualizationFilter.cpp b/Modules/IGT/IGTFilters/mitkNavigationDataObjectVisualizationFilter.cpp index 2d4aefb603..5963eb7876 100644 --- a/Modules/IGT/IGTFilters/mitkNavigationDataObjectVisualizationFilter.cpp +++ b/Modules/IGT/IGTFilters/mitkNavigationDataObjectVisualizationFilter.cpp @@ -1,219 +1,249 @@ /*=================================================================== 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() { } 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::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); 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 - data->GetGeometry()->SetIndexToWorldTransform(affineTransform); + 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 10cc79b66b..6fc80ff9e0 100644 --- a/Modules/IGT/IGTFilters/mitkNavigationDataObjectVisualizationFilter.h +++ b/Modules/IGT/IGTFilters/mitkNavigationDataObjectVisualizationFilter.h @@ -1,119 +1,129 @@ /*=================================================================== 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); /** * \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); + + /** @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; }; } // namespace mitk #endif /* MITKNAVIGATIONDATAOBJECTVISUALIZATIONFILTER_H_HEADER_INCLUDED_ */