Example #1
0
def allCards(main=None):
    '''
    Return all the cards, optionally taking a specific skeletonBlueprint.
    '''
    
    # Use cmds for speed (swift takes 0.20 with pymel but 0.04 with cmds)
    targetCards = set(
        cmds.ls( '*.skeletonInfo', o=True, r=True, l=True ) +
        cmds.ls( '*.fossilRigData', o=True, r=True, l=True )
    )
    
    if main:
        targetCards.intersection_update( cmds.listRelatives(main.name(), ad=True, type='transform', f=True) )
    
    def order(obj):
        try:
            return cmds.getAttr(obj + '.buildOrder')
        except Exception:
            pass
    
        try:
            return json.loads(cmds.getAttr(obj + '.fossilRigData')).get('buildOrder', 10)
        except Exception:
            pass
    
        return 10
    
    return [PyNode(c) for c in sorted(targetCards, key=order)]
Example #2
0
 def readSpec(self, spec):
     
     if 'id' in spec:
         cards = cmds.ls( '*.fossilRigData', o=True, r=True, l=True )
         
         for card in cards:
             data = json.loads( cmds.getAttr( card + '.fossilRigData' ) )
             if spec['id'] == data.get('id', None):
                 return PyNode(card)
     return None
Example #3
0
def controllers(main=None):
    '''
    Returns all the animation controllers in the scene.
    
    ..  todo:: Add the shapes that have ik/fk switching on them
    '''

    allControls = set(
        cmds.ls('*.' + config.FOSSIL_CTRL_TYPE, o=True, r=True, l=True))

    if main:
        mainTransforms = cmds.listRelatives(main.name(),
                                            ad=True,
                                            type='transform',
                                            f=True)
        if mainTransforms:
            allControls.intersection_update(mainTransforms)
            controls = [PyNode(o) for o in allControls]
            controls.append(main)

            root = rootMotion(main=main)
            if root:
                controls.append(root)

            return controls

        else:
            warning("No sub controls found for {0}".format(main.name()))

    else:
        controls = [PyNode(o) for o in allControls]
        main = mainGroup()
        if main:
            controls.append(main)

        root = rootMotion(main=main)
        if root:
            controls.append(root)

        return controls

    return []
Example #4
0
def getSwitcherPlug(obj):
    '''
    Will return either a string like "Arm_L_FKIK_SWITCH" or empty string if no
    switcher is found.
    
    Can't use pymel to avoid warnings of invalid node (nurbs with no cvs).
    This also means listRelatives returns None instead of []. Lame.
    '''
    shapes = cmds.listRelatives(str(obj), type='nurbsCurve', f=True)
    if shapes:
        for shape in shapes:
            # Check for new style switch first
            if cmds.objExists(shape + '.IkSwitch'):
                return shape + '.IkSwitch'

            # Fallback to old style switch
            if cmds.objExists(shape + '.kinematicSwitch'):

                attr = cmds.listAttr(shape, ud=1, st='*_Switch')
                return cmds.ls(shape, l=False)[0] + '.' + attr[0]  # noqa
    return ''
Example #5
0
def readCardPath(cpath):
    res = ast.parse(cpath)

    body = res.body[0]

    #if isinstance(body, ast.Subscript):
    if isinstance(body.value, ast.Subscript):
        assert body.value.value.attr == 'subControl'
        cardCallRes = body.value.value.value.value
        subName = body.value.slice.value.s

        side = cardCallRes.attr
        motionType = body.value.value.value.attr
        cardCall = cardCallRes

        cardName = cardCall.value.args[0].s.rsplit('|', 1)[-1]

    else:
        cardCallRes = body.value
        subName = None

        motionType = cardCallRes.attr
        side = cardCallRes.value.attr
        cardCall = cardCallRes.value

        cardName = cardCall.value.args[0].s.rsplit('|', 1)[-1]

    if cardCall.value.keywords:
        assert cardCall.value.keywords[0].arg == 'cardId'
        cardId = cardCall.value.keywords[0].value
    else:
        cardId = None

    targetCard = None

    cards = cmds.ls('*.fossilRigData', o=True, r=True, l=True)
    if cardId:
        for card in cards:
            data = json.loads(cmds.getAttr(card + '.fossilRigData'))
            if cardId == data.get('id', None):
                targetCard = PyNode(card)
                break

    if not targetCard:
        names = {card.rsplit('|', 1)[-1]: card for card in cards}
        if cardName in names:
            targetCard = PyNode(names[cardName])
        else:
            shortNames = {
                card.rsplit('|', 1)[-1].rsplit(':', 1)[-1]: card
                for card in cards
            }
            cardShortName = cardName.rsplit(':', 1)[-1]
            if cardShortName in shortNames:
                targetCard = PyNode(shortNames[cardShortName])

    if not targetCard:
        return None

    #mainControl = targetCard.attr(motionType)
    #print(targetCard, motionType, side)
    mainControl = getattr(getattr(targetCard, side), motionType)

    if subName:
        return mainControl.subControl[subName]
    else:
        return mainControl


