0
$\begingroup$

Does anyone have a clue how to do this? In python code i have a button that selects all my objects in the scene except 1 object named ‘PLANE’. Those objects have all a material (Principled BSDF and Material Output). When this button is pushed, the operator selects all the objects except the PLANE and adds a Groupnode to those materials of thos objects (in between the Princepled BSDF and the Material Output). This works, links the nodes and all. But my problem is that even when the PLANE is not selected and has also a specific other material, it also recieves the Groupnode. And that is just what i do not want. The PLANE must keep its own material. Anyone knows how to fix it? Thanks

this is the code.

class SETACTIVEMATERIAL_OT_operator(bpy.types.Operator):
    bl_idname = "object.section_material"
    bl_label = "Set color to all"
    bl_description = ""
    

# this gives the RGB controller in the panel
    col:bpy.props.FloatVectorProperty(name= "pick color", subtype= 'COLOR_GAMMA' , size=4, default= (0,1,0,1), min=0.0, max=1.0) 
   
    def execute(self, context):
        
        
    # selects all objects in the outliner that are a MESH, except a specific one called Section Plane A
        for collection in bpy.data.collections:
            bpy.data.collections.get("")  # between brackets is name of choice of the collection
            if collection:
               for obj in collection.objects:
                   obj.select_set(True)
                   obj.select_set(obj.type == "MESH")
            for obj in bpy.context.scene.objects:
                
                if obj.name.startswith("Sec"):   # even the beginletters are sufficiant
                    obj.select_set(False)
                else:
                      
                      bpy.context.view_layer.objects.active=obj
                      
                    
                  
        
        
        
        
       
            group_name = "GlobalMixer"
            mixer_name = "Overrider"
            MixerGlobalGroup = bpy.data.node_groups.get(group_name)
            # create a group
            if MixerGlobalGroup == None :
                test_group = bpy.data.node_groups.new(group_name, 'ShaderNodeTree')
                # create group inputs
                group_inputs = test_group.nodes.new('NodeGroupInput')
                group_inputs.location = (-200,0)
                test_group.inputs.new('NodeSocketShader','MainShader')
                # create group outputs
                group_outputs = test_group.nodes.new('NodeGroupOutput')
                group_outputs.location = (400,0)
                test_group.outputs.new('NodeSocketShader','MixedShader')
                # create three math nodes in a group
                node = test_group.nodes.new('ShaderNodeMixShader')
                node.location = (-200,-200)
                node.inputs[0].default_value = 1
                node2 = test_group.nodes.new('ShaderNodeBsdfDiffuse')
                node2.inputs[0].default_value = self.col ########
                
                node.location = (200,100)
                # link inputs
                test_group.links.new(group_inputs.outputs['MainShader'], node.inputs[1])
                #link output
                test_group.links.new(node.outputs[0], group_outputs.inputs['MixedShader'])
                test_group.links.new(node2.outputs[0], node.inputs[2])
                MixerGlobalGroup = test_group
                print('Global MIxer Created:', MixerGlobalGroup)
            else:
                test_group = bpy.data.node_groups[group_name]
                print('Global MIxer Exists: ', test_group)
                diffuse = test_group.nodes.get('Diffuse BSDF')  ##########
                diffuse.inputs[0].default_value = self.col      #########
            #####################################################################################
            # ADD A MIXER GROUP
            #####################################################################################
            
            
            for mat in bpy.data.materials:
 
                nodes = mat.node_tree.nodes
                if nodes.get(mixer_name) == None:
                    mixer = nodes.new(type="ShaderNodeGroup")
                    mixer.node_tree  = MixerGlobalGroup
                    mixer.name = mixer_name
                    mixer.location = (200,200)
                    print(mixer_name," [created] ", mixer)
                else:
                    print("....overrider already exists")
                mylinks = mat.node_tree.links
                matOut = nodes.get("Material Output")
                matInput = matOut.inputs
                mixerOut = nodes.get(mixer_name).outputs
                mixerIn = nodes.get(mixer_name).inputs
                old_link = matInput['Surface'].links[0].from_node
                if old_link.name != mixer_name:
                    print("conected to: ",old_link.name)
                    mylinks.new(mixerOut[0], matInput[0])
                    old_link = mylinks.new(mixerIn[0], old_link.outputs[0])
                
            return {"FINISHED"}
        
# to change it from an operator to a dialog box:
    def invoke(self, context, event):
        return context.window_manager.invoke_props_dialog(self) 
           
    

class RESTOREMATERIAL_OT_operator(bpy.types.Operator):
    bl_idname = "object.restore_material"
    bl_label = "restore material"
    bl_description = ""
    bl_options = {"REGISTER", "UNDO"}


   
    def execute(self, context):
        for mat in bpy.data.materials:
        
            node_tree = mat.node_tree
            nodes = mat.node_tree.nodes

            #Get the node / GroupNode in its node tree (replace the name below)
            node_to_delete =  mat.node_tree.nodes['Overrider']

            #Remove the node / GroupNode
            mat.node_tree.nodes.remove( node_to_delete )
            mainShader = nodes.get("Principled BSDF") 
            material_output = nodes.get("Material Output") 


            # Update the links. The current links will get overwritten
            links = node_tree.links
            links.new(mainShader.outputs[0], material_output.inputs[0])  
            
            
            
  
       
        return {"FINISHED"} 
$\endgroup$
1
  • $\begingroup$ Hi, so i have to remove that line of code?Sorry for the indentation, i copied my code from my phone. $\endgroup$
    – K VDAM
    Jan 26, 2022 at 8:21

1 Answer 1

1
$\begingroup$

Instead of running through all materials in your blend, filter the materials from the desired objects by using Object.material_slots and add the node group to these materials only: https://docs.blender.org/api/current/bpy.types.Object.html#bpy.types.Object.material_slots

import bpy

C = bpy.context

# Filter the materials from all objects in selection
mats_filter = set(slot.material for o in C.selected_objects for slot in o.material_slots)

# Loop through all materials of objects in selection
for material in mats_filter:
    custom_group = bpy.data.node_groups.get("NodeGroup")
    # Add the node group to each material
    if custom_group:
        new_node = material.node_tree.nodes.new(type='ShaderNodeGroup')
        new_node.node_tree = custom_group

How to iterate over material index using Python

How do I iterate over all selected objects and change a property on their materials?

$\endgroup$
3
  • $\begingroup$ Thank you for this info. I understand what you mean, but i do not know where to put those lines in the code above and what lines i have to remove. I keep messing up the code. The line custom_group = bpy.data.node_groups.get("NodeGroup") is where the NodeGroup name will be replaced by Override because that is the name of the Nodegroup i want to add i suppose. I am new to all the python coding stuff. It is cool to learn and i am learning every day. $\endgroup$
    – K VDAM
    Jan 26, 2022 at 10:51
  • $\begingroup$ @KVDAM -> codepile.net/pile/EgWBmDRk replace bpy.data.materials as mentioned in my very first comment. $\endgroup$
    – pyCod3R
    Jan 26, 2022 at 11:34
  • $\begingroup$ Thank you for helping. I followed your instructions and it seems to be working. By it seems i mean that when i for example have 1 object selected or active, that object also does not get that groupnode added. If i select the plane the groupnode gets added to all the objects like it supposed to be. I tried to copy my code into here but the indentation gets messed up. $\endgroup$
    – K VDAM
    Jan 26, 2022 at 13:22

You must log in to answer this question.

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