Exemplo n.º 1
0
def setCurveColor(ctrl, newColor):
    '''
    newColor can an indexed color or you can specify RGB.
    
    NOTE!!! RGB is NOT currently saved.
    '''

    curves = [
        c for c in cmds.listRelatives(ctrl.name(), type='nurbsCurve', f=True)
        if core.shape.isValidNurbsCurve(c)
    ]

    surfaces = cmds.listRelatives(ctrl.name(), type='nurbsSurface', f=True)
    if surfaces:
        curves += surfaces

    for shape in curves:
        try:
            cmds.setAttr(shape + '.overrideEnabled', True)

            if isinstance(newColor, int):
                cmds.setAttr(shape + '.overrideColor', newColor)
                cmds.setAttr(shape + '.overrideRGBColors', False)
            else:
                cmds.setAttr(shape + '.overrideRGBColors', True)
                cmds.setAttr(shape + '.overrideColorRGB', *newColor)

        except Exception:
            pass
Exemplo n.º 2
0
def assign(obj, color):
    '''
    Assign a shader of the given color and opacity, reusing shaders when possible.
    '''
    global namedColors
    if isinstance(color, basestring):
        color = parseStr(color)

    if len(color) == 3:
        color = list(color) + [1.0]

    shaders = findShaders(color)
    if not shaders:
        # No existing shader was found, so make it.
        shader = createShader(color)
        sg = shader.outColor.listConnections(type='shadingEngine')[0]
    else:
        # Matching shaders were found, find one that is valid.
        for shader in shaders:
            if shader.outColor.listConnections(type='shadingEngine'):
                sg = shader.outColor.listConnections(type='shadingEngine')[0]
                break
        # Or end up making one anyway.
        else:
            shader = createShader(color)
            sg = shader.outColor.listConnections(type='shadingEngine')[0]

    # cmds is much faster, but `sets` vs `pymel.core.sets` has different args (pymel made it saner but I need speed)
    cmds.sets(cmds.listRelatives(obj.name(), type='nurbsSurface', f=True),
              e=True,
              fe=sg.name())
Exemplo n.º 3
0
def rootMotion(main=None):
    ''' Returns the root motion, if main is specified, search that node.
    '''

    if main:

        children = cmds.listRelatives(main.name(),
                                      ad=True,
                                      type='transform',
                                      f=True)
        if children:  # cmds returns None instead of emtpy list
            for child in children:
                if child.rsplit('|', 1)[-1].rsplit(':', 1)[-1] == 'rootMotion':
                    return PyNode(child)

        return None

    if objExists('rootMotion'):
        return PyNode('rootMotion')
    else:
        rms = ls('rootMotion', r=True)
        if len(rms) == 1:
            return rms[0]

    return None
Exemplo n.º 4
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)]
Exemplo n.º 5
0
def get_slow(mesh):
    '''
    Given a mesh, returns a list, one entry per vertex, with a list of (joint, value) pairs.
    ex:
        [0] = [ (ja, .5), (jb, .5) ]
        [1] = [ (ja, .5), (jb, .25), (jc, .25) ]
    '''

    skinClusterName = mel.findRelatedSkinCluster(mesh)
    
    joints = cmds.skinCluster(mesh.name(), q=True, inf=True)
    
    weights = []
    
    required = {}
    for j in joints:
        parent = cmds.listRelatives(j, p=True)
        required[j] = [parent[0] if parent else None] + cmds.xform(j, q=True, ws=True, t=True)
    
    info = {
        'joints': required,
        'weights': weights,
    }
    
    vtxStr = mesh.name() + '.vtx[%i]'
    for i in xrange(mesh.vtx.count()):
        weights.append( [(t, v) for t, v in zip(joints, cmds.skinPercent(skinClusterName, vtxStr % i, q=1, v=1)) if v > 0] )
    
    return info
