Since C4DtoA 4.0 there are two types of materials: node-based material and legacy Xpresso-based material. The python API offers a similar interface to interact with both material types. The major difference is that the legacy material uses integer node and parameter ids while the Node Material uses string based ids.
Node Material
The ArnoldNodeMaterial class offers the following interface to create, query and modify Arnold Node Materials.
Create material
- Create(name): Creates a new Arnold Node Material with the given name.
Query shader graph
- GetShaders(self): Returns the list of shaders (maxon.frameworks.graph.GraphNode) within this shader graph.
- GetRootShader(self, rootPortId): Returns the shader (maxon.frameworks.graph.GraphNode) connected to given root port (e.g. 'shader').
- GetShaderRoot(self): Returns the shader (maxon.frameworks.graph.GraphNode) connected to 'shader' root port.
- GetDisplacementRoot(self): Returns the shader (maxon.frameworks.graph.GraphNode) connected to 'displacement' root port.
- GetEndNode(self): Returns the Arnold material end node.
- GetConnections(self): Returns the list of connections within this shader graph. A connection is a tuple of (source shader node, source shader output port id, target shader node, target shader input port id).
Query shader
- GetShaderId(self, shader): Returns the Arnold node id of the given shader (e.g. 'standard_surface').
- GetShaderName(self, shader): Returns the name of the given shader node.
- GetShaderValue(self, shader, paramId): Returns the value stored in the given shader parameter.
Modify shader graph
- AddShader(self, nodeId, name): Adds a new shader to the graph.
- RemoveShader(self, shader): Removes the given shader from the graph.
- AddRootConnection(self, src, outPort, rootPortId): Connects the given shader to the given root port (e.g. 'shader').
- RemoveRootConnection(self, rootPortId): Disconnects the given root port.
- AddConnection(self, src, outPort, dst, inPort): Connects the given shaders in the graph.
- RemoveConnection(self, dst, inPort): Disconnects the given shader input.
All shader graph modifications have to be done within a transaction. The API defines the ArnoldMaterialTransaction class, which is wrapper over the native transaction class.
with ArnoldMaterialTransaction(arnoldMaterial) as transaction: # do modifications
Modify shader
- SetShaderValue(self, shader, paramId, value): Sets the value stored in the given shader parameter.
Generic
- IsNodeBased(self): Returns whether this is a Node Material (true) or a legacy material (false).
Example
This example shows how to create an Arnold Node Material with a basic shader graph. More examples can be found in arnold_material_examples.py script, which is shipped with the plugin.
def CreateNodeMaterial(name): # create an Arnold Node Material arnoldMaterial = ArnoldNodeMaterial.Create(name) if arnoldMaterial is None or arnoldMaterial.material is None: raise Exception("Failed to create Arnold material") # create the shader graph # modification has to be done within a transaction with ArnoldMaterialTransaction(arnoldMaterial) as transaction: # create shaders # use the name of the Arnold node entry standard_surface = arnoldMaterial.AddShader("standard_surface", "my_standard_surface") c4d_noise = arnoldMaterial.AddShader("c4d_noise", "my_c4d_noise") displacement = arnoldMaterial.AddShader("displacement", "my_displacement") checkerboard = arnoldMaterial.AddShader("checkerboard", "my_checkerboard") # connect shaders # use the name of the input/output port # None or empty output means the default 'output' port arnoldMaterial.AddRootConnection(standard_surface, None, "shader") arnoldMaterial.AddConnection(c4d_noise, None, standard_surface, "base_color") arnoldMaterial.AddRootConnection(displacement, None, "displacement") arnoldMaterial.AddConnection(checkerboard, None, displacement, "normal_displacement_input") # set standard surface specular color # NOTE color is in linear sRGB space arnoldMaterial.SetShaderValue(standard_surface, "specular_color", maxon.Color(1.0, 0.8, 0)) # set standard surface specular roughness arnoldMaterial.SetShaderValue(standard_surface, "specular_roughness", 0.05) # set c4d_noise pattern arnoldMaterial.SetShaderValue(c4d_noise, "noise", SLA_NOISE_NOISE_HAMA) # add the material to the scene doc.InsertMaterial(arnoldMaterial.material) doc.SetActiveMaterial(arnoldMaterial.material) return arnoldMaterial
Legacy Material
The ArnoldLegacyMaterial class offers the following interface to create, query and modify Arnold legacy (Xpresso-based) Materials.
Node and parameter ids are integers, generated from the node and parameter name. Ids are defined in the respective resource files (e.g. C4DtoA/res/description/ainode_standard_surface.h) or you can use the GenerateId() function.
import arnold.util as arnold_util # node id C4DAIN_STANDARD_SURFACE = arnold_util.GenerateId("standard_surface") # parameter id C4DAIP_STANDARD_SURFACE_BASE_COLOR = arnold_util.GenerateId("standard_surface.base_color")
Create material
- Create(name): Creates a new legacy Arnold Material with the given name.
Query shader graph
- GetShaders(self): Returns the list of shaders (c4d.modules.graphview.GvNode) within this shader graph.
- GetRootShader(self, rootPortId): Returns the shader (c4d.modules.graphview.GvNode) connected to given root port (e.g. arnold.material.ARNOLD_SHADER_PORT_ID).
- GetShaderRoot(self): Returns the shader (c4d.modules.graphview.GvNode) connected to 'shader' root port.
- GetDisplacementRoot(self): Returns the shader (c4d.modules.graphview.GvNode) connected to 'displacement' root port.
- GetConnections(self): Returns the list of connections within this shader graph. A connection is a tuple of (source shader node, source shader output port id, target shader node, target shader input port id).
Query shader
- GetShaderId(self, shader): Returns the Arnold node id (int) of the given shader (e.g. C4DAIN_STANDARD_SURFACE).
- GetShaderName(self, shader): Returns the name of the given shader node.
- GetShaderValue(self, shader, paramId): Returns the value stored in the given shader parameter.
Modify shader graph
- AddShader(self, nodeId, name): Adds a new shader to the graph.
- RemoveShader(self, shader): Removes the given shader from the graph.
- AddRootConnection(self, src, outPort, rootPortId): Connects the given shader to the given root port (e.g. arnold.material.ARNOLD_SHADER_PORT_ID).
- RemoveRootConnection(self, rootPortId): Disconnects the given root port.
- AddConnection(self, src, outPort, dst, inPort): Connects the given shaders in the graph.
- RemoveConnection(self, dst, inPort): Disconnects the given shader input.
Modify shader
- SetShaderValue(self, shader, paramId, value): Sets the value stored in the given shader parameter.
Generic
- IsNodeBased(self): Returns whether this is a Node Material (true) or a legacy material (false).
- AlignShaders(self): Sets a flag in the material which triggers aligning shaders in the Node Editor when the material is displayed.
Example
This example shows how to create an Arnold Node Material with a basic shader graph. More examples can be found in arnold_material_examples.py script, which is shipped with the plugin.
# from api/include/util/NodeIds.h C4DAIN_CHECKERBOARD = 1208643042 C4DAIN_DISPLACEMENT = 1227821282 C4DAIN_NOISE = 268710787 C4DAIN_OSL = 193501779 C4DAIN_STANDARD_SURFACE = 314733630 # from res/description/ainode_standard_surface.h C4DAIP_STANDARD_SURFACE_BASE_COLOR = 1044225467 C4DAIP_STANDARD_SURFACE_SPECULAR_COLOR = 801517079 C4DAIP_STANDARD_SURFACE_SPECULAR_ROUGHNESS = 1876347704 # from res/description/gvaishader_displacement.h C4DAI_NORMAL_DISPLACEMENT_INPUT = 737403364 # from resource/modules/sla/description/xslanoise.h SLA_NOISE_NOISE_HAMA = 2009 def CreateLegacyMaterial(name): # create material arnoldMaterial = ArnoldLegacyMaterial.Create(name) if arnoldMaterial is None or arnoldMaterial.material is None: raise Exception("Failed to create Arnold material") # create a shader graph # create shaders # use the id of the Arnold node entry standard_surface = arnoldMaterial.AddShader(C4DAIN_STANDARD_SURFACE, "my_standard_surface") c4d_noise = arnoldMaterial.AddShader(C4DAIN_C4D_NOISE, "my_c4d_noise") displacement = arnoldMaterial.AddShader(C4DAIN_DISPLACEMENT, "my_displacement") # NOTE the id can be generated from the node entry name checkerboard = arnoldMaterial.AddShader(arnold_util.GenerateId("checkerboard"), "my_checkerboard") # connect shaders # use the id of the input/output port # None or empty output means the default 'output' port arnoldMaterial.AddRootConnection(standard_surface, None, ARNOLD_SHADER_PORT_ID) # NOTE in case of Arnold shaders the id can be generated from the node entry and parameter name arnoldMaterial.AddConnection(c4d_noise, None, standard_surface, arnold_util.GenerateId("standard_surface.base_color")) arnoldMaterial.AddRootConnection(displacement, None, ARNOLD_DISPLACEMENT_PORT_ID) arnoldMaterial.AddConnection(checkerboard, None, displacement, C4DAI_NORMAL_DISPLACEMENT_INPUT) # set standard surface specular color # NOTE color is in view color space (sRGB) arnoldMaterial.SetShaderValue(standard_surface, C4DAIP_STANDARD_SURFACE_SPECULAR_COLOR, c4d.Vector(1.0, 0.8, 0)) # set standard surface specular roughness arnoldMaterial.SetShaderValue(standard_surface, C4DAIP_STANDARD_SURFACE_SPECULAR_ROUGHNESS, 0.05) # set c4d_noise pattern # NOTE in case of C4D shaders the id is the one defined in the C4D shader description resource files arnoldMaterial.SetShaderValue(c4d_noise, c4d.SLA_NOISE_NOISE, SLA_NOISE_NOISE_HAMA) # align shaders arnoldMaterial.AlignShaders() # add the material to the scene doc.InsertMaterial(arnoldMaterial.material) doc.SetActiveMaterial(arnoldMaterial.material) return arnoldMaterial