diff --git a/Modules/IGT/IO/mitkNavigationDataPlayerBase.cpp b/Modules/IGT/IO/mitkNavigationDataPlayerBase.cpp index c278aa71c2..84e87b6b6b 100644 --- a/Modules/IGT/IO/mitkNavigationDataPlayerBase.cpp +++ b/Modules/IGT/IO/mitkNavigationDataPlayerBase.cpp @@ -1,104 +1,110 @@ /*=================================================================== 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" // include for exceptions #include "mitkIGTException.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) + if (m_NumberOfOutputs == 0) { - mitk::NavigationData* output = this->GetOutput(n); - if (!output) + m_NumberOfOutputs = m_NavigationDataSet->GetNumberOfTools(); + this->SetNumberOfRequiredOutputs(m_NumberOfOutputs); + + for (unsigned int n = 0; n < m_NumberOfOutputs; ++n) { - DataObjectPointer newOutput = this->MakeOutput(n); - this->SetNthOutput(n, newOutput); - this->Modified(); + mitk::NavigationData* output = this->GetOutput(n); + if (!output) + { + DataObjectPointer newOutput = this->MakeOutput(n); + this->SetNthOutput(n, newOutput); + this->Modified(); + } } } + else if (m_NumberOfOutputs != m_NavigationDataSet->GetNumberOfTools()) + { + mitkThrowException(mitk::IGTException) + << "Number of tools cannot be changed in existing player. Please create " + << "a new player, if the NavigationDataSet has another number of tools now."; + } + + this->Modified(); } 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/Testing/mitkNavigationDataRecorderTest.cpp b/Modules/IGT/Testing/mitkNavigationDataRecorderTest.cpp index a7555f9eb3..fedbb9c98d 100644 --- a/Modules/IGT/Testing/mitkNavigationDataRecorderTest.cpp +++ b/Modules/IGT/Testing/mitkNavigationDataRecorderTest.cpp @@ -1,120 +1,120 @@ /*=================================================================== 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 #include #include #include #include #include #include //for exceptions #include "mitkIGTException.h" #include "mitkIGTIOException.h" class mitkNavigationDataRecorderTestClass { public: static void PlayAndRecord() { // Aim is to read an xml into a pointset, play that set with a sequentialplayer, record it // again, write the result to xml , and compare the output mitk::NavigationDataReaderXML::Pointer reader = mitk::NavigationDataReaderXML::New(); std::string path = "F://Build//MITK-Data//IGT-Data//NavigationDataSet.xml"; mitk::NavigationDataSet::Pointer set = reader->Read(path); mitk::NavigationDataSequentialPlayer::Pointer player = mitk::NavigationDataSequentialPlayer::New(); player->SetNavigationDataSet(set); mitk::NavigationDataRecorder::Pointer recorder = mitk::NavigationDataRecorder::New(); recorder->SetStandardizeTime(false); // connect player to recorder for (int i = 0; i < player->GetNumberOfIndexedOutputs(); i++) { recorder->SetInput(i, player->GetOutput(i)); } recorder->StartRecording(); while (!player->IsAtEnd()) { recorder->Update(); } mitk::NavigationDataSetWriterXML writer; writer.Write("F://Build//MITK-Data//IGT-Data//NavigationDataSet2.xml", recorder->GetNavigationDataSet()); //MITK_TEST_CONDITION_REQUIRED(mitkNavigationDataRecorderTestClass::CompareFiles("F://Build//MITK-Data//IGT-Data//NavigationDataSet.xml", // "F://Build//MITK-Data//IGT-Data//NavigationDataSet2.xml"), "Asserting that played back file has been recorded correctly"); recorder->StopRecording(); MITK_TEST_CONDITION_REQUIRED(! recorder->GetRecording(), "Test if StopRecording is working"); recorder->ResetRecording(); MITK_TEST_CONDITION_REQUIRED(recorder->GetNavigationDataSet()->Size() == 0, "Test correct reset of recorder"); //Reset Player //player = mitk::NavigationDataSequentialPlayer::New(); player->SetNavigationDataSet(set); // Check if Limiting recording works //recorder->SetRecordCountLimit(100); recorder->StartRecording(); while (!player->IsAtEnd()) { player->Update(); recorder->Update(); } MITK_TEST_CONDITION_REQUIRED(recorder->GetNavigationDataSet()->Size() == 100, "Test if SetRecordCountLimit works as intended."); } - static bool mitkNavigationDataRecorderTestClass::CompareFiles(std::string file1, std::string file2) + static bool CompareFiles(std::string file1, std::string file2) { FILE* f1 = fopen (file1.c_str() , "r"); FILE* f2 = fopen (file2.c_str() , "r"); char buf1[10000]; char buf2[10000]; do { size_t r1 = fread(buf1, 1, 10000, f1); size_t r2 = fread(buf2, 1, 10000, f2); if (r1 != r2 || memcmp(buf1, buf2, r1)) { return false; // Files are not equal } } while (!feof(f1) && !feof(f2)); return feof(f1) && feof(f2); } }; /**Documentation * test for the class "NavigationDataRecorder". */ int mitkNavigationDataRecorderTest(int /* argc */, char* /*argv*/[]) { MITK_TEST_BEGIN("NavigationDataRecorder"); mitkNavigationDataRecorderTestClass::PlayAndRecord(); // always end with this! MITK_TEST_END(); -} \ No newline at end of file +} diff --git a/Modules/IGT/Testing/mitkNavigationDataSequentialPlayerTest.cpp b/Modules/IGT/Testing/mitkNavigationDataSequentialPlayerTest.cpp index 41a06aee9a..956a754196 100644 --- a/Modules/IGT/Testing/mitkNavigationDataSequentialPlayerTest.cpp +++ b/Modules/IGT/Testing/mitkNavigationDataSequentialPlayerTest.cpp @@ -1,219 +1,242 @@ /*=================================================================== 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 #include #include "mitkTestingMacros.h" #include "mitkNavigationDataReaderXML.h" #include #include //foe exceptions #include "mitkIGTException.h" #include "mitkIGTIOException.h" vnl_vector tTool0Snapshot1(3); vnl_vector tTool1Snapshot2(3); mitk::Quaternion qTool0Snapshot0; mitk::Quaternion qTool1Snapshot1; mitk::NavigationDataSequentialPlayer::Pointer player( mitk::NavigationDataSequentialPlayer::New()); bool runLoop() { bool success = true; mitk::NavigationData::Pointer nd0; mitk::NavigationData::Pointer nd1; for(unsigned int i=0; iGetNumberOfSnapshots();++i) { player->Update(); nd0 = player->GetOutput(); nd1 = player->GetOutput(1); // test some values if(nd0.IsNull() || nd1.IsNull()) return false; if(i==0) { if (!(qTool0Snapshot0.as_vector() == nd0->GetOrientation().as_vector())) {success = false;} } else if(i==1) { if (!(tTool0Snapshot1 == nd0->GetPosition().GetVnlVector())) {success = false;} else if (!(qTool1Snapshot1.as_vector() == nd1->GetOrientation().as_vector())) {success = false;} } else if(i==2) // should be repeated { if (!(tTool1Snapshot2 == nd1->GetPosition().GetVnlVector())) {success = false;} } } return success; } void TestStandardWorkflow() { // create test values valid for the xml data above tTool0Snapshot1[0] = -336.65; tTool0Snapshot1[1] = 138.5; tTool0Snapshot1[2]= -2061.07; tTool1Snapshot2[0] = -56.93; tTool1Snapshot2[1] = 233.79; tTool1Snapshot2[2]= -2042.6; vnl_vector_fixed qVec; qVec[0] = 0.0085; qVec[1] = -0.0576; qVec[2]= -0.0022; qVec[3]= 0.9982; qTool0Snapshot0 = mitk::Quaternion(qVec); qVec[0] = 0.4683; qVec[1] = 0.0188; qVec[2]= -0.8805; qVec[3]= 0.0696; qTool1Snapshot1 = mitk::Quaternion(qVec); //test SetXMLString() std::string file = mitk::StandardFileLocations::GetInstance()->FindFile("NavigationDataTestData_2ToolsDouble.xml", "Modules/IGT/Testing/Data"); mitk::NavigationDataReaderXML::Pointer reader = mitk::NavigationDataReaderXML::New(); player->SetNavigationDataSet(reader->Read(file)); MITK_TEST_CONDITION_REQUIRED(player->GetNumberOfSnapshots() == 3,"Testing method SetXMLString with 3 navigation datas."); MITK_TEST_CONDITION_REQUIRED(player->GetNumberOfIndexedOutputs() == 2,"Testing number of outputs"); //rest repeat player->SetRepeat(true); MITK_TEST_CONDITION_REQUIRED(runLoop(),"Testing first run."); MITK_TEST_CONDITION_REQUIRED(runLoop(),"Testing second run."); //repeat is on should work a second time // now test the go to snapshot function player->GoToSnapshot(2); mitk::NavigationData::Pointer nd1 = player->GetOutput(1); MITK_TEST_CONDITION(tTool1Snapshot2 == nd1->GetPosition().GetVnlVector(), "Testing GoToSnapshot() [1]"); MITK_TEST_OUTPUT( << tTool1Snapshot2 << "\t" << nd1->GetPosition().GetVnlVector()); player->GoToSnapshot(0); mitk::NavigationData::Pointer nd0 = player->GetOutput(); MITK_TEST_CONDITION(qTool0Snapshot0.as_vector() == nd0->GetOrientation().as_vector(), "Testing GoToSnapshot() [2]"); MITK_TEST_OUTPUT( << qTool0Snapshot0.as_vector() << "\t" <GetOrientation().as_vector() ); player->GoToSnapshot(2); // and a third time MITK_TEST_CONDITION_REQUIRED(runLoop(),"Tested if repeat works again."); } +void TestRestartWithNewNavigationDataSet() +{ + mitk::NavigationDataReaderXML::Pointer reader = mitk::NavigationDataReaderXML::New(); + + mitk::NavigationDataSequentialPlayer::Pointer player(mitk::NavigationDataSequentialPlayer::New()); + + std::string file = mitk::StandardFileLocations::GetInstance()->FindFile("NavigationDataTestData_2ToolsDouble.xml", "Modules/IGT/Testing/Data"); + + player->SetNavigationDataSet(reader->Read(file)); + mitk::NavigationData::Pointer nd1 = player->GetOutput(0); + player->SetNavigationDataSet(reader->Read(file)); + player->Update(); + mitk::NavigationData::Pointer nd2 = player->GetOutput(0); + + MITK_TEST_CONDITION(nd1->GetPosition() == nd2->GetPosition(), "First output must be the same after setting same navigation data again."); + + // setting new NavigationDataSet with different tool count should result in an exception + file = mitk::StandardFileLocations::GetInstance()->FindFile("NavigationDataTestData.xml", "Modules/IGT/Testing/Data"); + MITK_TEST_FOR_EXCEPTION(mitk::IGTException, player->SetNavigationDataSet(reader->Read(file))); +} + void TestSetFileNameException() { //testing exception if file name hasnt been set mitk::NavigationDataSequentialPlayer::Pointer myTestPlayer = mitk::NavigationDataSequentialPlayer::New(); bool exceptionThrown=false; try { mitk::NavigationDataReaderXML::Pointer reader = mitk::NavigationDataReaderXML::New(); myTestPlayer->SetNavigationDataSet(reader->Read("")); } catch(mitk::IGTIOException) { exceptionThrown=true; MITK_TEST_OUTPUT(<<"Tested exception for the case when file version is wrong in SetFileName. Application should not crash."); } MITK_TEST_CONDITION_REQUIRED(exceptionThrown, "Testing SetFileName method if exception (if file name hasnt been set) was thrown."); //testing ReInItXML method if data element is not found mitk::NavigationDataSequentialPlayer::Pointer myTestPlayer1 = mitk::NavigationDataSequentialPlayer::New(); std::string file = mitk::StandardFileLocations::GetInstance()->FindFile("NavigationDataTestDataInvalidTags.xml", "Modules/IGT/Testing/Data"); bool exceptionThrown1=false; try { mitk::NavigationDataReaderXML::Pointer reader = mitk::NavigationDataReaderXML::New(); myTestPlayer1->SetNavigationDataSet(reader->Read(file)); } catch(mitk::IGTException) { exceptionThrown1=true; } MITK_TEST_CONDITION_REQUIRED(exceptionThrown1, "Testing SetFileName method if exception (if data element not found) was thrown."); } void TestGoToSnapshotException() { //testing GoToSnapShot for exception mitk::NavigationDataSequentialPlayer::Pointer myTestPlayer2 = mitk::NavigationDataSequentialPlayer::New(); std::string file = mitk::StandardFileLocations::GetInstance()->FindFile("NavigationDataTestData_2Tools.xml", "Modules/IGT/Testing/Data"); mitk::NavigationDataReaderXML::Pointer reader = mitk::NavigationDataReaderXML::New(); myTestPlayer2->SetNavigationDataSet(reader->Read(file)); bool exceptionThrown2=false; try { myTestPlayer2->GoToSnapshot(1000); } catch(mitk::IGTException) { exceptionThrown2=true; } MITK_TEST_CONDITION_REQUIRED(exceptionThrown2, "Testing if exception is thrown when GoToSnapShot method is called with an index that doesn't exist."); } void TestSetXMLStringException() { mitk::NavigationDataSequentialPlayer::Pointer myTestPlayer3 = mitk::NavigationDataSequentialPlayer::New(); bool exceptionThrown3=false; //The string above XML_INVALID_TESTSTRING is a wrong string, some element were deleted in above try { std::string file = mitk::StandardFileLocations::GetInstance()->FindFile("InvalidVersionNavigationDataTestData.xml", "Modules/IGT/Testing/Data"); mitk::NavigationDataReaderXML::Pointer reader = mitk::NavigationDataReaderXML::New(); myTestPlayer3->SetNavigationDataSet(reader->Read(file)); } catch(mitk::IGTIOException) { exceptionThrown3=true; } MITK_TEST_CONDITION_REQUIRED(exceptionThrown3, "Testing SetXMLString method with an invalid XML string."); } /**Documentation * test for the class "NavigationDataRecorder". */ int mitkNavigationDataSequentialPlayerTest(int /* argc */, char* /*argv*/[]) { MITK_TEST_BEGIN("NavigationDataSequentialPlayer"); TestStandardWorkflow(); + TestRestartWithNewNavigationDataSet(); //TestSetFileNameException(); TestSetXMLStringException(); TestGoToSnapshotException(); + MITK_TEST_END(); }