Friday, 26 February 2016

MFnMesh Constraint Node

I recently decided to have a play with some of the functions available in the MFnMesh class within the Maya Python API . This led to the creation of a basic constraint that would allow a transform to follow a point based on the average position of a set of vertices. This was derived from a combination of getClosestPoint, getPolygonVertices and getPoints. Initial attempts failed as I fell into the clutches of the dreaded cycle error. This happened because when testing the idea in a custom node I created an input plug that took the worldMatrix of the transform, passed it through the node, decomposed the result and dropped it back on the translate input plug of the said transform.

I then altered the way the matrix data was sampled from the transform. Rather than connecting it and have the plug refresh on each update I read the worldMatrix manually, performed the required calculations before storing the result statically within the node. This pre-calculation was more than sufficient to give me the desired result and break the cycle.
This then took me back to an idea I had toyed with a year or so ago. Switching between constraints without offsetting the affected transform. This would be an incredibly useful tool for disciplines such as Character Technical Direction and Character Rigging. When I had originally tested this I had also hit the cycle wall. Discussing this with a colleague suggested that Maya, due to its nature of its Dependency Graph would not behave well when trying to implement such functionality. Never being one to give up I have decided to have another stab at it.
In addition to the implementation of the node described above I have concluded that aside from the usual cosmetic bits and bobs like functionality these extra steps will need to be added.

Read in local matrix of driven transform in relation to driver A and store in offset matrix. Offset matrix is not visible

On every update calculate position in relation to driver

On switch multiply local matrix by current driver position giving world space of driven transform

Multiply this new matrix by inverse world of other driver to get local in relation to that. Overwrite local matrix.

It does seem deceptively simple which begs the question, 'Why has no one else tried it'. The answer is of course that they probably have which suggests it will not work otherwise we would have hundreds of solutions for this by now. However succeed or fail part of the process is all about the journey and what I learn from it. I'll post up the results in due course with an explanation.


Post a Comment