OpenMaya node to multiply two matrix (doesnt work??)


#1

Hi!! I’m working in a node that multiplies two matrix, when i put the mouse over the input attribute “Matrix1” and “Matrix2” it show me that, by default, it contains the identity matrix, but when i put the mouse over the “Matrix Output”, it show me that the output value its all zero.

I tried to print the values of matrix1 and matrix2 but it show me all zero, whats happen?? I need help please!! Thanks in advanced!!


import sys
import maya.OpenMaya as om
import maya.OpenMayaMPx as omp

nodeTypeName = "m4MultiplierNode"
nodeTypeId = om.MTypeId(0x33335)

def MAKE_INPUT(attr):
    # Macro to define an attribute as input attribute
    attr.setKeyable(True)
    attr.setStorable(True)
    attr.setReadable(True)
    attr.setWritable(True)

def MAKE_OUTPUT(attr):
    # Macro to define an attribute as input attribute
    attr.setKeyable(False)
    attr.setStorable(False)
    attr.setReadable(True)
    attr.setWritable(False)

class m4MultiplierNode(omp.MPxNode):
    m1 = om.MObject()
    m2 = om.MObject()
    mOutput = om.MObject()

    def __init__(self):
        omp.MPxNode.__init__(self)

    def printMatrix(self, matrix):
        result = '% .2f % .2f % .2f % .2f
% .2f % .2f % .2f % .2f
% .2f % .2f % .2f % .2f
% .2f % .2f % .2f % .2f
'
        print "/////////////////////////////////////////////////"
        print result % (matrix(0, 0), matrix(0, 1), matrix(0, 2), matrix(0, 3),
                        matrix(1, 0), matrix(1, 1), matrix(1, 2), matrix(1, 3),
                        matrix(2, 0), matrix(2, 1), matrix(2, 2), matrix(2, 3),
                        matrix(3, 0), matrix(3, 1), matrix(3, 2), matrix(3, 3))
        print "/////////////--------finish-------//////////////"

    def compute(self, plug, block):
        print "> compute"
        try:
            m1_dh = block.inputValue(m4MultiplierNode.m1)
            m2_dh = block.inputValue(m4MultiplierNode.m2)
            mO_dh = block.inputValue(m4MultiplierNode.mOutput)
        except ImportError:
            sys.stderr.write("Failed to get MDataHandle")
        m1_value = m1_dh.asMatrix()
        m2_value = m2_dh.asMatrix()
        mO_value = mO_dh.asMatrix()
        for x in range(4):
            for y in range(4):
                sumatory = 0.0
                for z in range(4):
                    sumatory = sumatory + m1_value(x, z) * m2_value(z, y)
                om.MScriptUtil.setDoubleArray(mO_value[x], y, sumatory)

def nodeCreator():
    print "created"
    return omp.asMPxPtr(m4MultiplierNode())

def nodeInitializer():
    mAttr1 = om.MFnMatrixAttribute()
    m4MultiplierNode.m1 = mAttr1.create("matrix1", "m1", om.MFnMatrixAttribute.kFloat)
    MAKE_INPUT(mAttr1)
    m4MultiplierNode.addAttribute(m4MultiplierNode.m1)

    mAttr2 = om.MFnMatrixAttribute()
    m4MultiplierNode.m2 = mAttr2.create("matrix2", "m2", om.MFnMatrixAttribute.kFloat)
    MAKE_INPUT(mAttr2)
    m4MultiplierNode.addAttribute(m4MultiplierNode.m2)

    mAttr3 = om.MFnMatrixAttribute()
    m4MultiplierNode.mOutput = mAttr3.create("matrixOutput", "mO", om.MFnMatrixAttribute.kFloat)
    MAKE_OUTPUT(mAttr3)
    m4MultiplierNode.addAttribute(m4MultiplierNode.mOutput)

    m4MultiplierNode.attributeAffects(m4MultiplierNode.m1, m4MultiplierNode.mOutput)
    m4MultiplierNode.attributeAffects(m4MultiplierNode.m2, m4MultiplierNode.mOutput)

def initializePlugin(obj):
    # Aqui se registra el nodo
    plugin = omp.MFnPlugin(obj)
    plugin.registerNode(nodeTypeName, nodeTypeId, nodeCreator,
                        nodeInitializer, omp.MPxNode.kDependNode)

