R16 Reflectance channel API-texture access[SOLVED]

On 24/02/2015 at 01:25, xxxxxxxx wrote:

User Information:
Cinema 4D Version:   16 
Platform:   Windows  ;   
Language(s) :     C++  ;

Hello there,

we need to update our Export plugin for Cinema 4D 16. This version
introduced the new Reflectance channel's API. We can get the list of
reflection layers and we can also get the color of a relfection layer, but
we cannot get the texture name of the layer. I am sure its just a small
piece of code, but we just can't get it to work.

Material *mat = ... a valid c4d material pointer   
const int reflection_layer_count = mat->GetReflectionLayerCount();   
for ( int i=0; i < reflection_layer_count; ++i )   
auto *reflection_layer = matt->GetReflectionLayerIndex( i );   
auto reflection_layer_data_id = reflection_layer->GetDataID();   
auto *material_data = mat->GetDataInstance();   
// this works fine and returns us the color of the reflection layer   
auto color = material_data->GetVector( reflection_layer_data_id + REFLECTION_LAYER_COLOR_COLOR );   
// so how do we get the texture name? the following code doesn't work   
auto *base_link = material_data->GetBaseLink( reflection_layer_data_id + REFLECTION_LAYER_COLOR_TEXTURE );   
auto container = base_link->GetLink( base_document )->GetData();   
String fn = container.GetString( BASECHANNEL_TEXTURE, "" );   

Any help would be appreciated.

Note: We do not want to use the old way of getting these properties.

On 24/02/2015 at 11:42, xxxxxxxx wrote:

Hi marken,

I'm curious to know what you mean by "We do not want to use the old way of getting these properties"?

I've found only one way to retrieve the texture name of a material across our exporters and importers, whether for reflectance or the other channels.  Here are the steps:

1. Set a material pointer to the material in question (Material* ).

2. Get the base channel pointer for the reflection channel:
BaseChannel* baseChannel = material->GetChannel(CHANNEL_REFLECTION);

3. Get the base container from the base channel:
BaseContainer baseContainer = baseChannel->GetData();

4. Get the string containing the name of the texture:
String textureName = baseContainer.GetString(BASECHANNEL_TEXTURE);

That should work, and I don't know of any other method.

Joey Gaspe
SDK Support Engineer

On 25/02/2015 at 00:17, xxxxxxxx wrote:

Hi Joey,

the steps you mentioned are what I call the 'old' way. This is what we used to do for previous versions of our Export plugin and it worked just fine.
However with R16 and the introduction of the Reflectance layers, we can use this feature only, if our designers do NOT make modifications to the Reflectance layers. As soon as they play around with some parameters there, the legacy code you mentioned sometimes fails, e.g. we do not get the CHANNEL_REFLECTION or CHANNEL_SPECULAR.
So thats why we intend to rework this part of the code.

I was able to extract the Texture Filename by playing around a little. But I really want to now how to do it correct. For reference, here is the code:

auto *base_link = material_data->GetBaseLink( reflection_layer_data_id + REFLECTION_LAYER_COLOR_TEXTURE );
auto container = base_link->GetLink( base_document )->GetData();
// ID 1000 is just by trial and error
String texture_name = container.GetFilename( 1000 ).GetString();

However the ID 1000 was just a trial and error. I have no idea what IDs are allowed on the container type for the reflection layers.

Any insight would be appreciated.

On 27/02/2015 at 00:25, xxxxxxxx wrote:

I just wanted to ask again if somebody has some insight on how we can properly access the texture data of a reflection layer?

Again the ID of 1000 in my last posting is by trial and error, so its not the way to go.

On 27/02/2015 at 06:03, xxxxxxxx wrote:

Hi marken,
this ID comes from the shader which you get by using GetBaseLink().
In this case it seems that you are using a regular bitmap shader for REFLECTION_LAYER_COLOR_TEXTURE. You can find the corresponding ids in your Cinema 4D installation folder under resource\modules\c4dplugin\description\xbitmap.h.

Btw. don't forget to add a null check before accessing base_link.

On 02/03/2015 at 03:55, xxxxxxxx wrote:

Hi Satara,

thank you very much, that was the missing link for me. I will use the IDs from xbitmap.h then.

On 04/03/2015 at 10:10, xxxxxxxx wrote:

Hi marken,

I'd like to know if Satara's answer solved your issue?


Joey Gaspe
SDK Support Engineer

On 05/03/2015 at 01:45, xxxxxxxx wrote:

Hi Joey,

yes, the answer solved my issue. I was unclear what type of container

material_data->GetBaseLink( reflection_layer_data_id + REFLECTION_LAYER_COLOR_TEXTURE )

returned and Satara said its a shader and IDs can be fetched from xbitmap.h.

On 05/03/2015 at 06:53, xxxxxxxx wrote:

Hi marken,

Thanks for letting me know, I'll close the topic as solved.

Note: I had to truncate the name of the topic to make the solved tag fit.

Joey Gaspe
SDK Support Engineer