Create a Directory For the Source Code
% mkdir /home/username/development/MyVtkTest
First Program - Iterative Closest Point Registration
The first program here is an iterative closest point (ICP) algorithm to rigidly register two triangle meshes. Here is the basic program.
- Use compiler line directive to ignore certain warnings thrown by the Microsoft compilers. This is standard in ITK and VTK code
#if defined(_MSC_VER) #pragma warning ( disable : 4786 ) #endif
- Use compiler line directive to setup building for Borland Compilers. Again this is a standard directive commonly used in the code.
#ifdef __BORLANDC__ #define ITK_LEAN_AND_MEAN #endif
- Now include the header files for the classes used in the program. Each VTK class has its own header file that will need to be included. This will define the methods available for each class used in the code below.
#include <vtkPolyData.h> #include <vtkSTLReader.h> #include <vtkSTLWriter.h> #include <vtkIterativeClosestPointTransform.h> #include <vtkTransformPolyDataFilter.h> #include <vtkLandmarkTransform.h>
- Start of actual program.
- int argc - Number of command line parameters specified + 1 for program name
- char *argv[] - Command line arguements stored as character arrays
int main( int argc, char * argv[] ) {
if( argc != 7 ) { std::cerr << "Usage: " << std::endl; std::cerr << argv[0] << " Fixed-STL-Surface Moving-STL-Surface " std::cerr << "Output-STL-Mesh #-of-Iterations Max-Distance #-of-Landmarks" std::cerr << std::endl; return EXIT_FAILURE; }
- Read in the triangle meshes in STL format - VTK is a pipeline architecture. You specify the parameters for the pipeline using the class methods but nothing is done until the Update() method is called.
/*** Read the Meshes to Register ***/ vtkSTLReader *fixedReader = vtkSTLReader::New(); fixedReader->SetFileName(argv[1]); fixedReader->Update( );
vtkSTLReader *movingReader = vtkSTLReader::New(); movingReader->SetFileName(argv[2]); movingReader->Update( );
- Now setup the ICP Registration
vtkIterativeClosestPointTransform *icpTransform = vtkIterativeClosestPointTransform::New(); // Set the two surfaces for registration icpTransform->SetSource( movingReader->GetOutput( ) ); icpTransform->SetTarget( fixedReader->GetOutput( ) ); // Initialize transform by translation to align Center of masses icpTransform->StartByMatchingCentroidsOn( ); // Specify a Rigid Body registration - 6 degrees of freedom icpTransform->GetLandmarkTransform( )->SetModeToRigidBody( ); //Set registration parameters based on command line icpTransform->SetMaximumNumberOfIterations( atoi(argv[4]) ); icpTransform->CheckMeanDistanceOn(); icpTransform->SetMaximumMeanDistance( atof(argv[5]) ); icpTransform->SetMeanDistanceModeToRMS(); icpTransform->SetMaximumNumberOfLandmarks( atoi(argv[6]) );
- Run the ICP Registration
icpTransform->Update( );
- Apply the resulting transform to the moving surface
vtkTransformPolyDataFilter *resampleMeshFilter = vtkTransformPolyDataFilter::New(); resampleMeshFilter->SetInput( movingReader->GetOutput( ) ); resampleMeshFilter->SetTransform( icpTransform ); resampleMeshFilter->Update( );
- Write the resulting surface
vtkSTLWriter *meshWriter = vtkSTLWriter::New(); meshWriter->SetFileName(argv[3]); meshWriter->SetFileTypeToASCII(); meshWriter->SetInput( resampleMeshFilter->GetOutput( ) ); meshWriter->Update( );
- Return a status value - Usually 0 if things work properly
return 0; }
Build a CMake File For the ICP Registration
In the same directory as the sorce code create a file called CMakeLists.txt. This file is used by CMake to create by the Makefiles for Unix/Linux or the Solution files for Microsoft Visual Studio. Here is a basic CMakeLists.txt file for the ICP registration example.
- Define the project Name
PROJECT(IcpRegisterSurface)
- Include definitions from VTK. These lines will help to find VTK if installed in a standard location, otherwise the user will have to specify this via CMake.
INCLUDE (${CMAKE_ROOT}/Modules/FindVTK.cmake) FIND_PACKAGE(VTK) IF(VTK_FOUND) INCLUDE (${USE_VTK_FILE}) LINK_LIBRARIES( vtkHybrid vtkRendering vtkGraphics vtkImaging vtkIO vtkFiltering vtkCommon ) IF (${VTK_MAJOR_VERSION} GREATER 4) LINK_LIBRARIES( vtkWidgets ) ENDIF (${VTK_MAJOR_VERSION} GREATER 4) ENDIF(VTK_FOUND)
- Specify Additional default include directories. This is not required for this example but is useful for future programs.
- Specify the directory where the source code resides for the IcpRegisterSurface resides
- Specify the build directory for the IcpRegisterSurface. This is helpful when using FLTK for development of graphical user interface programs
INCLUDE_DIRECTORIES( ${IcpRegisterSurface_SOURCE_DIR} ${IcpRegisterSurface_BINARY_DIR} )
- Specify the program and the source code needed to build the executable (i.e. all cxx files in the project). You do not need to specify the .h or '.txx files since these should be included via the #include directive in the .cxx files.
ADD_EXECUTABLE(IcpRegisterSurface RegisterMesh.cxx )
- Specify libraries needed to link the resulting application. Here this will be the libraries containing the VTK classes.
TARGET_LINK_LIBRARIES(IcpRegisterSurface vtkIO vtkHybrid vtkFiltering vtkCommon)
Create the Solution Files
Create a build directory
% mkdir /home/username/development/MyVtkTest-Build
Repeat steps used for building VTK. This time however, select /home/username/development/MyVtkTest as the source directory and /home/username/development/MyVtkTest-Build as the build directory. You may also need to specify the location of the VTK build directory (e.g. /home/username/development/VTK-Build). Configure the project and press the OK button.
Build the Project Using Visual Studio
Load the IcpRegisterSurface solution file and build. Make sure that the same build type is selected as was used to compile VTK. Build the project. After compilation is complete you should see the following message in the Output tab: Build: 1 succeeded, 0 failed, 0 skipped
After building is complete you will find the executable program in a directory called /home/username/development/MyVtkTest-Build/debug
Run the ICP Registration Program
Change directories to the location where the ICP program resides.
% cd /home/username/development/MyVtkTest-Build/debug
Now give the program a try.
% ./IcpSurfaceRegister fixedSurface.stl movingSurfcae.stl / result.stl 1000 0.01 1000
You will need to replace the command line arguements fixedSurface.stl and movingSurfcae.stl with the name of actually STL files.