# Bone Collections
![](https://hackmd.io/_uploads/HyLXJmt2n.png)
Branch: https://projects.blender.org/dr.sybren/blender/src/branch/anim/armature-collections
## Properties
# Armatures
![](https://hackmd.io/_uploads/HyN9yVt22.png)
- Armatures have one or more bone collection.
- Top-level 'default' collection cannot be removed.
- It contains those bones that do not have any other collection assigned.
- Every bone is in one or more bone collections.
- Bone collections **cannot be nested**. At least not for 4.0, can be added later.
- Bone collections must have a **unique name** within the armature.
- Library Overrides:
- New bone collections can be added.
- Existing ones cannot be reordered / removed.
- Bone collections have the following properties:
- Name
- Selectable: 'set' wins over 'cleared'
- Visible: 'set' wins over 'cleared'
- Color palette: last collection wins.
- For 4.0: just a linear list anyway.
- Later, when nested: could be a breath-first or depth-first linearisation.
- *Is Selection Set* toggle?
- `IDProperties` (aka Custom Properties) for use by add-ons.
## Operations
These operations can be performed on/with bone collections:
- (De)select one or more collections themselves
- (De)select all bones in active collection
- (De)select all bones in collections containing the currently selected bones
- Create a new collection
- Delete a collection. Bones in the collection that are now 'orphaned' are assigned to the 'default' collection.
- Move collection up/down in the list.
## Conversion from Old to New [Before & after list / for beginners]
- Layers converted to `Layer {NUM}` collections.
- Bone groups converted to `{name}` collections.
- Selection Sets converted to `SelSet {name}` collections.
- Maybe even automatically merge these when they contain the same bones?
## Uses of the Current System
> [need a screenshot or a list of new blender edition]
### Bone Layers
- Visibility
- Logical grouping
### Bone Groups
- Coloring of logical groups
- Set by rigger
### Selection Sets
- (De)selecting logical groups of bones
- Base list of selection sets can be created by rigger
- Auxilliary selection sets can be added on a per-shot basis
- Simple to transfer selection sets between files
:::info
Conclusion: not part of this proposal for 4.0
:::
### Edit Mode vs. Pose Mode
This describes Blender's **current** behavior:
| Property / Action | Edit | Pose |
|---------------------------------------|------|------|
| Name Bone | ✅ | ✅ |
| Set Bone Layers | ✅ | ✅ |
| See Bone in Group Color | ❌ | ✅ |
| Create / Assign Bone Group | ❌ | ✅ |
| Select Bones in Group | ❌ | ✅ |
| Set Bone Group Color | ✅ | ✅ |
| Set Armature Viewport Display options | ✅ | ✅ |
| Set Bone Viewport Display options | ❌ ¹⁾ | ✅ |
| Create / Assign Selection Set | ❌ | ✅ |
| Select Bones in Selection Set | ❌ | ✅ |
¹⁾ Bones can only be hidden, which is separated between edit mode & pose mode.
## Future Work
These are ideas for future improvements / extensions:
- Nestable bone collections
- Per-collection option whether bones are deforming or not (rather than setting that per bone)
- Per-collection viewport display mode (octo, line, bbone, etc)
## New Blender Module for code
New code goes into `source/blender/animrig`.
### Speedups
These are some ideas to keep things fast.
- Linearise the list of bone collections (for now that's trivial, but for nested ones it might take a bit more effort), then use a bitmask to indicate which bone is in which collection.
- Per-bone cache of their color, selectability, etc. Might hint towards a common struct for these options, where a copy on the collection is the 'ground truth' and the copy on the bone is the evaluated result of the priority rules on its collections.
### `Armature::layer`
- [x] Direct access converted to C API
- [ ] ...
### `Armature::layer_protected`
Used by `rna_PoseChannel_proxy_editable` to prevent editing pose channels on protected layers. BUT, that function is `#if 0`-ed out.
- [ ] Remove the code
- [ ] ...
### RNA/Python API
- `Armature.layers`, `Armature.layers_protected` : getter & setter to transform bitmask to `int[32]` array. Needs to be removed and replaced with collections-based API.