2
$\begingroup$

My operator duplicates the active object, adds a solidify modifier to it, then applies it.

When run from my panel it works EXCEPT it does not apply the modifier and I can see it still under the duped object in the Outliner (I can then manual apply it, apparently correctly).

When I run the operator directly from the Python Console it DOES apply.

I've verified that after the duplicate, the new object is active and the sole selected object.

I must being doing something wrong that only manifests in a panel context, but I'm stumped. Below is the complete test script.

# Blender 2.82a
import bpy

class TestSolidifyOp(bpy.types.Operator):
    bl_idname = "object.test_solidify"
    bl_label = "Test solidify"

    @classmethod
    def poll(cls, context):
        return context.active_object is not None

    def execute(self, context):
        orig=context.active_object

        bpy.ops.object.duplicate()
        ob = context.active_object

        if orig is ob:   # Just to show orig obj is NOT still active
             return{'CANCELLED'}

        mod = ob.modifiers.new("Solidify", 'SOLIDIFY')
        mod.thickness = -1
        bpy.ops.object.modifier_apply(modifier="Solidify")

        return {'FINISHED'}

class TestSolidifyPanel(bpy.types.Panel):
    bl_label = "Test solidify Panel"
    bl_idname = "PANEL_PT_tsolid"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "object"

    @classmethod
    def poll(cls, context):
        return (context.mode == 'OBJECT')

    def draw(self, context):
        layout = self.layout
        row = layout.row()
        row.operator("object.test_solidify")

if __name__ == "__main__":
    bpy.utils.register_class(TestSolidifyOp)
    bpy.utils.register_class(TestSolidifyPanel)
$\endgroup$

1 Answer 1

4
$\begingroup$

Override the context.

TBH can't see why this is not working, the properties panel can be fickle, for example with context.object

Suggest two changes, make an override dictionary to be sure to be sure the object known as ob is the one having its modifier applied. Secondly using mod.name to identify the modifier ensures it is the last one added, in case the object has another already.

Blender 3.2+

import bpy
from bpy import context

with context.temp_override(object=bpy.data.objects['Cube']):
    bpy.ops.object.modifier_apply(modifier="Subdivision")

Blender 2.8+

bpy.ops.object.modifier_apply({"object" : bpy.data.objects['Cube']}, modifier="Subdivision")
$\endgroup$
2
  • $\begingroup$ Solved! Thank you! I didn't even know about overriding context (even though it is well documented). $\endgroup$
    – Wingman8
    Commented Apr 16, 2021 at 19:43
  • $\begingroup$ That temp_override doesn't seem to be in usable state yet though: developer.blender.org/T100664 $\endgroup$ Commented Sep 13, 2022 at 22:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .