00001 /*========================================================================= 00002 00003 Program: Medical Imaging & Interaction Toolkit 00004 Language: C++ 00005 Date: $Date$ 00006 Version: $Revision$ 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 "QmitkRegisterClasses.h" 00019 #include "QmitkRenderWindow.h" 00020 #include "QmitkSliceWidget.h" 00021 00022 #include "mitkDataNodeFactory.h" 00023 #include "mitkProperties.h" 00024 #include "mitkRenderingManager.h" 00025 #include "mitkStandaloneDataStorage.h" 00026 00027 #include "mitkGlobalInteraction.h" 00028 #include "mitkPointSet.h" 00029 #include "mitkPointSetInteractor.h" 00030 00031 #include <itksys/SystemTools.hxx> 00032 #include <QApplication> 00033 #include <QHBoxLayout> 00034 00035 //##Documentation 00036 //## @brief Interactively add points 00037 //## 00038 //## As in Step4, load one or more data sets (many image, 00039 //## surface and other formats) and create 3 views on the data. 00040 //## Additionally, we want to interactively add points. A node containing 00041 //## a PointSet as data is added to the data tree and a PointSetInteractor 00042 //## is associated with the node, which handles the interaction. The 00043 //## @em interaction @em pattern is defined in a state-machine, stored in an 00044 //## external XML file. Thus, we need to load a state-machine 00045 //## The interaction patterns defines the @em events, 00046 //## on which the interactor reacts (e.g., which mouse buttons are used to 00047 //## set a point), the @em transition to the next state (e.g., the initial 00048 //## may be "empty point set") and associated @a actions (e.g., add a point 00049 //## at the position where the mouse-click occured). 00050 int main(int argc, char* argv[]) 00051 { 00052 QApplication qtapplication( argc, argv ); 00053 00054 if(argc<2) 00055 { 00056 fprintf( stderr, "Usage: %s [filename1] [filename2] ...\n\n", itksys::SystemTools::GetFilenameName(argv[0]).c_str() ); 00057 return 1; 00058 } 00059 00060 // Register Qmitk-dependent global instances 00061 QmitkRegisterClasses(); 00062 00063 //************************************************************************* 00064 // Part I: Basic initialization 00065 //************************************************************************* 00066 00067 // Create a DataStorage 00068 mitk::StandaloneDataStorage::Pointer ds = mitk::StandaloneDataStorage::New(); 00069 00070 //************************************************************************* 00071 // Part II: Create some data by reading files 00072 //************************************************************************* 00073 int i; 00074 for(i=1; i<argc; ++i) 00075 { 00076 // For testing 00077 if(strcmp(argv[i], "-testing")==0) continue; 00078 00079 // Create a DataNodeFactory to read a data format supported 00080 // by the DataNodeFactory (many image formats, surface formats, etc.) 00081 mitk::DataNodeFactory::Pointer nodeReader=mitk::DataNodeFactory::New(); 00082 const char * filename = argv[i]; 00083 try 00084 { 00085 nodeReader->SetFileName(filename); 00086 nodeReader->Update(); 00087 //********************************************************************* 00088 // Part III: Put the data into the datastorage 00089 //********************************************************************* 00090 00091 // Since the DataNodeFactory directly creates a node, 00092 // use the iterator to add the read node to the tree 00093 mitk::DataNode::Pointer node = nodeReader->GetOutput(); 00094 ds->Add(node); 00095 } 00096 catch(...) 00097 { 00098 fprintf( stderr, "Could not open file %s \n\n", filename ); 00099 exit(2); 00100 } 00101 } 00102 00103 // ******************************************************* 00104 // ****************** START OF NEW PART ****************** 00105 // ******************************************************* 00106 00107 //************************************************************************* 00108 // Part VI: For allowing to interactively add points ... 00109 //************************************************************************* 00110 00111 // Create PointSet and a node for it 00112 mitk::PointSet::Pointer pointSet = mitk::PointSet::New(); 00113 mitk::DataNode::Pointer pointSetNode = mitk::DataNode::New(); 00114 pointSetNode->SetData(pointSet); 00115 00116 // Add the node to the tree 00117 ds->Add(pointSetNode); 00118 00119 // Create PointSetInteractor, associate to pointSetNode and add as 00120 // interactor to GlobalInteraction 00121 mitk::GlobalInteraction::GetInstance()->AddInteractor( 00122 mitk::PointSetInteractor::New("pointsetinteractor", pointSetNode) 00123 ); 00124 00125 // ******************************************************* 00126 // ******************* END OF NEW PART ******************* 00127 // ******************************************************* 00128 00129 //************************************************************************* 00130 // Part V: Create windows and pass the tree to it 00131 //************************************************************************* 00132 00133 // Create toplevel widget with horizontal layout 00134 QWidget toplevelWidget; 00135 QHBoxLayout layout; 00136 layout.setSpacing(2); 00137 layout.setMargin(0); 00138 toplevelWidget.setLayout(&layout); 00139 00140 //************************************************************************* 00141 // Part Va: 3D view 00142 //************************************************************************* 00143 00144 // Create a renderwindow 00145 QmitkRenderWindow renderWindow(&toplevelWidget); 00146 layout.addWidget(&renderWindow); 00147 00148 // Tell the renderwindow which (part of) the tree to render 00149 renderWindow.GetRenderer()->SetDataStorage(ds); 00150 00151 // Use it as a 3D view 00152 renderWindow.GetRenderer()->SetMapperID(mitk::BaseRenderer::Standard3D); 00153 00154 //************************************************************************* 00155 // Part Vb: 2D view for slicing transversally 00156 //************************************************************************* 00157 00158 // Create QmitkSliceWidget, which is based on the class 00159 // QmitkRenderWindow, but additionally provides sliders 00160 QmitkSliceWidget view2(&toplevelWidget); 00161 layout.addWidget(&view2); 00162 00163 // Tell the QmitkSliceWidget which (part of) the tree to render. 00164 // By default, it slices the data transversally 00165 view2.SetDataStorage(ds); 00166 mitk::DataStorage::SetOfObjects::ConstPointer rs = ds->GetAll(); 00167 view2.SetData(rs->Begin(), mitk::SliceNavigationController::Transversal); 00168 // We want to see the position of the slice in 2D and the 00169 // slice itself in 3D: add it to the tree! 00170 ds->Add(view2.GetRenderer()->GetCurrentWorldGeometry2DNode()); 00171 00172 //************************************************************************* 00173 // Part Vc: 2D view for slicing sagitally 00174 //************************************************************************* 00175 00176 // Create QmitkSliceWidget, which is based on the class 00177 // QmitkRenderWindow, but additionally provides sliders 00178 QmitkSliceWidget view3(&toplevelWidget); 00179 layout.addWidget(&view3); 00180 00181 // Tell the QmitkSliceWidget which (part of) the tree to render 00182 // and to slice sagitall 00183 view3.SetDataStorage(ds); 00184 view3.SetData(rs->Begin(), mitk::SliceNavigationController::Sagittal); 00185 00186 // We want to see the position of the slice in 2D and the 00187 // slice itself in 3D: add it to the tree! 00188 ds->Add(view3.GetRenderer()->GetCurrentWorldGeometry2DNode()); 00189 00190 //************************************************************************* 00191 //Part VII: Qt-specific initialization 00192 //************************************************************************* 00193 toplevelWidget.show(); 00194 00195 // For testing 00196 #include "QtTesting.h" 00197 if(strcmp(argv[argc-1], "-testing")!=0) 00198 return qtapplication.exec(); 00199 else 00200 return QtTesting(); 00201 }