Example #1
0
def validateMirrorNode(node):
    """
    Ensure the node still has a valid mirroring counterpart.
    If it does not, remove the mirror data from the node.

    Return:
        True if the node is a valid mirror node
    """
    if not isMirrorNode(node):
        return False
    data = meta.getMetaData(node, MIRROR_METACLASS)
    otherNode = data['otherNode']
    if otherNode is None:
        LOG.debug("{0} paired node not found, "
                  "removing mirroring data".format(node))
        meta.removeMetaData(node, MIRROR_METACLASS)
        return False
    else:
        othersOther = getPairedNode(otherNode, False)
        if othersOther != node:
            LOG.debug("{0} pairing is unreciprocated, "
                      "removing mirror data".format(node))
            meta.removeMetaData(node, MIRROR_METACLASS)
            return False
    return True
Example #2
0
 def test_removeLockedData(self):
     meta.setMetaData(self.node, 'myMetaClass', 'myTestData')
     self.node.attr(meta.core.METADATA_ATTR).setLocked(True)
     result = meta.removeMetaData(self.node)
     self.assertFalse(result)
     data = meta.getMetaData(self.node)
     self.assertEqual(data, {'myMetaClass': 'myTestData'})
Example #3
0
 def load(self, node=None):
     if not node:
         node = self.getNode()
     if node:
         data = meta.getMetaData(node, META_CLASSNAME)
         self.name = getCollectionNameFromNode(node)
         self.sets = [QuickSelectSet(**kwargs) for kwargs in data.get('sets', [])]
Example #4
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
Example #5
0
def _createSpaceConstraint(node, spaceNodesByName):
    """
    Connect all spaces defined in the node's space data
    to the space constraint utility nodes.

    Args:
        node (PyNode): The space constraint node
        spaceNodesByName (dict): A dict of the space
            nodes index by name.
    """
    data = meta.getMetaData(node, SPACECONSTRAINT_METACLASS)
    didConnectAny = False
    for spaceData in data['spaces']:
        index = spaceData['index']
        # ensure the switch is not already created
        if not spaceData['switch']:
            spaceNode = spaceNodesByName.get(spaceData['name'], None)
            if spaceNode:
                _connectSpaceToConstraint(node, data, index, spaceNode)
                didConnectAny = True
            else:
                LOG.warning("Space node not found: {0}".format(
                    spaceData['name']))

    if didConnectAny:
        # connect space constraint output now that at least one space is setup
        # TODO: make sure the space 0 is setup, or whatever the attrs value is
        decomp = data['decompose']
        follower = data['follower']
        decomp.outputTranslate >> follower.translate
        decomp.outputRotate >> follower.rotate
        decomp.outputScale >> follower.scale
Example #6
0
 def getRigMetaData(self):
     """
     Return all meta data on the rig being built
     """
     if not self.rig:
         self.log.error('Cannot get rig meta data, no rig is set')
         return
     return meta.getMetaData(self.rig, RIG_METACLASS)
Example #7
0
def getLinkMetaData(node):
    """
    Return all link metadata for a node
    """
    result = meta.getMetaData(node, className=LINK_METACLASS)
    if not result:
        return {}

    return result
Example #8
0
def getAllSpacesIndexedByName():
    """
    Return all space nodes in a dict indexed by their space name
    """
    allSpaceNodes = getAllSpaces()
    result = {}
    for spaceNode in allSpaceNodes:
        spaceData = meta.getMetaData(spaceNode, SPACE_METACLASS)
        result[spaceData['name']] = spaceNode
    return result
    def getFootControl(ctl: pm.PyNode):
        """
        Return the main foot control for a foot control system

        Args:
            ctl: A control with foot control meta data
        """
        if meta.hasMetaClass(ctl, FOOT_CTL_METACLASSNAME):
            return meta.getMetaData(ctl,
                                    FOOT_CTL_METACLASSNAME).get('foot_ctl')
Example #10
0
 def loadFromNode(self, node):
     """
     Load Blueprint data from a node.
     
     Args:
         node: A PyNode or node name
     """
     if not Blueprint.isBlueprintNode(node):
         raise ValueError(
             "Node does not contain Blueprint data: {0}".format(node))
     data = meta.getMetaData(node, BLUEPRINT_METACLASS)
     self.deserialize(data)
Example #11
0
    def debugOpenBlueprintScene(self):
        rigs = pulse.getAllRigs()
        if not rigs:
            print('No rig in the scene')
            return

        rigdata = meta.getMetaData(rigs[0], pulse.RIG_METACLASS)
        blueprintFile = rigdata.get('blueprintFile')
        if not blueprintFile:
            print('No blueprintFile set on the rig')
            return

        print('Opening blueprint: ' + blueprintFile)
        pm.openFile(blueprintFile, f=True)
        self.model.reloadBlueprint()
Example #12
0
def getAllRigsByName(names):
    """
    Return a list of all rigs in the scene that
    have a specific rig name

    Args:
        names: A list of string rig names
    """
    rigs = getAllRigs()
    matches = []
    for r in rigs:
        data = meta.getMetaData(r, RIG_METACLASS)
        if data.get('name') in names:
            matches.append(r)
    return matches
