def uniformCurve(curveName, name=None, degree=3): """ Returns a live, parametricallu unifrom curve driven by the supplied curve """ name = name or curveName # build a live normalized curve uniCrvName = names.nodeName('nurbsCurve', '{0}Uniform'.format(name)) uniformCurve = cmds.rebuildCurve(curveName, ch=1, rpo=0, rt=0, end=1, kr=0, kcp=1, kep=0, kt=1, s=0, d=degree, tol=0.01, name=uniCrvName) # query curve shape curveShape = cmds.listRelatives(uniformCurve, type='shape')[0] rebuildCrvName = names.nodeName('rebuildCurve', name) rebuildCrvName = cmds.rename(uniformCurve[1], rebuildCrvName) return { 'crv': [uniformCurve[0]], 'crvShape': curveShape, 'rebuildCurve': [rebuildCrvName] }
def clusterize(curve, baseName=None): """ Creates clusters for each CV """ if not baseName: baseName = curve # get the control points for the curve cvCount = numCVs(curve) # create a control set # cmds.select(cl= True) # self.controlSel = cmds.sets(n= self.getName('SEL', 'Control')) # clusterize each control point csrList = [] cshList = [] csrGrpList = [] controlPoints = [] for point in xrange(0, cvCount): controlPoints.append(point) cshName = names.nodeName("clusterHandle", description='{0}{1}'.format(baseName, point)) csrName = names.nodeName("cluster", description='{0}{1}'.format(baseName, point)) csrGrpName = names.nodeName("transform", description='{0}{1}'.format( baseName, point)) csr = cmds.cluster('%s.cv[%s]' % (curve, point)) csrName = cmds.rename(csr[0], csrName) csrGrpName = cmds.rename(csr[1], csrGrpName) csrChildren = cmds.listRelatives(csrGrpName, children=True, shapes=True, type='clusterHandle') if csrChildren: for shape in csrChildren: cshName = cmds.rename(shape, cshName) csrList.append(csrName) csrGrpList.append(csrGrpName) cshList.append(cshName) cmds.hide(csrGrpName) retArgs = {} retArgs['controlPoints'] = controlPoints retArgs['csrList'] = csrList retArgs['csrGrpList'] = csrGrpList retArgs['cshList'] = cshList return retArgs
def setPose(name, node=None, ns=""): """ Reads the attributes off all objects in the specified set (name) and sets those as the set values :param name str: name of the pose to set :param node str: if specified, only applies the pose on the specified node """ if name == 'default': raise NameError("Can't override the default pose!") setName = ns + names.nodeName( 'set', names.getDescriptor(name), side=names.getSide(name)) if node: node = node.replace(names.getNS(node), "") nodes = [ns + node] else: nodes = util.objectSet.getSetContents(setName) for node in nodes: if not cmds.objExists("{0}.{1}".format(node, name)): cmds.error("{0} is not part of the pose {1}".format(node, name)) data = json.loads(cmds.getAttr("{0}.{1}".format(node, name))) for attr in data: val = cmds.getAttr("{0}.{1}".format(node, attr)) data[attr] = val prettyData = json.dumps(data, sort_keys=True, indent=3, separators=(',', ': ')) cmds.setAttr("{0}.{1}".format(node, name), prettyData, type="string")
def loadPoses(nameList, path, ns=""): """ Tries to load all poses in specified location with specfied names :param nameList list : list of pose names to look for :param path str: folder to look in """ if not os.path.exists(path): raise NameError("The path '{0}' does not exist!".format(path)) if not cmds.objExists(ns + basePoseSet): raise ValueError("This scene does not have a base pose set!") for name in nameList: setName = ns + names.nodeName( 'set', names.getDescriptor(name), side=names.getSide(name)) if not cmds.objExists(setName): cmds.sets(setName, add=ns + basePoseSet) dataPath = os.path.join(path, name + "Pose.json") data = json.loads(open(dataPath).read()) for node in data: if not cmds.objExists("{0}.{1}".format(ns + node, name)): continue newData = {} for attr in data[node]: val = data[node][attr] newData[attr] = val prettyData = json.dumps(newData, sort_keys=True, indent=3, separators=(',', ': ')) cmds.setAttr("{0}.{1}".format(ns + node, name), prettyData, type="string")
def curveToJoints(curve, numJoints, name=None, oj='xyz', sao='yup'): """ """ crvShape = curve if not cmds.objectType(crvShape) == 'nurbsCurve': children = cmds.listRelatives(curve, children=1, type='nurbsCurve') if not children: raise Exception( 'the supplied curve argument {0} is not a curve'.format(curve)) crvShape = children[0] def getDagPath(node=None): sel = om.MSelectionList() sel.add(node) d = om.MDagPath() sel.getDagPath(0, d) return d cmds.select(cl=1) chain = [] crvFn = om.MFnNurbsCurve(getDagPath(crvShape)) for i in range(0, numJoints): parameter = crvFn.findParamFromLength( (crvFn.length() / (float(numJoints) - 1)) * i) # param = i/float(numJoints-1) pos = om.MPoint() crvFn.getPointAtParam(parameter, pos) if i < (numJoints - 1): jntName = names.nodeName('joint', '{0}{1}'.format(name, str(i + 1))) else: jntName = names.nodeName('joint', '{0}End'.format(name)) jnt = cmds.joint(p=[pos.x, pos.y, pos.z], n=jntName) if i > 0: jntName = names.nodeName('joint', '{0}{1}'.format(name, str(i + 1))) cmds.joint(chain[i - 1], e=1, zso=1, oj=oj, sao=sao) # jntName = util.names.nodeName('joint', '{0}End'.format(baseName)) chain.append(jnt) cmds.setAttr('{0}.jo'.format(chain[-1]), 0, 0, 0) cmds.select(cl=1) return chain
def savePoses(nameList, path, ns=""): """ Saves out all poses in nameList to specified path. Creates a new file per pose :param nameList list: list of pose names to save out :param path str: path to save to, should be in the style "/test/path" and cannot be a file """ if not os.path.exists(path): raise NameError("The path '{0}' does not exist!".format(path)) for name in nameList: setName = names.nodeName('set', names.getDescriptor(name), side=names.getSide(name)) nodes = util.objectSet.getSetContents(setName) data = {} for node in nodes: data[node] = {} if not cmds.objExists("{0}.{1}".format(node, name)): cmds.error("{0} is not part of the pose {1}".format( node, name)) poseData = json.loads(cmds.getAttr("{0}.{1}".format(node, name))) for attr in poseData: val = cmds.getAttr("{0}.{1}".format(node, attr)) poseData[attr] = val data[node] = poseData prettyData = json.dumps(data, sort_keys=True, indent=3, separators=(',', ': ')) # Create a file name dataPath = os.path.join(path, name + "Pose.json") if os.path.exists(dataPath): # os.rename and shutil.move both throws errors, doing it the manual way... old = json.loads(open(dataPath).read()) f = open(dataPath + "OLD", 'w') prettyData = json.dumps(old, sort_keys=True, indent=3, separators=(',', ': ')) print >> f, prettyData f.close() os.remove(dataPath) # Save the data to disc. Running json.dumps and printing line by line returns an easily readable json f = open(dataPath, 'w') prettyData = json.dumps(data, sort_keys=True, indent=3, separators=(',', ': ')) print >> f, prettyData f.close()
def createPoses(node, nameList=[], extra=[], ns=""): """ Creates poses specified in the nameList on specified node. :param node str: node to add poses to :param nameList list: list of pose names :param extra list: appends the attributes specified in this list to the default list of attrs Example: from ooutdmaya.rigging.core.util import pose reload(pose) if not cmds.objExists('pose_set'): cmds.sets('pose_set') mySphere = cmds.polySphere(n="test1_geo", ch=0)[0] cmds.addAttr(mySphere, ln="testAttr", at="float", k=True, dv=10) pose.createPoses(mySphere, ['default', 'test'], ['testAttr]) """ if not node: return if not cmds.objExists(ns + node): return attrList = [ 'tx', 'ty', 'tz', 'rx', 'ry', 'rz', 'sx', 'sy', 'sz', 'v', 'rotateOrder' ] if extra: attrList = attrList + extra data = {} for attr in attrList: val = cmds.getAttr("{0}.{1}".format(ns + node, attr)) data[attr] = val prettyData = json.dumps(data, sort_keys=True, indent=3, separators=(',', ': ')) for name in nameList: cmds.addAttr(ns + node, ln=name, dt="string", h=False) cmds.setAttr("{0}.{1}".format(ns + node, name), prettyData, type="string") setName = ns + names.nodeName( 'set', names.getDescriptor(name), side=names.getSide(name)) if cmds.objExists(setName): cmds.sets(ns + node, add=setName) else: newSet = util.lib.createNode('objectSet', name=ns + setName) cmds.sets(newSet, add=ns + basePoseSet) cmds.sets(ns + node, add=newSet)
def skinAs(src, dst, smooth=False): ''' Bind a destination mesh based on the influence list and weights of the skinCluster of a source mesh. :param src str: Source mesh that will be used to determine influence list and weights of destination mesh. :param dst str: Destination mesh to bind based on source mesh skinCluster. :param smooth bool: Smooth incoming skinCluster weights for destination mesh. :return: the resulting skinCluster :rtype: str ''' # Check inputs if not cmds.objExists(src): raise Exception('Source object {0} does not exist!'.format(src)) if not cmds.objExists(dst): raise Exception('Destination object {0} does not exist!'.format(dst)) # Get source skinCluster srcSkin = findRelatedSkinCluster(src) # Check destination skinCluster dstSkin = findRelatedSkinCluster(dst) # Build destination skinCluster if not dstSkin: dstPrefix = dst.split(':')[-1] srcInfList = cmds.skinCluster(srcSkin, q=True, inf=True) dstSkin = cmds.skinCluster(srcInfList, dst, toSelectedBones=True, rui=False, n=names.nodeName('skinCluster', dstPrefix))[0] # Copy skin weights cmds.copySkinWeights(sourceSkin=str(srcSkin), destinationSkin=str(dstSkin), surfaceAssociation='closestPoint', influenceAssociation='name', noMirror=True, smooth=smooth) # Return result return dstSkin
def applyPose(name, node=None, ns=""): """ Applies the pose specified (name) to all objects in the relevant pose set :param name str: name of the pose to apply """ setName = ns + names.nodeName( 'set', names.getDescriptor(ns + name), side=names.getSide(ns + name)) print setName if node: node = node.replace(names.getNS(node), "") nodes = [ns + node] else: nodes = util.objectSet.getSetContents(setName) for node in nodes: if not cmds.objExists("{0}.{1}".format(node, name)): cmds.error("{0} is not part of the pose {1}".format(node, name)) data = json.loads(cmds.getAttr("{0}.{1}".format(node, name))) for attr in data: try: cmds.setAttr("{0}.{1}".format(node, attr), data[attr]) except: continue
def skinObjectList(objList, jntList): ''' Skin a list of objects to a list of influences :param objList list: List of geoemrty to create skinClusters for. :param jntList list: List of joints to add as skinCluster influences. :return: list of skinClusters :rtype: list ''' # Check Geometry for obj in objList: if not cmds.objExists(obj): raise Exception('Object {0} does not exist!'.format(obj)) # Check Joints for jnt in jntList: if not cmds.objExists(jnt): raise Exception('Joint {0} does not exist!'.format(jnt)) # Initialize SkinCluster List skinClusterList = [] for obj in objList: # Get Short Name objName = cmds.ls(obj, sn=True)[0].split(':')[-1] # Create SkinCluster skinCluster = cmds.skinCluster(jntList, obj, tsb=True, rui=False, n=names.nodeName( 'skinCluster', objName))[0] # Append to Return List skinClusterList.append(skinCluster) return skinClusterList
def nodeName(*args, **kwargs): # cmds.warning('ooutdmaya.rigging.core.util.names.nodeName now DEPRECIATED... please use\n\tooutdmaya.common.util.names.nodeName instead') return names.nodeName(*args, **kwargs)
def run(self): """ """ # Run inherited functionality base.Base.run(self) # Create groups self.driverChain = self.chain #======================================================================= # self.driverChain = joint.duplicateSegment(self.chain, suffix='DRV', # searchReplaceSetList=[(names.getNS(self.chain[0]), '')]) #======================================================================= self.jawOffset = cmds.createNode('transform', n=names.nodeName('transform', '{0}{1}Offset'.format(self.prefix, self.name), self.side)) chainParent = cmds.listRelatives(self.chain[0], p=1)[0] if chainParent: easy.snapAlignScaleTo(chainParent, self.jawOffset) cmds.parent(self.jawOffset, self.grpSkeleton) cmds.parent(self.driverChain[0], self.jawOffset) key = 'jaw' self.buildCtl(key, lockAttrList=['scale'], movablePivot=False, keyAttrList=['rotateOrder']) ctlDict = self.ctls[key] easy.snapAlignTo(self.chain[-1], ctlDict['input']) self.sdkZeroGrp = cmds.createNode('transform', n=names.nodeName('transform', '{0}{1}SDKZero'.format(self.prefix, self.name), self.side)) if chainParent: cmds.parent(self.sdkZeroGrp, chainParent) cmds.parentConstraint(chainParent, self.ctls['jaw']['input'], mo=1, n=names.addModifier(self.ctls['jaw']['input'], 'parentConstraint')) cmds.delete(cmds.parentConstraint(self.chain[0], self.sdkZeroGrp)) cmds.delete(cmds.scaleConstraint(self.chain[0], self.sdkZeroGrp)) cmds.delete(cmds.aimConstraint(self.chain[-1], self.sdkZeroGrp, aimVector=[1, 0, 0], upVector=[0, 0, 1], worldUpType='objectrotation', worldUpVector=self.jawBaseUpVector, worldUpObject=chainParent)) # Create a rotation set driven key transform self.sdkRotGrp = cmds.duplicate(self.sdkZeroGrp, n=names.addModifier(self.sdkZeroGrp, 'transform', addSuffix="SetDrivenRot"))[0] # Create a position set driven key transform self.sdkPosGrp = cmds.duplicate(self.sdkZeroGrp, n=names.addModifier(self.sdkZeroGrp, 'transform', addSuffix="SetDrivenPos"))[0] # Parent all groups together cmds.parent(self.sdkRotGrp, self.sdkZeroGrp) cmds.parent(self.sdkPosGrp, self.sdkRotGrp) cmds.parent(self.jawOffset, self.sdkPosGrp) # Create a transform to drive our jaw transformations self.sdkDriverLoc = cmds.spaceLocator(n=names.nodeName('locator', "{0}{1}SdkDriver".format(self.prefix, self.name), ))[0] cmds.delete(cmds.pointConstraint(self.chain[-1], self.sdkDriverLoc)) cmds.hide(self.sdkDriverLoc) self.sdkDriverLocGrp = lib.createNode('transform', names.getDescriptor(self.sdkDriverLoc)) cmds.delete(cmds.pointConstraint(self.chain[-1], self.sdkDriverLocGrp)) cmds.parent(self.sdkDriverLoc, self.sdkDriverLocGrp) cmds.parent(self.sdkDriverLocGrp, self.grpMisc) # Set driven keys posTxAttrPlug = '{0}.translateZ'.format(self.sdkPosGrp) posTzAttrPlug = '{0}.translateX'.format(self.sdkPosGrp) rotTxAttrPlug = '{0}.translateZ'.format(self.sdkRotGrp) rotTzAttrPlug = '{0}.translateX'.format(self.sdkRotGrp) rotRyAttrPlug = '{0}.rotateY'.format(self.sdkRotGrp) rotRzAttrPlug = '{0}.rotateZ'.format(self.sdkRotGrp) # Protraction/Retraction driven keys cmds.setDrivenKeyframe(posTxAttrPlug, currentDriver='{0}.translateX'.format(self.sdkDriverLoc)) cmds.setDrivenKeyframe(posTzAttrPlug, currentDriver='{0}.translateX'.format(self.sdkDriverLoc)) # rename sdk nodes posTxSdk = cmds.listConnections(posTxAttrPlug, s=1, d=0, type='animCurve')[0] posTxSdk = cmds.rename(posTxSdk, '{0}PosTx_SDK'.format(self.prefix)) posTzSdk = cmds.listConnections(posTzAttrPlug, s=1, d=0, type='animCurve')[0] posTzSdk = cmds.rename(posTzSdk, '{0}PosTz_SDK'.format(self.prefix)) # Protraction driven key cmds.setAttr('{0}.translateX'.format(self.sdkDriverLoc), self.sdkDict['protraction']['locValue']) cmds.setAttr(posTxAttrPlug, self.sdkDict['protraction']['posTx']) cmds.setAttr(posTzAttrPlug, self.sdkDict['protraction']['posTz']) cmds.setDrivenKeyframe(posTxAttrPlug, currentDriver='{0}.translateX'.format(self.sdkDriverLoc)) cmds.setDrivenKeyframe(posTzAttrPlug, currentDriver='{0}.translateX'.format(self.sdkDriverLoc)) # Retraction driven key cmds.setAttr('{0}.translateX'.format(self.sdkDriverLoc), self.sdkDict['retraction']['locValue']) cmds.setAttr(posTxAttrPlug, self.sdkDict['retraction']['posTx']) cmds.setAttr(posTzAttrPlug, self.sdkDict['retraction']['posTz']) cmds.setDrivenKeyframe(posTxAttrPlug, currentDriver='{0}.translateX'.format(self.sdkDriverLoc)) cmds.setDrivenKeyframe(posTzAttrPlug, currentDriver='{0}.translateX'.format(self.sdkDriverLoc)) cmds.setAttr('{0}.translateX'.format(self.sdkDriverLoc), 0) # Sideways driven keys cmds.setDrivenKeyframe(rotRzAttrPlug, currentDriver='{0}.translateZ'.format(self.sdkDriverLoc)) # rename sdk node rotRzSdk = cmds.listConnections(rotRzAttrPlug, s=1, d=0, type='animCurve')[0] rotRzSdk = cmds.rename(rotRzSdk, '{0}RotRz_SDK'.format(self.prefix)) # Sideways left driven key cmds.setAttr('{0}.translateZ'.format(self.sdkDriverLoc), self.sdkDict['sideLeft']['locValue']) cmds.setAttr(rotRzAttrPlug, self.sdkDict['sideLeft']['rotRz']) cmds.setDrivenKeyframe(rotRzAttrPlug, currentDriver='{0}.translateZ'.format(self.sdkDriverLoc)) # Sideways right driven key cmds.setAttr('{0}.translateZ'.format(self.sdkDriverLoc), self.sdkDict['sideRight']['locValue']) cmds.setAttr(rotRzAttrPlug, self.sdkDict['sideRight']['rotRz']) cmds.setDrivenKeyframe(rotRzAttrPlug, currentDriver='{0}.translateZ'.format(self.sdkDriverLoc)) cmds.setAttr('{0}.translateZ'.format(self.sdkDriverLoc), 0) # Open/Close driven keys cmds.setDrivenKeyframe(rotRyAttrPlug, currentDriver='{0}.translateY'.format(self.sdkDriverLoc)) cmds.setDrivenKeyframe(rotTxAttrPlug, currentDriver='{0}.translateY'.format(self.sdkDriverLoc)) cmds.setDrivenKeyframe(rotTzAttrPlug, currentDriver='{0}.translateY'.format(self.sdkDriverLoc)) # rename sdk node rotRySdk = cmds.listConnections(rotRyAttrPlug, s=1, d=0, type='animCurve')[0] rotRySdk = cmds.rename(rotRySdk, '{0}RotRy_SDK'.format(self.prefix)) rotTxSdk = cmds.listConnections(rotTxAttrPlug, s=1, d=0, type='animCurve')[0] rotTxSdk = cmds.rename(rotTxSdk, '{0}RotTx_SDK'.format(self.prefix)) rotTzSdk = cmds.listConnections(rotTzAttrPlug, s=1, d=0, type='animCurve')[0] rotTzSdk = cmds.rename(rotTzSdk, '{0}RotTz_SDK'.format(self.prefix)) # Open driven key cmds.setAttr('{0}.translateY'.format(self.sdkDriverLoc), self.sdkDict['open']['locValue']) cmds.setAttr(rotRyAttrPlug, self.sdkDict['open']['rotRy']) cmds.setAttr(rotTxAttrPlug, self.sdkDict['open']['rotTx']) cmds.setAttr(rotTzAttrPlug, self.sdkDict['open']['rotTz']) cmds.setDrivenKeyframe(rotRyAttrPlug, currentDriver='{0}.translateY'.format(self.sdkDriverLoc)) cmds.setDrivenKeyframe(rotTxAttrPlug, currentDriver='{0}.translateY'.format(self.sdkDriverLoc)) cmds.setDrivenKeyframe(rotTzAttrPlug, currentDriver='{0}.translateY'.format(self.sdkDriverLoc)) # Close driven key cmds.setAttr('{0}.translateY'.format(self.sdkDriverLoc), self.sdkDict['close']['locValue']) cmds.setAttr(rotRyAttrPlug, self.sdkDict['close']['rotRy']) cmds.setAttr(rotTxAttrPlug, self.sdkDict['close']['rotTx']) cmds.setAttr(rotTzAttrPlug, self.sdkDict['close']['rotTz']) cmds.setDrivenKeyframe(rotRyAttrPlug, currentDriver='{0}.translateY'.format(self.sdkDriverLoc)) cmds.setDrivenKeyframe(rotTxAttrPlug, currentDriver='{0}.translateY'.format(self.sdkDriverLoc)) cmds.setDrivenKeyframe(rotTzAttrPlug, currentDriver='{0}.translateY'.format(self.sdkDriverLoc)) cmds.setAttr('{0}.translateY'.format(self.sdkDriverLoc), 0) # Set tangents to linear cmds.keyTangent(posTxSdk, itt='linear', ott='linear', e=1) cmds.keyTangent(posTzSdk, itt='linear', ott='linear', e=1) cmds.keyTangent(rotRzSdk, itt='linear', ott='linear', e=1) cmds.keyTangent(rotRySdk, itt='linear', ott='linear', e=1) cmds.keyTangent(rotTxSdk, itt='linear', ott='linear', e=1) cmds.keyTangent(rotTzSdk, itt='linear', ott='linear', e=1) cmds.connectAttr("{0}.{1}".format(ctlDict['ctl'][0], "translate"), "{0}.{1}".format(self.sdkDriverLoc, "translate")) # Set transform limits cmds.transformLimits(ctlDict['ctl'][0], tx=self.sdkDict['limits']['tx'], etx=[1, 1]) cmds.transformLimits(ctlDict['ctl'][0], ty=self.sdkDict['limits']['ty'], ety=[1, 1]) cmds.transformLimits(ctlDict['ctl'][0], tz=self.sdkDict['limits']['tz'], etz=[1, 1]) # ==================== # Curve shape data # ==================== if self.createCurveShapeDataSet: for k in self.ctls: if 'ctl' in self.ctls[k]: cmds.sets(self.ctls[k]['ctl'], add=self.curveShapeDataSet) self.importCurveShapeData()
def grpsToMotionPath(curveName, grpList, name=None, pointConstraint=True, createTangentLocs=False): """ Creates locators matching the number of transforms (grpList) and a motion path for locator which positions locator along by the curve (curveName) and finally locator point constrains each transform (grpList), if so desired """ retData = {} retData['grpMap'] = {} name = name or curveName locList = [] mphList = [] pocList = [] npoc = cmds.createNode('nearestPointOnCurve') crvShape = curveName if not cmds.objectType(crvShape) == 'nurbsCurve': children = cmds.listRelatives(curveName, children=1, type='nurbsCurve') if not children: raise Exception( 'the supplied curve argument {0} is not a curve'.format( curveName)) crvShape = children[0] cmds.connectAttr('{0}.worldSpace[0]'.format(crvShape), '{0}.inputCurve'.format(npoc)) ''' cviName = names.nodeName('curveInfo', '{0}'.format(name)) cvi = cmds.createNode('curveInfo', n=cviName) cmds.connectAttr('{0}.worldSpace[0]'.format(crvShape), '{0}.inputCurve'.format(cvi)) arcLenAttr = '{0}.arcLength'.format(cvi) ''' for i, grp in enumerate(grpList): ''' i = 6 grp = 'test7_jnt' ''' retData['grpMap'][grp] = {} pos = cmds.xform(grp, t=1, ws=1, q=1) cmds.setAttr('{0}.inPosition'.format(npoc), pos[0], pos[1], pos[2]) param = cmds.getAttr('{0}.parameter'.format(npoc)) mphLocName = names.nodeName('locator', '{0}{1}'.format(name, i + 1)) mphLoc = cmds.spaceLocator(n=mphLocName)[0] locList.append(mphLoc) retData['grpMap'][grp]['loc'] = mphLoc crvMphName = names.nodeName('motionPath', '{0}{1}'.format(name, i + 1)) crvMph = cmds.createNode('motionPath', n=crvMphName) retData['grpMap'][grp]['mph'] = crvMph mphList.append(crvMph) cmds.setAttr('{0}.fractionMode'.format(crvMph), 1) cmds.connectAttr('{0}.worldSpace[0]'.format(crvShape), '{0}.geometryPath'.format(crvMph)) cmds.setAttr('{0}.uValue'.format(crvMph), param) cmds.connectAttr('{0}.xCoordinate'.format(crvMph), '{0}.tx'.format(mphLoc)) cmds.connectAttr('{0}.yCoordinate'.format(crvMph), '{0}.ty'.format(mphLoc)) cmds.connectAttr('{0}.zCoordinate'.format(crvMph), '{0}.tz'.format(mphLoc)) if pointConstraint: poc = cmds.pointConstraint(mphLoc, grp, mo=1, n=names.addModifier( grp, 'pointConstraint')) retData['grpMap'][grp]['poc'] = poc cmds.delete(npoc) retData['loc'] = locList retData['poc'] = pocList retData['mph'] = mphList # Start and End tangent locators retData['sTanLoc'] = {} retData['eTanLoc'] = {} if createTangentLocs: # Start mphLocName = names.nodeName('locator', '{0}StartTangent'.format(name)) mphLoc = cmds.spaceLocator(n=mphLocName)[0] retData['sTanLoc']['loc'] = mphLoc crvMphName = names.nodeName('motionPath', '{0}StartTangent'.format(name)) crvMph = cmds.createNode('motionPath', n=crvMphName) retData['sTanLoc']['mph'] = crvMph mphList.append(crvMph) cmds.setAttr('{0}.fractionMode'.format(crvMph), 1) # Start connections cmds.connectAttr('{0}.worldSpace[0]'.format(crvShape), '{0}.geometryPath'.format(crvMph)) cmds.setAttr('{0}.uValue'.format(crvMph), 0.001) cmds.connectAttr('{0}.xCoordinate'.format(crvMph), '{0}.tx'.format(mphLoc)) cmds.connectAttr('{0}.yCoordinate'.format(crvMph), '{0}.ty'.format(mphLoc)) cmds.connectAttr('{0}.zCoordinate'.format(crvMph), '{0}.tz'.format(mphLoc)) # End mphLocName = names.nodeName('locator', '{0}EndTangent'.format(name)) mphLoc = cmds.spaceLocator(n=mphLocName)[0] retData['eTanLoc']['loc'] = mphLoc crvMphName = names.nodeName('motionPath', '{0}EndTangent'.format(name)) crvMph = cmds.createNode('motionPath', n=crvMphName) retData['eTanLoc']['mph'] = crvMph mphList.append(crvMph) cmds.setAttr('{0}.fractionMode'.format(crvMph), 1) # Start connections cmds.connectAttr('{0}.worldSpace[0]'.format(crvShape), '{0}.geometryPath'.format(crvMph)) cmds.setAttr('{0}.uValue'.format(crvMph), 0.999) cmds.connectAttr('{0}.xCoordinate'.format(crvMph), '{0}.tx'.format(mphLoc)) cmds.connectAttr('{0}.yCoordinate'.format(crvMph), '{0}.ty'.format(mphLoc)) cmds.connectAttr('{0}.zCoordinate'.format(crvMph), '{0}.tz'.format(mphLoc)) return retData