def findFurthestPointInRangeFromObject(self): ''' Find the furthest point in range on an axis. Useful for getting to the outershell of a surface ''' try: self._str_funcName = 'findFurthestPointInRangeFromObject' log.debug(">>> %s >> "%self._str_funcName + "="*75) if len(mc.ls(surface))>1: raise StandardError,"findFurthestPointInRangeFromObject>>> More than one surface named: %s"%surface #>>>First cast to get our initial range self.d_firstcast = findSurfaceIntersectionFromObjectAxis(surface, obj, axis, vector, maxDistance) if not self.d_firstcast.get('hit'): raise StandardError,"findFurthestPointInRangeFromObject>>> first cast failed to hit" self.baseDistance = distance.returnDistanceBetweenPoints(distance.returnWorldSpacePosition(obj),self.d_firstcast['hit']) log.debug("findFurthestPointInRangeFromObject>>>baseDistance: %s"%self.baseDistance) self.castDistance = self.baseDistance + pierceDepth log.debug("findFurthestPointInRangeFromObject>>>castDistance: %s"%castDistance) self.l_positions = [] self.d_castReturn = findSurfaceIntersectionFromObjectAxis(surface, obj, axis, maxDistance = castDistance, singleReturn=False) or {} log.debug("2nd castReturn: %s"%self.d_castReturn) if self.d_castReturn.get('hits'): self.closestPoint = distance.returnFurthestPoint(distance.returnWorldSpacePosition(obj),self.d_castReturn.get('hits')) or False self.d_castReturn['hit'] = self.closestPoint return self.d_castReturn except StandardError,error: for kw in [surface,obj,axis,pierceDepth,vector,maxDistance]: log.debug("%s"%kw) raise StandardError, " >> error"
def findFurthestPointInRangeFromObject(mesh,obj,axis = 'z+', pierceDepth = 4, vector = False, maxDistance = 1000): """ Find the furthest point in range on an axis. Useful for getting to the outershell of a mesh """ try: _str_funcName = 'findFurthestPointInRangeFromObject' log.debug(">>> %s >> "%_str_funcName + "="*75) if len(mc.ls(mesh))>1: raise StandardError,"findFurthestPointInRangeFromObject>>> More than one mesh named: %s"%mesh #>>>First cast to get our initial range d_firstcast = findMeshIntersectionFromObjectAxis(mesh, obj, axis = axis, vector=vector, maxDistance = maxDistance) if not d_firstcast.get('hit'): raise StandardError,"findFurthestPointInRangeFromObject>>> first cast failed to hit" baseDistance = distance.returnDistanceBetweenPoints(distance.returnWorldSpacePosition(obj),d_firstcast['hit']) log.debug("findFurthestPointInRangeFromObject>>>baseDistance: %s"%baseDistance) castDistance = baseDistance + pierceDepth log.debug("findFurthestPointInRangeFromObject>>>castDistance: %s"%castDistance) l_positions = [] d_castReturn = findMeshIntersectionFromObjectAxis(mesh, obj, axis=axis, maxDistance = castDistance, singleReturn=False) or {} log.debug("2nd castReturn: %s"%d_castReturn) if d_castReturn.get('hits'): closestPoint = distance.returnFurthestPoint(distance.returnWorldSpacePosition(obj),d_castReturn.get('hits')) or False d_castReturn['hit'] = closestPoint return d_castReturn except StandardError,error: for kw in [mesh,obj,axis,pierceDepth,vector,maxDistance]: log.debug("%s"%kw) raise StandardError, "%s >> error: %s"%(_str_funcName,error)
def getDistanceToCheck(self, m): assert mc.objExists( m), "'%s' doesn't exist. Couldn't check distance!" % m baseDistance = distance.returnDistanceBetweenPoints( self.clickPos, distance.returnWorldSpacePosition(m)) baseSize = distance.returnBoundingBoxSize(m) return distance.returnWorldSpaceFromMayaSpace(baseDistance + sum(baseSize))
def getDistanceToCheck(self,m): assert mc.objExists(m), "'%s' doesn't exist. Couldn't check distance!"%m baseDistance = distance.returnDistanceBetweenPoints(self.clickPos, distance.returnWorldSpacePosition(m)) baseSize = distance.returnBoundingBoxSize(m) return distance.returnWorldSpaceFromMayaSpace( baseDistance + sum(baseSize) )
def returnBaseControlSize(mi_obj, mesh, axis=True, closestInRange=True): """ >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DESCRIPTION: Figure out the base size for a control from a point in space within a mesh ARGUMENTS: mi_obj(cgmObject instance) mesh(obj) = ['option1','option2'] axis(list) -- what axis to check RETURNS: axisDistances(dict) -- axis distances, average >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> """ try: #>>Figure out the axis to do log.info(mi_obj) mi_obj = cgmMeta.validateObjArg(mi_obj, cgmMeta.cgmObject, noneValid=True) if not mi_obj: raise ValueError, "mi_obj kw: {0} ".format(mi_obj) _str_func = "returnBaseControlSize(%s)" % mi_obj.p_nameShort log.debug(">> %s " % (_str_func) + "=" * 75) start = time.clock() log.debug("%s >> mesh: %s " % (_str_func, mesh)) log.debug("%s >> axis: %s " % (_str_func, axis)) try: d_axisToDo = {} if axis == True: axis = ['x', 'y', 'z'] if type(axis) in [list, tuple]: for a in axis: if a in dictionary.stringToVectorDict.keys(): if list(a)[0] in d_axisToDo.keys(): d_axisToDo[list(a)[0]].append(a) else: d_axisToDo[list(a)[0]] = [a] elif type(a) is str and a.lower() in ['x', 'y', 'z']: buffer = [] buffer.append('%s+' % a.lower()) buffer.append('%s-' % a.lower()) d_axisToDo[a.lower()] = buffer else: log.warning("Don't know what with: '%s'" % a) log.debug("%s >> d_axisToDo: %s " % (_str_func, d_axisToDo)) if not d_axisToDo: return False except Exception, error: raise Exception, "Axis check | {0}".format(error) #>> d_returnDistances = {} for axis in d_axisToDo: log.debug("Checking: %s" % axis) directions = d_axisToDo[axis] if len(directions) == 1: #gonna multiply our distance try: info = RayCast.findMeshIntersectionFromObjectAxis( mesh, mi_obj.mNode, directions[0]) d_returnDistances[axis] = ( distance.returnDistanceBetweenPoints( info['near'], mi_obj.getPosition()) * 2) except Exception, error: raise Exception, "raycast | %s" % error else: try: info1 = RayCast.findMeshIntersectionFromObjectAxis( mesh, mi_obj.mNode, directions[0]) info2 = RayCast.findMeshIntersectionFromObjectAxis( mesh, mi_obj.mNode, directions[1]) if info1 and info2: d_returnDistances[ axis] = distance.returnDistanceBetweenPoints( info1['near'], info2['near']) except Exception, error: raise Exception, "raycast | %s" % error
def returnBaseControlSize(mi_obj,mesh,axis=True): """ >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DESCRIPTION: Figure out the base size for a control from a point in space within a mesh ARGUMENTS: mi_obj(cgmObject instance) mesh(obj) = ['option1','option2'] axis(list) -- what axis to check RETURNS: axisDistances(dict) -- axis distances, average >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> """ try:#>>Figure out the axis to do log.info(mi_obj) mi_obj = cgmMeta.validateObjArg(mi_obj,cgmMeta.cgmObject,noneValid = True) if not mi_obj: raise ValueError,"mi_obj kw: {0} ".format(mi_obj) _str_funcName = "returnBaseControlSize(%s)"%mi_obj.p_nameShort log.debug(">> %s "%(_str_funcName) + "="*75) start = time.clock() log.debug("%s >> mesh: %s "%(_str_funcName,mesh)) log.debug("%s >> axis: %s "%(_str_funcName,axis)) try: d_axisToDo = {} if axis == True: axis = ['x','y','z'] if type(axis) in [list,tuple]: for a in axis: if a in dictionary.stringToVectorDict.keys(): if list(a)[0] in d_axisToDo.keys(): d_axisToDo[list(a)[0]].append( a ) else: d_axisToDo[list(a)[0]] = [ a ] elif type(a) is str and a.lower() in ['x','y','z']: buffer = [] buffer.append('%s+'%a.lower()) buffer.append('%s-'%a.lower()) d_axisToDo[a.lower()] = buffer else: log.warning("Don't know what with: '%s'"%a) log.debug("%s >> d_axisToDo: %s "%(_str_funcName,d_axisToDo)) if not d_axisToDo:return False except Exception,error: raise Exception,"Axis check | {0}".format(error) #>> d_returnDistances = {} for axis in d_axisToDo: log.debug("Checking: %s"%axis) directions = d_axisToDo[axis] if len(directions) == 1:#gonna multiply our distance try: info = RayCast.findMeshIntersectionFromObjectAxis(mesh,mi_obj.mNode,directions[0]) d_returnDistances[axis] = (distance.returnDistanceBetweenPoints(info['hit'],mi_obj.getPosition()) *2) except Exception,error: raise Exception,"raycast | %s"%error else: try: info1 = RayCast.findMeshIntersectionFromObjectAxis(mesh,mi_obj.mNode,directions[0]) info2 = RayCast.findMeshIntersectionFromObjectAxis(mesh,mi_obj.mNode,directions[1]) if info1 and info2: d_returnDistances[axis] = distance.returnDistanceBetweenPoints(info1['hit'],info2['hit']) except Exception,error: raise Exception,"raycast | %s"%error
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() i_ball.__setattr__('t%s'%single_aimAxis,distM) i_ball.parent = False mc.delete(pBuffer) uPos = distance.returnClosestUPosition(i_ball.mNode,mi_crv.mNode) Snap.go(i_ball.mNode,mi_rootLoc.mNode,move = False, orient = False, aim=True, aimVector=[0,0,-1])
def makeLimbTemplate (self): #>>>Curve degree finder if self.optionCurveDegree.get() == 0: doCurveDegree = 1 else: if len(corePositionList) <= 3: doCurveDegree = 1 else: doCurveDegree = len(corePositionList) - 1 #Make some storage vehicles self.templatePosObjectsBuffer = BufferFactory(self.infoNulls['templatePosObjects'].get()) self.templatePosObjectsBuffer.purge() LocatorCatcher = ObjectFactory('') LocatorBuffer = BufferFactory(LocatorCatcher.nameLong) LocatorBuffer.purge() returnList = [] self.templHandleList = [] moduleColors = modules.returnModuleColors(self.ModuleNull.nameShort) #>>>Scale stuff moduleParent = self.msgModuleParent.get() if not moduleParent: length = (distance.returnDistanceBetweenPoints (corePositionList[0],corePositionList[-1])) size = length / self.optionHandles.get() else: #>>>>>>>>>>>>>>>>>>>>> NOT TOUCHED YET parentTemplatePosObjectsInfoNull = modules.returnInfoTypeNull(moduleParent,'templatePosObjects') parentTemplatePosObjectsInfoData = attributes.returnUserAttrsToDict (parentTemplatePosObjectsInfoNull) parentTemplateObjects = [] for key in parentTemplatePosObjectsInfoData.keys(): if (mc.attributeQuery (key,node=parentTemplatePosObjectsInfoNull,msg=True)) == True: if search.returnTagInfo((parentTemplatePosObjectsInfoData[key]),'cgmType') != 'templateCurve': parentTemplateObjects.append (parentTemplatePosObjectsInfoData[key]) createBuffer = curves.createControlCurve('sphere',1) pos = corePositionList[0] mc.move (pos[0], pos[1], pos[2], createBuffer, a=True) closestParentObject = distance.returnClosestObject(createBuffer,parentTemplateObjects) boundingBoxSize = distance.returnBoundingBoxSize (closestParentObject) maxSize = max(boundingBoxSize) size = maxSize *.25 mc.delete(createBuffer) if partType == 'clavicle': size = size * .5 elif partType == 'head': size = size * .75 if (search.returnTagInfo(moduleParent,'cgmModuleType')) == 'clavicle': size = size * 2 #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> # Making the template objects #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> self.TemplateObject = {} #>>> Template objects for cnt,pos in enumerate(corePositionList): #Size multiplier based on PuppetMode, make it take into account module mode eventually if PuppetInstance.optionPuppetMode.get() == 0: if cnt == 0: sizeMultiplier = 1 elif cnt == len(corePositionList) -1: sizeMultiplier = .8 else: sizeMultiplier = .5 else: sizeMultiplier = 1 #make a sphere and move it createBuffer = curves.createControlCurve('sphere',(size * sizeMultiplier)) self.TemplateObject[cnt] = ObjectFactory(createBuffer) # Instance the control to our module obj = self.TemplateObject[cnt] curves.setCurveColorByName(obj.nameLong,moduleColors[0]) obj.store('cgmName',coreNames[cnt]) obj.getNameTagsFromObject(self.ModuleNull.nameLong,['cgmName','cgmType']) obj.store('cgmType','templateObject') obj.doName() mc.move (pos[0], pos[1], pos[2], [obj.nameLong], a=True) #adds it to the list self.templHandleList.append (obj.nameLong) self.templatePosObjectsBuffer.store(obj.nameLong) #Aim the objects position.aimObjects(self.templHandleList, dictionary.axisDirectionsByString[ self.optionAimAxis.get() ], dictionary.axisDirectionsByString[ self.optionUpAxis.get() ], dictionary.axisDirectionsByString[ PuppetInstance.optionUpAxis.get() ]) #>>> Template curve crvName = mc.curve (d=doCurveDegree, p = corePositionList , os=True, n=('%s_%s' %(partName,(typesDictionary.get('templateCurve'))))) self.afTemplateCurve = AttrFactory(self.infoNulls['templatePosObjects'].get(), 'curve','message', value=crvName)# connect it back to our template objects info null curve = ObjectFactory(crvName) # instance it curve.getNameTagsFromObject(self.ModuleNull.nameLong,['cgmType']) #get name tags from the module attributes.storeInfo(crvName,'cgmType','templateCurve') # store type curves.setCurveColorByName(crvName,moduleColors[1]) # set curve color # Make locators to connect the cv's to for cnt,obj in enumerate(self.templHandleList): pointLoc = locators.locMeObject(obj) # make the loc loc = ObjectFactory(pointLoc) #instance it mc.setAttr ((loc.nameShort+'.visibility'),0) # turn off visibility mc.parentConstraint ([obj],[loc.nameShort],mo=False) # parent constrain mc.connectAttr ( (loc.nameShort+'.translate'), ('%s.controlPoints[%i]' % (crvName, cnt)), f=True ) # connect the cv to the loc self.TemplateObject[cnt].store('loc',loc.nameLong) LocatorBuffer.store(loc.nameLong) #>>> Direction and size Stuff """ # Directional data derived from joints generalDirection = logic.returnHorizontalOrVertical(self.templHandleList) if generalDirection == 'vertical' and 'leg' not in self.afModuleType.get(): worldUpVector = [0,0,-1] elif generalDirection == 'vertical' and 'leg' in self.afModuleType.get(): worldUpVector = [0,0,1] else: worldUpVector = [0,1,0] """ # Create root control templateNull = self.msgTemplateNull.get() handleList = copy.copy(self.templatePosObjectsBuffer.bufferList) rootSize = (distance.returnBoundingBoxSizeToAverage(self.templHandleList[0])*1.5) rootCtrl = ObjectFactory(curves.createControlCurve('cube',rootSize)) rootCtrl.getNameTagsFromObject(self.ModuleNull.nameLong) self.msgTemplateRoot = AttrFactory(self.infoNulls['templatePosObjects'].get(), 'root', 'message', value = rootCtrl.nameLong) curves.setCurveColorByName(rootCtrl.nameLong,moduleColors[0]) # move the root if self.afModuleType.get() == 'clavicle': position.movePointSnap(rootCtrl.nameLong,self.templHandleList[0]) else: position.movePointSnap(rootCtrl.nameLong,self.templHandleList[0]) # aim the root position.aimSnap(rootCtrl.nameShort,self.templHandleList[-1], dictionary.axisDirectionsByString[ self.optionAimAxis.get() ], dictionary.axisDirectionsByString[ self.optionUpAxis.get() ], dictionary.axisDirectionsByString[ PuppetInstance.optionUpAxis.get() ]) rootCtrl.store('cgmType','templateRoot') rootCtrl.doName() #>>> Parent the main objcts rootGroup = rootCtrl.doGroup() rootGroup = rigging.doParentReturnName(rootGroup,templateNull) curve.doParent(templateNull) for obj in LocatorBuffer.bufferList: rigging.doParentReturnName(obj,templateNull) mc.delete(LocatorCatcher.nameShort) # delete the locator buffer obj #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> #>> Orientation helpers #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> # Make our Orientation Helpers """ orientHelpersReturn = template.addOrientationHelpers(self) masterOrient = orientHelpersReturn[0] orientObjects = orientHelpersReturn[1] return #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> #>> Control helpers #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> print orientObjects print self.ModuleNull.nameShort print (templateNull+'.visControlHelpers') controlHelpersReturn = addControlHelpers(orientObjects,self.ModuleNull.nameShort,(templateNull+'.visControlHelpers'))""" #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> #>> Input the saved values if there are any #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> # Orientation Helpers """rotBuffer = coreRotationList[-1] #actualName = mc.spaceLocator (n= wantedName) rotCheck = sum(rotBuffer) if rotCheck != 0: mc.rotate(rotBuffer[0],rotBuffer[1],rotBuffer[2],masterOrient,os=True) cnt = 0 for obj in orientObjects: rotBuffer = coreRotationList[cnt] rotCheck = sum(rotBuffer) if rotCheck != 0: mc.rotate(rotBuffer[0],rotBuffer[1],rotBuffer[2],obj,os=True) cnt +=1 # Control Helpers controlHelpers = controlHelpersReturn[0] cnt = 0 for obj in controlHelpers: posBuffer = controlPositionList[cnt] posCheck = sum(posBuffer) if posCheck != 0: mc.xform(obj,t=[posBuffer[0],posBuffer[1],posBuffer[2]],ws=True) rotBuffer = controlRotationList[cnt] rotCheck = sum(rotBuffer) if rotCheck != 0: mc.rotate(rotBuffer[0],rotBuffer[1],rotBuffer[2],obj,ws=True) scaleBuffer = controlScaleList[cnt] scaleCheck = sum(scaleBuffer) if scaleCheck != 0: mc.scale(scaleBuffer[0],scaleBuffer[1],scaleBuffer[2],obj,absolute=True) cnt +=1 """ #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> #>> Final stuff #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> """ returnList.append(templObjNameList) returnList.append(self.templHandleList) returnList.append(rootCtrl)""" return True
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)