00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "QmitkIGTRecorderView.h"
00018
00019
00020
00021 #include "QmitkStdMultiWidget.h"
00022
00023 #include "mitkCone.h"
00024 #include "mitkInternalTrackingTool.h"
00025 #include "mitkNDIPassiveTool.h"
00026 #include "mitkNDITrackingDevice.h"
00027 #include "mitkTrackingVolume.h"
00028
00029 #include "mitkProperties.h"
00030
00031 #include "QmitkNDIConfigurationWidget.h"
00032
00033 #include "mitkNodePredicateProperty.h"
00034 #include "mitkNodePredicateDataType.h"
00035 #include "mitkNodePredicateAnd.h"
00036 #include "mitkNodePredicateNot.h"
00037 #include "mitkGroupTagProperty.h"
00038
00039 #include <itksys/SystemTools.hxx>
00040
00041 #include <QPushButton>
00042 #include <QTextEdit>
00043 #include <QTimer>
00044 #include <QLabel>
00045 #include <QLineEdit>
00046 #include <QFileDialog>
00047 #include <QTime>
00048
00049 #include <vtkTextSource.h>
00050 #include <vtkAppendPolyData.h>
00051 #include <vtkSphereSource.h>
00052 #include <vtkAxes.h>
00053 #include <vtkTubeFilter.h>
00054 #include <vtkConeSource.h>
00055 #include <vtkCamera.h>
00056
00057 #include "mitkStatusBar.h"
00058
00059
00060 QmitkIGTRecorderView::QmitkIGTRecorderView(QObject * , const char * )
00061 : QmitkFunctionality()
00062 {
00063 m_Timer = new QTimer(this);
00064 m_RecordingTimer = new QTimer(this);
00065 m_PlayingTimer = new QTimer(this);
00066
00067
00068 m_Controls = NULL;
00069 }
00070
00071
00072 QmitkIGTRecorderView::~QmitkIGTRecorderView()
00073 {
00074 this->OnStopRecording();
00075 m_RecordingTimer->stop();
00076 m_PlayingTimer->stop();
00077 m_Recorder = NULL;
00078
00079 m_RecordingTimer = NULL;
00080 m_PlayingTimer = NULL;
00081 }
00082
00083 void QmitkIGTRecorderView::CreateQtPartControl(QWidget *parent)
00084 {
00085 if (!m_Controls)
00086 {
00087 m_Controls = new Ui::QmitkIGTRecorderControls;
00088 m_Controls->setupUi(parent);
00089 m_ConfigWidget = new QmitkNDIConfigurationWidget(parent);
00090 mitk::NodePredicateAnd::Pointer pred = mitk::NodePredicateAnd::New(
00091 mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("already Assigned")),
00092 mitk::NodePredicateDataType::New("Surface"));
00093 m_ConfigWidget->SetDataStorage(this->GetDefaultDataStorage());
00094 m_ConfigWidget->SetPredicate(pred.GetPointer());
00095 m_ConfigWidget->SetTagPropertyName("already Assigned");
00096 m_ConfigWidget->SetTagProperty(mitk::GroupTagProperty::New().GetPointer());
00097 m_ConfigWidget->SetToolTypes(QStringList() << "Instrument");
00098 m_Controls->m_DeviceConfigGroup->layout()->addWidget(m_ConfigWidget);
00099
00100
00101 this->CreateConnections();
00102 }
00103 }
00104
00105
00106 void QmitkIGTRecorderView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget)
00107 {
00108 m_MultiWidget = &stdMultiWidget;
00109 }
00110
00111
00112 void QmitkIGTRecorderView::StdMultiWidgetNotAvailable()
00113 {
00114 m_MultiWidget = NULL;
00115 }
00116
00117
00118 void QmitkIGTRecorderView::CreateConnections()
00119 {
00120 if ( m_Controls )
00121 {
00122 connect((QObject*)(m_Controls->m_StartRecording), SIGNAL(clicked()), (QObject*) this, SLOT(OnStartRecording()));
00123 connect((QObject*)(m_Controls->m_PauseRecording), SIGNAL(toggled (bool)), (QObject*) this, SLOT(OnPauseRecording(bool)));
00124 connect((QObject*)(m_Controls->m_StopRecording), SIGNAL(clicked()), (QObject*) this, SLOT(OnStopRecording()));
00125 connect((QObject*)(m_Controls->m_StartReplay), SIGNAL(clicked()), (QObject*) this, SLOT(OnStartReplaying()));
00126 connect((QObject*)(m_Controls->m_StopReplay), SIGNAL(clicked()), (QObject*) this, SLOT(OnStopReplaying()));
00127 connect((QObject*)(m_RecordingTimer), SIGNAL(timeout()), (QObject*) this, SLOT(RecordFrame()));
00128 connect((QObject*)(m_ConfigWidget), SIGNAL(Connected()), this, SLOT(OnConnect()));
00129 connect((QObject*)(m_ConfigWidget), SIGNAL(Disconnected()), this, SLOT(OnDisconnect()));
00130 }
00131 }
00132
00133
00134 void QmitkIGTRecorderView::OnStartRecording()
00135 {
00136 if (m_Source.IsNotNull())
00137 if (m_Source->IsTracking())
00138 return;
00139
00140 if ((m_ConfigWidget == NULL))
00141 return;
00142 mitk::TrackingDevice::Pointer tracker = m_ConfigWidget->GetTracker();
00143
00144 QString fileName = QFileDialog::getSaveFileName(NULL, tr("Save tracking data to"),"D:/home/jochen/Versuche/2010.01.25 EM Messungen in der Speiseröhre" , tr("MITK Navigation Data XML logfile(*.xml)"));
00145 if (fileName.isEmpty())
00146 return;
00147
00148
00149 if (this->GetDefaultDataStorage()->GetNamedNode("Tracking Volume") == NULL)
00150 {
00151 mitk::TrackingVolume::Pointer tv = mitk::TrackingVolume::New();
00152 tv->SetTrackingDeviceType(tracker->GetType());
00153 mitk::DataNode::Pointer n = mitk::DataNode::New();
00154 n->SetData(tv);
00155 n->SetName("Tracking Volume");
00156 n->SetOpacity(0.1);
00157 n->SetColor(0.4, 0.4, 1.0);
00158 this->GetDefaultDataStorage()->Add(n);
00159 this->GetActiveStdMultiWidget()->SetWidgetPlanesVisibility(false);
00160 mitk::RenderingManager::GetInstance()->InitializeViews(this->GetDefaultDataStorage()->ComputeBoundingGeometry3D(this->GetDefaultDataStorage()->GetAll()));
00161 }
00162 try
00163 {
00164 this->SetupIGTPipeline(tracker, fileName);
00165
00166 m_Source->StartTracking();
00167 m_RecordingTimer->start(50);
00168 }
00169 catch (std::exception& e)
00170 {
00171 mitk::StatusBar::GetInstance()->DisplayText(QString("Error during navigation pipeline setup: %1").arg(e.what()).toLatin1(), 4000);
00172 m_RecordingTimer->stop();
00173 }
00174 }
00175
00176
00177 void QmitkIGTRecorderView::OnStopRecording()
00178 {
00179 if (m_RecordingTimer != NULL)
00180 m_RecordingTimer->stop();
00181 if (m_Recorder.IsNotNull())
00182 m_Recorder->StopRecording();
00183 if (m_Source.IsNotNull())
00184 {
00185 m_Source->StopTracking();
00186
00187 }
00188 m_MessageFilter = NULL;
00189 m_PointSetFilter = NULL;
00190 m_Recorder = NULL;
00191 m_Visualizer = NULL;
00192
00193 }
00194
00195
00196 void QmitkIGTRecorderView::OnPauseRecording( bool pause )
00197 {
00198 if (pause == true)
00199 m_RecordingTimer->stop();
00200 else
00201 m_RecordingTimer->start(50);
00202 }
00203
00204
00205 void QmitkIGTRecorderView::RecordFrame()
00206 {
00207
00208 try
00209 {
00210 bool updated = false;
00211 if ((m_Controls->m_UpdateTrajectory->checkState() == Qt::Checked) && (m_PointSetFilter.IsNotNull()))
00212 m_PointSetFilter->Update();
00213 else
00214 updated |= false;
00215 if ((m_Controls->m_UpdateRecorder->checkState() == Qt::Checked) && (m_Recorder.IsNotNull()))
00216 m_Recorder->Update();
00217 else
00218 updated |= false;
00219 if ((updated == false) && (m_Recorder.IsNotNull()))
00220 m_Visualizer->Update();
00221
00222 mitk::RenderingManager::GetInstance()->RequestUpdate(this->GetActiveStdMultiWidget()->GetRenderWindow4()->GetRenderWindow());
00223 }
00224 catch (...)
00225 {
00226 mitk::StatusBar::GetInstance()->DisplayText("Error during navigation pipeline update", 1000);
00227 }
00228 }
00229
00230
00231 void QmitkIGTRecorderView::OnStartReplaying()
00232 {
00233
00234 }
00235
00236
00237 void QmitkIGTRecorderView::OnStopReplaying()
00238 {
00239
00240 }
00241
00242
00243 void QmitkIGTRecorderView::SetupIGTPipeline(mitk::TrackingDevice::Pointer tracker, QString fileName)
00244 {
00245 mitk::DataStorage* ds = this->GetDefaultDataStorage();
00246 if (ds == NULL)
00247 throw std::invalid_argument("DataStorage not available");
00248 if (tracker.IsNull())
00249 throw std::invalid_argument("invalid tracking device provided.");
00250
00251
00252 if (m_ConfigWidget->GetToolsByToolType("Instrument").isEmpty())
00253 throw std::invalid_argument("insufficient tool assignments for instrument");
00254
00255
00256 if (m_Source.IsNull())
00257 {
00258 m_Source = mitk::TrackingDeviceSource::New();
00259 m_Source->SetTrackingDevice(tracker);
00260 }
00261 m_Visualizer = mitk::NavigationDataObjectVisualizationFilter::New();
00262 m_MessageFilter = mitk::NavigationDataToMessageFilter::New();
00263 m_PointSetFilter = mitk::NavigationDataToPointSetFilter::New();
00264 m_PointSetFilter->SetOperationMode(mitk::NavigationDataToPointSetFilter::Mode3D);
00265 m_Recorder = mitk::NavigationDataRecorder::New();
00266 m_Recorder->SetFileName(fileName.toLatin1());
00267
00268
00269 for (unsigned int i = 0; i < m_Source->GetNumberOfOutputs(); ++i)
00270 {
00271
00272 m_Visualizer->SetInput(i, m_Source->GetOutput(i));
00273
00274 m_MessageFilter->SetInput(i, m_Visualizer->GetOutput(i));
00275
00276 m_PointSetFilter->SetInput(i, m_MessageFilter->GetOutput(i));
00277 m_Recorder->AddNavigationData(m_MessageFilter->GetOutput(i));
00278 }
00279 m_Recorder->StartRecording();
00280
00281
00282 const QList<unsigned int> instruments = m_ConfigWidget->GetToolsByToolType("Instrument");
00283 foreach (const unsigned int& index, instruments)
00284 {
00285 mitk::DataNode::Pointer node = this->CreateInstrumentVisualization(m_Source->GetOutput(index)->GetName());
00286 ds->Add(node);
00287 m_Visualizer->SetRepresentationObject(index, node->GetData());
00288 }
00289 for (unsigned int i = 0; i < m_PointSetFilter->GetNumberOfOutputs(); i++)
00290 {
00291
00292 mitk::PointSet* p = m_PointSetFilter->GetOutput(i);
00293 assert(p);
00294
00295 mitk::DataNode::Pointer pointSetNode = mitk::DataNode::New();
00296 pointSetNode->SetData(p);
00297 pointSetNode->SetName(QString("Trajectory of Tool #%1 (%2)").arg(i).arg(QTime::currentTime().toString()).toLatin1());
00298 mitk::Color color;
00299 color.Set(0.2, 0.3 * i ,0.9 - 0.2 * i);
00300 pointSetNode->SetColor(color);
00301 pointSetNode->SetProperty("contourcolor", mitk::ColorProperty::New(color));
00302 pointSetNode->SetProperty("pointsize", mitk::FloatProperty::New(1.0));
00303 pointSetNode->SetProperty("contoursize", mitk::FloatProperty::New(0.5));
00304 pointSetNode->SetBoolProperty("show contour", true);
00305 pointSetNode->SetBoolProperty("updateDataOnRender", false);
00306 this->GetDefaultDataStorage()->Add(pointSetNode);
00307 }
00308 }
00309
00310 mitk::DataNode::Pointer QmitkIGTRecorderView::CreateInstrumentVisualization(const char* label)
00311 {
00312 vtkAxes* axes = vtkAxes::New();
00313 axes->SymmetricOn();
00314 axes->SetScaleFactor(10.0);
00315 vtkTubeFilter* tuber = vtkTubeFilter::New();
00316 tuber->SetRadius(0.02);
00317 tuber->SetNumberOfSides(6);
00318 tuber->SetInputConnection(axes->GetOutputPort());
00319 vtkTextSource* tss = vtkTextSource::New();
00320 tss->SetText(label);
00321 tss->BackingOff();
00322 vtkConeSource* cone = vtkConeSource::New();
00323 cone->SetDirection(0.0, 0.0, -1.0);
00324 cone->SetCenter(0.0, 0.0, 100.0);
00325 cone->SetHeight(200.0);
00326 cone->SetRadius(10.0);
00327 vtkAppendPolyData* ap = vtkAppendPolyData::New();
00328
00329 ap->AddInput(tuber->GetOutput());
00330
00331 ap->GetOutput()->Update();
00332 mitk::Surface::Pointer dummy = mitk::Surface::New();
00333 dummy->SetVtkPolyData(ap->GetOutput());
00334 ap->Delete();
00335 cone->Delete();
00336 tss->Delete();
00337 tuber->Delete();
00338 axes->Delete();
00339
00340 mitk::DataNode::Pointer node = mitk::DataNode::New();
00341 node->SetData(dummy);
00342 node->SetName(label);
00343 node->SetColor(0.2, 0.9, 0.2);
00344
00345 return node;
00346 }
00347
00348
00349 void QmitkIGTRecorderView::OnConnect()
00350 {
00351 m_Controls->m_StartRecording->setEnabled(true);
00352 m_Controls->m_StopRecording->setEnabled(true);
00353 m_Controls->m_PauseRecording->setEnabled(true);
00354
00355
00356
00357 }
00358
00359
00360 void QmitkIGTRecorderView::OnDisconnect()
00361 {
00362 this->OnStopRecording();
00363 m_Controls->m_StartRecording->setEnabled(false);
00364 m_Controls->m_StopRecording->setEnabled(false);
00365 m_Controls->m_PauseRecording->setEnabled(false);
00366 }