0
$\begingroup$

I want to have an object field in the Adjust Last Operation panel: the object selected there would be used in several modifiers I add. However I noticed two things:

  • if I use the Eyedropper to select an object in the scene OR click the X icon, the panel closes without keeping the result
  • if I set objects from the dropdown list the first selected object is 'stuck' in there even if I select other objects

Here's a gif. First I try the eyedropper, next I chose objects from the list.

enter image description here

My code:

import bpy

class TEST_Prop(bpy.types.PropertyGroup):
    obj: bpy.props.PointerProperty(name = "Object", type = bpy.types.Object)

class TEST_OT_TestOperator(bpy.types.Operator):
    bl_idname = "test.test_operator"
    bl_label = "Test Operator with Object prop"
    bl_options = {"REGISTER", "UNDO"}

    @classmethod
    def poll(cls, context):
        return context.object
    
    # to reset the object
    def invoke(self, context, event):
        context.scene.TEST_Prop.obj = None
        return self.execute(context)

    def execute(self, context):
        ob = context.view_layer.objects.active
        shr_mod = ob.modifiers.new(name='Shrap',type='SHRINKWRAP')
        shr_mod.target = context.scene.TEST_Prop.obj or None
        return {'FINISHED'}

    def draw(self, context):
        layout = self.layout
        row = layout.row()
        row.prop(context.scene.TEST_Prop, "obj")

def register():
    bpy.utils.register_class(TEST_OT_TestOperator)
    bpy.utils.register_class(TEST_Prop)
    bpy.types.Scene.TEST_Prop = bpy.props.PointerProperty(type=TEST_Prop)

def unregister():
    bpy.utils.unregister_class(TEST_OT_TestOperator)
    bpy.utils.unregister_class(TEST_Prop)
    del bpy.types.Scene.TEST_Prop

if __name__ == "__main__":
    register()

What am I missing?

$\endgroup$

1 Answer 1

3
$\begingroup$

Operators only work with primitive properties as arguments (why you're not keeping the PointerProperty inside the operator). Not sure why it's not working, but my guess is operators aren't good at using the PointerProperty as part of its arguments. May need to check if there's an existing bug for this...

A simple workaround is to only store the prop as its name, and then use it in your operator to find the given. Blender can even keep the same type of search UI with prop_search:

import bpy

class TEST_OT_TestOperator(bpy.types.Operator):
    bl_idname = "test.test_operator"
    bl_label = "Test Operator with Object prop"
    bl_options = {"REGISTER", "UNDO"}
    
    obj_name : bpy.props.StringProperty()

    @classmethod
    def poll(cls, context):
        return context.object

    def execute(self, context):
        ob = context.view_layer.objects.active
        shr_mod = ob.modifiers.new(name='Shrap',type='SHRINKWRAP')
        if self.obj_name in context.scene.objects:
            shr_mod.target = context.scene.objects[self.obj_name]
        else:
            shr_mod.target = Nonea
        return {'FINISHED'}

    def draw(self, context):
        layout = self.layout
        layout.prop_search(self, 'obj_name', context.scene, "objects")

def register():
    bpy.utils.register_class(TEST_OT_TestOperator)

def unregister():
    bpy.utils.unregister_class(TEST_OT_TestOperator)

if __name__ == "__main__":
    register()

I double checked your use cases and it worked for me :)

$\endgroup$
3
  • 1
    $\begingroup$ Thank you for explanation and the workaround! While this works, for me personally it won't work very well because clicking on X of the prop_search still closes the Adjust Last window and, more importantly, without the eyedropper this thing won't be much help for me (too many objects in a scene). I think I'll just use the Active Object as a target if more than 1 obj are selected. And yes, I'll check if there's a report for that. $\endgroup$ Nov 18, 2021 at 6:40
  • 1
    $\begingroup$ Another solution is to display the object pointer field in a panel somewhere, select it and then execute the operator. But agreed you may as well use the active object to do it $\endgroup$
    – Gorgious
    Nov 18, 2021 at 14:07
  • $\begingroup$ Agreed, the lack of eyedropper is rough. But I agree with @Gorgious in using a panel and not rely so much on the last operation section. Blender has set it up that operators should only expose primitive prop argument - anything else doesn't work as well :/ $\endgroup$ Nov 18, 2021 at 21:56

You must log in to answer this question.

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