Beispiel #1
0
 def setRot(obj, r, *args):
     obj = PyNode(obj)
     for axis, val in zip('xyz', r):
         try:
             obj.attr( 'r' + axis ).set(val)
         except Exception:
             pass
Beispiel #2
0
    def switchSpace(ctl: pm.PyNode, space: str) -> bool:
        """
        Switch a control into a new space

        Args:
            ctl: A node with space switching meta data
            space: The name of the space to switch to

        Returns:
            True if the space was changed, false otherwise
        """
        meta_data = meta.getMetaData(ctl,
                                     pulse.spaces.SPACECONSTRAINT_METACLASS)
        space_data = [
            s for s in meta_data.get('spaces', []) if s['name'] == space
        ]
        if not space_data:
            return False

        space_data = space_data[0]
        index = space_data['index']

        # remember world matrix
        wm = ctl.wm.get()
        # change space
        ctl.attr('space').set(index)
        # restore world matrix
        pulse.nodes.setWorldMatrix(ctl, wm)

        return True
Beispiel #3
0
 def setTrans(obj, t, *args):
     obj = PyNode(obj)
     for axis, val in zip('xyz', t):
         try:
             obj.attr( 't' + axis ).set(val)
         except Exception:
             pass
Beispiel #4
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
Beispiel #5
0
def readIdSpec(spec):
    global _specPlugins
    
    #if 'type' in spec: # At some point, say 2024, fully deprecate 'fossil_oldspec'
    #    spec['idtype'] = 'fossil_oldspec'
        
    readers = _specPlugins.get( spec['idtype'], (UnknownSpec,) )
    
    if 'ver' in spec:
        version = spec['ver']
        for reader in readers:
            if reader.version[0] == version[0]:
                break
        else:
            # &&& Is it sensible to default to the latest or error?
            reader = readers[0]
            print(reader, 'reader')
    else:
        reader = readers[0]
    
    # Finally, read the specialized spec but fallback to long, then short names if not found
    obj = reader.readSpec(spec)
    if not obj:
        if objExists(spec['long']):
            return PyNode(spec['long'])
        
        if objExists(spec['short']):
            return PyNode(spec['short'])
    
    return obj
Beispiel #6
0
def getRoot(nodes=None, make=None):
    '''
    Returns the root bone, trying to account for case and namespaces or None if
    not found.  `make` should be either 'root' or 'weaponRoot', specifying which
    to make (always top level) if a root is not found.
    
    Can be given a list of nodes to search for the root,
    '''

    names = [ 'b_root', 'b_Root', 'Rig:b_root', 'Rig:b_Root', 'b_weaponRoot', 'Rig:b_weaponRoot' ]

    if not nodes:
        # Check if any exist top level first
        top = ls(assemblies=True)
        for name in names:
            if name in top:
                return PyNode('|' + name)
    
    # See if there is a top level obj in a namespace named b_root of any casing.
    searchNodes = nodes if nodes else ls( assemblies=True )
    nodes = [obj for obj in searchNodes if simpleName( obj ).lower() == 'b_root' or simpleName(obj).lower() == 'b_weaponroot']
    if len(nodes) == 1:
        return nodes[0]

    # Then check if any exist at all (which will fail if several exist in separate groups).
    for name in names:
        if objExists( name ):
            return PyNode( name )

    if make:
        return joint(None, n='b_' + make)
    
    else:
        return None
Beispiel #7
0
def animInfoNode(create=True):
    '''
    Returns the MT_AnimationInfoNode, making it if it doesn't exist.
    '''

    animNode = None
    animNodes = ls('MT_AnimationInfoNode*')

    if len(animNodes) == 1:
        animNode = animNodes[0]
    elif not animNodes:
        if create:
            animNode = PyNode(
                scriptNode(name="MT_AnimationInfoNode",
                           scriptType=0,
                           sourceType=1))
        else:
            return None
    else:
        print("Multiple anim nodes found")
        for obj in animNodes:
            if simpleName(obj) == 'MT_AnimationInfoNode':
                return obj
        else:
            animNode = animNodes[0]

    _addSeqAttr(animNode)
    return PyNode(animNode)  # Recast to ensure SequenceNode api
