1
$\begingroup$

I am trying to transfer position of 2 points into a bone, so that the bone has the same direction as the 2 points I tried it with this initial position enter image description here this is the output after running the code enter image description here

this is the code

import bpy
from mathutils import Vector, Quaternion
use_bone = bpy.data.objects['Armature'].pose.bones['Bone']
 
p1 = bpy.data.objects['Point.001'].location
p2 = bpy.data.objects['Point.002'].location

 
p_v = p2-p1
 
loc_h = Vector(use_bone.head)
loc_t = Vector(use_bone.tail)
loc_v = loc_t - loc_h
 
q = loc_v.rotation_difference(p_v)

use_bone.rotation_quaternion = use_bone.rotation_quaternion @ q

It doesnt even close to what I was expecting, anyone please help

Edit: I tried XY comments, if the bone has random head and tail, the script doesnt work.... this is the example : initial enter image description here After run the code enter image description here

I appreciate the help, just a little bit more help :)

$\endgroup$

1 Answer 1

1
$\begingroup$

Get the scene to test

enter image description here

import bpy
from mathutils import Vector

def add_empty(loc):
    bpy.ops.object.empty_add(location=loc)

def get_scene_to_test(): # clear scene and add bone
    objects = bpy.data.objects
    for obj in objects:
        objects.remove(obj)

    bpy.ops.object.armature_add(enter_editmode=True, align='WORLD', location=(1,1,1), rotation=(1,1,1))
    ob = bpy.context.object
    bone = ob.data.edit_bones[0]
    bone.head = 1,1,1
    bone.tail = 2,3,4
    bpy.ops.object.mode_set(mode='OBJECT')
    b = ob.data.bones[0]
    p0 = ob.matrix_world @ b.head_local
    p1 = ob.matrix_world @ b.tail_local
    add_empty(p0)
    add_empty(p1)

# make sure in object mode and have a active object
get_scene_to_test()

Change the head and tail position in a specific direction in world space

enter image description here

import bpy
from mathutils import Vector

def add_empty(loc):
    bpy.ops.object.empty_add(location=loc)

new_head_loc = Vector((3,3,3))
new_tail_loc = Vector((5,5,5))

add_empty(new_head_loc)
add_empty(new_tail_loc)

ob = bpy.data.objects["Armature"]
bpy.context.view_layer.objects.active = ob
bpy.ops.object.mode_set(mode='EDIT')
bone = ob.data.edit_bones[0]
mat = ob.matrix_world.inverted()
bone.head = mat @ new_head_loc
bone.tail = mat @ new_tail_loc
$\endgroup$
11
  • $\begingroup$ Great answer, can you give me an example if the head and/or tail not at the 0,0,0. it still confuses me. thanks for the help $\endgroup$ Commented Jun 1, 2022 at 11:43
  • $\begingroup$ I tested it can work if the head and/or tail not at the 0,0,0. Is your object has non-zero rotation or parent? $\endgroup$
    – X Y
    Commented Jun 1, 2022 at 12:22
  • $\begingroup$ and make sure you are running in object mode. $\endgroup$
    – X Y
    Commented Jun 1, 2022 at 12:26
  • $\begingroup$ >>> print(p1) <Vector (1.5247, -0.0280, 0.6231)> >>> print(p2) <Vector (0.5795, 0.9002, 1.6301)> >>> print(bone.head) <Vector (0.1049, 2.2131, -0.9436)> >>> print(bone.tail) <Vector (0.8820, -0.0379, 1.5107)> This is the REST position of my bone... and location of my point after running your script I get this : >>> print(p1) <Vector (1.5247, -0.0280, 0.6231)> >>> print(p2) <Vector (0.5795, 0.9002, 1.6301)> >>> print(bone.head) <Vector (0.1049, 2.2131, -0.9436)> >>> print(bone.tail) <Vector (2.9421, 2.1281, 0.9637)> it is not close to point vector. $\endgroup$ Commented Jun 1, 2022 at 12:32
  • $\begingroup$ Try the new one and see if it's the same as me. $\endgroup$
    – X Y
    Commented Jun 1, 2022 at 12:50

You must log in to answer this question.

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