diff --git a/offline_ray_tracer/include/settings.hpp b/offline_ray_tracer/include/settings.hpp index ac18a8a74569aa16c3957aa0789a213dc0441565..90655bdb69595d4bf84b7cd7fa0102050a786fe7 100644 --- a/offline_ray_tracer/include/settings.hpp +++ b/offline_ray_tracer/include/settings.hpp @@ -40,12 +40,13 @@ struct settings if (iteratee.isMember("volume" )) entry.volume = iteratee["volume" ].asString(); } - time_scale = root["time_scale" ] .asFloat(); - loop = root["loop" ] .asBool (); - image_size = {root["image_size" ][0].asUInt (), - root["image_size" ][1].asUInt ()}; - samples = root["samples" ] .asUInt (); - update_rate = root["update_rate"] .asFloat(); + transfer_function = root["transfer_function"] .asString(); + time_scale = root["time_scale" ] .asFloat (); + loop = root["loop" ] .asBool (); + image_size = {root["image_size" ][0].asUInt (), + root["image_size" ][1].asUInt ()}; + samples = root["samples" ] .asUInt (); + update_rate = root["update_rate" ] .asFloat (); for (auto& iteratee : root["key_frames"]) { @@ -72,17 +73,18 @@ struct settings settings& operator=( settings&& temp) = default; // Input settings. - std::vector<data_filepath> data_filepaths = {}; - float time_scale = 1000.0f; - bool loop = true; + std::vector<data_filepath> data_filepaths = {}; + std::string transfer_function = ""; + float time_scale = 1000.0f; + bool loop = true; // Ray tracer settings. - std::array<std::size_t, 2> image_size = { 4096, 2160 }; - std::size_t samples = 8; + std::array<std::size_t, 2> image_size = { 4096, 2160 }; + std::size_t samples = 8; // Animation settings. - float update_rate = 16.0f; - std::vector<key_frame> key_frames = {}; + float update_rate = 16.0f; + std::vector<key_frame> key_frames = {}; }; } diff --git a/offline_ray_tracer/include/transfer_function.hpp b/offline_ray_tracer/include/transfer_function.hpp new file mode 100644 index 0000000000000000000000000000000000000000..230f2f9fc34369c171d53ad65fd2591351ec1a85 --- /dev/null +++ b/offline_ray_tracer/include/transfer_function.hpp @@ -0,0 +1,64 @@ +#ifndef TRANSFER_FUNCTION_HPP +#define TRANSFER_FUNCTION_HPP + +#include <cstdint> +#include <fstream> +#include <string> + +#include <vtk_jsoncpp.h> +#include <vtkColorTransferFunction.h> +#include <vtkPiecewiseFunction.h> +#include <vtkSmartPointer.h> + +namespace rt +{ +class transfer_function +{ +public: + explicit transfer_function (const std::string& filepath) + { + std::ifstream file_stream(filepath); + vtkJson::Reader reader; + vtkJson::Value root; + reader.parse(file_stream, root); + + auto& opacity = root[0]["Points" ]; + auto& color = root[0]["RGBPoints"]; + auto space = root[0]["ColorSpace"].asString(); + + for (auto i = 0; i < opacity.size(); i += 4) + opacity_function->AddPoint( + opacity[i ].asFloat(), + opacity[i + 1].asFloat()); + for (auto i = 0; i < color.size(); i += 4) + color_function->AddRGBPoint( + color [i ].asFloat(), + color [i + 1].asFloat(), + color [i + 2].asFloat(), + color [i + 3].asFloat()); + + if (space == "RGB") + color_function->SetColorSpace(VTK_CTF_RGB); + else if (space == "HSV") + color_function->SetColorSpace(VTK_CTF_HSV); + else if (space == "LAB") + color_function->SetColorSpace(VTK_CTF_LAB); + else if (space == "CIEDE2000") + color_function->SetColorSpace(VTK_CTF_LAB_CIEDE2000); + else if (space == "Diverging") + color_function->SetColorSpace(VTK_CTF_DIVERGING); + else if (space == "Step") + color_function->SetColorSpace(VTK_CTF_STEP); + } + transfer_function (const transfer_function& that) = default; + transfer_function ( transfer_function&& temp) = default; + ~transfer_function () = default; + transfer_function& operator=(const transfer_function& that) = default; + transfer_function& operator=( transfer_function&& temp) = default; + + vtkSmartPointer<vtkPiecewiseFunction> opacity_function = vtkSmartPointer<vtkPiecewiseFunction> ::New(); + vtkSmartPointer<vtkColorTransferFunction> color_function = vtkSmartPointer<vtkColorTransferFunction>::New(); +}; +} + +#endif diff --git a/offline_ray_tracer/source/main.cpp b/offline_ray_tracer/source/main.cpp index 03ef7b033ede9da9713bfd55000097c7b3157c4c..3527c796fcd5aafcbd8335aa1ecc349a2256aa19 100644 --- a/offline_ray_tracer/source/main.cpp +++ b/offline_ray_tracer/source/main.cpp @@ -4,24 +4,29 @@ #include <vtkActor.h> #include <vtkCamera.h> #include <vtkCameraInterpolator.h> +#include <vtkColorTransferFunction.h> #include <vtkOggTheoraWriter.h> #include <vtkOSPRayPass.h> +#include <vtkPiecewiseFunction.h> #include <vtkPolyDataMapper.h> #include <vtkRenderer.h> #include <vtkRenderWindow.h> #include <vtkSmartPointer.h> #include <vtkUnstructuredGridVolumeRayCastMapper.h> #include <vtkVolume.h> +#include <vtkVolumeProperty.h> #include <vtkWindowToImageFilter.h> #include <poly_data_io.hpp> #include <settings.hpp> +#include <transfer_function.hpp> #include <unstructured_grid_io.hpp> std::int32_t main(std::int32_t argc, char** argv) { std::cout << "Parsing settings.\n"; - auto settings = rt::settings(argv[1]); + auto settings = rt::settings(argv[1]); + auto transfer_function = rt::transfer_function(settings.transfer_function); std::cout << "Setting up renderer.\n"; auto renderer = vtkSmartPointer<vtkRenderer> ::New(); @@ -39,23 +44,25 @@ std::int32_t main(std::int32_t argc, char** argv) for (auto& key_frame : settings.key_frames) { auto camera = renderer->GetActiveCamera(); - camera ->SetPosition (key_frame.position[0] , key_frame.position[1] , key_frame.position[2]); + camera ->SetPosition (key_frame.position[0] , key_frame.position[1], key_frame.position[2]); camera ->SetFocalPoint(key_frame.position[0] + key_frame.forward [0], key_frame.position[1] + key_frame.forward [1], key_frame.position[2] + key_frame.forward [2]); - camera ->SetViewUp (key_frame.up [0] , key_frame.up [1] , key_frame.up [2]); + camera ->SetViewUp (key_frame.up [0] , key_frame.up [1], key_frame.up [2]); interpolator->AddCamera (key_frame.time, camera); } std::cout << "Setting up actors and volumes.\n"; - auto pd_mapper = vtkSmartPointer<vtkPolyDataMapper> ::New(); - auto ug_mapper = vtkSmartPointer<vtkUnstructuredGridVolumeRayCastMapper>::New(); - auto pd_actor = vtkSmartPointer<vtkActor> ::New(); - auto ug_volume = vtkSmartPointer<vtkVolume> ::New(); - pd_actor ->SetMapper(pd_mapper); - ug_volume->SetMapper(ug_mapper); - renderer ->AddActor (pd_actor ); - //renderer ->AddVolume(ug_volume); + auto pd_mapper = vtkSmartPointer<vtkPolyDataMapper> ::New(); + auto ug_mapper = vtkSmartPointer<vtkUnstructuredGridVolumeRayCastMapper>::New(); + auto pd_actor = vtkSmartPointer<vtkActor> ::New(); + auto ug_volume = vtkSmartPointer<vtkVolume> ::New(); + pd_actor ->SetMapper (pd_mapper); + ug_volume->SetMapper (ug_mapper); + renderer ->AddActor (pd_actor ); + renderer ->AddVolume (ug_volume); + ug_volume->GetProperty()->SetScalarOpacity(transfer_function.opacity_function); + ug_volume->GetProperty()->SetColor (transfer_function.color_function ); std::cout << "Setting up video writer.\n"; auto window_to_image = vtkSmartPointer<vtkWindowToImageFilter>::New(); @@ -79,7 +86,7 @@ std::int32_t main(std::int32_t argc, char** argv) std::cout << "Loading slice " << slice << ".\n"; last_slice = slice; pd_mapper->SetInputData(rt::poly_data_io ::read(settings.data_filepaths[slice].geometry)); - //ug_mapper->SetInputData(rt::unstructured_grid_io::read(settings.data_filepaths[slice].volume )); + ug_mapper->SetInputData(rt::unstructured_grid_io::read(settings.data_filepaths[slice].volume )); } std::cout << "Rendering frame " << current_time << ".\n"; diff --git a/settings.json b/settings.json index 4289a056443b077c550926070fdd243928d49008..5639f0703acb2f9fc4b773982e0a1ef50f4edb81 100644 --- a/settings.json +++ b/settings.json @@ -5,14 +5,15 @@ { "geometry": "/hpcwork/rwth0432/data/oxyflame/GEOM_0013200.vtp", "volume": "/hpcwork/rwth0432/data/oxyflame/QOUT_0013200.vtu" }, { "geometry": "/hpcwork/rwth0432/data/oxyflame/GEOM_0013200.vtp", "volume": "/hpcwork/rwth0432/data/oxyflame/QOUT_0013200.vtu" } ], - "time_scale" : 1000.0, - "loop" : true, + "transfer_function": "/hpcwork/rwth0432/data/oxyflame/transfer_function.json", + "time_scale" : 1000.0, + "loop" : true, - "image_size" : [1920, 1080], - "samples" : 32, + "image_size" : [1920, 1080], + "samples" : 32, - "update_rate": 16.0, - "key_frames" : + "update_rate" : 16.0, + "key_frames" : [ { "time": 0.0 , "position": [ 0.0, 0.0, -100.0], "forward": [0.0, 0.0, 1.0], "up": [0.0, 1.0, 0.0] }, { "time": 1000.0, "position": [ 0.0, -100.0, 0.0], "forward": [0.0, 1.0, 0.0], "up": [0.0, 0.0, 1.0] }, diff --git a/transfer_function.json b/transfer_function.json new file mode 100644 index 0000000000000000000000000000000000000000..54bbc7ebe54ff9e2740d973466b24ff4bdeb3ef1 --- /dev/null +++ b/transfer_function.json @@ -0,0 +1,33 @@ +[ + { + "ColorSpace" : "Diverging", + "Name" : "Basic", + "Points" : + [ + 200.0, + 0.0, + 0.5, + 0.0, + 287.01351928710938, + 1.0, + 0.5, + 0.0 + ], + "RGBPoints" : + [ + 200.0, + 0.231373, + 0.298039, + 0.75294099999999997, + 243.50675964355469, + 0.86500299999999997, + 0.86500299999999997, + 0.86500299999999997, + 287.01351928710938, + 0.70588200000000001, + 0.0156863, + 0.14902000000000001 + ] + } +] +