# Add Nodes to Material with Python

I have edited a script that creates some nodes, but the only problem is, it always created a new material. I want it to either add the nodes on the existing material, or a pre-defined material. Here is the script base I am using.

Thanks for the help in advance! :D

You can get the material node tree from bpy.data.materials['MyMaterial'].node_tree

Then add the nodes with node_tree.nodes.new()

For example, to add a diffuse shader node to MyMaterial and create MyMaterial if it doesn't exist:

import bpy
mat_name = "MyMaterial"
# Test if material exists
# If it does not exist, create it:
mat = (bpy.data.materials.get(mat_name) or
bpy.data.materials.new(mat_name))

# Enable 'Use nodes':
mat.use_nodes = True
nodes = mat.node_tree.nodes

node.location = (100,100)


The answer provided is only partially helpful. Or it is outdated in 2.7

Yes you have to add the nodes (use_nodes = True). However the default material is the Diffuse BSDF. So if you want to use this, fine, you're done. But to change the shader being used:

1. Remove the shader in place (Diffuse BSDF, otherwise the second element in the material.node_tree.nodes.values() list. This is sort of optional, as it can also stay in place, but it's just not tidy and confusing to leave it there.
2. Create a new shader node. e.g. material.node_tree.nodes.new('ShaderNodeEmission')
3. Update the link to the Material Output node. material.node_tree.links.new(mat.inputs[0], node.outputs[0])

Here an example I made I use quite often: a Mesh Light

    def create_light():
"""
Add a mesh light for cycles
"""

plane = bpy.context.active_object
plane.name = 'Light Plane'
plane.scale = mathutils.Vector((4, 4, 4))
# tilt

# Create a new material
material = bpy.data.materials.new(name="Plane Light Emission Shader")
material.use_nodes = True

# Remove default
material.node_tree.nodes.remove(material.node_tree.nodes.get('Diffuse BSDF'))
material_output = material.node_tree.nodes.get('Material Output')
emission.inputs['Strength'].default_value = 5.0

# set activer material to your new material
plane.active_material = material

• Your this code snippet is very helpful Sir. Thank you so much! Took me a while to figure out that link. Then I remember I saw your answer before. – Sibbs Gambling Dec 27 '16 at 2:46
• Color can be set analog to Strength: emission.inputs['Color'].default_value = (0,1,0,1) # green RGBA – jakob.j Dec 26 '19 at 12:55

now at first you have principled BSDF. a variation with a diffuse node on active object

import bpy

# Create a new material
material = bpy.data.materials.new(name="Diffuse")
material.use_nodes = True

# Remove default
material.node_tree.nodes.remove(material.node_tree.nodes.get('Principled BSDF')) #title of the existing node when materials.new
material_output = material.node_tree.nodes.get('Material Output')

diffuse.inputs['Color'].default_value = (1, 0, 1, 1) #last value alpha

# set activer material to your new material
bpy.context.object.active_material = material


Another way to do this is. It picks up a material if it exists, else creates a new one with that name.

import bpy

mat_name = "MyMaterial"
materials = bpy.data.materials

# if .get returns None, the assignment comes from the right of the 'or'
mat = materials.get(mat_name) or materials.new(mat_name)   # *** see comment
mat.use_nodes = True
nodes = mat.node_tree.nodes


mat = materials.get(mat_name, materials.new(mat_name))