Solved Accessing Redshift Material Parameters with User Data

I'm a beginner with Python in C4D and I've been having an issue with a Python tag for a while now and could use some assistance.
I can successfully control material parameters using user data with the following code:

import c4d

def main():
    obj = op.GetObject()

    mat = obj[c4d.ID_USERDATA,1]
    strength = obj[c4d.ID_USERDATA,2]

    if mat is None or not isinstance(strength, float):

    mat[c4d.MATERIAL_COLOR_BRIGHTNESS] = strength

However, I'm struggling to control Redshift material parameters in the same way. For example, I need to control the [c4d.REDSHIFT_SHADER_MATERIAL_DIFFUSE_WEIGHT] parameter.

What changes do I need to make in order to get this working properly?

Any help would be appreciated, thank you!

Hello @Easan,

Welcome to the Plugin Café forum and the Cinema 4D development community, it is great to have you with us!

Getting Started

Before creating your next postings, we would recommend making yourself accustomed with our Forum and Support Guidelines, as they line out details about the Maxon SDK Group support procedures. Of special importance are:

About your First Question

Please excuse the delayed answer to your posting.

Assuming you're working with the 'RS Shader Graph' materials (please try specifying complete information in you next postings), I'd suggest you having a look into awesome example from Ferdinand:

You can find simplified adopted code to your case below, which you can use as a starting point for your further investigations.



import c4d, maxon, typing
from c4d.modules.graphview import *

doc: c4d.documents.BaseDocument  # The active document

ID_NODE_TYPENAME: int = 1001 # The location at which type names are stored in an operator container.

def iterTree(tree: GvNode) -> typing.Iterator[GvNode]:
    """Yields all nodes in the given shader tree #tree.
    yield tree
    for child in tree.GetChildren():
        for desc in iterTree(child):
            yield desc

def main():
    mat = doc.GetActiveMaterial()
    if mat is None or not mat.CheckType(c4d.Mrsgraph):
        raise ValueError("There is no selected Redshift Shader Graph")

    # We traverse branches of this shader graph
    for info in mat.GetBranchInfo(c4d.GETBRANCHINFO_ONLYWITHCHILDREN):
        if info.get("name", "").lower() != "node":
        head: c4d.GeListHead | None = info.get("head", None)
        if not isinstance(head, c4d.GeListHead):
            raise RuntimeError(f"Malformed RS graph without head: {info}")
        root: GvNode = head.GetFirst() 
        for node in iterTree(root):
            # Get the data of container of #node which among other things contains its real type name.
            opData: c4d.BaseContainer = node.GetOperatorContainer()
            if opData[ID_NODE_TYPENAME] != RS_MATERIAL_NODE_TYPENAME: # filter out all non-material nodes
            print(f'Diffuse weight: {node[c4d.REDSHIFT_SHADER_MATERIAL_DIFFUSE_WEIGHT]}')

    # Pushes an update event to Cinema 4D

if __name__ == "__main__":

MAXON SDK Specialist

@i_mazlov Thank you very much for your help!