From 58bfced9ffef8e1016b8532b53c4054247b74b2a Mon Sep 17 00:00:00 2001 From: Fabio Pellacini Date: Wed, 9 Jun 2021 14:07:04 +0200 Subject: [PATCH 01/12] updated --- libs/yocto/yocto_math.h | 95 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 84 insertions(+), 11 deletions(-) diff --git a/libs/yocto/yocto_math.h b/libs/yocto/yocto_math.h index 123594e36..b22bd9cf7 100644 --- a/libs/yocto/yocto_math.h +++ b/libs/yocto/yocto_math.h @@ -1303,8 +1303,7 @@ inline frame3f camera_fpscam( // ----------------------------------------------------------------------------- namespace yocto { -// Python `range()` equivalent. Construct an object that iterates over an -// integer sequence. +// Python range. Construct an object that iterates over an integer sequence. template constexpr auto range(T max); template @@ -1312,6 +1311,12 @@ constexpr auto range(T min, T max); template constexpr auto range(T min, T max, T step); +// Python enumerate +template +constexpr auto enumerate(const Sequence& sequence, T start = 0); +template +constexpr auto enumerate(Sequence& sequence, T start = 0); + } // namespace yocto // ----------------------------------------------------------------------------- @@ -3411,28 +3416,96 @@ namespace yocto { // Python `range()` equivalent. Construct an object to iterate over a sequence. template constexpr auto range(T max) { - return range((T)0, max, (T)1); + return range((T)0, max); } template constexpr auto range(T min, T max) { - return range(min, max, (T)1); + struct range_iterator { + T index; + void operator++() { ++index; } + bool operator!=(const range_iterator& other) const { + return index != other.index; + } + T operator*() const { return index; } + }; + struct range_helper { + T begin_ = 0, end_ = 0; + range_iterator begin() const { return {begin_}; } + range_iterator end() const { return {end_}; } + }; + return range_helper{min, max}; } template constexpr auto range(T min, T max, T step) { - struct iterator { + struct range_iterator { T index; - void operator++() { ++index; } - bool operator!=(const iterator& other) const { + T step; + void operator++() { index += step; } + bool operator!=(const range_iterator& other) const { return index != other.index; } T operator*() const { return index; } }; struct range_helper { - T begin_ = 0, end_ = 0; - iterator begin() const { return {begin_}; } - iterator end() const { return {end_}; } + T begin_ = 0, end_ = 0, step_ = 0; + range_iterator begin() const { return {begin_, step_}; } + range_iterator end() const { + return {begin_ + ((end_ - begin_) / step_) * step_, step_}; + } }; - return range_helper{min, max}; + return range_helper{min, max, step}; +} + +// Python enumerate +template +constexpr auto enumerate(const Sequence& sequence, T start) { + using Iterator = typename Sequence::const_iterator; + using Reference = typename Sequence::const_reference; + struct enumerate_iterator { + T index; + Iterator iterator; + bool operator!=(const enumerate_iterator& other) const { + return index != other.index; + } + void operator++() { + ++index; + ++iterator; + } + pair operator*() const { return {index, *iterator}; } + }; + struct enumerate_helper { + Sequence& sequence; + T begin_, end_; + auto begin() { return enumerate_iterator{begin_, std::begin(sequence)}; } + auto end() { return enumerate_iterator{end_, std::end(sequence)}; } + }; + return enumerate_helper{sequence, 0, size(sequence)}; +} + +// Python enumerate +template +constexpr auto enumerate(Sequence& sequence, T start) { + using Iterator = typename Sequence::iterator; + using Reference = typename Sequence::reference; + struct enumerate_iterator { + T index; + Iterator iterator; + bool operator!=(const enumerate_iterator& other) const { + return index != other.index; + } + void operator++() { + ++index; + ++iterator; + } + pair operator*() const { return {index, *iterator}; } + }; + struct enumerate_helper { + Sequence& sequence; + T begin_, end_; + auto begin() { return enumerate_iterator{begin_, std::begin(sequence)}; } + auto end() { return enumerate_iterator{end_, std::end(sequence)}; } + }; + return enumerate_helper{sequence, 0, size(sequence)}; } } // namespace yocto From 6c188fc7d8cfdc0c000800c012687479bcb7ca02 Mon Sep 17 00:00:00 2001 From: Fabio Pellacini Date: Wed, 9 Jun 2021 14:44:50 +0200 Subject: [PATCH 02/12] updated --- apps/ymesh/ymesh.cpp | 12 ++++++------ docs/yocto/yocto_scene.md | 10 +++++----- docs/yocto/yocto_sceneio.md | 2 +- libs/yocto/yocto_scene.cpp | 12 ++++++------ libs/yocto/yocto_scene.h | 21 +++++++++++---------- libs/yocto/yocto_sceneio.cpp | 12 ++++++------ libs/yocto/yocto_sceneio.h | 7 +++---- libs/yocto/yocto_trace.cpp | 2 +- libs/yocto_gui/yocto_glview.cpp | 4 ++-- libs/yocto_gui/yocto_glview.h | 2 +- 10 files changed, 42 insertions(+), 42 deletions(-) diff --git a/apps/ymesh/ymesh.cpp b/apps/ymesh/ymesh.cpp index 9cdebc4bc..b28b143ce 100644 --- a/apps/ymesh/ymesh.cpp +++ b/apps/ymesh/ymesh.cpp @@ -630,7 +630,7 @@ struct sculpt_state { vector> adjacencies = {}; geodesic_solver solver = {}; // brush - scene_texture tex_image = {}; + texture_data tex_image = {}; // stroke vector stroke = {}; vec2f last_uv = {}; @@ -641,7 +641,7 @@ struct sculpt_state { // Initialize all sculpting parameters. sculpt_state make_sculpt_state( - const scene_shape& shape, const scene_texture& texture) { + const scene_shape& shape, const texture_data& texture) { auto state = sculpt_state{}; state.bvh = make_triangles_bvh( shape.triangles, shape.positions, shape.radius); @@ -931,7 +931,7 @@ bool gaussian_brush(vector& positions, const hash_grid& grid, // Compute texture values through the parameterization bool texture_brush(vector& positions, vector& texcoords, - const geodesic_solver& solver, const scene_texture& texture, + const geodesic_solver& solver, const texture_data& texture, const vector& triangles, const vector& base_positions, const vector& base_normals, const vector& stroke, const sculpt_params& params) { @@ -1141,7 +1141,7 @@ static scene_model make_sculptscene(const scene_shape& ioshape_) { // To make the stroke sampling (position, normal) following the mouse static pair, vec2f> sample_stroke(const shape_bvh& bvh, const scene_shape& shape, const vec2f& last_uv, const vec2f& mouse_uv, - const scene_camera& camera, const sculpt_params& params) { + const camera_data& camera, const sculpt_params& params) { // helper auto intersect_shape = [&](const vec2f& uv) { auto ray = camera_ray( @@ -1175,7 +1175,7 @@ static pair, vec2f> sample_stroke(const shape_bvh& bvh, } static pair sculpt_update(sculpt_state& state, scene_shape& shape, - scene_shape& cursor, const scene_camera& camera, const vec2f& mouse_uv, + scene_shape& cursor, const camera_data& camera, const vec2f& mouse_uv, bool mouse_pressed, const sculpt_params& params) { auto updated_shape = false, updated_cursor = false; @@ -1251,7 +1251,7 @@ int run_glsculpt(const glsculpt_params& params_) { } // loading texture - auto texture = scene_texture{}; + auto texture = texture_data{}; if (!params_.texture.empty()) { if (!load_texture(params_.texture, texture, ioerror)) print_fatal(ioerror); } diff --git a/docs/yocto/yocto_scene.md b/docs/yocto/yocto_scene.md index 629127797..fc56291b6 100644 --- a/docs/yocto/yocto_scene.md +++ b/docs/yocto/yocto_scene.md @@ -62,7 +62,7 @@ for(auto error : errors) print_error(error);// print error ## Cameras -Cameras, represented by `scene_camera`, are based on a simple lens model. +Cameras, represented by `camera_data`, are based on a simple lens model. Cameras coordinate systems are defined by their frame. Cameras projections are described in photographic terms. In particular, we specify film size (35mm by default), film aspect ration, @@ -83,7 +83,7 @@ To create cameras, you should set the camera frame, the camera view, via lens, aspect and film, and optionally the camera aperture and focus. ```cpp -auto camera = scene_camera{}; // create a camera +auto camera = camera_data{}; // create a camera camera.frame = identity3x4f; // set frame to identity camera.lens = 0.050; // set as 50mm lens camera.aspect = 1.5; // set 3:2 aspect ratio @@ -320,7 +320,7 @@ auto mat = eval_material(scene,material,{0.5,0.5}) // eval material ## Textures -Textures, represented as `scene_texture`, contains either 8-bit LDR or +Textures, represented as `texture_data`, contains either 8-bit LDR or 32-bit float HDR images with four channels. Textures can be encoded in either a linear color space or as sRGBs, depending on an internal flag. The use of float versus byte is just a memory saving feature. @@ -328,12 +328,12 @@ float versus byte is just a memory saving feature. For textures, set the size, the color space, and _either_ the hdr or ldr pixels. ```cpp -auto hdr_texture = scene_texture{}; // create a texture +auto hdr_texture = texture_data{}; // create a texture hdr_texture.width = 512; // set size hdr_texture.height = 512; hdr_texture.linear = true; // set color space and pixels for an HDR hdr_texture.pixelsf = vector{...}; -auto ldr_texture = scene_texture{}; // create a texture +auto ldr_texture = texture_data{}; // create a texture ldr_texture.width = 512; // set size ldr_texture.height = 512; ldr_texture.linear = false; // set color space and pixels for an LDR diff --git a/docs/yocto/yocto_sceneio.md b/docs/yocto/yocto_sceneio.md index dff74801c..b91670d9b 100644 --- a/docs/yocto/yocto_sceneio.md +++ b/docs/yocto/yocto_sceneio.md @@ -108,7 +108,7 @@ by the chosen file format. ```cpp auto error = string{}; -auto texture = scene_texture{}; // define a texture +auto texture = texture_data{}; // define a texture if(!load_texture(filename, texture, error)) // load texture print_error(error); // check and print error if(!save_texture(filename, texture, error)) // save texture diff --git a/libs/yocto/yocto_scene.cpp b/libs/yocto/yocto_scene.cpp index 4ede9a935..4ef123bec 100644 --- a/libs/yocto/yocto_scene.cpp +++ b/libs/yocto/yocto_scene.cpp @@ -66,7 +66,7 @@ namespace yocto { // Generates a ray from a camera for yimg::image plane coordinate uv and // the lens coordinates luv. ray3f eval_camera( - const scene_camera& camera, const vec2f& image_uv, const vec2f& lens_uv) { + const camera_data& camera, const vec2f& image_uv, const vec2f& lens_uv) { auto film = camera.aspect >= 1 ? vec2f{camera.film, camera.film / camera.aspect} : vec2f{camera.film * camera.aspect, camera.film}; @@ -111,7 +111,7 @@ namespace yocto { // pixel access vec4f lookup_texture( - const scene_texture& texture, int i, int j, bool as_linear) { + const texture_data& texture, int i, int j, bool as_linear) { auto color = vec4f{0, 0, 0, 0}; if (!texture.pixelsf.empty()) { color = texture.pixelsf[j * texture.width + i]; @@ -126,8 +126,8 @@ vec4f lookup_texture( } // Evaluates an image at a point `uv`. -vec4f eval_texture(const scene_texture& texture, const vec2f& uv, - bool as_linear, bool no_interpolation, bool clamp_to_edge) { +vec4f eval_texture(const texture_data& texture, const vec2f& uv, bool as_linear, + bool no_interpolation, bool clamp_to_edge) { if (texture.width == 0 || texture.height == 0) return {0, 0, 0, 0}; // get texture width/height @@ -170,8 +170,8 @@ vec4f eval_texture(const scene_model& scene, int texture, const vec2f& uv, } // conversion from image -scene_texture image_to_texture(const color_image& image) { - auto texture = scene_texture{image.width, image.height, image.linear, {}, {}}; +texture_data image_to_texture(const color_image& image) { + auto texture = texture_data{image.width, image.height, image.linear, {}, {}}; if (image.linear) { texture.pixelsf = image.pixels; } else { diff --git a/libs/yocto/yocto_scene.h b/libs/yocto/yocto_scene.h index 9eef28795..4bc28647d 100644 --- a/libs/yocto/yocto_scene.h +++ b/libs/yocto/yocto_scene.h @@ -80,7 +80,7 @@ inline const int invalidid = -1; // 2.4:1 on 35 mm: 0.036 x 0.015 or 0.05760 x 0.024 (approx. 2.39 : 1) // To compute good apertures, one can use the F-stop number from photography // and set the aperture to focal length over f-stop. -struct scene_camera { +struct camera_data { frame3f frame = identity3x4f; bool orthographic = false; float lens = 0.050f; @@ -92,7 +92,7 @@ struct scene_camera { // Texture data as array of float or byte pixels. Textures can be stored in // linear or non linear color space. -struct scene_texture { +struct texture_data { int width = 0; int height = 0; bool linear = false; @@ -219,11 +219,11 @@ struct scene_subdiv { // updates node transformations only if defined. struct scene_model { // scene elements - vector cameras = {}; + vector cameras = {}; vector instances = {}; vector environments = {}; vector shapes = {}; - vector textures = {}; + vector textures = {}; vector materials = {}; vector subdivs = {}; @@ -249,7 +249,7 @@ namespace yocto { // Generates a ray from a camera. ray3f eval_camera( - const scene_camera& camera, const vec2f& image_uv, const vec2f& lens_uv); + const camera_data& camera, const vec2f& image_uv, const vec2f& lens_uv); } // namespace yocto @@ -259,7 +259,7 @@ ray3f eval_camera( namespace yocto { // Evaluates a texture -vec4f eval_texture(const scene_texture& texture, const vec2f& uv, +vec4f eval_texture(const texture_data& texture, const vec2f& uv, bool as_linear = false, bool no_interpolation = false, bool clamp_to_edge = false); vec4f eval_texture(const scene_model& scene, int texture, const vec2f& uv, @@ -268,10 +268,10 @@ vec4f eval_texture(const scene_model& scene, int texture, const vec2f& uv, // pixel access vec4f lookup_texture( - const scene_texture& texture, int i, int j, bool as_linear = false); + const texture_data& texture, int i, int j, bool as_linear = false); // conversion from image -scene_texture image_to_texture(const color_image& image); +texture_data image_to_texture(const color_image& image); } // namespace yocto @@ -600,8 +600,9 @@ void make_cornellbox(scene_model& scene); namespace yocto { using sceneio_scene = scene_model; -using sceneio_camera = scene_camera; -using sceneio_texture = scene_texture; +using sceneio_camera = camera_data; +using scene_camera = camera_data; +using sceneio_texture = texture_data; using sceneio_material = scene_material; using sceneio_shape = scene_shape; using sceneio_instance = scene_instance; diff --git a/libs/yocto/yocto_sceneio.cpp b/libs/yocto/yocto_sceneio.cpp index 8fd462061..6cab0fce4 100644 --- a/libs/yocto/yocto_sceneio.cpp +++ b/libs/yocto/yocto_sceneio.cpp @@ -756,7 +756,7 @@ namespace yocto { // Loads/saves an image. Chooses hdr or ldr based on file name. bool load_texture( - const string& filename, scene_texture& texture, string& error) { + const string& filename, texture_data& texture, string& error) { auto format_error = [filename, &error]() { error = filename + ": unknown format"; return false; @@ -854,7 +854,7 @@ bool load_texture( // Saves an hdr image. bool save_texture( - const string& filename, const scene_texture& texture, string& error) { + const string& filename, const texture_data& texture, string& error) { auto format_error = [filename, &error]() { error = filename + ": unknown format"; return false; @@ -920,7 +920,7 @@ bool save_texture( } bool make_texture_preset( - scene_texture& texture, const string& type, string& error) { + texture_data& texture, const string& type, string& error) { auto image = color_image{}; if (!make_image_preset(image, type, error)) return false; texture = image_to_texture(image); @@ -1749,7 +1749,7 @@ namespace yocto { } [[maybe_unused]] static string get_camera_name( - const scene_model& scene, const scene_camera& camera) { + const scene_model& scene, const camera_data& camera) { return get_camera_name(scene, (int)(&camera - scene.cameras.data())); } [[maybe_unused]] static string get_environment_name( @@ -1762,7 +1762,7 @@ namespace yocto { return get_shape_name(scene, (int)(&shape - scene.shapes.data())); } [[maybe_unused]] static string get_texture_name( - const scene_model& scene, const scene_texture& texture) { + const scene_model& scene, const texture_data& texture) { return get_texture_name(scene, (int)(&texture - scene.textures.data())); } [[maybe_unused]] static string get_instance_name( @@ -3861,7 +3861,7 @@ static bool load_gltf_scene(const string& filename, scene_model& scene, } // convert cameras - auto cameras = vector{}; + auto cameras = vector{}; if (gltf.contains("cameras")) { try { for (auto& gcamera : gltf.at("cameras")) { diff --git a/libs/yocto/yocto_sceneio.h b/libs/yocto/yocto_sceneio.h index 2d1e09b00..e381c3dbc 100644 --- a/libs/yocto/yocto_sceneio.h +++ b/libs/yocto/yocto_sceneio.h @@ -100,14 +100,13 @@ bool make_image_preset(color_image& image, const string& type, string& error); namespace yocto { // Load/save a texture in the supported formats. -bool load_texture( - const string& filename, scene_texture& texture, string& error); +bool load_texture(const string& filename, texture_data& texture, string& error); bool save_texture( - const string& filename, const scene_texture& texture, string& error); + const string& filename, const texture_data& texture, string& error); // Make presets. Supported mostly in IO. bool make_texture_preset( - scene_texture& texture, const string& type, string& error); + texture_data& texture, const string& type, string& error); } // namespace yocto diff --git a/libs/yocto/yocto_trace.cpp b/libs/yocto/yocto_trace.cpp index 244931f43..0cab7820e 100644 --- a/libs/yocto/yocto_trace.cpp +++ b/libs/yocto/yocto_trace.cpp @@ -236,7 +236,7 @@ static float sample_scattering_pdf(const material_point& material, } // Sample camera -static ray3f sample_camera(const scene_camera& camera, const vec2i& ij, +static ray3f sample_camera(const camera_data& camera, const vec2i& ij, const vec2i& image_size, const vec2f& puv, const vec2f& luv, bool tent) { if (!tent) { auto uv = vec2f{ diff --git a/libs/yocto_gui/yocto_glview.cpp b/libs/yocto_gui/yocto_glview.cpp index c965e8fb6..566540ca9 100644 --- a/libs/yocto_gui/yocto_glview.cpp +++ b/libs/yocto_gui/yocto_glview.cpp @@ -83,7 +83,7 @@ static bool uiupdate_image_params( } static bool uiupdate_camera_params( - const glinput_state& input, scene_camera& camera) { + const glinput_state& input, camera_data& camera) { if ((input.mouse_left || input.mouse_right) && !input.modifier_alt && !input.modifier_ctrl && !input.widgets_active) { auto dolly = 0.0f; @@ -1275,7 +1275,7 @@ void main() { #endif // Create texture -void set_texture(glscene_texture& gltexture, const scene_texture& texture) { +void set_texture(glscene_texture& gltexture, const texture_data& texture) { if (!gltexture.texture || gltexture.width != texture.width || gltexture.height != texture.height) { if (!gltexture.texture) glGenTextures(1, &gltexture.texture); diff --git a/libs/yocto_gui/yocto_glview.h b/libs/yocto_gui/yocto_glview.h index ddb4ff835..3272a7770 100644 --- a/libs/yocto_gui/yocto_glview.h +++ b/libs/yocto_gui/yocto_glview.h @@ -152,7 +152,7 @@ struct glscene_texture { }; // Create texture -void set_texture(glscene_texture& gltexture, const scene_texture& texture); +void set_texture(glscene_texture& gltexture, const texture_data& texture); // Clean texture void clear_texture(glscene_texture& gltexture); From 83bb526363f3d282ba149a780d6d8214c3eaccdf Mon Sep 17 00:00:00 2001 From: Fabio Pellacini Date: Wed, 9 Jun 2021 14:46:52 +0200 Subject: [PATCH 03/12] updated --- apps/ymesh/ymesh.cpp | 26 ++++++------- docs/yocto/yocto_scene.md | 28 +++++++------- libs/yocto/yocto_scene.cpp | 64 ++++++++++++++++---------------- libs/yocto/yocto_scene.h | 59 +++++++++++++++-------------- libs/yocto/yocto_sceneio.cpp | 54 +++++++++++++-------------- libs/yocto/yocto_trace.cpp | 66 ++++++++++++++++----------------- libs/yocto_gui/yocto_glview.cpp | 12 +++--- 7 files changed, 156 insertions(+), 153 deletions(-) diff --git a/apps/ymesh/ymesh.cpp b/apps/ymesh/ymesh.cpp index b28b143ce..431d5859f 100644 --- a/apps/ymesh/ymesh.cpp +++ b/apps/ymesh/ymesh.cpp @@ -141,7 +141,7 @@ static scene_model make_shapescene(const scene_shape& ioshape_) { // material auto& shape_material = scene.materials.emplace_back(); - shape_material.type = scene_material_type::glossy; + shape_material.type = material_type::glossy; shape_material.color = {0.5, 1, 0.5}; shape_material.roughness = 0.2; @@ -226,15 +226,15 @@ static scene_model make_pathscene(const scene_shape& ioshape_) { // material auto& shape_material = scene.materials.emplace_back(); - shape_material.type = scene_material_type::glossy; + shape_material.type = material_type::glossy; shape_material.color = {0.5, 1, 0.5}; shape_material.roughness = 0.2; auto& points_material = scene.materials.emplace_back(); - points_material.type = scene_material_type::glossy; + points_material.type = material_type::glossy; points_material.color = {1, 0.5, 0.5}; points_material.roughness = 0.2; auto& lines_material = scene.materials.emplace_back(); - lines_material.type = scene_material_type::glossy; + lines_material.type = material_type::glossy; lines_material.color = {0.5, 0.5, 1}; lines_material.roughness = 0.2; @@ -395,26 +395,26 @@ static scene_model make_pathdscene(const scene_shape& ioshape) { // material auto& shape_material = scene.materials.emplace_back(); - shape_material.type = scene_material_type::glossy; + shape_material.type = material_type::glossy; shape_material.color = {0.5, 1, 0.5}; shape_material.roughness = 0.2; auto& points_material = scene.materials.emplace_back(); - points_material.type = scene_material_type::matte; + points_material.type = material_type::matte; points_material.color = {1, 0.5, 0.5}; auto& lines1_material = scene.materials.emplace_back(); - lines1_material.type = scene_material_type::matte; + lines1_material.type = material_type::matte; lines1_material.color = {0.5, 0.5, 1}; auto& lines2_material = scene.materials.emplace_back(); - lines2_material.type = scene_material_type::matte; + lines2_material.type = material_type::matte; lines2_material.color = {1, 1, 0.5}; auto& lines3_material = scene.materials.emplace_back(); - lines3_material.type = scene_material_type::matte; + lines3_material.type = material_type::matte; lines3_material.color = {1, 0.5, 1}; auto& lines4_material = scene.materials.emplace_back(); - lines4_material.type = scene_material_type::matte; + lines4_material.type = material_type::matte; lines4_material.color = {0.5, 0.5, 0.5}; auto& edges_material = scene.materials.emplace_back(); - edges_material.type = scene_material_type::matte; + edges_material.type = material_type::matte; edges_material.color = {0, 0, 0}; // shapes @@ -1117,10 +1117,10 @@ static scene_model make_sculptscene(const scene_shape& ioshape_) { // material auto& shape_material = scene.materials.emplace_back(); - shape_material.type = scene_material_type::matte; + shape_material.type = material_type::matte; shape_material.color = {0.78f, 0.31f, 0.23f}; auto& cursor_material = scene.materials.emplace_back(); - cursor_material.type = scene_material_type::matte; + cursor_material.type = material_type::matte; // shapes scene.shapes.emplace_back(ioshape); diff --git a/docs/yocto/yocto_scene.md b/docs/yocto/yocto_scene.md index fc56291b6..d982cca5f 100644 --- a/docs/yocto/yocto_scene.md +++ b/docs/yocto/yocto_scene.md @@ -233,7 +233,7 @@ with `shape_to_fvshape(shape)` and `fvshape_to_shape(fvshape)`. ## Materials -Materials, represented as `scene_material`, are defined by a material type +Materials, represented as `material_data`, are defined by a material type and a few parameters, common to all materials. In particular, we support the following materials: @@ -275,27 +275,27 @@ We can further control the appearance by changing surface roughness, index of refraction and volumetric properties, when appropriate. Here are some examples. ```cpp -auto matte = scene_material{}; // create a matte material -matte.type = scene_material_type::matte; +auto matte = material_data{}; // create a matte material +matte.type = material_type::matte; matte.color = {1,0.5,0.5}; // with base color and matte.color_tex = texture_id; // textured albedo -auto glossy = scene_material{}; // create a glossy material -glossy.type = scene_material_type::glossy; +auto glossy = material_data{}; // create a glossy material +glossy.type = material_type::glossy; glossy.color = {0.5,1,0.5}; // with constant color glossyv.roughness = 0.1; // base roughness and a glossy.roughness_tex = texture_id; // roughness texture -auto metallic = scene_material{}; // create a metallic material -glossy.type = scene_material_type::metallic +auto metallic = material_data{}; // create a metallic material +glossy.type = material_type::metallic metal.color = {0.5,0.5,1}; // constant color metal.roughness = 0.1; // constant roughness -auto tglass = scene_material{}; // create a transparent material -tglass.type = scene_material_type::transparent; +auto tglass = material_data{}; // create a transparent material +tglass.type = material_type::transparent; tglass.color = {1,1,1}; // with constant color -auto glass = scene_material{}; // create a refractive material -glass.type = scene_material_type::transparent; +auto glass = material_data{}; // create a refractive material +glass.type = material_type::transparent; glass.color = {1,0.9,0.9}; // constant color -auto subsurf = scene_material{}; // create a refractive material -subsurf.type = scene_material_type::subsurface; +auto subsurf = material_data{}; // create a refractive material +subsurf.type = material_type::subsurface; subsurf.color = {1,1,1}; // that transmits all light subsurf.scattering = {0.5,1,0.5}; // and has volumetric scattering ``` @@ -304,7 +304,7 @@ Lights are not explicit in Yocto/Scene but are specified by assigning emissive materials. ```cpp -auto light = scene_material{}; // create a material +auto light = material_data{}; // create a material light.color = {0,0,0}; // that does not reflect light light.emission = {10,10,10}; // but emits it instead ``` diff --git a/libs/yocto/yocto_scene.cpp b/libs/yocto/yocto_scene.cpp index 4ef123bec..ec348b694 100644 --- a/libs/yocto/yocto_scene.cpp +++ b/libs/yocto/yocto_scene.cpp @@ -193,7 +193,7 @@ static const auto min_roughness = 0.03f * 0.03f; // Evaluate material material_point eval_material(const scene_model& scene, - const scene_material& material, const vec2f& texcoord, + const material_data& material, const vec2f& texcoord, const vec4f& color_shp) { // evaluate textures auto emission_tex = eval_texture( @@ -219,18 +219,18 @@ material_point eval_material(const scene_model& scene, point.trdepth = material.trdepth; // volume density - if (material.type == scene_material_type::refractive || - material.type == scene_material_type::volume || - material.type == scene_material_type::subsurface) { + if (material.type == material_type::refractive || + material.type == material_type::volume || + material.type == material_type::subsurface) { point.density = -log(clamp(point.color, 0.0001f, 1.0f)) / point.trdepth; } else { point.density = {0, 0, 0}; } // fix roughness - if (point.type == scene_material_type::matte || - point.type == scene_material_type::gltfpbr || - point.type == scene_material_type::glossy) { + if (point.type == material_type::matte || + point.type == material_type::gltfpbr || + point.type == material_type::glossy) { point.roughness = clamp(point.roughness, min_roughness, 1.0f); } @@ -238,35 +238,35 @@ material_point eval_material(const scene_model& scene, } // check if a material is a delta or volumetric -bool is_delta(const scene_material& material) { - return (material.type == scene_material_type::metallic && +bool is_delta(const material_data& material) { + return (material.type == material_type::metallic && material.roughness == 0) || - (material.type == scene_material_type::refractive && + (material.type == material_type::refractive && material.roughness == 0) || - (material.type == scene_material_type::transparent && + (material.type == material_type::transparent && material.roughness == 0) || - (material.type == scene_material_type::volume); + (material.type == material_type::volume); } -bool is_volumetric(const scene_material& material) { - return material.type == scene_material_type::refractive || - material.type == scene_material_type::volume || - material.type == scene_material_type::subsurface; +bool is_volumetric(const material_data& material) { + return material.type == material_type::refractive || + material.type == material_type::volume || + material.type == material_type::subsurface; } // check if a brdf is a delta bool is_delta(const material_point& material) { - return (material.type == scene_material_type::metallic && + return (material.type == material_type::metallic && material.roughness == 0) || - (material.type == scene_material_type::refractive && + (material.type == material_type::refractive && material.roughness == 0) || - (material.type == scene_material_type::transparent && + (material.type == material_type::transparent && material.roughness == 0) || - (material.type == scene_material_type::volume); + (material.type == material_type::volume); } bool has_volume(const material_point& material) { - return material.type == scene_material_type::refractive || - material.type == scene_material_type::volume || - material.type == scene_material_type::subsurface; + return material.type == material_type::refractive || + material.type == material_type::volume || + material.type == material_type::subsurface; } } // namespace yocto @@ -937,7 +937,7 @@ vec3f eval_shading_normal(const scene_model& scene, if (material.normal_tex != invalidid) { normal = eval_normalmap(scene, instance, element, uv); } - if (material.type == scene_material_type::refractive) return normal; + if (material.type == material_type::refractive) return normal; return dot(normal, outgoing) >= 0 ? normal : -normal; } else if (!shape.lines.empty()) { auto normal = eval_normal(scene, instance, element, uv); @@ -1003,20 +1003,20 @@ material_point eval_material(const scene_model& scene, point.trdepth = material.trdepth; // volume density - if (material.type == scene_material_type::refractive || - material.type == scene_material_type::volume || - material.type == scene_material_type::subsurface) { + if (material.type == material_type::refractive || + material.type == material_type::volume || + material.type == material_type::subsurface) { point.density = -log(clamp(point.color, 0.0001f, 1.0f)) / point.trdepth; } else { point.density = {0, 0, 0}; } // fix roughness - if (point.type == scene_material_type::matte || - point.type == scene_material_type::gltfpbr || - point.type == scene_material_type::glossy) { + if (point.type == material_type::matte || + point.type == material_type::gltfpbr || + point.type == material_type::glossy) { point.roughness = clamp(point.roughness, min_roughness, 1.0f); - } else if (material.type == scene_material_type::volume) { + } else if (material.type == material_type::volume) { point.roughness = 0; } else { if (point.roughness < min_roughness) point.roughness = 0; @@ -1129,7 +1129,7 @@ scene_model make_shape_scene(const scene_shape& shape, bool addsky) { // material scene.material_names.emplace_back("material"); auto& shape_material = scene.materials.emplace_back(); - shape_material.type = scene_material_type::glossy; + shape_material.type = material_type::glossy; shape_material.color = {0.5f, 1.0f, 0.5f}; shape_material.roughness = 0.2f; // instance diff --git a/libs/yocto/yocto_scene.h b/libs/yocto/yocto_scene.h index 4bc28647d..d4e653068 100644 --- a/libs/yocto/yocto_scene.h +++ b/libs/yocto/yocto_scene.h @@ -101,7 +101,7 @@ struct texture_data { }; // Material type -enum struct scene_material_type { +enum struct material_type { // clang-format off matte, glossy, metallic, transparent, refractive, subsurface, volume, gltfpbr // clang-format on @@ -116,18 +116,18 @@ inline const auto scene_material_names = std::vector{"matte", // For surfaces, uses a microfacet model with thin sheet transmission. // The model is based on OBJ, but contains glTF compatibility. // For the documentation on the values, please see the OBJ format. -struct scene_material { +struct material_data { // material - scene_material_type type = scene_material_type::matte; - vec3f emission = {0, 0, 0}; - vec3f color = {0, 0, 0}; - float roughness = 0; - float metallic = 0; - float ior = 1.5f; - vec3f scattering = {0, 0, 0}; - float scanisotropy = 0; - float trdepth = 0.01f; - float opacity = 1; + material_type type = material_type::matte; + vec3f emission = {0, 0, 0}; + vec3f color = {0, 0, 0}; + float roughness = 0; + float metallic = 0; + float ior = 1.5f; + vec3f scattering = {0, 0, 0}; + float scanisotropy = 0; + float trdepth = 0.01f; + float opacity = 1; // textures int emission_tex = invalidid; @@ -224,7 +224,7 @@ struct scene_model { vector environments = {}; vector shapes = {}; vector textures = {}; - vector materials = {}; + vector materials = {}; vector subdivs = {}; // names (this will be cleanup significantly later) @@ -282,30 +282,30 @@ namespace yocto { // Material parameters evaluated at a point on the surface struct material_point { - scene_material_type type = scene_material_type::gltfpbr; - vec3f emission = {0, 0, 0}; - vec3f color = {0, 0, 0}; - float opacity = 1; - float roughness = 0; - float metallic = 0; - float ior = 1; - vec3f density = {0, 0, 0}; - vec3f scattering = {0, 0, 0}; - float scanisotropy = 0; - float trdepth = 0.01f; + material_type type = material_type::gltfpbr; + vec3f emission = {0, 0, 0}; + vec3f color = {0, 0, 0}; + float opacity = 1; + float roughness = 0; + float metallic = 0; + float ior = 1; + vec3f density = {0, 0, 0}; + vec3f scattering = {0, 0, 0}; + float scanisotropy = 0; + float trdepth = 0.01f; }; // Eval material to obtain emission, brdf and opacity. material_point eval_material(const scene_model& scene, - const scene_material& material, const vec2f& texcoord, + const material_data& material, const vec2f& texcoord, const vec4f& shape_color = {1, 1, 1, 1}); // check if a material is a delta -bool is_delta(const scene_material& material); +bool is_delta(const material_data& material); bool is_delta(const material_point& material); // check if a material has a volume -bool is_volumetric(const scene_material& material); +bool is_volumetric(const material_data& material); bool is_volumetric(const material_point& material); bool is_volumetric(const scene_model& scene, const scene_instance& instance); @@ -603,7 +603,10 @@ using sceneio_scene = scene_model; using sceneio_camera = camera_data; using scene_camera = camera_data; using sceneio_texture = texture_data; -using sceneio_material = scene_material; +using scene_texture = texture_data; +using sceneio_material = material_data; +using scene_material_type = material_type; +using sceneio_material = material_data; using sceneio_shape = scene_shape; using sceneio_instance = scene_instance; using sceneio_environment = scene_environment; diff --git a/libs/yocto/yocto_sceneio.cpp b/libs/yocto/yocto_sceneio.cpp index 6cab0fce4..a9af423ee 100644 --- a/libs/yocto/yocto_sceneio.cpp +++ b/libs/yocto/yocto_sceneio.cpp @@ -1770,7 +1770,7 @@ namespace yocto { return get_instance_name(scene, (int)(&instance - scene.instances.data())); } [[maybe_unused]] static string get_material_name( - const scene_model& scene, const scene_material& material) { + const scene_model& scene, const material_data& material) { return get_material_name(scene, (int)(&material - scene.materials.data())); } [[maybe_unused]] static string get_subdiv_name( @@ -2615,16 +2615,16 @@ inline void from_json(const njson& j, mat4f& value) { nlohmann::from_json(j, (array&)value); } -inline void to_json(njson& j, scene_material_type value) { +inline void to_json(njson& j, material_type value) { j = scene_material_names.at((int)value); } -inline void from_json(const njson& j, scene_material_type& value) { +inline void from_json(const njson& j, material_type& value) { auto values = j.get(); auto pos = std::find( scene_material_names.begin(), scene_material_names.end(), values); if (pos == scene_material_names.end()) throw std::invalid_argument{"unknown value"}; - value = (scene_material_type)(pos - scene_material_names.begin()); + value = (material_type)(pos - scene_material_names.begin()); } } // namespace yocto @@ -3476,23 +3476,23 @@ static bool load_obj_scene(const string& filename, scene_model& scene, // handler for materials for (auto& omaterial : obj.materials) { auto& material = scene.materials.emplace_back(); - material.type = scene_material_type::gltfpbr; + material.type = material_type::gltfpbr; material.emission = omaterial.emission; material.emission_tex = omaterial.emission_tex; if (max(omaterial.transmission) > 0.1) { - material.type = scene_material_type::transparent; + material.type = material_type::transparent; material.color = omaterial.transmission; material.color_tex = omaterial.transmission_tex; } else if (max(omaterial.specular) > 0.2) { - material.type = scene_material_type::metallic; + material.type = material_type::metallic; material.color = omaterial.specular; material.color_tex = omaterial.specular_tex; } else if (max(omaterial.specular) > 0) { - material.type = scene_material_type::glossy; + material.type = material_type::glossy; material.color = omaterial.diffuse; material.color_tex = omaterial.diffuse_tex; } else { - material.type = scene_material_type::matte; + material.type = material_type::matte; material.color = omaterial.diffuse; material.color_tex = omaterial.diffuse_tex; } @@ -3934,7 +3934,7 @@ static bool load_gltf_scene(const string& filename, scene_model& scene, try { for (auto& gmaterial : gltf.at("materials")) { auto& material = scene.materials.emplace_back(); - material.type = scene_material_type::gltfpbr; + material.type = material_type::gltfpbr; material.emission = gmaterial.value("emissiveFactor", vec3f{0, 0, 0}); material.emission_tex = get_texture(gmaterial, "emissiveTexture"); material.normal_tex = get_texture(gmaterial, "normalTexture"); @@ -3955,7 +3955,7 @@ static bool load_gltf_scene(const string& filename, scene_model& scene, gmaterial.at("extensions").at("KHR_materials_transmission"); auto transmission = gtransmission.value("transmissionFactor", 1.0f); if (transmission > 0) { - material.type = scene_material_type::transparent; + material.type = material_type::transparent; material.color = {transmission, transmission, transmission}; material.color_tex = get_texture(gmaterial, "transmissionTexture"); // material.roughness = 0; // leave it set from before @@ -4693,13 +4693,13 @@ static bool load_pbrt_scene(const string& filename, scene_model& scene, } // material type map - auto material_type_map = unordered_map{ - {pbrt_mtype::matte, scene_material_type::matte}, - {pbrt_mtype::plastic, scene_material_type::glossy}, - {pbrt_mtype::metal, scene_material_type::metallic}, - {pbrt_mtype::glass, scene_material_type::refractive}, - {pbrt_mtype::thinglass, scene_material_type::transparent}, - {pbrt_mtype::subsurface, scene_material_type::matte}, + auto material_type_map = unordered_map{ + {pbrt_mtype::matte, material_type::matte}, + {pbrt_mtype::plastic, material_type::glossy}, + {pbrt_mtype::metal, material_type::metallic}, + {pbrt_mtype::glass, material_type::refractive}, + {pbrt_mtype::thinglass, material_type::transparent}, + {pbrt_mtype::subsurface, material_type::matte}, }; // convert material @@ -4707,7 +4707,7 @@ static bool load_pbrt_scene(const string& filename, scene_model& scene, auto& material = scene.materials.emplace_back(); material.type = material_type_map.at(pmaterial.type); if (pmaterial.emission != zero3f) { - material.type = scene_material_type::matte; + material.type = material_type::matte; } material.emission = pmaterial.emission; material.color = pmaterial.color; @@ -4853,14 +4853,14 @@ static bool save_pbrt_scene(const string& filename, const scene_model& scene, } // material type map - auto material_type_map = unordered_map{ - {scene_material_type::matte, pbrt_mtype::matte}, - {scene_material_type::glossy, pbrt_mtype::plastic}, - {scene_material_type::metallic, pbrt_mtype::metal}, - {scene_material_type::refractive, pbrt_mtype::glass}, - {scene_material_type::transparent, pbrt_mtype::thinglass}, - {scene_material_type::subsurface, pbrt_mtype::matte}, - {scene_material_type::volume, pbrt_mtype::matte}, + auto material_type_map = unordered_map{ + {material_type::matte, pbrt_mtype::matte}, + {material_type::glossy, pbrt_mtype::plastic}, + {material_type::metallic, pbrt_mtype::metal}, + {material_type::refractive, pbrt_mtype::glass}, + {material_type::transparent, pbrt_mtype::thinglass}, + {material_type::subsurface, pbrt_mtype::matte}, + {material_type::volume, pbrt_mtype::matte}, }; // convert materials diff --git a/libs/yocto/yocto_trace.cpp b/libs/yocto/yocto_trace.cpp index 0cab7820e..7038fff2c 100644 --- a/libs/yocto/yocto_trace.cpp +++ b/libs/yocto/yocto_trace.cpp @@ -74,24 +74,24 @@ static vec3f eval_bsdfcos(const material_point& material, const vec3f& normal, const vec3f& outgoing, const vec3f& incoming) { if (material.roughness == 0) return zero3f; - if (material.type == scene_material_type::matte) { + if (material.type == material_type::matte) { return eval_matte(material.color, normal, outgoing, incoming); - } else if (material.type == scene_material_type::glossy) { + } else if (material.type == material_type::glossy) { return eval_glossy(material.color, material.ior, material.roughness, normal, outgoing, incoming); - } else if (material.type == scene_material_type::metallic) { + } else if (material.type == material_type::metallic) { return eval_metallic( material.color, material.roughness, normal, outgoing, incoming); - } else if (material.type == scene_material_type::transparent) { + } else if (material.type == material_type::transparent) { return eval_transparent(material.color, material.ior, material.roughness, normal, outgoing, incoming); - } else if (material.type == scene_material_type::refractive) { + } else if (material.type == material_type::refractive) { return eval_refractive(material.color, material.ior, material.roughness, normal, outgoing, incoming); - } else if (material.type == scene_material_type::subsurface) { + } else if (material.type == material_type::subsurface) { return eval_refractive(material.color, material.ior, material.roughness, normal, outgoing, incoming); - } else if (material.type == scene_material_type::gltfpbr) { + } else if (material.type == material_type::gltfpbr) { return eval_gltfpbr(material.color, material.ior, material.roughness, material.metallic, normal, outgoing, incoming); } else { @@ -103,15 +103,15 @@ static vec3f eval_delta(const material_point& material, const vec3f& normal, const vec3f& outgoing, const vec3f& incoming) { if (material.roughness != 0) return zero3f; - if (material.type == scene_material_type::metallic) { + if (material.type == material_type::metallic) { return eval_metallic(material.color, normal, outgoing, incoming); - } else if (material.type == scene_material_type::transparent) { + } else if (material.type == material_type::transparent) { return eval_transparent( material.color, material.ior, normal, outgoing, incoming); - } else if (material.type == scene_material_type::refractive) { + } else if (material.type == material_type::refractive) { return eval_refractive( material.color, material.ior, normal, outgoing, incoming); - } else if (material.type == scene_material_type::volume) { + } else if (material.type == material_type::volume) { return eval_passthrough(material.color, normal, outgoing, incoming); } else { return {0, 0, 0}; @@ -123,24 +123,24 @@ static vec3f sample_bsdfcos(const material_point& material, const vec3f& normal, const vec3f& outgoing, float rnl, const vec2f& rn) { if (material.roughness == 0) return zero3f; - if (material.type == scene_material_type::matte) { + if (material.type == material_type::matte) { return sample_matte(material.color, normal, outgoing, rn); - } else if (material.type == scene_material_type::glossy) { + } else if (material.type == material_type::glossy) { return sample_specular(material.color, material.ior, material.roughness, normal, outgoing, rnl, rn); - } else if (material.type == scene_material_type::metallic) { + } else if (material.type == material_type::metallic) { return sample_metallic( material.color, material.roughness, normal, outgoing, rn); - } else if (material.type == scene_material_type::transparent) { + } else if (material.type == material_type::transparent) { return sample_transparent(material.color, material.ior, material.roughness, normal, outgoing, rnl, rn); - } else if (material.type == scene_material_type::refractive) { + } else if (material.type == material_type::refractive) { return sample_refractive(material.color, material.ior, material.roughness, normal, outgoing, rnl, rn); - } else if (material.type == scene_material_type::subsurface) { + } else if (material.type == material_type::subsurface) { return sample_refractive(material.color, material.ior, material.roughness, normal, outgoing, rnl, rn); - } else if (material.type == scene_material_type::gltfpbr) { + } else if (material.type == material_type::gltfpbr) { return sample_gltfpbr(material.color, material.ior, material.roughness, material.metallic, normal, outgoing, rnl, rn); } else { @@ -152,15 +152,15 @@ static vec3f sample_delta(const material_point& material, const vec3f& normal, const vec3f& outgoing, float rnl) { if (material.roughness != 0) return zero3f; - if (material.type == scene_material_type::metallic) { + if (material.type == material_type::metallic) { return sample_metallic(material.color, normal, outgoing); - } else if (material.type == scene_material_type::transparent) { + } else if (material.type == material_type::transparent) { return sample_transparent( material.color, material.ior, normal, outgoing, rnl); - } else if (material.type == scene_material_type::refractive) { + } else if (material.type == material_type::refractive) { return sample_refractive( material.color, material.ior, normal, outgoing, rnl); - } else if (material.type == scene_material_type::volume) { + } else if (material.type == material_type::volume) { return sample_passthrough(material.color, normal, outgoing); } else { return {0, 0, 0}; @@ -172,24 +172,24 @@ static float sample_bsdfcos_pdf(const material_point& material, const vec3f& normal, const vec3f& outgoing, const vec3f& incoming) { if (material.roughness == 0) return 0; - if (material.type == scene_material_type::matte) { + if (material.type == material_type::matte) { return sample_matte_pdf(material.color, normal, outgoing, incoming); - } else if (material.type == scene_material_type::glossy) { + } else if (material.type == material_type::glossy) { return sample_glossy_pdf(material.color, material.ior, material.roughness, normal, outgoing, incoming); - } else if (material.type == scene_material_type::metallic) { + } else if (material.type == material_type::metallic) { return sample_metallic_pdf( material.color, material.roughness, normal, outgoing, incoming); - } else if (material.type == scene_material_type::transparent) { + } else if (material.type == material_type::transparent) { return sample_tranparent_pdf(material.color, material.ior, material.roughness, normal, outgoing, incoming); - } else if (material.type == scene_material_type::refractive) { + } else if (material.type == material_type::refractive) { return sample_refractive_pdf(material.color, material.ior, material.roughness, normal, outgoing, incoming); - } else if (material.type == scene_material_type::subsurface) { + } else if (material.type == material_type::subsurface) { return sample_refractive_pdf(material.color, material.ior, material.roughness, normal, outgoing, incoming); - } else if (material.type == scene_material_type::gltfpbr) { + } else if (material.type == material_type::gltfpbr) { return sample_gltfpbr_pdf(material.color, material.ior, material.roughness, material.metallic, normal, outgoing, incoming); } else { @@ -201,15 +201,15 @@ static float sample_delta_pdf(const material_point& material, const vec3f& normal, const vec3f& outgoing, const vec3f& incoming) { if (material.roughness != 0) return 0; - if (material.type == scene_material_type::metallic) { + if (material.type == material_type::metallic) { return sample_metallic_pdf(material.color, normal, outgoing, incoming); - } else if (material.type == scene_material_type::transparent) { + } else if (material.type == material_type::transparent) { return sample_tranparent_pdf( material.color, material.ior, normal, outgoing, incoming); - } else if (material.type == scene_material_type::refractive) { + } else if (material.type == material_type::refractive) { return sample_refractive_pdf( material.color, material.ior, normal, outgoing, incoming); - } else if (material.type == scene_material_type::volume) { + } else if (material.type == material_type::volume) { return sample_passthrough_pdf(material.color, normal, outgoing, incoming); } else { return 0; diff --git a/libs/yocto_gui/yocto_glview.cpp b/libs/yocto_gui/yocto_glview.cpp index 566540ca9..f7bb3a11f 100644 --- a/libs/yocto_gui/yocto_glview.cpp +++ b/libs/yocto_gui/yocto_glview.cpp @@ -1588,14 +1588,14 @@ void draw_scene(glscene_state& glscene, const scene_model& scene, glUniform1f(glGetUniformLocation(program, "metallic"), material.metallic); glUniform1f(glGetUniformLocation(program, "roughness"), material.roughness); glUniform1f(glGetUniformLocation(program, "opacity"), material.opacity); - if (material.type == scene_material_type::matte || - material.type == scene_material_type::transparent || - material.type == scene_material_type::refractive || - material.type == scene_material_type::subsurface || - material.type == scene_material_type::volume) { + if (material.type == material_type::matte || + material.type == material_type::transparent || + material.type == material_type::refractive || + material.type == material_type::subsurface || + material.type == material_type::volume) { glUniform1f(glGetUniformLocation(program, "specular"), 0); } - if (material.type == scene_material_type::metallic) { + if (material.type == material_type::metallic) { glUniform1f(glGetUniformLocation(program, "metallic"), 1); } glUniform1f(glGetUniformLocation(program, "double_sided"), From 1d13ee4f8a77430d1473bb0abac2e82b9723f4ea Mon Sep 17 00:00:00 2001 From: Fabio Pellacini Date: Wed, 9 Jun 2021 14:49:48 +0200 Subject: [PATCH 04/12] updated --- apps/ymesh/ymesh.cpp | 34 +++--- apps/yshape/yshape.cpp | 12 +- docs/yocto/yocto_scene.md | 14 +-- docs/yocto/yocto_sceneio.md | 2 +- docs/yocto/yocto_shape.md | 2 +- libs/yocto/yocto_bvh.cpp | 16 +-- libs/yocto/yocto_bvh.h | 8 +- libs/yocto/yocto_scene.cpp | 192 ++++++++++++++++---------------- libs/yocto/yocto_scene.h | 136 +++++++++++----------- libs/yocto/yocto_sceneio.cpp | 34 +++--- libs/yocto/yocto_sceneio.h | 6 +- libs/yocto_gui/yocto_glview.cpp | 2 +- libs/yocto_gui/yocto_glview.h | 2 +- 13 files changed, 232 insertions(+), 228 deletions(-) diff --git a/apps/ymesh/ymesh.cpp b/apps/ymesh/ymesh.cpp index 431d5859f..cde874bc2 100644 --- a/apps/ymesh/ymesh.cpp +++ b/apps/ymesh/ymesh.cpp @@ -69,7 +69,7 @@ int run_view(const view_params& params) { // view shapes int run_view(const view_params& params) { // load mesh - auto shape = scene_shape{}; + auto shape = shape_data{}; auto ioerror = ""s; if (path_filename(params.shape) == ".ypreset") { if (!make_shape_preset(shape, path_basename(params.shape), ioerror)) @@ -110,7 +110,7 @@ int run_glview(const glview_params& params) { #else -static scene_model make_shapescene(const scene_shape& ioshape_) { +static scene_model make_shapescene(const shape_data& ioshape_) { // Frame camera auto camera_frame = [](float lens, float aspect, float film = 0.036) -> frame3f { @@ -160,7 +160,7 @@ static scene_model make_shapescene(const scene_shape& ioshape_) { int run_glview(const glview_params& params) { // loading shape auto ioerror = ""s; - auto shape = scene_shape{}; + auto shape = shape_data{}; if (!load_shape(params.shape, shape, ioerror, true)) print_fatal(ioerror); // create scene @@ -195,7 +195,7 @@ int run_glpath(const glpath_params& params) { #else -static scene_model make_pathscene(const scene_shape& ioshape_) { +static scene_model make_pathscene(const shape_data& ioshape_) { // Frame camera auto camera_frame = [](float lens, float aspect, float film = 0.036) -> frame3f { @@ -261,7 +261,7 @@ static scene_model make_pathscene(const scene_shape& ioshape_) { int run_glpath(const glpath_params& params) { // loading shape auto ioerror = ""s; - auto ioshape = scene_shape{}; + auto ioshape = shape_data{}; if (!load_shape(params.shape, ioshape, ioerror, true)) print_fatal(ioerror); if (!ioshape.quads.empty()) { ioshape.triangles = quads_to_triangles(ioshape.quads); @@ -372,7 +372,7 @@ int run_glpathd(const glpathd_params& params) { #else -static scene_model make_pathdscene(const scene_shape& ioshape) { +static scene_model make_pathdscene(const shape_data& ioshape) { // Frame camera auto camera_frame = [](float lens, float aspect, float film = 0.036) -> frame3f { @@ -467,7 +467,7 @@ static scene_model make_pathdscene(const scene_shape& ioshape) { int run_glpathd(const glpathd_params& params) { // loading shape auto ioerror = ""s; - auto ioshape = scene_shape{}; + auto ioshape = shape_data{}; if (!load_shape(params.shape, ioshape, ioerror, true)) print_fatal(ioerror); if (!ioshape.quads.empty()) { ioshape.triangles = quads_to_triangles(ioshape.quads); @@ -636,12 +636,12 @@ struct sculpt_state { vec2f last_uv = {}; bool instroke = false; // shape at the beginning of the stroke - scene_shape base_shape = {}; + shape_data base_shape = {}; }; // Initialize all sculpting parameters. sculpt_state make_sculpt_state( - const scene_shape& shape, const texture_data& texture) { + const shape_data& shape, const texture_data& texture) { auto state = sculpt_state{}; state.bvh = make_triangles_bvh( shape.triangles, shape.positions, shape.radius); @@ -656,7 +656,7 @@ sculpt_state make_sculpt_state( return state; } -scene_shape make_circle( +shape_data make_circle( const vec3f& center, const mat3f& basis, float radius, int steps) { // 4 initial vertices auto lines = make_lines({1, 4}); @@ -703,8 +703,8 @@ scene_shape make_circle( } // To visualize mouse intersection on mesh -scene_shape make_cursor(const vec3f& position, const vec3f& normal, - float radius, float height = 0.05f) { +shape_data make_cursor(const vec3f& position, const vec3f& normal, float radius, + float height = 0.05f) { auto basis = basis_fromz(normal); auto cursor = make_circle(position, basis, radius, 32); cursor.normals.clear(); @@ -1087,7 +1087,7 @@ bool smooth_brush(vector& positions, const geodesic_solver& solver, return true; } -static scene_model make_sculptscene(const scene_shape& ioshape_) { +static scene_model make_sculptscene(const shape_data& ioshape_) { // Frame camera auto camera_frame = [](float lens, float aspect, float film = 0.036) -> frame3f { @@ -1140,7 +1140,7 @@ static scene_model make_sculptscene(const scene_shape& ioshape_) { // To make the stroke sampling (position, normal) following the mouse static pair, vec2f> sample_stroke(const shape_bvh& bvh, - const scene_shape& shape, const vec2f& last_uv, const vec2f& mouse_uv, + const shape_data& shape, const vec2f& last_uv, const vec2f& mouse_uv, const camera_data& camera, const sculpt_params& params) { // helper auto intersect_shape = [&](const vec2f& uv) { @@ -1174,8 +1174,8 @@ static pair, vec2f> sample_stroke(const shape_bvh& bvh, return {samples, cur_uv}; } -static pair sculpt_update(sculpt_state& state, scene_shape& shape, - scene_shape& cursor, const camera_data& camera, const vec2f& mouse_uv, +static pair sculpt_update(sculpt_state& state, shape_data& shape, + shape_data& cursor, const camera_data& camera, const vec2f& mouse_uv, bool mouse_pressed, const sculpt_params& params) { auto updated_shape = false, updated_cursor = false; @@ -1243,7 +1243,7 @@ static pair sculpt_update(sculpt_state& state, scene_shape& shape, int run_glsculpt(const glsculpt_params& params_) { // loading shape auto ioerror = ""s; - auto ioshape = scene_shape{}; + auto ioshape = shape_data{}; if (!load_shape(params_.shape, ioshape, ioerror, true)) print_fatal(ioerror); if (!ioshape.quads.empty()) { ioshape.triangles = quads_to_triangles(ioshape.quads); diff --git a/apps/yshape/yshape.cpp b/apps/yshape/yshape.cpp index 8f3dabd1d..51c3811f6 100644 --- a/apps/yshape/yshape.cpp +++ b/apps/yshape/yshape.cpp @@ -83,7 +83,7 @@ void add_command(const cli_command& cli, const string& name, // convert images int run_convert(const convert_params& params) { // shape data - auto shape = scene_shape{}; + auto shape = shape_data{}; // load mesh auto ioerror = ""s; @@ -309,7 +309,7 @@ int run_view(const view_params& params) { // view shapes int run_view(const view_params& params) { // load shape - auto shape = scene_shape{}; + auto shape = shape_data{}; auto ioerror = ""s; if (path_filename(params.shape) == ".ypreset") { if (!make_shape_preset(shape, path_basename(params.shape), ioerror)) @@ -432,7 +432,7 @@ void add_command(const cli_command& cli, const string& name, int run_hair(const hair_params& params) { // load mesh - auto shape = scene_shape{}; + auto shape = shape_data{}; auto ioerror = ""s; if (!load_shape(params.shape, shape, ioerror)) print_fatal(ioerror); @@ -464,7 +464,7 @@ void add_command(const cli_command& cli, const string& name, int run_sample(const sample_params& params) { // load mesh - auto shape = scene_shape{}; + auto shape = shape_data{}; auto ioerror = ""s; if (!load_shape(params.shape, shape, ioerror)) print_fatal(ioerror); @@ -472,7 +472,7 @@ int run_sample(const sample_params& params) { auto samples = sample_shape(shape, params.samples); // sample shape - auto sshape = scene_shape{}; + auto sshape = shape_data{}; for (auto& sample : samples) { sshape.points.push_back((int)sshape.points.size()); sshape.positions.push_back(eval_position(shape, sample.element, sample.uv)); @@ -511,7 +511,7 @@ int run_glview(const glview_params& params) { int run_glview(const glview_params& params) { // loading shape auto ioerror = ""s; - auto shape = scene_shape{}; + auto shape = shape_data{}; if (!load_shape(params.shape, shape, ioerror, true)) print_fatal(ioerror); // make scene diff --git a/docs/yocto/yocto_scene.md b/docs/yocto/yocto_scene.md index d982cca5f..5091bb164 100644 --- a/docs/yocto/yocto_scene.md +++ b/docs/yocto/yocto_scene.md @@ -37,7 +37,7 @@ Here is an sketch of how to create a shape instance in a scene. ```cpp auto scene = scene_model{}; // create a scene -auto shape = scene_shape{}; // create a shape and add it +auto shape = shape_data{}; // create a shape and add it set_shape_properties(shape, ...); scene.shapes.push_back(shape); scene.materials.push_back({}); // create a black material directly @@ -173,7 +173,7 @@ auto envi = eval_environment(environment, dir); // eval environment ## Shapes -Shapes, represented by `scene_shape`, are indexed meshes of elements. +Shapes, represented by `shape_data`, are indexed meshes of elements. Shapes can contain only one type of element, either points, lines, triangles or quads. Shape elements are parametrized as in [Yocto/Geometry](yocto_geometry.md). @@ -190,7 +190,7 @@ or quads, and the vertex properties, i.e. positions, normals, texture coordinates, colors and radia. Shapes support only one element type. ```cpp -auto shape = scene_shape{}; // create a shape +auto shape = shape_data{}; // create a shape shape.triangles = vector{...}; // set triangle indices shape.positions = vector{...}; // set positions shape.normals = vector{...}; // set normals @@ -419,7 +419,7 @@ a comprehensive list of all procedural shapes supported. Procedural shapes take as input the desired shape resolution, the shape scale, the uv scale, and additional parameters specific to that procedural shape. -These functions return a quad mesh, stored as a `scene_shape` struct. +These functions return a quad mesh, stored as a `shape_data` struct. Use `make_rect(...)` for a rectangle in the XY plane, `make_bulged_rect(...)` for a bulged rectangle, `make_recty(...)` for a rectangle in the XZ plane, @@ -473,14 +473,14 @@ auto fvshape_03 = make_fvsphere(32, 1); Yocto/Shape provides functions to create predefined shapes helpful in testing. These functions take only a scale and often provide only the positions as vertex data. These functions return either triangles, quads, or -face-varying quads in a `scene_shape` or `scene_fvshape` struct. +face-varying quads in a `shape_data` or `scene_fvshape` struct. Use `make_monkey(...)` for the Blender monkey as quads and positions only, `make_quad(...)` for a simple quad, `make_quady(...)` for a simple quad in the XZ plane, `make_cube(...)` for a simple cube as quads and positions only, `make_fvcube(...)` for a simple face-varying unit cube, `make_geosphere(...)` for a geodesic sphere as triangles and positions only. -These functions return a `scene_shape` or `scene_fvshape`. +These functions return a `shape_data` or `scene_fvshape`. ```cpp auto monkey = make_monkey(1); @@ -495,7 +495,7 @@ Yocto/Shape supports the generation of points and lines sets. Use `make_lines(...)` to create a line set in the XY plane, `make_points(...)` for a collection of points at the origin, adn `make_random_points(...)` for a point set randomly placed in a box. -These functions return points or lines, packed in a `scene_shape` struct. +These functions return points or lines, packed in a `shape_data` struct. ```cpp auto lines_01 = make_lines({4, 65536}, // line steps and number of lines diff --git a/docs/yocto/yocto_sceneio.md b/docs/yocto/yocto_sceneio.md index b91670d9b..984ab7bc4 100644 --- a/docs/yocto/yocto_sceneio.md +++ b/docs/yocto/yocto_sceneio.md @@ -73,7 +73,7 @@ are flipped vertically to match the convention of OpenGL texturing; this can be disabled by setting the `flipv` flag. ```cpp -auto shape = scene_shape{}; // shape +auto shape = shape_data{}; // shape auto error = string{}; // error buffer if(!load_shape(filename, shape, error)) // load shape print_error(error); diff --git a/docs/yocto/yocto_shape.md b/docs/yocto/yocto_shape.md index 233956c56..7f95d07c5 100644 --- a/docs/yocto/yocto_shape.md +++ b/docs/yocto/yocto_shape.md @@ -43,7 +43,7 @@ appropriate. This design tries to balance readability and generality, without forcing a single convention that would not be appropriate everywhere. If a higher level design is needed, [Yocto/Scene](yocto_scene.md) contains -the standalone types `scene_shape` and `scene_fvshape` to store indexed +the standalone types `shape_data` and `scene_fvshape` to store indexed and face-varying shapes respectively, a a collection of methods to work on these type, that are essentially wrappers to the functionality in this library. diff --git a/libs/yocto/yocto_bvh.cpp b/libs/yocto/yocto_bvh.cpp index 5163a45b7..7c9b3deb0 100644 --- a/libs/yocto/yocto_bvh.cpp +++ b/libs/yocto/yocto_bvh.cpp @@ -116,7 +116,7 @@ void clear_embree_bvh(void* embree_bvh) { // Initialize Embree BVH static void build_embree_bvh( - bvh_shape& bvh, const scene_shape& shape, bool highquality) { + bvh_shape& bvh, const shape_data& shape, bool highquality) { auto edevice = bvh_embree_device(); bvh.embree_bvh = unique_ptr{ rtcNewScene(edevice), &clear_embree_bvh}; @@ -240,7 +240,7 @@ static void update_embree_bvh(bvh_scene& bvh, const scene_model& scene, rtcCommitScene(escene); } -static bool intersect_embree_bvh(const bvh_shape& bvh, const scene_shape& shape, +static bool intersect_embree_bvh(const bvh_shape& bvh, const shape_data& shape, const ray3f& ray, int& element, vec2f& uv, float& distance, bool find_any) { RTCRayHit embree_ray; embree_ray.ray.org_x = ray.o.x; @@ -630,7 +630,7 @@ static void refit_bvh(bvh_tree& bvh, const vector& bboxes) { } static void build_bvh( - bvh_shape& bvh, const scene_shape& shape, bool highquality, bool embree) { + bvh_shape& bvh, const shape_data& shape, bool highquality, bool embree) { #ifdef YOCTO_EMBREE if (embree) { return build_embree_bvh(bvh, shape, highquality); @@ -695,7 +695,7 @@ static void build_bvh(bvh_scene& bvh, const scene_model& scene, build_bvh_serial(bvh.bvh, bboxes, highquality); } -bvh_shape make_bvh(const scene_shape& shape, bool highquality, bool embree) { +bvh_shape make_bvh(const shape_data& shape, bool highquality, bool embree) { // bvh auto bvh = bvh_shape{}; @@ -731,7 +731,7 @@ bvh_scene make_bvh( return bvh; } -static void refit_bvh(bvh_shape& bvh, const scene_shape& shape) { +static void refit_bvh(bvh_shape& bvh, const shape_data& shape) { #ifdef YOCTO_EMBREE if (bvh.embree_bvh) { throw std::runtime_error("embree shape refit not supported"); @@ -793,7 +793,7 @@ void refit_bvh(bvh_scene& bvh, const scene_model& scene, refit_bvh(bvh.bvh, bboxes); } -void update_bvh(bvh_shape& bvh, const scene_shape& shape) { +void update_bvh(bvh_shape& bvh, const shape_data& shape) { // handle instances refit_bvh(bvh, shape); } @@ -817,7 +817,7 @@ void update_bvh(bvh_scene& bvh, const scene_model& scene, namespace yocto { // Intersect ray with a bvh. -static bool intersect_bvh(const bvh_shape& bvh, const scene_shape& shape, +static bool intersect_bvh(const bvh_shape& bvh, const shape_data& shape, const ray3f& ray_, int& element, vec2f& uv, float& distance, bool find_any) { #ifdef YOCTO_EMBREE @@ -1009,7 +1009,7 @@ static bool intersect_bvh(const bvh_scene& bvh, const scene_model& scene, namespace yocto { // Intersect ray with a bvh. -static bool overlap_bvh(const bvh_shape& bvh, const scene_shape& shape, +static bool overlap_bvh(const bvh_shape& bvh, const shape_data& shape, const vec3f& pos, float max_distance, int& element, vec2f& uv, float& distance, bool find_any) { // check if empty diff --git a/libs/yocto/yocto_bvh.h b/libs/yocto/yocto_bvh.h index 79e28a71a..55607e074 100644 --- a/libs/yocto/yocto_bvh.h +++ b/libs/yocto/yocto_bvh.h @@ -102,12 +102,12 @@ struct bvh_scene { // Build the bvh acceleration structure. bvh_shape make_bvh( - const scene_shape& shape, bool highquality = false, bool embree = false); + const shape_data& shape, bool highquality = false, bool embree = false); bvh_scene make_bvh(const scene_model& scene, bool highquality = false, bool embree = false, bool noparallel = false); // Refit bvh data -void update_bvh(bvh_shape& bvh, const scene_shape& shape); +void update_bvh(bvh_shape& bvh, const shape_data& shape); void update_bvh(bvh_scene& bvh, const scene_model& scene, const vector& updated_instances, const vector& updated_shapes); @@ -127,7 +127,7 @@ struct bvh_intersection { // Intersect ray with a bvh returning either the first or any intersection // depending on `find_any`. Returns the ray distance , the instance id, // the shape element index and the element barycentric coordinates. -bvh_intersection intersect_bvh(const bvh_shape& bvh, const scene_shape& shape, +bvh_intersection intersect_bvh(const bvh_shape& bvh, const shape_data& shape, const ray3f& ray, bool find_any = false, bool non_rigid_frames = true); bvh_intersection intersect_bvh(const bvh_scene& bvh, const scene_model& scene, const ray3f& ray, bool find_any = false, bool non_rigid_frames = true); @@ -139,7 +139,7 @@ bvh_intersection intersect_bvh(const bvh_scene& bvh, const scene_model& scene, // max distance, returning either the closest or any overlap depending on // `find_any`. Returns the point distance, the instance id, the shape element // index and the element barycentric coordinates. -bvh_intersection overlap_bvh(const bvh_shape& bvh, const scene_shape& shape, +bvh_intersection overlap_bvh(const bvh_shape& bvh, const shape_data& shape, const vec3f& pos, float max_distance, bool find_any = false); bvh_intersection overlap_bvh(const bvh_scene& bvh, const scene_model& scene, const vec3f& pos, float max_distance, bool find_any = false, diff --git a/libs/yocto/yocto_scene.cpp b/libs/yocto/yocto_scene.cpp index ec348b694..e251196e0 100644 --- a/libs/yocto/yocto_scene.cpp +++ b/libs/yocto/yocto_scene.cpp @@ -277,7 +277,7 @@ bool has_volume(const material_point& material) { namespace yocto { // Interpolate vertex data -vec3f eval_position(const scene_shape& shape, int element, const vec2f& uv) { +vec3f eval_position(const shape_data& shape, int element, const vec2f& uv) { if (!shape.points.empty()) { auto& point = shape.points[element]; return shape.positions[point]; @@ -298,7 +298,7 @@ vec3f eval_position(const scene_shape& shape, int element, const vec2f& uv) { } } -vec3f eval_normal(const scene_shape& shape, int element, const vec2f& uv) { +vec3f eval_normal(const shape_data& shape, int element, const vec2f& uv) { if (shape.normals.empty()) return eval_element_normal(shape, element); if (!shape.points.empty()) { auto& point = shape.points[element]; @@ -321,11 +321,11 @@ vec3f eval_normal(const scene_shape& shape, int element, const vec2f& uv) { } } -vec3f eval_tangent(const scene_shape& shape, int element, const vec2f& uv) { +vec3f eval_tangent(const shape_data& shape, int element, const vec2f& uv) { return eval_normal(shape, element, uv); } -vec2f eval_texcoord(const scene_shape& shape, int element, const vec2f& uv) { +vec2f eval_texcoord(const shape_data& shape, int element, const vec2f& uv) { if (shape.texcoords.empty()) return {0, 0}; if (!shape.points.empty()) { auto& point = shape.points[element]; @@ -347,7 +347,7 @@ vec2f eval_texcoord(const scene_shape& shape, int element, const vec2f& uv) { } } -vec4f eval_color(const scene_shape& shape, int element, const vec2f& uv) { +vec4f eval_color(const shape_data& shape, int element, const vec2f& uv) { if (shape.colors.empty()) return {1, 1, 1, 1}; if (!shape.points.empty()) { auto& point = shape.points[element]; @@ -368,7 +368,7 @@ vec4f eval_color(const scene_shape& shape, int element, const vec2f& uv) { } } -float eval_radius(const scene_shape& shape, int element, const vec2f& uv) { +float eval_radius(const shape_data& shape, int element, const vec2f& uv) { if (shape.radius.empty()) return 0; if (!shape.points.empty()) { auto& point = shape.points[element]; @@ -390,7 +390,7 @@ float eval_radius(const scene_shape& shape, int element, const vec2f& uv) { } // Evaluate element normals -vec3f eval_element_normal(const scene_shape& shape, int element) { +vec3f eval_element_normal(const shape_data& shape, int element) { if (!shape.points.empty()) { return {0, 0, 1}; } else if (!shape.lines.empty()) { @@ -410,7 +410,7 @@ vec3f eval_element_normal(const scene_shape& shape, int element) { } // Compute per-vertex normals/tangents for lines/triangles/quads. -vector compute_normals(const scene_shape& shape) { +vector compute_normals(const shape_data& shape) { if (!shape.points.empty()) { return vector(shape.positions.size(), {0, 0, 1}); } else if (!shape.lines.empty()) { @@ -423,7 +423,7 @@ vector compute_normals(const scene_shape& shape) { return vector(shape.positions.size(), {0, 0, 1}); } } -void compute_normals(vector& normals, const scene_shape& shape) { +void compute_normals(vector& normals, const shape_data& shape) { if (!shape.points.empty()) { normals.assign(shape.positions.size(), {0, 0, 1}); } else if (!shape.lines.empty()) { @@ -438,7 +438,7 @@ void compute_normals(vector& normals, const scene_shape& shape) { } // Shape sampling -vector sample_shape_cdf(const scene_shape& shape) { +vector sample_shape_cdf(const shape_data& shape) { if (!shape.points.empty()) { return sample_points_cdf((int)shape.points.size()); } else if (!shape.lines.empty()) { @@ -452,7 +452,7 @@ vector sample_shape_cdf(const scene_shape& shape) { } } -void sample_shape_cdf(vector& cdf, const scene_shape& shape) { +void sample_shape_cdf(vector& cdf, const shape_data& shape) { if (!shape.points.empty()) { sample_points_cdf(cdf, (int)shape.points.size()); } else if (!shape.lines.empty()) { @@ -466,7 +466,7 @@ void sample_shape_cdf(vector& cdf, const scene_shape& shape) { } } -shape_point sample_shape(const scene_shape& shape, const vector& cdf, +shape_point sample_shape(const shape_data& shape, const vector& cdf, float rn, const vec2f& ruv) { if (!shape.points.empty()) { auto element = sample_points(cdf, rn); @@ -487,7 +487,7 @@ shape_point sample_shape(const scene_shape& shape, const vector& cdf, } vector sample_shape( - const scene_shape& shape, int num_samples, uint64_t seed) { + const shape_data& shape, int num_samples, uint64_t seed) { auto cdf = sample_shape_cdf(shape); auto points = vector(num_samples); auto rng = make_rng(seed); @@ -498,22 +498,22 @@ vector sample_shape( } // Conversions -scene_shape quads_to_triangles(const scene_shape& shape) { +shape_data quads_to_triangles(const shape_data& shape) { auto result = shape; quads_to_triangles(result, result); return result; } -void quads_to_triangles(scene_shape& result, const scene_shape& shape) { +void quads_to_triangles(shape_data& result, const shape_data& shape) { result.triangles = quads_to_triangles(shape.quads); result.quads = {}; } // Subdivision -scene_shape subdivide_shape( - const scene_shape& shape, int subdivisions, bool catmullclark) { +shape_data subdivide_shape( + const shape_data& shape, int subdivisions, bool catmullclark) { // This should probably be reimplemented in a faster fashion, // but how it is not obvious - auto subdivided = scene_shape{}; + auto subdivided = shape_data{}; if (!shape.points.empty()) { // nothing to do } else if (!shape.lines.empty()) { @@ -628,15 +628,15 @@ void compute_normals(vector& normals, const scene_fvshape& shape) { } // Conversions -scene_shape fvshape_to_shape(const scene_fvshape& fvshape, bool as_triangles) { - auto shape = scene_shape{}; +shape_data fvshape_to_shape(const scene_fvshape& fvshape, bool as_triangles) { + auto shape = shape_data{}; split_facevarying(shape.quads, shape.positions, shape.normals, shape.texcoords, fvshape.quadspos, fvshape.quadsnorm, fvshape.quadstexcoord, fvshape.positions, fvshape.normals, fvshape.texcoords); return shape; } -scene_fvshape shape_to_fvshape(const scene_shape& shape) { +scene_fvshape shape_to_fvshape(const shape_data& shape) { if (!shape.points.empty() || !shape.lines.empty()) throw std::invalid_argument{"cannor convert shape"}; auto fvshape = scene_fvshape{}; @@ -675,7 +675,7 @@ scene_fvshape subdivide_fvshape( return subdivided; } -vector shape_stats(const scene_shape& shape, bool verbose) { +vector shape_stats(const shape_data& shape, bool verbose) { auto format = [](auto num) { auto str = std::to_string(num); while (str.size() < 13) str = " " + str; @@ -1120,7 +1120,7 @@ int find_camera(const scene_model& scene, const string& name) { } // create a scene from a shape -scene_model make_shape_scene(const scene_shape& shape, bool addsky) { +scene_model make_shape_scene(const shape_data& shape, bool addsky) { // scene auto scene = scene_model{}; // shape @@ -1168,7 +1168,7 @@ bbox3f compute_bounds(const scene_model& scene) { namespace yocto { void tesselate_subdiv( - scene_shape& shape, scene_subdiv& subdiv_, const scene_model& scene) { + shape_data& shape, scene_subdiv& subdiv_, const scene_model& scene) { auto subdiv = subdiv_; if (subdiv.subdivisions > 0) { @@ -1394,192 +1394,192 @@ vector scene_validation(const scene_model& scene, bool notextures) { namespace yocto { // Make a plane. -scene_shape make_rect( +shape_data make_rect( const vec2i& steps, const vec2f& scale, const vec2f& uvscale) { - auto shape = scene_shape{}; + auto shape = shape_data{}; make_rect(shape.quads, shape.positions, shape.normals, shape.texcoords, steps, scale, uvscale); return shape; } -scene_shape make_bulged_rect(const vec2i& steps, const vec2f& scale, +shape_data make_bulged_rect(const vec2i& steps, const vec2f& scale, const vec2f& uvscale, float radius) { - auto shape = scene_shape{}; + auto shape = shape_data{}; make_bulged_rect(shape.quads, shape.positions, shape.normals, shape.texcoords, steps, scale, uvscale, radius); return shape; } // Make a plane in the xz plane. -scene_shape make_recty( +shape_data make_recty( const vec2i& steps, const vec2f& scale, const vec2f& uvscale) { - auto shape = scene_shape{}; + auto shape = shape_data{}; make_recty(shape.quads, shape.positions, shape.normals, shape.texcoords, steps, scale, uvscale); return shape; } -scene_shape make_bulged_recty(const vec2i& steps, const vec2f& scale, +shape_data make_bulged_recty(const vec2i& steps, const vec2f& scale, const vec2f& uvscale, float radius) { - auto shape = scene_shape{}; + auto shape = shape_data{}; make_bulged_recty(shape.quads, shape.positions, shape.normals, shape.texcoords, steps, scale, uvscale, radius); return shape; } // Make a box. -scene_shape make_box( +shape_data make_box( const vec3i& steps, const vec3f& scale, const vec3f& uvscale) { - auto shape = scene_shape{}; + auto shape = shape_data{}; make_box(shape.quads, shape.positions, shape.normals, shape.texcoords, steps, scale, uvscale); return shape; } -scene_shape make_rounded_box(const vec3i& steps, const vec3f& scale, +shape_data make_rounded_box(const vec3i& steps, const vec3f& scale, const vec3f& uvscale, float radius) { - auto shape = scene_shape{}; + auto shape = shape_data{}; make_rounded_box(shape.quads, shape.positions, shape.normals, shape.texcoords, steps, scale, uvscale, radius); return shape; } // Make a quad stack -scene_shape make_rect_stack( +shape_data make_rect_stack( const vec3i& steps, const vec3f& scale, const vec2f& uvscale) { - auto shape = scene_shape{}; + auto shape = shape_data{}; make_rect_stack(shape.quads, shape.positions, shape.normals, shape.texcoords, steps, scale, uvscale); return shape; } // Make a floor. -scene_shape make_floor( +shape_data make_floor( const vec2i& steps, const vec2f& scale, const vec2f& uvscale) { - auto shape = scene_shape{}; + auto shape = shape_data{}; make_floor(shape.quads, shape.positions, shape.normals, shape.texcoords, steps, scale, uvscale); return shape; } -scene_shape make_bent_floor( +shape_data make_bent_floor( const vec2i& steps, const vec2f& scale, const vec2f& uvscale, float bent) { - auto shape = scene_shape{}; + auto shape = shape_data{}; make_bent_floor(shape.quads, shape.positions, shape.normals, shape.texcoords, steps, scale, uvscale, bent); return shape; } // Make a sphere. -scene_shape make_sphere(int steps, float scale, float uvscale) { - auto shape = scene_shape{}; +shape_data make_sphere(int steps, float scale, float uvscale) { + auto shape = shape_data{}; make_sphere(shape.quads, shape.positions, shape.normals, shape.texcoords, steps, scale, uvscale); return shape; } // Make a sphere. -scene_shape make_uvsphere( +shape_data make_uvsphere( const vec2i& steps, float scale, const vec2f& uvscale) { - auto shape = scene_shape{}; + auto shape = shape_data{}; make_uvsphere(shape.quads, shape.positions, shape.normals, shape.texcoords, steps, scale, uvscale); return shape; } // Make a sphere. -scene_shape make_uvspherey( +shape_data make_uvspherey( const vec2i& steps, float scale, const vec2f& uvscale) { - auto shape = scene_shape{}; + auto shape = shape_data{}; make_uvspherey(shape.quads, shape.positions, shape.normals, shape.texcoords, steps, scale, uvscale); return shape; } // Make a sphere with slipped caps. -scene_shape make_capped_uvsphere( +shape_data make_capped_uvsphere( const vec2i& steps, float scale, const vec2f& uvscale, float height) { - auto shape = scene_shape{}; + auto shape = shape_data{}; make_capped_uvsphere(shape.quads, shape.positions, shape.normals, shape.texcoords, steps, scale, uvscale, height); return shape; } // Make a sphere with slipped caps. -scene_shape make_capped_uvspherey( +shape_data make_capped_uvspherey( const vec2i& steps, float scale, const vec2f& uvscale, float height) { - auto shape = scene_shape{}; + auto shape = shape_data{}; make_capped_uvspherey(shape.quads, shape.positions, shape.normals, shape.texcoords, steps, scale, uvscale, height); return shape; } // Make a disk -scene_shape make_disk(int steps, float scale, float uvscale) { - auto shape = scene_shape{}; +shape_data make_disk(int steps, float scale, float uvscale) { + auto shape = shape_data{}; make_disk(shape.quads, shape.positions, shape.normals, shape.texcoords, steps, scale, uvscale); return shape; } // Make a bulged disk -scene_shape make_bulged_disk( +shape_data make_bulged_disk( int steps, float scale, float uvscale, float height) { - auto shape = scene_shape{}; + auto shape = shape_data{}; make_bulged_disk(shape.quads, shape.positions, shape.normals, shape.texcoords, steps, scale, uvscale, height); return shape; } // Make a uv disk -scene_shape make_uvdisk(const vec2i& steps, float scale, const vec2f& uvscale) { - auto shape = scene_shape{}; +shape_data make_uvdisk(const vec2i& steps, float scale, const vec2f& uvscale) { + auto shape = shape_data{}; make_uvdisk(shape.quads, shape.positions, shape.normals, shape.texcoords, steps, scale, uvscale); return shape; } // Make a uv cylinder -scene_shape make_uvcylinder( +shape_data make_uvcylinder( const vec3i& steps, const vec2f& scale, const vec3f& uvscale) { - auto shape = scene_shape{}; + auto shape = shape_data{}; make_uvcylinder(shape.quads, shape.positions, shape.normals, shape.texcoords, steps, scale, uvscale); return shape; } // Make a rounded uv cylinder -scene_shape make_rounded_uvcylinder(const vec3i& steps, const vec2f& scale, +shape_data make_rounded_uvcylinder(const vec3i& steps, const vec2f& scale, const vec3f& uvscale, float radius) { - auto shape = scene_shape{}; + auto shape = shape_data{}; make_rounded_uvcylinder(shape.quads, shape.positions, shape.normals, shape.texcoords, steps, scale, uvscale, radius); return shape; } // Generate lines set along a quad. Returns lines, pos, norm, texcoord, radius. -scene_shape make_lines(const vec2i& steps, const vec2f& scale, +shape_data make_lines(const vec2i& steps, const vec2f& scale, const vec2f& uvscale, const vec2f& rad) { - auto shape = scene_shape{}; + auto shape = shape_data{}; make_lines(shape.lines, shape.positions, shape.normals, shape.texcoords, shape.radius, steps, scale, uvscale, rad); return shape; } // Make point primitives. Returns points, pos, norm, texcoord, radius. -scene_shape make_point(float radius) { - auto shape = scene_shape{}; +shape_data make_point(float radius) { + auto shape = shape_data{}; make_point(shape.points, shape.positions, shape.normals, shape.texcoords, shape.radius, radius); return shape; } -scene_shape make_points(int num, float uvscale, float radius) { - auto shape = scene_shape{}; +shape_data make_points(int num, float uvscale, float radius) { + auto shape = shape_data{}; make_points(shape.points, shape.positions, shape.normals, shape.texcoords, shape.radius, num, uvscale, radius); return shape; } -scene_shape make_random_points( +shape_data make_random_points( int num, const vec3f& size, float uvscale, float radius, uint64_t seed) { - auto shape = scene_shape{}; + auto shape = shape_data{}; make_random_points(shape.points, shape.positions, shape.normals, shape.texcoords, shape.radius, num, size, uvscale, radius, seed); return shape; @@ -1612,25 +1612,25 @@ scene_fvshape make_fvsphere(int steps, float scale, float uvscale) { } // Predefined meshes -scene_shape make_monkey(float scale, int subdivisions) { - auto shape = scene_shape{}; +shape_data make_monkey(float scale, int subdivisions) { + auto shape = shape_data{}; make_monkey(shape.quads, shape.positions, scale, subdivisions); return shape; } -scene_shape make_quad(float scale, int subdivisions) { - auto shape = scene_shape{}; +shape_data make_quad(float scale, int subdivisions) { + auto shape = shape_data{}; make_quad(shape.quads, shape.positions, shape.normals, shape.texcoords, scale, subdivisions); return shape; } -scene_shape make_quady(float scale, int subdivisions) { - auto shape = scene_shape{}; +shape_data make_quady(float scale, int subdivisions) { + auto shape = shape_data{}; make_quady(shape.quads, shape.positions, shape.normals, shape.texcoords, scale, subdivisions); return shape; } -scene_shape make_cube(float scale, int subdivisions) { - auto shape = scene_shape{}; +shape_data make_cube(float scale, int subdivisions) { + auto shape = shape_data{}; make_cube(shape.quads, shape.positions, shape.normals, shape.texcoords, scale, subdivisions); return shape; @@ -1641,18 +1641,18 @@ scene_fvshape make_fvcube(float scale, int subdivisions) { shape.positions, shape.normals, shape.texcoords, scale, subdivisions); return shape; } -scene_shape make_geosphere(float scale, int subdivisions) { - auto shape = scene_shape{}; +shape_data make_geosphere(float scale, int subdivisions) { + auto shape = shape_data{}; make_geosphere( shape.triangles, shape.positions, shape.normals, scale, subdivisions); return shape; } // Make a hair ball around a shape -scene_shape make_hair(const scene_shape& base, const vec2i& steps, +shape_data make_hair(const shape_data& base, const vec2i& steps, const vec2f& length, const vec2f& radius, const vec2f& noise, const vec2f& clump, const vec2f& rotation, int seed) { - auto shape = scene_shape{}; + auto shape = shape_data{}; make_hair(shape.lines, shape.positions, shape.normals, shape.texcoords, shape.radius, base.triangles, base.quads, base.positions, base.normals, base.texcoords, steps, length, radius, noise, clump, rotation, seed); @@ -1660,10 +1660,10 @@ scene_shape make_hair(const scene_shape& base, const vec2i& steps, } // Grow hairs around a shape -scene_shape make_hair2(const scene_shape& base, const vec2i& steps, +shape_data make_hair2(const shape_data& base, const vec2i& steps, const vec2f& length, const vec2f& radius, float noise, float gravity, int seed) { - auto shape = scene_shape{}; + auto shape = shape_data{}; make_hair2(shape.lines, shape.positions, shape.normals, shape.texcoords, shape.radius, base.triangles, base.quads, base.positions, base.normals, base.texcoords, steps, length, radius, noise, gravity, seed); @@ -1671,14 +1671,14 @@ scene_shape make_hair2(const scene_shape& base, const vec2i& steps, } // Make a heightfield mesh. -scene_shape make_heightfield(const vec2i& size, const vector& height) { - auto shape = scene_shape{}; +shape_data make_heightfield(const vec2i& size, const vector& height) { + auto shape = shape_data{}; make_heightfield(shape.quads, shape.positions, shape.normals, shape.texcoords, size, height); return shape; } -scene_shape make_heightfield(const vec2i& size, const vector& color) { - auto shape = scene_shape{}; +shape_data make_heightfield(const vec2i& size, const vector& color) { + auto shape = shape_data{}; make_heightfield(shape.quads, shape.positions, shape.normals, shape.texcoords, size, color); return shape; @@ -1687,30 +1687,30 @@ scene_shape make_heightfield(const vec2i& size, const vector& color) { // Convert points to small spheres and lines to small cylinders. This is // intended for making very small primitives for display in interactive // applications, so the spheres are low res. -scene_shape points_to_spheres( +shape_data points_to_spheres( const vector& vertices, int steps, float scale) { - auto shape = scene_shape{}; + auto shape = shape_data{}; points_to_spheres(shape.quads, shape.positions, shape.normals, shape.texcoords, vertices, steps, scale); return shape; } -scene_shape polyline_to_cylinders( +shape_data polyline_to_cylinders( const vector& vertices, int steps, float scale) { - auto shape = scene_shape{}; + auto shape = shape_data{}; polyline_to_cylinders(shape.quads, shape.positions, shape.normals, shape.texcoords, vertices, steps, scale); return shape; } -scene_shape lines_to_cylinders( +shape_data lines_to_cylinders( const vector& vertices, int steps, float scale) { - auto shape = scene_shape{}; + auto shape = shape_data{}; lines_to_cylinders(shape.quads, shape.positions, shape.normals, shape.texcoords, vertices, steps, scale); return shape; } -scene_shape lines_to_cylinders(const vector& lines, +shape_data lines_to_cylinders(const vector& lines, const vector& positions, int steps, float scale) { - auto shape = scene_shape{}; + auto shape = shape_data{}; lines_to_cylinders(shape.quads, shape.positions, shape.normals, shape.texcoords, lines, positions, steps, scale); return shape; diff --git a/libs/yocto/yocto_scene.h b/libs/yocto/yocto_scene.h index d4e653068..3f45d9708 100644 --- a/libs/yocto/yocto_scene.h +++ b/libs/yocto/yocto_scene.h @@ -108,7 +108,7 @@ enum struct material_type { }; // Enum labels -inline const auto scene_material_names = std::vector{"matte", +inline const auto material_type_names = std::vector{"matte", "glossy", "metallic", "transparent", "refractive", "subsurface", "volume", "gltfpbr"}; @@ -139,7 +139,7 @@ struct material_data { // Shape data represented as indexed meshes of elements. // May contain either points, lines, triangles and quads. -struct scene_shape { +struct shape_data { // element data vector points = {}; vector lines = {}; @@ -222,7 +222,7 @@ struct scene_model { vector cameras = {}; vector instances = {}; vector environments = {}; - vector shapes = {}; + vector shapes = {}; vector textures = {}; vector materials = {}; vector subdivs = {}; @@ -317,19 +317,19 @@ bool is_volumetric(const scene_model& scene, const scene_instance& instance); namespace yocto { // Interpolate vertex data -vec3f eval_position(const scene_shape& shape, int element, const vec2f& uv); -vec3f eval_normal(const scene_shape& shape, int element, const vec2f& uv); -vec3f eval_tangent(const scene_shape& shape, int element, const vec2f& uv); -vec2f eval_texcoord(const scene_shape& shape, int element, const vec2f& uv); -vec4f eval_color(const scene_shape& shape, int element, const vec2f& uv); -float eval_radius(const scene_shape& shape, int element, const vec2f& uv); +vec3f eval_position(const shape_data& shape, int element, const vec2f& uv); +vec3f eval_normal(const shape_data& shape, int element, const vec2f& uv); +vec3f eval_tangent(const shape_data& shape, int element, const vec2f& uv); +vec2f eval_texcoord(const shape_data& shape, int element, const vec2f& uv); +vec4f eval_color(const shape_data& shape, int element, const vec2f& uv); +float eval_radius(const shape_data& shape, int element, const vec2f& uv); // Evaluate element normals -vec3f eval_element_normal(const scene_shape& shape, int element); +vec3f eval_element_normal(const shape_data& shape, int element); // Compute per-vertex normals/tangents for lines/triangles/quads. -vector compute_normals(const scene_shape& shape); -void compute_normals(vector& normals, const scene_shape& shape); +vector compute_normals(const shape_data& shape); +void compute_normals(vector& normals, const shape_data& shape); // An unevaluated location on a shape struct shape_point { @@ -338,25 +338,25 @@ struct shape_point { }; // Shape sampling -vector sample_shape_cdf(const scene_shape& shape); -void sample_shape_cdf(vector& cdf, const scene_shape& shape); -shape_point sample_shape(const scene_shape& shape, const vector& cdf, +vector sample_shape_cdf(const shape_data& shape); +void sample_shape_cdf(vector& cdf, const shape_data& shape); +shape_point sample_shape(const shape_data& shape, const vector& cdf, float rn, const vec2f& ruv); vector sample_shape( - const scene_shape& shape, int num_samples, uint64_t seed = 98729387); + const shape_data& shape, int num_samples, uint64_t seed = 98729387); // Conversions -scene_shape quads_to_triangles(const scene_shape& shape); -void quads_to_triangles(scene_shape& result, const scene_shape& shape); +shape_data quads_to_triangles(const shape_data& shape); +void quads_to_triangles(shape_data& result, const shape_data& shape); // Subdivision -scene_shape subdivide_shape( - const scene_shape& shape, int subdivisions, bool catmullclark); +shape_data subdivide_shape( + const shape_data& shape, int subdivisions, bool catmullclark); // Interpolate vertex data vec3f eval_position(const scene_fvshape& shape, int element, const vec2f& uv); vec3f eval_normal(const scene_fvshape& shape, int element, const vec2f& uv); -vec2f eval_texcoord(const scene_shape& shape, int element, const vec2f& uv); +vec2f eval_texcoord(const shape_data& shape, int element, const vec2f& uv); // Evaluate element normals vec3f eval_element_normal(const scene_fvshape& shape, int element); @@ -366,16 +366,16 @@ vector compute_normals(const scene_fvshape& shape); void compute_normals(vector& normals, const scene_fvshape& shape); // Conversions -scene_shape fvshape_to_shape( +shape_data fvshape_to_shape( const scene_fvshape& shape, bool as_triangles = false); -scene_fvshape shape_to_fvshape(const scene_shape& shape); +scene_fvshape shape_to_fvshape(const shape_data& shape); // Subdivision scene_fvshape subdivide_fvshape( const scene_fvshape& shape, int subdivisions, bool catmullclark); // Shape statistics -vector shape_stats(const scene_shape& shape, bool verbose = false); +vector shape_stats(const shape_data& shape, bool verbose = false); vector fvshape_stats(const scene_fvshape& shape, bool verbose = false); } // namespace yocto @@ -440,7 +440,7 @@ void add_sky(scene_model& scene, float sun_angle = pif / 4); int find_camera(const scene_model& scene, const string& name); // create a scene from a shape -scene_model make_shape_scene(const scene_shape& shape, bool add_sky = false); +scene_model make_shape_scene(const shape_data& shape, bool add_sky = false); // Return scene statistics as list of strings. vector scene_stats(const scene_model& scene, bool verbose = false); @@ -466,57 +466,57 @@ void tesselate_subdivs(scene_model& scene); namespace yocto { // Make a plane. -scene_shape make_rect(const vec2i& steps = {1, 1}, const vec2f& scale = {1, 1}, +shape_data make_rect(const vec2i& steps = {1, 1}, const vec2f& scale = {1, 1}, const vec2f& uvscale = {1, 1}); -scene_shape make_bulged_rect(const vec2i& steps = {1, 1}, +shape_data make_bulged_rect(const vec2i& steps = {1, 1}, const vec2f& scale = {1, 1}, const vec2f& uvscale = {1, 1}, float radius = 0.3); // Make a plane in the xz plane. -scene_shape make_recty(const vec2i& steps = {1, 1}, const vec2f& scale = {1, 1}, +shape_data make_recty(const vec2i& steps = {1, 1}, const vec2f& scale = {1, 1}, const vec2f& uvscale = {1, 1}); -scene_shape make_bulged_recty(const vec2i& steps = {1, 1}, +shape_data make_bulged_recty(const vec2i& steps = {1, 1}, const vec2f& scale = {1, 1}, const vec2f& uvscale = {1, 1}, float radius = 0.3); // Make a box. -scene_shape make_box(const vec3i& steps = {1, 1, 1}, +shape_data make_box(const vec3i& steps = {1, 1, 1}, const vec3f& scale = {1, 1, 1}, const vec3f& uvscale = {1, 1, 1}); -scene_shape make_rounded_box(const vec3i& steps = {1, 1, 1}, +shape_data make_rounded_box(const vec3i& steps = {1, 1, 1}, const vec3f& scale = {1, 1, 1}, const vec3f& uvscale = {1, 1, 1}, float radius = 0.3); // Make a quad stack -scene_shape make_rect_stack(const vec3i& steps = {1, 1, 1}, +shape_data make_rect_stack(const vec3i& steps = {1, 1, 1}, const vec3f& scale = {1, 1, 1}, const vec2f& uvscale = {1, 1}); // Make a floor. -scene_shape make_floor(const vec2i& steps = {1, 1}, +shape_data make_floor(const vec2i& steps = {1, 1}, const vec2f& scale = {10, 10}, const vec2f& uvscale = {10, 10}); -scene_shape make_bent_floor(const vec2i& steps = {1, 1}, +shape_data make_bent_floor(const vec2i& steps = {1, 1}, const vec2f& scale = {10, 10}, const vec2f& uvscale = {10, 10}, float bent = 0.5); // Make a sphere. -scene_shape make_sphere(int steps = 32, float scale = 1, float uvscale = 1); +shape_data make_sphere(int steps = 32, float scale = 1, float uvscale = 1); // Make a sphere. -scene_shape make_uvsphere(const vec2i& steps = {32, 32}, float scale = 1, +shape_data make_uvsphere(const vec2i& steps = {32, 32}, float scale = 1, const vec2f& uvscale = {1, 1}); -scene_shape make_uvspherey(const vec2i& steps = {32, 32}, float scale = 1, +shape_data make_uvspherey(const vec2i& steps = {32, 32}, float scale = 1, const vec2f& uvscale = {1, 1}); // Make a sphere with slipped caps. -scene_shape make_capped_uvsphere(const vec2i& steps = {32, 32}, float scale = 1, +shape_data make_capped_uvsphere(const vec2i& steps = {32, 32}, float scale = 1, + const vec2f& uvscale = {1, 1}, float height = 0.3); +shape_data make_capped_uvspherey(const vec2i& steps = {32, 32}, float scale = 1, const vec2f& uvscale = {1, 1}, float height = 0.3); -scene_shape make_capped_uvspherey(const vec2i& steps = {32, 32}, - float scale = 1, const vec2f& uvscale = {1, 1}, float height = 0.3); // Make a disk -scene_shape make_disk(int steps = 32, float scale = 1, float uvscale = 1); +shape_data make_disk(int steps = 32, float scale = 1, float uvscale = 1); // Make a bulged disk -scene_shape make_bulged_disk( +shape_data make_bulged_disk( int steps = 32, float scale = 1, float uvscale = 1, float height = 0.3); // Make a uv disk -scene_shape make_uvdisk(const vec2i& steps = {32, 32}, float scale = 1, +shape_data make_uvdisk(const vec2i& steps = {32, 32}, float scale = 1, const vec2f& uvscale = {1, 1}); // Make a uv cylinder -scene_shape make_uvcylinder(const vec3i& steps = {32, 32, 32}, +shape_data make_uvcylinder(const vec3i& steps = {32, 32, 32}, const vec2f& scale = {1, 1}, const vec3f& uvscale = {1, 1, 1}); // Make a rounded uv cylinder -scene_shape make_rounded_uvcylinder(const vec3i& steps = {32, 32, 32}, +shape_data make_rounded_uvcylinder(const vec3i& steps = {32, 32, 32}, const vec2f& scale = {1, 1}, const vec3f& uvscale = {1, 1, 1}, float radius = 0.3); @@ -530,24 +530,24 @@ scene_fvshape make_fvbox(const vec3i& steps = {1, 1, 1}, scene_fvshape make_fvsphere(int steps = 32, float scale = 1, float uvscale = 1); // Generate lines set along a quad. Returns lines, pos, norm, texcoord, radius. -scene_shape make_lines(const vec2i& steps = {4, 65536}, +shape_data make_lines(const vec2i& steps = {4, 65536}, const vec2f& scale = {1, 1}, const vec2f& uvscale = {1, 1}, const vec2f& radius = {0.001f, 0.001f}); // Make point primitives. Returns points, pos, norm, texcoord, radius. -scene_shape make_point(float radius = 0.001f); -scene_shape make_points( +shape_data make_point(float radius = 0.001f); +shape_data make_points( int num = 65536, float uvscale = 1, float radius = 0.001f); -scene_shape make_random_points(int num = 65536, const vec3f& size = {1, 1, 1}, +shape_data make_random_points(int num = 65536, const vec3f& size = {1, 1, 1}, float uvscale = 1, float radius = 0.001f, uint64_t seed = 17); // Predefined meshes -scene_shape make_monkey(float scale = 1, int subdivisions = 0); -scene_shape make_quad(float scale = 1, int subdivisions = 0); -scene_shape make_quady(float scale = 1, int subdivisions = 0); -scene_shape make_cube(float scale = 1, int subdivisions = 0); +shape_data make_monkey(float scale = 1, int subdivisions = 0); +shape_data make_quad(float scale = 1, int subdivisions = 0); +shape_data make_quady(float scale = 1, int subdivisions = 0); +shape_data make_cube(float scale = 1, int subdivisions = 0); scene_fvshape make_fvcube(float scale = 1, int subdivisions = 0); -scene_shape make_geosphere(float scale = 1, int subdivisions = 0); +shape_data make_geosphere(float scale = 1, int subdivisions = 0); // Make a hair ball around a shape. // length: minimum and maximum length @@ -555,32 +555,31 @@ scene_shape make_geosphere(float scale = 1, int subdivisions = 0); // noise: noise added to hair (strength/scale) // clump: clump added to hair (strength/number) // rotation: rotation added to hair (angle/strength) -scene_shape make_hair(const scene_shape& shape, const vec2i& steps = {8, 65536}, +shape_data make_hair(const shape_data& shape, const vec2i& steps = {8, 65536}, const vec2f& length = {0.1f, 0.1f}, const vec2f& radius = {0.001f, 0.001f}, const vec2f& noise = {0, 10}, const vec2f& clump = {0, 128}, const vec2f& rotation = {0, 0}, int seed = 7); // Grow hairs around a shape -scene_shape make_hair2(const scene_shape& shape, - const vec2i& steps = {8, 65536}, const vec2f& length = {0.1f, 0.1f}, - const vec2f& radius = {0.001f, 0.001f}, float noise = 0, - float gravity = 0.001f, int seed = 7); +shape_data make_hair2(const shape_data& shape, const vec2i& steps = {8, 65536}, + const vec2f& length = {0.1f, 0.1f}, const vec2f& radius = {0.001f, 0.001f}, + float noise = 0, float gravity = 0.001f, int seed = 7); // Convert points to small spheres and lines to small cylinders. This is // intended for making very small primitives for display in interactive // applications, so the spheres are low res. -scene_shape points_to_spheres( +shape_data points_to_spheres( const vector& vertices, int steps = 2, float scale = 0.01f); -scene_shape polyline_to_cylinders( +shape_data polyline_to_cylinders( const vector& vertices, int steps = 4, float scale = 0.01f); -scene_shape lines_to_cylinders( +shape_data lines_to_cylinders( const vector& vertices, int steps = 4, float scale = 0.01f); -scene_shape lines_to_cylinders(const vector& lines, +shape_data lines_to_cylinders(const vector& lines, const vector& positions, int steps = 4, float scale = 0.01f); // Make a heightfield mesh. -scene_shape make_heightfield(const vec2i& size, const vector& height); -scene_shape make_heightfield(const vec2i& size, const vector& color); +shape_data make_heightfield(const vec2i& size, const vector& height); +shape_data make_heightfield(const vec2i& size, const vector& color); } // namespace yocto @@ -607,10 +606,15 @@ using scene_texture = texture_data; using sceneio_material = material_data; using scene_material_type = material_type; using sceneio_material = material_data; -using sceneio_shape = scene_shape; +using sceneio_shape = shape_data; +using scene_shape = shape_data; using sceneio_instance = scene_instance; using sceneio_environment = scene_environment; +inline const auto scene_material_names = std::vector{"matte", + "glossy", "metallic", "transparent", "refractive", "subsurface", "volume", + "gltfpbr"}; + } // namespace yocto #endif diff --git a/libs/yocto/yocto_sceneio.cpp b/libs/yocto/yocto_sceneio.cpp index a9af423ee..bbd7816fd 100644 --- a/libs/yocto/yocto_sceneio.cpp +++ b/libs/yocto/yocto_sceneio.cpp @@ -935,7 +935,7 @@ bool make_texture_preset( namespace yocto { // Load ply mesh -bool load_shape(const string& filename, scene_shape& shape, string& error, +bool load_shape(const string& filename, shape_data& shape, string& error, bool flip_texcoord) { auto format_error = [filename, &error]() { error = filename + ": unknown format"; @@ -1001,7 +1001,7 @@ bool load_shape(const string& filename, scene_shape& shape, string& error, } // Save ply mesh -bool save_shape(const string& filename, const scene_shape& shape, string& error, +bool save_shape(const string& filename, const shape_data& shape, string& error, bool flip_texcoord, bool ascii) { auto format_error = [filename, &error]() { error = filename + ": unknown format"; @@ -1278,27 +1278,27 @@ bool save_fvshape(const string& filename, const scene_fvshape& shape, } // Shape presets used ofr testing. -bool make_shape_preset(scene_shape& shape, const string& type, string& error) { - auto set_quads = [&](scene_shape&& shape_) { +bool make_shape_preset(shape_data& shape, const string& type, string& error) { + auto set_quads = [&](shape_data&& shape_) { shape.quads = shape_.quads; shape.positions = shape_.positions; shape.normals = shape_.normals; shape.texcoords = shape_.texcoords; }; - auto set_triangles = [&](scene_shape&& shape_) { + auto set_triangles = [&](shape_data&& shape_) { shape.triangles = shape_.triangles; shape.positions = shape_.positions; shape.normals = shape_.normals; shape.texcoords = shape_.texcoords; }; - auto set_lines = [&](scene_shape&& shape_) { + auto set_lines = [&](shape_data&& shape_) { shape.lines = shape_.lines; shape.positions = shape_.positions; shape.normals = shape_.normals; shape.texcoords = shape_.texcoords; shape.radius = shape_.radius; }; - auto set_points = [&](scene_shape&& shape_) { + auto set_points = [&](shape_data&& shape_) { shape.points = shape_.points; shape.positions = shape_.positions; shape.normals = shape_.normals; @@ -1495,7 +1495,7 @@ bool make_shape_preset(scene_shape& shape, const string& type, string& error) { // Shape presets used for testing. bool make_fvshape_preset( scene_fvshape& shape, const string& type, string& error) { - auto set_quads = [&](scene_shape&& shape_) { + auto set_quads = [&](shape_data&& shape_) { shape.quadspos = shape_.quads; shape.positions = shape_.positions; if (!shape_.normals.empty()) shape.quadsnorm = shape_.quads; @@ -1503,13 +1503,13 @@ bool make_fvshape_preset( if (!shape_.texcoords.empty()) shape.quadstexcoord = shape_.quads; shape.texcoords = shape_.texcoords; }; - auto set_triangles = [&](scene_shape&& shape) { + auto set_triangles = [&](shape_data&& shape) { throw std::invalid_argument{"bad shape type"}; }; - auto set_lines = [&](scene_shape&& shape) { + auto set_lines = [&](shape_data&& shape) { throw std::invalid_argument{"bad shape type"}; }; - auto set_points = [&](scene_shape&& shape) { + auto set_points = [&](shape_data&& shape) { throw std::invalid_argument{"bad shape type"}; }; auto set_fvquads = [&](scene_fvshape&& shape_) { @@ -1758,7 +1758,7 @@ namespace yocto { scene, (int)(&environment - scene.environments.data())); } [[maybe_unused]] static string get_shape_name( - const scene_model& scene, const scene_shape& shape) { + const scene_model& scene, const shape_data& shape) { return get_shape_name(scene, (int)(&shape - scene.shapes.data())); } [[maybe_unused]] static string get_texture_name( @@ -2520,7 +2520,7 @@ bool save_subdiv( // save binary shape static bool save_binshape( - const string& filename, const scene_shape& shape, string& error) { + const string& filename, const shape_data& shape, string& error) { auto open_error = [filename, &error]() { error = filename + ": file not found"; return false; @@ -2616,15 +2616,15 @@ inline void from_json(const njson& j, mat4f& value) { } inline void to_json(njson& j, material_type value) { - j = scene_material_names.at((int)value); + j = material_type_names.at((int)value); } inline void from_json(const njson& j, material_type& value) { auto values = j.get(); auto pos = std::find( - scene_material_names.begin(), scene_material_names.end(), values); - if (pos == scene_material_names.end()) + material_type_names.begin(), material_type_names.end(), values); + if (pos == material_type_names.end()) throw std::invalid_argument{"unknown value"}; - value = (material_type)(pos - scene_material_names.begin()); + value = (material_type)(pos - material_type_names.begin()); } } // namespace yocto diff --git a/libs/yocto/yocto_sceneio.h b/libs/yocto/yocto_sceneio.h index e381c3dbc..18af6e284 100644 --- a/libs/yocto/yocto_sceneio.h +++ b/libs/yocto/yocto_sceneio.h @@ -116,9 +116,9 @@ bool make_texture_preset( namespace yocto { // Load/save a shape -bool load_shape(const string& filename, scene_shape& shape, string& error, +bool load_shape(const string& filename, shape_data& shape, string& error, bool flip_texcoords = true); -bool save_shape(const string& filename, const scene_shape& shape, string& error, +bool save_shape(const string& filename, const shape_data& shape, string& error, bool flip_texcoords = true, bool ascii = false); // Load/save a subdiv @@ -128,7 +128,7 @@ bool save_fvshape(const string& filename, const scene_fvshape& shape, string& error, bool flip_texcoords = true, bool ascii = false); // Make presets. Supported mostly in IO. -bool make_shape_preset(scene_shape& shape, const string& type, string& error); +bool make_shape_preset(shape_data& shape, const string& type, string& error); bool make_fvshape_preset( scene_fvshape& shape, const string& type, string& error); diff --git a/libs/yocto_gui/yocto_glview.cpp b/libs/yocto_gui/yocto_glview.cpp index f7bb3a11f..50798925d 100644 --- a/libs/yocto_gui/yocto_glview.cpp +++ b/libs/yocto_gui/yocto_glview.cpp @@ -1313,7 +1313,7 @@ void clear_texture(glscene_texture& gltexture) { } // Create shape -void set_shape(glscene_shape& glshape, const scene_shape& shape) { +void set_shape(glscene_shape& glshape, const shape_data& shape) { auto set_vertex = [](uint& buffer, int& num, const auto& data, const auto& def, int location) { if (data.empty()) { diff --git a/libs/yocto_gui/yocto_glview.h b/libs/yocto_gui/yocto_glview.h index 3272a7770..65e933ea5 100644 --- a/libs/yocto_gui/yocto_glview.h +++ b/libs/yocto_gui/yocto_glview.h @@ -185,7 +185,7 @@ struct glscene_shape { }; // Create shape -void set_shape(glscene_shape& glshape, const scene_shape& shape); +void set_shape(glscene_shape& glshape, const shape_data& shape); // Clean shape void clear_shape(glscene_shape& glshape); From 53be1e32f29746fc40a33f89dc36e9c0907d1c75 Mon Sep 17 00:00:00 2001 From: Fabio Pellacini Date: Wed, 9 Jun 2021 14:52:01 +0200 Subject: [PATCH 05/12] updated --- apps/yshape/yshape.cpp | 2 +- docs/yocto/yocto_scene.md | 16 ++++----- docs/yocto/yocto_sceneio.md | 2 +- docs/yocto/yocto_shape.md | 2 +- libs/yocto/yocto_scene.cpp | 62 ++++++++++++++++---------------- libs/yocto/yocto_scene.h | 70 ++++++++++++++++++------------------ libs/yocto/yocto_sceneio.cpp | 18 +++++----- libs/yocto/yocto_sceneio.h | 6 ++-- 8 files changed, 90 insertions(+), 88 deletions(-) diff --git a/apps/yshape/yshape.cpp b/apps/yshape/yshape.cpp index 51c3811f6..b836dcfc1 100644 --- a/apps/yshape/yshape.cpp +++ b/apps/yshape/yshape.cpp @@ -214,7 +214,7 @@ void add_command(const cli_command& cli, const string& name, // convert images int run_fvconvert(const fvconvert_params& params) { // mesh data - auto shape = scene_fvshape{}; + auto shape = fvshape_data{}; // load mesh auto ioerror = ""s; diff --git a/docs/yocto/yocto_scene.md b/docs/yocto/yocto_scene.md index 5091bb164..6a685ce97 100644 --- a/docs/yocto/yocto_scene.md +++ b/docs/yocto/yocto_scene.md @@ -41,7 +41,7 @@ auto shape = shape_data{}; // create a shape and add it set_shape_properties(shape, ...); scene.shapes.push_back(shape); scene.materials.push_back({}); // create a black material directly -auto instance = scene_instance{}; // create an instance of last added shape +auto instance = instance_data{}; // create an instance of last added shape instance.shape = (int)scene.shapes.size()-1; instance.material = (int)scene.materials.size()-1; ``` @@ -105,7 +105,7 @@ auto ray = eval_camera(camera,{0.5,0.5},{0,0});// get ray though image center ## Instances -Instances, represented as `scene_instance`, place shapes in the scene by +Instances, represented as `instance_data`, place shapes in the scene by defining their coordinate frame, a shape index and a material index. Through the use of instancing, Yocto/Scene scales well to large environments without introducing more complex mechanisms. @@ -113,7 +113,7 @@ without introducing more complex mechanisms. For instances, you should set the instance frame, shape and material. ```cpp -auto instance = scene_instance{}; // create an instance +auto instance = instance_data{}; // create an instance instance.frame = identity3x4f; // set frame to identity instance.shape = shape_index; // set shape index instance.material = material_index; // set material index @@ -179,7 +179,7 @@ points, lines, triangles or quads. Shape elements are parametrized as in [Yocto/Geometry](yocto_geometry.md). Vertex properties are defined as separate arrays and include positions, normals, texture coords, colors, radius and tangent spaces. -Additionally, Yocto/Scene supports face-varying primitives, as `scene_fvshape`, +Additionally, Yocto/Scene supports face-varying primitives, as `fvshape_data`, where each vertex data has its own topology. Shapes also work as a standalone mesh representation throughout the @@ -393,7 +393,7 @@ We also support standalone face-varying shapes, that are not stored in the scene normals and texture coordinates. ```cpp -auto shape = scene_fvshape{}; // create a shape +auto shape = fvshape_data{}; // create a shape shape.quadspos = vector{...}; // set face-varying indices shape.quadstexcoord = vector{...}; // for positions and textures shape.positions = vector{...}; // set positions @@ -458,7 +458,7 @@ auto shape_15 = make_rounded_uvcylinder({32,32,32}, {1,1}); Yocto/Shape defines a few procedural face-varying shapes with similar interfaces to the above functions. In this case, the functions return face-varying quads -packed in a `scene_fvshape` struct. +packed in a `fvshape_data` struct. Use `make_fvrect(...)` for a rectangle in the XY plane, `make_fvbox(...)` for a box, `make_fvsphere(...)` for a sphere obtained from a cube. @@ -473,14 +473,14 @@ auto fvshape_03 = make_fvsphere(32, 1); Yocto/Shape provides functions to create predefined shapes helpful in testing. These functions take only a scale and often provide only the positions as vertex data. These functions return either triangles, quads, or -face-varying quads in a `shape_data` or `scene_fvshape` struct. +face-varying quads in a `shape_data` or `fvshape_data` struct. Use `make_monkey(...)` for the Blender monkey as quads and positions only, `make_quad(...)` for a simple quad, `make_quady(...)` for a simple quad in the XZ plane, `make_cube(...)` for a simple cube as quads and positions only, `make_fvcube(...)` for a simple face-varying unit cube, `make_geosphere(...)` for a geodesic sphere as triangles and positions only. -These functions return a `shape_data` or `scene_fvshape`. +These functions return a `shape_data` or `fvshape_data`. ```cpp auto monkey = make_monkey(1); diff --git a/docs/yocto/yocto_sceneio.md b/docs/yocto/yocto_sceneio.md index 984ab7bc4..1715e943e 100644 --- a/docs/yocto/yocto_sceneio.md +++ b/docs/yocto/yocto_sceneio.md @@ -80,7 +80,7 @@ if(!load_shape(filename, shape, error)) // load shape if(!save_shape(filename, shape, error)) // save shape print_error(error); -auto fvshape = scene_fvshape{}; // face-varying shape +auto fvshape = fvshape_data{}; // face-varying shape auto error = string{}; // error buffer if(!load_fvshape(filename, fvshape, error)) // load shape print_error(error); diff --git a/docs/yocto/yocto_shape.md b/docs/yocto/yocto_shape.md index 7f95d07c5..bc1a14e48 100644 --- a/docs/yocto/yocto_shape.md +++ b/docs/yocto/yocto_shape.md @@ -43,7 +43,7 @@ appropriate. This design tries to balance readability and generality, without forcing a single convention that would not be appropriate everywhere. If a higher level design is needed, [Yocto/Scene](yocto_scene.md) contains -the standalone types `shape_data` and `scene_fvshape` to store indexed +the standalone types `shape_data` and `fvshape_data` to store indexed and face-varying shapes respectively, a a collection of methods to work on these type, that are essentially wrappers to the functionality in this library. diff --git a/libs/yocto/yocto_scene.cpp b/libs/yocto/yocto_scene.cpp index e251196e0..0fba10c78 100644 --- a/libs/yocto/yocto_scene.cpp +++ b/libs/yocto/yocto_scene.cpp @@ -567,7 +567,7 @@ shape_data subdivide_shape( } // Interpolate vertex data -vec3f eval_position(const scene_fvshape& shape, int element, const vec2f& uv) { +vec3f eval_position(const fvshape_data& shape, int element, const vec2f& uv) { if (!shape.quadspos.empty()) { auto& quad = shape.quadspos[element]; return interpolate_quad(shape.positions[quad.x], shape.positions[quad.y], @@ -577,7 +577,7 @@ vec3f eval_position(const scene_fvshape& shape, int element, const vec2f& uv) { } } -vec3f eval_normal(const scene_fvshape& shape, int element, const vec2f& uv) { +vec3f eval_normal(const fvshape_data& shape, int element, const vec2f& uv) { if (shape.normals.empty()) return eval_element_normal(shape, element); if (!shape.quadspos.empty()) { auto& quad = shape.quadsnorm[element]; @@ -589,7 +589,7 @@ vec3f eval_normal(const scene_fvshape& shape, int element, const vec2f& uv) { } } -vec2f eval_texcoord(const scene_fvshape& shape, int element, const vec2f& uv) { +vec2f eval_texcoord(const fvshape_data& shape, int element, const vec2f& uv) { if (shape.texcoords.empty()) return {0, 0}; if (!shape.quadspos.empty()) { auto& quad = shape.quadstexcoord[element]; @@ -601,7 +601,7 @@ vec2f eval_texcoord(const scene_fvshape& shape, int element, const vec2f& uv) { } // Evaluate element normals -vec3f eval_element_normal(const scene_fvshape& shape, int element) { +vec3f eval_element_normal(const fvshape_data& shape, int element) { if (!shape.quadspos.empty()) { auto& quad = shape.quadspos[element]; return quad_normal(shape.positions[quad.x], shape.positions[quad.y], @@ -612,14 +612,14 @@ vec3f eval_element_normal(const scene_fvshape& shape, int element) { } // Compute per-vertex normals/tangents for lines/triangles/quads. -vector compute_normals(const scene_fvshape& shape) { +vector compute_normals(const fvshape_data& shape) { if (!shape.quadspos.empty()) { return quads_normals(shape.quadspos, shape.positions); } else { return vector(shape.positions.size(), {0, 0, 1}); } } -void compute_normals(vector& normals, const scene_fvshape& shape) { +void compute_normals(vector& normals, const fvshape_data& shape) { if (!shape.quadspos.empty()) { quads_normals(normals, shape.quadspos, shape.positions); } else { @@ -628,7 +628,7 @@ void compute_normals(vector& normals, const scene_fvshape& shape) { } // Conversions -shape_data fvshape_to_shape(const scene_fvshape& fvshape, bool as_triangles) { +shape_data fvshape_to_shape(const fvshape_data& fvshape, bool as_triangles) { auto shape = shape_data{}; split_facevarying(shape.quads, shape.positions, shape.normals, shape.texcoords, fvshape.quadspos, fvshape.quadsnorm, @@ -636,10 +636,10 @@ shape_data fvshape_to_shape(const scene_fvshape& fvshape, bool as_triangles) { fvshape.texcoords); return shape; } -scene_fvshape shape_to_fvshape(const shape_data& shape) { +fvshape_data shape_to_fvshape(const shape_data& shape) { if (!shape.points.empty() || !shape.lines.empty()) throw std::invalid_argument{"cannor convert shape"}; - auto fvshape = scene_fvshape{}; + auto fvshape = fvshape_data{}; fvshape.positions = shape.positions; fvshape.normals = shape.normals; fvshape.texcoords = shape.texcoords; @@ -653,9 +653,9 @@ scene_fvshape shape_to_fvshape(const shape_data& shape) { } // Subdivision -scene_fvshape subdivide_fvshape( - const scene_fvshape& shape, int subdivisions, bool catmullclark) { - auto subdivided = scene_fvshape{}; +fvshape_data subdivide_fvshape( + const fvshape_data& shape, int subdivisions, bool catmullclark) { + auto subdivided = fvshape_data{}; if (!catmullclark) { std::tie(subdivided.quadspos, subdivided.positions) = subdivide_quads( shape.quadspos, shape.positions, subdivisions); @@ -709,7 +709,7 @@ vector shape_stats(const shape_data& shape, bool verbose) { return stats; } -vector fvshape_stats(const scene_fvshape& shape, bool verbose) { +vector fvshape_stats(const fvshape_data& shape, bool verbose) { auto format = [](auto num) { auto str = std::to_string(num); while (str.size() < 13) str = " " + str; @@ -746,7 +746,7 @@ vector fvshape_stats(const scene_fvshape& shape, bool verbose) { namespace yocto { // Eval position -vec3f eval_position(const scene_model& scene, const scene_instance& instance, +vec3f eval_position(const scene_model& scene, const instance_data& instance, int element, const vec2f& uv) { auto& shape = scene.shapes[instance.shape]; if (!shape.triangles.empty()) { @@ -773,7 +773,7 @@ vec3f eval_position(const scene_model& scene, const scene_instance& instance, // Shape element normal. vec3f eval_element_normal( - const scene_model& scene, const scene_instance& instance, int element) { + const scene_model& scene, const instance_data& instance, int element) { auto& shape = scene.shapes[instance.shape]; if (!shape.triangles.empty()) { auto t = shape.triangles[element]; @@ -797,7 +797,7 @@ vec3f eval_element_normal( } // Eval normal -vec3f eval_normal(const scene_model& scene, const scene_instance& instance, +vec3f eval_normal(const scene_model& scene, const instance_data& instance, int element, const vec2f& uv) { auto& shape = scene.shapes[instance.shape]; if (shape.normals.empty()) @@ -826,7 +826,7 @@ vec3f eval_normal(const scene_model& scene, const scene_instance& instance, } // Eval texcoord -vec2f eval_texcoord(const scene_model& scene, const scene_instance& instance, +vec2f eval_texcoord(const scene_model& scene, const instance_data& instance, int element, const vec2f& uv) { auto& shape = scene.shapes[instance.shape]; if (shape.texcoords.empty()) return uv; @@ -882,7 +882,7 @@ static pair eval_tangents( // Shape element normal. pair eval_element_tangents( - const scene_model& scene, const scene_instance& instance, int element) { + const scene_model& scene, const instance_data& instance, int element) { auto& shape = scene.shapes[instance.shape]; if (!shape.triangles.empty() && !shape.texcoords.empty()) { auto t = shape.triangles[element]; @@ -904,7 +904,7 @@ pair eval_element_tangents( } } -vec3f eval_normalmap(const scene_model& scene, const scene_instance& instance, +vec3f eval_normalmap(const scene_model& scene, const instance_data& instance, int element, const vec2f& uv) { auto& shape = scene.shapes[instance.shape]; auto& material = scene.materials[instance.material]; @@ -928,7 +928,7 @@ vec3f eval_normalmap(const scene_model& scene, const scene_instance& instance, // Eval shading normal vec3f eval_shading_normal(const scene_model& scene, - const scene_instance& instance, int element, const vec2f& uv, + const instance_data& instance, int element, const vec2f& uv, const vec3f& outgoing) { auto& shape = scene.shapes[instance.shape]; auto& material = scene.materials[instance.material]; @@ -950,7 +950,7 @@ vec3f eval_shading_normal(const scene_model& scene, } // Eval color -vec4f eval_color(const scene_model& scene, const scene_instance& instance, +vec4f eval_color(const scene_model& scene, const instance_data& instance, int element, const vec2f& uv) { auto& shape = scene.shapes[instance.shape]; if (shape.colors.empty()) return {1, 1, 1, 1}; @@ -974,7 +974,7 @@ vec4f eval_color(const scene_model& scene, const scene_instance& instance, // Evaluate material material_point eval_material(const scene_model& scene, - const scene_instance& instance, int element, const vec2f& uv) { + const instance_data& instance, int element, const vec2f& uv) { auto& material = scene.materials[instance.material]; auto texcoord = eval_texcoord(scene, instance, element, uv); @@ -1026,7 +1026,7 @@ material_point eval_material(const scene_model& scene, } // check if an instance is volumetric -bool is_volumetric(const scene_model& scene, const scene_instance& instance) { +bool is_volumetric(const scene_model& scene, const instance_data& instance) { return is_volumetric(scene.materials[instance.material]); } @@ -1586,26 +1586,26 @@ shape_data make_random_points( } // Make a facevarying rect -scene_fvshape make_fvrect( +fvshape_data make_fvrect( const vec2i& steps, const vec2f& scale, const vec2f& uvscale) { - auto shape = scene_fvshape{}; + auto shape = fvshape_data{}; make_fvrect(shape.quadspos, shape.quadsnorm, shape.quadstexcoord, shape.positions, shape.normals, shape.texcoords, steps, scale, uvscale); return shape; } // Make a facevarying box -scene_fvshape make_fvbox( +fvshape_data make_fvbox( const vec3i& steps, const vec3f& scale, const vec3f& uvscale) { - auto shape = scene_fvshape{}; + auto shape = fvshape_data{}; make_fvbox(shape.quadspos, shape.quadsnorm, shape.quadstexcoord, shape.positions, shape.normals, shape.texcoords, steps, scale, uvscale); return shape; } // Make a facevarying sphere -scene_fvshape make_fvsphere(int steps, float scale, float uvscale) { - auto shape = scene_fvshape{}; +fvshape_data make_fvsphere(int steps, float scale, float uvscale) { + auto shape = fvshape_data{}; make_fvsphere(shape.quadspos, shape.quadsnorm, shape.quadstexcoord, shape.positions, shape.normals, shape.texcoords, steps, scale, uvscale); return shape; @@ -1635,8 +1635,8 @@ shape_data make_cube(float scale, int subdivisions) { subdivisions); return shape; } -scene_fvshape make_fvcube(float scale, int subdivisions) { - auto shape = scene_fvshape{}; +fvshape_data make_fvcube(float scale, int subdivisions) { + auto shape = fvshape_data{}; make_fvcube(shape.quadspos, shape.quadsnorm, shape.quadstexcoord, shape.positions, shape.normals, shape.texcoords, scale, subdivisions); return shape; diff --git a/libs/yocto/yocto_scene.h b/libs/yocto/yocto_scene.h index 3f45d9708..aa413ee42 100644 --- a/libs/yocto/yocto_scene.h +++ b/libs/yocto/yocto_scene.h @@ -156,7 +156,7 @@ struct shape_data { }; // Shape data stored as a face-varying mesh -struct scene_fvshape { +struct fvshape_data { // element data vector quadspos = {}; vector quadsnorm = {}; @@ -169,7 +169,7 @@ struct scene_fvshape { }; // Instance. -struct scene_instance { +struct instance_data { // instance data frame3f frame = identity3x4f; int shape = invalidid; @@ -220,7 +220,7 @@ struct scene_subdiv { struct scene_model { // scene elements vector cameras = {}; - vector instances = {}; + vector instances = {}; vector environments = {}; vector shapes = {}; vector textures = {}; @@ -307,7 +307,7 @@ bool is_delta(const material_point& material); // check if a material has a volume bool is_volumetric(const material_data& material); bool is_volumetric(const material_point& material); -bool is_volumetric(const scene_model& scene, const scene_instance& instance); +bool is_volumetric(const scene_model& scene, const instance_data& instance); } // namespace yocto @@ -354,29 +354,29 @@ shape_data subdivide_shape( const shape_data& shape, int subdivisions, bool catmullclark); // Interpolate vertex data -vec3f eval_position(const scene_fvshape& shape, int element, const vec2f& uv); -vec3f eval_normal(const scene_fvshape& shape, int element, const vec2f& uv); +vec3f eval_position(const fvshape_data& shape, int element, const vec2f& uv); +vec3f eval_normal(const fvshape_data& shape, int element, const vec2f& uv); vec2f eval_texcoord(const shape_data& shape, int element, const vec2f& uv); // Evaluate element normals -vec3f eval_element_normal(const scene_fvshape& shape, int element); +vec3f eval_element_normal(const fvshape_data& shape, int element); // Compute per-vertex normals/tangents for lines/triangles/quads. -vector compute_normals(const scene_fvshape& shape); -void compute_normals(vector& normals, const scene_fvshape& shape); +vector compute_normals(const fvshape_data& shape); +void compute_normals(vector& normals, const fvshape_data& shape); // Conversions shape_data fvshape_to_shape( - const scene_fvshape& shape, bool as_triangles = false); -scene_fvshape shape_to_fvshape(const shape_data& shape); + const fvshape_data& shape, bool as_triangles = false); +fvshape_data shape_to_fvshape(const shape_data& shape); // Subdivision -scene_fvshape subdivide_fvshape( - const scene_fvshape& shape, int subdivisions, bool catmullclark); +fvshape_data subdivide_fvshape( + const fvshape_data& shape, int subdivisions, bool catmullclark); // Shape statistics vector shape_stats(const shape_data& shape, bool verbose = false); -vector fvshape_stats(const scene_fvshape& shape, bool verbose = false); +vector fvshape_stats(const fvshape_data& shape, bool verbose = false); } // namespace yocto @@ -386,29 +386,29 @@ vector fvshape_stats(const scene_fvshape& shape, bool verbose = false); namespace yocto { // Evaluate instance properties -vec3f eval_position(const scene_model& scene, const scene_instance& instance, +vec3f eval_position(const scene_model& scene, const instance_data& instance, int element, const vec2f& uv); vec3f eval_element_normal( - const scene_model& scene, const scene_instance& instance, int element); -vec3f eval_normal(const scene_model& scene, const scene_instance& instance, + const scene_model& scene, const instance_data& instance, int element); +vec3f eval_normal(const scene_model& scene, const instance_data& instance, int element, const vec2f& uv); -vec2f eval_texcoord(const scene_model& scene, const scene_instance& instance, +vec2f eval_texcoord(const scene_model& scene, const instance_data& instance, int element, const vec2f& uv); pair eval_element_tangents( - const scene_model& scene, const scene_instance& instance, int element); -vec3f eval_normalmap(const scene_model& scene, const scene_instance& instance, + const scene_model& scene, const instance_data& instance, int element); +vec3f eval_normalmap(const scene_model& scene, const instance_data& instance, int element, const vec2f& uv); vec3f eval_shading_normal(const scene_model& scene, - const scene_instance& instance, int element, const vec2f& uv, + const instance_data& instance, int element, const vec2f& uv, const vec3f& outgoing); -vec4f eval_color(const scene_model& scene, const scene_instance& instance, +vec4f eval_color(const scene_model& scene, const instance_data& instance, int element, const vec2f& uv); // Eval material to obtain emission, brdf and opacity. material_point eval_material(const scene_model& scene, - const scene_instance& instance, int element, const vec2f& uv); + const instance_data& instance, int element, const vec2f& uv); // check if a material has a volume -bool is_volumetric(const scene_model& scene, const scene_instance& instance); +bool is_volumetric(const scene_model& scene, const instance_data& instance); } // namespace yocto @@ -521,13 +521,13 @@ shape_data make_rounded_uvcylinder(const vec3i& steps = {32, 32, 32}, float radius = 0.3); // Make a facevarying rect -scene_fvshape make_fvrect(const vec2i& steps = {1, 1}, +fvshape_data make_fvrect(const vec2i& steps = {1, 1}, const vec2f& scale = {1, 1}, const vec2f& uvscale = {1, 1}); // Make a facevarying box -scene_fvshape make_fvbox(const vec3i& steps = {1, 1, 1}, +fvshape_data make_fvbox(const vec3i& steps = {1, 1, 1}, const vec3f& scale = {1, 1, 1}, const vec3f& uvscale = {1, 1, 1}); // Make a facevarying sphere -scene_fvshape make_fvsphere(int steps = 32, float scale = 1, float uvscale = 1); +fvshape_data make_fvsphere(int steps = 32, float scale = 1, float uvscale = 1); // Generate lines set along a quad. Returns lines, pos, norm, texcoord, radius. shape_data make_lines(const vec2i& steps = {4, 65536}, @@ -542,12 +542,12 @@ shape_data make_random_points(int num = 65536, const vec3f& size = {1, 1, 1}, float uvscale = 1, float radius = 0.001f, uint64_t seed = 17); // Predefined meshes -shape_data make_monkey(float scale = 1, int subdivisions = 0); -shape_data make_quad(float scale = 1, int subdivisions = 0); -shape_data make_quady(float scale = 1, int subdivisions = 0); -shape_data make_cube(float scale = 1, int subdivisions = 0); -scene_fvshape make_fvcube(float scale = 1, int subdivisions = 0); -shape_data make_geosphere(float scale = 1, int subdivisions = 0); +shape_data make_monkey(float scale = 1, int subdivisions = 0); +shape_data make_quad(float scale = 1, int subdivisions = 0); +shape_data make_quady(float scale = 1, int subdivisions = 0); +shape_data make_cube(float scale = 1, int subdivisions = 0); +fvshape_data make_fvcube(float scale = 1, int subdivisions = 0); +shape_data make_geosphere(float scale = 1, int subdivisions = 0); // Make a hair ball around a shape. // length: minimum and maximum length @@ -608,7 +608,9 @@ using scene_material_type = material_type; using sceneio_material = material_data; using sceneio_shape = shape_data; using scene_shape = shape_data; -using sceneio_instance = scene_instance; +using scene_fvshape = fvshape_data; +using sceneio_instance = instance_data; +using scene_instance = instance_data; using sceneio_environment = scene_environment; inline const auto scene_material_names = std::vector{"matte", diff --git a/libs/yocto/yocto_sceneio.cpp b/libs/yocto/yocto_sceneio.cpp index bbd7816fd..bf4eb528d 100644 --- a/libs/yocto/yocto_sceneio.cpp +++ b/libs/yocto/yocto_sceneio.cpp @@ -1115,7 +1115,7 @@ bool save_shape(const string& filename, const shape_data& shape, string& error, } // Load ply mesh -bool load_fvshape(const string& filename, scene_fvshape& shape, string& error, +bool load_fvshape(const string& filename, fvshape_data& shape, string& error, bool flip_texcoord) { auto format_error = [filename, &error]() { error = filename + ": unknown format"; @@ -1177,7 +1177,7 @@ bool load_fvshape(const string& filename, scene_fvshape& shape, string& error, } // Save ply mesh -bool save_fvshape(const string& filename, const scene_fvshape& shape, +bool save_fvshape(const string& filename, const fvshape_data& shape, string& error, bool flip_texcoord, bool ascii) { auto format_error = [filename, &error]() { error = filename + ": unknown format"; @@ -1305,7 +1305,7 @@ bool make_shape_preset(shape_data& shape, const string& type, string& error) { shape.texcoords = shape_.texcoords; shape.radius = shape_.radius; }; - auto set_fvquads = [&](scene_fvshape&& shape_) { + auto set_fvquads = [&](fvshape_data&& shape_) { shape.quads = shape_.quadspos; shape.positions = shape_.positions; shape.normals = shape_.normals; @@ -1494,7 +1494,7 @@ bool make_shape_preset(shape_data& shape, const string& type, string& error) { // Shape presets used for testing. bool make_fvshape_preset( - scene_fvshape& shape, const string& type, string& error) { + fvshape_data& shape, const string& type, string& error) { auto set_quads = [&](shape_data&& shape_) { shape.quadspos = shape_.quads; shape.positions = shape_.positions; @@ -1512,7 +1512,7 @@ bool make_fvshape_preset( auto set_points = [&](shape_data&& shape) { throw std::invalid_argument{"bad shape type"}; }; - auto set_fvquads = [&](scene_fvshape&& shape_) { + auto set_fvquads = [&](fvshape_data&& shape_) { shape.quadspos = shape_.quadspos; shape.quadsnorm = shape_.quadsnorm; shape.quadstexcoord = shape_.quadstexcoord; @@ -1766,7 +1766,7 @@ namespace yocto { return get_texture_name(scene, (int)(&texture - scene.textures.data())); } [[maybe_unused]] static string get_instance_name( - const scene_model& scene, const scene_instance& instance) { + const scene_model& scene, const instance_data& instance) { return get_instance_name(scene, (int)(&instance - scene.instances.data())); } [[maybe_unused]] static string get_material_name( @@ -2494,7 +2494,7 @@ bool save_instance(const string& filename, const vector& frames, // load subdiv bool load_subdiv(const string& filename, scene_subdiv& subdiv, string& error) { - auto lsubdiv = scene_fvshape{}; + auto lsubdiv = fvshape_data{}; if (!load_fvshape(filename, lsubdiv, error, true)) return false; subdiv.quadspos = lsubdiv.quadspos; subdiv.quadsnorm = lsubdiv.quadsnorm; @@ -2508,7 +2508,7 @@ bool load_subdiv(const string& filename, scene_subdiv& subdiv, string& error) { // save subdiv bool save_subdiv( const string& filename, const scene_subdiv& subdiv, string& error) { - auto ssubdiv = scene_fvshape{}; + auto ssubdiv = fvshape_data{}; ssubdiv.quadspos = subdiv.quadspos; ssubdiv.quadsnorm = subdiv.quadsnorm; ssubdiv.quadstexcoord = subdiv.quadstexcoord; @@ -2752,7 +2752,7 @@ static bool load_json_scene(const string& filename, scene_model& scene, auto get_ply_instances = [&scene, &ply_instances, &ply_instances_names, &ply_instance_map, &instance_ply, &get_value](const njson& js, - const scene_instance& instance) -> bool { + const instance_data& instance) -> bool { auto name = ""s; if (!get_value(js, name)) return false; if (name.empty()) return true; diff --git a/libs/yocto/yocto_sceneio.h b/libs/yocto/yocto_sceneio.h index 18af6e284..c62fce960 100644 --- a/libs/yocto/yocto_sceneio.h +++ b/libs/yocto/yocto_sceneio.h @@ -122,15 +122,15 @@ bool save_shape(const string& filename, const shape_data& shape, string& error, bool flip_texcoords = true, bool ascii = false); // Load/save a subdiv -bool load_fvshape(const string& filename, scene_fvshape& shape, string& error, +bool load_fvshape(const string& filename, fvshape_data& shape, string& error, bool flip_texcoords = true); -bool save_fvshape(const string& filename, const scene_fvshape& shape, +bool save_fvshape(const string& filename, const fvshape_data& shape, string& error, bool flip_texcoords = true, bool ascii = false); // Make presets. Supported mostly in IO. bool make_shape_preset(shape_data& shape, const string& type, string& error); bool make_fvshape_preset( - scene_fvshape& shape, const string& type, string& error); + fvshape_data& shape, const string& type, string& error); } // namespace yocto From 5a47eaecf336173e4272b8d00b21dae44d7372c8 Mon Sep 17 00:00:00 2001 From: Fabio Pellacini Date: Wed, 9 Jun 2021 14:53:54 +0200 Subject: [PATCH 06/12] updated --- docs/yocto/yocto_scene.md | 4 ++-- libs/yocto/yocto_scene.cpp | 2 +- libs/yocto/yocto_scene.h | 21 +++++++++++---------- libs/yocto/yocto_sceneio.cpp | 2 +- 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/docs/yocto/yocto_scene.md b/docs/yocto/yocto_scene.md index 6a685ce97..3549a361f 100644 --- a/docs/yocto/yocto_scene.md +++ b/docs/yocto/yocto_scene.md @@ -144,7 +144,7 @@ auto mat = eval_material(instance, eid, euv); // eval point material ## Environments -Environments, represented as `scene_environment`, store the background +Environments, represented as `environment_data`, store the background illumination as a scene. Environments have a frame, to rotate illumination, an emission term and an optional emission texture. The emission texture is an HDR environment map stored in a LatLon @@ -153,7 +153,7 @@ parametrization. For environments, set the frame, emission and optionally the emission texture. ```cpp -auto& environment = scene_environment{}; // create an environment +auto& environment = environment_data{}; // create an environment environment.frame = identity3x4f; // set identity transform environment.emission = {1,1,1}; // set emission scale environment.emission_tex = texture_index; // add emission texture diff --git a/libs/yocto/yocto_scene.cpp b/libs/yocto/yocto_scene.cpp index 0fba10c78..360a3ed4c 100644 --- a/libs/yocto/yocto_scene.cpp +++ b/libs/yocto/yocto_scene.cpp @@ -1039,7 +1039,7 @@ namespace yocto { // Evaluate environment color. vec3f eval_environment(const scene_model& scene, - const scene_environment& environment, const vec3f& direction) { + const environment_data& environment, const vec3f& direction) { auto wl = transform_direction(inverse(environment.frame), direction); auto texcoord = vec2f{ atan2(wl.z, wl.x) / (2 * pif), acos(clamp(wl.y, -1.0f, 1.0f)) / pif}; diff --git a/libs/yocto/yocto_scene.h b/libs/yocto/yocto_scene.h index aa413ee42..28fb111ef 100644 --- a/libs/yocto/yocto_scene.h +++ b/libs/yocto/yocto_scene.h @@ -177,7 +177,7 @@ struct instance_data { }; // Environment map. -struct scene_environment { +struct environment_data { // environment data frame3f frame = identity3x4f; vec3f emission = {0, 0, 0}; @@ -219,13 +219,13 @@ struct scene_subdiv { // updates node transformations only if defined. struct scene_model { // scene elements - vector cameras = {}; - vector instances = {}; - vector environments = {}; - vector shapes = {}; - vector textures = {}; - vector materials = {}; - vector subdivs = {}; + vector cameras = {}; + vector instances = {}; + vector environments = {}; + vector shapes = {}; + vector textures = {}; + vector materials = {}; + vector subdivs = {}; // names (this will be cleanup significantly later) vector camera_names = {}; @@ -419,7 +419,7 @@ namespace yocto { // Environment vec3f eval_environment(const scene_model& scene, - const scene_environment& environment, const vec3f& direction); + const environment_data& environment, const vec3f& direction); vec3f eval_environment(const scene_model& scene, const vec3f& direction); } // namespace yocto @@ -611,7 +611,8 @@ using scene_shape = shape_data; using scene_fvshape = fvshape_data; using sceneio_instance = instance_data; using scene_instance = instance_data; -using sceneio_environment = scene_environment; +using sceneio_environment = environment_data; +using scene_environment = environment_data; inline const auto scene_material_names = std::vector{"matte", "glossy", "metallic", "transparent", "refractive", "subsurface", "volume", diff --git a/libs/yocto/yocto_sceneio.cpp b/libs/yocto/yocto_sceneio.cpp index bf4eb528d..64e80eb48 100644 --- a/libs/yocto/yocto_sceneio.cpp +++ b/libs/yocto/yocto_sceneio.cpp @@ -1753,7 +1753,7 @@ namespace yocto { return get_camera_name(scene, (int)(&camera - scene.cameras.data())); } [[maybe_unused]] static string get_environment_name( - const scene_model& scene, const scene_environment& environment) { + const scene_model& scene, const environment_data& environment) { return get_environment_name( scene, (int)(&environment - scene.environments.data())); } From cd3b12482780cd779d289e47f621d4f5902eda39 Mon Sep 17 00:00:00 2001 From: Fabio Pellacini Date: Wed, 9 Jun 2021 14:55:33 +0200 Subject: [PATCH 07/12] updated --- docs/yocto/yocto_scene.md | 2 +- libs/yocto/yocto_scene.cpp | 2 +- libs/yocto/yocto_scene.h | 5 +++-- libs/yocto/yocto_sceneio.cpp | 8 ++++---- libs/yocto/yocto_sceneio.h | 4 ++-- 5 files changed, 11 insertions(+), 10 deletions(-) diff --git a/docs/yocto/yocto_scene.md b/docs/yocto/yocto_scene.md index 3549a361f..fbc38987e 100644 --- a/docs/yocto/yocto_scene.md +++ b/docs/yocto/yocto_scene.md @@ -350,7 +350,7 @@ auto col = eval_texture(texture,{0.5,0.5}); // eval texture ## Subdivs -Subdivs, represented as `scene_subdiv`, support tesselation and displacement +Subdivs, represented as `subdiv_data`, support tesselation and displacement mapping. Subdivs are represented as facee-varying shapes. Subdivs specify a level of subdivision and can be subdivide elements either linearly or using Catmull-Clark subdivision. Subdivs also support diff --git a/libs/yocto/yocto_scene.cpp b/libs/yocto/yocto_scene.cpp index 360a3ed4c..316dddf88 100644 --- a/libs/yocto/yocto_scene.cpp +++ b/libs/yocto/yocto_scene.cpp @@ -1168,7 +1168,7 @@ bbox3f compute_bounds(const scene_model& scene) { namespace yocto { void tesselate_subdiv( - shape_data& shape, scene_subdiv& subdiv_, const scene_model& scene) { + shape_data& shape, subdiv_data& subdiv_, const scene_model& scene) { auto subdiv = subdiv_; if (subdiv.subdivisions > 0) { diff --git a/libs/yocto/yocto_scene.h b/libs/yocto/yocto_scene.h index 28fb111ef..5ae5a8125 100644 --- a/libs/yocto/yocto_scene.h +++ b/libs/yocto/yocto_scene.h @@ -186,7 +186,7 @@ struct environment_data { // Subdiv data represented as face-varying primitives where // each vertex data has its own topology. -struct scene_subdiv { +struct subdiv_data { // face-varying primitives vector quadspos = {}; vector quadsnorm = {}; @@ -225,7 +225,7 @@ struct scene_model { vector shapes = {}; vector textures = {}; vector materials = {}; - vector subdivs = {}; + vector subdivs = {}; // names (this will be cleanup significantly later) vector camera_names = {}; @@ -613,6 +613,7 @@ using sceneio_instance = instance_data; using scene_instance = instance_data; using sceneio_environment = environment_data; using scene_environment = environment_data; +using scene_subdiv = subdiv_data; inline const auto scene_material_names = std::vector{"matte", "glossy", "metallic", "transparent", "refractive", "subsurface", "volume", diff --git a/libs/yocto/yocto_sceneio.cpp b/libs/yocto/yocto_sceneio.cpp index 64e80eb48..85188b7d4 100644 --- a/libs/yocto/yocto_sceneio.cpp +++ b/libs/yocto/yocto_sceneio.cpp @@ -1774,7 +1774,7 @@ namespace yocto { return get_material_name(scene, (int)(&material - scene.materials.data())); } [[maybe_unused]] static string get_subdiv_name( - const scene_model& scene, const scene_subdiv& subdiv) { + const scene_model& scene, const subdiv_data& subdiv) { return get_subdiv_name(scene, (int)(&subdiv - scene.subdivs.data())); } @@ -2493,7 +2493,7 @@ bool save_instance(const string& filename, const vector& frames, } // load subdiv -bool load_subdiv(const string& filename, scene_subdiv& subdiv, string& error) { +bool load_subdiv(const string& filename, subdiv_data& subdiv, string& error) { auto lsubdiv = fvshape_data{}; if (!load_fvshape(filename, lsubdiv, error, true)) return false; subdiv.quadspos = lsubdiv.quadspos; @@ -2507,7 +2507,7 @@ bool load_subdiv(const string& filename, scene_subdiv& subdiv, string& error) { // save subdiv bool save_subdiv( - const string& filename, const scene_subdiv& subdiv, string& error) { + const string& filename, const subdiv_data& subdiv, string& error) { auto ssubdiv = fvshape_data{}; ssubdiv.quadspos = subdiv.quadspos; ssubdiv.quadsnorm = subdiv.quadsnorm; @@ -3307,7 +3307,7 @@ static bool save_json_scene(const string& filename, const scene_model& scene, } } - auto def_subdiv = scene_subdiv{}; + auto def_subdiv = subdiv_data{}; if (!scene.subdivs.empty()) { auto& group = insert_object(js, "subdivs"); for (auto& subdiv : scene.subdivs) { diff --git a/libs/yocto/yocto_sceneio.h b/libs/yocto/yocto_sceneio.h index c62fce960..ad2ae50a3 100644 --- a/libs/yocto/yocto_sceneio.h +++ b/libs/yocto/yocto_sceneio.h @@ -140,9 +140,9 @@ bool make_fvshape_preset( namespace yocto { // Load/save a subdiv in the supported formats. -bool load_subdiv(const string& filename, scene_subdiv& subdiv, string& error); +bool load_subdiv(const string& filename, subdiv_data& subdiv, string& error); bool save_subdiv( - const string& filename, const scene_subdiv& subdiv, string& error); + const string& filename, const subdiv_data& subdiv, string& error); } // namespace yocto From 3a95c70c14c6dc1189ff21ad337c377831662792 Mon Sep 17 00:00:00 2001 From: Fabio Pellacini Date: Wed, 9 Jun 2021 14:57:14 +0200 Subject: [PATCH 08/12] updated --- apps/ymesh/ymesh.cpp | 16 ++--- apps/yscene/yscene.cpp | 10 +-- docs/yocto/yocto_bvh.md | 4 +- docs/yocto/yocto_scene.md | 6 +- docs/yocto/yocto_sceneio.md | 2 +- docs/yocto/yocto_trace.md | 6 +- libs/yocto/yocto_bvh.cpp | 28 ++++---- libs/yocto/yocto_bvh.h | 10 +-- libs/yocto/yocto_scene.cpp | 54 +++++++-------- libs/yocto/yocto_scene.h | 53 +++++++------- libs/yocto/yocto_sceneio.cpp | 119 ++++++++++++++++---------------- libs/yocto/yocto_sceneio.h | 10 +-- libs/yocto/yocto_trace.cpp | 36 +++++----- libs/yocto/yocto_trace.h | 12 ++-- libs/yocto_gui/yocto_glview.cpp | 12 ++-- libs/yocto_gui/yocto_glview.h | 10 +-- 16 files changed, 194 insertions(+), 194 deletions(-) diff --git a/apps/ymesh/ymesh.cpp b/apps/ymesh/ymesh.cpp index cde874bc2..32f43ed47 100644 --- a/apps/ymesh/ymesh.cpp +++ b/apps/ymesh/ymesh.cpp @@ -110,7 +110,7 @@ int run_glview(const glview_params& params) { #else -static scene_model make_shapescene(const shape_data& ioshape_) { +static scene_data make_shapescene(const shape_data& ioshape_) { // Frame camera auto camera_frame = [](float lens, float aspect, float film = 0.036) -> frame3f { @@ -121,7 +121,7 @@ static scene_model make_shapescene(const shape_data& ioshape_) { }; // init scene - auto scene = scene_model{}; + auto scene = scene_data{}; // rescale shape to unit auto ioshape = ioshape_; @@ -195,7 +195,7 @@ int run_glpath(const glpath_params& params) { #else -static scene_model make_pathscene(const shape_data& ioshape_) { +static scene_data make_pathscene(const shape_data& ioshape_) { // Frame camera auto camera_frame = [](float lens, float aspect, float film = 0.036) -> frame3f { @@ -206,7 +206,7 @@ static scene_model make_pathscene(const shape_data& ioshape_) { }; // init scene - auto scene = scene_model{}; + auto scene = scene_data{}; // rescale shape to unit auto ioshape = ioshape_; @@ -372,7 +372,7 @@ int run_glpathd(const glpathd_params& params) { #else -static scene_model make_pathdscene(const shape_data& ioshape) { +static scene_data make_pathdscene(const shape_data& ioshape) { // Frame camera auto camera_frame = [](float lens, float aspect, float film = 0.036) -> frame3f { @@ -383,7 +383,7 @@ static scene_model make_pathdscene(const shape_data& ioshape) { }; // init scene - auto scene = scene_model{}; + auto scene = scene_data{}; // camera auto& camera = scene.cameras.emplace_back(); @@ -1087,7 +1087,7 @@ bool smooth_brush(vector& positions, const geodesic_solver& solver, return true; } -static scene_model make_sculptscene(const shape_data& ioshape_) { +static scene_data make_sculptscene(const shape_data& ioshape_) { // Frame camera auto camera_frame = [](float lens, float aspect, float film = 0.036) -> frame3f { @@ -1098,7 +1098,7 @@ static scene_model make_sculptscene(const shape_data& ioshape_) { }; // init scene - auto scene = scene_model{}; + auto scene = scene_data{}; // rescale shape to unit auto ioshape = ioshape_; diff --git a/apps/yscene/yscene.cpp b/apps/yscene/yscene.cpp index 8f0adb60e..286b53b26 100644 --- a/apps/yscene/yscene.cpp +++ b/apps/yscene/yscene.cpp @@ -60,7 +60,7 @@ void add_command(const cli_command& cli, const string& name, // convert images int run_convert(const convert_params& params) { // load scene - auto scene = scene_model{}; + auto scene = scene_data{}; auto ioerror = ""s; print_progress_begin("load scene"); if (!load_scene(params.scene, scene, ioerror)) print_fatal(ioerror); @@ -119,7 +119,7 @@ void add_command(const cli_command& cli, const string& name, // print info for scenes int run_info(const info_params& params) { // load scene - auto scene = scene_model{}; + auto scene = scene_data{}; auto ioerror = ""s; print_progress_begin("load scene"); if (!load_scene(params.scene, scene, ioerror)) print_fatal(ioerror); @@ -186,7 +186,7 @@ int run_render(const render_params& params_) { auto params = params_; // scene loading - auto scene = scene_model{}; + auto scene = scene_data{}; auto ioerror = string{}; print_progress_begin("load scene"); if (!load_scene(params.scene, scene, ioerror)) return print_fatal(ioerror); @@ -311,7 +311,7 @@ int run_view(const view_params& params_) { auto params = params_; // load scene - auto scene = scene_model{}; + auto scene = scene_data{}; auto ioerror = ""s; print_progress_begin("load scene"); if (!load_scene(params.scene, scene, ioerror)) print_fatal(ioerror); @@ -372,7 +372,7 @@ int run_glview(const glview_params& params_) { // loading scene auto ioerror = ""s; - auto scene = scene_model{}; + auto scene = scene_data{}; print_progress_begin("load scene"); if (!load_scene(params.scene, scene, ioerror)) print_fatal(ioerror); print_progress_end(); diff --git a/docs/yocto/yocto_bvh.md b/docs/yocto/yocto_bvh.md index 7a596f408..9485f3750 100644 --- a/docs/yocto/yocto_bvh.md +++ b/docs/yocto/yocto_bvh.md @@ -45,7 +45,7 @@ By default, Yocto/BVH uses the internal BVH. Intel's Embree can be used by setting the `embree` flag to true. ```cpp -auto scene = scene_model{...}; // make a complete scene +auto scene = scene_data{...}; // make a complete scene auto bvh = build_bvh(scene); // build a BVH auto embree = build_bvh(scene,true,true); // use Embree ``` @@ -57,7 +57,7 @@ Updating works ony for change to instance frames and shapes positions. For changes like adding or removing elements, the BVH has to be built again. ```cpp -auto scene = scene_model{...}; // make a complete scene +auto scene = scene_data{...}; // make a complete scene auto bvh = build_bvh(scene); // build a BVH auto shapes = update_shapes(scene); // updates some shapes auto instances = update_instances(scene); // updates some instances diff --git a/docs/yocto/yocto_scene.md b/docs/yocto/yocto_scene.md index fbc38987e..5bbfa9876 100644 --- a/docs/yocto/yocto_scene.md +++ b/docs/yocto/yocto_scene.md @@ -6,7 +6,7 @@ Yocto/Scene is implemented in `yocto_scene.h` and `yocto_scene.cpp`. ## Scene representation -Scenes are stored in `scene_model` structs and are comprised of arrays of +Scenes are stored in `scene_data` structs and are comprised of arrays of cameras, instances, shapes, materials, textures and environments. The various objects are stored as values in arrays named like the object type. Animation is not currently supported. @@ -36,7 +36,7 @@ that "if you know how to use `std::vector`, you know how to use scenes". Here is an sketch of how to create a shape instance in a scene. ```cpp -auto scene = scene_model{}; // create a scene +auto scene = scene_data{}; // create a scene auto shape = shape_data{}; // create a shape and add it set_shape_properties(shape, ...); scene.shapes.push_back(shape); @@ -98,7 +98,7 @@ to get a camera ray from the normalized image coordinates `image_uv` and lens coordinates `lens_uv`. ```cpp -auto scene = scene_model{...}; // create a complete scene +auto scene = scene_data{...}; // create a complete scene auto& camera = get_camera(scene); // get default camera auto ray = eval_camera(camera,{0.5,0.5},{0,0});// get ray though image center ``` diff --git a/docs/yocto/yocto_sceneio.md b/docs/yocto/yocto_sceneio.md index 1715e943e..e5d86f6c5 100644 --- a/docs/yocto/yocto_sceneio.md +++ b/docs/yocto/yocto_sceneio.md @@ -47,7 +47,7 @@ Yocto/SceneIO supports loading and saving to a custom Json format, Obj, glTF, Pbrt, and all shape file formats. ```cpp -auto scene = scene_model{}; // scene +auto scene = scene_data{}; // scene auto error = string{}; // error buffer if(!load_scene(filename, scene, error)) // load scene print_error(error); diff --git a/docs/yocto/yocto_trace.md b/docs/yocto/yocto_trace.md index a28e8a12e..3cd2001c3 100644 --- a/docs/yocto/yocto_trace.md +++ b/docs/yocto/yocto_trace.md @@ -27,7 +27,7 @@ with `tesselate_shapes(scene, params)`, then call `trace_image(scene, camera, params)`, where `params` are the rendering options. ```cpp -auto scene = scene_model{...}; // initialize scene +auto scene = scene_data{...}; // initialize scene auto params = trace_params{}; // default params tesselate_shapes(scene, params); // tesselate shapes if needed trace_image(scene, params); // render image @@ -104,7 +104,7 @@ and retrieve the computed image with `get_render(state)` or feedback by either saving or displaying partial images. ```cpp -auto scene = scene_model{...}; // initialize scene +auto scene = scene_data{...}; // initialize scene auto params = trace_params{}; // default params tesselate_shapes(scene, params); // tesselate shapes if needed auto bvh = make_bvh(scene, params); // init bvh @@ -128,7 +128,7 @@ To denoise within Yocto/GL, the library should be compiled with OIDN support by setting the `YOCTO_DENOISE` compile flag and linking to OIDN's libraries. ```cpp -auto scene = scene_model{...}; // initialize scene +auto scene = scene_data{...}; // initialize scene auto params = trace_params{}; // default params tesselate_shapes(scene, params); // tesselate shapes if needed auto bvh = make_bvh(scene, params); // init bvh diff --git a/libs/yocto/yocto_bvh.cpp b/libs/yocto/yocto_bvh.cpp index 7c9b3deb0..f63a707f6 100644 --- a/libs/yocto/yocto_bvh.cpp +++ b/libs/yocto/yocto_bvh.cpp @@ -198,7 +198,7 @@ static void build_embree_bvh( } static void build_embree_bvh( - bvh_scene& bvh, const scene_model& scene, bool highquality) { + bvh_scene& bvh, const scene_data& scene, bool highquality) { // scene bvh auto edevice = bvh_embree_device(); bvh.embree_bvh = unique_ptr{ @@ -224,7 +224,7 @@ static void build_embree_bvh( rtcCommitScene(escene); } -static void update_embree_bvh(bvh_scene& bvh, const scene_model& scene, +static void update_embree_bvh(bvh_scene& bvh, const scene_data& scene, const vector& updated_instances) { // scene bvh auto escene = (RTCScene)bvh.embree_bvh.get(); @@ -264,7 +264,7 @@ static bool intersect_embree_bvh(const bvh_shape& bvh, const shape_data& shape, return true; } -static bool intersect_embree_bvh(const bvh_scene& bvh, const scene_model& scene, +static bool intersect_embree_bvh(const bvh_scene& bvh, const scene_data& scene, const ray3f& ray, int& instance, int& element, vec2f& uv, float& distance, bool find_any) { RTCRayHit embree_ray; @@ -672,8 +672,8 @@ static void build_bvh( build_bvh_serial(bvh.bvh, bboxes, highquality); } -static void build_bvh(bvh_scene& bvh, const scene_model& scene, - bool highquality, bool embree, bool noparallel) { +static void build_bvh(bvh_scene& bvh, const scene_data& scene, bool highquality, + bool embree, bool noparallel) { // embree #ifdef YOCTO_EMBREE if (embree) { @@ -707,7 +707,7 @@ bvh_shape make_bvh(const shape_data& shape, bool highquality, bool embree) { } bvh_scene make_bvh( - const scene_model& scene, bool highquality, bool embree, bool noparallel) { + const scene_data& scene, bool highquality, bool embree, bool noparallel) { // bvh auto bvh = bvh_scene{}; @@ -773,7 +773,7 @@ static void refit_bvh(bvh_shape& bvh, const shape_data& shape) { refit_bvh(bvh.bvh, bboxes); } -void refit_bvh(bvh_scene& bvh, const scene_model& scene, +void refit_bvh(bvh_scene& bvh, const scene_data& scene, const vector& updated_instances) { #ifdef YOCTO_EMBREE if (bvh.embree_bvh) { @@ -798,7 +798,7 @@ void update_bvh(bvh_shape& bvh, const shape_data& shape) { refit_bvh(bvh, shape); } -void update_bvh(bvh_scene& bvh, const scene_model& scene, +void update_bvh(bvh_scene& bvh, const scene_data& scene, const vector& updated_instances, const vector& updated_shapes) { // update shapes for (auto shape : updated_shapes) { @@ -918,7 +918,7 @@ static bool intersect_bvh(const bvh_shape& bvh, const shape_data& shape, } // Intersect ray with a bvh. -static bool intersect_bvh(const bvh_scene& bvh, const scene_model& scene, +static bool intersect_bvh(const bvh_scene& bvh, const scene_data& scene, const ray3f& ray_, int& instance, int& element, vec2f& uv, float& distance, bool find_any, bool non_rigid_frames) { #ifdef YOCTO_EMBREE @@ -992,7 +992,7 @@ static bool intersect_bvh(const bvh_scene& bvh, const scene_model& scene, } // Intersect ray with a bvh. -static bool intersect_bvh(const bvh_scene& bvh, const scene_model& scene, +static bool intersect_bvh(const bvh_scene& bvh, const scene_data& scene, int instance_, const ray3f& ray, int& element, vec2f& uv, float& distance, bool find_any, bool non_rigid_frames) { auto& instance = scene.instances[instance_]; @@ -1095,7 +1095,7 @@ static bool overlap_bvh(const bvh_shape& bvh, const shape_data& shape, } // Intersect ray with a bvh. -static bool overlap_bvh(const bvh_scene& bvh, const scene_model& scene, +static bool overlap_bvh(const bvh_scene& bvh, const scene_data& scene, const vec3f& pos, float max_distance, int& instance, int& element, vec2f& uv, float& distance, bool find_any, bool non_rigid_frames) { // check if empty @@ -1208,7 +1208,7 @@ void overlap_bvh_elems(const bvh_data& bvh1, const bvh_data& bvh2, } #endif -bvh_intersection intersect_bvh(const bvh_scene& bvh, const scene_model& scene, +bvh_intersection intersect_bvh(const bvh_scene& bvh, const scene_data& scene, const ray3f& ray, bool find_any, bool non_rigid_frames) { auto intersection = bvh_intersection{}; intersection.hit = intersect_bvh(bvh, scene, ray, intersection.instance, @@ -1216,7 +1216,7 @@ bvh_intersection intersect_bvh(const bvh_scene& bvh, const scene_model& scene, non_rigid_frames); return intersection; } -bvh_intersection intersect_bvh(const bvh_scene& bvh, const scene_model& scene, +bvh_intersection intersect_bvh(const bvh_scene& bvh, const scene_data& scene, int instance, const ray3f& ray, bool find_any, bool non_rigid_frames) { auto intersection = bvh_intersection{}; intersection.hit = intersect_bvh(bvh, scene, instance, ray, @@ -1226,7 +1226,7 @@ bvh_intersection intersect_bvh(const bvh_scene& bvh, const scene_model& scene, return intersection; } -bvh_intersection overlap_bvh(const bvh_scene& bvh, const scene_model& scene, +bvh_intersection overlap_bvh(const bvh_scene& bvh, const scene_data& scene, const vec3f& pos, float max_distance, bool find_any, bool non_rigid_frames) { auto intersection = bvh_intersection{}; diff --git a/libs/yocto/yocto_bvh.h b/libs/yocto/yocto_bvh.h index 55607e074..4f69d68b9 100644 --- a/libs/yocto/yocto_bvh.h +++ b/libs/yocto/yocto_bvh.h @@ -103,12 +103,12 @@ struct bvh_scene { // Build the bvh acceleration structure. bvh_shape make_bvh( const shape_data& shape, bool highquality = false, bool embree = false); -bvh_scene make_bvh(const scene_model& scene, bool highquality = false, +bvh_scene make_bvh(const scene_data& scene, bool highquality = false, bool embree = false, bool noparallel = false); // Refit bvh data void update_bvh(bvh_shape& bvh, const shape_data& shape); -void update_bvh(bvh_scene& bvh, const scene_model& scene, +void update_bvh(bvh_scene& bvh, const scene_data& scene, const vector& updated_instances, const vector& updated_shapes); // Results of intersect_xxx and overlap_xxx functions that include hit flag, @@ -129,9 +129,9 @@ struct bvh_intersection { // the shape element index and the element barycentric coordinates. bvh_intersection intersect_bvh(const bvh_shape& bvh, const shape_data& shape, const ray3f& ray, bool find_any = false, bool non_rigid_frames = true); -bvh_intersection intersect_bvh(const bvh_scene& bvh, const scene_model& scene, +bvh_intersection intersect_bvh(const bvh_scene& bvh, const scene_data& scene, const ray3f& ray, bool find_any = false, bool non_rigid_frames = true); -bvh_intersection intersect_bvh(const bvh_scene& bvh, const scene_model& scene, +bvh_intersection intersect_bvh(const bvh_scene& bvh, const scene_data& scene, int instance, const ray3f& ray, bool find_any = false, bool non_rigid_frames = true); @@ -141,7 +141,7 @@ bvh_intersection intersect_bvh(const bvh_scene& bvh, const scene_model& scene, // index and the element barycentric coordinates. bvh_intersection overlap_bvh(const bvh_shape& bvh, const shape_data& shape, const vec3f& pos, float max_distance, bool find_any = false); -bvh_intersection overlap_bvh(const bvh_scene& bvh, const scene_model& scene, +bvh_intersection overlap_bvh(const bvh_scene& bvh, const scene_data& scene, const vec3f& pos, float max_distance, bool find_any = false, bool non_rigid_frames = true); diff --git a/libs/yocto/yocto_scene.cpp b/libs/yocto/yocto_scene.cpp index 316dddf88..7740ea573 100644 --- a/libs/yocto/yocto_scene.cpp +++ b/libs/yocto/yocto_scene.cpp @@ -162,7 +162,7 @@ vec4f eval_texture(const texture_data& texture, const vec2f& uv, bool as_linear, } // Helpers -vec4f eval_texture(const scene_model& scene, int texture, const vec2f& uv, +vec4f eval_texture(const scene_data& scene, int texture, const vec2f& uv, bool ldr_as_linear, bool no_interpolation, bool clamp_to_edge) { if (texture == invalidid) return {1, 1, 1, 1}; return eval_texture( @@ -192,7 +192,7 @@ namespace yocto { static const auto min_roughness = 0.03f * 0.03f; // Evaluate material -material_point eval_material(const scene_model& scene, +material_point eval_material(const scene_data& scene, const material_data& material, const vec2f& texcoord, const vec4f& color_shp) { // evaluate textures @@ -746,7 +746,7 @@ vector fvshape_stats(const fvshape_data& shape, bool verbose) { namespace yocto { // Eval position -vec3f eval_position(const scene_model& scene, const instance_data& instance, +vec3f eval_position(const scene_data& scene, const instance_data& instance, int element, const vec2f& uv) { auto& shape = scene.shapes[instance.shape]; if (!shape.triangles.empty()) { @@ -773,7 +773,7 @@ vec3f eval_position(const scene_model& scene, const instance_data& instance, // Shape element normal. vec3f eval_element_normal( - const scene_model& scene, const instance_data& instance, int element) { + const scene_data& scene, const instance_data& instance, int element) { auto& shape = scene.shapes[instance.shape]; if (!shape.triangles.empty()) { auto t = shape.triangles[element]; @@ -797,7 +797,7 @@ vec3f eval_element_normal( } // Eval normal -vec3f eval_normal(const scene_model& scene, const instance_data& instance, +vec3f eval_normal(const scene_data& scene, const instance_data& instance, int element, const vec2f& uv) { auto& shape = scene.shapes[instance.shape]; if (shape.normals.empty()) @@ -826,7 +826,7 @@ vec3f eval_normal(const scene_model& scene, const instance_data& instance, } // Eval texcoord -vec2f eval_texcoord(const scene_model& scene, const instance_data& instance, +vec2f eval_texcoord(const scene_data& scene, const instance_data& instance, int element, const vec2f& uv) { auto& shape = scene.shapes[instance.shape]; if (shape.texcoords.empty()) return uv; @@ -882,7 +882,7 @@ static pair eval_tangents( // Shape element normal. pair eval_element_tangents( - const scene_model& scene, const instance_data& instance, int element) { + const scene_data& scene, const instance_data& instance, int element) { auto& shape = scene.shapes[instance.shape]; if (!shape.triangles.empty() && !shape.texcoords.empty()) { auto t = shape.triangles[element]; @@ -904,7 +904,7 @@ pair eval_element_tangents( } } -vec3f eval_normalmap(const scene_model& scene, const instance_data& instance, +vec3f eval_normalmap(const scene_data& scene, const instance_data& instance, int element, const vec2f& uv) { auto& shape = scene.shapes[instance.shape]; auto& material = scene.materials[instance.material]; @@ -927,7 +927,7 @@ vec3f eval_normalmap(const scene_model& scene, const instance_data& instance, } // Eval shading normal -vec3f eval_shading_normal(const scene_model& scene, +vec3f eval_shading_normal(const scene_data& scene, const instance_data& instance, int element, const vec2f& uv, const vec3f& outgoing) { auto& shape = scene.shapes[instance.shape]; @@ -950,7 +950,7 @@ vec3f eval_shading_normal(const scene_model& scene, } // Eval color -vec4f eval_color(const scene_model& scene, const instance_data& instance, +vec4f eval_color(const scene_data& scene, const instance_data& instance, int element, const vec2f& uv) { auto& shape = scene.shapes[instance.shape]; if (shape.colors.empty()) return {1, 1, 1, 1}; @@ -973,7 +973,7 @@ vec4f eval_color(const scene_model& scene, const instance_data& instance, } // Evaluate material -material_point eval_material(const scene_model& scene, +material_point eval_material(const scene_data& scene, const instance_data& instance, int element, const vec2f& uv) { auto& material = scene.materials[instance.material]; auto texcoord = eval_texcoord(scene, instance, element, uv); @@ -1026,7 +1026,7 @@ material_point eval_material(const scene_model& scene, } // check if an instance is volumetric -bool is_volumetric(const scene_model& scene, const instance_data& instance) { +bool is_volumetric(const scene_data& scene, const instance_data& instance) { return is_volumetric(scene.materials[instance.material]); } @@ -1038,7 +1038,7 @@ bool is_volumetric(const scene_model& scene, const instance_data& instance) { namespace yocto { // Evaluate environment color. -vec3f eval_environment(const scene_model& scene, +vec3f eval_environment(const scene_data& scene, const environment_data& environment, const vec3f& direction) { auto wl = transform_direction(inverse(environment.frame), direction); auto texcoord = vec2f{ @@ -1049,7 +1049,7 @@ vec3f eval_environment(const scene_model& scene, } // Evaluate all environment color. -vec3f eval_environment(const scene_model& scene, const vec3f& direction) { +vec3f eval_environment(const scene_data& scene, const vec3f& direction) { auto emission = zero3f; for (auto& environment : scene.environments) { emission += eval_environment(scene, environment, direction); @@ -1065,7 +1065,7 @@ vec3f eval_environment(const scene_model& scene, const vec3f& direction) { namespace yocto { // Add missing cameras. -void add_camera(scene_model& scene) { +void add_camera(scene_data& scene) { scene.camera_names.emplace_back("camera"); auto& camera = scene.cameras.emplace_back(); camera.orthographic = false; @@ -1087,7 +1087,7 @@ void add_camera(scene_model& scene) { } // Add a sky environment -void add_sky(scene_model& scene, float sun_angle) { +void add_sky(scene_data& scene, float sun_angle) { scene.texture_names.emplace_back("sky"); auto& texture = scene.textures.emplace_back(); texture = image_to_texture(make_sunsky(1024, 512, sun_angle)); @@ -1098,7 +1098,7 @@ void add_sky(scene_model& scene, float sun_angle) { } // get named camera or default if camera is empty -int find_camera(const scene_model& scene, const string& name) { +int find_camera(const scene_data& scene, const string& name) { if (scene.cameras.empty()) return invalidid; if (scene.camera_names.empty()) return 0; for (auto idx = 0; idx < (int)scene.camera_names.size(); idx++) { @@ -1120,9 +1120,9 @@ int find_camera(const scene_model& scene, const string& name) { } // create a scene from a shape -scene_model make_shape_scene(const shape_data& shape, bool addsky) { +scene_data make_shape_scene(const shape_data& shape, bool addsky) { // scene - auto scene = scene_model{}; + auto scene = scene_data{}; // shape scene.shape_names.emplace_back("shape"); scene.shapes.push_back(shape); @@ -1146,7 +1146,7 @@ scene_model make_shape_scene(const shape_data& shape, bool addsky) { } // Updates the scene and scene's instances bounding boxes -bbox3f compute_bounds(const scene_model& scene) { +bbox3f compute_bounds(const scene_data& scene) { auto shape_bbox = vector{}; auto bbox = invalidb3f; for (auto& shape : scene.shapes) { @@ -1168,7 +1168,7 @@ bbox3f compute_bounds(const scene_model& scene) { namespace yocto { void tesselate_subdiv( - shape_data& shape, subdiv_data& subdiv_, const scene_model& scene) { + shape_data& shape, subdiv_data& subdiv_, const scene_data& scene) { auto subdiv = subdiv_; if (subdiv.subdivisions > 0) { @@ -1231,7 +1231,7 @@ void tesselate_subdiv( subdiv.positions, subdiv.normals, subdiv.texcoords); } -void tesselate_subdivs(scene_model& scene) { +void tesselate_subdivs(scene_data& scene) { // tesselate shapes for (auto& subdiv : scene.subdivs) { tesselate_subdiv(scene.shapes[subdiv.shape], subdiv, scene); @@ -1245,7 +1245,7 @@ void tesselate_subdivs(scene_model& scene) { // ----------------------------------------------------------------------------- namespace yocto { -size_t compute_memory(const scene_model& scene) { +size_t compute_memory(const scene_data& scene) { auto vector_memory = [](auto& values) -> size_t { if (values.empty()) return 0; return values.size() * sizeof(values[0]); @@ -1290,7 +1290,7 @@ size_t compute_memory(const scene_model& scene) { return memory; } -vector scene_stats(const scene_model& scene, bool verbose) { +vector scene_stats(const scene_data& scene, bool verbose) { auto accumulate = [](const auto& values, const auto& func) -> size_t { auto sum = (size_t)0; for (auto& value : values) sum += func(value); @@ -1352,7 +1352,7 @@ vector scene_stats(const scene_model& scene, bool verbose) { } // Checks for validity of the scene. -vector scene_validation(const scene_model& scene, bool notextures) { +vector scene_validation(const scene_data& scene, bool notextures) { auto errs = vector(); auto check_names = [&errs](const vector& names, const string& base) { auto used = unordered_map(); @@ -1366,7 +1366,7 @@ vector scene_validation(const scene_model& scene, bool notextures) { } } }; - auto check_empty_textures = [&errs](const scene_model& scene) { + auto check_empty_textures = [&errs](const scene_data& scene) { for (auto idx = 0; idx < (int)scene.textures.size(); idx++) { auto& texture = scene.textures[idx]; if (texture.pixelsf.empty() && texture.pixelsb.empty()) { @@ -1723,7 +1723,7 @@ shape_data lines_to_cylinders(const vector& lines, // ----------------------------------------------------------------------------- namespace yocto { -void make_cornellbox(scene_model& scene) { +void make_cornellbox(scene_data& scene) { auto& camera = scene.cameras.emplace_back(); camera.frame = frame3f{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}, {0, 1, 3.9f}}; camera.lens = 0.035f; diff --git a/libs/yocto/yocto_scene.h b/libs/yocto/yocto_scene.h index 5ae5a8125..2d55fa6dd 100644 --- a/libs/yocto/yocto_scene.h +++ b/libs/yocto/yocto_scene.h @@ -217,7 +217,7 @@ struct subdiv_data { // environment. In that case, the element transforms are computed from // the hierarchy. Animation is also optional, with keyframe data that // updates node transformations only if defined. -struct scene_model { +struct scene_data { // scene elements vector cameras = {}; vector instances = {}; @@ -262,7 +262,7 @@ namespace yocto { vec4f eval_texture(const texture_data& texture, const vec2f& uv, bool as_linear = false, bool no_interpolation = false, bool clamp_to_edge = false); -vec4f eval_texture(const scene_model& scene, int texture, const vec2f& uv, +vec4f eval_texture(const scene_data& scene, int texture, const vec2f& uv, bool as_linear = false, bool no_interpolation = false, bool clamp_to_edge = false); @@ -296,7 +296,7 @@ struct material_point { }; // Eval material to obtain emission, brdf and opacity. -material_point eval_material(const scene_model& scene, +material_point eval_material(const scene_data& scene, const material_data& material, const vec2f& texcoord, const vec4f& shape_color = {1, 1, 1, 1}); @@ -307,7 +307,7 @@ bool is_delta(const material_point& material); // check if a material has a volume bool is_volumetric(const material_data& material); bool is_volumetric(const material_point& material); -bool is_volumetric(const scene_model& scene, const instance_data& instance); +bool is_volumetric(const scene_data& scene, const instance_data& instance); } // namespace yocto @@ -386,29 +386,29 @@ vector fvshape_stats(const fvshape_data& shape, bool verbose = false); namespace yocto { // Evaluate instance properties -vec3f eval_position(const scene_model& scene, const instance_data& instance, +vec3f eval_position(const scene_data& scene, const instance_data& instance, int element, const vec2f& uv); vec3f eval_element_normal( - const scene_model& scene, const instance_data& instance, int element); -vec3f eval_normal(const scene_model& scene, const instance_data& instance, + const scene_data& scene, const instance_data& instance, int element); +vec3f eval_normal(const scene_data& scene, const instance_data& instance, int element, const vec2f& uv); -vec2f eval_texcoord(const scene_model& scene, const instance_data& instance, +vec2f eval_texcoord(const scene_data& scene, const instance_data& instance, int element, const vec2f& uv); pair eval_element_tangents( - const scene_model& scene, const instance_data& instance, int element); -vec3f eval_normalmap(const scene_model& scene, const instance_data& instance, + const scene_data& scene, const instance_data& instance, int element); +vec3f eval_normalmap(const scene_data& scene, const instance_data& instance, int element, const vec2f& uv); -vec3f eval_shading_normal(const scene_model& scene, +vec3f eval_shading_normal(const scene_data& scene, const instance_data& instance, int element, const vec2f& uv, const vec3f& outgoing); -vec4f eval_color(const scene_model& scene, const instance_data& instance, +vec4f eval_color(const scene_data& scene, const instance_data& instance, int element, const vec2f& uv); // Eval material to obtain emission, brdf and opacity. -material_point eval_material(const scene_model& scene, +material_point eval_material(const scene_data& scene, const instance_data& instance, int element, const vec2f& uv); // check if a material has a volume -bool is_volumetric(const scene_model& scene, const instance_data& instance); +bool is_volumetric(const scene_data& scene, const instance_data& instance); } // namespace yocto @@ -418,9 +418,9 @@ bool is_volumetric(const scene_model& scene, const instance_data& instance); namespace yocto { // Environment -vec3f eval_environment(const scene_model& scene, +vec3f eval_environment(const scene_data& scene, const environment_data& environment, const vec3f& direction); -vec3f eval_environment(const scene_model& scene, const vec3f& direction); +vec3f eval_environment(const scene_data& scene, const vec3f& direction); } // namespace yocto @@ -430,23 +430,23 @@ vec3f eval_environment(const scene_model& scene, const vec3f& direction); namespace yocto { // compute scene bounds -bbox3f compute_bounds(const scene_model& scene); +bbox3f compute_bounds(const scene_data& scene); // add missing elements -void add_camera(scene_model& scene); -void add_sky(scene_model& scene, float sun_angle = pif / 4); +void add_camera(scene_data& scene); +void add_sky(scene_data& scene, float sun_angle = pif / 4); // get named camera or default if name is empty -int find_camera(const scene_model& scene, const string& name); +int find_camera(const scene_data& scene, const string& name); // create a scene from a shape -scene_model make_shape_scene(const shape_data& shape, bool add_sky = false); +scene_data make_shape_scene(const shape_data& shape, bool add_sky = false); // Return scene statistics as list of strings. -vector scene_stats(const scene_model& scene, bool verbose = false); +vector scene_stats(const scene_data& scene, bool verbose = false); // Return validation errors as list of strings. vector scene_validation( - const scene_model& scene, bool notextures = false); + const scene_data& scene, bool notextures = false); } // namespace yocto @@ -456,7 +456,7 @@ vector scene_validation( namespace yocto { // Apply subdivision and displacement rules. -void tesselate_subdivs(scene_model& scene); +void tesselate_subdivs(scene_data& scene); } // namespace yocto @@ -589,7 +589,7 @@ shape_data make_heightfield(const vec2i& size, const vector& color); namespace yocto { // Make Cornell Box scene -void make_cornellbox(scene_model& scene); +void make_cornellbox(scene_data& scene); } // namespace yocto @@ -598,7 +598,8 @@ void make_cornellbox(scene_model& scene); // ----------------------------------------------------------------------------- namespace yocto { -using sceneio_scene = scene_model; +using sceneio_scene = scene_data; +using scene_model = scene_data; using sceneio_camera = camera_data; using scene_camera = camera_data; using sceneio_texture = texture_data; diff --git a/libs/yocto/yocto_sceneio.cpp b/libs/yocto/yocto_sceneio.cpp index 85188b7d4..8c024dbc2 100644 --- a/libs/yocto/yocto_sceneio.cpp +++ b/libs/yocto/yocto_sceneio.cpp @@ -1706,80 +1706,80 @@ namespace yocto { // get name [[maybe_unused]] static string get_camera_name( - const scene_model& scene, int idx) { + const scene_data& scene, int idx) { if (scene.camera_names.empty()) return get_element_name("camera", idx, scene.cameras.size()); return scene.camera_names[idx]; } [[maybe_unused]] static string get_environment_name( - const scene_model& scene, int idx) { + const scene_data& scene, int idx) { if (scene.environment_names.empty()) return get_element_name("environment", idx, scene.environments.size()); return scene.environment_names[idx]; } [[maybe_unused]] static string get_shape_name( - const scene_model& scene, int idx) { + const scene_data& scene, int idx) { if (scene.shape_names.empty()) return get_element_name("shape", idx, scene.shapes.size()); return scene.shape_names[idx]; } [[maybe_unused]] static string get_texture_name( - const scene_model& scene, int idx) { + const scene_data& scene, int idx) { if (scene.texture_names.empty()) return get_element_name("texture", idx, scene.textures.size()); return scene.texture_names[idx]; } [[maybe_unused]] static string get_instance_name( - const scene_model& scene, int idx) { + const scene_data& scene, int idx) { if (scene.instance_names.empty()) return get_element_name("instance", idx, scene.instances.size()); return scene.instance_names[idx]; } [[maybe_unused]] static string get_material_name( - const scene_model& scene, int idx) { + const scene_data& scene, int idx) { if (scene.material_names.empty()) return get_element_name("material", idx, scene.materials.size()); return scene.material_names[idx]; } [[maybe_unused]] static string get_subdiv_name( - const scene_model& scene, int idx) { + const scene_data& scene, int idx) { if (scene.subdiv_names.empty()) return get_element_name("subdiv", idx, scene.subdivs.size()); return scene.subdiv_names[idx]; } [[maybe_unused]] static string get_camera_name( - const scene_model& scene, const camera_data& camera) { + const scene_data& scene, const camera_data& camera) { return get_camera_name(scene, (int)(&camera - scene.cameras.data())); } [[maybe_unused]] static string get_environment_name( - const scene_model& scene, const environment_data& environment) { + const scene_data& scene, const environment_data& environment) { return get_environment_name( scene, (int)(&environment - scene.environments.data())); } [[maybe_unused]] static string get_shape_name( - const scene_model& scene, const shape_data& shape) { + const scene_data& scene, const shape_data& shape) { return get_shape_name(scene, (int)(&shape - scene.shapes.data())); } [[maybe_unused]] static string get_texture_name( - const scene_model& scene, const texture_data& texture) { + const scene_data& scene, const texture_data& texture) { return get_texture_name(scene, (int)(&texture - scene.textures.data())); } [[maybe_unused]] static string get_instance_name( - const scene_model& scene, const instance_data& instance) { + const scene_data& scene, const instance_data& instance) { return get_instance_name(scene, (int)(&instance - scene.instances.data())); } [[maybe_unused]] static string get_material_name( - const scene_model& scene, const material_data& material) { + const scene_data& scene, const material_data& material) { return get_material_name(scene, (int)(&material - scene.materials.data())); } [[maybe_unused]] static string get_subdiv_name( - const scene_model& scene, const subdiv_data& subdiv) { + const scene_data& scene, const subdiv_data& subdiv) { return get_subdiv_name(scene, (int)(&subdiv - scene.subdivs.data())); } // Add missing cameras. -void add_missing_camera(scene_model& scene) { +void add_missing_camera(scene_data& scene) { if (!scene.cameras.empty()) return; scene.camera_names.emplace_back("camera"); auto& camera = scene.cameras.emplace_back(); @@ -1802,7 +1802,7 @@ void add_missing_camera(scene_model& scene) { } // Add missing radius. -static void add_missing_radius(scene_model& scene, float radius = 0.001f) { +static void add_missing_radius(scene_data& scene, float radius = 0.001f) { for (auto& shape : scene.shapes) { if (shape.points.empty() && shape.lines.empty()) continue; if (!shape.radius.empty()) continue; @@ -1811,7 +1811,7 @@ static void add_missing_radius(scene_model& scene, float radius = 0.001f) { } // Add missing cameras. -void add_missing_material(scene_model& scene) { +void add_missing_material(scene_data& scene) { auto default_material = invalidid; for (auto& instance : scene.instances) { if (instance.material >= 0) continue; @@ -1825,7 +1825,7 @@ void add_missing_material(scene_model& scene) { } // Reduce memory usage -static void trim_memory(scene_model& scene) { +static void trim_memory(scene_data& scene) { for (auto& shape : scene.shapes) { shape.points.shrink_to_fit(); shape.lines.shrink_to_fit(); @@ -1895,7 +1895,7 @@ struct test_params { }; // Scene test -void make_test(scene_model& scene, const test_params& params) { +void make_test(scene_data& scene, const test_params& params) { return; // // cameras // switch (params.cameras) { @@ -2194,7 +2194,7 @@ void make_test(scene_model& scene, const test_params& params) { } // Scene presets used for testing. -bool make_scene_preset(scene_model& scene, const string& type, string& error) { +bool make_scene_preset(scene_data& scene, const string& type, string& error) { if (type == "cornellbox") { make_cornellbox(scene); return true; @@ -2302,49 +2302,49 @@ namespace yocto { // Load/save a scene in the builtin JSON format. static bool load_json_scene( - const string& filename, scene_model& scene, string& error, bool noparallel); -static bool save_json_scene(const string& filename, const scene_model& scene, + const string& filename, scene_data& scene, string& error, bool noparallel); +static bool save_json_scene(const string& filename, const scene_data& scene, string& error, bool noparallel); // Load/save a scene from/to OBJ. static bool load_obj_scene( - const string& filename, scene_model& scene, string& error, bool noparallel); -static bool save_obj_scene(const string& filename, const scene_model& scene, + const string& filename, scene_data& scene, string& error, bool noparallel); +static bool save_obj_scene(const string& filename, const scene_data& scene, string& error, bool noparallel); // Load/save a scene from/to PLY. Loads/saves only one mesh with no other data. static bool load_ply_scene( - const string& filename, scene_model& scene, string& error, bool noparallel); -static bool save_ply_scene(const string& filename, const scene_model& scene, + const string& filename, scene_data& scene, string& error, bool noparallel); +static bool save_ply_scene(const string& filename, const scene_data& scene, string& error, bool noparallel); // Load/save a scene from/to STL. Loads/saves only one mesh with no other data. static bool load_stl_scene( - const string& filename, scene_model& scene, string& error, bool noparallel); -static bool save_stl_scene(const string& filename, const scene_model& scene, + const string& filename, scene_data& scene, string& error, bool noparallel); +static bool save_stl_scene(const string& filename, const scene_data& scene, string& error, bool noparallel); // Load/save a scene from/to glTF. static bool load_gltf_scene( - const string& filename, scene_model& scene, string& error, bool noparallel); -static bool save_gltf_scene(const string& filename, const scene_model& scene, + const string& filename, scene_data& scene, string& error, bool noparallel); +static bool save_gltf_scene(const string& filename, const scene_data& scene, string& error, bool noparallel); // Load/save a scene from/to pbrt-> This is not robust at all and only // works on scene that have been previously adapted since the two renderers // are too different to match. static bool load_pbrt_scene( - const string& filename, scene_model& scene, string& error, bool noparallel); -static bool save_pbrt_scene(const string& filename, const scene_model& scene, + const string& filename, scene_data& scene, string& error, bool noparallel); +static bool save_pbrt_scene(const string& filename, const scene_data& scene, string& error, bool noparallel); // Load/save a scene preset. static bool load_preset_scene( - const string& filename, scene_model& scene, string& error, bool noparallel); + const string& filename, scene_data& scene, string& error, bool noparallel); // Load a scene -bool load_scene(const string& filename, scene_model& scene, string& error, - bool noparallel) { +bool load_scene( + const string& filename, scene_data& scene, string& error, bool noparallel) { auto format_error = [filename, &error]() { error = filename + ": unknown format"; return false; @@ -2371,7 +2371,7 @@ bool load_scene(const string& filename, scene_model& scene, string& error, } // Save a scene -bool save_scene(const string& filename, const scene_model& scene, string& error, +bool save_scene(const string& filename, const scene_data& scene, string& error, bool noparallel) { auto format_error = [filename, &error]() { error = filename + ": unknown format"; @@ -2397,8 +2397,8 @@ bool save_scene(const string& filename, const scene_model& scene, string& error, } // Load/save a scene preset. -static bool load_preset_scene(const string& filename, scene_model& scene, - string& error, bool noparallel) { +static bool load_preset_scene( + const string& filename, scene_data& scene, string& error, bool noparallel) { auto preset_error = [filename, &error]() { error = filename + ": " + error; return false; @@ -2414,7 +2414,7 @@ static bool load_preset_scene(const string& filename, scene_model& scene, // Make missing scene directories bool make_scene_directories( - const string& filename, const scene_model& scene, string& error) { + const string& filename, const scene_data& scene, string& error) { // make a directory if needed if (!make_directory(path_dirname(filename), error)) return false; if (!scene.shapes.empty()) { @@ -2429,8 +2429,7 @@ bool make_scene_directories( } // Add environment -bool add_environment( - scene_model& scene, const string& filename, string& error) { +bool add_environment(scene_data& scene, const string& filename, string& error) { // load texture auto& texture = scene.textures.emplace_back(); if (!load_texture(filename, texture, error)) return false; @@ -2635,8 +2634,8 @@ inline void from_json(const njson& j, material_type& value) { namespace yocto { // Load a scene in the builtin JSON format. -static bool load_json_scene(const string& filename, scene_model& scene, - string& error, bool noparallel) { +static bool load_json_scene( + const string& filename, scene_data& scene, string& error, bool noparallel) { auto json_error = [filename]() { // error does not need setting return false; @@ -2770,7 +2769,7 @@ static bool load_json_scene(const string& filename, scene_model& scene, return true; }; auto get_ply_instance_name = [&ply_instances, &ply_instances_names]( - const scene_model& scene, + const scene_data& scene, const ply_instance& instance) -> string { return ply_instances_names[&instance - ply_instances.data()]; }; @@ -3148,7 +3147,7 @@ static bool load_json_scene(const string& filename, scene_model& scene, } // Save a scene in the builtin JSON format. -static bool save_json_scene(const string& filename, const scene_model& scene, +static bool save_json_scene(const string& filename, const scene_data& scene, string& error, bool noparallel) { auto conversion_error = [filename, &error](const string& message) { // should never happen @@ -3425,8 +3424,8 @@ static bool save_json_scene(const string& filename, const scene_model& scene, namespace yocto { // Loads an OBJ -static bool load_obj_scene(const string& filename, scene_model& scene, - string& error, bool noparallel) { +static bool load_obj_scene( + const string& filename, scene_data& scene, string& error, bool noparallel) { auto shape_error = [filename, &error]() { error = filename + ": empty shape"; return false; @@ -3564,7 +3563,7 @@ static bool load_obj_scene(const string& filename, scene_model& scene, return true; } -static bool save_obj_scene(const string& filename, const scene_model& scene, +static bool save_obj_scene(const string& filename, const scene_data& scene, string& error, bool noparallel) { auto shape_error = [filename, &error]() { error = filename + ": empty shape"; @@ -3696,8 +3695,8 @@ static bool save_obj_scene(const string& filename, const scene_model& scene, // ----------------------------------------------------------------------------- namespace yocto { -static bool load_ply_scene(const string& filename, scene_model& scene, - string& error, bool noparallel) { +static bool load_ply_scene( + const string& filename, scene_data& scene, string& error, bool noparallel) { // load ply mesh auto& shape = scene.shapes.emplace_back(); if (!load_shape(filename, shape, error, true)) return false; @@ -3715,7 +3714,7 @@ static bool load_ply_scene(const string& filename, scene_model& scene, return true; } -static bool save_ply_scene(const string& filename, const scene_model& scene, +static bool save_ply_scene(const string& filename, const scene_data& scene, string& error, bool noparallel) { auto shape_error = [filename, &error]() { error = filename + ": empty shape"; @@ -3739,8 +3738,8 @@ static bool save_ply_scene(const string& filename, const scene_model& scene, // ----------------------------------------------------------------------------- namespace yocto { -static bool load_stl_scene(const string& filename, scene_model& scene, - string& error, bool noparallel) { +static bool load_stl_scene( + const string& filename, scene_data& scene, string& error, bool noparallel) { // load stl mesh auto& shape = scene.shapes.emplace_back(); if (!load_shape(filename, shape, error, true)) return false; @@ -3758,7 +3757,7 @@ static bool load_stl_scene(const string& filename, scene_model& scene, return true; } -static bool save_stl_scene(const string& filename, const scene_model& scene, +static bool save_stl_scene(const string& filename, const scene_data& scene, string& error, bool noparallel) { auto shape_error = [filename, &error]() { error = filename + ": empty shape"; @@ -3783,8 +3782,8 @@ static bool save_stl_scene(const string& filename, const scene_model& scene, namespace yocto { // Load a scene -static bool load_gltf_scene(const string& filename, scene_model& scene, - string& error, bool noparallel) { +static bool load_gltf_scene( + const string& filename, scene_data& scene, string& error, bool noparallel) { auto read_error = [filename, &error]() { error = filename + ": read error"; return false; @@ -4287,7 +4286,7 @@ static bool load_gltf_scene(const string& filename, scene_model& scene, } // Load a scene -static bool save_gltf_scene(const string& filename, const scene_model& scene, +static bool save_gltf_scene(const string& filename, const scene_data& scene, string& error, bool noparallel) { auto write_error = [filename, &error]() { error = filename + ": write error"; @@ -4664,8 +4663,8 @@ static bool save_gltf_scene(const string& filename, const scene_model& scene, namespace yocto { // load pbrt scenes -static bool load_pbrt_scene(const string& filename, scene_model& scene, - string& error, bool noparallel) { +static bool load_pbrt_scene( + const string& filename, scene_data& scene, string& error, bool noparallel) { auto dependent_error = [filename, &error]() { error = filename + ": error in " + error; return false; @@ -4827,7 +4826,7 @@ static bool load_pbrt_scene(const string& filename, scene_model& scene, } // Save a pbrt scene -static bool save_pbrt_scene(const string& filename, const scene_model& scene, +static bool save_pbrt_scene(const string& filename, const scene_data& scene, string& error, bool noparallel) { auto dependent_error = [filename, &error]() { error = filename + ": error in " + error; diff --git a/libs/yocto/yocto_sceneio.h b/libs/yocto/yocto_sceneio.h index ad2ae50a3..0e2719612 100644 --- a/libs/yocto/yocto_sceneio.h +++ b/libs/yocto/yocto_sceneio.h @@ -153,20 +153,20 @@ namespace yocto { // Load/save a scene in the supported formats. // Calls the progress callback, if defined, as we process more data. -bool load_scene(const string& filename, scene_model& scene, string& error, +bool load_scene(const string& filename, scene_data& scene, string& error, bool noparallel = false); -bool save_scene(const string& filename, const scene_model& scene, string& error, +bool save_scene(const string& filename, const scene_data& scene, string& error, bool noparallel = false); // Make missing scene directories bool make_scene_directories( - const string& filename, const scene_model& scene, string& error); + const string& filename, const scene_data& scene, string& error); // Scene presets used for testing. -bool make_scene_preset(scene_model& scene, const string& type, string& error); +bool make_scene_preset(scene_data& scene, const string& type, string& error); // Add environment -bool add_environment(scene_model& scene, const string& filename, string& error); +bool add_environment(scene_data& scene, const string& filename, string& error); } // namespace yocto diff --git a/libs/yocto/yocto_trace.cpp b/libs/yocto/yocto_trace.cpp index 7038fff2c..5ee722f61 100644 --- a/libs/yocto/yocto_trace.cpp +++ b/libs/yocto/yocto_trace.cpp @@ -51,7 +51,7 @@ namespace yocto { // Build the bvh acceleration structure. -bvh_scene make_bvh(const scene_model& scene, const trace_params& params) { +bvh_scene make_bvh(const scene_data& scene, const trace_params& params) { return make_bvh( scene, params.highqualitybvh, params.embreebvh, params.noparallel); } @@ -259,7 +259,7 @@ static ray3f sample_camera(const camera_data& camera, const vec2i& ij, } // Sample lights wrt solid angle -static vec3f sample_lights(const scene_model& scene, const trace_lights& lights, +static vec3f sample_lights(const scene_data& scene, const trace_lights& lights, const vec3f& position, float rl, float rel, const vec2f& ruv) { auto light_id = sample_uniform((int)lights.lights.size(), rl); auto& light = lights.lights[light_id]; @@ -289,7 +289,7 @@ static vec3f sample_lights(const scene_model& scene, const trace_lights& lights, } // Sample lights pdf -static float sample_lights_pdf(const scene_model& scene, const bvh_scene& bvh, +static float sample_lights_pdf(const scene_data& scene, const bvh_scene& bvh, const trace_lights& lights, const vec3f& position, const vec3f& direction) { auto pdf = 0.0f; for (auto& light : lights.lights) { @@ -351,7 +351,7 @@ struct trace_result { }; // Recursive path tracing. -static trace_result trace_path(const scene_model& scene, const bvh_scene& bvh, +static trace_result trace_path(const scene_data& scene, const bvh_scene& bvh, const trace_lights& lights, const ray3f& ray_, rng_state& rng, const trace_params& params) { // initialize @@ -498,7 +498,7 @@ static trace_result trace_path(const scene_model& scene, const bvh_scene& bvh, } // Recursive path tracing. -static trace_result trace_pathdirect(const scene_model& scene, +static trace_result trace_pathdirect(const scene_data& scene, const bvh_scene& bvh, const trace_lights& lights, const ray3f& ray_, rng_state& rng, const trace_params& params) { // initialize @@ -669,9 +669,9 @@ static trace_result trace_pathdirect(const scene_model& scene, } // Recursive path tracing with MIS. -static trace_result trace_pathmis(const scene_model& scene, - const bvh_scene& bvh, const trace_lights& lights, const ray3f& ray_, - rng_state& rng, const trace_params& params) { +static trace_result trace_pathmis(const scene_data& scene, const bvh_scene& bvh, + const trace_lights& lights, const ray3f& ray_, rng_state& rng, + const trace_params& params) { // initialize auto radiance = zero3f; auto weight = vec3f{1, 1, 1}; @@ -853,7 +853,7 @@ static trace_result trace_pathmis(const scene_model& scene, } // Recursive path tracing. -static trace_result trace_naive(const scene_model& scene, const bvh_scene& bvh, +static trace_result trace_naive(const scene_data& scene, const bvh_scene& bvh, const trace_lights& lights, const ray3f& ray_, rng_state& rng, const trace_params& params) { // initialize @@ -933,7 +933,7 @@ static trace_result trace_naive(const scene_model& scene, const bvh_scene& bvh, } // Eyelight for quick previewing. -static trace_result trace_eyelight(const scene_model& scene, +static trace_result trace_eyelight(const scene_data& scene, const bvh_scene& bvh, const trace_lights& lights, const ray3f& ray_, rng_state& rng, const trace_params& params) { // initialize @@ -1002,7 +1002,7 @@ static trace_result trace_eyelight(const scene_model& scene, } // Eyelight with ambient occlusion for quick previewing. -static trace_result trace_eyelightao(const scene_model& scene, +static trace_result trace_eyelightao(const scene_data& scene, const bvh_scene& bvh, const trace_lights& lights, const ray3f& ray_, rng_state& rng, const trace_params& params) { // initialize @@ -1075,7 +1075,7 @@ static trace_result trace_eyelightao(const scene_model& scene, } // False color rendering -static trace_result trace_falsecolor(const scene_model& scene, +static trace_result trace_falsecolor(const scene_data& scene, const bvh_scene& bvh, const trace_lights& lights, const ray3f& ray, rng_state& rng, const trace_params& params) { // intersect next point @@ -1158,7 +1158,7 @@ static trace_result trace_falsecolor(const scene_model& scene, } // Trace a single ray from the camera using the given algorithm. -using sampler_func = trace_result (*)(const scene_model& scene, +using sampler_func = trace_result (*)(const scene_data& scene, const bvh_scene& bvh, const trace_lights& lights, const ray3f& ray, rng_state& rng, const trace_params& params); static sampler_func get_trace_sampler_func(const trace_params& params) { @@ -1194,7 +1194,7 @@ bool is_sampler_lit(const trace_params& params) { } // Trace a block of samples -void trace_sample(trace_state& state, const scene_model& scene, +void trace_sample(trace_state& state, const scene_data& scene, const bvh_scene& bvh, const trace_lights& lights, int i, int j, const trace_params& params) { auto& camera = scene.cameras[params.camera]; @@ -1221,7 +1221,7 @@ void trace_sample(trace_state& state, const scene_model& scene, } // Init a sequence of random number generators. -trace_state make_state(const scene_model& scene, const trace_params& params) { +trace_state make_state(const scene_data& scene, const trace_params& params) { auto& camera = scene.cameras[params.camera]; auto state = trace_state{}; if (camera.aspect >= 1) { @@ -1250,7 +1250,7 @@ static trace_light& add_light(trace_lights& lights) { } // Init trace lights -trace_lights make_lights(const scene_model& scene, const trace_params& params) { +trace_lights make_lights(const scene_data& scene, const trace_params& params) { auto lights = trace_lights{}; for (auto handle = 0; handle < scene.instances.size(); handle++) { @@ -1305,7 +1305,7 @@ trace_lights make_lights(const scene_model& scene, const trace_params& params) { } // Progressively computes an image. -color_image trace_image(const scene_model& scene, const trace_params& params) { +color_image trace_image(const scene_data& scene, const trace_params& params) { auto bvh = make_bvh(scene, params); auto lights = make_lights(scene, params); auto state = make_state(scene, params); @@ -1316,7 +1316,7 @@ color_image trace_image(const scene_model& scene, const trace_params& params) { } // Progressively compute an image by calling trace_samples multiple times. -void trace_samples(trace_state& state, const scene_model& scene, +void trace_samples(trace_state& state, const scene_data& scene, const bvh_scene& bvh, const trace_lights& lights, const trace_params& params) { if (state.samples >= params.samples) return; diff --git a/libs/yocto/yocto_trace.h b/libs/yocto/yocto_trace.h index ae2348214..8440a384b 100644 --- a/libs/yocto/yocto_trace.h +++ b/libs/yocto/yocto_trace.h @@ -127,7 +127,7 @@ inline const auto trace_falsecolor_names = vector{"position", "normal", using image_callback = function; // Progressively computes an image. -color_image trace_image(const scene_model& scene, const trace_params& params); +color_image trace_image(const scene_data& scene, const trace_params& params); } // namespace yocto @@ -164,19 +164,19 @@ struct trace_state { }; // Initialize state. -trace_state make_state(const scene_model& scene, const trace_params& params); +trace_state make_state(const scene_data& scene, const trace_params& params); // Initialize lights. -trace_lights make_lights(const scene_model& scene, const trace_params& params); +trace_lights make_lights(const scene_data& scene, const trace_params& params); // Build the bvh acceleration structure. -bvh_scene make_bvh(const scene_model& scene, const trace_params& params); +bvh_scene make_bvh(const scene_data& scene, const trace_params& params); // Progressively computes an image. -void trace_samples(trace_state& state, const scene_model& scene, +void trace_samples(trace_state& state, const scene_data& scene, const bvh_scene& bvh, const trace_lights& lights, const trace_params& params); -void trace_sample(trace_state& state, const scene_model& scene, +void trace_sample(trace_state& state, const scene_data& scene, const bvh_scene& bvh, const trace_lights& lights, int i, int j, const trace_params& params); diff --git a/libs/yocto_gui/yocto_glview.cpp b/libs/yocto_gui/yocto_glview.cpp index 50798925d..abb65ae37 100644 --- a/libs/yocto_gui/yocto_glview.cpp +++ b/libs/yocto_gui/yocto_glview.cpp @@ -152,7 +152,7 @@ struct scene_selection { int subdiv = 0; }; -static bool draw_scene_editor(scene_model& scene, scene_selection& selection, +static bool draw_scene_editor(scene_data& scene, scene_selection& selection, const function& before_edit) { auto edited = 0; if (begin_glheader("cameras")) { @@ -433,7 +433,7 @@ void colorgrade_image( } // Open a window and show an scene via path tracing -void view_scene(const string& title, const string& name, scene_model& scene, +void view_scene(const string& title, const string& name, scene_data& scene, const trace_params& params_, bool print, bool edit) { // copy params and camera auto params = params_; @@ -641,7 +641,7 @@ void view_scene(const string& title, const string& name, scene_model& scene, stop_render(); } -void glview_scene(const string& title, const string& name, scene_model& scene, +void glview_scene(const string& title, const string& name, scene_data& scene, const glscene_params& params_, const glview_callback& widgets_callback, const glview_callback& uiupdate_callback, const glview_callback& update_callback) { @@ -1409,7 +1409,7 @@ void clear_shape(glscene_shape& glshape) { } // init scene -void init_glscene(glscene_state& glscene, const scene_model& ioscene) { +void init_glscene(glscene_state& glscene, const scene_data& ioscene) { // program set_program(glscene.program, glscene.vertex, glscene.fragment, glscene_vertex, glscene_fragment); @@ -1428,7 +1428,7 @@ void init_glscene(glscene_state& glscene, const scene_model& ioscene) { } // update scene -void update_glscene(glscene_state& glscene, const scene_model& scene, +void update_glscene(glscene_state& glscene, const scene_data& scene, const vector& updated_shapes, const vector& updated_textures) { for (auto shape_id : updated_shapes) { set_shape(glscene.shapes[shape_id], scene.shapes[shape_id]); @@ -1478,7 +1478,7 @@ void clear_scene(glscene_state& glscene) { assert_glerror(); } -void draw_scene(glscene_state& glscene, const scene_model& scene, +void draw_scene(glscene_state& glscene, const scene_data& scene, const vec4i& viewport, const glscene_params& params) { // check errors assert_glerror(); diff --git a/libs/yocto_gui/yocto_glview.h b/libs/yocto_gui/yocto_glview.h index 65e933ea5..e88b06f30 100644 --- a/libs/yocto_gui/yocto_glview.h +++ b/libs/yocto_gui/yocto_glview.h @@ -72,7 +72,7 @@ void colorgrade_image( const string& title, const string& name, const color_image& image); // Open a window and show an scene via path tracing -void view_scene(const string& title, const string& name, scene_model& scene, +void view_scene(const string& title, const string& name, scene_data& scene, const trace_params& params = {}, bool print = true, bool edit = false); // GUI callback @@ -82,7 +82,7 @@ using glview_callback = std::function& updated_shapes, const vector& updated_textures); // Clear an OpenGL scene void clear_scene(glscene_state& scene); // draw scene -void draw_scene(glscene_state& glscene, const scene_model& scene, +void draw_scene(glscene_state& glscene, const scene_data& scene, const vec4i& viewport, const glscene_params& params); } // namespace yocto From ea4e65e1a774bdd67a6a8197fcab339d5b107958 Mon Sep 17 00:00:00 2001 From: Fabio Pellacini Date: Wed, 9 Jun 2021 15:38:34 +0200 Subject: [PATCH 09/12] updated --- apps/yimage/yimage.cpp | 10 +-- apps/yshape/yshape.cpp | 2 +- docs/yocto/yocto_image.md | 2 +- docs/yocto/yocto_sceneio.md | 2 +- libs/yocto/yocto_image.cpp | 103 ++++++++++++++--------------- libs/yocto/yocto_image.h | 113 +++++++++++++++++--------------- libs/yocto/yocto_scene.cpp | 2 +- libs/yocto/yocto_scene.h | 2 +- libs/yocto/yocto_sceneio.cpp | 16 ++--- libs/yocto/yocto_sceneio.h | 6 +- libs/yocto/yocto_trace.cpp | 28 ++++---- libs/yocto/yocto_trace.h | 26 ++++---- libs/yocto_gui/yocto_glview.cpp | 14 ++-- libs/yocto_gui/yocto_glview.h | 8 +-- libs/yocto_gui/yocto_opengl.cpp | 2 +- libs/yocto_gui/yocto_opengl.h | 2 +- 16 files changed, 173 insertions(+), 165 deletions(-) diff --git a/apps/yimage/yimage.cpp b/apps/yimage/yimage.cpp index f098f334b..a3e2e3fa2 100644 --- a/apps/yimage/yimage.cpp +++ b/apps/yimage/yimage.cpp @@ -63,7 +63,7 @@ void add_command(const cli_command& cli, const string& name, // convert images int run_convert(const convert_params& params) { // load - auto image = color_image{}; + auto image = image_data{}; auto ioerror = string{}; if (!load_image(params.image, image, ioerror)) return print_fatal(ioerror); @@ -110,7 +110,7 @@ int run_view(const view_params& params) { // view images int run_view(const view_params& params) { // load - auto images = vector(params.images.size()); + auto images = vector(params.images.size()); for (auto idx = 0; idx < (int)params.images.size(); idx++) { auto ioerror = string{}; if (!load_image(params.images[idx], images[idx], ioerror)) @@ -152,7 +152,7 @@ int run_grade(const grade_params& params) { // grade images int run_grade(const grade_params& params) { // load image - auto image = color_image{}; + auto image = image_data{}; auto ioerror = string{}; if (!load_image(params.image, image, ioerror)) return print_fatal(ioerror); @@ -189,7 +189,7 @@ void add_command(const cli_command& cli, const string& name, int run_diff(const diff_params& params) { // load auto ioerror = string{}; - auto image1 = color_image{}, image2 = color_image{}; + auto image1 = image_data{}, image2 = image_data{}; if (!load_image(params.image1, image1, ioerror)) return false; if (!load_image(params.image2, image2, ioerror)) return false; @@ -253,7 +253,7 @@ void add_command(const cli_command& cli, const string& name, int run_setalpha(const setalpha_params& params) { // load auto ioerror = string{}; - auto image = color_image{}, alpha = color_image{}; + auto image = image_data{}, alpha = image_data{}; if (!load_image(params.image, image, ioerror)) return print_fatal(ioerror); if (!load_image(params.alpha, alpha, ioerror)) return print_fatal(ioerror); diff --git a/apps/yshape/yshape.cpp b/apps/yshape/yshape.cpp index b836dcfc1..ba485687d 100644 --- a/apps/yshape/yshape.cpp +++ b/apps/yshape/yshape.cpp @@ -364,7 +364,7 @@ void add_command(const cli_command& cli, const string& name, int run_heightfield(const heightfield_params& params) { // load mesh - auto image = color_image{}; + auto image = image_data{}; auto ioerror = ""s; if (!load_image(params.image, image, ioerror)) print_fatal(ioerror); diff --git a/docs/yocto/yocto_image.md b/docs/yocto/yocto_image.md index e9657a356..6e7461490 100644 --- a/docs/yocto/yocto_image.md +++ b/docs/yocto/yocto_image.md @@ -8,7 +8,7 @@ depends on `stb_image_resize.h`. ## Image representation -Images are represented as a simple struct called `color_image`, that stores +Images are represented as a simple struct called `image_data`, that stores the image width and height, a boolean flat that indicates whether the colors are in linear ot sRGB color space, and an array of pixels of `vec4f` type. diff --git a/docs/yocto/yocto_sceneio.md b/docs/yocto/yocto_sceneio.md index e5d86f6c5..a0ccc16a7 100644 --- a/docs/yocto/yocto_sceneio.md +++ b/docs/yocto/yocto_sceneio.md @@ -28,7 +28,7 @@ by the chosen file format. ```cpp auto error = string{}; -auto image = color_image{}; // define an image +auto image = image_data{}; // define an image if(!load_image(filename, image, error)) // load image print_error(error); // check and print error if(!save_image(filename, image, error)) // save image diff --git a/libs/yocto/yocto_image.cpp b/libs/yocto/yocto_image.cpp index 47ac7a58f..a15015326 100644 --- a/libs/yocto/yocto_image.cpp +++ b/libs/yocto/yocto_image.cpp @@ -56,23 +56,23 @@ using std::unique_ptr; namespace yocto { // image creation -color_image make_image(int width, int height, bool linear) { - return color_image{ +image_data make_image(int width, int height, bool linear) { + return image_data{ width, height, linear, vector(width * height, vec4f{0, 0, 0, 0})}; } // equality -bool operator==(const color_image& a, const color_image& b) { +bool operator==(const image_data& a, const image_data& b) { return a.width == b.width && a.height == b.height && a.linear == b.linear && a.pixels == b.pixels; } -bool operator!=(const color_image& a, const color_image& b) { +bool operator!=(const image_data& a, const image_data& b) { return a.width != b.width || a.height != b.height || a.linear != b.linear || a.pixels != b.pixels; } // swap -void swap(color_image& a, color_image& b) { +void swap(image_data& a, image_data& b) { std::swap(a.width, b.width); std::swap(a.height, b.height); std::swap(a.linear, b.linear); @@ -80,13 +80,13 @@ void swap(color_image& a, color_image& b) { } // conversions -color_image convert_image(const color_image& image, bool linear) { +image_data convert_image(const image_data& image, bool linear) { if (image.linear == linear) return image; auto result = make_image(image.width, image.height, linear); convert_image(result, image); return result; } -void convert_image(color_image& result, const color_image& image) { +void convert_image(image_data& result, const image_data& image) { if (image.width != result.width || image.height != result.height) throw std::invalid_argument{"image have to be the same size"}; if (image.linear == result.linear) { @@ -101,7 +101,7 @@ void convert_image(color_image& result, const color_image& image) { // Lookup pixel for evaluation static vec4f lookup_image( - const color_image& image, int i, int j, bool as_linear) { + const image_data& image, int i, int j, bool as_linear) { if (as_linear && !image.linear) { return srgb_to_rgb(image.pixels[j * image.width + i]); } else { @@ -110,7 +110,7 @@ static vec4f lookup_image( } // Evaluates an image at a point `uv`. -vec4f eval_image(const color_image& image, const vec2f& uv, bool as_linear, +vec4f eval_image(const image_data& image, const vec2f& uv, bool as_linear, bool no_interpolation, bool clamp_to_edge) { if (image.width == 0 || image.height == 0) return {0, 0, 0, 0}; @@ -146,8 +146,7 @@ vec4f eval_image(const color_image& image, const vec2f& uv, bool as_linear, } // Apply tone mapping returning a float or byte image. -color_image tonemap_image( - const color_image& image, float exposure, bool filmic) { +image_data tonemap_image(const image_data& image, float exposure, bool filmic) { if (!image.linear) return image; auto result = make_image(image.width, image.height, false); for (auto idx = 0; idx < image.width * image.height; idx++) { @@ -157,8 +156,8 @@ color_image tonemap_image( } // Apply tone mapping. If the input image is an ldr, does nothing. -void tonemap_image(color_image& result, const color_image& image, - float exposure, bool filmic) { +void tonemap_image( + image_data& result, const image_data& image, float exposure, bool filmic) { if (image.width != result.width || image.height != result.height) throw std::invalid_argument{"image should be the same size"}; if (result.linear) throw std::invalid_argument{"ldr expected"}; @@ -174,8 +173,8 @@ void tonemap_image(color_image& result, const color_image& image, } } // Apply tone mapping using multithreading for speed. -void tonemap_image_mt(color_image& result, const color_image& image, - float exposure, bool filmic) { +void tonemap_image_mt( + image_data& result, const image_data& image, float exposure, bool filmic) { if (image.width != result.width || image.height != result.height) throw std::invalid_argument{"image should be the same size"}; if (result.linear) throw std::invalid_argument{"ldr expected"}; @@ -194,8 +193,8 @@ void tonemap_image_mt(color_image& result, const color_image& image, } // Resize an image. -color_image resize_image( - const color_image& image, int res_width, int res_height) { +image_data resize_image( + const image_data& image, int res_width, int res_height) { if (res_width == 0 && res_height == 0) { throw std::invalid_argument{"bad image size in resize"}; } @@ -216,8 +215,8 @@ color_image resize_image( } // Compute the difference between two images. -color_image image_difference( - const color_image& image1, const color_image& image2, bool display) { +image_data image_difference( + const image_data& image1, const image_data& image2, bool display) { // check sizes if (image1.width != image2.width || image1.height != image2.height) { throw std::invalid_argument{"image sizes are different"}; @@ -238,7 +237,7 @@ color_image image_difference( return difference; } -void set_region(color_image& image, const color_image& region, int x, int y) { +void set_region(image_data& image, const image_data& region, int x, int y) { for (auto j = 0; j < region.height; j++) { for (auto i = 0; i < region.width; i++) { image.pixels[(j + y) * image.width + (i + x)] = @@ -247,7 +246,7 @@ void set_region(color_image& image, const color_image& region, int x, int y) { } } -void get_region(color_image& region, const color_image& image, int x, int y, +void get_region(image_data& region, const image_data& image, int x, int y, int width, int height) { if (region.width != width || region.height != height) { region = make_image(width, height, image.linear); @@ -261,8 +260,8 @@ void get_region(color_image& region, const color_image& image, int x, int y, } // Composite two images together. -color_image composite_image( - const color_image& image_a, const color_image& image_b) { +image_data composite_image( + const image_data& image_a, const image_data& image_b) { if (image_a.width != image_b.width || image_a.height != image_b.height) throw std::invalid_argument{"image should be the same size"}; if (image_a.linear != image_b.linear) @@ -275,8 +274,8 @@ color_image composite_image( } // Composite two images together. -void composite_image(color_image& result, const color_image& image_a, - const color_image& image_b) { +void composite_image( + image_data& result, const image_data& image_a, const image_data& image_b) { if (image_a.width != image_b.width || image_a.height != image_b.height) throw std::invalid_argument{"image should be the same size"}; if (image_a.linear != image_b.linear) @@ -327,8 +326,8 @@ vec4f colorgradeb( } // Color grade an hsr or ldr image to an ldr image. -color_image colorgrade_image( - const color_image& image, const colorgrade_params& params) { +image_data colorgrade_image( + const image_data& image, const colorgrade_params& params) { auto result = make_image(image.width, image.height, false); for (auto idx = (size_t)0; idx < image.pixels.size(); idx++) { result.pixels[idx] = colorgrade(image.pixels[idx], image.linear, params); @@ -338,7 +337,7 @@ color_image colorgrade_image( // Color grade an hsr or ldr image to an ldr image. // Uses multithreading for speed. -void colorgrade_image(color_image& result, const color_image& image, +void colorgrade_image(image_data& result, const image_data& image, const colorgrade_params& params) { if (image.width != result.width || image.height != result.height) throw std::invalid_argument{"image should be the same size"}; @@ -350,7 +349,7 @@ void colorgrade_image(color_image& result, const color_image& image, // Color grade an hsr or ldr image to an ldr image. // Uses multithreading for speed. -void colorgrade_image_mt(color_image& result, const color_image& image, +void colorgrade_image_mt(image_data& result, const image_data& image, const colorgrade_params& params) { if (image.width != result.width || image.height != result.height) throw std::invalid_argument{"image should be the same size"}; @@ -363,7 +362,7 @@ void colorgrade_image_mt(color_image& result, const color_image& image, } // determine white balance colors -vec4f compute_white_balance(const color_image& image) { +vec4f compute_white_balance(const image_data& image) { auto rgb = vec3f{0, 0, 0}; for (auto idx = (size_t)0; image.pixels.size(); idx++) { rgb += xyz(image.pixels[idx]); @@ -382,7 +381,7 @@ namespace yocto { // Comvert a bump map to a normal map. void bump_to_normal( - color_image& normalmap, const color_image& bumpmap, float scale) { + image_data& normalmap, const image_data& bumpmap, float scale) { auto width = bumpmap.width, height = bumpmap.height; if (normalmap.width != bumpmap.width || normalmap.height != bumpmap.height) { normalmap = make_image(width, height, bumpmap.linear); @@ -406,14 +405,14 @@ void bump_to_normal( } } } -color_image bump_to_normal(const color_image& bumpmap, float scale) { +image_data bump_to_normal(const image_data& bumpmap, float scale) { auto normalmap = make_image(bumpmap.width, bumpmap.height, bumpmap.linear); bump_to_normal(normalmap, bumpmap, scale); return normalmap; } template -static color_image make_proc_image( +static image_data make_proc_image( int width, int height, bool linear, Shader&& shader) { auto image = make_image(width, height, linear); auto scale = 1.0f / max(width, height); @@ -427,7 +426,7 @@ static color_image make_proc_image( } // Make an image -color_image make_grid(int width, int height, float scale, const vec4f& color0, +image_data make_grid(int width, int height, float scale, const vec4f& color0, const vec4f& color1) { return make_proc_image(width, height, true, [=](vec2f uv) { uv *= 4 * scale; @@ -441,8 +440,8 @@ color_image make_grid(int width, int height, float scale, const vec4f& color0, }); } -color_image make_checker(int width, int height, float scale, - const vec4f& color0, const vec4f& color1) { +image_data make_checker(int width, int height, float scale, const vec4f& color0, + const vec4f& color1) { return make_proc_image(width, height, true, [=](vec2f uv) { uv *= 4 * scale; uv -= vec2f{(float)(int)uv.x, (float)(int)uv.y}; @@ -451,7 +450,7 @@ color_image make_checker(int width, int height, float scale, }); } -color_image make_bumps(int width, int height, float scale, const vec4f& color0, +image_data make_bumps(int width, int height, float scale, const vec4f& color0, const vec4f& color1) { return make_proc_image(width, height, true, [=](vec2f uv) { uv *= 4 * scale; @@ -468,7 +467,7 @@ color_image make_bumps(int width, int height, float scale, const vec4f& color0, }); } -color_image make_ramp(int width, int height, float scale, const vec4f& color0, +image_data make_ramp(int width, int height, float scale, const vec4f& color0, const vec4f& color1) { return make_proc_image(width, height, true, [=](vec2f uv) { uv *= scale; @@ -477,7 +476,7 @@ color_image make_ramp(int width, int height, float scale, const vec4f& color0, }); } -color_image make_gammaramp(int width, int height, float scale, +image_data make_gammaramp(int width, int height, float scale, const vec4f& color0, const vec4f& color1) { return make_proc_image(width, height, false, [=](vec2f uv) { uv *= scale; @@ -492,7 +491,7 @@ color_image make_gammaramp(int width, int height, float scale, }); } -color_image make_uvramp(int width, int height, float scale) { +image_data make_uvramp(int width, int height, float scale) { return make_proc_image(width, height, true, [=](vec2f uv) { uv *= scale; uv -= vec2f{(float)(int)uv.x, (float)(int)uv.y}; @@ -500,7 +499,7 @@ color_image make_uvramp(int width, int height, float scale) { }); } -color_image make_uvgrid(int width, int height, float scale, bool colored) { +image_data make_uvgrid(int width, int height, float scale, bool colored) { return make_proc_image(width, height, true, [=](vec2f uv) { uv *= scale; uv -= vec2f{(float)(int)uv.x, (float)(int)uv.y}; @@ -528,7 +527,7 @@ color_image make_uvgrid(int width, int height, float scale, bool colored) { }); } -color_image make_blackbodyramp( +image_data make_blackbodyramp( int width, int height, float scale, float from, float to) { return make_proc_image(width, height, true, [=](vec2f uv) { uv *= scale; @@ -538,7 +537,7 @@ color_image make_blackbodyramp( }); } -color_image make_colormapramp(int width, int height, float scale) { +image_data make_colormapramp(int width, int height, float scale) { return make_proc_image(width, height, false, [=](vec2f uv) { uv *= scale; uv -= vec2f{(float)(int)uv.x, (float)(int)uv.y}; @@ -556,7 +555,7 @@ color_image make_colormapramp(int width, int height, float scale) { }); } -color_image make_noisemap(int width, int height, float scale, +image_data make_noisemap(int width, int height, float scale, const vec4f& color0, const vec4f& color1) { return make_proc_image(width, height, true, [=](vec2f uv) { uv *= 8 * scale; @@ -566,7 +565,7 @@ color_image make_noisemap(int width, int height, float scale, }); } -color_image make_fbmmap(int width, int height, float scale, const vec4f& noise, +image_data make_fbmmap(int width, int height, float scale, const vec4f& noise, const vec4f& color0, const vec4f& color1) { return make_proc_image(width, height, true, [=](vec2f uv) { uv *= 8 * scale; @@ -576,7 +575,7 @@ color_image make_fbmmap(int width, int height, float scale, const vec4f& noise, }); } -color_image make_turbulencemap(int width, int height, float scale, +image_data make_turbulencemap(int width, int height, float scale, const vec4f& noise, const vec4f& color0, const vec4f& color1) { return make_proc_image(width, height, true, [=](vec2f uv) { uv *= 8 * scale; @@ -586,8 +585,8 @@ color_image make_turbulencemap(int width, int height, float scale, }); } -color_image make_ridgemap(int width, int height, float scale, - const vec4f& noise, const vec4f& color0, const vec4f& color1) { +image_data make_ridgemap(int width, int height, float scale, const vec4f& noise, + const vec4f& color0, const vec4f& color1) { return make_proc_image(width, height, true, [=](vec2f uv) { uv *= 8 * scale; auto v = perlin_ridge( @@ -598,8 +597,8 @@ color_image make_ridgemap(int width, int height, float scale, } // Add image border -color_image add_border( - const color_image& image, float width, const vec4f& color) { +image_data add_border( + const image_data& image, float width, const vec4f& color) { auto result = image; auto scale = 1.0f / max(image.width, image.height); for (auto j = 0; j < image.height; j++) { @@ -615,7 +614,7 @@ color_image add_border( } // Implementation of sunsky modified heavily from pbrt -color_image make_sunsky(int width, int height, float theta_sun, float turbidity, +image_data make_sunsky(int width, int height, float theta_sun, float turbidity, bool has_sun, float sun_intensity, float sun_radius, const vec3f& ground_albedo) { auto zenith_xyY = vec3f{ @@ -752,7 +751,7 @@ color_image make_sunsky(int width, int height, float theta_sun, float turbidity, } // Make an image of multiple lights. -color_image make_lights(int width, int height, const vec3f& le, int nlights, +image_data make_lights(int width, int height, const vec3f& le, int nlights, float langle, float lwidth, float lheight) { auto img = make_image(width, height, true); for (auto j = 0; j < height / 2; j++) { diff --git a/libs/yocto/yocto_image.h b/libs/yocto/yocto_image.h index e3ff40b79..65e2c881f 100644 --- a/libs/yocto/yocto_image.h +++ b/libs/yocto/yocto_image.h @@ -65,7 +65,7 @@ namespace yocto { // Image data as array of float or byte pixels. Images can be stored in linear // or non linear color space. -struct color_image { +struct image_data { // image data int width = 0; int height = 0; @@ -78,78 +78,78 @@ struct color_image { }; // image creation -color_image make_image(int width, int height, bool linear); +image_data make_image(int width, int height, bool linear); // equality -bool operator==(const color_image& a, const color_image& b); -bool operator!=(const color_image& a, const color_image& b); +bool operator==(const image_data& a, const image_data& b); +bool operator!=(const image_data& a, const image_data& b); // swap -void swap(color_image& a, color_image& b); +void swap(image_data& a, image_data& b); // pixel access -inline vec4f get_pixel(const color_image& image, int i, int j); -inline void set_pixel(color_image& image, int i, int j, const vec4f& pixel); +inline vec4f get_pixel(const image_data& image, int i, int j); +inline void set_pixel(image_data& image, int i, int j, const vec4f& pixel); // conversions -color_image convert_image(const color_image& image, bool linear); -void convert_image(color_image& result, const color_image& image); +image_data convert_image(const image_data& image, bool linear); +void convert_image(image_data& result, const image_data& image); // Evaluates an image at a point `uv`. -vec4f eval_image(const color_image& image, const vec2f& uv, +vec4f eval_image(const image_data& image, const vec2f& uv, bool as_linear = false, bool no_interpolation = false, bool clamp_to_edge = false); // Apply tone mapping returning a float or byte image. -color_image tonemap_image( - const color_image& image, float exposure, bool filmic = false); +image_data tonemap_image( + const image_data& image, float exposure, bool filmic = false); // Apply tone mapping. If the input image is an ldr, does nothing. -void tonemap_image(color_image& ldr, const color_image& image, float exposure, +void tonemap_image(image_data& ldr, const image_data& image, float exposure, bool filmic = false); // Apply tone mapping using multithreading for speed. -void tonemap_image_mt(color_image& ldr, const color_image& image, - float exposure, bool filmic = false); +void tonemap_image_mt(image_data& ldr, const image_data& image, float exposure, + bool filmic = false); // Resize an image. -color_image resize_image(const color_image& image, int width, int height); +image_data resize_image(const image_data& image, int width, int height); // set/get region -void set_region(color_image& image, const color_image& region, int x, int y); -void get_region(color_image& region, const color_image& image, int x, int y, +void set_region(image_data& image, const image_data& region, int x, int y); +void get_region(image_data& region, const image_data& image, int x, int y, int width, int height); // Compute the difference between two images. -color_image image_difference( - const color_image& image_a, const color_image& image_b, bool display_diff); +image_data image_difference( + const image_data& image_a, const image_data& image_b, bool display_diff); // Composite two images together. -color_image composite_image( - const color_image& image_a, const color_image& image_b); +image_data composite_image( + const image_data& image_a, const image_data& image_b); // Composite two images together. -void composite_image(color_image& result, const color_image& image_a, - const color_image& image_b); +void composite_image( + image_data& result, const image_data& image_a, const image_data& image_b); // Composite two images together. -void composite_image(color_image& result, const vector& images); +void composite_image(image_data& result, const vector& images); // Color grade an hsr or ldr image to an ldr image. -color_image colorgrade_image( - const color_image& image, const colorgrade_params& params); +image_data colorgrade_image( + const image_data& image, const colorgrade_params& params); // Color grade an hsr or ldr image to an ldr image. // Uses multithreading for speed. -void colorgrade_image(color_image& result, const color_image& image, +void colorgrade_image(image_data& result, const image_data& image, const colorgrade_params& params); // Color grade an hsr or ldr image to an ldr image. // Uses multithreading for speed. -void colorgrade_image_mt(color_image& result, const color_image& image, +void colorgrade_image_mt(image_data& result, const image_data& image, const colorgrade_params& params); // determine white balance colors -vec4f compute_white_balance(const color_image& image); +vec4f compute_white_balance(const image_data& image); } // namespace yocto @@ -159,45 +159,45 @@ vec4f compute_white_balance(const color_image& image); namespace yocto { // Make a grid image. -color_image make_grid(int width, int height, float scale = 1, +image_data make_grid(int width, int height, float scale = 1, const vec4f& color0 = vec4f{0.2f, 0.2f, 0.2f, 1.0f}, const vec4f& color1 = vec4f{0.5f, 0.5f, 0.5f, 1.0f}); // Make a checker image. -color_image make_checker(int width, int height, float scale = 1, +image_data make_checker(int width, int height, float scale = 1, const vec4f& color0 = vec4f{0.2f, 0.2f, 0.2f, 1.0f}, const vec4f& color1 = vec4f{0.5f, 0.5f, 0.5f, 1.0f}); // Make a bump map. -color_image make_bumps(int width, int height, float scale = 1, +image_data make_bumps(int width, int height, float scale = 1, const vec4f& color0 = vec4f{0, 0, 0, 1}, const vec4f& color1 = vec4f{1, 1, 1, 1}); // Make a ramp -color_image make_ramp(int width, int height, float scale = 1, +image_data make_ramp(int width, int height, float scale = 1, const vec4f& color0 = vec4f{0, 0, 0, 1}, const vec4f& color1 = vec4f{1, 1, 1, 1}); // Make a gamma ramp. -color_image make_gammaramp(int width, int height, float scale = 1, +image_data make_gammaramp(int width, int height, float scale = 1, const vec4f& color0 = vec4f{0, 0, 0, 1}, const vec4f& color1 = vec4f{1, 1, 1, 1}); // Make a uv ramp -color_image make_uvramp(int width, int height, float scale = 1); +image_data make_uvramp(int width, int height, float scale = 1); // Make a uv grid -color_image make_uvgrid( +image_data make_uvgrid( int width, int height, float scale = 1, bool colored = true); // Make blackbody ramp. -color_image make_blackbodyramp(int width, int height, float scale = 1, +image_data make_blackbodyramp(int width, int height, float scale = 1, float from = 1000, float to = 12000); // Make color map ramp. -color_image make_colormapramp(int width, int height, float scale = 1); +image_data make_colormapramp(int width, int height, float scale = 1); // Make a noise image. Noise parameters: lacunarity, gain, octaves, offset. -color_image make_noisemap(int width, int height, float scale = 1, +image_data make_noisemap(int width, int height, float scale = 1, const vec4f& color0 = {0, 0, 0, 1}, const vec4f& color1 = {1, 1, 1, 1}); -color_image make_fbmmap(int width, int height, float scale = 1, +image_data make_fbmmap(int width, int height, float scale = 1, const vec4f& noise = {2, 0.5, 8, 1}, const vec4f& color0 = {0, 0, 0, 1}, const vec4f& color1 = {1, 1, 1, 1}); -color_image make_turbulencemap(int width, int height, float scale = 1, +image_data make_turbulencemap(int width, int height, float scale = 1, const vec4f& noise = {2, 0.5, 8, 1}, const vec4f& color0 = {0, 0, 0, 1}, const vec4f& color1 = {1, 1, 1, 1}); -color_image make_ridgemap(int width, int height, float scale = 1, +image_data make_ridgemap(int width, int height, float scale = 1, const vec4f& noise = {2, 0.5, 8, 1}, const vec4f& color0 = {0, 0, 0, 1}, const vec4f& color1 = {1, 1, 1, 1}); @@ -206,20 +206,20 @@ color_image make_ridgemap(int width, int height, float scale = 1, // disabled with has_sun. The sun parameters can be slightly modified by // changing the sun intensity and temperature. Has a convention, a temperature // of 0 sets the eath sun defaults (ignoring intensity too). -color_image make_sunsky(int width, int height, float sun_angle, +image_data make_sunsky(int width, int height, float sun_angle, float turbidity = 3, bool has_sun = false, float sun_intensity = 1, float sun_radius = 1, const vec3f& ground_albedo = {0.2f, 0.2f, 0.2f}); // Make an image of multiple lights. -color_image make_lights(int width, int height, const vec3f& le = {1, 1, 1}, +image_data make_lights(int width, int height, const vec3f& le = {1, 1, 1}, int nlights = 4, float langle = pif / 4, float lwidth = pif / 16, float lheight = pif / 16); // Comvert a bump map to a normal map. All linear color spaces. -color_image bump_to_normal(const color_image& image, float scale = 1); +image_data bump_to_normal(const image_data& image, float scale = 1); // Add a border to an image -color_image add_border( - const color_image& img, float width, const vec4f& color = {0, 0, 0, 1}); +image_data add_border( + const image_data& img, float width, const vec4f& color = {0, 0, 0, 1}); } // namespace yocto @@ -353,6 +353,15 @@ void add_border(vector& pixels, const vector& source, int width, } // namespace yocto +// ----------------------------------------------------------------------------- +// BACKWARDS COMPATIBILITY +// ----------------------------------------------------------------------------- +namespace yocto { + +using color_image = image_data; + +} // namespace yocto + // ----------------------------------------------------------------------------- // // @@ -367,18 +376,18 @@ void add_border(vector& pixels, const vector& source, int width, namespace yocto { // pixel access -inline vec4f& color_image::operator[](vec2i ij) { +inline vec4f& image_data::operator[](vec2i ij) { return pixels[ij.y * width + ij.x]; } -inline const vec4f& color_image::operator[](vec2i ij) const { +inline const vec4f& image_data::operator[](vec2i ij) const { return pixels[ij.y * width + ij.x]; } // pixel access -inline vec4f get_pixel(const color_image& image, int i, int j) { +inline vec4f get_pixel(const image_data& image, int i, int j) { return image.pixels[j * image.width + i]; } -inline void set_pixel(color_image& image, int i, int j, const vec4f& pixel) { +inline void set_pixel(image_data& image, int i, int j, const vec4f& pixel) { image.pixels[j * image.width + i] = pixel; } diff --git a/libs/yocto/yocto_scene.cpp b/libs/yocto/yocto_scene.cpp index 7740ea573..9370c17c1 100644 --- a/libs/yocto/yocto_scene.cpp +++ b/libs/yocto/yocto_scene.cpp @@ -170,7 +170,7 @@ vec4f eval_texture(const scene_data& scene, int texture, const vec2f& uv, } // conversion from image -texture_data image_to_texture(const color_image& image) { +texture_data image_to_texture(const image_data& image) { auto texture = texture_data{image.width, image.height, image.linear, {}, {}}; if (image.linear) { texture.pixelsf = image.pixels; diff --git a/libs/yocto/yocto_scene.h b/libs/yocto/yocto_scene.h index 2d55fa6dd..7c1aabf81 100644 --- a/libs/yocto/yocto_scene.h +++ b/libs/yocto/yocto_scene.h @@ -271,7 +271,7 @@ vec4f lookup_texture( const texture_data& texture, int i, int j, bool as_linear = false); // conversion from image -texture_data image_to_texture(const color_image& image); +texture_data image_to_texture(const image_data& image); } // namespace yocto diff --git a/libs/yocto/yocto_sceneio.cpp b/libs/yocto/yocto_sceneio.cpp index 8c024dbc2..3a7d1931d 100644 --- a/libs/yocto/yocto_sceneio.cpp +++ b/libs/yocto/yocto_sceneio.cpp @@ -445,7 +445,7 @@ bool is_ldr_filename(const string& filename) { } // Loads/saves an image. Chooses hdr or ldr based on file name. -bool load_image(const string& filename, color_image& image, string& error) { +bool load_image(const string& filename, image_data& image, string& error) { auto format_error = [filename, &error]() { error = filename + ": unknown format"; return false; @@ -549,7 +549,7 @@ bool load_image(const string& filename, color_image& image, string& error) { // Saves an hdr image. bool save_image( - const string& filename, const color_image& image, string& error) { + const string& filename, const image_data& image, string& error) { auto format_error = [filename, &error]() { error = filename + ": unknown format"; return false; @@ -560,13 +560,13 @@ bool save_image( }; // conversion helpers - auto to_linear = [](const color_image& image) { + auto to_linear = [](const image_data& image) { if (image.linear) return image.pixels; auto pixelsf = vector(image.pixels.size()); srgb_to_rgb(pixelsf, image.pixels); return pixelsf; }; - auto to_srgb = [](const color_image& image) { + auto to_srgb = [](const image_data& image) { auto pixelsb = vector(image.pixels.size()); if (image.linear) { rgb_to_srgb(pixelsb, image.pixels); @@ -618,7 +618,7 @@ bool save_image( } } -bool make_image_preset(color_image& image, const string& type_, string& error) { +bool make_image_preset(image_data& image, const string& type_, string& error) { auto type = path_basename(type_); auto width = 1024, height = 1024; @@ -661,7 +661,7 @@ bool make_image_preset(color_image& image, const string& type_, string& error) { } else if (type == "images1") { auto sub_types = vector{"grid", "uvgrid", "checker", "gammaramp", "bumps", "bump-normal", "noise", "fbm", "blackbodyramp"}; - auto sub_imgs = vector(sub_types.size()); + auto sub_imgs = vector(sub_types.size()); for (auto i = 0; i < sub_imgs.size(); i++) { if (!make_image_preset(sub_imgs[i], sub_types[i], error)) return false; } @@ -678,7 +678,7 @@ bool make_image_preset(color_image& image, const string& type_, string& error) { } } else if (type == "images2") { auto sub_types = vector{"sky", "sunsky"}; - auto sub_imgs = vector(sub_types.size()); + auto sub_imgs = vector(sub_types.size()); for (auto i = 0; i < sub_imgs.size(); i++) { if (!make_image_preset(sub_imgs[i], sub_types[i], error)) return false; } @@ -921,7 +921,7 @@ bool save_texture( bool make_texture_preset( texture_data& texture, const string& type, string& error) { - auto image = color_image{}; + auto image = image_data{}; if (!make_image_preset(image, type, error)) return false; texture = image_to_texture(image); return true; diff --git a/libs/yocto/yocto_sceneio.h b/libs/yocto/yocto_sceneio.h index 0e2719612..54c3af11d 100644 --- a/libs/yocto/yocto_sceneio.h +++ b/libs/yocto/yocto_sceneio.h @@ -86,11 +86,11 @@ bool is_hdr_filename(const string& filename); bool is_ldr_filename(const string& filename); // Loads/saves a 4 channels float/byte image in linear/srgb color space. -bool load_image(const string& filename, color_image& img, string& error); -bool save_image(const string& filename, const color_image& img, string& error); +bool load_image(const string& filename, image_data& img, string& error); +bool save_image(const string& filename, const image_data& img, string& error); // Make presets. Supported mostly in IO. -bool make_image_preset(color_image& image, const string& type, string& error); +bool make_image_preset(image_data& image, const string& type, string& error); } // namespace yocto diff --git a/libs/yocto/yocto_trace.cpp b/libs/yocto/yocto_trace.cpp index 5ee722f61..bd02134ae 100644 --- a/libs/yocto/yocto_trace.cpp +++ b/libs/yocto/yocto_trace.cpp @@ -1305,7 +1305,7 @@ trace_lights make_lights(const scene_data& scene, const trace_params& params) { } // Progressively computes an image. -color_image trace_image(const scene_data& scene, const trace_params& params) { +image_data trace_image(const scene_data& scene, const trace_params& params) { auto bvh = make_bvh(scene, params); auto lights = make_lights(scene, params); auto state = make_state(scene, params); @@ -1336,7 +1336,7 @@ void trace_samples(trace_state& state, const scene_data& scene, // Check image type static void check_image( - const color_image& image, int width, int height, bool linear) { + const image_data& image, int width, int height, bool linear) { if (image.width != width || image.height != height) throw std::invalid_argument{"image should have the same size"}; if (image.linear != linear) @@ -1345,12 +1345,12 @@ static void check_image( } // Get resulting render -color_image get_render(const trace_state& state) { +image_data get_render(const trace_state& state) { auto image = make_image(state.width, state.height, true); get_render(image, state); return image; } -void get_render(color_image& image, const trace_state& state) { +void get_render(image_data& image, const trace_state& state) { check_image(image, state.width, state.height, true); auto scale = 1.0f / (float)state.samples; for (auto idx = 0; idx < state.width * state.height; idx++) { @@ -1359,12 +1359,12 @@ void get_render(color_image& image, const trace_state& state) { } // Get denoised render -color_image get_denoised(const trace_state& state) { +image_data get_denoised(const trace_state& state) { auto image = make_image(state.width, state.height, true); get_denoised(image, state); return image; } -void get_denoised(color_image& image, const trace_state& state) { +void get_denoised(image_data& image, const trace_state& state) { #if YOCTO_DENOISE // Create an Intel Open Image Denoise device oidn::DeviceRef device = oidn::newDevice(); @@ -1404,12 +1404,12 @@ void get_denoised(color_image& image, const trace_state& state) { } // Get denoising buffers -color_image get_albedo(const trace_state& state) { +image_data get_albedo(const trace_state& state) { auto albedo = make_image(state.width, state.height, true); get_albedo(albedo, state); return albedo; } -void get_albedo(color_image& albedo, const trace_state& state) { +void get_albedo(image_data& albedo, const trace_state& state) { check_image(albedo, state.width, state.height, true); auto scale = 1.0f / (float)state.samples; for (auto idx = 0; idx < state.width * state.height; idx++) { @@ -1417,12 +1417,12 @@ void get_albedo(color_image& albedo, const trace_state& state) { state.albedo[idx].y * scale, state.albedo[idx].z * scale, 1.0f}; } } -color_image get_normal(const trace_state& state) { +image_data get_normal(const trace_state& state) { auto normal = make_image(state.width, state.height, true); get_normal(normal, state); return normal; } -void get_normal(color_image& normal, const trace_state& state) { +void get_normal(image_data& normal, const trace_state& state) { check_image(normal, state.width, state.height, true); auto scale = 1.0f / (float)state.samples; for (auto idx = 0; idx < state.width * state.height; idx++) { @@ -1432,14 +1432,14 @@ void get_normal(color_image& normal, const trace_state& state) { } // Denoise image -color_image denoise_render(const color_image& render, const color_image& albedo, - const color_image& normal) { +image_data denoise_render(const image_data& render, const image_data& albedo, + const image_data& normal) { auto denoised = make_image(render.width, render.height, render.linear); denoise_render(denoised, render, albedo, normal); return denoised; } -void denoise_render(color_image& denoised, const color_image& render, - const color_image& albedo, const color_image& normal) { +void denoise_render(image_data& denoised, const image_data& render, + const image_data& albedo, const image_data& normal) { check_image(denoised, render.width, render.height, render.linear); check_image(albedo, render.width, render.height, albedo.linear); check_image(normal, render.width, render.height, normal.linear); diff --git a/libs/yocto/yocto_trace.h b/libs/yocto/yocto_trace.h index 8440a384b..f4cb12b86 100644 --- a/libs/yocto/yocto_trace.h +++ b/libs/yocto/yocto_trace.h @@ -127,7 +127,7 @@ inline const auto trace_falsecolor_names = vector{"position", "normal", using image_callback = function; // Progressively computes an image. -color_image trace_image(const scene_data& scene, const trace_params& params); +image_data trace_image(const scene_data& scene, const trace_params& params); } // namespace yocto @@ -181,24 +181,24 @@ void trace_sample(trace_state& state, const scene_data& scene, const trace_params& params); // Get resulting render -color_image get_render(const trace_state& state); -void get_render(color_image& render, const trace_state& state); +image_data get_render(const trace_state& state); +void get_render(image_data& render, const trace_state& state); // Get denoised result -color_image get_denoised(const trace_state& state); -void get_denoised(color_image& render, const trace_state& state); +image_data get_denoised(const trace_state& state); +void get_denoised(image_data& render, const trace_state& state); // Get denoising buffers -color_image get_albedo(const trace_state& state); -void get_albedo(color_image& albedo, const trace_state& state); -color_image get_normal(const trace_state& state); -void get_normal(color_image& normal, const trace_state& state); +image_data get_albedo(const trace_state& state); +void get_albedo(image_data& albedo, const trace_state& state); +image_data get_normal(const trace_state& state); +void get_normal(image_data& normal, const trace_state& state); // Denoise image -color_image denoise_render(const color_image& render, const color_image& albedo, - const color_image& normal); -void denoise_render(color_image& denoised, const color_image& render, - const color_image& albedo, const color_image& normal); +image_data denoise_render(const image_data& render, const image_data& albedo, + const image_data& normal); +void denoise_render(image_data& denoised, const image_data& render, + const image_data& albedo, const image_data& normal); } // namespace yocto diff --git a/libs/yocto_gui/yocto_glview.cpp b/libs/yocto_gui/yocto_glview.cpp index abb65ae37..44303b118 100644 --- a/libs/yocto_gui/yocto_glview.cpp +++ b/libs/yocto_gui/yocto_glview.cpp @@ -59,7 +59,7 @@ namespace yocto { static void update_image_params(const glinput_state& input, - const color_image& image, glimage_params& glparams) { + const image_data& image, glimage_params& glparams) { glparams.window = input.window_size; glparams.framebuffer = input.framebuffer_viewport; std::tie(glparams.center, glparams.scale) = camera_imview(glparams.center, @@ -119,7 +119,7 @@ static bool draw_tonemap_params( } static bool draw_image_inspector(const glinput_state& input, - const color_image& image, const color_image& display, + const image_data& image, const image_data& display, glimage_params& glparams) { if (begin_glheader("inspect")) { draw_glslider("zoom", glparams.scale, 0.1, 10); @@ -265,7 +265,7 @@ namespace yocto { // Open a window and show an image void view_image( - const string& title, const string& name, const color_image& image) { + const string& title, const string& name, const image_data& image) { // display image auto display = make_image(image.width, image.height, false); float exposure = 0; @@ -311,9 +311,9 @@ void view_image( // Open a window and show an image void view_images(const string& title, const vector& names, - const vector& images) { + const vector& images) { // display image - auto displays = vector(images.size()); + auto displays = vector(images.size()); auto exposures = vector(images.size(), 0); auto filmics = vector(images.size(), false); for (auto idx = 0; idx < (int)images.size(); idx++) { @@ -367,7 +367,7 @@ void view_images(const string& title, const vector& names, // Open a window and show an image void colorgrade_image( - const string& title, const string& name, const color_image& image) { + const string& title, const string& name, const image_data& image) { // color grading parameters auto params = colorgrade_params{}; @@ -945,7 +945,7 @@ void clear_image(glimage_state& glimage) { glimage = {}; } -void set_image(glimage_state& glimage, const color_image& image) { +void set_image(glimage_state& glimage, const image_data& image) { if (!glimage.texture || glimage.width != image.width || glimage.height != image.height) { if (!glimage.texture) glGenTextures(1, &glimage.texture); diff --git a/libs/yocto_gui/yocto_glview.h b/libs/yocto_gui/yocto_glview.h index e88b06f30..c4b639083 100644 --- a/libs/yocto_gui/yocto_glview.h +++ b/libs/yocto_gui/yocto_glview.h @@ -61,15 +61,15 @@ namespace yocto { // Open a window and show an image void view_image( - const string& title, const string& name, const color_image& image); + const string& title, const string& name, const image_data& image); // Open a window and show a set of images void view_images(const string& title, const vector& names, - const vector& images); + const vector& images); // Open a window and show an image for color grading void colorgrade_image( - const string& title, const string& name, const color_image& image); + const string& title, const string& name, const image_data& image); // Open a window and show an scene via path tracing void view_scene(const string& title, const string& name, scene_data& scene, @@ -117,7 +117,7 @@ bool init_image(glimage_state& glimage); void clear_image(glimage_state& glimage); // update image data -void set_image(glimage_state& glimage, const color_image& image); +void set_image(glimage_state& glimage, const image_data& image); // OpenGL image drawing params struct glimage_params { diff --git a/libs/yocto_gui/yocto_opengl.cpp b/libs/yocto_gui/yocto_opengl.cpp index 313a18d3d..4d0f6e9a5 100644 --- a/libs/yocto_gui/yocto_opengl.cpp +++ b/libs/yocto_gui/yocto_opengl.cpp @@ -1170,7 +1170,7 @@ void clear_image(ogl_image& oimg) { } void set_image( - ogl_image& oimg, const color_image& img, bool linear, bool mipmap) { + ogl_image& oimg, const image_data& img, bool linear, bool mipmap) { set_texture(oimg.texture, img.width, img.height, 4, (const float*)img.pixels.data(), false, linear, mipmap); } diff --git a/libs/yocto_gui/yocto_opengl.h b/libs/yocto_gui/yocto_opengl.h index 7eb133c24..106e237ce 100644 --- a/libs/yocto_gui/yocto_opengl.h +++ b/libs/yocto_gui/yocto_opengl.h @@ -502,7 +502,7 @@ bool is_initialized(const ogl_image& oimg); void clear_image(ogl_image& oimg); // update image data -void set_image(ogl_image& oimg, const color_image& img, bool linear = false, +void set_image(ogl_image& oimg, const image_data& img, bool linear = false, bool mipmap = false); // OpenGL image drawing params From 7e208d2fdd7597da2da977140605e79abf17dc83 Mon Sep 17 00:00:00 2001 From: Fabio Pellacini Date: Wed, 9 Jun 2021 15:56:49 +0200 Subject: [PATCH 10/12] updated --- docs/yocto/yocto_bvh.md | 14 ++--- docs/yocto/yocto_trace.md | 2 +- libs/yocto/yocto_bvh.cpp | 110 ++++++++++++++++++------------------- libs/yocto/yocto_bvh.h | 39 +++++-------- libs/yocto/yocto_trace.cpp | 28 +++++----- libs/yocto/yocto_trace.h | 6 +- 6 files changed, 94 insertions(+), 105 deletions(-) diff --git a/docs/yocto/yocto_bvh.md b/docs/yocto/yocto_bvh.md index 9485f3750..93ac63f8a 100644 --- a/docs/yocto/yocto_bvh.md +++ b/docs/yocto/yocto_bvh.md @@ -10,26 +10,24 @@ Yocto/Bvh provides ray-scene intersection for points, lines, triangles and quads accelerated by a BVH data structure. Our BVH is written for minimal code and not maximum speed, but still gives fast-enough results. -The BVH tree is stored in a `bvh_tree` struct. The tree stores an array of +The BVH tree is stored in a `bvh_data` struct. The tree stores an array of nodes and an array of element indices. Each node in the tree has references to either other nodes or elements. References are represented as indices in the nodes or elements arrays. Nodes indices refer to the nodes array, for internal nodes, or the element arrays, for leaf nodes. -The BVH does not store shape data, which is instead passed explicitly +The BVH does not store shape or scene data, which is instead passed explicitly to all calls. +We use the same data structure to store the BVH for [Yocto/Scene](yocto_scene.md) +shapes and scenes. To support scene intersection, we store the shapes BVHs +together with the other data. BVH nodes contain their bounds, indices to the BVH arrays of either primitives or internal nodes, node element type, and the split axis. Leaf and internal nodes are identical, except that indices refer to primitives for leaf nodes or other nodes for internal nodes. -Two wrappers, `bvh_scene` and `bvh_shape` are used to store the BVH for -[Yocto/Scene](yocto_scene.md) scenes and shapes. For shapes, we store a -single BVH, while for scene we store the scene BVH and all shapes BVHs. -These wrappers does not store copies to shape or scene data, so that data is -passed in for all subsequent calls. -These wrappers can alternatively store references to Intel's Embree BVH, +The BVH data structure can also function as a wrapper for Intel's Embree BVH, for faster ray-scene intersection. To use Embree, the library should be compiled with Embree support by setting the `YOCTO_EMBREE` compile flag and linking to Embree's libraries. diff --git a/docs/yocto/yocto_trace.md b/docs/yocto/yocto_trace.md index 3cd2001c3..b8d4cffd6 100644 --- a/docs/yocto/yocto_trace.md +++ b/docs/yocto/yocto_trace.md @@ -87,7 +87,7 @@ Yocto/Trace supports a low-level rendering API that is more flexible for applications that need it. In this modality, you have to manage all state manually. -Yocto/Trace internally uses a `bvh_scene` BVH for ray-scene intersection, +Yocto/Trace internally uses a `bvh_data` BVH for ray-scene intersection, a `trace_lights` objects to store lighting information, and a `trace_state` object to tracks the rendering process and contains all data needed to perform progressive computation. Each object need to be initialized separately. diff --git a/libs/yocto/yocto_bvh.cpp b/libs/yocto/yocto_bvh.cpp index f63a707f6..614776a12 100644 --- a/libs/yocto/yocto_bvh.cpp +++ b/libs/yocto/yocto_bvh.cpp @@ -116,7 +116,7 @@ void clear_embree_bvh(void* embree_bvh) { // Initialize Embree BVH static void build_embree_bvh( - bvh_shape& bvh, const shape_data& shape, bool highquality) { + bvh_data& bvh, const shape_data& shape, bool highquality) { auto edevice = bvh_embree_device(); bvh.embree_bvh = unique_ptr{ rtcNewScene(edevice), &clear_embree_bvh}; @@ -198,7 +198,7 @@ static void build_embree_bvh( } static void build_embree_bvh( - bvh_scene& bvh, const scene_data& scene, bool highquality) { + bvh_data& bvh, const scene_data& scene, bool highquality) { // scene bvh auto edevice = bvh_embree_device(); bvh.embree_bvh = unique_ptr{ @@ -224,7 +224,7 @@ static void build_embree_bvh( rtcCommitScene(escene); } -static void update_embree_bvh(bvh_scene& bvh, const scene_data& scene, +static void update_embree_bvh(bvh_data& bvh, const scene_data& scene, const vector& updated_instances) { // scene bvh auto escene = (RTCScene)bvh.embree_bvh.get(); @@ -240,7 +240,7 @@ static void update_embree_bvh(bvh_scene& bvh, const scene_data& scene, rtcCommitScene(escene); } -static bool intersect_embree_bvh(const bvh_shape& bvh, const shape_data& shape, +static bool intersect_embree_bvh(const bvh_data& bvh, const shape_data& shape, const ray3f& ray, int& element, vec2f& uv, float& distance, bool find_any) { RTCRayHit embree_ray; embree_ray.ray.org_x = ray.o.x; @@ -264,7 +264,7 @@ static bool intersect_embree_bvh(const bvh_shape& bvh, const shape_data& shape, return true; } -static bool intersect_embree_bvh(const bvh_scene& bvh, const scene_data& scene, +static bool intersect_embree_bvh(const bvh_data& bvh, const scene_data& scene, const ray3f& ray, int& instance, int& element, vec2f& uv, float& distance, bool find_any) { RTCRayHit embree_ray; @@ -444,7 +444,7 @@ const int bvh_max_prims = 4; // Build BVH nodes static void build_bvh_serial( - bvh_tree& bvh, const vector& bboxes, bool highquality) { + bvh_data& bvh, const vector& bboxes, bool highquality) { // get values auto& nodes = bvh.nodes; auto& primitives = bvh.primitives; @@ -613,7 +613,7 @@ static void build_bvh_parallel( #endif // Update bvh -static void refit_bvh(bvh_tree& bvh, const vector& bboxes) { +static void refit_bvh(bvh_data& bvh, const vector& bboxes) { for (auto nodeid = (int)bvh.nodes.size() - 1; nodeid >= 0; nodeid--) { auto& node = bvh.nodes[nodeid]; node.bbox = invalidb3f; @@ -630,7 +630,7 @@ static void refit_bvh(bvh_tree& bvh, const vector& bboxes) { } static void build_bvh( - bvh_shape& bvh, const shape_data& shape, bool highquality, bool embree) { + bvh_data& bvh, const shape_data& shape, bool highquality, bool embree) { #ifdef YOCTO_EMBREE if (embree) { return build_embree_bvh(bvh, shape, highquality); @@ -669,10 +669,10 @@ static void build_bvh( } // build nodes - build_bvh_serial(bvh.bvh, bboxes, highquality); + build_bvh_serial(bvh, bboxes, highquality); } -static void build_bvh(bvh_scene& bvh, const scene_data& scene, bool highquality, +static void build_bvh(bvh_data& bvh, const scene_data& scene, bool highquality, bool embree, bool noparallel) { // embree #ifdef YOCTO_EMBREE @@ -686,18 +686,18 @@ static void build_bvh(bvh_scene& bvh, const scene_data& scene, bool highquality, for (auto idx = 0; idx < bboxes.size(); idx++) { auto& instance = scene.instances[idx]; auto& sbvh = bvh.shapes[instance.shape]; - bboxes[idx] = sbvh.bvh.nodes.empty() + bboxes[idx] = sbvh.nodes.empty() ? invalidb3f - : transform_bbox(instance.frame, sbvh.bvh.nodes[0].bbox); + : transform_bbox(instance.frame, sbvh.nodes[0].bbox); } // build nodes - build_bvh_serial(bvh.bvh, bboxes, highquality); + build_bvh_serial(bvh, bboxes, highquality); } -bvh_shape make_bvh(const shape_data& shape, bool highquality, bool embree) { +bvh_data make_bvh(const shape_data& shape, bool highquality, bool embree) { // bvh - auto bvh = bvh_shape{}; + auto bvh = bvh_data{}; // build scene bvh build_bvh(bvh, shape, highquality, embree); @@ -706,10 +706,10 @@ bvh_shape make_bvh(const shape_data& shape, bool highquality, bool embree) { return bvh; } -bvh_scene make_bvh( +bvh_data make_bvh( const scene_data& scene, bool highquality, bool embree, bool noparallel) { // bvh - auto bvh = bvh_scene{}; + auto bvh = bvh_data{}; // build shape bvh bvh.shapes.resize(scene.shapes.size()); @@ -731,7 +731,7 @@ bvh_scene make_bvh( return bvh; } -static void refit_bvh(bvh_shape& bvh, const shape_data& shape) { +static void refit_bvh(bvh_data& bvh, const shape_data& shape) { #ifdef YOCTO_EMBREE if (bvh.embree_bvh) { throw std::runtime_error("embree shape refit not supported"); @@ -770,10 +770,10 @@ static void refit_bvh(bvh_shape& bvh, const shape_data& shape) { } // update nodes - refit_bvh(bvh.bvh, bboxes); + refit_bvh(bvh, bboxes); } -void refit_bvh(bvh_scene& bvh, const scene_data& scene, +void refit_bvh(bvh_data& bvh, const scene_data& scene, const vector& updated_instances) { #ifdef YOCTO_EMBREE if (bvh.embree_bvh) { @@ -785,20 +785,20 @@ void refit_bvh(bvh_scene& bvh, const scene_data& scene, auto bboxes = vector(scene.instances.size()); for (auto idx = 0; idx < bboxes.size(); idx++) { auto& instance = scene.instances[idx]; - auto& sbvh = bvh.shapes[instance.shape].bvh; + auto& sbvh = bvh.shapes[instance.shape]; bboxes[idx] = transform_bbox(instance.frame, sbvh.nodes[0].bbox); } // update nodes - refit_bvh(bvh.bvh, bboxes); + refit_bvh(bvh, bboxes); } -void update_bvh(bvh_shape& bvh, const shape_data& shape) { +void update_bvh(bvh_data& bvh, const shape_data& shape) { // handle instances refit_bvh(bvh, shape); } -void update_bvh(bvh_scene& bvh, const scene_data& scene, +void update_bvh(bvh_data& bvh, const scene_data& scene, const vector& updated_instances, const vector& updated_shapes) { // update shapes for (auto shape : updated_shapes) { @@ -817,7 +817,7 @@ void update_bvh(bvh_scene& bvh, const scene_data& scene, namespace yocto { // Intersect ray with a bvh. -static bool intersect_bvh(const bvh_shape& bvh, const shape_data& shape, +static bool intersect_bvh(const bvh_data& bvh, const shape_data& shape, const ray3f& ray_, int& element, vec2f& uv, float& distance, bool find_any) { #ifdef YOCTO_EMBREE @@ -829,7 +829,7 @@ static bool intersect_bvh(const bvh_shape& bvh, const shape_data& shape, #endif // check empty - if (bvh.bvh.nodes.empty()) return false; + if (bvh.nodes.empty()) return false; // node stack auto node_stack = array{}; @@ -850,7 +850,7 @@ static bool intersect_bvh(const bvh_shape& bvh, const shape_data& shape, // walking stack while (node_cur != 0) { // grab node - auto& node = bvh.bvh.nodes[node_stack[--node_cur]]; + auto& node = bvh.nodes[node_stack[--node_cur]]; // intersect bbox // if (!intersect_bbox(ray, ray_dinv, ray_dsign, node.bbox)) continue; @@ -870,41 +870,41 @@ static bool intersect_bvh(const bvh_shape& bvh, const shape_data& shape, } } else if (!shape.points.empty()) { for (auto idx = node.start; idx < node.start + node.num; idx++) { - auto& p = shape.points[bvh.bvh.primitives[idx]]; + auto& p = shape.points[bvh.primitives[idx]]; if (intersect_point( ray, shape.positions[p], shape.radius[p], uv, distance)) { hit = true; - element = bvh.bvh.primitives[idx]; + element = bvh.primitives[idx]; ray.tmax = distance; } } } else if (!shape.lines.empty()) { for (auto idx = node.start; idx < node.start + node.num; idx++) { - auto& l = shape.lines[bvh.bvh.primitives[idx]]; + auto& l = shape.lines[bvh.primitives[idx]]; if (intersect_line(ray, shape.positions[l.x], shape.positions[l.y], shape.radius[l.x], shape.radius[l.y], uv, distance)) { hit = true; - element = bvh.bvh.primitives[idx]; + element = bvh.primitives[idx]; ray.tmax = distance; } } } else if (!shape.triangles.empty()) { for (auto idx = node.start; idx < node.start + node.num; idx++) { - auto& t = shape.triangles[bvh.bvh.primitives[idx]]; + auto& t = shape.triangles[bvh.primitives[idx]]; if (intersect_triangle(ray, shape.positions[t.x], shape.positions[t.y], shape.positions[t.z], uv, distance)) { hit = true; - element = bvh.bvh.primitives[idx]; + element = bvh.primitives[idx]; ray.tmax = distance; } } } else if (!shape.quads.empty()) { for (auto idx = node.start; idx < node.start + node.num; idx++) { - auto& q = shape.quads[bvh.bvh.primitives[idx]]; + auto& q = shape.quads[bvh.primitives[idx]]; if (intersect_quad(ray, shape.positions[q.x], shape.positions[q.y], shape.positions[q.z], shape.positions[q.w], uv, distance)) { hit = true; - element = bvh.bvh.primitives[idx]; + element = bvh.primitives[idx]; ray.tmax = distance; } } @@ -918,7 +918,7 @@ static bool intersect_bvh(const bvh_shape& bvh, const shape_data& shape, } // Intersect ray with a bvh. -static bool intersect_bvh(const bvh_scene& bvh, const scene_data& scene, +static bool intersect_bvh(const bvh_data& bvh, const scene_data& scene, const ray3f& ray_, int& instance, int& element, vec2f& uv, float& distance, bool find_any, bool non_rigid_frames) { #ifdef YOCTO_EMBREE @@ -930,7 +930,7 @@ static bool intersect_bvh(const bvh_scene& bvh, const scene_data& scene, #endif // check empty - if (bvh.bvh.nodes.empty()) return false; + if (bvh.nodes.empty()) return false; // node stack auto node_stack = array{}; @@ -951,7 +951,7 @@ static bool intersect_bvh(const bvh_scene& bvh, const scene_data& scene, // walking stack while (node_cur != 0) { // grab node - auto& node = bvh.bvh.nodes[node_stack[--node_cur]]; + auto& node = bvh.nodes[node_stack[--node_cur]]; // intersect bbox // if (!intersect_bbox(ray, ray_dinv, ray_dsign, node.bbox)) continue; @@ -971,14 +971,14 @@ static bool intersect_bvh(const bvh_scene& bvh, const scene_data& scene, } } else { for (auto idx = node.start; idx < node.start + node.num; idx++) { - auto& instance_ = scene.instances[bvh.bvh.primitives[idx]]; + auto& instance_ = scene.instances[bvh.primitives[idx]]; auto inv_ray = transform_ray( inverse(instance_.frame, non_rigid_frames), ray); if (intersect_bvh(bvh.shapes[instance_.shape], scene.shapes[instance_.shape], inv_ray, element, uv, distance, find_any)) { hit = true; - instance = bvh.bvh.primitives[idx]; + instance = bvh.primitives[idx]; ray.tmax = distance; } } @@ -992,7 +992,7 @@ static bool intersect_bvh(const bvh_scene& bvh, const scene_data& scene, } // Intersect ray with a bvh. -static bool intersect_bvh(const bvh_scene& bvh, const scene_data& scene, +static bool intersect_bvh(const bvh_data& bvh, const scene_data& scene, int instance_, const ray3f& ray, int& element, vec2f& uv, float& distance, bool find_any, bool non_rigid_frames) { auto& instance = scene.instances[instance_]; @@ -1009,11 +1009,11 @@ static bool intersect_bvh(const bvh_scene& bvh, const scene_data& scene, namespace yocto { // Intersect ray with a bvh. -static bool overlap_bvh(const bvh_shape& bvh, const shape_data& shape, +static bool overlap_bvh(const bvh_data& bvh, const shape_data& shape, const vec3f& pos, float max_distance, int& element, vec2f& uv, float& distance, bool find_any) { // check if empty - if (bvh.bvh.nodes.empty()) return false; + if (bvh.nodes.empty()) return false; // node stack auto node_stack = array{}; @@ -1026,7 +1026,7 @@ static bool overlap_bvh(const bvh_shape& bvh, const shape_data& shape, // walking stack while (node_cur != 0) { // grab node - auto& node = bvh.bvh.nodes[node_stack[--node_cur]]; + auto& node = bvh.nodes[node_stack[--node_cur]]; // intersect bbox if (!overlap_bbox(pos, max_distance, node.bbox)) continue; @@ -1039,7 +1039,7 @@ static bool overlap_bvh(const bvh_shape& bvh, const shape_data& shape, node_stack[node_cur++] = node.start + 1; } else if (!shape.points.empty()) { for (auto idx = 0; idx < node.num; idx++) { - auto primitive = bvh.bvh.primitives[node.start + idx]; + auto primitive = bvh.primitives[node.start + idx]; auto& p = shape.points[primitive]; if (overlap_point(pos, max_distance, shape.positions[p], shape.radius[p], uv, distance)) { @@ -1050,7 +1050,7 @@ static bool overlap_bvh(const bvh_shape& bvh, const shape_data& shape, } } else if (!shape.lines.empty()) { for (auto idx = 0; idx < node.num; idx++) { - auto primitive = bvh.bvh.primitives[node.start + idx]; + auto primitive = bvh.primitives[node.start + idx]; auto& l = shape.lines[primitive]; if (overlap_line(pos, max_distance, shape.positions[l.x], shape.positions[l.y], shape.radius[l.x], shape.radius[l.y], uv, @@ -1062,7 +1062,7 @@ static bool overlap_bvh(const bvh_shape& bvh, const shape_data& shape, } } else if (!shape.triangles.empty()) { for (auto idx = 0; idx < node.num; idx++) { - auto primitive = bvh.bvh.primitives[node.start + idx]; + auto primitive = bvh.primitives[node.start + idx]; auto& t = shape.triangles[primitive]; if (overlap_triangle(pos, max_distance, shape.positions[t.x], shape.positions[t.y], shape.positions[t.z], shape.radius[t.x], @@ -1074,7 +1074,7 @@ static bool overlap_bvh(const bvh_shape& bvh, const shape_data& shape, } } else if (!shape.quads.empty()) { for (auto idx = 0; idx < node.num; idx++) { - auto primitive = bvh.bvh.primitives[node.start + idx]; + auto primitive = bvh.primitives[node.start + idx]; auto& q = shape.quads[primitive]; if (overlap_quad(pos, max_distance, shape.positions[q.x], shape.positions[q.y], shape.positions[q.z], @@ -1095,11 +1095,11 @@ static bool overlap_bvh(const bvh_shape& bvh, const shape_data& shape, } // Intersect ray with a bvh. -static bool overlap_bvh(const bvh_scene& bvh, const scene_data& scene, +static bool overlap_bvh(const bvh_data& bvh, const scene_data& scene, const vec3f& pos, float max_distance, int& instance, int& element, vec2f& uv, float& distance, bool find_any, bool non_rigid_frames) { // check if empty - if (bvh.bvh.nodes.empty()) return false; + if (bvh.nodes.empty()) return false; // node stack auto node_stack = array{}; @@ -1112,7 +1112,7 @@ static bool overlap_bvh(const bvh_scene& bvh, const scene_data& scene, // walking stack while (node_cur != 0) { // grab node - auto& node = bvh.bvh.nodes[node_stack[--node_cur]]; + auto& node = bvh.nodes[node_stack[--node_cur]]; // intersect bbox if (!overlap_bbox(pos, max_distance, node.bbox)) continue; @@ -1125,7 +1125,7 @@ static bool overlap_bvh(const bvh_scene& bvh, const scene_data& scene, node_stack[node_cur++] = node.start + 1; } else { for (auto idx = 0; idx < node.num; idx++) { - auto primitive = bvh.bvh.primitives[node.start + idx]; + auto primitive = bvh.primitives[node.start + idx]; auto& instance_ = scene.instances[primitive]; auto& shape = scene.shapes[instance_.shape]; auto& sbvh = bvh.shapes[instance_.shape]; @@ -1208,7 +1208,7 @@ void overlap_bvh_elems(const bvh_data& bvh1, const bvh_data& bvh2, } #endif -bvh_intersection intersect_bvh(const bvh_scene& bvh, const scene_data& scene, +bvh_intersection intersect_bvh(const bvh_data& bvh, const scene_data& scene, const ray3f& ray, bool find_any, bool non_rigid_frames) { auto intersection = bvh_intersection{}; intersection.hit = intersect_bvh(bvh, scene, ray, intersection.instance, @@ -1216,7 +1216,7 @@ bvh_intersection intersect_bvh(const bvh_scene& bvh, const scene_data& scene, non_rigid_frames); return intersection; } -bvh_intersection intersect_bvh(const bvh_scene& bvh, const scene_data& scene, +bvh_intersection intersect_bvh(const bvh_data& bvh, const scene_data& scene, int instance, const ray3f& ray, bool find_any, bool non_rigid_frames) { auto intersection = bvh_intersection{}; intersection.hit = intersect_bvh(bvh, scene, instance, ray, @@ -1226,7 +1226,7 @@ bvh_intersection intersect_bvh(const bvh_scene& bvh, const scene_data& scene, return intersection; } -bvh_intersection overlap_bvh(const bvh_scene& bvh, const scene_data& scene, +bvh_intersection overlap_bvh(const bvh_data& bvh, const scene_data& scene, const vec3f& pos, float max_distance, bool find_any, bool non_rigid_frames) { auto intersection = bvh_intersection{}; diff --git a/libs/yocto/yocto_bvh.h b/libs/yocto/yocto_bvh.h index 4f69d68b9..b36dafefd 100644 --- a/libs/yocto/yocto_bvh.h +++ b/libs/yocto/yocto_bvh.h @@ -81,34 +81,25 @@ struct bvh_node { // BVH tree stored as a node array with the tree structure is encoded using // array indices. BVH nodes indices refer to either the node array, // for internal nodes, or the primitive arrays, for leaf nodes. +// For instance BVHs, we also store the BVH of the contained shapes. // Application data is not stored explicitly. -struct bvh_tree { - vector nodes = {}; - vector primitives = {}; -}; - -// BVH data for whole shapes. This interface makes copies of all the data. -struct bvh_shape { - bvh_tree bvh = {}; // nodes - unique_ptr embree_bvh = {nullptr, nullptr}; // embree -}; - -// BVH data for whole shapes. This interface makes copies of all the data. -struct bvh_scene { - bvh_tree bvh = {}; // nodes - vector shapes = {}; // shapes +// Additionally, we support the use of Intel Embree. +struct bvh_data { + vector nodes = {}; + vector primitives = {}; + vector shapes = {}; // shapes unique_ptr embree_bvh = {nullptr, nullptr}; // embree }; // Build the bvh acceleration structure. -bvh_shape make_bvh( +bvh_data make_bvh( const shape_data& shape, bool highquality = false, bool embree = false); -bvh_scene make_bvh(const scene_data& scene, bool highquality = false, +bvh_data make_bvh(const scene_data& scene, bool highquality = false, bool embree = false, bool noparallel = false); // Refit bvh data -void update_bvh(bvh_shape& bvh, const shape_data& shape); -void update_bvh(bvh_scene& bvh, const scene_data& scene, +void update_bvh(bvh_data& bvh, const shape_data& shape); +void update_bvh(bvh_data& bvh, const scene_data& scene, const vector& updated_instances, const vector& updated_shapes); // Results of intersect_xxx and overlap_xxx functions that include hit flag, @@ -127,11 +118,11 @@ struct bvh_intersection { // Intersect ray with a bvh returning either the first or any intersection // depending on `find_any`. Returns the ray distance , the instance id, // the shape element index and the element barycentric coordinates. -bvh_intersection intersect_bvh(const bvh_shape& bvh, const shape_data& shape, +bvh_intersection intersect_bvh(const bvh_data& bvh, const shape_data& shape, const ray3f& ray, bool find_any = false, bool non_rigid_frames = true); -bvh_intersection intersect_bvh(const bvh_scene& bvh, const scene_data& scene, +bvh_intersection intersect_bvh(const bvh_data& bvh, const scene_data& scene, const ray3f& ray, bool find_any = false, bool non_rigid_frames = true); -bvh_intersection intersect_bvh(const bvh_scene& bvh, const scene_data& scene, +bvh_intersection intersect_bvh(const bvh_data& bvh, const scene_data& scene, int instance, const ray3f& ray, bool find_any = false, bool non_rigid_frames = true); @@ -139,9 +130,9 @@ bvh_intersection intersect_bvh(const bvh_scene& bvh, const scene_data& scene, // max distance, returning either the closest or any overlap depending on // `find_any`. Returns the point distance, the instance id, the shape element // index and the element barycentric coordinates. -bvh_intersection overlap_bvh(const bvh_shape& bvh, const shape_data& shape, +bvh_intersection overlap_bvh(const bvh_data& bvh, const shape_data& shape, const vec3f& pos, float max_distance, bool find_any = false); -bvh_intersection overlap_bvh(const bvh_scene& bvh, const scene_data& scene, +bvh_intersection overlap_bvh(const bvh_data& bvh, const scene_data& scene, const vec3f& pos, float max_distance, bool find_any = false, bool non_rigid_frames = true); diff --git a/libs/yocto/yocto_trace.cpp b/libs/yocto/yocto_trace.cpp index bd02134ae..3bf5f13b0 100644 --- a/libs/yocto/yocto_trace.cpp +++ b/libs/yocto/yocto_trace.cpp @@ -51,7 +51,7 @@ namespace yocto { // Build the bvh acceleration structure. -bvh_scene make_bvh(const scene_data& scene, const trace_params& params) { +bvh_data make_bvh(const scene_data& scene, const trace_params& params) { return make_bvh( scene, params.highqualitybvh, params.embreebvh, params.noparallel); } @@ -289,7 +289,7 @@ static vec3f sample_lights(const scene_data& scene, const trace_lights& lights, } // Sample lights pdf -static float sample_lights_pdf(const scene_data& scene, const bvh_scene& bvh, +static float sample_lights_pdf(const scene_data& scene, const bvh_data& bvh, const trace_lights& lights, const vec3f& position, const vec3f& direction) { auto pdf = 0.0f; for (auto& light : lights.lights) { @@ -351,7 +351,7 @@ struct trace_result { }; // Recursive path tracing. -static trace_result trace_path(const scene_data& scene, const bvh_scene& bvh, +static trace_result trace_path(const scene_data& scene, const bvh_data& bvh, const trace_lights& lights, const ray3f& ray_, rng_state& rng, const trace_params& params) { // initialize @@ -499,7 +499,7 @@ static trace_result trace_path(const scene_data& scene, const bvh_scene& bvh, // Recursive path tracing. static trace_result trace_pathdirect(const scene_data& scene, - const bvh_scene& bvh, const trace_lights& lights, const ray3f& ray_, + const bvh_data& bvh, const trace_lights& lights, const ray3f& ray_, rng_state& rng, const trace_params& params) { // initialize auto radiance = zero3f; @@ -669,7 +669,7 @@ static trace_result trace_pathdirect(const scene_data& scene, } // Recursive path tracing with MIS. -static trace_result trace_pathmis(const scene_data& scene, const bvh_scene& bvh, +static trace_result trace_pathmis(const scene_data& scene, const bvh_data& bvh, const trace_lights& lights, const ray3f& ray_, rng_state& rng, const trace_params& params) { // initialize @@ -853,7 +853,7 @@ static trace_result trace_pathmis(const scene_data& scene, const bvh_scene& bvh, } // Recursive path tracing. -static trace_result trace_naive(const scene_data& scene, const bvh_scene& bvh, +static trace_result trace_naive(const scene_data& scene, const bvh_data& bvh, const trace_lights& lights, const ray3f& ray_, rng_state& rng, const trace_params& params) { // initialize @@ -933,9 +933,9 @@ static trace_result trace_naive(const scene_data& scene, const bvh_scene& bvh, } // Eyelight for quick previewing. -static trace_result trace_eyelight(const scene_data& scene, - const bvh_scene& bvh, const trace_lights& lights, const ray3f& ray_, - rng_state& rng, const trace_params& params) { +static trace_result trace_eyelight(const scene_data& scene, const bvh_data& bvh, + const trace_lights& lights, const ray3f& ray_, rng_state& rng, + const trace_params& params) { // initialize auto radiance = zero3f; auto weight = vec3f{1, 1, 1}; @@ -1003,7 +1003,7 @@ static trace_result trace_eyelight(const scene_data& scene, // Eyelight with ambient occlusion for quick previewing. static trace_result trace_eyelightao(const scene_data& scene, - const bvh_scene& bvh, const trace_lights& lights, const ray3f& ray_, + const bvh_data& bvh, const trace_lights& lights, const ray3f& ray_, rng_state& rng, const trace_params& params) { // initialize auto radiance = zero3f; @@ -1076,7 +1076,7 @@ static trace_result trace_eyelightao(const scene_data& scene, // False color rendering static trace_result trace_falsecolor(const scene_data& scene, - const bvh_scene& bvh, const trace_lights& lights, const ray3f& ray, + const bvh_data& bvh, const trace_lights& lights, const ray3f& ray, rng_state& rng, const trace_params& params) { // intersect next point auto intersection = intersect_bvh(bvh, scene, ray); @@ -1159,7 +1159,7 @@ static trace_result trace_falsecolor(const scene_data& scene, // Trace a single ray from the camera using the given algorithm. using sampler_func = trace_result (*)(const scene_data& scene, - const bvh_scene& bvh, const trace_lights& lights, const ray3f& ray, + const bvh_data& bvh, const trace_lights& lights, const ray3f& ray, rng_state& rng, const trace_params& params); static sampler_func get_trace_sampler_func(const trace_params& params) { switch (params.sampler) { @@ -1195,7 +1195,7 @@ bool is_sampler_lit(const trace_params& params) { // Trace a block of samples void trace_sample(trace_state& state, const scene_data& scene, - const bvh_scene& bvh, const trace_lights& lights, int i, int j, + const bvh_data& bvh, const trace_lights& lights, int i, int j, const trace_params& params) { auto& camera = scene.cameras[params.camera]; auto sampler = get_trace_sampler_func(params); @@ -1317,7 +1317,7 @@ image_data trace_image(const scene_data& scene, const trace_params& params) { // Progressively compute an image by calling trace_samples multiple times. void trace_samples(trace_state& state, const scene_data& scene, - const bvh_scene& bvh, const trace_lights& lights, + const bvh_data& bvh, const trace_lights& lights, const trace_params& params) { if (state.samples >= params.samples) return; if (params.noparallel) { diff --git a/libs/yocto/yocto_trace.h b/libs/yocto/yocto_trace.h index f4cb12b86..595160680 100644 --- a/libs/yocto/yocto_trace.h +++ b/libs/yocto/yocto_trace.h @@ -170,14 +170,14 @@ trace_state make_state(const scene_data& scene, const trace_params& params); trace_lights make_lights(const scene_data& scene, const trace_params& params); // Build the bvh acceleration structure. -bvh_scene make_bvh(const scene_data& scene, const trace_params& params); +bvh_data make_bvh(const scene_data& scene, const trace_params& params); // Progressively computes an image. void trace_samples(trace_state& state, const scene_data& scene, - const bvh_scene& bvh, const trace_lights& lights, + const bvh_data& bvh, const trace_lights& lights, const trace_params& params); void trace_sample(trace_state& state, const scene_data& scene, - const bvh_scene& bvh, const trace_lights& lights, int i, int j, + const bvh_data& bvh, const trace_lights& lights, int i, int j, const trace_params& params); // Get resulting render From 7b05986a4617cced3f4087b52b67d0036cdd8c83 Mon Sep 17 00:00:00 2001 From: Fabio Pellacini Date: Wed, 9 Jun 2021 16:04:11 +0200 Subject: [PATCH 11/12] updated --- libs/yocto/yocto_bvh.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/libs/yocto/yocto_bvh.h b/libs/yocto/yocto_bvh.h index b36dafefd..317657371 100644 --- a/libs/yocto/yocto_bvh.h +++ b/libs/yocto/yocto_bvh.h @@ -138,4 +138,14 @@ bvh_intersection overlap_bvh(const bvh_data& bvh, const scene_data& scene, } // namespace yocto +// ----------------------------------------------------------------------------- +// BACKWARDS COMPATIBILITY +// ----------------------------------------------------------------------------- +namespace yocto { + +using bvh_shape = bvh_data; +using bvh_scene = bvh_data; + +} // namespace yocto + #endif From 1812db84a5bc0c2aa3037b4e42c7ce4c7218ad17 Mon Sep 17 00:00:00 2001 From: Fabio Pellacini Date: Wed, 9 Jun 2021 16:33:10 +0200 Subject: [PATCH 12/12] updated --- libs/yocto/yocto_math.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/libs/yocto/yocto_math.h b/libs/yocto/yocto_math.h index b22bd9cf7..b849aee93 100644 --- a/libs/yocto/yocto_math.h +++ b/libs/yocto/yocto_math.h @@ -75,6 +75,7 @@ inline float min(float a, float b); inline float max(float a, float b); inline float clamp(float a, float min, float max); inline float sign(float a); +inline float sqr(float a); inline float sqrt(float a); inline float sin(float a); inline float cos(float a); @@ -222,6 +223,7 @@ inline float mean(const vec2f& a); // Functions applied to vector elements inline vec2f abs(const vec2f& a); +inline vec2f sqr(const vec2f& a); inline vec2f sqrt(const vec2f& a); inline vec2f exp(const vec2f& a); inline vec2f log(const vec2f& a); @@ -307,6 +309,7 @@ inline float mean(const vec3f& a); // Functions applied to vector elements inline vec3f abs(const vec3f& a); +inline vec3f sqr(const vec3f& a); inline vec3f sqrt(const vec3f& a); inline vec3f exp(const vec3f& a); inline vec3f log(const vec3f& a); @@ -384,6 +387,7 @@ inline float mean(const vec4f& a); // Functions applied to vector elements inline vec4f abs(const vec4f& a); +inline vec4f sqr(const vec4f& a); inline vec4f sqrt(const vec4f& a); inline vec4f exp(const vec4f& a); inline vec4f log(const vec4f& a); @@ -637,6 +641,7 @@ inline double min(double a, double b); inline double max(double a, double b); inline double clamp(double a, double min, double max); inline double sign(double a); +inline double sqr(double a); inline double sqrt(double a); inline double sin(double a); inline double cos(double a); @@ -773,6 +778,7 @@ inline double mean(const vec2d& a); // Functions applied to vector elements inline vec2d abs(const vec2d& a); +inline vec2d sqr(const vec2d& a); inline vec2d sqrt(const vec2d& a); inline vec2d exp(const vec2d& a); inline vec2d log(const vec2d& a); @@ -858,6 +864,7 @@ inline double mean(const vec3d& a); // Functions applied to vector elements inline vec3d abs(const vec3d& a); +inline vec3d sqr(const vec3d& a); inline vec3d sqrt(const vec3d& a); inline vec3d exp(const vec3d& a); inline vec3d log(const vec3d& a); @@ -935,6 +942,7 @@ inline double mean(const vec4d& a); // Functions applied to vector elements inline vec4d abs(const vec4d& a); +inline vec4d sqr(const vec4d& a); inline vec4d sqrt(const vec4d& a); inline vec4d exp(const vec4d& a); inline vec4d log(const vec4d& a); @@ -1339,6 +1347,7 @@ inline float clamp(float a, float min_, float max_) { return min(max(a, min_), max_); } inline float sign(float a) { return a < 0 ? -1.0f : 1.0f; } +inline float sqr(float a) { return a * a; } inline float sqrt(float a) { return std::sqrt(a); } inline float sin(float a) { return std::sin(a); } inline float cos(float a) { return std::cos(a); } @@ -1503,6 +1512,7 @@ inline float mean(const vec2f& a) { return sum(a) / 2; } // Functions applied to vector elements inline vec2f abs(const vec2f& a) { return {abs(a.x), abs(a.y)}; } +inline vec2f sqr(const vec2f& a) { return {sqr(a.x), sqr(a.y)}; } inline vec2f sqrt(const vec2f& a) { return {sqrt(a.x), sqrt(a.y)}; } inline vec2f exp(const vec2f& a) { return {exp(a.x), exp(a.y)}; } inline vec2f log(const vec2f& a) { return {log(a.x), log(a.y)}; } @@ -1657,6 +1667,7 @@ inline float mean(const vec3f& a) { return sum(a) / 3; } // Functions applied to vector elements inline vec3f abs(const vec3f& a) { return {abs(a.x), abs(a.y), abs(a.z)}; } +inline vec3f sqr(const vec3f& a) { return {sqr(a.x), sqr(a.y), sqr(a.z)}; } inline vec3f sqrt(const vec3f& a) { return {sqrt(a.x), sqrt(a.y), sqrt(a.z)}; } inline vec3f exp(const vec3f& a) { return {exp(a.x), exp(a.y), exp(a.z)}; } inline vec3f log(const vec3f& a) { return {log(a.x), log(a.y), log(a.z)}; } @@ -1808,6 +1819,9 @@ inline float mean(const vec4f& a) { return sum(a) / 4; } inline vec4f abs(const vec4f& a) { return {abs(a.x), abs(a.y), abs(a.z), abs(a.w)}; } +inline vec4f sqr(const vec4f& a) { + return {sqr(a.x), sqr(a.y), sqr(a.z), sqr(a.w)}; +} inline vec4f sqrt(const vec4f& a) { return {sqrt(a.x), sqrt(a.y), sqrt(a.z), sqrt(a.w)}; } @@ -2160,6 +2174,7 @@ inline double clamp(double a, double min_, double max_) { return min(max(a, min_), max_); } inline double sign(double a) { return a < 0 ? -1 : 1; } +inline double sqr(double a) { return a * a; } inline double sqrt(double a) { return std::sqrt(a); } inline double sin(double a) { return std::sin(a); } inline double cos(double a) { return std::cos(a); } @@ -2317,6 +2332,7 @@ inline double mean(const vec2d& a) { return sum(a) / 2; } // Functions applied to vector elements inline vec2d abs(const vec2d& a) { return {abs(a.x), abs(a.y)}; } +inline vec2d sqr(const vec2d& a) { return {sqr(a.x), sqr(a.y)}; } inline vec2d sqrt(const vec2d& a) { return {sqrt(a.x), sqrt(a.y)}; } inline vec2d exp(const vec2d& a) { return {exp(a.x), exp(a.y)}; } inline vec2d log(const vec2d& a) { return {log(a.x), log(a.y)}; } @@ -2473,6 +2489,7 @@ inline double mean(const vec3d& a) { return sum(a) / 3; } // Functions applied to vector elements inline vec3d abs(const vec3d& a) { return {abs(a.x), abs(a.y), abs(a.z)}; } +inline vec3d sqr(const vec3d& a) { return {sqr(a.x), sqr(a.y), sqr(a.z)}; } inline vec3d sqrt(const vec3d& a) { return {sqrt(a.x), sqrt(a.y), sqrt(a.z)}; } inline vec3d exp(const vec3d& a) { return {exp(a.x), exp(a.y), exp(a.z)}; } inline vec3d log(const vec3d& a) { return {log(a.x), log(a.y), log(a.z)}; } @@ -2624,6 +2641,9 @@ inline double mean(const vec4d& a) { return sum(a) / 4; } inline vec4d abs(const vec4d& a) { return {abs(a.x), abs(a.y), abs(a.z), abs(a.w)}; } +inline vec4d sqr(const vec4d& a) { + return {sqr(a.x), sqr(a.y), sqr(a.z), sqr(a.w)}; +} inline vec4d sqrt(const vec4d& a) { return {sqrt(a.x), sqrt(a.y), sqrt(a.z), sqrt(a.w)}; }