Pointer Property To Armature And Bone

I have used the pointer property to an armature like this:

    armature : bpy.props.PointerProperty(name = 'Armature', description= 'Selected Armature',
        type = bpy.types.Object,
        poll = lambda self, object: object.type == 'ARMATURE')

Now I will think to have the currently selected/active bone in another property, however this is tricky. Do you know how is done?

If you have any references or any github links drop some info. :slight_smile:

I find the PointerProperty behaves differently when used within a PropertyGroup vs when used in an operator like you are doing. Inside an operator it always seems to throw a registration error saying it doesn’t support data-blocks. Even thought the Blender documentation says:

Instead of trying to do it using a PointerProperty, you could try using a StringProperty, although you need to do one extra step of writing a draw() method (which, I believe, you are doing anyway):

import bpy

class MyArmatureOperator(bpy.types.Operator):
    bl_label = "Armature Operator"
    bl_idname = "object.armature_operator"
    bl_options = {'REGISTER', 'UNDO'}
    
    armature: bpy.props.StringProperty(
        name="Armature",
    )
    
    def execute(self, context):
        print(self.armature)
        # Do something here
        return {'FINISHED'}
    
    def draw(self, context):
        layout = self.layout
        layout.prop_search(self, "armature", bpy.data, "armatures")

bpy.utils.register_class(MyArmatureOperator)

The layout.prop_search() would do the magic for you:

And it also adds a nice indication by showing the corresponding icon of the data it expects.

1 Like

You may want to look at this example as a possible solution.

Best way for user to specify armature bones? - Coding / Python Support - Blender Artists Community

2 Likes

Oh, looks like I missed the bone part of the question.

You can search for the bones in the selected armature by conditionally rendering the bone property in the draw() method, similar to @nezumi.blend’s example:


class MyArmatureOperator(bpy.types.Operator):
    ...
    
    armature: bpy.props.StringProperty(
        name="Armature",
    )

    bone: bpy.props.StringProperty(
        name="Bone",
    )
    
    ...
    
    def draw(self, context):
        layout = self.layout
        layout.prop_search(self, "armature", bpy.data, "armatures")
        if self.armature:
            layout.prop_search(self, "bone", bpy.data.armatures[self.armature], "bones")

ezgif-2-bb5ed3daf2

This way, the Bone property will show up only after selecting an Armature.