diff --git a/Core/Code/TestingHelper/mitkInteractionTestHelper.cpp b/Core/Code/TestingHelper/mitkInteractionTestHelper.cpp index 9e97533485..8801b56701 100644 --- a/Core/Code/TestingHelper/mitkInteractionTestHelper.cpp +++ b/Core/Code/TestingHelper/mitkInteractionTestHelper.cpp @@ -1,155 +1,198 @@ /*=================================================================== 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. ===================================================================*/ //MITK #include #include #include #include #include //us #include #include mitk::InteractionTestHelper::InteractionTestHelper(const std::string &interactionXmlFilePath) : m_InteractionFilePath(interactionXmlFilePath) { this->Initialize(interactionXmlFilePath); } void mitk::InteractionTestHelper::Initialize(const std::string &interactionXmlFilePath) { //TiXmlDocument document(interactionXmlPath.c_str()); TiXmlDocument document(interactionXmlFilePath); bool loadOkay = document.LoadFile(); if (loadOkay) { // Global interaction must(!) be initialized if(! mitk::GlobalInteraction::GetInstance()->IsInitialized()) mitk::GlobalInteraction::GetInstance()->Initialize("global"); //get RenderingManager instance mitk::RenderingManager* rm = mitk::RenderingManager::GetInstance(); //create data storage m_DataStorage = mitk::StandaloneDataStorage::New(); //for each renderer found create a render window and configure for( TiXmlElement* element = document.FirstChildElement(mitk::InteractionEventConst::xmlTagInteractions())->FirstChildElement(mitk::InteractionEventConst::xmlTagConfigRoot())->FirstChildElement(mitk::InteractionEventConst::xmlTagRenderer()); element != NULL; element = element->NextSiblingElement(mitk::InteractionEventConst::xmlTagRenderer()) ) { //get name of renderer const char* rendererName = element->Attribute(mitk::InteractionEventConst::xmlEventPropertyRendererName().c_str()); //get view direction int viewDirectionNum = std::atoi(element->Attribute(mitk::InteractionEventConst::xmlEventPropertyViewDirection())->c_str()); mitk::SliceNavigationController::ViewDirection viewDirection = static_cast(viewDirectionNum); //create renderWindow, renderer and dispatcher mitk::RenderWindow::Pointer rw = mitk::RenderWindow::New(NULL, rendererName, rm); //VtkRenderWindow is created within constructor if NULL //set storage of renderer rw->GetRenderer()->SetDataStorage(m_DataStorage); //set view direction to axial rw->GetSliceNavigationController()->SetDefaultViewDirection( viewDirection ); //set renderer to render 2D rw->GetRenderer()->SetMapperID(mitk::BaseRenderer::Standard2D); //connect SliceNavigationControllers to timestep changed event of TimeNavigationController rw->GetSliceNavigationController()->ConnectGeometryTimeEvent(rm->GetTimeNavigationController(), false); //add to list of kown render windows m_RenderWindowList.push_back(rw); } //########### register display interactor to handle scroll events ################## //use MouseModeSwitcher to ensure that the statemachine of DisplayInteractor is loaded correctly m_MouseModeSwitcher = mitk::MouseModeSwitcher::New(); } else { mitkThrow() << "Can not load interaction xml file <" << m_InteractionFilePath << ">"; } } mitk::InteractionTestHelper::~InteractionTestHelper() { //unregister renderers InteractionTestHelper::RenderWindowListType::iterator it = m_RenderWindowList.begin(); InteractionTestHelper::RenderWindowListType::iterator end = m_RenderWindowList.end(); for(; it != end; it++) { mitk::BaseRenderer::RemoveInstance((*it)->GetVtkRenderWindow()); } } mitk::DataStorage::Pointer mitk::InteractionTestHelper::GetDataStorage() { return m_DataStorage; } void mitk::InteractionTestHelper::AddNodeToStorage(mitk::DataNode::Pointer node) { this->m_DataStorage->Add(node); mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(m_DataStorage); } void mitk::InteractionTestHelper::PlaybackInteraction() { //load events if not loaded yet if(m_Events.empty()) this->LoadInteraction(); //playback all events in queue for (unsigned long i=0; i < m_Events.size(); ++i) { //let dispatcher of sending renderer process the event m_Events.at(i)->GetSender()->GetDispatcher()->ProcessEvent(m_Events.at(i)); } } void mitk::InteractionTestHelper::LoadInteraction() { //load interaction pattern from xml file std::ifstream xmlStream(m_InteractionFilePath.c_str()); mitk::XML2EventParser parser(xmlStream); m_Events = parser.GetInteractions(); xmlStream.close(); } void mitk::InteractionTestHelper::SetTimeStep(int newTimeStep) { bool timeStepIsvalid = mitk::RenderingManager::GetInstance()->GetTimeNavigationController()->GetCreatedWorldGeometry()->IsValidTimeStep(newTimeStep); if(timeStepIsvalid) { mitk::RenderingManager::GetInstance()->GetTimeNavigationController()->GetTime()->SetPos(newTimeStep); } } + + +mitk::RenderWindow* mitk::InteractionTestHelper::GetRenderWindowByName(const std::string &name) +{ + InteractionTestHelper::RenderWindowListType::iterator it = m_RenderWindowList.begin(); + InteractionTestHelper::RenderWindowListType::iterator end = m_RenderWindowList.end(); + + for(; it != end; it++) + { + if( name.compare( (*it)->GetRenderer()->GetName() ) == 0) + return (*it).GetPointer(); + } + + return NULL; +} + + +mitk::RenderWindow* mitk::InteractionTestHelper::GetRenderWindowByDefaultViewDirection(mitk::SliceNavigationController::ViewDirection viewDirection) +{ + InteractionTestHelper::RenderWindowListType::iterator it = m_RenderWindowList.begin(); + InteractionTestHelper::RenderWindowListType::iterator end = m_RenderWindowList.end(); + + for(; it != end; it++) + { + if( viewDirection == (*it)->GetSliceNavigationController()->GetDefaultViewDirection() ) + return (*it).GetPointer(); + } + + return NULL; +} + + +mitk::RenderWindow* mitk::InteractionTestHelper::GetRenderWindow(unsigned int index) +{ + if( index < m_RenderWindowList.size() ) + { + return m_RenderWindowList.at(index).GetPointer(); + } + else + { + return NULL; + } +} diff --git a/Core/Code/TestingHelper/mitkInteractionTestHelper.h b/Core/Code/TestingHelper/mitkInteractionTestHelper.h index 6094d6f149..03fcc08766 100644 --- a/Core/Code/TestingHelper/mitkInteractionTestHelper.h +++ b/Core/Code/TestingHelper/mitkInteractionTestHelper.h @@ -1,117 +1,140 @@ /*=================================================================== 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 mitkInteractionTestHelper_h #define mitkInteractionTestHelper_h #include #include #include #include #include #include class vtkRenderWindow; class vtkRenderer; namespace mitk { /** @brief Creates everything needed to load and playback interaction events. * * The interaction is loaded from an xml file and the event are created. This file is * usually a recorded user interaction with the GUI. This can be done with InteractionEventRecorder * plugin. Also all necessary objects to handle interaction events are generated. * The user of this class is responsible to add the data object to interact with to the data storage * of InteractionTestHelper. And must also make sure that a proper data interactor is associated with the data object. * * To test a PointSet interaction for instance make sure you have a PointSet node and a PointSetDataInteractor. * Then just add the node to the storage of the your InteractionTestHelper by calling InteractionTestHelper::AddNodeToStorage. * Use InteractionTestHelper::PlaybackInteraction to execute. The result can afterwards be compared to a reference object. * * Make sure to destroy the test helper instance after each test, since all render windows and its renderers have to be unregistered. * * \sa XML2EventParser * \sa EventFactory * \sa EventRecorder */ class MITK_TESTINGHELPER_EXPORT InteractionTestHelper { public: /** * @brief InteractionTestHelper set up all neseccary objects by calling Initialize. * @param interactionXmlFilePath path to xml file containing events and configuration information for the render windows. */ InteractionTestHelper(const std::string &interactionXmlFilePath); //unregisters all render windows and its renderers. virtual ~InteractionTestHelper(); /** @brief Returns the datastorage, in order to modify the data inside a rendering test. **/ mitk::DataStorage::Pointer GetDataStorage(); /** * @brief AddNodeToStorage Add a node to the datastorage and perform a reinit which is necessary for rendering. * @param node The data you want to add. */ void AddNodeToStorage(mitk::DataNode::Pointer node); /** * @brief PlaybackInteraction playback loaded interaction by passing events to the dispatcher. */ void PlaybackInteraction(); /** * @brief SetTimeStep Sets timesteps of all SliceNavigationControllers to given timestep. * @param newTimeStep new timestep * * Does the same as using ImageNavigators Time slider. Use this if your data was modified in a timestep other than 0. */ void SetTimeStep(int newTimeStep); typedef std::vector RenderWindowListType; + const RenderWindowListType& GetRenderWindowList() { return m_RenderWindowList;} + + /** + * @brief GetRenderWindowByName Get renderWindow by the name of its renderer. + * @param name The name of the renderer of the desired renderWindow. + * @return NULL if not found. + */ + RenderWindow* GetRenderWindowByName(const std::string &name); + + /** + * @brief GetRenderWindowByDefaultViewDirection Get a renderWindow by its default viewdirection. + * @param viewDirection + * @return NULL if not found. + */ + RenderWindow* GetRenderWindowByDefaultViewDirection(mitk::SliceNavigationController::ViewDirection viewDirection); + + /** + * @brief GetRenderWindow Get renderWindow at position 'index'. + * @param index Position within the renderWindow list. + * @return NULL if index is out of bounds. + */ + RenderWindow* GetRenderWindow(unsigned int index); + protected: /** * @brief Initialize Internal method to initialize the renderwindow and set the datastorage. * @throws mitk::Exception if interaction xml file can not be loaded. */ void Initialize(const std::string &interactionXmlFilePath); /** * @brief LoadInteraction loads events from xml file. * @param interactionXmlPath path to xml file with interaction events. */ void LoadInteraction(); mitk::XML2EventParser::EventContainerType m_Events; // List with loaded interaction events std::string m_InteractionFilePath; RenderWindowListType m_RenderWindowList; mitk::DataStorage::Pointer m_DataStorage; mitk::MouseModeSwitcher::Pointer m_MouseModeSwitcher; }; }//namespace mitk #endif