def compute(self, plug, data): if plug == Node.aOutCurve: matricesHandle = data.inputArrayValue(Node.aMatrices) curveHandle = data.outputValue(Node.aOutCurve) points = om.MPointArray() while True: mat = matricesHandle.inputValue().asMatrix() p = om.MPoint(0, 0, 0, 1) points.append(p*mat) p = om.MPoint(0, 0.1, 0, 1) points.append(p*mat) if not matricesHandle.next(): break print points curveDataCreator = om.MFnNurbsCurveData() curveData = curveDataCreator.create() curveFn = om.MFnNurbsCurve() curve = curveFn.create( points, range(len(points)), 1, om.MFnNurbsCurve.kOpen, False, False, curveData) curveHandle.setMObject(curveData) data.setClean(plug)
def set_nurbsCurve_data(node, curves_data, world_space=False): """Set the nurbsCurve shapes' data on `node`. Parameters ---------- node : maya.api.OpenMaya.MObject A DAG node in the scene curves_data : list List of nurbsCurve data world_space : bool If True, assign the nurbsCurve data in world space. Otherwise, assign the data local to the node. """ dagMod = OpenMaya.MDagModifier() number_of_curves = len(curves_data) curves = [ obj for obj in iter_shapes(node) if obj.hasFn(OpenMaya.MFn.kNurbsCurve) ] excess = len(curves) - number_of_curves if excess > 0: for i in range(excess): obj = curves.pop(-1) dagMod.deleteNode(obj) elif excess < 0: for i in range(-excess): obj = dagMod.createNode('nurbsCurve', node) curves.append(obj) dagMod.doIt() for data, curve in zip(curves_data, curves): curve_fn = OpenMaya.MFnNurbsCurve() curveData_fn = OpenMaya.MFnNurbsCurveData() curveData_obj = curveData_fn.create() if world_space: wm = get_world_matrix(curve) else: wm = OpenMaya.MMatrix(data['worldMatrix']) wim = wm.inverse() cvs = [OpenMaya.MPoint(p) * wim for p in data['cvs']] knots = OpenMaya.MDoubleArray(data['knots']) curve_fn.create(cvs, knots, data['degree'], data['form'], False, True, curveData_obj) create_plug = OpenMaya.MFnDagNode(curve).findPlug('create', True) if is_locked_or_connected(create_plug): raise ValueError() create_plug.setMObject(curveData_obj) return dagMod
def compute(self, _plug, _dataBlock): # Check if the plug is the curveL attribute if (_plug == RiverNodeClass.outCurveL): # Get handles for the attributes inputCurveDataHandle = _dataBlock.inputValue( RiverNodeClass.inInputCurve) terrainDataHandle = _dataBlock.inputValue(RiverNodeClass.inTerrain) widthDataHandle = _dataBlock.inputValue(RiverNodeClass.inWidth) curveDataHandle = _dataBlock.outputValue(RiverNodeClass.outCurveL) # Get values for the attributes inputCurveValue = inputCurveDataHandle.asNurbsCurve() terrainValue = terrainDataHandle.asMesh() widthValue = widthDataHandle.asFloat() / 2.0 # Computation # Get curve properties inCurveFn = om.MFnNurbsCurve(inputCurveValue) curvePoints, directionVectors = self.getPointsAndDirections( inCurveFn) normalVectors = self.getNormals(terrainValue, curvePoints) tangentVectors = self.getTangents(directionVectors, normalVectors) # Calculate new edit points numPoints = len(curvePoints) for curvePoint, tangentVector in zip(curvePoints, tangentVectors): curvePoint += tangentVector * widthValue # Create a new empty curve and curve data function set curveDataFn = om.MFnNurbsCurveData() curveDataObj = curveDataFn.create() curveFn = om.MFnNurbsCurve() # Create the curve and parent to curveDataFn curveFn.createWithEditPoints(curvePoints, 3, om.MFnNurbsCurve.kOpen, False, False, True, curveDataObj) # Set the output value curveDataHandle.setMObject(curveDataObj) # Mark the output data handle as clean curveDataHandle.setClean() # Check if the plug is the curveR attribute if (_plug == RiverNodeClass.outCurveR): # Get handles for the attributes inputCurveDataHandle = _dataBlock.inputValue( RiverNodeClass.inInputCurve) terrainDataHandle = _dataBlock.inputValue(RiverNodeClass.inTerrain) widthDataHandle = _dataBlock.inputValue(RiverNodeClass.inWidth) curveDataHandle = _dataBlock.outputValue(RiverNodeClass.outCurveR) # Get values for the attributes inputCurveValue = inputCurveDataHandle.asNurbsCurve() terrainValue = terrainDataHandle.asMesh() widthValue = widthDataHandle.asFloat() / 2.0 # Computation # Get curve properties inCurveFn = om.MFnNurbsCurve(inputCurveValue) curvePoints, directionVectors = self.getPointsAndDirections( inCurveFn) normalVectors = self.getNormals(terrainValue, curvePoints) tangentVectors = self.getTangents(directionVectors, normalVectors) # Calculate new edit points numPoints = len(curvePoints) for curvePoint, tangentVector in zip(curvePoints, tangentVectors): curvePoint -= tangentVector * widthValue # Create a new empty curve and curve data function set curveDataFn = om.MFnNurbsCurveData() curveDataObj = curveDataFn.create() curveFn = om.MFnNurbsCurve() # Create the curve and parent to curveDataFn curveFn.createWithEditPoints(curvePoints, 3, om.MFnNurbsCurve.kOpen, False, False, True, curveDataObj) # Set the output value curveDataHandle.setMObject(curveDataObj) # Mark the output data handle as clean curveDataHandle.setClean() # Check if the plug is the curveB attribute if (_plug == RiverNodeClass.outCurveB): # Get handles for the attributes inputCurveDataHandle = _dataBlock.inputValue( RiverNodeClass.inInputCurve) terrainDataHandle = _dataBlock.inputValue(RiverNodeClass.inTerrain) depthDataHandle = _dataBlock.inputValue(RiverNodeClass.inDepth) curveDataHandle = _dataBlock.outputValue(RiverNodeClass.outCurveB) # Get values for the attributes inputCurveValue = inputCurveDataHandle.asNurbsCurve() terrainValue = terrainDataHandle.asMesh() depthValue = depthDataHandle.asFloat() # Computation # Get curve properties inCurveFn = om.MFnNurbsCurve(inputCurveValue) curvePoints, directionVectors = self.getPointsAndDirections( inCurveFn) normalVectors = self.getNormals(terrainValue, curvePoints) # Calculate new edit points numPoints = len(curvePoints) for curvePoint, normalVector in zip(curvePoints, normalVectors): curvePoint -= normalVector * depthValue # Create a new empty curve and curve data function set curveDataFn = om.MFnNurbsCurveData() curveDataObj = curveDataFn.create() curveFn = om.MFnNurbsCurve() # Create the curve and parent to curveDataFn curveFn.createWithEditPoints(curvePoints, 3, om.MFnNurbsCurve.kOpen, False, False, True, curveDataObj) # Set the output value curveDataHandle.setMObject(curveDataObj) # Mark the output data handle as clean curveDataHandle.setClean()
def compute(self, _plug, _dataBlock): # Check if the plug is the output if (_plug == CaveNodeClass.outCurve): # Get data handles and typecast inCurveDataHandle = _dataBlock.inputValue(CaveNodeClass.inCurve) inCurveValue = inCurveDataHandle.asNurbsCurve() inTerrainDataHandle = _dataBlock.inputValue( CaveNodeClass.inTerrain) inTerrainValue = inTerrainDataHandle.asMesh() depthDataHandle = _dataBlock.inputValue(CaveNodeClass.depth) depthValue = depthDataHandle.asFloat() outCurveDataHandle = _dataBlock.outputValue(CaveNodeClass.outCurve) # Computation # Get the input curve data inCurveFn = om.MFnNurbsCurve(inCurveValue) curvePoints = inCurveFn.cvPositions(om.MSpace.kWorld) knots = inCurveFn.knots() # Find the curve centre numPoints = inCurveFn.numCVs * 2 curveCentre = om.MVector(0.0, 0.0, 0.0) for i in range(numPoints): point = inCurveFn.getPointAtParam( float(i) / numPoints, om.MSpace.kWorld) curveCentre += om.MVector(point) curveCentre /= float(numPoints) curveCentre = om.MPoint(curveCentre) # Get the normal from the closest point to the centre meshFn = om.MFnMesh(inTerrainValue) normal = meshFn.getClosestNormal(curveCentre, om.MSpace.kWorld)[0] normal.normalize() # Scale the normal normalScaled = normal * depthValue # Move the curve points for curvePoint in curvePoints: # Calculate the vector from the centre to the curve point centreToCurvePoint = curvePoint - curveCentre offset = (centreToCurvePoint * normalScaled) / depthValue # Move the point curvePoint -= (offset + depthValue) * normal # Create a new curve data fn and object curveDataFn = om.MFnNurbsCurveData() outCurve = curveDataFn.create() outCurveFn = om.MFnNurbsCurve() outCurveFn.create(curvePoints, knots, 3, inCurveFn.form, False, False, outCurve) # Set the output value outCurveDataHandle.setMObject(outCurve) # Mark the plug as clean outCurveDataHandle.setClean()
def initialize(cls): print('initialize') nData = ompy.MFnNumericData() cData = ompy.MFnNurbsCurveData() mData = ompy.MFnMeshData() sData = ompy.MFnStringData() nAttr = ompy.MFnNumericAttribute() eAttr = ompy.MFnEnumAttribute() mAttr = ompy.MFnMatrixAttribute() gAttr = ompy.MFnGenericAttribute() tAttr = ompy.MFnTypedAttribute() sAttr = ompy.MFnTypedAttribute() cls.inAttrs = [] # OUT ATTR cls.inAttrs.append(mAttr.create('camMatrix', 'camMatrix', nData.kFloat)) drawPlaneMode_choices = ['none', 'foreground', 'background'] cls.inAttrs.append(eAttr.create('drawPlaneMode', 'drawPlaneMode', 0)) for i in range(0, len(drawPlaneMode_choices)): eAttr.addField(drawPlaneMode_choices[i], i) eAttr.channelBox = True cls.inAttrs.append(nAttr.create('shapes', 'shapes', nData.kInt, 0)) nAttr.array = True #nAttr.dynamic = True nAttr.usesArrayDataBuilder = True cls.inAttrs.append(nAttr.createPoint('coords', 'coords')) nAttr.array = True #nAttr.dynamic = True nAttr.usesArrayDataBuilder = True cls.inAttrs.append( nAttr.createPoint('screenSpaceOffsets', 'screenSpaceOffsets')) nAttr.array = True #nAttr.dynamic = True nAttr.usesArrayDataBuilder = True cls.inAttrs.append(nAttr.create('sizes', 'sizes', nData.kFloat, 1.0)) nAttr.array = True #nAttr.dynamic = True nAttr.usesArrayDataBuilder = True cls.inAttrs.append( nAttr.create('thicknesses', 'thicknesses', nData.kFloat, 1.0)) nAttr.array = True #nAttr.dynamic = True nAttr.usesArrayDataBuilder = True cls.inAttrs.append(nAttr.createPoint('colors', 'colors')) nAttr.array = True #nAttr.dynamic = True nAttr.usesArrayDataBuilder = True cls.inAttrs.append(tAttr.create('names', 'names', sData.kString)) tAttr.array = True #nAttr.dynamic = True tAttr.usesArrayDataBuilder = True ''' cls.attrOutTrig = nAttr.create( 'outTrig', 'outTrig' , nData.kFloat ) nAttr.setReadable(True) nAttr.setStorable(True) nAttr.setConnectable(True) ''' for i in range(0, len(cls.inAttrs)): cls.addAttribute(cls.inAttrs[i]) #INFLUENCE '''
def nodeInitializer(): # create attributes # don't take too much now iterAttrFn = om.MFnNumericAttribute() rmfPci.aIter = iterAttrFn.create("iterations", "i", om.MFnNumericData.kLong, 30) iterAttrFn.storable = True iterAttrFn.keyable = True iterAttrFn.readable = True iterAttrFn.writable = True iterAttrFn.setMin(3) om.MPxNode.addAttribute(rmfPci.aIter) # HELLO MY BABY curveAttrFn = om.MFnTypedAttribute() rmfPci.aCurve = curveAttrFn.create("curve", "crv", om.MFnNurbsCurveData.kNurbsCurve) om.MPxNode.addAttribute(rmfPci.aCurve) # internal extended curve, stored on master node intCurveAF = om.MFnTypedAttribute() intCurveData = om.MFnNurbsCurveData() # intCurveAF.storable = True # intCurveAF.readable = True rmfPci.aIntCurve = intCurveAF.create("intCurve", "intCrv", om.MFnNurbsCurveData.kNurbsCurve, intCurveData.create()) intCurveAF.writable = False intCurveAF.storable = True om.MPxNode.addAttribute(rmfPci.aIntCurve) # bind switch to create the internal curve nodeio.makeBindAttr(rmfPci, extras=None) # switch to use percentage for u lookup percentAttrFn = om.MFnNumericAttribute() rmfPci.aPercent = percentAttrFn.create( "turnOnPercentage", "top", om.MFnNumericData.kBoolean, 1) percentAttrFn.keyable = True om.MPxNode.addAttribute(rmfPci.aPercent) # create vector arrays to transmit and receive rmf function vAttrFn = om.MFnTypedAttribute() vArrayData = om.MFnVectorArrayData() rmfPci.aNormals = vAttrFn.create("normals", "ns", om.MFnData.kVectorArray, vArrayData.create()) om.MPxNode.addAttribute(rmfPci.aNormals) # create vector arrays to transmit and receive rmf function vTanArrayData = om.MFnVectorArrayData() rmfPci.aTangents = vAttrFn.create("tangents", "ts", om.MFnData.kVectorArray, vTanArrayData.create()) om.MPxNode.addAttribute(rmfPci.aTangents) # u lookup uAttrFn = om.MFnNumericAttribute() rmfPci.aU = uAttrFn.create("u", "u", om.MFnNumericData.kDouble, 0) uAttrFn.writable = True uAttrFn.keyable = True uAttrFn.setMin(0.0) uAttrFn.setMax(1.0) om.MPxNode.addAttribute(rmfPci.aU) # basic attributes returning the actual point information # rotate outRxAttrFn = om.MFnUnitAttribute() rmfPci.aOutRx = outRxAttrFn.create("outputRotateX", "outRx", 1, 0.0) outRxAttrFn.writable = False outRxAttrFn.keyable = False outRyAttrFn = om.MFnUnitAttribute() rmfPci.aOutRy = outRyAttrFn.create("outputRotateY", "outRy", 1, 0.0) outRyAttrFn.writable = False outRyAttrFn.keyable = False outRzAttrFn = om.MFnUnitAttribute() rmfPci.aOutRz = outRzAttrFn.create("outputRotateZ", "outRz", 1, 0.0) outRzAttrFn.writable = False outRzAttrFn.keyable = False outRotAttrFn = om.MFnCompoundAttribute() rmfPci.aOutRot = outRotAttrFn.create("outputRotate", "outRot") outRotAttrFn.storable = False outRotAttrFn.writable = False outRotAttrFn.keyable = False outRotAttrFn.addChild(rmfPci.aOutRx) outRotAttrFn.addChild(rmfPci.aOutRy) outRotAttrFn.addChild(rmfPci.aOutRz) om.MPxNode.addAttribute(rmfPci.aOutRot) # translate outTxAttrFn = om.MFnNumericAttribute() rmfPci.aOutTx = outTxAttrFn.create("outputTranslateX", "outTx", om.MFnNumericData.kDouble, 0) outTyAttrFn = om.MFnNumericAttribute() rmfPci.aOutTy = outTyAttrFn.create("outputTranslateY", "outTy", om.MFnNumericData.kDouble, 0) outTzAttrFn = om.MFnNumericAttribute() rmfPci.aOutTz = outTzAttrFn.create("outputTranslateZ", "outTz", om.MFnNumericData.kDouble, 0) outTransAttrFn = om.MFnCompoundAttribute() rmfPci.aOutTrans = outTransAttrFn.create("outputTranslate", "outTrans") outTransAttrFn.storable = False outTransAttrFn.writable = False outTransAttrFn.keyable = False outTransAttrFn.addChild(rmfPci.aOutTx) outTransAttrFn.addChild(rmfPci.aOutTy) outTransAttrFn.addChild(rmfPci.aOutTz) om.MPxNode.addAttribute(rmfPci.aOutTrans) rmfPci.attributeAffects(rmfPci.aCurve, rmfPci.aOutTrans) rmfPci.attributeAffects(rmfPci.aCurve, rmfPci.aOutRot) rmfPci.attributeAffects(rmfPci.aCurve, rmfPci.aIntCurve) rmfPci.attributeAffects(rmfPci.aU, rmfPci.aOutTrans) rmfPci.attributeAffects(rmfPci.aU, rmfPci.aOutTx) rmfPci.attributeAffects(rmfPci.aU, rmfPci.aOutTy) rmfPci.attributeAffects(rmfPci.aU, rmfPci.aOutTz) rmfPci.attributeAffects(rmfPci.aU, rmfPci.aOutRot) rmfPci.attributeAffects(rmfPci.aU, rmfPci.aOutRx) rmfPci.attributeAffects(rmfPci.aU, rmfPci.aOutRy) rmfPci.attributeAffects(rmfPci.aU, rmfPci.aOutRz) rmfPci.attributeAffects(rmfPci.aBind, rmfPci.aOutTrans) rmfPci.attributeAffects(rmfPci.aBind, rmfPci.aOutRot)
def compute(self, pPlug, pData): bind = pData.inputValue(rmfPci.aBind).asShort() curveDH = pData.inputValue(rmfPci.aCurve) curveFn = om.MFnNurbsCurve(curveDH.asNurbsCurve()) maxIter = int(pData.inputValue(rmfPci.aIter).asInt()) u = pData.inputValue(rmfPci.aU).asDouble() # print "u is {}".format(u) # always turn on percentage curveU = curveFn.numSpans * u outPos = curveFn.getPointAtParam(curveU) # there is currently mismatch between point and orient because of # different curve lengths internalCurveData = om.MFnNurbsCurveData( pData.outputValue(rmfPci.aIntCurve).asNurbsCurve()) internalDH = pData.outputValue(rmfPci.aIntCurve) intFn = om.MFnNurbsCurve(internalCurveData.object()) # check that vector arrays are not calculated before doing anything obj = self.thisMObject() nodeFn = om.MFnDependencyNode(obj) normalPlug = nodeFn.findPlug("normals", False) # don't want networked plugs tangentPlug = nodeFn.findPlug("tangents", False) if normalPlug.connectedTo(True, False) and \ tangentPlug.connectedTo(True, False): # asDest, not asSource # get vector array inputs print "" print "we are connected" normalDH = pData.inputValue(rmfPci.aNormals) normalData = om.MFnVectorArrayData(normalDH.data()) normals = normalData.array() print "received normals {}".format(normals) # not receiving networked normals properly for some reason - oh well tangentDH = pData.inputValue(rmfPci.aTangents) tangentData = om.MFnVectorArrayData(tangentDH.data()) tangents = tangentData.array() else: # do the full calculation # if bind and curvePlug.isDestination: # print "bind is {}".format(bind) if bind == 1: internalCurveDataObj = self.bind(pData, curveFn, internalCurveData) # print "int curve data is {}".format(internalCurveData) intFn = om.MFnNurbsCurve(internalCurveDataObj) # if not curveDH.isClean(): # how to check if input is dirty or not? # update the internal curve self.updateInternal(pData, curveFn, intFn) # make the frame normals, tangents, binormals = self.makeRmf(maxIter, intFn) # print "normals are {}".format(normals) # print "tangents are {}".format(tangents) # set vector array values before we mutilate them normalDH = pData.outputValue(rmfPci.aNormals) normalData = om.MFnVectorArrayData(normalDH.data()) normalData.set(normals) normalDH.setClean() tangentDH = pData.outputValue(rmfPci.aTangents) tangentData = om.MFnVectorArrayData(tangentDH.data()) tangentData.set(tangents) tangentDH.setClean() # # cull the vector values lying before the true curve? realFraction = curveFn.numSpans / float(intFn.numSpans) cullFraction = (1 - realFraction) * maxIter for i in [normals, tangents]: for n in range(int(cullFraction) - 1): i.remove(0) normalValue = om.MVector(self.vecArrayInterpolate(normals, u)) tangentValue = om.MVector(self.vecArrayInterpolate(tangents, u)) binormalValue = normalValue ^ tangentValue resultMat = self.matrixFromVectors(tangentValue, normalValue, binormalValue) # set output plugs to matrix rotation outRot = om.MTransformationMatrix(resultMat).rotation() # # if vector arrays are connected, don't compute anything # # apart from interpolation between values outRotAll = pData.outputValue(rmfPci.aOutRot) # outRotAll.set3Float(*outRot) outRotAll.set3Double(*outRot) outRotAll.setClean() outRotX = pData.outputValue(rmfPci.aOutRx) outRotX.setMAngle(om.MAngle(outRot[0], 1)) outRotY = pData.outputValue(rmfPci.aOutRy) outRotY.setMAngle(om.MAngle(outRot[1], 1)) outRotZ = pData.outputValue(rmfPci.aOutRz) outRotZ.setMAngle(om.MAngle(outRot[2], 1)) for i in [outRotX, outRotY, outRotZ]: i.setClean() outTAll = pData.outputValue(rmfPci.aOutTrans) # print "outPos is {}".format(outPos) # outTAll.set3Float(outPos[0], outPos[1], outPos[2]) outTx = pData.outputValue(rmfPci.aOutTx) # outTx.setFloat(outPos[0]) outTx.setDouble(outPos[0]) outTx.setClean() outTy = pData.outputValue(rmfPci.aOutTy) # outTy.setFloat(outPos[1]) outTy.setDouble(outPos[1]) outTy.setClean() outTz = pData.outputValue(rmfPci.aOutTz) # outTz.setFloat(outPos[2]) outTz.setDouble(outPos[2]) outTz.setClean() pData.setClean(pPlug)
def __init__(self): om.MPxNode.__init__(self) self.internalCurve = om.MFnNurbsCurveData()