2
$\begingroup$

I have an armature which has its origin at 0,0,0. I want to move the armature so that the lowest zvalue of it's bounding box is placed at 0,0,0 using python as shown below without changing the origin, as I want the origin to stay at 0,0,0.

This is my armature with origin at 0,0,0

enter image description here

Result I want:

enter image description here

$\endgroup$
6
  • 1
    $\begingroup$ How is this different then this other question you asked? $\endgroup$
    – David
    Mar 5, 2017 at 3:50
  • 1
    $\begingroup$ @David because here I want to do it for both mesh and armature, the other way only works with meshes. $\endgroup$
    – Tak
    Mar 5, 2017 at 3:52
  • $\begingroup$ I think it is very much the same, but please clarify you are looking for something for an armature. $\endgroup$
    – David
    Mar 5, 2017 at 3:54
  • 1
    $\begingroup$ @David it's not the same, if you look at the answer there it uses the mesh vertices to get the lowest Z location, while with an armature it won't work. Sure, I'll update it $\endgroup$
    – Tak
    Mar 5, 2017 at 3:55
  • 1
    $\begingroup$ awesome! much better. Now let me see if I can't answer :) $\endgroup$
    – David
    Mar 5, 2017 at 4:05

2 Answers 2

2
$\begingroup$

This is probably more akin to "moving the object origin without changing the location". The object's origin is the location of (0, 0, 0) in local coordinates.

Basically, find the minimum z location (minz) of all bones' heads and tails, then translate all such that the lowest local z is now 0.

With operators, select all bones, translate.

import bpy

context = bpy.context
arm_obj = context.object
arm = arm_obj.data
bpy.ops.object.mode_set(mode='EDIT')
# get min z 
minz = min(min(b.tail.z, b.head.z) for b in arm.edit_bones)

bpy.ops.armature.select_all(action='SELECT')
bpy.ops.transform.translate(
                       value=(0, 0, -minz),
                       constraint_orientation='LOCAL')

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

Without operators (except edit toggle), create a translation matrix (T = Matrix.Translation((0, 0, -minz))) and use it to translate the matrix of each bone.

import bpy
from mathutils import Matrix

context = bpy.context
arm_obj = context.object
arm = arm_obj.data
bpy.ops.object.mode_set(mode='EDIT')
# get min z 
minz = min(min(b.tail.z, b.head.z) for b in arm.edit_bones)
# calculte the translation matrix
T = Matrix.Translation((0, 0, -minz))
# translate all bones.
for b in arm.edit_bones:
    b.matrix = T * b.matrix

bpy.ops.object.mode_set(mode='OBJECT')
$\endgroup$
5
  • $\begingroup$ what if my armature rest position was like the second photo but it's pose position was like the first photo? I want the pose position of the first frame of my armature to map the rest pose. Any thoughts? $\endgroup$
    – Tak
    Mar 20, 2017 at 12:50
  • $\begingroup$ Pose > Clear Transform > All ... will match pose mode to rest pose. (with no constraints / drivers etc) $\endgroup$
    – batFINGER
    Mar 20, 2017 at 12:57
  • $\begingroup$ But this will remove the animation, right? I want to shift the armature pose position to be the same as rest position in rest pose, and apply this shift to the pose position of the rest of the animation. I'm not sure if you got what I mean? so imagine in my question the rest position was the 2nd photo and the first frame in the pose position is the 1st photo and in all frames 2->end had the same displacement, any idea how to apply this displacement in the rest of the frames? like if I used Pose > Clear Transform > All in all the frames this will remove the animation from all the frames, right? $\endgroup$
    – Tak
    Mar 20, 2017 at 13:13
  • $\begingroup$ What I'm trying to say is that pose mode with no animation (or all zeros for loc, rot, and unit scale) is rest pose. $\endgroup$
    – batFINGER
    Mar 20, 2017 at 13:38
  • $\begingroup$ yes, I know, but is there a way to apply the displacement difference (between the first frame pose position and rest position) to all frames without clearing transforms? So have you used makewalk before? I'm using it to load an animation from a bvh file to my armature which is in rest pose having the feet on the ground. Once I load the animation the pose position is shifted from the rest pose, I don't know why? $\endgroup$
    – Tak
    Mar 20, 2017 at 13:40
0
$\begingroup$

It's very easy. If you go to edit mode you can move the armature without moving the origin. When you enter the edit mode press the "a" key to select everything (if everything is not selected press it again) then press the "g" key and the "z" key to move it precisely along the z axis. When you're done go to object mode and it's done

$\endgroup$
2
  • 2
    $\begingroup$ Hello... the aim of the question is to do it using a Python script... $\endgroup$
    – lemon
    Mar 6, 2017 at 16:44
  • $\begingroup$ As @lemon mentioned, I want it to be done in python not manually $\endgroup$
    – Tak
    Mar 6, 2017 at 22:43

You must log in to answer this question.

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