Beispiel #8
0
def test_basicBiped():

    #gui = main.RigTool()

    # Make the default biped
    card.bipedSetup(spineCount=5)

    # Make all the bones and test their existence
    select(core.findNode.allCards())
    main.RigTool.buildBones()

    for j in jointsToMake:
        assert objExists(j), 'Joint ' + j + ' was not made'

    root = core.findNode.getRoot()

    assert len(listRelatives(root, ad=True,
                             type='joint')) == (len(jointsToMake) -
                                                1), 'Too many bones were made'

    # Build the rig
    spine = PyNode('Spine_card')
    rigData = spine.rigData
    rigData['rigCmd'] = 'SplineChest'
    spine.rigData = rigData

    select(core.findNode.allCards())
    main.RigTool.buildRig()
Beispiel #9
0
def fixUnhookedSpaces(ctrl):
    '''
    Preliminary tool to deal with messed up spaces.
    
    Right now ONLY deals if there is a space name and destination unhookedup.
    FILL IN OTHERS WITH ERROR IN NAME???
    '''

    names = common.getNames(ctrl)
    space = pdil.dagObj.zero(ctrl, apply=False)
    constraint = PyNode(parentConstraint(space, q=True))
    targetPlugs = constraint.getWeightAliasList()

    if len(names) != len(targetPlugs):
        print('There are', len(names), 'but', len(targetPlugs),
              ', you will need to figure out what is right!')

    noDriver = {}
    for i, plug in enumerate(targetPlugs):
        cons = plug.listConnections(s=True, d=False)
        if not cons:
            noDriver[i] = plug

    #
    connected = {}
    unconnected = []
    conditions = ctrl.attr(common.ENUM_ATTR).listConnections(type='condition')

    for c in conditions:
        con = c.outColorR.listConnections()
        if con:
            order = c.secondTerm.get()
            connected[order] = con[0]
        else:
            unconnected.append(c)

    missingIndex = range(len(targetPlugs))
    for i in connected:
        missingIndex.remove(i)

    if len(noDriver) == 1 and len(unconnected) == 1:
        print(noDriver, unconnected)
        print(connected.keys())
        print(missingIndex)

        print('Autofixing!',
              noDriver.values()[0], 'is "%s"' % names[missingIndex[0]])
        unconnected[0].secondTerm.set(missingIndex[0])
        #print( noDriver.values()[0] )
        unconnected[0].outColorR >> noDriver.values()[0]

    if not noDriver and not unconnected:
        print('All good!')
    else:
        print('This had some errors')

    'FILL IN OTHERS WITH ERROR IN NAME???'
Beispiel #10
0
def findFromIds(ids):
    '''
    Given the dict from `getIds()`, returns an object if possible.
    '''

    if len(ls(ids['short'], r=True)) == 1:
        return PyNode(ids['short'])

    if len(ls(ids['long'], r=True)) == 1:
        return PyNode(ids['long'])
Beispiel #11
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
Beispiel #12
0
def findFromIds(ids):
    '''
    Given the dict from `getIds()`, returns an object if possible.
    
    ..todo:: Process card path and joint paths, (as defined in `getIds`)
    '''

    if len(ls(ids['short'], r=True)) == 1:
        return PyNode(ids['short'])

    if len(ls(ids['long'], r=True)) == 1:
        return PyNode(ids['long'])
Beispiel #13
0
    def configure_global(self):
        """
        Configure V-Ray global baking options
        """

        # Create default VRay bake options node
        # NOTE: Doesn't work in batch mode, assuming already exist
        # pm.mel.vrayShowDefaultBakeOptions()
        bake_options = PyNode('vrayDefaultBakeOptions')

        # Set global bake options
        # bake_options.setAttr('filenamePrefix', self.cur_version_string)
        bake_options.setAttr('outputTexturePath', self.output_texture_path)
Beispiel #14
0
def ikFkSwitch(obj, start, end):
    '''
    Ik/Fk switch
    
    Takes any controller type (ik or fk) and switches to the other.
    '''

    obj = PyNode(obj)

    if isinstance(obj, fossilNodes.RigController):
        mainCtrl = obj
    else:
        mainCtrl = obj.message.listConnections(
            type=fossilNodes.RigController)[0]

    otherCtrl = mainCtrl.getOtherMotionType()

    # If we are changing to fk...
    if otherCtrl.fossilCtrlType.get() in ['translate', 'rotate']:

        if start == end and start is not None:  # Might want ikFkRange to handle this distinction
            activateFk(otherCtrl)
        else:
            ikFkRange(otherCtrl, start, end)

    # If we are changing to ik
    else:
        activateIk(otherCtrl, start, end)
