Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware 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
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Redshift Standard Material base Properties

    Bugs
    3
    3
    1.1k
    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.
    • S
      simonator420
      last edited by

      Hi,

      I am trying to insert the full_path into "Load texture..." into Redshift Standard Material base color but all I got so far is this code. Could you help me solve this?

      full_path = os.path.join(folder_path, file)
      
      rsNodeSpaceID: maxon.Id = maxon.Id("com.redshift3d.redshift4c4d.class.nodespace")
      textureNodeID: maxon.Id = maxon.Id("com.redshift3d.redshift4c4d.nodes.core.texturesampler")
      textureNodePortID: maxon.String = "com.redshift3d.redshift4c4d.nodes.core.texturesampler.tex0"
      textureNodePathPortID: maxon.String = "path"textureColorOutPortID: maxon.String = "com.redshift3d.redshift4c4d.nodes.core.texturesampler.outcolor"
      
      mat: c4d.BaseMaterial = c4d.BaseMaterial(c4d.Mmaterial)
      nodeMaterial: c4d.NodeMaterial = mat.GetNodeMaterialReference()
      graph: maxon.GraphModelRef = nodeMaterial.CreateDefaultGraph(rsNodeSpaceID)
      
      doc.InsertMaterial(mat)
      
      result: list[maxon.GraphNode] = []
      maxon.GraphModelHelper.FindNodesByAssetId(graph, outputNodeID, True, result)
      
      outputNode: maxon.GraphNode = result[0]
      
      with graph.BeginTransaction() as transaction:
      	textureNode: maxon.GraphNode = graph.AddChild(maxon.Id(), textureNodeID)
      	pathPort: maxon.GraphNode = textureNode.GetInputs().FindChild(textureNodePortID).FindChild(textureNodePathPortID)
      	pathPort.SetDefaultValue(maxon.Url(full_path))
      	textureColorOutPort: maxon.GraphNode = textureNode.GetOutputs().FindChild(textureColorOutPortID)
      	colorInputPortInOutputNode : maxon.GraphNode = outputNode.GetInputs().FindChild(colorInputPortInOutputNodeId)
      	textureColorOutPort.Connect(colorInputPortInOutputNode)
      	transaction.Commit()
      	
      

      321c714b-6cdb-4038-9100-8aa871aef503-image.png

      DunhouD ferdinandF 2 Replies Last reply Reply Quote 0
      • DunhouD
        Dunhou @simonator420
        last edited by

        Hi @simonator420 ,

        You should get the base color port( a maxon.GraphNode ), and connect with a Texture node ( also a maxon.GraphNode ), the texture path is also a port in Texture node, just set it's value is what you need,
        I have a little example here which used my api helper renderEngine, I think it is easy to use and less code for general task. but it should be pointed out that use Maxon python sdk is more customized.

        Cheers~
        DunHou

        import c4d,maxon
        from importlib import reload
        from renderEngine.redshift import redshift_helper as rs
        reload(rs)
        try:
            from redshift_id import *
        except:
            from renderEngine.redshift.redshift_id import *
        from renderEngine import node_helper
        reload(node_helper)
        
        def AddandModify(name):
            redshiftMaterial =  rs.MaterialHelper.CreateStandardSurface(name)
        
            # modification has to be done within a transaction
            with rs.RSMaterialTransaction(redshiftMaterial) as transaction:
        
                # Find brdf node (in this case : standard surface)
                standard_surface = redshiftMaterial.helper.GetRootBRDF()
        
                # Change a shader name
                redshiftMaterial.helper.SetName(standard_surface,'My BRDF Shader')
        
                # TexPath
                tex_helper = node_helper.TextureHelper()
                url: maxon.Url = tex_helper.GetAssetStr(maxon.Id("file_5b6a5fe03176444c"))
                tar = redshiftMaterial.helper.GetPort(standard_surface,'com.redshift3d.redshift4c4d.nodes.core.standardmaterial.base_color')
        
                # Add a texture to base color
                redshiftMaterial.AddTexture(shadername = 'My texture', filepath = url, raw = True, target_port = tar)
                
            redshiftMaterial.InsertMaterial()
            redshiftMaterial.SetActive()
            c4d.EventAdd()
            
            return redshiftMaterial.material
        
        if __name__ == '__main__':
            AddandModify("Example")
        

        https://boghma.com
        https://github.com/DunHouGo

        1 Reply Last reply Reply Quote 0
        • ferdinandF
          ferdinand @simonator420
          last edited by

          Hey @simonator420,

          Thank you for reaching out to us. And thank you @Dunhou for providing a solution. You should however be aware that Dunhou's solution requires his proprietary library as he states below. I think you should give it a spin because it is quite useful.

          When you must remain within the bounds of the Cinema 4D standard library, find an example for how to do that below.

          Cheers,
          Ferdinand

          PS: I have added the example below to the code examples of the upcoming release alongside the standard renderer example.

          Result:
          2f242653-ad67-4010-a78a-277f5953b856-image.png

          Code:

          #coding: utf-8
          """Demonstrates setting up a Redshift node material composed out of multiple nodes.
          
          Creates a new node material with a graph in the Redshift material space, containing two texture 
          nodes and a mix node, in addition to the default core material and material node of the material.
          
          Topics:
              * Creating a node material and adding a graph
              * Adding nodes to a graph
              * Setting the value of ports without wires
              * Connecting ports with a wires
              * (Asset API): Using texture assets in a node graph
          
          """
          __author__ = "Ferdinand Hoppe"
          __copyright__ = "Copyright (C) 2023 MAXON Computer GmbH"
          __date__ = "01/09/2023"
          __license__ = "Apache-2.0 License"
          __version__ = "2023.2.0"
          
          
          import c4d
          import maxon
          
          doc: c4d.documents.BaseDocument # The active document.
          
          def main() -> None:
              """Runs the example.
              """
              # The asset URLs for the "RustPaint0291_M.jpg" and "Sketch (HR basic026).jpg" texture assets in 
              # "tex/Surfaces/Dirt Scratches & Smudges/". These could also be replaced with local texture URLs,
              # e.g., "file:///c:/textures/stone.jpg". These IDs can be discovered with the #-button in the info
              # area of the Asset Browser.
              urlTexRust: maxon.Url = maxon.Url(r"asset:///file_edb3eb584c0d905c")
              urlTexSketch: maxon.Url = maxon.Url(r"asset:///file_3b194acc5a745a2c")
          
              # The node asset IDs for the two node types to be added in the example; the texture node and the
              # mix node. These and all other node IDs can be discovered in the node info overlay in the 
              # bottom left corner of the Node Editor. Open the Cinema 4D preferences by pressing CTRL/CMD + E
              # and enable Node Editor -> Ids in order to see node and port IDs in the Node Editor.
              idTextureNode: maxon.Id = maxon.Id("com.redshift3d.redshift4c4d.nodes.core.texturesampler")
              idMixNode: maxon.Id = maxon.Id("com.redshift3d.redshift4c4d.nodes.core.rscolormix")
              idCoreMaterialNode: maxon.Id = maxon.Id("com.redshift3d.redshift4c4d.nodes.core.material")
          
              # Instantiate a material, get its node material and the graph for the RS material space.
              material: c4d.BaseMaterial = c4d.BaseMaterial(c4d.Mmaterial)
              if not material:
                  raise MemoryError(f"{material = }")
          
              nodeMaterial: c4d.NodeMaterial = material.GetNodeMaterialReference()
              graph: maxon.GraphModelRef = nodeMaterial.AddGraph(
                  maxon.Id("com.redshift3d.redshift4c4d.class.nodespace"))
              if graph.IsNullValue():
                  raise RuntimeError("Could not add RS graph to material.")
          
              doc.InsertMaterial(material)
              c4d.EventAdd()
          
              # Attempt to find the core material node contained in the default graph setup.
              result: list[maxon.GraphNode] = []
              maxon.GraphModelHelper.FindNodesByAssetId(graph, idCoreMaterialNode, True, result)
              if len(result) < 1:
                  raise RuntimeError("Could not find standard node in material.")
              standardNode: maxon.GraphNode = result[0]
          
              # Start modifying the graph by opening a transaction. Node graphs follow a database like 
              # transaction model where all changes are only finally applied once a transaction is committed.
              with graph.BeginTransaction() as transaction:
                  # Add two texture nodes and a blend node to the graph.
                  rustTexNode: maxon.GraphNode = graph.AddChild(maxon.Id(), idTextureNode)
                  sketchTexNode: maxon.GraphNode = graph.AddChild(maxon.Id(), idTextureNode)
                  mixNode: maxon.GraphNode = graph.AddChild(maxon.Id(), idMixNode)
          
                  # Set the default value of the 'Mix Amount' port, i.e., the value the port has when no 
                  # wire is connected to it. This is equivalent to the user setting the value to "0.5" in 
                  # the Attribute Manager.
                  mixAmount: maxon.GraphNode = mixNode.GetInputs().FindChild(
                      "com.redshift3d.redshift4c4d.nodes.core.rscolormix.mixamount")
                  mixAmount.SetDefaultValue(0.5)
          
                  # Set the path sub ports of the 'File' ports of the two image nodes to the texture URLs 
                  # established above. Other than for the standard node space image node, the texture is 
                  # expressed as a port bundle, i.e., a port which holds other ports. The texture of a texture
                  # node is expressed as the "File" port, of which "Path", the URL, is only one of the possible
                  # sub-ports to set.
                  pathRustPort: maxon.GraphNode = rustTexNode.GetInputs().FindChild(
                      "com.redshift3d.redshift4c4d.nodes.core.texturesampler.tex0").FindChild("path")
                  pathSketchPort: maxon.GraphNode = sketchTexNode.GetInputs().FindChild(
                      "com.redshift3d.redshift4c4d.nodes.core.texturesampler.tex0").FindChild("path")
                  pathRustPort.SetDefaultValue(urlTexRust)
                  pathSketchPort.SetDefaultValue(urlTexSketch)
          
                  # Get the color output ports of the two texture nodes and the color blend node.
                  rustTexColorOutPort: maxon.GraphNode = rustTexNode.GetOutputs().FindChild(
                      "com.redshift3d.redshift4c4d.nodes.core.texturesampler.outcolor")
                  sketchTexColorOutPort: maxon.GraphNode = sketchTexNode.GetOutputs().FindChild(
                      "com.redshift3d.redshift4c4d.nodes.core.texturesampler.outcolor")
                  mixColorOutPort: maxon.GraphNode = mixNode.GetOutputs().FindChild(
                      "com.redshift3d.redshift4c4d.nodes.core.rscolormix.outcolor")
          
                  # Get the fore- and background port of the blend node and the color port of the BSDF node.
                  mixInput1Port: maxon.GraphNode = mixNode.GetInputs().FindChild(
                      "com.redshift3d.redshift4c4d.nodes.core.rscolormix.input1")
                  mixInput2Port: maxon.GraphNode = mixNode.GetInputs().FindChild(
                      "com.redshift3d.redshift4c4d.nodes.core.rscolormix.input2")
                  coreDiffusePort: maxon.GraphNode = standardNode.GetInputs().FindChild(
                      "com.redshift3d.redshift4c4d.nodes.core.material.diffuse_color")
          
                  # Wire up the two texture nodes to the blend node and the blend node to the BSDF node.
                  rustTexColorOutPort.Connect(mixInput1Port, modes=maxon.WIRE_MODE.NORMAL, reverse=False)
                  sketchTexColorOutPort.Connect(mixInput2Port, modes=maxon.WIRE_MODE.NORMAL, reverse=False)
                  mixColorOutPort.Connect(coreDiffusePort, modes=maxon.WIRE_MODE.NORMAL, reverse=False)
          
                  # Finish the transaction to apply the changes to the graph.
                  transaction.Commit()
          
              # Insert the material into the document and push an update event.
              doc.InsertMaterial(material)
              c4d.EventAdd()
              
          if __name__ == "__main__":
              main()
          

          MAXON SDK Specialist
          developers.maxon.net

          1 Reply Last reply Reply Quote 0
          • maxonM maxon moved this topic from Cinema 4D SDK on
          • First post
            Last post