def removeSpace( src, tgt ): ''' removes a target (or space) from a "space switching" object ''' tgts, names = getSpaceTargetsNames( src ) tgt_mobject = asMObject( tgt ) name = None for index, (aTgt, aName) in enumerate( zip( tgts, names ) ): aTgt = asMObject( aTgt ) if aTgt == tgt_mobject: name = aName break if name is None: raise AttributeError( "no such target" ) delete = False if len( tgts ) == 1: delete = True constraint = findConstraint( src ) parentAttrOn = findSpaceAttrNode( src ) space = findSpace( src ) srcTrigger = Trigger( src ) cmds = srcTrigger.iterMenus() if delete: delete( constraint ) deleteAttr( '%s.parent' % src ) else: constraintType = nodeType( constraint ) constraintFunc = getattr( cmd, constraintType ) constraintFunc( tgt, constraint, rm=True ) for slot, cmdName, cmdStr in srcTrigger.iterMenus(): if cmdName == ( "parent to %s" % name ): srcTrigger.removeMenu( slot ) #rebuild the parent attribute newNames = names[:] newNames.pop( index ) addAttr( '%s.parent' % parentAttrOn, e=True, enumName=':'.join( newNames ) ) #now we need to update the indicies in the right click command - all targets that were beyond the one we #just removed need to have their indices decremented for slot, cmdName, cmdStr in srcTrigger.iterMenus(): if not cmdName.startswith( 'parent to ' ): continue cmdStrObj = ChangeSpaceCmd( cmdStr ) cmdIndex = cmdStrObj.getIndex() if cmdIndex < index: continue cmdStrObj = cmdStrObj.setIndex( cmdIndex-1 ) srcTrigger.setMenuCmd( slot, cmdStrObj )
def getSpaceTargetsNames( src ): ''' this procedure returns a 2-tuple: a list of all targets, and a list of user specified names - for the right click menus ''' constraint = findConstraint( src ) if constraint is None: return [], [] space = findSpace( src, constraint ) if space is None: return [], [] constraintType = nodeType( constraint ) constraintFunc = getattr( cmd, constraintType ) targetsOnConstraint = constraintFunc( constraint, q=True, tl=True ) trigger = Trigger( src ) SPECIAL_STRING = 'parent to ' LEN_SPECIAL_STRING = len( SPECIAL_STRING ) tgts, names = [], [] for slotIdx, slotName, slotCmd in trigger.iterMenus(): if slotName.startswith( SPECIAL_STRING ): names.append( slotName[ LEN_SPECIAL_STRING: ] ) cmdStrObj = ChangeSpaceCmd( slotCmd ) cmdIndex = cmdStrObj.getIndex() tgts.append( targetsOnConstraint[ cmdIndex ] ) return tgts, names
def getControlsFromObjs( control ): ''' attempts to retrieve the pole vector control, the ik handle and all fk controls given an ik rig control. The information is returned in a 3 tuple containing: ikHandle, poleControl, fkControls ''' errorValue = None, None, None, None try: part = rigPrimitives.RigPart.InitFromItem( control ) return part.getControl( 'control' ), part.getIkHandle(), part.getControl( 'poleControl' ), part.getFkControls() except rigPrimitives.RigPartError: pass #so if the control we've been given isn't a rig primitive, lets try to extract whatever information we can from right click commands - if any exist trigger = Trigger( ikControl ) switchCmdStr = None for n, cmdName, cmdStr in trigger.iterMenus(): if cmdName.lower() == _IK_CMD_NAME: switchCmdStr = trigger.resolve( cmdStr ) break if switchCmdStr is None: printWarningStr( "Cannot find the %s command - aborting!" % _IK_CMD_NAME ) return errorValue #extract the control handle from the switch command - it may or may not exist, depending on which rexStr = re.compile( '-ikHandle \%([a-ZA-Z0-9_:|]+)', re.IGNORECASE | re.MULTILINE ) match = rexStr.search( switchCmdStr ) if not match: if match.groups()[0]: control = match.groups()[0] #extract the ik handle from the switch command rexStr = re.compile( '-ikHandle \%([a-ZA-Z0-9_:|]+)', re.IGNORECASE | re.MULTILINE ) match = rexStr.search( switchCmdStr ) if not match: printWarningStr( "Could not determine the ik handle from the given control" ) return errorValue handle = match.groups()[0] if handle is None: printWarningStr( "Could not find the ik handle at the given connect index!" ) return errorValue #now extract the pole control from the switch command rexStr = re.compile( '-pole \%([a-ZA-Z0-9_:|]+)', re.IGNORECASE | re.MULTILINE ) match = rexStr.search( switchCmdStr ) if not match: printWarningStr( "Could not determine the pole vector control from the given control" ) return errorValue poleControl = match.groups()[0] if poleControl is None: printWarningStr( "Could not find the ik handle at the given connect index!" ) return errorValue return control, poleControl, handle, getJointsFromIkHandle( handle )
def findSpaceAttrNode( obj ): ''' returns the node that contains the parent attribute for the space switch ''' parentAttrOn = ""; trigger = Trigger( obj ) for slotIdx, slotName, slotCmd in trigger.iterMenus(): if slotName.startswith( 'parent to ' ): cmdStrObj = ChangeSpaceCmd( slotCmd ) connectToken = cmdStrObj.getConnectToken() return trigger.resolve( connectToken )