Beispiel #15
0
    def rotate(self, dir, angle):
        rot = [0, 0, 0]
        rot[ord(dir) - ord('x')] = angle

        trans = [
            PyNode(obj) for obj in selectedNodes()
            if objectType(obj) == 'transform'
        ]
        trans += [
            PyNode(obj).getParent() for obj in selectedNodes()
            if objectType(obj).startswith('nurbs')
        ]

        for obj in set(trans):
            for shape in core.shape.getShapes(obj):
                rotate(shape.cv, rot, r=True, os=True)
Beispiel #16
0
def loadCardStates():
    try:
        cardStateInfo = json.loads( pdil.text.clipboard.get() )
    except Exception:
        print( 'Valid json was not found in the clipboard' )
        return
    
    selectedCards = getSelectedCards()
    
    # If there is a single card, just apply the data
    if len(cardStateInfo) == 1 and len(selectedCards) == 1:
        info = cardStateInfo.values()[0]
        cardAndInfo = [(selectedCards[0], info)]
    
    # Otherwise apply data to as many cards with the same names
    else:
        cardAndInfo = [(PyNode(card), info) for card, info in cardStateInfo.items() if objExists(card)]
                
        
    for card, info in cardAndInfo:
        if 'fossilRigState' in info:
            card.fossilRigState.set( info['fossilRigState'] )
            
        for side in ('Left', 'Center', 'Right'):
            for kinematic in ('ik', 'fk'):
                shapeAttr = 'outputShape' + side + kinematic
                if shapeAttr in info:
                    card.attr( shapeAttr ).set( info[ shapeAttr ] )
Beispiel #17
0
def mainGroup(nodePool=None):
    '''
    Returns the main group containing the rig, named "main", or an object tagged as the main.
    
    todo: This logic should mainly go into `mainControls`, and this just returns the first.
    '''
    
    if nodePool:
        for n in nodePool:
            if simpleName(n) == 'main' or n.hasAttr(MAIN_CONTROL_TAG):
                return n
    
    if objExists('|main'):
        return PyNode('|main')
    else:
        # A pymel bug is sometimes returning duplicate nodes
        main = list(set([ obj for obj in ls( 'main', r=True) if not obj.getParent() ]))
        if len(main) == 1:
            return main[0]
    
    # No "main" ojbect was found, looking for tags
    plugs = ls('*.' + MAIN_CONTROL_TAG)
    if plugs:
        return plugs[0].node()
    
    return None
Beispiel #18
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)]
Beispiel #19
0
    def configure_global(self):
        """
        Configure V-Ray global baking options
        """
        bake_options = PyNode('vrayDefaultBakeOptions')

        bake_options.setAttr('filenamePrefix', self.cur_version_string)
        bake_options.setAttr('outputTexturePath', self.output_texture_path)
        bake_options.setAttr('resolutionX', self.image_width)
Beispiel #20
0
def deserializeAllConnections(connections=None):

    if connections is None:
        connections = json.loads(core.text.clipboard.get())

    for obj, data in connections.items():
        if objExists(obj):
            connect(PyNode(obj), data)
Beispiel #21
0
def makeMirrored(reposeJoint):
    ''' Makes a joint that mirrors the transforms of the given repose joint, possibly returning an already existing one.
    '''
    
    if hasAttr(reposeJoint, 'mirrorGroup'):
        con = reposeJoint.mirrorGroup.listConnections()
        if con:
            return con[0]
    else:
        reposeJoint.addAttr('mirrorGroup', at='message')
    
    root = PyNode(reposeJoint.fullPath().split('|', 2)[1])
    print(root)
    for child in root.listRelatives():
        if child.name() == 'mirrorGroups':
            grouper = child
            break
    else:
        grouper = group(em=True, n='mirrorGroups')
        grouper.inheritsTransform.set(False)
        grouper.setParent(root)
    
    
    follower = group(em=True)
    mirror = group(em=True)
    reposeMirror = group(em=True)
    
    pdil.math.multiply(follower.tx, -1) >> mirror.tx
    follower.ty >> mirror.ty
    follower.tz >> mirror.tz
    
    follower.rx >> mirror.rx
    pdil.math.multiply(follower.ry, -1) >> mirror.ry
    pdil.math.multiply(follower.rz, -1) >> mirror.rz
    
    parentConstraint(reposeJoint, follower, mo=False)
    parentConstraint(mirror, reposeMirror)
    reposeMirror.setParent(reposeJoint)
    
    reposeMirror.message >> reposeJoint.mirrorGroup
    
    follower.setParent(grouper)
    mirror.setParent(grouper)
    
    return reposeMirror
