Select Git revision
main.cpp 7.17 KiB
#include <cstddef>
#include <cstdint>
#include <iostream>
#include <limits>
#include <vtkActor.h>
#include <vtkAVIWriter.h>
#include <vtkCamera.h>
#include <vtkCameraInterpolator.h>
#include <vtkInformation.h>
#include <vtkOSPRayPass.h>
#include <vtkOSPRayRendererNode.h>
#include <vtkOSPRayVolumeMapper.h>
#include <vtkPointData.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkSmartPointer.h>
#include <vtkVolume.h>
#include <vtkVolumeProperty.h>
#include <vtkWindowToImageFilter.h>
#include <vtkXMLImageDataReader.h>
#include <vtkXMLPolyDataReader.h>
#include <settings.hpp>
#include <transfer_function.hpp>
std::int32_t main(std::int32_t argc, char** argv)
{
std::cout << "Parsing settings.\n";
const rt::settings settings (argv[1]);
const rt::transfer_function transfer_function(settings.transfer_function);
std::cout << "Setting up renderer.\n";
auto renderer = vtkSmartPointer<vtkRenderer> ::New();
auto window = vtkSmartPointer<vtkRenderWindow>::New();
auto ospray_pass = vtkSmartPointer<vtkOSPRayPass> ::New();
window ->AddRenderer (renderer);
window ->SetOffScreenRendering (true);
window ->SetSize (settings.image_size[0], settings.image_size[1]);
window ->SetPolygonSmoothing (true);
renderer->SetPass (ospray_pass);
renderer->SetUseShadows (settings.shadows);
renderer->SetAutomaticLightCreation (true);
vtkOSPRayRendererNode::SetSamplesPerPixel(settings.samples , renderer);
vtkOSPRayRendererNode::SetAmbientSamples (settings.ambient_samples, renderer);
std::cout << "Setting up camera interpolator.\n";
auto interpolator = vtkSmartPointer<vtkCameraInterpolator>::New();
interpolator->SetInterpolationType(vtkCameraInterpolator::INTERPOLATION_TYPE_SPLINE);
for (const auto& key_frame : settings.key_frames)
{
auto* camera = renderer->GetActiveCamera();
camera ->SetPosition (key_frame.position.data());
camera ->SetFocalPoint(key_frame.center .data());
camera ->SetViewUp (key_frame.up .data());
interpolator->AddCamera (key_frame.time, camera);
}
std::cout << "Setting up geometry and volume.\n";
auto geometry_reader = vtkSmartPointer<vtkXMLPolyDataReader> ::New();
auto geometry_mapper = vtkSmartPointer<vtkPolyDataMapper> ::New();
auto actor = vtkSmartPointer<vtkActor> ::New();
auto volume_reader = vtkSmartPointer<vtkXMLImageDataReader>::New();
auto volume_mapper = vtkSmartPointer<vtkOSPRayVolumeMapper>::New();
auto volume = vtkSmartPointer<vtkVolume> ::New();
std::cout << "Setting up video writer.\n";
auto window_to_image = vtkSmartPointer<vtkWindowToImageFilter>::New();
auto video_writer = vtkSmartPointer<vtkAVIWriter> ::New();
window_to_image->SetInput (window);
window_to_image->ReadFrontBufferOff ();
video_writer ->SetInputConnection (window_to_image->GetOutputPort());
video_writer ->SetFileName ("video.avi");
video_writer ->SetRate (static_cast<std::int32_t>(1000.0 / settings.update_rate));
video_writer ->SetQuality (2);
video_writer ->Start ();
std::cout << "Starting rendering.\n";
auto current_time = 0.0;
auto last_slice = std::numeric_limits<std::size_t>::max();
while (current_time < settings.key_frames.back().time)
{
auto slice = static_cast<std::size_t>(std::floor(current_time / settings.time_scale));
slice = settings.loop ? slice % settings.data_file_paths.size() : std::min(slice, settings.data_file_paths.size() - 1);
if (last_slice != slice)
{
if (last_slice != std::numeric_limits<std::size_t>::max())
{
std::cout << "Clearing previous slice.\n";
renderer ->RemoveActor (actor);
actor ->SetMapper (nullptr);
geometry_mapper->RemoveInputConnection(0, geometry_reader->GetOutputPort());
renderer ->RemoveVolume (volume);
volume ->SetMapper (nullptr);
volume_mapper ->RemoveInputConnection(0, volume_reader ->GetOutputPort());
geometry_reader = nullptr;
geometry_mapper = nullptr;
actor = nullptr;
volume_reader = nullptr;
volume_mapper = nullptr;
volume = nullptr;
}
geometry_reader = vtkSmartPointer<vtkXMLPolyDataReader> ::New();
geometry_mapper = vtkSmartPointer<vtkPolyDataMapper> ::New();
actor = vtkSmartPointer<vtkActor> ::New();
volume_reader = vtkSmartPointer<vtkXMLImageDataReader>::New();
volume_mapper = vtkSmartPointer<vtkOSPRayVolumeMapper>::New();
volume = vtkSmartPointer<vtkVolume> ::New();
auto* actor_property = actor ->GetProperty();
auto* volume_property = volume->GetProperty();
std::cout << "Loading next slice: " << slice << ".\n";
geometry_reader->SetFileName (settings.data_file_paths[slice].geometry.c_str());
geometry_mapper->SetInputConnection (geometry_reader->GetOutputPort());
actor ->SetMapper (geometry_mapper);
actor_property ->SetInterpolation (VTK_PBR);
renderer ->AddActor (actor);
volume_reader ->SetFileName (settings.data_file_paths[slice].volume .c_str());
volume_reader ->SetInputArrayToProcess (0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_POINTS, settings.data_file_paths[slice].scalar.c_str());
volume_reader ->Update ();
volume_reader ->GetOutput ()->GetPointData()->SetActiveScalars(settings.data_file_paths[slice].scalar.c_str());
volume_mapper ->SetInputData (volume_reader->GetOutput());
volume_mapper ->SetInputArrayToProcess (0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_POINTS, settings.data_file_paths[slice].scalar.c_str());
volume ->SetMapper (volume_mapper);
volume_property->SetScalarOpacity (transfer_function.opacity_function);
volume_property->SetColor (transfer_function.color_function );
volume_property->SetScalarOpacityUnitDistance(settings.step_size);
volume_property->SetInterpolationType (VTK_LINEAR_INTERPOLATION);
volume_property->ShadeOn ();
renderer ->AddVolume (volume);
last_slice = slice;
}
std::cout << "Rendering frame: " << current_time << ".\n";
interpolator ->InterpolateCamera (current_time, renderer->GetActiveCamera());
renderer ->ResetCameraClippingRange();
window ->Render ();
window_to_image->Modified ();
video_writer ->Write ();
current_time += settings.update_rate;
}
std::cout << "Finished rendering. Finalizing video.\n";
video_writer->End();
return 0;
}