Ben Traje
← Back to cinema4d

How to Retrieve Redshift Node Materials in Cinema 4D via Python

02 Oct 26 (Today)

With recent versions of Cinema 4D (S26 and newer), Redshift materials transitioned from the legacy Xpresso/GraphView system to the new Maxon Nodes API. When writing Python scripts to automate your pipeline, you can no longer rely on standard material iteration. You must explicitly interact with the Node Graph and target the Redshift Node Space.

The Challenge: Filtering Node Materials Safely

A common workflow is iterating through a scene's materials to find and modify Redshift Node Materials. However, simply looping through doc.GetMaterials() and attempting to access the graph is prone to crashes.

Two common pitfalls developers face:

  1. AttributeError: Trying to use non-existent Python methods like HasGraph on the NodeMaterial object.
  2. RuntimeError: Attempting to retrieve a node graph from a legacy standard material or non-node shader. The API will throw a RuntimeError: Illegal state: Invalid Space because the material lacks a valid node implementation.

The Solution: A Robust Retrieval Script

To safely retrieve Redshift Node Materials without breaking your script, you must use GetGraph() and wrap the call in a try...except block. This ensures that non-node materials are gracefully skipped rather than halting the execution.

Here is the production-ready script:

import c4d
import maxon

def main():
    # Get the active document
    doc = c4d.documents.GetActiveDocument()
    if not doc:
        return

    # Retrieve all materials in the scene
    materials = doc.GetMaterials()
    
    print(f"--- Scanning {len(materials)} materials ---")

    # Define the specific Redshift Node Space ID
    redshift_nodespace_id = maxon.Id("com.redshift3d.redshift4c4d.class.nodespace")
    count = 0

    for mat in materials:
        # 1. Get the Node Material Reference
        # This generic wrapper usually succeeds for any BaseMaterial
        node_material = mat.GetNodeMaterialReference()
        
        try:
            # 2. Try to retrieve the graph
            # This is where the error happens for non-node materials.
            graph = node_material.GetGraph(redshift_nodespace_id)
            
            # 3. If successful, check if the graph is valid
            if not graph.IsNullValue():
                print(f"Found Redshift Node Material: {mat.GetName()}")
                count += 1
                
        except RuntimeError:
            # Catch "Illegal state" or "Invalid Space" errors triggered
            # by materials that do not support the Maxon Nodes API.
            continue

    print(f"--- Total Redshift Node Materials found: {count} ---")

if __name__ == '__main__':
    main()

Key Concepts

  • Node Space Targeting: com.redshift3d.redshift4c4d.class.nodespace is the critical identifier. It ensures you are targeting the modern Redshift graph, filtering out legacy Xpresso materials.
  • GetNodeMaterialReference(): This method bridges standard C4D materials with the new Maxon Nodes framework.
  • Exception Handling: Because GetGraph() strictly checks the material's internal implementation, wrapping it in a try/except block is the standard Pythonic way to handle the API's volatility when scanning mixed-material scenes.