Skip to content

CameraModel2

vtk-examples/Cxx/Visualization/CameraModel2


Description

This example illustrates the camera movement centered at the camera position.

Note

For camera movement around the focal point see CameraModel1.

Note

This is an adaptation of the code written by Chung Kai Lun Pete.

Other languages

See (Python)

Question

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

Code

CameraModel2.cxx

/*
   Adaptation of the code by
        Author: Chung Kai Lun Peter
        Email: hkpeterpeter@gmail.com
        File:
            demo_vtk_camera_2.cpp
        Purpose:
                Ported from camera2.tcl.
                It illustrates the camera model of VTK.
*/

#include <vtkAppendPolyData.h>
#include <vtkCamera.h>
#include <vtkCellArray.h>
#include <vtkConeSource.h>
#include <vtkContourFilter.h>
#include <vtkCubeSource.h>
#include <vtkDataSetMapper.h>
#include <vtkImplicitModeller.h>
#include <vtkLODActor.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkRotationalExtrusionFilter.h>
#include <vtkSphereSource.h>
#include <vtkTextActor.h>
#include <vtkTextProperty.h>
#include <vtkTransform.h>
#include <vtkTransformFilter.h>
#include <vtkTransformPolyDataFilter.h>
#include <vtkWarpTo.h>

#include <algorithm>
#include <array>

