diff --git a/Modules/IGTBase/include/mitkNavigationDataSet.h b/Modules/IGTBase/include/mitkNavigationDataSet.h index be1ab96b09..d5eec8f00d 100644 --- a/Modules/IGTBase/include/mitkNavigationDataSet.h +++ b/Modules/IGTBase/include/mitkNavigationDataSet.h @@ -1,171 +1,174 @@ /*=================================================================== 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 MITKNAVIGATIONDATASET_H_HEADER_INCLUDED_ #define MITKNAVIGATIONDATASET_H_HEADER_INCLUDED_ #include #include "mitkBaseData.h" #include "mitkNavigationData.h" namespace mitk { /** * \brief Data structure which stores streams of mitk::NavigationData for * multiple tools. * * Use mitk::NavigationDataRecorder to create these sets easily from pipelines. * Use mitk::NavigationDataPlayer to stream from these sets easily. * */ class MITKIGTBASE_EXPORT NavigationDataSet : public BaseData { public: /** * \brief This iterator iterates over the distinct time steps in this set. * * It returns an array of the length equal to GetNumberOfTools(), containing a * mitk::NavigationData for each tool.. */ typedef std::vector< std::vector >::iterator NavigationDataSetIterator; /** * \brief This iterator iterates over the distinct time steps in this set. And is const. * * It returns an array of the length equal to GetNumberOfTools(), containing a * mitk::NavigationData for each tool.. */ typedef std::vector< std::vector >::const_iterator NavigationDataSetConstIterator; mitkClassMacro(NavigationDataSet, BaseData); mitkNewMacro1Param(Self, unsigned int); /** * \brief Add mitk::NavigationData of the given tool to the Set. * * @param navigationDatas vector of mitk::NavigationData objects to be added. Make sure that the size of the * vector equals the number of tools given in the constructor * @return true if object was be added to the set successfully, false otherwise */ bool AddNavigationDatas( std::vector navigationDatas ); /** * \brief Get mitk::NavigationData from the given tool at given index. * * @param toolIndex Index of the tool from which mitk::NavigationData should be returned. * @param index Index of the mitk::NavigationData object that should be returned. * @return mitk::NavigationData at the specified indices, 0 if there is no object at the indices. */ NavigationData::Pointer GetNavigationDataForIndex( unsigned int index, unsigned int toolIndex ) const; ///** //* \brief Get last mitk::Navigation object for given tool whose timestamp is less than the given timestamp. //* @param toolIndex Index of the tool from which mitk::NavigationData should be returned. //* @param timestamp Timestamp for selecting last object before. //* @return Last mitk::NavigationData with timestamp less than given timestamp, 0 if there is no adequate object. //*/ // Method not yet supported! //NavigationData::Pointer GetNavigationDataBeforeTimestamp( mitk::NavigationData::TimeStampType timestamp , unsigned int toolIndex ) const; /** * \brief Returns a vector that contains all tracking data for a given tool. * * This is a relatively expensive operation, as it requires the construction of a new vector. * * @param toolIndex Index of the tool for which the stream should be returned. * @return Returns a vector that contains all tracking data for a given tool. */ virtual std::vector< mitk::NavigationData::Pointer > GetDataStreamForTool(unsigned int toolIndex); /** * \brief Returns a vector that contains NavigationDatas for each tool for a given timestep. * * If GetNumberOFTools() equals four, then 4 NavigationDatas will be returned. * * @param index Index of the timeStep for which the datas should be returned. cannot be larger than mitk::NavigationDataSet::Size() * @return Returns a vector that contains all tracking data for a given tool. */ virtual std::vector< mitk::NavigationData::Pointer > GetTimeStep(unsigned int index) const; /** * \brief Returns the number of tools for which NavigationDatas are stored in this set. * * This is always equal to the number given in the constructor of this class. * * @return the number of tools for which NavigationDatas are stored in this set. */ unsigned int GetNumberOfTools() const; /** * \brief Returns the number of time steps stored in this NavigationDataSet. * * This is not the total number of Navigation Datas stored in this set, but the number stored for each tool. * i.e. the total number of NavigationDatas equals Size() * GetNumberOfTools(); * * @return Returns the number of time steps stored in this NavigationDataSet. */ unsigned int Size() const; /** * \brief Returns an iterator pointing to the first TimeStep. * * @return Returns an iterator pointing to the first TimeStep. */ virtual NavigationDataSetConstIterator Begin() const; /** * \brief Returns an iterator pointing behind to the last TimeStep. * * @return Returns an iterator pointing behind to the last TimeStep. */ virtual NavigationDataSetConstIterator End() const; // virtual methods, that need to be implemented, but aren't reasonable for NavigationData virtual void SetRequestedRegionToLargestPossibleRegion( ) override; virtual bool RequestedRegionIsOutsideOfTheBufferedRegion( ) override; virtual bool VerifyRequestedRegion( ) override; virtual void SetRequestedRegion( const itk::DataObject *data ) override; /** * \brief This overrid is probably a little hacky. See Bug 19086. */ virtual bool IsEmpty() const override; + //Converts Navigation Data for each tool to a Point Set and adds it to the data storage + void ConvertNavigationDataToPointSet() const; + protected: /** * \brief Constructs set with fixed number of tools. * @param numTools How many tools are used with this mitk::NavigationDataSet. */ NavigationDataSet( unsigned int numTools ); virtual ~NavigationDataSet( ); /** * \brief Holds all the mitk::NavigationData objects managed by this class. * * The first dimension is the index of the navigation data, the second is the * tool to which this data belongs. i.e. the first dimension is usually the longer one. */ std::vector > m_NavigationDataVectors; /** * \brief The Number of Tools that this class is going to support. */ unsigned int m_NumberOfTools; }; } #endif // MITKNAVIGATIONDATASET_H_HEADER_INCLUDED_ diff --git a/Modules/IGTBase/src/mitkNavigationDataSet.cpp b/Modules/IGTBase/src/mitkNavigationDataSet.cpp index 4424ec9fc1..559fe3fc01 100644 --- a/Modules/IGTBase/src/mitkNavigationDataSet.cpp +++ b/Modules/IGTBase/src/mitkNavigationDataSet.cpp @@ -1,167 +1,190 @@ /*=================================================================== 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 "mitkNavigationDataSet.h" +#include "mitkPointSet.h" +#include "mitkBaseRenderer.h" mitk::NavigationDataSet::NavigationDataSet( unsigned int numberOfTools ) : m_NavigationDataVectors(std::vector >()), m_NumberOfTools(numberOfTools) { } mitk::NavigationDataSet::~NavigationDataSet( ) { } bool mitk::NavigationDataSet::AddNavigationDatas( std::vector navigationDatas ) { // test if tool with given index exist if ( navigationDatas.size() != m_NumberOfTools ) { MITK_WARN("NavigationDataSet") << "Tried to add too many or too few navigation Datas to NavigationDataSet. " << m_NumberOfTools << " required, tried to add " << navigationDatas.size() << "."; return false; } // test for consistent timestamp if ( m_NavigationDataVectors.size() > 0) { for (std::vector::size_type i = 0; i < navigationDatas.size(); i++) if (navigationDatas[i]->GetIGTTimeStamp() <= m_NavigationDataVectors.back()[i]->GetIGTTimeStamp()) { MITK_WARN("NavigationDataSet") << "IGTTimeStamp of new NavigationData should be newer than timestamp of last NavigationData."; return false; } } m_NavigationDataVectors.push_back(navigationDatas); return true; } mitk::NavigationData::Pointer mitk::NavigationDataSet::GetNavigationDataForIndex( unsigned int index, unsigned int toolIndex ) const { if ( index >= m_NavigationDataVectors.size() ) { MITK_WARN("NavigationDataSet") << "There is no NavigationData available at index " << index << "."; return nullptr; } if ( toolIndex >= m_NavigationDataVectors.at(index).size() ) { MITK_WARN("NavigationDataSet") << "There is NavigatitionData available at index " << index << " for tool " << toolIndex << "."; return nullptr; } return m_NavigationDataVectors.at(index).at(toolIndex); } // Method not yet supported, code below compiles but delivers wrong results //mitk::NavigationData::Pointer mitk::NavigationDataSet::GetNavigationDataBeforeTimestamp( // mitk::NavigationData::TimeStampType timestamp, unsigned int toolIndex) const //{ // if ( toolIndex >= m_NavigationDataVectors.size() ) // { // MITK_WARN("NavigationDataSet") << "There is no tool with index " << toolIndex << "."; // return NULL; // } // // std::vector::const_iterator it; // // // iterate through all NavigationData objects of the given tool index // // till the timestamp of the NavigationData is greater then the given timestamp // for (it = m_NavigationDataVectors.at(toolIndex).begin(); // it != m_NavigationDataVectors.at(toolIndex).end(); ++it) // { // if ( (*it)->GetIGTTimeStamp() > timestamp) { break; } // } // // // first element was greater than timestamp -> return null // if ( it == m_NavigationDataVectors.at(toolIndex).begin() ) // { // MITK_WARN("NavigationDataSet") << "No NavigationData was recorded before given timestamp."; // return NULL; // } // // // return last element smaller than the given timestamp // return *(it-1); //} std::vector< mitk::NavigationData::Pointer > mitk::NavigationDataSet::GetDataStreamForTool(unsigned int toolIndex) { if (toolIndex >= m_NumberOfTools ) { MITK_WARN("NavigationDataSet") << "Invalid toolIndex: " << m_NumberOfTools << " Tools known, requested index " << toolIndex << ""; return std::vector(); } std::vector< mitk::NavigationData::Pointer > result; for(std::vector >::size_type i = 0; i < m_NavigationDataVectors.size(); i++) result.push_back(m_NavigationDataVectors[i][toolIndex]); return result; } std::vector< mitk::NavigationData::Pointer > mitk::NavigationDataSet::GetTimeStep(unsigned int index) const { return m_NavigationDataVectors[index]; } unsigned int mitk::NavigationDataSet::GetNumberOfTools() const { return m_NumberOfTools; } unsigned int mitk::NavigationDataSet::Size() const { return m_NavigationDataVectors.size(); } // ---> methods necessary for BaseData void mitk::NavigationDataSet::SetRequestedRegionToLargestPossibleRegion() { } bool mitk::NavigationDataSet::RequestedRegionIsOutsideOfTheBufferedRegion() { return false; } bool mitk::NavigationDataSet::VerifyRequestedRegion() { return true; } void mitk::NavigationDataSet::SetRequestedRegion(const DataObject * ) { } bool mitk::NavigationDataSet::IsEmpty() const { return (Size() == 0); } +void mitk::NavigationDataSet::ConvertNavigationDataToPointSet() const +{ + //iterate over all tools + for (int toolIndex = 0; toolIndex < this->GetNumberOfTools(); ++ toolIndex) + { + mitk::PointSet::Pointer _tempPointSet = mitk::PointSet::New(); + //iterate over all time steps + for (int time = 0; time < m_NavigationDataVectors.size(); time++) + { + _tempPointSet->InsertPoint(time,m_NavigationDataVectors[time][toolIndex]->GetPosition()); + MITK_DEBUG << m_NavigationDataVectors[time][toolIndex]->GetPosition() << " --- " << _tempPointSet->GetPoint(time); + } + mitk::DataNode::Pointer dn = mitk::DataNode::New(); + std::stringstream str; + str << "NavigationData Tool " << toolIndex; + dn->SetProperty("name", mitk::StringProperty::New(str.str())); + dn->SetData(_tempPointSet); + mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget4"))->GetDataStorage()->Add(dn); + } +} + // <--- methods necessary for BaseData // ---> methods for Iterators mitk::NavigationDataSet::NavigationDataSetConstIterator mitk::NavigationDataSet::Begin() const { return m_NavigationDataVectors.cbegin(); } mitk::NavigationDataSet::NavigationDataSetConstIterator mitk::NavigationDataSet::End() const { return m_NavigationDataVectors.cend(); } diff --git a/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkNavigationDataPlayerView.cpp b/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkNavigationDataPlayerView.cpp index 3767f5598c..eabc7aa9a4 100644 --- a/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkNavigationDataPlayerView.cpp +++ b/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkNavigationDataPlayerView.cpp @@ -1,237 +1,240 @@ /*=================================================================== 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. ===================================================================*/ // Qmitk #include "QmitkNavigationDataPlayerView.h" // QT #include #include //mitk #include #include #include #include #include #include // VTK #include const std::string QmitkNavigationDataPlayerView::VIEW_ID = "org.mitk.views.navigationdataplayer"; QmitkNavigationDataPlayerView::QmitkNavigationDataPlayerView() : m_Controls( 0 ) { } QmitkNavigationDataPlayerView::~QmitkNavigationDataPlayerView() { } void QmitkNavigationDataPlayerView::CreateQtPartControl( QWidget *parent ) { // build up qt view, unless already done if ( !m_Controls ) { // create GUI widgets from the Qt Designer's .ui file m_Controls = new Ui::QmitkNavigationDataPlayerViewControls; m_Controls->setupUi( parent ); this->CreateConnections(); // make deselected Player invisible m_Controls->m_TimedWidget->setVisible(false); } } void QmitkNavigationDataPlayerView::SetFocus() { if ( m_Controls ) { m_Controls->m_grpbxControls->setFocus(); } } void QmitkNavigationDataPlayerView::CreateConnections() { connect( m_Controls->m_RdbSequential, SIGNAL(released()), this, SLOT(OnSelectPlayer()) ); connect( m_Controls->m_RdbTimeBased, SIGNAL(released()), this, SLOT(OnSelectPlayer()) ); connect( m_Controls->m_BtnOpenFile, SIGNAL(released()), this, SLOT(OnOpenFile()) ); connect( m_Controls->m_ChkDisplay, SIGNAL(released()), this, SLOT(OnSetDisplay()) ); connect( m_Controls->m_chkRepeat, SIGNAL(stateChanged(int)), this, SLOT(OnSetRepeat(int)) ); connect( m_Controls->m_ChkMicroservice, SIGNAL(released()), this, SLOT(OnSetMicroservice()) ); connect( m_Controls->m_SequentialWidget, SIGNAL(SignalUpdate()), this, SLOT(OnUpdate()) ); connect( m_Controls->m_TimedWidget, SIGNAL(SignalUpdate()), this, SLOT(OnUpdate()) ); this->SetInteractionComponentsEnabledState(false); } void QmitkNavigationDataPlayerView::OnOpenFile() { mitk::NavigationDataReaderInterface::Pointer reader = NULL; QString filter = tr("NavigationData File (*.csv *.xml)"); QString fileName = QFileDialog::getOpenFileName(NULL, tr("Open NavigationData Set"), "", filter); if ( fileName.isNull() ) { return; } // user pressed cancel try { m_Data = dynamic_cast (mitk::IOUtil::LoadBaseData(fileName.toStdString()).GetPointer()); } catch ( const mitk::Exception &e ) { MITK_WARN("NavigationDataPlayerView") << "could not open file " << fileName.toStdString(); QMessageBox::critical(0, "Error Reading File", "The file '" + fileName +"' could not be read.\n" + e.GetDescription() ); return; } + if (m_Controls->m_ChkConvertToPointSet->isChecked()) + m_Data->ConvertNavigationDataToPointSet(); + // Update Labels m_Controls->m_LblFilePath->setText(fileName); m_Controls->m_LblFrames->setText(QString::number(m_Data->Size())); m_Controls->m_LblTools->setText(QString::number(m_Data->GetNumberOfTools())); // Initialize Widgets and create Player this->OnSelectPlayer(); this->SetInteractionComponentsEnabledState(true); } void QmitkNavigationDataPlayerView::OnSelectPlayer() { if (m_Controls->m_RdbSequential->isChecked()) { m_Controls->m_SequentialWidget->setVisible(true); m_Controls->m_TimedWidget->setVisible(false); mitk::NavigationDataSequentialPlayer::Pointer seqPlayer = mitk::NavigationDataSequentialPlayer::New(); seqPlayer->SetNavigationDataSet(m_Data); m_Controls->m_SequentialWidget->SetPlayer(seqPlayer); m_Player = seqPlayer; } else { m_Controls->m_SequentialWidget->setVisible(false); m_Controls->m_TimedWidget->setVisible(true); mitk::NavigationDataPlayer::Pointer timedPlayer = mitk::NavigationDataPlayer::New(); timedPlayer->SetNavigationDataSet(m_Data); m_Controls->m_TimedWidget->SetPlayer(timedPlayer); m_Player = timedPlayer; } this->ConfigurePlayer(); // SetupRenderingPipeline this->OnSetDisplay(); } void QmitkNavigationDataPlayerView::ConfigurePlayer() { // set repeat mode according to the checkbox m_Player->SetRepeat( m_Controls->m_chkRepeat->isChecked() ); } void QmitkNavigationDataPlayerView::OnSetRepeat(int checkState) { m_Player->SetRepeat(checkState != 0); } void QmitkNavigationDataPlayerView::OnSetMicroservice(){ if(m_Controls->m_ChkMicroservice->isChecked()) { m_ToolStorage = mitk::NavigationToolStorage::New(); for (itk::ProcessObject::DataObjectPointerArraySizeType i = 0; i < m_Player->GetNumberOfIndexedOutputs(); i++) { mitk::NavigationTool::Pointer currentDummyTool = mitk::NavigationTool::New(); mitk::VirtualTrackingTool::Pointer dummyTool = mitk::VirtualTrackingTool::New(); std::stringstream name; name << "Virtual Tool " << i; dummyTool->SetToolName(name.str()); currentDummyTool->SetTrackingTool(dummyTool.GetPointer()); currentDummyTool->SetDataNode(m_RenderingNodes.at(i)); currentDummyTool->SetIdentifier(name.str()); m_ToolStorage->AddTool(currentDummyTool); } m_Player->RegisterAsMicroservice(); m_ToolStorage->SetName("NavigationDataPlayer Tool Storage"); m_ToolStorage->RegisterAsMicroservice(m_Player->GetMicroserviceID()); } else { if (m_ToolStorage.IsNotNull()) m_ToolStorage->UnRegisterMicroservice(); m_ToolStorage = NULL; m_Player->UnRegisterMicroservice(); } } void QmitkNavigationDataPlayerView::OnUpdate(){ if (m_VisFilter.IsNotNull()) { m_VisFilter->Update(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkNavigationDataPlayerView::OnSetDisplay(){ DestroyPipeline(); if ( (m_Controls->m_ChkDisplay->isChecked()) && ( m_Player.IsNotNull() )) { CreatePipeline(); } } void QmitkNavigationDataPlayerView::CreatePipeline(){ m_VisFilter = mitk::NavigationDataObjectVisualizationFilter::New(); m_VisFilter->ConnectTo(m_Player); for (unsigned int i = 0 ; i < m_Player->GetNumberOfIndexedOutputs(); i++ ) { mitk::DataNode::Pointer node = mitk::DataNode::New(); QString name = "Recorded Tool " + QString::number(i + 1); node->SetName(name.toStdString()); //create small sphere and use it as surface mitk::Surface::Pointer mySphere = mitk::Surface::New(); vtkSphereSource *vtkData = vtkSphereSource::New(); vtkData->SetRadius(5.0f); vtkData->SetCenter(0.0, 0.0, 0.0); vtkData->Update(); mySphere->SetVtkPolyData(vtkData->GetOutput()); vtkData->Delete(); node->SetData(mySphere); m_VisFilter->SetRepresentationObject(i, mySphere); // Add Node to DataStorageand to local list of Nodes GetDataStorage()->Add(node); m_RenderingNodes.push_back(node); } m_VisFilter->Update(); mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(GetDataStorage()); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkNavigationDataPlayerView::DestroyPipeline(){ m_VisFilter = NULL; for (unsigned int i = 0; i < m_RenderingNodes.size(); i++){ this->GetDataStorage()->Remove(m_RenderingNodes[i]); } m_RenderingNodes.clear(); } void QmitkNavigationDataPlayerView::SetInteractionComponentsEnabledState(bool isActive){ m_Controls->m_grpbxSettings->setEnabled(isActive); m_Controls->m_grpbxControls->setEnabled(isActive); } \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkNavigationDataPlayerViewControls.ui b/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkNavigationDataPlayerViewControls.ui index 01b0369fbc..4e0f4e029a 100644 --- a/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkNavigationDataPlayerViewControls.ui +++ b/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkNavigationDataPlayerViewControls.ui @@ -1,188 +1,195 @@ QmitkNavigationDataPlayerViewControls 0 0 415 762 0 0 QmitkTemplate File Management - + Open File - + No navigation data set loaded... - + Frames: - + + + + N/A + + + + Tools: - - + + N/A - + - N/A + Convert navigation data to point set true Settings Sequential Player true Time-based Player Repeat true Register as Microservice false Display true Player Controls Qt::Vertical 20 40 QmitkNavigationDataSequentialPlayerControlWidget QWidget
QmitkNavigationDataSequentialPlayerControlWidget.h
1
QmitkNavigationDataPlayerControlWidget QWidget
QmitkNavigationDataPlayerControlWidget.h
1