Example #13
0
    def getBlueprintFilepath(self):
        """
        Return the filepath for the Blueprint being edited
        """
        sceneName = None

        if self.rigExists:
            # get filepath from rig
            rig = pulse.getAllRigs()[0]
            rigdata = meta.getMetaData(rig, pulse.RIG_METACLASS)
            sceneName = rigdata.get('blueprintFile')
        else:
            sceneName = pm.sceneName()

        if sceneName:
            filepath = os.path.splitext(sceneName)[0] + '.yaml'
            return filepath
Example #14
0
    def getBlueprintFilepath(self) -> str:
        """
        Return the full path to the Blueprint file being edited.
        """
        sceneName = None

        allRigs = rigs.getAllRigs()
        if len(allRigs) > 0:
            # get filepath from rig
            rig = allRigs[0]
            rigdata = meta.getMetaData(rig, rigs.RIG_METACLASS)
            sceneName = rigdata.get('blueprintFile')
        else:
            sceneName = pm.sceneName()

        if sceneName:
            baseName = os.path.splitext(sceneName)[0]
            filepath = '%s.%s' % (baseName, BLUEPRINT_FILE_EXT)
            return filepath
Example #15
0
def openRigBlueprint(rig):
    """
    Open the Blueprint source file that was used
    to build a rig.

    Args:
        rig: A rig node
    """

    rigdata = meta.getMetaData(rig, RIG_METACLASS)
    blueprintFile = rigdata.get('blueprintFile')
    if not blueprintFile:
        LOG.warning('No blueprintFile set on the rig')
        return

    LOG.info('Opening blueprint: ' + blueprintFile)
    saveCameras()
    pm.openFile(blueprintFile, f=True)
    restoreCameras()
Example #16
0
def _connectSpaceConstraint(node, spaceNodesByName):
    """
    Connect all spaces defined in the node's space data
    to the space constraint utility nodes.

    Args:
        node (PyNode): The space constraint node
        spaceNodesByName (dict): A dict of the space
            nodes index by name.
    """
    data = meta.getMetaData(node, SPACECONSTRAINT_METACLASS)
    didConnectAny = False
    for spaceData in data['spaces']:
        index = spaceData['index']
        # ensure the switch is not already created
        if not spaceData['switch']:
            spaceNode = spaceNodesByName.get(spaceData['name'], None)
            if spaceNode:
                _connectSpaceToConstraint(data, index, spaceNode)
                didConnectAny = True
            else:
                LOG.warning("Space node not found: {0}".format(
                    spaceData['name']))

    if didConnectAny:
        # connect final output now that at least one space is connected
        # TODO: make sure the space 0 is setup, or whatever the attrs value is
        follower = data['follower']
        useOffsetMatrix = data['useOffsetMatrix']

        if useOffsetMatrix:
            multMatrix = data['multMatrix']
            nodes.connectMatrix(multMatrix.matrixSum, follower,
                                nodes.ConnectMatrixMethod.CONNECT_ONLY)
        else:
            # TODO: support joint matrix constraints that don't disable inheritsTransform,
            #       or just remove this path altogether
            decomp = data['decompose']
            decomp.outputTranslate >> follower.translate
            decomp.outputRotate >> follower.rotate
            decomp.outputScale >> follower.scale
            # no longer need to inherit transform
            follower.inheritsTransform.set(False)
Example #17
0
    def buildMenuItems(self):
        ctl = self.getSelectedNodesWithMetaClass(
            pulse.spaces.SPACECONSTRAINT_METACLASS)[0]
        meta_data = meta.getMetaData(ctl,
                                     pulse.spaces.SPACECONSTRAINT_METACLASS)
        spaces = meta_data.get('spaces', [])
        if spaces:
            pm.menuItem(l="Spaces", enable=False)
            for space in spaces:
                index = space['index']
                is_current = ctl.attr('space').get() == index

                title = pulse.names.toTitle(space['name'])
                suffix = ' (Default)' if index == 0 else ''
                prefix = '> ' if is_current else '    '
                display_name = f"{prefix}{title}{suffix}"

                pm.menuItem(l=display_name,
                            c=pm.Callback(SpaceSwitchUtils.switchSpace, ctl,
                                          space['name']))
Example #18
0
def getPairedNode(node, validate=True):
    """
    For a node with mirroring data, return the other node.

    Args:
        node: A node with mirroring data that references another node
        validate (bool): When true, ensures that the pairing is
            reciprocated by the other node
    """
    if isMirrorNode(node):
        data = meta.getMetaData(node, MIRROR_METACLASS)
        if validate:
            otherNode = data['otherNode']
            if otherNode and validate:
                if getPairedNode(otherNode, False) == node:
                    return otherNode
                else:
                    LOG.debug('{0} pairing not reciprocated'.format(node))
        else:
            return data['otherNode']
