PineRootDecimation
VTKExamples/Cxx/VisualizationAlgorithms/PineRootDecimation
Description¶
Demonstrates how to apply the decimation filter to get a reduced data size and then the connectivity filter to remove noisy isosurfaces. The data is from the root system of a pine tree.
To count the number of triangles in the polydata we do the following:
C++¶
We use a lambda function
auto NumberofTriangles = [](auto *pd)
Python¶
We just implement:
def NumberOfTriangles(pd):
within the scope of the calling function.
Info
See Figure 9-52 in Chapter 9 in the VTK Textbook.
Other Languages
See (Python)
Code¶
PineRootDecimation.cxx
#include <vtkActor.h> #include <vtkCamera.h> #include <vtkConnectivityFilter.h> #include <vtkDataSetMapper.h> #include <vtkDecimatePro.h> #include <vtkMCubesReader.h> #include <vtkNamedColors.h> #include <vtkOutlineFilter.h> #include <vtkPolyData.h> #include <vtkPolyDataMapper.h> #include <vtkProperty.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h> #include <vtkRenderer.h> int main(int argc, char* argv[]) { if (argc < 2) { std::cout << "Usage: " << argv[0] << " filename" << std::endl; std::cout << "where: filename is pine_root.tri." << std::endl; return EXIT_FAILURE; } /** * Count the triangles in the polydata. * @param pd: vtkPolyData. * @return The number of triangles. */ auto NumberofTriangles = [](vtkPolyData* pd) { vtkCellArray* cells = pd->GetPolys(); vtkIdType npts = 0; vtkIdType* pts; auto numOfTriangles = 0; for (auto i = 0; i < pd->GetNumberOfPolys(); ++i) { int c = cells->GetNextCell(npts, pts); if (c == 0) { break; } // If a cell has three points it is a triangle. if (npts == 3) { numOfTriangles++; } } return numOfTriangles; }; std::string fileName = argv[1]; vtkSmartPointer<vtkNamedColors> colors = vtkSmartPointer<vtkNamedColors>::New(); // Create the pipeline. vtkSmartPointer<vtkMCubesReader> reader = vtkSmartPointer<vtkMCubesReader>::New(); reader->SetFileName(fileName.c_str()); reader->FlipNormalsOff(); reader->Update(); std::cout << "Before Decimation." << std::endl; std::cout << "There are: " << NumberofTriangles(reader->GetOutput()) << " triangles." << std::endl; vtkSmartPointer<vtkDecimatePro> deci = vtkSmartPointer<vtkDecimatePro>::New(); deci->SetInputConnection(reader->GetOutputPort()); deci->SetTargetReduction(0.9); deci->SetAbsoluteError(0.0005); deci->SetFeatureAngle(30); deci->SetErrorIsAbsolute(1); deci->AccumulateErrorOn(); // deci->SplittingOff(); deci->Update(); std::cout << "After Decimation." << std::endl; std::cout << "There are: " << NumberofTriangles(deci->GetOutput()) << " triangles." << std::endl; vtkSmartPointer<vtkConnectivityFilter> connect = vtkSmartPointer<vtkConnectivityFilter>::New(); connect->SetInputConnection(deci->GetOutputPort()); connect->SetExtractionModeToLargestRegion(); connect->Update(); std::cout << "After Connectivity." << std::endl; // Note the use of vtkPolyData::SafeDownCast here. std::cout << "There are: " << NumberofTriangles(vtkPolyData::SafeDownCast( connect->GetOutput())) << " triangles." << std::endl; vtkSmartPointer<vtkDataSetMapper> isoMapper = vtkSmartPointer<vtkDataSetMapper>::New(); isoMapper->SetInputConnection(connect->GetOutputPort()); isoMapper->ScalarVisibilityOff(); vtkSmartPointer<vtkActor> isoActor = vtkSmartPointer<vtkActor>::New(); isoActor->SetMapper(isoMapper); isoActor->GetProperty()->SetColor(colors->GetColor3d("raw_sienna").GetData()); // Get an outline of the data set for context. vtkSmartPointer<vtkOutlineFilter> outline = vtkSmartPointer<vtkOutlineFilter>::New(); outline->SetInputConnection(reader->GetOutputPort()); vtkSmartPointer<vtkPolyDataMapper> outlineMapper = vtkSmartPointer<vtkPolyDataMapper>::New(); outlineMapper->SetInputConnection(outline->GetOutputPort()); vtkSmartPointer<vtkActor> outlineActor = vtkSmartPointer<vtkActor>::New(); outlineActor->SetMapper(outlineMapper); outlineActor->GetProperty()->SetColor(colors->GetColor3d("Black").GetData()); // Create the Renderer, RenderWindow and RenderWindowInteractor. vtkSmartPointer<vtkRenderer> ren = vtkSmartPointer<vtkRenderer>::New(); vtkSmartPointer<vtkRenderWindow> renWin = vtkSmartPointer<vtkRenderWindow>::New(); renWin->AddRenderer(ren); vtkSmartPointer<vtkRenderWindowInteractor> iren = vtkSmartPointer<vtkRenderWindowInteractor>::New(); iren->SetRenderWindow(renWin); // Add the actors to the renderer, set the background and size. ren->AddActor(outlineActor); ren->AddActor(isoActor); // renWin->SetSize(750, 750); renWin->SetSize(512, 512); ren->SetBackground(colors->GetColor3d("SlateGray").GetData()); vtkCamera* cam = ren->GetActiveCamera(); cam->SetFocalPoint(40.6018, 37.2813, 50.1953); cam->SetPosition(40.6018, -280.533, 47.0172); cam->ComputeViewPlaneNormal(); cam->SetClippingRange(26.1073, 1305.36); cam->SetViewAngle(20.9219); cam->SetViewUp(0.0, 0.0, 1.0); iren->Initialize(); renWin->Render(); iren->Start(); return EXIT_SUCCESS; }
CMakeLists.txt¶
cmake_minimum_required(VERSION 3.3 FATAL_ERROR) project(PineRootDecimation) find_package(VTK COMPONENTS vtkCommonColor vtkCommonDataModel vtkFiltersCore vtkFiltersModeling vtkIOGeometry vtkInteractionStyle vtkRenderingCore vtkRenderingFreeType vtkRenderingOpenGL2 QUIET) if (NOT VTK_FOUND) message("Skipping PineRootDecimation: ${VTK_NOT_FOUND_MESSAGE}") return () endif() message (STATUS "VTK_VERSION: ${VTK_VERSION}") if (VTK_VERSION VERSION_LESS "8.90.0") # old system include(${VTK_USE_FILE}) add_executable(PineRootDecimation MACOSX_BUNDLE PineRootDecimation.cxx ) target_link_libraries(PineRootDecimation PRIVATE ${VTK_LIBRARIES}) else () # include all components add_executable(PineRootDecimation MACOSX_BUNDLE PineRootDecimation.cxx ) target_link_libraries(PineRootDecimation PRIVATE ${VTK_LIBRARIES}) # vtk_module_autoinit is needed vtk_module_autoinit( TARGETS PineRootDecimation MODULES ${VTK_LIBRARIES} ) endif ()
Download and Build PineRootDecimation¶
Click here to download PineRootDecimation and its CMakeLists.txt file. Once the tarball PineRootDecimation.tar has been downloaded and extracted,
cd PineRootDecimation/build
If VTK is installed:
cmake ..
If VTK is not installed but compiled on your system, you will need to specify the path to your VTK build:
cmake -DVTK_DIR:PATH=/home/me/vtk_build ..
Build the project:
make
and run it:
./PineRootDecimation
WINDOWS USERS
Be sure to add the VTK bin directory to your path. This will resolve the VTK dll's at run time.