Open mottosso opened 9 years ago
Here are some notes about this:
Maya has a polyCompare
method that can compare vertices between two polygonal shapes. Since this is running the C++ implementation of comparison that Maya provides it might just be fast enough to not even become problematic for larger meshes. Maya also has a shapeCompare
but I'm not entirely sure what does (it might only work for instances) but it's nice to see if that works for nurbsSurfaces and nurbsCurves. It would be trivial to implement a geoCompare() method that has the most optimal solution per nodeType and one that also supports custom shape types. That last might be overkill? ;)
Take all output renderable shapes and for each retrieve the first input (intermediate) mesh (in its history) and compare the vertices.
Since meshes in the history could be objects that are inputs to deformers as collision objects or blendShapes we could also check for comparison of vertex count to find the original mesh (though this won't solve it for blendShapes). Another solution here could be to implement a custom _find_maininput method for each nodeType, though I wouldn't recommend that because it would make it hard working with custom nodes/plug-ins that users might be using.
Assuming the original source mesh is the one furthest back down the chain is unlikely to be correct. (eg. the chain for blendShapes could be much longer or the influence mesh for a collision deformer as well)
We could retrieve all deformers in the history and set the envelopes to zero. This assumes that anything that alters the vertex topology is inherited from a Maya deformer and has a working envelope
attribute. Default Maya nodes have this consistency and most plug-in nodes will as well, though for plug-ins its up to the programmer to implement it correctly as such so might not be 100% accurate. Also it's possible to create a DG node that changes geometry without inheriting from a Maya deformer, which wouldn't get caught correctly.
What are your thoughts? How do we know what the source mesh was if it's stacked with tons of deformers in the history?
Good notes, Roy.
I also had some further thoughts, in particular about the dagPose
node which..
..is typically used in conjunction with the dagPose command in order to save and restore poses. Poses are also created when skin is bound to a skeleton. These poses are called bindPoses
Thus a light method of determining whether the skeleton is different in it's current state from when it was bound could be to cycle through the values stored in this node, and compare them to the current values.
How do we know what the source mesh was if it's stacked with tons of deformers in the history?
Automating this, as you've nicely concluded, can be quite tricky, so I might instead try and delegate this responsibility to the rigger.
It would be trivial for a rigger to choose which mesh mean "input" and which mesh mean "output" and potentially store this within an object set or the like, which we could use to compare with. Such as collection has other uses too, for example point-caching, and would align with other styles of collecting important nodes, such as animatable controls.
Furthermore, "input" typically means a separate "model" asset, in which case we could leave the responsibility of this definition to the modeler who came before, or simply assert that every mesh from this asset are "inputs" or "originals", in which case the rigger only has to pick his output.
Note that the dagPose
node is only used for skinClusters. Plus I think skinClusters can live without it, so you would be free to delete it. The skinCluster itself contains information about the position during the bind in the form of a matrix per joint. Note that this is only for skinClusters and not for other deformers like blendShape.
Now that I think of it setting the envelope to zero on all deformers should capture most of the errors that happen during rigging. So we could check whether the output meshes stay in the same position with all deformers disabled and enabled? Basically all built-in deformers should behave as expected. If custom nodes are used one might want to implement custom Validators anyway?
About letting the artist (rigger or modeler) tag the meshes as inputs/outputs I'm not too sure about the gain it has in productions. You'll have extra work to set it up. Plus this extra set up is still prone to human error. But it's definitely an interesting technique if we can simplify or automate this in a sense so it feels like an industry standard.
Basically we want everyone to hop in the project, make a rig and now how to get perfect publishes.
Basically we want everyone to hop in the project, make a rig and now how to get perfect publishes.
That is my goal as well, but one step at a time.
This validator, as far as I'm concerned, should only concern itself with the bind pose; that is, the envelope deformer and it's associated skeleton. I'd leave it to other validators to worry about more specific things like blendshapes, their defaults and whether they are valid.
In that case I'll set up a draft for this in the coming week!
About letting the artist (rigger or modeler) tag the meshes as inputs/outputs I'm not too sure about the gain it has in productions. You'll have extra work to set it up. Plus this extra set up is still prone to human error.
These are good and valid points. In my experience and opinion, some things simply aren't a good fit for automation. Sometimes you'll have to rely on manual processes. The challenge then is to find a way of making these manual processes more intuitive and robust. For example, in the form of surrounding tools.
My goal is to find the sweet spot, the point at which a rigger has manual control over core essentials, whilst leaving detail and repetition to the pipeline.
Goal
To assert that a mesh with an envelope looks identical (within range) with or without the envelope when no animation has been applied to any of it's controllers.
Motivation
Sometimes, a controller may have gotten zeroed out when the envelope is still active, resulting in an offset when controls have been zeroed out. It's also a good indicator that one or more controllers are not in their default position/orientation.
Implementation
Randomly sample 3-4 global point-positions on relevant meshes and compare to positions of vertices on the envelope source (intermediate) mesh.