1
$\begingroup$

I have 10 bones inside a cylinder so the cylinder can bend, like an elephant nose or octopus leg. However, when I rotate a higher bone, eg bone 5, the children bones stretch or get longer. How do I turn this off, so bones keep the same length when higher bones are rotated?

Edit: adding screenshots: Here is a screenshot. It is a cylinder, I used extrude so it would have several sections of vertices, and it has 7 bones in it (the cylinder has the Armature as parent.) I added a cube to show the stretching, it also has the armature as parent with Automatic Weights.

After rotating bone 4, the cube is stretched, and it looks like the bones after bone 4 are stretched too.

enter image description here

What I'd like to do is have the rotation applied, the further down children bones keep their length and not stretch, and for the cube to point in the direction of rotation as it does now, but not stretch the cube.

I've uploaded my blender file, named as "bendAndScale.blend". I'm sure it's some constraint, I tried to add one but couldn't figure it out. Thanks in advance for the help.

$\endgroup$
2
  • $\begingroup$ Welcome! This sounds like you have some scaling issues on some of your objects, but to be sure, it would help us if you provided an example blend file demonstrating the problem. You can upload a blend for your question here: blend-exchange.giantcowfilms.com $\endgroup$
    – Italic_
    Jul 3, 2016 at 2:35
  • $\begingroup$ Thank you for the welcome. I've uploaded my blender file, and added a screenshot to show what is happening. $\endgroup$
    – d l
    Jul 3, 2016 at 17:46

2 Answers 2

2
$\begingroup$

The Problem

As I suspected, this is a scaling problem. The bones distort because you have non-uniform scaling on your armature object. Select your armature object (not a bone in pose mode) and look at the scale values in the transform properties. The object is scaled by 0.5 on the Z axis. With non-uniform scaling, any transformation done in a space influenced by this object's scaling will appear distorted. In an armature's case, bones in pose mode will be distorted by the object's scale. Likewise with other objects, if you have a cube parented to an empty, the empty's scaling will affect the cube's transforms. This is all because transform "space" is inherited from parent objects. A good explanation is in Nathan Vegdahl's Humane Rigging course.

The Solution

You need to apply the scale transformation on the armature object. With the armature object selected, press Ctrl+A and choose Scale. The appearance of the bones will change (some axes look like they scale), but the overall function should remain the same. For the sake of cleanliness, I would apply rotation as well. Before applying any transforms, it would be a good idea to unbind and unparent any objects influenced by the armature. This will keep them from being influenced by the transform application and keep their position in 3D space.

For the future, it is best to always leave your armature scaling and rotation unchanged, for this exact reason. To change the size of the bones, it's best to edit the armature in edit mode, or if you're doing animation, scale the bones in pose mode instead.

Non-uniform scaling

Apply scale

$\endgroup$
1
  • $\begingroup$ Thank you -- worked perfectly to solve the problem, and the detailed explanation and tips are very helpful !! $\endgroup$
    – d l
    Jul 4, 2016 at 1:22
1
$\begingroup$

I found a much better alternative solution:

  • go to bone edit mode.
  • select the bone ex.: boneA
  • duplicate it: boneA.001
  • change its length to a minimum but dont let it reach 0 or it will mess up! the idea is to keep it aligned with the original bone and dont interfere on selecting that.
  • reparent it to the original bone: boneA is now parent of boneA.001
  • rename boneA.001 to boneA.adj (to help on filtering)
  • go to the mesh weight mode
  • create a copy of boneA weight
  • rename the copy to boneA.adj

Now you can scale every part independently without letting it mess on rotations!
I think this probably can be scripted too like by working on the selected bone. Will do some day. If you do it, tell us!


(Old answer)

In my case, in blender 2.93.4, for each bone that was messed, I had to go on:
poseMode/BoneProperties/Relations/InheritScale
and chose between
None or Aligned or Average (the one that looks better), but None will prevent all scaling inheritance.

Modifying scaling in pose mode is good to avoid further sculpting the mesh or creating new meshes, but needs these tweaks. Not sure if it is the best option tho.

Also, I found no way to apply the change to all bones at once, so I used this:
cat >FixActiveArmatureBoneInheritScale.py

# USAGE: select the armature you want to apply the fix and run this script

import bpy

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

iDo=2

if iDo == 1: # restore default to all bones of all armatures
    for ob in bpy.data.objects:
        if ob.type == "ARMATURE" and ob.users !=0:
            for bone in ob.data.bones:
                bone.inherit_scale="FULL"
                print('BONE: name="%s" inherit_scale=%s' %(bone.name, bone.inherit_scale))

if iDo == 2: # apply inherit_scale mode to active selected armature
    armature = bpy.context.active_object
    for bone in armature.data.bones:
        bone.inherit_scale="NONE"
        print('BONE: name="%s" inherit_scale=%s' %(bone.name, bone.inherit_scale))

if iDo == 3: # read inherit_scale mode from active selected armature
    armature = bpy.context.active_object
    for bone in armature.data.bones:
        print('BONE: name="%s" inherit_scale=%s' %(bone.name, bone.inherit_scale))

$\endgroup$

You must log in to answer this question.

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