python-3.xblenderbpy

Append Existing Custom Node Group in Blender


I tried to append my blend file and import the node group in my new environment. I tried different methods on how to append my own custom node group in my environment, and still not working. Here's my boilerplate.

class SHADER(Operator):
bl_idname = "material.append_shader_nodes"
bl_label = "Add Shader"
bl_options = {'REGISTER', 'UNDO'}


def execute(self,context):
    # Importing the blend file (working)
    import_from_library('shader');
    
    bpy.ops.object.material_slot_add()
    
    # Creates new Material
    npr_material = bpy.data.materials.new(name='SHADER')
    npr_material.use_nodes = True

    # Remove the default shader
    npr_material.node_tree.nodes.remove(npr_material.node_tree.nodes.get('Principled BSDF'))
    material_output = npr_material.node_tree.nodes.get('Material Output')

    # Problem
    SHADER = bpy.data.node_groups['NPREEVEE'] # Import my custom node group from my different blend file

    # link shader to material
    npr_material.node_tree.links.new(material_output.inputs[0], SHADER.outputs[0])

    # set activer material to your new material
    bpy.context.object.active_material = npr_material
    return {'FINISHED'}

It seems like it didn't import my node group, but when I tried to manually add my custom node group, it displayed on my materials properties. I'm not totally familiar with this package. Is this is a bug or there is something that I missed while creating my node group?


Solution

  • I finally figured out how to import a file from another blend file. Using the os library, you can import your selected blend file and make parameters for it, and then you can import your custom node group by using bpy.data.libraries.load.

    Here is my example:

    # Importing necessary libraries
    import bpy
    import os
    
    # Operator class for importing custom nodes
    class AppendCustomNode(Operator):
        bl_idname = "append_cutom_nodes.op"
        bl_label = "IMPORT YOUR CUSTOM NODE"
        bl_options = {'REGISTER'}
    
        def __init__(self):
            # Define the path to the blend file containing the custom node
            self.source_file = os.path.join(os.path.dirname(__file__), "..", "FOLDER_NAME", "BLENDER_FILENAME.blend")
    
        def import_file(self):
            # Check if the file exists
            if not os.path.isfile(self.source_file):
                self.report({'ERROR'}, "File not found: {}".format(self.source_file))
                return {'CANCELLED'}
            return {'FINISHED'}
    
        def import_node_group(self, node_group_name):
            # Load the custom node group from the blend file
            with bpy.data.libraries.load(self.source_file, link=False) as (data_from, data_to):
                if node_group_name in data_from.node_groups:
                    data_to.node_groups = [node_group_name]
    
            # Check if the node group was successfully loaded
            if not data_to.node_groups or not data_to.node_groups[0]:
                self.report({'ERROR'}, "Failed to load the node group: {}".format(node_group_name))
                return {'CANCELLED'}
    
            # Report successful import
            self.report({'INFO'}, "Successfully appended node group: {}".format(node_group_name))
            return {'FINISHED'}
    
        def execute(self, context):
            # Import the blend file
            if self.import_file() == {'CANCELLED'}:
                return {'CANCELLED'}
    
            # Import the custom node group
            self.import_node_group("YOUR_CUSTOM_NODE")
            return {'FINISHED'}