def verify_customizationData(i_network, skinDepth=2.5): """ Gather info from customization asset from morpheusRig_v2.core import MorpheusFactory as morphyF reload(morphyF) morphyF.verify_customizationData('Morphy_customizationNetwork') """ #These are the controls we'll drive positional data from to plug to our modules d_initialData = {} #>>> Verify our arg try: i_network.mNode except: if mc.objExists(i_network): i_network = r9Meta.MetaClass(i_network) else: log.error("'%s' doesn't exist" % i_network) return False assert i_network.mClass == 'cgmMorpheusMakerNetwork', "Not a cgmMorpheusMakerNetwork. Aborted!" #>> Collect our positional info #==================================================================== i_objSet = i_network.objSetAll #Should I use this or the message info log.debug(i_objSet.value) controlBuffer = i_network.objSetAll.value for moduleKey in l_modulesToDoOrder: if moduleKey not in d_moduleControls.keys(): log.warning("Missing controls info for: '%s'" % moduleKey) return False log.debug("On moduleKey: '%s'" % moduleKey) controls = d_moduleControls.get(moduleKey) posBuffer = [] for c in controls: if not mc.objExists(c): log.warning("Necessary positioning control not found: '%s'" % c) return False else: log.debug("Found: '%s'" % c) i_c = cgmMeta.cgmNode(c) if i_c.isComponent(): #If it's a component i_loc = cgmMeta.cgmObject( mc.spaceLocator()[0]) #make a loc Snap.go(i_loc.mNode, targets=c, move=True, orient=True) #Snap to the surface i_loc.tz -= skinDepth #Offset on z by skin depth pos = i_loc.getPosition() #get position i_loc.delete() else: pos = i_c.getPosition() if not pos: return False posBuffer.append(pos) d_initialData[moduleKey] = posBuffer return d_initialData
def verify_customizationData(i_network, skinDepth = 2.5): """ Gather info from customization asset from morpheusRig_v2.core import MorpheusFactory as morphyF reload(morphyF) morphyF.verify_customizationData('Morphy_customizationNetwork') """ #These are the controls we'll drive positional data from to plug to our modules d_initialData = {} #>>> Verify our arg try:i_network.mNode except: if mc.objExists(i_network): i_network = r9Meta.MetaClass(i_network) else: log.error("'%s' doesn't exist"%i_network) return False assert i_network.mClass == 'cgmMorpheusMakerNetwork',"Not a cgmMorpheusMakerNetwork. Aborted!" #>> Collect our positional info #==================================================================== i_objSet = i_network.objSetAll#Should I use this or the message info log.debug(i_objSet.value) controlBuffer = i_network.objSetAll.value for moduleKey in l_modulesToDoOrder: if moduleKey not in d_moduleControls.keys(): log.warning("Missing controls info for: '%s'"%moduleKey) return False log.debug("On moduleKey: '%s'"%moduleKey) controls = d_moduleControls.get(moduleKey) posBuffer = [] for c in controls: if not mc.objExists(c): log.warning("Necessary positioning control not found: '%s'"%c) return False else: log.debug("Found: '%s'"%c) i_c = cgmMeta.cgmNode(c) if i_c.isComponent():#If it's a component i_loc = cgmMeta.cgmObject(mc.spaceLocator()[0])#make a loc Snap.go(i_loc.mNode,targets = c,move = True, orient = True)#Snap to the surface i_loc.tz -= skinDepth#Offset on z by skin depth pos = i_loc.getPosition()#get position i_loc.delete() else: pos = i_c.getPosition() if not pos:return False posBuffer.append(pos) d_initialData[moduleKey] = posBuffer return d_initialData
log.debug("|{0}| >> vectorOffset: {1}".format(_str_func, vectorOffset)) if posOffset is not None: if MATH.is_vector_equivalent(posOffset, [0, 0, 0]): posOffset = None #midMeshCast if midMeshCast: axisToCheck = axisToCheck or [ a for a in ['x', 'y', 'z'] if a != latheAxis ] log.debug("createMeshSliceCurve>> axisToCheck: %s" % axisToCheck) try: Snap.go(mi_loc.parent, mesh[0], True, False, midSurfacePos=True, axisToCheck=axisToCheck) except: log.error("createMeshSliceCurve >> failed to midMeshCast") #Rotate obj mi_rotObj = mi_loc if rotateBank is not None and type(rotateBank) is not list: rotateGroup = mi_loc.doGroup(True) mi_rotObj = cgmMeta.cgmObject(rotateGroup) mi_loc.__setattr__('rotate%s' % bankAxis.capitalize(), rotateBank) #Figure out the rotateBaseValue if minRotate is not None: rotateFloor = minRotate
reload(cgmMeta) obj = mc.ls(sl=True)[0] or False obj = '' objList = [] #>>> Modules #======================================================= i_obj = cgmMeta.cgmObject(mc.spaceLocator()[0]) i_obj = cgmMeta.cgmNode(obj) i_obj = cgmMeta.cgmNode(mc.ls(sl=True)[0]) i_obj.getComponents() i_obj.getComponent() a = i_obj i_obj.mNode i_obj.isTransform() Snap.go(i_obj) mc.xform(q_object, q=True, os=True, t = True) mc.xform(a.getComponent(), q=True, ws=True, rp=True) mc.pointPosition(a.getComponent()) cgmMeta.cgmNode(q_object).getPosition(True) cgmMeta.cgmNode(q_object).getPosition(False) i_obj = cgmMeta.cgmObject(mc.spaceLocator()[0]) Snap.go('hips_anim_shape1.ep[3]',targets = q_object,orient = False,posOffset=[0,0,2], snapToSurface=True,softSelection=True,softSelectDistance=20) Snap.go(i_obj.getComponent(),targets = q_object,orient = False,posOffset=[0,0,2], snapToSurface=True,softSelection=True,softSelectDistance=20) Snap.go(i_obj.getComponent(),targets = q_object,orient = False,snapToSurface=True,snapComponents=True) Snap.go(i_obj.mNode,targets = q_object,move = False, orient = True,snapToSurface=True) Snap.go(i_obj,targets = q_object,orient = False,snapToSurface=True) Snap.go(i_obj,targets = q_object,snapToSurface=True,posOffset=[0,0,10]) Snap.go(i_obj,targets = q_object,orient = True, snapToSurface=True,posOffset=[0,0,1.5])
cgm.core._reload() import maya.cmds as mc import Red9.core.Red9_Meta as r9Meta reload(r9Meta) from cgm.lib import curves from cgm.core.classes import SnapFactory as Snap reload(Snap) from cgm.core import cgm_Meta as cgmMeta reload(cgmMeta) obj = mc.ls(sl=True)[0] or False obj = '' objList = [] #>>>aim Snap.go(i_obj,target,False,orient = False, aim = True,aimVector=[0,0,-1],upVector=[0,0,-1]) Snap.go(i_obj,target,False,orient = True) target = mc.ls(sl=True)[0] or [] #>>> Modules #======================================================= i_obj = cgmMeta.cgmObject(mc.spaceLocator()[0]) i_obj = cgmMeta.cgmNode(obj) i_obj = cgmMeta.cgmNode(mc.ls(sl=True)[0]) i_obj.getComponents() i_obj.getComponent() a = i_obj i_obj.mNode i_obj.isTransform() Snap.go(i_obj)
def createWrapControlShape(targetObjects, targetGeo = None, latheAxis = 'z',aimAxis = 'y+',objectUp = 'y+', points = 8, curveDegree = 1, insetMult = None,#Inset multiplier posOffset = [], rootOffset = [],#offset root before cast rootRotate = None, joinMode = False, extendMode = None, closedCurve = True, l_specifiedRotates = None, maxDistance = 1000, closestInRange = True, midMeshCast = False, rotateBank = None, joinHits = None,#keys to processed hits to see what to join axisToCheck = ['x','y'], ):#'segment,radial,disc' """ Function for creating control curves from other objects. Currently assumes z aim, y up 1) Cather info 2) Get initial curves 3) Store info 4) return TODO: Change offsets to use lathe axis rather than """ _str_funcName = "createWrapControlShape" log.debug(">> %s >> "%(_str_funcName) + "="*75) if type(targetObjects) not in [list,tuple]:targetObjects = [targetObjects] if not targetGeo: raise NotImplementedError, "Must have geo for now" if len(mc.ls(targetGeo))>1: raise StandardError,"createWrapControlShape>> More than one mesh named: %s"%targetGeo assert type(points) is int,"Points must be int: %s"%points assert type(curveDegree) is int,"Points must be int: %s"%points assert curveDegree > 0,"Curve degree must be greater than 1: %s"%curveDegree if posOffset is not None and len(posOffset) and len(posOffset)!=3:raise StandardError, "posOffset must be len(3): %s | len: %s"%(posOffset,len(posOffset)) if rootOffset is not None and len(rootOffset) and len(rootOffset)!=3:raise StandardError, "rootOffset must be len(3): %s | len: %s"%(rootOffset,len(rootOffset)) if rootRotate is not None and len(rootRotate) and len(rootRotate)!=3:raise StandardError, "rootRotate must be len(3): %s | len: %s"%(rootRotate,len(rootRotate)) if extendMode in ['loliwrap'] and insetMult is None:insetMult = 1 for axis in ['x','y','z']: if axis in latheAxis.lower():latheAxis = axis log.debug("targetObjects: %s"%targetObjects) if len(aimAxis) == 2:single_aimAxis = aimAxis[0] else:single_aimAxis = aimAxis log.debug("Single aim: %s"%single_aimAxis) log.debug("createWrapControlShape>> midMeshCast: %s"%midMeshCast) #>> Info l_groupsBuffer = [] il_curvesToCombine = [] l_sliceReturns = [] #Need to do more to get a better size #>> Build curves #================================================================= #> Root curve # log.debug("RootRotate: %s"%rootRotate) mi_rootLoc = cgmMeta.cgmNode(targetObjects[0]).doLoc() if rootOffset: log.debug("rootOffset: %s"%rootOffset) mc.move(rootOffset[0],rootOffset[1],rootOffset[2], [mi_rootLoc.mNode], r=True, rpr = True, os = True, wd = True) if rootRotate is not None and len(rootRotate): log.debug("rootRotate: %s"%rootRotate) mc.rotate(rootRotate[0],rootRotate[1],rootRotate[2], [mi_rootLoc.mNode], os = True,r=True) #>> Root mi_rootLoc.doGroup()#Group to zero if extendMode == 'segment': log.debug("segment mode. Target len: %s"%len(targetObjects[1:])) try: if len(targetObjects) < 2: log.warning("Segment build mode only works with two objects or more") else: if insetMult is not None: rootDistanceToMove = distance.returnDistanceBetweenObjects(targetObjects[0],targetObjects[1]) log.debug("rootDistanceToMove: %s"%rootDistanceToMove) mi_rootLoc.__setattr__('t%s'%latheAxis,rootDistanceToMove*insetMult) #mi_rootLoc.tz = (rootDistanceToMove*insetMult)#Offset it #Notes -- may need to play with up object for aim snapping #mi_upLoc = cgmMeta.cgmNode(targetObjects[0]).doLoc() #mi_upLoc.doGroup()#To zero objectUpVector = dictionary.returnStringToVectors(objectUp) log.debug("objectUpVector: %s"%objectUpVector) #mi_uploc for i,obj in enumerate(targetObjects[1:]): log.debug("i: %s"%i) #> End Curve mi_endLoc = cgmMeta.cgmNode(obj).doLoc() aimVector = dictionary.returnStringToVectors(latheAxis+'-') log.debug("segment aimback: %s"%aimVector) #Snap.go(mi_endLoc.mNode,mi_rootLoc.mNode,move=False,aim=True,aimVector=aimVector,upVector=objectUpVector) Snap.go(mi_endLoc.mNode,mi_rootLoc.mNode,move=False,orient=True) mi_endLoc.doGroup() if i == len(targetObjects[1:])-1: if insetMult is not None: log.debug("segment insetMult: %s"%insetMult) distanceToMove = distance.returnDistanceBetweenObjects(targetObjects[-1],targetObjects[0]) log.debug("distanceToMove: %s"%distanceToMove) #mi_endLoc.tz = -(distanceToMove*insetMult)#Offset it mi_endLoc.__setattr__('t%s'%latheAxis,-(distanceToMove*insetMult)) log.debug("segment lathe: %s"%latheAxis) log.debug("segment aim: %s"%aimAxis) log.debug("segment rotateBank: %s"%rotateBank) d_endCastInfo = createMeshSliceCurve(targetGeo,mi_endLoc,midMeshCast=midMeshCast,curveDegree=curveDegree,latheAxis=latheAxis,aimAxis=aimAxis,posOffset = posOffset,points = points,returnDict=True,closedCurve = closedCurve, maxDistance = maxDistance, closestInRange=closestInRange, rotateBank=rotateBank, l_specifiedRotates = l_specifiedRotates,axisToCheck = axisToCheck) l_sliceReturns.append(d_endCastInfo) mi_end = cgmMeta.cgmObject(d_endCastInfo['curve']) il_curvesToCombine.append(mi_end) mc.delete(mi_endLoc.parent)#delete the loc except StandardError,error: raise StandardError,"createWrapControlShape>> segment wrap fail! | %s"%error
il_curvesToCombine.append(cgmMeta.cgmObject(returnBuffer2)) mi_rootLoc.rotate = [0,0,0] #Now cast our root since we needed to move it with segment mode before casting if extendMode == 'cylinder': mi_rootLoc.__setattr__('t%s'%latheAxis,-discOffset) d_rootCastInfo = createMeshSliceCurve(targetGeo,mi_rootLoc,curveDegree=curveDegree,latheAxis=latheAxis,midMeshCast=midMeshCast,aimAxis=aimAxis,posOffset = posOffset,points = points,returnDict=True,closedCurve = closedCurve, maxDistance = maxDistance, closestInRange=closestInRange, rotateBank=rotateBank, l_specifiedRotates = l_specifiedRotates,axisToCheck = axisToCheck) if extendMode == 'disc': l_sliceReturns.insert(1,d_rootCastInfo) else: l_sliceReturns.insert(0,d_rootCastInfo) #Special loli stuff if extendMode == 'loliwrap': Snap.go(i_ball.mNode,mi_rootLoc.mNode,True, True)#Snap to main object log.debug("hitReturns: %s"%d_rootCastInfo['hitReturns']) mi_crv = cgmMeta.cgmObject( d_rootCastInfo['curve'] ) #Pos data pos = distance.returnWorldSpacePosition("%s"%distance.returnMidU(mi_crv.mNode)) dist = distance.returnDistanceBetweenPoints(i_ball.getPosition(),pos) if '-' in aimAxis: distM = -dist else: distM = dist log.debug("distM: %s"%distM) #Move the ball pBuffer = i_ball.doGroup()
def createWrapControlShape(targetObjects, targetGeo = None, latheAxis = 'z',aimAxis = 'y+',objectUp = 'y+', points = 8, curveDegree = 1, insetMult = None,#Inset multiplier posOffset = [], rootOffset = [],#offset root before cast rootRotate = None, joinMode = False, extendMode = None, closedCurve = True, l_specifiedRotates = None, maxDistance = 1000, closestInRange = True, midMeshCast = False, rotateBank = None, joinHits = None,#keys to processed hits to see what to join axisToCheck = ['x','y'], ):#'segment,radial,disc' """ This function lathes an axis of an object, shoot rays out the aim axis at the provided mesh and returning hits. it then uses this information to build a curve shape. :parameters: mesh(string) | Surface to cast at mi_obj(string/mObj) | our casting object latheAxis(str) | axis of the objec to lathe TODO: add validation aimAxis(str) | axis to shoot out of points(int) | how many points you want in the curve curveDegree(int) | specified degree minRotate(float) | let's you specify a valid range to shoot maxRotate(float) | let's you specify a valid range to shoot posOffset(vector) | transformational offset for the hit from a normalized locator at the hit. Oriented to the surface markHits(bool) | whether to keep the hit markers returnDict(bool) | whether you want all the infomation from the process. rotateBank (float) | let's you add a bank to the rotation object l_specifiedRotates(list of values) | specify where to shoot relative to an object. Ignores some other settings maxDistance(float) | max distance to cast rays closestInRange(bool) | True by default. If True, takes first hit. Else take the furthest away hit in range. :returns: Dict ------------------------------------------------------------------ 'source'(double3) | point from which we cast 'hit'(double3) | world space points | active during single return 'hits'(list) | world space points | active during multi return 'uv'(double2) | uv on surface of hit | only works for mesh surfaces :raises: Exception | if reached """ _str_funcName = "createWrapControlShape" log.debug(">> %s >> "%(_str_funcName) + "="*75) _joinModes = [] _extendMode = [] if type(targetObjects) not in [list,tuple]:targetObjects = [targetObjects] targetGeo = cgmValid.objStringList(targetGeo, calledFrom = _str_funcName) assert type(points) is int,"Points must be int: %s"%points assert type(curveDegree) is int,"Points must be int: %s"%points assert curveDegree > 0,"Curve degree must be greater than 1: %s"%curveDegree if posOffset is not None and len(posOffset) and len(posOffset)!=3:raise StandardError, "posOffset must be len(3): %s | len: %s"%(posOffset,len(posOffset)) if rootOffset is not None and len(rootOffset) and len(rootOffset)!=3:raise StandardError, "rootOffset must be len(3): %s | len: %s"%(rootOffset,len(rootOffset)) if rootRotate is not None and len(rootRotate) and len(rootRotate)!=3:raise StandardError, "rootRotate must be len(3): %s | len: %s"%(rootRotate,len(rootRotate)) if extendMode in ['loliwrap','cylinder','disc'] and insetMult is None:insetMult = 1 for axis in ['x','y','z']: if axis in latheAxis.lower():latheAxis = axis log.debug("targetObjects: %s"%targetObjects) if len(aimAxis) == 2:single_aimAxis = aimAxis[0] else:single_aimAxis = aimAxis log.debug("Single aim: %s"%single_aimAxis) log.debug("createWrapControlShape>> midMeshCast: %s"%midMeshCast) #>> Info l_groupsBuffer = [] il_curvesToCombine = [] l_sliceReturns = [] #Need to do more to get a better size #>> Build curves #================================================================= #> Root curve # log.debug("RootRotate: %s"%rootRotate) mi_rootLoc = cgmMeta.cgmNode(targetObjects[0]).doLoc() if rootOffset: log.debug("rootOffset: %s"%rootOffset) mc.move(rootOffset[0],rootOffset[1],rootOffset[2], [mi_rootLoc.mNode], r=True, rpr = True, os = True, wd = True) if rootRotate is not None and len(rootRotate): log.debug("rootRotate: %s"%rootRotate) mc.rotate(rootRotate[0],rootRotate[1],rootRotate[2], [mi_rootLoc.mNode], os = True,r=True) #>> Root mi_rootLoc.doGroup()#Group to zero if extendMode == 'segment': log.debug("segment mode. Target len: %s"%len(targetObjects[1:])) try: if len(targetObjects) < 2: log.warning("Segment build mode only works with two objects or more") else: if insetMult is not None: rootDistanceToMove = distance.returnDistanceBetweenObjects(targetObjects[0],targetObjects[1]) log.debug("rootDistanceToMove: %s"%rootDistanceToMove) mi_rootLoc.__setattr__('t%s'%latheAxis,rootDistanceToMove*insetMult) #mi_rootLoc.tz = (rootDistanceToMove*insetMult)#Offset it #Notes -- may need to play with up object for aim snapping #mi_upLoc = cgmMeta.cgmNode(targetObjects[0]).doLoc() #mi_upLoc.doGroup()#To zero objectUpVector = dictionary.returnStringToVectors(objectUp) log.debug("objectUpVector: %s"%objectUpVector) #mi_uploc for i,obj in enumerate(targetObjects[1:]): log.debug("i: %s"%i) #> End Curve mi_endLoc = cgmMeta.cgmNode(obj).doLoc() aimVector = dictionary.returnStringToVectors(latheAxis+'-') log.debug("segment aimback: %s"%aimVector) #Snap.go(mi_endLoc.mNode,mi_rootLoc.mNode,move=False,aim=True,aimVector=aimVector,upVector=objectUpVector) Snap.go(mi_endLoc.mNode,mi_rootLoc.mNode,move=False,orient=True) mi_endLoc.doGroup() if i == len(targetObjects[1:])-1: if insetMult is not None: log.debug("segment insetMult: %s"%insetMult) distanceToMove = distance.returnDistanceBetweenObjects(targetObjects[-1],targetObjects[0]) log.debug("distanceToMove: %s"%distanceToMove) #mi_endLoc.tz = -(distanceToMove*insetMult)#Offset it mi_endLoc.__setattr__('t%s'%latheAxis,-(distanceToMove*insetMult)) log.debug("segment lathe: %s"%latheAxis) log.debug("segment aim: %s"%aimAxis) log.debug("segment rotateBank: %s"%rotateBank) d_endCastInfo = createMeshSliceCurve(targetGeo,mi_endLoc,midMeshCast=midMeshCast,curveDegree=curveDegree,latheAxis=latheAxis,aimAxis=aimAxis,posOffset = posOffset,points = points,returnDict=True,closedCurve = closedCurve, maxDistance = maxDistance, closestInRange=closestInRange, rotateBank=rotateBank, l_specifiedRotates = l_specifiedRotates,axisToCheck = axisToCheck) l_sliceReturns.append(d_endCastInfo) mi_end = cgmMeta.cgmObject(d_endCastInfo['curve']) il_curvesToCombine.append(mi_end) mc.delete(mi_endLoc.parent)#delete the loc except StandardError,error: raise StandardError,"createWrapControlShape>> segment wrap fail! | %s"%error
def build_FKIK(goInstance = None): class fncWrap(modUtils.rigStep): def __init__(self,goInstance = None): super(fncWrap, self).__init__(goInstance) self._str_funcName = 'build_FKIK(%s)'%self.d_kws['goInstance']._strShortName self.__dataBind__() self.l_funcSteps = [{'step':'Build NOT BROKEN UP YET','call':self.build}] #================================================================= def build(self):#================================================================================ #>>>Get data ml_controlsFK = self._go._i_rigNull.msgList_get('controlsFK') ml_rigJoints = self._go._i_rigNull.msgList_get('rigJoints') ml_blendJoints = self._go._i_rigNull.msgList_get('blendJoints') ml_fkJoints = self._go._i_rigNull.msgList_get('fkJoints') ml_ikJoints = self._go._i_rigNull.msgList_get('ikJoints') mi_settings = self._go._i_rigNull.settings aimVector = dictionary.stringToVectorDict.get("%s+"%self._go._jointOrientation[0]) upVector = dictionary.stringToVectorDict.get("%s+"%self._go._jointOrientation[1]) outVector = dictionary.stringToVectorDict.get("%s+"%self._go._jointOrientation[2]) mi_controlIK = self._go._i_rigNull.controlIK for chain in [ml_ikJoints,ml_blendJoints]: chain[0].parent = self._go._i_constrainNull.mNode self.ml_fkAttachJoints = [] if self._go._str_mirrorDirection == 'Right':#mirror control setup self.ml_fkAttachJoints = self._go._i_rigNull.msgList_get('fkAttachJoints') #for more stable ik, we're gonna lock off the lower channels degrees of freedom for chain in [ml_ikJoints]: for axis in self._go._jointOrientation[:2]: log.info(axis) for i_j in chain[1:]: attributes.doSetAttr(i_j.mNode,"jointType%s"%axis.upper(),1) #============================================================= try:#>>>Finger Root Control and root follow for attr in ['tx','ty','tz']:#Unlock a few things i_attr = cgmMeta.cgmAttr(ml_fkJoints[0],attr) i_attr.p_keyable = True i_attr.p_locked = False #we have to rebuild a little so that we can use our fk base control both for fk and ik #Create a orient group that tracks the module constrain null if self._go._partType == 'finger': buffer_fkGroup = ml_fkJoints[0].parent i_orientGroup = cgmMeta.asMeta( ml_fkJoints[1].doGroup(True),'cgmObject',setClass=True ) i_orientGroup.addAttr('cgmTypeModifier','toOrient') i_orientGroup.doName() #constrain it str_orConst = mc.orientConstraint(self._go._i_constrainNull.mNode,i_orientGroup.mNode,maintainOffset = True)[0] self._go._i_constrainNull.connectChildNode(i_orientGroup,'fingerRoot','owner')#Connect i_orientGroup.parent = self._go._i_constrainNull.mNode attributes.doSetLockHideKeyableAttr(i_orientGroup.mNode)#lockNHide i_parentGroup = cgmMeta.asMeta( i_orientGroup.doGroup(True),'cgmObject',setClass=True ) i_parentGroup.addAttr('cgmTypeModifier','toParent') i_parentGroup.doName() str_prntConst = mc.parentConstraint( ml_fkJoints[0].mNode,i_parentGroup.mNode,maintainOffset = True)[0] i_parentGroup.parent = buffer_fkGroup #attributes.doSetLockHideKeyableAttr(ml_fkJoints[0].mNode,lock = False, visible=True, keyable=True, channels=['tx','ty','tz']) #Constrain ik base to fk base mc.orientConstraint(ml_fkJoints[0].mNode,ml_ikJoints[0].mNode,maintainOffset = True) ml_fkJoints[0].parent = self._go._i_constrainNull.mNode except Exception,error: raise Exception,"%s.build_FKIK>>> Finger Root Control error: %s"%(self._go._strShortName,error) #============================================================= try:#>>>FK Length connector if self._go._partType == 'finger': ml_fkToDo = ml_fkJoints[1:-1] else:#thumb ml_fkToDo = ml_fkJoints[:-1] log.info([i_jnt.getShortName() for i_jnt in ml_fkToDo]) for i,i_jnt in enumerate(ml_fkToDo): rUtils.addJointLengthAttr(i_jnt,orientation=self._go._jointOrientation) #IK rUtils.addJointLengthAttr(ml_ikJoints[-2],[mi_controlIK,'length'],orientation=self._go._jointOrientation) except Exception,error: raise Exception,"%s.build_FKIK>>> fk length connect error: %s"%(self._go._strShortName,error) #============================================================= try:#>>>IK No Flip Chain self._go._verify_moduleMasterScale() mPlug_masterScale = self._go._get_masterScalePlug() ml_ikNoFlipJoints = ml_ikJoints#Link if self._go._partType == 'finger': mi_ikStart = ml_ikNoFlipJoints[1] mi_ikEnd = ml_ikNoFlipJoints[-2] mi_constraintGroup = self._go._i_constrainNull.fingerRoot else:#thumb mi_ikStart = ml_ikNoFlipJoints[0] mi_ikEnd = ml_ikNoFlipJoints[-2] mi_constraintGroup = self._go._i_constrainNull i_tmpLoc = mi_ikEnd.doLoc()#loc the first real i_tmpLoc.parent = mi_controlIK.mNode str_twistGroup = i_tmpLoc.doGroup(True) f_dist = distance.returnDistanceBetweenPoints(mi_ikStart.getPosition(),ml_ikNoFlipJoints[-1].getPosition()) #Measure first finger joint to end f_dist = f_dist * 1.5 if self._go._direction == 'left':#if right, rotate the pivots i_tmpLoc.__setattr__('t%s'%self._go._jointOrientation[2],-f_dist) else: i_tmpLoc.__setattr__('t%s'%self._go._jointOrientation[2],f_dist) #Create no flip finger IK d_ankleNoFlipReturn = rUtils.IKHandle_create(mi_ikStart.mNode,mi_ikEnd.mNode,lockMid=False, nameSuffix = 'noFlip',rpHandle=True,controlObject=mi_controlIK,addLengthMulti=True, globalScaleAttr=mPlug_masterScale.p_combinedName, stretch='translate',moduleInstance=self._go._mi_module) mi_fingerIKHandleNF = d_ankleNoFlipReturn['mi_handle'] ml_distHandlesNF = d_ankleNoFlipReturn['ml_distHandles'] mi_rpHandleNF = d_ankleNoFlipReturn['mi_rpHandle'] #No Flip RP handle Snap.go(mi_rpHandleNF,i_tmpLoc.mNode,True)#Snape to hand control, then move it out... i_tmpLoc.delete() mi_rpHandleNF.doCopyNameTagsFromObject(self._go._mi_module.mNode, ignore = ['cgmName','cgmType']) mi_rpHandleNF.addAttr('cgmName','%sPoleVector'%self._go._partName, attrType = 'string') mi_rpHandleNF.addAttr('cgmTypeModifier','noFlip') mi_rpHandleNF.doName() #spin #========================================================================================= #Make a spin group i_spinGroup = cgmMeta.cgmObject(str_twistGroup) i_spinGroup.doCopyNameTagsFromObject(self._go._mi_module.mNode, ignore = ['cgmName','cgmType']) i_spinGroup.addAttr('cgmName','%sNoFlipSpin'%self._go._partName) i_spinGroup.doName() i_spinGroup.doZeroGroup() mi_rpHandleNF.parent = i_spinGroup.mNode #Setup arg mPlug_fingerSpin = cgmMeta.cgmAttr(mi_controlIK,'fingerSpin') mPlug_fingerSpin.doConnectOut("%s.r%s"%(i_spinGroup.mNode,self._go._jointOrientation[0])) #>>>Parent IK handles mi_fingerIKHandleNF.parent = mi_controlIK.mNode#handle to control ml_distHandlesNF[-1].parent = mi_controlIK.mNode#handle to control ml_distHandlesNF[0].parent = mi_constraintGroup.mNode#start to root ml_distHandlesNF[1].parent = mi_constraintGroup.mNode#mid to root #>>> Fix our ik_handle twist at the end of all of the parenting rUtils.IKHandle_fixTwist(mi_fingerIKHandleNF)#Fix the twist except Exception,error: raise Exception,"%s.build_FKIK>>> IK No Flip error: %s"%(self._go._strShortName,error)