Example #19
0
def _createSpaceConstraint(node, spaceNodesByName):
    """
    Create the actual constraints for each defined space in
    a space constraint node.

    Args:
        node (PyNode): The space constraint node
        spaceNodesByName (dict): A dict of the space
            nodes index by name.
    """
    data = meta.getMetaData(node, SPACECONSTRAINT_METACLASS)
    for spaceData in data['spaces']:
        # ensure the switch is not already created
        if not spaceData['switch']:
            spaceNode = spaceNodesByName.get(spaceData['name'], None)
            if spaceNode:
                _createConstraintSwitchForSpace(
                    node, data, spaceData, spaceNode)
            else:
                LOG.warning(
                    "Space node not found: {0}".format(spaceData['name']))
Example #20
0
 def test_setAndGetData(self):
     setData = ['myData', {'a': 1, 'b': 2}, ('x', 'y', 'z')]
     className = 'myMetaClass'
     meta.setMetaData(self.node, className, setData)
     self.assertEqual(meta.getMetaData(self.node, className), setData)
Example #21
0
def getLink(node):
    """
    Return the leader that a node is linked to
    """
    return meta.getMetaData(node, className=LINK_METACLASS)
Example #22
0
 def getDelegateControl(node):
     ctl_delegate_data = meta.getMetaData(node, 'pulse_ctl_delegate')
     if ctl_delegate_data:
         return ctl_delegate_data['delegate_ctl']
     return node
Example #23
0
 def getIKFKData(ctl):
     return meta.getMetaData(ctl, IKFK_CONTROL_METACLASS)
Example #24
0
 def metaData(self):
     if self._metaData is None:
         self._metaData = meta.getMetaData(self.node, RIG_METACLASS)
     return self._metaData if self._metaData else {}
Example #25
0
 def test_multiClassData(self):
     cls1 = 'myMetaClass1'
     cls2 = 'myMetaClass2'
     meta.setMetaData(self.node, cls1, None)
     meta.setMetaData(self.node, cls2, None)
     self.assertEqual(meta.getMetaData(self.node), {cls1: None, cls2: None})
Example #26
0
def getMirrorSettings(sourceNode,
                      destNode=None,
                      useNodeSettings=True,
                      excludedNodeSettings=None,
                      **kwargs):
    """
    Get mirror settings that represent mirroring from a source
    node to a target node.

    Args:
        sourceNode: A node to get matrix and other settings from
        destNode: A node that will have mirrored settings applied,
            necessary when evaluating custom mirroring attributes that
            need both nodes to compute
        useNodeSettings: A bool, whether to load custom settings from
            the node or not
        excludedNodeSettings: A list of settings to exclude when loading
            from node

    kwargs are divided up and used as necessary between 3 mirroring stages:
        See 'getMirroredMatrices' for a list of kwargs that can be given
        `mirroredAttrs` -- a list list of custom attribute names that will
            be included when mirroring
        `customMirrorAttrExps` -- a dictionary of {attr: expression} that
            are evaluated using the given sourceNode, destNode to determine
            custom mirroring behaviour for any attributes
    """
    def filterNodeSettings(settings):
        if excludedNodeSettings:
            return {
                k: v
                for k, v in settings.items() if k not in excludedNodeSettings
            }
        return settings

    result = {}

    LOG.debug("Getting Mirror Settings: {0}".format(sourceNode))
    if not destNode:
        destNode = getPairedNode(sourceNode)
    if not destNode:
        return

    # if enabled, pull some custom mirroring settings from the node,
    # these are stored in a string attr as a python dict
    if useNodeSettings:
        data = meta.getMetaData(sourceNode, MIRROR_METACLASS)
        customSettings = data.get('customSettings')
        if customSettings is not None:
            LOG.debug("Custom Mirror Node")
            # nodeStngs = data['customSettings']
            LOG.debug("Settings: {0}".format(customSettings))
            kwargs.update(filterNodeSettings(customSettings))

    # pull some kwargs used for getMirroredMatrices
    matrixKwargs = dict([(k, v) for k, v in kwargs.items()
                         if k in ('axis', 'axisMatrix', 'translate', 'rotate',
                                  'mirrorMode')])
    result['matrices'] = getMirroredMatrices(sourceNode, **matrixKwargs)

    # add list of mirrored attributes as designated by kwargs
    mirAttrKwargs = dict([(a, getattr(sourceNode, a).get())
                          for a in kwargs.get('mirroredAttrs', [])])
    result.setdefault('mirroredAttrs', {}).update(mirAttrKwargs)

    for attr, exp in kwargs.get('customMirrorAttrExps', {}).items():
        if exp:
            LOG.debug("Attr: {0}".format(attr))
            LOG.debug("Exp:\n{0}".format(exp))
            val = evalCustomMirrorAttrExp(sourceNode, destNode, attr, exp)
            LOG.debug("Result: {0}".format(val))
            # Eval from the mirror to the dest
            result['mirroredAttrs'][attr] = val

    LOG.debug("Mirrored Attrs: {0}".format(result['mirroredAttrs']))

    # Save additional variables
    result['sourceNode'] = sourceNode
    result['destNode'] = destNode

    return result
 def getFootControlData(ctl):
     return meta.getMetaData(ctl, FOOT_CTL_METACLASSNAME)