ITarget_code::get_texture_owner_module returns empty string with 'resolve_resources' context option


I’m trying to resolve resource paths myself similar to how it’s done in this forum answer:

This means I set the "resolve_resources" execution context option, load a module from an MDL file via IMdl_impexp_api::load_module, create a link unit and generate the target code with the GLSL backend.

However, while targetCode->get_texture_url(i) returns the relative texture path (e.g. /Reel_to_Reel_Metal/Reel_to_Reel_Normal.png), targetCode->get_texture_owner_module(i) always returns the empty string.

I need the owner module to resolve the relative path to an absolute one.

Is this behaviour intended?

Yes. Either the SDK handles the resources, or you. If you set this option, resource handling is completely in your hand. “Resolve” means, “find out its place”. Hence, this is expected behavior. In general, there are not much use cases for this option.

Maybe an additional information to also answer the last part of your question:

In your example the resource name /Reel_to_Reel_Metal/Reel_to_Reel_Normal.png starts with a leading slash. This means the path is absolute, wrt. to an MDL search path root. In that case the importing module is not relevant for the resolution of the image location. If you reference a resource relative to module, e.g., ./some_texture.png, the owning module will not be empty as it is required for the resolution.

If you just want to defer the resource resolution you can also get the built-in entity resolver and resolve the resources manually: IMdl_configuration::get_entity_resolver()

@krohmer thank you for the clarification.

In fact the path in question is defined as a relative one in the MDL file:

normalmap_texture: texture_2d("./Reel_to_Reel_Metal/Reel_to_Reel_Normal.png", ::tex::gamma_linear),

Hence, I expected to get the module path too. And just to clarify: the path returned by get_texture_url does not start with the dot.

You can find the model (and MDL file) I’m using here: 3D Models for NVIDIA Omniverse

Well, seems I need to go a bit deeper even ;)

The material you are looking it has MDL version 1.4. There has been a change with 1.6 concerning weak relative paths:

strict relative means: "./Reel_to_Reel_Metal/Reel_to_Reel_Normal.png" (with leading ./) → resolves relative to the module
absolute means: "/Reel_to_Reel_Metal/Reel_to_Reel_Normal.png" (with leading /) → resolves to a search path root
weak relative means: "Reel_to_Reel_Metal/Reel_to_Reel_Normal.png" (no leading ./) →
before 1.6: it resolved relative to module and if not found we looked in the search path root
starting with 1.6: we consider them as strict relative as well, so we don’t need to search anymore

For your case, with the strict relative name, the compiler already knows where the module has to be located and this is next to the module. Because the compiler knows the absolute path of the module already, it can also tell what the absolute path of the texture is and it will. This is what you are seeing when calling get_texture_url it has no leading . and it has no owner. The difference is this small here because the module is located in a search path root. If it would be in some package lets say foo, the texture url would be "/foo/Reel_to_Reel_Metal/Reel_to_Reel_Normal.png".

When you change the resource path in the MDL to a weak relative path, you would get the owner module because in 1.4, the rules would allow multiple resolved paths and the compiler does not know.

When you then also change the version to 1.6, you will get the same behavior as with the strict relative path.

@krohmer thank you again for this detailed elaboration! And sorry for the late answer.

I’ve decided to switch from a single link unit / shader to a ray tracing pipeline with multiple independent link units / shaders, which eliminates the search path problem for me.

Thanks again!