Redshift Standard Material base Properties
-
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()
-
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~
DunHouimport 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")
-
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,
FerdinandPS: I have added the example below to the code examples of the upcoming release alongside the standard renderer example.
Result:
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()
-