Rotations
Repository source: Rotations
Description¶
Rotations of a cow about her axes. In this model, the x axis is from the left to right; the y axis is from bottom to top; and the z axis emerges from the image. The camera location is the same in all four images.
Info
See Figure 3-31 in Chapter 3 the VTK Textbook.
Other languages
See (Python)
Question
If you have a question about this example, please use the VTK Discourse Forum
Code¶
Rotations.cxx
#include <vtkActor.h>
#include <vtkAxes.h>
#include <vtkCamera.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPolyDataMapper.h>
#include <vtkPolyDataReader.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSmartPointer.h>
// Readers
#include <vtkBYUReader.h>
#include <vtkOBJReader.h>
#include <vtkPLYReader.h>
#include <vtkPolyDataReader.h>
#include <vtkSTLReader.h>
#include <vtkXMLPolyDataReader.h>
#include <vtkPolyData.h>
#include <vtkSphereSource.h>
#include <algorithm> // For transform()
#include <array>
#include <cctype> // For to_lower
#include <string> // For find_last_of()
namespace {
vtkSmartPointer<vtkPolyData> ReadPolyData(std::string const& fileName);
void RotateX(vtkRenderWindow* renWin, vtkActor* actor);
void RotateY(vtkRenderWindow* renWin, vtkActor* actor);
void RotateZ(vtkRenderWindow* renWin, vtkActor* actor);
void RotateXY(vtkRenderWindow* renWin, vtkActor* actor);
} // namespace
int main(int argc, char* argv[])
{
/*
To match the illustrations in VTKTextbook.pdf, use BkgColor as the background
and Wheat as the cow colour.
Also comment out the lines:
modelActor->GetProperty()->SetSpecular(.6);
modelActor->GetProperty()->SetSpecularPower(30);
and use cow.g as the input data.
*/
auto figure = 0;
std::string actorColor = "Wheat";
if (argc < 2)
{
std::cout << "Usage: " << argv[0] << " filename [figure] [actorColor]"
<< std::endl;
std::cout << "where: filename is the file cow.obj" << std::endl;
std::cout << " figure is 0, 1, 2, or 3, default 0" << std::endl;
std::cout << " actorColor: A color name, default Wheat." << std::endl;
std::cout << "Options 0, 1, 2 and 3 are provided to let you generate "
"approximations to the following figures:\n Figure 3-31d, "
"Figure 3-31a, Figure 3-33b and Figure 3-33c in Chapter 3 of "
"the VTK Textbook."
<< std::endl;
return EXIT_FAILURE;
}
std::string fileName = argv[1];
if (argc == 3)
{
figure = atoi(argv[2]);
}
else if (argc > 3)
{
figure = atoi(argv[2]);
actorColor = argv[3];
}
// Create renderer stuff
//
vtkNew<vtkNamedColors> colors;
// Set the background color.
std::array<unsigned char, 4> bkg{{26, 51, 102, 255}};
// std::array<unsigned char, 4> bkg{{60, 93, 144, 255}};
colors->SetColor("BkgColor", bkg.data());
vtkNew<vtkRenderer> ren1;
vtkNew<vtkRenderWindow> renWin;
renWin->AddRenderer(ren1);
renWin->SetWindowName("Rotations");
vtkNew<vtkRenderWindowInteractor> iren;
iren->SetRenderWindow(renWin);
// Create the pipeline.
//
auto polyData = ReadPolyData(fileName.c_str());
vtkNew<vtkPolyDataMapper> modelMapper;
modelMapper->SetInputData(polyData);
vtkNew<vtkActor> modelActor;
modelActor->SetMapper(modelMapper);
modelActor->GetProperty()->SetDiffuseColor(
colors->GetColor3d(actorColor).GetData());
if (actorColor != "Wheat")
{
modelActor->GetProperty()->SetSpecular(0.6);
modelActor->GetProperty()->SetSpecularPower(30);
}
vtkNew<vtkAxes> modelAxesSource;
modelAxesSource->SetScaleFactor(10);
modelAxesSource->SetOrigin(0, 0, 0);
vtkNew<vtkPolyDataMapper> modelAxesMapper;
modelAxesMapper->SetInputConnection(modelAxesSource->GetOutputPort());
vtkNew<vtkActor> modelAxes;
modelAxes->SetMapper(modelAxesMapper);
ren1->AddActor(modelAxes);
modelAxes->VisibilityOff();
// Add the actors to the renderer, set the background and size.
//
ren1->AddActor(modelActor);
if (actorColor == "Wheat")
{
ren1->SetBackground(colors->GetColor3d("BkgColor").GetData());
}
else
{
ren1->SetBackground(colors->GetColor3d("Silver").GetData());
}
renWin->SetSize(640, 480);
ren1->ResetCamera();
ren1->GetActiveCamera()->Azimuth(0);
ren1->GetActiveCamera()->SetClippingRange(0.1, 1000.0);
modelAxes->VisibilityOn();
renWin->Render();
renWin->Render();
switch (figure)
{
default:
case 0:
RotateXY(renWin, modelActor);
break;
case 1:
RotateX(renWin, modelActor);
break;
case 2:
RotateY(renWin, modelActor);
break;
case 3:
RotateZ(renWin, modelActor);
break;
}
renWin->EraseOff();
iren->Start();
return EXIT_SUCCESS;
}
namespace {
void RotateX(vtkRenderWindow* renWin, vtkActor* actor)
{
actor->SetOrientation(0, 0, 0);
renWin->Render();
renWin->Render();
renWin->EraseOff();
for (auto i = 0; i < 6; ++i)
{
actor->RotateX(60);
renWin->Render();
renWin->Render();
}
renWin->EraseOn();
}
void RotateY(vtkRenderWindow* renWin, vtkActor* actor)
{
actor->SetOrientation(0, 0, 0);
renWin->Render();
renWin->EraseOff();
for (auto i = 0; i < 6; ++i)
{
actor->RotateY(60);
renWin->Render();
renWin->Render();
}
renWin->EraseOn();
}
void RotateZ(vtkRenderWindow* renWin, vtkActor* actor)
{
actor->SetOrientation(0, 0, 0);
renWin->Render();
renWin->EraseOff();
for (auto i = 0; i < 6; ++i)
{
actor->RotateZ(60);
renWin->Render();
renWin->Render();
}
renWin->EraseOn();
}
void RotateXY(vtkRenderWindow* renWin, vtkActor* actor)
{
actor->SetOrientation(0, 0, 0);
actor->RotateX(60);
renWin->Render();
renWin->Render();
renWin->EraseOff();
for (auto i = 0; i < 6; ++i)
{
actor->RotateY(60);
renWin->Render();
renWin->Render();
}
renWin->EraseOn();
}
vtkSmartPointer<vtkPolyData> ReadPolyData(std::string const& fileName)
{
vtkSmartPointer<vtkPolyData> polyData;
std::string extension = "";
if (fileName.find_last_of(".") != std::string::npos)
{
extension = fileName.substr(fileName.find_last_of("."));
}
// Make the extension lowercase
std::transform(extension.begin(), extension.end(), extension.begin(),
::tolower);
if (extension == ".ply")
{
vtkNew<vtkPLYReader> reader;
reader->SetFileName(fileName.c_str());
reader->Update();
polyData = reader->GetOutput();
}
else if (extension == ".vtp")
{
vtkNew<vtkXMLPolyDataReader> reader;
reader->SetFileName(fileName.c_str());
reader->Update();
polyData = reader->GetOutput();
}
else if (extension == ".obj")
{
vtkNew<vtkOBJReader> reader;
reader->SetFileName(fileName.c_str());
reader->Update();
polyData = reader->GetOutput();
}
else if (extension == ".stl")
{
vtkNew<vtkSTLReader> reader;
reader->SetFileName(fileName.c_str());
reader->Update();
polyData = reader->GetOutput();
}
else if (extension == ".vtk")
{
vtkNew<vtkPolyDataReader> reader;
reader->SetFileName(fileName.c_str());
reader->Update();
polyData = reader->GetOutput();
}
else if (extension == ".g")
{
vtkNew<vtkBYUReader> reader;
reader->SetGeometryFileName(fileName.c_str());
reader->Update();
polyData = reader->GetOutput();
}
else
{
// Return a polydata sphere if the extension is unknown.
vtkNew<vtkSphereSource> source;
source->SetThetaResolution(20);
source->SetPhiResolution(11);
source->Update();
polyData = source->GetOutput();
}
return polyData;
}
} // namespace
CMakeLists.txt¶
cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
project(Rotations)
find_package(VTK COMPONENTS
CommonColor
CommonCore
CommonDataModel
FiltersGeneral
FiltersSources
IOGeometry
IOLegacy
IOPLY
IOXML
InteractionStyle
RenderingContextOpenGL2
RenderingCore
RenderingFreeType
RenderingGL2PSOpenGL2
RenderingOpenGL2
)
if (NOT VTK_FOUND)
message(FATAL_ERROR "Rotations: 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(Rotations MACOSX_BUNDLE Rotations.cxx )
target_link_libraries(Rotations PRIVATE ${VTK_LIBRARIES}
)
# vtk_module_autoinit is needed
vtk_module_autoinit(
TARGETS Rotations
MODULES ${VTK_LIBRARIES}
)
Download and Build Rotations¶
Click here to download Rotations and its CMakeLists.txt file. Once the tarball Rotations.tar has been downloaded and extracted,
cd Rotations/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:
./Rotations
WINDOWS USERS
Be sure to add the VTK bin directory to your path. This will resolve the VTK dll's at run time.