Skip to content

DisplacementPlot

web-test/Cxx/VisualizationAlgorithms/DisplacementPlot



Description

This example shows modal lines for a vibrating rectangular beam. The vibration mode in this figure is the second torsional mode, clearly indicated by the crossing modal lines.

The default color scheme shows cool color for maximum negative motion, warm color maximum positive motion, with white at the nodes.

For other possible color maps see: Diverging Color Maps for Scientific Visualization.

Other languages

See (Python)

Question

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

Code

DisplacementPlot.cxx

// Translated from dispPlot.tcl
/*
Produce figure 6-15(b) from the VTK Textbook.
Surface plot of a vibrating plane.

The color_scheme option allows you to select a series of colour schemes.
0: The default:- cool maximum negative motion,
                 warm maximum positive motion, white at the nodes.
1: Alternate choice:- green maximum negative motion,
                      purple maximum positive motion, white at the nodes.
2: The original:- white at maximum motion, black at the nodes.

*/

#include <vtkActor.h>
#include <vtkCamera.h>
#include <vtkColorTransferFunction.h>
#include <vtkDataSetMapper.h>
#include <vtkLookupTable.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPolyDataNormals.h>
#include <vtkPolyDataReader.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkVectorDot.h>
#include <vtkWarpVector.h>

namespace {
//! Create a lookup table.
/*!
@param lut - An indexed lookup table.
*/
void MakeLUT(int const& colorScheme, vtkLookupTable* lut);
} // namespace

int main(int argc, char* argv[])
{
  if (argc < 2)
  {
    std::cout << "Usage: " << argv[0] << " filename [colorScheme]" << std::endl;
    std::cout << "where: filename is the file plate.vtk." << std::endl;
    std::cout << "       colorScheme is 0, 1, or 2, default 0" << std::endl;
    std::cout << "Produces figure 6-15(b) Surface plot of vibrating plane from "
                 "the VTK Textbook."
              << std::endl;
    return EXIT_FAILURE;
  }

  int colorScheme = 0;
  std::string fileName = argv[1];

  if (argc == 3)
  {
    colorScheme = std::abs(atoi(argv[2]));
    colorScheme = (colorScheme > 2) ? 0 : colorScheme;
  }

  vtkNew<vtkNamedColors> colors;

  // Read a vtk file
  //
  vtkNew<vtkPolyDataReader> plate;
  plate->SetFileName(fileName.c_str());
  plate->SetVectorsName("mode8");
  plate->Update();

  vtkNew<vtkWarpVector> warp;
  warp->SetInputConnection(plate->GetOutputPort());
  warp->SetScaleFactor(0.5);

  vtkNew<vtkPolyDataNormals> normals;
  normals->SetInputConnection(warp->GetOutputPort());

  vtkNew<vtkVectorDot> color;
  color->SetInputConnection(normals->GetOutputPort());

  vtkNew<vtkLookupTable> lut;
  MakeLUT(colorScheme, lut);

  vtkNew<vtkDataSetMapper> plateMapper;
  plateMapper->SetInputConnection(color->GetOutputPort());
  plateMapper->SetLookupTable(lut);
  plateMapper->SetScalarRange(-1, 1);

  vtkNew<vtkActor> plateActor;
  plateActor->SetMapper(plateMapper);

  // Create the RenderWindow, Renderer and both Actors
  //
  vtkNew<vtkRenderer> ren;
  vtkNew<vtkRenderWindow> renWin;
  renWin->AddRenderer(ren);
  renWin->SetSize(512, 512);
  renWin->SetWindowName("DisplacementPlot");

  vtkNew<vtkRenderWindowInteractor> iren;
  iren->SetRenderWindow(renWin);

  // Add the actors to the renderer, set the background and size
  //
  ren->AddActor(plateActor);
  ren->SetBackground(colors->GetColor3d("Wheat").GetData());

  ren->GetActiveCamera()->SetPosition(13.3991, 14.0764, 9.97787);
  ren->GetActiveCamera()->SetFocalPoint(1.50437, 0.481517, 4.52992);
  ren->GetActiveCamera()->SetViewAngle(30);
  ren->GetActiveCamera()->SetViewUp(-0.120861, 0.458556, -0.880408);
  ren->GetActiveCamera()->SetClippingRange(12.5724, 26.8374);
  // Render the image.
  renWin->Render();

  iren->Start();

  return EXIT_SUCCESS;
}

namespace {
void MakeLUT(int const& colorScheme, vtkLookupTable* lut)
{
  // See: [Diverging Color Maps for Scientific Visualization]
  //      (http://www.kennethmoreland.com/color-maps/)
  auto nc = 256;
  vtkNew<vtkColorTransferFunction> ctf;
  switch (colorScheme)
  {
  case 0:
  default:
    // Cool to warm diverging.
    ctf->SetColorSpaceToDiverging();
    ctf->AddRGBPoint(0.0, 0.230, 0.299, 0.754);
    ctf->AddRGBPoint(0.5, 0.865, 0.865, 0.865);
    ctf->AddRGBPoint(1.0, 0.706, 0.016, 0.150);
    lut->SetNumberOfTableValues(nc);
    lut->Build();
    for (auto i = 0; i < nc; ++i)
    {
      double rgb[4] = {0.0, 0.0, 0.0, 1.0};
      ctf->GetColor(static_cast<double>(i) / nc, rgb);
      lut->SetTableValue(i, rgb);
    }
    break;
  case 1:
    // Green to purple diverging.
    ctf->SetColorSpaceToDiverging();
    ctf->AddRGBPoint(0.0, 0.085, 0.532, 0.201);
    ctf->AddRGBPoint(1.0, 0.436, 0.308, 0.631);
    lut->SetNumberOfTableValues(nc);
    lut->Build();
    for (auto i = 0; i < nc; ++i)
    {
      double rgb[4] = {0.0, 0.0, 0.0, 1.0};
      ctf->GetColor(static_cast<double>(i) / nc, rgb);
      lut->SetTableValue(i, rgb);
    }
    break;
  case 2: {
    // Make a lookup table, black in the centre with bright areas
    //   at the beginning and end of the table.
    // This is from the original code.
    auto nc2 = nc / 2;
    lut->SetNumberOfColors(nc);
    lut->Build();
    for (auto i = 0; i < nc2; ++i)
    {
      // White to black.
      auto v = (double(nc2) - i) / double(nc2);
      lut->SetTableValue(i, v, v, v, 1);
    }
    for (auto i = nc2; i < nc; ++i)
    {
      // Black to white.
      auto v = (i - double(nc2)) / double(nc2);
      lut->SetTableValue(i, v, v, v, 1);
    }
    break;
  }
  }
}
} // namespace

CMakeLists.txt

cmake_minimum_required(VERSION 3.12 FATAL_ERROR)

project(DisplacementPlot)

find_package(VTK COMPONENTS 
  CommonColor
  CommonCore
  FiltersCore
  FiltersGeneral
  IOLegacy
  InteractionStyle
  RenderingContextOpenGL2
  RenderingCore
  RenderingFreeType
  RenderingGL2PSOpenGL2
  RenderingOpenGL2
)

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

Download and Build DisplacementPlot

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

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

./DisplacementPlot

WINDOWS USERS

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