def compute(self, plug, dataBlock): if plug == computePoleVector.poleVector: ''' dataHandleInString = dataBlock.inputValue(computePoleVector.inString) dataHandleInParam = dataBlock.inputValue(computePoleVector.inParam) inStringVal = dataHandleInString.asString() inParamVal = dataHandleInParam.asInt() outVal = inStringVal.replace('<param>', str(inParamVal).zfill(3)) dataHandleOutString = dataBlock.outputValue(computePoleVector.outString) dataHandleOutString.setString(outVal) dataBlock.setClean(plug) ''' dataHandle = OpenMaya.MDataHandle(dataBlock.inputValue(computePoleVector.inLegPosition)) legPositionValue = dataHandle.asVector() dataHandle = OpenMaya.MDataHandle (dataBlock.inputValue (computePoleVector.inKneePosition)) kneePositionValue = dataHandle.asVector() dataHandle = OpenMaya.MDataHandle (dataBlock.inputValue (computePoleVector.inFootPosition)) footPositionValue = dataHandle.asVector() #computations #find start of vector pt0 = legPositionValue pt1 = kneePositionValue pt2 = footPositionValue res1 = OpenMaya.MVector (pt1.x - pt0.x, pt1.y - pt0.y, pt1.z - pt0.z) res1Raw = res1 res2 = OpenMaya.MVector (pt2.x - pt0.x, pt2.y - pt0.y, pt2.z - pt0.z) res2Raw = res2 thetaCos = normalize (res2) * normalize (res1) thetaSin = math.sqrt(1-math.sqrt(thetaCos)) vectorProject = thetaCos * res1.length () poleStartPos = (normalize (res2) * vectorProject) + pt0 #find pole vector poleVector = OpenMaya.MVector(pt1.x - poleStartPos.x, pt1.y - poleStartPos.y, pt1.z - poleStartPos.z) #vectorCrossProduct = res1 ^ res2 offset = 10 polePos = normalize (poleVector) * offset + pt1 result = polePos dataHandle = OpenMaya.MDataHandle(dataBlock.outputValue (computePoleVector.poleVector)) dataHandle.set3Double(result.x, result.y, result.z) dataBlock.setClean(plug) else: return OpenMaya.kUnknownParameter
def compute(self, plug, dataBlock): if plug == oyCenterOfMass.aCOMPos: # get the mesh vertices for time from start to end # get the meshes arrayDataHandle = dataBlock.inputArrayValue( oyCenterOfMass.aObjectList ) numOfConnections = arrayDataHandle.elementCount() inputDataHandle = OpenMaya.MDataHandle() inputGeometryDataHandle = OpenMaya.MDataHandle() mesh = OpenMaya.MObject() meshList = OpenMaya.MObjectArray() for i in range(numOfConnections): arrayDataHandle.jumpToElement(i) inputDataHandle = arrayDataHandle.inputValue() inputGeometryDataHandle = inputDataHandle.child( oyCenterOfMass.aObjectList ) mesh = inputGeometryDataHandle.asMesh() if mesh.hasFn( OpenMaya.MFn.kMesh ): meshList.append( mesh ) numOfMesh = meshList.length() # return if no mesh if numOfMesh == 0: return OpenMaya.MStatus.kSuccess # read the mesh vertices in to one big array verticesOfOneMesh = OpenMaya.MPointArray() allVertices = OpenMaya.MPointArray() meshFn = OpenMaya.MFnMesh() for i in range(numOfMesh): meshFn.getPoints ( verticesOfOneMesh, OpenMaya.MSpace.kWorld ) for j in range(verticesOfOneMesh.length()): allVertices.append( verticesOfOneMesh[j] ) # set the time return OpenMaya.MStatus.kSuccess else: return OpenMaya.kUnknownParameter
def write_ouputState(self, outState_handle, numberofOutput_Val, activeIndex_Val, ThsNde): cBuilder = outState_handle.builder() bldChck = cBuilder.elementCount() growVal = numberofOutput_Val - bldChck if growVal > 0: #print 'we need to grow this array of ', bldChck , ' elements by ', growVal cBuilder.growArray(growVal) stateList = [] stateList = [0 for k in range(numberofOutput_Val)] stateList[activeIndex_Val] = 1 currentDH = OpenMaya.MDataHandle() for n in range(0, numberofOutput_Val): currentDH = cBuilder.addElement(n) currentDH.setBool(stateList[n]) bldChck = cBuilder.elementCount() # prune unwanted index --> equivalent to removeMultiInstance... if bldChck > numberofOutput_Val: depFn = OpenMaya.MFnDependencyNode(ThsNde) curvePointsPlug = depFn.findPlug('outState') outName = curvePointsPlug.info() for k in range(bldChck - 1, numberofOutput_Val - 1, -1): try: cBuilder.removeElement(k) except: # --> a bit dirty but it help when node is not connected yet we have access to the correct number of output attribute # when node is connected this fallback is not needed anymore cmds.removeMultiInstance('%s[%s]' % (outName, k), b=True) outState_handle.set(cBuilder) outState_handle.setAllClean()
def compute(self, plug, dataBlock): if plug == arrayTest.output1WgtAttr: #calculations here #get inputs dataHandleInput = dataBlock.inputValue(arrayTest.input1VecAttr) inVal = dataHandleInput.asFloat() #get ouput array arrayDataHandle = OpenMaya.MArrayDataHandle( dataBlock.outputArrayValue(arrayTest.output1WgtAttr)) myBuilder = OpenMaya.MArrayDataBuilder(arrayTest.output1WgtAttr, 0) for i in range(arrayDataHandle.elementCount()): #arrayDataHandle.next() output = inVal / (i + 1) #output = inVal + outValue myElementHandle = OpenMaya.MDataHandle(myBuilder.addElement(i)) myElementHandle.setFloat(output) arrayDataHandle.set(myBuilder) arrayDataHandle.setAllClean() dataBlock.setClean(plug) else: return OpenMaya.kUnknownParameter
def compute(self, plug, dataBlock): dataHandle = om.MDataHandle(dataBlock.inputValue(mat_test.sourceAttr)) sourcePos = dataHandle.asFloat3() dataHandle = om.MDataHandle(dataBlock.inputValue(mat_test.targetAttr)) targetPos = dataHandle.asFloat3() #dataHandle = om.MDataHandle(dataBlock.inputValue(mat_test.inMeshAttr)) #inMesh = dataHandle.asMesh() outPos =[ ( targetPos[0] - sourcePos[0] ) / 2 , ( targetPos[1] - sourcePos[1] ) / 2 , ( targetPos[1] - sourcePos[1] ) / 2 ] dataHandle = om.MDataHandle(dataBlock.outputValue(mat_test.outputAttr)) dataHandle.asFloat3(outPos) dataBlock.setClean(plug)
def compute(self, plug, dataBlock): """Compute the arithmetic mean of input 1 and input 2.""" if (plug == AR_AverageDoublesNode.outputAttr): # get the incoming data dataHandle = om.MDataHandle( dataBlock.inputValue(AR_AverageDoublesNode.input1Attr)) input1 = dataHandle.asDouble() dataHandle = om.MDataHandle( dataBlock.inputValue(AR_AverageDoublesNode.input2Attr)) input2 = dataHandle.asDouble() # compute output output = (input1 + input2) * 0.5 # set the outgoing plug dataHandle = om.MDataHandle( dataBlock.outputValue(AR_AverageDoublesNode.outputAttr)) dataHandle.setDouble(output) dataBlock.setClean(plug) else: return om.kUnknownParameter
def compute(self, plug, data): if plug.isNull(): return OpenMayaMPx.MPxNode.compute(plug, data) type_handle = OpenMaya.MDataHandle(data.inputValue(Connect.type)) type_value = type_handle.asChar() count_handle = OpenMaya.MDataHandle(data.inputValue(Connect.count)) count_value = count_handle.asLong() row_handle = OpenMaya.MDataHandle(data.inputValue(Connect.row)) row_value = row_handle.asLong() column_handle = OpenMaya.MDataHandle(data.inputValue(Connect.column)) column_value = column_handle.asLong() offset_handle = OpenMaya.MDataHandle(data.inputValue(Connect.offset)) offset_value = offset_handle.asLong() random_handle = OpenMaya.MDataHandle(data.inputValue(Connect.random)) random_value = random_handle.asLong() print 'random_value', random_value self.crowd_setup(type=type_value, count=count_value, row=row_value, column=column_value, offset=offset_value, random=random_value)
def compute(self, plug, dataBlock): """Compute the mean of input 1 and input 2.""" if (plug == AR_WeightedAverageVectorsNode.outputAttr or (plug.isChild() and plug.parent() == AR_WeightedAverageVectorsNode.outputAttr)): # get the incoming data dataHandle = om.MDataHandle( dataBlock.inputValue( AR_WeightedAverageVectorsNode.input1VecAttr)) input1Vector = dataHandle.asVector() dataHandle = om.MDataHandle( dataBlock.inputValue( AR_WeightedAverageVectorsNode.input1WgtAttr)) input1Weight = dataHandle.asDouble() dataHandle = om.MDataHandle( dataBlock.inputValue( AR_WeightedAverageVectorsNode.input2VecAttr)) input2Vector = dataHandle.asVector() dataHandle = om.MDataHandle( dataBlock.inputValue( AR_WeightedAverageVectorsNode.input2WgtAttr)) input2Weight = dataHandle.asDouble() # compute output totalWeight = input1Weight + input2Weight if not abs( totalWeight) <= abs(totalWeight) * sys.float_info.epsilon: output = (input1Vector * input1Weight + input2Vector * input2Weight) / totalWeight else: output = (input1Vector + input2Vector) * 0.5 # set the outgoing plug dataHandle = om.MDataHandle( dataBlock.outputValue( AR_WeightedAverageVectorsNode.outputAttr)) dataHandle.set3Double(output.x, output.y, output.z) dataBlock.setClean(plug) else: return om.kUnknownParameter
def compute(self, plug, dataBlock): """Compute the arithmetic mean of all the items in input array.""" if (plug == AR_AverageDoubleArrayNode.outputAttr): # get the incoming data dataHandle = om.MDataHandle( dataBlock.inputValue(AR_AverageDoubleArrayNode.inputAttr)) doubleArrayFn = om.MFnDoubleArrayData(dataHandle.data()) doubleArray = om.MDoubleArray(doubleArrayFn.array()) # compute output output = 0.0 for i in range(doubleArray.length()): output += doubleArray[i] try: output /= doubleArray.length() except: pass # set the outgoing plug dataHandle = om.MDataHandle( dataBlock.outputValue(AR_AverageDoubleArrayNode.outputAttr)) dataHandle.setDouble(output) dataBlock.setClean(plug) else: return om.kUnknownParameter
def compute(self, plug, dataBlock): self.sourcePos = dataBlock.inputValue(self.sourceAttr).asFloat3() self.targetPos = dataBlock.inputValue(self.targetAttr).asFloat3() #dataHandle = om.MDataHandle(dataBlock.inputValue(mat_test.sourceAttr)) #self.sourcePos = dataHandle.asFloat3() #dataHandle = om.MDataHandle(dataBlock.inputValue(mat_test.targetAttr)) #self.targetPos = dataHandle.asFloat3() startPnt = om.MPoint(self.sourcePos[0], self.sourcePos[1], self.sourcePos[2]) targetPnt = om.MPoint(self.targetPos[0], self.targetPos[1], self.targetPos[2]) outPos = [0, 0, 0] outPos = [(startPnt.x - targetPnt.x) / 2, (startPnt.y - targetPnt.x) / 2, (startPnt.z - targetPnt.x) / 2] dataHandle = om.MDataHandle(dataBlock.outputValue(mat_test.outputAttr)) dataHandle.asFloat3(outPos) dataBlock.setClean(plug)
def compute(self, plug, dataBlock): """Compute the arithmetic mean of all the items in input array.""" if (plug == AR_AverageArrayDoublesNode.outputAttr): # get the incoming data arrayDataHandle = om.MArrayDataHandle( dataBlock.inputValue(AR_AverageArrayDoublesNode.inputAttr)) # compute output output = 0.0 try: output = (arrayDataHandle.inputValue()).asDouble() except: pass for i in range(arrayDataHandle.elementCount() - 1): arrayDataHandle.next() output += (arrayDataHandle.inputValue()).asDouble() try: output /= arrayDataHandle.elementCount() except: pass """ # an alternative approach using an MPlug; less efficient because MPlug is slower arrayPlug = om.MPlug(self.thisMObject(), AR_AverageArrayDoublesNode.inputAttr) output = 0.0 for i in range(arrayPlug.numElements()): elementPlug = om.MPlug(arrayPlug[i]).asDouble() # index operator works with physical indices output += elementPlug.asDouble() try: output /= arrayPlug.numElements() except: pass """ # set the outgoing plug dataHandle = om.MDataHandle( dataBlock.outputValue(AR_AverageArrayDoublesNode.outputAttr)) dataHandle.setDouble(output) dataBlock.setClean(plug) else: return om.kUnknownParameter
def compute(self, plug, dataBlock): """Compute an exposed object's transformations with respect to a reference object.""" if (plug == AM_ExposeTransformNode.position or ( plug.isChild() and plug.parent() == AM_ExposeTransformNode.position ) or # WARNING: without this, position always initializes to 0, 0, 0 when connection is made plug == AM_ExposeTransformNode.distance or plug == AM_ExposeTransformNode.rotation or ( plug.isChild() and plug.parent() == AM_ExposeTransformNode.rotation ) or # WARNING: without this, setting rotateOrder attribute manually won't push a compute() plug == AM_ExposeTransformNode.dot or plug == AM_ExposeTransformNode.angle or plug == AM_ExposeTransformNode.dotToTarget or plug == AM_ExposeTransformNode.angleToTarget): # get the incoming data # rotation order for Euler output dataHandle = OM.MDataHandle( dataBlock.inputValue(AM_ExposeTransformNode.rotateOrder)) eRotateOrder = dataHandle.asShort() # should the incoming axes be normalized for computing dot products? dataHandle = OM.MDataHandle( dataBlock.inputValue(AM_ExposeTransformNode.normalize)) bNormalizeInputAxes = dataHandle.asBool() # axis on the object for computing dot product and angle dataHandle = OM.MDataHandle( dataBlock.inputValue(AM_ExposeTransformNode.objectAxis)) vObjectAxis = OM.MVector(dataHandle.asVector()) if bNormalizeInputAxes: vObjectAxis.normalize() # axis on the reference object for computing dot product and angle dataHandle = OM.MDataHandle( dataBlock.inputValue(AM_ExposeTransformNode.referenceAxis)) vReferenceAxis = OM.MVector(dataHandle.asVector()) if bNormalizeInputAxes: vReferenceAxis.normalize() # worldMatrix of the object dataHandle = OM.MDataHandle( dataBlock.inputValue(AM_ExposeTransformNode.objectMatrix)) mObjectMatrix = OM.MMatrix(dataHandle.asMatrix()) # worldMatrix of the reference dataHandle = OM.MDataHandle( dataBlock.inputValue(AM_ExposeTransformNode.referenceMatrix)) mReferenceMatrix = OM.MMatrix(dataHandle.asMatrix()) # compute the output values mOutputMatrix = OM.MTransformationMatrix( mObjectMatrix * mReferenceMatrix.inverse()) vOutPosition = OM.MVector( mOutputMatrix.getTranslation(OM.MSpace.kTransform)) vOutRotation = OM.MEulerRotation( mOutputMatrix.eulerRotation().reorder(eRotateOrder)) vObjectAxis *= mObjectMatrix # rotate objectAxis into world space vReferenceAxis *= mReferenceMatrix # rotate referenceAxis into world space vToTarget = OM.MVector( mReferenceMatrix(3, 0) - mObjectMatrix(3, 0), mReferenceMatrix(3, 1) - mObjectMatrix(3, 1), mReferenceMatrix(3, 2) - mObjectMatrix(3, 2) ) # the vector from the object's axis to the reference object's position if bNormalizeInputAxes: vObjectAxis.normalize() vReferenceAxis.normalize() vToTarget.normalize() # set the outgoing plugs outputHandle = dataBlock.outputValue( AM_ExposeTransformNode.position) outputHandle.set3Double(vOutPosition.x, vOutPosition.y, vOutPosition.z) outputHandle = dataBlock.outputValue( AM_ExposeTransformNode.distance) outputHandle.setDouble(vOutPosition.length()) outputHandle = dataBlock.outputValue( AM_ExposeTransformNode.rotation) outputHandle.set3Double(math.degrees(vOutRotation.x), math.degrees(vOutRotation.y), math.degrees(vOutRotation.z)) outputHandle = dataBlock.outputValue(AM_ExposeTransformNode.dot) outputHandle.setDouble(vObjectAxis * vReferenceAxis) outputHandle = dataBlock.outputValue(AM_ExposeTransformNode.angle) outputHandle.setDouble( math.degrees(vObjectAxis.angle(vReferenceAxis))) outputHandle = dataBlock.outputValue( AM_ExposeTransformNode.dotToTarget) outputHandle.setDouble(vObjectAxis * vToTarget) outputHandle = dataBlock.outputValue( AM_ExposeTransformNode.angleToTarget) outputHandle.setDouble(math.degrees(vObjectAxis.angle(vToTarget))) dataBlock.setClean(plug) else: return OM.kUnknownParameter
def compute(self, plug, dataBlock): dataBlock.setClean(plug) if plug != angleReader.outAngle_nAttr and plug != angleReader.outWeight_nAttr: return om.kUnknownParameter baseMatrix_DH = om.MDataHandle() baseMatrix_DH = dataBlock.inputValue(angleReader.baseMatrix_mAttr) base_M = baseMatrix_DH.asMatrix() driverMatrix_DH = om.MDataHandle() driverMatrix_DH = dataBlock.inputValue(angleReader.driverMatrix_mAttr) driver_M = driverMatrix_DH.asMatrix() rotateAxisX_DH = om.MDataHandle() rotateAxisX_DH = dataBlock.inputValue(angleReader.rotateAxisX_nAttr) rotateAxisY_DH = om.MDataHandle() rotateAxisY_DH = dataBlock.inputValue(angleReader.rotateAxisY_nAttr) rotateAxisZ_DH = om.MDataHandle() rotateAxisZ_DH = dataBlock.inputValue(angleReader.rotateAxisZ_nAttr) rotateAxis_V = om.MVector(rotateAxisX_DH.asFloat(), rotateAxisY_DH.asFloat(), rotateAxisZ_DH.asFloat()) frontAxisX_DH = om.MDataHandle() frontAxisX_DH = dataBlock.inputValue(angleReader.frontAxisX_nAttr) frontAxisY_DH = om.MDataHandle() frontAxisY_DH = dataBlock.inputValue(angleReader.frontAxisY_nAttr) frontAxisZ_DH = om.MDataHandle() frontAxisZ_DH = dataBlock.inputValue(angleReader.frontAxisZ_nAttr) frontAxis_V = om.MVector(frontAxisX_DH.asFloat(), frontAxisY_DH.asFloat(), frontAxisZ_DH.asFloat()) preStart_DH = om.MDataHandle() preStart_DH = dataBlock.inputValue(angleReader.preStart_nAttr) preStart = preStart_DH.asFloat() start_DH = om.MDataHandle() start_DH = dataBlock.inputValue(angleReader.start_nAttr) start = start_DH.asFloat() end_DH = om.MDataHandle() end_DH = dataBlock.inputValue(angleReader.end_nAttr) end = end_DH.asFloat() postEnd_DH = om.MDataHandle() postEnd_DH = dataBlock.inputValue(angleReader.postEnd_nAttr) postEnd = postEnd_DH.asFloat() negate_DH = om.MDataHandle() negate_DH = dataBlock.inputValue(angleReader.negate_nAttr) negate = negate_DH.asInt() # compute the angle # first get the local axis of the matrices driverFront_V = frontAxis_V * driver_M driverFront_V.normalize() baseRotate_V = rotateAxis_V * base_M baseRotate_V.normalize() baseFront_V = frontAxis_V * base_M baseFront_V.normalize() # then calculate the third axis for the baseMatrix upAxis_V = baseFront_V ^ baseRotate_V # then make a projection from driver's frontAxis to the base rotate vector projected_V = driverFront_V ^ baseRotate_V dotProjBaseFront = projected_V * baseFront_V dotProjUp = projected_V * upAxis_V angle = math.atan2(dotProjBaseFront, dotProjUp) mAngle = om.MAngle(angle, om.MAngle.kRadians) outAngle_DH = om.MDataHandle() outAngle_DH = dataBlock.outputValue(angleReader.outAngle_nAttr) outAngle_DH.setMAngle(mAngle) outAngle_DH.setClean() # print pluginName + ' : ' + str(angle) outWeight_DH = om.MDataHandle() outWeight_DH = dataBlock.outputValue(angleReader.outWeight_nAttr) weight = computeWeight(math.degrees(angle), preStart, start, end, postEnd, negate) outWeight_DH.setFloat(weight) outWeight_DH.setClean()
def compute(self, plug, dataBlock): """Use a NURBS curve and other input parameters to generate mesh data to be piped into a shape node.""" if (plug == AM_RibbonsNode.output): # get the incoming data # the input nurbs curve dataHandle = OM.MDataHandle( dataBlock.inputValue(AM_RibbonsNode.inputCurve)) curve = OM.MObject(dataHandle.asNurbsCurve()) # early out if there is no curve data if curve.isNull(): return OM.kUnknownParameter # width of the ribbon in centimeters dataHandle = OM.MDataHandle( dataBlock.inputValue(AM_RibbonsNode.inputWidth)) width = dataHandle.asDouble() # number of divisions along the ribbon dataHandle = OM.MDataHandle( dataBlock.inputValue(AM_RibbonsNode.inputDivisions)) divisions = dataHandle.asInt() # the ribbon must have at least one division if divisions < 1: divisions = 1 dataHandle.setInt(1) dataHandle.setClean() # amount of taper at the far end of the ribbon dataHandle = OM.MDataHandle( dataBlock.inputValue(AM_RibbonsNode.inputTaper)) taper = dataHandle.asDouble() # amount of twisting of the ribbon at its base dataHandle = OM.MDataHandle( dataBlock.inputValue(AM_RibbonsNode.inputTwistBase)) twistBase = dataHandle.asDouble() # amount of twisting of the ribbon at its far end dataHandle = OM.MDataHandle( dataBlock.inputValue(AM_RibbonsNode.inputTwistLength)) twistLength = dataHandle.asDouble() # up-vector for the ribbon at its base dataHandle = OM.MDataHandle( dataBlock.inputValue(AM_RibbonsNode.inputUpVector)) upVector = OM.MVector(dataHandle.asVector()) upVector.normalize() if upVector.length() == 0: upVector = OM.MVector(0.0, 1.0, 0.0) # scale factor applied to the default uv layout dataHandle = OM.MDataHandle( dataBlock.inputValue(AM_RibbonsNode.inputUVScale)) uvScale = dataHandle.asDouble() # pin location for the default uv layout dataHandle = OM.MDataHandle( dataBlock.inputValue(AM_RibbonsNode.inputUVPin)) uvPin = dataHandle.asShort() # create data for the output mesh dataCreator = OM.MFnMeshData() outputData = dataCreator.create() numVertices = 2 + divisions * 2 numPolygons = divisions newMeshVertices = OM.MPointArray() newMeshPolyCount = OM.MIntArray() newMeshPolyConnects = OM.MIntArray() newMeshUVCounts = OM.MIntArray() newMeshUVIDs = OM.MIntArray() meshFn = OM.MFnMesh() # find the points and tangents at each division along the curve pointsOnCurve = OM.MPointArray() tangentsOnCurve = OM.MVectorArray() curveFn = OM.MFnNurbsCurve(curve) maxParam = curveFn.findParamFromLength(curveFn.length()) paramStep = maxParam / divisions startPoint = OM.MPoint() currentPoint = OM.MPoint() curveFn.getPointAtParam(0.0, startPoint) for i in range(divisions + 1): curveFn.getPointAtParam(i * paramStep, currentPoint) pointsOnCurve.append(OM.MPoint(currentPoint - startPoint)) tangentsOnCurve.append(curveFn.tangent(i * paramStep).normal()) # determine the amount of twisting to apply at the base and per division twistBaseRotation = OM.MQuaternion(math.radians(twistBase), tangentsOnCurve[0]) twistStepAngle = math.radians(twistLength / divisions) # if the first tangent is roughly the same as the up-vector, then simply override the up-vector to be the z-axis upVector = upVector.rotateBy(twistBaseRotation) if upVector * tangentsOnCurve[0] > 0.999999999999999: upVector = OM.MVector(0.0, 0.0, 1.0) # orthonormalize the up-vector and first tangent rightVector = OM.MVector(upVector ^ tangentsOnCurve[0]).normal() upVector = tangentsOnCurve[0] ^ rightVector # create the points along the curve for i in range(pointsOnCurve.length()): if i is not 0: upVector = upVector.rotateBy( OM.MQuaternion(tangentsOnCurve[i - 1], tangentsOnCurve[i])) upVector = upVector.rotateBy( OM.MQuaternion(twistStepAngle, tangentsOnCurve[i])) newMeshPolyCount.append(4) newMeshUVCounts.append(4) rightVector = upVector ^ tangentsOnCurve[i] newMeshVertices.append( OM.MPoint(pointsOnCurve[i] + rightVector * 0.5 * width * (1.0 + (taper - 1.0) / pointsOnCurve.length() * (i + 1)))) newMeshVertices.append( OM.MPoint(pointsOnCurve[i] + rightVector * -0.5 * width * (1.0 + (taper - 1.0) / pointsOnCurve.length() * (i + 1)))) # connect the points in the new mesh and assign uv values to the faces for i in range(newMeshPolyCount.length()): newMeshPolyConnects.append(i * 2 + 0) newMeshPolyConnects.append(i * 2 + 1) newMeshPolyConnects.append(i * 2 + 3) newMeshPolyConnects.append(i * 2 + 2) newMeshUVIDs.append(i * 2 + 0) newMeshUVIDs.append(i * 2 + 1) newMeshUVIDs.append(i * 2 + 3) newMeshUVIDs.append(i * 2 + 2) # establish other parameters for the new mesh data numVertices = newMeshVertices.length() numPolygons = divisions # create the new mesh from all of the data mesh = meshFn.create(numVertices, numPolygons, newMeshVertices, newMeshPolyCount, newMeshPolyConnects, outputData) # set and assign uv values for i in range(pointsOnCurve.length()): meshFn.setUV( i * 2 + 0, 1.0, 1.0 - uvScale * (float(i) / (pointsOnCurve.length() - 1)) - uvPin * (1.0 - uvScale)) meshFn.setUV( i * 2 + 1, 0.0, 1.0 - uvScale * (float(i) / (pointsOnCurve.length() - 1)) - uvPin * (1.0 - uvScale)) meshFn.assignUVs(newMeshUVCounts, newMeshUVIDs) # set the outgoing plug outputHandle = dataBlock.outputValue(AM_RibbonsNode.output) outputHandle.setMObject(outputData) dataBlock.setClean(plug) else: return OM.kUnknownParameter