1

I am familiar with scripting, a fair bit, but I dont know how to tackle this challenge...

I have a big amount of Materials with a principle BSDF and I need to disconnect the ImageTexture
from the Roughness-Channel insert a invert node and reconnect everything.

Maybe I can check the nodeTree which Map is connected to Roughness, save that - disconnect, insert and
reconnect, and go to the next tree...

but I dont have any clue how that could happen....

Master Heavy
  • 595
  • 2
  • 15

2 Answers2

3

I propose the following script for this.

Basically, you access each material in the file, then get a reference to the image texture and bsdf nodes, then create a new invert node and connect everything. You don't care about unlinking first because it will be overwritten by your new link.

import bpy

for mat in bpy.data.materials: node_tree = mat.node_tree if not node_tree: continue

# Get a reference to the image and bsdf nodes
tex_image = bsdf = None
for node in node_tree.nodes:
    if node.type == 'TEX_IMAGE':
        tex_image = node
    elif node.type == 'BSDF_PRINCIPLED':
        bsdf = node

# If you have several Image Texture nodes, you can access a specific one by its name
# tex_image = node_tree.nodes.get("Image Texture") # (Or whatever the name of the image texture node connected to the roughness channel usually is)

if not (tex_image and bsdf):
    continue

invert_node = node_tree.nodes.new(type='ShaderNodeInvert')
invert_node.location = (-200, 50) 

tex_image.location = (-600, 50)

# Update the links. We don't care about unlinking because the current links will get overwritten
links = node_tree.links
links.new(tex_image.outputs[0], invert_node.inputs[1])
links.new(invert_node.outputs[0], bsdf.inputs["Roughness"])

enter image description here

Gorgious
  • 30,723
  • 2
  • 44
  • 101
  • Ok, great, that works... but how do I check if bsdf.inputs["Roughness"] is unconnected before.... so that only already connected nodes get the Invert -- can I check if input[""] == none? – Master Heavy Jun 19 '20 at 11:50
  • 1
    I cant edit my comment, so here we go... I put "if bsdf.inputs["Roughness"].links:" in front of your invert node, where you make the links and now it works only for allready connected nodes. thx – Master Heavy Jun 19 '20 at 12:01
  • Oh, I didn't know you needed that but I am glad you solved it yourself :) – Gorgious Jun 19 '20 at 12:06
  • Yes, some failsafe is everytimes good, - if nothing is connected then dont do nothing... if you think that will improve your answer, maybe you would like to integrated in your answer so people facing the same problem can have a proper helpful answer.thx – Master Heavy Jun 19 '20 at 12:16
1

Look for the links

Similarly as in Blender scripting connect nodes look for the links.

In this case a link from an image texture node to the roughness socket of the bsdf node.

Test script, looks for that link(s) in all materials and if found inserts an invert node between.

import bpy

for m in bpy.data.materials: if not m.use_nodes: continue nodes = m.node_tree.nodes links = m.node_tree.links image_ps_links = [ l for l in links if l.from_node.type == "TEX_IMAGE" and l.to_node.type == 'BSDF_PRINCIPLED' and l.to_socket.name == "Roughness"] for l in image_ps_links: invert_node = nodes.new(type='ShaderNodeInvert') links.new(l.from_socket, invert_node.inputs[1]) links.new(invert_node.outputs[0], l.to_socket)

Note: Using the socket name "Roughness" may not work if you are using a language other than english. If this is the case would need to translate or use a method that takes into account the socket index.

batFINGER
  • 84,216
  • 10
  • 108
  • 233