Skip to content

QuadricVisualization

vtk-examples/Cxx/Visualization/QuadricVisualization


Description

Visualizing a quadric function F(x,y,z) = c

This example is inspired by the Figure 4-1, page 83, in the VTK Book.

Info

See Figure 4-1 in Chapter 4 the VTK Textbook.

Other languages

See (Python)

Question

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

Code

QuadricVisualization.cxx

#include <vtkActor.h>
#include <vtkAppendFilter.h>
#include <vtkCamera.h>
#include <vtkContourFilter.h>
#include <vtkDataSetMapper.h>
#include <vtkExtractVOI.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkOutlineFilter.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkQuadric.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSampleFunction.h>
#include <vtkUnstructuredGrid.h>

namespace {
void CreateIsosurface(vtkSampleFunction* function, vtkActor* actor,
                      unsigned int numberOfContours = 5);

void CreatePlanes(vtkSampleFunction* function, vtkActor* actor,
                  unsigned numberOfPlanes);

void CreateContours(vtkSampleFunction* function, vtkActor* actor,
                    unsigned numberOfPlanes, unsigned numberOfContours);

void CreateOutline(vtkSampleFunction* function, vtkActor* actor);

} // namespace

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

  vtkNew<vtkRenderer> renderer;

  vtkNew<vtkRenderWindow> renderWindow;
  renderWindow->AddRenderer(renderer);

  vtkNew<vtkRenderWindowInteractor> interactor;
  interactor->SetRenderWindow(renderWindow);
  renderWindow->SetSize(640, 480);

  //
  // Create surface of implicit function
  //
  // double range[2];

  // Sample quadric function
  vtkNew<vtkQuadric> quadric;
  quadric->SetCoefficients(1, 2, 3, 0, 1, 0, 0, 0, 0, 0);

  vtkNew<vtkSampleFunction> sample;
  sample->SetSampleDimensions(25, 25, 25);
  sample->SetImplicitFunction(quadric);

  vtkNew<vtkActor> isoActor;
  CreateIsosurface(sample, isoActor);
  vtkNew<vtkActor> outlineIsoActor;
  CreateOutline(sample, outlineIsoActor);

  vtkNew<vtkActor> planesActor;
  CreatePlanes(sample, planesActor, 3);
  vtkNew<vtkActor> outlinePlanesActor;
  CreateOutline(sample, outlinePlanesActor);
  planesActor->AddPosition(isoActor->GetBounds()[0] * 2.0, 0, 0);
  outlinePlanesActor->AddPosition(isoActor->GetBounds()[0] * 2.0, 0, 0);

  vtkNew<vtkActor> contourActor;
  CreateContours(sample, contourActor, 3, 15);
  vtkNew<vtkActor> outlineContourActor;
  CreateOutline(sample, outlineContourActor);
  contourActor->AddPosition(isoActor->GetBounds()[0] * 4.0, 0, 0);
  outlineContourActor->AddPosition(isoActor->GetBounds()[0] * 4.0, 0, 0);

  renderer->AddActor(planesActor);
  renderer->AddActor(outlinePlanesActor);
  renderer->AddActor(contourActor);
  renderer->AddActor(outlineContourActor);
  renderer->AddActor(isoActor);
  renderer->AddActor(outlineIsoActor);

  renderer->TwoSidedLightingOn();

  renderer->SetBackground(colors->GetColor3d("SlateGray").GetData());

  // Try to set camera to match figure on book
  renderer->GetActiveCamera()->SetPosition(0, -1, 0);
  renderer->GetActiveCamera()->SetFocalPoint(0, 0, 0);
  renderer->GetActiveCamera()->SetViewUp(0, 0, -1);
  renderer->ResetCamera();
  renderer->GetActiveCamera()->Elevation(20);
  renderer->GetActiveCamera()->Azimuth(10);
  renderer->GetActiveCamera()->Dolly(1.2);
  renderer->ResetCameraClippingRange();

  renderWindow->SetSize(640, 480);
  renderWindow->SetWindowName("QuadricVisualization");

  renderWindow->Render();

  // interact with data
  interactor->Start();

  return EXIT_SUCCESS;
}

