diff --git a/scripts/startup/bl_operators/__init__.py b/scripts/startup/bl_operators/__init__.py index 90f07a0e172..a9331415626 100644 --- a/scripts/startup/bl_operators/__init__.py +++ b/scripts/startup/bl_operators/__init__.py @@ -21,6 +21,7 @@ _modules = [ "constraint", "file", "geometry_nodes", + "grease_pencil", "image", "image_as_planes", "mesh", diff --git a/scripts/startup/bl_operators/grease_pencil.py b/scripts/startup/bl_operators/grease_pencil.py new file mode 100644 index 00000000000..2d952524a2e --- /dev/null +++ b/scripts/startup/bl_operators/grease_pencil.py @@ -0,0 +1,58 @@ +# SPDX-FileCopyrightText: 2025 Blender Authors +# +# SPDX-License-Identifier: GPL-2.0-or-later + +import bpy +from bpy.types import Operator +from bpy.props import ( + EnumProperty, +) + + +class GREASE_PENCIL_OT_relative_layer_mask_add(Operator): + """Mask active layer with layer above or below""" + + bl_idname = "grease_pencil.relative_layer_mask_add" + bl_label = "Mask with Layer Above/Below" + bl_options = {'REGISTER', 'UNDO'} + + mode: EnumProperty( + name="Mode", + items=( + ('ABOVE', "Above", ""), + ('BELOW', "Below", "") + ), + description="Which relative layer (above or below) to use as a mask", + default='ABOVE', + ) + + @classmethod + def poll(cls, context): + obj = context.active_object + return obj is not None and obj.is_editable and obj.data.layers.active is not None + + def execute(self, context): + obj = context.active_object + active_layer = obj.data.layers.active + + if self.mode == 'ABOVE': + masking_layer = active_layer.next_node + elif self.mode == 'BELOW': + masking_layer = active_layer.prev_node + + if masking_layer is None or type(masking_layer) != bpy.types.GreasePencilLayer: + self.report({'ERROR'}, "No layer found") + return {'CANCELLED'} + + if masking_layer.name in active_layer.mask_layers: + self.report({'ERROR'}, "Layer is already added as a mask") + return {'CANCELLED'} + + bpy.ops.grease_pencil.layer_mask_add(name=masking_layer.name) + active_layer.use_masks = True + return {'FINISHED'} + + +classes = ( + GREASE_PENCIL_OT_relative_layer_mask_add, +) diff --git a/scripts/startup/bl_ui/properties_data_grease_pencil.py b/scripts/startup/bl_ui/properties_data_grease_pencil.py index 55a95d57311..965ab63fdcd 100644 --- a/scripts/startup/bl_ui/properties_data_grease_pencil.py +++ b/scripts/startup/bl_ui/properties_data_grease_pencil.py @@ -227,6 +227,10 @@ class GREASE_PENCIL_MT_grease_pencil_add_layer_extra(Menu): layout.operator("grease_pencil.layer_merge", text="Merge Group").mode = 'GROUP' layout.operator("grease_pencil.layer_merge", text="Merge All").mode = 'ALL' + layout.separator() + layout.operator("grease_pencil.relative_layer_mask_add", text="Mask with Layer Above").mode = 'ABOVE' + layout.operator("grease_pencil.relative_layer_mask_add", text="Mask with Layer Below").mode = 'BELOW' + layout.separator() layout.operator("grease_pencil.layer_duplicate_object", text="Copy Layer to Selected").only_active = True layout.operator("grease_pencil.layer_duplicate_object", text="Copy All Layers to Selected").only_active = False