Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Recent
    • Tags
    • Users
    • Register
    • Login

    Access Node Material Path Redshift 2026

    Scheduled Pinned Locked Moved Cinema 4D SDK
    2026pythonwindows
    2 Posts 1 Posters 33 Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • R Offline
      randmcnally
      last edited by

      hello.
      working on a project where I have 8x materials with 11 texture nodes on a shader switch for a total of 88 textures that are mapped to the indexid of a clone object via a userdata node

      I have been attempting to script this via python where I can swap the textures based on the material name, then within each texture I mape 1-11 on clone material 01, 12-22 on clone material 02 but I am running into troubles accessing the 2026.1 command to access the Redshift Texture path. I think I have spent more time on this than it would have taken to do this manually, but I am interested in fixiing this. I have seem previous posts on the forum related to this, but in 2025 things seem to have changed and I am not sure where the "Path" is located on a Redshift material and how I can link that path to a user generated name on the material.

      essentially I am trying to get python to see "cloner_01" material, then within that add textures 01-11 to the textures within it based on the user generated name on the texture node, 01-11. then for "cloner_02" material add textures 12-22 into, and so on and so forth until "cloner_08" 78-88. I was able to do this failry easily on a displacer deformer to swap the shader per clone there. but I am having trouble access Redshift's Path.

      could I get a few hints as to where I need to be looking to do this, or maybe there is a better logic? thanks.

      1 Reply Last reply Reply Quote 0
      • R Offline
        randmcnally
        last edited by

        hi there, I actually did sort this out in a very round about way with some "vibe coding". this was for a mapp creation project I am working where I am displaying various eras of map onto 20km grids (so as not to kill the viewport functionality). have a look at the below and let me know if this is a solid approach or if there was a better way:

        import c4d
        import maxon
        
        def main():
            era = "INSERT_YOUR_ERA_HERE"
            basePath = "INSERT_YOUR_PATH_HERE"
            prefix = f"map_{era}_tile_20k_"
            extension = ".tif"
        
            doc = c4d.documents.GetActiveDocument()
            if doc is None:
                return
        
            nodeSpaceId = maxon.Id("com.redshift3d.redshift4c4d.class.nodespace")
            textureNodeId = maxon.Id("com.redshift3d.redshift4c4d.nodes.core.texturesampler")
        
            for mat_index in range(1, 9):
                mat_name = f"column_{mat_index:02d}"
                mat = doc.SearchMaterial(mat_name)
                if not mat:
                    print(f"Material {mat_name} not found.")
                    continue
        
                nodeMat = mat.GetNodeMaterialReference()
                if nodeMat is None:
                    print(f"{mat_name} is not a node material.")
                    continue
        
                graph = nodeMat.GetGraph(nodeSpaceId)
                if graph.IsNullValue():
                    print(f"No Redshift graph for {mat_name}.")
                    continue
        
                textureNodes = []
                maxon.GraphModelHelper.FindNodesByAssetId(graph, textureNodeId, False, textureNodes)
        
                with graph.BeginTransaction() as transaction:
                    for node in textureNodes:
                        node_name = node.GetValue(maxon.NODE.BASE.NAME)
                        if not node_name:
                            print(f"Unnamed node in {mat_name}, skipping.")
                            continue
                        node_name = str(node_name)
        
                        try:
                            local_index = int(node_name)
                        except:
                            print(f"Non-numeric node name '{node_name}' in {mat_name}, skipping.")
                            continue
        
                        global_index = (mat_index - 1) * 11 + local_index
                        filename = f"{prefix}{global_index:03d}{extension}"
                        full_path = basePath + filename
        
                        tex0 = node.GetInputs().FindChild(
                            "com.redshift3d.redshift4c4d.nodes.core.texturesampler.tex0"
                        )
                        if tex0.IsNullValue():
                            print(f"No tex0 on node '{node_name}' in {mat_name}")
                            continue
        
                        pathPort = tex0.FindChild("path")
                        if pathPort.IsNullValue():
                            print(f"No path port on node '{node_name}' in {mat_name}")
                            continue
        
                        pathPort.SetDefaultValue(maxon.Url(full_path))
                        print(f"{mat_name} → Node '{node_name}' set to {full_path}")
        
                    transaction.Commit()
        
            c4d.EventAdd()
        
        if __name__ == "__main__":
            main()
        
        
        
        1 Reply Last reply Reply Quote 0
        • First post
          Last post