Beispiel #22
0
def addMissingJoints(obj, joints):
    '''
    Adds the given joints to the mesh if they aren't already influencing without affecting the current skinning.
    '''
    boundJoints = skinCluster(obj, q=True, inf=True)

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

    skinCluster(obj, e=True, addInfluence=missing, weight=0)
Beispiel #23
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
Beispiel #24
0
def customUp(jnt, arrow=None):

    if not arrow:
        arrow = makeArrow()
        arrow.setParent(jnt.getParent())
        arrow.rename('custom_arrow')
        util.moveTo(arrow, jnt)

    PyNode(jnt).customUp = arrow
    return arrow
Beispiel #25
0
    def rotate(dir, angle, space):
        rot = [0, 0, 0]
        rot[ord(dir) - ord('x')] = angle

        trans = [
            PyNode(obj) for obj in selectedNodes()
            if objectType(obj) == 'transform'
        ]
        trans += [
            PyNode(obj).getParent() for obj in selectedNodes()
            if objectType(obj).startswith('nurbs')
        ]

        for obj in set(trans):
            for shape in pdil.shape.getNurbsShapes(obj):
                if space == 'world':
                    rotate(shape.cv, rot, r=True, ws=True)
                else:
                    rotate(shape.cv, rot, r=True, os=True)
Beispiel #26
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 []
Beispiel #27
0
def serializeAllConnections(toClipboard=False):
    visGroup = PyNode(get(create=False))

    connections = {}

    for plug in visGroup.listAttr(ud=True, s=True, w=True):
        for node in plug.listConnections():
            if node.type() == 'condition':
                for obj in node.listConnections(s=False, d=True):
                    data = getVisGroup(obj)
                    if data:
                        connections[obj.name()] = data
            else:
                data = getVisGroup(node)
                connections[node.name()] = data

    if toClipboard:
        core.text.clipboard.set(json.dumps(connections))
    else:
        return connections
Beispiel #28
0
def findRelatedSkinCluster(skin):
    '''
    Mel's findRelatedSkinCluster that returns a PyNode.
    '''
    try:
        skin = mel.findRelatedSkinCluster( str(skin) )
        if skin:
            return PyNode(skin)
        else:
            return None
    except Exception:
        return None
Beispiel #29
0
def activate_ik(chestCtrl):
    '''
    '''
    util.alignToMatcher(chestCtrl)
    matcher = util.getMatcher(chestCtrl)
    endJoint = PyNode(parentConstraint(matcher, q=True, tl=True)[0])

    endBpj = rig.getBPJoint(endJoint)

    if chestCtrl.isPrimarySide:
        children = [c.real for c in endBpj.proxyChildren if not c.isHelper]
    else:
        children = [
            c.realMirror for c in endBpj.proxyChildren if not c.isHelper
        ]

    if children:
        rot = xform(children[0], q=True, ws=True, ro=True)
        pos = xform(children[0], q=True, ws=True, t=True)

    # ---

    midJnt = chestCtrl.subControl['mid'].listRelatives(type='joint')[0]

    skin = listConnections(midJnt, type='skinCluster')
    curveShape = skin[0].outputGeometry[0].listConnections(p=True)[0].node()
    ikHandle = curveShape.worldSpace.listConnections(type='ikHandle')[0]

    chain = util.getChainFromIk(ikHandle)

    boundJoints = util.getConstraineeChain(chain)

    if len(boundJoints) % 2 == 1:
        #switch_logger.debug('Mid point ODD moved, # bound = {}'.format(len(boundJoints)))
        i = int(len(boundJoints) / 2) + 1
        xform(chestCtrl.subControl['mid'],
              ws=True,
              t=xform(boundJoints[i], q=True, ws=True, t=True))
    else:
        i = int(len(boundJoints) / 2)
        xform(chestCtrl.subControl['mid'],
              ws=True,
              t=xform(boundJoints[i], q=True, ws=True, t=True))
        #switch_logger.debug('Mid point EVEN moved, # bound = {}'.format(len(boundJoints)))

    # FK match joints beyond the chest control

    if children:
        print(rot, pos)
        xform(chestCtrl.subControl['offset'], ws=True, ro=rot)
        xform(chestCtrl.subControl['offset'], ws=True, t=pos)
    """
Beispiel #30
0
def load(jsonfile='', subst={}, remove=[], replace=OrderedDict()):
    if not jsonfile:
        data = _loadTempWeight()
    else:
        with open(jsonfile, 'r') as fid:
            data = json.load(fid)
    
    for mesh, weightData in data.items():
        
        if subst or remove or replace:
            processWeightData(weightData, subst, remove, replace)
        
        apply( PyNode(mesh), weightData)