Create a sphere and the cube structure that is composed of many small points. We will compute the distance to the sphere for every point. Write the distance value to point data as scalars. Set different colors for the different distance ranges.
#include <iostream>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkPolyData.h>
#include <vtkColorTransferFunction.h>
#include <vtkImplicitPolyDataDistance.h>
#include <vtkProperty.h>
#include <vtkTriangleFilter.h>
#include <vtkFloatArray.h>
#include <vtkPointData.h>
#include <vtkVertexGlyphFilter.h>
#include <vtkColorTransferFunction.h>
#include <vtkPolyDataConnectivityFilter.h>
#include <vtkLinearSubdivisionFilter.h>
#include <vtkButterflySubdivisionFilter.h>
#include <vtkNamedColors.h>
#include <vtkClipPolyData.h>
#include <vtkVertexGlyphFilter.h>
#include "point.hpp"
int main()
{
// Setup a grid
vtkSmartPointer<vtkPoints> points =
vtkSmartPointer<vtkPoints>::New();
float step = 0.1;
for(float x = - 2.0; x <= 2.0; x += step)
{
for(float y = - 2.0; y <= 2.0; y += step)
{
for(float z = - 2.0; z <= 2.0; z += step)
{
points->InsertNextPoint(x,y,z);
}
}
}
vtkSmartPointer<vtkPolyData> polyData =
vtkSmartPointer<vtkPolyData>::New();
polyData->SetPoints(points);
vtkSmartPointer<vtkSphereSource> sphereSource =
vtkSmartPointer<vtkSphereSource>::New();
sphereSource->SetCenter(0.0, 0.0, 0.0);
sphereSource->SetRadius(0.5);
sphereSource->Update();
vtkSmartPointer<vtkImplicitPolyDataDistance> implicitPolyDataDistance =
vtkSmartPointer<vtkImplicitPolyDataDistance>::New();
implicitPolyDataDistance->SetInput( sphereSource->GetOutput() );
// Add distances to each point
vtkSmartPointer<vtkFloatArray> signedDistances =
vtkSmartPointer<vtkFloatArray>::New();
signedDistances->SetNumberOfComponents(1);
signedDistances->SetName("SignedDistances");
// Evaluate the signed distance function at all of the grid points
double maxValue = VTK_DOUBLE_MIN, minValue = VTK_DOUBLE_MAX;
for(vtkIdType pointId = 0; pointId < points->GetNumberOfPoints(); ++pointId)
{
double p[3];
points->GetPoint(pointId, p);
double signedDistance = implicitPolyDataDistance->EvaluateFunction(p);
signedDistances->InsertNextValue(signedDistance);
maxValue = std::max( maxValue, signedDistance );
minValue = std::min( minValue, signedDistance );
}
polyData->GetPointData()->SetScalars( signedDistances );
std::cout << minValue << ", " << maxValue << std::endl;
vtkSmartPointer<vtkVertexGlyphFilter> vertexGlyphFilter =
vtkSmartPointer<vtkVertexGlyphFilter>::New();
vertexGlyphFilter->SetInputData( polyData );
vtkSmartPointer<vtkPolyDataMapper> signedDistanceMapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
signedDistanceMapper->SetInputConnection( vertexGlyphFilter->GetOutputPort() );
signedDistanceMapper->ScalarVisibilityOn();
double colors[5][3] = { { 0, 0, 1},
{ 0, 0.5, 0.5 },
{ 0, 1, 0 },
{ 0.5, 0.5, 0 },
{ 1, 0, 0 } };
vtkSmartPointer<vtkColorTransferFunction> colorFunction =
vtkSmartPointer<vtkColorTransferFunction>::New();
colorFunction->SetUseBelowRangeColor( true );
colorFunction->SetBelowRangeColor( colors[0] );
colorFunction->SetNanColor( colors[0] );
colorFunction->AddRGBPoint( -0.4, colors[0][0], colors[0][1], colors[0][2] );
colorFunction->AddRGBPoint( 0, colors[1][0], colors[1][1], colors[1][2] );
colorFunction->AddRGBPoint( 0.6, colors[2][0], colors[2][1], colors[2][2] );
colorFunction->AddRGBPoint( 1.5, colors[3][0], colors[3][1], colors[3][2] );
colorFunction->AddRGBPoint( 2.9, colors[4][0], colors[4][1], colors[4][2] );
colorFunction->Build();
signedDistanceMapper->SetLookupTable( colorFunction );
signedDistanceMapper->UseLookupTableScalarRangeOn();
vtkSmartPointer<vtkActor> signedDistanceActor =
vtkSmartPointer<vtkActor>::New();
signedDistanceActor->SetMapper( signedDistanceMapper );
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
renderer->AddViewProp(signedDistanceActor);
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer( renderer );
vtkSmartPointer<vtkRenderWindowInteractor> renWinInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
renWinInteractor->SetRenderWindow( renderWindow );
renderWindow->Render();
renWinInteractor->Start();
return 0;
}