diff --git a/Modules/IGT/IO/mitkNavigationDataPlayer.cpp b/Modules/IGT/IO/mitkNavigationDataPlayer.cpp index 6f4dc70913..9c7a0c1c56 100644 --- a/Modules/IGT/IO/mitkNavigationDataPlayer.cpp +++ b/Modules/IGT/IO/mitkNavigationDataPlayer.cpp @@ -1,157 +1,152 @@ /*=================================================================== 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 "mitkNavigationDataPlayer.h" #include #include #include #include "mitkNavigationDataReaderXML.h" #include "mitkIGTException.h" mitk::NavigationDataPlayer::NavigationDataPlayer() : m_CurPlayerState(PlayerStopped), m_StartPlayingTimeStamp(0.0), m_PauseTimeStamp(0.0) { // to get a start time mitk::IGTTimeStamp::GetInstance()->Start(this); } mitk::NavigationDataPlayer::~NavigationDataPlayer() { StopPlaying(); } void mitk::NavigationDataPlayer::GenerateData() { //Only produce new output if the player is started if (m_CurPlayerState != PlayerRunning) { //The output is not valid anymore this->GraftEmptyOutput(); return; } // get elapsed time since start of playing TimeStampType timeSinceStart = mitk::IGTTimeStamp::GetInstance()->GetElapsed() - m_StartPlayingTimeStamp; // iterate through all NavigationData objects of the given tool index // till the timestamp of the NavigationData is greater then the given timestamp for (; m_NavigationDataSetIterator != m_NavigationDataSet->End(); ++m_NavigationDataSetIterator) { if ( m_NavigationDataSetIterator->at(0)->GetIGTTimeStamp() > timeSinceStart) { break; } } // first element was greater than timestamp -> return null if ( m_NavigationDataSetIterator == m_NavigationDataSet->Begin() ) { MITK_WARN("NavigationDataSet") << "No NavigationData was recorded before given timestamp."; //The output is not at this time this->GraftEmptyOutput(); return; } for (unsigned int index = 0; index < m_NumberOfOutputs; index++) { mitk::NavigationData* output = this->GetOutput(index); if( !output ) { mitkThrowException(mitk::IGTException) << "Output of index "<Graft(curIterator->at(index)); } // stop playing if the last NavigationData objects were grafted if (m_NavigationDataSetIterator == m_NavigationDataSet->End()) { this->StopPlaying(); } } void mitk::NavigationDataPlayer::UpdateOutputInformation() { this->Modified(); // make sure that we need to be updated Superclass::UpdateOutputInformation(); } void mitk::NavigationDataPlayer::StartPlaying() { // make sure that player is initialized before playing starts this->InitPlayer(); // set state and iterator for playing from start m_CurPlayerState = PlayerRunning; m_NavigationDataSetIterator = m_NavigationDataSet->Begin(); // timestamp for indicating playing start is set to the past // so that the first navigation data object will be shown NOW m_StartPlayingTimeStamp = mitk::IGTTimeStamp::GetInstance()->GetElapsed() - m_NavigationDataSet->Begin()->at(0)->GetIGTTimeStamp(); } void mitk::NavigationDataPlayer::StopPlaying() { m_CurPlayerState = PlayerStopped; // reset playing timestamps m_StartPlayingTimeStamp = 0; m_PauseTimeStamp = 0; } void mitk::NavigationDataPlayer::Pause() { //player runs and pause was called -> pause the player if(m_CurPlayerState == PlayerRunning) { m_CurPlayerState = PlayerPaused; m_PauseTimeStamp = mitk::IGTTimeStamp::GetInstance()->GetElapsed(); } else { MITK_ERROR << "Player is either not started or already is paused" << std::endl; } } void mitk::NavigationDataPlayer::Resume() { // player is in pause mode -> play at the last position if(m_CurPlayerState == PlayerPaused) { m_CurPlayerState = PlayerRunning; // in this case m_StartPlayingTimeStamp is set to the total elapsed time with NO playback m_StartPlayingTimeStamp = mitk::IGTTimeStamp::GetInstance()->GetElapsed() - (m_PauseTimeStamp - m_StartPlayingTimeStamp); } else { MITK_ERROR << "Player is not paused!" << std::endl; } } - -bool mitk::NavigationDataPlayer::IsAtEnd() -{ - return m_NavigationDataSetIterator == m_NavigationDataSet->End(); -} diff --git a/Modules/IGT/IO/mitkNavigationDataPlayer.h b/Modules/IGT/IO/mitkNavigationDataPlayer.h index 0b8ce97ec6..7c00898a54 100644 --- a/Modules/IGT/IO/mitkNavigationDataPlayer.h +++ b/Modules/IGT/IO/mitkNavigationDataPlayer.h @@ -1,109 +1,103 @@ /*=================================================================== 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 MITKNavigationDataPlayer_H_HEADER_INCLUDED_ #define MITKNavigationDataPlayer_H_HEADER_INCLUDED_ #include #include namespace mitk { /**Documentation * \brief This class is used to play recorded (see mitkNavigationDataRecorder class) files. * * If you want to play a file you have to set an input stream. This can be an own one (use StartPlaying(std::istream*)) * or a preset (use StartPlaying()). The presets are NormalFile and ZipFile and can be set with the method * SetPlayerMode(PlayerMode). The presets need a FileName. Therefore the FileName must be set before the preset. * For pausing the player call Pause(). A call of Resume() will continue the playing. * * * \ingroup IGT */ class MitkIGT_EXPORT NavigationDataPlayer : public NavigationDataPlayerBase { public: mitkClassMacro(NavigationDataPlayer, NavigationDataPlayerBase); itkNewMacro(Self); /** * \brief Used for pipeline update just to tell the pipeline that we always have to update */ virtual void UpdateOutputInformation(); /** * \brief This method starts the player. * * The method mitk::NavigationDataPlayer::SetNavigationDataSet() has to be called before. * * @throw mitk::IGTException If m_NavigationDataSet is null. */ void StartPlaying(); /** * \brief Stops the player and closes the stream. After a call of StopPlaying() * StartPlaying() must be called to get new output data * * \warning the output is generated in this method because we know first about the number of output after * reading the first lines of the XML file. Therefore you should assign your output after the call of this method */ void StopPlaying(); /** * \brief This method pauses the player. If you want to play again call Resume() */ void Pause(); /** * \brief This method resumes the player when it was paused. */ void Resume(); - /** - * \brief This method checks if player arrived at end of file. - * - */ - virtual bool IsAtEnd(); - protected: NavigationDataPlayer(); virtual ~NavigationDataPlayer(); /** * \brief Set outputs to the navigation data object corresponding to current time. */ virtual void GenerateData(); enum PlayerState { PlayerStopped, PlayerRunning, PlayerPaused }; PlayerState m_CurPlayerState; typedef mitk::NavigationData::TimeStampType TimeStampType; /** * \brief The start time of the playing. Set in the method mitk::NavigationDataPlayer::StartPlaying(). */ TimeStampType m_StartPlayingTimeStamp; /** * \brief Stores the time when a pause began. */ TimeStampType m_PauseTimeStamp; }; } // namespace mitk #endif /* MITKNavigationDataPlayer_H_HEADER_INCLUDED_ */ diff --git a/Modules/IGT/IO/mitkNavigationDataPlayerBase.cpp b/Modules/IGT/IO/mitkNavigationDataPlayerBase.cpp index 80412e5b29..c278aa71c2 100644 --- a/Modules/IGT/IO/mitkNavigationDataPlayerBase.cpp +++ b/Modules/IGT/IO/mitkNavigationDataPlayerBase.cpp @@ -1,172 +1,104 @@ /*=================================================================== 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 "mitkNavigationDataPlayerBase.h" -// includes for exceptions +// include for exceptions #include "mitkIGTException.h" -//#include "mitkIGTIOException.h" mitk::NavigationDataPlayerBase::NavigationDataPlayerBase() : m_NumberOfOutputs(0) { m_Name ="Navigation Data Player Source"; } mitk::NavigationDataPlayerBase::~NavigationDataPlayerBase() { } void mitk::NavigationDataPlayerBase::UpdateOutputInformation() { this->Modified(); // make sure that we need to be updated Superclass::UpdateOutputInformation(); } + +bool mitk::NavigationDataPlayerBase::IsAtEnd() +{ + return m_NavigationDataSetIterator == m_NavigationDataSet->End(); +} + void mitk::NavigationDataPlayerBase::SetNavigationDataSet(NavigationDataSet::Pointer navigationDataSet) { m_NavigationDataSet = navigationDataSet; m_NavigationDataSetIterator = navigationDataSet->Begin(); this->InitPlayer(); } unsigned int mitk::NavigationDataPlayerBase::GetNumberOfSnapshots() { return m_NavigationDataSet.IsNull() ? 0 : m_NavigationDataSet->Size(); } void mitk::NavigationDataPlayerBase::InitPlayer() { if ( m_NavigationDataSet.IsNull() ) { mitkThrowException(mitk::IGTException) << "NavigationDataSet has to be set before initializing player."; } + // remove all outputs before creating the new ones + for (unsigned int n = 0; n < this->GetNumberOfIndexedOutputs(); ++n) + { + this->RemoveOutput(n); + } + m_NumberOfOutputs = m_NavigationDataSet->GetNumberOfTools(); this->SetNumberOfRequiredOutputs(m_NumberOfOutputs); for (unsigned int n = 0; n < m_NumberOfOutputs; ++n) { mitk::NavigationData* output = this->GetOutput(n); if (!output) { DataObjectPointer newOutput = this->MakeOutput(n); this->SetNthOutput(n, newOutput); this->Modified(); } } } -mitk::NavigationData::Pointer mitk::NavigationDataPlayerBase::ReadNavigationData(TiXmlElement* elem) -{ - if (elem == NULL) {mitkThrow() << "Error: Element is NULL!";} - - mitk::NavigationData::Pointer nd = mitk::NavigationData::New(); - - mitk::NavigationData::PositionType position; - mitk::NavigationData::OrientationType orientation(0.0,0.0,0.0,0.0); - mitk::NavigationData::TimeStampType timestamp = -1; - mitk::NavigationData::CovarianceMatrixType matrix; - - bool hasPosition = true; - bool hasOrientation = true; - bool dataValid = false; - - position.Fill(0.0); - matrix.SetIdentity(); - - elem->QueryDoubleAttribute("Time",×tamp); - if (timestamp == -1) - { - return NULL; //the calling method should check the return value if it is valid/not NULL - } - - elem->QueryDoubleAttribute("X", &position[0]); - elem->QueryDoubleAttribute("Y", &position[1]); - elem->QueryDoubleAttribute("Z", &position[2]); - - elem->QueryDoubleAttribute("QX", &orientation[0]); - elem->QueryDoubleAttribute("QY", &orientation[1]); - elem->QueryDoubleAttribute("QZ", &orientation[2]); - elem->QueryDoubleAttribute("QR", &orientation[3]); - - elem->QueryDoubleAttribute("C00", &matrix[0][0]); - elem->QueryDoubleAttribute("C01", &matrix[0][1]); - elem->QueryDoubleAttribute("C02", &matrix[0][2]); - elem->QueryDoubleAttribute("C03", &matrix[0][3]); - elem->QueryDoubleAttribute("C04", &matrix[0][4]); - elem->QueryDoubleAttribute("C05", &matrix[0][5]); - elem->QueryDoubleAttribute("C10", &matrix[1][0]); - elem->QueryDoubleAttribute("C11", &matrix[1][1]); - elem->QueryDoubleAttribute("C12", &matrix[1][2]); - elem->QueryDoubleAttribute("C13", &matrix[1][3]); - elem->QueryDoubleAttribute("C14", &matrix[1][4]); - elem->QueryDoubleAttribute("C15", &matrix[1][5]); - - int tmpval = 0; - elem->QueryIntAttribute("Valid", &tmpval); - if (tmpval == 0) - dataValid = false; - else - dataValid = true; - - tmpval = 0; - elem->QueryIntAttribute("hO", &tmpval); - if (tmpval == 0) - hasOrientation = false; - else - hasOrientation = true; - - tmpval = 0; - elem->QueryIntAttribute("hP", &tmpval); - if (tmpval == 0) - hasPosition = false; - else - hasPosition = true; - - nd->SetIGTTimeStamp(timestamp); - nd->SetPosition(position); - nd->SetOrientation(orientation); - nd->SetCovErrorMatrix(matrix); - nd->SetDataValid(dataValid); - nd->SetHasOrientation(hasOrientation); - nd->SetHasPosition(hasPosition); - - - return nd; -} - void mitk::NavigationDataPlayerBase::GraftEmptyOutput() { for (unsigned int index = 0; index < m_NavigationDataSet->GetNumberOfTools(); index++) { mitk::NavigationData* output = this->GetOutput(index); assert(output); mitk::NavigationData::Pointer nd = mitk::NavigationData::New(); mitk::NavigationData::PositionType position; mitk::NavigationData::OrientationType orientation(0.0,0.0,0.0,0.0); position.Fill(0.0); nd->SetPosition(position); nd->SetOrientation(orientation); nd->SetDataValid(false); output->Graft(nd); } } diff --git a/Modules/IGT/IO/mitkNavigationDataPlayerBase.h b/Modules/IGT/IO/mitkNavigationDataPlayerBase.h index edff7742b8..01d12e6d7f 100644 --- a/Modules/IGT/IO/mitkNavigationDataPlayerBase.h +++ b/Modules/IGT/IO/mitkNavigationDataPlayerBase.h @@ -1,89 +1,104 @@ /*=================================================================== 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 MITKNavigationDataPlayerBase_H_HEADER_INCLUDED_ #define MITKNavigationDataPlayerBase_H_HEADER_INCLUDED_ -#include -#include "mitkNavigationDataReaderInterface.h" -#include "tinyxml.h" - +#include "mitkNavigationDataSource.h" +#include "mitkNavigationDataSet.h" namespace mitk{ /**Documentation - * \brief This class is a slightly changed reimplementation of the - * NavigationDataPlayer which does not care about timestamps and just - * outputs the navigationdatas in their sequential order - * - * \ingroup IGT - */ + * \brief Base class for using mitk::NavigationData as a filter source. + * Subclasses can play objects of mitk::NavigationDataSet. + * + * \ingroup IGT + */ class MitkIGT_EXPORT NavigationDataPlayerBase : public NavigationDataSource { public: mitkClassMacro(NavigationDataPlayerBase, NavigationDataSource); /** - * \brief Used for pipeline update just to tell the pipeline that we always have to update - */ + * \brief Used for pipeline update just to tell the pipeline that we always have to update. + */ virtual void UpdateOutputInformation(); itkGetMacro(NavigationDataSet, NavigationDataSet::Pointer); + + /** + * \brief Set mitk::NavigationDataSet for playing. + * Player is initialized by call to mitk::NavigationDataPlayerBase::InitPlayer() + * inside this method. Method must be called before this object can be used as + * a filter source. + * + * @param navigationDataSet mitk::NavigationDataSet which will be played by this player. + */ void SetNavigationDataSet(NavigationDataSet::Pointer navigationDataSet); /** - * @return Returns the number of navigation data snapshots available in the player + * \brief Getter for the size of the mitk::NavigationDataSet used in this object. + * + * @return Returns the number of navigation data snapshots available in the player. */ unsigned int GetNumberOfSnapshots(); /** * \brief This method checks if player arrived at end of file. * + * @return true if last mitk::NavigationData object is in the outputs, false otherwise */ - virtual bool IsAtEnd() = 0; + bool IsAtEnd(); protected: NavigationDataPlayerBase(); virtual ~NavigationDataPlayerBase(); + /** + * \brief Every subclass hast to implement this method. See ITK filter documentation for details. + */ virtual void GenerateData() = 0; /** * \brief Initializes the outputs of this NavigationDataSource. */ void InitPlayer(); /** - * + * \brief Convenience method for subclasses. + * When there are no further mitk::NavigationData objects available, this + * method can be called in the implementation of mitk::NavigationDataPlayerBase::GenerateData(). */ void GraftEmptyOutput(); NavigationDataSet::Pointer m_NavigationDataSet; - mitk::NavigationDataSet::NavigationDataSetIterator m_NavigationDataSetIterator; - unsigned int m_NumberOfOutputs; ///< stores the number of outputs known from NavigationDataSet + /** + * \brief Iterator always points to the NavigationData object which is in the outputs at the moment. + */ + mitk::NavigationDataSet::NavigationDataSetIterator m_NavigationDataSetIterator; /** - * \brief Creates NavigationData from XML element and returns it - * @throw mitk::Exception Throws an exception if elem is NULL. - */ - mitk::NavigationData::Pointer ReadNavigationData(TiXmlElement* elem); + * \brief Stores the number of outputs known from NavigationDataSet. + */ + unsigned int m_NumberOfOutputs; }; } // namespace mitk #endif /* MITKNavigationDataSequentialPlayer_H_HEADER_INCLUDED_ */ diff --git a/Modules/IGT/IO/mitkNavigationDataSequentialPlayer.cpp b/Modules/IGT/IO/mitkNavigationDataSequentialPlayer.cpp index df72011dc1..918a3b5a46 100644 --- a/Modules/IGT/IO/mitkNavigationDataSequentialPlayer.cpp +++ b/Modules/IGT/IO/mitkNavigationDataSequentialPlayer.cpp @@ -1,89 +1,84 @@ /*=================================================================== 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 "mitkNavigationDataSequentialPlayer.h" #include //for the pause #include #include //Exceptions #include "mitkIGTException.h" #include "mitkIGTIOException.h" mitk::NavigationDataSequentialPlayer::NavigationDataSequentialPlayer() : m_Repeat(false) { } mitk::NavigationDataSequentialPlayer::~NavigationDataSequentialPlayer() { } void mitk::NavigationDataSequentialPlayer::GoToSnapshot(unsigned int i) { if( !m_Repeat && (this->GetNumberOfSnapshots() <= i) ) { MITK_ERROR << "Snaphot " << i << " does not exist and repat is off: can't go to that snapshot!"; mitkThrowException(mitk::IGTException) << "Snapshot " << i << " does not exist and repat is off: can't go to that snapshot!"; } // set iterator to given position (modulo for allowing repeat) m_NavigationDataSetIterator = m_NavigationDataSet->Begin() + ( i % this->GetNumberOfSnapshots() ); // set outputs to selected snapshot this->Update(); } void mitk::NavigationDataSequentialPlayer::GenerateData() { if ( m_NavigationDataSetIterator == m_NavigationDataSet->End() ) { if ( m_Repeat ) { // set data back to start if repeat is enabled m_NavigationDataSetIterator = m_NavigationDataSet->Begin(); } else { // no more data available this->GraftEmptyOutput(); return; } } for (unsigned int index = 0; index < m_NumberOfOutputs; index++) { mitk::NavigationData* output = this->GetOutput(index); if( !output ) { mitkThrowException(mitk::IGTException) << "Output of index "<Graft(m_NavigationDataSetIterator->at(index)); } ++m_NavigationDataSetIterator; } void mitk::NavigationDataSequentialPlayer::UpdateOutputInformation() { this->Modified(); // make sure that we need to be updated Superclass::UpdateOutputInformation(); } - -bool mitk::NavigationDataSequentialPlayer::IsAtEnd() -{ - return m_NavigationDataSetIterator == m_NavigationDataSet->End(); -} diff --git a/Modules/IGT/IO/mitkNavigationDataSequentialPlayer.h b/Modules/IGT/IO/mitkNavigationDataSequentialPlayer.h index f9360e83ec..0da4eef70e 100644 --- a/Modules/IGT/IO/mitkNavigationDataSequentialPlayer.h +++ b/Modules/IGT/IO/mitkNavigationDataSequentialPlayer.h @@ -1,88 +1,85 @@ /*=================================================================== 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 MITKNavigationDataSequentialPlayer_H_HEADER_INCLUDED_ #define MITKNavigationDataSequentialPlayer_H_HEADER_INCLUDED_ #include namespace mitk { /**Documentation * \brief This class is a slightly changed reimplementation of the * NavigationDataPlayer which does not care about timestamps and just * outputs the navigationdatas in their sequential order * * \ingroup IGT */ class MitkIGT_EXPORT NavigationDataSequentialPlayer : public NavigationDataPlayerBase { public: mitkClassMacro(NavigationDataSequentialPlayer, NavigationDataPlayerBase); itkNewMacro(Self); /** * \brief Set to true if the data player should repeat the outputs. */ itkSetMacro(Repeat, bool); /** * \return Returns if the data player should repeat the outputs. */ itkGetMacro(Repeat, bool); /** * \brief Advance the output to the i-th snapshot of mitk::NavigationData. * E.g. if you want to have the NavData of snapshot * 18 then you can call GoToSnapshot(17). Index begins at 0. * You can only go back if m_Repeat is set true. * * Filter output is updated inside the function. * * @throw mitk::IGTException Throws an exception if cannot go back to particular snapshot. */ void GoToSnapshot(unsigned int i); /** * \brief Used for pipeline update just to tell the pipeline * that we always have to update */ virtual void UpdateOutputInformation(); - /** - * \brief This method checks if player arrived at end of file. - * - */ - virtual bool IsAtEnd(); - protected: NavigationDataSequentialPlayer(); virtual ~NavigationDataSequentialPlayer(); /** * * @throw mitk::IGTException Throws an exception if an output is null. */ virtual void GenerateData(); + /** + * \brief If the player should repeat outputs. Default is false. + */ bool m_Repeat; }; } // namespace mitk #endif /* MITKNavigationDataSequentialPlayer_H_HEADER_INCLUDED_ */