# findSDK and applySDK updated to idSpec
Example #6
0
def buildBones(cards=None, removeTempBind=True):
    global _meshStorage

    if not cards:
        cards = set(util.selectedCards())
        if not cards:
            pdil.ui.notify(m='No cards selected')
            return

    issues = validateBoneNames(cards)
    if issues:
        pdil.ui.notify(m='\n'.join(issues), t='Fix these')
        return

    cardBuildOrder = find.cardJointBuildOrder()

    skinning.cacheWeights(cards, _meshStorage)

    useRepose = tpose.reposerExists()
    if useRepose:
        log.debug('Reposer Exists')
        realJoints = [
        ]  # This is a list of the joints that are ACTUALLY built in this process
        bindPoseJoints = []  # Matches realJoints, the cards that are bound
        tempBindJoints = [
        ]  # Super set of bindPoseJoints, including the hierarchy leading up to the bindBoseJoints

        estRealJointCount = len(cmds.ls('*.realJoint'))

        with pdil.ui.progressWin(title='Build Bones',
                                 max=estRealJointCount * 3 +
                                 len(cards)) as prog:
            # Build the tpose joints
            with tpose.matchReposer(cardBuildOrder):
                for card in cardBuildOrder:
                    if card in cards:
                        newJoints = card.buildJoints_core(
                            nodeApi.fossilNodes.JointMode.tpose)
                        realJoints += newJoints

                        accessoryFixup(newJoints, card)

                    prog.update()

                # The hierarchy has to be built to determine the right bindZero, so build everything if all cards
                # are being made, otherwise target just a few
                if len(cardBuildOrder) == len(cards):
                    bindCardsToBuild = cardBuildOrder
                else:
                    bindCardsToBuild = getRequiredHierarchy(cards)

            # Temp build the bind pose joints
            for card in bindCardsToBuild:
                joints = card.buildJoints_core(
                    nodeApi.fossilNodes.JointMode.bind)
                tempBindJoints += joints
                if card in cards:
                    bindPoseJoints += joints

            with tpose.goToBindPose():
                # Setup all the constraints first so joint order doesn't matter
                constraints = []
                prevTrans = []
                for bind, real in zip(bindPoseJoints, realJoints):
                    #with core.dagObj.Solo(bind):
                    #    bind.jo.set( real.jo.get() )

                    prevTrans.append(real.t.get())
                    constraints.append([
                        orientConstraint(bind, real),
                        pointConstraint(bind, real)
                    ])

                    real.addAttr('bindZero', at='double3')
                    real.addAttr('bindZeroX', at='double', p='bindZero')
                    real.addAttr('bindZeroY', at='double', p='bindZero')
                    real.addAttr('bindZeroZ', at='double', p='bindZero')
                    prog.update()
                    #real.addAttr( 'bindZeroTr', at='double3' )
                    #real.addAttr( 'bindZeroTrX', at='double', p='bindZeroTr' )
                    #real.addAttr( 'bindZeroTrY', at='double', p='bindZeroTr' )
                    #real.addAttr( 'bindZeroTrZ', at='double', p='bindZeroTr' )

                    #real.bindZero.set( real.r.get() )

                # Harvest all the values
                for real in realJoints:
                    real.bindZero.set(real.r.get())
                    #real.bindZeroTr.set( real.t.get() )
                    prog.update()

                # Return the real joints back to their proper location/orientation
                for constraint, real, trans in zip(constraints, realJoints,
                                                   prevTrans):
                    delete(constraint)
                    real.r.set(0, 0, 0)
                    real.t.set(trans)
                    prog.update()

        root = node.getTrueRoot()
        topJoints = root.listRelatives(type='joint')

        for jnt in topJoints:
            try:
                index = realJoints.index(jnt)
                real = jnt
                bind = bindPoseJoints[index]

                real.addAttr('bindZeroTr', at='double3')
                real.addAttr('bindZeroTrX', at='double', p='bindZeroTr')
                real.addAttr('bindZeroTrY', at='double', p='bindZeroTr')
                real.addAttr('bindZeroTrZ', at='double', p='bindZeroTr')

                delta = bind.worldMatrix[0].get(
                ) * real.worldInverseMatrix[0].get()
                real.bindZeroTr.set(delta[3][:3])

            except ValueError:
                pass

        if removeTempBind:
            delete(tempBindJoints)

    else:
        log.debug('No reposer')
        # Only build the selected cards, but always do it in the right order.
        with pdil.ui.progressWin(title='Build Bones', max=len(cards)) as prog:
            for card in cardBuildOrder:
                if card in cards:
                    newJoints = card.buildJoints_core(
                        nodeApi.fossilNodes.JointMode.default)
                    accessoryFixup(newJoints, card)
                    prog.update()

    if useRepose:
        with tpose.goToBindPose():
            skinning.loadCachedWeights(_meshStorage)
    else:
        skinning.loadCachedWeights(_meshStorage)

    select(cards)
