Material Definition Language API nvidia_logo_transpbg.gif Up
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Example for Discovery of MDL modules
[Previous] [Up] [Next]

This example introduces the MDL Discovery Api that helps to overview the MDL includes.

New Topics

Detailed Description

Discovering MDL archives, packages and modules


The mi::neuraylib::IMdl_discovery_api eases the discovery of available MDL modules by providing a graph view on all MDL packages and modules that can be found in the currently installed search paths.

In this example we will show how to use the mi::neuraylib::IMdl_discovery_api and how to traverse the resulting graph structure provided as mi::neuraylib::IMdl_discovery_result. As a first step we register the MDL search paths by calling the function configure(), where all paths given on the command line are added to the MDL compiler by using the method add_module_path(). The next step is to retrieve a pointer to the mi::neuraylib::IMdl_discovery_api interface and call the method discover(). As a result a mi::neuraylib::IMdl_discovery_result will be returned, which contains a pointer to the discovered MDL graph structure. An example how to traverse this MDL graph structure is shown in the function log_api_package(). The given data structure is a simple directed graph consisting of nodes representing MDL packages and modules. Starting from the root node, the recursive function log_api_package() traverses through of the graph and interprets each node, depending of the given mi::neuraylib::IMdl_info::Kind type. If a mi::neuraylib::IMdl_package_info kind is found, that has been declared in multiple search paths, all these paths are listed to the log output. If a mi::neuraylib::IMdl_module_info is found, that shadows modules from other search paths, this is indicated in the log output as well.
This information makes it easier to overview the interaction of modules and packages from various sources no matter if they have been discovered a from file systems or from an archive.

Example Source

Source Code Location: examples/mdl_sdk/example_discovery.cpp

