diff --git a/Modules/IGT/Documentation/doxygen/IGTTutorialStep1_buildInstrLinux.png b/Modules/IGT/Documentation/doxygen/IGTTutorialStep1_buildInstrLinux.png index 74f9aded61..7af736cc3a 100644 Binary files a/Modules/IGT/Documentation/doxygen/IGTTutorialStep1_buildInstrLinux.png and b/Modules/IGT/Documentation/doxygen/IGTTutorialStep1_buildInstrLinux.png differ diff --git a/Modules/IGT/Documentation/doxygen/IGTTutorialStep2.dox b/Modules/IGT/Documentation/doxygen/IGTTutorialStep2.dox index 2e6dd9ac2d..803aa5044f 100644 --- a/Modules/IGT/Documentation/doxygen/IGTTutorialStep2.dox +++ b/Modules/IGT/Documentation/doxygen/IGTTutorialStep2.dox @@ -1,9 +1,55 @@ /** \page IGTTutorialStepVisualization IGT Visualization Filter and MITK Concepts The following code shows how to insert IGT tracking data into an mitk::DataStorage and render the data with the mitk::NavigationDataObjectVisualizationFilter in an mitk::RenderWindow. The full code is shown below and can be found in MITK-Source/Modules/IGT/Tutorial/mitkIGTTutorialStep2.cpp. This tutorial is an extra target which can be build separately (see \ref IGTTutStep1Build). +The example we are using here regards a moving tracker and a fixed object, and after tracking a transform to move the fixed object to the tracked one is calculated and applied. + +\snippet mitkIGTTutorialStep2.cpp What we will do + +The next image describes, what happens in this example. The blue and red object are labeled with "1" at their initial position. Next, the blue object will move (approximately along the yellow arrow) to the second position, while the red one stayes fixed. Now we calculate the transform of the blue cones initial and moved position (1 -> 2) and apply this transform to shift the red object to its final position (3). Now, the relative distance and orientation of the blue and red object is as it was in the beginning. + +\imageMacro{IGTTutorialStep2_overview.png,"Overlay of the three steps in this example: 1. Initial position\, 2. Blue object moved along the yellow arc\, 3. Final position\, the red object is moved to get the initial relative position compared to the blue object.",9.53} + +\section igtTut2sec1 Set up Render Window and Tracking Device + +First of all, we create a new render window. For simplicity, we are not using the MITK workbench yet but run this example as a stand alone application. Hence, we need to create a render window and a data storage. + +\snippet mitkIGTTutorialStep2.cpp Render Window + +Next, we need to set up the tracking device like we did in the last tutorial step \ref IGTTutorialStepFilterPipeline . We set additionally some boundaries for the tracking. + +\snippet mitkIGTTutorialStep2.cpp Setup Tracking Device + +\section igtTut2sec2 Create Objects + +Now we create a fixed and a moving object. For the moving (tracked) object, we decided for a blue cone. First, we set the name and color and add it to the data storage. Next, we need to create a visualitation filter to display it. Here, we connect in the visualization filter the output of our tracking device source to the cone representation. + +\snippet mitkIGTTutorialStep2.cpp Moving Object + +The fixed object is created accordingly, with a cylindrical shape and red color. As it is not tracked, we define an initial position and orientation, set it to the cylinder object and also store it as fixedNavigationData for later usage. As the object is not continuously updated, we don't need a visualization filter. + +\snippet mitkIGTTutorialStep2.cpp Fixed Object + +\section igtTut2sec3 The Tracking loop + +Before we start tracking, we need to initialize the rendering manager. + +\snippet mitkIGTTutorialStep2.cpp Initialize views + +We now move the tracked blue cone object for 75 steps, update the rendering and print the position to the output console. + +\snippet mitkIGTTutorialStep2.cpp Tracking + +\section igtTut2sec2 Final Transform + +Finally, we apply the new position of the tracked object (source->GetOutput) to the stored fixedNavigationData transform and update the rendering one last time. + +\snippet mitkIGTTutorialStep2.cpp Calculate Transform + +The red cylinder is now moved accodring to the tracked transform. + \ref Return to the \ref IGTTutorialOverview "[IGT Tutorial Overview]" */ \ No newline at end of file diff --git a/Modules/IGT/Documentation/doxygen/IGTTutorialStep2_end.png b/Modules/IGT/Documentation/doxygen/IGTTutorialStep2_end.png new file mode 100644 index 0000000000..0c1dab6571 Binary files /dev/null and b/Modules/IGT/Documentation/doxygen/IGTTutorialStep2_end.png differ diff --git a/Modules/IGT/Documentation/doxygen/IGTTutorialStep2_init.png b/Modules/IGT/Documentation/doxygen/IGTTutorialStep2_init.png new file mode 100644 index 0000000000..f0863748b2 Binary files /dev/null and b/Modules/IGT/Documentation/doxygen/IGTTutorialStep2_init.png differ diff --git a/Modules/IGT/Documentation/doxygen/IGTTutorialStep2_overview.png b/Modules/IGT/Documentation/doxygen/IGTTutorialStep2_overview.png new file mode 100644 index 0000000000..ea3307d239 Binary files /dev/null and b/Modules/IGT/Documentation/doxygen/IGTTutorialStep2_overview.png differ diff --git a/Modules/IGT/Documentation/doxygen/IGTTutorialStep2_track.png b/Modules/IGT/Documentation/doxygen/IGTTutorialStep2_track.png new file mode 100644 index 0000000000..508d8abcde Binary files /dev/null and b/Modules/IGT/Documentation/doxygen/IGTTutorialStep2_track.png differ diff --git a/Modules/IGT/Tutorial/mitkIGTTutorialStep2.cpp b/Modules/IGT/Tutorial/mitkIGTTutorialStep2.cpp index d42d86a99c..e7e86dbe71 100644 --- a/Modules/IGT/Tutorial/mitkIGTTutorialStep2.cpp +++ b/Modules/IGT/Tutorial/mitkIGTTutorialStep2.cpp @@ -1,159 +1,183 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include #include #include #include #include #include #include #include //The next line starts a snippet to display this code in the documentation. If you don't revise the documentation, don't remove it! //! [What we will do] //************************************************************************* // What we will do... //************************************************************************* // This tutorial shows how to compose navigation datas. Therefore we render two objects. //The first object is a cone that is tracked. The second object is a cylinder at a fixed position //relative to the cone. At the end of the tracking, the cylinder is moved to its new relative position //according to the last output of the tracking device. //In addition to IGT tutorial step 1, the objects are added to a datastorage. Furthermore, a renderwindow //is used for visual output. //! [What we will do] int main(int argc, char* argv[]) { + //************************************************************************* + // Set up Render Window and Tracking Device + //************************************************************************* + //! [Render Window] //General code rendering the data in a renderwindow. See MITK Tutorial Step1 for more details. mitk::StandaloneDataStorage::Pointer dataStorage = mitk::StandaloneDataStorage::New(); mitk::RenderWindow::Pointer renderWindow = mitk::RenderWindow::New(); mitk::DataNode::Pointer dataNode = mitk::DataNode::New(); //Here, we want a 3D renderwindow renderWindow->GetRenderer()->SetMapperID(mitk::BaseRenderer::Standard3D); renderWindow->GetVtkRenderWindow()->SetSize(500, 500); renderWindow->GetRenderer()->Resize(500, 500); //Connect datastorage and renderwindow renderWindow->GetRenderer()->SetDataStorage(dataStorage); - // --------------begin of moving object code -------------------------- // + //! [Render Window] + //! [Setup Tracking Device] //Virtual tracking device to generate random positions mitk::VirtualTrackingDevice::Pointer tracker = mitk::VirtualTrackingDevice::New(); //Bounds (within the random numbers are generated) must be set before the tools are added double bound = 10.0; mitk::ScalarType bounds[] = { -bound, bound, -bound, bound, -bound, bound }; tracker->SetBounds(bounds); tracker->AddTool("tool1"); //Tracking device source to get the data mitk::TrackingDeviceSource::Pointer source = mitk::TrackingDeviceSource::New(); source->SetTrackingDevice(tracker); source->Connect(); + //! [Setup Tracking Device] + + //************************************************************************* + // Create Objects + //************************************************************************* + + //! [Moving Object] //Cone representation for rendering of the moving object mitk::Cone::Pointer cone = mitk::Cone::New(); dataNode->SetData(cone); dataNode->SetName("My tracked object"); dataNode->SetColor(0.0, 1.0, 1.0); dataStorage->Add(dataNode); //Filter for rendering the cone at correct postion and orientation mitk::NavigationDataObjectVisualizationFilter::Pointer visualizer = mitk::NavigationDataObjectVisualizationFilter::New(); visualizer->SetInput(0, source->GetOutput()); visualizer->SetRepresentationObject(0, cone); - source->StartTracking(); - - // --------------end of moving object code -------------------------- // - - // --------------begin of fixed object code ------------------------- // + //! [Moving Object] + //! [Fixed Object] //Cylinder representation for rendering of the fixed object mitk::DataNode::Pointer cylinderNode = mitk::DataNode::New(); mitk::Cylinder::Pointer cylinder = mitk::Cylinder::New(); cylinderNode->SetData(cylinder); cylinderNode->SetName("My fixed object"); cylinderNode->SetColor(1.0, 0.0, 0.0); dataStorage->Add(cylinderNode); //Define a rotation and a translation for the fixed object mitk::Matrix3D rotationMatrix; rotationMatrix.SetIdentity(); double alpha = 0.3; rotationMatrix[1][1] = cos(alpha); rotationMatrix[1][2] = -sin(alpha); rotationMatrix[2][1] = sin(alpha); rotationMatrix[2][2] = cos(alpha); mitk::Vector3D offset; offset.Fill(5.0); //Add rotation and translation to affine transform mitk::AffineTransform3D::Pointer affineTransform3D = mitk::AffineTransform3D::New(); affineTransform3D->SetOffset(offset); affineTransform3D->SetMatrix(rotationMatrix); //apply rotation and translation mitk::NavigationData::Pointer fixedNavigationData = mitk::NavigationData::New(affineTransform3D); cylinder->GetGeometry()->SetIndexToWorldTransform(fixedNavigationData->GetAffineTransform3D()); + //! [Fixed Object] - // --------------end of fixed object code ------------------------- // + //************************************************************************* + // The Tracking loop + //************************************************************************* + //! [Initialize views] // Global reinit with the bounds of the virtual tracking device mitk::TimeGeometry::Pointer timeGeometry = dataStorage->ComputeBoundingGeometry3D(dataStorage->GetAll()); mitk::BaseGeometry::Pointer geometry = timeGeometry->GetGeometryForTimeStep(0); geometry->SetBounds(bounds); mitk::RenderingManager::GetInstance()->InitializeViews(geometry); + source->StartTracking(); + //! [Initialize views] + + //! [Tracking] //Generate and render 75 time steps to move the tracked object for (int i = 0; i < 75; ++i) { //Update the cone position visualizer->Update(); //Update rendering renderWindow->GetVtkRenderWindow()->Render(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); MITK_INFO << "Position " << source->GetOutput()->GetPosition(); //Slight delay for the random numbers itksys::SystemTools::Delay(100); } //Stop the tracking device and disconnect it //The tracking is done, now we want to move the fixed object to its correct relative position regarding the tracked object. source->StopTracking(); source->Disconnect(); + //! [Tracking] + + //************************************************************************* + // Final Transform + //************************************************************************* + //! [Calculate Transform] //Now the tracking is finished and we can use the transformation to move //the fixed object to its correct position relative to the new position //of the moving/tracked object. Therefore, we compose the navigation datas. fixedNavigationData->Compose(source->GetOutput(), false); //Update the transformation matrix of the cylinder cylinder->GetGeometry()->SetIndexToWorldTransform(fixedNavigationData->GetAffineTransform3D()); //Update the rendering renderWindow->GetVtkRenderWindow()->Render(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); //Wait a little before closing the renderwindow itksys::SystemTools::Delay(2000); + //! [Calculate Transform] } \ No newline at end of file