Skip to content

Instantly share code, notes, and snippets.

@SuperFLEB
Last active March 28, 2024 22:32
Show Gist options
  • Save SuperFLEB/d106ceb376cad518f0b9d86e32cb9e8e to your computer and use it in GitHub Desktop.
Save SuperFLEB/d106ceb376cad518f0b9d86e32cb9e8e to your computer and use it in GitHub Desktop.
Blender Python Memory Jobs

Blender Python Memory Jogs

This is a list of things that I'm always forgetting how to do, especially things I tend to have trouble looking up, for some reason or another.

Display the reason an operator poll failed

Use the cls.poll_message_set(...) function:

    @classmethod
    def poll(cls, context) -> bool:
        if len(bpy.context.selected_objects) == 0:
            cls.poll_message_set("No objects selected")
            return False
        return True

Display an error or informational blurb from an operator

Use self.report(...):

    def execute(self, context):
        # ...
        if is_okay:
            self.report({'INFO'}, "Something good happened.")
        elif is_iffy:
            self.report({'WARNING'}, "Watch your back. Shit's sketchy.")
        else:
            self.report({'ERROR'}, "It's all fucked.")

        return {'FINISHED'}

How to transfer data from an n-panel draw method to an operator

There are two ways to transmit data (i.e., send "params") to an operator from a layout, using operator properties and using context overrides. Operator properties are most useful when transmitting data that matches a bpy.props type, e.g. simple strings, numbers, vectors, enums, etc. Context overrides are more useful when referencing something like an object.

Operator Property

In the operator, add the relevant property:

class MYADDON_OT_DoThing(Operator):
    """Do a thing"""
    bl_idname = "plaidiator.move_stripe_down"
    bl_label = "Do The Thing"
    bl_options = {'REGISTER', 'UNDO'}

    # This is the property that will be set on the operator instance
    thing_index: IntProperty()

    def execute(self, context) -> set[str]:
        print(f"Do the thing to index {thing_index}")
        return {'FINISHED'}

...and set it on the "operator" object in the panel draw function:

        # ...(within "draw" function)...
        dt_operator = layout.operator(MYADDON_OT_DoThing.bl_idname, text="Do the thing")
        dt_operator.thing_index = 123
        # ...

Context Override

Context overrides are done in the draw method of the panel, and apply to an entire layout.

    # (within panel class)
    def draw(self, context: bpy_struct) -> None:
        layout = self.layout

        # For example, we want to pass the active node in the node editor:
        node = context.active_node

        context_sub_layout = layout.column
        context_sub_layout.context_pointer_set(name="target_node", data=node)

The pointer then ends up in the context of the operator:

class MYADDON_OT_DoThing(Operator):
    """Do a thing"""
    bl_idname = "plaidiator.move_stripe_down"
    bl_label = "Do The Thing"
    bl_options = {'REGISTER', 'UNDO'}

    def execute(self, context) -> set[str]:
        node = context.target_node
        print(f"Do the thing to node {node.name}")
        return {'FINISHED'}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment