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$
  • 1
    $\begingroup$ How is this different then this other question you asked? $\endgroup$ – David Mar 5 '17 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 '17 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 '17 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 '17 at 3:55
  • 1
    $\begingroup$ awesome! much better. Now let me see if I can't answer :) $\endgroup$ – David Mar 5 '17 at 4:05
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$
  • $\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 '17 at 12:50
  • $\begingroup$ Pose > Clear Transform > All ... will match pose mode to rest pose. (with no constraints / drivers etc) $\endgroup$ – batFINGER Mar 20 '17 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 '17 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 '17 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 '17 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
    $\begingroup$ Hello... the aim of the question is to do it using a Python script... $\endgroup$ – lemon Mar 6 '17 at 16:44
  • $\begingroup$ As @lemon mentioned, I want it to be done in python not manually $\endgroup$ – Tak Mar 6 '17 at 22:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.