SOLVED How to add tex to legacy materials specular maps?

Qustion:
Maps for glTF need some specular tex link like maxon gltf documents do,but I can't asign a tex for it.
Some texs log like this ,and some texs didn't bug anything.
Snipaste_2022-07-22_16-58-41.png

Details:
I want to custom a tool to read maps in folder with the same name export form SP like :
Mat Name : Cube, Maps Name:Cube_Base_color
And specular seems change a lot ,How can I do like gltf document requires ?

import c4d

def main() -> None:
    mat = mattag.GetMaterial()
    matname = mat.GetName()
    picformat = "png"
    # color map
    abscolormap = matname + "_Base_color." + picformat
    colormap = os.path.join(mappath,abscolormap)
    # metallic map
    absmetallicmap = matname + "_Metallic." + picformat
    matellicmap = os.path.join(mappath,absmetallicmap)
    #print(abscolormap)
    #print(colormap)

    # ========== Shader ========== #
    # 颜色 color
    shacolor = c4d.BaseList2D(c4d.Xbitmap)
    shacolor[c4d.BITMAPSHADER_FILENAME] = colormap
    mat[c4d.MATERIAL_COLOR_SHADER] = shacolor

    # 反射强度 refl
    shaspec = c4d.BaseList2D(c4d.Xbitmap)
    shaspec[c4d.BITMAPSHADER_FILENAME] = matellicmap
    mat[c4d.REFLECTION_LAYER_MAIN_SHADER_REFLECTIONLINK] = shaspec
    # ========== Insert ========== #
    mat.InsertShader(shacolor)
    # Pushes an update event to Cinema 4D
    c4d.EventAdd()
if __name__ == '__main__':
    main()

Thanks

Hello @dunhou,

Thank you for reaching out to us. The reason why you are getting this error message is that the reflection layer IDs are not predefined IDs, but IDs that are being placed dynamically with a stride. The symbol you used, REFLECTION_LAYER_MAIN_SHADER_REFLECTIONLINK, is therefore not a final value, but only an offset within that stride.

The basic methods for interacting with reflection layers can be found in the c4d.Material documentation. On GitHub we also provide a small example script for dealing with reflection layers.

Cheers,
Ferdinand

@ferdinand Thanks for that
So that is why I cann't get the IDs in console , I never realized C++ docs have some relationship with python docs 😧
Thanks for you explain, Here is a little test works well.

import c4d

def main():
    # Creates a standard C4D Material
    mat = c4d.Material()
    if mat is None:
        raise RuntimeError("Failed to create a new default material.")

    # Removes the default specular layer
    mat.RemoveReflectionLayerIndex(0)

    # Adds a layer
    layer = mat.AddReflectionLayer()
    if layer is None:
        raise RuntimeError("Failed to create a new reflection layer.")

    # Sets the Layer to Blinn mode
    mat[layer.GetDataID() + c4d.REFLECTION_LAYER_MAIN_DISTRIBUTION] = c4d.REFLECTION_DISTRIBUTION_SPECULAR_BLINN
    
    # Sets the shader for width
    colormap = "filename"
    shacolor = c4d.BaseList2D(c4d.Xbitmap)
    shacolor[c4d.BITMAPSHADER_FILENAME] = colormap
    mat.InsertShader(shacolor)    
    
    # Defines the Roughness float value
    mat[layer.GetDataID() + c4d.REFLECTION_LAYER_MAIN_SHADER_ROUGHNESS] = shacolor

    # Inserts a material in the active doc
    doc.InsertMaterial(mat)

    # Pushes an update event to Cinema 4D
    c4d.EventAdd()

if __name__ == '__main__':
    main()

@ferdinand
Another problem,when I insert a 2nd layer in specular,I cann't find how to change layer to add or something like that. thr log display a c4d.REFLECTION_LAYER_DATA which I didn't find a function to do this.
Do I miss something?(Not sure but wished this post should be post in this topic)
Thanks

Hey @dunhou,

This is a perfectly fine follow up question. I am, however, not 100% sure that I understand your question correctly.

The symbol REFLECTION_LAYER_DATA is neither too useful in Python nor C++ because it has an internal purpose and is just a pointer to the reflection layer data bundle. I assume you dragged the Layer Setup text into the console and so came across it.

The public interface for reading and writing reflection layer data (e.g., add a layer or get a layer as you want), is attached to the c4d.Material as pointed out in my last posting. You are already using the method c4d.Material.AddReflectionLayer in your last posting. There also methods to retrieve and remove layers.

Cheers,
Ferdinand

@ferdinand
Sorry for my bad descriptions, What I mean is change a layer to multiply mode or add mode.
I didn't know how to set it. AddReflectionLayer seems like only return a layer.

Hey @dunhou,

I am still a bit confused. From the context I would have assumed that you are talking about the blend mode of the layers, i.e., REFLECTION_LAYER_MAIN_BLEND_MODE. But layers do not have any blend mode Multiply, only Normal and Add. I am in fact not aware of anything that has the option Multiply in a reflection layer. Could you please make a screenshot of what you mean?

Find below a script which shows how you set the blend mode, strength, and name of a layer anyways.

Cheers,
Ferdinand

A result:
6fe7e01c-e78f-4d17-a8e1-8a24d1b38a9d-image.png

The code:

"""Demonstrates how to set the blend mode and strength of reflection layers.
"""

import c4d
import random

def main():

    mat = c4d.Material()
    if mat is None:
        raise RuntimeError("Failed to create a new default material.")
    mat.RemoveReflectionLayerIndex(0)

    # There are no smybols for the blend modes, 0 is "Normal", 1 is "Add"
    for blendMode in [0, 1]:
        layer = mat.AddReflectionLayer()
        if layer is None:
            raise RuntimeError("Failed to create a new reflection layer.")
        
        lid: int = layer.GetDataID()

        # Set the name of layer.
        layer.SetName("Normal-Layer" if blendMode == 0 else "Add-Layer")
        
        # Set the mode and a random layer strength.
        mat[lid + c4d.REFLECTION_LAYER_MAIN_BLEND_MODE] = blendMode
        mat[lid + c4d.REFLECTION_LAYER_TRANS_BRIGHTNESS] = random.uniform(0., 1.)

    doc.InsertMaterial(mat)
    c4d.EventAdd()

if __name__ == '__main__':
    main()

@ferdinand Thanks !

Sorry for my bad descriptions again, All I mean is Blending Mode ,I didn't remember this word in that moment, my stupid😢 I say multiply and try to explain the Blending Mode , seems more confusing,hhhh

Back to the problem, this line is what I want:

# Set the name of layer.
layer.SetName("Normal-Layer" if blendMode == 0 else "Add-Layer")

Sometimes I want to define a attribute like Blending Mode , It has some attributes can not drag to console or darg then nothing happened, perhaps the real qustion is where I can find those atrributes and set them?

Thanks

Hey @dunhou,

console dragging is the right way to go in 99% of the cases. It is only that you have happened to pick here a case where the description (i.e., that parameter set of the node and the GUI which is associated with it) is quite complex and being built at runtime, i.e., is a dynamic description. There are no too many cases of this in our APIs (in Character animation are quite a few).

If you want more information, I would recommend looking at the header file c4d_reflection.h and its documentation as it will line out the elements in the data package of a reflection layer. For more complex and fringe systems like this, there is however no exhaustive documentation, and you are instead expected to tinker a bit yourself.

Cheers,
Ferdinand

@ferdinand
It seems more complicate and detailed doc in C++ document than python. I will be helpful to move on.
Thanks to that