Skip to main content
added 1008 characters in body; added 87 characters in body
Source Link
unwave
  • 4.3k
  • 1
  • 6
  • 19

When you run a script from the Text Editor you use its bpy.context. The Text Editor does not have anya node trees you have to call in the right contexttree related API.

To use the context of an editor which API you use, you can create a button in that editor to run your script. in a right context you can:

  1. Pass a context to an API function as an argument.
  2. Run an operator with your script in the editor using search menu.

Or, as it was suggested, to pass a contextenter image description here

To be able to an API function as an argumentfind the operator in the search menu Developer Extras should be enabled.

You cannot make it simpler with a context-dependent API.enter image description here

  1. Create a button in that editor to run your script.

Your code should be in thatthe def execute() function.

import bpy

class TEST_OT_poll():
    @classmethod
    def poll(cls, context):
        if context.space_data.type == 'NODE_EDITOR' and context.space_data.tree_type == 'ShaderNodeTree':
            return True
        else:
            return False

class TEST_OT_make_group(bpy.types.Operator, TEST_OT_poll):
    bl_idname = "node.test_make_group"
    bl_label = "Make Group"
    bl_description = ""
    bl_options = {'REGISTER', 'UNDO'}
    

    def execute(self, context):
        
        bpy.ops.node.group_make()
        bpy.ops.node.group_edit(exit=True)
        
        return {'FINISHED'}
  
    
class TEST_PT_panel(bpy.types.Panel):
    bl_idname = "TEST_PT_panel"
    bl_label = "Make group"
    bl_space_type = 'NODE_EDITOR'
    bl_region_type = "UI"
    bl_category = "Tool"

    @classmethod
    def poll(cls, context):
        if context.space_data.tree_type == 'ShaderNodeTree':
            return True
        else:
            return False

    def draw(self, context):
        
        layout = self.layout
        column = layout.column()
        column.operator("node.test_make_group", text = "Make Group")
    

classes = (
    TEST_PT_panel,
    TEST_OT_make_group,
)

def register():
    for c in classes:
        bpy.utils.register_class(c)

def unregister():
    for c in classes:
        bpy.utils.unregister_class(c)
        
        
if __name__ == "__main__":
    register()
  1. Change the editor in the script with changing it back at the end.

But in this case, it may not update the UI correctly, and you have to use an unrecommended force update.

import bpy

try:
    initial_area_type = bpy.context.area.type
    bpy.context.area.type = 'NODE_EDITOR'
    bpy.context.area.ui_type = 'ShaderNodeTree'
    bpy.ops.wm.redraw_timer(type='DRAW_WIN', iterations=1)
    
    bpy.ops.node.group_make()
    bpy.ops.node.group_edit(exit=True)
    
except Exception as e:
    print(e)
finally:
    bpy.context.area.type = initial_area_type

When you run a script from the Text Editor you use its bpy.context. The Text Editor does not have any node trees you have to call in the right context.

To use the context of an editor which API you use, you can create a button in that editor to run your script.

Or, as it was suggested, to pass a context to an API function as an argument.

You cannot make it simpler with a context-dependent API.

Your code should be in that def execute() function.

import bpy

class TEST_OT_poll():
    @classmethod
    def poll(cls, context):
        if context.space_data.type == 'NODE_EDITOR' and context.space_data.tree_type == 'ShaderNodeTree':
            return True
        else:
            return False

class TEST_OT_make_group(bpy.types.Operator, TEST_OT_poll):
    bl_idname = "node.test_make_group"
    bl_label = "Make Group"
    bl_description = ""
    bl_options = {'REGISTER', 'UNDO'}
    

    def execute(self, context):
        
        bpy.ops.node.group_make()
        bpy.ops.node.group_edit(exit=True)
        
        return {'FINISHED'}
  
    
class TEST_PT_panel(bpy.types.Panel):
    bl_idname = "TEST_PT_panel"
    bl_label = "Make group"
    bl_space_type = 'NODE_EDITOR'
    bl_region_type = "UI"
    bl_category = "Tool"

    @classmethod
    def poll(cls, context):
        if context.space_data.tree_type == 'ShaderNodeTree':
            return True
        else:
            return False

    def draw(self, context):
        
        layout = self.layout
        column = layout.column()
        column.operator("node.test_make_group", text = "Make Group")
    

classes = (
    TEST_PT_panel,
    TEST_OT_make_group,
)

def register():
    for c in classes:
        bpy.utils.register_class(c)

