# Principled BSDF via Python API

The title is general: how can we use the API to edit Principled BSDF properties?

More specifically, I have a mesh that has vertex colors in it. The colors are fine, and I can use the mouse to have vertex colors as base color using the Shader Editor. Likewise, I can use the Material Properties and select "Vertex Colors | Color" for the base color of the material assigned to the mesh. This is all fine and both are equivalent ways.

However, how to accomplish that programmatically, via the API? I could do that in 2.7x but don't seem to be able to do the same in 2.81. Any idea?

EDIT: here a minimal example that works with 2.7x:

import bpy
mat = "MyMaterial"
bpy.ops.material.new()
setattr(bpy.data.materials["Material"],"name",mat)
setattr(bpy.data.materials[mat],"use_vertex_color_paint",True)

Traceback (most recent call last):
File "<blender_console>", line 1, in <module>
AttributeError: 'Material' object has no attribute 'use_vertex_color_paint'
$$$$

• The concept remains pretty much the same in 2.8x. Perhaps you can add your current script for 2.79 to your question and explain what particular part you have trouble implementing in 2.81. – Robert Gützkow Dec 4 '19 at 22:34
• Thanks for the suggestion. I've just added above. The "use_vertex_color_paint" has been removed from the current API, according to the release notes. – amwink Dec 5 '19 at 1:43
• This post on Stack overflow stackoverflow.com/a/36194568/808940 just use "ShaderNodeVertexColor" instead. – Moog Dec 5 '19 at 2:30
• Thanks. It seems this would also work. The one below is straight to the point and very general, so I'm taking it as 'the' answer. – amwink Dec 5 '19 at 12:30

Adds a new material using mat = bpy.data.materials.new()

Recommend: almost never use bpy.ops.materials.new() The material bpy.data.materials[mat] in script in question is confusing and varies dependant on pre existing materials "Material" and "MyMaterial".

Notice I used the index of the io when making links. Could use vcol.outputs["Color"] for vcol.outputs[0], however if the user is using a different language, then "Color" will be in that language.

The principled bsdf base color is input 0. A simple test in python console to save counting by eye.

>>> for i, o in enumerate(bsdf.inputs):
...     i, o.name
...
(0, 'Base Color')
(1, 'Subsurface')
(3, 'Subsurface Color')
(4, 'Metallic')
(5, 'Specular')
(6, 'Specular Tint')
(7, 'Roughness')
(8, 'Anisotropic')
(9, 'Anisotropic Rotation')
(10, 'Sheen')
(11, 'Sheen Tint')
(12, 'Clearcoat')
(13, 'Clearcoat Roughness')
(14, 'IOR')
(15, 'Transmission')
(16, 'Transmission Roughness')
(17, 'Emission')
(18, 'Alpha')
(19, 'Normal')
(20, 'Clearcoat Normal')
(21, 'Tangent')


import bpy

newmat = bpy.data.materials.new("VertCol")
newmat.use_nodes = True
node_tree = newmat.node_tree
nodes = node_tree.nodes

bsdf = nodes.get("Principled BSDF")
'''
# alternatively

output, bsdf = nodes
'''

assert(bsdf) # make sure it exists to continue

`