Hey,
we are just getting started with the mdl sdk and we have some troubles with enums. We’ve created a little repro case that should generate a mdl module that looks somewhat like this:
export enum someEnum
{
case0 = 0,
case1 = 1,
case2 = 2,
case3 = 3,
case4 = 4
};
export someEnum foo(someEnum arg0 = case0)
{
return arg0;
}
However, what we actually get is this:
export enum someEnum [[
]] {
case0 = 0,
case1 = 1,
case2 = 2,
case3 = 3,
case4 = 4
};
export ::test::materials::someEnum [[
]] foo(someEnum arg0 = ::test::materials::case0)
[[
]]
{
return arg0;
}
Note that the return type of the function uses a fully qualified name, as well as the default value for arg0
, while the type of arg0
doesn’t.
We did some debugger hackery to get this dump, by forcing it in MDL-SDK\src\io\scene\mdl_elements\mdl_elements_module_builder.cpp:2215
so this is not a final output.
Unfortunately, we can’t generate the module because the module analysis fails because it can’t find the module ::test::materials
. Here are the error messages:
C108 ‘test::materials’ is not a package or module name
C108 ‘test::materials’ is not a package or module name
Failed to analyze created module “::test::materials”.
What can we do to fix these errors?
We are using VS 17.1 (and 16.11) with C++20 and we built the mdl sdk from current master (commit d6c9a6560265025a30d16fcd9d664f830ab63109).
Here is the full repro code
#include <mi/mdl_sdk.h>
#include <cassert>
#include <iostream>
#include <string>
using namespace mi::neuraylib;
using mi::base::Handle;
void check(bool test, const IMdl_execution_context* context)
{
if (!test)
{
for (mi::Size i = 0; i < context->get_messages_count(); i++)
std::cout << context->get_message(i)->get_string() << "\n";
std::cout.flush();
}
assert(test);
}
int main()
{
// Load the sdk (we use the loader lib that VS generates when building the sdk)
Handle neuray { mi_factory<INeuray>(::mi_factory) };
assert(neuray.is_valid_interface());
Handle mdlConfig { neuray->get_api_component<IMdl_configuration>() };
mdlConfig->add_mdl_system_paths();
mdlConfig->add_mdl_user_paths();
auto err = neuray->start();
assert(err == 0);
Handle factory { neuray->get_api_component<IMdl_factory>() };
Handle context { factory->create_execution_context() };
Handle db { neuray->get_api_component<IDatabase>() };
Handle scope { db->get_global_scope() };
Handle transaction { scope->create_transaction() };
Handle expressionFactory { factory->create_expression_factory(transaction.get()) };
Handle valueFactory { factory->create_value_factory(transaction.get()) };
Handle typeFactory { factory->create_type_factory(transaction.get()) };
Handle impExpApi { neuray->get_api_component<IMdl_impexp_api>() };
err = impExpApi->load_module(transaction.get(), "::df", context.get());
check(err == 0, context.get());
// Create module ::test::materials
Handle moduleBuilder {
factory->create_module_builder(transaction.get(), "mdl::test::materials", MDL_VERSION_1_0, MDL_VERSION_1_4, context.get())
};
// Define enum someEnum
Handle enumCases { expressionFactory->create_expression_list() };
for (int i = 0; i < 5; i++)
{
auto name = "case" + std::to_string(i);
Handle value { valueFactory->create_int(i) };
Handle enumCase { expressionFactory->create_constant(value.get()) };
enumCases->add_expression(name.data(), enumCase.get());
}
err = moduleBuilder->add_enum_type("someEnum", enumCases.get(), nullptr, nullptr, true, context.get());
check(err == 0, context.get());
// Get enum type, we have to use the full qualified name, otherwise the handle will be invalid
Handle enumType { typeFactory->create_enum("::test::materials::someEnum") };
check(enumType, context.get());
// Define foo function
Handle paramTypes { typeFactory->create_type_list() };
paramTypes->add_type("arg0", enumType.get());
Handle paramDefaults { expressionFactory->create_expression_list() };
Handle case0Value { valueFactory->create_enum(enumType.get(), 0) };
Handle enumDefaultValue { expressionFactory->create_constant(case0Value.get()) };
paramDefaults->add_expression("arg0", enumDefaultValue.get());
Handle body { expressionFactory->create_parameter(enumType.get(), 0) };
check(err == 0, context.get());
// Add foo to the module, this step fails with the mentioned errors
err = moduleBuilder->add_function("foo", body.get(), paramTypes.get(), paramDefaults.get(), nullptr, nullptr, nullptr, true,
IType::MK_NONE, context.get());
check(err == 0, context.get());
// Write module to disk
err = impExpApi->export_module(transaction.get(), "mdl::test::materials", "test_material", context.get());
check(err == 0, context.get());
err = transaction->commit();
check(err == 0, context.get());
err = neuray->shutdown();
assert(err == 0);
}
I can also share a complete VS 2022 project with our mdl sdk build if you need it. We didn’t make any changes to the sdk itself tho and the code above is the same.