6
$\begingroup$

I'm trying to use the function bpy.ops.pose.constraint_add() on bones through a script, but stupid thing is that I can't find how to set the bones as active ones which is needed to call this function.

$\endgroup$
1
  • $\begingroup$ My bad, I forgot to mention that this is under Blender 2.8 $\endgroup$
    – Branck
    Commented Mar 13, 2019 at 23:32

2 Answers 2

7
$\begingroup$

Set bpy.types.ArmatureBones.active

It's a matter of setting the active bone of the armature (the data part), and hence the active pose bone.

Python console code. An armature object is active and in pose mode. Long windedly sets the active bone.

>>> C.object
bpy.data.objects['Armature']

>>> C.object.data
bpy.data.armatures['Armature']

>>> C.object.data.bones["Bone"]
bpy.data.armatures['Armature'].bones["Bone"]

>>> C.object.pose.bones["Bone"]
bpy.data.objects['Armature'].pose.bones["Bone"]

>>> C.object.pose.bones["Bone"].bone
bpy.data.objects['Armature'].pose.bones["Bone"].bone

>>> C.object.data.bones["Bone"] == C.object.pose.bones['Bone'].bone
True

>>> bone = C.object.pose.bones["Bone"].bone
>>> C.active_pose_bone
bpy.data.objects['Armature'].pose.bones["Bone.001"]

>>> C.object.data.bones.active
bpy.data.armatures['Armature'].bones["Bone.001"]

>>> C.object.data.bones.active = bone
>>> C.object.data.bones.active
bpy.data.armatures['Armature'].bones["Bone"]

>>> C.active_pose_bone
bpy.data.objects['Armature'].pose.bones["Bone"]

Use bone.select = True to have bone both active and selected.

Note There is no need for the operator.

Example adds a copy rotation constraint to each selected pose bone. The cube is used as the constraint target. Run script in pose mode, else context.selected_pose_bones will be None

import bpy

context = bpy.context
scene = context.scene
cube = context.scene.objects.get("Cube")

if cube and context.object.mode == 'POSE':
    for pb in context.selected_pose_bones_from_active_object:
        # use if already existes, else create
        cr = (pb.constraints.get("CubeRot")
                or pb.constraints.new(type='COPY_ROTATION'))
        # set some properties
        cr.name = "CubeRot"
        cr.target_space = 'LOCAL'
        cr.target = cube
$\endgroup$
2
  • $\begingroup$ Thanks, that was quite simple after all. The API seems so different in 2.8 that i'm quite lost with it. Thanks again $\endgroup$
    – Branck
    Commented Mar 16, 2019 at 23:02
  • $\begingroup$ Isn't "Use bone.select=True to have bone both active and selected." wrong? I believe "object.data.bones.active=bone" is correct. $\endgroup$
    – tetii
    Commented Jul 25, 2023 at 2:42
2
$\begingroup$

i want to add a little snippet for clarity. Thanks to batFinger for the detail. It was quite tough to find out.


import bpy
#The desired Bone
boneToSelect = bpy.data.objects['Rigify'].pose.bones['spine'].bone
#Set as active 
bpy.context.object.data.bones.active = boneToSelect
#Select in viewport
boneToSelect.select = True

$\endgroup$
2
  • $\begingroup$ I am wondering how you have the armature object be the armature currently in pose mode for and not an armature that has to be named 'Rigify'. $\endgroup$ Commented Aug 8, 2023 at 3:32
  • $\begingroup$ I figured it out. boneToSelect = bpy.context.active_object.data.bones['spine'] $\endgroup$ Commented Aug 8, 2023 at 4:00

You must log in to answer this question.

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