WebGPU PointCloudMapper
Repository source: WebGPU_PointCloudMapper
Description¶
This example demonstrates how to use the vtkWebGPUPointCloudMapper
of the WebGPU module with colors mapped on points through scalars.
This mapper derives from [vtkPolyDataMapper](https://www.vtk.org/doc/nightly/html/classvtkPolyDataMapper.html)
and is thus used analogously. The mapper will only render points (and not 1-vertex cells) of the polydata it is given as input.
The colors can be set on points through the use of scalars.
Note that to use this example, you will need your VTK to be built with WebGPU. Building instructions can be found here.
It is expected that the illustration image of this example is flipped compared to what is rendered on screen when running the example locally.
Question
If you have a question about this example, please use the VTK Discourse Forum
Code¶
WebGPU_PointCloudMapper.cxx
#include "vtkCamera.h"
#include "vtkNew.h"
#include "vtkPointData.h"
#include "vtkPolyDataMapper.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderer.h"
#include "vtkWebGPUComputePointCloudMapper.h"
namespace {
vtkSmartPointer<vtkPolyData> CreatePointCloud()
{
vtkNew<vtkUnsignedCharArray> colors;
colors->SetNumberOfComponents(4);
vtkNew<vtkPoints> points;
// How many points in X, Y, Z direction
constexpr int sizeX = 1200;
constexpr int sizeY = 12;
constexpr int sizeZ = 1200;
// 'divider' controls the space between the points. Higher values means points
// closer together
constexpr float divider = 16.0f;
// Controls the 'width' of the cosine wave
constexpr float divider_cos = divider * 8;
// Height of the cosine wave
constexpr float cos_height_multiplier = 8;
// Variables that indicates what the maximum extent of the point is expected
// to be
constexpr float maxX = sizeX / divider;
constexpr float maxY = sizeY / divider;
constexpr float maxZ = sizeZ / divider;
for (int i = 0; i < sizeX; i++)
{
for (int j = 0; j < sizeY; j++)
{
for (int k = 0; k < sizeZ; k++)
{
int pointIndex = k + j * sizeZ + i * sizeY * sizeZ;
// Using rand() here to jitter the points a little bit to reduce visible
// aliasing
double pointX = i / divider + rand() / (float)RAND_MAX;
double pointZ = k / divider + rand() / (float)RAND_MAX;
double cosX = std::cos(i / divider_cos);
double sinZ = std::sin(k / divider_cos);
double pointY = cosX * cos_height_multiplier * sinZ + j / 10.0f;
points->InsertNextPoint(pointX, pointY, pointZ);
// Inserting the R, G, B components to create color gradients
colors->InsertComponent(
pointIndex, 0,
static_cast<unsigned char>(i / divider / maxX * 255.0f));
colors->InsertComponent(
pointIndex, 1,
static_cast<unsigned char>(j / divider / maxY * 255.0f));
colors->InsertComponent(
pointIndex, 2,
static_cast<unsigned char>(k / divider / maxZ * 127.0f + 127.0f));
colors->InsertComponent(pointIndex, 3, 255);
}
}
}
vtkSmartPointer<vtkPolyData> polydata;
polydata = vtkSmartPointer<vtkPolyData>::New();
polydata->SetPoints(points);
polydata->GetPointData()->SetScalars(colors);
return polydata;
}
} // namespace
//------------------------------------------------------------------------------
int main(int argc, char* argv[])
{
vtkNew<vtkRenderWindow> renWin;
renWin->SetWindowName(__func__);
renWin->SetMultiSamples(0);
renWin->SetSize(1280, 720);
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
renderer->SetBackground(0.2, 0.3, 0.4);
// Setting the camera to a nice position for looking at the point cloud
renderer->GetActiveCamera()->SetPosition(150.594, 37.6722, 40.0177);
renderer->GetActiveCamera()->SetFocalPoint(38.6725, -1.44734, 37.6991);
renWin->AddRenderer(renderer);
vtkSmartPointer<vtkPolyData> polydata = CreatePointCloud();
// Center the camera on the point cloud
renderer->ResetCamera(polydata->GetBounds());
// Create the mapper and set its input as any other poly data mapper
vtkNew<vtkWebGPUComputePointCloudMapper> pointCloudMapper;
pointCloudMapper->SetInputData(polydata);
vtkNew<vtkActor> actor;
actor->SetMapper(pointCloudMapper);
renderer->AddActor(actor);
// Start an interactor to interact with the point cloud
vtkNew<vtkRenderWindowInteractor> iren;
iren->SetRenderWindow(renWin);
iren->Start();
return 0;
}
CMakeLists.txt¶
cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
project(WebGPU_PointCloudMapper)
find_package(VTK COMPONENTS
CommonCore
CommonDataModel
InteractionStyle
RenderingContextOpenGL2
RenderingCore
RenderingFreeType
RenderingGL2PSOpenGL2
RenderingOpenGL2
)
if (NOT VTK_FOUND)
message(FATAL_ERROR "WebGPU_PointCloudMapper: Unable to find the VTK build folder.")
endif()
# Prevent a "command line is too long" failure in Windows.
set(CMAKE_NINJA_FORCE_RESPONSE_FILE "ON" CACHE BOOL "Force Ninja to use response files.")
add_executable(WebGPU_PointCloudMapper MACOSX_BUNDLE WebGPU_PointCloudMapper.cxx )
target_link_libraries(WebGPU_PointCloudMapper PRIVATE ${VTK_LIBRARIES}
)
# vtk_module_autoinit is needed
vtk_module_autoinit(
TARGETS WebGPU_PointCloudMapper
MODULES ${VTK_LIBRARIES}
)
Download and Build WebGPU_PointCloudMapper¶
Click here to download WebGPU_PointCloudMapper and its CMakeLists.txt file. Once the tarball WebGPU_PointCloudMapper.tar has been downloaded and extracted,
cd WebGPU_PointCloudMapper/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:
./WebGPU_PointCloudMapper
WINDOWS USERS
Be sure to add the VTK bin directory to your path. This will resolve the VTK dll's at run time.