Page MenuHome

Fix T70269: ChildOf 'Set Inverse' not working when targeting vertex group
AbandonedPublic

Authored by Sybren A. Stüvel (sybren) on Dec 19 2019, 4:08 PM.

Details

Summary

This fixes T70269: ChildOf constraint 'Set Inverse' not working when targeting vertex group.

The old code relied on some DAG_id_tag_update(&ob->id, OB_RECALC_OB) call in UI code that was removed in rB4c2b79a1d5a63. Having constraint functionality rely on UI code seemed like a bad idea, so I reimplemented the 'Set Inverse' functionality.

The old code used BKE_object_workob_calc_parent() to do the heavy lifting. However, that function uses a 'cleaned copy' of the object, so it only has its matrix, a parent pointer, and the list of constraints. This would fail to take the target vertex group into account, as that cleaned copy did not have any mesh data whatsoever.

This new implementation uses depsgraph evaluation to obtain the world matrix before and after this constraint, and computes the inverse matrix from that. This could be slightly slower than before, as objects depending on the constrained object are also recalculated a few times, but I think this is a small price to pay for actually doing the correct thing.

An alternative approach could store the applied matrix as part of the constraint data, and invert that when the user presses the 'Set Inverse' button. As this would require more CPU ticks on every evaluation, rather than just on a button press, I rejected this alternative.

Diff Detail

Repository
rB Blender
Branch
temp-sybren-childof-set-inverse (branched from master)
Build Status
Buildable 6073
Build 6073: arc lint + arc unit

Event Timeline

How about getting rid of this hackery trying to pull evaluation state by modifying the constraint stack, and do the neutral state computation in the constraint itself based on a flag, similar to most others like Stretch To? Most of my D6091 patch is actually adressing that.

Also, the inverse matrix handling makes no sense when some of the checkboxes are disabled - that also needs a rewrite (with versioning).

Maybe I should re-purpose D6091 to just fixing the inverse matrix, while postponing the functional changes to further consideration?

How about getting rid of this hackery trying to pull evaluation state by modifying the constraint stack, and do the neutral state computation in the constraint itself based on a flag, similar to most others like Stretch To? Most of my D6091 patch is actually adressing that.

I think that's a good idea.

Also, the inverse matrix handling makes no sense when some of the checkboxes are disabled - that also needs a rewrite (with versioning).

Do you know of uses of the constraint where some of the checkboxes are disabled?

Maybe I should re-purpose D6091 to just fixing the inverse matrix, while postponing the functional changes to further consideration?

Sounds good.

Do you know of uses of the constraint where some of the checkboxes are disabled?

Child-Of for e.g. just rotation is useful when you want a bone to inherit rotation (and not location) from another bone without using a world-space constraint that might flip in a situation where local-space constraints don't work (usually, LOCAL_WITH_PARENT is sufficient to do this kind of thing, but if the bone to be copied from is higher in the parenting hierarchy, like a grand-parent, it won't work.) Child-of is a handy way of doing these kinds of not-flipping constraints when the alternative is to do complicated parent tricks and numerous other constraints.

Another use of Child-Of constraint is to hack around badly planned constraints- e.g. a set of constraints uses local space rotation, but the rotation (of the constraint target) should be inherited by a common parent. The rigger may not want to change the space<==>space or may not know a way of making it work with the new hierarchy. And of course, using world space for example simply won't work the same way. In this situation, maybe the rigger should have targeted the constraints to the parent in the first place, but the Child-Of provides a way to avoid creating a problem. This is even more useful with drivers, which can be a lot harder to edit efficiently (constraints being easier to find, easier to edit in the UI, and more friendly to edit with bpy,). It's really useful to have these kinds of tricks in your back pocket when a production schedule pushes you into crunch mode, and anything that works is good enough because time is running out.

The Child-Of constraint is essentially the equivalent of Maya's Parent Constraint, and I imagine riggers coming from that background make heavy use of it because it's such a common tool in their former workflow (in which local-space constraints don't exist without editing nodes and doing matrix maths, and using the parent constraint is one of the easier ways of getting similar results). I think it would be beneficial to users coming to Blender from other softwares to have an easy to use and understand child-of-constraint.