DepthSortPolyData
Repository source: DepthSortPolyData
Description¶
- Contributed by: Lars Friedrich
This is a C++-port of the VTK example '''DepthSort.py''' found in [VTKSourceDir/Examples/VisualizationAlgorithms/Python(https://gitlab.kitware.com/vtk/vtk/blob/master/Examples/VisualizationAlgorithms/Python/DepthSort.py). It was slightly modified. It generates 5 spheres with configurable PHI and THETA resolution. The spheres overlap. Therefore, correct blending and visualization in general requires depth sorting of the underlying polygons which will not happen when simply using a poly data mapper. Depth sorting can be achieved by connecting a vtkDepthSortPolyData filter to the mapper instead of the pure poly data.
Program Usage¶
Usage: ./DepthSortPolyData DepthSortFlag ThetaResolution PhiResolution ScalarVisibilityFlag*
DepthSortFlag ... activate/deactivate the depth sorting algorithm
ThetaResolution ... THETA resolution for the spheres
PhiResolution ... PHI resolution for the spheres
ScalarVisibilityFlag ... show/hide the found depth values as scalars
Example calls:
./DepthSortPolyData 0 100 100 0
... will render the spheres 'as usual' (without depth sorting); in general you will be confronted with situations (specific view directions) where you cannot determine whether a small sphere is behind or in front of the big center sphere
./DepthSortPolyData 1 100 100 0
... will render the spheres using depth sorting; the sphere depth order should now be visually traceable
./DepthSortPolyData 1 100 100 1
... will render the spheres using depth sorting; the depth values are mapped to the spheres and renderd on the surfaces
Using higher PHI/THETA resolutions shows how depth sorting reduces the frame rate.
Question
If you have a question about this example, please use the VTK Discourse Forum
Code¶
DepthSortPolyData.cxx
#include <vtkActor.h>
#include <vtkAppendPolyData.h>
#include <vtkCamera.h>
#include <vtkDepthSortPolyData.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSphereSource.h>
int main(int argc, char* argv[])
{
if (argc != 5)
{
std::cerr << "Usage: " << argv[0] << " DepthSortFlag ThetaResolution "
<< " PhiResolution ScalarVisibilityFlag" << std::endl;
std::cerr << "1 100 100 0" << std::endl;
return EXIT_FAILURE;
}
bool doDepthSort = atoi(argv[1]) == 1;
int theta = atoi(argv[2]);
int phi = atoi(argv[3]);
bool scalarVisibility = atoi(argv[4]) == 1;
vtkNew<vtkNamedColors> colors;
// Create a bunch of spheres that overlap and cannot be easily arranged
// so that the blending works without sorting. They are appended into a
// single vtkPolyData because the filter only sorts within a single
// vtkPolyData input.
vtkNew<vtkAppendPolyData> appendData;
for (int i = 0; i < 5; i++)
{
vtkNew<vtkSphereSource> sphereSource;
sphereSource->SetThetaResolution(theta);
sphereSource->SetPhiResolution(phi);
sphereSource->SetRadius(
0.5); // all sphere except the center one should have radius = 0.5
switch (i)
{
case 0:
sphereSource->SetRadius(1);
sphereSource->SetCenter(0, 0, 0);
break;
case 1:
sphereSource->SetCenter(1, 0, 0);
break;
case 2:
sphereSource->SetCenter(-1, 0, 0);
break;
case 3:
sphereSource->SetCenter(0, 1, 0);
break;
case 4:
sphereSource->SetCenter(0, -1, 0);
break;
}
sphereSource->Update();
appendData->AddInputConnection(sphereSource->GetOutputPort());
}
// The dephSort object is set up to generate scalars representing
// the sort depth. A camera is assigned for the sorting. The camera
// defines the sort vector (position and focal point).
vtkNew<vtkCamera> camera;
vtkNew<vtkDepthSortPolyData> depthSort;
depthSort->SetInputConnection(appendData->GetOutputPort());
depthSort->SetDirectionToBackToFront();
depthSort->SetVector(1, 1, 1);
depthSort->SetCamera(camera);
depthSort->SortScalarsOn();
depthSort->Update();
vtkNew<vtkPolyDataMapper> mapper;
if (doDepthSort)
{
mapper->SetInputConnection(depthSort->GetOutputPort());
}
else
{
mapper->SetInputConnection(appendData->GetOutputPort());
}
mapper->SetScalarVisibility(scalarVisibility);
if (scalarVisibility)
{
mapper->SetScalarRange(0, depthSort->GetOutput()->GetNumberOfCells());
}
vtkNew<vtkActor> actor;
actor->SetMapper(mapper);
actor->GetProperty()->SetOpacity(0.5);
actor->GetProperty()->SetColor(colors->GetColor3d("Crimson").GetData());
actor->RotateX(-72); // put the object in a position where it is easy
// to see different overlapping regions
// If an Prop3D is supplied, then its transformation matrix is taken
// into account during sorting.
depthSort->SetProp3D(actor);
// Create the RenderWindow, Renderer and both Actors
vtkNew<vtkRenderer> renderer;
renderer->SetActiveCamera(camera);
vtkNew<vtkRenderWindow> renderWindow;
renderWindow->AddRenderer(renderer);
renderWindow->SetWindowName("DepthSortPolyData");
vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;
renderWindowInteractor->SetRenderWindow(renderWindow);
// Add the actors to the renderer, set the background and size
renderer->AddActor(actor);
renderer->SetBackground(colors->GetColor3d("SlateGray").GetData());
renderWindow->SetSize(600, 400);
renderer->ResetCamera();
renderer->GetActiveCamera()->Zoom(2.2); // so the object is larger
renderWindowInteractor->Initialize();
renderWindow->Render();
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}
CMakeLists.txt¶
cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
project(DepthSortPolyData)
find_package(VTK COMPONENTS
CommonColor
CommonCore
FiltersCore
FiltersHybrid
FiltersSources
InteractionStyle
RenderingContextOpenGL2
RenderingCore
RenderingFreeType
RenderingGL2PSOpenGL2
RenderingOpenGL2
)
if (NOT VTK_FOUND)
message(FATAL_ERROR "DepthSortPolyData: 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(DepthSortPolyData MACOSX_BUNDLE DepthSortPolyData.cxx )
target_link_libraries(DepthSortPolyData PRIVATE ${VTK_LIBRARIES}
)
# vtk_module_autoinit is needed
vtk_module_autoinit(
TARGETS DepthSortPolyData
MODULES ${VTK_LIBRARIES}
)
Download and Build DepthSortPolyData¶
Click here to download DepthSortPolyData and its CMakeLists.txt file. Once the tarball DepthSortPolyData.tar has been downloaded and extracted,
cd DepthSortPolyData/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:
./DepthSortPolyData
WINDOWS USERS
Be sure to add the VTK bin directory to your path. This will resolve the VTK dll's at run time.