0
$\begingroup$

N Panel

I am creating a button on the 'N' panel that when you click, adds a Shrink Wrap modifier to the currently selected object. I would like the object picker below the 'Test Button' to be the Target Property for the Shrink Wrap modifier instead of the currently set 'Sphere' so I can select my target object from the dropdown. And the object picker is to be conditioned to only appear when the 'Test Button' is clicked. How do I go about it? See my current code set up below.

#######   IMPORTS
import bpy
from bpy.props import *


#######   THE USER PANEL
class MODIFIER_PT_Test_Panel(bpy.types.Panel):
    bl_label = "Test Panel"
    bl_idname = "MODIFIER_PT_Test_Panel"
    bl_space_type = "VIEW_3D"
    bl_region_type = "UI"
    bl_category = 'Test'
    bl_order = 0

    def draw(self, context):
        layout = self.layout
        
        #This is the 'Test Button' on 'Test' panel
        op = layout.operator("view3d.add_modifier_to_object",text= "Test Button")
        
        #This is the object picker property above the 'Test Button' on 'Test' panel
        self.layout.prop(context.scene, "object_selector_for_modifier", text = "")



#######   OPERATORS

#######   Focus 3D view to selected object operator
class ModifierOnOjectOperator(bpy.types.Operator):
    """Center the 3D view on a selected object"""
    bl_idname = "view3d.add_modifier_to_object"
    bl_label = "Center On Cube"

    def execute(self, context):
        if context.scene.object_selector_for_modifier is None:
            self.report({"ERROR"}, "You must select an object to center the view on")
            return {"CANCELLED"}
            
        orig_selected = bpy.context.selected_objects
            
        bpy.ops.object.select_all(action = "DESELECT")
        context.scene.object_selector_for_modifier.select_set(True)
        
#######   Add a shrink wrap modifier
        shrink_mod = context.object.modifiers.new(name="Shrinkie", type='SHRINKWRAP')
        shrink_mod.offset = 0.01
        shrink_mod.target = context.scene.objects['Sphere']
        
        bpy.ops.object.select_all(action = "DESELECT")
        for obj in orig_selected:
            obj.select_set(True)
            return {"FINISHED"}



#######   REGISTER ADDON
def register():
    bpy.utils.register_class(MODIFIER_PT_Test_Panel)
    bpy.utils.register_class(ModifierOnOjectOperator)
    bpy.types.Scene.object_selector_for_modifier = bpy.props.PointerProperty(
        type = bpy.types.Object,
        name = "Shrink Wrap Target",
    )


#######   UNREGISTER ADDON
def unregister():
    bpy.utils.unregister_class(MODIFIER_PT_Test_Panel)
    bpy.utils.unregister_class(ModifierOnOjectOperator)
    bpy.types.Scene.object_selector_for_modifier = bpy.props.PointerProperty(
        type = bpy.types.Object,
        name = "Shrink Wrap Target",
    )
```
$\endgroup$

1 Answer 1

1
$\begingroup$

You can save the user a click by allowing them to select the target object and then add the modifier. Also have a look into: Limit "prop_search" to Specific Types of Objects

import bpy

class OBJECT_OT_SimpleOperator(bpy.types.Operator):
    """Tooltip"""
    bl_idname = "object.simple_operator"
    bl_label = "Simple Object Operator"

    @classmethod
    def poll(cls, context):
        return context.scene.shrink_target != context.active_object

    def execute(self, context):
        obj = context.object
        
        shrink_mod = None
        for m in obj.modifiers:
            if m.type == 'SHRINKWRAP':
                shrink_mod = m
        if shrink_mod is None:
            shrink_mod = obj.modifiers.new(name="Shrinkie", type='SHRINKWRAP')
        
        shrink_mod.offset = 0.01
        shrink_mod.target = context.scene.shrink_target
        return {'FINISHED'}
    

class OBJECT_PT_HelloWorldPanel(bpy.types.Panel):
    bl_label = "My Panel"
    bl_idname = "OBJECT_PT_HelloWorldPanel"
    bl_space_type = "VIEW_3D"   
    bl_region_type = "UI"
    bl_category = "Tools"
    bl_context = "objectmode"

    def draw(self, context):
        layout = self.layout
        scene = context.scene
        obj = context.object
        
        col = layout.column()
        col.alert = False if scene.shrink_target else True
        col.prop(scene, "shrink_target")
        col = layout.column()
        col.operator(OBJECT_OT_SimpleOperator.bl_idname)
        

def target_poll(self, object):
    return object.type == 'MESH'

def register():
    bpy.utils.register_class(OBJECT_PT_HelloWorldPanel)
    bpy.utils.register_class(OBJECT_OT_SimpleOperator)
    bpy.types.Scene.shrink_target = bpy.props.PointerProperty(
        name="Target",
        type=bpy.types.Object,
        poll=target_poll
    )

def unregister():
    bpy.utils.unregister_class(OBJECT_PT_HelloWorldPanel)
    bpy.utils.unregister_class(OBJECT_OT_SimpleOperator)
    del bpy.types.Scene.shrink_target


if __name__ == "__main__":
    register()
$\endgroup$

You must log in to answer this question.

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