Skip to content

QuadricVisualization

Repository source: 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), (PythonicAPI)

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>

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

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

void CreateContours(vtkSampleFunction* function, vtkActor* actor,
                    unsigned int numberOfPlanes, unsigned int 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 the surface of the implicit function.
  //
  // double range[2];

  // Sample the 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 the 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> isosurfaceMapper;
  isosurfaceMapper->SetInputConnection(contour->GetOutputPort());
  isosurfaceMapper->SetScalarRange(0, 7);

  actor->SetMapper(isosurfaceMapper);
  return;
}

void CreatePlanes(vtkSampleFunction* function, vtkActor* actor,
                  unsigned int numberOfPlanes)
{
  //
  // Extract planes from the 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 the 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 contours.
  vtkNew<vtkDataSetMapper> contoursMapper;
  contoursMapper->SetInputConnection(append->GetOutputPort());
  contoursMapper->SetScalarRange(0, 7);

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

void CreateOutline(vtkSampleFunction* source, vtkActor* actor)
{
  vtkNew<vtkOutlineFilter> outline;
  outline->SetInputConnection(source->GetOutputPort());

  vtkNew<vtkPolyDataMapper> outlineMapper;
  outlineMapper->SetInputConnection(outline->GetOutputPort());
  actor->SetMapper(outlineMapper);
  return;
}
} // namespace

CMakeLists.txt

cmake_minimum_required(VERSION 3.12 FATAL_ERROR)

project(QuadricVisualization)

find_package(VTK COMPONENTS 
  CommonColor
  CommonCore
  CommonDataModel
  FiltersCore
  FiltersModeling
  ImagingCore
  ImagingHybrid
  InteractionStyle
  RenderingContextOpenGL2
  RenderingCore
  RenderingFreeType
  RenderingGL2PSOpenGL2
  RenderingOpenGL2
)

if (NOT VTK_FOUND)
  message(FATAL_ERROR "QuadricVisualization: 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(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}
)

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.