7
$\begingroup$

So I have a bone driving the 'scale' property of another bone, along with the value of a shape key. If move the driver bone, it works fine, but right click to cancel, the scale of the driven bone doesn't update until a frame change or movement on the bone itself, but the shape key does. Here's what I'm talking about: enter image description here

Notice how the teeth reset, but the mouth doesn't.

$\endgroup$
9
$\begingroup$

So I found out what it was. Odly enough, the driver bone has to be in a separate armature from the bone that you are driving. Annoyingly you can not use 'Whole Character' key framing properly anymore, but it works nonetheless.

Edit: Thanks to aliasguru, I found out to solve this you can:

1. Create a blender shortcut

2. Go to its properties

3. After the path in 'Target', paste in '--enable-new-depsgraph'

4. Click apply, and launch blender from there.

Done!

Edit by aliasguru: Why does this work?

The main question is: Why do 3D packages in general need something called 'Dependency Graph' at all (this is not Blender a specific thing, other apps like Maya, Alias, etc. have this as well!)? This can be re-phrased as 'how does a 3D app know what needs to be recalculated'? Each time you change something in your scene, some kind of update cycle needs to be triggered, forcing things to be updated.

Example: change the location of an object by setting the z-value. What sounds stupidly simple triggers a massive chain of possible updates: The object in question could:

  • have some dependency to a driver in the scene, forcing another property to update
  • have a constraint relationship to another object
  • be part of a group, and the instance needs to be updated too
  • could be a target for a modifier
  • could have a material node tree that reads the location
  • could be the parent of other objects
  • ...

As you can see, there is a Ton (pun intended) of possible follow-up calculations that might need to happen. If Blender was forced to manually check EVERY possible effect, you'd propably need to go for a coffee on each screen refresh in a not even complex scene. Now, if there was a way to cleverly identify what needs to be updated, and what can be skipped, that would be awesome, right? Right? That awesomeness is called Dependency Graph.

The Depsgraph keeps track of the relations of properties in the scene to each other, and of their status. However, it does NOT run an update cycle on each property change! Instead, it runs in a scheduled or event-driven way, one could say 'from time to time'. Between these schedules, Blender does nothing else than tagging each property which needs updates, as well as tagging the depending propertiers as dirty as well. It does not change or recalculate values just yet. In Depsgraph terms, this is called mark as dirty.

When the scheduled update happens, it will only ever touch properties which have been marked as dirty, completely ignoring anything related. If an update by the scheduler triggers further updates, it will only mark the prop in question as dirty again (unless the coders decided to put hacks in the code, and there might be plenty) and update in the next cycle. And here is where the current problem of Blender starts, and Sergey came in.

When Blender received its first implementation of a Depsgraph, computer power was limited. I mean, really limited. So they had to make a compromise: They could not afford to trigger depsgraph updates on every nitty little property, they had to make the system less fine-granular. What they went for is a Depsgraph that does its work on an object level. What does this mean for your example case?

Your case

Your single armature contains bones, which trigger a Shapekey change as well as properties of other bones. So let's pull that handle like in your GIF. The rig scales the mesh up somehow first. I'm guessing there is a parent-child relationship somewhere, or an Armature modifier. Then the system detects that a shape key value has to be changed too. It marks the object containing the mesh as dirty. It checks if there are connections, and if they are found, marks them as dirty. Etc. Where's the catch?

So far, there were just things marked as dirty. Nothing has been recalculated just yet. The armature OBJECT has been marked as dirty, then the Mesh OBJECT containing the shape key. The mesh clearly is dependent on the Armature. But the armature might influence your mesh twice. First the parent/child (or Armature), secondly the shape key. It's not foreseeable any more which one should come into play first, scale or shape key. With the specific case you have (and I can only guess without having the rig in hand), The depsgraph needs to update the mesh object twice to calculate the final solution. Potentially first the result of scaling the bone on the mesh, and then - in a second cycle - the repositioning of vertices due to the shape key. On a Cancel event, only one update ever seems to run, leaving the Shape key in a dirty stage. It IS marked as dirty in the depsgraph, but it will only recalculate once the scheduler is run again. That's the case for instance if you change a frame, or if two armatures influence it (each one triggers one recalculation).

So why does the new depsgraph work?

Because the granularity has been reworked to a more fine level. In case of armatures, this means update scheduling per BONE, not per Armature as present. Note that this makes the depsgraph slower, but since Sergey is a goddamn genius, so far no one measured more than 20% slowdown.

See this link for further information: https://code.blender.org/2015/03/more-dependency-graph-tricks/ and this one: https://code.blender.org/2015/02/blender-dependency-graph-branch-for-users/

Final note: Blender 2.8 afaik will only have the new Depsgraph. The current one will be deprecated. Further info on 2.8 Depsgraph: https://code.blender.org/2016/12/dependency-graph-proposal/

$\endgroup$
  • 4
    $\begingroup$ very likely this is due to the granularity of the default blender dependency graph, which works on an object level. You could try running Blender with the new depsgraph enabled from a command line. The command on windows for example would be blender.exe --enable-new-depsgraph $\endgroup$ – aliasguru Mar 18 '17 at 17:58
  • $\begingroup$ @aliasguru This is interesting. Would you mind going into more detail about what is happening when you do this? I think many people don't understand the depsgraph well. $\endgroup$ – Mentalist Mar 21 '17 at 17:57
  • 1
    $\begingroup$ @Mentalist I tried pulling some more info together out of corners of my brain, and edited the answer. However, keep in mind I a) don't have this specific rig, and b) I don't know the code in Blender in&out. I'm basing my answer on what I know from Maya, and what I read here: code.blender.org/2015/03/more-dependency-graph-tricks $\endgroup$ – aliasguru Mar 22 '17 at 9:45
  • $\begingroup$ could also add has_new_depsgraph = context.scene.depsgraph is not None as a test to see which depsgraph is currently in use. $\endgroup$ – batFINGER Mar 22 '17 at 14:44
  • $\begingroup$ @batFINGER I noticed there are debug_graphviz(filename), debug_rebuild() and debug_stats() methods on that depsgraph property. Do you know how to use those? I can see a file is created, and it is a textfile, but how would I make it human readable? $\endgroup$ – aliasguru Mar 22 '17 at 15:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.