Skip to content

Bone Collections & Colors: Upgrading to 4.0

This page documents the upgrade path, from Blender 3.6 to 4.0, for Python code that was working with armature layers and bone collections.

Armature Layers

  • Blender 4.0 will convert armature layers to bone collections.
  • The name of the collection will be Layer N, where N is 1…32.
  • If the armature had layer names set via the [Bone Manager add-on](https://fin.gumroad.com/l/STdb), these names will be appended: Layer N - Name. That add-on stores the desired names in custom properties on the armature named layer_name_M, with M ranging 0…31.
  • Each layer that contains one or more bones will be converted. Empty layers are skipped.

Changing Visibility

Blender 3.6 and older:

arm.layers = [True, False, True] + 29 * [False]
arm.layers[0] = False

Blender 4.0:

for bcoll in arm.collections:
    bcoll.is_visible = True

arm.collections['IK Controls'].is_visible = False
arm.collections[0].is_visible = False

Assigning & Unassigning Bones

Blender 3.6 and older:

arm.bones['arm_lower_R'].layers = [True, False, True] + 29 * [False]
arm.bones['arm_lower_R'].layers[1] = True

Blender 4.0:

arm.collections['IK Controls'].assign(arm.bones['arm_lower_R'])
arm.collections['IK Controls'].unassign(arm.bones['arm_lower_R'])
arm.collections[2].assign(arm.bones['arm_lower_R'])
arm.collections[2].unassign(arm.bones['arm_lower_R'])

Assigning bone to collections of another Bone:

Blender 3.6 and older:

arm.bones['arm_lower_R'].layers = arm.bones['other_bone'].layers

Blender 4.0 (until there is a bone.collections.set(other_collections) function):

bone = arm.bones['arm_lower_R']
bone.collections.clear()
for bcoll in arm.bones['other_bone'].collections:
    bcoll.assign(bone)

Bones in a Layer / Collection

Blender 3.6 and older:

in_layer_3 = [bone for bone in arm.bones
              if bone.layers[3]]

Blender 4.0:

# Any mode but armature edit mode:
in_collection = arm.collections['IK Controls'].bones

# Armature edit mode:
in_collection = [ebone for ebone in arm.edit_bones
                 if 'IK Controls' in ebone.collections]

Custom Properties on Collections

Blender 3.6 and older had to store data on the Armature itself:

arm["custom_layer_data"] = {
    0: 'some data for layer 0',
    1: 'other data for layer 1',
}

Blender 4.0 has custom properties on bone collections:

arm.collections['IK Controls']['custom'] = 'some custom data'
arm.collections[3]['whatever'] = 'you need'

Bone Groups to Bone Collections

  • Blender 4.0 will convert bone groups to bone collections.
  • The name of the collection will be the same as that of the bone group.
  • Bone Groups are converted *after* Armature Layers. This means that if you had a bone group named Layer 1, and armature layer 1 also was converted into a bone collection, the collection for the bone group will be named Layer 1.001.
  • The collections for bone groups are initially hidden. This is to ensure the same behavior as Blender 3.6 and older, where the layers determined visibility and the groups did not (see above for the visibility rules of bone collections).
  • As bone groups were stored on the Object's pose data, and not on the Armature itself, this only happens when the Object is available. Linking the Armature from a 3.6 file (in contrast to linking the armature Object) will *not* do this conversion, as the data simply is not available.
  • All bone groups are converted, so also when they did not contain any bones.

Bone Color

Blender 3.6 used Bone Groups to color bones. Bone Groups were stored on the object's pose data, and not the armature itself, which had certain implications:

  • Bone color was not available in armature edit mode.
  • Bone color could not be shared between all users of an armature, but had to be set up and maintained per obj.
  • Bone color could be set on a per-object basis, even when they shared the armature. This is useful, for example, to ensure good contrast between bones and each character's colors.

Blender 4.0 stores the bone color directly on the armature bone. The pose bone can override this color. This makes it possible to retain the per-object unique color described above.

Python code

Blender 3.6 and older. Assumption: the bone is already assigned to the bone group.

# Set theme color:
obj.pose.bone_groups['IK Bones'].color_set = 'THEME09'

# Set custom color:
group = obj.pose.bone_groups['IK Bones']
group.color_set = 'CUSTOM'
group.colors.active = (0.95, 1.0, 0.0)

# Disable display of bone colors on the armature:
arm.show_group_colors = False

Blender 4.0:

# On the armature bone:
bone = arm.bones['arm_lower_R']
# Alternatively, set on the pose bone:
bone = obj.pose.bones['arm_lower_R']

# Set theme color:
bone.color.palette = 'THEME09'

# Set custom color:
bone.color.palette = 'CUSTOM'
bone.color.custom.active = (0.95, 1.0, 0.0)

# Disable display of bone colors on the armature:
arm.show_bone_colors = False