1
$\begingroup$

my code creates a node group and I needed it to be automatically assigned between the principled shader and the output node. It works if I try to connect any nodes, but not with my node group’s input and ouput. I’ve been trying for hours and I am clueless. I appreciate any possible help.

group created by the script that should be connected between principled shader and material output

That group there is what my script creates. I just need to connect the "shaderIn" and "shaderOut" outputs between them.

Here is the code, with one of the many failed attempts at linking the node at the bottom. I managed to make the code add the group to the materials, but it’s as far as I could go:

import bpy
pathImg = "D:\\MaxToBlender\\Lightmaps\\"

selection_names = [] #declaring array
for obj in bpy.context.selected_objects: #loop through all the selected objects
  if obj.type == 'MESH':
    selection_names.append(obj) #add to array
    obj.select_set(False)
if selection_names != []:
    count = 00 #set the count
    for obj in selection_names: #loop through array
        count = count + 1
        bpy.context.view_layer.objects.active = obj
        imageNumber = (f"{(count):02d}")
        imageFile = (str(pathImg) + str(imageNumber) + "_c.exr")
        print(imageFile)
        
        # create a group for this object
        groupName = ("group" + str(imageNumber))
        bakeGroup = bpy.data.node_groups.new(groupName, 'ShaderNodeTree')
        # create group inputs
        group_inputs = bakeGroup.nodes.new('NodeGroupInput')
        group_inputs.location = (0,0)
        bakeGroup.inputs.new('NodeSocketShader','shaderIn')
        # create group outputs
        group_outputs = bakeGroup.nodes.new('NodeGroupOutput')
        group_outputs.location = (300,0)
        bakeGroup.outputs.new('NodeSocketShader','shaderOut')
        # create nodes in a group
        addShader = bakeGroup.nodes.new(type="ShaderNodeAddShader")
        addShader.location = 400,-200
        emissiveShader = bakeGroup.nodes.new(type="ShaderNodeEmission")
        emissiveShader.location = 300, -100
        lightImgNode = bakeGroup.nodes.new(type="ShaderNodeTexImage")
        lightImgNode.image = bpy.data.images.load(imageFile)
        lightImgNode.location = 200,-200
        # link nodes together
        bakeGroup.links.new(addShader.inputs[1], emissiveShader.outputs[0])
        bakeGroup.links.new(emissiveShader.inputs[0], lightImgNode.outputs[0])
        #link input and output of group
        bakeGroup.links.new(group_inputs.outputs['shaderIn'], addShader.inputs[0])
        bakeGroup.links.new(addShader.outputs[0], group_outputs.inputs['shaderOut'])
        
        for m in bpy.context.object.material_slots: #iterate through all materials on the object
            override = bpy.context.copy() #i don't know what it does. without it it says the context is wrong
            material = m.material.copy()#makes this material unique otherwise the shader will be created multiple times or same material in different objects will have the same lightmap
            m.link = 'OBJECT' #not necessary unless the objects are linked, but just in case...
            m.material = material #reassigns the material that goes away when the link is changed
 
            nodes = material.node_tree.nodes # get all material nodes
            material_output = nodes.get("Material Output") 
            mainShader = nodes.get("Principled BSDF") #get the principled hoping there's only one
            
            #add the group
            dummy_group_node = material.node_tree.nodes.new(type='ShaderNodeGroup')
            dummy_group_node.node_tree = bakeGroup
            
            #link input and output of group
            material.node_tree.links.new(bakeGroup.outputs['shaderIn'], mainShader.outputs[0])
            material.node_tree.links.new(material_output.inputs[0], bakeGroup.inputs['shaderOut'])
$\endgroup$

1 Answer 1

1
$\begingroup$

Here:

            #link input and output of group
            material.node_tree.links.new(bakeGroup.outputs['shaderIn'], mainShader.outputs[0])
            material.node_tree.links.new(material_output.inputs[0], bakeGroup.inputs['shaderOut'])

bakeGroup is a NodeGroup. You want to use the Group Node dummy_group_node.

Also remember in links.new(A, B), A is the input socket, and B is the output socket.

So do this instead:

            #link input and output of group
            material.node_tree.links.new(dummy_group_node.inputs['shaderIn'], mainShader.outputs[0])
            material.node_tree.links.new(material_output.inputs[0], dummy_group_node.outputs['shaderOut'])
$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .