diff --git a/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/CMakeLists.txt b/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/CMakeLists.txt new file mode 100644 index 0000000000..3fa8aadb8b --- /dev/null +++ b/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/CMakeLists.txt @@ -0,0 +1,2 @@ + +MACRO_CREATE_MITK_PLUGIN(QmitkExt MitkIGTUI MitkIGT) \ No newline at end of file diff --git a/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/META-INF/MANIFEST.MF b/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..3ab01ebe75 --- /dev/null +++ b/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/META-INF/MANIFEST.MF @@ -0,0 +1,7 @@ +Manifest-Version: 1.0 +Bundle-Name: NavigationData Player +Bundle-SymbolicName: org.mitk.gui.qt.navigationdataplayer +Bundle-Version: 0.1 +Bundle-Vendor: DKFZ, Medical and Biological Informatics +Require-Bundle: org.mitk.gui.qt.common +Bundle-Activator: diff --git a/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/documentation/Manual/Manual.dox b/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/documentation/Manual/Manual.dox new file mode 100644 index 0000000000..07e803a7e2 --- /dev/null +++ b/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/documentation/Manual/Manual.dox @@ -0,0 +1,13 @@ +/** +\bundlemainpage{org.mitk.gui.qt.navigationdataplayer} NavigationData Player + +\image html icon.png "Icon of NavigationData Player" + +Available sections: + - \ref org.mitk.gui.qt.navigationdataplayerOverview + +\section org.mitk.gui.qt.navigationdataplayerOverview +This is the description for the NavigationData Player. + +*/ + diff --git a/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/documentation/Manual/icon.png b/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/documentation/Manual/icon.png new file mode 100644 index 0000000000..f1ad7558e4 --- /dev/null +++ b/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/documentation/Manual/icon.png @@ -0,0 +1 @@ +‰PNG diff --git a/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/documentation/doxygen/modules.dox b/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/documentation/doxygen/modules.dox new file mode 100644 index 0000000000..3f39547f7e --- /dev/null +++ b/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/documentation/doxygen/modules.dox @@ -0,0 +1,16 @@ +/** + \defgroup org_mitk_gui_qt_navigationdataplayer org.mitk.gui.qt.navigationdataplayer Plugin + \ingroup MITKPlugins + + \brief Describe your plugin here. + +*/ + +/** + \defgroup org_mitk_gui_qt_navigationdataplayer_internal Internal + \ingroup org_mitk_gui_qt_navigationdataplayer + + \brief This subcategory includes the internal classes of the org.mitk.gui.qt.navigationdataplayer plugin. Other + plugins must not rely on these classes. They contain implementation details and their interface + may change at any time. We mean it. +*/ diff --git a/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/files.cmake b/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/files.cmake new file mode 100644 index 0000000000..d17000428e --- /dev/null +++ b/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/files.cmake @@ -0,0 +1,35 @@ +SET(SRC_CPP_FILES + +) + +SET(INTERNAL_CPP_FILES + QmitkNavigationDataPlayerView.cpp + +) + +SET(UI_FILES + src/internal/QmitkNavigationDataPlayerViewControls.ui +) + +SET(MOC_H_FILES + src/internal/QmitkNavigationDataPlayerView.h +) + +SET(RESOURCE_FILES + resources/icon.png +) + +SET(RES_FILES + resources/QmitkNavigationDataPlayerView.qrc +) + +SET(CPP_FILES manifest.cpp) + +foreach(file ${SRC_CPP_FILES}) + SET(CPP_FILES ${CPP_FILES} src/${file}) +endforeach(file ${SRC_CPP_FILES}) + +foreach(file ${INTERNAL_CPP_FILES}) + SET(CPP_FILES ${CPP_FILES} src/internal/${file}) +endforeach(file ${INTERNAL_CPP_FILES}) + diff --git a/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/manifest.cpp b/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/manifest.cpp new file mode 100644 index 0000000000..4860b13718 --- /dev/null +++ b/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/manifest.cpp @@ -0,0 +1,26 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date$ +Version: $Revision$ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#include + + + +#include "src/internal/QmitkNavigationDataPlayerView.h" + +POCO_BEGIN_NAMED_MANIFEST(berryIViewPart, berry::IViewPart) + POCO_EXPORT_CLASS(::QmitkNavigationDataPlayerView) +POCO_END_MANIFEST diff --git a/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/plugin.xml b/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/plugin.xml new file mode 100644 index 0000000000..82831636fc --- /dev/null +++ b/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/plugin.xml @@ -0,0 +1,12 @@ + + + + + + + + + diff --git a/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/resources/QmitkNavigationDataPlayerView.qrc b/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/resources/QmitkNavigationDataPlayerView.qrc new file mode 100644 index 0000000000..bd00f445c1 --- /dev/null +++ b/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/resources/QmitkNavigationDataPlayerView.qrc @@ -0,0 +1,5 @@ + + + icon.png + + diff --git a/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/resources/icon.png b/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/resources/icon.png new file mode 100644 index 0000000000..52f0fa42df Binary files /dev/null and b/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/resources/icon.png differ diff --git a/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/resources/icon.xpm b/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/resources/icon.xpm new file mode 100644 index 0000000000..9057c20bc6 --- /dev/null +++ b/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/resources/icon.xpm @@ -0,0 +1,21 @@ +/* XPM */ +static const char * icon_xpm[] = { +"16 16 2 1", +" c #FF0000", +". c #000000", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/src/NavigationdataplayerDll.h b/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/src/NavigationdataplayerDll.h new file mode 100644 index 0000000000..cd105c39da --- /dev/null +++ b/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/src/NavigationdataplayerDll.h @@ -0,0 +1,43 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date$ +Version: $Revision$ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#ifndef _NAVIGATIONDATAPLAYER_EXPORT_DLL_H_ +#define _NAVIGATIONDATAPLAYER_EXPORT_DLL_H_ + + +// +// The following block is the standard way of creating macros which make exporting +// from a DLL simpler. All files within this DLL are compiled with the org_mitk_gui_qt_navigationdataplayer_EXPORTS +// symbol defined on the command line. this symbol should not be defined on any project +// that uses this DLL. This way any other project whose source files include this file see +// org_mitk_gui_qt_navigationdataplayer_EXPORTS functions as being imported from a DLL, wheras this DLL sees symbols +// defined with this macro as being exported. +// +#if defined(_WIN32) && !defined(MITK_STATIC) + #if defined(org_mitk_gui_qt_navigationdataplayer_EXPORTS) + #define NAVIGATIONDATAPLAYER_EXPORT __declspec(dllexport) + #else + #define NAVIGATIONDATAPLAYER_EXPORT __declspec(dllimport) + #endif +#endif + + +#if !defined(NAVIGATIONDATAPLAYER_EXPORT) + #define NAVIGATIONDATAPLAYER_EXPORT +#endif + +#endif /*_NAVIGATIONDATAPLAYER_EXPORT_DLL_H_*/ diff --git a/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/src/internal/QmitkNavigationDataPlayerView.cpp b/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/src/internal/QmitkNavigationDataPlayerView.cpp new file mode 100644 index 0000000000..96e09ba4b3 --- /dev/null +++ b/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/src/internal/QmitkNavigationDataPlayerView.cpp @@ -0,0 +1,475 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date: 2010-03-31 16:40:27 +0200 (Mi, 31 Mrz 2010) $ +Version: $Revision: 21975 $ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +// Blueberry +#include +#include + +// Qmitk +#include "QmitkNavigationDataPlayerView.h" +#include "QmitkStdMultiWidget.h" + +//mitk +#include +#include +#include + +// Qt +#include + +// vtk +#include + + +const std::string QmitkNavigationDataPlayerView::VIEW_ID = "org.mitk.views.navigationdataplayer"; + +QmitkNavigationDataPlayerView::QmitkNavigationDataPlayerView() +: QmitkFunctionality() +, m_Controls( 0 ) +, m_MultiWidget( NULL ) +, m_Trajectory( NULL ) +, m_TrajectoryIndex( -1 ) +, m_ReloadData( true ) +, m_ShowTrajectory( false ) +, m_SplineMapper( NULL ) +, m_PointSetMapper( NULL ) +{ + + m_TrajectoryPointSet = mitk::PointSet::New(); // PointSet for trajectory points +} + + + +QmitkNavigationDataPlayerView::~QmitkNavigationDataPlayerView() +{ + delete m_PlayerWidget; +} + + +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->CreateBundleWidgets( parent ); + this->CreateConnections(); + } +} + + + +void QmitkNavigationDataPlayerView::CreateBundleWidgets(QWidget* parent) +{ + m_PlayerWidget = new QmitkIGTPlayerWidget( parent ); // this bundle's ND player widget +} + + +void QmitkNavigationDataPlayerView::CreateConnections() +{ + connect( m_PlayerWidget, SIGNAL(SignalPlayingStarted()), this, SLOT(OnCreatePlaybackVisualization()) ); + connect( m_PlayerWidget, SIGNAL(SignalPlayerUpdated()), this, SLOT(OnPerformPlaybackVisualization()) ); + connect( m_PlayerWidget, SIGNAL(SignalInputFileChanged()), this, SLOT(OnReinit()) ); + connect( m_PlayerWidget, SIGNAL(SignalCurrentTrajectoryChanged(int)), this, SLOT (OnShowTrajectory(int)) ); + connect( m_PlayerWidget, SIGNAL(SignalPlayingStarted()), this, SLOT(OnPlayingStarted()) ); + connect( m_PlayerWidget, SIGNAL(SignalSplineModeToggled(bool)), this, SLOT(OnEnableSplineTrajectoryMapper(bool)) ); +} + + +void QmitkNavigationDataPlayerView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) +{ + m_MultiWidget = &stdMultiWidget; +} + + +void QmitkNavigationDataPlayerView::StdMultiWidgetNotAvailable() +{ + m_MultiWidget = NULL; +} + + +void QmitkNavigationDataPlayerView::OnPlayingStarted() +{ + m_TrajectoryPointSet->Clear(); // clear trajectory data before every replay +} + +void QmitkNavigationDataPlayerView::OnCreatePlaybackVisualization() +{ + if(m_ReloadData) // only if input file changed + { + m_Visualizer = mitk::NavigationDataObjectVisualizationFilter::New(); + + mitk::DataStorage* ds = this->GetDefaultDataStorage(); + + unsigned int nrTools = m_PlayerWidget->GetNumberOfTools(); // obtain number of tools from replay file + + QStringList toolNames; + toolNames << "No trajectory selected ..."; // info statement at beginning of trajectories list + + for(int i=0; iGetColorCircleColor(i); // color for replay object + + mitk::DataNode::Pointer playbackRepresentation = this->CreateRepresentationObject( nodeName.toStdString(), color ); // create replay DataNode object + + m_Visualizer->SetRepresentationObject(i, playbackRepresentation->GetData()); // add replay object to visualizer + + // add new representation object to DataStorage + this->AddRepresentationObject(this->GetDefaultDataStorage(), playbackRepresentation); + + } + + this->m_PlayerWidget->SetTrajectoryNames(toolNames); // set names in player widget trajectory selection combobox + m_ReloadData = false; + + + /// request global reiinit + mitk::NodePredicateNot::Pointer pred + = mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("includeInBoundingBox" + , mitk::BoolProperty::New(false))); + + mitk::DataStorage::SetOfObjects::ConstPointer rs = this->GetDataStorage()->GetSubset(pred); + // calculate bounding geometry of these nodes + mitk::TimeSlicedGeometry::Pointer bounds = this->GetDataStorage()->ComputeBoundingGeometry3D(rs, "visible"); + + // initialize the views to the bounding geometry + mitk::RenderingManager::GetInstance()->InitializeViews(bounds); + + /// global reinit end + + + + } + +} + +mitk::DataNode::Pointer QmitkNavigationDataPlayerView::CreateTrajectory( mitk::PointSet::Pointer points, const std::string& name, const mitk::Color color ) +{ + mitk::DataNode::Pointer result = mitk::DataNode::New(); + + // instantiate return DataNode + result->SetData(points); + result->SetName(name); + result->SetColor(color); + + mitk::PointSetVtkMapper3D::Pointer mapper; + + // create mapper for trajectory visualization + if(m_PlayerWidget->IsTrajectoryInSplineMode()) + mapper = this->GetTrajectoryMapper(Splines); + else + mapper = this->GetTrajectoryMapper(Points); + + result->SetMapper(mitk::BaseRenderer::Standard3D, mapper); + + // trajectory properties + result->SetProperty("contourcolor", mitk::ColorProperty::New(color)); + result->SetBoolProperty("show contour", true); + result->SetBoolProperty("updateDataOnRender", false); + + return result; +} + + +mitk::DataNode::Pointer QmitkNavigationDataPlayerView::CreateRepresentationObject(const std::string& name, const mitk::Color color) +{ + mitk::DataNode::Pointer representationNode = mitk::DataNode::New(); + + // creating cone DataNode for tool visualization + mitk::Cone::Pointer cone = mitk::Cone::New(); + vtkConeSource* vtkData = vtkConeSource::New(); + + vtkData->SetRadius(7.5); + vtkData->SetHeight(15.0); + vtkData->SetDirection(0.0, 0.0, 1.0); + vtkData->SetCenter(0.0, 0.0, 0.0); + vtkData->SetResolution(20); + vtkData->CappingOn(); + vtkData->Update(); + + cone->SetVtkPolyData(vtkData->GetOutput()); + + vtkData->Delete(); + + representationNode->SetData(cone); + + representationNode->GetPropertyList()->SetProperty("name", mitk::StringProperty::New( name.c_str() )); + representationNode->GetPropertyList()->SetProperty("layer", mitk::IntProperty::New(0)); + representationNode->GetPropertyList()->SetProperty("visible", mitk::BoolProperty::New(true)); + representationNode->SetColor(color); + representationNode->SetOpacity(1.0); + representationNode->Modified(); + + return representationNode; +} + + +void QmitkNavigationDataPlayerView::OnPerformPlaybackVisualization() +{ + if(m_PlayerWidget == NULL || m_Visualizer.IsNull()) + return; + + static int update = 0; + static int counter = -1; + + for(unsigned int i = 0 ; i < m_PlayerWidget->GetNavigationDatas().size(); ++i) + { + m_Visualizer->SetInput(i, m_PlayerWidget->GetNavigationDatas().at(i)); // pass updated tool NDs to visualizer + + + // show trajectory for selected tool with user given resolution + if(m_ShowTrajectory && (i == m_TrajectoryIndex) && (update++ % m_PlayerWidget->GetResolution() == 0) ) + { + + mitk::PointSet::PointType currentPoint = m_PlayerWidget->GetNavigationDataPoint(i); // current ND point for tool trajectory + + // if realtime mode is selected, trajectory points that are equal in position to their antecessor + // will not be inserted in the trajectory pointset to avoid "vtk can't create normals" warning + if(m_PlayerWidget->GetCurrentPlaybackMode() == QmitkIGTPlayerWidget::RealTimeMode) + { + mitk::PointSet::PointType lastPoint; + if(counter == -1) + { + lastPoint[0] = -1; + lastPoint[1] = -1; + lastPoint[2] = -1; + } + else + lastPoint = m_TrajectoryPointSet->GetPoint(counter); // antecessor point is last point from PointSet + + mitk::PointSet::PointType currentPoint = m_PlayerWidget->GetNavigationDataPoint(i); + + // check for position differences between last and current point + bool diff0 = lastPoint[0] != currentPoint[0]; + bool diff1 = lastPoint[1] != currentPoint[1]; + bool diff2 = lastPoint[2] != currentPoint[2]; + + if(diff0 || diff1 || diff2) + m_TrajectoryPointSet->InsertPoint(++counter, currentPoint); // insert only if there are differences + } + else + { + m_TrajectoryPointSet->InsertPoint(++counter, currentPoint); // insert point in trajectory PointSet + } + + } + } + + this->RenderScene(); +} + +void QmitkNavigationDataPlayerView::RenderScene() +{ + try + { + if (m_Visualizer.IsNull() || this->GetActiveStdMultiWidget() == NULL) + return; + + try + { + m_Visualizer->Update(); + } + catch(std::exception& e) + { + std::cout << "Exception during QmitkNavigationDataPlayerView::RenderScene():" << e.what() << "\n"; + } + + //update all Widgets + // mitk::RenderingManager::GetInstance()->RequestUpdateAll(mitk::RenderingManager::REQUEST_UPDATE_3DWINDOWS); + + // update only Widget4 + mitk::BaseRenderer::GetInstance(m_MultiWidget->mitkWidget4->GetRenderWindow())->RequestUpdate(); // update 3D render window + } + catch (std::exception& e) + { + std::cout << "RenderAll exception: " << e.what() << "\n"; + } + catch (...) + { + std::cout << "RenderAll unknown exception\n"; + } +} + +void QmitkNavigationDataPlayerView::OnReinit() +{ + + std::vector::iterator it; + + mitk::DataStorage* ds = this->GetDefaultDataStorage(); + + // clear tool representation objects from DataStorage + for ( it = m_RepresentationObjects.begin() ; it != m_RepresentationObjects.end(); it++ ) + { + //ds->Remove(*it); + mitk::DataNode::Pointer dn = ds->GetNamedNode((*it)->GetName()); + if(dn.IsNotNull()) + ds->Remove(dn); + } + + m_RepresentationObjects.clear(); // clear tool representation objects vector + + if(m_Trajectory.IsNotNull()) + this->GetDefaultDataStorage()->Remove(m_Trajectory); // remove trajectory DataNode from DataStorage + + m_TrajectoryPointSet->Clear(); // clear trajectory PointSet + this->m_PlayerWidget->ClearTrajectorySelectCombobox(); // clear trajectory selection combobox in player widget + + m_ReloadData = true; // set flag to true so representation data will be reload if play is triggered again + +} + +void QmitkNavigationDataPlayerView::AddTrajectory(mitk::DataStorage* ds, mitk::DataNode::Pointer trajectoryNode) +{ + if(ds == NULL) + return; + + if(m_Trajectory.IsNotNull()) + ds->Remove(m_Trajectory); // remove trajectory from DataStorage if already exists + + + // add trajectory to DataStorage + if(ds != NULL && trajectoryNode.IsNotNull()) + { + m_Trajectory = trajectoryNode; + ds->Add(m_Trajectory); + } +} + +void QmitkNavigationDataPlayerView::AddRepresentationObject(mitk::DataStorage* ds, mitk::DataNode::Pointer reprObject) +{ + m_RepresentationObjects.push_back(reprObject); + ds->Add(reprObject); +} + +void QmitkNavigationDataPlayerView::RemoveRepresentationObject(mitk::DataStorage* ds, mitk::DataNode::Pointer reprObject) +{ + std::vector::iterator it; + + for ( it = m_RepresentationObjects.begin() ; it != m_RepresentationObjects.end(); it++ ) + { + if(*it == reprObject) + { + m_RepresentationObjects.erase(it); + ds->Remove(reprObject); + } + } +} + +void QmitkNavigationDataPlayerView::OnShowTrajectory(int index) +{ + + mitk::DataStorage* ds = this->GetDefaultDataStorage(); + + + // no trajectory selected + if(index == 0) + { + m_ShowTrajectory = false; + m_TrajectoryIndex = -1; + + if(m_Trajectory.IsNotNull()) + ds->Remove(m_Trajectory); + } + + else + { + m_ShowTrajectory = true; + + // index-1 because combobox is filled with infovalue at index = 0 + mitk::DataNode::Pointer replayObject = m_RepresentationObjects.at(index-1); + + std::string prefix("Trajectory of "); + std::string name = replayObject->GetName(); + + mitk::Color color = this->GetColorCircleColor(index-1); + + if(m_TrajectoryPointSet.IsNotNull()) + m_TrajectoryPointSet->Clear(); + + m_TrajectoryIndex = index-1; + + mitk::DataNode::Pointer trajectory = this->CreateTrajectory( m_TrajectoryPointSet, prefix.append(name), color ); + this->AddTrajectory(this->GetDefaultDataStorage(), trajectory); + } +} + + +void QmitkNavigationDataPlayerView::OnEnableSplineTrajectoryMapper(bool enable) +{ + if(m_Trajectory.IsNull()) + return; + + // if enabled set spline mapper + if(enable) + m_Trajectory->SetMapper(mitk::BaseRenderer::Standard3D, this->GetTrajectoryMapper(Splines)); + + // if disabled set pointset mapper + else + m_Trajectory->SetMapper(mitk::BaseRenderer::Standard3D, this->GetTrajectoryMapper(Points)); + + + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); // request update after mapper change +} + + + +mitk::Color QmitkNavigationDataPlayerView::GetColorCircleColor(int index) +{ + mitk::Color result; + + mitk::ColorSequenceCycleH colorCycle; + + for(int i=0; i <= index; ++i) + { + result = colorCycle.GetNextColor(); + } + + return result; +} + + +mitk::PointSetVtkMapper3D::Pointer QmitkNavigationDataPlayerView::GetTrajectoryMapper(TrajectoryStyle style) +{ + if(style == Points) + { + if(m_PointSetMapper.IsNull()) + m_PointSetMapper = mitk::PointSetVtkMapper3D::New(); + + return m_PointSetMapper; + } + + else if(style == Splines) + { + if(m_SplineMapper.IsNull()) + m_SplineMapper = mitk::SplineVtkMapper3D::New(); + + return m_SplineMapper.GetPointer(); + } + else + return NULL; +} + + + diff --git a/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/src/internal/QmitkNavigationDataPlayerView.h b/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/src/internal/QmitkNavigationDataPlayerView.h new file mode 100644 index 0000000000..7985048f10 --- /dev/null +++ b/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/src/internal/QmitkNavigationDataPlayerView.h @@ -0,0 +1,179 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date: 2010-03-31 16:40:27 +0200 (Mi, 31 Mrz 2010) $ +Version: $Revision: 21975 $ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#ifndef QmitkNavigationDataPlayerView_h +#define QmitkNavigationDataPlayerView_h + +#include + +//Qmitk +#include +#include + +#include +#include + +// ui +#include "ui_QmitkNavigationDataPlayerViewControls.h" + +//mitk +#include +#include + + + + + +/*! +\brief QmitkNavigationDataPlayerView + +\warning This application module is not yet documented. Use "svn blame/praise/annotate" and ask the author to provide basic documentation. + +\sa QmitkFunctionality +\ingroup Functionalities +*/ +class QmitkNavigationDataPlayerView : public QObject, public QmitkFunctionality +{ + // this is needed for all Qt objects that should have a Qt meta-object + // (everything that derives from QObject and wants to have signal/slots) + Q_OBJECT + +public: + + static const std::string VIEW_ID; + + QmitkNavigationDataPlayerView(); + virtual ~QmitkNavigationDataPlayerView(); + + virtual void CreateQtPartControl(QWidget *parent); + + /** + \brief This method creates this bundle's SIGNAL and SLOT connections + */ + virtual void CreateConnections(); + + + virtual void StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget); + virtual void StdMultiWidgetNotAvailable(); + + + protected slots: + + /*! + \brief Creates DataNodes for all available playback objects + */ + void OnCreatePlaybackVisualization(); + /*! + \brief Assigns position changings from the player widget to the visualization objects + */ + void OnPerformPlaybackVisualization(); + /*! + \brief Reinits this player. Cleans all timers and trajectory data + */ + void OnReinit(); + /*! + \brief Shows trajectory of tool with index + */ + void OnShowTrajectory(int index); + /*! + \brief Cleans trajectory data before playing is started + */ + void OnPlayingStarted(); + /*! + \brief Enables or disables trajectory visualization with splines + */ + void OnEnableSplineTrajectoryMapper(bool enable); + + +protected: + + enum TrajectoryStyle { + Points = 1, + Splines = 2 + }; + + void CreateBundleWidgets(QWidget* parent); + + /** + \brief Refreshes the visualization of the playback object DataNodes. + */ + void RenderScene(); + + /** + \brief Creates representation DataNode with given name and color + */ + mitk::DataNode::Pointer CreateRepresentationObject( const std::string& name , const mitk::Color color ); + /** + \brief Adds representation DataNode to the DataStorage + */ + void AddRepresentationObject(mitk::DataStorage* ds, mitk::DataNode::Pointer reprObject); + /** + \brief Removes representation DataNode from the DataStorage + */ + void RemoveRepresentationObject(mitk::DataStorage* ds, mitk::DataNode::Pointer reprObject); + + /** + \brief Adds trajectory DataNode to the DataStorage + */ + void AddTrajectory(mitk::DataStorage* ds, mitk::DataNode::Pointer trajectoryNode); + + /** + \brief Creates a trajectory DataNode from given PointSet with given name and color + */ + mitk::DataNode::Pointer CreateTrajectory( mitk::PointSet::Pointer points, const std::string& name, const mitk::Color color ); + + + + + Ui::QmitkNavigationDataPlayerViewControls* m_Controls; + + QmitkStdMultiWidget* m_MultiWidget; + QmitkIGTPlayerWidget* m_PlayerWidget; ///< this bundle's playback widget + + mitk::NavigationDataObjectVisualizationFilter::Pointer m_Visualizer; ///< this filter visualizes the navigation data + + std::vector m_RepresentationObjects; ///< vector for current visualization objects + + mitk::DataNode::Pointer m_Trajectory; ///< main trajectory visualization DataNode + mitk::PointSet::Pointer m_TrajectoryPointSet; ///< PointSet with all points for trajectory + int m_TrajectoryIndex; ///< trajectory tool index + + bool m_ReloadData; ///< flag needed for refresh of visualization if needed + bool m_ShowTrajectory; ///< flag needed for trajectory visualization + + mitk::SplineVtkMapper3D::Pointer m_SplineMapper; ///< spline trajectory mapper + mitk::PointSetVtkMapper3D::Pointer m_PointSetMapper; ///< standard trajectroy mapper + + + + +private: + /** + \brief Returns color from colorcycle with given index + */ + mitk::Color GetColorCircleColor(int index); + /** + \brief Returns the trajectory mapper for the given style if stýle is not Points or Splines NULL will be returned. + */ + mitk::PointSetVtkMapper3D::Pointer GetTrajectoryMapper(TrajectoryStyle style); + +}; + + + +#endif // _QMITKNAVIGATIONDATAPLAYERVIEW_H_INCLUDED + diff --git a/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/src/internal/QmitkNavigationDataPlayerViewControls.ui b/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/src/internal/QmitkNavigationDataPlayerViewControls.ui new file mode 100644 index 0000000000..f136cc7545 --- /dev/null +++ b/Modules/Bundles/org.mitk.gui.qt.navigationdataplayer/src/internal/QmitkNavigationDataPlayerViewControls.ui @@ -0,0 +1,44 @@ + + + QmitkNavigationDataPlayerViewControls + + + + 0 + 0 + 222 + 161 + + + + + 0 + 0 + + + + QmitkTemplate + + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 20 + 220 + + + + + + + + + + diff --git a/Modules/IGT/IGTFilters/mitkNavigationDataPlayer.cpp b/Modules/IGT/IGTFilters/mitkNavigationDataPlayer.cpp index 646462529f..da0399a097 100644 --- a/Modules/IGT/IGTFilters/mitkNavigationDataPlayer.cpp +++ b/Modules/IGT/IGTFilters/mitkNavigationDataPlayer.cpp @@ -1,584 +1,534 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2009-02-10 18:08:54 +0100 (Di, 10 Feb 2009) $ Version: $Revision: 16228 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkNavigationDataPlayer.h" //for the pause #include #include #include mitk::NavigationDataPlayer::NavigationDataPlayer() { m_NumberOfOutputs = 0; m_Pause = false; m_Playing = false; m_Stream = NULL; m_PlayerMode = NormalFile; m_FileName = ""; m_FileVersion = 1; m_Playing = false; m_Pause = false; m_NumberOfOutputs = 0; m_StartPlayingTimeStamp = 0.0; m_PauseTimeStamp = 0.0; m_parentElement = NULL; m_currentNode = NULL; m_StreamEnd = false; //To get a start time mitk::TimeStamp::GetInstance()->Start(this); } mitk::NavigationDataPlayer::~NavigationDataPlayer() { StopPlaying(); delete m_parentElement; } void mitk::NavigationDataPlayer::GenerateData() { //Only produce new output if the player is started if (!m_Playing) { //The output is not valid anymore for (unsigned int index = 0; index < m_NumberOfOutputs; 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); } return; } //first of all get current time TimeStampType now = mitk::TimeStamp::GetInstance()->GetElapsed(); //now we make a little time arithmetic //to get the elapsed time since the start of the player TimeStampType timeSinceStart = now - m_StartPlayingTimeStamp; //init the vectors std::vector< NavigationData::Pointer > nextCandidates; std::vector< NavigationData::Pointer > lastCandidates; std::vector< NavigationData::TimeStampType > currentTimeOfData; for (unsigned int index=0; index < m_NumberOfOutputs; index++) { nextCandidates.push_back(m_NextToPlayNavigationData.at(index)); lastCandidates.push_back(m_NextToPlayNavigationData.at(index)); currentTimeOfData.push_back(timeSinceStart + m_StartTimeOfData.at(index)); } if (m_NextToPlayNavigationData.size() != m_NumberOfOutputs) { std::cout << "Mismatch in data" << std::endl; return; } // Now we try to find next NavigationData in the stream: // This means we step through the stream of NavigationDatas until we find // a NavigationData which has a current timestamp (currentTimeOfData) greater // then the current playing time. Then we store the data in // m_NextToPlayNavigationData and take the last data (lastCandidates) for the // output of this filter. // // The loop will stop when a suitable NavigationData is found or we reach EOF. // The timestamps of each recorded NavigationData should be equal // therefore we take always the time from the first. while( nextCandidates[0]->GetTimeStamp() < currentTimeOfData[0]) { for (unsigned int index=0; index < m_NumberOfOutputs; index++) { lastCandidates[index] = nextCandidates.at(index); switch(m_FileVersion) { case 1: nextCandidates[index] = ReadVersion1(); break; default: //this case should not happen! therefore the return at this point return; break; } //check if the input stream delivered a correct NavigationData object for (unsigned int i = 0; i < m_NumberOfOutputs; i++) { if (nextCandidates.at(index).IsNull()) { m_StreamEnd = true; StopPlaying(); return; //the case if no NavigationData is found, e.g. EOF, bad stream } } } } //Now lastCandidates stores the new output and nextCandidates is stored to the m_NextToPlay vector for (unsigned int index = 0; index < m_NumberOfOutputs; index++) { mitk::NavigationData* output = this->GetOutput(index); assert(output); output->Graft(lastCandidates.at(index)); m_NextToPlayNavigationData[index] = nextCandidates.at(index); } } - - - void mitk::NavigationDataPlayer::UpdateOutputInformation() { this->Modified(); // make sure that we need to be updated Superclass::UpdateOutputInformation(); } void mitk::NavigationDataPlayer::InitPlayer() { if (m_Stream == NULL) { m_StreamEnd = true; StopPlaying(); std::cout << "Playing not possible. Wrong file name or path? " << std::endl; return; } if (!m_Stream->good()) { m_StreamEnd = true; StopPlaying(); std::cout << "Playing not possible. Stream is not good!" << std::endl; return; } m_FileVersion = GetFileVersion(m_Stream); //first get the file version //check if we have a valid version if (m_FileVersion < 1) { m_StreamEnd = true; StopPlaying(); std::cout << "Playing not possible. Stream is not good!" << std::endl; return; } if(m_NumberOfOutputs == 0){ m_NumberOfOutputs = GetNumberOfNavigationDatas(m_Stream); //now read the number of Tracked Tools } //with the information about the tracked tool number we can generate the output if (m_NumberOfOutputs > 0) { //Generate the output only if there are changes to the amount of outputs //This happens when the player is stopped and start again with different file if (this->GetNumberOfOutputs() != m_NumberOfOutputs) { this->SetNumberOfOutputs(m_NumberOfOutputs); } GetFirstData(); //initialize the player with first data } else { std::cout << "The input stream seems to have NavigationData incompatible format" << std::endl; StopPlaying(); } } unsigned int mitk::NavigationDataPlayer::GetFileVersion(std::istream* stream) { if (stream==NULL) { std::cout << "No input stream set!" << std::endl; return 0; } if (!stream->good()) { std::cout << "Stream not good!" << std::endl; return 0; } int version = 1; TiXmlDeclaration* dec = new TiXmlDeclaration(); *stream >> *dec; if(strcmp(dec->Version(),"") == 0){ std::cout << "The input stream seems to have XML incompatible format" << std::endl; return 0; } m_parentElement = new TiXmlElement(""); *stream >> *m_parentElement; //2nd line this is the file version std::string tempValue = m_parentElement->Value(); if(tempValue != "Version") { if(tempValue == "Data"){ m_parentElement->QueryIntAttribute("version",&version); } } else { m_parentElement->QueryIntAttribute("Ver",&version); } if (version > 0) return version; else return 0; } unsigned int mitk::NavigationDataPlayer::GetNumberOfNavigationDatas(std::istream* stream) { if (stream == NULL) { std::cout << "No input stream set!" << std::endl; return 0; } if (!stream->good()) { std::cout << "Stream not good!" << std::endl; return 0; } //If something has changed in a future version of the XML definition e.g. navigationcount or addional parameters //catch this here with a select case block (see GenerateData() method) int numberOfTools = 0; std::string tempValue = m_parentElement->Value(); if(tempValue == "Version"){ *stream >> *m_parentElement; } m_parentElement->QueryIntAttribute("ToolCount",&numberOfTools); if (numberOfTools > 0) return numberOfTools; return 0; } mitk::NavigationData::Pointer mitk::NavigationDataPlayer::ReadVersion1() { if (m_Stream == NULL) { m_Playing = false; std::cout << "Playing not possible. Wrong file name or path? " << std::endl; return NULL; } if (!m_Stream->good()) { m_Playing = false; std::cout << "Playing not possible. Stream is not good!" << std::endl; return 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(); - - TiXmlElement* elem = new TiXmlElement(""); + /*TiXmlElement* elem = new TiXmlElement(""); m_currentNode = m_parentElement->IterateChildren(m_currentNode); - if(m_currentNode){ + + if(m_currentNode) + { elem = m_currentNode->ToElement(); - } + }*/ - //check here if EOF (the query don't change the timestamp value which should always be > 0) - elem->QueryDoubleAttribute("Time",×tamp); - if (timestamp == -1) - { - return NULL; //the calling method should check the return value if it is valid/not NULL - } - - elem->QueryFloatAttribute("X", &position[0]); - elem->QueryFloatAttribute("Y", &position[1]); - elem->QueryFloatAttribute("Z", &position[2]); - - elem->QueryFloatAttribute("QX", &orientation[0]); - elem->QueryFloatAttribute("QY", &orientation[1]); - elem->QueryFloatAttribute("QZ", &orientation[2]); - elem->QueryFloatAttribute("QR", &orientation[3]); - - elem->QueryFloatAttribute("C00", &matrix[0][0]); - elem->QueryFloatAttribute("C01", &matrix[0][1]); - elem->QueryFloatAttribute("C02", &matrix[0][2]); - elem->QueryFloatAttribute("C03", &matrix[0][3]); - elem->QueryFloatAttribute("C04", &matrix[0][4]); - elem->QueryFloatAttribute("C05", &matrix[0][5]); - elem->QueryFloatAttribute("C10", &matrix[1][0]); - elem->QueryFloatAttribute("C11", &matrix[1][1]); - elem->QueryFloatAttribute("C12", &matrix[1][2]); - elem->QueryFloatAttribute("C13", &matrix[1][3]); - elem->QueryFloatAttribute("C14", &matrix[1][4]); - elem->QueryFloatAttribute("C15", &matrix[1][5]); - - int tmpval = 0; - elem->QueryIntAttribute("Valid", &tmpval); - if (tmpval == 0) - dataValid = false; - else - dataValid = true; + TiXmlElement* elem; + m_currentNode = m_parentElement->IterateChildren(m_currentNode); - tmpval = 0; - elem->QueryIntAttribute("hO", &tmpval); - if (tmpval == 0) - hasOrientation = false; - else - hasOrientation = true; + bool delElem; - tmpval = 0; - elem->QueryIntAttribute("hP", &tmpval); - if (tmpval == 0) - hasPosition = false; + if(m_currentNode) + { + elem = m_currentNode->ToElement(); + delElem = false; + } + else - hasPosition = true; + { + elem = new TiXmlElement(""); + delElem = true; + } + + + mitk::NavigationData::Pointer nd = this->ReadNavigationData(elem); - nd->SetTimeStamp(timestamp); - nd->SetPosition(position); - nd->SetOrientation(orientation); - nd->SetCovErrorMatrix(matrix); - nd->SetDataValid(dataValid); - nd->SetHasOrientation(hasOrientation); - nd->SetHasPosition(hasPosition); + if(delElem) + delete elem; - //delete elem; return nd; } void mitk::NavigationDataPlayer::StartPlaying() { if (m_Stream == NULL) { m_Playing = false; //Perhaps the SetStream method was not called so we do this when a FileName is set with SetStream(PlayerMode) if (m_FileName != "") { //The PlayerMode is initialized with LastSetStream //SetStream also calls InitPlayer() SetStream(m_PlayerMode); } //now check again if (m_Stream == NULL) { StopPlaying(); std::cout << "Playing not possible. Wrong file name or path? " << std::endl; return; } } if (!m_Playing && m_Stream->good()) { m_Playing = true; //starts the player m_StartPlayingTimeStamp = mitk::TimeStamp::GetInstance()->GetElapsed(); } else { std::cout << "Player already started or stream is not good" << std::endl; StopPlaying(); } } void mitk::NavigationDataPlayer::StopPlaying() { //re init all data!! for playing again with different data //only PlayerMode and FileName are not changed m_Pause = false; m_Playing = false; m_Stream = NULL; m_FileVersion = 1; m_Playing = false; m_Pause = false; m_StartPlayingTimeStamp = 0.0; m_PauseTimeStamp = 0.0; m_NextToPlayNavigationData.clear(); m_StartTimeOfData.clear(); } void mitk::NavigationDataPlayer::GetFirstData() { //Here we read the first lines of input (dependend on the number of inputs) for (unsigned int index=0; index < m_NumberOfOutputs; index++) { //Here we init the vector for later use m_NextToPlayNavigationData.push_back(NULL); m_StartTimeOfData.push_back(0.0); mitk::NavigationData::Pointer nd = this->GetOutput(index); switch(m_FileVersion) { case 1: m_NextToPlayNavigationData[index] = ReadVersion1(); //check if there is valid data in it if (m_NextToPlayNavigationData[index].IsNull()) { m_StreamEnd = true; StopPlaying(); std::cout << "XML File is corrupt or has no NavigationData" << std::endl; return; } //Have a look it the output was set already without this check the pipline will disconnect after a start/stop cycle if (nd.IsNull()) this->SetNthOutput(index, m_NextToPlayNavigationData[index]); m_StartTimeOfData[index] = m_NextToPlayNavigationData[index]->GetTimeStamp(); break; default: //this case should not happen! therefore the return at this point return; break; } } } void mitk::NavigationDataPlayer::Pause() { //player runs and pause was called -> pause the player if(m_Playing && !m_Pause) { m_Playing = false; m_Pause = true; m_PauseTimeStamp = mitk::TimeStamp::GetInstance()->GetElapsed(); } else { std::cout << "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_Playing && m_Pause) { m_Playing = true; m_Pause = false; mitk::NavigationData::TimeStampType now = mitk::TimeStamp::GetInstance()->GetElapsed(); // in this case m_StartPlayingTimeStamp is set to the total elapsed time with NO playback m_StartPlayingTimeStamp = now - (m_PauseTimeStamp - m_StartPlayingTimeStamp); } else { std::cout << "Player is not paused!" << std::endl; } } void mitk::NavigationDataPlayer::SetStream( PlayerMode /*mode*/ ) { m_Stream = NULL; if (!itksys::SystemTools::FileExists(m_FileName.c_str())) { std::cout << "File dont exist!" << std::endl; return; } switch(m_PlayerMode) { case NormalFile: m_Stream = new std::ifstream(m_FileName.c_str()); break; case ZipFile: m_Stream = NULL; std::cout << "Sorry no ZipFile support yet"; break; default: m_Stream = NULL; break; } this->Modified(); InitPlayer(); } void mitk::NavigationDataPlayer::SetStream( std::istream* stream ) { if (!stream->good()) { m_StreamEnd = true; std::cout << "The stream is not good" << std::endl; return; } m_Stream = stream; this->Modified(); InitPlayer(); } const bool mitk::NavigationDataPlayer::IsAtEnd() { return this->m_StreamEnd; } \ No newline at end of file diff --git a/Modules/IGT/IGTFilters/mitkNavigationDataPlayer.h b/Modules/IGT/IGTFilters/mitkNavigationDataPlayer.h index 3ec554e02d..e7e8bfa64e 100644 --- a/Modules/IGT/IGTFilters/mitkNavigationDataPlayer.h +++ b/Modules/IGT/IGTFilters/mitkNavigationDataPlayer.h @@ -1,203 +1,204 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2009-02-10 18:08:54 +0100 (Di, 10 Feb 2009) $ Version: $Revision: 16228 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef MITKNavigationDataPlayer_H_HEADER_INCLUDED_ #define MITKNavigationDataPlayer_H_HEADER_INCLUDED_ +#include #include #include //for the Recording Mode enum #include "mitkTrackingDevice.h" #include #include "tinyxml.h" #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 NavigationDataSource + class MitkIGT_EXPORT NavigationDataPlayer : public NavigationDataPlayerBase { public: - mitkClassMacro(NavigationDataPlayer, NavigationDataSource); + mitkClassMacro(NavigationDataPlayer, NavigationDataPlayerBase); itkNewMacro(Self); /** * \brief sets the file name and path for the PlayerMode NormalFile and ZipFile */ itkSetStringMacro(FileName); /** * \brief returns the file name and path for the PlayerMode NormalFile and ZipFile */ itkGetStringMacro(FileName); /** * \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. * * Before the stream has to be set. Either with a PlayingMode (SetStream(PlayerMode)) and FileName. Or * with an own inputstream (SetStream(istream*)). */ 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() * *\warning This method is not tested yet. It is not save to use! */ void Pause(); /** * \brief This method resumes the player when it was paused. * *\warning This method is not tested yet. It is not save to use! */ void Resume(); /** * \brief This method checks if player arrived at end of file. * *\warning This method is not tested yet. It is not save to use! */ const bool IsAtEnd(); /** * \brief The PlayerMode is used for generating a presetted output stream. You do not need to * set it if you want to use your own stream. * * There are: * NormalFile: ifstream * ZipFile: not implemented yet * *\warning The ZipFile Mode is not implemented yet */ enum PlayerMode { NormalFile, ZipFile }; /** * \brief sets the recording mode which causes different types of output streams * This method is overloaded with SetStream( ostream* ) */ void SetStream(PlayerMode mode); /** * \brief sets the recording mode which causes different types of output streams * This method is overloaded with SetStream( PlayerMode ) */ void SetStream(std::istream* stream); protected: NavigationDataPlayer(); virtual ~NavigationDataPlayer(); typedef mitk::NavigationData::TimeStampType TimeStampType; /** * \brief filter execute method */ virtual void GenerateData(); /** * \brief Returns the file version out of the XML document. */ unsigned int GetFileVersion(std::istream* stream); /** * \brief Returns the number of tracked tools out of the XML document. */ unsigned int GetNumberOfNavigationDatas(std::istream* stream); /** * \brief Gets the first data for initializing the player */ void GetFirstData(); /** * \brief This method reads one line of the XML document and returns the data as a NavigationData object * If there is a new file version another method must be added which reads this data. */ mitk::NavigationData::Pointer ReadVersion1(); /** * \brief This method initializes the player with first data */ void InitPlayer(); std::istream* m_Stream; ///< stores a pointer to the input stream PlayerMode m_PlayerMode; ///< stores the mode for the presetted PlayerMode sieh enum PlayerMode std::string m_FileName; ///< stores the filename unsigned int m_FileVersion; ///< indicates which XML encoding is used bool m_Playing; ///< indicates whether the generateoutput method generates new output or not bool m_Pause; ///< indicates if the player is paused unsigned int m_NumberOfOutputs; ///< stores the number of outputs known from the XML document TimeStampType m_StartPlayingTimeStamp; ///< the starttime of the playing set in the method StartPlaying() TimeStampType m_PauseTimeStamp; ///< stores the beginning of a pause std::vector m_NextToPlayNavigationData; ///< stores the next possible candidate for playing std::vector m_StartTimeOfData; ///< stores the start time of the different tools TiXmlElement * m_parentElement; TiXmlNode * m_currentNode; bool m_StreamEnd; ///< stores if the input stream arrived at end }; } // namespace mitk #endif /* MITKNavigationDataPlayer_H_HEADER_INCLUDED_ */ diff --git a/Modules/IGT/IGTFilters/mitkNavigationDataPlayerBase.cpp b/Modules/IGT/IGTFilters/mitkNavigationDataPlayerBase.cpp new file mode 100644 index 0000000000..543812eea9 --- /dev/null +++ b/Modules/IGT/IGTFilters/mitkNavigationDataPlayerBase.cpp @@ -0,0 +1,114 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date: 2009-02-10 18:08:54 +0100 (Di, 10 Feb 2009) $ +Version: $Revision: 16228 $ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#include "mitkNavigationDataPlayerBase.h" + + + + +mitk::NavigationDataPlayerBase::~NavigationDataPlayerBase() +{ +} + + + + +void mitk::NavigationDataPlayerBase::UpdateOutputInformation() +{ + this->Modified(); // make sure that we need to be updated + Superclass::UpdateOutputInformation(); +} + + + +mitk::NavigationData::Pointer mitk::NavigationDataPlayerBase::ReadNavigationData(TiXmlElement* elem) +{ + 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->QueryFloatAttribute("X", &position[0]); + elem->QueryFloatAttribute("Y", &position[1]); + elem->QueryFloatAttribute("Z", &position[2]); + + elem->QueryFloatAttribute("QX", &orientation[0]); + elem->QueryFloatAttribute("QY", &orientation[1]); + elem->QueryFloatAttribute("QZ", &orientation[2]); + elem->QueryFloatAttribute("QR", &orientation[3]); + + elem->QueryFloatAttribute("C00", &matrix[0][0]); + elem->QueryFloatAttribute("C01", &matrix[0][1]); + elem->QueryFloatAttribute("C02", &matrix[0][2]); + elem->QueryFloatAttribute("C03", &matrix[0][3]); + elem->QueryFloatAttribute("C04", &matrix[0][4]); + elem->QueryFloatAttribute("C05", &matrix[0][5]); + elem->QueryFloatAttribute("C10", &matrix[1][0]); + elem->QueryFloatAttribute("C11", &matrix[1][1]); + elem->QueryFloatAttribute("C12", &matrix[1][2]); + elem->QueryFloatAttribute("C13", &matrix[1][3]); + elem->QueryFloatAttribute("C14", &matrix[1][4]); + elem->QueryFloatAttribute("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->SetTimeStamp(timestamp); + nd->SetPosition(position); + nd->SetOrientation(orientation); + nd->SetCovErrorMatrix(matrix); + nd->SetDataValid(dataValid); + nd->SetHasOrientation(hasOrientation); + nd->SetHasPosition(hasPosition); + + + return nd; +} diff --git a/Modules/IGT/IGTFilters/mitkNavigationDataPlayerBase.h b/Modules/IGT/IGTFilters/mitkNavigationDataPlayerBase.h new file mode 100644 index 0000000000..d18055e449 --- /dev/null +++ b/Modules/IGT/IGTFilters/mitkNavigationDataPlayerBase.h @@ -0,0 +1,66 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date: 2009-02-10 18:08:54 +0100 (Di, 10 Feb 2009) $ +Version: $Revision: 16228 $ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + + +#ifndef MITKNavigationDataPlayerBase_H_HEADER_INCLUDED_ +#define MITKNavigationDataPlayerBase_H_HEADER_INCLUDED_ + +#include +#include "tinyxml.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 + */ + 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 + */ + virtual void UpdateOutputInformation(); + + /** + * \brief This method checks if player arrived at end of file. + * + *\warning This method is not tested yet. It is not save to use! + */ + const bool IsAtEnd(); + + protected: + virtual ~NavigationDataPlayerBase(); + virtual void GenerateData() = 0; + + + /** + * \brief Creates NavigationData from XML element and returns it + */ + mitk::NavigationData::Pointer ReadNavigationData(TiXmlElement* elem); + + }; +} // namespace mitk + +#endif /* MITKNavigationDataSequentialPlayer_H_HEADER_INCLUDED_ */ diff --git a/Modules/IGT/IGTFilters/mitkNavigationDataSequentialPlayer.cpp b/Modules/IGT/IGTFilters/mitkNavigationDataSequentialPlayer.cpp index a1fff5d0ba..eb2b131467 100644 --- a/Modules/IGT/IGTFilters/mitkNavigationDataSequentialPlayer.cpp +++ b/Modules/IGT/IGTFilters/mitkNavigationDataSequentialPlayer.cpp @@ -1,261 +1,190 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2009-02-10 18:08:54 +0100 (Di, 10 Feb 2009) $ Version: $Revision: 16228 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkNavigationDataSequentialPlayer.h" //for the pause #include #include #include #include mitk::NavigationDataSequentialPlayer::NavigationDataSequentialPlayer() : m_Doc(new TiXmlDocument) , m_DataElem(0) , m_CurrentElem(0) , m_Repeat(false) , m_NumberOfSnapshots(0) , m_LastGoTo(0) { } mitk::NavigationDataSequentialPlayer::~NavigationDataSequentialPlayer() { delete m_Doc; } void mitk::NavigationDataSequentialPlayer::ReinitXML() { m_DataElem = m_Doc->FirstChildElement("Data"); int toolcount; if(!m_DataElem) MITK_WARN << "Data element not found"; else { m_DataElem->QueryIntAttribute("ToolCount", &toolcount); this->SetNumberOfOutputs(toolcount); mitk::NavigationData::Pointer emptyNd = mitk::NavigationData::New(); mitk::NavigationData::PositionType position; mitk::NavigationData::OrientationType orientation(0.0,0.0,0.0,0.0); position.Fill(0.0); emptyNd->SetPosition(position); emptyNd->SetOrientation(orientation); emptyNd->SetDataValid(false); mitk::NavigationData::Pointer tmp; for (unsigned int index = 0; index < this->GetNumberOfOutputs(); index++) { tmp = mitk::NavigationData::New(); tmp->Graft(emptyNd); this->SetNthOutput(index, tmp); } // find out _NumberOfSnapshots m_NumberOfSnapshots = 0; TiXmlElement* nextND = m_DataElem->FirstChildElement("ND"); while(nextND) { ++m_NumberOfSnapshots; nextND = nextND->NextSiblingElement("ND"); } // e.g. 12 nd found and 2 tools used => number of snapshots is 12:2=6 m_NumberOfSnapshots = m_NumberOfSnapshots/toolcount; } } void mitk::NavigationDataSequentialPlayer::GoToSnapshot(int i) { assert(m_DataElem); int numOfUpdateCalls = 0; // i.e. number of snapshots 10 // goto(7), m_LastGoTo=3 => numOfUpdateCalls = 4 if(m_LastGoTo <= i) numOfUpdateCalls = i - m_LastGoTo; // goto(4), m_LastGoTo=7 => numOfUpdateCalls = 7 else { if(!m_Repeat) { MITK_WARN << "cannot go back to snapshot " << i << " because the " << this->GetNameOfClass() << " is configured to not repeat the" << " navigation data"; } else { numOfUpdateCalls = (m_NumberOfSnapshots - m_LastGoTo) + i; } } for(int j=0; jUpdate(); m_LastGoTo = i; } void mitk::NavigationDataSequentialPlayer:: SetFileName(const std::string& _FileName) { m_FileName = _FileName; if(!m_Doc->LoadFile(m_FileName)) { this->SetNumberOfOutputs(0); std::ostringstream s; s << "File " << _FileName << " could not be loaded"; throw std::invalid_argument(s.str()); } else this->ReinitXML(); this->Modified(); } void mitk::NavigationDataSequentialPlayer:: SetXMLString(const std::string& _XMLString) { m_XMLString = _XMLString; m_Doc->Parse( m_XMLString.c_str() ); this->ReinitXML(); this->Modified(); } void mitk::NavigationDataSequentialPlayer::GenerateData() { assert(m_DataElem); // very important: go through the tools (there could be more then one) mitk::NavigationData::Pointer tmp; for (unsigned int index = 0; index < this->GetNumberOfOutputs(); index++) { // go to the first element if(!m_CurrentElem) m_CurrentElem = m_DataElem->FirstChildElement("ND"); // go to the next element else m_CurrentElem = m_CurrentElem->NextSiblingElement(); // if repeat is on: go back to the first element (prior calls delivered NULL // elem) if(!m_CurrentElem && m_Repeat) m_CurrentElem = m_DataElem->FirstChildElement("ND"); mitk::NavigationData* output = this->GetOutput(index); tmp = this->ReadVersion1(); if(tmp.IsNotNull()) output->Graft(tmp); else // no valid output output->SetDataValid(false); } } mitk::NavigationData::Pointer mitk::NavigationDataSequentialPlayer::ReadVersion1() { - 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(); TiXmlElement* elem = m_CurrentElem; if(!elem) return NULL; - //check here if EOF (the query don't change the timestamp value which should always be > 0) - elem->QueryDoubleAttribute("Time",×tamp); - if (timestamp == -1) - { - return NULL; //the calling method should check the return value if it is valid/not NULL - } - - elem->QueryFloatAttribute("X", &position[0]); - elem->QueryFloatAttribute("Y", &position[1]); - elem->QueryFloatAttribute("Z", &position[2]); - - elem->QueryFloatAttribute("QX", &orientation[0]); - elem->QueryFloatAttribute("QY", &orientation[1]); - elem->QueryFloatAttribute("QZ", &orientation[2]); - elem->QueryFloatAttribute("QR", &orientation[3]); - - elem->QueryFloatAttribute("C00", &matrix[0][0]); - elem->QueryFloatAttribute("C01", &matrix[0][1]); - elem->QueryFloatAttribute("C02", &matrix[0][2]); - elem->QueryFloatAttribute("C03", &matrix[0][3]); - elem->QueryFloatAttribute("C04", &matrix[0][4]); - elem->QueryFloatAttribute("C05", &matrix[0][5]); - elem->QueryFloatAttribute("C10", &matrix[1][0]); - elem->QueryFloatAttribute("C11", &matrix[1][1]); - elem->QueryFloatAttribute("C12", &matrix[1][2]); - elem->QueryFloatAttribute("C13", &matrix[1][3]); - elem->QueryFloatAttribute("C14", &matrix[1][4]); - elem->QueryFloatAttribute("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->SetTimeStamp(timestamp); - nd->SetPosition(position); - nd->SetOrientation(orientation); - nd->SetCovErrorMatrix(matrix); - nd->SetDataValid(dataValid); - nd->SetHasOrientation(hasOrientation); - nd->SetHasPosition(hasPosition); - - //delete elem; - return nd; + return this->ReadNavigationData(elem); } void mitk::NavigationDataSequentialPlayer::UpdateOutputInformation() { this->Modified(); // make sure that we need to be updated Superclass::UpdateOutputInformation(); } diff --git a/Modules/IGT/IGTFilters/mitkNavigationDataSequentialPlayer.h b/Modules/IGT/IGTFilters/mitkNavigationDataSequentialPlayer.h index 2b0673842f..0958e25c06 100644 --- a/Modules/IGT/IGTFilters/mitkNavigationDataSequentialPlayer.h +++ b/Modules/IGT/IGTFilters/mitkNavigationDataSequentialPlayer.h @@ -1,111 +1,111 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2009-02-10 18:08:54 +0100 (Di, 10 Feb 2009) $ Version: $Revision: 16228 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef MITKNavigationDataSequentialPlayer_H_HEADER_INCLUDED_ #define MITKNavigationDataSequentialPlayer_H_HEADER_INCLUDED_ -#include +#include #include "tinyxml.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 */ class MitkIGT_EXPORT NavigationDataSequentialPlayer - : public NavigationDataSource + : public NavigationDataPlayerBase { public: - mitkClassMacro(NavigationDataSequentialPlayer, NavigationDataSource); + mitkClassMacro(NavigationDataSequentialPlayer, NavigationDataPlayerBase); itkNewMacro(Self); /** * \brief sets the file name and path (if XMLString is set, this is neglected) */ void SetFileName(const std::string& _FileName); /** * \brief returns the file name and path */ itkGetStringMacro(FileName); /** * \brief sets a xml string (by this, the xml string is not read from file) */ void SetXMLString(const std::string& _XMLString); /** * \brief returns the current xml string */ itkGetStringMacro(XMLString); /// /// set to true if the data player should repeat the outputs /// itkSetMacro(Repeat, bool); /// /// set if the data player should repeat the outputs /// itkGetMacro(Repeat, bool); /// /// \return the number of navigation data snapshots available in the file /// itkGetMacro(NumberOfSnapshots, unsigned int); /// /// advance the output to the i-th snapshot /// e.g. if you want to have the NavData of snapshot /// 17 then you can call GoToSnapshot(17). index begins at 1! /// you can then also go back to snapshot 1 with GoToSnapshot(1) /// void GoToSnapshot(int i); /** * \brief Used for pipeline update just to tell the pipeline * that we always have to update */ virtual void UpdateOutputInformation(); protected: NavigationDataSequentialPlayer(); virtual ~NavigationDataSequentialPlayer(); void ReinitXML(); mitk::NavigationData::Pointer ReadVersion1(); /// /// do the work here /// virtual void GenerateData(); std::string m_FileName; std::string m_XMLString; TiXmlDocument* m_Doc; TiXmlElement* m_DataElem; TiXmlElement* m_CurrentElem; bool m_Repeat; unsigned int m_NumberOfSnapshots; int m_LastGoTo; }; } // namespace mitk #endif /* MITKNavigationDataSequentialPlayer_H_HEADER_INCLUDED_ */ diff --git a/Modules/IGT/IGTFilters/mitkNavigationDataToPointSetPlayer.cpp b/Modules/IGT/IGTFilters/mitkNavigationDataToPointSetPlayer.cpp new file mode 100644 index 0000000000..1ea2dbc3b2 --- /dev/null +++ b/Modules/IGT/IGTFilters/mitkNavigationDataToPointSetPlayer.cpp @@ -0,0 +1,193 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date: 2009-02-10 18:08:54 +0100 (Di, 10 Feb 2009) $ +Version: $Revision: 16228 $ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#include "mitkNavigationDataToPointSetPlayer.h" + +//for the pause +#include + +#include +#include +#include + +#include + +mitk::NavigationDataToPointSetPlayer::NavigationDataToPointSetPlayer() + : m_Doc(new TiXmlDocument) + , m_DataElem(0) + , m_CurrentElem(0) + , m_Repeat(false) + , m_NumberOfSnapshots(0) + , m_LastGoTo(0) +{ +} + + +mitk::NavigationDataToPointSetPlayer::~NavigationDataToPointSetPlayer() +{ + delete m_Doc; +} + +void mitk::NavigationDataToPointSetPlayer::ReinitXML() +{ + m_NDPointSet.clear(); + m_PointSetFilter = mitk::NavigationDataToPointSetFilter::New(); + + m_DataElem = m_Doc->FirstChildElement("Data"); + int toolcount; + if(!m_DataElem) + MITK_WARN << "Data element not found"; + else + { + m_DataElem->QueryIntAttribute("ToolCount", &toolcount); + this->SetNumberOfOutputs(toolcount); + + mitk::NavigationData::Pointer emptyNd = mitk::NavigationData::New(); + mitk::NavigationData::PositionType position; + mitk::NavigationData::OrientationType orientation(0.0,0.0,0.0,0.0); + position.Fill(0.0); + + emptyNd->SetPosition(position); + emptyNd->SetOrientation(orientation); + emptyNd->SetDataValid(false); + + mitk::NavigationData::Pointer tmp; + for (unsigned int index = 0; index < this->GetNumberOfOutputs(); index++) + { + tmp = mitk::NavigationData::New(); + tmp->Graft(emptyNd); + this->SetNthOutput(index, tmp); + } + + // find out _NumberOfSnapshots + + NavigationData::Pointer nd; + + m_NumberOfSnapshots = 0; + TiXmlElement* nextND = m_DataElem->FirstChildElement("ND"); + + while(nextND) + { + ++m_NumberOfSnapshots; + nextND = nextND->NextSiblingElement("ND"); + } + + // e.g. 12 nd found and 2 tools used => number of snapshots is 12:2=6 + m_NumberOfSnapshots = m_NumberOfSnapshots/toolcount; + + /*NavigationData::TimeStampType recordedTime = (lastTimestamp-firstTimestamp) / 1000; + int frameRate = static_cast(floor(1000 / (float) (m_NumberOfSnapshots/recordedTime) + 0.5));*/ + + } +} + + + +void mitk::NavigationDataToPointSetPlayer:: + SetFileName(const std::string& _FileName) +{ + m_FileName = _FileName; + + if(!m_Doc->LoadFile(m_FileName)) + { + this->SetNumberOfOutputs(0); + std::ostringstream s; + s << "File " << _FileName << " could not be loaded"; + throw std::invalid_argument(s.str()); + } + else + { + this->ReinitXML(); + } + + this->Modified(); +} + + +void mitk::NavigationDataToPointSetPlayer::GenerateData() +{ + assert(m_DataElem); + + // very important: go through the tools (there could be more then one) + mitk::NavigationData::Pointer tmp; + for (unsigned int index = 0; index < this->GetNumberOfOutputs(); index++) + { + // go to the first element + if(!m_CurrentElem) + m_CurrentElem = m_DataElem->FirstChildElement("ND"); + // go to the next element + else + m_CurrentElem = m_CurrentElem->NextSiblingElement(); + + // if repeat is on: go back to the first element (prior calls delivered NULL + // elem) + if(!m_CurrentElem && m_Repeat) + m_CurrentElem = m_DataElem->FirstChildElement("ND"); + + mitk::NavigationData* output = this->GetOutput(index); + tmp = this->ReadVersion1(); + if(tmp.IsNotNull()) + output->Graft(tmp); + else // no valid output + output->SetDataValid(false); + } +} + + +void mitk::NavigationDataToPointSetPlayer::StartPlaying() +{ + //TODO +} + +void mitk::NavigationDataToPointSetPlayer::StopPlaying() +{ + //TODO +} + +void mitk::NavigationDataToPointSetPlayer::Pause() +{ + //TODO +} + +void mitk::NavigationDataToPointSetPlayer::Resume() +{ + //TODO +} + + +//TODO +const bool mitk::NavigationDataToPointSetPlayer::IsAtEnd() +{ + bool result = false; + return result; +} + +mitk::NavigationData::Pointer mitk::NavigationDataToPointSetPlayer::ReadVersion1() +{ + TiXmlElement* elem = m_CurrentElem; + + if(!elem) + return NULL; + + return this->ReadNavigationData(elem); +} + +void mitk::NavigationDataToPointSetPlayer::UpdateOutputInformation() +{ + this->Modified(); // make sure that we need to be updated + Superclass::UpdateOutputInformation(); +} diff --git a/Modules/IGT/IGTFilters/mitkNavigationDataSequentialPlayer.h b/Modules/IGT/IGTFilters/mitkNavigationDataToPointSetPlayer.h similarity index 61% copy from Modules/IGT/IGTFilters/mitkNavigationDataSequentialPlayer.h copy to Modules/IGT/IGTFilters/mitkNavigationDataToPointSetPlayer.h index 2b0673842f..cc75553f23 100644 --- a/Modules/IGT/IGTFilters/mitkNavigationDataSequentialPlayer.h +++ b/Modules/IGT/IGTFilters/mitkNavigationDataToPointSetPlayer.h @@ -1,111 +1,159 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2009-02-10 18:08:54 +0100 (Di, 10 Feb 2009) $ Version: $Revision: 16228 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ -#ifndef MITKNavigationDataSequentialPlayer_H_HEADER_INCLUDED_ -#define MITKNavigationDataSequentialPlayer_H_HEADER_INCLUDED_ +#ifndef MITKNavigationDataToPointSetPlayer_H_HEADER_INCLUDED_ +#define MITKNavigationDataToPointSetPlayer_H_HEADER_INCLUDED_ -#include +#include +#include +#include #include "tinyxml.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 */ - class MitkIGT_EXPORT NavigationDataSequentialPlayer - : public NavigationDataSource + class MitkIGT_EXPORT NavigationDataToPointSetPlayer + : public NavigationDataPlayerBase { public: - mitkClassMacro(NavigationDataSequentialPlayer, NavigationDataSource); + mitkClassMacro(NavigationDataToPointSetPlayer, NavigationDataPlayerBase); itkNewMacro(Self); /** * \brief sets the file name and path (if XMLString is set, this is neglected) */ void SetFileName(const std::string& _FileName); /** * \brief returns the file name and path */ itkGetStringMacro(FileName); /** * \brief sets a xml string (by this, the xml string is not read from file) */ void SetXMLString(const std::string& _XMLString); /** * \brief returns the current xml string */ itkGetStringMacro(XMLString); /// /// set to true if the data player should repeat the outputs /// itkSetMacro(Repeat, bool); /// /// set if the data player should repeat the outputs /// itkGetMacro(Repeat, bool); /// /// \return the number of navigation data snapshots available in the file /// itkGetMacro(NumberOfSnapshots, unsigned int); /// /// advance the output to the i-th snapshot /// e.g. if you want to have the NavData of snapshot /// 17 then you can call GoToSnapshot(17). index begins at 1! /// you can then also go back to snapshot 1 with GoToSnapshot(1) /// void GoToSnapshot(int i); /** * \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. + * + * Before the stream has to be set. Either with a PlayingMode (SetStream(PlayerMode)) and FileName. Or + * with an own inputstream (SetStream(istream*)). + */ + 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() + * + *\warning This method is not tested yet. It is not save to use! + */ + void Pause(); + + /** + * \brief This method resumes the player when it was paused. + * + *\warning This method is not tested yet. It is not save to use! + */ + void Resume(); + + + + + + + + const bool IsAtEnd(); + protected: - NavigationDataSequentialPlayer(); - virtual ~NavigationDataSequentialPlayer(); + NavigationDataToPointSetPlayer(); + virtual ~NavigationDataToPointSetPlayer(); void ReinitXML(); mitk::NavigationData::Pointer ReadVersion1(); /// /// do the work here /// virtual void GenerateData(); + + NavigationDataToPointSetFilter::Pointer m_PointSetFilter; + std::string m_FileName; std::string m_XMLString; TiXmlDocument* m_Doc; TiXmlElement* m_DataElem; TiXmlElement* m_CurrentElem; bool m_Repeat; unsigned int m_NumberOfSnapshots; int m_LastGoTo; + + std::vector m_NDPointSet; }; } // namespace mitk -#endif /* MITKNavigationDataSequentialPlayer_H_HEADER_INCLUDED_ */ +#endif /* MITKNavigationDataToPointSetPlayer_H_HEADER_INCLUDED_ */ diff --git a/Modules/IGT/files.cmake b/Modules/IGT/files.cmake index 628aeb2fe0..fd9fde96d0 100644 --- a/Modules/IGT/files.cmake +++ b/Modules/IGT/files.cmake @@ -1,57 +1,59 @@ SET(CPP_FILES IGTFilters/mitkNavigationDataLandmarkTransformFilter.cpp IGTFilters/mitkNavigationDataReferenceTransformFilter.cpp IGTFilters/mitkNavigationDataTransformFilter.cpp IGTFilters/mitkNavigationDataRecorder.cpp IGTFilters/mitkNavigationDataPlayer.cpp + IGTFilters/mitkNavigationDataPlayerBase.cpp IGTFilters/mitkNavigationDataObjectVisualizationFilter.cpp IGTFilters/mitkCameraVisualization.cpp IGTFilters/mitkNavigationData.cpp IGTFilters/mitkNavigationDataDisplacementFilter.cpp IGTFilters/mitkNavigationDataSequentialPlayer.cpp IGTFilters/mitkNavigationDataSource.cpp IGTFilters/mitkNavigationDataToMessageFilter.cpp IGTFilters/mitkNavigationDataToNavigationDataFilter.cpp IGTFilters/mitkNavigationDataToOpenGLFilter.cpp IGTFilters/mitkNavigationDataToPointSetFilter.cpp + IGTFilters/mitkTrackingDeviceSource.cpp IGTFilters/mitkTimeStamp.cpp IGTFilters/mitkRealTimeClock.cpp IGTFilters/mitkTrackingDeviceSourceConfigurator.cpp IGTTrackingDevices/mitkClaronTool.cpp IGTTrackingDevices/mitkClaronTrackingDevice.cpp IGTTrackingDevices/mitkInternalTrackingTool.cpp IGTTrackingDevices/mitkNDIPassiveTool.cpp IGTTrackingDevices/mitkNDIProtocol.cpp IGTTrackingDevices/mitkNDITrackingDevice.cpp IGTTrackingDevices/mitkSerialCommunication.cpp IGTTrackingDevices/mitkTrackingDevice.cpp IGTTrackingDevices/mitkTrackingTool.cpp IGTTrackingDevices/mitkTrackingVolume.cpp IGTTrackingDevices/mitkVirtualTrackingDevice.cpp IGTTrackingDevices/mitkVirtualTrackingTool.cpp IGTToolManagement/mitkNavigationToolStorage.cpp IGTToolManagement/mitkNavigationToolStorageSerializer.cpp IGTToolManagement/mitkNavigationToolStorageDeserializer.cpp IGTToolManagement/mitkNavigationTool.cpp IGTToolManagement/mitkNavigationToolReader.cpp IGTToolManagement/mitkNavigationToolWriter.cpp ) IF(MITK_USE_MICRON_TRACKER) SET(CPP_FILES ${CPP_FILES} IGTTrackingDevices/mitkClaronInterface.cpp) ELSE() SET(CPP_FILES ${CPP_FILES} IGTTrackingDevices/mitkClaronInterfaceStub.cpp) ENDIF(MITK_USE_MICRON_TRACKER) IF(MITK_USE_MICROBIRD_TRACKER) SET(CPP_FILES ${CPP_FILES} IGTTrackingDevices/mitkMicroBirdTrackingDevice.cpp) ENDIF(MITK_USE_MICROBIRD_TRACKER) IF(WIN32) SET(CPP_FILES ${CPP_FILES} IGTFilters/mitkWindowsRealTimeClock.cpp) ELSE() SET(CPP_FILES ${CPP_FILES} IGTFilters/mitkLinuxRealTimeClock.cpp) ENDIF(WIN32) \ No newline at end of file diff --git a/Modules/IGTUI/Qmitk/QmitkIGTPlayerWidget.cpp b/Modules/IGTUI/Qmitk/QmitkIGTPlayerWidget.cpp index 3b5e69c077..d511b02490 100644 --- a/Modules/IGTUI/Qmitk/QmitkIGTPlayerWidget.cpp +++ b/Modules/IGTUI/Qmitk/QmitkIGTPlayerWidget.cpp @@ -1,327 +1,387 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2009-05-12 19:14:45 +0200 (Di, 12 Mai 2009) $ Version: $Revision: 1.12 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "QmitkIGTPlayerWidget.h" //mitk headers #include "mitkTrackingTypes.h" #include #include #include #include #include #include #include - - //qt headers #include #include #include QmitkIGTPlayerWidget::QmitkIGTPlayerWidget(QWidget* parent, Qt::WindowFlags f) : QWidget(parent, f), m_Player(NULL), m_StartTime(-1.0) { m_Controls = NULL; CreateQtPartControl(this); CreateConnections(); - this->ResetLCDNumbers(); + + this->ResetLCDNumbers(); // reset lcd numbers at start } QmitkIGTPlayerWidget::~QmitkIGTPlayerWidget() { m_PlayingTimer->stop(); m_Player = NULL; m_PlayingTimer = NULL; } void QmitkIGTPlayerWidget::CreateQtPartControl(QWidget *parent) { if (!m_Controls) { // create GUI widgets m_Controls = new Ui::QmitkIGTPlayerWidgetControls; m_Controls->setupUi(parent); m_PlayingTimer = new QTimer(this); // initialize update timer - } + + } } void QmitkIGTPlayerWidget::CreateConnections() { if ( m_Controls ) { - connect( (QObject*)(m_Controls->m_pbLoadDir), SIGNAL(clicked()), this, SLOT(OnSelectPressed()) ); // open file dialog - connect( (QObject*)(m_Controls->m_leInputFile), SIGNAL(editingFinished()), this, SLOT(UpdateInputFileName()) ); // for manual file name input - - connect( (QObject*) (m_Controls->m_cbPointSetMode), SIGNAL(clicked(bool)), this, SLOT(OnChangeWidgetView(bool)) ); // widget view switcher - - connect( (QObject*)(m_Controls->m_pbPlay), SIGNAL(clicked(bool)), this, SLOT(OnPlayButtonClicked(bool)) ); // play button + connect( (QObject*)(m_Controls->selectPushButton), SIGNAL(clicked()), this, SLOT(OnSelectPressed()) ); // open file dialog + connect( (QObject*)(m_Controls->playPushButton), SIGNAL(clicked(bool)), this, SLOT(OnPlayButtonClicked(bool)) ); // play button connect( (QObject*)(m_PlayingTimer), SIGNAL(timeout()), this, SLOT(OnPlaying()) ); // update timer - - connect( (QObject*) (m_Controls->m_pbBegin), SIGNAL(clicked()), this, SLOT(OnGoToBegin()) ); // reset player and go to begin - connect( (QObject*) (m_Controls->m_pbEnd), SIGNAL(clicked()), this, SLOT(OnGoToEnd()) ); // reset player + connect( (QObject*) (m_Controls->beginPushButton), SIGNAL(clicked()), this, SLOT(OnGoToBegin()) ); // reset player and go to begin + connect( (QObject*) (m_Controls->stopPushButton), SIGNAL(clicked()), this, SLOT(OnGoToEnd()) ); // reset player + // pass this widgets protected combobox signal to public signal + connect( (QObject*) (m_Controls->trajectorySelectComboBox), SIGNAL(currentIndexChanged(int)), this, SIGNAL(SignalCurrentTrajectoryChanged(int)) ); + // pass this widgets protected checkbox signal to public signal + connect( m_Controls->splineModeCheckBox, SIGNAL(toggled(bool)), this, SIGNAL(SignalSplineModeToggled(bool)) ); } } +bool QmitkIGTPlayerWidget::IsTrajectoryInSplineMode() +{ + return m_Controls->splineModeCheckBox->isChecked(); +} + + bool QmitkIGTPlayerWidget::CheckInputFileValid() { QFile file(m_CmpFilename); - if(!file.exists()) + // check if file exists + if(!file.exists()) { QMessageBox::warning(NULL, "IGTPlayer: Error", "No valid input file was loaded. Please load input file first!"); return false; } return true; } +unsigned int QmitkIGTPlayerWidget::GetNumberOfTools() +{ + unsigned int result = 0; + + // at the moment this works only if player is initialized + if(m_Player.IsNotNull()) + result = m_Player->GetNumberOfOutputs(); + + return result; +} + + void QmitkIGTPlayerWidget::SetUpdateRate(unsigned int msecs) { - m_PlayingTimer->setInterval((int) msecs); + m_PlayingTimer->setInterval((int) msecs); // set update timer update rate } void QmitkIGTPlayerWidget::OnPlayButtonClicked(bool checked) { if(CheckInputFileValid()) // no playing possible without valid input file { if(checked) // play { if(m_Player.IsNull()) // start play { m_Player = mitk::NavigationDataPlayer::New(); m_Player->SetFileName(m_CmpFilename.toStdString()); m_Player->StartPlaying(); m_PlayingTimer->start(100); - emit PlayingStarted(); + emit SignalPlayingStarted(); } else // resume play { m_Player->Resume(); m_PlayingTimer->start(100); - emit PlayingResumed(); + emit SignalPlayingResumed(); } } else // pause { m_Player->Pause(); m_PlayingTimer->stop(); - emit PlayingPaused(); + emit SignalPlayingPaused(); } } else - m_Controls->m_pbPlay->setChecked(false); // uncheck play button if file unvalid + m_Controls->playPushButton->setChecked(false); // uncheck play button if file unvalid } QTimer* QmitkIGTPlayerWidget::GetPlayingTimer() { return m_PlayingTimer; } void QmitkIGTPlayerWidget::OnStopPlaying() { this->StopPlaying(); } void QmitkIGTPlayerWidget::StopPlaying() { m_PlayingTimer->stop(); - emit PlayingStopped(); + emit SignalPlayingStopped(); if(m_Player.IsNotNull()) m_Player->StopPlaying(); m_Player = NULL; m_StartTime = -1; // set starttime back - - m_Controls->m_pbPlay->setChecked(false); // set play button unchecked + this->ResetLCDNumbers(); + m_Controls->playPushButton->setChecked(false); // set play button unchecked } void QmitkIGTPlayerWidget::OnPlaying() { if(m_Player.IsNull()) return; if(m_StartTime < 0) m_StartTime = m_Player->GetOutput()->GetTimeStamp(); // get playback start time if(!m_Player->IsAtEnd()) { m_Player->Update(); // update player int msc = (int) (m_Player->GetOutput()->GetTimeStamp() - m_StartTime); // calculation for playing time display int ms = msc % 1000; msc = (msc - ms) / 1000; int s = msc % 60; int min = (msc-s) / 60; // set lcd numbers - m_Controls->m_lcdNrMsec->display(ms); - m_Controls->m_lcdNrSec->display(s); - m_Controls->m_lcdNrMin->display(min); + m_Controls->msecLCDNumber->display(ms); + m_Controls->secLCDNumber->display(s); + m_Controls->minLCDNumber->display(min); - emit PlayerUpdated(); // player successfully updated + emit SignalPlayerUpdated(); // player successfully updated } else this->StopPlaying(); // if player is at EOF } const std::vector QmitkIGTPlayerWidget::GetNavigationDatas() { std::vector navDatas; if(m_Player.IsNotNull()) { for(unsigned int i=0; i < m_Player->GetNumberOfOutputs(); ++i) { - navDatas.push_back(m_Player->GetOutput(i)); + navDatas.push_back(m_Player->GetOutput(i)); // push back current navigation data for each tool } - } - + } + return navDatas; } +const mitk::PointSet::Pointer QmitkIGTPlayerWidget::GetNavigationDatasPointSet() +{ + mitk::PointSet::Pointer result = mitk::PointSet::New(); + + mitk::PointSet::PointType pointType; + + if(m_Player.IsNotNull()) + { + for(unsigned int i=0; i < m_Player->GetNumberOfOutputs(); ++i) + { + mitk::NavigationData::PositionType position = m_Player->GetOutput(i)->GetPosition(); + + pointType[0] = position[0]; + pointType[1] = position[1]; + pointType[2] = position[2]; + + result->InsertPoint(i,pointType); // insert current ND as Pointtype in PointSet for return + } + } -void QmitkIGTPlayerWidget::UpdateInputFileName() + return result; +} + +const mitk::PointSet::PointType QmitkIGTPlayerWidget::GetNavigationDataPoint(unsigned int index) { + if( index > this->GetNumberOfTools() || index < 0 ) + throw std::out_of_range("Tool Index out of range!"); + + mitk::PointSet::PointType result; + + if(m_Player.IsNotNull()) + { + // create return PointType from current ND for tool index + mitk::NavigationData::PositionType position = m_Player->GetOutput(index)->GetPosition(); + result[0] = position[0]; + result[1] = position[1]; + result[2] = position[2]; + } + + return result; +} + +void QmitkIGTPlayerWidget::SetInputFileName(const QString& inputFileName) +{ this->OnGoToEnd(); /// stops playing and resets lcd numbers QString oldName = m_CmpFilename; m_CmpFilename.clear(); - m_CmpFilename = m_Controls->m_leInputFile->text(); + m_CmpFilename = inputFileName; + QFile file(m_CmpFilename); if(m_CmpFilename.isEmpty() || !file.exists()) { QMessageBox::warning(NULL, "Warning", QString("Please enter valid path! Using previous path again.")); m_CmpFilename=oldName; - m_Controls->m_leInputFile->setText(m_CmpFilename); + m_Controls->inputFileLineEdit->setText(m_CmpFilename); } } void QmitkIGTPlayerWidget::SetPlayer( mitk::NavigationDataPlayer::Pointer player ) { if(player.IsNotNull()) m_Player = player; } void QmitkIGTPlayerWidget::OnSelectPressed() { - this->OnGoToEnd(); /// stops playing and resets lcd numbers - + QString oldName = m_CmpFilename; m_CmpFilename.clear(); m_CmpFilename = QFileDialog::getOpenFileName(this, "Load tracking data", QDir::currentPath(),"XML files (*.xml)"); if (m_CmpFilename.isEmpty())//if something went wrong or user pressed cancel in the save dialog - { m_CmpFilename=oldName; + else + { + this->OnGoToEnd(); /// stops playing and resets lcd numbers + emit SignalInputFileChanged(); } - m_Controls->m_leInputFile->setText(m_CmpFilename); + + m_Controls->inputFileLineEdit->setText(m_CmpFilename); } void QmitkIGTPlayerWidget::OnGoToEnd() { this->StopPlaying(); // reset lcd numbers this->ResetLCDNumbers(); } void QmitkIGTPlayerWidget::OnGoToBegin() { // stop player manual so no PlayingStopped() m_PlayingTimer->stop(); if(m_Player.IsNotNull()) m_Player->StopPlaying(); m_Player = NULL; // set player to NULL so it can be initialized again if playback is called afterwards m_StartTime = -1; // set starttime back //reset view elements - m_Controls->m_pbPlay->setChecked(false); + m_Controls->playPushButton->setChecked(false); this->ResetLCDNumbers(); } +void QmitkIGTPlayerWidget::ResetLCDNumbers() +{ + m_Controls->minLCDNumber->display(QString("00")); + m_Controls->secLCDNumber->display(QString("00")); + m_Controls->msecLCDNumber->display(QString("000")); +} -void QmitkIGTPlayerWidget::SetWidgetViewToNormalPlayback() -{ - m_Controls->m_lblResolution->setHidden(true); - m_Controls->m_sbResolution->setHidden(true); - m_Controls->m_hsPlaybackPosition->setHidden(true); - m_Controls->m_pbFrameBackward->setHidden(true); - m_Controls->m_pbFastBackward->setHidden(true); - m_Controls->m_pbFrameForward->setHidden(true); - m_Controls->m_pbFastForward->setHidden(true); - m_Controls->m_lblSample->setHidden(true); - m_Controls->m_lcdNrSample->setHidden(true); -} +void QmitkIGTPlayerWidget::SetTrajectoryNames(const QStringList toolNames) +{ + QComboBox* cBox = m_Controls->trajectorySelectComboBox; + + if(cBox->count() > 0) + this->ClearTrajectorySelectCombobox(); + + // before making changed to QComboBox it is recommended to disconnet it's SIGNALS and SLOTS + disconnect( (QObject*) (m_Controls->trajectorySelectComboBox), SIGNAL(currentIndexChanged(int)), this, SIGNAL(SignalCurrentTrajectoryChanged(int)) ); + if(!toolNames.isEmpty()) + m_Controls->trajectorySelectComboBox->insertItems(0, toolNames); // adding current tool names to combobox -void QmitkIGTPlayerWidget::SetWidgetViewToPointSetPlayback() -{ - m_Controls->m_lblResolution->setVisible(true); - m_Controls->m_sbResolution->setVisible(true); - m_Controls->m_hsPlaybackPosition->setHidden(false); - m_Controls->m_pbFrameBackward->setVisible(true); - m_Controls->m_pbFastBackward->setVisible(true); - m_Controls->m_pbFrameForward->setVisible(true); - m_Controls->m_pbFastForward->setVisible(true); - m_Controls->m_lblSample->setVisible(true); - m_Controls->m_lcdNrSample->setVisible(true); + // reconnect after performed changes + connect( (QObject*) (m_Controls->trajectorySelectComboBox), SIGNAL(currentIndexChanged(int)), this, SIGNAL(SignalCurrentTrajectoryChanged(int)) ); } -void QmitkIGTPlayerWidget::OnChangeWidgetView(bool pointSetPlaybackView) +int QmitkIGTPlayerWidget::GetResolution() { - if(pointSetPlaybackView) - this->SetWidgetViewToPointSetPlayback(); + return m_Controls->resolutionSpinBox->value(); +} - else - this->SetWidgetViewToNormalPlayback(); +void QmitkIGTPlayerWidget::ClearTrajectorySelectCombobox() +{ + // before making changed to QComboBox it is recommended to disconnet it's SIGNALS and SLOTS + disconnect( (QObject*) (m_Controls->trajectorySelectComboBox), SIGNAL(currentIndexChanged(int)), this, SIGNAL(SignalCurrentTrajectoryChanged(int)) ); + + m_Controls->trajectorySelectComboBox->clear(); + + // reconnect after performed changes + connect( (QObject*) (m_Controls->trajectorySelectComboBox), SIGNAL(currentIndexChanged(int)), this, SIGNAL(SignalCurrentTrajectoryChanged(int)) ); } -void QmitkIGTPlayerWidget::ResetLCDNumbers() -{ - m_Controls->m_lcdNrMin->display(QString("00")); - m_Controls->m_lcdNrSec->display(QString("00")); - m_Controls->m_lcdNrMsec->display(QString("000")); -} \ No newline at end of file diff --git a/Modules/IGTUI/Qmitk/QmitkIGTPlayerWidget.h b/Modules/IGTUI/Qmitk/QmitkIGTPlayerWidget.h index a39f01e5e6..932f125d7a 100644 --- a/Modules/IGTUI/Qmitk/QmitkIGTPlayerWidget.h +++ b/Modules/IGTUI/Qmitk/QmitkIGTPlayerWidget.h @@ -1,198 +1,235 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2009-05-12 19:14:45 +0200 (Di, 12 Mai 2009) $ Version: $Revision: 1.12 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef QmitkIGTPlayerWidget_H #define QmitkIGTPlayerWidget_H //QT headers #include //mitk headers #include "MitkIGTUIExports.h" #include "mitkNavigationTool.h" #include "mitkNavigationDataPlayer.h" #include +#include + //ui header #include "ui_QmitkIGTPlayerWidgetControls.h" /** Documentation: * \brief GUI to access the IGT Player. * User must specify the file name where the input xml-file is located. The NavigationDatas from the xml-file can be * played in normal mode or in PointSet mode. * * In normal mode the player updates the NavigationDatas every 100ms (can be changed in SetUpdateRate()) and returns * them when GetNavigationDatas() is called. * In PointSet mode the player generates a PointSet with all NavigationDatas from the xml-file. So the playback is * performed on this ND PointSet. * * \ingroup IGTUI */ class MitkIGTUI_EXPORT QmitkIGTPlayerWidget : public QWidget { Q_OBJECT public: static const std::string VIEW_ID; /*! \brief default constructor */ QmitkIGTPlayerWidget(QWidget* parent = 0, Qt::WindowFlags f = 0); /*! \brief default deconstructor */ ~QmitkIGTPlayerWidget(); /*! \brief Sets the player for this player widget */ void SetPlayer(mitk::NavigationDataPlayer::Pointer player); /*! \brief Returns the playing timer of this widget */ QTimer* GetPlayingTimer(); /*! \brief Returns the current playback NavigationDatas from the xml-file */ const std::vector GetNavigationDatas(); /*! - \brief Sets the widget's look for the normal playback - */ - void SetWidgetViewToNormalPlayback(); + \brief Returns a PointSet of the current NavigationDatas for all recorded tools. + */ + const mitk::PointSet::Pointer GetNavigationDatasPointSet(); /*! - \brief Sets the widget's look for the PointSet playback - */ - void SetWidgetViewToPointSetPlayback(); + \brief Returns a PointType of the current NavigationData for a specific tool with the given index. + */ + const mitk::PointSet::PointType GetNavigationDataPoint(unsigned int index); + /*! \brief Sets the update rate of this widget's playing timer */ void SetUpdateRate(unsigned int msecs); + /*! + \brief Returns the number of different tools from the current playing stream. + * + * Retuns 0 if playback file is invalid. + */ + unsigned int GetNumberOfTools(); + + /*! + \brief Stops the playback + */ + void StopPlaying(); + + /*! + \brief Sets the given tool names list to the trajectory select combobox. + */ + void SetTrajectoryNames(const QStringList toolNames); + + /*! + \brief Returns the current resolution value from the resolution spinbox. + */ + int GetResolution(); + + /*! + \brief Clears all items in the trajectory selection combobox. + */ + void ClearTrajectorySelectCombobox(); + + /*! + \brief Returns whether spline mode checkbox is selected. + */ + bool IsTrajectoryInSplineMode(); + + signals: /*! - \brief This signal is emitted when the player starts the playback + \brief This signal is emitted when the player starts the playback. */ - void PlayingStarted(); + void SignalPlayingStarted(); /*! - \brief This signal is emitted when the player resumes after a pause + \brief This signal is emitted when the player resumes after a pause. */ - void PlayingResumed(); + void SignalPlayingResumed(); /*! - \brief This signal is emitted when the player stops + \brief This signal is emitted when the player stops. */ - void PlayingStopped(); + void SignalPlayingStopped(); /*! - \brief This signal is emitted when the player is paused + \brief This signal is emitted when the player is paused. */ - void PlayingPaused(); + void SignalPlayingPaused(); /*! - \brief This signal is emitted when the player reaches the end of the playback + \brief This signal is emitted when the player reaches the end of the playback. */ - void PlayingEnded(); + void SignalPlayingEnded(); /*! - \brief This signal is emitted every time the player updated the NavigationDatas + \brief This signal is emitted every time the player updated the NavigationDatas. */ - void PlayerUpdated(); + void SignalPlayerUpdated(); + + /*! + \brief This signal is emitted if the input file for the replay was changed. + */ + void SignalInputFileChanged(); + + /*! + \brief This signal is emitted if the index of the current selected trajectory select combobox item changes. + */ + void SignalCurrentTrajectoryChanged(int index); + + /*! + \brief This signal is emitted if the spline mode checkbox is toggled or untoggled. + */ + void SignalSplineModeToggled(bool checked); + + protected slots: /*! \brief Starts or pauses the playback */ void OnPlayButtonClicked(bool toggled); /*! \brief Updates the playback data */ void OnPlaying(); /*! \brief Stops the playback */ void OnStopPlaying(); /*! \brief Updates the input filename */ - void UpdateInputFileName(); + void SetInputFileName(const QString& inputFileName); /*! \brief Opens file open dialog for searching the input file */ void OnSelectPressed(); /*! \brief Stops the playback */ void OnGoToEnd(); /*! \brief Stops the playback and resets the player to the beginning */ void OnGoToBegin(); - /*! - \brief Switches between the normal playback view and the PointSet playback view - */ - void OnChangeWidgetView(bool pointSetPlaybackView); - protected: /// \brief Creation of the connections virtual void CreateConnections(); virtual void CreateQtPartControl(QWidget *parent); - /*! - \brief Sets the filename of the input file - */ - void SetInputFileName(); - - /*! - \brief Stops the playback - */ - void StopPlaying(); - /*! \brief Checks if an imput file with the set filename exists */ bool CheckInputFileValid(); /*! \brief Sets all LCD numbers to 0 */ void ResetLCDNumbers(); Ui::QmitkIGTPlayerWidgetControls* m_Controls; mitk::NavigationDataPlayer::Pointer m_Player; ///< plays NDs from a XML file QString m_CmpFilename; ///< filename of the input file QTimer* m_PlayingTimer; ///< update timer mitk::NavigationData::TimeStampType m_StartTime; ///< start time of playback needed for time display - }; #endif \ No newline at end of file diff --git a/Modules/IGTUI/Qmitk/QmitkIGTPlayerWidgetControls.ui b/Modules/IGTUI/Qmitk/QmitkIGTPlayerWidgetControls.ui index e1bc8891bd..14d04a5314 100644 --- a/Modules/IGTUI/Qmitk/QmitkIGTPlayerWidgetControls.ui +++ b/Modules/IGTUI/Qmitk/QmitkIGTPlayerWidgetControls.ui @@ -1,456 +1,405 @@ QmitkIGTPlayerWidgetControls 0 0 398 689 Form - + Settings true false + + + 2 + 0 + + Input File - + + + + 8 + 0 + + 150 0 + + true + - + + + + 2 + 0 + + 90 16777215 50 false Select false - - - false + + + + 1 + 0 + - Playback in PointSet Mode + Trajectory - + + + + 7 + 0 + + + + + + Qt::Horizontal 40 20 - + + + + 2 + 0 + + Resolution 1 : - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - + + + + 1 + 0 + + 1 - 10 + 25 + + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + Qt::LeftToRight + + + Spline Trajectory - + Player true - + background-color: rgb(60, 60, 60); color: rgb(250, 250, 250); 3 QLCDNumber::Flat 0 min - + background-color: rgb(60, 60, 60); color: rgb(250, 250, 250); 2 QLCDNumber::Flat 0 sec - + background-color: rgb(60, 60, 60); color: rgb(250, 250, 250); 3 QLCDNumber::Flat 0 msec Qt::Horizontal 40 20 - + + + Qt::LeftToRight + - Sample + Sequential Mode + + + + - - - background-color: rgb(60, 60, 60); -color: rgb(250, 250, 250); + + + + 1 + 0 + - - 8 + + - - QLCDNumber::Flat + + + :/IGTUI/firstframe.png:/IGTUI/firstframe.png - - - - - - color: rgb(170, 0, 0); - - - 0 - - - 100 - - - 5 - - - Qt::Horizontal - - - false - - - false - - - QSlider::NoTicks - - - - - - - - - - - 0 - 0 - - - - - - - - :/IGTUI/firstframe.png:/IGTUI/firstframe.png - - - - - - - - 0 - 0 - - - - - - - - :/IGTUI/fastbackward.png:/IGTUI/fastbackward.png - - - - 20 - 16 - - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - - - - :/IGTUI/previousframe.png:/IGTUI/previousframe.png - - - - - - - + - - 0 + + 4 0 Play at normal speed :/IGTUI/play.png :/IGTUI/pause.png:/IGTUI/play.png 16 16 true false - - - - - - 0 - 0 - - - - - - - - :/IGTUI/nextframe.png:/IGTUI/nextframe.png - - - - - - - - 0 - 0 - - - - - - - - :/IGTUI/fastforward.png:/IGTUI/fastforward.png - - - - 20 - 16 - - - - - - - - - 0 - 0 - - - - - - - - :/IGTUI/stop.png:/IGTUI/stop.png - - - - + + + + 1 + 0 + + + + + + + + :/IGTUI/stop.png:/IGTUI/stop.png + + Qt::Vertical 20 40