Example #7
0
def buildRig(cards=None):
    '''
    Makes the rig, saving shapes and removing the old rig if needed.
    '''
    # &&& Need to move find.cardJointBuildOrder to util and make selectedCards() use it.
    if not cards:
        cards = set(util.selectedCards())

    mode = 'Use Rig Info Shapes'

    if not cards:
        pdil.ui.notify(m='No cards to selected to operate on.')
        return

    # &&& BUG, need to ONLY check against joints under the root, since other non-joint objects might have the same name

    # allJoints = ...

    for card in cards:
        joints = card.getOutputJoints()
        if joints and card.rigData.get(
                'rigCmd', '') != 'Group':  # Group doesn't build joints
            if len(cmds.ls(joints)) != len(
                    joints
            ):  # &&& This is a bad check, a reference mesh joints can mess it up.
                # &&& Ideall this prompts to build joints
                pdil.ui.notify(m='{} does not have joints built.'.format(card))
                raise Exception('Joints not built')

    a = pdil.debug.Timer('Overall build')

    cardBuildOrder = find.cardJointBuildOrder()

    with tpose.matchReposer(
            cardBuildOrder) if tpose.reposerExists() else nothing():

        with pdil.ui.progressWin(title='Building', max=len(cards) * 3) as pr:

            for card in cardBuildOrder:
                if card not in cards:
                    continue
                pr.update(status=card.name() + ' prep')
                if mode == 'Use Current Shapes':
                    card.saveShapes()

                # If this being rebuilt, also restore the if it's in ik or fk
                switchers = [
                    controllerShape.getSwitcherPlug(x[0])
                    for x in card._outputs()
                ]
                prevValues = [(s, getAttr(s)) for s in switchers if s]

                card.removeRig()
                pr.update(status=card.name() + ' build')
                _buildRig([card])

                pr.update(status=card.name() + ' build')
                if mode != 'Use Rig Info Shapes':
                    card.restoreShapes()

                # Restore ik/fk-ness
                for switch, value in prevValues:
                    if objExists(switch):
                        setAttr(switch, value)

    tpose.markBindPose(cards)

    select(cards)
    a.stop()
