2
$\begingroup$

I have an operator that needs an object in order to work, but here's the trick, it is required to use some sort of picker GUI in order to select the object first before execution() (instead of using the more traditional bpy.context.selection or active)

It is for creating a paint bucket tool or something similar

Note that blender does have such "pick before execute" behavior by default, for example you can use

def invoke(self, context, event):
    context.window_manager.fileselect_add(self)
    return {'RUNNING_MODAL'}

to select a filepath before execution, well I want to do exactly the same thing but with a bpy.props.PointerProperty(type=bpy.types.Object) instead of a filepath

unfortunately I didn't find any function similar to fileselect_add(), I was hoping for something like objectselect_add() sadfly it does not exists, does he?

so now I'm stuck as I don't have any picker method at my disposal

I suppose I need to go modal? i don't have any modal experience, is there a similar project I can take a look at?

$\endgroup$
1
3
$\begingroup$

Update method on pointer property

enter image description here

Not sure if this is a bit of an XY Problem

In as much as agree that invoking the filebrowser is a way to select the filepath before executing the operator it is generally displaying other options (often for import export) while it runs modally.

To simply select a filepath before running could achieve same with

def foo(self, context):
    bpy.ops.export_scene.foo(filepath=self.filepath)

Foo.filepath = StringProperty(subtype='FILE_PATH`, update=foo)

So similarly, can "do your thang" when the object is selected via the eyedropper.

Object selection box with eyedropper

import bpy
from bpy.props import PointerProperty

def poll(self, obj):
    return obj.type == 'MESH'

def update(self, context):
    # self is scene (or self.id_data if in prop group)
    ob = self.prop
    if ob is not None:
        print(f"Run operator or do something to {ob.name}")
        self.prop = None # reset?
    
class TEST_PT_layout_panel(bpy.types.Panel):
    bl_label = "Prop Panels"
    bl_category = "Test Panel"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "scene"

    def draw(self, context):
        scene = context.scene
        layout = self.layout
        
        col = layout.column()
        col.prop(scene, "prop")


def register():
    bpy.types.Scene.prop = PointerProperty(
            type=bpy.types.Object,
            poll=poll,
            update=update)
    bpy.utils.register_class(TEST_PT_layout_panel)


def unregister():
    bpy.utils.unregister_class(TEST_PT_layout_panel)
    
if __name__ == "__main__":
    register()

Note: have reset the pointer to none after each pick for way of example. Will prompt the "No value set warning in UI.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.