def create_primitives_from_input(classtype, name, dataBlock): primitives = [] primitivesHandle = dataBlock.inputArrayValue(getattr(classtype, name)) while primitivesHandle.isDone() == False: primitiveHandle = primitivesHandle.inputValue() boneParent = primitiveHandle.child( getattr(classtype, name + "BoneParent")).asInt() primitive = Primitive(boneParent) primitives.append(primitive) capsulesHandle = OpenMaya.MArrayDataHandle( primitiveHandle.child(getattr(classtype, name + "Capsule"))) while capsulesHandle.isDone() == False: capsuleHandle = capsulesHandle.inputValue() matrix = mayaToMatrix( capsuleHandle.child(getattr(classtype, name + "CapsuleMatrix")).asMatrix()) radius = capsuleHandle.child( getattr(classtype, name + "CapsuleRadius")).asDouble() height = capsuleHandle.child( getattr(classtype, name + "CapsuleHeight")).asDouble() capsulesHandle.next() primitive.addCapsule( t.Capsule(t.PosQuat.fromMatrix(matrix), radius, height)) primitivesHandle.next() return primitives
def compute(self, plug, dataBlock): # get the incoming data # print 'compute' inAllSampleInfoList_mArrayDataHandle = dataBlock.inputArrayValue( SampleValueBlender.inAllSampleInfoList) poseNameList = [] sampleValueList = [] for i in range(len(inAllSampleInfoList_mArrayDataHandle)): # print 'i, ', i inAllSampleInfoList_mArrayDataHandle.jumpToPhysicalElement(i) currentSampleInfoDataHandle = inAllSampleInfoList_mArrayDataHandle.inputValue( ) poseName = currentSampleInfoDataHandle.child( SampleValueBlender.inPoseName).asString() poseNameList.append(poseName) blendMode = currentSampleInfoDataHandle.child( SampleValueBlender.inSampleValueMode).asInt() sampleValListData = om.MArrayDataHandle( currentSampleInfoDataHandle.child( SampleValueBlender.inSampleValue)) sampleValueSum = 0 # print 'len of sampleValListData, ', len(sampleValListData) if blendMode == 0: sampleValueSum = 0 elif blendMode == 1: sampleValueSum = 1 for s in range(len(sampleValListData)): sampleValListData.jumpToPhysicalElement(s) f = sampleValListData.inputValue().asFloat() if blendMode == 0: sampleValueSum += f elif blendMode == 1: sampleValueSum *= f sampleValueList.append(sampleValueSum) out_mArrayData = dataBlock.outputArrayValue( SampleValueBlender.outWeightList) builder = out_mArrayData.builder() for n in range(len(sampleValueList)): newElem = builder.addElement(n) val = sampleValueList[n] val = max(min(val, 1), 0) newElem.setFloat(val) out_mArrayData.set(builder) dataBlock.setClean(plug)
def addElementToPlug(self, plug): """Maya routine to add a new element to the compound plug array.""" # MPlug.setNumElements works only if MPlug is not allocated. Maya, why # is it so compicated? data = plug.asMDataHandle() arrayData = om.MArrayDataHandle(data) builder = arrayData.builder() builder.addLastArray() arrayData.set(builder) plug.setMDataHandle(data) return plug.elementByPhysicalIndex(plug.numElements() - 1)
def fixIt(plug, path): # fix most vertices cmds.polyMoveVertex(path, lt=(0, 0, 0), nodeState=1, ch=False) # Sometimes the above comand doesn't fix very small number such as 0.000.....1 # So manually reset those numbers to 0 dataHandle = plug.asMDataHandle() arrayDataHandle = OpenMaya.MArrayDataHandle(dataHandle) while not arrayDataHandle.isDone(): outputHandle = arrayDataHandle.outputValue() outputHandle.set3Float(0.0, 0.0, 0.0) arrayDataHandle.next() plug.setMDataHandle(dataHandle) plug.destructHandle(dataHandle)
def checkIt(plug): dataHandle = plug.asMDataHandle() arrayDataHandle = OpenMaya.MArrayDataHandle(dataHandle) while not arrayDataHandle.isDone(): outputHandle = arrayDataHandle.outputValue() x, y, z = outputHandle.asFloat3() if x != 0.0: plug.destructHandle(dataHandle) return True if y != 0.0: plug.destructHandle(dataHandle) return True if z != 0.0: plug.destructHandle(dataHandle) return True arrayDataHandle.next() return False
def compute(self, plug, dataBlock): pointIndex = dataBlock.inputValue( FacialControllerConstraint.inPointIndex).asInt() baseMeshData = dataBlock.inputValue( FacialControllerConstraint.inBaseMesh).asMesh() baseMeshFn = om.MFnMesh(baseMeshData) inBlendShapeHandle = dataBlock.inputArrayValue( FacialControllerConstraint.inBlendshapeInfoList) basePointPos = baseMeshFn.getPoint(pointIndex, om.MSpace.kObject) outPos = [0, 0, 0] for i in range(len(inBlendShapeHandle)): # print 'i,', i inBlendShapeHandle.jumpToPhysicalElement(i) currentBlendshapeInfoHandle = inBlendShapeHandle.inputValue() meshData = currentBlendshapeInfoHandle.child( FacialControllerConstraint.inMesh).asMesh() if meshData: meshFn = om.MFnMesh(meshData) weightListDataHandle = om.MArrayDataHandle( currentBlendshapeInfoHandle.child( FacialControllerConstraint.inWeightList)) weightSum = 0 for s in range(len(weightListDataHandle)): # print 'i,', i # print '--s,', s weightListDataHandle.jumpToPhysicalElement(s) weightSum += weightListDataHandle.inputValue().asFloat() # print '-weightSum,', weightSum pos = meshFn.getPoint(pointIndex, om.MSpace.kObject) # print '-pos,', pos deltaPos = [ pos[0] - basePointPos[0], pos[1] - basePointPos[1], pos[2] - basePointPos[2] ] # print '-deltaPos,', deltaPos deltaPos = [ deltaPos[0] * weightSum, deltaPos[1] * weightSum, deltaPos[2] * weightSum ] # print '-weighted delta pos,', deltaPos outPos[0] += deltaPos[0] outPos[1] += deltaPos[1] outPos[2] += deltaPos[2] # print '-outPos,', outPos offsetX = dataBlock.inputValue( FacialControllerConstraint.inOffsetX).asFloat() offsetY = dataBlock.inputValue( FacialControllerConstraint.inOffsetY).asFloat() offsetZ = dataBlock.inputValue( FacialControllerConstraint.inOffsetZ).asFloat() outPos[0] += basePointPos[0] + offsetX outPos[1] += basePointPos[1] + offsetY outPos[2] += basePointPos[2] + offsetZ outputDataHandle = dataBlock.outputValue( FacialControllerConstraint.outPositionX) outputDataHandle.setFloat(outPos[0]) outputDataHandle = dataBlock.outputValue( FacialControllerConstraint.outPositionY) outputDataHandle.setFloat(outPos[1]) outputDataHandle = dataBlock.outputValue( FacialControllerConstraint.outPositionZ) outputDataHandle.setFloat(outPos[2]) dataBlock.setClean(plug)
def compute(self, plug, dataBlock): # get the incoming data inOverridingPoseIndex = dataBlock.inputValue( MatrixCombine.inOverridingPoseIndex).asInt() inOverridingWeight = dataBlock.inputValue( MatrixCombine.inOverridingWeight).asFloat() inOverridingIntensity = dataBlock.inputValue( MatrixCombine.inOverridingIntensity).asFloat() inInitialMatrix = dataBlock.inputValue( MatrixCombine.inInitialMatrix).asMatrix() inAllPoseInfoDataHandle = dataBlock.inputArrayValue( MatrixCombine.inAllPoseInfoList) inEditMode = dataBlock.inputValue(MatrixCombine.inEditMode).asFloat() inEditMatrix = dataBlock.inputValue( MatrixCombine.inEditMatrix).asMatrix() identityMatrix = om.MMatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) poseTranslation = om.MVector() poseQuaternion = om.MQuaternion() poseTransformMatrix = om.MTransformationMatrix(identityMatrix) if inOverridingIntensity > 0.0: # set the outgoing plug inAllPoseInfoDataHandle.jumpToPhysicalElement( inOverridingPoseIndex) currentPoseInfoDataHandle = inAllPoseInfoDataHandle.inputValue() inPoseMatrixDataHandle = currentPoseInfoDataHandle.child( MatrixCombine.inPoseMatrix) poseMatrixData = inPoseMatrixDataHandle.asMatrix() poseMatrix = om.MMatrix(poseMatrixData) poseTransformMatrix = om.MTransformationMatrix(poseMatrix) poseTranslation = poseTransformMatrix.translation(1) poseQuaternion = om.MQuaternion( poseTransformMatrix.rotationComponents(asQuaternion=True)) else: poseMatrixList = [] poseWeightsList = [] for i in range(len(inAllPoseInfoDataHandle)): inAllPoseInfoDataHandle.jumpToPhysicalElement(i) currentPoseInfoDataHandle = inAllPoseInfoDataHandle.inputValue( ) inPoseWeightDataHandle = currentPoseInfoDataHandle.child( MatrixCombine.inPoseWeights) inPoseMatrixDataHandle = currentPoseInfoDataHandle.child( MatrixCombine.inPoseMatrix) inPoseWeightArrayDataHandle = om.MArrayDataHandle( inPoseWeightDataHandle) poseMatrixData = inPoseMatrixDataHandle.asMatrix() poseMatrix = om.MMatrix(poseMatrixData) poseMatrixList.append(poseMatrix) poseWeight = 0 for w in range(len(inPoseWeightArrayDataHandle)): inPoseWeightArrayDataHandle.jumpToPhysicalElement(w) poseWeight += inPoseWeightArrayDataHandle.inputValue( ).asFloat() if poseWeight > 1: poseWeight = 1 if poseWeight < 0: poseWeight = 0 poseWeightsList.append(poseWeight) # print 'poseWeightsList', poseWeightsList for i in range(len(poseMatrixList)): if poseWeightsList[i] > 0: transMatrix = om.MTransformationMatrix(poseMatrixList[i]) translation = transMatrix.translation(1) poseTranslation += translation * poseWeightsList[i] quatTarget = om.MQuaternion( transMatrix.rotationComponents(asQuaternion=True)) quatIdentity = om.MQuaternion() quatBlend = om.MQuaternion.slerp(quatIdentity, quatTarget, poseWeightsList[i]) poseQuaternion = poseQuaternion * quatBlend poseTransformMatrix.setRotationComponents(poseQuaternion, asQuaternion=True) poseTransformMatrix.setTranslation(poseTranslation, 1) inInitialTransform = om.MTransformationMatrix(inInitialMatrix) inInitialQuat = om.MQuaternion(inInitialTransform.rotationComponents()) inInitTranslation = om.MVector(inInitialTransform.translation(1)) poseTransformMatrix.translateBy(inInitTranslation, 1) finalTranslation = poseTransformMatrix.translation(1) finalQuaternion = poseQuaternion * inInitialQuat finalEuler = finalQuaternion.asEulerRotation() # set the outgoing plug outTranslationX = finalTranslation[0] outTranslationY = finalTranslation[1] outTranslationZ = finalTranslation[2] outRotationX = om.MAngle(finalEuler[0], 1) outRotationY = om.MAngle(finalEuler[1], 1) outRotationZ = om.MAngle(finalEuler[2], 1) # set the outgoing plug dataHandle0 = dataBlock.outputValue(MatrixCombine.outTranslationX) dataHandle0.setFloat(outTranslationX) dataHandle1 = dataBlock.outputValue(MatrixCombine.outTranslationY) dataHandle1.setFloat(outTranslationY) dataHandle2 = dataBlock.outputValue(MatrixCombine.outTranslationZ) dataHandle2.setFloat(outTranslationZ) dataHandleRot0 = dataBlock.outputValue(MatrixCombine.outRotationX) dataHandleRot0.setMAngle(outRotationX) dataHandleRot1 = dataBlock.outputValue(MatrixCombine.outRotationY) dataHandleRot1.setMAngle(outRotationY) dataHandleRot2 = dataBlock.outputValue(MatrixCombine.outRotationZ) dataHandleRot2.setMAngle(outRotationZ) dataBlock.setClean(plug)
def testDdm(): # test for skin mesh = cmds.polyCylinder(r=1, h=10, sx=8, sy=40, sz=8, ax=(0, 0, 1), ch=0)[0] # skin cluster to transfer base weights skcMesh = cmds.duplicate(mesh, n="skcMesh")[0] refMesh = cmds.duplicate(mesh, n="refDdmMesh")[0] joints = [] refJoints = [] for i in range(3): jnt = cmds.createNode("joint", n="mainJnt_{}".format(i)) cmds.setAttr(jnt + ".translateZ", i * 5 - 5) joints.append(jnt) if i: cmds.parent(jnt, joints[i - 1]) skin = cmds.skinCluster(joints, skcMesh)[0] ddm = cmds.deformer(mesh, type="directDeltaMush")[0] refDdm = cmds.deformer(refMesh, type="refDDM")[0] for mush in [ddm, refDdm]: # copy matrix connections for i in range(3): cmds.connectAttr(joints[i] + ".worldMatrix[0]", mush + ".matrix[{}]".format(i)) #cmds.connectAttr(joints[i] + ".worldMatrix[0]", refDdm + ".matrix[{}]".format(i)) pass # copy plug connections and weights to deltamush copyPlugs = ("weightList", "bindPreMatrix") size = cmds.getAttr(skin + ".weightList", size=1) cmds.setAttr(mush + ".weightList", size=size) cmds.select(cl=1) for i in copyPlugs: sourcePlug = getMPlug(getMObject(skin), i) sourceDH = om.MArrayDataHandle(sourcePlug.asMDataHandle()) sinkPlug = getMPlug(getMObject(mush), i) sinkDH = om.MArrayDataHandle(sinkPlug.asMDataHandle()) sinkDH.copy(sourceDH) sourceDH = sourcePlug.asMDataHandle() sinkPlug.setMDataHandle(om.MDataHandle(sourceDH)) cmds.select(mush) # direct weight connections from skincluster to allow live weight editing for i in range(cmds.getAttr(skin + ".weightList", size=1)): array = skin + ".weightList[{}]".format(i) # for n in range( cmds.getAttr(array + ".weights", size=1 )): # srcPlug = array + ".weights[{}]".format(n) srcPlug = array dstPlug = srcPlug.replace(skin, mush) cmds.connectAttr(srcPlug, dstPlug, f=1) cmds.setAttr(ddm + ".iterations", 10) cmds.setAttr(ddm + ".alpha", 0.5) cmds.setAttr(ddm + ".smoothTranslation", 10.0) cmds.setAttr(ddm + ".smoothRotation", 10.0) # move skc mesh off to side group = cmds.group(skcMesh, n="skcOffsetGrp") cmds.setAttr(group + ".translateX", 5) group = cmds.group(refMesh, n="refOffsetGrp") cmds.setAttr(group + ".translateX", -5)
def compute(instance, plug, datablock): """ request node compute attribute data :param instance - plugin node instance (Plugin) :param plug - attribute plug (OpenMaya.MPLug) :param datablock - attribute data handle (OpenMaya.MDataBlock) """ from camerahudlib.private.plugin import Plugin # get this node node = instance.thisMObject() # get manager date instance time_index_handle = datablock.inputValue(Plugin.aCreationUnixTime) creation_time = time_index_handle.asDouble() time_index_handle.setClean() # get manager instance hud_index_handle = datablock.inputValue(Plugin.aHudIndex) hud_index = hud_index_handle.asShort() hud_index_handle.setClean() manager = PluginDrawManager(hud_index) # get drawing request id active_request_index = None used_plug = plug if plug.isElement: # can parent array attribute used_plug = plug.array() # attribute is child of compound attribute if used_plug.isNull is False: ui_compound_plug = None compound_child_plug = None if used_plug.isChild: # get parent compound attribute compound_child_plug = used_plug.parent() if compound_child_plug.isNull is False: if compound_child_plug.isElement: ui_compound_plug = compound_child_plug.array() elif used_plug.isCompound: if plug.isElement: compound_child_plug = plug ui_compound_plug = used_plug if compound_child_plug is not None and ui_compound_plug is not None: if ui_compound_plug.isNull is False and ui_compound_plug.partialName( False, False, False, False, False, False) == "ui": # get active request index active_request_index = compound_child_plug.logicalIndex() # update resolution gate resolution_gate_handle = datablock.inputValue(Plugin.aResolution) width, height = resolution_gate_handle.asDouble2() resolution_gate_handle.setClean() manager.setResolution(width, height) # compute drawing request data if active_request_index is not None: request = manager[active_request_index] # update scene info request.file = cmds.file(q=True, sn=True) if not request.file: request.file = "" # update creation date date = datetime.datetime.fromtimestamp(creation_time) request.year = "%04d" % date.year request.month = "%02d" % date.month request.day = "%02d" % date.day request.hour = "%02d" % date.hour request.minute = "%02d" % date.minute # get parent compound attribute ui_compound_array_handle = datablock.inputArrayValue(Plugin.aUI) ui_compound_array_handle.jumpToLogicalElement(active_request_index) ui_compound_handle = ui_compound_array_handle.inputValue() # prepare manager drawing data # get hud type data_handle = ui_compound_handle.child(Plugin.aUIType) request.uiType = data_handle.asShort() data_handle.setClean() # get size data_handle = ui_compound_handle.child(Plugin.aSize) request.uiSize = data_handle.asDouble() data_handle.setClean() # get fill data_handle = ui_compound_handle.child(Plugin.aFilled) request.uiFilled = data_handle.asBool() data_handle.setClean() # get size data_handle = ui_compound_handle.child(Plugin.aRadius) request.uiRadius = data_handle.asDouble() data_handle.setClean() # get color data_handle = ui_compound_handle.child(Plugin.aColor) color = data_handle.asFloat3() request.uiColor = OpenMaya.MColor([color[0], color[1], color[2]]) data_handle.setClean() # get transparency data_handle = ui_compound_handle.child(Plugin.aTransparency) request.uiColor.a = 1.0 - data_handle.asFloat() data_handle.setClean() # Get resolution gate. data_handle = ui_compound_handle.child(Plugin.aResolutionGate) request.uiResolutionGate = data_handle.asShort() data_handle.setClean() # get region position offset data_handle = ui_compound_handle.child(Plugin.aUIRegionPosition) position = data_handle.asDouble2() request.uiRegionPosition = OpenMaya.MPoint(position[0], position[1], 0.0, 1.0) data_handle.setClean() # get region size data_handle = ui_compound_handle.child(Plugin.aUIRegion) size = data_handle.asDouble2() request.uiRegion = OpenMaya.MVector(size[0], size[1], 0.0) data_handle.setClean() # get region draw enable data_handle = ui_compound_handle.child(Plugin.aUIRegionDrawEnable) draw_region = data_handle.asBool() request.uiDrawRegion = draw_region data_handle.setClean() # get resolution gate draw enable data_handle = ui_compound_handle.child( Plugin.aDrawResolutionGateEnable) draw_gate = data_handle.asBool() request.uiDrawResolutionGate = draw_gate data_handle.setClean() # get region attachment side data_handle = ui_compound_handle.child(Plugin.aHorizontalUiAttach) request.uiHorisontalAttach = data_handle.asShort() data_handle.setClean() data_handle = ui_compound_handle.child(Plugin.aVerticalUiAttach) request.uiVerticalAttach = data_handle.asShort() data_handle.setClean() # get region content alignment side data_handle = ui_compound_handle.child( Plugin.aHorizontalUiAlignment) request.uiHorisontalAlignment = data_handle.asShort() data_handle.setClean() data_handle = ui_compound_handle.child(Plugin.aVerticalUiAlignment) request.uiVerticalAlignment = data_handle.asShort() data_handle.setClean() # get region filling state data_handle = ui_compound_handle.child(Plugin.aUIRegionIsFilled) request.uiRegionIsFilled = data_handle.asBool() data_handle.setClean() # Set request drawing state data_handle = ui_compound_handle.child(Plugin.aUIDrawEnable) request.uiDraw = data_handle.asBool() data_handle.setClean() # get region color data_handle = ui_compound_handle.child(Plugin.aUIRegionColor) color = data_handle.asFloat3() request.uiRegionColor = OpenMaya.MColor( [color[0], color[1], color[2]]) data_handle.setClean() # get region transparency data_handle = ui_compound_handle.child( Plugin.aUIRegionTransparency) request.uiRegionColor.a = 1.0 - data_handle.asFloat() data_handle.setClean() # get position data ui_position_handle = ui_compound_handle.child(Plugin.aPosition) ui_position_list_handle = OpenMaya.MArrayDataHandle( ui_position_handle) request.uiPositionList = [] if len(ui_position_list_handle) > 0: if request.uiType != constants.kText: i = 0 while i < len(ui_position_list_handle): ui_position_list_handle.jumpToPhysicalElement(i) data_handle = ui_position_list_handle.inputValue() position = data_handle.asDouble2() request.uiPositionList.append( OpenMaya.MPoint(position[0], position[1], 0.0, 1.0)) i += 1 else: data_handle = ui_position_list_handle.inputValue() position = data_handle.asDouble2() request.uiPositionList.append( OpenMaya.MPoint(position[0], position[1], 0.0, 1.0)) else: request.uiPositionList.append( OpenMaya.MPoint(0.0, 0.0, 0.0, 1.0)) ui_position_list_handle.setClean() # get text data request.uiFontStyleLine = constants.kFontStyleLineNone if request.uiType == constants.kText: # get text string data_handle = ui_compound_handle.child(Plugin.aText) request.uiText = data_handle.asString() # get text is dynamic data_handle = ui_compound_handle.child(Plugin.aTextDynamic) request.uiTextDynamic = data_handle.asBool() # get text is auto resize data_handle = ui_compound_handle.child( Plugin.aFitToResolutionGate) request.uiFitToResolutionGate = data_handle.asBool() # get text line data_handle = ui_compound_handle.child(Plugin.aFontLine) request.uiFontStyleLine = data_handle.asShort() data_handle.setClean() # get font incline mode data_handle = ui_compound_handle.child(Plugin.aFontIncline) request.uiFontStyleIncline = data_handle.asShort() data_handle.setClean() # get font weight data_handle = ui_compound_handle.child(Plugin.aFontWeight) request.uiFontStyleWeight = data_handle.asShort() data_handle.setClean() # get font size data_handle = ui_compound_handle.child(Plugin.aFontStyleSize) request.uiFontStyleSize = data_handle.asShort() data_handle.setClean() # get font size data_handle = ui_compound_handle.child( Plugin.aFontStyleStretch) request.uiFontStyleStretch = data_handle.asShort() data_handle.setClean() # get font style data_handle = ui_compound_handle.child(Plugin.aFontStyleName) font_style_index = data_handle.asShort() if 0 <= font_style_index < len(Plugin.uiFontStyleList): request.uiFontStyle = Plugin.uiFontStyleList[ font_style_index] data_handle.setClean() # get text background transparency data_handle = ui_compound_handle.child( Plugin.aUITextBackgroundTransparency) alpha = 1.0 - data_handle.asFloat() data_handle.setClean() if alpha > 0.0: # get text background color data_handle = ui_compound_handle.child( Plugin.aUITextBackgroundColor) color = data_handle.asFloat3() request.uiTextBackgroundColor = OpenMaya.MColor( [color[0], color[1], color[2]]) request.uiTextBackgroundColor.a = alpha data_handle.setClean() else: request.uiTextBackgroundColor = None # get line style data_handle = ui_compound_handle.child(Plugin.aLineStyle) request.uiLineStyle = data_handle.asShort() data_handle.setClean() # get line width data_handle = ui_compound_handle.child(Plugin.aLineWidth) request.uiLineWidth = data_handle.asFloat() data_handle.setClean() ui_compound_handle.setClean() ui_compound_array_handle.setClean()
def compute(self, plug, dataBlock): thisNode = self.thisMObject() if plug not in [ prCurveMatrix.output, prCurveMatrix.outputMatrix, prCurveMatrix.outputTranslate ]: return counter = dataBlock.inputValue(prCurveMatrix.counter).asInt() inputArrayHandle = dataBlock.inputArrayValue(self.input) distributionEnabled = dataBlock.inputValue( self.distributionEnabled).asBool() if distributionEnabled: distribution = om.MRampAttribute(thisNode, self.distribution) outputArrayHandle = dataBlock.outputArrayValue(self.output) outputBuilder = outputArrayHandle.builder() for i in range(len(inputArrayHandle)): inputArrayHandle.jumpToPhysicalElement(i) index = inputArrayHandle.elementLogicalIndex() outputHandle = outputBuilder.addElement(index) outputArrayHandle.set(outputBuilder) inputHandle = inputArrayHandle.inputValue() curveHandle = inputHandle.child(self.inputCurve) curveData = curveHandle.data() if curveData.isNull(): continue curveFn = om.MFnNurbsCurve(curveData) curveLength = curveFn.length() stepLength = 1.0 / (counter - 1 if counter > 2 else 1) positions = [] tangents = [] for x in range(counter): if distributionEnabled: distributionValue = distribution.getValueAtPosition( x * stepLength) parameter = curveFn.findParamFromLength(distributionValue * curveLength) else: parameter = curveFn.findParamFromLength(x * stepLength * curveLength) positions.append( curveFn.getPointAtParam(parameter, space=om.MSpace.kWorld)) tangents.append( curveFn.tangent(parameter, space=om.MSpace.kWorld)) outTranslateArrayHandle = om.MArrayDataHandle( outputHandle.child(self.outputTranslate)) outTranslateBuilder = outTranslateArrayHandle.builder() for x, position in enumerate(positions): outTranslateHandle = outTranslateBuilder.addElement(x) outTranslateHandle.set3Float(position[0], position[1], position[2]) outTranslateArrayHandle.set(outTranslateBuilder) outTranslateArrayHandle.setAllClean() if plug == prCurveMatrix.outputMatrix: # TODO FIX TEMP CODE worldUpMatrix = inputHandle.child( self.worldUpMatrix).asMatrix() normals = [om.MVector(list(worldUpMatrix)[4:7])] bitangents = [om.MVector(list(worldUpMatrix)[7:10])] for x in range(counter - 1): bitangent = tangents[x] ^ tangents[x + 1] if bitangent.length() == 0: normal = normals[x] else: bitangent.normalize() angle = math.radians( math.acos(tangents[x] * tangents[x + 1])) normal = normals[x].rotateBy( om.MQuaternion(angle, bitangent)) # normal = normal[x] * getRotationMatrix(angle, bitangent) normals.append(normal) bitangents.append(bitangent) outputMatrixArrayHandle = om.MArrayDataHandle( outputHandle.child(self.outputMatrix)) outputMatrixBuilder = outputMatrixArrayHandle.builder() for x in range(counter): matrix = om.MMatrix( (list(tangents[x]) + [0], list(normals[x]) + [0], list(bitangents[x]) + [0], list(positions[x]))) outputMatrixHandle = outputMatrixBuilder.addElement(x) outputMatrixHandle.setMMatrix(matrix) outputMatrixArrayHandle.set(outputMatrixBuilder) outputMatrixArrayHandle.setAllClean() # outputArrayHandle.setAllClean() dataBlock.setClean(plug)