def uninitializePlugin(obj):
    # Aqui se elimina del registro
    plugin = omp.MFnPlugin(obj)
    plugin.deregisterNode(nodeTypeId)

If I put something like "print "value = ", m1_value(0,0) it does not work either =(


#2

Hey,

I think MMatrix type use doubles, and as you’ve declared your matrix attributes as kFloat, they are not compatible when reading them in from the dataHandle. It might be better using .asFloatMatrix() instead.

You should also grab the output dataHandle using outputValue() instead of inputValue() (possibly to avoid extra computation?)

I think you need to also directly set the outputValue using the method .setMFloatMatrix().

One last thing, matrix multiplication can be done using the * operator, so no loops necessary :slight_smile:


m1_dh = block.inputValue(m4MultiplierNode.m1)
m2_dh = block.inputValue(m4MultiplierNode.m2)
m1_value = m1_dh.asFloatMatrix()
m2_value = m2_dh.asFloatMatrix()
outMatrix = m1_value * m2_value

mO_dh = block.outputValue(m4MultiplierNode.mOutput)
mO_dh.setMFloatMatrix(outMatrix)
block.setClean(plug)

Hope that helps!


#3

That works!! Thanks!! The problem was that i declare it as kFloat!! Thanks so much!!

PD: I love all your vimeo videos jejej congratulations!! =)


#4

I am studying with maya python api.
I’m making a simple mult_matrix node plugin, and for some reason, the multiplied output keeps coming out to zero. I’m going to receive the output by matrix.
Can you help me?

import maya.OpenMaya as OpenMaya
import maya.OpenMayaMPx as OpenMayaMPx
import sys
import math

kPluginNodeName = “TestMultMatrix”

KPluginNodeId = OpenMaya.MTypeID(0X80005)

class node(OpenMayaMPx.MPxNode):
reader = OpenMaya.MObject()
target = OpenMaya.MObject()
Moutput = OpenMaya.MObject()

def init(self):
OpenMayaMPx.MPxNode.init(self):

def compute(self,plug,data):
if plug == node.Moutput:
readerMtx = data.inputValue(node.reader).asFloathMatrix()
targetMtx = data.inputValue(node.target).asFloathMatrix()
result = readerMtx * targetMtx

     outputHandle = data.outputValue(node.Moutput)
     outputHandle.setMFloatMatrix(result)
     data.setClean(plug)

def Creator():
return OpenMayaMPx.asMPxPtr(node())

def initializer():
mtxAttr1 = OpenMaya.MFnMatrixAttribute()
node.reader = mtxAttr1.create(“In_Matrix”,“reader”,OpenMaya.MFnMatrixData.kMatrix)
mtxAttr1.setKeyable = True
mtxAttr1.setStorable = True
mtxAttr1.Readable = True
mtxAttr1.setWrit = True

   mtxAttr2 = OpenMaya.MFnMatrixAttribute()
   node.Target = mtxAttr2.create("Target_Matrix","reader",OpenMaya.MFnMatrixData.kMatrix)
   mtxAttr2.setKeyable = True
   mtxAttr2.setStorable = True
   mtxAttr2.Readable = True
   mtxAttr2.setWrit = True

   mtxAttr3 = OpenMaya.MFnMatrixAttribute()
   node.MOutput = mtxAttr3.create("In_Matrix","Moutput",OpenMaya.MFnMatrixData.kMatrix)
   mtxAttr3.writable = True
   mtxAttr3.keyable = True

   node.addAttribute(node.reader)
   node.addAttribute(node.Target)
   node.addAttribute(node.MOutput)
   
   node.AttributeAffects(node.reader , node.MOutput)
   node.AttributeAffects(node.Target , node.MOutput)

def initializePlugin(obj):
mPlugin = OpenMayaMPx.MFnPlugin(obj)
mPluging.registerNode(kpluginNodeName , KpluginNodeId , creator , initializer)

def uninitializePlugin(obj):
mplugin = OpenMayaMPx.MFnPlugin(obj)
mplugin.deregisterNode(kpluginNodeId)

Help me a lot!