diff --git a/Modules/DataTypesExt/Resources/Interactions/AffineInteraction3D.xml b/Modules/DataTypesExt/Resources/Interactions/AffineInteraction3D.xml index 36d4e14d15..27d4b05091 100644 --- a/Modules/DataTypesExt/Resources/Interactions/AffineInteraction3D.xml +++ b/Modules/DataTypesExt/Resources/Interactions/AffineInteraction3D.xml @@ -1,72 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Modules/DataTypesExt/Resources/Interactions/AffineRotationConfig.xml b/Modules/DataTypesExt/Resources/Interactions/AffineRotationConfig.xml index fb9c6fe6d1..055a898d7f 100644 --- a/Modules/DataTypesExt/Resources/Interactions/AffineRotationConfig.xml +++ b/Modules/DataTypesExt/Resources/Interactions/AffineRotationConfig.xml @@ -1,13 +1,33 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/Modules/DataTypesExt/Resources/Interactions/AffineTranslationConfig.xml b/Modules/DataTypesExt/Resources/Interactions/AffineTranslationConfig.xml index 4bbbe5c8be..4bcb41ee09 100644 --- a/Modules/DataTypesExt/Resources/Interactions/AffineTranslationConfig.xml +++ b/Modules/DataTypesExt/Resources/Interactions/AffineTranslationConfig.xml @@ -1,13 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Modules/DataTypesExt/mitkAffineDataInteractor3D.cpp b/Modules/DataTypesExt/mitkAffineDataInteractor3D.cpp index 81e22e2871..1751257632 100644 --- a/Modules/DataTypesExt/mitkAffineDataInteractor3D.cpp +++ b/Modules/DataTypesExt/mitkAffineDataInteractor3D.cpp @@ -1,380 +1,521 @@ /*=================================================================== 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 "mitkAffineDataInteractor3D.h" #include "mitkInteractionConst.h" #include "mitkInteractionPositionEvent.h" #include "mitkRotationOperation.h" #include "mitkSurface.h" #include #include #include #include #include #include +#include +const char* translationStepSizePropertyName = "AffineDataInteractor3D.Translation Step Size"; +const char* selectedColorPropertyName = "AffineDataInteractor3D.Selected Color"; +const char* deselectedColorPropertyName = "AffineDataInteractor3D.Deselected Color"; +const char* priorPropertyName = "AffineDataInteractor3D.Prior Color"; +const char* rotationStepSizePropertyName = "AffineDataInteractor3D.Rotation Step Size"; +const char* scaleStepSizePropertyName = "AffineDataInteractor3D.Scale Step Size"; mitk::AffineDataInteractor3D::AffineDataInteractor3D() { - m_OriginalGeometry = Geometry3D::New(); + m_OriginalGeometry = mitk::Geometry3D::New(); // Initialize vector arithmetic m_ObjectNormal[0] = 0.0; m_ObjectNormal[1] = 0.0; m_ObjectNormal[2] = 1.0; - - //define the colors for selected/deselected state - m_DataNode->AddProperty( "AffineDataInteractor3D.SelectedColor", ColorProperty::New(0.0,1.0,0.0) ); - m_DataNode->AddProperty( "AffineDataInteractor3D.DeselectedColor", ColorProperty::New(0.0,0.0,1.0) ); - //save the previous color of the node, in order to restore it after the interactor is destroyed - mitk::ColorProperty::Pointer priorColor = dynamic_cast(m_DataNode->GetProperty("color")); - if ( priorColor.IsNotNull() ) - { - mitk::ColorProperty::Pointer tmpCopyOfPriorColor = mitk::ColorProperty::New(); - tmpCopyOfPriorColor->SetColor( priorColor->GetColor() ); - m_DataNode->AddProperty( "AffineDataInteractor3D.PriorColor", tmpCopyOfPriorColor ); - } - mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } mitk::AffineDataInteractor3D::~AffineDataInteractor3D() { - mitk::ColorProperty::Pointer color = dynamic_cast(m_DataNode->GetProperty("AffineDataInteractor3D.PriorColor")); - if ( color.IsNotNull() ) - { - m_DataNode->GetPropertyList()->SetProperty("color", color); - } - - m_DataNode->GetPropertyList()->DeleteProperty("AffineDataInteractor3D.SelectedColor"); - m_DataNode->GetPropertyList()->DeleteProperty("AffineDataInteractor3D.DeselectedColor"); - m_DataNode->GetPropertyList()->DeleteProperty("AffineDataInteractor3D.PriorColor"); - //update rendering - mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + this->RestoreNodeColor(); } void mitk::AffineDataInteractor3D::ConnectActionsAndFunctions() { // **Conditions** that can be used in the state machine, to ensure that certain conditions are met, before actually executing an action CONNECT_CONDITION("isOverObject", CheckOverObject); // **Function** in the statmachine patterns also referred to as **Actions** CONNECT_FUNCTION("selectObject",SelectObject); CONNECT_FUNCTION("deselectObject",DeselectObject); CONNECT_FUNCTION("initTranslate",InitTranslate); CONNECT_FUNCTION("initRotate",InitRotate); CONNECT_FUNCTION("translateObject",TranslateObject); CONNECT_FUNCTION("rotateObject",RotateObject); + CONNECT_FUNCTION("translateUpKey",TranslateUpKey); + CONNECT_FUNCTION("translateDownKey",TranslateDownKey); + CONNECT_FUNCTION("translateLeftKey",TranslateLeftKey); + CONNECT_FUNCTION("translateRightKey",TranslateRightKey); + CONNECT_FUNCTION("translateUpModifierKey",TranslateUpModifierKey); + CONNECT_FUNCTION("translateDownModifierKey",TranslateDownModifierKey); + + CONNECT_FUNCTION("scaleKey",ScaleGeometry); + + + CONNECT_FUNCTION("rotateUpKey",RotateUpKey); + CONNECT_FUNCTION("rotateDownKey",RotateDownKey); + CONNECT_FUNCTION("rotateLeftKey",RotateLeftKey); + CONNECT_FUNCTION("rotateRightKey",RotateRightKey); + CONNECT_FUNCTION("rotateUpModifierKey",RotateUpModifierKey); + CONNECT_FUNCTION("rotateDownModifierKey",RotateDownModifierKey); +} + +bool mitk::AffineDataInteractor3D::TranslateUpKey(StateMachineAction*, InteractionEvent*) +{ + float stepSize = 1.0f; + this->GetDataNode()->GetFloatProperty(translationStepSizePropertyName, stepSize); + mitk::Vector3D movementVector; + movementVector.SetElement(0, stepSize); + movementVector.SetElement(1, 0.0); + movementVector.SetElement(2, 0.0); + this->TranslateGeometry(movementVector); + return true; +} + +bool mitk::AffineDataInteractor3D::TranslateDownKey(mitk::StateMachineAction*, mitk::InteractionEvent*) +{ + float stepSize = 1.0f; + this->GetDataNode()->GetFloatProperty(translationStepSizePropertyName, stepSize); + mitk::Vector3D movementVector; + movementVector.SetElement(0, -stepSize); + movementVector.SetElement(1, 0.0); + movementVector.SetElement(2, 0.0); + this->TranslateGeometry(movementVector); + return true; +} + +bool mitk::AffineDataInteractor3D::TranslateLeftKey(mitk::StateMachineAction*, mitk::InteractionEvent*) +{ + float stepSize = 1.0f; + this->GetDataNode()->GetFloatProperty(translationStepSizePropertyName, stepSize); + mitk::Vector3D movementVector; + movementVector.SetElement(0, 0.0); + movementVector.SetElement(1, -stepSize); + movementVector.SetElement(2, 0.0); + this->TranslateGeometry(movementVector); + return true; +} + +bool mitk::AffineDataInteractor3D::TranslateRightKey(mitk::StateMachineAction*, mitk::InteractionEvent*) +{ + float stepSize = 1.0f; + this->GetDataNode()->GetFloatProperty(translationStepSizePropertyName, stepSize); + mitk::Vector3D movementVector; + movementVector.SetElement(0, 0.0); + movementVector.SetElement(1, stepSize); + movementVector.SetElement(2, 0.0); + this->TranslateGeometry(movementVector); + return true; +} + +bool mitk::AffineDataInteractor3D::TranslateUpModifierKey(mitk::StateMachineAction*, mitk::InteractionEvent*) +{ + float stepSize = 1.0f; + this->GetDataNode()->GetFloatProperty(translationStepSizePropertyName, stepSize); + mitk::Vector3D movementVector; + movementVector.SetElement(0, 0.0); + movementVector.SetElement(1, 0.0); + movementVector.SetElement(2, stepSize); + this->TranslateGeometry(movementVector); + return true; +} + +bool mitk::AffineDataInteractor3D::TranslateDownModifierKey(mitk::StateMachineAction*, mitk::InteractionEvent*) +{ + float stepSize = 1.0f; + this->GetDataNode()->GetFloatProperty(translationStepSizePropertyName, stepSize); + mitk::Vector3D movementVector; + movementVector.SetElement(0, 0.0); + movementVector.SetElement(1, 0.0); + movementVector.SetElement(2, -stepSize); + this->TranslateGeometry(movementVector); + return true; +} + +bool mitk::AffineDataInteractor3D::RotateUpKey(mitk::StateMachineAction*, mitk::InteractionEvent*) +{ + float stepSize = 1.0f; + this->GetDataNode()->GetFloatProperty(rotationStepSizePropertyName, stepSize); + this->RotateGeometry(stepSize, 0); + return true; +} + +bool mitk::AffineDataInteractor3D::RotateDownKey(mitk::StateMachineAction*, mitk::InteractionEvent*) +{ + return true; +} + +bool mitk::AffineDataInteractor3D::RotateLeftKey(mitk::StateMachineAction*, mitk::InteractionEvent*) +{ + return true; +} + +bool mitk::AffineDataInteractor3D::RotateRightKey(mitk::StateMachineAction*, mitk::InteractionEvent*) +{ + return true; +} + +bool mitk::AffineDataInteractor3D::RotateUpModifierKey(mitk::StateMachineAction*, mitk::InteractionEvent*) +{ + return true; +} + +bool mitk::AffineDataInteractor3D::RotateDownModifierKey(mitk::StateMachineAction*, mitk::InteractionEvent*) +{ + return true; +} + + +bool mitk::AffineDataInteractor3D::ScaleGeometry(mitk::StateMachineAction*, mitk::InteractionEvent*) +{ + mitk::Point3D newScale; + newScale[0] = 1.5; + newScale[1] = 1.5; + newScale[2] = 1.5; + /* generate Operation and send it to the receiving geometry */ + PointOperation* doOp = new mitk::PointOperation(OpSCALE, newScale, 0); // Index is not used here + + /* execute the Operation */ + this->GetDataNode()->GetData()->GetGeometry()->ExecuteOperation(doOp); + + delete doOp; + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + return true; +} + +void mitk::AffineDataInteractor3D::RotateGeometry(mitk::ScalarType angle, int rotationaxis) +{ + BaseGeometry* geometry = this->GetDataNode()->GetData()->GetGeometry(); + mitk::Vector3D rotationAxis = geometry->GetAxisVector(rotationaxis); + mitk::Point3D center = geometry->GetCenter(); + + mitk::RotationOperation* doOp = new mitk::RotationOperation(OpROTATE, center, rotationAxis, angle); + + /* execute the Operation */ + geometry->ExecuteOperation(doOp); + delete doOp; + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); +} + +void mitk::AffineDataInteractor3D::TranslateGeometry(mitk::Vector3D translate) +{ + BaseGeometry* geometry = this->GetDataNode()->GetData()->GetUpdatedTimeGeometry()->GetGeometryForTimeStep( 0 ); + geometry->Translate(translate); + + // indicate modification of data tree node + this->GetDataNode()->Modified(); + + //update rendering + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void mitk::AffineDataInteractor3D::DataNodeChanged() { + mitk::DataNode::Pointer newInputNode = this->GetDataNode(); + //add default properties + newInputNode->AddProperty( selectedColorPropertyName, mitk::ColorProperty::New(0.0,1.0,0.0) ); + newInputNode->AddProperty( deselectedColorPropertyName, mitk::ColorProperty::New(0.0,0.0,1.0) ); + newInputNode->AddProperty( translationStepSizePropertyName, mitk::FloatProperty::New(1.0f) ); + newInputNode->AddProperty( rotationStepSizePropertyName, mitk::FloatProperty::New(1.0f) ); + newInputNode->AddProperty( scaleStepSizePropertyName, mitk::FloatProperty::New(1.0f) ); + + //save the previous color of the node, in order to restore it after the interactor is destroyed + mitk::ColorProperty::Pointer priorColor = dynamic_cast(newInputNode->GetProperty("color")); + if ( priorColor.IsNotNull() ) + { + mitk::ColorProperty::Pointer tmpCopyOfPriorColor = mitk::ColorProperty::New(); + tmpCopyOfPriorColor->SetColor( priorColor->GetColor() ); + newInputNode->AddProperty( priorPropertyName, tmpCopyOfPriorColor ); + } + newInputNode->SetColor(0.0,0.0,1.0); + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); +} + +void mitk::AffineDataInteractor3D::SetDataNode(mitk::DataInteractor::NodeType node) +{ + this->RestoreNodeColor(); //if there was another node set, restore it's color + DataInteractor::SetDataNode(node); } bool mitk::AffineDataInteractor3D::CheckOverObject(const InteractionEvent* interactionEvent) { const InteractionPositionEvent* positionEvent = dynamic_cast(interactionEvent); if(positionEvent == NULL) return false; Point3D currentWorldPoint; if(interactionEvent->GetSender()->PickObject(positionEvent->GetPointerPositionOnScreen(), currentWorldPoint) == this->GetDataNode().GetPointer()) return true; return false; } bool mitk::AffineDataInteractor3D::SelectObject(StateMachineAction*, InteractionEvent* interactionEvent) { DataNode::Pointer node = this->GetDataNode(); if (node.IsNull()) return false; - node->SetColor(1.0, 0.0, 0.0); - - // Colorize surface / wireframe dependend on distance from picked point - this->ColorizeSurface(interactionEvent->GetSender(), 0.0); - + mitk::ColorProperty::Pointer selectedColor = dynamic_cast(node->GetProperty(selectedColorPropertyName)); + if ( selectedColor.IsNotNull() ) + { + node->GetPropertyList()->SetProperty("color", selectedColor); + } interactionEvent->GetSender()->GetRenderingManager()->RequestUpdateAll(); return true; } bool mitk::AffineDataInteractor3D::DeselectObject(StateMachineAction*, InteractionEvent* interactionEvent) { DataNode::Pointer node = this->GetDataNode(); if (node.IsNull()) return false; - node->SetColor( 1.0, 1.0, 1.0 ); - - // Colorize surface / wireframe as inactive - this->ColorizeSurface(interactionEvent->GetSender(), -1.0); + mitk::ColorProperty::Pointer selectedColor = dynamic_cast(node->GetProperty(deselectedColorPropertyName)); + if ( selectedColor.IsNotNull() ) + { + node->GetPropertyList()->SetProperty("color", selectedColor); + } interactionEvent->GetSender()->GetRenderingManager()->RequestUpdateAll(); return true; } bool mitk::AffineDataInteractor3D::InitTranslate(StateMachineAction*, InteractionEvent* interactionEvent) { InteractionPositionEvent* positionEvent = dynamic_cast(interactionEvent); if(positionEvent == NULL) return false; m_InitialPickedDisplayPoint = positionEvent->GetPointerPositionOnScreen(); vtkInteractorObserver::ComputeDisplayToWorld( interactionEvent->GetSender()->GetVtkRenderer(), m_InitialPickedDisplayPoint[0], m_InitialPickedDisplayPoint[1], 0.0, //m_InitialInteractionPickedPoint[2], m_InitialPickedWorldPoint ); // Get the timestep to also support 3D+t int timeStep = 0; if ((interactionEvent->GetSender()) != NULL) timeStep = interactionEvent->GetSender()->GetTimeStep(this->GetDataNode()->GetData()); // Make deep copy of current Geometry3D of the plane this->GetDataNode()->GetData()->UpdateOutputInformation(); // make sure that the Geometry is up-to-date m_OriginalGeometry = static_cast(this->GetDataNode()->GetData()->GetGeometry(timeStep)->Clone().GetPointer()); return true; } bool mitk::AffineDataInteractor3D::InitRotate(StateMachineAction*, InteractionEvent* interactionEvent) { InteractionPositionEvent* positionEvent = dynamic_cast(interactionEvent); - if(positionEvent == NULL) - return false; m_InitialPickedDisplayPoint = positionEvent->GetPointerPositionOnScreen(); vtkInteractorObserver::ComputeDisplayToWorld( interactionEvent->GetSender()->GetVtkRenderer(), m_InitialPickedDisplayPoint[0], m_InitialPickedDisplayPoint[1], 0.0, //m_InitialInteractionPickedPoint[2], m_InitialPickedWorldPoint ); // Get the timestep to also support 3D+t int timeStep = interactionEvent->GetSender()->GetTimeStep(this->GetDataNode()->GetData()); // Make deep copy of current Geometry3D of the plane this->GetDataNode()->GetData()->UpdateOutputInformation(); // make sure that the Geometry is up-to-date m_OriginalGeometry = static_cast(this->GetDataNode()->GetData()->GetGeometry(timeStep)->Clone().GetPointer()); return true; } bool mitk::AffineDataInteractor3D::TranslateObject (StateMachineAction*, InteractionEvent* interactionEvent) { InteractionPositionEvent* positionEvent = dynamic_cast(interactionEvent); if(positionEvent == NULL) return false; double currentWorldPoint[4]; mitk::Point2D currentDisplayPoint = positionEvent->GetPointerPositionOnScreen(); vtkInteractorObserver::ComputeDisplayToWorld( interactionEvent->GetSender()->GetVtkRenderer(), currentDisplayPoint[0], currentDisplayPoint[1], 0.0, //m_InitialInteractionPickedPoint[2], currentWorldPoint); Vector3D interactionMove; interactionMove[0] = currentWorldPoint[0] - m_InitialPickedWorldPoint[0]; interactionMove[1] = currentWorldPoint[1] - m_InitialPickedWorldPoint[1]; interactionMove[2] = currentWorldPoint[2] - m_InitialPickedWorldPoint[2]; Point3D origin = m_OriginalGeometry->GetOrigin(); // Get the timestep to also support 3D+t int timeStep = interactionEvent->GetSender()->GetTimeStep(this->GetDataNode()->GetData()); // If data is an mitk::Surface, extract it Surface::Pointer surface = dynamic_cast< Surface* >(this->GetDataNode()->GetData()); vtkPolyData* polyData = NULL; if (surface.IsNotNull()) { polyData = surface->GetVtkPolyData( timeStep ); // Extract surface normal from surface (if existent, otherwise use default) vtkPointData* pointData = polyData->GetPointData(); if (pointData != NULL) { vtkDataArray* normal = polyData->GetPointData()->GetVectors("planeNormal"); if (normal != NULL) { m_ObjectNormal[0] = normal->GetComponent( 0, 0 ); m_ObjectNormal[1] = normal->GetComponent( 0, 1 ); m_ObjectNormal[2] = normal->GetComponent( 0, 2 ); } } } Vector3D transformedObjectNormal; this->GetDataNode()->GetData()->GetGeometry( timeStep )->IndexToWorld(m_ObjectNormal, transformedObjectNormal); this->GetDataNode()->GetData()->GetGeometry( timeStep )->SetOrigin(origin + transformedObjectNormal * (interactionMove * transformedObjectNormal)); interactionEvent->GetSender()->GetRenderingManager()->RequestUpdateAll(); return true; } bool mitk::AffineDataInteractor3D::RotateObject (StateMachineAction*, InteractionEvent* interactionEvent) { InteractionPositionEvent* positionEvent = dynamic_cast(interactionEvent); if(positionEvent == NULL) return false; double currentWorldPoint[4]; Point2D currentPickedDisplayPoint = positionEvent->GetPointerPositionOnScreen(); vtkInteractorObserver::ComputeDisplayToWorld( interactionEvent->GetSender()->GetVtkRenderer(), currentPickedDisplayPoint[0], currentPickedDisplayPoint[1], 0.0, //m_InitialInteractionPickedPoint[2], currentWorldPoint); vtkCamera* camera = NULL; vtkRenderer* currentVtkRenderer = NULL; if ((interactionEvent->GetSender()) != NULL) { vtkRenderWindow* renderWindow = interactionEvent->GetSender()->GetRenderWindow(); if (renderWindow != NULL) { vtkRenderWindowInteractor* renderWindowInteractor = renderWindow->GetInteractor(); if ( renderWindowInteractor != NULL ) { currentVtkRenderer = renderWindowInteractor->GetInteractorStyle()->GetCurrentRenderer(); if (currentVtkRenderer != NULL) camera = currentVtkRenderer->GetActiveCamera(); } } } if ( camera ) { double vpn[3]; camera->GetViewPlaneNormal( vpn ); Vector3D viewPlaneNormal; viewPlaneNormal[0] = vpn[0]; viewPlaneNormal[1] = vpn[1]; viewPlaneNormal[2] = vpn[2]; Vector3D interactionMove; interactionMove[0] = currentWorldPoint[0] - m_InitialPickedWorldPoint[0]; interactionMove[1] = currentWorldPoint[1] - m_InitialPickedWorldPoint[1]; interactionMove[2] = currentWorldPoint[2] - m_InitialPickedWorldPoint[2]; if (interactionMove[0] == 0 && interactionMove[1] == 0 && interactionMove[2] == 0) return true; Vector3D rotationAxis = itk::CrossProduct(viewPlaneNormal, interactionMove); rotationAxis.Normalize(); int* size = currentVtkRenderer->GetSize(); double l2 = (currentPickedDisplayPoint[0] - m_InitialPickedDisplayPoint[0]) * (currentPickedDisplayPoint[0] - m_InitialPickedDisplayPoint[0]) + (currentPickedDisplayPoint[1] - m_InitialPickedDisplayPoint[1]) * (currentPickedDisplayPoint[1] - m_InitialPickedDisplayPoint[1]); double rotationAngle = 360.0 * sqrt(l2 / (size[0] * size[0] + size[1] * size[1])); // Use center of data bounding box as center of rotation Point3D rotationCenter = m_OriginalGeometry->GetCenter(); int timeStep = 0; if ((interactionEvent->GetSender()) != NULL) timeStep = interactionEvent->GetSender()->GetTimeStep(this->GetDataNode()->GetData()); // Reset current Geometry3D to original state (pre-interaction) and // apply rotation RotationOperation op( OpROTATE, rotationCenter, rotationAxis, rotationAngle ); Geometry3D::Pointer newGeometry = static_cast(m_OriginalGeometry->Clone().GetPointer()); newGeometry->ExecuteOperation( &op ); mitk::TimeGeometry::Pointer timeGeometry = this->GetDataNode()->GetData()->GetTimeGeometry(); if (timeGeometry.IsNotNull()) timeGeometry->SetTimeStepGeometry(newGeometry, timeStep); interactionEvent->GetSender()->GetRenderingManager()->RequestUpdateAll(); return true; } else return false; } - -bool mitk::AffineDataInteractor3D::ColorizeSurface(BaseRenderer::Pointer renderer, double scalar) +void mitk::AffineDataInteractor3D::RestoreNodeColor() { - BaseData::Pointer data = this->GetDataNode()->GetData(); - if(data.IsNull()) - { - MITK_ERROR << "AffineInteractor3D: No data object present!"; - return false; - } - - // Get the timestep to also support 3D+t - int timeStep = 0; - if (renderer.IsNotNull()) - timeStep = renderer->GetTimeStep(data); - - - // If data is an mitk::Surface, extract it - Surface::Pointer surface = dynamic_cast< Surface* >(data.GetPointer()); - vtkPolyData* polyData = NULL; - if (surface.IsNotNull()) - polyData = surface->GetVtkPolyData(timeStep); - - if (polyData == NULL) - { - MITK_ERROR << "AffineInteractor3D: No poly data present!"; - return false; - } - - vtkPointData* pointData = polyData->GetPointData(); - if (pointData == NULL) - { - MITK_ERROR << "AffineInteractor3D: No point data present!"; - return false; - } - - vtkDataArray* scalars = pointData->GetScalars(); - if (scalars == NULL) - { - MITK_ERROR << "AffineInteractor3D: No scalars for point data present!"; - return false; - } - - for (vtkIdType i = 0; i < pointData->GetNumberOfTuples(); ++i) + mitk::DataNode::Pointer inputNode = this->GetDataNode(); + if(inputNode.IsNull()) + return; + mitk::ColorProperty::Pointer color = dynamic_cast(inputNode->GetProperty(priorPropertyName)); + if ( color.IsNotNull() ) { - scalars->SetComponent(i, 0, scalar); + inputNode->GetPropertyList()->SetProperty("color", color); } - polyData->Modified(); - pointData->Update(); + inputNode->GetPropertyList()->DeleteProperty(selectedColorPropertyName); + inputNode->GetPropertyList()->DeleteProperty(deselectedColorPropertyName); + inputNode->GetPropertyList()->DeleteProperty(priorPropertyName); + inputNode->GetPropertyList()->DeleteProperty(translationStepSizePropertyName); + inputNode->GetPropertyList()->DeleteProperty(rotationStepSizePropertyName); + inputNode->GetPropertyList()->DeleteProperty(scaleStepSizePropertyName); - return true; + //update rendering + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } diff --git a/Modules/DataTypesExt/mitkAffineDataInteractor3D.h b/Modules/DataTypesExt/mitkAffineDataInteractor3D.h index 38a7cac017..24794ad068 100644 --- a/Modules/DataTypesExt/mitkAffineDataInteractor3D.h +++ b/Modules/DataTypesExt/mitkAffineDataInteractor3D.h @@ -1,82 +1,98 @@ /*=================================================================== 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 mitkAffineDataInteractor3D_h_ #define mitkAffineDataInteractor3D_h_ -#include "mitkBaseRenderer.h" -#include "mitkDataInteractor.h" +#include +#include #include "MitkDataTypesExtExports.h" -#include "mitkGeometry3D.h" namespace mitk { /** * \brief Affine interaction with objects in 3D windows. * * \ingroup Interaction */ // Inherit from DataInteratcor, this provides functionality of a state machine and configurable inputs. class MitkDataTypesExt_EXPORT AffineDataInteractor3D: public DataInteractor { public: mitkClassMacro(AffineDataInteractor3D, DataInteractor); itkFactorylessNewMacro(Self) itkCloneMacro(Self) + virtual void SetDataNode(NodeType node); + void TranslateGeometry(mitk::Vector3D translate); + void RotateGeometry(mitk::ScalarType angle, int rotationaxis); protected: AffineDataInteractor3D(); virtual ~AffineDataInteractor3D(); /** * Here actions strings from the loaded state machine pattern are mapped to functions of * the DataInteractor. These functions are called when an action from the state machine pattern is executed. */ virtual void ConnectActionsAndFunctions(); /** * This function is called when a DataNode has been set/changed. */ virtual void DataNodeChanged(); + /** * Initializes the movement, stores starting position. */ - virtual bool CheckOverObject (const InteractionEvent *); + virtual bool CheckOverObject (const InteractionEvent*); virtual bool SelectObject (StateMachineAction*, InteractionEvent*); virtual bool DeselectObject (StateMachineAction*, InteractionEvent*); virtual bool InitTranslate (StateMachineAction*, InteractionEvent*); virtual bool InitRotate (StateMachineAction*, InteractionEvent*); virtual bool TranslateObject (StateMachineAction*, InteractionEvent*); virtual bool RotateObject (StateMachineAction*, InteractionEvent*); + virtual bool TranslateUpKey(StateMachineAction*, InteractionEvent*); + virtual bool TranslateDownKey(StateMachineAction*, InteractionEvent*); + virtual bool TranslateLeftKey(StateMachineAction*, InteractionEvent*); + virtual bool TranslateRightKey(StateMachineAction*, InteractionEvent*); + virtual bool TranslateUpModifierKey(StateMachineAction*, InteractionEvent*); + virtual bool TranslateDownModifierKey(StateMachineAction*, InteractionEvent*); + + virtual bool RotateUpKey(StateMachineAction*, InteractionEvent*); + virtual bool RotateDownKey(StateMachineAction*, InteractionEvent*); + virtual bool RotateLeftKey(StateMachineAction*, InteractionEvent*); + virtual bool RotateRightKey(StateMachineAction*, InteractionEvent*); + virtual bool RotateUpModifierKey(StateMachineAction*, InteractionEvent*); + virtual bool RotateDownModifierKey(StateMachineAction*, InteractionEvent*); + + virtual bool ScaleGeometry(mitk::StateMachineAction *, mitk::InteractionEvent *); -private: - bool ColorizeSurface(BaseRenderer::Pointer renderer, double scalar = 0.0); + virtual void RestoreNodeColor(); + +private: double m_InitialPickedWorldPoint[4]; Point2D m_InitialPickedDisplayPoint; - //Point3D m_CurrentPickedPoint; - //Point2D m_CurrentPickedDisplayPoint; - Geometry3D::Pointer m_OriginalGeometry; Vector3D m_ObjectNormal; }; } #endif diff --git a/Plugins/PluginList.cmake b/Plugins/PluginList.cmake index 3bf25ed2aa..2b4db8f5bf 100644 --- a/Plugins/PluginList.cmake +++ b/Plugins/PluginList.cmake @@ -1,49 +1,50 @@ # Plug-ins must be ordered according to their dependencies set(MITK_EXT_PLUGINS org.mitk.core.services:ON org.mitk.gui.common:ON org.mitk.planarfigure:ON org.mitk.core.ext:OFF org.mitk.core.jobs:OFF org.mitk.diffusionimaging:OFF org.mitk.simulation:OFF org.mitk.gui.qt.application:ON org.mitk.gui.qt.coreapplication:OFF org.mitk.gui.qt.ext:OFF org.mitk.gui.qt.extapplication:OFF org.mitk.gui.qt.common:ON org.mitk.gui.qt.stdmultiwidgeteditor:ON org.mitk.gui.qt.common.legacy:OFF org.mitk.gui.qt.cmdlinemodules:OFF org.mitk.gui.qt.diffusionimagingapp:OFF org.mitk.gui.qt.datamanager:ON org.mitk.gui.qt.datamanagerlight:OFF org.mitk.gui.qt.properties:ON org.mitk.gui.qt.basicimageprocessing:OFF org.mitk.gui.qt.dicom:OFF org.mitk.gui.qt.diffusionimaging:OFF org.mitk.gui.qt.dtiatlasapp:OFF + org.mitk.gui.qt.geometrytools:OFF org.mitk.gui.qt.igtexamples:OFF org.mitk.gui.qt.igttracking:OFF org.mitk.gui.qt.imagecropper:OFF org.mitk.gui.qt.imagenavigator:ON org.mitk.gui.qt.viewnavigator:OFF org.mitk.gui.qt.materialeditor:OFF org.mitk.gui.qt.measurementtoolbox:OFF org.mitk.gui.qt.moviemaker:OFF org.mitk.gui.qt.pointsetinteraction:OFF org.mitk.gui.qt.python:OFF org.mitk.gui.qt.registration:OFF org.mitk.gui.qt.remeshing:OFF org.mitk.gui.qt.segmentation:OFF org.mitk.gui.qt.simulation:OFF org.mitk.gui.qt.toftutorial:OFF org.mitk.gui.qt.tofutil:OFF org.mitk.gui.qt.ugvisualization:OFF org.mitk.gui.qt.ultrasound:OFF org.mitk.gui.qt.volumevisualization:OFF org.mitk.gui.qt.eventrecorder:OFF org.mitk.gui.qt.xnat:OFF ) diff --git a/Plugins/org.mitk.gui.qt.geometrytools/CMakeLists.txt b/Plugins/org.mitk.gui.qt.geometrytools/CMakeLists.txt new file mode 100644 index 0000000000..f5f6599fe5 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.geometrytools/CMakeLists.txt @@ -0,0 +1,7 @@ +project(org_mitk_gui_qt_geometrytools) + +MACRO_CREATE_MITK_CTK_PLUGIN( + EXPORT_DIRECTIVE GEOMETRYTOOLS_EXPORT + EXPORTED_INCLUDE_SUFFIXES src + MODULE_DEPENDS MitkQtWidgetsExt +) diff --git a/Plugins/org.mitk.gui.qt.geometrytools/documentation/UserManual/Manual.dox b/Plugins/org.mitk.gui.qt.geometrytools/documentation/UserManual/Manual.dox new file mode 100644 index 0000000000..43ddcf1d36 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.geometrytools/documentation/UserManual/Manual.dox @@ -0,0 +1,17 @@ +/** +\page org_mitk_gui_qt_geometrytools The Geometry Tools + +\imageMacro{icon.png,"Icon of Geometry Tools",2.00} + +\tableofcontents + +\section org_mitk_gui_qt_geometrytoolsOverview Overview +Describe the features of your awesome plugin here +
    +
  • Increases productivity +
  • Creates beautiful images +
  • Generates PhD thesis +
  • Brings world peace +