Exemplo n.º 6
0
 def setInputField(self, card, row, param):
     '''
     Given a `Param`, build, and place, the correct ui element for the param's data type.
     '''
     self.params.append(param)
     
     if param.type == param.BOOL:
         checkBox = QtWidgets.QTableWidgetItem()
         state = Qt.Checked if card.rigData.get('ikParams', {}).get(param.kwargName, param.default) else Qt.Unchecked
         checkBox.setCheckState( state )
         self.setItem( row, 1, checkBox )
         
     elif param.type == param.INT:
         self.setItem( row, 1, QtWidgets.QTableWidgetItem(str(card.rigData.get('ikParams', {}).get(param.kwargName, param.default))) )
         
     elif param.type == param.FLOAT:
         self.setItem( row, 1, QtWidgets.QTableWidgetItem(str( card.rigData.get('ikParams', {}).get(param.kwargName, param.default))) )
         
     elif param.type == param.ENUM:
         dropdown = QtWidgets.QComboBox()
         dropdown.addItems(param.enum.keys())
         #dropdown.currentIndexChanged.connect( partial(self.enumChange, param) )
         #for key, val in param.enum.items():
         #    dropdown.addItem( key ).triggered.connect( partial(self.changeEnum, param.kwargName, val) )
         
         self.setCellWidget(row, 1, dropdown)
         
         try:
             enumVal = param.enum.values().index( card.rigData.get('ikParams', {}).get(param.kwargName, param.default) )
             dropdown.setCurrentIndex(enumVal)
             dropdown.currentIndexChanged.connect( partial(self.enumChange, param=param) )
         except:
             print( 'oerror with', param.kwargName, param.default, card, row )
         
     elif param.type == param.STR:
         val = card.rigData.get('ikParams', {}).get(param.kwargName, param.default)
         self.setItem( row, 1, QtWidgets.QTableWidgetItem(val) )
         
     elif param.type in (param.CURVE, param.NODE_0):  # Just accept curves, they are all I connect to
         dropdown = QtWidgets.QComboBox()
         # Get all the curve transforms under the skeletonBlueprint
         curves = cmds.listRelatives( cmds.listRelatives('skeletonBlueprint', type='nurbsCurve', f=True, ad=True), p=True, f=True)
         self.paramSceneOptions[param] = curves
         if curves:  # &&& This can sometimes be empty, which causes the gui to choke on the error (in 2019, but not 2016)
             dropdown.addItems( curves )  # ERROR?
         
         self.setCellWidget(row, 1, dropdown)
Exemplo n.º 7
0
    def parentName(jnt):
        parent = cmds.listRelatives(j, p=True)
        if parent:
            try:
                return jointNames.index( parent[0] )
            except ValueError:
                return parent[0]

        return None
Exemplo n.º 8
0
def rootMotion(main=None):
    '''
    Returns the root motion, optionally making one if it doesn't exist.

    If main is specified, search its descendents.
    '''
    
    ''' Timing test with Swift as main, re and split are about equal and 200x faster!
        re and split were almost identical, even on the whole scene.
    
        s = time.time()
        #oldGetRootMotion(main)
        for child in listRelatives(main, ad=True, type='transform'):
        #for child in ls(type='transform'):
            if lib.dagObj.simpleName( child ) == 'rootMotion':
                break
                #return child
        print( time.time() - s, 'orig')

        s = time.time()
        for child in cmds.listRelatives(main.name(), ad=True, type='transform'):
        #for child in cmds.ls(type='transform'):
            if child.rsplit('|',1)[-1].rsplit(':', 1)[-1] == 'rootMotion':
                #print( child)
                break
        print( time.time() - s, 'split')

        s = time.time()
        simpleName = re.compile( '\w+$' )
        for child in cmds.listRelatives(main.name(), ad=True, type='transform'):
        #for child in cmds.ls(type='transform'):
            if simpleName.search(child).group(0) == 'rootMotion':
                #print( child)
                break
        print( time.time() - s, 're')
    '''
    
    if main:
                
        children = cmds.listRelatives(main.name(), ad=True, type='transform')
        if children:   # cmds returns None instead of emtpy list
            for child in children:
                if child.rsplit('|', 1)[-1].rsplit(':', 1)[-1] == 'rootMotion':
                    return PyNode(child)
                
        return None

    if objExists( 'rootMotion' ):
        return PyNode( 'rootMotion' )
    else:
        rms = ls( 'rootMotion', r=True )
        if len(rms) == 1:
            return rms[0]
    
    return None
