FindCellIntersections
VTKExamples/Cxx/VisualizationAlgorithms/FindCellIntersections
Description
This example shows how to use cell locator's FindCellsAlongLine method to visualize the cells that are intersected in an unstructured grid. The example uses the data file: https://github.com/lorensen/VTKWikiExamples/raw/master/Testing/Data/Disc_BiQuadraticQuads_0_0.vtu
Code
FindCellIntersections.cxx
#include <vtkSmartPointer.h>
#include <vtkCellLocator.h>
#include <vtkXMLUnstructuredGridReader.h>
#include <vtkDataObject.h>
#include <vtkUnstructuredGrid.h>
#include <vtkIdList.h>
#include <vtkCellArray.h>
#include <vtkUnsignedCharArray.h>
#include <vtkCellData.h>
#include <vtkLineSource.h>
#include <vtkShrinkFilter.h>
#include <vtkDataSetSurfaceFilter.h>
#include <vtkDataSetMapper.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkProperty.h>
#include <vtkCamera.h>
int main (int argc, char *argv[])
{
if (argc < 2)
{
std::cout << "Usage: " << argv[0] << " filename.vtu" << std::endl;
return EXIT_FAILURE;
}
// Get the filename from the command line
std::string inputFilename = argv[1];
// Read a xml unstructured grid dataset
vtkSmartPointer<vtkXMLUnstructuredGridReader> reader =
vtkSmartPointer<vtkXMLUnstructuredGridReader>::New();
reader->SetFileName(inputFilename.c_str());
reader->Update();
// The line goes through the center of the data and runs along the x axis
double center[3];
reader->GetOutput()->GetCenter(center);
double bounds[6];
reader->GetOutput()->GetBounds(bounds);
double startRay[3];
startRay[0] = bounds[0] - center[0];
startRay[1] = center[1];
startRay[2] = center[2];
double endRay[3];
endRay[0] = bounds[1] + center[0];
endRay[1] = center[1];
endRay[2] = center[2];
std::cout << "center: "
<< center[0] << ", "
<< center[1] << ", "
<< center[2] << std::endl;
std::cout << "startRay: "
<< startRay[0] << ", "
<< startRay[1] << ", "
<< startRay[2] << std::endl;
std::cout << "endRay: "
<< endRay[0] << ", "
<< endRay[1] << ", "
<< endRay[2] << std::endl;
// Initialize all of the cell data colors
vtkSmartPointer<vtkUnsignedCharArray> cellData =
vtkSmartPointer<vtkUnsignedCharArray>::New();
cellData->SetNumberOfComponents(3);
cellData->SetNumberOfTuples(reader->GetOutput()->GetNumberOfCells());
reader->GetOutput()->GetCellData()->SetScalars(cellData);
for (int i = 0; i < cellData->GetNumberOfTuples(); ++i)
{
float rgb[3];
rgb[0] = 227.0; rgb[1] = 207.0; rgb[2] = 87.0; // banana
cellData->InsertTuple(i, rgb);
}
// Find the cells that intersect the line and color those cells
vtkSmartPointer<vtkIdList> cellIds =
vtkSmartPointer<vtkIdList>::New();
vtkSmartPointer<vtkCellLocator> locator =
vtkSmartPointer<vtkCellLocator>::New();
locator->SetDataSet(reader->GetOutput());
locator->BuildLocator();
locator->FindCellsAlongLine(startRay, endRay, .001, cellIds);
for (vtkIdType i = 0; i < cellIds->GetNumberOfIds(); ++i)
{
float rgb[3];
rgb[0] = 255; rgb[1] = 99; rgb[2] = 71; // tomato
cellData->InsertTuple(cellIds->GetId(i), rgb);
}
// Shrink each cell to make them visible
vtkSmartPointer<vtkShrinkFilter> shrink =
vtkSmartPointer<vtkShrinkFilter>::New();
shrink->SetInputConnection(reader->GetOutputPort());
shrink->SetShrinkFactor(.95);
// Convert the cells to polydata
vtkSmartPointer<vtkDataSetSurfaceFilter> surface =
vtkSmartPointer<vtkDataSetSurfaceFilter>::New();
surface->SetInputConnection(shrink->GetOutputPort());
surface->SetNonlinearSubdivisionLevel(2);
surface->Update();
// Create a line
vtkSmartPointer<vtkLineSource> lineSource =
vtkSmartPointer<vtkLineSource>::New();
lineSource->SetPoint1(startRay);
lineSource->SetPoint2(endRay);
vtkSmartPointer<vtkPolyDataMapper> lineMapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
lineMapper->SetInputConnection(lineSource->GetOutputPort());
vtkSmartPointer<vtkActor> lineActor =
vtkSmartPointer<vtkActor>::New();
lineActor->SetMapper(lineMapper);
// Render the results
vtkSmartPointer<vtkPolyDataMapper> mapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(surface->GetOutputPort());
mapper->ScalarVisibilityOn();
mapper->SetScalarModeToUseCellData();
vtkSmartPointer<vtkActor> actor =
vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(actor);
renderer->AddActor(lineActor);
renderer->SetBackground(.2, .3, .4);
// Make an oblique view
renderer->GetActiveCamera()->Azimuth(30);
renderer->GetActiveCamera()->Elevation(30);
renderer->ResetCamera();
vtkSmartPointer<vtkRenderWindow> renWin =
vtkSmartPointer<vtkRenderWindow>::New();
vtkSmartPointer<vtkRenderWindowInteractor>
iren = vtkSmartPointer<vtkRenderWindowInteractor>::New();
iren->SetRenderWindow(renWin);
renWin->AddRenderer(renderer);
renWin->SetSize(640, 480);
renWin->Render();
iren->Start();
return EXIT_SUCCESS;
}
CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
PROJECT(FindCellIntersections)
find_package(VTK REQUIRED)
include(${VTK_USE_FILE})
add_executable(FindCellIntersections MACOSX_BUNDLE FindCellIntersections.cxx)
target_link_libraries(FindCellIntersections ${VTK_LIBRARIES})
Download and Build FindCellIntersections
Click here to download FindCellIntersections and its CMakeLists.txt file. Once the tarball FindCellIntersections.tar has been downloaded and extracted,
cd FindCellIntersections/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:
./FindCellIntersections
WINDOWS USERS PLEASE NOTE: Be sure to add the VTK bin directory to your path. This will resolve the VTK dll's at run time.