def unregister():
    for c in classes:
        bpy.utils.unregister_class(c)
        
        
if __name__ == "__main__":
    register()

When you run a script from the Text Editor you use its bpy.context. The Text Editor does not have a node tree related API.

To run your script in a right context you can:

  1. Pass a context to an API function as an argument.
  2. Run an operator with your script in the editor using search menu.

enter image description here

To be able to find the operator in the search menu Developer Extras should be enabled.

enter image description here

  1. Create a button in that editor to run your script.

Your code should be in the execute() function.

import bpy

class TEST_OT_poll():
    @classmethod
    def poll(cls, context):
        if context.space_data.type == 'NODE_EDITOR' and context.space_data.tree_type == 'ShaderNodeTree':
            return True
        else:
            return False

class TEST_OT_make_group(bpy.types.Operator, TEST_OT_poll):
    bl_idname = "node.test_make_group"
    bl_label = "Make Group"
    bl_description = ""
    bl_options = {'REGISTER', 'UNDO'}
    

    def execute(self, context):
        
        bpy.ops.node.group_make()
        bpy.ops.node.group_edit(exit=True)
        
        return {'FINISHED'}
  
    
class TEST_PT_panel(bpy.types.Panel):
    bl_idname = "TEST_PT_panel"
    bl_label = "Make group"
    bl_space_type = 'NODE_EDITOR'
    bl_region_type = "UI"
    bl_category = "Tool"

    @classmethod
    def poll(cls, context):
        if context.space_data.tree_type == 'ShaderNodeTree':
            return True
        else:
            return False

    def draw(self, context):
        
        layout = self.layout
        column = layout.column()
        column.operator("node.test_make_group", text = "Make Group")
    

classes = (
    TEST_PT_panel,
    TEST_OT_make_group,
)

def register():
    for c in classes:
        bpy.utils.register_class(c)

def unregister():
    for c in classes:
        bpy.utils.unregister_class(c)
        
        
if __name__ == "__main__":
    register()
  1. Change the editor in the script with changing it back at the end.

But in this case, it may not update the UI correctly, and you have to use an unrecommended force update.

import bpy

try:
    initial_area_type = bpy.context.area.type
    bpy.context.area.type = 'NODE_EDITOR'
    bpy.context.area.ui_type = 'ShaderNodeTree'
    bpy.ops.wm.redraw_timer(type='DRAW_WIN', iterations=1)
    
    bpy.ops.node.group_make()
    bpy.ops.node.group_edit(exit=True)
    
except Exception as e:
    print(e)
finally:
    bpy.context.area.type = initial_area_type
Source Link
unwave
  • 4.3k
  • 1
  • 6
  • 19

When you run a script from the Text Editor you use its bpy.context. The Text Editor does not have any node trees you have to call in the right context.

To use the context of an editor which API you use, you can create a button in that editor to run your script.

Or, as it was suggested, to pass a context to an API function as an argument.

You cannot make it simpler with a context-dependent API.

enter image description here

Your code should be in that def execute() function.

import bpy

class TEST_OT_poll():
    @classmethod
    def poll(cls, context):
        if context.space_data.type == 'NODE_EDITOR' and context.space_data.tree_type == 'ShaderNodeTree':
            return True
        else:
            return False

class TEST_OT_make_group(bpy.types.Operator, TEST_OT_poll):
    bl_idname = "node.test_make_group"
    bl_label = "Make Group"
    bl_description = ""
    bl_options = {'REGISTER', 'UNDO'}
    

    def execute(self, context):
        
        bpy.ops.node.group_make()
        bpy.ops.node.group_edit(exit=True)
        
        return {'FINISHED'}
  
    
class TEST_PT_panel(bpy.types.Panel):
    bl_idname = "TEST_PT_panel"
    bl_label = "Make group"
    bl_space_type = 'NODE_EDITOR'
    bl_region_type = "UI"
    bl_category = "Tool"

    @classmethod
    def poll(cls, context):
        if context.space_data.tree_type == 'ShaderNodeTree':
            return True
        else:
            return False

    def draw(self, context):
        
        layout = self.layout
        column = layout.column()
        column.operator("node.test_make_group", text = "Make Group")
    

classes = (
    TEST_PT_panel,
    TEST_OT_make_group,
)

def register():
    for c in classes:
        bpy.utils.register_class(c)

def unregister():
    for c in classes:
        bpy.utils.unregister_class(c)
        
        
if __name__ == "__main__":
    register()