+ +*/ diff --git a/Plugins/org.mitk.gui.qt.geometrytools/documentation/UserManual/icon.xpm b/Plugins/org.mitk.gui.qt.geometrytools/documentation/UserManual/icon.xpm new file mode 100644 index 0000000000..9057c20bc6 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.geometrytools/documentation/UserManual/icon.xpm @@ -0,0 +1,21 @@ +/* XPM */ +static const char * icon_xpm[] = { +"16 16 2 1", +" c #FF0000", +". c #000000", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/Plugins/org.mitk.gui.qt.geometrytools/documentation/doxygen/modules.dox b/Plugins/org.mitk.gui.qt.geometrytools/documentation/doxygen/modules.dox new file mode 100644 index 0000000000..257a5d7d17 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.geometrytools/documentation/doxygen/modules.dox @@ -0,0 +1,16 @@ +/** + \defgroup org_mitk_gui_qt_geometrytools org.mitk.gui.qt.geometrytools + \ingroup MITKPlugins + + \brief Describe your plugin here. + +*/ + +/** + \defgroup org_mitk_gui_qt_geometrytools_internal Internal + \ingroup org_mitk_gui_qt_geometrytools + + \brief This subcategory includes the internal classes of the org.mitk.gui.qt.geometrytools plugin. Other + plugins must not rely on these classes. They contain implementation details and their interface + may change at any time. We mean it. +*/ diff --git a/Plugins/org.mitk.gui.qt.geometrytools/files.cmake b/Plugins/org.mitk.gui.qt.geometrytools/files.cmake new file mode 100644 index 0000000000..39da839b64 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.geometrytools/files.cmake @@ -0,0 +1,42 @@ +set(SRC_CPP_FILES + +) + +set(INTERNAL_CPP_FILES + org_mitk_gui_qt_geometrytools_Activator.cpp + mitkGeometryToolsView.cpp +) + +set(UI_FILES + src/internal/mitkGeometryToolsViewControls.ui +) + +set(MOC_H_FILES + src/internal/org_mitk_gui_qt_geometrytools_Activator.h + src/internal/mitkGeometryToolsView.h +) + +# list of resource files which can be used by the plug-in +# system without loading the plug-ins shared library, +# for example the icon used in the menu and tabs for the +# plug-in views in the workbench +set(CACHED_RESOURCE_FILES + resources/icon.xpm + plugin.xml +) + +# list of Qt .qrc files which contain additional resources +# specific to this plugin +set(QRC_FILES + +) + +set(CPP_FILES ) + +foreach(file ${SRC_CPP_FILES}) + set(CPP_FILES ${CPP_FILES} src/${file}) +endforeach(file ${SRC_CPP_FILES}) + +foreach(file ${INTERNAL_CPP_FILES}) + set(CPP_FILES ${CPP_FILES} src/internal/${file}) +endforeach(file ${INTERNAL_CPP_FILES}) diff --git a/Plugins/org.mitk.gui.qt.geometrytools/manifest_headers.cmake b/Plugins/org.mitk.gui.qt.geometrytools/manifest_headers.cmake new file mode 100644 index 0000000000..17165dc97f --- /dev/null +++ b/Plugins/org.mitk.gui.qt.geometrytools/manifest_headers.cmake @@ -0,0 +1,5 @@ +set(Plugin-Name "Geometry Tools") +set(Plugin-Version "0.1") +set(Plugin-Vendor "DKFZ") +set(Plugin-ContactAddress "") +set(Require-Plugin org.mitk.gui.qt.common) diff --git a/Plugins/org.mitk.gui.qt.geometrytools/plugin.xml b/Plugins/org.mitk.gui.qt.geometrytools/plugin.xml new file mode 100644 index 0000000000..efb63bfd54 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.geometrytools/plugin.xml @@ -0,0 +1,11 @@ + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.geometrytools/resources/icon.xpm b/Plugins/org.mitk.gui.qt.geometrytools/resources/icon.xpm new file mode 100644 index 0000000000..9057c20bc6 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.geometrytools/resources/icon.xpm @@ -0,0 +1,21 @@ +/* XPM */ +static const char * icon_xpm[] = { +"16 16 2 1", +" c #FF0000", +". c #000000", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/Plugins/org.mitk.gui.qt.geometrytools/src/internal/mitkGeometryToolsView.cpp b/Plugins/org.mitk.gui.qt.geometrytools/src/internal/mitkGeometryToolsView.cpp new file mode 100644 index 0000000000..37de84d983 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.geometrytools/src/internal/mitkGeometryToolsView.cpp @@ -0,0 +1,92 @@ +/*=================================================================== + +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. + +===================================================================*/ + + +// Blueberry +#include +#include + +// Qmitk +#include "mitkGeometryToolsView.h" + +// Qt +#include + +//mitk image +#include +#include +#include +#include + +const std::string mitkGeometryToolsView::VIEW_ID = "org.mitk.views.geometrytools"; + +void mitkGeometryToolsView::SetFocus() +{ + m_Controls.m_TranslateButton->setFocus(); +} + +void mitkGeometryToolsView::CreateQtPartControl( QWidget *parent ) +{ + // create GUI widgets from the Qt Designer's .ui file + m_Controls.setupUi( parent ); + connect( m_Controls.m_TranslateButton, SIGNAL(clicked()), this, SLOT(DoImageProcessing()) ); + connect( m_Controls.m_RotateButton, SIGNAL(clicked()), this, SLOT(AddRotationInteractor()) ); +} + +void mitkGeometryToolsView::OnSelectionChanged( berry::IWorkbenchPart::Pointer /*source*/, + const QList& nodes ) +{ + // iterate all selected objects, adjust warning visibility + foreach( mitk::DataNode::Pointer node, nodes ) + { + if( node.IsNotNull() ) + { + m_Controls.m_TranslateButton->setEnabled( true ); + return; + } + } + + m_Controls.m_TranslateButton->setEnabled( false ); +} + + +void mitkGeometryToolsView::DoImageProcessing() +{ + QList nodes = this->GetDataManagerSelection(); + if (nodes.empty()) return; + + mitk::DataNode::Pointer node = nodes.front(); + + mitk::AffineDataInteractor3D::Pointer affineDataInteractor = mitk::AffineDataInteractor3D::New(); + affineDataInteractor->LoadStateMachine("AffineInteraction3D.xml", us::ModuleRegistry::GetModule("MitkDataTypesExt")); + affineDataInteractor->SetEventConfig("AffineTranslationConfig.xml", us::ModuleRegistry::GetModule("MitkDataTypesExt")); + affineDataInteractor->SetDataNode(node); + node->SetBoolProperty("pickable", true); +} + +void mitkGeometryToolsView::AddRotationInteractor() +{ + QList nodes = this->GetDataManagerSelection(); + if (nodes.empty()) return; + + mitk::DataNode::Pointer node = nodes.front(); + + mitk::AffineDataInteractor3D::Pointer affineDataInteractor = mitk::AffineDataInteractor3D::New(); + affineDataInteractor->LoadStateMachine("AffineInteraction3D.xml", us::ModuleRegistry::GetModule("MitkDataTypesExt")); + affineDataInteractor->SetEventConfig("AffineRotationConfig.xml", us::ModuleRegistry::GetModule("MitkDataTypesExt")); + affineDataInteractor->SetDataNode(node); + node->SetBoolProperty("pickable", true); +} diff --git a/Plugins/org.mitk.gui.qt.geometrytools/src/internal/mitkGeometryToolsView.h b/Plugins/org.mitk.gui.qt.geometrytools/src/internal/mitkGeometryToolsView.h new file mode 100644 index 0000000000..b0bd72fcda --- /dev/null +++ b/Plugins/org.mitk.gui.qt.geometrytools/src/internal/mitkGeometryToolsView.h @@ -0,0 +1,66 @@ +/*=================================================================== + +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 mitkGeometryToolsView_h +#define mitkGeometryToolsView_h + +#include + +#include + +#include "ui_mitkGeometryToolsViewControls.h" + + +/** + \brief mitkGeometryToolsView + + \warning This class is not yet documented. Use "git blame" and ask the author to provide basic documentation. + + \sa QmitkAbstractView + \ingroup ${plugin_target}_internal +*/ +class mitkGeometryToolsView : public QmitkAbstractView +{ + // this is needed for all Qt objects that should have a Qt meta-object + // (everything that derives from QObject and wants to have signal/slots) + Q_OBJECT + + public: + + static const std::string VIEW_ID; + +protected slots: + + /// \brief Called when the user clicks the GUI button + void DoImageProcessing(); + void AddRotationInteractor(); + + protected: + + virtual void CreateQtPartControl(QWidget *parent); + + virtual void SetFocus(); + + /// \brief called by QmitkFunctionality when DataManager's selection has changed + virtual void OnSelectionChanged( berry::IWorkbenchPart::Pointer source, + const QList& nodes ); + + Ui::mitkGeometryToolsViewControls m_Controls; + +}; + +#endif // mitkGeometryToolsView_h diff --git a/Plugins/org.mitk.gui.qt.geometrytools/src/internal/mitkGeometryToolsViewControls.ui b/Plugins/org.mitk.gui.qt.geometrytools/src/internal/mitkGeometryToolsViewControls.ui new file mode 100644 index 0000000000..5c2d4dc81b --- /dev/null +++ b/Plugins/org.mitk.gui.qt.geometrytools/src/internal/mitkGeometryToolsViewControls.ui @@ -0,0 +1,68 @@ + + + mitkGeometryToolsViewControls + + + + 0 + 0 + 222 + 161 + + + + + 0 + 0 + + + + QmitkTemplate + + + + + + Do image processing + + + Translate + + + + + + + Rotate + + + + + + + Scale + + + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 20 + 220 + + + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.geometrytools/src/internal/org_mitk_gui_qt_geometrytools_Activator.cpp b/Plugins/org.mitk.gui.qt.geometrytools/src/internal/org_mitk_gui_qt_geometrytools_Activator.cpp new file mode 100644 index 0000000000..8729a61d9e --- /dev/null +++ b/Plugins/org.mitk.gui.qt.geometrytools/src/internal/org_mitk_gui_qt_geometrytools_Activator.cpp @@ -0,0 +1,40 @@ +/*=================================================================== + +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 "org_mitk_gui_qt_geometrytools_Activator.h" + +#include + +#include "mitkGeometryToolsView.h" + +namespace mitk { + +void org_mitk_gui_qt_geometrytools_Activator::start(ctkPluginContext* context) +{ + BERRY_REGISTER_EXTENSION_CLASS(mitkGeometryToolsView, context) +} + +void org_mitk_gui_qt_geometrytools_Activator::stop(ctkPluginContext* context) +{ + Q_UNUSED(context) +} + +} + +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + Q_EXPORT_PLUGIN2(org_mitk_gui_qt_geometrytools, mitk::org_mitk_gui_qt_geometrytools_Activator) +#endif diff --git a/Plugins/org.mitk.gui.qt.geometrytools/src/internal/org_mitk_gui_qt_geometrytools_Activator.h b/Plugins/org.mitk.gui.qt.geometrytools/src/internal/org_mitk_gui_qt_geometrytools_Activator.h new file mode 100644 index 0000000000..324aff00a6 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.geometrytools/src/internal/org_mitk_gui_qt_geometrytools_Activator.h @@ -0,0 +1,43 @@ +/*=================================================================== + +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 org_mitk_gui_qt_geometrytools_Activator_h +#define org_mitk_gui_qt_geometrytools_Activator_h + +#include + +namespace mitk { + +class org_mitk_gui_qt_geometrytools_Activator : + public QObject, public ctkPluginActivator +{ + Q_OBJECT +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_geometrytools") +#endif + Q_INTERFACES(ctkPluginActivator) + +public: + + void start(ctkPluginContext* context); + void stop(ctkPluginContext* context); + +}; // org_mitk_gui_qt_geometrytools_Activator + +} + +#endif // org_mitk_gui_qt_geometrytools_Activator_h