Using OpenMaya for applying transformations to animated objects while maintaining sparse curves

Work In Progress / 24 June 2020

Been doing some research on methods to apply spatial transformations to animated objects.
The main problem I was trying to solve here is how to offset animated transforms while maintaining sparse curves - the obvious solution is to add another transform as a parent and simply offset that but I was curious if there was a way to do it directly on the animated transform.
The resulting tool is still work-in-progress but I wanted to get the first version out there and see if people may have suggestions for improvements.

I chose to approach this using OpenMaya for speed reasons, using the cmds library works as well but doesn't allow you to query values using a time context, rather having to set the currentTime which is much, much slower.

time_context = OpenMaya.MDGContext(OpenMaya.MTime(frame))
matrix_object = plug.asMObject(time_context)
fn_matrix_data = OpenMaya.MFnMatrixData(matrix_object)
matrix = fn_matrix_data.matrix()
Another benefit is being able to directly manipulate animation curves, for animated objects.
m_plug = m_dag_node.findPlug(attribute, False)
m_source = m_plug.source()
if m_source.isNull:
m_source_node = m_source.node()
if not m_source_node.apiTypeStr.startswith('kAnimCurve'):
fn_curve = OpenMayaAnim.MFnAnimCurve(m_source_node)
fn_curve.addKey(OpenMaya.MTime(input), value)

The main outstanding issue are the that it doesn't account for rotation order changes and the way it handles rotations over the 180 degree threshold, it's internally using matrices so this information gets lost during calculations. I've implemented an experimental flipping filter that works quite well but I'm continuing to do research on how to improve it when I have some time.

Full code available on my github:

mnCollisionDeformer; a collision deformer for Maya.

Work In Progress / 23 May 2020

A collision deformer I'm writing for learning purposes in my spare time.
Not very performant at the minute as it's written in Python and I came up with my own logic rather than using an established algorithm, this also means it's got some issues with edge-cases, but a very good learning exercise.

I will be releasing the code and a tutorial on how to approach something like this when I find some time for code clean up.