Exemplo n.º 9
0
def find(obj):
    '''
    If there is a shared shape, returns it.  If not, returns None.
    '''
    shapes = cmds.listRelatives(obj.name(), type='nurbsCurve', f=True)
    if not shapes:
        return None
    
    for shape in shapes:
        if objExists( shape + '.sharedShape' ):
            return shape
    return None
Exemplo n.º 10
0
def find(obj, shapeType):
    ''' If `obj` has shared shape of `shapeType`, return it or None if not found.
    '''
    shapes = cmds.listRelatives(obj.name(), type='nurbsCurve', f=True)
    if not shapes:
        return None

    for shape in shapes:
        if (cmds.attributeQuery(core.shape.SHARED_SHAPE, n=shape, ex=True)
                and cmds.getAttr(shape + '.' + core.shape.SHARED_SHAPE)
                == shapeType):
            return shape

    return None
Exemplo n.º 11
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 []
Exemplo n.º 12
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 ''
Exemplo n.º 13
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 []
Exemplo n.º 14
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())
    
        '''
Exemplo n.º 15
0
def get_old(mesh):
    '''
    Creates as dictionary that looks like the following:
    
    {
        'weights': [   ], # index is vertex index, value is list of bone, weight pairs
        [0] = [ ('j1', .75), ('j2', .25) ]...
        
        'joints': {
            'j1': [parent, global_x, global_y, global_z]
            ...
        }
    }
    '''
    
    ''' DEBUG
    from pdil.core import capi
    from maya.api.OpenMayaAnim import MFnSkinCluster
    '''
    
    
    skinClusterName = mel.findRelatedSkinCluster(mesh)
    
    skinClusterMObj = capi.asMObject( skinClusterName )
    skinFn = MFnSkinCluster( skinClusterMObj.object() )
    
    #construct a dict mapping joint names to joint indices
    jointApiIndices = {}
    
    for jointDagMObj in skinFn.influenceObjects():
        jointApiIndices[ skinFn.indexForInfluenceObject( jointDagMObj ) ] = jointDagMObj.partialPathName()
        
    weightListPlug = skinFn.findPlug( 'weightList', True )
    weightListObj = weightListPlug.attribute()
    weightsPlug = skinFn.findPlug( 'weights', True )
    
    weights = [None] * mesh.vtx.count() # Prebuilding the whole range is nearly instant, appending is probably slower
    # since it will trigger resizing.
    
    for vertIdx in xrange(mesh.vtx.count()):  # noqa
        # We need to use the api to query the physical indices used
        weightsPlug.selectAncestorLogicalIndex( vertIdx, weightListObj )
        activeJointIndices = weightsPlug.getExistingArrayAttributeIndices()
        
        # Values = cmds_getAttr( baseFmtStr % vertIdx + '.weights' )[0] # api 2.0 is 0.09 instead of  0.25
        values = [weightsPlug.elementByLogicalIndex(i).asDouble() for i in activeJointIndices]
        
        try:
            # If `i` isn't in jointApiIndices, that value is skipped.  Not sure why these garbage values are just left behind...
            weights[vertIdx] = [ (jointApiIndices[idx], v) for idx, v in zip( activeJointIndices, values ) if idx in jointApiIndices]
        except Exception:
            raise
            '''
            weights[vertIdx] = []
            # This gets hit when an influence object has been removed
            for i, v in zip(activeJointIndices, values):
                if v > 0.000001:
                    weights[vertIdx].append( (jointApiIndices[i], v) )
            '''
    
    # Prune out the unused joints (Maybe make an option?)
    joints = {}
    requiredJoints = set()
    for wgt in weights:
        for j, v in wgt:
            requiredJoints.add(j)
    
    # Save the joint's parent and worldspace position, for possible future use/issue detection.
    for j in requiredJoints:
        parent = cmds.listRelatives(j, p=True)
        joints[j] = [parent[0] if parent else None] + cmds.xform(j, q=True, ws=True, t=True)
    
    
    return {'weights': weights, 'joints': joints}