From c3a368b900db1c1f04f5f2c2721d0ad92b17fe1d Mon Sep 17 00:00:00 2001 From: 20kdc Date: Sun, 23 Nov 2025 21:39:38 +0000 Subject: [PATCH 1/2] Fix 'Apply Selected Modifier' operator issues with improper sequencing. --- __init__.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/__init__.py b/__init__.py index 86785bf..d163f6b 100644 --- a/__init__.py +++ b/__init__.py @@ -248,25 +248,26 @@ def poll(cls, context): return obj and obj.type == 'MESH' def execute(self, context): - obj = context.window.view_layer.objects.active - + obj = context.object + if self.modifier_names and len(self.modifier_names) > 0: bpy.ops.object.select_all(action='DESELECT') str_targets = [] - for i in range(len(self.modifier_names)): + usable_slots = min(len(self.modifier_names), 32) + for i in range(usable_slots): if self.flags[i] and obj.modifiers[self.modifier_names[i]]: str_targets.append(self.modifier_names[i]) apply_modifier(target_object=obj, target_modifiers=str_targets) obj.select_set(True) - else: - self.modifier_names = tuple(i.name for i in obj.modifiers) - self.flags = tuple(False for i in range(32)) return {'FINISHED'} def invoke(self, context, event): wm = context.window_manager + obj = context.object + self.modifier_names = tuple(i.name for i in obj.modifiers) + self.flags = tuple(False for i in range(32)) return wm.invoke_props_dialog(self) def draw(self, context): @@ -275,7 +276,8 @@ def draw(self, context): layout = self.layout col = layout.column() - for i in range(len(self.modifier_names)): + usable_slots = min(len(self.modifier_names), 32) + for i in range(usable_slots): col.prop(self, "flags", text=self.modifier_names[i], index=i) From 3564645e328f1d554d7690a13efea0c3595d2785 Mon Sep 17 00:00:00 2001 From: 20kdc Date: Sun, 23 Nov 2025 21:54:51 +0000 Subject: [PATCH 2/2] Make apply_modifier clearer Due to some of the oddities with the operators (AMWSK_OT_apply_selected_modifier's API utility is questionable, though I would say this definitely seems to be a Blender properties limitations problem more than anything else), I've been personally using this as a de-facto API to the addon. However, obviously there are downsides to this; I'm now smoothing over some of the edges I found by accident. --- __init__.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/__init__.py b/__init__.py index d163f6b..f8654d7 100644 --- a/__init__.py +++ b/__init__.py @@ -81,11 +81,21 @@ def copy_attributes(a, b): ###################################################### def apply_modifier(target_object=None, target_modifiers=None): + """ + Applies the given list of modifiers (or all if target_modifiers is None) to the given object. + If no object is supplied, the currently active object is assumed. + This function expects Object Mode, and changes the selection and active object. + """ if target_object is None: obj_src = bpy.context.window.view_layer.objects.active else: obj_src = target_object + # Without this guard, direct invocation of apply_modifier can cause an odd situation. + # Even if the only selected object is the target, it causes a change in behaviour. + # An extra unwanted shape key, named after the object, is created. + bpy.ops.object.select_all(action='DESELECT') + if target_modifiers is None: target_modifiers = [] for x in obj_src.modifiers: