Hey Leonardo.
Thanks a lot for the answer, it's been very useful.

So revised my code, but it's still not working. I mean... Maya handles the 
node smoothly, I can connect a mesh into the inMesh attribute, tweak the 
value of the positionOffset attribute, and even connect the values of the 
outPosition array to the translate channel of the locators. But still the 
locators all stay in the center of the scene (0,0,0) and if I modify the 
positionOffset or tweak the mesh, nothing happens: they stay there.
I also have an error (one for each connected locator, it doesn't show up if 
the locators are not connected..) :

> " Error: RuntimeError: file 
> S:\Maya_2015_DI\build\Release\runTime\Python\Lib\site-packages\maya\OpenMaya.py
>  
> line 8174: (kInvalidParameter): Object is incompatible with this method "

 
Most likely my error is how I write the data into the array, but I don't 
know which is the right way to do it!
Here's a snippet of my code:

class AttachToMesh(OMMPx.MPxNode):

    a_inMesh = OM.MObject()
    a_positionOffset = OM.MObject()
    a_outPosition = OM.MObject()

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

    def compute(self,plug,dataBlock):

        thisNode = AttachToMesh.thisMObject(self)
        inputMeshPlug = OM.MPlug(thisNode, AttachToMesh.a_inMesh)

        if not inputMeshPlug.isConnected():
            return OM.kNotImplemented

        if plug == AttachToMesh.a_outPosition:

            # GET MESH DATA
            inMesh = dataBlock.inputValue(AttachToMesh.a_inMesh).asMesh()
            
            # GET POSITION OFFSET VALUE
            dataHandlePositionOffset = dataBlock.inputValue(AttachToMesh.
a_positionOffset)
            positionOffsetValue = dataHandlePositionOffset.asFloat()

            # OUT POSITION
            dataHandleArrayOutPosition = dataBlock.outputArrayValue(
AttachToMesh.a_outPosition)
            dataBuilderOutPosition = dataHandleArrayOutPosition.builder()
            
            geoIterator = OM.MItGeometry(inMesh)            
            mFnMesh = OM.MFnMesh(inMesh)
            vertexPosition = OM.MPoint()
            normals = OM.MFloatVectorArray()
            mFnMesh.getVertexNormals(False, normals)

            while not geoIterator.isDone():

                vertexPosition.x = geoIterator.position().x + ( normals[
geoIterator.index()].x * positionOffsetValue )
                vertexPosition.y = geoIterator.position().y + ( normals[
geoIterator.index()].y * positionOffsetValue )
                vertexPosition.z = geoIterator.position().z + ( normals[
geoIterator.index()].z * positionOffsetValue )
                
                dataHandleOutPosition = dataBuilderOutPosition.addElement(
geoIterator.index())
                dataHandleOutPosition.set3Double(vertexPosition.x, 
vertexPosition.y, vertexPosition.z)

                geoIterator.next()
            
            dataHandleArrayOutPosition.set(dataBuilderOutPosition)

            dataBlock.setClean(plug)

        else:
            return OM.kUnknownParameter
    
def nodeInitializer():

    mFnTypedAttr = OM.MFnTypedAttribute()
    mFnAttr = OM.MFnNumericAttribute()

    AttachToMesh.a_inMesh = mFnTypedAttr.create("inputMesh", "inMesh", OM.
MFnData.kMesh)

    AttachToMesh.a_positionOffset = mFnAttr.create("positionOffset", 
"posOff", OM.MFnNumericData.kFloat, 0.0)
    mFnAttr.setKeyable(1)

    AttachToMesh.a_outPosition = mFnAttr.create("outPosition", "outPos", OM.
MFnNumericData.k3Double, 0.0)
    mFnAttr.setKeyable(0)
    mFnAttr.setWritable(0)
    mFnAttr.setArray(1)
    mFnAttr.setUsesArrayDataBuilder(1)

    AttachToMesh.addAttribute(AttachToMesh.a_inMesh)
    AttachToMesh.addAttribute(AttachToMesh.a_positionOffset)
    AttachToMesh.addAttribute(AttachToMesh.a_outPosition)

    AttachToMesh.attributeAffects(AttachToMesh.a_inMesh, AttachToMesh.
a_outPosition)
    AttachToMesh.attributeAffects(AttachToMesh.a_positionOffset, 
AttachToMesh.a_outPosition)


Thanks, folks!

PS... In Maya I piped a cubeShape's outMesh into my node's inMesh 
attribute. (Is it right? I guess so). And in the Hypergraph (Heat Map 
Display On) I see that my node is red, meaning that is making heavy 
calculations (0.05 s).
So far I kept the code as simple as possible! Does that mean that it will 
be super slow when I'll add more functionalities or use it with hi-poly 
meshes?




