# Using python to batch link image texture alpha to Principled BSDF

Ron Jensen's comment was the solution! Thank you!

My goal is to cycle through a bunch of different materials that have image textures, and link the alpha output of the image texture to a Principled BSDF node that is also in the material. What I have at the moment doesn't work, and while I do know a little bit of python, I don't think I have a deep enough understanding of blender's libraries to figure this out on my own.

This is patched together from this highlighted youtube comment and BlenderBoi2018's post here:

https://blenderartists.org/t/how-to-connect-existing-node-group-in-a-material-in-python/1295671/4#post_4

import bpy

# Run through all materials of the current blend file

for mat in bpy.data.materials:

# If the material has a node tree

if mat.node_tree:

# Link alpha from image texture to alpha on principled bsdf



My (potentially very wrong) understanding of the last line is material name.the material's node tree.links between nodes.new link(target node.input slot[name], node to link from.output slot[name]). Somebody please explain it if I have that wrong. The use of PrincipledBSDFWrapper comes from here:

But it doesn't seem to be intended for use in that way.

I couldn't find a bl_idname for the Pricipled BSDF, which I think would have worked in this context, but I don't know that for sure. If I have all my information correct my holdup here is figuring out how to specify which node is which.

• Assuming the material has exactly one Principled BSDF and exactly one Image Texture, you could do: mat.node_tree.links.new( mat.node_tree.nodes['Principled BSDF'].inputs['Alpha'], mat.node_tree.nodes['Image Texture'].outputs['Alpha'] ) however, this may be brittle due to name mangling internal to Blender. Oct 4 '21 at 20:12

You don't need to use the wrapper class, but as Ron Jensen commented yesterday, the obvious way to do this is very fragile. Here is a long script that tries to do as much error handling as possible, and uses node types rather than naming conventions. But even this is fragile in the face of multiple image textures or multiple principled shaders, as it only picks one at random and doesn't retry with the others if that fails.

import bpy

def find_nodes_by_type(material, node_type):
""" Return a list of all of the nodes in the material
that match the node type.
Return an empty list if the material doesn't use
nodes or doesn't have a tree.
"""
node_list = []
if material.use_nodes and material.node_tree:
for n in material.node_tree.nodes:
if n.type == node_type:
node_list.append(n)
return node_list

""" Find at least one image texture in the material
and at least one Principled shader.
If they both exist and neither have a link to
the relevant alpha socket, connect them.
There are many ways this can fail.
if there's no image; if there's no principled
shader; if the selected image/principled sockets
Returns false on any detected error.
Does not try alternatives if there are multiple
"""
print(f'processing material {material.name}')
it_list = find_nodes_by_type(material, 'TEX_IMAGE')
if len(it_list) == 0:
print(f'{material.name}: no image texture nodes.')
return False
if len(it_list) > 1:
print(f'{material.name}: too many image textures. Trying the first one')
s_list = find_nodes_by_type(material, 'BSDF_PRINCIPLED')
if len(s_list) == 0:
return False
if len(s_list) != 1:
print(f'{material.name}: too many principled shaders. Trying the first one')
image_node = it_list[0]
print(f'{material.name}: Attempting to connect {image_node.name} alpha to {shader_node.name}')
image_socket = image_node.outputs['Alpha']
if not image_socket:
print(f'{material.name}: Image texture does not have an alpha node.  Something is seriously broken.')
return False
print(f'{material.name}: Image texture alpha output already in use.')
return False
print(f'{material.name}: Principled BSDF does not have an alpha node. Version of Blender too old?')
return False