Example #8
0
def load(filename,
         insertTime=None,
         alterPlug=None,
         bufferKeys=True,
         targetPool=None):
    '''
    Loads a file containing animCurves (made with `save`) and hooks them up.
    
    :param func alterPlug:  If the input needs some sort of transformation, provide
        a function that takes the plug string, ex "someSphere.tx" and returns
        a plug string of how it maps back, ex "zCube.tx" or "zCube.ty" and
        a function to alter the curve (or None)

        def alterPlug( 'inputNode.attr' ):
            return 'transformed'
        
    :param bool bufferKeys: If True (default), will add keys a frame before and
        after the range.
    '''
    global TAGGING_ATTR
    global _loadAlterPlug

    existingSelection = selected()

    # Hook for easily providing an alterPlug via the GUI
    if _loadAlterPlug and not alterPlug:
        alterPlug = _loadAlterPlug

    # Using cmds for speed
    getAttr = cmds.getAttr
    objExists = cmds.objExists
    ls = cmds.ls
    # ---

    if insertTime is None:
        insertTime = currentTime(q=True)

    missingObj = set()
    missingAttr = []
    pasteError = []

    newNodes = cmds.file(filename, i=True, rnn=True)

    curves = cmds.ls(newNodes, type='animCurve')
    info = ls(newNodes, type='network')[0]

    start = getAttr(info + '.start')
    end = getAttr(info + '.end')
    length = end - start

    attr = '.' + TAGGING_ATTR

    singleObj = ''

    if len(existingSelection) == 1:
        targetObj = getAttr(curves[0] + attr).split('.')[0]
        for c in curves:
            loadedTarget = getAttr(c + attr).split('.')[0]
            # FKIK_SWITCH is a hack to deal with the switching attr if a single
            # obj is selected
            if loadedTarget != targetObj and not loadedTarget.endswith(
                    'FKIK_SWITCH'):
                break
        else:
            singleObj = targetObj

    if singleObj:
        targetObj = existingSelection[0].longName()

        def alter(plug):
            return targetObj + '.' + plug.split('.')[-1], None
    else:
        # Determine if there is a namespace mismatch
        if alterPlug:
            targets = [
                alterPlug(cmds.getAttr(crv + attr))[0].split('.')[0]
                for crv in curves
            ]
        else:
            targets = [
                cmds.getAttr(crv + attr).split('.')[0] for crv in curves
            ]

        changeNamespace = None

        newTargets = core.names.findAlternates(targets, targetPool)

        global JUNK
        JUNK = targets

        if newTargets.alteration:
            print('NS change', '--' * 20, newTargets.alteration)
            if newTargets.alteration[0] == 'add':

                def changeNamespace(plug):
                    return newTargets.alteration[1] + plug
            elif newTargets.alteration[0] == 'sub':

                def changeNamespace(plug):
                    return plug.replace(newTargets.alteration[1],
                                        newTargets.alteration[2])
            elif newTargets.alteration[0] == 'rem':

                def changeNamespace(plug):
                    return plug.replace(newTargets.alteration[1], '')

        # Build an alteration function if needed
        alter = None
        if alterPlug and changeNamespace:

            def alter(plug):
                newPlug, curveEditFunc = alterPlug(changeNamespace(plug))
                return newPlug, curveEditFunc
        elif alterPlug:
            alter = alterPlug
        elif changeNamespace:

            def alter(plug):
                return changeNamespace(plug), None

    if hasAttr(PyNode(info), 'staticValues'):
        keys = json.loads(
            core.text.asciiDecompress(getAttr(info + '.staticValues')))

        for plug, value in keys.items():
            try:
                if alter:
                    setAttr(alter(plug), value)
                else:
                    setAttr(plug, value)
            except Exception:
                pass

    # Finally, actually copy over the animation
    for node in curves:
        alterCurve = None
        if objExists(node + '.' + TAGGING_ATTR):
            dest = getAttr(node + '.' + TAGGING_ATTR)
            if alter:
                dest, alterCurve = alter(dest)

            if alterCurve:
                alterCurve(node)

            if objExists(dest):

                # If we aren't going to be able to paste, just punt.
                if not getAttr(dest, k=True):
                    pasteError.append(dest)
                    continue

                if bufferKeys or getAttr(node, s=1) <= 1:
                    setKeyframe(node, time=(insertTime - 1), insert=True)
                    setKeyframe(node,
                                time=(insertTime + length + 1),
                                insert=True)

                copyKey(node, time=(start, end), iub=True, option='curve')

                try:
                    pasteKey(dest,
                             time=(insertTime, insertTime + length),
                             option='replace')
                except Exception:
                    pasteError.append(dest)
            else:
                obj, attr = dest.split('.')
                if objExists(obj):
                    missingAttr.append(dest)
                else:
                    missingObj.add(obj)

    if missingObj:
        print(
            core.text.writeInBox("These objects don't exist:\n\n" +
                                 '\n'.join(missingObj)))
    if missingAttr:
        print(
            core.text.writeInBox("These attribute couldn't be found:\n\n" +
                                 '\n'.join(missingAttr)))
    if pasteError:
        print(
            core.text.writeInBox(
                "Errors occurred when pasting animation onto:\n\n" +
                '\n'.join(pasteError)))

    if missingObj or missingAttr or pasteError:
        warning('Completed but with errors. See script editor for details.')

    delete(newNodes)

    return SavedCurveInfo(insertTime, insertTime + length, length)