int main(int /* argc */, char* /* argv */[])
{

  vtkNew<vtkNamedColors> colors;

  // Set the colors.
  std::array<unsigned char, 4> azArrowColor{{255, 77, 77}};
  colors->SetColor("AzimuthArrowColor", azArrowColor.data());
  std::array<unsigned char, 4> elevArrowColor{{77, 255, 77}};
  colors->SetColor("ElevationArrowColor", elevArrowColor.data());
  std::array<unsigned char, 4> rollArrowColor{{255, 255, 77}};
  colors->SetColor("RollArrowColor", rollArrowColor.data());
  std::array<unsigned char, 4> spikeColor{{255, 77, 255}};
  colors->SetColor("SpikeColor", spikeColor.data());
  std::array<unsigned char, 4> upSpikeColor{{77, 255, 255}};
  colors->SetColor("UpSpikeColor", upSpikeColor.data());

  // create a camera model
  vtkNew<vtkConeSource> camCS;
  camCS->SetHeight(1.5);
  camCS->SetResolution(12);
  camCS->SetRadius(0.4);

  vtkNew<vtkCubeSource> camCBS;
  camCBS->SetXLength(1.5);
  camCBS->SetZLength(0.8);
  camCBS->SetCenter(0.4, 0, 0);

  vtkNew<vtkAppendPolyData> camAPD;
  camAPD->AddInputConnection(camCBS->GetOutputPort());
  camAPD->AddInputConnection(camCS->GetOutputPort());

  vtkNew<vtkPolyDataMapper> camMapper;
  camMapper->SetInputConnection(camAPD->GetOutputPort());
  vtkNew<vtkLODActor> camActor;
  camActor->SetMapper(camMapper);
  camActor->SetScale(2, 2, 2);

  // draw the arrows
  vtkNew<vtkPolyData> pd;
  vtkNew<vtkCellArray> ca;
  vtkNew<vtkPoints> pts;
  pts->InsertNextPoint(0, 1, 0);
  pts->InsertNextPoint(8, 1, 0);
  pts->InsertNextPoint(8, 2, 0);
  pts->InsertNextPoint(10, 0, 0);
  pts->InsertNextPoint(8, -2, 0);
  pts->InsertNextPoint(8, -1, 0);
  pts->InsertNextPoint(0, -1, 0);
  ca->InsertNextCell(7);
  ca->InsertCellPoint(0);
  ca->InsertCellPoint(1);
  ca->InsertCellPoint(2);
  ca->InsertCellPoint(3);
  ca->InsertCellPoint(4);
  ca->InsertCellPoint(5);
  ca->InsertCellPoint(6);
  pd->SetPoints(pts);
  pd->SetPolys(ca);

  vtkNew<vtkPolyData> pd2;
  vtkNew<vtkCellArray> ca2;
  vtkNew<vtkPoints> pts2;
  pts2->InsertNextPoint(0, 1, 0);
  pts2->InsertNextPoint(8, 1, 0);
  pts2->InsertNextPoint(8, 2, 0);
  pts2->InsertNextPoint(10, 0.01, 0);
  ca2->InsertNextCell(4);
  ca2->InsertCellPoint(0);
  ca2->InsertCellPoint(1);
  ca2->InsertCellPoint(2);
  ca2->InsertCellPoint(3);
  pd2->SetPoints(pts2);
  pd2->SetLines(ca2);

  vtkNew<vtkImplicitModeller> arrowIM;
  arrowIM->SetInputData(pd);
  arrowIM->SetSampleDimensions(50, 20, 8);

  vtkNew<vtkContourFilter> arrowCF;
  arrowCF->SetInputConnection(arrowIM->GetOutputPort());
  arrowCF->SetValue(0, 0.2);

  vtkNew<vtkWarpTo> arrowWT;
  arrowWT->SetInputConnection(arrowCF->GetOutputPort());
  arrowWT->SetPosition(5, 0, 5);
  arrowWT->SetScaleFactor(0.85);
  arrowWT->AbsoluteOn();

  vtkNew<vtkTransform> arrowT;
  arrowT->RotateY(60);
  arrowT->Translate(-1.33198, 0, -1.479);
  arrowT->Scale(1, 0.5, 1);

  vtkNew<vtkTransformFilter> arrowTF;
  arrowTF->SetInputConnection(arrowWT->GetOutputPort());
  arrowTF->SetTransform(arrowT);

  vtkNew<vtkDataSetMapper> arrowMapper;
  arrowMapper->SetInputConnection(arrowTF->GetOutputPort());
  arrowMapper->ScalarVisibilityOff();

  // draw the azimuth arrows
  vtkNew<vtkLODActor> a1Actor;
  a1Actor->SetMapper(arrowMapper);
  a1Actor->SetPosition(-9, 0, -1);
  a1Actor->GetProperty()->SetColor(
      colors->GetColor3d("AzimuthArrowColor").GetData());
  a1Actor->GetProperty()->SetSpecularColor(
      colors->GetColor3d("White").GetData());
  a1Actor->GetProperty()->SetSpecular(0.3);
  a1Actor->GetProperty()->SetSpecularPower(20);
  a1Actor->GetProperty()->SetAmbient(0.2);
  a1Actor->GetProperty()->SetDiffuse(0.8);

  vtkNew<vtkLODActor> a2Actor;
  a2Actor->SetMapper(arrowMapper);
  a2Actor->RotateX(180);
  a2Actor->SetPosition(-9, 0, 1);
  a2Actor->GetProperty()->SetColor(
      colors->GetColor3d("AzimuthArrowColor").GetData());
  a2Actor->GetProperty()->SetSpecularColor(
      colors->GetColor3d("White").GetData());
  a2Actor->GetProperty()->SetSpecular(0.3);
  a2Actor->GetProperty()->SetSpecularPower(20);
  a2Actor->GetProperty()->SetAmbient(0.2);
  a2Actor->GetProperty()->SetDiffuse(0.8);

  // draw the elevation arrows
  vtkNew<vtkLODActor> a3Actor;
  a3Actor->SetMapper(arrowMapper);
  a3Actor->RotateX(-90);
  a3Actor->SetPosition(-9, -1, 0);
  a3Actor->GetProperty()->SetColor(
      colors->GetColor3d("ElevationArrowColor").GetData());
  a3Actor->GetProperty()->SetSpecularColor(
      colors->GetColor3d("White").GetData());
  a3Actor->GetProperty()->SetSpecular(0.3);
  a3Actor->GetProperty()->SetSpecularPower(20);
  a3Actor->GetProperty()->SetAmbient(0.2);
  a3Actor->GetProperty()->SetDiffuse(0.8);

  vtkNew<vtkLODActor> a4Actor;
  a4Actor->SetMapper(arrowMapper);
  a4Actor->RotateX(90);
  a4Actor->SetPosition(-9, 1, 0);
  a4Actor->GetProperty()->SetColor(
      colors->GetColor3d("ElevationArrowColor").GetData());
  a4Actor->GetProperty()->SetSpecularColor(
      colors->GetColor3d("White").GetData());
  a4Actor->GetProperty()->SetSpecular(0.3);
  a4Actor->GetProperty()->SetSpecularPower(20);
  a4Actor->GetProperty()->SetAmbient(0.2);
  a4Actor->GetProperty()->SetDiffuse(0.8);

  // draw the DOP
  vtkNew<vtkTransform> arrowT2;
  arrowT2->Scale(1, 0.6, 1);
  arrowT2->RotateY(90);

  vtkNew<vtkTransformPolyDataFilter> arrowTF2;
  arrowTF2->SetInputData(pd2);
  arrowTF2->SetTransform(arrowT2);

  vtkNew<vtkRotationalExtrusionFilter> arrowREF;
  arrowREF->SetInputConnection(arrowTF2->GetOutputPort());
  arrowREF->CappingOff();
  arrowREF->SetResolution(30);

  vtkNew<vtkPolyDataMapper> spikeMapper;
  spikeMapper->SetInputConnection(arrowREF->GetOutputPort());

  vtkNew<vtkLODActor> a5Actor;
  a5Actor->SetMapper(spikeMapper);
  a5Actor->SetScale(0.3, 0.3, 0.6);
  a5Actor->RotateY(-90);
  a5Actor->SetPosition(-8, 0, 0);
  a5Actor->GetProperty()->SetColor(colors->GetColor3d("SpikeColor").GetData());
  a5Actor->GetProperty()->SetSpecularColor(
      colors->GetColor3d("White").GetData());
  a5Actor->GetProperty()->SetSpecular(0.3);
  a5Actor->GetProperty()->SetAmbient(0.2);
  a5Actor->GetProperty()->SetDiffuse(0.8);
  a5Actor->GetProperty()->SetSpecularPower(20);

  vtkNew<vtkLODActor> a7Actor;
  a7Actor->SetMapper(spikeMapper);
  a7Actor->SetScale(0.2, 0.2, 0.7);
  a7Actor->RotateZ(90);
  a7Actor->RotateY(-90);
  a7Actor->SetPosition(-9, 1, 0);
  a7Actor->GetProperty()->SetColor(
      colors->GetColor3d("UpSpikeColor").GetData());
  a7Actor->GetProperty()->SetSpecularColor(
      colors->GetColor3d("White").GetData());
  a7Actor->GetProperty()->SetSpecular(0.3);
  a7Actor->GetProperty()->SetAmbient(0.2);
  a7Actor->GetProperty()->SetDiffuse(0.8);
  a7Actor->GetProperty()->SetSpecularPower(20);

  // focal point
  vtkNew<vtkSphereSource> ss;
  ss->SetRadius(0.5);
  vtkNew<vtkPolyDataMapper> fpMapper;
  fpMapper->SetInputConnection(ss->GetOutputPort());
  vtkNew<vtkLODActor> fpActor;
  fpActor->SetMapper(fpMapper);
  fpActor->SetPosition(-9, 0, 0);
  fpActor->GetProperty()->SetSpecularColor(
      colors->GetColor3d("White").GetData());
  fpActor->GetProperty()->SetSpecular(0.3);
  fpActor->GetProperty()->SetAmbient(0.2);
  fpActor->GetProperty()->SetDiffuse(0.8);
  fpActor->GetProperty()->SetSpecularPower(20);

  // create the roll arrows
  vtkNew<vtkWarpTo> arrowWT2;
  arrowWT2->SetInputConnection(arrowCF->GetOutputPort());
  arrowWT2->SetPosition(5, 0, 2.5);
  arrowWT2->SetScaleFactor(0.95);
  arrowWT2->AbsoluteOn();

  vtkNew<vtkTransform> arrowT3;
  arrowT3->Translate(-2.50358, 0, -1.70408);
  arrowT3->Scale(0.5, 0.3, 1);

  vtkNew<vtkTransformFilter> arrowTF3;
  arrowTF3->SetInputConnection(arrowWT2->GetOutputPort());
  arrowTF3->SetTransform(arrowT3);

  vtkNew<vtkDataSetMapper> arrowMapper2;
  arrowMapper2->SetInputConnection(arrowTF3->GetOutputPort());
  arrowMapper2->ScalarVisibilityOff();

  // draw the roll arrows
  vtkNew<vtkLODActor> a6Actor;
  a6Actor->SetMapper(arrowMapper2);
  a6Actor->RotateZ(90);
  a6Actor->SetPosition(-4, 0, 0);
  a6Actor->SetScale(1.5, 1.5, 1.5);
  a6Actor->GetProperty()->SetColor(
      colors->GetColor3d("RollArrowColor").GetData());
  a6Actor->GetProperty()->SetSpecularColor(
      colors->GetColor3d("White").GetData());
  a6Actor->GetProperty()->SetSpecular(0.3);
  a6Actor->GetProperty()->SetSpecularPower(20);
  a6Actor->GetProperty()->SetAmbient(0.2);
  a6Actor->GetProperty()->SetDiffuse(0.8);

  // Create the RenderWindow, Renderer and both Actors
  //
  vtkNew<vtkRenderer> ren1;
  vtkNew<vtkRenderWindow> renWin;
  renWin->AddRenderer(ren1);
  vtkNew<vtkRenderWindowInteractor> iren;
  iren->SetRenderWindow(renWin);

  // Add the actors to the renderer, set the background and size
  ren1->AddActor(camActor);
  ren1->AddActor(a1Actor);
  ren1->AddActor(a2Actor);
  ren1->AddActor(a3Actor);
  ren1->AddActor(a4Actor);
  ren1->AddActor(a5Actor);
  ren1->AddActor(a6Actor);
  ren1->AddActor(a7Actor);
  ren1->AddActor(fpActor);
  ren1->SetBackground(colors->GetColor3d("SlateGray").GetData());
  renWin->SetSize(640, 480);
  renWin->SetWindowName("CameraModel2");

  // render the image

  vtkCamera* cam1 = (ren1->GetActiveCamera());
  ren1->ResetCamera();
  cam1->Azimuth(150);
  cam1->Elevation(30);
  cam1->Dolly(1.5);
  ren1->ResetCameraClippingRange();

  // Create a TextActor for Yaw  (a1 and a2 actor's color)
  vtkNew<vtkTextActor> text;
  text->SetInput("Yaw");
  vtkTextProperty* tprop = text->GetTextProperty();
  tprop->SetFontFamilyToArial();
  tprop->ShadowOff();
  tprop->SetLineSpacing(1.0);
  tprop->SetFontSize(36);
  tprop->SetColor(a1Actor->GetProperty()->GetColor());
  text->SetDisplayPosition(20, 50);
  ren1->AddActor2D(text);

  // Create a TextActor for Pitch  (a3 and a4 actor's color)
  vtkNew<vtkTextActor> text2;
  text2->SetInput("Pitch");
  tprop = text2->GetTextProperty();
  tprop->SetFontFamilyToArial();
  tprop->ShadowOff();
  tprop->SetLineSpacing(1.0);
  tprop->SetFontSize(36);
  tprop->SetColor(a3Actor->GetProperty()->GetColor());
  text2->SetDisplayPosition(20, 100);
  ren1->AddActor2D(text2);

  // Create a TextActor for roll (a6 actor's color)
  vtkNew<vtkTextActor> text3;
  text3->SetInput("Roll");
  tprop = text3->GetTextProperty();
  tprop->SetFontFamilyToArial();
  tprop->ShadowOff();
  tprop->SetLineSpacing(1.0);
  tprop->SetFontSize(36);
  tprop->SetColor(a6Actor->GetProperty()->GetColor());
  text3->SetDisplayPosition(20, 150);
  ren1->AddActor2D(text3);

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

  return EXIT_SUCCESS;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.12 FATAL_ERROR)

project(CameraModel2)

find_package(VTK COMPONENTS 
)

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

Download and Build CameraModel2

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

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

./CameraModel2

WINDOWS USERS

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