This example introduces the distillation of mdl materials to a fixed target model and showcases how to bake material sub-expressions to a texture.
#include <cassert>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <map>
#include <fstream>
#include <thread>
#include "example_shared.h"
#include "example_distilling_shared.h"
#include "utils/profiling.h"
using namespace mi::examples::profiling;
struct Material_parameter
{
struct UVTile
{
:min_uv(u, v)
{}
std::pair<mi::Sint32, mi::Sint32> min_uv;
{
return min_uv < o.min_uv;
}
};
std::map<UVTile, mi::base::Handle<mi::neuraylib::ICanvas>> uv_tile_textures;
std::string value_type;
std::string bake_path;
Remap_func* remap_func;
Material_parameter() : remap_func(nullptr)
{
}
Material_parameter(
const std::string& value_type,
Remap_func* func = nullptr)
: value_type(value_type)
, remap_func(func)
{
}
};
typedef std::map<std::string, Material_parameter> Material;
const std::string& module_qualified_name,
const std::string& material_simple_name)
{
mdl_impexp_api->
load_module(transaction, module_qualified_name.c_str(), context);
if (!print_messages(context))
exit_failure("Loading module '%s' failed.", module_qualified_name.c_str());
if (!module)
exit_failure("Failed to access the loaded module.");
std::string material_db_name
= std::string(module_db_name->get_c_str()) + "::" + material_simple_name;
material_db_name = mi::examples::mdl::add_missing_material_signature(
module.get(), material_db_name);
if (material_db_name.empty())
exit_failure("Failed to find the material %s in the module %s.",
material_simple_name.c_str(), module_qualified_name.c_str());
if (!material_definition)
exit_failure("Accessing definition '%s' failed.", material_db_name.c_str());
material_definition->create_function_call(0, &result);
if (result != 0)
exit_failure("Instantiating '%s' failed.", material_db_name.c_str());
return material_instance;
}
bool class_compilation)
{
Timing timing("Compiling");
context->
set_option(
"target_type", standard_material_type.get());
material_instance2->create_compiled_material(flags, context);
check_success(print_messages(context));
return compiled_material;
}
const char* target_model)
{
distiller_api->
distill_material(compiled_material, target_model,
nullptr, &result));
check_success(result == 0);
distilled_material->retain();
return distilled_material.get();
}
{
if(!canvas)
return;
const mi::Uint32 n = canvas->get_resolution_x() * canvas->get_resolution_y() * 3;
{
data[i] = (data[i] + 1.f) * 0.5f;
}
}
{
if(canvas)
{
const mi::Uint32 n = canvas->get_resolution_x() * canvas->get_resolution_y();
{
data[i] = 1.0f - data[i];
}
return;
}
if(value)
{
value->set_value(1.0f - f);
}
}
void setup_target_material(
const std::string& target_model,
Material& out_material)
{
Timing timing("Setup");
lookup_call("surface.scattering", cm));
get_call_semantic(transaction, parent_call.get()));
if(target_model == "diffuse")
{
check_success(semantic ==
out_material["color"] = Material_parameter("Rgb_fp");
out_material["roughness"] = Material_parameter("Float32");
out_material["normal"] = Material_parameter("Float32<3>", remap_normal);
out_material["color"].bake_path = "surface.scattering.tint";
out_material["roughness"].bake_path = "surface.scattering.roughness";
out_material["normal"].bake_path = "geometry.normal";
}
else if (target_model == "ue4" || target_model == "transmissive_pbr")
{
out_material["base_color"] = Material_parameter("Rgb_fp");
out_material["metallic"] = Material_parameter("Float32");
out_material["specular"] = Material_parameter("Float32");
out_material["roughness"] = Material_parameter("Float32");
out_material["normal"] = Material_parameter("Float32<3>", remap_normal);
out_material["clearcoat_weight"] = Material_parameter("Float32");
out_material["clearcoat_roughness"] = Material_parameter("Float32");
out_material["clearcoat_normal"] = Material_parameter("Float32<3>", remap_normal);
out_material["opacity"] = Material_parameter("Float32");
std::string path_prefix = "surface.scattering.";
bool is_transmissive_pbr = false;
if (target_model == "transmissive_pbr")
{
is_transmissive_pbr = true;
out_material["anisotropy"] = Material_parameter("Float32");
out_material["anisotropy_rotation"] = Material_parameter("Float32");
out_material["transparency"] = Material_parameter("Float32");
out_material["transmission_color"] = Material_parameter("Rgb_fp");
out_material["attenuation_color"] = Material_parameter("Rgb_fp");
out_material["attenuation_distance"] = Material_parameter("Float32");
out_material["subsurface_color"] = Material_parameter("Rgb_fp");
out_material["volume_ior"] = Material_parameter("Rgb_fp");
out_material["attenuation_color"].bake_path = "volume.absorption_coefficient.s.v.attenuation";
out_material["subsurface_color"].bake_path = "volume.absorption_coefficient.s.v.subsurface";
out_material["attenuation_distance"].bake_path = "volume.scattering_coefficient.s.v.distance";
out_material["volume_ior"].bake_path = "ior";
}
{
out_material["clearcoat_weight"].bake_path = path_prefix + "weight";
out_material["clearcoat_roughness"].bake_path = path_prefix + "layer.roughness_u";
out_material["clearcoat_normal"].bake_path = path_prefix + "normal";
parent_call = lookup_call("base", cm, parent_call.get());
semantic = get_call_semantic(transaction, parent_call.get());
path_prefix += "base.";
}
{
out_material["normal"].bake_path = path_prefix + "normal";
parent_call = lookup_call("layer", cm, parent_call.get());
semantic = get_call_semantic(transaction, parent_call.get());
path_prefix += "layer.";
}
{
out_material["metallic"].bake_path = path_prefix + "components.value1.weight";
if (is_transmissive_pbr) {
out_material["roughness"].bake_path = path_prefix + "components.value1.component.roughness_u.s.r.roughness";
out_material["anisotropy"].bake_path = path_prefix + "components.value1.component.roughness_u.s.r.anisotropy";
out_material["anisotropy_rotation"].bake_path = path_prefix + "components.value1.component.roughness_u.s.r.rotation";
}
else
out_material["roughness"].bake_path = path_prefix + "components.value1.component.roughness_u";
out_material["base_color"].bake_path = path_prefix + "components.value1.component.tint";
parent_call = lookup_call(
"components.value0.component", cm, parent_call.get());
semantic = get_call_semantic(transaction, parent_call.get());
path_prefix += "components.value0.component.";
}
{
out_material["specular"].bake_path = path_prefix + "weight";
if (is_transmissive_pbr)
{
out_material["roughness"].bake_path = path_prefix + "layer.roughness_u.s.r.roughness";
out_material["anisotropy"].bake_path = path_prefix + "layer.roughness_u.s.r.anisotropy";
out_material["anisotropy_rotation"].bake_path = path_prefix + "layer.roughness_u.s.r.rotation";
}
else
{
out_material["roughness"].bake_path = path_prefix + "layer.roughness_u";
}
parent_call = lookup_call("base", cm, parent_call.get());
semantic = get_call_semantic(transaction, parent_call.get());
path_prefix += "base.";
}
{
check_success(is_transmissive_pbr);
out_material["transparency"].bake_path = path_prefix + "components.value1.weight";
out_material["transmission_color"].bake_path = path_prefix + "components.value1.component.tint";
parent_call = lookup_call("components.value0.component", cm, parent_call.get());
semantic = get_call_semantic(transaction, parent_call.get());
path_prefix += "components.value0.component.";
}
if(semantic ==
{
if(out_material["metallic"].bake_path.empty())
out_material["metallic"].value = create_value(transaction, "Float32", 1.0f);
if(out_material["roughness"].bake_path.empty())
out_material["roughness"].bake_path = path_prefix + "roughness_u";
if(out_material["base_color"].bake_path.empty())
out_material["base_color"].bake_path = path_prefix + "tint";
}
else if(semantic ==
{
if(out_material["base_color"].bake_path.empty())
out_material["base_color"].bake_path = path_prefix + "tint";
}
if(cutout.is_valid_interface())
out_material["opacity"].bake_path = "geometry.cutout_opacity";
}
else if (target_model == "specular_glossy")
{
out_material["base_color"] = Material_parameter("Rgb_fp");
out_material["f0"] = Material_parameter("Rgb_fp");
out_material["f0_color"] = Material_parameter("Rgb_fp");
out_material["f0_refl"] = Material_parameter("Float32");
out_material["f0_weight"] = Material_parameter("Float32");
out_material["glossiness"] = Material_parameter("Float32", rough_to_gloss);
out_material["opacity"] = Material_parameter("Float32");
out_material["normal_map"] = Material_parameter("Float32<3>", remap_normal);
switch(semantic)
{
out_material["base_color"].bake_path = "surface.scattering.tint";
out_material["f0_weight"].value = create_value(transaction, "Float32", 0.0f);
out_material[
"f0_color"].value = create_value(transaction,
"Color",
mi::Color(0.0f));
break;
out_material["f0_color"].bake_path = "surface.scattering.tint";
out_material["f0_refl"].value = create_value(transaction, "Float32", 1.0f);
out_material["f0_weight"].value = create_value(transaction, "Float32", 1.0f);
out_material["glossiness"].bake_path =
"surface.scattering.roughness_u";
break;
out_material["base_color"].bake_path ="surface.scattering.base.tint";
out_material["f0_color"].bake_path = "surface.scattering.layer.tint";
out_material["f0_refl"].bake_path = "surface.scattering.normal_reflectivity";
out_material["f0_weight"].bake_path = "surface.scattering.weight";
out_material["glossiness"].bake_path =
"surface.scattering.layer.roughness_u";
break;
default:
break;
}
out_material["normal_map"].bake_path = "geometry.normal";
out_material["opacity"].bake_path = "geometry.cutout_opacity";
}
}
Material_parameter& param)
{
return 0;
const char* texture_name = value_texture->get_value();
if( !texture_name)
return 0;
if( !texture)
return 0;
const char* image_name = texture->get_image();
if( !image_name)
return 0;
if( !image)
return 0;
mi::Size frame_length = image->get_frame_length( i);
count += frame_length;
for(
mi::Size j = 0; j < frame_length; ++j) {
image->get_uvtile_uv( i, j, u, v);
param.uv_tile_textures[Material_parameter::UVTile(u, v)] = NULL;
}
}
return count;
}
Material_parameter& param)
{
return search_for_uv_textures( transaction, value.get(), param);
}
direct_call->get_arguments());
for(
mi::Size i = 0; i < args->get_size(); ++i) {
count += search_for_uv_textures( transaction, arg.get(), cm, param);
}
return count;
}
mi::Size index = temporary_ref->get_index();
return search_for_uv_textures( transaction, temporary.get(), cm, param);
}
mi::Size index = parameter_ref->get_index();
return search_for_uv_textures( transaction, parameter.get(), param);
}
break;
case mi::neuraylib::IExpression::EK_FORCE_32_BIT:
break;
}
assert( false);
return 0;
}
Material& out_material)
{
for (Material::iterator it = out_material.begin(); it != out_material.end(); ++it)
{
Material_parameter& param = it->second;
if (param.bake_path.empty())
continue;
count += search_for_uv_textures(transaction, expr.get(), cm, param);
}
return count;
}
void bake_target_material_inputs(
Material& out_material)
{
Timing timing("Baking");
for(Material::iterator it = out_material.begin();
it != out_material.end(); ++it)
{
Material_parameter& param = it->second;
if(param.bake_path.empty())
continue;
cm, param.bake_path.c_str(), baker_resource));
check_success(baker.is_valid_interface());
if(baker->is_uniform())
{
if(param.value_type == "Rgb_fp")
{
}
else if(param.value_type == "Float32<3>")
{
}
else if(param.value_type == "Float32")
{
}
else
{
std::cout << "Ignoring unsupported value type '" << param.value_type
<< "'" << std::endl;
continue;
}
check_success(result == 0);
if(param.remap_func)
param.remap_func(value.
get());
param.value = value;
}
else
{
if (!param.uv_tile_textures.empty())
{
std::map<Material_parameter::UVTile, mi::base::Handle<mi::neuraylib::ICanvas>>::iterator it;
for (it = param.uv_tile_textures.begin(); it != param.uv_tile_textures.end(); it++)
{
image_api->
create_canvas(param.value_type.c_str(), baking_resolution, baking_resolution));
mi::Sint32 result = baker->bake_texture(canvas.get(), min_u, max_u, min_v, max_v, baking_samples);
check_success(result == 0);
if (param.remap_func)
param.remap_func(canvas.get());
it->second = canvas;
}
}
else
{
image_api->
create_canvas(param.value_type.c_str(), baking_resolution, baking_resolution));
mi::Sint32 result = baker->bake_texture(canvas.get(), min_u, max_u, min_v, max_v, baking_samples);
check_success(result == 0);
if (param.remap_func)
param.remap_func(canvas.get());
param.texture = canvas;
}
}
}
}
template <typename T, typename U>
{
if(canvas)
{
out_array =static_cast<T*>(tile->get_data());
}
else if(value)
{
}
}
{
if(material["f0_weight"].value)
{
float v;
if(v==0.0f)
{
material[
"f0"].value = create_value(trans,
"Color",
mi::Color(0.0f));
material["f0"].texture = 0;
return;
}
}
mi::Uint32 rx = material[
"f0"].texture->get_resolution_x();
mi::Uint32 ry = material[
"f0"].texture->get_resolution_y();
init_value(material["f0"].texture.get(), nullptr,
f0, f0_color_value);
init_value(material["f0_color"].texture.get(), material["f0_color"].value.get(),
f0_color, f0_color_value);
init_value(material["f0_weight"].texture.get(), material["f0_weight"].value.get(),
f0_weight, f0_weight_value);
init_value(material["f0_refl"].texture.get(), material["f0_refl"].value.get(),
f0_refl, f0_refl_value);
{
const mi::Float32 t = (f0_weight ? f0_weight[i] : f0_weight_value) *
(f0_refl ? f0_refl[i] : f0_refl_value);
f0[i][0] = (f0_color ? f0_color[i][0] : f0_color_value[0]) * t;
f0[i][1] = (f0_color ? f0_color[i][1] : f0_color_value[1]) * t;
f0[i][2] = (f0_color ? f0_color[i][2] : f0_color_value[2]) * t;
}
}
class Canvas_exporter
{
bool m_in_parallel = true;
public:
Canvas_exporter(bool parallel)
: m_in_parallel(parallel)
{
}
{
}
{
{
check_success(mdl_impexp_api->
export_canvas(filename, canvas) == 0);
};
std::vector<std::thread> threads;
for (auto & canvas_file : m_canvases)
{
const char * filename(canvas_file.first.c_str());
if (m_in_parallel)
{
threads.emplace_back(
std::thread(export_canvas, filename, canvas)
);
}
else
{
export_canvas(filename, canvas);
}
}
for (auto & t : threads)
{
t.join();
}
}
};
void process_target_material(
const std::string& target_model,
const std::string& material_name,
const Material& material,
bool save_baked_textures,
bool parallel,
{
Timing timing("Saving");
std::cout << "--------------------------------------------------------------------------------"
<< std::endl;
std::cout << "Material model: " << target_model << std::endl;
std::cout << "--------------------------------------------------------------------------------"
<< std::endl;
Canvas_exporter canvas_exporter(parallel);
for(Material::const_iterator it = material.begin();
it != material.end(); ++it)
{
const std::string& param_name = it->first;
const Material_parameter& param = it->second;
std::cout << "Parameter: '" << param_name << "': ";
if(param.bake_path.empty())
{
std::cout << " no matching bake path found in target material."
<< std::endl;
if(param.value)
std::cout << "--> value set to ";
if(param.texture)
std::cout << "--> calculated ";
}
else
std::cout << "path '"<< param.bake_path << "' baked to ";
if (!param.uv_tile_textures.empty())
{
std::cout << "texture" << (param.uv_tile_textures.size() > 1 ? "s:" : ":") << std::endl << std::endl;
std::map<Material_parameter::UVTile, mi::base::Handle<mi::neuraylib::ICanvas>>::const_iterator it;
for (it = param.uv_tile_textures.begin(); it != param.uv_tile_textures.end(); it++)
{
if (!it->second)
continue;
if (save_baked_textures)
{
std::stringstream file_name;
file_name << material_name << "-" << param_name << "_u" << it->first.min_uv.first << "_v" << it->first.min_uv.second << ".png";
canvas_exporter.add_canvas(file_name.str(), it->second.get());
std::cout << file_name.str() << std::endl;
}
else
{
std::cout << "<Not saved>" << std::endl;
}
}
}
else if (param.texture)
{
std::cout << "texture:" << std::endl << std::endl;
if (save_baked_textures)
{
std::stringstream file_name;
file_name << material_name << "-" << param_name << ".png";
canvas_exporter.add_canvas(file_name.str(), param.texture.get());
std::cout << file_name.str() << std::endl;
}
else
{
std::cout << "<Not saved>" << std::endl;
}
}
else if(param.value)
{
std::cout << "constant ";
if(param.value_type == "Rgb_fp")
{
color->get_value(c);
std::cout << "color ("
<< c.
r <<
", " << c.
g <<
", " << c.
b <<
")."<< std::endl << std::endl;
}
else if(param.value_type == "Float32")
{
value->get_value(v);
std::cout << "float " << v << "." << std::endl;
}
else if(param.value_type == "Float32<3>")
{
value->get_value(v);
std::cout << "vector ("
<< v.x << ", " << v.y << ", " << v.z << ")."<< std::endl << std::endl;
}
}
std::cout
<< "--------------------------------------------------------------------------------"
<< std::endl;
}
canvas_exporter.do_export(mdl_impexp_api);
}
static void usage(const char *name)
{
std::cout
<< "usage: " << name << " [options] [<material_name1> ...]\n"
<< "-h print this text\n"
<< "--target distilling target:diffuse|ue4|transmissive_pbr|\n"
<< " specular_glossy (default: ue4)\n"
<< "--baker_resource baking device: gpu|cpu|gpu_with_cpu_fallback (default: cpu)\n"
<< "--samples baking samples (default: 4)\n"
<< "--resolution baking resolution (default: 1024)\n"
<< "--uv_range baking UV range: min_u max_u min_v max_v (default: 0 1 0 1)\n"
<< "--material_file <file> file containing fully qualified names of materials to distill\n"
<< "--do_not_save_textures if set, avoid saving baked textures to file\n"
<< "--module <module_name> distill all materials from the module, can occur multiple times\n"
<< "--no_parallel do not save texture files in parallel threads\n"
<< "--mdl_path <path> mdl search path, can occur multiple times.\n"
<< "--plugin <filename> add additional distiller plugin, can be used more than once.\n";
exit(EXIT_FAILURE);
}
void load_materials_from_file(const std::string & material_file, std::vector<std::string> & material_names)
{
std::fstream file;
file.open(material_file, std::fstream::in);
if (!file)
{
std::cout << "Invalid file: " + material_file;
return;
}
std::string fn;
while (getline(file, fn))
{
material_names.emplace_back(fn);
}
file.close();
}
void load_materials_from_modules(
, const std::vector<std::string> & module_names
, std::vector<std::string> & material_names)
{
for (auto module_name : module_names)
{
if (module_name.find("::") != 0)
{
module_name = std::string("::") + module_name;
}
check_success(rtn == 0 || rtn == 1);
check_success(module.is_valid_interface());
mi::Size material_count = module->get_material_count();
for (
mi::Size i = 0; i < material_count; i++)
{
std::string mname(module->get_material(i));
material_names.push_back(material->get_mdl_name());
}
}
}
int MAIN_UTF8(int argc, char* argv[])
{
std::string target_model = "ue4";
bool uv_range_set(false);
bool parallel = true;
std::vector<std::string> material_names;
std::vector<std::string> module_names;
std::string material_file;
std::vector<std::string> additional_plugins;
bool save_baked_textures(true);
mi::examples::mdl::Configure_options configure_options;
for (int i = 1; i < argc; ++i) {
const char *opt = argv[i];
if (opt[0] == '-') {
if (strcmp(opt, "--mdl_path") == 0) {
if (i < argc - 1)
configure_options.additional_mdl_paths.push_back(argv[++i]);
else
usage(argv[0]);
}
else if (strcmp(opt, "--plugin") == 0) {
if (i < argc - 1)
additional_plugins.push_back(argv[++i]);
else
usage(argv[0]);
}
else if (strcmp(opt, "--target") == 0) {
if (i < argc - 1)
target_model = argv[++i];
else
usage(argv[0]);
}
else if (strcmp(opt, "--baker_resource") == 0) {
if (i < argc - 1) {
std::string res = argv[++i];
if (res == "gpu")
else if (res == "gpu_with_cpu_fallback")
else if (res != "cpu")
usage(argv[0]);
}
else
usage(argv[0]);
}
else if (strcmp(opt, "--samples") == 0) {
if (i < argc - 1)
{
int val(atoi(argv[++i]));
if (val > 0)
baking_samples = val;
else
std::cout << "Invalid number of samples ignored\n";
}
else
usage(argv[0]);
}
else if (strcmp(opt, "--resolution") == 0) {
if (i < argc - 1)
{
int val(atoi(argv[++i]));
if (val > 0)
baking_resolution = val;
else
std::cout << "Invalid resolution ignored\n";
}
else
usage(argv[0]);
}
else if (strcmp(opt, "--uv_range") == 0)
{
for (int idx = 0; idx < 4; idx++)
{
if (i < argc - 1)
{
int ok = sscanf(argv[++i], "%f", &val);
if (ok != 1)
{
std::cout << "Invalid UV range\n";
usage(argv[0]);
}
uv_range[idx] = val;
}
else
{
std::cout << "Invalid UV range\n";
usage(argv[0]);
}
}
min_u = uv_range[0];
max_u = uv_range[1];
min_v = uv_range[2];
max_v = uv_range[3];
uv_range_set = true;
}
else if (strcmp(opt, "--material_file") == 0) {
if (i < argc - 1)
material_file = argv[++i];
else
usage(argv[0]);
}
else if (strcmp(opt, "--do_not_save_textures") == 0) {
save_baked_textures = false;
}
else if (strcmp(opt, "--no_parallel") == 0) {
parallel = false;
}
else if (strcmp(opt, "--module") == 0) {
if (i < argc - 1)
module_names.emplace_back(argv[++i]);
else
usage(argv[0]);
}
else
usage(argv[0]);
}
else
material_names.push_back(opt);
}
if (!material_file.empty())
load_materials_from_file(material_file, material_names);
if (!neuray.is_valid_interface())
exit_failure("Failed to load the SDK.");
if (!mi::examples::mdl::configure(neuray.get(), configure_options))
exit_failure("Failed to initialize the SDK.");
exit_failure("Failed to load the mdl_distiller plugin.");
for (auto& plugin : additional_plugins) {
std::string plugin_filename(plugin);
if (mi::examples::mdl::load_plugin(neuray.get(), plugin.c_str()) != 0)
exit_failure("Failed to load the %s plugin.", plugin.c_str());
}
if (ret != 0)
exit_failure("Failed to initialize the SDK. Result code: %d", ret);
{
if (!module_names.empty())
{
load_materials_from_modules(mdl_factory.get(), transaction.get(), mdl_impexp_api.get(), module_names, material_names);
}
if (material_names.empty())
{
material_names.push_back(
"::nvidia::sdk_examples::tutorials_distilling::example_distilling1");
}
for (const auto& m : material_names)
{
std::string module_qualified_name, material_simple_name;
if (!mi::examples::mdl::parse_cmd_argument_material_name(
m, module_qualified_name, material_simple_name, true))
exit_failure();
create_material_instance(
mdl_factory.get(),
transaction.get(),
mdl_impexp_api.get(),
context.get(),
module_qualified_name,
material_simple_name));
compile_material_instance(
mdl_factory.get(),
transaction.get(),
instance.get(),
context.get(),
false));
create_distilled_material(
distilling_api.get(),
compiled_material.get(),
target_model.c_str()));
Material out_material;
setup_target_material(
target_model,
transaction.get(),
distilled_material.get(),
out_material);
mi::Size uv_texture_count = search_for_uv_textures(
transaction.get(),
distilled_material.get(),
out_material);
if (uv_texture_count > 0 && uv_range_set)
{
std::cerr << "WARNING: UV range will be ignored for UV tile textured parameters\n";
}
bake_target_material_inputs(
baker_resource,
baking_samples,
baking_resolution,
min_u,
max_u,
min_v,
max_v,
transaction.get(),
distilled_material.get(),
distilling_api.get(),
image_api.get(),
out_material);
if (target_model == "specular_glossy")
{
out_material["f0"].texture =
image_api->
create_canvas(
"Rgb_fp", baking_resolution, baking_resolution);
calculate_f0(transaction.get(), out_material);
}
process_target_material(
target_model,
material_simple_name,
out_material,
save_baked_textures,
parallel,
mdl_impexp_api.get());
}
}
if (neuray->shutdown() != 0)
exit_failure("Failed to shutdown the SDK.");
neuray = nullptr;
if (!mi::examples::mdl::unload())
exit_failure("Failed to unload the SDK.");
exit_success();
}
COMMANDLINE_TO_UTF8
This interface represents RGBA colors.
Definition: icolor.h:28
This interface is the base interface of all types.
Definition: idata.h:297
This interface represents a vector of three Float32.
Definition: ivector.h:249
This interface represents mi::Float32.
Definition: inumber.h:221
Handle class template for interfaces, automatizing the lifetime control via reference counting.
Definition: handle.h:113
The basic extensible interface.
Definition: iinterface.h:103
Standard RGBA color class with floating point elements and operations.
Definition: color.h:81
Fixed-size math vector class template with generic operations.
Definition: vector.h:286
Abstract interface for a canvas represented by a rectangular array of tiles.
Definition: icanvas.h:89
virtual const ITile * get_tile(Uint32 layer=0) const =0
Returns the tile for the given layer.
This interface represents a compiled material.
Definition: icompiled_material.h:97
virtual const IExpression * lookup_sub_expression(const char *path) const =0
Looks up a sub-expression of the compiled material.
virtual const IValue * get_argument(Size index) const =0
Returns the value of an argument.
virtual const IExpression * get_temporary(Size index) const =0
Returns a temporary.
This interface is used to interact with the distributed database.
Definition: idatabase.h:289
A constant expression.
Definition: iexpression.h:96
A direct call expression.
Definition: iexpression.h:241
A parameter reference expression.
Definition: iexpression.h:217
A temporary reference expression.
Definition: iexpression.h:299
The interface to MDL expressions.
Definition: iexpression.h:50
@ EK_CALL
An indirect call expression. See mi::neuraylib::IExpression_call.
Definition: iexpression.h:57
@ EK_DIRECT_CALL
A direct call expression. See mi::neuraylib::IExpression_direct_call.
Definition: iexpression.h:61
@ EK_CONSTANT
A constant expression. See mi::neuraylib::IExpression_constant.
Definition: iexpression.h:55
@ EK_PARAMETER
A parameter reference expression. See mi::neuraylib::IExpression_parameter.
Definition: iexpression.h:59
@ EK_TEMPORARY
A temporary reference expression. See mi::neuraylib::IExpression_temporary.
Definition: iexpression.h:63
virtual Kind get_kind() const =0
Returns the kind of this expression.
This interface represents a function call.
Definition: ifunction_call.h:52
This interface represents a function definition.
Definition: ifunction_definition.h:44
Semantics
All known semantics of functions definitions.
Definition: ifunction_definition.h:54
@ DS_INTRINSIC_DF_MICROFACET_GGX_VCAVITIES_BSDF
The df::microfacet_ggx_vcavities() function.
Definition: ifunction_definition.h:295
@ DS_INTRINSIC_DF_DIFFUSE_REFLECTION_BSDF
The df::diffuse_reflection_bsdf() function.
Definition: ifunction_definition.h:259
@ DS_INTRINSIC_DF_NORMALIZED_MIX
The df::normalized_mix() function.
Definition: ifunction_definition.h:274
@ DS_INTRINSIC_DF_CUSTOM_CURVE_LAYER
The df::custom_curve_layer() function.
Definition: ifunction_definition.h:278
@ DS_INTRINSIC_DF_WEIGHTED_LAYER
The df::weighted_layer() function.
Definition: ifunction_definition.h:276
This interface provides various utilities related to canvases and buffers.
Definition: iimage_api.h:72
virtual ICanvas * create_canvas(const char *pixel_type, Uint32 width, Uint32 height, Uint32 layers=1, bool is_cubemap=false, Float32 gamma=0.0f) const =0
Creates a canvas with given pixel type, resolution, and layers.
This interface represents a pixel image file.
Definition: iimage.h:66
This interface represents a material instance.
Definition: imaterial_instance.h:34
@ CLASS_COMPILATION
Selects class compilation instead of instance compilation.
Definition: imaterial_instance.h:41
@ DEFAULT_OPTIONS
Default compilation options (e.g., instance compilation).
Definition: imaterial_instance.h:40
Provides access to various functionality related to MDL distilling.
Definition: imdl_distiller_api.h:47
virtual ICompiled_material * distill_material(const ICompiled_material *material, const char *target, const IMap *distiller_options=0, Sint32 *errors=0) const =0
Distills a material.
virtual const IBaker * create_baker(const ICompiled_material *material, const char *path, Baker_resource resource=BAKE_ON_CPU, Uint32 gpu_device_id=0) const =0
Creates a baker for texture baking.
The execution context can be used to query status information like error and warning messages concern...
Definition: imdl_execution_context.h:131
virtual Sint32 set_option(const char *name, const char *value)=0
Sets a string option.
Factory for various MDL interfaces and functions.
Definition: imdl_factory.h:53
virtual IMdl_execution_context * create_execution_context()=0
Creates an execution context.
virtual IType_factory * create_type_factory(ITransaction *transaction)=0
Returns an MDL type factory for the given transaction.
virtual const IString * get_db_module_name(const char *mdl_name)=0
Returns the DB name for the MDL name of a module (or file path for MDLE modules).
API component for MDL related import and export operations.
Definition: imdl_impexp_api.h:43
virtual Sint32 export_canvas(const char *filename, const ICanvas *canvas, const IMap *export_options=0) const =0
Exports a canvas to a file on disk.
virtual Sint32 load_module(ITransaction *transaction, const char *argument, IMdl_execution_context *context=0)=0
Loads an MDL module from disk (or a builtin module) into the database.
This interface represents an MDL module.
Definition: imodule.h:634
Textures add image processing options to images.
Definition: itexture.h:68
A transaction provides a consistent view on the database.
Definition: itransaction.h:82
virtual const base::IInterface * access(const char *name)=0
Retrieves an element from the database.
virtual base::IInterface * create(const char *type_name, Uint32 argc=0, const base::IInterface *argv[]=0)=0
Creates an object of the type type_name.
virtual Sint32 commit()=0
Commits the transaction.
@ SID_MATERIAL
The "::material" struct type.
Definition: itype.h:484
A texture value.
Definition: ivalue.h:525
The interface to MDL values.
Definition: ivalue.h:33
virtual Kind get_kind() const =0
Returns the kind of the value.
@ VK_TEXTURE
A texture value. See mi::neuraylib::IValue_texture.
Definition: ivalue.h:62
#define MI_BASE_DLL_FILE_EXT
The operating system specific default filename extension for shared libraries (DLLs)
Definition: config.h:340
virtual const IInterface * get_interface(const Uuid &interface_id) const =0
Acquires a const interface from another.
Handle<Interface> make_handle_dup(Interface *iptr)
Converts passed-in interface pointer to a handle, without taking interface over.
Definition: handle.h:439
Handle<New_interface> get_interface() const
Returns a new handle for a possibly different interface type, similar to a dynamic cast,...
Definition: handle.h:353
Interface * get() const
Access to the interface. Returns 0 for an invalid interface.
Definition: handle.h:294
unsigned int Uint32
32-bit unsigned integer.
Definition: types.h:49
Uint64 Size
Unsigned integral type that is large enough to hold the size of all types.
Definition: types.h:112
float Float32
32-bit float.
Definition: types.h:51
signed int Sint32
32-bit signed integer.
Definition: types.h:46
Float32 length(Float32 a)
Returns the Euclidean norm of the scalar a (its absolute value).
Definition: function.h:1107
bool operator<(const Bbox<T, DIM> &lhs, const Bbox<T, DIM> &rhs)
Returns true if lhs is lexicographically less than rhs.
Definition: bbox.h:607
Float32 g
Green color component.
Definition: vector.h:71
Float32 r
Red color component.
Definition: vector.h:69
Float32 b
Blue color component.
Definition: vector.h:73
Baker_resource
Identifies the resource(s) to be used by a baker.
Definition: imdl_distiller_api.h:30
@ BAKE_ON_CPU
Use only the CPU for texture baking.
Definition: imdl_distiller_api.h:33
@ BAKE_ON_GPU_WITH_CPU_FALLBACK
Prefer using the GPU for texture baking, use the CPU as fallback.
Definition: imdl_distiller_api.h:37
@ BAKE_ON_GPU
Use only the GPU for texture baking.
Definition: imdl_distiller_api.h:35
mi::Sint32 get_value(const mi::IData *data, T &value)
Simplifies reading the value of mi::IData into the corresponding classes from the base and math API.
Definition: set_get.h:341