Example #9
0
def controllers(main=None):
    '''
    Returns all the animation controllers in the scene.
    
    ..  todo:: Add the shapes that have ik/fk switching on them
    '''
    
    ''' Timing experiments: Results, cmds + sets is WAY faster!
        s = time.time()
        controls = [c for c in listRelatives(main, ad=True, type='transform') if c.hasAttr('fossilCtrlType')]
        print( time.time() - s, 'ls(*.fossilCtrlType) ORIGINAL' )


        s = time.time()
        controls = [PyNode(c) for c in cmds.listRelatives(main.name(), ad=True, type='transform', f=1) if cmds.attributeQuery('fossilCtrlType', node=c, ex=True)]
        print( time.time() - s, 'cmds.listRelatives() list comp' )


        s = time.time()
        #controls = [c for c in listRelatives(main, ad=True, type='transform') if c.hasAttr('fossilCtrlType')]
        allControls = set(cmds.ls('*.fossilCtrlType', type='transform', r=True, o=True))
        allControls.intersection_update( cmds.listRelatives(main.name(), ad=True, type='transform') )
        controls = [PyNode(o) for o in allControls]
        print( time.time() - s, 'cmds and set filtering' )
        
        Swift Cat as main:
        0.611000061035 ls(*.fossilCtrlType) ORIGINAL
        0.123000144958 cmds.listRelatives() list comp
        0.0439999103546 cmds and set filtering

        Swift as Main:

        2.1210000515 ls(*.fossilCtrlType) ORIGINAL
        0.398999929428 cmds.listRelatives() list comp
        0.0769999027252 cmds and set filtering

    '''
    
    allControls = set( cmds.ls( '*.fossilCtrlType', o=True, r=True ) )
    
    if main:
        mainTransforms = cmds.listRelatives(main.name(), ad=True, type='transform')
        if mainTransforms:
            allControls.intersection_update( mainTransforms )
            controls = [PyNode(o) for o in allControls]
            controls.append(main)
            
            root = rootMotion(main=main)
            if root:
                controls.append(root)
                
            return controls
            
        else:
            warning("No sub controls found for {0}".format(main.name()))
    
    else:
        controls = [PyNode(o) for o in allControls]
        main = mainGroup()
        if main:
            controls.append(main)

        root = rootMotion(main=main)
        if root:
            controls.append(root)
    
        return controls
    
    return []
