This example loads an MDL module and inspects it contents.
- Configuration of the MDL API
In order to allow the the MDL API to locate MDL modules and its resources in the file system it is necessary to configure the MDL module search path. This is done by calling mi::neuraylib::IMdl_compiler::add_module_path().
Our example module ::nvidia::sdk_examples::tutorials
makes use of textures. The support for image formats in the the MDL API is provided by image plugins, which have to be loaded explicitly via mi::neuraylib::IMdl_compiler::load_plugin_library().
In this and most other examples the configuration is done within the utility function configure()
. Here, we set the module search path to the MDL directory shipped wit the examples. We also load the FreeImage
plugin which comes with the the MDL API and is capable of handling
.png files.
- Loading of MDL modules
MDL modules are loaded with the method mi::neuraylib::IMdl_compiler::load_module(). Note that this method expects the module name, not the name of the file containing the module. To find the corresponding file it is necessary to configure the module search path as described above.
- Enumerating the contents of MDL modules
The mi::neuraylib::IModule interface offers various methods related to metadata, like the name of the module, or the name of the file it was loaded from. Furthermore, it offers methods to enumerate the material and function definitions contained in the module. It also allows to enumerate all modules that have been (directly) imported by that module. Imported modules will be automatically loaded (if not already loaded before).
- Inspecting the parameters of material and function definitions
MDL materials and functions (as found in a
.mdl file) are represented in the MDL API by the interfaces mi::neuraylib::IMaterial_definition and mi::neuraylib::IFunction_definition. Similar to the module interface these interfaces offer various methods related to metadata, like the name of the definition, or the name of the containing module. Important methods are those that provide details about the parameters, like their names, types, and the values of defaults (if present).
In this example we simply dump the parameter information for the first material and function definition. The textual representation of the default values is generated by the method mi::neuraylib::IExpression_factory::dump().
- Enumerating resources required by a module
The example also demonstrates the iteration of required resources. After reading the number of resources, we can iterate them and get the database name, the mdl file path, and the resource type. Based on the latter, it is possible to fetch the resolved resource path that points to the file on the current system. In case the resource could not be resolved, the database name will be NULL
. However, the mdl file path will still point to the missing resource.
#include <iostream>
#include <string>
#include "example_shared.h"
template <class T>
void dump_definition(
const T* material,
{
mi::Size count = material->get_parameter_count();
for(
mi::Size index = 0; index < count; index++) {
std::string name = material->get_parameter_name( index);
s << " parameter " << type_text->get_c_str() << " " << name;
defaults->get_expression( name.
c_str()));
if( default_.is_valid_interface()) {
expression_factory->
dump( default_.get(), 0, depth+1));
s <<
", default = " << default_text->get_c_str() <<
std::endl;
} else {
}
}
}
{
{
transaction.get(), "::nvidia::sdk_examples::tutorials", context.get()) >= 0);
print_messages( context.get());
check_success( module.is_valid_interface());
mi::Size module_count = module->get_import_count();
for(
mi::Size i = 0; i < module_count; i++)
for(
mi::Size i = 0; i < types->get_size(); ++i) {
}
for(
mi::Size i = 0; i < constants->get_size(); ++i) {
}
mi::Size function_count = module->get_function_count();
for(
mi::Size i = 0; i < function_count; i++)
mi::Size material_count = module->get_material_count();
for(
mi::Size i = 0; i < material_count; i++)
const char* function_definition_name = module->get_function( 0);
std::cout <<
"Dumping function definition \"" << function_definition_name <<
"\":"
dump_definition(
transaction.get(), mdl_factory.get(), function_definition.get(), 1,
std::cout);
const char* material_definition_name = module->get_material( 0);
std::cout <<
"Dumping material definition \"" << material_definition_name <<
"\":"
dump_definition(
transaction.get(), mdl_factory.get(), material_definition.get(), 1,
std::cout);
std::cout <<
"Dumping resources of this module: \n";
for(
mi::Size r = 0, rn = module->get_resources_count(); r < rn; ++r)
{
const char* db_name = module->get_resource_name( r);
const char* mdl_file_path = module->get_resource_mdl_file_path( r);
if( db_name == nullptr)
{
std::cout << " The module contains a resource that could not be resolved:"
std::cout << " mdl_file_path: " << mdl_file_path << std::endl
continue;
}
std::cout <<
" db_name: " << db_name <<
std::endl;
std::cout <<
" mdl_file_path: " << mdl_file_path <<
std::endl;
module->get_resource_type( r));
switch( type->get_kind())
{
{
if( texture)
{
for(
mi::Size t = 0, tn = image->get_uvtile_length(); t < tn; ++t)
{
const char* system_file_path = image->get_filename(
static_cast<mi::Uint32>( t));
std::cout << " resolved_file_path[" << t << "]: "
}
}
break;
}
{
if( light_profile)
{
const char* system_file_path = light_profile->get_filename();
std::cout <<
" resolved_file_path: " << system_file_path <<
std::endl;
}
break;
}
{
if( mbsdf)
{
const char* system_file_path = mbsdf->get_filename();
std::cout <<
" resolved_file_path: " << system_file_path <<
std::endl;
}
break;
}
default:
break;
}
}
}
}
int main( int , char* [])
{
check_success( neuray.is_valid_interface());
configure( neuray.get());
check_start_success( result);
load_module( neuray.get());
check_success( neuray->
shutdown() == 0);
neuray = 0;
check_success( unload());
keep_console_open();
return EXIT_SUCCESS;
}