Il giorno mercoledì 30 luglio 2014 01:21:38 UTC+2, Enrico Losavio ha 
scritto:
>
> Hi everyone!
>
> I'm trying to write a sort of River node, but I ran into some difficulties 
> (obviously :) ) and any help would be greatly appreciated!
>
> Basically i want a DG node that can
>
>    - accept geometry as an input
>    - retrieve mesh information
>    - make up his own calculations based on the mesh information and a few 
>    custom attributes
>    - have an array of MPoints (or k3Double i guess) as output to be piped 
>    into each locator
>    - have the output updated every time an attribute or the mesh itself 
>    changes
>
> As far as I know, the MPxDeformerNode is the only way to access the 
> geometry data. But I don't want to deform the mesh, just query information.
> And yet I don't fully understand how the push-pull mechanism works in this 
> case. In a custom DG node i would use the "if plug == attribute" to force 
> the evaluation, but in this case...?
> I've already jot down the basic structure for the node, but it doesn't 
> work as it should.
> In Maya I loaded the plugin, applied the deformer to a simple cube, and 
> fed each value of the array into the Translate attribute of specifically 
> created locators (that thus went in the correct position, one on each 
> vertex)
> If I tweak the mesh, the locators remain in the same position, don't 
> follow the vertices. If I change the value of the positionOffset attribute, 
> nothing happens.
> But I noticed that if i tweak the mesh and then change the value of the 
> attribute, the position of all the locators suddenly updates as though the 
> mesh is read properly, but the positionOffset value remains the previous 
> one.
>
> Here's a simplified version of the code I wrote...:
>
> class AttachToMesh(OMMPx.MPxDeformerNode):
>
>
>     mObj_positionOffset = OM.MObject()
>     mObj_outPosition = OM.MObject()
>
>
>     def __init__(self):
>         OMMPx.MPxDeformerNode.__init__(self)
>
>
>     def deform(self, dataBlock, geoIterator, matrix, geometryIndex):
>         
>         # RETRIEVE GEOMETRY DATA
>         input = OMMPx.cvar.MPxDeformerNode_input
>         dataHandleInputArray = dataBlock.outputArrayValue(input)
>         dataHandleInputArray.jumpToElement(geometryIndex)
>         dataHandleInputElement = dataHandleInputArray.outputValue()
>
>         inputGeom = OMMPx.cvar.MPxDeformerNode_inputGeom
>         dataHandleInputGeom = dataHandleInputElement.child(inputGeom)
>         inMesh = dataHandleInputGeom.asMesh()
>
>
>         # POSITION OFFSET
>         dataHandlePositionOffset = dataBlock.inputValue(AttachToMesh.
> mObj_positionOffset)
>         positionOffsetValue = dataHandlePositionOffset.asFloat()
>
>         # OUT POSITION
>         dataHandleArrayOutPosition = dataBlock.outputArrayValue(
> AttachToMesh.mObj_outPosition)
>         dataBuilderOutPosition = dataHandleArrayOutPosition.builder()
>
>         vertexPosition = OM.MPoint()
>         mFnMesh = OM.MFnMesh(inMesh)
>         
>         normals = OM.MFloatVectorArray()
>         mFnMesh.getVertexNormals(False, normals)
>
>
>         while not geoIterator.isDone():
>
>
>             vertexPosition.x = geoIterator.position().x + ( normals[
> geoIterator.index()].x * positionOffsetValue )
>             vertexPosition.y = geoIterator.position().y + ( normals[
> geoIterator.index()].y * positionOffsetValue )
>             vertexPosition.z = geoIterator.position().z + ( normals[
> geoIterator.index()].z * positionOffsetValue )
>             
>             dataHandleOutPosition = dataBuilderOutPosition.addElement(
> geoIterator.index())
>             dataHandleOutPosition.set3Double(vertexPosition.x, 
> vertexPosition.y, vertexPosition.z)
>
>             geoIterator.next()
>         
>         dataHandleArrayOutPosition.set(dataBuilderOutPosition)
>         
>         #here I'm not sure which setClean function I'm supposed to use... 
> in this case I chose dataBlock.setClean
>         #dataHandleArrayOutPosition.setAllClean()
>         
>         dataBlock.setClean(AttachToMesh.mObj_outPosition)
>
>
> def nodeInitializer():    
>     mFnAttr = OM.MFnNumericAttribute()
>
>
>     AttachToMesh.mObj_positionOffset = mFnAttr.create("positionOffset", 
> "posOff", OM.MFnNumericData.kFloat, 0.0)
>     mFnAttr.setKeyable(1)
>
>     AttachToMesh.mObj_outPosition = mFnAttr.create("outPosition", "outPos"
> , OM.MFnNumericData.k3Double, 0.0)
>     mFnAttr.setKeyable(0)
>     mFnAttr.setWritable(0)
>     mFnAttr.setArray(1)
>     mFnAttr.setUsesArrayDataBuilder(1)
>
>     AttachToMesh.addAttribute(AttachToMesh.mObj_outPosition)
>
>     AttachToMesh.attributeAffects(AttachToMesh.mObj_positionOffset, 
> AttachToMesh.mObj_outPosition)
>
>
>
> Thank you in advance for any reply!!
>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/python_inside_maya/ca4f33c8-66a7-4bc5-b38a-1d9726c59c15%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to