diff --git a/CHANGELOG.md b/CHANGELOG.md index 7347ce55a..f7c8777ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,49 @@ Change Log ========== -MDL SDK 2021.1 (349500.7063): 18 Jan 2022 +MDL SDK 2021.1.1 (349500.8264): 18 Mar 2022 ----------------------------------------------- +ABI compatible with the MDL SDK 2021.1.1 (349500.8264) binary release +(see [https://developer.nvidia.com/mdl-sdk](https://developer.nvidia.com/mdl-sdk)) + +**Known Issues** + +- The version text in the MI_NEURAYLIB_PRODUCT_VERSION_STRING macro + in the version.h include file contains the previous version number + of "2021.1" instead of "2021.1.1". + +**Added and Changed Features** + +- Image File Format Plugins + + - Support .rgb extension for textures in the SGI file format. + +**Fixed Bugs** + +- General + + - Fixed filename extension mismatch when exporting textures referenced from MDL modules. + Under certain circumstances, the texture was copied, but got a different filename extension, + causing problems importing the MDL module again. + - Fixed creation of function calls of the cast operator if the target type has frequency + qualifiers. Similarly, fixed creation of function calls of the ternary operator if the + argument types have frequency qualifiers. + - Fixed handling of memory allocation failures in `IImage_api::create_canvas()/create_tile()` + methods. + - Also encode the simple name of function definitions. For almost all functions this does not + make any change since the simple name is usually an identifier, except for a couple of + operators from the builtins module. + +- MDL Compiler and Backends + + - libbsdf: Fixed incorrect child normal orientation usage in `df::(color_)fresnel_layer`, + `df::(color_)custom_curve_layer` and `df::(color_)measured_curve_layer` for backside hits. + - HLSL backend: Fixed code generation for scene data access functions inside automatically + derived expressions. + +MDL SDK 2021.1 (349500.7063): 26 Jan 2022 +----------------------------------------- + ABI compatible with the MDL SDK 2021.1 (349500.7063) binary release (see [https://developer.nvidia.com/mdl-sdk](https://developer.nvidia.com/mdl-sdk)) diff --git a/README.md b/README.md index b7c0d12e4..f13d1553e 100644 --- a/README.md +++ b/README.md @@ -297,7 +297,7 @@ Required tools to build the documentation: are available in the package management system: ```bash - sudo apt-get install git build-essential python cmake g++ + sudo apt-get install git git-lfs build-essential python cmake sudo apt-get install libboost-dev libfreeimage-dev libglew-dev libglfw3-dev ``` @@ -318,6 +318,7 @@ Required tools to build the documentation: ```bash export MDL_SDK_ROOT=$HOME/projects/mdl-sdk + git lfs install git clone https://github.com/NVIDIA/MDL-SDK.git $MDL_SDK_ROOT ``` diff --git a/doc/base_module/index.html b/doc/base_module/index.html index 7571435e6..68b8d88be 100644 --- a/doc/base_module/index.html +++ b/doc/base_module/index.html @@ -155,7 +155,7 @@

Edge

-18 January 2022, 21:07, rev.349500.7063 +18 March 2022, 20:50, rev.349500.8264 © 2022 NVIDIA Corporation. All rights reserved. diff --git a/doc/build/doxygen_footer_1_8_4.html b/doc/build/doxygen_footer_1_8_4.html index e7259a347..7180b7571 100644 --- a/doc/build/doxygen_footer_1_8_4.html +++ b/doc/build/doxygen_footer_1_8_4.html @@ -2,10 +2,10 @@ diff --git a/doc/core_definitions/index.html b/doc/core_definitions/index.html index 2c6fc4552..83fa62a9b 100644 --- a/doc/core_definitions/index.html +++ b/doc/core_definitions/index.html @@ -186,8 +186,8 @@

Page cannot be loaded

bottom of the page or from the following links:

-View documentation in A4 format
-View documentation in US Letter format
+View documentation in A4 format
+View documentation in US Letter format

Overriding security settings

@@ -261,7 +261,7 @@

Edge

-18 January 2022, 21:08, rev.349500.7063 +18 March 2022, 20:52, rev.349500.8264 © 2022 NVIDIA Corporation. All rights reserved. diff --git a/doc/core_definitions/kt_js/s_image.js b/doc/core_definitions/kt_js/s_image.js old mode 100755 new mode 100644 diff --git a/doc/core_definitions/kt_js/search.js b/doc/core_definitions/kt_js/search.js old mode 100755 new mode 100644 diff --git a/doc/core_definitions/kt_js/toc.js b/doc/core_definitions/kt_js/toc.js old mode 100755 new mode 100644 diff --git a/doc/index.html b/doc/index.html index 4083204fd..c982885da 100644 --- a/doc/index.html +++ b/doc/index.html @@ -61,11 +61,11 @@
- MDL SDK 2021.1 (349500.7063): 18 Jan 2022 + MDL SDK 2021.1 (349500.8264): 18 Mar 2022 - © 2020 NVIDIA Corporation.  All rights reserved. + © 2022 NVIDIA Corporation.  All rights reserved.
diff --git a/doc/mdl_sdkapi/Doxyfile b/doc/mdl_sdkapi/Doxyfile index 22eaa10ba..fb89cd452 100644 --- a/doc/mdl_sdkapi/Doxyfile +++ b/doc/mdl_sdkapi/Doxyfile @@ -668,7 +668,92 @@ WARN_LOGFILE = INPUT = . \ ../../include/mi/mdl_sdk.h \ - ../../include/mi/neuraylib \ + ../../include/mi/neuraylib/annotation_wrapper.h \ + ../../include/mi/neuraylib/argument_editor.h \ + ../../include/mi/neuraylib/assert.h \ + ../../include/mi/neuraylib/bsdf_isotropic_data.h \ + ../../include/mi/neuraylib/definition_wrapper.h \ + ../../include/mi/neuraylib/factory.h \ + ../../include/mi/neuraylib/iallocator.h \ + ../../include/mi/neuraylib/iarray.h \ + ../../include/mi/neuraylib/iattribute_container.h \ + ../../include/mi/neuraylib/iattribute_set.h \ + ../../include/mi/neuraylib/ibbox.h \ + ../../include/mi/neuraylib/ibsdf_isotropic_data.h \ + ../../include/mi/neuraylib/ibsdf_measurement.h \ + ../../include/mi/neuraylib/ibuffer.h \ + ../../include/mi/neuraylib/icanvas.h \ + ../../include/mi/neuraylib/icolor.h \ + ../../include/mi/neuraylib/icompiled_material.h \ + ../../include/mi/neuraylib/icompound.h \ + ../../include/mi/neuraylib/idata.h \ + ../../include/mi/neuraylib/idatabase.h \ + ../../include/mi/neuraylib/idebug_configuration.h \ + ../../include/mi/neuraylib/idynamic_array.h \ + ../../include/mi/neuraylib/ienum.h \ + ../../include/mi/neuraylib/ienum_decl.h \ + ../../include/mi/neuraylib/iexpression.h \ + ../../include/mi/neuraylib/ifactory.h \ + ../../include/mi/neuraylib/ifunction_call.h \ + ../../include/mi/neuraylib/ifunction_definition.h \ + ../../include/mi/neuraylib/iimage.h \ + ../../include/mi/neuraylib/iimage_api.h \ + ../../include/mi/neuraylib/iimage_plugin.h \ + ../../include/mi/neuraylib/iimpexp_base.h \ + ../../include/mi/neuraylib/ilightprofile.h \ + ../../include/mi/neuraylib/imap.h \ + ../../include/mi/neuraylib/imaterial_definition.h \ + ../../include/mi/neuraylib/imaterial_instance.h \ + ../../include/mi/neuraylib/imatrix.h \ + ../../include/mi/neuraylib/imdl_archive_api.h \ + ../../include/mi/neuraylib/imdl_backend.h \ + ../../include/mi/neuraylib/imdl_backend_api.h \ + ../../include/mi/neuraylib/imdl_compatibility_api.h \ + ../../include/mi/neuraylib/imdl_compiler.h \ + ../../include/mi/neuraylib/imdl_configuration.h \ + ../../include/mi/neuraylib/imdl_discovery_api.h \ + ../../include/mi/neuraylib/imdl_entity_resolver.h \ + ../../include/mi/neuraylib/imdl_evaluator_api.h \ + ../../include/mi/neuraylib/imdl_execution_context.h \ + ../../include/mi/neuraylib/imdl_factory.h \ + ../../include/mi/neuraylib/imdl_i18n_configuration.h \ + ../../include/mi/neuraylib/imdl_impexp_api.h \ + ../../include/mi/neuraylib/imdl_loading_wait_handle.h \ + ../../include/mi/neuraylib/imdl_module_builder.h \ + ../../include/mi/neuraylib/imdl_module_transformer.h \ + ../../include/mi/neuraylib/imdle_api.h \ + ../../include/mi/neuraylib/imodule.h \ + ../../include/mi/neuraylib/ineuray.h \ + ../../include/mi/neuraylib/inumber.h \ + ../../include/mi/neuraylib/iplugin_api.h \ + ../../include/mi/neuraylib/iplugin_configuration.h \ + ../../include/mi/neuraylib/ipointer.h \ + ../../include/mi/neuraylib/ireader.h \ + ../../include/mi/neuraylib/ireader_writer_base.h \ + ../../include/mi/neuraylib/iref.h \ + ../../include/mi/neuraylib/iscene_element.h \ + ../../include/mi/neuraylib/iscope.h \ + ../../include/mi/neuraylib/ispectrum.h \ + ../../include/mi/neuraylib/istream_position.h \ + ../../include/mi/neuraylib/istring.h \ + ../../include/mi/neuraylib/istructure.h \ + ../../include/mi/neuraylib/istructure_decl.h \ + ../../include/mi/neuraylib/itexture.h \ + ../../include/mi/neuraylib/itile.h \ + ../../include/mi/neuraylib/itransaction.h \ + ../../include/mi/neuraylib/itype.h \ + ../../include/mi/neuraylib/iuuid.h \ + ../../include/mi/neuraylib/ivalue.h \ + ../../include/mi/neuraylib/ivector.h \ + ../../include/mi/neuraylib/iversion.h \ + ../../include/mi/neuraylib/iwriter.h \ + ../../include/mi/neuraylib/matrix_typedefs.h \ + ../../include/mi/neuraylib/set_get.h \ + ../../include/mi/neuraylib/target_code_types.h \ + ../../include/mi/neuraylib/type_traits.h \ + ../../include/mi/neuraylib/typedefs.h \ + ../../include/mi/neuraylib/vector_typedefs.h \ + ../../include/mi/neuraylib/version.h \ ../../include/mi/math.h \ ../../include/mi/math \ ../../include/mi/base.h \ diff --git a/doc/mdl_sdkapi/main.dox b/doc/mdl_sdkapi/main.dox index 80bae9fd0..6340f644c 100644 --- a/doc/mdl_sdkapi/main.dox +++ b/doc/mdl_sdkapi/main.dox @@ -94,6 +94,7 @@ them, assertions, and configurations. - \ref mi_neuray_configuration "Configuration Interfaces" - \ref mi_neuray_types "Types" - \ref mi_neuray_mdl_types "MDL type system" + - \ref mi_neuray_mdl_misc "MDL-related interfaces" - \ref mi_neuray_database_access "Database Access" - \ref mi_neuray_scene_element "Scene Elements" - \ref mi_neuray_mdl_elements "MDL-related elements", diff --git a/examples/mdl_sdk/shared/texture_support_native.h b/examples/mdl_sdk/shared/texture_support_native.h index be2604a32..23e1d8beb 100644 --- a/examples/mdl_sdk/shared/texture_support_native.h +++ b/examples/mdl_sdk/shared/texture_support_native.h @@ -937,6 +937,11 @@ mi::neuraylib::Texture_handler_vtable tex_vtable = { scene_data_lookup_int3, scene_data_lookup_int4, scene_data_lookup_color, + /*m_scene_data_lookup_deriv_float*/ nullptr, + /*m_scene_data_lookup_deriv_float2*/ nullptr, + /*m_scene_data_lookup_deriv_float3*/ nullptr, + /*m_scene_data_lookup_deriv_float4*/ nullptr, + /*m_scene_data_lookup_deriv_color*/ nullptr }; // The vtable containing all texture access handlers required by the generated code diff --git a/examples/mdl_sdk/traversal/compiled_material_traverser_print.cpp b/examples/mdl_sdk/traversal/compiled_material_traverser_print.cpp index 617bfb4de..829a45f16 100644 --- a/examples/mdl_sdk/traversal/compiled_material_traverser_print.cpp +++ b/examples/mdl_sdk/traversal/compiled_material_traverser_print.cpp @@ -50,7 +50,7 @@ static bool is_selector_operator(mi::neuraylib::IFunction_definition::Semantics static bool is_call_like_operator(mi::neuraylib::IFunction_definition::Semantics semantic); Compiled_material_traverser_print::Context::Context( - mi::neuraylib::ITransaction* transaction, + mi::neuraylib::ITransaction* transaction, mi::neuraylib::IMdl_factory* mdl_factory, bool keep_structure) : m_transaction(transaction) @@ -227,9 +227,9 @@ void Compiled_material_traverser_print::visit_begin( element.expression->get_interface()); - // get the parameter name + // get the parameter name bool generated; - std::string name = get_parameter_name(material, expr_param->get_index(), + std::string name = get_parameter_name(material, expr_param->get_index(), &generated); // if we choose to inline generated parameters, we do it here @@ -245,7 +245,7 @@ void Compiled_material_traverser_print::visit_begin( { ctx->m_print << name << "/*param*/"; } - + return; } @@ -267,9 +267,10 @@ void Compiled_material_traverser_print::visit_begin( std::string function_name; if (is_builtins) - function_name = func_def->get_mdl_simple_name(); + function_name = ctx->decode_name(func_def->get_mdl_simple_name()); else - function_name = module_name + "::" + func_def->get_mdl_simple_name(); + function_name = + module_name + "::" + ctx->decode_name(func_def->get_mdl_simple_name()); // keep track of used modules and/or imports const std::string m = func_def->get_module(); @@ -287,14 +288,14 @@ void Compiled_material_traverser_print::visit_begin( const mi::base::Handle return_type( func_def->get_return_type()); - const mi::base::Handle + const mi::base::Handle return_type_struct( return_type->get_interface()); const mi::base::Handle return_type_enum( return_type->get_interface()); - + const mi::base::Handle return_type_array( return_type->get_interface()); @@ -324,11 +325,11 @@ void Compiled_material_traverser_print::visit_begin( if (drop_qualification) { // strip qualification part of the name - function_name = func_def->get_mdl_simple_name(); + function_name = ctx->decode_name(func_def->get_mdl_simple_name()); } else { - // add the struct or enum definition to the imports + // add the struct or enum definition to the imports ctx->m_imports.insert(function_name); } } @@ -537,7 +538,7 @@ void Compiled_material_traverser_print::visit_begin( std::string type_name = struct_type_to_string(struct_type.get(), ctx, &is_keyword); ctx->m_print << type_name << "("; - if (!is_keyword) + if (!is_keyword) ctx->m_print << "/*struct*/"; return; } @@ -568,7 +569,7 @@ void Compiled_material_traverser_print::visit_begin( { ctx->m_print << '\"' << mdl_path << '\"'; ctx->m_used_resources.insert(mdl_path); // keep track of this information - + // get the texture for gamma value const mi::base::Handle texture( ctx->m_transaction->access( @@ -683,7 +684,7 @@ void Compiled_material_traverser_print::visit_begin( { mi::base::Handle type(element.parameter->value->get_type()); // assuming all parameters are uniforms at this point - ctx->m_print << indent(ctx) << "uniform " + ctx->m_print << indent(ctx) << "uniform " << type_to_string(type.get(), ctx) << " " << name << " = "; } @@ -699,7 +700,7 @@ void Compiled_material_traverser_print::visit_begin( // include the return type if required const std::string return_type = type_to_string(temporary_return_type.get(), ctx); if(return_type.rfind("::") != std::string::npos) // no '::' has to be a build-in type - ctx->m_imports.insert(return_type); + ctx->m_imports.insert(return_type); ctx->m_print << indent(ctx) << return_type << " " << get_temporary_name( material, element.sibling_index) << " = "; @@ -731,7 +732,7 @@ void Compiled_material_traverser_print::visit_child( expr_dcall->get_definition())); const mi::neuraylib::IFunction_definition::Semantics semantic = func_def-> get_semantic(); - std::string function_name = func_def->get_mdl_simple_name(); + std::string function_name = ctx->decode_name(func_def->get_mdl_simple_name()); // check for special cases based on the semantic @@ -784,7 +785,7 @@ void Compiled_material_traverser_print::visit_child( if ( is_call_like_operator(semantic) || is_constructor(semantic)) { - ctx->m_print << (child_index == 0 ? "\n" : ",\n") << indent(ctx) + ctx->m_print << (child_index == 0 ? "\n" : ",\n") << indent(ctx) << arguments->get_name(child_index) << ": "; // named parameters return; } @@ -794,7 +795,7 @@ void Compiled_material_traverser_print::visit_child( ctx->m_print << (child_index == 0 ? "\n" : ",\n") << indent(ctx); // no names return; } - + // error case (should not happen): std::cerr << "[Compiled_material_traverser_print] ran into unhandled semantic: '" << func_def->get_mdl_name() << "' Semantic:" << semantic << "\n"; @@ -872,7 +873,7 @@ void Compiled_material_traverser_print::visit_end( if (is_selector_operator(semantic)) { - std::string selector = func_def->get_mdl_simple_name(); + std::string selector = ctx->decode_name(func_def->get_mdl_simple_name()); selector = selector.substr(selector.rfind('.')); ctx->m_print << selector; break; @@ -907,7 +908,7 @@ void Compiled_material_traverser_print::visit_end( if (is_array_constructor(semantic)) { - // a bit special because the parameter count is zero + // a bit special because the parameter count is zero // for the array constructor semantic ctx->m_print << "\n" << indent(ctx, -1) << ")"; break; @@ -957,7 +958,7 @@ void Compiled_material_traverser_print::visit_end( std::string name = get_parameter_name(material, element.sibling_index, &generated); // optionally add annotations here (in the generated == false case) - + // in case we want to inline the compiler generated parameters // we temporarily swapped the the stream for the time we process the parameter // this happened in the 'visit_begin' method @@ -969,7 +970,7 @@ void Compiled_material_traverser_print::visit_end( { // c++11 //std::swap(ctx->m_print, ctx->m_print_inline_swap); - + // c++0x (knowing that ctx->m_print_inline_swap will be discarded) ctx->m_print.str(""); ctx->m_print.clear(); @@ -1168,7 +1169,7 @@ std::string Compiled_material_traverser_print::atomic_type_to_string( return "float"; case mi::neuraylib::IType::TK_DOUBLE: return "double"; - case mi::neuraylib::IType::TK_STRING: + case mi::neuraylib::IType::TK_STRING: return "string"; case mi::neuraylib::IType::TK_ENUM: { @@ -1206,7 +1207,7 @@ std::string Compiled_material_traverser_print::matrix_type_to_string( column_type->get_element_type()); std::stringstream s; - s << atomic_type_to_string(elem_type.get(), context) + s << atomic_type_to_string(elem_type.get(), context) << column_type->get_size() << "x" << matrix_type->get_size(); return s.str();; } @@ -1220,7 +1221,7 @@ std::string Compiled_material_traverser_print::array_type_to_string( const mi::base::Handle atomic_type( elem_type->get_interface()); - std::stringstream s; + std::stringstream s; s << type_to_string(elem_type.get(), context); if (array_type->is_immediate_sized()) @@ -1236,7 +1237,7 @@ std::string Compiled_material_traverser_print::array_type_to_string( // local helper functions //-------------------------------------------------------------------------------------------------- -inline std::string replace_all(const std::string& input, +inline std::string replace_all(const std::string& input, const std::string& old, const std::string& with) { if (input.empty()) return input; diff --git a/include/mi/math/function.h b/include/mi/math/function.h index 0176ad643..2add58ca2 100644 --- a/include/mi/math/function.h +++ b/include/mi/math/function.h @@ -873,10 +873,10 @@ using std::isnan; #ifndef __CUDA_ARCH__ -inline float uint_as_float(const unsigned v) +inline float __uint_as_float(const unsigned v) { return base::binary_cast(v);} -inline unsigned float_as_uint(const float v) +inline unsigned __float_as_uint(const float v) { return base::binary_cast(v);} #endif @@ -1032,8 +1032,8 @@ MI_HOST_DEVICE_INLINE void to_rgbe( const Float32 color[3], Uint32& rgbe) else if( m >= 1.7014118346046923173168730371588e+38f) // 2^127 rgbe = 0xFFFFFFFFu; else { - const Uint32 e = float_as_uint( m) & 0x7F800000u; - const Float32 v = uint_as_float( 0x82800000u - e); + const Uint32 e = __float_as_uint( m) & 0x7F800000u; + const Float32 v = __uint_as_float( 0x82800000u - e); rgbe = Uint32( c[0] * v) | (Uint32( c[1] * v) << 8) @@ -1058,8 +1058,8 @@ MI_HOST_DEVICE_INLINE void to_rgbe( const Float32 color[3], Uint8 rgbe[4]) else if( m >= 1.7014118346046923173168730371588e+38f) // 2^127 rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 255; else { - const Uint32 e = float_as_uint( m) & 0x7F800000u; - const Float32 v = uint_as_float( 0x82800000u - e); + const Uint32 e = __float_as_uint( m) & 0x7F800000u; + const Float32 v = __uint_as_float( 0x82800000u - e); rgbe[0] = Uint8( c[0] * v); rgbe[1] = Uint8( c[1] * v); @@ -1077,12 +1077,12 @@ MI_HOST_DEVICE_INLINE void from_rgbe( const Uint8 rgbe[4], Float32 color[3]) } const Uint32 e = (static_cast( rgbe[3]) << 23) - 0x800000u; - const Float32 v = uint_as_float( e); + const Float32 v = __uint_as_float( e); const Float32 c = static_cast( 1.0 - 0.5/256.0) * v; - color[0] = uint_as_float( e | (static_cast( rgbe[0]) << 15)) - c; - color[1] = uint_as_float( e | (static_cast( rgbe[1]) << 15)) - c; - color[2] = uint_as_float( e | (static_cast( rgbe[2]) << 15)) - c; + color[0] = __uint_as_float( e | (static_cast( rgbe[0]) << 15)) - c; + color[1] = __uint_as_float( e | (static_cast( rgbe[1]) << 15)) - c; + color[2] = __uint_as_float( e | (static_cast( rgbe[2]) << 15)) - c; } /// Decodes a color from RGBE representation. @@ -1095,12 +1095,12 @@ MI_HOST_DEVICE_INLINE void from_rgbe( const Uint32 rgbe, Float32 color[3]) } const Uint32 e = (rgbe3 >> 1) - 0x800000u; - const Float32 v = uint_as_float( e); + const Float32 v = __uint_as_float( e); const Float32 c = static_cast( 1.0 - 0.5/256.0) * v; - color[0] = uint_as_float( e | ((rgbe << 15) & 0x7F8000u)) - c; - color[1] = uint_as_float( e | ((rgbe << 7) & 0x7F8000u)) - c; - color[2] = uint_as_float( e | ((rgbe >> 1) & 0x7F8000u)) - c; + color[0] = __uint_as_float( e | ((rgbe << 15) & 0x7F8000u)) - c; + color[1] = __uint_as_float( e | ((rgbe << 7) & 0x7F8000u)) - c; + color[2] = __uint_as_float( e | ((rgbe >> 1) & 0x7F8000u)) - c; } diff --git a/include/mi/neuraylib/ibsdf_measurement.h b/include/mi/neuraylib/ibsdf_measurement.h index fd134bbe0..31a4d0403 100644 --- a/include/mi/neuraylib/ibsdf_measurement.h +++ b/include/mi/neuraylib/ibsdf_measurement.h @@ -71,6 +71,9 @@ class IBsdf_measurement : /// exist. /// - -3: Invalid file format or invalid filename extension (only \c .mbsdf is /// supported). + /// + /// \see #mi::neuraylib::IMdl_factory::create_bsdf_measurement() for a way to create a BSDF + /// measurement based on an MDL file path instead of a filename. virtual Sint32 reset_file( const char* filename) = 0; /// Sets the BSDF measurement to the data provided by a reader. diff --git a/include/mi/neuraylib/ideserializer.h b/include/mi/neuraylib/ideserializer.h index 97c4b56ec..ad6116947 100644 --- a/include/mi/neuraylib/ideserializer.h +++ b/include/mi/neuraylib/ideserializer.h @@ -40,7 +40,7 @@ namespace neuraylib { /** \if IRAY_API \addtogroup mi_neuray_plugins -\elseif MDL_SOURCE_RELEASE \addtogroup mi_neuray_plugins +\elseif MDL_SDK_API \addtogroup mi_neuray_plugins \else \addtogroup mi_neuray_dice \endif @{ @@ -176,4 +176,3 @@ class IDeserializer : } // namespace mi #endif // MI_NEURAYLIB_IDESERIALIZER_H - diff --git a/include/mi/neuraylib/iexport_result.h b/include/mi/neuraylib/iexport_result.h index aca24e488..b5f22a26f 100644 --- a/include/mi/neuraylib/iexport_result.h +++ b/include/mi/neuraylib/iexport_result.h @@ -39,15 +39,13 @@ namespace mi { namespace neuraylib { /** -\ifnot MDL_SOURCE_RELEASE \addtogroup mi_neuray_impexp @{ -\endif */ /// This interface represents the result of an export operation. /// -/// \ifnot MDL_SOURCE_RELEASE +/// \ifnot MDL_SDK_API /// Such an export operation is triggered by #mi::neuraylib::IExport_api::export_elements() or /// #mi::neuraylib::IExport_api::export_scene(). It gives access to messages, message numbers, and /// and message severities. @@ -115,7 +113,7 @@ class IExport_result : /// exporter writers. In addition to the #mi::neuraylib::IExport_result interface it provides /// methods to set all values. /// -/// \ifnot MDL_SOURCE_RELEASE +/// \ifnot MDL_SDK_API /// See #mi::neuraylib::IExport_api::export_scene() and /// #mi::neuraylib::IExport_api::export_elements() for common message numbers. Numbers in the range /// 6000-7999 are reserved for exporter-specific messages. All other numbers are reserved for other @@ -185,9 +183,7 @@ class IExport_result_ext : }; /* -\ifnot MDL_SOURCE_RELEASE @} -\endif */ // end group mi_neuray_impexp } // namespace neuraylib @@ -195,4 +191,3 @@ class IExport_result_ext : } // namespace mi #endif // MI_NEURAYLIB_IEXPORT_RESULT_H - diff --git a/include/mi/neuraylib/iexpression.h b/include/mi/neuraylib/iexpression.h index 9fc5cd07e..5928752a6 100644 --- a/include/mi/neuraylib/iexpression.h +++ b/include/mi/neuraylib/iexpression.h @@ -335,10 +335,10 @@ class IAnnotation_definition : public enum Semantics { AS_UNKNOWN = 0, ///< Unknown semantics. - AS_ANNOTATION_FIRST = 0x0100, /// This is the internal intrinsic() annotation. - AS_INTRINSIC_ANNOTATION = AS_ANNOTATION_FIRST, + AS_INTRINSIC_ANNOTATION = 0x0100, + AS_ANNOTATION_FIRST = AS_INTRINSIC_ANNOTATION, AS_THROWS_ANNOTATION, ///< This is the internal throws() annotation. AS_SINCE_ANNOTATION, ///< This is the internal since() annotation. AS_REMOVED_ANNOTATION, ///< This is the internal removed() annotation. @@ -685,12 +685,12 @@ class IExpression_factory : public /// identity. That is, the comparison is not done via /// #mi::neuraylib::IExpression::get_value(), but by traversing into the referenced /// function call, i.e., comparing the function definition reference and the arguments. - /// This option is useful if you want to decide wether an argument is \em semantically equal + /// This option is useful if you want to decide whether an argument is \em semantically equal /// to the corresponding default parameter. DEEP_CALL_COMPARISONS = 1, /// This option indicates that all type aliases should be skipped before types of /// expression are compared. Defaults and argument might sometimes differ in explicit type - /// modifiers, therefore this option is useful if you want to decide wether an argument is + /// modifiers, therefore this option is useful if you want to decide whether an argument is /// \em semantically equal to the corresponding default parameter. SKIP_TYPE_ALIASES = 2, // Undocumented, for alignment only @@ -828,7 +828,8 @@ class IExpression_factory : public /// If the type of \p src_expr and \p target_type are not compatible, \c NULL is returned. /// /// \param src_expr The expression whose type is supposed to be casted. - /// \param target_type The result type of the cast. + /// \param target_type The result type of the cast. Note that the inserted cast operator acts on + /// types without qualifiers, i.e., modifiers on \p target_type are ignored. /// \param cast_db_name This name is used when storing the instance /// of the cast-operator function into the database. If the name is already /// taken by another DB element, this string will be used as the base for diff --git a/include/mi/neuraylib/iextension_api.h b/include/mi/neuraylib/iextension_api.h index 86bba8cb1..b1edc374f 100644 --- a/include/mi/neuraylib/iextension_api.h +++ b/include/mi/neuraylib/iextension_api.h @@ -62,9 +62,8 @@ class IExtension_api : public /// /// All user-defined classes to be used with the \neurayApiName must be registered. The only /// exception are classes that never cross the API boundary, for example, classes only used - /// locally within a plugin. Class registration must be done - /// \ifnot MDL_SOURCE_RELEASE in #mi::neuraylib::IPlugin::init() or \endif - /// before \neurayProductName has been started. + /// locally within a plugin. Class registration must be done in #mi::neuraylib::IPlugin::init() + /// or before \neurayProductName has been started. /// /// \param class_name The class name under which the class is to be registered. The class /// name must consist only of alphanumeric characters or underscores, @@ -86,9 +85,8 @@ class IExtension_api : public /// /// All user-defined classes to be used with the \neurayApiName must be registered. The only /// exception are classes that never cross the API boundary, for example, classes only used - /// locally within a plugin. Class registration must be done - /// \ifnot MDL_SOURCE_RELEASE in #mi::neuraylib::IPlugin::init() or \endif - /// before \neurayProductName has been started. + /// locally within a plugin. Class registration must be done in #mi::neuraylib::IPlugin::init() + /// or before \neurayProductName has been started. /// /// This templated member function is a wrapper of the non-template variant for the user's /// convenience. It uses the default class factory #mi::neuraylib::User_class_factory @@ -113,9 +111,8 @@ class IExtension_api : public /// Unregisters a class with the \neurayApiName. /// - /// Class unregistration must be done - /// \ifnot MDL_SOURCE_RELEASE in #mi::neuraylib::IPlugin::exit() or \endif - /// after \neurayProductName has been shut down. + /// Class unregistration must be done in #mi::neuraylib::IPlugin::exit() or after + /// \neurayProductName has been shut down. /// /// \param class_name The class name under which the class was registered. /// \param uuid The class ID of the class. You can simply pass IID() of your class @@ -131,9 +128,8 @@ class IExtension_api : public /// Unregisters a class with the \neurayApiName. /// - /// Class unregistration must be done - /// \ifnot MDL_SOURCE_RELEASE in #mi::neuraylib::IPlugin::exit() or \endif - /// before \neurayProductName has been shut down. + /// Class unregistration must be done in #mi::neuraylib::IPlugin::exit() or after + /// \neurayProductName has been shut down. /// /// This templated member function is a wrapper of the non-template variant for the user's /// convenience. It uses the default class factory #mi::neuraylib::User_class_factory @@ -159,9 +155,8 @@ class IExtension_api : public /// Registers a new importer with the \neurayApiName. /// - /// Importer registration must be done - /// \ifnot MDL_SOURCE_RELEASE in #mi::neuraylib::IPlugin::init() or \endif - /// before \neurayProductName has been started. + /// Importer registration must be done in #mi::neuraylib::IPlugin::exit() or before + /// \neurayProductName has been started. /// /// \param importer The new importer to register. /// \return @@ -172,9 +167,8 @@ class IExtension_api : public /// Registers a new exporter with the \neurayApiName. /// - /// Exporter registration must be done - /// \ifnot MDL_SOURCE_RELEASE in #mi::neuraylib::IPlugin::init() or \endif - /// before \neurayProductName has been started. + /// Importer registration must be done in #mi::neuraylib::IPlugin::exit() or before + /// \neurayProductName has been started. /// /// \param exporter The new exporter to register. /// \return @@ -185,9 +179,8 @@ class IExtension_api : public /// Unregisters an importer registered with the \neurayApiName. /// - /// Unregistration must be done - /// \ifnot MDL_SOURCE_RELEASE in #mi::neuraylib::IPlugin::exit() or \endif - /// after \neurayProductName has been shut down. + /// Unregistration must be done in #mi::neuraylib::IPlugin::exit() or after + /// \neurayProductName has been shut down. /// /// \param importer The importer to unregister. /// \return @@ -199,9 +192,8 @@ class IExtension_api : public /// Unregisters an exporter registered with the \neurayApiName. /// - /// Unregistration must be done - /// \ifnot MDL_SOURCE_RELEASE in #mi::neuraylib::IPlugin::exit() or \endif - /// after \neurayProductName has been shut down. + /// Unregistration must be done in #mi::neuraylib::IPlugin::exit() or after + /// \neurayProductName has been shut down. /// /// \param exporter The exporter to unregister. /// \return @@ -297,4 +289,3 @@ class IExtension_api : public } // namespace mi #endif // MI_NEURAYLIB_IEXTENSION_API_H - diff --git a/include/mi/neuraylib/ifunction_definition.h b/include/mi/neuraylib/ifunction_definition.h index fd3d32965..d804dc22c 100644 --- a/include/mi/neuraylib/ifunction_definition.h +++ b/include/mi/neuraylib/ifunction_definition.h @@ -71,7 +71,7 @@ class IFunction_definition : public /// All known semantics of functions definitions. /// - /// Material definitions always have the sematic #DS_UNKNOWN. + /// Material definitions always have the semantic #DS_UNKNOWN. /// /// \note Do not rely on the numeric values of the enumerators since they may change without /// further notice. @@ -87,15 +87,14 @@ class IFunction_definition : public DS_INVALID_REF_CONSTRUCTOR, ///< The invalid reference constructor. DS_DEFAULT_STRUCT_CONSTRUCTOR, ///< The default constructor for a struct. DS_TEXTURE_CONSTRUCTOR, ///< The texture constructor. - DS_CONV_OPERATOR, ///< The type conversion operator. - DS_COPY_CONSTRUCTOR, ///< The copy constructor. // Unary operators - DS_OPERATOR_FIRST = 0x0200, - DS_UNARY_FIRST = DS_OPERATOR_FIRST, - DS_BITWISE_COMPLEMENT = DS_UNARY_FIRST, ///< The bitwise complement operator. + + DS_BITWISE_COMPLEMENT = 0x0200, ///< The bitwise complement operator. + DS_UNARY_FIRST = DS_BITWISE_COMPLEMENT, + DS_OPERATOR_FIRST = DS_UNARY_FIRST, DS_LOGICAL_NOT, ///< The unary logical negation operator. DS_POSITIVE, ///< The unary arithmetic positive operator. DS_NEGATIVE, ///< The unary arithmetic negation operator. @@ -103,15 +102,14 @@ class IFunction_definition : public DS_PRE_DECREMENT, ///< The pre-decrement operator. DS_POST_INCREMENT, ///< The post-increment operator. DS_POST_DECREMENT, ///< The post-decrement operator. - - /// The cast operator. See \ref mi_neuray_mdl_cast_operator. + /// The cast operator. See \ref mi_neuray_mdl_cast_operator. DS_CAST, DS_UNARY_LAST = DS_CAST, // Binary operators - DS_BINARY_FIRST, - DS_SELECT = DS_BINARY_FIRST, ///< The select operator. + DS_SELECT, ///< The select operator. + DS_BINARY_FIRST = DS_SELECT, /// The array index operator. See \ref mi_neuray_mdl_array_index_operator. DS_ARRAY_INDEX, DS_MULTIPLY, ///< The multiplication operator. @@ -149,13 +147,14 @@ class IFunction_definition : public DS_BINARY_LAST = DS_SEQUENCE, // Ternary operator + /// The ternary operator (conditional). See \ref mi_neuray_mdl_ternary_operator. DS_TERNARY, DS_OPERATOR_LAST = DS_TERNARY, // ::math module intrinsics - DS_INTRINSIC_MATH_FIRST = 0x0300, - /// The %math::abs() intrinsic function. + + DS_INTRINSIC_MATH_FIRST = 0x0300, ///< The %math::abs() intrinsic function. DS_INTRINSIC_MATH_ABS = DS_INTRINSIC_MATH_FIRST, DS_INTRINSIC_MATH_ACOS, ///< The %math::acos() intrinsic function. DS_INTRINSIC_MATH_ALL, ///< The %math::all() intrinsic function. @@ -171,9 +170,8 @@ class IFunction_definition : public DS_INTRINSIC_MATH_DEGREES, ///< The %math::degrees() intrinsic function. DS_INTRINSIC_MATH_DISTANCE, ///< The %math::distance() intrinsic function. DS_INTRINSIC_MATH_DOT, ///< The %math::dot() intrinsic function. - - /// The %math::eval_at_wavelength() intrinsic function. - DS_INTRINSIC_MATH_EVAL_AT_WAVELENGTH, + DS_INTRINSIC_MATH_EVAL_AT_WAVELENGTH, ///< The %math::eval_at_wavelength() intrinsic + /// function. DS_INTRINSIC_MATH_EXP, ///< The %math::exp() intrinsic function. DS_INTRINSIC_MATH_EXP2, ///< The %math::exp2() intrinsic function. DS_INTRINSIC_MATH_FLOOR, ///< The %math::floor() intrinsic function. @@ -189,14 +187,12 @@ class IFunction_definition : public DS_INTRINSIC_MATH_LUMINANCE, ///< The %math::luminance() intrinsic function. DS_INTRINSIC_MATH_MAX, ///< The %math::max() intrinsic function. DS_INTRINSIC_MATH_MAX_VALUE, ///< The %math::max_value() intrinsic function. - - /// The %math::max_value_wavelength() intrinsic function. - DS_INTRINSIC_MATH_MAX_VALUE_WAVELENGTH, + DS_INTRINSIC_MATH_MAX_VALUE_WAVELENGTH, ///< The %math::max_value_wavelength() intrinsic + /// function. DS_INTRINSIC_MATH_MIN, ///< The %math::min() intrinsic function. DS_INTRINSIC_MATH_MIN_VALUE, ///< The %math::min_value() intrinsic function. - - /// The %math::min_value_wavelength() intrinsic function. - DS_INTRINSIC_MATH_MIN_VALUE_WAVELENGTH, + DS_INTRINSIC_MATH_MIN_VALUE_WAVELENGTH, ///< The %math::min_value_wavelength() intrinsic + /// function. DS_INTRINSIC_MATH_MODF, ///< The %math::modf() intrinsic function. DS_INTRINSIC_MATH_NORMALIZE, ///< The %math::normalize() intrinsic function. DS_INTRINSIC_MATH_POW, ///< The %math::pow() intrinsic function. @@ -213,9 +209,8 @@ class IFunction_definition : public DS_INTRINSIC_MATH_TAN, ///< The %math::tan() intrinsic function. DS_INTRINSIC_MATH_TRANSPOSE, ///< The %math::transpose() intrinsic function. DS_INTRINSIC_MATH_BLACKBODY, ///< The %math::blackbody() intrinsic function. - - /// The %math::emission_color() intrinsic function. - DS_INTRINSIC_MATH_EMISSION_COLOR, + DS_INTRINSIC_MATH_EMISSION_COLOR, ///< The %math::emission_color() intrinsic + /// function. DS_INTRINSIC_MATH_COSH, ///< The %math::cosh() intrinsic function. DS_INTRINSIC_MATH_SINH, ///< The %math::sinh() intrinsic function. DS_INTRINSIC_MATH_TANH, ///< The %math::tanh() intrinsic function. @@ -228,9 +223,9 @@ class IFunction_definition : public DS_INTRINSIC_MATH_LAST = DS_INTRINSIC_MATH_DY, // ::state module intrinsics - DS_INTRINSIC_STATE_FIRST = 0x0400, - /// The %state::position() function. - DS_INTRINSIC_STATE_POSITION = DS_INTRINSIC_STATE_FIRST, + + DS_INTRINSIC_STATE_POSITION = 0x0400, ///< The %state::position() function. + DS_INTRINSIC_STATE_FIRST = DS_INTRINSIC_STATE_POSITION, DS_INTRINSIC_STATE_NORMAL, ///< The %state::normal() function. DS_INTRINSIC_STATE_GEOMETRY_NORMAL, ///< The %state::geometry_normal() function. DS_INTRINSIC_STATE_MOTION, ///< The %state::motion() function. @@ -258,10 +253,9 @@ class IFunction_definition : public DS_INTRINSIC_STATE_LAST = DS_INTRINSIC_STATE_WAVELENGTH_MAX, // ::tex module intrinsics - DS_INTRINSIC_TEX_FIRST = 0x0500, - /// The tex::width() function. - DS_INTRINSIC_TEX_WIDTH = DS_INTRINSIC_TEX_FIRST, + DS_INTRINSIC_TEX_WIDTH = 0x0500, ///< The tex::width() function. + DS_INTRINSIC_TEX_FIRST = DS_INTRINSIC_TEX_WIDTH, DS_INTRINSIC_TEX_HEIGHT, ///< The tex::height() function. DS_INTRINSIC_TEX_DEPTH, ///< The tex::depth() function. DS_INTRINSIC_TEX_LOOKUP_FLOAT, ///< The tex::lookup_float() function. @@ -284,14 +278,13 @@ class IFunction_definition : public DS_INTRINSIC_TEX_LAST = DS_INTRINSIC_TEX_GRID_TO_OBJECT_SPACE, // ::df module intrinsics - DS_INTRINSIC_DF_FIRST = 0x0600, /// The df::diffuse_reflection_bsdf() function. - DS_INTRINSIC_DF_DIFFUSE_REFLECTION_BSDF = DS_INTRINSIC_DF_FIRST, + DS_INTRINSIC_DF_DIFFUSE_REFLECTION_BSDF = 0x0600, + DS_INTRINSIC_DF_FIRST = DS_INTRINSIC_DF_DIFFUSE_REFLECTION_BSDF, DS_INTRINSIC_DF_DIFFUSE_TRANSMISSION_BSDF,///< The df::diffuse_transmission_bsdf() function. DS_INTRINSIC_DF_SPECULAR_BSDF, ///< The df::specular_bsdf() function. DS_INTRINSIC_DF_SIMPLE_GLOSSY_BSDF, ///< The df::simple_glossy_bsdf() function. - /// The df::backscattering_glossy_reflection_bsdf() function. DS_INTRINSIC_DF_BACKSCATTERING_GLOSSY_REFLECTION_BSDF, DS_INTRINSIC_DF_MEASURED_BSDF, ///< The df::measured_bsdf() function. @@ -313,7 +306,6 @@ class IFunction_definition : public DS_INTRINSIC_DF_LIGHT_PROFILE_MAXIMUM, ///< The df::light_profile_maximum() function. DS_INTRINSIC_DF_LIGHT_PROFILE_ISVALID, ///< The df::light_profile_isvalid() function. DS_INTRINSIC_DF_BSDF_MEASUREMENT_ISVALID, ///< The df::bsdf_measurement_is_valid() function. - /// The df::microfacet_beckmann_smith_bsdf() function. DS_INTRINSIC_DF_MICROFACET_BECKMANN_SMITH_BSDF, /// The df::microfacet_ggx_smith_bsdf() function. @@ -329,7 +321,6 @@ class IFunction_definition : public DS_INTRINSIC_DF_COLOR_WEIGHTED_LAYER, ///< The df::color_weighted_layer() function. DS_INTRINSIC_DF_COLOR_FRESNEL_LAYER, ///< The df::color_fresnel_layer() function. DS_INTRINSIC_DF_COLOR_CUSTOM_CURVE_LAYER, ///< The df::color_custom_curve_layer() function. - /// The df::color_measured_curve_layer() function. DS_INTRINSIC_DF_COLOR_MEASURED_CURVE_LAYER, DS_INTRINSIC_DF_FRESNEL_FACTOR, ///< The df::fresnel_factor() function. @@ -342,42 +333,61 @@ class IFunction_definition : public // ::scene module intrinsics - DS_INTRINSIC_SCENE_FIRST = 0x0800, - - DS_INTRINSIC_SCENE_DATA_ISVALID = DS_INTRINSIC_SCENE_FIRST, - DS_INTRINSIC_SCENE_DATA_LOOKUP_INT, ///< scene::data_lookup_int() - DS_INTRINSIC_SCENE_DATA_LOOKUP_INT2, ///< scene::data_lookup_int2() - DS_INTRINSIC_SCENE_DATA_LOOKUP_INT3, ///< scene::data_lookup_int3() - DS_INTRINSIC_SCENE_DATA_LOOKUP_INT4, ///< scene::data_lookup_int4() - DS_INTRINSIC_SCENE_DATA_LOOKUP_FLOAT, ///< scene::data_lookup_float() - DS_INTRINSIC_SCENE_DATA_LOOKUP_FLOAT2, ///< scene::data_lookup_float2() - DS_INTRINSIC_SCENE_DATA_LOOKUP_FLOAT3, ///< scene::data_lookup_float3() - DS_INTRINSIC_SCENE_DATA_LOOKUP_FLOAT4, ///< scene::data_lookup_float4() - DS_INTRINSIC_SCENE_DATA_LOOKUP_COLOR, ///< scene::data_lookup_color() - DS_INTRINSIC_SCENE_DATA_LOOKUP_UNIFORM_INT, ///< scene::data_lookup_uniform_int() - DS_INTRINSIC_SCENE_DATA_LOOKUP_UNIFORM_INT2, ///< scene::data_lookup_uniform_int2() - DS_INTRINSIC_SCENE_DATA_LOOKUP_UNIFORM_INT3, ///< scene::data_lookup_uniform_int3() - DS_INTRINSIC_SCENE_DATA_LOOKUP_UNIFORM_INT4, ///< scene::data_lookup_uniform_int4() - DS_INTRINSIC_SCENE_DATA_LOOKUP_UNIFORM_FLOAT, ///< scene::data_lookup_uniform_float() - DS_INTRINSIC_SCENE_DATA_LOOKUP_UNIFORM_FLOAT2, ///< scene::data_lookup_uniform_float2() - DS_INTRINSIC_SCENE_DATA_LOOKUP_UNIFORM_FLOAT3, ///< scene::data_lookup_uniform_float3() - DS_INTRINSIC_SCENE_DATA_LOOKUP_UNIFORM_FLOAT4, ///< scene::data_lookup_uniform_float4() - DS_INTRINSIC_SCENE_DATA_LOOKUP_UNIFORM_COLOR, ///< scene::data_lookup_uniform_color() + + /// The scene::data_is_valid() function. + DS_INTRINSIC_SCENE_DATA_ISVALID = 0x0800, + DS_INTRINSIC_SCENE_FIRST = DS_INTRINSIC_SCENE_DATA_ISVALID, + /// The scene::data_lookup_int() function. + DS_INTRINSIC_SCENE_DATA_LOOKUP_INT, + /// The scene::data_lookup_int2() function. + DS_INTRINSIC_SCENE_DATA_LOOKUP_INT2, + /// The scene::data_lookup_int3() function. + DS_INTRINSIC_SCENE_DATA_LOOKUP_INT3, + /// The scene::data_lookup_int4() function. + DS_INTRINSIC_SCENE_DATA_LOOKUP_INT4, + /// The scene::data_lookup_float() function. + DS_INTRINSIC_SCENE_DATA_LOOKUP_FLOAT, + /// The scene::data_lookup_float2() function. + DS_INTRINSIC_SCENE_DATA_LOOKUP_FLOAT2, + /// The scene::data_lookup_float3() function. + DS_INTRINSIC_SCENE_DATA_LOOKUP_FLOAT3, + /// The scene::data_lookup_float4() function. + DS_INTRINSIC_SCENE_DATA_LOOKUP_FLOAT4, + /// The scene::data_lookup_color() function. + DS_INTRINSIC_SCENE_DATA_LOOKUP_COLOR, + /// The scene::data_lookup_uniform_int() function. + DS_INTRINSIC_SCENE_DATA_LOOKUP_UNIFORM_INT, + /// The scene::data_lookup_uniform_int2() function. + DS_INTRINSIC_SCENE_DATA_LOOKUP_UNIFORM_INT2, + /// The scene::data_lookup_uniform_int3() function. + DS_INTRINSIC_SCENE_DATA_LOOKUP_UNIFORM_INT3, + /// The scene::data_lookup_uniform_int4() function. + DS_INTRINSIC_SCENE_DATA_LOOKUP_UNIFORM_INT4, + /// The scene::data_lookup_uniform_float() function. + DS_INTRINSIC_SCENE_DATA_LOOKUP_UNIFORM_FLOAT, + /// The scene::data_lookup_uniform_float2() function. + DS_INTRINSIC_SCENE_DATA_LOOKUP_UNIFORM_FLOAT2, + /// The scene::data_lookup_uniform_float3() function. + DS_INTRINSIC_SCENE_DATA_LOOKUP_UNIFORM_FLOAT3, + /// The scene::data_lookup_uniform_float4() function. + DS_INTRINSIC_SCENE_DATA_LOOKUP_UNIFORM_FLOAT4, + /// The scene::data_lookup_uniform_color() function. + DS_INTRINSIC_SCENE_DATA_LOOKUP_UNIFORM_COLOR, DS_INTRINSIC_SCENE_LAST = DS_INTRINSIC_SCENE_DATA_LOOKUP_UNIFORM_COLOR, // ::debug module intrinsics - DS_INTRINSIC_DEBUG_FIRST = 0x0900, - /// The debug::breakpoint() function. - DS_INTRINSIC_DEBUG_BREAKPOINT = DS_INTRINSIC_DEBUG_FIRST, + DS_INTRINSIC_DEBUG_BREAKPOINT = 0x0900, ///< The debug::breakpoint() function. + DS_INTRINSIC_DEBUG_FIRST = DS_INTRINSIC_DEBUG_BREAKPOINT, DS_INTRINSIC_DEBUG_ASSERT, ///< The debug::assert() function. DS_INTRINSIC_DEBUG_PRINT, ///< The debug::print() function. DS_INTRINSIC_DEBUG_LAST = DS_INTRINSIC_DEBUG_PRINT, // DAG backend intrinsics - DS_INTRINSIC_DAG_FIRST = 0x0A00, + /// The structure field access function. - DS_INTRINSIC_DAG_FIELD_ACCESS = DS_INTRINSIC_DAG_FIRST, + DS_INTRINSIC_DAG_FIELD_ACCESS = 0x0A00, + DS_INTRINSIC_DAG_FIRST = DS_INTRINSIC_DAG_FIELD_ACCESS, /// The array constructor. See \ref mi_neuray_mdl_array_constructor. DS_INTRINSIC_DAG_ARRAY_CONSTRUCTOR, /// The array length operator. See \ref mi_neuray_mdl_array_length_operator. diff --git a/include/mi/neuraylib/iimage.h b/include/mi/neuraylib/iimage.h index 56942186e..f89388430 100644 --- a/include/mi/neuraylib/iimage.h +++ b/include/mi/neuraylib/iimage.h @@ -151,6 +151,9 @@ class IImage : /// - -3: Failure to open the file. /// - -4: No image plugin found to handle the file. /// - -5: The image plugin failed to import the file. + /// + /// \see #mi::neuraylib::IMdl_factory::create_texture() for a way to create a texture based + /// on an MDL file path instead of a filename. virtual Sint32 reset_file( const char* filename, const char* selector = 0) = 0; /// Sets the image to the data provided by a reader. @@ -277,7 +280,7 @@ class IImage : /// Returns the frame number for a give frame ID. /// - /// This function is stricly monotonically increasing. Frame numbers are not necessarily + /// This function is strictly monotonically increasing. Frame numbers are not necessarily /// consecutive, there can be missing frame numbers. /// /// \param frame_id The frame ID of the frame. @@ -361,7 +364,7 @@ class IImage : /// passed to #reset_file(). /// /// \param frame_id The frame ID of the mipmap. - /// \param uvtile_id The uv-tile ID of the mimap. + /// \param uvtile_id The uv-tile ID of the mipmap. /// /// \see #get_original_filename() virtual const char* get_filename( Size frame_id, Size uvtile_id) const = 0; @@ -404,7 +407,7 @@ class IImage : /// Returns the pixel type of a mipmap. /// /// \param frame_id The frame ID of the mipmap. - /// \param uvtile_id The uv-tile ID of the mimap to get the pixel type for. + /// \param uvtile_id The uv-tile ID of the mipmap to get the pixel type for. /// \return The pixel type, or \c NULL in case of an invalid frame ID or uv-tile ID. /// /// See \ref mi_neuray_types for a list of supported pixel types. @@ -417,7 +420,7 @@ class IImage : /// Returns the number of levels in the mipmap pyramid. /// /// \param frame_id The frame ID of the mipmap. - /// \param uvtile_id The uv-tile ID of the mimap to get the number of levels for. + /// \param uvtile_id The uv-tile ID of the mipmap to get the number of levels for. /// \return The number of levels, or -1 in case of an invalid frame ID or uv-tile ID. virtual Uint32 get_levels( Size frame_id, Size uvtile_id) const = 0; diff --git a/include/mi/neuraylib/iimage_api.h b/include/mi/neuraylib/iimage_api.h index e8a7defbe..b999c021f 100644 --- a/include/mi/neuraylib/iimage_api.h +++ b/include/mi/neuraylib/iimage_api.h @@ -50,11 +50,6 @@ class ITile; \defgroup mi_neuray_mdl_sdk_misc Miscellaneous Interfaces \ingroup mi_neuray - \brief Various utility classes. -\elseif IRAY_API - \defgroup mi_neuray_mdl_sdk_misc Miscellaneous MDL-related Interfaces - \ingroup mi_neuray - \brief Various utility classes. \endif */ @@ -93,7 +88,7 @@ class IImage_api : public /// \param width The desired width. /// \param height The desired height. /// \return The requested tile, or \c NULL in case of invalid pixel type, width, or - /// height. + /// height, or memory allocation failures. virtual ITile* create_tile( const char* pixel_type, Uint32 width, @@ -116,7 +111,7 @@ class IImage_api : public /// \param gamma The desired gamma value. The special value 0.0 represents the default /// gamma which is 1.0 for HDR pixel types and 2.2 for LDR pixel types. /// \return The requested canvas, or \c NULL in case of invalid pixel type, width, - /// height, layers, or cubemap flag. + /// height, layers, or cubemap flag, or memory allocation failures. virtual ICanvas* create_canvas( const char* pixel_type, Uint32 width, diff --git a/include/mi/neuraylib/iimpexp_base.h b/include/mi/neuraylib/iimpexp_base.h index a4c868cdd..30d55645a 100644 --- a/include/mi/neuraylib/iimpexp_base.h +++ b/include/mi/neuraylib/iimpexp_base.h @@ -39,11 +39,10 @@ namespace neuraylib { class IImpexp_state; -/** -\ifnot MDL_SOURCE_RELEASE -\addtogroup mi_neuray_impexp +/** \if MDL_SDK_API \addtogroup mi_neuray_mdl_sdk_misc + \else \addtogroup mi_neuray_impexp + \endif @{ -\endif */ /// Confidence in capabilities of an importer or exporter. @@ -173,9 +172,7 @@ class IImpexp_base : }; /* -\ifnot MDL_SOURCE_RELEASE @} -\endif */ // end group mi_neuray_impexp } // namespace neuraylib @@ -183,4 +180,3 @@ class IImpexp_base : } // namespace mi #endif // MI_NEURAYLIB_IIMPEXP_BASE_H - diff --git a/include/mi/neuraylib/iimpexp_state.h b/include/mi/neuraylib/iimpexp_state.h index dc83b5c86..b96780256 100644 --- a/include/mi/neuraylib/iimpexp_state.h +++ b/include/mi/neuraylib/iimpexp_state.h @@ -38,10 +38,8 @@ namespace mi { namespace neuraylib { /** -\ifnot MDL_SOURCE_RELEASE \addtogroup mi_neuray_impexp @{ -\endif */ /// This interface represents states that are passed to recursive calls of importers and exporters. @@ -91,9 +89,7 @@ class IImpexp_state : }; /* -\ifnot MDL_SOURCE_RELEASE @} -\endif */ // end group mi_neuray_impexp } // namespace neuraylib @@ -101,4 +97,3 @@ class IImpexp_state : } // namespace mi #endif // MI_NEURAYLIB_IIMPEXP_STATE_H - diff --git a/include/mi/neuraylib/iimport_result.h b/include/mi/neuraylib/iimport_result.h index 147f20215..ee04d78ad 100644 --- a/include/mi/neuraylib/iimport_result.h +++ b/include/mi/neuraylib/iimport_result.h @@ -39,15 +39,12 @@ namespace mi { namespace neuraylib { /** -\ifnot MDL_SOURCE_RELEASE \addtogroup mi_neuray_impexp @{ -\endif */ /// This interface represents the result of an import operation. /// -/// \ifnot MDL_SOURCE_RELEASE /// Such an import operation is triggered by #mi::neuraylib::IImport_api::import_elements() or /// #mi::neuraylib::IImport_api::import_elements_from_string(). It gives access /// to messages, message numbers, and message severities, and to important scene elements like root @@ -66,7 +63,6 @@ namespace neuraylib { /// - #mi::base::details::MESSAGE_SEVERITY_VERBOSE and /// #mi::base::details::MESSAGE_SEVERITY_DEBUG \n /// These message severities should be avoided by importers. -/// \endif class IImport_result : public base::Interface_declare<0xa47741d4,0x49c5,0x418d,0xa5,0x4b,0xa6,0xfb,0xf4,0xa0,0x91,0x44> { @@ -142,11 +138,9 @@ class IImport_result : /// importer writers. In addition to the #mi::neuraylib::IImport_result interface it provides /// methods to set all values. /// -/// \ifnot MDL_SOURCE_RELEASE /// See #mi::neuraylib::IImport_api::import_elements() for common message numbers. Numbers in the /// range 4000-5999 are reserved for importer-specific messages. All other numbers are reserved for /// other purposes. -/// \endif /// /// \note In case of a successful Import operation the array of messages should not contain an /// explicit message with message number 0. If there are no other importer-specific messages, @@ -264,9 +258,7 @@ class IImport_result_ext : /* -\ifnot MDL_SOURCE_RELEASE @} -\endif */ // end group mi_neuray_impexp } // namespace neuraylib @@ -274,4 +266,3 @@ class IImport_result_ext : } // namespace mi #endif // MI_NEURAYLIB_IIMPORT_RESULT_H - diff --git a/include/mi/neuraylib/ilightprofile.h b/include/mi/neuraylib/ilightprofile.h index daccd4248..d74fa001d 100644 --- a/include/mi/neuraylib/ilightprofile.h +++ b/include/mi/neuraylib/ilightprofile.h @@ -133,6 +133,9 @@ class ILightprofile : /// - -4: File format error. /// - -5: \p resolution_phi or \p resolution_theta is invalid (must /// not be 1). + /// + /// \see #mi::neuraylib::IMdl_factory::create_light_profile() for a way to create a light + /// profile based on an MDL file path instead of a filename. virtual Sint32 reset_file( const char* filename, Uint32 resolution_phi = 0, diff --git a/include/mi/neuraylib/imdl_archive_api.h b/include/mi/neuraylib/imdl_archive_api.h index 86554cd5a..3936cfd9a 100644 --- a/include/mi/neuraylib/imdl_archive_api.h +++ b/include/mi/neuraylib/imdl_archive_api.h @@ -42,7 +42,7 @@ namespace neuraylib { class IManifest; class IReader; -/** \addtogroup mi_neuray_mdl_types +/** \addtogroup mi_neuray_mdl_misc @{ */ @@ -152,7 +152,7 @@ class IManifest : public virtual const char* get_value( const char* key, Size index) const = 0; }; -/*@}*/ // end group mi_neuray_mdl_types +/*@}*/ // end group mi_neuray_mdl_misc } // namespace neuraylib diff --git a/include/mi/neuraylib/imdl_backend_api.h b/include/mi/neuraylib/imdl_backend_api.h index b5485537d..f47771406 100644 --- a/include/mi/neuraylib/imdl_backend_api.h +++ b/include/mi/neuraylib/imdl_backend_api.h @@ -52,7 +52,7 @@ class IMdl_backend; #mi::neuraylib::IMdl_backend_api::get_backend(). */ -/** \addtogroup mi_neuray_mdl_types +/** \addtogroup mi_neuray_mdl_misc @{ */ @@ -114,7 +114,7 @@ class IMdl_backend_api : public Size &rz) const = 0; }; -/*@}*/ // end group mi_neuray_mdl_types +/*@}*/ // end group mi_neuray_mdl_misc } // namespace neuraylib diff --git a/include/mi/neuraylib/imdl_compatibility_api.h b/include/mi/neuraylib/imdl_compatibility_api.h index 9ee941508..3105681d9 100644 --- a/include/mi/neuraylib/imdl_compatibility_api.h +++ b/include/mi/neuraylib/imdl_compatibility_api.h @@ -42,7 +42,7 @@ namespace neuraylib { class IMdl_execution_context; -/** \addtogroup mi_neuray_mdl_types +/** \addtogroup mi_neuray_mdl_misc @{ */ @@ -93,7 +93,7 @@ class IMdl_compatibility_api : public IMdl_execution_context* context) const = 0; }; -/*@}*/ // end group mi_neuray_mdl_types +/*@}*/ // end group mi_neuray_mdl_misc } // namespace neuraylib } // namespace mi diff --git a/include/mi/neuraylib/imdl_entity_resolver.h b/include/mi/neuraylib/imdl_entity_resolver.h index e07794e67..2f7a19e2b 100644 --- a/include/mi/neuraylib/imdl_entity_resolver.h +++ b/include/mi/neuraylib/imdl_entity_resolver.h @@ -42,7 +42,7 @@ class IMdl_resolved_module; class IMdl_resolved_resource; class IReader; -/** \addtogroup mi_neuray_mdl_sdk_misc +/** \addtogroup mi_neuray_mdl_misc @{ */ @@ -188,7 +188,7 @@ class IMdl_resolved_resource_element : public /// \param[out] u The u coordinate of the resource. /// \param[out] v The v coordinate of the resource. /// \return \c true if the uvtile mode is not #mi::neuraylib::UVTILE_MODE_NONE and \p i is - /// in range, \c false otherwise (and the output values are undefine). + /// in range, \c false otherwise (and the output values are undefined). virtual bool get_uvtile_uv( Size i, Sint32& u, Sint32& v) const = 0; }; @@ -244,7 +244,7 @@ class IMdl_resolved_resource : public virtual const IMdl_resolved_resource_element* get_element( Size i) const = 0; }; -/*@}*/ // end group mi_neuray_mdl_sdk_misc +/*@}*/ // end group mi_neuray_mdl_misc } // namespace neuraylib diff --git a/include/mi/neuraylib/imdl_evaluator_api.h b/include/mi/neuraylib/imdl_evaluator_api.h index 38dfb992d..a7ee250d5 100644 --- a/include/mi/neuraylib/imdl_evaluator_api.h +++ b/include/mi/neuraylib/imdl_evaluator_api.h @@ -43,7 +43,7 @@ class ITransaction; class IValue_bool; class IValue_factory; -/** \addtogroup mi_neuray_mdl_types +/** \addtogroup mi_neuray_mdl_misc @{ */ @@ -101,7 +101,7 @@ class IMdl_evaluator_api : public Sint32* error) const = 0; }; -/*@}*/ // end group mi_neuray_mdl_types +/*@}*/ // end group mi_neuray_mdl_misc } // namespace neuraylib } // namespace mi diff --git a/include/mi/neuraylib/imdl_execution_context.h b/include/mi/neuraylib/imdl_execution_context.h index 7af79c556..9a3da76c1 100644 --- a/include/mi/neuraylib/imdl_execution_context.h +++ b/include/mi/neuraylib/imdl_execution_context.h @@ -40,7 +40,7 @@ namespace mi { namespace neuraylib { -/** \addtogroup mi_neuray_mdl_types +/** \addtogroup mi_neuray_mdl_misc @{ */ @@ -316,7 +316,7 @@ class IMdl_execution_context: public }; -/*@}*/ // end group mi_neuray_mdl_types +/*@}*/ // end group mi_neuray_mdl_misc } // namespace neuraylib } // namespace mi diff --git a/include/mi/neuraylib/imdl_factory.h b/include/mi/neuraylib/imdl_factory.h index bfd9c2af8..04caee7b7 100644 --- a/include/mi/neuraylib/imdl_factory.h +++ b/include/mi/neuraylib/imdl_factory.h @@ -53,7 +53,14 @@ class IValue_factory; class IValue_light_profile; class IValue_texture; -/** \addtogroup mi_neuray_mdl_types +/** + \defgroup mi_neuray_mdl_misc Miscellaneous MDL-related Interfaces + \ingroup mi_neuray + + MDL-related interfaces excluding types, scene elements, and the compiler +*/ + +/** \addtogroup mi_neuray_mdl_misc @{ */ @@ -113,7 +120,10 @@ class IMdl_factory : public /// - -3: Failed to resolve the given file path, or no suitable image /// plugin available. /// \return The value referencing the texture, or \c NULL in case of failure. - virtual IValue_texture* create_texture( + /// + /// \see #mi::neuraylib::IImage::reset_file() if you are given a plain filename instead of an + /// MDL file path. + virtual IValue_texture* create_texture( ITransaction* transaction, const char* file_path, IType_texture::Shape shape, @@ -152,6 +162,9 @@ class IMdl_factory : public /// - -2: The file path is not an absolute MDL file path. /// - -3: Failed to resolve the given file path. /// \return The value referencing the light profile, or \c NULL in case of failure. + /// + /// \see #mi::neuraylib::ILightprofile::reset_file() if you are given a plain filename instead + /// of an MDL file path. virtual IValue_light_profile* create_light_profile( ITransaction* transaction, const char* file_path, bool shared, Sint32* errors = 0) = 0; @@ -175,6 +188,9 @@ class IMdl_factory : public /// - -3: Failed to resolve the given file path. /// \return The value referencing the BSDF measurement, or \c NULL in case of /// failure. + /// + /// \see #mi::neuraylib::IBsdf_measurement::reset_file() if you are given a plain filename + /// instead of an MDL file path. virtual IValue_bsdf_measurement* create_bsdf_measurement( ITransaction* transaction, const char* file_path, bool shared, Sint32* errors = 0) = 0; @@ -371,7 +387,7 @@ class IMdl_factory : public IMdl_execution_context* context) = 0; }; -/*@}*/ // end group mi_neuray_mdl_types +/*@}*/ // end group mi_neuray_mdl_misc } // namespace neuraylib diff --git a/include/mi/neuraylib/imdl_impexp_api.h b/include/mi/neuraylib/imdl_impexp_api.h index 9fe0d6f98..a87959582 100644 --- a/include/mi/neuraylib/imdl_impexp_api.h +++ b/include/mi/neuraylib/imdl_impexp_api.h @@ -56,7 +56,7 @@ class IType; class IType_list; class IWriter; -/** \addtogroup mi_neuray_mdl_types +/** \addtogroup mi_neuray_mdl_misc @{ */ @@ -596,7 +596,7 @@ class IMdle_deserialization_callback : public virtual const IString* get_deserialized_filename( const char* serialized_filename) const = 0; }; -/*@}*/ // end group mi_neuray_mdl_types +/*@}*/ // end group mi_neuray_mdl_misc } // namespace neuraylib diff --git a/include/mi/neuraylib/imdl_loading_wait_handle.h b/include/mi/neuraylib/imdl_loading_wait_handle.h index 22d0e6907..5dbd0038e 100644 --- a/include/mi/neuraylib/imdl_loading_wait_handle.h +++ b/include/mi/neuraylib/imdl_loading_wait_handle.h @@ -38,7 +38,7 @@ namespace mi { namespace neuraylib { -/** \addtogroup mi_neuray_mdl_types +/** \addtogroup mi_neuray_mdl_misc @{ */ @@ -95,7 +95,7 @@ class IMdl_loading_wait_handle_factory : public virtual IMdl_loading_wait_handle* create_wait_handle() const = 0; }; -/*@}*/ // end group mi_neuray_mdl_types +/*@}*/ // end group mi_neuray_mdl_misc } // namespace neuraylib } // namespace mi diff --git a/include/mi/neuraylib/imdl_module_builder.h b/include/mi/neuraylib/imdl_module_builder.h index c85392b7e..325987870 100644 --- a/include/mi/neuraylib/imdl_module_builder.h +++ b/include/mi/neuraylib/imdl_module_builder.h @@ -46,7 +46,7 @@ class IExpression; class IExpression_list; class IMdl_execution_context; -/** \addtogroup mi_neuray_mdl_sdk_misc +/** \addtogroup mi_neuray_mdl_misc @{ */ @@ -245,7 +245,7 @@ class IMdl_module_builder: public IMdl_execution_context* context) = 0; }; -/*@}*/ // end group mi_neuray_mdl_sdk_misc +/*@}*/ // end group mi_neuray_mdl_misc } // namespace neuraylib diff --git a/include/mi/neuraylib/imdl_module_transformer.h b/include/mi/neuraylib/imdl_module_transformer.h index 37fdd4b90..9ac814b8e 100644 --- a/include/mi/neuraylib/imdl_module_transformer.h +++ b/include/mi/neuraylib/imdl_module_transformer.h @@ -42,7 +42,7 @@ namespace neuraylib { class IMdl_execution_context; -/** \addtogroup mi_neuray_mdl_sdk_misc +/** \addtogroup mi_neuray_mdl_misc @{ */ diff --git a/include/mi/neuraylib/imdle_api.h b/include/mi/neuraylib/imdle_api.h index d9232d993..40b89bd6f 100644 --- a/include/mi/neuraylib/imdle_api.h +++ b/include/mi/neuraylib/imdle_api.h @@ -44,7 +44,7 @@ class IMdl_execution_context; class IReader; class ITransaction; -/** \addtogroup mi_neuray_mdl_types +/** \addtogroup mi_neuray_mdl_misc @{ */ @@ -172,7 +172,7 @@ class IMdle_api : public IMdl_execution_context* context) const = 0; }; -/*@}*/ // end group mi_neuray_mdl_types +/*@}*/ // end group mi_neuray_mdl_misc } // namespace neuraylib } // namespace mi diff --git a/include/mi/neuraylib/imodule.h b/include/mi/neuraylib/imodule.h index f81f6b510..3a324e29e 100644 --- a/include/mi/neuraylib/imodule.h +++ b/include/mi/neuraylib/imodule.h @@ -619,7 +619,7 @@ The following requirements apply when creating function calls of the ternary ope - the expression named \c "cast" is of an arbitrary type (this is the intended argument of the function call), - the type of the expression named \c "cast_return" specifies the return type of the function - call (the expression itself is not used), and + call (no frequency qualifiers; the expression itself is not used), and - the types of \c "cast" and \c "cast_return" are compatible. The suffix for the serialized name has two arguments, the type name of the \c "cast" expression, @@ -660,7 +660,7 @@ obtain that interface right before that call, and to use it only for that call i \subsection mi_mdl_materials_are_functions_api_changes API Changes when materials are functions -Treating materials as functionse comes with a few API changes that need to be takes into account. +Treating materials as functions comes with a few API changes that need to be takes into account. Code shared between different applications, i.e., in plugins, should be able to handle both settings. diff --git a/include/mi/neuraylib/iserializer.h b/include/mi/neuraylib/iserializer.h index 036f275ae..e6f36342e 100644 --- a/include/mi/neuraylib/iserializer.h +++ b/include/mi/neuraylib/iserializer.h @@ -49,7 +49,7 @@ class IDeserializer; */ /** \if IRAY_API \addtogroup mi_neuray_plugins -\elseif MDL_SOURCE_RELEASE \addtogroup mi_neuray_plugins +\elseif MDL_SDK_API \addtogroup mi_neuray_plugins \else \addtogroup mi_neuray_dice \endif @{ @@ -309,4 +309,3 @@ class ISerializer : } // namespace mi #endif // MI_NEURAYLIB_ISERIALIZER_H - diff --git a/include/mi/neuraylib/itransaction.h b/include/mi/neuraylib/itransaction.h index 90e8c8dce..993299dc0 100644 --- a/include/mi/neuraylib/itransaction.h +++ b/include/mi/neuraylib/itransaction.h @@ -56,7 +56,7 @@ class IScope; /// #mi::neuraylib::IScope::create_transaction(). /// /// Transactions are not thread-safe. If you use a particular transaction from multiple threads, -/// then you have to serialize all transaction uses. This does not ony apply to methods of +/// then you have to serialize all transaction uses. This does not only apply to methods of /// #mi::neuraylib::ITransaction, but all methods that implicitly use the transaction. For example, /// such a use can happen by methods of DB elements returned from #access() or #edit() calls, or by /// objects returned from factories taking the transaction as \ifnot DICE_API argument, like diff --git a/include/mi/neuraylib/itype.h b/include/mi/neuraylib/itype.h index a7f9c80b3..6e84961d3 100644 --- a/include/mi/neuraylib/itype.h +++ b/include/mi/neuraylib/itype.h @@ -57,7 +57,8 @@ namespace neuraylib { In addition, the free functions #mi::neuraylib::get_value() and #mi::neuraylib::set_value() are useful to read and write instances of #mi::neuraylib::IValue. - See \ref mi_neuray_mdl_elements for MDL elements that make use of this type system. + See \ref mi_neuray_mdl_elements and \ref mi_neuray_mdl_misc for interfaces that make use of + this type system. */ /** \addtogroup mi_neuray_mdl_types diff --git a/src/api/api/neuray/neuray_attribute_set_impl_helper.cpp b/src/api/api/neuray/neuray_attribute_set_impl_helper.cpp index 8987244a5..2ec9f344f 100644 --- a/src/api/api/neuray/neuray_attribute_set_impl_helper.cpp +++ b/src/api/api/neuray/neuray_attribute_set_impl_helper.cpp @@ -538,12 +538,12 @@ std::string Attribute_set_impl_helper::get_attribute_type_name( while( member_type) { std::string member_type_name = get_attribute_type_name( *member_type, false); if( member_type_name.empty()) - return ""; - attribute_type_name += " "; + return std::string(); + attribute_type_name += ' '; attribute_type_name += member_type_name; - attribute_type_name += " "; + attribute_type_name += ' '; attribute_type_name += member_type->get_name(); //-V769 PVS - attribute_type_name += ";"; + attribute_type_name += ';'; member_type = member_type->get_next(); } attribute_type_name += " }"; diff --git a/src/api/api/neuray/neuray_factory_impl.cpp b/src/api/api/neuray/neuray_factory_impl.cpp index 8a9c97b78..21133d079 100644 --- a/src/api/api/neuray/neuray_factory_impl.cpp +++ b/src/api/api/neuray/neuray_factory_impl.cpp @@ -1323,11 +1323,11 @@ mi::neuraylib::ITransaction* Factory_impl::get_transaction( const mi::IData* dat } // extract transaction from ICompound - if( data->compare_iid( mi::ICompound::IID())) + if( mi::ICompound::compare_iid( data->get_iid())) return nullptr; // all interfaces derived from IData_collection should be handled now - ASSERT( M_NEURAY_API, !data->compare_iid( mi::IData_collection::IID())); + ASSERT( M_NEURAY_API, !mi::IData_collection::compare_iid( data->get_iid())); // extract transaction from IPointer mi::base::Handle pointer( data->get_interface()); diff --git a/src/api/api/neuray/neuray_mdl_resource_callback.cpp b/src/api/api/neuray/neuray_mdl_resource_callback.cpp index 6c3895c81..2885f4fa6 100644 --- a/src/api/api/neuray/neuray_mdl_resource_callback.cpp +++ b/src/api/api/neuray/neuray_mdl_resource_callback.cpp @@ -582,7 +582,7 @@ std::string Resource_callback::export_texture_image( mi::base::Handle mipmap( image->get_mipmap( m_transaction, /*frame_id*/ 0, /*uvtile_id*/ 0)); mi::base::Handle canvas( mipmap->get_level( 0)); - const char* extension = get_extension( canvas->get_type()); + const char* new_extension = get_extension( canvas->get_type()); bool add_sequence_marker = image->is_animated(); bool add_uvtile_marker = image->is_uvtile(); @@ -592,11 +592,28 @@ std::string Resource_callback::export_texture_image( mi::Size f = n > 0 ? image->get_frame_number( n-1) : 0; while( f > 9) { ++frame_digits; f /= 10; } + // Figure out whether we can copy all frames/uvtiles. If yes, then we can keep the extension. + // Otherwise we need to re-export all frames/uvtiles to match the chosen extension. + bool copy_all = !buffer_callback; + for( mi::Size i = 0; copy_all && (i < n); ++i) { + mi::Size m = image->get_frame_length( i); + for( mi::Size j = 0; copy_all && (j < m); ++j) { + std::string old_filename_fuv = image->get_filename( i, j); + if( old_filename_fuv.empty()) + copy_all = false; + if( !DISK::is_file( old_filename_fuv.c_str())) + copy_all = false; + } + } + // Both filenames might include frame/uvtile markers. - std::string old_filename = image->get_original_filename(); + std::string old_filename = image->get_mdl_file_path(); + if( old_filename.empty()) + old_filename = image->get_original_filename(); std::string new_filename = get_new_resource_filename_marker( - extension, + new_extension, old_filename.empty() ? nullptr : old_filename.c_str(), + !copy_all, add_sequence_marker, add_uvtile_marker, frame_digits); @@ -622,12 +639,13 @@ std::string Resource_callback::export_texture_image( if( buffer_callback) { // export via buffer callback + assert( !copy_all); mi::base::Handle mipmap( image->get_mipmap( m_transaction, i, j)); mi::base::Handle canvas( mipmap->get_level( 0)); mi::base::Handle buffer( m_image_module->create_buffer_from_canvas( - canvas.get(), extension+1, canvas->get_type())); + canvas.get(), new_extension+1, canvas->get_type())); if( buffer) { std::string tmp = (*buffer_callback)( buffer.get(), new_filename_fuv.c_str()); @@ -635,11 +653,12 @@ std::string Resource_callback::export_texture_image( } else { success = false; } - } else if( !old_filename_fuv.empty() && DISK::is_file( old_filename_fuv.c_str())) { + } else if( copy_all) { // copy the file success &= DISK::file_copy( old_filename_fuv.c_str(), new_filename_fuv.c_str()); } else { // export to file + assert( !copy_all); success &= m_image_module->export_canvas( canvas.get(), new_filename_fuv.c_str()); } } @@ -656,8 +675,9 @@ std::string Resource_callback::export_light_profile( std::string old_filename = profile->get_filename(); if( old_filename.empty()) old_filename = profile->get_original_filename(); + // Value of use_new_extension does not matter since there is only one valid extension. std::string new_filename = get_new_resource_filename( - ".ies", old_filename.empty() ? nullptr : old_filename.c_str()); + ".ies", old_filename.empty() ? nullptr : old_filename.c_str(), /*use_new_extension*/ true); bool success = false; @@ -687,8 +707,9 @@ std::string Resource_callback::export_bsdf_measurement( std::string old_filename = measurement->get_filename(); if( old_filename.empty()) old_filename = measurement->get_original_filename(); + // Value of use_new_extension does not matter since there is only one valid extension. std::string new_filename = get_new_resource_filename( - ".mbsdf", old_filename.empty() ? nullptr : old_filename.c_str()); + ".mbsdf", old_filename.empty() ? nullptr : old_filename.c_str(), /*use_new_extension*/ true); mi::base::Handle refl( measurement->get_reflection( m_transaction)); @@ -717,23 +738,26 @@ std::string Resource_callback::export_bsdf_measurement( } std::string Resource_callback::get_new_resource_filename( - const char* extension, const char* old_filename) + const char* new_extension, const char* old_filename, bool use_new_extension) { ASSERT( M_NEURAY_API, !m_path_prefix.empty()); + ASSERT( M_NEURAY_API, old_filename || use_new_extension); - std::string s; + std::string s, old_extension; if( old_filename) { - std::string old_root, old_ext; - HAL::Ospath::splitext( strip_directories( old_filename), old_root, old_ext); - s = m_path_prefix + "_" + old_root + extension; + std::string old_root; + HAL::Ospath::splitext( strip_directories( old_filename), old_root, old_extension); + s = m_path_prefix + "_" + old_root; + s += use_new_extension ? std::string( new_extension) : old_extension; if( !DISK::is_file( s.c_str())) return s; } do { std::ostringstream ss; - ss << m_path_prefix << "_resource_" << m_counter++ << extension; + ss << m_path_prefix << "_resource_" << m_counter++; + ss << (use_new_extension ? std::string( new_extension) : old_extension); s = ss.str(); } while( DISK::is_file( s.c_str())); @@ -741,23 +765,26 @@ std::string Resource_callback::get_new_resource_filename( } std::string Resource_callback::get_new_resource_filename_marker( - const char* extension, + const char* new_extension, const char* old_filename, + bool use_new_extension, bool add_sequence_marker, bool add_uvtile_marker, mi::Size frame_digits) { if( !add_sequence_marker && !add_uvtile_marker) - return get_new_resource_filename( extension, old_filename); + return get_new_resource_filename( new_extension, old_filename, use_new_extension); ASSERT( M_NEURAY_API, !m_path_prefix.empty()); + ASSERT( M_NEURAY_API, old_filename || use_new_extension); - std::string s; + std::string s, old_extension; if( old_filename) { - std::string old_root, old_ext; - HAL::Ospath::splitext( strip_directories( old_filename), old_root, old_ext); - s = m_path_prefix + "_" + old_root + extension; + std::string old_root; + HAL::Ospath::splitext( strip_directories( old_filename), old_root, old_extension); + s = m_path_prefix + "_" + old_root; + s += use_new_extension ? std::string( new_extension) : old_extension; return s; } @@ -789,7 +816,7 @@ std::string Resource_callback::get_new_resource_filename_marker( } } - s += extension; + s += use_new_extension ? std::string( new_extension) : old_extension; return s; } diff --git a/src/api/api/neuray/neuray_mdl_resource_callback.h b/src/api/api/neuray/neuray_mdl_resource_callback.h index a17b7cb7a..59b2a5d9d 100644 --- a/src/api/api/neuray/neuray_mdl_resource_callback.h +++ b/src/api/api/neuray/neuray_mdl_resource_callback.h @@ -171,29 +171,31 @@ class Resource_callback /// \name Utilities //@{ - /// Generates a filename for resources with the given extension and/or based on old filename. + /// Generates a filename for resources with the new extension and/or based on old filename. /// /// Does not support images with uvtiles or non-trivial frames. /// /// If \p old_filename is not \p NULL and the filename derived from it does not already exist, - /// return it. Otherwise, generate a generic filename with the given extension that does not - /// already exist. + /// return it. Otherwise, generate a generic filename with the new or original extension that + /// does not already exist. /// - /// Returns m_path_prefix + "_" + strip_directories(old_filename) or + /// Returns m_path_prefix + "_" + stem(old_filename) + "." + extension or /// m_path_prefix + _resource_" + counter + extension . - std::string get_new_resource_filename( const char* extension, const char* old_filename); + std::string get_new_resource_filename( + const char* new_extension, const char* old_filename, bool use_new_extension); - /// Generates a filename for images with the given extension and/or based on old filename. + /// Generates a filename for images with the new extension and/or based on old filename. /// /// Invokes #get_new_resource_filename() if \p add_sequence_marker and \p add_uvtile_marker /// are \c false. /// /// Otherwise, if \p old_filename is not \p NULL, returns a filename with markers derived from - /// it (no existence check). Otherwise, generate a generic filename with the given extension - /// and markers (no existence check). + /// it (no existence check). Otherwise, generate a generic filename with the new or original + /// extension and markers (no existence check). std::string get_new_resource_filename_marker( - const char* extension, + const char* new_extension, const char* old_filename, + bool use_new_extension, bool add_sequence_marker, bool add_uvtile_marker, mi::Size frame_digits); diff --git a/src/api/api/neuray/neuray_version_impl.cpp b/src/api/api/neuray/neuray_version_impl.cpp index 2e0e772d9..24a1989ec 100644 --- a/src/api/api/neuray/neuray_version_impl.cpp +++ b/src/api/api/neuray/neuray_version_impl.cpp @@ -72,7 +72,7 @@ Version_impl::Version_impl() { m_stripped_platform = strip_compiler_suffix(VERSION::get_platform_os()); - m_version = get_product_name() + std::string(" ") + get_product_version(); + m_version = std::string(get_product_name()) + ' ' + get_product_version(); m_version += std::string( ", build ") + VERSION::get_platform_version(); m_version += std::string( ", ") + VERSION::get_platform_date(); m_version += std::string( ", ") + m_stripped_platform; diff --git a/src/base/data/attr/attr.h b/src/base/data/attr/attr.h index 3ca091a0d..f4ed4ee32 100644 --- a/src/base/data/attr/attr.h +++ b/src/base/data/attr/attr.h @@ -372,16 +372,28 @@ class Attribute_set : public SERIAL::Serializable /// Detach an attribute, but don't destroy it. The std::shared_ptr return value /// takes care of destroying the attribute in the end. + /// + /// All iterators and references to the given element become invalid. + /// /// \param id ID of attribute to detach std::shared_ptr detach( Attribute_id id); /// Detach an attribute, but don't destroy it. The std::shared_ptr return value /// takes care of destroying the attribute in the end. + /// + /// All iterators and references to the given element become invalid. + /// /// \param name name of attribute to detach std::shared_ptr detach( const char* name); + /// Replaces the attribute at the given value's id with the given value. + /// See #attach for details. + /// \return success or failure + bool replace( + const std::shared_ptr& attr); + /// Clear the attribute set, i.e. detach and delete all attributes void clear(); diff --git a/src/base/data/attr/attr_attrset.cpp b/src/base/data/attr/attr_attrset.cpp index 70090da48..d613291d9 100644 --- a/src/base/data/attr/attr_attrset.cpp +++ b/src/base/data/attr/attr_attrset.cpp @@ -278,6 +278,19 @@ std::shared_ptr Attribute_set::detach( return detach(Attribute::id_lookup(name)); } +bool Attribute_set::replace( + const std::shared_ptr& attr) +{ + Iter it = m_attrs.find(attr->get_id()); + if (it != m_attrs.end()) { + it->second = attr; + return true; + } + + return false; +} + + // // deep copy of all Attributes diff --git a/src/base/data/attr/attr_inline_type.h b/src/base/data/attr/attr_inline_type.h index 93b21c14e..f50b656a3 100644 --- a/src/base/data/attr/attr_inline_type.h +++ b/src/base/data/attr/attr_inline_type.h @@ -31,10 +31,28 @@ #include #include +#include namespace MI { namespace ATTR { +namespace { + +ATTR::Type_code to_valid_range(const ATTR::Type_code code) +{ + if (code < TYPE_UNDEF || code >= TYPE_NUM) + { + MI::LOG::mod_log->warning(M_ATTR, LOG::Mod_log::C_DATABASE, 49, + "Invalid type code: %d", code); + return TYPE_UNDEF; + } + + return code; +} + +} // unnamed namespace + + // return true if the two types agree exactly, including all child types. This // is useful to check that the values are compatible, for example for shader // parameter inheritance and assignment. Names are not compared. @@ -146,6 +164,89 @@ MI_INLINE std::vector >* Type::get_enum() const return m_enum; } +MI_INLINE void Type::set_name( + const char *name) // new field name +{ + if (name) + m_name = name; + else + m_name.clear(); +} + + +// +// Set the next Type. +// + +MI_INLINE void Type::set_next( + const Type &next) // new successor +{ + delete m_next; + m_next = new Type(next); +} + +// +// return the size of one member of a type. For example, a color is 16 +// bytes, regardless of the array size because the array size isn't known +// here. Note that the nonstatic sizeof_one() does include the static array +// size. Structs have size 0 since their members are not included either. +// + +MI_INLINE size_t Type::sizeof_one( + Type_code type) // return size of one of this type +{ + return m_typeinfo[type].comp * m_typeinfo[type].size; +} + + +// +// return the ascii name of a type. Useful for all sorts of user messages. +// + +MI_INLINE const char *Type::type_name( + Type_code type) // type to look up +{ + type = to_valid_range(type); + return m_typeinfo[type].name; +} + + +// +// return how a type is composed of component types, ie. a Color is 4 Scalars. +// + +MI_INLINE Uint Type::component_count( + Type_code type) // type, ie. Color -> 4 components +{ + type = to_valid_range(type); + return m_typeinfo[type].comp; +} + + +MI_INLINE Type_code Type::component_type( + Type_code type) // type, ie. Color -> Scalar +{ + type = to_valid_range(type); + return m_typeinfo[type].base; +} + +MI_INLINE const char *Type::component_name( //-V524 PVS + Type_code type) // type, ie. Color -> Scalar +{ + type = to_valid_range(type); + return m_typeinfo[type].name; +} + +// +// Am I the given subclass? (poor man's dynamic_cast support) +// This base class implementation return false in any case. +// + +MI_INLINE bool Type::is_type_subclass( + SERIAL::Class_id id) const // id of the requested subclass +{ + return false; +} // write access functions. Setting next/child deletes the entire old chain. MI_INLINE void Type::set_typecode( @@ -181,6 +282,12 @@ MI_INLINE void Type::set_arraysize( } } +MI_INLINE void Type::set_type_name( + const std::string& str) +{ + m_type_name = str; +} + // return the alignment of one member of this type. The alignment is an address // multiple where a compiler would store a value of this type. For example, an diff --git a/src/base/data/attr/attr_type.cpp b/src/base/data/attr/attr_type.cpp index abc98adab..28df176d5 100644 --- a/src/base/data/attr/attr_type.cpp +++ b/src/base/data/attr/attr_type.cpp @@ -40,7 +40,6 @@ #include #include #include -#include #undef EXPERIMENTAL_ARRAYS_OF_ARRAYS_MODE @@ -152,22 +151,6 @@ const Type::Typeinfo Type::m_typeinfo[] = { }; -namespace { - -ATTR::Type_code to_valid_range(const ATTR::Type_code code) -{ - if (code < TYPE_UNDEF || code >= TYPE_NUM) - { - mod_log->warning(M_ATTR, LOG::Mod_log::C_DATABASE, 49, - "Invalid type code: %d", code); - return TYPE_UNDEF; - } - - return code; -} - -} // unnamed namespace - // // constructor. // @@ -178,6 +161,7 @@ Type::Type( Uint arraysize) // number of elements, 0=dynamic { mi_static_assert(TYPE_NUM == (sizeof(m_typeinfo) / sizeof(Typeinfo))); + mi_static_assert(sizeof(Type::m_typeinfo) == TYPE_NUM * sizeof(Type::Typeinfo)); ASSERT(M_ATTR, type != TYPE_ID); type = to_valid_range(type); @@ -223,28 +207,6 @@ Type::~Type() } -void Type::set_name( - const char *name) // new field name -{ - if (name) - m_name = name; - else - m_name.clear(); -} - - -// -// Set the next Type. -// - -void Type::set_next( - const Type &next) // new successor -{ - delete m_next; - m_next = new Type(next); -} - - // The normal handling for structs is unchanged. Only adding a child Type to an array Type requires // special handling. void Type::set_child( @@ -292,60 +254,6 @@ void Type::set_child( } -// -// return the size of one member of a type. For example, a color is 16 -// bytes, regardless of the array size because the array size isn't known -// here. Note that the nonstatic sizeof_one() does include the static array -// size. Structs have size 0 since their members are not included either. -// - -size_t Type::sizeof_one( - Type_code type) // return size of one of this type -{ - mi_static_assert(sizeof(m_typeinfo) == TYPE_NUM * sizeof(Type::Typeinfo)); - return m_typeinfo[type].comp * m_typeinfo[type].size; -} - - -// -// return the ascii name of a type. Useful for all sorts of user messages. -// - -const char *Type::type_name( - Type_code type) // type to look up -{ - type = to_valid_range(type); - return m_typeinfo[type].name; -} - - -// -// return how a type is composed of component types, ie. a Color is 4 Scalars. -// - -Uint Type::component_count( - Type_code type) // type, ie. Color -> 4 components -{ - type = to_valid_range(type); - return m_typeinfo[type].comp; -} - - -Type_code Type::component_type( - Type_code type) // type, ie. Color -> Scalar -{ - type = to_valid_range(type); - return m_typeinfo[type].base; -} - -const char *Type::component_name( //-V524 PVS - Type_code type) // type, ie. Color -> Scalar -{ - type = to_valid_range(type); - return m_typeinfo[type].name; -} - - //-------------------------------------------------------------------------------------------------- // Given a complete name, return the Type of the subtree, and an offset into a value structure @@ -559,18 +467,6 @@ const Type* Type::lookup( } -// -// Am I the given subclass? (poor man's dynamic_cast support) -// This base class implementation return false in any case. -// - -bool Type::is_type_subclass( - SERIAL::Class_id id) const // id of the requested subclass -{ - return false; -} - - // // serialize the object to the given serializer including all sub elements. // It must return a pointer behind itself (e.g. this + 1) to handle arrays. @@ -708,13 +604,6 @@ void Type::dump() const } -void Type::set_type_name( - const std::string& str) -{ - m_type_name = str; -} - - // // return a string that describes the type including subtypes. // diff --git a/src/base/hal/disk/disk.cpp b/src/base/hal/disk/disk.cpp index ed322bcbd..8909fc877 100644 --- a/src/base/hal/disk/disk.cpp +++ b/src/base/hal/disk/disk.cpp @@ -549,7 +549,7 @@ std::string get_cwd() } set_error(0); - std::string cwd(STRING::wchar_to_utf8(&buf[0])); + std::string cwd(STRING::wchar_to_utf8(buf.data())); return cwd; } diff --git a/src/base/lib/config/config.cpp b/src/base/lib/config/config.cpp index f55463a74..937c43d79 100644 --- a/src/base/lib/config/config.cpp +++ b/src/base/lib/config/config.cpp @@ -235,7 +235,7 @@ std::pair parse( } else { // numbers: copy ASSERT(M_CONFIG, newtype == 'f'); - float val = float(atof(&(value[0])[0])); + float val = float(atof(value[0].c_str())); result.second = STLEXT::Any(val); } diff --git a/src/base/system/main/common.ver b/src/base/system/main/common.ver index f3560749e..9503fdf73 100644 --- a/src/base/system/main/common.ver +++ b/src/base/system/main/common.ver @@ -36,7 +36,7 @@ BEGIN VALUE "Copyright", VER_LEGALCOPYRIGHT_STR VALUE "ProductName", VER_PRODUCTNAME_STR #ifdef VER_BRIDGE_VERSION_STR - VALUE "ProductVersion", VER_PRODUCTVERSION_STR " (Bridge Version:" VER_BRIDGE_VERSION_STR ")" + VALUE "ProductVersion", VER_PRODUCTVERSION_STR " (Bridge:" VER_BRIDGE_VERSION_STR ")" #else VALUE "ProductVersion", VER_PRODUCTVERSION_STR #endif diff --git a/src/base/system/version/version.h b/src/base/system/version/version.h index d967578d4..ebee0fbb9 100644 --- a/src/base/system/version/version.h +++ b/src/base/system/version/version.h @@ -1,15 +1,15 @@ /* Globally unique version identifier string. */ -#define MI_VERSION_STRING "349500.7063" +#define MI_VERSION_STRING "349500.8264" /* Version identifier for use in Windows resource compiler scripts (4 x 16bits) */ -#define MI_VERSION_CSV 34,9500,7063,0 +#define MI_VERSION_CSV 34,9500,8264,0 /* Alternate version identifier for compatibility with existing mill builds */ -#define MI_VERSION_CSV_BIG 34950,0,7063,0 +#define MI_VERSION_CSV_BIG 34950,0,8264,0 /* Numeric version identifier, meaningful only in the context of this branch. */ -#define MI_BUILD_NUMBER 7063 +#define MI_BUILD_NUMBER 8264 /* Global numeric version identifier */ -#define MI_BUILD_NUMBER_FULL 356563 +#define MI_BUILD_NUMBER_FULL 357764 -#define MI_DATE_STRING "18 Jan 2022" +#define MI_DATE_STRING "18 Mar 2022" diff --git a/src/base/util/string_utils/string_utils.cpp b/src/base/util/string_utils/string_utils.cpp index 4ad5270c3..357ed2ef9 100644 --- a/src/base/util/string_utils/string_utils.cpp +++ b/src/base/util/string_utils/string_utils.cpp @@ -34,8 +34,6 @@ #include #include -#include -#include #include @@ -168,7 +166,7 @@ string to_lower( const string& input) { std::string result(input); - to_lower(static_cast(result)); + to_lower(result); return result; } @@ -177,7 +175,7 @@ string to_upper( const string& input) { std::string result(input); - to_upper(static_cast(result)); + to_upper(result); return result; } @@ -245,6 +243,38 @@ string wchar_to_mbs( return result; } + +#if 0 // uses windows.h functionality instead of "manual" en/decoding +// from UTF8 +std::wstring string_to_wide_string(const std::string& str) +{ + if (str.empty()) + return std::wstring(); + + const int size_needed = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), (int)str.length(), nullptr, 0); + if (size_needed <= 0) + return std::wstring(); + + std::vector result(size_needed+10); // MSDN has this +10, for whatever reason + MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, result.data(), size_needed+10); + return result.data(); +} + +// to UTF8 +std::string wide_string_to_string(const std::wstring& wide_str) +{ + if (wide_str.empty()) + return std::string(); + + const int size_needed = WideCharToMultiByte(CP_UTF8, 0, wide_str.c_str(), (int)wide_str.length(), nullptr, 0, nullptr, nullptr); + if (size_needed <= 0) + return std::string(); + + std::vector result(size_needed); + WideCharToMultiByte(CP_UTF8, 0, wide_str.c_str(), -1, result.data(), size_needed, nullptr, nullptr); + return result.data(); +} +#endif #endif // Converts a wchar_t * string into an utf8 encoded string. diff --git a/src/io/image/image/i_image.h b/src/io/image/image/i_image.h index 07e77b719..1897834dd 100644 --- a/src/io/image/image/i_image.h +++ b/src/io/image/image/i_image.h @@ -131,7 +131,8 @@ class Image_module : public SYSTEM::IModule /// default gamma which is 1.0 for HDR pixel types and 2.2 for LDR /// pixel types. /// \return The requested mipmap, or \c NULL in case of invalid pixel type, - /// width, height, layers, or cubemap flag. + /// width, height, layers, or cubemap flag, or memory allocation + /// failures. virtual IMipmap* create_mipmap( Pixel_type pixel_type, mi::Uint32 width, @@ -254,7 +255,8 @@ class Image_module : public SYSTEM::IModule /// default gamma which is 1.0 for HDR pixel types and 2.2 for LDR /// pixel types. /// \return The requested canvas, or \c NULL in case of invalid pixel type, - /// width, height, layers, or cubemap flag. + /// width, height, layers, or cubemap flag, or memory allocation + /// failures. virtual mi::neuraylib::ICanvas* create_canvas( Pixel_type pixel_type, mi::Uint32 width, @@ -361,7 +363,7 @@ class Image_module : public SYSTEM::IModule /// \param width The desired width. /// \param height The desired height. /// \return The requested tile, or \c NULL in case of invalid pixel type, - /// width, or height. + /// width, or height, or memory allocation failures. virtual mi::neuraylib::ITile* create_tile( Pixel_type pixel_type, mi::Uint32 width, diff --git a/src/io/image/image/i_image_quantization.h b/src/io/image/image/i_image_quantization.h index 950170e29..52e68a4b7 100644 --- a/src/io/image/image/i_image_quantization.h +++ b/src/io/image/image/i_image_quantization.h @@ -74,7 +74,7 @@ MI_HOST_DEVICE_INLINE unsigned quantize_unsigned(const float x) enum { N = (1u << bits) - 1, Np1 = (1u << bits) }; //return min((unsigned)(x * (float)Np1),(unsigned)N); // does not handle large values, as these trigger undefined behavior (on x86: 0) #ifdef __CUDA_ARCH__ - return (unsigned)(fminf(x, uint_as_float(0x3f800000u-1)) * (float)Np1); + return (unsigned)(fminf(x, __uint_as_float(0x3f800000u-1)) * (float)Np1); #else return (unsigned)(min(x, mi::base::binary_cast(0x3f800000u-1)) * (float)Np1); #endif diff --git a/src/io/image/image/image_module_impl.cpp b/src/io/image/image/image_module_impl.cpp index 6380ae2e4..fed33be75 100644 --- a/src/io/image/image/image_module_impl.cpp +++ b/src/io/image/image/image_module_impl.cpp @@ -159,8 +159,11 @@ IMipmap* Image_module_impl::create_mipmap( if( is_cubemap && layers != 6) return nullptr; - return new Mipmap_impl( - pixel_type, width, height, layers, is_cubemap, gamma); + try { + return new Mipmap_impl( pixel_type, width, height, layers, is_cubemap, gamma); + } catch( const std::bad_alloc& e) { + return nullptr; + } } IMipmap* Image_module_impl::create_mipmap( @@ -266,8 +269,11 @@ mi::neuraylib::ICanvas* Image_module_impl::create_canvas( if( is_cubemap && layers != 6) return nullptr; - return new Canvas_impl( - pixel_type, width, height, layers, is_cubemap, gamma); + try { + return new Canvas_impl( pixel_type, width, height, layers, is_cubemap, gamma); + } catch( const std::bad_alloc& e) { + return nullptr; + } } mi::neuraylib::ICanvas* Image_module_impl::create_canvas( @@ -340,7 +346,11 @@ mi::neuraylib::ITile* Image_module_impl::create_tile( if( width == 0 || height == 0 || pixel_type == PT_UNDEF) return nullptr; - return IMAGE::create_tile( pixel_type, width, height); + try { + return IMAGE::create_tile( pixel_type, width, height); + } catch( const std::bad_alloc& e) { + return nullptr; + } } IMipmap* Image_module_impl::copy_mipmap( const IMipmap* other, bool only_first_level) const diff --git a/src/io/scene/lightprofile/lightprofile_ies_parser.cpp b/src/io/scene/lightprofile/lightprofile_ies_parser.cpp index 61408c54d..681c83c12 100644 --- a/src/io/scene/lightprofile/lightprofile_ies_parser.cpp +++ b/src/io/scene/lightprofile/lightprofile_ies_parser.cpp @@ -497,7 +497,7 @@ bool Lightprofile_ies_parser::parse_label(char* label) while(*label && isspace(static_cast(*label))) label++; // remove trailing white space - std::string label_tag = ""; + std::string label_tag; if(*label == '[') { label++; @@ -516,7 +516,7 @@ bool Lightprofile_ies_parser::parse_label(char* label) while(*label && isspace(static_cast(*label))) label++; // remove trailing white space - std::string label_contents = ""; + std::string label_contents; while(*label) { label_contents += *label; @@ -559,7 +559,7 @@ void Lightprofile_ies_parser::parse_tilt(char* tilt) while (*tilt && isspace(static_cast(*tilt))) tilt++; // remove trailing white space - std::string tilt_value = ""; + std::string tilt_value; while (*tilt) { tilt_value += *tilt; diff --git a/src/io/scene/mdl_elements/mdl_elements_ast_builder.cpp b/src/io/scene/mdl_elements/mdl_elements_ast_builder.cpp index cdc0e45a1..175725eee 100644 --- a/src/io/scene/mdl_elements/mdl_elements_ast_builder.cpp +++ b/src/io/scene/mdl_elements/mdl_elements_ast_builder.cpp @@ -1303,10 +1303,17 @@ static std::string get_texture_resource_name_gamma_selector( if( !s1.empty()) return s1; const std::string& s2 = image->get_filename( 0, 0); + if( s2.empty()) + return std::string(); + const std::string& s3 = get_file_path( + s2, mi::neuraylib::IMdl_impexp_api::SEARCH_OPTION_USE_FIRST); // Do not use the filename for animated textures/uvtiles since it only identifies the first // frame/uvtile. - if( !s2.empty() && (image->get_length() == 0) && !image->is_uvtile()) - return get_file_path( s2, mi::neuraylib::IMdl_impexp_api::SEARCH_OPTION_USE_FIRST); + if( !s3.empty() && !image->is_uvtile() && !image->is_animated()) + return s3; + const char* name = trans->tag_to_name( image_tag); + LOG::mod_log->error( M_SCENE, LOG::Mod_log::C_DATABASE, + "Failed to construct MDL file path for image resource \"%s\".", name ? name : ""); return std::string(); } return std::string(); @@ -1321,7 +1328,7 @@ static std::string get_light_profile_resource_name( if( class_id != LIGHTPROFILE::Lightprofile::id) { const char* name = trans->tag_to_name( tag); LOG::mod_log->error( M_SCENE, LOG::Mod_log::C_DATABASE, - "Incorrect type for light profile resource \"%s\".", name?name:""); + "Incorrect type for light profile resource \"%s\".", name ? name : ""); return std::string(); } DB::Access lightprofile( tag, trans); @@ -1329,8 +1336,15 @@ static std::string get_light_profile_resource_name( if( !s1.empty()) return s1; const std::string& s2 = lightprofile->get_filename(); - if( !s2.empty()) - return get_file_path( s2, mi::neuraylib::IMdl_impexp_api::SEARCH_OPTION_USE_FIRST); + if( s2.empty()) + return std::string(); + const std::string& s3 = get_file_path( + s2, mi::neuraylib::IMdl_impexp_api::SEARCH_OPTION_USE_FIRST); + if( !s3.empty()) + return s3; + const char* name = trans->tag_to_name( tag); + LOG::mod_log->error( M_SCENE, LOG::Mod_log::C_DATABASE, + "Failed to construct MDL file path for light profile resource \"%s\".", name ? name : ""); return std::string(); } @@ -1343,7 +1357,7 @@ static std::string get_bsdf_measurement_resource_name( if( class_id != BSDFM::Bsdf_measurement::id) { const char* name = trans->tag_to_name( tag); LOG::mod_log->error( M_SCENE, LOG::Mod_log::C_DATABASE, - "Incorrect type for BSDF measurement resource \"%s\".", name?name:""); + "Incorrect type for BSDF measurement resource \"%s\".", name ? name : ""); return std::string(); } DB::Access bsdf_measurement( tag, trans); @@ -1351,8 +1365,16 @@ static std::string get_bsdf_measurement_resource_name( if( !s1.empty()) return s1; const std::string& s2 = bsdf_measurement->get_filename(); - if( !s2.empty()) - return get_file_path( s2, mi::neuraylib::IMdl_impexp_api::SEARCH_OPTION_USE_FIRST); + if( s2.empty()) + return std::string(); + const std::string& s3 = get_file_path( + s2, mi::neuraylib::IMdl_impexp_api::SEARCH_OPTION_USE_FIRST); + if( !s3.empty()) + return s3; + const char* name = trans->tag_to_name( tag); + LOG::mod_log->error( M_SCENE, LOG::Mod_log::C_DATABASE, + "Failed to construct MDL file path for BSDF measurement resource \"%s\".", + name ? name : ""); return std::string(); } diff --git a/src/io/scene/mdl_elements/mdl_elements_expression.cpp b/src/io/scene/mdl_elements/mdl_elements_expression.cpp index 062ff3f82..bc363c417 100644 --- a/src/io/scene/mdl_elements/mdl_elements_expression.cpp +++ b/src/io/scene/mdl_elements/mdl_elements_expression.cpp @@ -808,11 +808,14 @@ IExpression* Expression_factory::create_cast( ASSERT(M_SCENE, src_expr); ASSERT(M_SCENE, target_type); ASSERT(M_SCENE, errors); - + mi::base::Handle src_type(src_expr->get_type()); + mi::base::Handle stripped_src_type(src_type->skip_all_type_aliases()); + mi::base::Handle stripped_target_type(target_type->skip_all_type_aliases()); + mi::base::Handle tf(m_value_factory->get_type_factory()); - mi::Sint32 r = tf->is_compatible(src_type.get(), target_type); + mi::Sint32 r = tf->is_compatible(stripped_src_type.get(), stripped_target_type.get()); if (r < 0) { *errors = -2; return nullptr; @@ -831,7 +834,9 @@ IExpression* Expression_factory::create_cast( args->add_expression("cast", src_expr); if (direct_call) { - return create_direct_call(target_type, cast_def->get_module(transaction), + return create_direct_call( + stripped_target_type.get(), + cast_def->get_module(transaction), Mdl_tag_ident(cast_def_tag, cast_def->get_ident()), get_cast_operator_db_name(), args.get()); } @@ -846,14 +851,14 @@ IExpression* Expression_factory::create_cast( store_level = transaction->get_tag_storage_level(t); } - mi::base::Handle target_type_value(m_value_factory->create(target_type)); + mi::base::Handle target_type_value(m_value_factory->create(stripped_target_type.get())); mi::base::Handle target_type_expr(create_constant(target_type_value.get())); args->add_expression("cast_return", target_type_expr.get()); std::string call_name; if (cast_db_name) { DB::Tag tag = transaction->name_to_tag(cast_db_name); - if (tag.is_valid()) + if (tag) call_name = DETAIL::generate_unique_db_name(transaction, cast_db_name); else call_name = cast_db_name; @@ -866,7 +871,7 @@ IExpression* Expression_factory::create_cast( cast_call, call_name.c_str(), level, store_level); ASSERT(M_SCENE, call_tag); // should always succeed - return create_call(target_type, call_tag); + return create_call(stripped_target_type.get(), call_tag); } void Expression_factory::serialize( SERIAL::Serializer* serializer, const IExpression* expr) const diff --git a/src/io/scene/mdl_elements/mdl_elements_function_definition.cpp b/src/io/scene/mdl_elements/mdl_elements_function_definition.cpp index bb0814535..a531efd5c 100644 --- a/src/io/scene/mdl_elements/mdl_elements_function_definition.cpp +++ b/src/io/scene/mdl_elements/mdl_elements_function_definition.cpp @@ -132,7 +132,7 @@ Mdl_function_definition::Mdl_function_definition( Code_dag code_dag( mdl_code_dag, m_is_material); - m_simple_name = code_dag.get_simple_name( index); + m_simple_name = encode_name_without_signature( code_dag.get_simple_name( index)); m_mdl_name = MDL::get_mdl_name( mdl_code_dag, is_material, index); m_db_name = get_db_name( m_mdl_name); m_mdl_semantic = code_dag.get_semantics( index); @@ -1656,6 +1656,7 @@ Mdl_function_definition::check_and_prepare_arguments_cast_operator( mi::base::Handle cast_from( arguments->get_expression( index_cast)); mi::base::Handle cast_from_type( cast_from->get_type()); + cast_from_type = cast_from_type->skip_all_type_aliases(); mi::base::Handle cast_to( arguments->get_expression( index_cast_return)); @@ -1726,12 +1727,14 @@ Mdl_function_definition::check_and_prepare_arguments_ternary_operator( mi::base::Handle true_exp( arguments->get_expression( index_true_exp)); mi::base::Handle true_type( true_exp->get_type()); + mi::base::Handle s_true_type( true_type->skip_all_type_aliases()); mi::base::Handle false_exp( arguments->get_expression( index_false_exp)); mi::base::Handle false_type( false_exp->get_type()); + mi::base::Handle s_false_type( false_type->skip_all_type_aliases()); - if( m_tf->compare( true_type.get(), false_type.get()) != 0) { + if( m_tf->compare( s_true_type.get(), s_false_type.get()) != 0) { *errors = -2; return std::make_tuple( nullptr, nullptr, nullptr); } @@ -1743,13 +1746,13 @@ Mdl_function_definition::check_and_prepare_arguments_ternary_operator( // create parameter type list mi::base::Handle parameter_types( m_tf->create_type_list()); parameter_types->add_type( "cond", cond_type.get()); - parameter_types->add_type( "true_exp", true_type.get()); - parameter_types->add_type( "false_exp", false_type.get()); + parameter_types->add_type( "true_exp", s_true_type.get()); + parameter_types->add_type( "false_exp", s_false_type.get()); new_arguments->retain(); parameter_types->retain(); - true_type->retain(); - return std::make_tuple( new_arguments.get(), parameter_types.get(), true_type.get()); + s_true_type->retain(); + return std::make_tuple( new_arguments.get(), parameter_types.get(), s_true_type.get()); } std::tuple diff --git a/src/io/scene/scene/i_scene_attr_resv_id.h b/src/io/scene/scene/i_scene_attr_resv_id.h index 25a294d7f..a5127338f 100644 --- a/src/io/scene/scene/i_scene_attr_resv_id.h +++ b/src/io/scene/scene/i_scene_attr_resv_id.h @@ -248,7 +248,7 @@ enum Attr_resv_id { OPT_CA_IMPORTANCE_MAX, ///< scalar unused OPT_SECTION_PLANES, ///< struct[] section planes OPT_MDL_METERS_PER_SCENE_UNIT, ///< scalar conversion config - OPT_MDL_DISTILLING_TARGET, /// < uint + OPT_MDL_DISTILLING_TARGET, /// < string OPT_FORCE_BUILTIN_BUMP_LINEAR_GAMMA, /// < bool force linear gamma for builtin bumps OPT_IRAY_ALLOW_SURFACE_VOLUME_COEFFICIENTS, /// < bool allow surface-varying volume coeffs in iray OPT_IRAY_SPECTRAL_OBSERVER_CUSTOM_CURVE, /// < Vector3[] photometric spectral color response curve diff --git a/src/mdl/jit/generator_jit/generator_jit_hlsl_writer.cpp b/src/mdl/jit/generator_jit/generator_jit_hlsl_writer.cpp index cd7bd9a56..d5f167451 100644 --- a/src/mdl/jit/generator_jit/generator_jit_hlsl_writer.cpp +++ b/src/mdl/jit/generator_jit/generator_jit_hlsl_writer.cpp @@ -3727,10 +3727,14 @@ hlsl::Type *HLSLWriterPass::convert_struct_type( // Slang does not Symbol *struct_sym; bool is_api_type = false; - if (is_deriv && s_type == m_type_mapper.get_deriv_float2_type()) { + if (is_deriv && s_type == m_type_mapper.get_deriv_float_type()) { + struct_sym = get_sym("Derived_float"), is_api_type = true; + } else if (is_deriv && s_type == m_type_mapper.get_deriv_float2_type()) { struct_sym = get_sym("Derived_float2"), is_api_type = true; } else if (is_deriv && s_type == m_type_mapper.get_deriv_float3_type()) { struct_sym = get_sym("Derived_float3"), is_api_type = true; + } else if (is_deriv && s_type == m_type_mapper.get_deriv_float4_type()) { + struct_sym = get_sym("Derived_float4"), is_api_type = true; } else { struct_sym = get_unique_hlsl_sym( struct_name.c_str(), diff --git a/src/mdl/jit/generator_jit/generator_jit_type_map.cpp b/src/mdl/jit/generator_jit/generator_jit_type_map.cpp index 9175a1a61..9bd9d8c43 100644 --- a/src/mdl/jit/generator_jit/generator_jit_type_map.cpp +++ b/src/mdl/jit/generator_jit/generator_jit_type_map.cpp @@ -118,6 +118,7 @@ Type_mapper::Type_mapper( , m_type_deriv_float(NULL) , m_type_deriv_float2(NULL) , m_type_deriv_float3(NULL) +, m_type_deriv_float4(NULL) , m_type_deriv_arr_float_2(NULL) , m_type_deriv_arr_float_3(NULL) , m_type_deriv_arr_float_4(NULL) @@ -304,6 +305,7 @@ Type_mapper::Type_mapper( m_type_deriv_float3 = lookup_deriv_type(m_type_float3); m_type_deriv_arr_float_4 = lookup_deriv_type(m_type_arr_float_4); + m_type_deriv_float4 = lookup_deriv_type(m_type_float4); } bool vec_in_structs = !target_supports_pointers(); diff --git a/src/mdl/jit/generator_jit/generator_jit_type_map.h b/src/mdl/jit/generator_jit/generator_jit_type_map.h index 67b102f12..3164ac5b7 100644 --- a/src/mdl/jit/generator_jit/generator_jit_type_map.h +++ b/src/mdl/jit/generator_jit/generator_jit_type_map.h @@ -490,6 +490,9 @@ class Type_mapper { /// Get the LLVM derivative type for float[3]. llvm::StructType *get_deriv_arr_float_3_type() const { return m_type_deriv_arr_float_3; } + /// Get the LLVM derivative type for float4. + llvm::StructType *get_deriv_float4_type() const { return m_type_deriv_float4; } + /// Get the LLVM derivative type for float[4]. llvm::StructType *get_deriv_arr_float_4_type() const { return m_type_deriv_arr_float_4; } @@ -719,6 +722,7 @@ class Type_mapper { llvm::StructType *m_type_deriv_float; llvm::StructType *m_type_deriv_float2; llvm::StructType *m_type_deriv_float3; + llvm::StructType *m_type_deriv_float4; llvm::StructType *m_type_deriv_arr_float_2; llvm::StructType *m_type_deriv_arr_float_3; llvm::StructType *m_type_deriv_arr_float_4; diff --git a/src/mdl/jit/libbsdf/libbsdf.cpp b/src/mdl/jit/libbsdf/libbsdf.cpp index 115fb5218..a633efad8 100644 --- a/src/mdl/jit/libbsdf/libbsdf.cpp +++ b/src/mdl/jit/libbsdf/libbsdf.cpp @@ -3263,6 +3263,7 @@ BSDF_API void tint_edf_auxiliary( base.auxiliary(data, state, inherited_normal, factor * inherited_weight); } +//!! TODO: remove thin film, no longer standalone implementation! ///////////////////////////////////////////////////////////////////// // bsdf thin_film( @@ -3370,7 +3371,10 @@ BSDF_API void thin_film_auxiliary( // assuming perfect reflection of k1, so the half-vector equals the normal const float kh = math::abs(math::dot(data->k1, shading_normal)); - const float3 factor = thin_film_factor(ior, thickness, mat_ior, kh); + const float3 base_ior = make(mat_ior.y); + const float3 base_k = make(0.0f); + const float3 incoming_ior = make(mat_ior.x); + const float3 factor = thin_film_factor(thickness, ior, base_ior, base_k, incoming_ior, kh); base.auxiliary(data, state, inherited_normal, factor * inherited_weight); } @@ -3660,8 +3664,8 @@ BSDF_API void fresnel_factor_sample( return; } - const float2 material_ior = process_ior(data, state); - const float inv_eta_i = 1.0f / material_ior.x; + const float3 incoming_ior = process_incoming_ior(data, state); + const float3 inv_eta_i = make(1.0f) / incoming_ior; const float3 eta = ior * inv_eta_i; const float3 eta_k = extinction_coefficient * inv_eta_i; data->bsdf_over_pdf *= complex_ior_fresnel(eta, eta_k, kh); @@ -3688,8 +3692,8 @@ BSDF_INLINE float3 fresnel_factor_get_factor_impl( return make_float3(0.0f, 0.0f, 0.0f); } - const float2 material_ior = process_ior(data, state); - const float inv_eta_i = 1.0f / material_ior.x; + const float3 incoming_ior = process_incoming_ior(data, state); + const float3 inv_eta_i = make(1.0f) / incoming_ior; const float3 eta = ior * inv_eta_i; const float3 eta_k = extinction_coefficient * inv_eta_i; @@ -3758,8 +3762,8 @@ BSDF_API void fresnel_factor_auxiliary( return; } - const float2 material_ior = process_ior(data, state); - const float inv_eta_i = 1.0f / material_ior.x; + const float3 incoming_ior = process_incoming_ior(data, state); + const float3 inv_eta_i = make(1.0f) / incoming_ior; const float3 eta = ior * inv_eta_i; const float3 eta_k = extinction_coefficient * inv_eta_i; @@ -3767,6 +3771,155 @@ BSDF_API void fresnel_factor_auxiliary( base.auxiliary(data, state, inherited_normal, factor * inherited_weight); } +///////////////////////////////////////////////////////////////////// +// bsdf thin_film( +// float coating_thickness, +// color coating_ior, +// bsdf base = fresnel_factor( +// color ior, +// color extinction_coefficent, +// bsdf base = bsdf() +// ) +// ) +///////////////////////////////////////////////////////////////////// + +BSDF_API void thin_film_fresnel_factor_sample( + BSDF_sample_data *data, + State *state, + const float3 &inherited_normal, + const float3 &ior, + const float3 &extinction_coefficient, + const BSDF &base, + const float coating_thickness, + const float3 &coating_ior) +{ + base.sample(data, state, inherited_normal); + if (data->event_type == BSDF_EVENT_ABSORB) + return; + + float3 shading_normal, geometry_normal; + get_oriented_normals( + shading_normal, geometry_normal, inherited_normal, state->geometry_normal(), data->k1); + + const float nk2 = math::abs(math::dot(data->k2, shading_normal)); + const float3 h = compute_half_vector( + data->k1, data->k2, shading_normal, nk2, + (data->event_type & BSDF_EVENT_TRANSMISSION) != 0); + const float kh = math::dot(data->k1, h); + if (kh < 0.0f) { + absorb(data); + return; + } + + const float3 incoming_ior = process_incoming_ior(data, state); + data->bsdf_over_pdf *= thin_film_factor( + coating_thickness, coating_ior, ior, extinction_coefficient, incoming_ior, kh); +} + +// we need an extra function, as clang doesn't allow to inline and export the same function +BSDF_INLINE float3 thin_film_fresnel_factor_get_factor_impl( + BSDF_evaluate_data *data, + State *state, + const float3 &inherited_normal, + const float3 &ior, + const float3 &extinction_coefficient, + const float coating_thickness, + const float3 &coating_ior) +{ + float3 shading_normal, geometry_normal; + get_oriented_normals( + shading_normal, geometry_normal, inherited_normal, state->geometry_normal(), data->k1); + + const float nk2 = math::abs(math::dot(data->k2, shading_normal)); + const float3 h = compute_half_vector( + data->k1, data->k2, shading_normal, nk2, + math::dot(data->k2, geometry_normal) < 0.0f); + const float kh = math::dot(data->k1, h); + if (kh < 0.0f) { + return make_float3(0.0f, 0.0f, 0.0f); + } + + const float3 incoming_ior = process_incoming_ior(data, state); + const float3 factor = thin_film_factor( + coating_thickness, coating_ior, ior, extinction_coefficient, incoming_ior, kh); + return factor; +} + +BSDF_API float3 thin_film_fresnel_factor_get_factor( + BSDF_evaluate_data *data, + State *state, + const float3 &inherited_normal, + const float3 &ior, + const float3 &extinction_coefficient, + const float coating_thickness, + const float3 &coating_ior) +{ + return thin_film_fresnel_factor_get_factor_impl( + data, state, inherited_normal, ior, extinction_coefficient, coating_thickness, coating_ior); +} + +BSDF_API void thin_film_fresnel_factor_evaluate( + BSDF_evaluate_data *data, + State *state, + const float3 &inherited_normal, + const float3 &inherited_weight, + const float3 &ior, + const float3 &extinction_coefficient, + const BSDF &base, + const float coating_thickness, + const float3 &coating_ior) +{ + const float3 factor = thin_film_fresnel_factor_get_factor_impl( + data, state, inherited_normal, ior, extinction_coefficient, coating_thickness, coating_ior); + + if (factor.x == 0.0f && factor.y == 0.0f && factor.z == 0.0f) { + absorb(data); + return; + } + + base.evaluate(data, state, inherited_normal, factor * inherited_weight); +} + +BSDF_API void thin_film_fresnel_factor_pdf( + BSDF_pdf_data *data, + State *state, + const float3 &inherited_normal, + const float3 &ior, + const float3 &extinction_coefficient, + const BSDF &base, + const float coating_thickness, + const float3 &coating_ior) +{ + base.pdf(data, state, inherited_normal); +} + +BSDF_API void thin_film_fresnel_factor_auxiliary( + BSDF_auxiliary_data *data, + State *state, + const float3 &inherited_normal, + const float3 &inherited_weight, + const float3 &ior, + const float3 &extinction_coefficient, + const BSDF &base, + const float coating_thickness, + const float3 &coating_ior) +{ + float3 shading_normal, geometry_normal; + get_oriented_normals( + shading_normal, geometry_normal, inherited_normal, state->geometry_normal(), data->k1); + + const float nk1 = math::dot(data->k1, shading_normal); + if (nk1 < 0.0f) { + absorb(data); + return; + } + + const float3 incoming_ior = process_incoming_ior(data, state); + const float3 factor = thin_film_factor( + coating_thickness, coating_ior, ior, extinction_coefficient, incoming_ior, nk1); + + base.auxiliary(data, state, inherited_normal, factor * inherited_weight); +} ///////////////////////////////////////////////////////////////////// // bsdf measured_curve_factor( @@ -4282,11 +4435,15 @@ BSDF_INLINE void curve_layer_sample( float weight, const BSDF &layer, const BSDF &base, - const float3 &layer_normal, + const float3 &layer_normal_unoriented, const float3 &base_normal) { weight = math::saturate(weight); + float3 layer_normal, geometry_normal; + get_oriented_normals( + layer_normal, geometry_normal, layer_normal_unoriented, state->geometry_normal(), data->k1); + const float nk1 = math::saturate(math::dot(data->k1, layer_normal)); const float estimated_curve_factor = c.estimate(nk1); @@ -4299,7 +4456,7 @@ BSDF_INLINE void curve_layer_sample( else data->xi.z = (1.0f - data->xi.z) / (1.0f - prob_layer); - BSDF::select_sample(sample_layer, data, state, layer, layer_normal, base, base_normal); + BSDF::select_sample(sample_layer, data, state, layer, layer_normal_unoriented, base, base_normal); if (data->event_type == BSDF_EVENT_ABSORB) return; @@ -4326,7 +4483,7 @@ BSDF_INLINE void curve_layer_sample( data->bsdf_over_pdf *= w_base / (1.0f - prob_layer); } - BSDF::select_pdf(sample_layer, &pdf_data, state, base, base_normal, layer, layer_normal); + BSDF::select_pdf(sample_layer, &pdf_data, state, base, base_normal, layer, layer_normal_unoriented); if (sample_layer) data->pdf = pdf_data.pdf * (1.0f - prob_layer) + data->pdf * prob_layer; @@ -4342,13 +4499,16 @@ BSDF_INLINE void curve_layer_evaluate( float weight, const BSDF &layer, const BSDF &base, - const float3 &layer_normal, + const float3 &layer_normal_unoriented, const float3 &base_normal, - const float3 &geometry_normal, const float3 &inherited_weight) { weight = math::saturate(weight); + float3 layer_normal, geometry_normal; + get_oriented_normals( + layer_normal, geometry_normal, layer_normal_unoriented, state->geometry_normal(), data->k1); + const float nk1 = math::saturate(math::dot(data->k1, layer_normal)); const float nk2 = math::abs(math::dot(data->k2, layer_normal)); @@ -4368,7 +4528,7 @@ BSDF_INLINE void curve_layer_evaluate( const float nk2_refl = no_refraction ? nk2 : (2.0f * kh * math::dot(layer_normal, h) - nk1); const float3 cf2 = c.eval(nk2_refl); - layer.evaluate(data, state, layer_normal, weight * curve_factor * inherited_weight); + layer.evaluate(data, state, layer_normal_unoriented, weight * curve_factor * inherited_weight); if (base.is_black()) return; @@ -4388,18 +4548,21 @@ BSDF_INLINE void curve_layer_auxiliary( float weight, const BSDF &layer, const BSDF &base, - const float3 &layer_normal, + const float3 &layer_normal_unoriented, const float3 &base_normal, - const float3 &geometry_normal, const float3 &inherited_weight) { weight = math::saturate(weight); + float3 layer_normal, geometry_normal; + get_oriented_normals( + layer_normal, geometry_normal, layer_normal_unoriented, state->geometry_normal(), data->k1); + // assuming perfect reflection const float nk1 = math::saturate(math::dot(data->k1, layer_normal)); const float3 curve_factor = weight * c.eval(nk1); - layer.auxiliary(data, state, layer_normal, curve_factor * inherited_weight); + layer.auxiliary(data, state, layer_normal_unoriented, curve_factor * inherited_weight); if (base.is_black()) return; @@ -4414,13 +4577,16 @@ BSDF_INLINE void curve_layer_pdf( float weight, const BSDF &layer, const BSDF &base, - const float3 &layer_normal, - const float3 &base_normal, - const float3 &geometry_normal) + const float3 &layer_normal_unoriented, + const float3 &base_normal) { weight = math::saturate(weight); - layer.pdf(data, state, layer_normal); + float3 layer_normal, geometry_normal; + get_oriented_normals( + layer_normal, geometry_normal, layer_normal_unoriented, state->geometry_normal(), data->k1); + + layer.pdf(data, state, layer_normal_unoriented); if (base.is_black()) return; @@ -4432,7 +4598,6 @@ BSDF_INLINE void curve_layer_pdf( data->pdf = (1.0f - prob_layer) * data->pdf + pdf_layer; } - ///////////////////////////////////////////////////////////////////// // bsdf fresnel_layer( // float ior, @@ -4478,14 +4643,10 @@ BSDF_API void fresnel_layer_sample( { const float3 adapted_normal = state->adapt_normal(normal); - float3 shading_normal, geometry_normal; - get_oriented_normals( - shading_normal, geometry_normal, adapted_normal, state->geometry_normal(), data->k1); - const float2 mat_ior = process_ior_fresnel_layer(data, state, ior); const Fresnel_curve_eval c(mat_ior); curve_layer_sample( - c, data, state, weight, layer, base, shading_normal, inherited_normal); + c, data, state, weight, layer, base, adapted_normal, inherited_normal); } BSDF_API void fresnel_layer_evaluate( @@ -4501,15 +4662,11 @@ BSDF_API void fresnel_layer_evaluate( { const float3 adapted_normal = state->adapt_normal(normal); - float3 shading_normal, geometry_normal; - get_oriented_normals( - shading_normal, geometry_normal, adapted_normal, state->geometry_normal(), data->k1); - const float2 mat_ior = process_ior_fresnel_layer(data, state, ior); const Fresnel_curve_eval c(mat_ior); curve_layer_evaluate( c, data, state, weight, layer, base, - shading_normal, inherited_normal, geometry_normal, inherited_weight); + adapted_normal, inherited_normal, inherited_weight); } BSDF_API void fresnel_layer_pdf( @@ -4524,14 +4681,10 @@ BSDF_API void fresnel_layer_pdf( { const float3 adapted_normal = state->adapt_normal(normal); - float3 shading_normal, geometry_normal; - get_oriented_normals( - shading_normal, geometry_normal, adapted_normal, state->geometry_normal(), data->k1); - const float2 mat_ior = process_ior_fresnel_layer(data, state, ior); const Fresnel_curve_eval c(mat_ior); curve_layer_pdf( - c, data, state, weight, layer, base, shading_normal, inherited_normal, geometry_normal); + c, data, state, weight, layer, base, adapted_normal, inherited_normal); } BSDF_API void fresnel_layer_auxiliary( @@ -4547,17 +4700,134 @@ BSDF_API void fresnel_layer_auxiliary( { const float3 adapted_normal = state->adapt_normal(normal); - float3 shading_normal, geometry_normal; - get_oriented_normals( - shading_normal, geometry_normal, adapted_normal, state->geometry_normal(), data->k1); - const float2 mat_ior = process_ior_fresnel_layer(data, state, ior); const Fresnel_curve_eval c(mat_ior); curve_layer_auxiliary( c, data, state, weight, layer, base, - shading_normal, inherited_normal, geometry_normal, inherited_weight); + adapted_normal, inherited_normal, inherited_weight); +} + + +///////////////////////////////////////////////////////////////////// +// bsdf thin_film( +// float coating_thickness, +// color coating_ior, +// bsdf base = fresnel_layer( +// float ior, +// float weight = 1.0, +// bsdf layer = bsdf(), +// bsdf base = bsdf(), +// float3 normal = state->normal() +// ) +// ) +///////////////////////////////////////////////////////////////////// + +class Thin_film_fresnel_curve_eval { +public: + Thin_film_fresnel_curve_eval(const float coating_thickness, const float3 coating_ior, const float2 &ior) : + m_coating_thickness(coating_thickness), m_coating_ior(coating_ior), m_ior(ior) { + } + + float estimate(const float cosine) const { + return math::luminance(eval(cosine)); + } + + float3 eval(const float cosine) const { + return thin_film_factor(m_coating_thickness, m_coating_ior, make(m_ior.y), make(0.0f), make(m_ior.x), cosine); + } + + float2 ior() const { + return m_ior; + } +private: + float m_coating_thickness; + float3 m_coating_ior; + float2 m_ior; +}; + +BSDF_API void thin_film_fresnel_layer_sample( + BSDF_sample_data *data, + State *state, + const float3 &inherited_normal, + const float ior, + const float weight, + const BSDF &layer, + const BSDF &base, + const float3 &normal, + const float coating_thickness, + const float3 &coating_ior) +{ + const float3 adapted_normal = state->adapt_normal(normal); + + const float2 mat_ior = process_ior_fresnel_layer(data, state, ior); + const Thin_film_fresnel_curve_eval c(coating_thickness, coating_ior, mat_ior); + curve_layer_sample( + c, data, state, weight, layer, base, adapted_normal, inherited_normal); +} + +BSDF_API void thin_film_fresnel_layer_evaluate( + BSDF_evaluate_data *data, + State *state, + const float3 &inherited_normal, + const float3 &inherited_weight, + const float ior, + const float weight, + const BSDF &layer, + const BSDF &base, + const float3 &normal, + const float coating_thickness, + const float3 &coating_ior) +{ + const float3 adapted_normal = state->adapt_normal(normal); + + const float2 mat_ior = process_ior_fresnel_layer(data, state, ior); + const Thin_film_fresnel_curve_eval c(coating_thickness, coating_ior, mat_ior); + curve_layer_evaluate( + c, data, state, weight, layer, base, + adapted_normal, inherited_normal, inherited_weight); +} + +BSDF_API void thin_film_fresnel_layer_pdf( + BSDF_pdf_data *data, + State *state, + const float3 &inherited_normal, + const float ior, + const float weight, + const BSDF &layer, + const BSDF &base, + const float3 &normal, + const float coating_thickness, + const float3 &coating_ior) +{ + const float3 adapted_normal = state->adapt_normal(normal); + + const float2 mat_ior = process_ior_fresnel_layer(data, state, ior); + const Thin_film_fresnel_curve_eval c(coating_thickness, coating_ior, mat_ior); + curve_layer_pdf( + c, data, state, weight, layer, base, adapted_normal, inherited_normal); } +BSDF_API void thin_film_fresnel_layer_auxiliary( + BSDF_auxiliary_data *data, + State *state, + const float3 &inherited_normal, + const float3 &inherited_weight, + const float ior, + const float weight, + const BSDF &layer, + const BSDF &base, + const float3 &normal, + const float coating_thickness, + const float3 &coating_ior) +{ + const float3 adapted_normal = state->adapt_normal(normal); + + const float2 mat_ior = process_ior_fresnel_layer(data, state, ior); + const Thin_film_fresnel_curve_eval c(coating_thickness, coating_ior, mat_ior); + curve_layer_auxiliary( + c, data, state, weight, layer, base, + adapted_normal, inherited_normal, inherited_weight); +} ///////////////////////////////////////////////////////////////////// // bsdf color_fresnel_layer( @@ -4607,14 +4877,10 @@ BSDF_API void color_fresnel_layer_sample( { const float3 adapted_normal = state->adapt_normal(normal); - float3 shading_normal, geometry_normal; - get_oriented_normals( - shading_normal, geometry_normal, adapted_normal, state->geometry_normal(), data->k1); - const Color_fresnel_ior mat_ior = process_ior_color_fresnel_layer(data, state, ior); const Color_fresnel_curve_eval c(mat_ior.eta, weight, mat_ior.ior); curve_layer_sample( - c, data, state, 1.0f, layer, base, shading_normal, inherited_normal); + c, data, state, 1.0f, layer, base, adapted_normal, inherited_normal); } BSDF_API void color_fresnel_layer_evaluate( @@ -4630,15 +4896,11 @@ BSDF_API void color_fresnel_layer_evaluate( { const float3 adapted_normal = state->adapt_normal(normal); - float3 shading_normal, geometry_normal; - get_oriented_normals( - shading_normal, geometry_normal, adapted_normal, state->geometry_normal(), data->k1); - const Color_fresnel_ior mat_ior = process_ior_color_fresnel_layer(data, state, ior); const Color_fresnel_curve_eval c(mat_ior.eta, weight, mat_ior.ior); curve_layer_evaluate( c, data, state, 1.0f, layer, base, - shading_normal, inherited_normal, geometry_normal, inherited_weight); + adapted_normal, inherited_normal, inherited_weight); } BSDF_API void color_fresnel_layer_pdf( @@ -4653,14 +4915,10 @@ BSDF_API void color_fresnel_layer_pdf( { const float3 adapted_normal = state->adapt_normal(normal); - float3 shading_normal, geometry_normal; - get_oriented_normals( - shading_normal, geometry_normal, adapted_normal, state->geometry_normal(), data->k1); - const Color_fresnel_ior mat_ior = process_ior_color_fresnel_layer(data, state, ior); const Color_fresnel_curve_eval c(mat_ior.eta, weight, mat_ior.ior); curve_layer_pdf( - c, data, state, 1.0f, layer, base, shading_normal, inherited_normal, geometry_normal); + c, data, state, 1.0f, layer, base, adapted_normal, inherited_normal); } BSDF_API void color_fresnel_layer_auxiliary( @@ -4676,17 +4934,143 @@ BSDF_API void color_fresnel_layer_auxiliary( { const float3 adapted_normal = state->adapt_normal(normal); - float3 shading_normal, geometry_normal; - get_oriented_normals( - shading_normal, geometry_normal, adapted_normal, state->geometry_normal(), data->k1); - const Color_fresnel_ior mat_ior = process_ior_color_fresnel_layer(data, state, ior); const Color_fresnel_curve_eval c(mat_ior.eta, weight, mat_ior.ior); curve_layer_auxiliary( c, data, state, 1.0f, layer, base, - shading_normal, inherited_normal, geometry_normal, inherited_weight); + adapted_normal, inherited_normal, inherited_weight); } +///////////////////////////////////////////////////////////////////// +// bsdf thin_film( +// float coating_thickness, +// color coating_ior, +// base = color_fresnel_layer( +// color ior, +// color weight = 1.0, +// bsdf layer = bsdf(), +// bsdf base = bsdf(), +// float3 normal = state->normal() +// ) +// ) +///////////////////////////////////////////////////////////////////// + +class Thin_film_color_fresnel_curve_eval { +public: + Thin_film_color_fresnel_curve_eval( + const float3 &weight, + const float coating_thickness, + const float3 &coating_ior, + const float3 &ior1, + const float3 &ior2, + const float2 &ior) : + m_weight(math::saturate(weight)), m_coating_thickness(coating_thickness), m_coating_ior(coating_ior), + m_base_ior(ior2), m_incoming_ior(ior1), m_ior(ior) { + } + + float estimate(const float cosine) const { + return math::luminance(eval(cosine)); + } + + float3 eval(const float cosine) const { + return m_weight * thin_film_factor(m_coating_thickness, m_coating_ior, m_base_ior, make(0.0f), m_incoming_ior, cosine); + } + float2 ior() const { + return m_ior; + } + +private: + float m_coating_thickness; + float3 m_coating_ior; + float3 m_base_ior; + float3 m_incoming_ior; + float3 m_weight; + float2 m_ior; +}; + +BSDF_API void thin_film_color_fresnel_layer_sample( + BSDF_sample_data *data, + State *state, + const float3 &inherited_normal, + const float3 &ior, + const float3 &weight, + const BSDF &layer, + const BSDF &base, + const float3 &normal, + const float coating_thickness, + const float3 &coating_ior) +{ + const float3 adapted_normal = state->adapt_normal(normal); + + const Thin_film_color_fresnel_ior mat_ior = process_ior_thin_film_color_fresnel_layer(data, state, ior); + const Thin_film_color_fresnel_curve_eval c(weight, coating_thickness, coating_ior, mat_ior.ior1, mat_ior.ior2, mat_ior.ior); + curve_layer_sample( + c, data, state, 1.0f, layer, base, adapted_normal, inherited_normal); +} + +BSDF_API void thin_film_color_fresnel_layer_evaluate( + BSDF_evaluate_data *data, + State *state, + const float3 &inherited_normal, + const float3 &inherited_weight, + const float3 &ior, + const float3 &weight, + const BSDF &layer, + const BSDF &base, + const float3 &normal, + const float coating_thickness, + const float3 &coating_ior) +{ + const float3 adapted_normal = state->adapt_normal(normal); + + const Thin_film_color_fresnel_ior mat_ior = process_ior_thin_film_color_fresnel_layer(data, state, ior); + const Thin_film_color_fresnel_curve_eval c(weight, coating_thickness, coating_ior, mat_ior.ior1, mat_ior.ior2, mat_ior.ior); + curve_layer_evaluate( + c, data, state, 1.0f, layer, base, + adapted_normal, inherited_normal, inherited_weight); +} + +BSDF_API void thin_film_color_fresnel_layer_pdf( + BSDF_pdf_data *data, + State *state, + const float3 &inherited_normal, + const float3 &ior, + const float3 &weight, + const BSDF &layer, + const BSDF &base, + const float3 &normal, + const float coating_thickness, + const float3 &coating_ior) +{ + const float3 adapted_normal = state->adapt_normal(normal); + + const Thin_film_color_fresnel_ior mat_ior = process_ior_thin_film_color_fresnel_layer(data, state, ior); + const Thin_film_color_fresnel_curve_eval c(weight, coating_thickness, coating_ior, mat_ior.ior1, mat_ior.ior2, mat_ior.ior); + curve_layer_pdf( + c, data, state, 1.0f, layer, base, adapted_normal, inherited_normal); +} + +BSDF_API void thin_film_color_fresnel_layer_auxiliary( + BSDF_auxiliary_data *data, + State *state, + const float3 &inherited_normal, + const float3 &inherited_weight, + const float3 &ior, + const float3 &weight, + const BSDF &layer, + const BSDF &base, + const float3 &normal, + const float coating_thickness, + const float3 &coating_ior) +{ + const float3 adapted_normal = state->adapt_normal(normal); + + const Thin_film_color_fresnel_ior mat_ior = process_ior_thin_film_color_fresnel_layer(data, state, ior); + const Thin_film_color_fresnel_curve_eval c(weight, coating_thickness, coating_ior, mat_ior.ior1, mat_ior.ior2, mat_ior.ior); + curve_layer_auxiliary( + c, data, state, 1.0f, layer, base, + adapted_normal, inherited_normal, inherited_weight); +} ///////////////////////////////////////////////////////////////////// // bsdf custom_curve_layer( @@ -4738,12 +5122,8 @@ BSDF_API void custom_curve_layer_sample( { const float3 adapted_normal = state->adapt_normal(normal); - float3 shading_normal, geometry_normal; - get_oriented_normals( - shading_normal, geometry_normal, adapted_normal, state->geometry_normal(), data->k1); - const Custom_curve_eval c(normal_reflectivity, grazing_reflectivity, exponent); - curve_layer_sample(c, data, state, weight, layer, base, shading_normal, inherited_normal); + curve_layer_sample(c, data, state, weight, layer, base, adapted_normal, inherited_normal); } BSDF_API void custom_curve_layer_evaluate( @@ -4761,14 +5141,10 @@ BSDF_API void custom_curve_layer_evaluate( { const float3 adapted_normal = state->adapt_normal(normal); - float3 shading_normal, geometry_normal; - get_oriented_normals( - shading_normal, geometry_normal, adapted_normal, state->geometry_normal(), data->k1); - const Custom_curve_eval c(normal_reflectivity, grazing_reflectivity, exponent); curve_layer_evaluate( c, data, state, weight, layer, base, - shading_normal, inherited_normal, geometry_normal, inherited_weight); + adapted_normal, inherited_normal, inherited_weight); } BSDF_API void custom_curve_layer_pdf( @@ -4785,13 +5161,9 @@ BSDF_API void custom_curve_layer_pdf( { const float3 adapted_normal = state->adapt_normal(normal); - float3 shading_normal, geometry_normal; - get_oriented_normals( - shading_normal, geometry_normal, adapted_normal, state->geometry_normal(), data->k1); - const Custom_curve_eval c(normal_reflectivity, grazing_reflectivity, exponent); curve_layer_pdf( - c, data, state, weight, layer, base, shading_normal, inherited_normal, geometry_normal); + c, data, state, weight, layer, base, adapted_normal, inherited_normal); } @@ -4810,14 +5182,10 @@ BSDF_API void custom_curve_layer_auxiliary( { const float3 adapted_normal = state->adapt_normal(normal); - float3 shading_normal, geometry_normal; - get_oriented_normals( - shading_normal, geometry_normal, adapted_normal, state->geometry_normal(), data->k1); - const Custom_curve_eval c(normal_reflectivity, grazing_reflectivity, exponent); curve_layer_auxiliary( c, data, state, weight, layer, base, - shading_normal, inherited_normal, geometry_normal, inherited_weight); + adapted_normal, inherited_normal, inherited_weight); } @@ -4873,12 +5241,8 @@ BSDF_API void color_custom_curve_layer_sample( { const float3 adapted_normal = state->adapt_normal(normal); - float3 shading_normal, geometry_normal; - get_oriented_normals( - shading_normal, geometry_normal, adapted_normal, state->geometry_normal(), data->k1); - const Color_custom_curve_eval c(normal_reflectivity, grazing_reflectivity, weight, exponent); - curve_layer_sample(c, data, state, 1.0f, layer, base, shading_normal, inherited_normal); + curve_layer_sample(c, data, state, 1.0f, layer, base, adapted_normal, inherited_normal); } BSDF_API void color_custom_curve_layer_evaluate( @@ -4896,14 +5260,10 @@ BSDF_API void color_custom_curve_layer_evaluate( { const float3 adapted_normal = state->adapt_normal(normal); - float3 shading_normal, geometry_normal; - get_oriented_normals( - shading_normal, geometry_normal, adapted_normal, state->geometry_normal(), data->k1); - const Color_custom_curve_eval c(normal_reflectivity, grazing_reflectivity, weight, exponent); curve_layer_evaluate( c, data, state, 1.0f, layer, base, - shading_normal, inherited_normal, geometry_normal, inherited_weight); + adapted_normal, inherited_normal, inherited_weight); } BSDF_API void color_custom_curve_layer_pdf( @@ -4920,13 +5280,9 @@ BSDF_API void color_custom_curve_layer_pdf( { const float3 adapted_normal = state->adapt_normal(normal); - float3 shading_normal, geometry_normal; - get_oriented_normals( - shading_normal, geometry_normal, adapted_normal, state->geometry_normal(), data->k1); - const Color_custom_curve_eval c(normal_reflectivity, grazing_reflectivity, weight, exponent); curve_layer_pdf( - c, data, state, 1.0f, layer, base, shading_normal, inherited_normal, geometry_normal); + c, data, state, 1.0f, layer, base, adapted_normal, inherited_normal); } BSDF_API void color_custom_curve_layer_auxiliary( @@ -4944,14 +5300,10 @@ BSDF_API void color_custom_curve_layer_auxiliary( { const float3 adapted_normal = state->adapt_normal(normal); - float3 shading_normal, geometry_normal; - get_oriented_normals( - shading_normal, geometry_normal, adapted_normal, state->geometry_normal(), data->k1); - const Color_custom_curve_eval c(normal_reflectivity, grazing_reflectivity, weight, exponent); curve_layer_auxiliary( c, data, state, 1.0f, layer, base, - shading_normal, inherited_normal, geometry_normal, inherited_weight); + adapted_normal, inherited_normal, inherited_weight); } @@ -5006,12 +5358,10 @@ BSDF_API void measured_curve_layer_sample( const BSDF &base, const float3 &normal) { - float3 shading_normal, geometry_normal; - get_oriented_normals( - shading_normal, geometry_normal, normal, state->geometry_normal(), data->k1); + const float3 adapted_normal = state->adapt_normal(normal); const Measured_curve_eval c(curve_values, num_curve_values); - curve_layer_sample(c, data, state, weight, layer, base, shading_normal, inherited_normal); + curve_layer_sample(c, data, state, weight, layer, base, adapted_normal, inherited_normal); } BSDF_API void measured_curve_layer_evaluate( @@ -5026,14 +5376,12 @@ BSDF_API void measured_curve_layer_evaluate( const BSDF &base, const float3 &normal) { - float3 shading_normal, geometry_normal; - get_oriented_normals( - shading_normal, geometry_normal, normal, state->geometry_normal(), data->k1); + const float3 adapted_normal = state->adapt_normal(normal); const Measured_curve_eval c(curve_values, num_curve_values); curve_layer_evaluate( c, data, state, weight, layer, base, - shading_normal, inherited_normal, geometry_normal, inherited_weight); + adapted_normal, inherited_normal, inherited_weight); } BSDF_API void measured_curve_layer_pdf( @@ -5047,13 +5395,11 @@ BSDF_API void measured_curve_layer_pdf( const BSDF &base, const float3 &normal) { - float3 shading_normal, geometry_normal; - get_oriented_normals( - shading_normal, geometry_normal, normal, state->geometry_normal(), data->k1); + const float3 adapted_normal = state->adapt_normal(normal); const Measured_curve_eval c(curve_values, num_curve_values); curve_layer_pdf( - c, data, state, weight, layer, base, shading_normal, inherited_normal, geometry_normal); + c, data, state, weight, layer, base, adapted_normal, inherited_normal); } BSDF_API void measured_curve_layer_auxiliary( @@ -5068,14 +5414,12 @@ BSDF_API void measured_curve_layer_auxiliary( const BSDF &base, const float3 &normal) { - float3 shading_normal, geometry_normal; - get_oriented_normals( - shading_normal, geometry_normal, normal, state->geometry_normal(), data->k1); + const float3 adapted_normal = state->adapt_normal(normal); const Measured_curve_eval c(curve_values, num_curve_values); curve_layer_auxiliary( c, data, state, weight, layer, base, - shading_normal, inherited_normal, geometry_normal, inherited_weight); + shading_normal, adapted_normal, geometry_normal, inherited_weight); } #else @@ -5111,7 +5455,7 @@ BSDF_API void measured_curve_layer_sample( else data->xi.z = (1.0f - data->xi.z) / (1.0f - prob_layer); - BSDF::select_sample(sample_layer, data, state, layer, layer_normal, base, base_normal); + BSDF::select_sample(sample_layer, data, state, layer, adapted_normal, base, base_normal); if (data->event_type == BSDF_EVENT_ABSORB) return; @@ -5134,7 +5478,7 @@ BSDF_API void measured_curve_layer_sample( data->bsdf_over_pdf *= w_base / (1.0f - prob_layer); } - BSDF::select_pdf(sample_layer, &pdf_data, state, base, base_normal, layer, layer_normal); + BSDF::select_pdf(sample_layer, &pdf_data, state, base, base_normal, layer, adapted_normal); if (sample_layer) data->pdf = pdf_data.pdf * (1.0f - prob_layer) + data->pdf * prob_layer; @@ -5174,7 +5518,7 @@ BSDF_API void measured_curve_layer_evaluate( const float3 cf1 = measured_curve_factor_eval(nk1, curve_values, num_curve_values); const float3 cf2 = measured_curve_factor_eval(nk2, curve_values, num_curve_values); - layer.evaluate(data, state, layer_normal, (weight * curve_factor) * inherited_weight); + layer.evaluate(data, state, adapted_normal, (weight * curve_factor) * inherited_weight); if (base.is_black()) return; @@ -5206,7 +5550,7 @@ BSDF_API void measured_curve_layer_pdf( weight = math::saturate(weight); - layer.pdf(data, state, layer_normal); + layer.pdf(data, state, adapted_normal); if (base.is_black()) return; @@ -5242,7 +5586,7 @@ BSDF_API void measured_curve_layer_auxiliary( const float nk1 = math::saturate(math::dot(data->k1, layer_normal)); const float3 curve_factor = weight * measured_curve_factor_eval(nk1, curve_values, num_curve_values); - layer.auxiliary(data, state, layer_normal, curve_factor * inherited_weight); + layer.auxiliary(data, state, adapted_normal, curve_factor * inherited_weight); if (base.is_black()) return; @@ -5305,12 +5649,10 @@ BSDF_API void color_measured_curve_layer_sample( const BSDF &base, const float3 &normal) { - float3 shading_normal, geometry_normal; - get_oriented_normals( - shading_normal, geometry_normal, normal, state->geometry_normal(), data->k1); + const float3 adapted_normal = state->adapt_normal(normal); const Color_measured_curve_eval c(curve_values, num_curve_values, weight); - curve_layer_sample(c, data, state, 1.0f, layer, base, shading_normal, inherited_normal); + curve_layer_sample(c, data, state, 1.0f, layer, base, adapted_normal, inherited_normal); } BSDF_API void color_measured_curve_layer_evaluate( @@ -5325,14 +5667,12 @@ BSDF_API void color_measured_curve_layer_evaluate( const BSDF &base, const float3 &normal) { - float3 shading_normal, geometry_normal; - get_oriented_normals( - shading_normal, geometry_normal, normal, state->geometry_normal(), data->k1); + const float3 adapted_normal = state->adapt_normal(normal); const Color_measured_curve_eval c(curve_values, num_curve_values, weight); curve_layer_evaluate( c, data, state, 1.0f, layer, base, - shading_normal, inherited_normal, geometry_normal, inherited_weight); + adapted_normal, inherited_normal, inherited_weight); } BSDF_API void color_measured_curve_layer_pdf( @@ -5346,13 +5686,11 @@ BSDF_API void color_measured_curve_layer_pdf( const BSDF &base, const float3 &normal) { - float3 shading_normal, geometry_normal; - get_oriented_normals( - shading_normal, geometry_normal, normal, state->geometry_normal(), data->k1); + const float3 adapted_normal = state->adapt_normal(normal); const Color_measured_curve_eval c(curve_values, num_curve_values, weight); curve_layer_pdf( - c, data, state, 1.0f, layer, base, shading_normal, inherited_normal, geometry_normal); + c, data, state, 1.0f, layer, base, adapted_normal, inherited_normal); } BSDF_API void color_measured_curve_layer_auxiliary( @@ -5367,14 +5705,12 @@ BSDF_API void color_measured_curve_layer_auxiliary( const BSDF &base, const float3 &normal) { - float3 shading_normal, geometry_normal; - get_oriented_normals( - shading_normal, geometry_normal, normal, state->geometry_normal(), data->k1); + const float3 adapted_normal = state->adapt_normal(normal); const Color_measured_curve_eval c(curve_values, num_curve_values, weight); curve_layer_auxiliary( c, data, state, 1.0f, layer, base, - shading_normal, inherited_normal, geometry_normal, inherited_weight); + adapted_normal, inherited_normal, inherited_weight); } @@ -5412,7 +5748,7 @@ BSDF_API void color_measured_curve_layer_sample( else data->xi.z = (1.0f - data->xi.z) / (1.0f - prob_layer); - BSDF::select_sample(sample_layer, data, state, layer, layer_normal, base, base_normal); + BSDF::select_sample(sample_layer, data, state, layer, adapted_normal, base, base_normal); if (data->event_type == BSDF_EVENT_ABSORB) return; @@ -5438,7 +5774,7 @@ BSDF_API void color_measured_curve_layer_sample( data->bsdf_over_pdf *= w_base / (1.0f - prob_layer); } - BSDF::select_pdf(sample_layer, &pdf_data, state, base, base_normal, layer, layer_normal); + BSDF::select_pdf(sample_layer, &pdf_data, state, base, base_normal, layer, adapted_normal); if (sample_layer) data->pdf = pdf_data.pdf * (1.0f - prob_layer) + data->pdf * prob_layer; @@ -5481,7 +5817,7 @@ BSDF_API void color_measured_curve_layer_evaluate( const float3 cf2 = color_measured_curve_factor_eval( nk2, curve_values, num_curve_values, color_weight); - layer.evaluate(data, state, layer_normal, (weight * curve_factor) * inherited_weight); + layer.evaluate(data, state, adapted_normal, (weight * curve_factor) * inherited_weight); if (base.is_black()) return; @@ -5513,7 +5849,7 @@ BSDF_API void color_measured_curve_layer_pdf( const float weight = 1.0f; // TODO check if that is right - layer.pdf(data, state, layer_normal); + layer.pdf(data, state, adapted_normal); if (base.is_black()) return; @@ -5550,7 +5886,7 @@ BSDF_API void color_measured_curve_layer_auxiliary( const float3 curve_factor = weight * color_measured_curve_factor_eval( nk1, curve_values, num_curve_values, color_weight); - layer.auxiliary(data, state, layer_normal, curve_factor * inherited_weight); + layer.auxiliary(data, state, adapted_normal, curve_factor * inherited_weight); if (base.is_black()) return; diff --git a/src/mdl/jit/libbsdf/libbsdf_utilities.h b/src/mdl/jit/libbsdf/libbsdf_utilities.h index b1ff6fb25..873946a20 100644 --- a/src/mdl/jit/libbsdf/libbsdf_utilities.h +++ b/src/mdl/jit/libbsdf/libbsdf_utilities.h @@ -146,6 +146,14 @@ BSDF_INLINE float2 process_ior(Data *data, State *state) return ior; } +template +BSDF_INLINE float3 process_incoming_ior(Data *data, State *state) +{ + if (data->ior1.x == BSDF_USE_MATERIAL_IOR) + data->ior1 = get_material_ior(state); + return data->ior1; +} + BSDF_INLINE void compute_eta(float &eta, const float3 &ior1, const float3 &ior2) { eta = (ior2.x + ior2.y + ior2.z) / (ior1.x + ior1.y + ior1.z); @@ -228,6 +236,46 @@ BSDF_INLINE Color_fresnel_ior process_ior_color_fresnel_layer(Data *data, State return ret_val; } +// variant of the above for color thin film Fresnel layering, replaces one of the IORs by +// the parameter of the layerer for weight computation +struct Thin_film_color_fresnel_ior { + float3 ior1; + float3 ior2; + float2 ior; +}; +template +BSDF_INLINE Thin_film_color_fresnel_ior process_ior_thin_film_color_fresnel_layer(Data *data, State *state, const float3 &ior_param) +{ + const float3 material_ior = get_material_ior(state); + + if (data->ior1.x == BSDF_USE_MATERIAL_IOR) + data->ior1 = material_ior; + if (data->ior2.x == BSDF_USE_MATERIAL_IOR) + data->ior2 = material_ior; + + //!! this property should be communicated by the renderer + const bool outside = + (material_ior.x == data->ior2.x) && + (material_ior.y == data->ior2.y) && + (material_ior.z == data->ior2.z); + + Thin_film_color_fresnel_ior ret_val; + ret_val.ior1 = outside ? data->ior1 : ior_param; + ret_val.ior2 = outside ? ior_param : data->ior2; + + ret_val.ior = make_float2( + (ret_val.ior1.x + ret_val.ior1.y + ret_val.ior1.z) * (float)(1.0 / 3.0), + (ret_val.ior2.x + ret_val.ior2.y + ret_val.ior2.z) * (float)(1.0 / 3.0)); + + const float IOR_THRESHOLD = 1e-4f; + const float ior_diff = ret_val.ior.y - ret_val.ior.x; + if (math::abs(ior_diff) < IOR_THRESHOLD) { + ret_val.ior.y = ret_val.ior.x + copysignf(IOR_THRESHOLD, ior_diff); + } + + return ret_val; +} + // uniformly sample projected hemisphere BSDF_INLINE float3 cosine_hemisphere_sample( const float2 &v) // uniform numbers in [0, 1] @@ -1078,28 +1126,73 @@ BSDF_INLINE float refraction_cosine( return math::sqrt(1.0f - sintheta2_sqr); } -// Fresnel s/p-polarized reflectance/transmittance factors -BSDF_INLINE float fresnel_rs(const float n1, const float n2, const float cos1, const float cos2) { - return (n1 * cos1 - n2 * cos2) / (n1 * cos1 + n2 * cos2); -} -BSDF_INLINE float fresnel_rp(const float n1, const float n2, const float cos1, const float cos2) { - return (n2 * cos1 - n1 * cos2) / (n1 * cos2 + n2 * cos1); -} -BSDF_INLINE float fresnel_ts(const float n1, const float n2, const float cos1, const float cos2) { - return 2.0f * n1 * cos1 / (n1 * cos1 + n2 * cos2); +template +BSDF_INLINE T sqr(const T t) { + return t * t; } -BSDF_INLINE float fresnel_tp(const float n1, const float n2, const float cos1, const float cos2) { - return 2.0f * n1 * cos1 / (n1 * cos2 + n2 * cos1); + +// compute squared norm of s/p polarized Fresnel reflection coefficients and phase shifts in complex unit circle +// Born/Wolf - "Principles of Optics", section 13.4 +BSDF_INLINE float2 fresnel_conductor(float2 &phase_shift_sin, float2 &phase_shift_cos, const float n_a, const float n_b, const float k_b, const float cos_a, const float sin_a_sqd) +{ + const float k_b2 = k_b * k_b; + const float n_b2 = n_b * n_b; + const float n_a2 = n_a * n_a; + const float tmp0 = n_b2 - k_b2; + const float half_U = 0.5f * (tmp0 - n_a2 * sin_a_sqd); + const float half_V = math::sqrt(math::max(half_U * half_U + k_b2 * n_b2, 0.0f)); + + const float u_b2 = half_U + half_V; + const float v_b2 = half_V - half_U; + const float u_b = math::sqrt(math::max(u_b2, 0.0f)); + const float v_b = math::sqrt(math::max(v_b2, 0.0f)); + + const float tmp1 = tmp0 * cos_a; + const float tmp2 = n_a * u_b; + const float tmp3 = (2.0f * n_b * k_b) * cos_a; + const float tmp4 = n_a * v_b; + const float tmp5 = n_a * cos_a; + + const float tmp6 = (2.0f * tmp5) * v_b; + const float tmp7 = (u_b2 + v_b2) - tmp5 * tmp5; + + const float tmp8 = (2.0f * tmp5) * ((2.0f * n_b * k_b) * u_b - tmp0 * v_b); + const float tmp9 = sqr((n_b2 + k_b2) * cos_a) - n_a2 * (u_b2 + v_b2); + + const float tmp67 = tmp6 * tmp6 + tmp7 * tmp7; + const float inv_sqrt_x = (tmp67 > 0.0f) ? (1.0f / math::sqrt(tmp67)) : 0.0f; + const float tmp89 = tmp8 * tmp8 + tmp9 * tmp9; + const float inv_sqrt_y = (tmp89 > 0.0f) ? (1.0f / math::sqrt(tmp89)) : 0.0f; + phase_shift_cos = make_float2(tmp7 * inv_sqrt_x, tmp9 * inv_sqrt_y); + phase_shift_sin = make_float2(tmp6 * inv_sqrt_x, tmp8 * inv_sqrt_y); + + return make_float2( + (sqr(tmp5 - u_b) + v_b2) / (sqr(tmp5 + u_b) + v_b2), + (sqr(tmp1 - tmp2) + sqr(tmp3 - tmp4)) / (sqr(tmp1 + tmp2) + sqr(tmp3 + tmp4))); } +// simplified for dielectric, no phase shift computation +BSDF_INLINE float2 fresnel_dielectric(const float n_a, const float n_b, const float cos_a, const float cos_b) +{ + const float naca = n_a * cos_a; + const float nbcb = n_b * cos_b; + const float r_s = (naca - nbcb) / (naca + nbcb); + + const float nacb = n_a * cos_b; + const float nbca = n_b * cos_a; + const float r_p = (nbca - nacb) / (nbca + nacb); + + return make_float2(r_s * r_s, r_p * r_p); +} // compute the reflection color tint caused by a thin-film coating -// good reference: -// https://www.gamedev.net/tutorials/_/technical/graphics-programming-and-theory/thin-film-interference-for-computer-graphics-r2962/ +// for reference, see Born/Wolf - "Principles of Optics", section 13.4.2, equation 30 BSDF_INLINE float3 thin_film_factor( - const float3 coating_ior3, const float coating_thickness, - const float2 material_ior, + const float3 &coating_ior3, + const float3 &base_ior3, + const float3 &base_k3, + const float3 &incoming_ior3, const float kh) { if (coating_thickness <= 0.0f) @@ -1120,21 +1213,23 @@ BSDF_INLINE float3 thin_film_factor( {0.38751f, 0.16135f, 0.00000f}, {0.13401f, 0.05298f, 0.00000f}, {0.03531f, 0.01375f, 0.00000f}, {0.00817f, 0.00317f, 0.00000f}}; + const float sin0_sqr = math::max(1.0f - kh * kh, 0.0f); + //!! poor handling of color data here... just using "closest" color component of color IOR float coating_ior = coating_ior3.z; + float base_ior = base_ior3.z; + float base_k = base_k3.z; + float incoming_ior = incoming_ior3.z; float lambda = lambda_min; + unsigned int i = 0; while (i < 16) { - const float eta01 = material_ior.x / coating_ior; - const float eta01_sqr = eta01 * eta01; - const float sin1_sqr = eta01_sqr * (1.0f - kh * kh); + const float eta01 = incoming_ior / coating_ior; - const float eta02 = material_ior.x / material_ior.y; - const float eta02_sqr = eta02 * eta02; - const float sin2_sqr = eta02_sqr * (1.0f - kh * kh); - - if (sin1_sqr > 1.0f || sin2_sqr > 1.0f) { + const float eta01_sqr = eta01 * eta01; + const float sin1_sqr = eta01_sqr * sin0_sqr; + if (sin1_sqr > 1.0f) { while (i < 16) { @@ -1143,50 +1238,105 @@ BSDF_INLINE float3 thin_film_factor( lambda += lambda_step; ++i; + //!! poor handling of color data here... just using "closest" color component of color IOR const float d_x = math::abs(lambda - 700.0f); const float d_y = math::abs(lambda - 546.1f); const float d_z = math::abs(lambda - 435.8f); - const float coating_ior_next = (d_x < d_y && d_x < d_z) ? coating_ior3.x : ((d_y < d_z) ? coating_ior3.y : coating_ior3.z); - - if (coating_ior_next != coating_ior) { + float coating_ior_next; + float base_ior_next; + float base_k_next; + float incoming_ior_next; + if (d_x < d_y && d_x < d_z) { + coating_ior_next = coating_ior3.x; + base_ior_next = base_ior3.x; + base_k_next = base_k3.x; + incoming_ior_next = incoming_ior3.x; + } else if (d_y < d_z) { + coating_ior_next = coating_ior3.y; + base_ior_next = base_ior3.y; + base_k_next = base_k3.y; + incoming_ior_next = incoming_ior3.y; + } else { + coating_ior_next = coating_ior3.z; + base_ior_next = base_ior3.z; + base_k_next = base_k3.z; + incoming_ior_next = incoming_ior3.z; + } + if (coating_ior_next != coating_ior || base_ior_next != base_ior || base_k_next != base_k || incoming_ior_next != incoming_ior) { coating_ior = coating_ior_next; + base_ior = base_ior_next; + base_k = base_k_next; + incoming_ior = incoming_ior_next; break; } } - continue; } - - const float cos1 = math::sqrt(1.0f - sin1_sqr); - const float cos2 = math::sqrt(1.0f - sin2_sqr); + else + { + const float cos1 = math::sqrt(math::max(1.0f - sin1_sqr, 0.0f)); - const float alpha_s = fresnel_rs(coating_ior, material_ior.x, cos1, kh) * fresnel_rs(coating_ior, material_ior.y, cos1, cos2); - const float alpha_p = fresnel_rp(coating_ior, material_ior.x, cos1, kh) * fresnel_rp(coating_ior, material_ior.y, cos1, cos2); - const float beta_s = fresnel_ts(material_ior.x, coating_ior, kh, cos1) * fresnel_ts(coating_ior, material_ior.y, cos1, cos2); - const float beta_p = fresnel_tp(material_ior.x, coating_ior, kh, cos1) * fresnel_tp(coating_ior, material_ior.y, cos1, cos2); + const float2 R01 = fresnel_dielectric(incoming_ior, coating_ior, kh, cos1); + float2 phi12_sin, phi12_cos; + const float2 R12 = fresnel_conductor(phi12_sin, phi12_cos, coating_ior, base_ior, base_k, cos1, sin1_sqr); - while (i < 16) { + const float tmp = (float)(4.0 * M_PI) * coating_ior * coating_thickness * cos1; + + const float R01R12_s = math::max(R01.x * R12.x, 0.0f); + const float r01r12_s = math::sqrt(R01R12_s); + const float R01R12_p = math::max(R01.y * R12.y, 0.0f); + const float r01r12_p = math::sqrt(R01R12_p); - const float phi = (float)(4.0 * M_PI) * coating_ior * coating_thickness * cos1 / lambda; - const float cosphi = math::cos(phi); - - const float ts = beta_s * beta_s / ((alpha_s * alpha_s) - 2.0f * alpha_s * cosphi + 1.0f); - const float tp = beta_p * beta_p / ((alpha_p * alpha_p) - 2.0f * alpha_p * cosphi + 1.0f); - const float val = 1.0f - 0.5f * (ts + tp) * (material_ior.y * cos2) / (material_ior.x * kh); - xyz += cie_xyz[i] * val; + while (i < 16) { - lambda += lambda_step; - ++i; + const float phi = tmp / lambda; - //!! poor handling of color data here... just using "closest" color component of color IOR - const float d_x = math::abs(lambda - 700.0f); - const float d_y = math::abs(lambda - 546.1f); - const float d_z = math::abs(lambda - 435.8f); - const float coating_ior_next = (d_x < d_y && d_x < d_z) ? coating_ior3.x : ((d_y < d_z) ? coating_ior3.y : coating_ior3.z); + float phi_s, phi_c; + math::sincos(phi, &phi_s, &phi_c); + const float cos_phi_s = phi_c * phi12_cos.x - phi_s * phi12_sin.x; // cos(a+b) = cos(a) * cos(b) - sin(a) * sin(b) + const float tmp_s = 2.0f * r01r12_s * cos_phi_s; + const float R_s = (R01.x + R12.x + tmp_s) / (1.0f + R01R12_s + tmp_s); - if (coating_ior_next != coating_ior) { - coating_ior = coating_ior_next; - break; + const float cos_phi_p = phi_c * phi12_cos.y - phi_s * phi12_sin.y; // cos(a+b) = cos(a) * cos(b) - sin(a) * sin(b) + const float tmp_p = 2.0f * r01r12_p * cos_phi_p; + const float R_p = (R01.y + R12.y + tmp_p) / (1.0f + R01R12_p + tmp_p); + + xyz += cie_xyz[i] * (0.5f * (R_s + R_p)); + + lambda += lambda_step; + ++i; + + //!! poor handling of color data here... just using "closest" color component of color IOR + const float d_x = math::abs(lambda - 700.0f); + const float d_y = math::abs(lambda - 546.1f); + const float d_z = math::abs(lambda - 435.8f); + float coating_ior_next; + float base_ior_next; + float base_k_next; + float incoming_ior_next; + if (d_x < d_y && d_x < d_z) { + coating_ior_next = coating_ior3.x; + base_ior_next = base_ior3.x; + base_k_next = base_k3.x; + incoming_ior_next = incoming_ior3.x; + } else if (d_y < d_z) { + coating_ior_next = coating_ior3.y; + base_ior_next = base_ior3.y; + base_k_next = base_k3.y; + incoming_ior_next = incoming_ior3.y; + } else { + coating_ior_next = coating_ior3.z; + base_ior_next = base_ior3.z; + base_k_next = base_k3.z; + incoming_ior_next = incoming_ior3.z; + } + if (coating_ior_next != coating_ior || base_ior_next != base_ior || base_k_next != base_k || incoming_ior_next != incoming_ior) { + coating_ior = coating_ior_next; + base_ior = base_ior_next; + base_k = base_k_next; + incoming_ior = incoming_ior_next; + break; + } } } } @@ -1219,7 +1369,10 @@ BSDF_INLINE float3 thin_film_factor( const float kh = math::abs(math::dot(k1, h)); - return thin_film_factor(coating_ior3, coating_thickness, material_ior, kh); + const float3 base_ior = make(material_ior.y); + const float3 base_k = make(0.0f); + const float3 incoming_ior = make(material_ior.x); + return thin_film_factor(coating_thickness, coating_ior3, base_ior, base_k, incoming_ior, kh); } // evaluate measured color curve diff --git a/src/shaders/plugin/freeimage/freeimage_image_file_reader_impl.cpp b/src/shaders/plugin/freeimage/freeimage_image_file_reader_impl.cpp index 858f52328..a97d00ae3 100644 --- a/src/shaders/plugin/freeimage/freeimage_image_file_reader_impl.cpp +++ b/src/shaders/plugin/freeimage/freeimage_image_file_reader_impl.cpp @@ -153,7 +153,7 @@ bool Image_file_reader_impl::get_is_cubemap() const mi::Float32 Image_file_reader_impl::get_gamma() const { - IMAGE::Pixel_type pixel_type = IMAGE::convert_pixel_type_string_to_enum( m_bitmap_pixel_type); + const IMAGE::Pixel_type pixel_type = IMAGE::convert_pixel_type_string_to_enum( m_bitmap_pixel_type); return IMAGE::get_default_gamma( pixel_type); } diff --git a/src/shaders/plugin/freeimage/freeimage_image_file_writer_impl.cpp b/src/shaders/plugin/freeimage/freeimage_image_file_writer_impl.cpp index 6a7cae330..0e74e61f6 100644 --- a/src/shaders/plugin/freeimage/freeimage_image_file_writer_impl.cpp +++ b/src/shaders/plugin/freeimage/freeimage_image_file_writer_impl.cpp @@ -115,7 +115,7 @@ Image_file_writer_impl::~Image_file_writer_impl() if( !FreeImage_SaveToHandle( m_format, m_bitmap, &io, static_cast( m_writer), flags)) { - std::string message + const std::string message = "The image plugin \"" + m_plugin_name + "\" failed to export an image."; log( mi::base::MESSAGE_SEVERITY_ERROR, message.c_str()); } diff --git a/src/shaders/plugin/freeimage/freeimage_image_plugin_impl.cpp b/src/shaders/plugin/freeimage/freeimage_image_plugin_impl.cpp index 535cf22b2..a5489a7d6 100644 --- a/src/shaders/plugin/freeimage/freeimage_image_plugin_impl.cpp +++ b/src/shaders/plugin/freeimage/freeimage_image_plugin_impl.cpp @@ -155,6 +155,10 @@ const char* Image_plugin_impl::get_file_extension( mi::Uint32 index) const if( index == 1) return "pic"; if( index == 2) return "pict"; return 0; + case FIF_SGI: + if( index == 0) return "rgb"; + if( index == 1) return "sgi"; + return 0; case FIF_TARGA: if( index == 0) return "targa"; if( index == 1) return "tga";