Featured post

new redirect for blender.org bpy docs.

http://www.blender.org/api/blender_python_api_current/ As of 10/11 november 2015 we can now link to the current api docs and not be worr...

September 11, 2012

A guy walks into a bar - Asks a cycles nodes question.

Guy walks into a bar, poses a question. I'll restate without attribution.

Hello, I would like to do the following:
1. with existing Diffuse BSDF material
2. add input node of type Attribute
3. connect Attribute node output color to BSDF default (input)
4. Change the name socket of the "Attribute"

For sake of demonstration your material is the only material in the blend, so we can acces it by index=0, and it's a good idea to alias the material as mymat, purely for convenience

get active node:
mymat = bpy.data.materials[0]
mymat.node_tree.nodes.active
bpy and cycles have a large collection of methods and attributes, most of which vacate the mind within days of use, so i query the python console. this returns a list of nodes that we can add, looks like 'ATTRIBUTE' is on this list
mymat.node_tree.nodes.new('_')
add input node:
attr_node = mymat.node_tree.nodes.new('ATTRIBUTE')
This places the new node most likely in an inconvenient place, but gives you a reference to it: attr_node. The location of this attr_node defaults to vector((0.0, 0.0)). If we want to place the attr_node 200 units to the left of the Diffuse Node we need to know the location of the Diffuse Node.
dif_node = mymat.node_tree.nodes['Diffuse BSDF']
dif_loc = dif_node.location.copy()
attr_loc = dif_loc + Vector((-200.0, 0.0))

# update attr_node location
attr_node.location = attr_loc
Renaming the attr_node.attribute_name is the easiest bit
attr_node.attribute_name = 'kung fu'
Connecting the nodes i'm not sure about, let's try something..
# colour output node of attribute Node
attr_node.outputs['Color']

# colour input node of diffuse BSDF Node (shader)
dif_node.inputs['Color']

mymat.node_tree.links.new(attr_node.outputs['Color'],dif_node.inputs['Color'])
thus, to sum up.
# make sure for this particular script that you have the diffuse shader active, 
# before running it. else modify to satisfaction.

import bpy 
from mathutils import Vector

mymat = bpy.data.materials[0]
mymat.node_tree.nodes.active

attr_node = mymat.node_tree.nodes.new('ATTRIBUTE')
dif_node = mymat.node_tree.nodes['Diffuse BSDF']

# update attr_node location
dif_loc = dif_node.location.copy()
attr_loc = dif_loc + Vector((-200.0, 0.0))
attr_node.location = attr_loc

attr_node.attribute_name = 'kung fu'

output_node = attr_node.outputs['Color']
input_node = dif_node.inputs['Color']

mymat.node_tree.links.new(output_node, input_node)
i learnt a lot, thanks