Custom joint type with Maya Python API 1.0 or 2.0

Previously asked here.

I’m looking to subclass Maya’s default joint and hand it a few extra attributes, but I can’t find any suitable class nor example of how to go about it.

I managed to put together a transform like this…

myTransform.py

from maya import OpenMaya
from maya import OpenMayaMPx


class MyNode(OpenMayaMPx.MPxTransform):
    name = "myNode"
    id = OpenMaya.MTypeId(0x87014)
    matrixId = OpenMaya.MTypeId(0x87015)

    @classmethod
    def create(cls):
        return OpenMayaMPx.asMPxPtr(cls())

    @classmethod
    def init(cls):
        numFn = OpenMaya.MFnNumericAttribute()

        cls.myAttr = numFn.create(
            "myAttr", "mya", OpenMaya.MFnNumericData.kDouble, 0.0
        )

        numFn.setKeyable(True)
        numFn.setAffectsWorldSpace(True)

        cls.addAttribute(cls.myAttr)

    @classmethod
    def matrix(cls):
        class _(OpenMayaMPx.MPxTransformationMatrix):
            pass

        return OpenMayaMPx.asMPxPtr(_())


def initializePlugin(mobject):
    mplugin = OpenMayaMPx.MFnPlugin(mobject)
    mplugin.registerTransform(
        MyNode.name,
        MyNode.id,
        MyNode.create,
        MyNode.init,
        MyNode.matrix,
        MyNode.matrixId
    )


def uninitializePlugin(mobject):
    mplugin = OpenMayaMPx.MFnPlugin(mobject)
    mplugin.deregisterNode(MyNode.id)

But how does one make a new joint type? I could settle for a re-implementation of a new joint, starting from MPxTransform as that’s what it looks to be originally subclassed from.

If all you want to do is add attributes, you might just want to make an MDagMessage callbakck to add the attributes: it will be much less complex over than maintaining a completely new class.

The rocking transfomr example in C++ gives a proper example of how to implement a custom transform if you actually want to create custom behaviors; translating it to api 2 is pretty simple. As I said, however, I thnk it’s overkill for most purposes

Thanks @Theodox, in this particular case I’m already maintaining a series of nodes and the joint class is currently the odd one out.

Do you know if I could use that mechanism to make updates to the attributes after the node has been created? My motivation for using a custom node to begin with was because I found myself manually updating old attributes and adding new ones to old scenes and enjoyed the reference-like behaviour of a custom node where I could update a class and both existing and new scenes would follow suite.

Also I would much prefer not to alter the default joint type.

I’d try a two-step solution: a file open callback that looks for nodes with out of date attributes and updates them, and a message callback that adds them as needed.

In either case the big problem is the same: if the spec changes over time, old scenes won’t know what to do. One slight improvement is to make a custom node type for the attribute holder and them connect instances of that to the joints via a message attribute, instead of adding the attribute set to the joints directly. That makes it much easier to manage and version the data.

Yeah, a separate node with attributes connected to each joint is what I’ve got now and it’s working swell. Before that I was creating joints from a common function that added attributes as needed, similar to a callback approach.

Both of these approaches work well, the current approach all the better. But I still manage two nodes for every one joint, and so if there is a way to merge these - like I have with various transform-inherited nodes - then I’d be all the more happy.

My impression so far is that the joint type isn’t exposed by Maya, which is a little unfortunate but the sooner I get confirmation of this the sooner I can move on to greener plains.

For future readers, I’ve gotten confirmation from Cyrille that this is indeed not possible. Instead, one would need to subclass MPxNode or the like and re-implement all of what it means to be a joint. Even though that information likely isn’t readily available; it’d be reverse engineering which defeats the purpose (for me) to append to the existing joint type.