namespace {
void CreateIsosurface(vtkSampleFunction* function, vtkActor* actor,
                      unsigned int numberOfContours)
{
  double range[2];
  // Generate implicit surface
  vtkNew<vtkContourFilter> contour;
  contour->SetInputConnection(function->GetOutputPort());
  range[0] = 1.0;
  range[1] = 6.0;
  contour->GenerateValues(numberOfContours, range);

  // Map contour
  vtkNew<vtkPolyDataMapper> contourMapper;
  contourMapper->SetInputConnection(contour->GetOutputPort());
  contourMapper->SetScalarRange(0, 7);

  actor->SetMapper(contourMapper);
  return;
}

void CreatePlanes(vtkSampleFunction* function, vtkActor* actor,
                  unsigned int numberOfPlanes)
{
  //
  // Extract planes from implicit function
  //

  vtkNew<vtkAppendFilter> append;

  int dims[3];
  function->GetSampleDimensions(dims);
  int sliceIncr = (dims[2] - 1) / (numberOfPlanes + 1);

  int slice = -4;
  for (unsigned int i = 0; i < numberOfPlanes; ++i)
  {
    vtkNew<vtkExtractVOI> extract;
    extract->SetInputConnection(function->GetOutputPort());
    extract->SetVOI(0, dims[0] - 1, 0, dims[1] - 1, slice + sliceIncr,
                    slice + sliceIncr);
    append->AddInputConnection(extract->GetOutputPort());
    slice += sliceIncr;
  }
  append->Update();

  // Map planes
  vtkNew<vtkDataSetMapper> planesMapper;
  planesMapper->SetInputConnection(append->GetOutputPort());
  planesMapper->SetScalarRange(0, 7);

  actor->SetMapper(planesMapper);
  actor->GetProperty()->SetAmbient(1.);
  return;
}

void CreateContours(vtkSampleFunction* function, vtkActor* actor,
                    unsigned int numberOfPlanes, unsigned int numberOfContours)
{
  //
  // Extract planes from implicit function
  //

  vtkNew<vtkAppendFilter> append;

  int dims[3];
  function->GetSampleDimensions(dims);
  int sliceIncr = (dims[2] - 1) / (numberOfPlanes + 1);

  int slice = -4;
  for (unsigned int i = 0; i < numberOfPlanes; ++i)
  {
    vtkNew<vtkExtractVOI> extract;
    extract->SetInputConnection(function->GetOutputPort());
    extract->SetVOI(0, dims[0] - 1, 0, dims[1] - 1, slice + sliceIncr,
                    slice + sliceIncr);
    double range[2];
    range[0] = 1.0;
    range[1] = 6.0;
    vtkNew<vtkContourFilter> contour;
    contour->SetInputConnection(extract->GetOutputPort());
    contour->GenerateValues(numberOfContours, range);
    append->AddInputConnection(contour->GetOutputPort());
    slice += sliceIncr;
  }
  append->Update();

  // Map planes
  vtkNew<vtkDataSetMapper> planesMapper;
  planesMapper->SetInputConnection(append->GetOutputPort());
  planesMapper->SetScalarRange(0, 7);

  actor->SetMapper(planesMapper);
  actor->GetProperty()->SetAmbient(1.);
  return;
}

void CreateOutline(vtkSampleFunction* source, vtkActor* actor)
{
  vtkNew<vtkOutlineFilter> outline;
  outline->SetInputConnection(source->GetOutputPort());
  vtkNew<vtkPolyDataMapper> mapper;
  mapper->SetInputConnection(outline->GetOutputPort());
  actor->SetMapper(mapper);
  return;
}
} // namespace

CMakeLists.txt

cmake_minimum_required(VERSION 3.3 FATAL_ERROR)

project(QuadricVisualization)

find_package(VTK COMPONENTS 
  vtkCommonColor
  vtkCommonCore
  vtkCommonDataModel
  vtkFiltersCore
  vtkFiltersModeling
  vtkImagingCore
  vtkImagingHybrid
  vtkInteractionStyle
  vtkRenderingContextOpenGL2
  vtkRenderingCore
  vtkRenderingFreeType
  vtkRenderingGL2PSOpenGL2
  vtkRenderingOpenGL2
  QUIET
)

if (NOT VTK_FOUND)
  message("Skipping QuadricVisualization: ${VTK_NOT_FOUND_MESSAGE}")
  return ()
endif()
message (STATUS "VTK_VERSION: ${VTK_VERSION}")
if (VTK_VERSION VERSION_LESS "8.90.0")
  # old system
  include(${VTK_USE_FILE})
  add_executable(QuadricVisualization MACOSX_BUNDLE QuadricVisualization.cxx )
  target_link_libraries(QuadricVisualization PRIVATE ${VTK_LIBRARIES})
else ()
  # include all components
  add_executable(QuadricVisualization MACOSX_BUNDLE QuadricVisualization.cxx )
  target_link_libraries(QuadricVisualization PRIVATE ${VTK_LIBRARIES})
  # vtk_module_autoinit is needed
  vtk_module_autoinit(
    TARGETS QuadricVisualization
    MODULES ${VTK_LIBRARIES}
    )
endif ()

Download and Build QuadricVisualization

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

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

./QuadricVisualization

WINDOWS USERS

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