00001 /*========================================================================= 00002 00003 Program: Medical Imaging & Interaction Toolkit 00004 Language: C++ 00005 Date: $Date: 2009-03-21 19:27:37 +0100 (Sa, 21 Mrz 2009) $ 00006 Version: $Revision: 16719 $ 00007 00008 Copyright (c) German Cancer Research Center, Division of Medical and 00009 Biological Informatics. All rights reserved. 00010 See MITKCopyright.txt or https://www.mitk.org/copyright.html for details. 00011 00012 This software is distributed WITHOUT ANY WARRANTY; without even 00013 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 00014 PURPOSE. See the above copyright notices for more information. 00015 00016 =========================================================================*/ 00017 00018 #include "QmitkImageGuidedTherapyTutorialView.h" 00019 00020 #include "QmitkStdMultiWidget.h" 00021 #include "QmitkStdMultiWidgetEditor.h" 00022 00023 #include "mitkNDIPassiveTool.h" 00024 #include "mitkNDITrackingDevice.h" 00025 #include "mitkVirtualTrackingDevice.h" 00026 #include "mitkStandardFileLocations.h" 00027 #include "mitkSerialCommunication.h" 00028 #include "mitkCone.h" 00029 00030 #include <QTimer> 00031 #include <QMessageBox> 00032 00033 00034 const std::string QmitkImageGuidedTherapyTutorialView::VIEW_ID = "org.mitk.views.imageguidedtherapytutorial"; 00035 00036 QmitkImageGuidedTherapyTutorialView::QmitkImageGuidedTherapyTutorialView() 00037 : QmitkFunctionality(), 00038 m_Controls(NULL), m_MultiWidget(NULL), m_Source(NULL), m_Visualizer(NULL), m_Timer(NULL) 00039 { 00040 } 00041 00042 00043 QmitkImageGuidedTherapyTutorialView::~QmitkImageGuidedTherapyTutorialView() 00044 { 00045 } 00046 00047 00048 void QmitkImageGuidedTherapyTutorialView::CreateQtPartControl(QWidget *parent) 00049 { 00050 if (!m_Controls) 00051 { 00052 // create GUI widget 00053 m_Controls = new Ui::QmitkImageGuidedTherapyTutorialViewControls; 00054 m_Controls->setupUi(parent); 00055 this->CreateConnections(); 00056 } 00057 } 00058 00059 00060 void QmitkImageGuidedTherapyTutorialView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) 00061 { 00062 m_MultiWidget = &stdMultiWidget; 00063 } 00064 00065 00066 void QmitkImageGuidedTherapyTutorialView::StdMultiWidgetNotAvailable() 00067 { 00068 m_MultiWidget = NULL; 00069 } 00070 00071 00072 void QmitkImageGuidedTherapyTutorialView::CreateConnections() 00073 { 00074 if ( m_Controls ) 00075 { 00076 connect( (QObject*)(m_Controls->m_StartButton), SIGNAL(clicked()),(QObject*) this, SLOT(OnStartIGT())); 00077 connect( (QObject*)(m_Controls->m_StopButton), SIGNAL(clicked()),(QObject*) this, SLOT(OnStopIGT())); 00078 } 00079 } 00080 00081 00082 void QmitkImageGuidedTherapyTutorialView::Activated() 00083 { 00084 QmitkFunctionality::Activated(); 00085 } 00086 00087 00088 void QmitkImageGuidedTherapyTutorialView::Deactivated() 00089 { 00090 QmitkFunctionality::Deactivated(); 00091 } 00092 00093 00094 void QmitkImageGuidedTherapyTutorialView::OnStartIGT() 00095 { 00096 //This method is called when when the Do IGT button is pressed. Any kind of navigation application will 00097 //start with the connection to a tracking system and as we do image guided procedures we want to show 00098 //something on the screen. In this tutorial we connect to the NDI Polaris tracking system and we will 00099 //show the movement of a tool as cone in MITK. 00100 00101 //Check if we have a widget for visualization. Makes no sense to start otherwise. 00102 //If there is no multiwidget, create one. 00103 //if (m_MultiWidget == NULL) 00104 //{ 00105 //} 00106 if (m_MultiWidget == NULL) // if creating the multiwidget failed, stop here. 00107 { 00108 QMessageBox::warning ( NULL, "Error", "Starting the tutorial is not possible without an initialized " 00109 "rendering widget. Please load a dataset first."); 00110 return; 00111 } 00112 00113 try 00114 { 00115 /**************** Variant 1: Use a NDI Polaris Tracking Device ****************/ 00118 //mitk::NDITrackingDevice::Pointer tracker = mitk::NDITrackingDevice::New(); //instantiate 00119 //tracker->SetPortNumber(mitk::SerialCommunication::COM4); //set the comport 00120 //tracker->SetBaudRate(mitk::SerialCommunication::BaudRate115200); //set the baud rate 00121 //tracker->SetType(mitk::NDIPolaris); //set the type there you can choose between Polaris and Aurora 00122 00126 //mitk::NDIPassiveTool::Pointer tool = mitk::NDIPassiveTool::New(); 00127 //tool->SetToolName("MyInstrument"); //Every tool should have a name. 00128 //tool->LoadSROMFile("c:\\myinstrument.rom"); //The Polaris system needs a ".rom" file which describes 00132 00134 //tracker->Add6DTool(tool); //Add the tool to the TrackingDevice object. 00135 /**************** End of Variant 1 ****************/ 00136 00137 /**************** Variant 2: Emulate a Tracking Device with mitk::VirtualTrackingDevice ****************/ 00138 // For tests, it is useful to simulate a tracking device in software. This is what mitk::VirtualTrackingDevice does. 00139 // It will produce random position, orientation and error values for each tool that is added. 00140 mitk::VirtualTrackingDevice::Pointer tracker = mitk::VirtualTrackingDevice::New(); // create virtual tracker 00141 mitk::ScalarType bounds[] = {0.0, 200.0, 0.0, 200.0, 0.0, 200.0}; 00142 tracker->SetBounds(bounds); 00143 tracker->AddTool("MyInstrument"); // add a tool to tracker 00144 /**************** End of Variant 2 ****************/ 00145 00146 //The tracking device object is used for the physical connection to the device. To use the 00147 //data inside of our tracking pipeline we need a source. This source encapsulate the tracking device 00148 //and provides objects of the type mitk::NavigationData as output. The NavigationData objects stores 00149 //position, orientation, if the data is valid or not and special error informations in a covariance 00150 //matrix. 00151 // 00152 //Typically the start of a pipeline is a TrackingDeviceSource. To work correct we have to set a 00153 //TrackingDevice object. Attention you have to set the tools before you set the whole TrackingDevice 00154 //object to the TrackingDeviceSource because the source need to know how many outputs should be 00155 //generated. 00156 m_Source = mitk::TrackingDeviceSource::New(); //We need the filter objects to stay alive, 00157 //therefore they must be members. 00158 m_Source->SetTrackingDevice(tracker); //Here we set the tracking device to the source of the pipeline. 00159 m_Source->Connect(); //Now we connect to the tracking system. 00160 //Note we do not call this on the TrackingDevice object 00161 00162 00163 //As we wish to visualize our tool we need to have a PolyData which shows us the movement of our tool. 00164 //Here we take a cone shaped PolyData. In MITK you have to add the PolyData as a node into the DataStorage 00165 //to show it inside of the rendering windows. After that you can change the properties of the cone 00166 //to manipulate rendering, e.g. the position and orientation as in our case. 00167 mitk::Cone::Pointer cone = mitk::Cone::New(); //instantiate a new cone 00168 float scale[] = {10.0, 10.0, 10.0}; 00169 cone->GetGeometry()->SetSpacing(scale); //scale it a little that so we can see something 00170 mitk::DataNode::Pointer node = mitk::DataNode::New(); //generate a new node to store the cone into 00171 //the DataStorage. 00172 node->SetData(cone); //The data of that node is our cone. 00173 node->SetName("My tracked object"); //The node has additional properties like a name 00174 node->SetColor(1.0, 0.0, 0.0); //or the color. Here we make it red. 00175 this->GetDefaultDataStorage()->Add(node); //After adding the Node with the cone in it to the 00176 //DataStorage, MITK will show the cone in the 00177 //render windows. 00178 00179 //For updating the render windows we use another filter of the MITK-IGT pipeline concept. The 00180 //NavigationDataObjectVisualizationFilter needs as input a NavigationData and a 00181 //PolyData. In our case the input is the source and the PolyData our cone. 00182 00183 //First we create a new filter for the visualization update. 00184 m_Visualizer = mitk::NavigationDataObjectVisualizationFilter::New(); 00185 m_Visualizer->SetInput(0, m_Source->GetOutput(0)); //Then we connect to the pipeline. 00186 m_Visualizer->SetRepresentationObject(0, cone); //After that we have to assign the cone to the input 00187 00188 //Now this simple pipeline is ready, so we can start the tracking. Here again: We do not call the 00189 //StartTracking method from the tracker object itself. Instead we call this method from our source. 00190 m_Source->StartTracking(); 00191 00192 //Now every call of m_Visualizer->Update() will show us the cone at the position and orientation 00193 //given from the tracking device. 00194 //We use a QTimer object to call this Update() method in a fixed interval. 00195 if (m_Timer == NULL) 00196 { 00197 m_Timer = new QTimer(this); //create a new timer 00198 } 00199 connect(m_Timer, SIGNAL(timeout()), this, SLOT(OnTimer())); //connect the timer to the method OnTimer() 00200 00201 m_Timer->start(100); //Every 100ms the method OnTimer() is called. -> 10fps 00202 //Now have look at the OnTimer() method. 00203 } 00204 catch (std::exception& e) 00205 { 00206 // add cleanup 00207 std::cout << "Error in QmitkIGTTutorial::OnDoIGT():" << e.what() << std::endl; 00208 } 00209 } 00210 00211 00212 void QmitkImageGuidedTherapyTutorialView::OnTimer() 00213 { 00214 //Here we call the Update() method from the Visualization Filter. Internally the filter checks if 00215 //new NavigationData is available. If we have a new NavigationData the cone position and orientation 00216 //will be adapted. 00217 m_Visualizer->Update(); 00218 mitk::RenderingManager::GetInstance()->RequestUpdateAll(); //update the render windows 00219 } 00220 00221 00222 void QmitkImageGuidedTherapyTutorialView::OnStopIGT() 00223 { 00224 //This method is called when the Stop button is pressed. Here we disconnect the pipeline. 00225 if (m_Timer == NULL) 00226 { 00227 std::cout << "No Timer was set yet!" << std::endl; 00228 return; 00229 } 00230 //To disconnect the pipeline in a save way we first stop the timer than we disconnect the tracking device. 00231 //After that we destroy all filters with changing them to NULL. 00232 m_Timer->stop(); 00233 disconnect(m_Timer, SIGNAL(timeout()), this, SLOT(OnTimer())); 00234 m_Timer = NULL; 00235 m_Source->StopTracking(); 00236 m_Source->Disconnect(); 00237 m_Source = NULL; 00238 m_Visualizer = NULL; 00239 m_Source = NULL; 00240 this->GetDefaultDataStorage()->Remove(this->GetDefaultDataStorage()->GetNamedNode("My tracked object")); 00241 }