Example #10
0
def generateReposer(cards=None, placeholder=False, progress=None):
    ''' If no cards are specificed, a new reposer is build, otherwise it
    rebuilds/adds reposers for the specified cards.
    
    
    Args:
        cards
        placeholder
        progress: Optional `progressWindow` that will be `.update()`'d twice for
            each card, MUST be preconfigured (in case several things are updating)
    
    &&& TODO Verify the cards can be built in any order
    '''
    
    global jointMapping # global'd for debugging
    suffix = '_placeholder' if placeholder else ''
    
    rJoints = []
    rCards = []
    unlock = {} # <repose joint or card>: <list of attrs to be re-locked>

    jointMapping = {}  # Lazy "bi-directional mapping" of bpj <-> reposeJoint, both are added as keys to eachother

    # Build all the cards and joints
    if not cards:
        cards = find.blueprintCards()
        # Delete previous roots
        for oldRoot in getReposeRoots():
            oldRoot.deleteAttr('reposeRoot')
            
    # Otherwise populate the containers with the existing reposer to build/add new stuff.
    else:
        #allExistingRCards = set( cmds.ls( '*.bpCard', o=True, r=True, l=True ) )
        allExistingRJoints = set( cmds.ls( '*.bpj', o=True, r=True, l=True ) )
        
        for oldRoot in getReposeRoots():
            joints = cmds.listRelatives( str(oldRoot), f=True, ad=True, type='joint' )
            joints = [PyNode(c) for c in allExistingRJoints.intersection(joints)]
        
            for rj in joints:
                bpj = rj.bpj.listConnections()[0]
                jointMapping[rj] = bpj
                jointMapping[bpj] = rj

    
    for card in cards:
        if progress:
            progress.update()
        
        rCard = duplicate(card, po=0)[0]
        showHidden(rCard)
        pdil.dagObj.unlock(rCard)
        stripReposerCard(rCard)
        
        targetName = simpleName(card, '{}_repose' + suffix)
        
        previous, attrs = reposeLink(card, rCard, 'bpCard') if not placeholder else (None, [])
        unlock[rCard] = attrs
        
        renameReposeObj(rCard, targetName, previous)
        
        for child in rCard.listRelatives():
            if not child.type() == 'nurbsSurface':
                delete(child)
        rCards.append(rCard)
        makeIdentity(rCard, t=False, r=False, s=True, apply=True)
        pdil.dagObj.lock( rCard, 's' )

        for jnt in card.joints:
            reposeJoint = joint(None)
            targetName = simpleName(jnt, '{}_repose' + suffix)
            
            previous, attrs = reposeLink(jnt, reposeJoint, 'bpj') if not placeholder else (None, [])
            unlock[reposeJoint] = attrs
            renameReposeObj(reposeJoint, targetName, previous)

            pdil.dagObj.matchTo(reposeJoint, jnt)

            #assert jnt.info.get('options', {}).get('mirroredSide', False) is False, 'parent to mirrored joints not supported yet'
            
            jointMapping[jnt] = reposeJoint
            jointMapping[reposeJoint] = jnt

            rJoints.append(reposeJoint)
            
    
    # Set their parents
    for reposeJoint in rJoints:
        parent = jointMapping[reposeJoint].parent
        if parent in jointMapping: # Check against joint mapping in case only a few selected cards a being tposed
            reposeJoint.setParent( jointMapping[parent] )
    
    reposeContainer = getReposeContainer()
    
    
    # Put under cards, card pivot to lead joint
    for rCard, card in zip(rCards, cards):
        if progress:
            progress.update()
        bpj = card.parentCardJoint
        #print('BPJ - - - - ', bpj, bpj in jointMapping)
        if bpj in jointMapping:
            start = card.start() if card.joints else bpj
            #rCard.setParent( getRJoint(bpj) )
            pdil.dagObj.unlock(rCard)
            
            #firstBpj = card.joints[0]
            #return
            
            isMirrored = card.isCardMirrored()
            
            
            mirroredSide = card.joints[0].info.get('options', {}).get('mirroredSide')
            #print('rCard.mirror', rCard.mirror, 'info:', mirroredSide)
            #if rCard.mirror is False and mirroredSide:
            if isMirrored is False and card.mirror is False and mirroredSide:
                #print('opposite mirror')
                rCard.setParent( makeMirrored( jointMapping[bpj] ) )
            else:
                #print('regular side stuff')
                rCard.setParent( jointMapping[bpj] )
                
            #cmds.parent(str(rCard), str(jointMapping[bpj]))
            xform(rCard, ws=True, piv=xform(start, q=True, t=True, ws=True) )
            pdil.dagObj.lock(rCard, 't')
            
        else:
            if not placeholder:
                rCard.addAttr('reposeRoot', at='message')
                rCard.setParent( reposeContainer )
                
        addVector(rCard, 'origRot', rCard.r.get())
        addVector(rCard, 'origTrans', rCard.t.get())
        #start = getRJoint(card.start())
        start = jointMapping[card.start()]
        start.setParent( rCard )
        pdil.dagObj.lock( start, 't s' )

        if rCard in unlock:
            for attr in unlock[rCard]:
                rCard.attr(attr).unlock()
                rCard.attr(attr).showInChannelBox(True)
                
    for reposeJoint in rJoints:
        pdil.dagObj.lock(reposeJoint, 'ry rz')
        pdil.dagObj.lock(reposeJoint, 't s') # I can't see why I wasn't locking t/s already.  Possible exception, `freeform`
        
        if reposeJoint in unlock:
            for attr in unlock[reposeJoint]:
                reposeJoint.attr(attr).unlock()
                reposeJoint.attr(attr).showInChannelBox(True)
        
        addVector(reposeJoint, 'origRot', reposeJoint.r.get())
        addVector(reposeJoint, 'origTrans', reposeJoint.t.get())
    
        '''
Example #11
0
def findAlternates(joints, available=None):
    '''
    Given a list of objects, see if they all exist in the scene and try to
    figure out if they have lost or gained namespaces.
    
    :param list joints: A list of string names, not PyNodes.
    :param list available: If specified, only these objects will be considered
        valid targets, otherwise the whole scene will be considered.
    :return: None if unable to find matches for everything or a NSChange with
        the alterations made and list of new joints.
        NSCHange.alteration is a list with will be:
            * ['rem', <ns>] # The namespace was removed
            * ['add', <ns>] # The namespace was add
            * ['sub', <old>, <new>] # <old> was replaced with <new>
        
    '''

    if available is not None:

        def objExists(obj):
            #print 'searching for', obj, type(obj)
            return obj in available
    else:
        objExists = pymel.core.objExists

    missing = [j for j in joints if not objExists(j)]

    fixed = not bool(missing)
    alteration = []

    lowestFail = len(missing)
    bestChoice = None

    if missing:
        print('# missing %i / %i' % (len(missing), len(joints)))

    if not missing:
        return NSChange([], joints)
    else:
        for missingObj in missing:
            if missingObj.count(':'):

                # Try stripping off any namespace (accounting for long names) and proceed if all bones exist.
                namespace, simpleName = missingObj.split('|')[-1].rsplit(
                    ':', 1)

                if objExists(simpleName):
                    newJoints, failedCount = _remNS(joints, namespace)
                    if newJoints:
                        #weights = substitute( weights, [(namespace, '')] )
                        alteration = ['rem', namespace + ':']
                        fixed = True
                    else:
                        if failedCount < lowestFail:
                            lowestFail = failedCount
                            bestChoice = ['rem', namespace + ':']

                if not fixed:
                    #print 'Testing to see if joints exist with a different namespace l.m.fa'
                    # See if only one obj exists in the scene with the
                    # simple name and try adding that namespace
                    if available:
                        others = [
                            obj for obj in available
                            if _add.simpleName(obj) == simpleName
                        ]
                    else:
                        others = ls(simpleName, r=1)

                    for other in others:
                        newNamespace = _add.shortName(other).rsplit(':', 1)[0]

                        newJoints, failedCount = _changeNS(
                            joints, namespace, newNamespace)

                        if newJoints:
                            #weights = substitute( weights, [(namespace, newNamespace)] )
                            alteration = [
                                'sub', namespace + ':', newNamespace + ':'
                            ]
                            fixed = True
                            break
                        else:
                            if failedCount < lowestFail:
                                lowestFail = failedCount
                                bestChoice = [
                                    'sub', namespace + ':', newNamespace + ':'
                                ]

            else:
                # See if the first bone has a namespace and try adding it
                # to all the others.
                others = cmds.ls(missingObj, r=1)

                for other in others:

                    if available is not None and other not in available:
                        continue

                    namespace = other[:-len(missingObj)]
                    newJoints, failedCount = _addNS(joints, namespace)
                    if newJoints:
                        #weights = prepend( weights, namespace )
                        alteration = ['add', namespace]
                        fixed = True
                        break
                    else:
                        if failedCount < lowestFail:
                            lowestFail = failedCount
                            bestChoice = ['add', namespace]

            if fixed:
                return NSChange(alteration, newJoints)

    if bestChoice:
        return NSChange(bestChoice, [])
    else:
        return NSChange([], [])
Example #12
0
def _adjustForNamespace(jointNames):
    alts = cmds.ls( [name.rsplit(':', 1)[-1] for name in jointNames], r=True)
    if len(alts) == len(jointNames):
        return alts
    return []