diff --git a/Applications/CMakeLists.txt b/Applications/CMakeLists.txt index 5817ec8b58..bebe1f297b 100644 --- a/Applications/CMakeLists.txt +++ b/Applications/CMakeLists.txt @@ -1,13 +1,13 @@ IF(MITK_USE_QT AND QT4_FOUND) IF(MITK_USE_OPENCHERRY) ADD_SUBDIRECTORY(CoreApp) ADD_SUBDIRECTORY(ExtApp) ENDIF() - OPTION(MITK_BUILD_TUTORIAL "Build the MITK tutorial" OFF) + OPTION(MITK_BUILD_TUTORIAL "Build the MITK tutorial" ON) IF(MITK_BUILD_TUTORIAL) ADD_SUBDIRECTORY(Tutorial) ENDIF() ENDIF() diff --git a/Applications/Tutorial/CMakeLists.txt b/Applications/Tutorial/CMakeLists.txt index 9da3674012..2158ed224f 100644 --- a/Applications/Tutorial/CMakeLists.txt +++ b/Applications/Tutorial/CMakeLists.txt @@ -1,25 +1,26 @@ -INCLUDE_DIRECTORIES(${Q${KITNAME}_INCLUDE_DIRS}) -INCLUDE(${QT_USE_FILE}) +MITK_USE_MODULE(QmitkExt) + +INCLUDE_DIRECTORIES(${ALL_INCLUDE_DIRECTORIES}) -INCLUDE_DIRECTORIES(.) # initialize only the source lists which need additional files # Step6 is reused in Step7 and Step8. Step6.cpp has to be added # explicitly since it is not a member of ${STEP6_CPP} at this point SET(STEP6_CPP Step6RegionGrowing1.cpp Step6RegionGrowing2.cpp Step6main.cpp) SET(STEP7_CPP Step6RegionGrowing1.cpp Step6RegionGrowing2.cpp Step6.cpp Step7main.cpp) SET(STEP8_CPP Step6RegionGrowing1.cpp Step6RegionGrowing2.cpp Step6.cpp Step8main.cpp) # some files need Qt wrapping QT4_WRAP_CPP(STEP6_CPP Step6.h) QT4_WRAP_CPP(STEP7_CPP Step6.h Step7.h) QT4_WRAP_CPP(STEP8_CPP Step6.h Step8.h) # for the others it's all the same -FOREACH(stepNo RANGE 1 3) # exclude steps 4 to 8 for now +FOREACH(stepNo RANGE 1 8) SET(STEP${stepNo}_CPP ${STEP${stepNo}_CPP} Step${stepNo}.cpp QtTesting.cpp) ADD_EXECUTABLE(Step${stepNo} ${STEP${stepNo}_CPP}) - TARGET_LINK_LIBRARIES(Step${stepNo} Qmitk ${QT_LIBRARIES}) + TARGET_LINK_LIBRARIES(Step${stepNo} ${ALL_LIBRARIES}) + ENDFOREACH(stepNo) diff --git a/Applications/Tutorial/Step4.cpp b/Applications/Tutorial/Step4.cpp index 83d61bcff9..49ccd972b5 100644 --- a/Applications/Tutorial/Step4.cpp +++ b/Applications/Tutorial/Step4.cpp @@ -1,162 +1,165 @@ #include "QmitkRegisterClasses.h" #include "QmitkRenderWindow.h" #include "QmitkSliceWidget.h" #include "mitkDataTreeNodeFactory.h" #include "mitkProperties.h" #include "mitkRenderingManager.h" -#include "mitkDataStorage.h" +#include "mitkStandaloneDataStorage.h" #include #include #include //##Documentation //## @brief Use several views to explore data //## //## As in Step2 and Step3, load one or more data sets (many image, //## surface and other formats), but create 3 views on the data. //## The QmitkRenderWindow is used for displaying a 3D view as in Step3, //## but without volume-rendering. //## Furthermore, we create two 2D views for slicing through the data. //## We use the class QmitkSliceWidget, which is based on the class //## QmitkRenderWindow, but additionally provides sliders //## to slice through the data. We create two instances of //## QmitkSliceWidget, one for transversal and one for sagittal slicing. //## The two slices are also shown at their correct position in 3D as //## well as intersection-line, each in the other 2D view. int main(int argc, char* argv[]) { QApplication qtapplication( argc, argv ); if(argc<2) { fprintf( stderr, "Usage: %s [filename1] [filename2] ...\n\n", itksys::SystemTools::GetFilenameName(argv[0]).c_str() ); return 1; } // Register Qmitk-dependent global instances QmitkRegisterClasses(); //************************************************************************* // Part I: Basic initialization //************************************************************************* - // Create a DataStorage + // Create a DataStorage mitk::StandaloneDataStorage::Pointer ds = mitk::StandaloneDataStorage::New(); //************************************************************************* // Part II: Create some data by reading files //************************************************************************* int i; for(i=1; iSetFileName(filename); nodeReader->Update(); //********************************************************************* //Part III: Put the data into the datastorage //********************************************************************* // Since the DataTreeNodeFactory directly creates a node, // use the datastorage to add the read node mitk::DataTreeNode::Pointer node = nodeReader->GetOutput(); ds->Add(node); } catch(...) { fprintf( stderr, "Could not open file %s \n\n", filename ); exit(2); } } //************************************************************************* // Part IV: Create windows and pass the tree to it //************************************************************************* // Create toplevel widget with horizontal layout QWidget toplevelWidget; QHBoxLayout layout; layout.setSpacing(2); layout.setMargin(0); toplevelWidget.setLayout(&layout); //************************************************************************* // Part IVa: 3D view //************************************************************************* // Create a renderwindow QmitkRenderWindow renderWindow(&toplevelWidget); layout.addWidget(&renderWindow); // Tell the renderwindow which (part of) the datastorage to render renderWindow.GetRenderer()->SetDataStorage(ds); // Use it as a 3D view renderWindow.GetRenderer()->SetMapperID(mitk::BaseRenderer::Standard3D); // ******************************************************* // ****************** START OF NEW PART ****************** // ******************************************************* //************************************************************************* // Part IVb: 2D view for slicing transversally //************************************************************************* // Create QmitkSliceWidget, which is based on the class // QmitkRenderWindow, but additionally provides sliders QmitkSliceWidget view2(&toplevelWidget); layout.addWidget(&view2); + view2.SetLevelWindowEnabled(true); // Tell the QmitkSliceWidget which (part of) the tree to render. // By default, it slices the data transversally - view2.SetData(&it); + view2.SetDataStorage(ds); + mitk::DataStorage::SetOfObjects::ConstPointer rs = ds->GetAll(); + view2.SetData(rs->Begin(),mitk::SliceNavigationController::Transversal); // We want to see the position of the slice in 2D and the // slice itself in 3D: add it to the datastorage! ds->Add(view2.GetRenderer()->GetCurrentWorldGeometry2DNode()); //************************************************************************* // Part IVc: 2D view for slicing sagitally //************************************************************************* // Create QmitkSliceWidget, which is based on the class // QmitkRenderWindow, but additionally provides sliders QmitkSliceWidget view3(&toplevelWidget); layout.addWidget(&view3); - + view3.SetDataStorage(ds); // Tell the QmitkSliceWidget which (part of) the datastorage to render // and to slice sagitally - view3.SetData(&it, mitk::SliceNavigationController::Sagittal); + view3.SetData(rs->Begin(), mitk::SliceNavigationController::Sagittal); // We want to see the position of the slice in 2D and the // slice itself in 3D: add it to the datastorage! ds->Add(view3.GetRenderer()->GetCurrentWorldGeometry2DNode()); // ******************************************************* // ******************* END OF NEW PART ******************* // ******************************************************* //************************************************************************* // Part V: Qt-specific initialization //************************************************************************* toplevelWidget.show(); // for testing #include "QtTesting.h" if(strcmp(argv[argc-1], "-testing")!=0) return qtapplication.exec(); else return QtTesting(); } /** \example Step4.cpp */ diff --git a/Applications/Tutorial/Step5.cpp b/Applications/Tutorial/Step5.cpp index d93d36aaf8..cdcb19ff66 100644 --- a/Applications/Tutorial/Step5.cpp +++ b/Applications/Tutorial/Step5.cpp @@ -1,186 +1,188 @@ #include "QmitkRegisterClasses.h" #include "QmitkRenderWindow.h" #include "QmitkSliceWidget.h" #include "mitkDataTreeNodeFactory.h" #include "mitkProperties.h" #include "mitkRenderingManager.h" -#include "mitkDataStorage.h" +#include "mitkStandaloneDataStorage.h" #include "mitkGlobalInteraction.h" #include "mitkPointSet.h" #include "mitkPointSetInteractor.h" #include #include #include //##Documentation //## @brief Interactively add points //## //## As in Step4, load one or more data sets (many image, //## surface and other formats) and create 3 views on the data. //## Additionally, we want to interactively add points. A node containing //## a PointSet as data is added to the data tree and a PointSetInteractor //## is associated with the node, which handles the interaction. The //## @em interaction @em pattern is defined in a state-machine, stored in an //## external XML file. Thus, we need to load a state-machine //## The interaction patterns defines the @em events, //## on which the interactor reacts (e.g., which mouse buttons are used to //## set a point), the @em transition to the next state (e.g., the initial //## may be "empty point set") and associated @a actions (e.g., add a point //## at the position where the mouse-click occured). int main(int argc, char* argv[]) { QApplication qtapplication( argc, argv ); if(argc<2) { fprintf( stderr, "Usage: %s [filename1] [filename2] ...\n\n", itksys::SystemTools::GetFilenameName(argv[0]).c_str() ); return 1; } // Register Qmitk-dependent global instances QmitkRegisterClasses(); //************************************************************************* // Part I: Basic initialization //************************************************************************* - // Create a DataStorage + // Create a DataStorage mitk::StandaloneDataStorage::Pointer ds = mitk::StandaloneDataStorage::New(); //************************************************************************* // Part II: Create some data by reading files //************************************************************************* int i; for(i=1; iSetFileName(filename); nodeReader->Update(); //********************************************************************* // Part III: Put the data into the datastorage //********************************************************************* // Since the DataTreeNodeFactory directly creates a node, // use the iterator to add the read node to the tree mitk::DataTreeNode::Pointer node = nodeReader->GetOutput(); ds->Add(node); } catch(...) { fprintf( stderr, "Could not open file %s \n\n", filename ); exit(2); } } // ******************************************************* // ****************** START OF NEW PART ****************** // ******************************************************* //************************************************************************* // Part VI: For allowing to interactively add points ... //************************************************************************* // Create PointSet and a node for it mitk::PointSet::Pointer pointSet = mitk::PointSet::New(); mitk::DataTreeNode::Pointer pointSetNode = mitk::DataTreeNode::New(); pointSetNode->SetData(pointSet); // Add the node to the tree ds->Add(pointSetNode); // Create PointSetInteractor, associate to pointSetNode and add as // interactor to GlobalInteraction mitk::GlobalInteraction::GetInstance()->AddInteractor( mitk::PointSetInteractor::New("pointsetinteractor", pointSetNode) ); // ******************************************************* // ******************* END OF NEW PART ******************* // ******************************************************* //************************************************************************* // Part V: Create windows and pass the tree to it //************************************************************************* // Create toplevel widget with horizontal layout QWidget toplevelWidget; QHBoxLayout layout; layout.setSpacing(2); layout.setMargin(0); toplevelWidget.setLayout(&layout); //************************************************************************* // Part Va: 3D view //************************************************************************* // Create a renderwindow QmitkRenderWindow renderWindow(&toplevelWidget); layout.addWidget(&renderWindow); // Tell the renderwindow which (part of) the tree to render renderWindow.GetRenderer()->SetDataStorage(ds); // Use it as a 3D view renderWindow.GetRenderer()->SetMapperID(mitk::BaseRenderer::Standard3D); //************************************************************************* // Part Vb: 2D view for slicing transversally //************************************************************************* // Create QmitkSliceWidget, which is based on the class // QmitkRenderWindow, but additionally provides sliders QmitkSliceWidget view2(&toplevelWidget); layout.addWidget(&view2); // Tell the QmitkSliceWidget which (part of) the tree to render. // By default, it slices the data transversally view2.SetDataStorage(ds); - + mitk::DataStorage::SetOfObjects::ConstPointer rs = ds->GetAll(); + view2.SetData(rs->Begin(), mitk::SliceNavigationController::Transversal); // We want to see the position of the slice in 2D and the // slice itself in 3D: add it to the tree! ds->Add(view2.GetRenderer()->GetCurrentWorldGeometry2DNode()); //************************************************************************* // Part Vc: 2D view for slicing sagitally //************************************************************************* // Create QmitkSliceWidget, which is based on the class // QmitkRenderWindow, but additionally provides sliders QmitkSliceWidget view3(&toplevelWidget); layout.addWidget(&view3); // Tell the QmitkSliceWidget which (part of) the tree to render - // and to slice sagitally - view3.SetDataStorage(ds, mitk::SliceNavigationController::Sagittal); + // and to slice sagitall + view3.SetDataStorage(ds); + view3.SetData(rs->Begin(), mitk::SliceNavigationController::Sagittal); // We want to see the position of the slice in 2D and the // slice itself in 3D: add it to the tree! ds->Add(view3.GetRenderer()->GetCurrentWorldGeometry2DNode()); //************************************************************************* //Part VII: Qt-specific initialization //************************************************************************* toplevelWidget.show(); // For testing #include "QtTesting.h" if(strcmp(argv[argc-1], "-testing")!=0) return qtapplication.exec(); else return QtTesting(); } /** \example Step5.cpp */ diff --git a/Applications/Tutorial/Step6.cpp b/Applications/Tutorial/Step6.cpp index 9fc656dae5..b374dc8ea4 100644 --- a/Applications/Tutorial/Step6.cpp +++ b/Applications/Tutorial/Step6.cpp @@ -1,228 +1,232 @@ #include "Step6.h" #include "QmitkRenderWindow.h" #include "QmitkSliceWidget.h" #include "mitkDataTreeNodeFactory.h" #include "mitkProperties.h" #include "mitkRenderingManager.h" #include "mitkGlobalInteraction.h" #include "mitkPointSet.h" #include "mitkPointSetInteractor.h" #include "mitkImageAccessByItk.h" #include "mitkRenderingManager.h" #include #include #include #include #include #include //##Documentation //## @brief Start region-grower at interactively added points -Step6::Step6( int argc, char* argv[], QWidget *parent ) -: QWidget( parent ), m_FirstImage(NULL), m_ResultImage(NULL), - m_ResultNode(NULL), m_DataStorage(NULL); +Step6::Step6(int argc, char* argv[], QWidget *parent) : + QWidget(parent), m_FirstImage(NULL), m_ResultImage(NULL), + m_ResultNode(NULL), m_DataStorage(NULL) { - // load data as in the previous steps; a reference to the first loaded - // image is kept in the member m_FirstImage and used as input for the - // region growing - Load(argc, argv); + // load data as in the previous steps; a reference to the first loaded + // image is kept in the member m_FirstImage and used as input for the + // region growing + Load(argc, argv); } void Step6::Initialize() { - // setup the widgets as in the previous steps, but with an additional - // QVBox for a button to start the segmentation - this->SetupWidgets(); - - // Create controlsParent widget with horizontal layout - QWidget *controlsParent = new QWidget(this); - this->layout()->addWidget( controlsParent); - - QHBoxLayout* hlayout = new QHBoxLayout( controlsParent ); - hlayout->setSpacing(2); - - QLabel *labelThresholdMin = - new QLabel( "Lower Threshold:", controlsParent ); - hlayout->addWidget( labelThresholdMin ); - - m_LineEditThresholdMin = new QLineEdit( "-1000", controlsParent ); - hlayout->addWidget( m_LineEditThresholdMin ); - - QLabel *labelThresholdMax = - new QLabel( "Upper Threshold:", controlsParent ); - hlayout->addWidget( labelThresholdMax ); - - m_LineEditThresholdMax = new QLineEdit( "-400", controlsParent ); - hlayout->addWidget( m_LineEditThresholdMax ); - - // create button to start the segmentation and connect its clicked() - // signal to method StartRegionGrowing - QPushButton* startButton = new QPushButton( "start region growing", controlsParent ); - hlayout->addWidget( startButton ); - - connect(startButton, SIGNAL(clicked()), this, SLOT(StartRegionGrowing())); - if(m_FirstImage.IsNull()) startButton->setEnabled(false); - - // as in Step5, create PointSet (now as a member m_Seeds) and - // associate a interactor to it - m_Seeds = mitk::PointSet::New(); - mitk::DataTreeNode::Pointer pointSetNode = mitk::DataTreeNode::New(); - pointSetNode->SetData(m_Seeds); - pointSetNode->SetProperty("layer", mitk::IntProperty::New(2)); - m_DataStorage->Add(pointSetNode); - mitk::GlobalInteraction::GetInstance()->AddInteractor( - mitk::PointSetInteractor::New("pointsetinteractor", pointSetNode) - ); + // setup the widgets as in the previous steps, but with an additional + // QVBox for a button to start the segmentation + this->SetupWidgets(); + + // Create controlsParent widget with horizontal layout + QWidget *controlsParent = new QWidget(this); + this->layout()->addWidget(controlsParent); + + QHBoxLayout* hlayout = new QHBoxLayout(controlsParent); + hlayout->setSpacing(2); + + QLabel *labelThresholdMin = new QLabel("Lower Threshold:", controlsParent); + hlayout->addWidget(labelThresholdMin); + + m_LineEditThresholdMin = new QLineEdit("-1000", controlsParent); + hlayout->addWidget(m_LineEditThresholdMin); + + QLabel *labelThresholdMax = new QLabel("Upper Threshold:", controlsParent); + hlayout->addWidget(labelThresholdMax); + + m_LineEditThresholdMax = new QLineEdit("-400", controlsParent); + hlayout->addWidget(m_LineEditThresholdMax); + + // create button to start the segmentation and connect its clicked() + // signal to method StartRegionGrowing + QPushButton* startButton = new QPushButton("start region growing", + controlsParent); + hlayout->addWidget(startButton); + + connect(startButton, SIGNAL(clicked()), this, SLOT(StartRegionGrowing())); + if (m_FirstImage.IsNull()) + startButton->setEnabled(false); + + // as in Step5, create PointSet (now as a member m_Seeds) and + // associate a interactor to it + m_Seeds = mitk::PointSet::New(); + mitk::DataTreeNode::Pointer pointSetNode = mitk::DataTreeNode::New(); + pointSetNode->SetData(m_Seeds); + pointSetNode->SetProperty("layer", mitk::IntProperty::New(2)); + m_DataStorage->Add(pointSetNode); + mitk::GlobalInteraction::GetInstance()->AddInteractor( + mitk::PointSetInteractor::New("pointsetinteractor", pointSetNode)); } int Step6::GetThresholdMin() { - return m_LineEditThresholdMin->text().toInt(); + return m_LineEditThresholdMin->text().toInt(); } int Step6::GetThresholdMax() { - return m_LineEditThresholdMax->text().toInt(); + return m_LineEditThresholdMax->text().toInt(); } void Step6::StartRegionGrowing() { - AccessByItk_1(m_FirstImage, RegionGrowing, this); + AccessByItk_1(m_FirstImage, RegionGrowing, this); - mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void Step6::Load(int argc, char* argv[]) { - //************************************************************************* - // Part I: Basic initialization - //************************************************************************* - - m_DataStorage = mitk::StandaloneDataStorage::New(); - - //************************************************************************* - // Part II: Create some data by reading files - //************************************************************************* - int i; - for(i=1; iSetFileName(filename); - nodeReader->Update(); - //********************************************************************* - // Part III: Put the data into the datastorage - //********************************************************************* - - // Since the DataTreeNodeFactory directly creates a node, - // use the iterator to add the read node to the tree - mitk::DataTreeNode::Pointer node = nodeReader->GetOutput(); - m_DataStorage->Add(node); - - mitk::Image::Pointer image = dynamic_cast(node->GetData()); - if((m_FirstImage.IsNull()) && (image.IsNotNull())) - m_FirstImage = image; - } - catch(...) - { - fprintf( stderr, "Could not open file %s \n\n", filename ); - exit(2); - } - } + //************************************************************************* + // Part I: Basic initialization + //************************************************************************* + + m_DataStorage = mitk::StandaloneDataStorage::New(); + + //************************************************************************* + // Part II: Create some data by reading files + //************************************************************************* + int i; + for (i = 1; i < argc; ++i) + { + // For testing + if (strcmp(argv[i], "-testing") == 0) + continue; + + // Create a DataTreeNodeFactory to read a data format supported + // by the DataTreeNodeFactory (many image formats, surface formats, etc.) + mitk::DataTreeNodeFactory::Pointer nodeReader = + mitk::DataTreeNodeFactory::New(); + const char * filename = argv[i]; + try + { + nodeReader->SetFileName(filename); + nodeReader->Update(); + //********************************************************************* + // Part III: Put the data into the datastorage + //********************************************************************* + + // Since the DataTreeNodeFactory directly creates a node, + // use the iterator to add the read node to the tree + mitk::DataTreeNode::Pointer node = nodeReader->GetOutput(); + m_DataStorage->Add(node); + + mitk::Image::Pointer image = + dynamic_cast (node->GetData()); + if ((m_FirstImage.IsNull()) && (image.IsNotNull())) + m_FirstImage = image; + } catch (...) + { + fprintf(stderr, "Could not open file %s \n\n", filename); + exit(2); + } + } } void Step6::SetupWidgets() { - //************************************************************************* - // Part I: Create windows and pass the datastorage to it - //************************************************************************* - - // Create toplevel widget with vertical layout - QVBoxLayout* vlayout = new QVBoxLayout(this); - vlayout->setMargin(0); - vlayout->setSpacing(2); - - // Create viewParent widget with horizontal layout - QWidget* viewParent = new QWidget(this); - vlayout->addWidget(viewParent); - - QHBoxLayout* hlayout = new QHBoxLayout(viewParent); - hlayout->setMargin(0); - hlayout->setSpacing(2); - - //************************************************************************* - // Part Ia: 3D view - //************************************************************************* - - // Create a renderwindow - QmitkRenderWindow* renderWindow = new QmitkRenderWindow(viewParent); - hlayout->addWidget(renderWindow); - - // Tell the renderwindow which (part of) the tree to render - renderWindow->GetRenderer()->SetDataStorage(m_DataStorage); - - // Use it as a 3D view - renderWindow->GetRenderer()->SetMapperID(mitk::BaseRenderer::Standard3D); - - //************************************************************************* - // Part Ib: 2D view for slicing transversally - //************************************************************************* - - // Create QmitkSliceWidget, which is based on the class - // QmitkRenderWindow, but additionally provides sliders - QmitkSliceWidget *view2 = new QmitkSliceWidget(viewParent); - hlayout->addWidget(view2); - - // Tell the QmitkSliceWidget which (part of) the tree to render. - // By default, it slices the data transversally - view2->SetDataStorage(m_DataStorage); - - // We want to see the position of the slice in 2D and the - // slice itself in 3D: add it to the tree! - m_DataStorage->Add(view2->GetRenderer()->GetCurrentWorldGeometry2DNode()); - - //************************************************************************* - // Part Ic: 2D view for slicing sagitally - //************************************************************************* - - // Create QmitkSliceWidget, which is based on the class - // QmitkRenderWindow, but additionally provides sliders - QmitkSliceWidget *view3 = new QmitkSliceWidget(viewParent); - hlayout->addWidget(view3); - - // Tell the QmitkSliceWidget which (part of) the tree to render - // and to slice sagitally - view3->SetDataStorage(m_DataStorage, mitk::SliceNavigationController::Sagittal); - - // We want to see the position of the slice in 2D and the - // slice itself in 3D: add it to the tree! - m_DataStorage->Add(view3->GetRenderer()->GetCurrentWorldGeometry2DNode()); - - //************************************************************************* - // Part II: handle updates: To avoid unnecessary updates, we have to - //************************************************************************* - // define when to update. The RenderingManager serves this purpose, and - // each RenderWindow has to be registered to it. - /*mitk::RenderingManager *renderingManager = - mitk::RenderingManager::GetInstance(); - renderingManager->AddRenderWindow( renderWindow ); - renderingManager->AddRenderWindow( view2->GetRenderWindow() ); - renderingManager->AddRenderWindow( view3->GetRenderWindow() );*/ + //************************************************************************* + // Part I: Create windows and pass the datastorage to it + //************************************************************************* + + // Create toplevel widget with vertical layout + QVBoxLayout* vlayout = new QVBoxLayout(this); + vlayout->setMargin(0); + vlayout->setSpacing(2); + + // Create viewParent widget with horizontal layout + QWidget* viewParent = new QWidget(this); + vlayout->addWidget(viewParent); + + QHBoxLayout* hlayout = new QHBoxLayout(viewParent); + hlayout->setMargin(0); + hlayout->setSpacing(2); + + //************************************************************************* + // Part Ia: 3D view + //************************************************************************* + + // Create a renderwindow + QmitkRenderWindow* renderWindow = new QmitkRenderWindow(viewParent); + hlayout->addWidget(renderWindow); + + // Tell the renderwindow which (part of) the tree to render + renderWindow->GetRenderer()->SetDataStorage(m_DataStorage); + + // Use it as a 3D view + renderWindow->GetRenderer()->SetMapperID(mitk::BaseRenderer::Standard3D); + + //************************************************************************* + // Part Ib: 2D view for slicing transversally + //************************************************************************* + + // Create QmitkSliceWidget, which is based on the class + // QmitkRenderWindow, but additionally provides sliders + QmitkSliceWidget *view2 = new QmitkSliceWidget(viewParent); + hlayout->addWidget(view2); + + // Tell the QmitkSliceWidget which (part of) the tree to render. + // By default, it slices the data transversally + view2->SetDataStorage(m_DataStorage); + mitk::DataStorage::SetOfObjects::ConstPointer rs = m_DataStorage->GetAll(); + view2->SetData(rs->Begin(), mitk::SliceNavigationController::Transversal); + + // We want to see the position of the slice in 2D and the + // slice itself in 3D: add it to the tree! + m_DataStorage->Add(view2->GetRenderer()->GetCurrentWorldGeometry2DNode()); + + //************************************************************************* + // Part Ic: 2D view for slicing sagitally + //************************************************************************* + + // Create QmitkSliceWidget, which is based on the class + // QmitkRenderWindow, but additionally provides sliders + QmitkSliceWidget *view3 = new QmitkSliceWidget(viewParent); + hlayout->addWidget(view3); + + // Tell the QmitkSliceWidget which (part of) the tree to render + // and to slice sagitally + view3->SetDataStorage(m_DataStorage); + view3->SetData(rs->Begin(), mitk::SliceNavigationController::Sagittal); + + // We want to see the position of the slice in 2D and the + // slice itself in 3D: add it to the tree! + m_DataStorage->Add(view3->GetRenderer()->GetCurrentWorldGeometry2DNode()); + + //************************************************************************* + // Part II: handle updates: To avoid unnecessary updates, we have to + //************************************************************************* + // define when to update. The RenderingManager serves this purpose, and + // each RenderWindow has to be registered to it. + /*mitk::RenderingManager *renderingManager = + mitk::RenderingManager::GetInstance(); + renderingManager->AddRenderWindow( renderWindow ); + renderingManager->AddRenderWindow( view2->GetRenderWindow() ); + renderingManager->AddRenderWindow( view3->GetRenderWindow() );*/ } /** -\example Step6.cpp -*/ + \example Step6.cpp + */ diff --git a/Applications/Tutorial/Step6.h b/Applications/Tutorial/Step6.h index 753d7e6305..69d3ef024b 100644 --- a/Applications/Tutorial/Step6.h +++ b/Applications/Tutorial/Step6.h @@ -1,55 +1,55 @@ #ifndef STEP6_H #define STEP6_H //#include #include #include #include #include #include #ifndef DOXYGEN_IGNORE class QLineEdit; class Step6 : public QWidget { Q_OBJECT public: Step6( int argc, char* argv[], QWidget *parent=0 ); ~Step6() {}; virtual void Initialize(); virtual int GetThresholdMin(); virtual int GetThresholdMax(); protected: void Load(int argc, char* argv[]); virtual void SetupWidgets(); template < typename TPixel, unsigned int VImageDimension > friend void RegionGrowing( itk::Image* itkImage, Step6* step6); - mitk::DataStorage::Pointer m_DataStorage; + mitk::StandaloneDataStorage::Pointer m_DataStorage; mitk::Image::Pointer m_FirstImage; mitk::PointSet::Pointer m_Seeds; mitk::Image::Pointer m_ResultImage; mitk::DataTreeNode::Pointer m_ResultNode; - + QLineEdit *m_LineEditThresholdMin; QLineEdit *m_LineEditThresholdMax; protected slots: virtual void StartRegionGrowing(); }; #endif // DOXYGEN_IGNORE #endif // STEP6_H /** \example Step6.h */ diff --git a/Applications/Tutorial/Step6main.cpp b/Applications/Tutorial/Step6main.cpp index 17a4897ed5..f80c528e80 100644 --- a/Applications/Tutorial/Step6main.cpp +++ b/Applications/Tutorial/Step6main.cpp @@ -1,34 +1,35 @@ #include "Step6.h" #include "QmitkRegisterClasses.h" #include "mitkDataStorage.h" #include #include int main(int argc, char* argv[]) { QApplication qtapplication( argc, argv ); if(argc<2) { fprintf( stderr, "Usage: %s [filename1] [filename2] ...\n\n", itksys::SystemTools::GetFilenameName(argv[0]).c_str() ); return 1; } // Register Qmitk-dependent global instances QmitkRegisterClasses(); Step6 mainWidget(argc, argv, NULL); mainWidget.Initialize(); mainWidget.show(); // for testing #include "QtTesting.h" if(strcmp(argv[argc-1], "-testing")!=0) return qtapplication.exec(); else return QtTesting(); + } /** \example Step6main.cpp */ diff --git a/Applications/Tutorial/Step7.cpp b/Applications/Tutorial/Step7.cpp index ff480bf3a1..f7d7dac235 100644 --- a/Applications/Tutorial/Step7.cpp +++ b/Applications/Tutorial/Step7.cpp @@ -1,50 +1,55 @@ #include "Step7.h" #include #include #include #include #include #include #include #include //##Documentation //## @brief Convert result of region-grower into a surface //## by means of a VTK filter Step7::Step7( int argc, char* argv[], QWidget *parent ) : Step6( argc, argv, parent ) { } void Step7::StartRegionGrowing() { Step6::StartRegionGrowing(); + std::cout << "7"; if(m_ResultImage.IsNotNull()) { m_ResultNode->SetProperty("volumerendering", mitk::BoolProperty::New(false)); vtkMarchingCubes* surfaceCreator = vtkMarchingCubes::New(); surfaceCreator->SetInput(m_ResultImage->GetVtkImageData()); surfaceCreator->SetValue(0, 1); mitk::Surface::Pointer surface = mitk::Surface::New(); surface->SetVtkPolyData(surfaceCreator->GetOutput()); mitk::DataTreeNode::Pointer surfaceNode = mitk::DataTreeNode::New(); surfaceNode->SetData(surface); m_DataStorage->Add(surfaceNode); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + std::cout << "8"; } + + std::cout << "9"; + } /** \example Step7.cpp */ diff --git a/Applications/Tutorial/Step8.cpp b/Applications/Tutorial/Step8.cpp index a8c7d71f80..f6cdb02a56 100644 --- a/Applications/Tutorial/Step8.cpp +++ b/Applications/Tutorial/Step8.cpp @@ -1,72 +1,76 @@ #include "Step8.h" #include "QmitkStdMultiWidget.h" #include "mitkGlobalInteraction.h" #include "mitkRenderingManager.h" #include #include //##Documentation //## @brief As Step6, but with QmitkStdMultiWidget as widget -Step8::Step8( int argc, char* argv[], QWidget *parent ) - : Step6( argc, argv, parent ) +Step8::Step8(int argc, char* argv[], QWidget *parent) : + Step6(argc, argv, parent) { } void Step8::SetupWidgets() { - //************************************************************************* - // Part I: Create windows and pass the tree to it - //************************************************************************* - - // Create toplevel widget with vertical layout - QVBoxLayout* vlayout = new QVBoxLayout(this); - vlayout->setMargin(0); - vlayout->setSpacing(2); - - // Create viewParent widget with horizontal layout - QWidget* viewParent = new QWidget(this); - vlayout->addWidget(viewParent); - QHBoxLayout* hlayout = new QHBoxLayout(viewParent); - hlayout->setMargin(0); - - //************************************************************************* - // Part Ia: create and initialize QmitkStdMultiWidget - //************************************************************************* - QmitkStdMultiWidget* multiWidget = new QmitkStdMultiWidget(viewParent); - hlayout->addWidget(multiWidget); - - - // Tell the multiWidget which DataStorage to render - multiWidget->SetDataStorage(m_DataStorage); - - // Initialize views as transversal, sagittal, coronar (from - // top-left to bottom) - mitk::RenderingManager::GetInstance()->InitializeViews(); - - // Initialize bottom-right view as 3D view - multiWidget->GetRenderWindow4()->GetRenderer()->SetMapperID( mitk::BaseRenderer::Standard3D ); - - // Enable standard handler for levelwindow-slider - multiWidget->EnableStandardLevelWindow(); - - // Add the displayed views to the DataStorage to see their positions in 2D and 3D - multiWidget->AddDisplayPlaneSubTree(); - - //************************************************************************* - // Part II: Setup standard interaction with the mouse - //************************************************************************* - - // Moving the cut-planes to click-point - multiWidget->EnableNavigationControllerEventListening(); - - // Zooming and panning - mitk::GlobalInteraction::GetInstance()->AddListener( - multiWidget->GetMoveAndZoomInteractor() - ); + //************************************************************************* + // Part I: Create windows and pass the tree to it + //************************************************************************* + + // Create toplevel widget with vertical layout + QVBoxLayout* vlayout = new QVBoxLayout(this); + vlayout->setMargin(0); + vlayout->setSpacing(2); + + // Create viewParent widget with horizontal layout + QWidget* viewParent = new QWidget(this); + vlayout->addWidget(viewParent); + QHBoxLayout* hlayout = new QHBoxLayout(viewParent); + hlayout->setMargin(0); + + //************************************************************************* + // Part Ia: create and initialize QmitkStdMultiWidget + //************************************************************************* + QmitkStdMultiWidget* multiWidget = new QmitkStdMultiWidget(viewParent); + + hlayout->addWidget(multiWidget); + + // Tell the multiWidget which DataStorage to render + multiWidget->SetDataStorage(m_DataStorage); + + // Initialize views as transversal, sagittal, coronar (from + // top-left to bottom) + mitk::Geometry3D::Pointer geo = m_DataStorage->ComputeBoundingGeometry3D( + m_DataStorage->GetAll()); + mitk::RenderingManager::GetInstance()->InitializeViews(geo); + + // mitk::RenderingManager::GetInstance()->InitializeViews(); + + // Initialize bottom-right view as 3D view + multiWidget->GetRenderWindow4()->GetRenderer()->SetMapperID( + mitk::BaseRenderer::Standard3D); + + // Enable standard handler for levelwindow-slider + multiWidget->EnableStandardLevelWindow(); + + // Add the displayed views to the DataStorage to see their positions in 2D and 3D + multiWidget->AddDisplayPlaneSubTree(); + + //************************************************************************* + // Part II: Setup standard interaction with the mouse + //************************************************************************* + + // Moving the cut-planes to click-point + multiWidget->EnableNavigationControllerEventListening(); + + // Zooming and panning + mitk::GlobalInteraction::GetInstance()->AddListener( + multiWidget->GetMoveAndZoomInteractor()); } /** -\example Step8.cpp -*/ + \example Step8.cpp + */