def getParentAndRootControl( theJoint ): ''' returns a 2 tuple containing the nearest control up the hierarchy, and the most likely control to use as the "root" control for the rig. either of these may be the world control, but both values are guaranteed to be an existing control object ''' parentControl, rootControl = None, None for p in apiExtensions.iterParents( theJoint ): theControl = getItemRigControl( p ) if theControl is None: continue if parentControl is None: parentControl = theControl skelPart = SkeletonPart.InitFromItem( p ) if isinstance( skelPart, skeletonBuilder.Root ): rootControl = theControl if parentControl is None or rootControl is None: world = WorldPart.Create() if parentControl is None: parentControl = world.getControl( 'control' ) if rootControl is None: rootControl = world.getControl( 'control' ) return parentControl, rootControl
def getSpaceSwitchControls( theJoint ): ''' walks up the joint chain and returns a list of controls that drive parent joints ''' parentControls = [] for p in apiExtensions.iterParents( theJoint ): theControl = getItemRigControl( p ) if theControl is not None: parentControls.append( theControl ) return parentControls
def getChain( startNode, endNode ): ''' returns a list of all the joints from the given start to the end inclusive ''' chainNodes = [ endNode ] for p in apiExtensions.iterParents( endNode ): if not p: raise ValueError( "Chain terminated before reaching the end node!" ) chainNodes.append( p ) if apiExtensions.cmpNodes( p, startNode ): #cmpNodes is more reliable than just string comparing - cmpNodes casts to MObjects and compares object handles break chainNodes.reverse() return chainNodes
def chainLength( startNode, endNode ): ''' measures the length of the chain were it to be straightened out ''' length = 0 curNode = endNode for p in apiExtensions.iterParents( endNode ): curPos = Vector( xform( curNode, q=True, ws=True, rp=True ) ) parPos = Vector( xform( p, q=True, ws=True, rp=True ) ) dif = curPos - parPos length += dif.get_magnitude() if apiExtensions.cmpNodes( p, startNode ): #cmpNodes is more reliable than just string comparing - cmpNodes casts to MObjects and compares object handles break curNode = p return length
def on_xfer( self, *a ): mapping = mappingUtils.resolveMappingToScene( self.UI_mapping.getMapping() ) theSrcs = [] theTgts = [] #perform the hierarchy sort idx = 0 if self.sortBySrcs else 1 toSort = [ (len(list(iterParents( srcAndTgt[ idx ] ))), srcAndTgt) for srcAndTgt in mapping.iteritems() if cmd.objExists( srcAndTgt[ idx ] ) ] toSort.sort() for idx, (src, tgt) in toSort: theSrcs.append( src ) theTgts.append( tgt ) offset = '' isDupe = self.isTraceMode( self.RAD_dupe ) isCopy = self.isTraceMode( self.RAD_copy ) isTraced = self.isTraceMode( self.RAD_trace ) instance = cmd.checkBox( self.UI_check1, q=True, v=True ) traceKeys = cmd.checkBox( self.UI_keysOnly, q=True, v=True ) matchRo = cmd.checkBox( self.UI_check2, q=True, v=True ) startTime = cmd.textField( self.UI_start, q=True, tx=True ) endTime = cmd.textField( self.UI_end, q=True, tx=True ) world = processPostCmds = cmd.checkBox( self.UI_check3, q=True, v=True ) #this is also "process trace cmds" nocreate = cmd.checkBox( self.UI_check4, q=True, v=True ) if startTime.isdigit(): startTime = int( startTime ) else: if startTime == '!': startTime = cmd.playbackOptions( q=True, min=True ) elif startTime == '.': startTime = cmd.currentTime( q=True ) elif startTime == '$': startTime = cmd.playbackOptions( q=True, animationStartTime=True ) if endTime.isdigit(): endTime = int( endTime ) else: if endTime == '!': endTime = cmd.playbackOptions( q=True, max=True ) elif endTime == '.': endTime = cmd.currentTime( q=True ) elif endTime == '$': endTime = cmd.playbackOptions( q=True, animationEndTime=True ) withinRange = cmd.checkBox( self.UI_withinRange, q=True, v=True ) if withinRange: traceKeys = 2 if isCopy: offset = "*" if self._clipPreset is not None: #convert to mapping as expected by animLib... this is messy! animLibMapping = {} for src, tgts in mapping.iteritems(): animLibMapping[ src ] = tgts[ 0 ] self._clipPreset.asClip().apply( animLibMapping ) elif isDupe: melecho.zooXferBatch( "-mode 0 -instance %d -matchRo %d" % (instance, matchRo), theSrcs, theTgts ) elif isCopy: melecho.zooXferBatch( "-mode 1 -range %s %s -matchRo %d" % (startTime, endTime, matchRo), theSrcs, theTgts ) elif isTraced: xferAnim.trace( theSrcs, theTgts, traceKeys, matchRo, processPostCmds, True, startTime, endTime )