LoopBooleanPolyDataFilter
VTKExamples/Cxx/PolyData/LoopBooleanPolyDataFilter
Description¶
The vtkLoopBooleanPolyDataFilter works best with "clean" data, so this examples first runs vtkTriangleFilter and then vtkCleanPolyData.
This example can be run in three ways:
-
LoopBooleanPolyDataFilter - Computes the intersection of two spheres
-
LoopBooleanPolyDataFilter intersection|difference|union - Computes the intersection(difference or union) of two spheres
-
LoopBooleanPolyDataFilter input1.vtk intersection|difference|union input2.vtk - Computes the intersection(difference or union) of two vtkPolyData's
Seealso
BooleanOperationPolyDataFilter uses an alternative algorithm to do the boolean operations.
Code¶
LoopBooleanPolyDataFilter.cxx
#include <vtkSmartPointer.h> #include <vtkLoopBooleanPolyDataFilter.h> #include <vtkCleanPolyData.h> #include <vtkTriangleFilter.h> #include <vtkActor.h> #include <vtkPolyDataMapper.h> #include <vtkProperty.h> #include <vtkRenderer.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h> #include <vtkNamedColors.h> #include <vtkBYUReader.h> #include <vtkOBJReader.h> #include <vtkPLYReader.h> #include <vtkPolyDataReader.h> #include <vtkSTLReader.h> #include <vtkXMLPolyDataReader.h> #include <vtkSphereSource.h> #include <vtksys/SystemTools.hxx> #include <vtkCamera.h> namespace { vtkSmartPointer<vtkPolyData> ReadPolyData(const char *fileName); void PositionCamera(vtkSmartPointer<vtkRenderer> &renderer, double *viewUp, double *position); } int main(int argc, char *argv[]) { vtkSmartPointer<vtkPolyData> input1; vtkSmartPointer<vtkPolyData> input2; std::string operation("intersection"); if (argc == 4) { vtkSmartPointer<vtkPolyData> poly1; poly1 = ReadPolyData(argv[1]); vtkSmartPointer<vtkTriangleFilter> tri1 = vtkSmartPointer<vtkTriangleFilter>::New(); tri1->SetInputData(poly1); vtkSmartPointer<vtkCleanPolyData> clean1 = vtkSmartPointer<vtkCleanPolyData>::New(); clean1->SetInputConnection(tri1->GetOutputPort()); clean1->Update(); input1 = clean1->GetOutput(); vtkSmartPointer<vtkPolyData> poly2; poly2 = ReadPolyData(argv[3]); vtkSmartPointer<vtkTriangleFilter> tri2 = vtkSmartPointer<vtkTriangleFilter>::New(); tri2->SetInputData(poly2); tri2->Update(); vtkSmartPointer<vtkCleanPolyData> clean2 = vtkSmartPointer<vtkCleanPolyData>::New(); clean2->SetInputConnection(tri2->GetOutputPort()); clean2->Update(); input2 = clean2->GetOutput(); operation = argv[2]; } else { vtkSmartPointer<vtkSphereSource> sphereSource1 = vtkSmartPointer<vtkSphereSource>::New(); sphereSource1->SetCenter(.25, 0, 0); sphereSource1->SetPhiResolution(21); sphereSource1->SetThetaResolution(21); sphereSource1->Update(); input1 = sphereSource1->GetOutput(); vtkSmartPointer<vtkSphereSource> sphereSource2 = vtkSmartPointer<vtkSphereSource>::New(); sphereSource2->Update(); input2 = sphereSource2->GetOutput(); if (argc == 2) { operation = argv[1]; } } vtkSmartPointer<vtkNamedColors> colors = vtkSmartPointer<vtkNamedColors>::New(); vtkSmartPointer<vtkPolyDataMapper> input1Mapper = vtkSmartPointer<vtkPolyDataMapper>::New(); input1Mapper->SetInputData( input1 ); input1Mapper->ScalarVisibilityOff(); vtkSmartPointer<vtkActor> input1Actor = vtkSmartPointer<vtkActor>::New(); input1Actor->SetMapper( input1Mapper ); input1Actor->GetProperty()->SetDiffuseColor(colors->GetColor3d("Tomato").GetData()); input1Actor->GetProperty()->SetSpecular(.6); input1Actor->GetProperty()->SetSpecularPower(20); input1Actor->SetPosition( input1->GetBounds()[1]-input1->GetBounds()[0], 0, 0); vtkSmartPointer<vtkPolyDataMapper> input2Mapper = vtkSmartPointer<vtkPolyDataMapper>::New(); input2Mapper->SetInputData( input2 ); input2Mapper->ScalarVisibilityOff(); vtkSmartPointer<vtkActor> input2Actor = vtkSmartPointer<vtkActor>::New(); input2Actor->SetMapper( input2Mapper ); input2Actor->GetProperty()->SetDiffuseColor(colors->GetColor3d("Mint").GetData()); input2Actor->GetProperty()->SetSpecular(.6); input2Actor->GetProperty()->SetSpecularPower(20); input2Actor->SetPosition( -(input1->GetBounds()[1]-input1->GetBounds()[0]), 0, 0); vtkSmartPointer<vtkLoopBooleanPolyDataFilter> booleanOperation = vtkSmartPointer<vtkLoopBooleanPolyDataFilter>::New(); if (operation == "union") { booleanOperation->SetOperationToUnion(); } else if (operation == "intersection") { booleanOperation->SetOperationToIntersection(); } else if (operation == "difference") { booleanOperation->SetOperationToDifference(); } else { std::cout << "Unknown operation: " << operation << std::endl; return EXIT_FAILURE; } booleanOperation->SetInputData( 0, input1 ); booleanOperation->SetInputData( 1, input2 ); vtkSmartPointer<vtkPolyDataMapper> booleanOperationMapper = vtkSmartPointer<vtkPolyDataMapper>::New(); booleanOperationMapper->SetInputConnection( booleanOperation->GetOutputPort() ); booleanOperationMapper->ScalarVisibilityOff(); vtkSmartPointer<vtkActor> booleanOperationActor = vtkSmartPointer<vtkActor>::New(); booleanOperationActor->SetMapper( booleanOperationMapper ); booleanOperationActor->GetProperty()->SetDiffuseColor(colors->GetColor3d("Banana").GetData()); booleanOperationActor->GetProperty()->SetSpecular(.6); booleanOperationActor->GetProperty()->SetSpecularPower(20); vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New(); renderer->AddViewProp(input1Actor); renderer->AddViewProp(input2Actor); renderer->AddViewProp(booleanOperationActor); renderer->SetBackground(colors->GetColor3d("Silver").GetData()); vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New(); renderWindow->AddRenderer( renderer ); renderWindow->SetSize(640, 480); double viewUp[3] = {0.0, 0.0, 1.0}; double position[3] = {0.0, -1.0, 0.0}; PositionCamera(renderer, viewUp, position); renderer->GetActiveCamera()->Dolly(1.5); renderer->ResetCameraClippingRange(); vtkSmartPointer<vtkRenderWindowInteractor> renWinInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New(); renWinInteractor->SetRenderWindow( renderWindow ); renderWindow->Render(); renWinInteractor->Start(); return EXIT_SUCCESS; } namespace { vtkSmartPointer<vtkPolyData> ReadPolyData(const char *fileName) { vtkSmartPointer<vtkPolyData> polyData; std::string extension = vtksys::SystemTools::GetFilenameExtension(std::string(fileName)); if (extension == ".ply") { vtkSmartPointer<vtkPLYReader> reader = vtkSmartPointer<vtkPLYReader>::New(); reader->SetFileName (fileName); reader->Update(); polyData = reader->GetOutput(); } else if (extension == ".vtp") { vtkSmartPointer<vtkXMLPolyDataReader> reader = vtkSmartPointer<vtkXMLPolyDataReader>::New(); reader->SetFileName (fileName); reader->Update(); polyData = reader->GetOutput(); } else if (extension == ".obj") { vtkSmartPointer<vtkOBJReader> reader = vtkSmartPointer<vtkOBJReader>::New(); reader->SetFileName (fileName); reader->Update(); polyData = reader->GetOutput(); } else if (extension == ".stl") { vtkSmartPointer<vtkSTLReader> reader = vtkSmartPointer<vtkSTLReader>::New(); reader->SetFileName (fileName); reader->Update(); polyData = reader->GetOutput(); } else if (extension == ".vtk") { vtkSmartPointer<vtkPolyDataReader> reader = vtkSmartPointer<vtkPolyDataReader>::New(); reader->SetFileName (fileName); reader->Update(); polyData = reader->GetOutput(); } else if (extension == ".g") { vtkSmartPointer<vtkBYUReader> reader = vtkSmartPointer<vtkBYUReader>::New(); reader->SetGeometryFileName (fileName); reader->Update(); polyData = reader->GetOutput(); } else { vtkSmartPointer<vtkSphereSource> source = vtkSmartPointer<vtkSphereSource>::New(); source->Update(); polyData = source->GetOutput(); } return polyData; } void PositionCamera(vtkSmartPointer<vtkRenderer> &renderer, double *viewUp, double *position) { renderer->GetActiveCamera()->SetFocalPoint(0.0, 0.0, 0.0); renderer->GetActiveCamera()->SetViewUp(viewUp); renderer->GetActiveCamera()->SetPosition(position); renderer->ResetCamera(); return; } }
CMakeLists.txt¶
cmake_minimum_required(VERSION 3.3 FATAL_ERROR) project(LoopBooleanPolyDataFilter) find_package(VTK COMPONENTS vtkCommonColor vtkCommonCore vtkFiltersCore vtkFiltersGeneral vtkFiltersSources vtkIOGeometry vtkIOLegacy vtkIOPLY vtkIOXML vtkInteractionStyle vtkRenderingCore vtkRenderingFreeType vtkRenderingOpenGL2 QUIET) if (NOT VTK_FOUND) message("Skipping LoopBooleanPolyDataFilter: ${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(LoopBooleanPolyDataFilter MACOSX_BUNDLE LoopBooleanPolyDataFilter.cxx ) target_link_libraries(LoopBooleanPolyDataFilter PRIVATE ${VTK_LIBRARIES}) else () # include all components add_executable(LoopBooleanPolyDataFilter MACOSX_BUNDLE LoopBooleanPolyDataFilter.cxx ) target_link_libraries(LoopBooleanPolyDataFilter PRIVATE ${VTK_LIBRARIES}) # vtk_module_autoinit is needed vtk_module_autoinit( TARGETS LoopBooleanPolyDataFilter MODULES ${VTK_LIBRARIES} ) endif ()
Download and Build LoopBooleanPolyDataFilter¶
Click here to download LoopBooleanPolyDataFilter and its CMakeLists.txt file. Once the tarball LoopBooleanPolyDataFilter.tar has been downloaded and extracted,
cd LoopBooleanPolyDataFilter/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:
./LoopBooleanPolyDataFilter
WINDOWS USERS
Be sure to add the VTK bin directory to your path. This will resolve the VTK dll's at run time.