1
$\begingroup$

I want to move and resize a bone by setting the coordinates of the head of the bone and the tail of the bone explicitly.

For example, let's say that these are my coordinates of my bone head:

[181, 151, 67]

and that these are the coordinates of my bone tail:

[224, 129, 76]

I accessed my bone (actually, the armature) in code as follows:

right_upper_hand_bone = bpy.data.objects["Armature"]

Now I want to move and resize right_upper_hand_bone such that its head is located at [181, 151, 67] and its tail is located at [224, 129, 76].

I Googled around, but I haven't been able to find out how to do this.

Can anyone tell me how to do this?

EDIT: I'm looking how to reshape the bone such that I explicitly set its head and its tail. Currently, I have a structure where I have a lot of armatures and only one bone within them, but I think it shouldn't be hard to adjust my code to work with one armature with many bones etc.

$\endgroup$
2
  • $\begingroup$ Changing the position is easy, referencing it to the global coordinate system is what I don’t know about. Look for that. $\endgroup$
    – TheLabCat
    Commented Jan 13, 2023 at 14:34
  • $\begingroup$ @TheLabCat can you describe what you had in mind? $\endgroup$ Commented Jan 16, 2023 at 8:43

1 Answer 1

0
$\begingroup$

I have an armature called "Armature" containing 1 bone named "Bone". Here's a script that will reposition your bone's head and bone's tail to the positions $(181, 151, 67)$ & $(224, 129, 76)$ in global space, respectively. Just adjust head_pos & tail_pos as needed. Take note that the Origin of your armature will still remain at whatever position it was after you run the script.

import bpy
from mathutils import Vector

bpy.ops.object.mode_set(mode='EDIT')

armature = bpy.data.objects["Armature"]
bone = armature.data.edit_bones["Bone"]

head_pos = Vector((181, 151, 67))
tail_pos = Vector((224, 129, 76))

matrix_world_inv = armature.matrix_world.inverted()

bone.head = matrix_world_inv @ head_pos
bone.tail = matrix_world_inv @ tail_pos
$\endgroup$
10
  • $\begingroup$ Thank you for the script. It works for one bone. However, I tried it for multiple bones and it doesn't work. I get an error KeyError: 'bpy_prop_collection[key]: key "Bone" not found' for any other Bone i try to access, even though the names of all of my bones are Bone under different armatures. Do you know why this code doesn't work for multiple bones? $\endgroup$ Commented Jan 16, 2023 at 10:41
  • $\begingroup$ uhm. you asked for one bone. you did not specify exactly what the requirement was. so what exactly do you need? please update your question post. Like is it for alot of armatures with one bone or is it for armatures with many bones? or is it only 1 armature with many bones? please be specific. $\endgroup$
    – Harry McKenzie
    Commented Jan 16, 2023 at 12:06
  • $\begingroup$ But i think you should be knowledgable enough to figure that out. that's just a matter of simple looping, the heavy lifting of your requirement is basically there. It should be a piece of cake for you to figure out the rest :) $\endgroup$
    – Harry McKenzie
    Commented Jan 16, 2023 at 12:10
  • 1
    $\begingroup$ Thank you so much. I was able to make it work. Thank you again :) $\endgroup$ Commented Jan 16, 2023 at 13:57
  • 1
    $\begingroup$ Have done so. Thanks again! $\endgroup$ Commented Jan 16, 2023 at 14:16

You must log in to answer this question.

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