diff --git a/Core/Code/Interactions/mitkMoveBaseDataInteractor.cpp b/Core/Code/Interactions/mitkMoveBaseDataInteractor.cpp index 5af2fbdd24..73aa38f073 100644 --- a/Core/Code/Interactions/mitkMoveBaseDataInteractor.cpp +++ b/Core/Code/Interactions/mitkMoveBaseDataInteractor.cpp @@ -1,190 +1,182 @@ /*=================================================================== 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 "mitkMoveBaseDataInteractor.h" -#include "mitkSurface.h" #include "mitkInteractionConst.h" #include #include "mitkDisplayPositionEvent.h" #include "mitkStateEvent.h" #include "mitkProperties.h" //for an temporary update #include "mitkRenderingManager.h" //## Default Constructor mitk::MoveBaseDataInteractor ::MoveBaseDataInteractor(const char * type, DataNode* dataNode) :Interactor(type, dataNode) { } mitk::MoveBaseDataInteractor::~MoveBaseDataInteractor() { mitk::ColorProperty::Pointer color = dynamic_cast(m_DataNode->GetProperty("color")); if ( color.IsNull() ) { color = mitk::ColorProperty::New(); m_DataNode->GetPropertyList()->SetProperty("color", color); } color->SetColor(1.0, 1.0, 1.0); //update rendering mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } bool mitk::MoveBaseDataInteractor::ExecuteAction( Action* action, mitk::StateEvent const* stateEvent ) { bool ok = false; /*Each case must watch the type of the event!*/ switch (action->GetActionId()) { case AcDONOTHING: ok = true; break; case AcCHECKELEMENT: /* * picking: Answer the question if the given position within stateEvent is close enough to select an object * send yes if close enough and no if not picked */ { mitk::DisplayPositionEvent const *posEvent = dynamic_cast (stateEvent->GetEvent()); if (posEvent == NULL) { MITK_WARN<<"Wrong usage of mitkMoveBaseDataInteractor! Aborting interaction!\n"; return false; } mitk::Point3D worldPoint = posEvent->GetWorldPosition(); /* now we have a worldpoint. check if it is inside our object and select/deselect it accordingly */ std::auto_ptr newStateEvent; const Geometry3D* geometry = GetData()->GetUpdatedTimeSlicedGeometry()->GetGeometry3D( m_TimeStep ); if (geometry->IsInside(worldPoint)) newStateEvent.reset(new mitk::StateEvent(EIDYES, stateEvent->GetEvent())); else newStateEvent.reset(new mitk::StateEvent(EIDNO, stateEvent->GetEvent())); /* write new state (selected/not selected) to the property */ this->HandleEvent( newStateEvent.get() ); ok = true; break; } case AcSELECT: // select the data { mitk::BoolProperty::Pointer selected = dynamic_cast(m_DataNode->GetProperty("selected")); if ( selected.IsNull() ) { selected = mitk::BoolProperty::New(); m_DataNode->GetPropertyList()->SetProperty("selected", selected); } mitk::ColorProperty::Pointer color = dynamic_cast(m_DataNode->GetProperty("color")); if ( color.IsNull() ) { color = mitk::ColorProperty::New(); m_DataNode->GetPropertyList()->SetProperty("color", color); } selected->SetValue(true); color->SetColor(0.0, 1.0, 0.0); //update rendering mitk::RenderingManager::GetInstance()->RequestUpdateAll(); ok = true; break; } case AcDESELECT: //deselect the data { mitk::BoolProperty::Pointer selected = dynamic_cast(m_DataNode->GetProperty("selected")); if ( selected.IsNull() ) { selected = mitk::BoolProperty::New(); m_DataNode->GetPropertyList()->SetProperty("selected", selected); } mitk::ColorProperty::Pointer color = dynamic_cast(m_DataNode->GetProperty("color")); if ( color.IsNull() ) { color = mitk::ColorProperty::New(); m_DataNode->GetPropertyList()->SetProperty("color", color); } selected = mitk::BoolProperty::New(false); color->SetColor(0.0, 0.0, 1.0); //update rendering mitk::RenderingManager::GetInstance()->RequestUpdateAll(); ok = true; break; } case AcMOVE: { //modify Geometry from data as given in parameters or in event mitk::IntProperty* xP = dynamic_cast(action->GetProperty("DIRECTION_X")); mitk::IntProperty* yP = dynamic_cast(action->GetProperty("DIRECTION_Y")); mitk::IntProperty* zP = dynamic_cast(action->GetProperty("DIRECTION_Z")); if (xP == NULL || yP == NULL || zP == NULL) { MITK_WARN<<"No properties returned\n!"; return false; } mitk::Vector3D movementVector; movementVector.SetElement(0, (float) xP->GetValue()); movementVector.SetElement(1, (float) yP->GetValue()); movementVector.SetElement(2, (float) zP->GetValue()); - //checking corresponding Data; has to be a surface or a subclass - mitk::BaseData* surface = dynamic_cast(m_DataNode->GetData()); - if ( surface == NULL ) - { - MITK_WARN<<"MoveBaseDataInteractor got wrong type of data! Aborting interaction!\n"; - return false; - } - Geometry3D* geometry = surface->GetUpdatedTimeSlicedGeometry()->GetGeometry3D( m_TimeStep ); + Geometry3D* geometry = m_DataNode->GetData()->GetUpdatedTimeSlicedGeometry()->GetGeometry3D( m_TimeStep ); geometry->Translate(movementVector); // indicate modification of data tree node m_DataNode->Modified(); //update rendering mitk::RenderingManager::GetInstance()->RequestUpdateAll(); ok = true; break; } default: return Superclass::ExecuteAction( action, stateEvent ); } return ok; } /** \example mitkMoveBaseDataInteractor.cpp * This is an example of how to implement a new Interactor. * See more details about this example in tutorial Step10. */ diff --git a/Examples/Tutorial/Step10.cpp b/Examples/Tutorial/Step10.cpp index 2e6f311aca..6e16968c09 100644 --- a/Examples/Tutorial/Step10.cpp +++ b/Examples/Tutorial/Step10.cpp @@ -1,154 +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. ===================================================================*/ #include "QmitkRegisterClasses.h" #include "QmitkRenderWindow.h" -#include -#include #include +#include #include #include //for the interaction #include #include "mitkGlobalInteraction.h" //##Documentation -//## @brief Load two or more surfaces (stl format, see e.g. Core/Code/Testing/data directory for binary.stl) and display it in a 3D view. +//## @brief Load two or more surfaces (or objects) (e.g. ../mitk-superbuild-release/CMakeExternals/Source/MITK-Data/ball.stl) and display it in a 3D view. //## The MoveBaseDataInteractor explained in tutorial Step10.dox is used to move the surfaces in 3D by arrow keys in combination //## with and without Shift key. Use two surfaces to see that the objects and not the camera are moving. +//## @Warning: In principle, the MoveBaseDataInteractor can move any object +//## and IOUtil can be used to load any object, however, there are no helper +//## planes in this example added to scene. Thus, no image is displayed in +//## the 3D renderwindow (and nothing can be moved/visualized/picked). The +//## data repository contains some pointsets with a single point. For unknown +//## reasons, the picking does not work on pointsets with just one point. +//## You have to use pointsets like: +//## ../mitk-superbuild-release/CMakeExternals/Source/MITK-Data/RenderingTestData/openMeAlone.mps +//## in order to perform the picking/moving. int main(int argc, char* argv[]) { QApplication qtapplication( argc, argv ); if (argc < 2) { fprintf( stderr, "Usage: %s [filename_1] ... [filename_n] \n\n", itksys::SystemTools::GetFilenameName(argv[0]).c_str() ); return 1; } // Register Qmitk-dependent global instances QmitkRegisterClasses(); //************************************************************************* // Part I: Basic initialization //************************************************************************* // Create a DataStorage // The DataStorage manages all data objects. It is used by the // rendering mechanism to render all data objects // We use the standard implementation mitk::StandaloneDataStorage. mitk::StandaloneDataStorage::Pointer ds = mitk::StandaloneDataStorage::New(); - //************************************************************************* - // Part II: Create surface data by reading an stl file + // Part II: Create objects by reading files //************************************************************************* for(int i=1; iSetFileName(filename); - reader->Update(); + //try to read the file with IOUtil which offers lots of I/O methods + node = mitk::IOUtil::LoadDataNode(filename); + // Add the node to the DataStorage + ds->Add(node); } - catch(...) + catch(mitk::Exception &e) { - fprintf( stderr, "Could not open file %s \n\n", filename ); - exit(2); + MITK_ERROR << "An exception occured! Message: " << e.what(); + exit(2); } - - //************************************************************************* - // Part III: Put the data into the datastorage - //************************************************************************* - - // Create a node and add the Image (which is read from the file) to it - mitk::DataNode::Pointer node = mitk::DataNode::New(); - node->SetData(reader->GetOutput()); - - // ******************************************************* - // ****************** START OF NEW PART ****************** - // ******************************************************* - // create interactor // use it with up, down (->z direction), left and right (x-direction) arrow keys. Also hold Shift to translate in y direction. // see state machine pattern SelectAndMoveObjectWithArrowKeys in file StateMachine.xml for definition of interaction or use the StatemachineEditor. - mitk::MoveBaseDataInteractor::Pointer surfaceInteractor = + mitk::MoveBaseDataInteractor::Pointer moveBaseDataInteractor = mitk::MoveBaseDataInteractor::New("SelectAndMoveObjectWithArrowKeys",node); //activate interactor at interaction controller: - mitk::GlobalInteraction::GetInstance()->AddInteractor(surfaceInteractor); - - // ******************************************************* - // ******************* END OF NEW PART ******************* - // ******************************************************* - - // Add the node to the DataStorage - ds->Add(node); + mitk::GlobalInteraction::GetInstance()->AddInteractor(moveBaseDataInteractor); //doesn't have to be done, but nicer! Is destroyed when leaving the sccope anyway - reader = NULL; - surfaceInteractor = NULL; + moveBaseDataInteractor = NULL; } + // ******************************************************* + // ******************* END OF NEW PART ******************* + // ******************************************************* //************************************************************************* // Part IV: Create window and pass the datastorage to it //************************************************************************* // Create a RenderWindow QmitkRenderWindow renderWindow; // Tell the RenderWindow which (part of) the datastorage to render renderWindow.GetRenderer()->SetDataStorage(ds); // Use it as a 3D view renderWindow.GetRenderer()->SetMapperID(mitk::BaseRenderer::Standard3D); // Initialize the RenderWindow mitk::TimeSlicedGeometry::Pointer geo = ds->ComputeBoundingGeometry3D(ds->GetAll()); mitk::RenderingManager::GetInstance()->InitializeViews( geo ); //************************************************************************* // Part V: Qt-specific initialization //************************************************************************* renderWindow.show(); renderWindow.resize( 256, 256 ); - MITK_INFO<<"Select an object with a mouse click. Use arrow keys (also with shift-key) to move the surface.\n"; - MITK_INFO<<"Deselecting and selecting an other surface by clicking onto it. Selected surfaces turn yellow, deselected blue.\n"; + MITK_INFO<<"Select an object with a mouse click. Use arrow keys (also with shift-key) to move the object.\n"; + MITK_INFO<<"Deselecting and selecting an other object by clicking onto it. Selected objects turn green, deselected blue.\n"; // for testing #include "QtTesting.h" if (strcmp(argv[argc-1], "-testing") != 0) return qtapplication.exec(); else return QtTesting(); // cleanup: Remove References ds = NULL; } /** \example Step10.cpp */