/******************************************************************************
* Copyright 2018 NVIDIA Corporation. All rights reserved.
*****************************************************************************/
// examples/example_discovery.cpp
//
// Discovers MDL files in file system and MDL archives and measures the traversal time
#include <chrono>
#include <ctime>
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <mi/mdl_sdk.h>
#include "example_shared.h"
using namespace mi::neuraylib;
using namespace std;
//-----------------------------------------------------------------------------
// Helper function to add the root paths to the MDL SDK
//
void configure(mi::neuraylib::INeuray* neuray, const vector<string> &roots)
{
// Add mdl search paths
for (size_t p = 0; p < roots.size(); ++p)
{
mi::Sint32 res = mdl_compiler->add_module_path(roots[p].c_str());
if ( res != 0)
std::cerr << "Error: Issue with adding path " << roots[p] << "\n";
}
}
//-----------------------------------------------------------------------------
// Helper function for discovery info kind logging
//
std::string DK_to_string(IMdl_info::Kind kind)
{
switch (kind)
{
case IMdl_info::DK_PACKAGE: return "DK_PACKAGE";
case IMdl_info::DK_MODULE: return "DK_MODULE";
default: return "UNKNOWN";
}
}
//-----------------------------------------------------------------------------
// Helper function for discovery logging
//
void log_api_package(const IMdl_info* info, int level)
{
string shift(" ");
for (int s = 0; s < level; s++)
shift.append(" ");
// Retrieve base properties
cout << "\n" << shift.c_str() << "simple name: " << info->get_simple_name();
cout << "\n" << shift.c_str() << "qualified name: " << info->get_qualified_name();
cout << "\n" << shift.c_str() << "kind: " << DK_to_string(info->get_kind());
// Retrieve module properties
if (info->get_kind() == IMdl_info::DK_MODULE)
{
cout << "\n" << shift.c_str() << "search path index: "
<< module_info->get_search_path_index();
cout << "\n" << shift.c_str() << "search path: "
<< module_info->get_search_path();
mi::base::Handle<const mi::IString> res_path(module_info->get_resolved_path());
cout << "\n" << shift.c_str() << "resolved path: " << res_path->get_c_str();
cout << "\n" << shift.c_str() << "found in archive: "
<< (module_info->in_archive() ? "true" : "false");
cout << "\n" << shift.c_str() << "number of shadows: "
<< module_info->get_shadows_count();
for (mi::Size s = 0; s < module_info->get_shadows_count(); s++)
{
const mi::base::Handle<const IMdl_module_info> sh(module_info->get_shadow(s));
cout << "\n" << shift.c_str() << "* in search path: " << sh->get_search_path();
}
cout << "\n";
return;
}
// Retrieve package properties
if (info->get_kind() == IMdl_info::DK_PACKAGE)
{
const mi::Size spi_count = package_info->get_search_path_index_count();
if (spi_count > 0)
{
cout << "\n" << shift.c_str() << "discovered in " << spi_count << " search paths:";
for (mi::Size i = 0; i < spi_count; ++i)
{
cout << "\n" << shift.c_str() << "* search path index: "
<< package_info->get_search_path_index(i);
cout << "\n" << shift.c_str() << " search path: "
<< package_info->get_search_path(i);
mi::base::Handle<const mi::IString> res_path(package_info->get_resolved_path(i));
cout << "\n" << shift.c_str() << " resolved path: " << res_path->get_c_str();
cout << "\n" << shift.c_str() << " found in archive: "
<< (package_info->in_archive(i) ? "true" : "false");
}
}
// Recursively iterate over all sub-packages and modules
const mi::Size child_count = package_info->get_child_count();
cout << "\n" << shift.c_str() << "number of children: " << child_count;
if (child_count > 0) cout << "\n";
for (mi::Size i = 0; i < child_count; i++)
{
const mi::base::Handle<const IMdl_info> child(package_info->get_child(i));
log_api_package(child.get(), level + 1);
}
if (child_count == 0) cout << "\n";
return;
}
cerr << "\n Unhandled IMdl_info::Kind found!\n";
}
//-----------------------------------------------------------------------------
//
//
int main(int argc, char* argv[])
{
vector<string> search_paths;
if (argc == 1)
search_paths.push_back(get_samples_mdl_root());
else
// Add search paths from command line
for (int index = 1; index < argc; ++index)
search_paths.push_back(argv[index]);
// Access the MDL SDK
mi::base::Handle<mi::neuraylib::INeuray> neuray(load_and_get_ineuray());
check_success(neuray.is_valid_interface());
// Config root paths and logging
configure(neuray.get(), search_paths);
// Start the MDL SDK
mi::Sint32 result = neuray->start();
check_start_success(result);
{
vector<string> mdl_files;
// Load discovery API
// Create root package
start = chrono::system_clock::now();
// Get complete graph
disc_result(discovery_api->discover());
end = chrono::system_clock::now();
chrono::duration<double> elapsed_seconds = end - start;
if (disc_result != nullptr)
{
disc_result->get_graph());
cout << "\nsearch path";
mi::Size num = disc_result->get_search_paths_count();
// Exclude '.'
if (num > 1)
cout << "s: \n";
else
cout << ": \n";
for (mi::Size i = 0; i < num; i++)
cout << disc_result->get_search_path(i) << "\n";
cout << "\n -------------------- MDL graph --------------------\n";
log_api_package(root.get(), 0);
cout << "\n ------------------ \\ MDL graph --------------------\n";
// Print traverse benchmark result
m << "\nTraversed search path(s) ";
for (size_t p = 0; p < search_paths.size(); ++p)
m << search_paths[p] << " ";
m << "in " << elapsed_seconds.count() << " seconds \n\n";
cerr << m.str();
}
else
cerr << "Failed to create collapsing graph out of search path"<<search_paths[0]<<"\n";
discovery_api = 0;
}
// Shut down the MDL SDK
check_success(neuray->shutdown() == 0);
neuray = 0;
// Unload the MDL SDK
check_success(unload());
keep_console_open();
return EXIT_SUCCESS;
}
[Previous] [Up] [Next]