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)
--
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 python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/1e1a201e-452c-4f97-bb73-4abc120f5430%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
" 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 "
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)
class AttachToMesh(OMMPx.MPxNode):
def compute(self,plug,dataBlock):
if plug == AttachToMesh.a_outPosition:
inMesh = dataBlock.inputValue(AttachToMesh.a_inMesh).asMesh ()
positionOffsetValue = dataBlock.inputValue(AttachToMesh.a_positionOffset).asFloat()
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)
def nodeInitializer():
AttachToMesh.a_inMesh = mFnTypedAttr.create("inputMesh", "inMesh", OM.MFnData.kMesh)
AttachToMesh.a_positionOffset = mFnAttr.create("positionOffset", "posOff", OM.MFnNumericData.kFloat, 0.0)
AttachToMesh.a_outPosition = mFnAttr.create("outPosition", "outPos", OM.MFnNumericData.k3Double, 0.0)
mFnAttr.setKeyable(0)
mFnAttr.setWritable(0)
mFnAttr.setArray(1)
mFnAttr.setUsesArrayDataBuilder(1)First time posting. This past week I also started to dive into the Python API more thoroughly, and started creating the very node I think you're trying to as well. You can find the code below, hopefully it helps. I know it's not perfect, but it's where I've gotten after a week of research on the subject.
import math
import maya.OpenMaya as om
import maya.OpenMayaMPx as ompx
class RivetNode(ompx.MPxNode):
#plugin id
kPluginNodeId = om.MTypeId(0x00000001)
#plugin attrs
targetMesh = om.MObject()
targetVert = om.MObject()
outTranslate = om.MObject()
outRotate = om.MObject()
def __init__(self):
ompx.MPxNode.__init__(self)
def compute(self, plug, data):
"""check for connection of output before computing"""
'''
if plug != RivetNode.outMatrix:
return om.kUnknownParameter
'''
"""Get input plug data"""
inputMeshHandle = data.inputValue(RivetNode.targetMesh).asMesh()
inputVertIndex = data.inputValue(RivetNode.targetVert).asInt()
"""need to set incoming mesh as mesh, before it was just a handle"""
inMeshData = om.MFnMesh(inputMeshHandle)
inMeshVertData = om.MItMeshVertex(inputMeshHandle)
"""need a few spare instance objs"""
pp = om.MPoint()
pn = om.MVector()
pb = om.MPoint()
adjVerts = om.MIntArray()
"""get connected vert info"""
vertUtil = om.MScriptUtil()
vertUtil.createFromInt(0)
vertPtr = vertUtil.asIntPtr()
inMeshVertData.setIndex(inputVertIndex, vertPtr)
inMeshVertData.getConnectedVertices(adjVerts)
"""get the mesh data we need"""
pos = inMeshData.getPoint(inputVertIndex, pp, om.MSpace.kObject)
nor = inMeshData.getVertexNormal(inputVertIndex, True, pn, om.MSpace.kObject)
bi = inMeshData.getPoint(adjVerts[0], pb, om.MSpace.kObject)
"""need to convert to vectors"""
position = om.MVector(pp)
binormal = om.MVector(pb)
"""the math"""
a = binormal^pn
b = a^pn
"""manually making the matrix with a py list"""
listOfFloats = [pn.x, a.x, b.x, 0.0,
pn.y, a.y, b.y, 0.0,
pn.z, a.z, b.z, 0.0,
position.x, position.y, position.z, 1.0]
"""create matrix obj and add the values in"""
mm = om.MMatrix()
om.MScriptUtil.createMatrixFromList(listOfFloats, mm)
"""make transformation matrix to grab trans and rots"""
mt = om.MTransformationMatrix(mm)
translation = mt.getTranslation(om.MSpace.kWorld)
eulerRot = mt.eulerRotation()
rotation = [math.degrees(i) for i in (eulerRot.x, eulerRot.y, eulerRot.z)]
"""set values to output handles"""
outputTranslateHandle = data.outputValue(RivetNode.outTranslate)
outputTranslateHandle.set3Double(translation[0], translation[1], translation[2])
outputTranslateHandle.setClean()
outputRotateHandle = data.outputValue(RivetNode.outRotate)
outputRotateHandle.set3Double(rotation[0], rotation[1], rotation[2])
outputRotateHandle.setClean()
def creator():
return ompx.asMPxPtr(RivetNode())
def initialize():
"""output translate value attr"""
tAttr = om.MFnNumericAttribute()
RivetNode.outTranslate = tAttr.create('outputTranslate','outTranslate', om.MFnNumericData.k3Double)
tAttr.setWritable(False)
tAttr.setStorable(False)
RivetNode.addAttribute(RivetNode.outTranslate)
"""output rotate value attr"""
rAttr = om.MFnNumericAttribute()
RivetNode.outRotate = rAttr.create('outputRotate','outRotate', om.MFnNumericData.k3Double)
rAttr.setWritable(False)
rAttr.setStorable(False)
RivetNode.addAttribute(RivetNode.outRotate)
"""input mesh attr"""
tmAttr = om.MFnTypedAttribute()
RivetNode.targetMesh = tmAttr.create('targetMesh', 'tm', om.MFnData.kMesh)
RivetNode.addAttribute(RivetNode.targetMesh)
RivetNode.attributeAffects(RivetNode.targetMesh, RivetNode.outTranslate)
RivetNode.attributeAffects(RivetNode.targetMesh, RivetNode.outRotate)
"""vert index to find position/orientation attr"""
tvAttr = om.MFnNumericAttribute()
RivetNode.targetVert = tvAttr.create('targetVertex', 'tv', om.MFnNumericData.kInt)
RivetNode.addAttribute(RivetNode.targetVert)
RivetNode.attributeAffects(RivetNode.targetVert, RivetNode.outTranslate)
RivetNode.attributeAffects(RivetNode.targetVert, RivetNode.outRotate)
def initializePlugin(obj):
plugin = ompx.MFnPlugin(obj, 'Rick Silliker', '1.0', 'Any')
try:
plugin.registerNode('rivetNode', RivetNode.kPluginNodeId, creator, initialize)
except:
raise RuntimeError, 'Failed to register node'
def uninitializePlugin(obj):
plugin = ompx.MFnPlugin(obj)
try:
plugin.deregisterNode(RivetNode.kPluginNodeId)
except:
raise RuntimeError, 'Failed to register node'