Page MenuHome

Fix T76689: Armature layers not indicating the existence of bones
ClosedPublic

Authored by Sybren A. Stüvel (sybren) on May 12 2020, 6:29 PM.

Details

Summary

From what I can see, there are two issues at play in T76689: Armature layers not indicating the existence of bones and its merged-in report T76590: New undo in 2.83 causes armature to disappear from viewport and seemingly makes it permanently invisible:

  • In Blender ≤ 2.79 the bone layer dots were updated in the draw code. This ensured the info was up to date before drawing. This is no longer possible, as the drawing code uses evaluated objects, and those should not be written to. This has been addressed in rB709f126e8143 by calling the update function explicitly in various places in the code. The problem is that this wasn't added to all necessary spots.
  • When in edit mode, changes are made to the edit bones but not to the 'actual' bones (this is synced when exiting edit mode). This causes undo to mess up the layer indicators.

I think both issues can be addressed by having the dependency graph update the used layer info as part of the armature evaluation. This will make the undo system work properly, and allows the removal of some BKE_armature_refresh_layer_used() from various places.

There is still the issue that there are two functions (BKE_armature_refresh_layer_used() and ED_armature_edit_refresh_layer_used()) that are both responsible for updating bArmature::layer_used. This is a trickier thing to solve, though, as the definition of the EditBone struct resides in the armature editor module. This means that blenkernel can't iterate over edit bones, but on the other hand the dependency graph shouldn't call any editor functions either. This is why I left the ED_armature_edit_refresh_layer_used() calls untouched.

The downside of recalculating layer_used from the dependency graph (at least in the way that I did it now) is that it is called every time a user moves a bone in pose mode. This frequency of updates is not necessary.

Diff Detail

Repository
rB Blender

Event Timeline

Sybren A. Stüvel (sybren) requested review of this revision.May 12 2020, 6:29 PM
Sybren A. Stüvel (sybren) created this revision.

The downside of recalculating layer_used from the dependency graph (at least in the way that I did it now) is that it is called every time a user moves a bone in pose mode. This frequency of updates is not necessary.

Maybe it's possible to make a relation between ID_RECALC_COPY_ON_WRITE / ID_RECALC_SELECT and this refresh operation?

Basically whenever the depsgraph copies the original datablock contents to the CoW datablock, this refresh is needed. Or does this refresh need to take into account properties that can be animated or driven?

Maybe it's possible to make a relation between ID_RECALC_COPY_ON_WRITE / ID_RECALC_SELECT and this refresh operation?

Basically whenever the depsgraph copies the original datablock contents to the CoW datablock, this refresh is needed.

If I understand things well, this is already what happens. In this patch the operation is run on the evaluation of the ARMATURE_EVAL node, which is directly connected to the CoW datablock already:

Both ID_RECALC_COPY_ON_WRITE and ID_RECALC_SELECT tag the CoW datablock for update.

Or does this refresh need to take into account properties that can be animated or driven?

No, it's just computing a bitwise OR of layer bits on the individual bones. These cannot be animated.

I can make this refresh operation a separate node in the depsgraph, but I don't think it'll matter in practice. I've done some more digging, and moving a bone in pose mode will create a new CoW copy anyway for every motion of the mouse.

This revision is now accepted and ready to land.May 18 2020, 2:40 PM