Skip to content

Planes

vtk-examples/Cxx/GeometricObjects/Planes


Other languages

See (Python), (CSharp)

Question

If you have a question about this example, please use the VTK Discourse Forum

Code

Planes.cxx

#include <vtkActor.h>
#include <vtkActor2D.h>
#include <vtkCamera.h>
#include <vtkHull.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPlanes.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkTextMapper.h>
#include <vtkTextProperty.h>

#include <string>
#include <vector>

int main(int, char*[])
{
  vtkNew<vtkNamedColors> colors;

  // These are the two methods we will use.
  std::vector<std::string> titles{"Using frustum planes", "Using bounds"};
  std::vector<vtkSmartPointer<vtkPlanes>> planes;
  for (auto i = 0; i < titles.size(); ++i)
  {
    planes.push_back(vtkSmartPointer<vtkPlanes>::New());
  }

  // Using frustum planes.
  vtkNew<vtkCamera> camera;
  double planesArray[24];
  camera->GetFrustumPlanes(1, planesArray);
  planes[0]->SetFrustumPlanes(planesArray);

  // Using bounds.
  vtkNew<vtkSphereSource> sphereSource;
  sphereSource->Update();
  double bounds[6];
  sphereSource->GetOutput()->GetBounds(bounds);
  planes[1]->SetBounds(bounds);

  // At this point we have the planes created by both of the methods above.
  // You can do whatever you want with them.

  // For visualisation we will produce an n-sided convex hull
  // and visualise it.

  // Create a common text property.
  vtkNew<vtkTextProperty> textProperty;
  textProperty->SetFontSize(16);
  textProperty->SetJustificationToCentered();

  // Create the render window and interactor.
  vtkNew<vtkRenderWindow> renWin;
  renWin->SetWindowName("Planes");
  vtkNew<vtkRenderWindowInteractor> iRen;
  iRen->SetRenderWindow(renWin);

  std::vector<vtkSmartPointer<vtkHull>> hulls;
  std::vector<vtkSmartPointer<vtkPolyData>> pds;
  std::vector<vtkSmartPointer<vtkPolyDataMapper>> mappers;
  std::vector<vtkSmartPointer<vtkActor>> actors;
  std::vector<vtkSmartPointer<vtkTextMapper>> textMappers;
  std::vector<vtkSmartPointer<vtkActor2D>> textActors;
  std::vector<vtkSmartPointer<vtkRenderer>> renderers;

  for (auto i = 0; i < titles.size(); ++i)
  {
    hulls.push_back(vtkSmartPointer<vtkHull>::New());
    hulls[i]->SetPlanes(planes[i]);

    pds.push_back(vtkSmartPointer<vtkPolyData>::New());

    // To generate the convex hull we supply a vtkPolyData object and a bounding
    // box.
    // We define the bounding box to be where we expect the resulting polyhedron
    // to lie.
    // Make it a generous fit as it is only used to create the initial
    // polygons that are eventually clipped.
    hulls[i]->GenerateHull(pds[i], -200, 200, -200, 200, -200, 200);

    mappers.push_back(vtkSmartPointer<vtkPolyDataMapper>::New());
    mappers[i]->SetInputData(pds[i]);

    actors.push_back(vtkSmartPointer<vtkActor>::New());
    actors[i]->SetMapper(mappers[i]);
    actors[i]->GetProperty()->SetColor(
        colors->GetColor3d("Moccasin").GetData());
    actors[i]->GetProperty()->SetSpecular(0.8);
    actors[i]->GetProperty()->SetSpecularPower(30);

    textMappers.push_back(vtkSmartPointer<vtkTextMapper>::New());
    textMappers[i]->SetInput(titles[i].c_str());
    textMappers[i]->SetTextProperty(textProperty);

    textActors.push_back(vtkSmartPointer<vtkActor2D>::New());
    textActors[i]->SetMapper(textMappers[i]);
    textActors[i]->SetPosition(120, 16);

    renderers.push_back(vtkSmartPointer<vtkRenderer>::New());
    renderers[i]->AddActor(actors[i]);
    renderers[i]->AddViewProp(textActors[i]);

    renWin->AddRenderer(renderers[i]);
  }

  // Setup the viewports
  auto xGridDimensions = 2;
  auto yGridDimensions = 1;
  auto rendererSize = 300;
  renWin->SetSize(rendererSize * xGridDimensions,
                  rendererSize * yGridDimensions);
  for (auto row = 0; row < yGridDimensions; ++row)
  {
    for (auto col = 0; col < xGridDimensions; ++col)
    {
      auto index = row * xGridDimensions + col;

      // (xmin, ymin, xmax, ymax)
      double viewport[4] = {
          static_cast<double>(col) / xGridDimensions,
          static_cast<double>(yGridDimensions - (row + 1)) / yGridDimensions,
          static_cast<double>(col + 1) / xGridDimensions,
          static_cast<double>(yGridDimensions - row) / yGridDimensions};
      if (index > (actors.size() - 1))
      {
        // Add a renderer even if there is no actor.
        // This makes the render window background all the same color.
        vtkSmartPointer<vtkRenderer> ren = vtkSmartPointer<vtkRenderer>::New();
        ren->SetBackground(colors->GetColor3d("DarkSlateGray").GetData());
        ren->SetViewport(viewport);
        renWin->AddRenderer(ren);
        continue;
      }

      renderers[index]->SetViewport(viewport);
      renderers[index]->SetBackground(
          colors->GetColor3d("DarkSlateGray").GetData());
      renderers[index]->ResetCamera();
      renderers[index]->GetActiveCamera()->Azimuth(30);
      renderers[index]->GetActiveCamera()->Elevation(-30);
      renderers[index]->ResetCameraClippingRange();
    }
  }

  iRen->Initialize();
  renWin->Render();
  iRen->Start();

  return EXIT_SUCCESS;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.12 FATAL_ERROR)

project(Planes)

find_package(VTK COMPONENTS 
  CommonColor
  CommonCore
  CommonDataModel
  FiltersCore
  FiltersSources
  InteractionStyle
  RenderingContextOpenGL2
  RenderingCore
  RenderingFreeType
  RenderingGL2PSOpenGL2
  RenderingOpenGL2
)

if (NOT VTK_FOUND)
  message(FATAL_ERROR "Planes: 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(Planes MACOSX_BUNDLE Planes.cxx )
  target_link_libraries(Planes PRIVATE ${VTK_LIBRARIES}
)
# vtk_module_autoinit is needed
vtk_module_autoinit(
  TARGETS Planes
  MODULES ${VTK_LIBRARIES}
)

Download and Build Planes

Click here to download Planes and its CMakeLists.txt file. Once the tarball Planes.tar has been downloaded and extracted,

cd Planes/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:

./Planes

WINDOWS USERS

Be sure to add the VTK bin directory to your path. This will resolve the VTK dll's at run time.