def getValue(self):
        """Get the asset ID from this browser window"""

        show = str(self.__showEdit.text())
        shot = str(self.__shotEdit.text())
        asset = str(self.__assetEdit.text())
        version = str(self.__versionEdit.text())

        assetFields = {
            "show": show,
            "shot": shot,
            AssetAPI.kAssetFieldName: asset,
            AssetAPI.kAssetFieldVersion: version
        }
        assetPlugin = AssetAPI.GetDefaultAssetPlugin()

        assetId = assetPlugin.buildAssetId(assetFields)
        return assetId
Пример #2
0
    def setValue(self, value):
        """
        Given an asset ID. Set the Show, Shot, Asset and version in the UI.
        """

        assetPlugin = AssetAPI.GetDefaultAssetPlugin()
        if not assetPlugin.isAssetId(value):
            return

        assetFields = assetPlugin.getAssetFields(value, True)
        self.__showEdit.setText(assetFields["show"])
        self.__shotEdit.setText(assetFields["shot"])
        self.__assetEdit.setText(assetFields[AssetAPI.kAssetFieldName])
        self.__versionEdit.setText(assetFields[AssetAPI.kAssetFieldVersion])

        if assetFields.get("protocol", "") == "sandbox":
            self.__protocolLabel.setText("sandbox://")
        else:
            self.__protocolLabel.setText("mock://")
Пример #3
0
    def getValue(self):
        """Get the asset ID from this browser window"""

        show = str(self.__showEdit.text())
        shot = str(self.__shotEdit.text())
        asset = str(self.__assetEdit.text())
        version = str(self.__versionEdit.text())

        protocol = "asset"
        if self.__protocolLabel.text() == "sandbox://":
            protocol = "sandbox"

        assetFields = {"protocol" : protocol,
                       "show" : show,
                       "shot" : shot,
                       AssetAPI.kAssetFieldName : asset,
                       AssetAPI.kAssetFieldVersion : version}
        assetPlugin = AssetAPI.GetDefaultAssetPlugin()

        assetId = assetPlugin.buildAssetId(assetFields)
        return assetId
Пример #4
0
    def __traverseItemTree(self,
                           assetItem,
                           treeParent,
                           selectedKeys,
                           openState,
                           node=None):
        item = AssetListViewItem(treeParent, '')
        key = node
        selectable = True
        if not node:
            try:
                key = assetItem.getItemKey()
                selectable = assetItem.isSelectable()
            except Exception as exception:
                log.exception('Error accessing asset item %s: %s' %
                              (assetItem, str(exception)))

        item.setItemData({
            'type': 'assetTree',
            'assetItem': assetItem,
            'key': key
        })
        if selectable:
            item.setSelected(key in selectedKeys)
            item.setFlags(
                QtCore.Qt.ItemFlags(QtCore.Qt.ItemIsSelectable
                                    | QtCore.Qt.ItemIsEnabled))
        else:
            item.setFlags(QtCore.Qt.ItemFlags(QtCore.Qt.ItemIsEnabled))
        defaultState = assetItem.getDefaultOpenState()
        expanded = openState.get(key, defaultState)
        item.setExpanded(expanded)
        try:
            assetId = assetItem.getAssetId()
            if assetId:
                assetPlugin = AssetAPI.GetDefaultAssetPlugin()
                if assetPlugin.isAssetId(assetId):
                    fields = assetPlugin.getAssetFields(assetId, True)
                    version = fields.get('version', None)
                    resolvedVersion = assetPlugin.resolveAssetVersion(
                        assetId, throwOnError=True)
                    if version:
                        item.setText(VERSION_COLUMN, version)
                        item.setIcon(
                            VERSION_COLUMN,
                            UI4.Util.IconManager.GetIcon(
                                'Icons/heightAdjustDownHilite16.png'))
                    if resolvedVersion:
                        item.setText(RESOLVED_VERSION_COLUMN, resolvedVersion)
        except Exception as exception:
            log.exception('Error getting version of asset item %s: %s' %
                          (assetItem, str(exception)))

        try:
            assetItem.setItemState(item)
        except Exception as exception:
            log.exception('Error setting state of asset item %s: %s' %
                          (assetItem, str(exception)))

        if assetItem.isIgnorable() and assetItem.isIgnored():
            item.setIcon(NAME_COLUMN,
                         UI4.Util.IconManager.GetIcon('Icons/ignore16.png'))
        try:
            children = assetItem.getChildren()
            if children:
                for child in children:
                    self.__traverseItemTree(child, item, selectedKeys,
                                            openState)

        except Exception as exception:
            log.exception('Error traversing children of asset item %s: %s' %
                          (assetItem, str(exception)))

        try:
            assetItem.addNodeObservers(self.__addObserverNode)
        except Exception as exception:
            log.exception('Error adding node observer to asset item %s: %s' %
                          (assetItem, str(exception)))

        return item
    def getResult(self):
        assetFields = self.__widget.getAssetFields()
        assetPlugin = AssetAPI.GetDefaultAssetPlugin()

        return assetPlugin.buildAssetId(assetFields)
Пример #6
0
def _Populate(filepath, node, graveyard={}):
    """
    Populate the casting sheet node with the contents of the casting sheet file
    pointed to by 'filepath'.
    
    Use the graveyard parameter to bring back locked nodes that were not part of the last
    set casting sheet version.  
    """

    # Create a new merge node
    #
    merge = NodegraphAPI.CreateNode('Merge')
    merge.setName('MergeCastingSheet')
    merge.setParent(node)
    mergeOut = merge.getOutputPort("out")

    # Connect the merge node
    # to this nodes output port
    #
    returnOut = node.getReturnPort("out")
    mergeOut.connect(returnOut)

    # Resolve the asset file path
    #
    assetPlugin = AssetAPI.GetDefaultAssetPlugin()

    # Iterate over all the entries
    # in the casting sheet loading
    # their respective nodes
    #
    GRID_WIDTH = 200
    GRID_Y_OFFSET = 200
    FIRST = 0
    ID, NAME = (0, 1)
    for index, asset in enumerate(CastingSheetIO.Iterator(filepath)):
        assetId = asset[ID]
        assetName = asset[NAME]

        # If it exists in the 'graveyard'.
        # bring it back to life
        #
        child = graveyard.get(assetName, None)

        if not child:

            # Get hold of a plug-in that can load this asset
            #
            plugin_name = FindPluginFromAssetIdType(assetId)

            # Ensure that a matching plug-in was found
            # for the asset type
            #
            if plugin_name == None:
                log.error(
                    "We were unable to find a plug-in to load the the asset '%s'."
                    % (assetId))

            else:

                # The location of the casting sheet asset in the scene graph
                #
                locationExpression = 'getParam("%s.castingInfo.name") + "/" + getNode(nodeName).getParent().castingInfo.name' % (
                    node.getName())

                # Load it in
                #
                child = AssetModule.TriggerBatchCreateCallback(
                    plugin_name, node, assetId, locationExpression)

                # We can try to set the name of the casting sheet item
                # but if there is already an item that exists in the scene
                # with that same name then we will be given a different name.
                #
                child.setName(assetName)

                # So store the casting sheet name on the node as a parameter.
                # We will use this later for synching.
                #
                setCastingParam(child, "name", assetName)
                setCastingParam(child, "locked", UNLOCK,
                                NodegraphAPI.Parameter.createChildNumber)

        if child:
            # Re-parent the node
            #
            child.setParent(node)

            # Merge this input in
            #
            entry = merge.addInputPort(assetName)
            main = child.getOutputPortByIndex(FIRST)

            main.connect(entry)

        else:
            log.warning(
                "We were unable to create a new casting node for the casting sheet entry '%s' at '%s'."
                % (assetName, assetId))
Пример #7
0
def SyncCastingSheet(node, assetId):
    """
    Sync the casting sheet node to the given asset.
    
    -------------------------------------------------------------------
    Syncing steps
    
    Delete the merge node.
    
    Iterate over all of child nodes and ...
       - If they are locked:
           - Move the current node to the 'graveyard' group node.
               We are guaranteed that there will not be a node with the same casting name
               in this group node because if there had been it would have been in the
               casting sheet.
    
       - If they are not locked
           - Delete them
    
    For every node in the 'graveyard' node create an entry in a graveyard map.
    
    Create a new merge node.
    
    Iterate over all of the entries in the casting sheet:
        - If an asset of the given instance name exists in the graveyard map then:
           - re-parent the node under the casting sheet and use it
           
        - Otherwise:
           - Create a new node with the plug-in callback system
    
        Then connect the node to the merge node.
        
    Save the casting sheet asset id in to the parameter castingInfo.asset
    """

    # Type check
    #
    nodeType = node.getType()
    if nodeType != "CastingSheet":
        log.error(
            "You are trying to delete a node that is not a casting sheet node")
        return

    # For the casting sheet we always
    # resolve the asset version in the asset id
    # immediately.
    #
    assetPlugin = AssetAPI.GetDefaultAssetPlugin()
    assetId = _ReplaceTagsWithNumbers(assetId)
    filepath = assetPlugin.resolveAsset(assetId)
    if not filepath:
        log.error(
            "Unable to resolve the casting sheet asset ID for '%s' in the casting sheet node '%s'"
            % (assetId, node.getName()))
        return

    # Check if we will be able to load
    # the asset ids casting sheet on file
    #
    if not _PopulatePreCondition(filepath):
        return

    # Ensure that the casting sheet node has a valid internal state
    #
    children = list(node.getChildren())
    if not children:
        log.error(
            "Casting sheet node '%s' is in an invalid state it has no merge node or graveyard node, remove it and create a new one"
            % node.getName())
        return

    # The graveyard node is always first, then the merge node.
    #
    graveyardNode = _GetGraveyardNode(node)
    mergeNode = _GetMergeNode(node)

    # This is done to support an assertion only.
    # It does not contribute to the functionality of this code.
    #
    takenGraveyardNames = set(
        (GetCastingName(child) for child in graveyardNode.getChildren()))

    # Get hold of the children before the
    # merge node is deleted
    #
    entries = _GetInputNodes(mergeNode)

    # In case the merge node doesn't exist
    #
    if mergeNode.getType() == "Merge":
        mergeNode.delete()

    # Everything else is a casting sheet entry
    #
    for child in entries:
        if IsLocked(child):
            assert GetCastingName(child) not in takenGraveyardNames
            child.setParent(graveyardNode)
        else:
            child.delete()

    # Create a casting name to node mapping
    #
    graveyard = [(GetCastingName(n), n) for n in graveyardNode.getChildren()]
    graveyard = dict(graveyard)

    # Populate the node with casting sheet entries
    #
    _Populate(filepath, node, graveyard)

    # Now store the asset id so that we know where this all came from
    #
    setCastingParam(node,
                    "asset",
                    assetId,
                    hintsDict={'widget': 'assetIdInput'})

    # Finally rebuild the layout
    #
    _LayoutContents(node)
Пример #8
0
def AddCastingSheet(importomaticNode, assetId, locationExpression=None):
    """
    Load the chosen casting sheet specified by assetId to the location specified by locationExpression.
    """

    # We can't do anything without a casting sheet asset id

    if assetId == None:
        log.error("No asset id given for new casting sheet")
        return

    # Resolve the asset file path
    #
    # Get hold of the primary asset plugin
    # so that we can resolve the casting sheet asset.

    assetPlugin = AssetAPI.GetDefaultAssetPlugin()
    filepath = assetPlugin.resolveAsset(assetId)
    if not filepath:
        log.error("Unable to resolve the casting sheet asset ID for '%s'" %
                  assetId)
        return

    # Check if we will be able to load
    # the asset ids in the casting sheet on file

    if not _PopulatePreCondition(filepath):
        return

    # Store everything inside of the casting sheet group

    node = NodegraphAPI.CreateNode('Group')
    node.setName('CastingSheet')
    node.setType(CASTINGSHEET_TYPE)
    node.addOutputPort('out')
    returnOut = node.getReturnPort("out")

    # CastingSheet parameters - Scene graph location

    if locationExpression:
        setCastingStringParamExpression(
            node,
            "name",
            locationExpression,
            hintsDict={'widget': 'scenegraphLocation'})

    # If a locationExpression wasn't given
    # default to a sensible place

    else:
        location = '/root/world/geo/%s' % node.getName()
        setCastingParam(node,
                        "name",
                        location,
                        hintsDict={'widget': 'scenegraphLocation'})

    # Create our graveyard node
    # This should be created first because it
    # never gets deleted

    graveyard = NodegraphAPI.CreateNode('Group')
    graveyard.setName('Graveyard')
    graveyard.setParent(node)

    # Read the casting sheet and populate
    # the casting sheet node.

    _Populate(filepath, node)

    # Now store the asset id so that we know where this all came from

    setCastingParam(node,
                    "asset",
                    assetId,
                    hintsDict={'widget': 'assetIdInput'})

    # Finally adjust the layout in the nodegraph ui

    _LayoutContents(node)

    return node
Пример #9
0
def AddScenegraphXmlGeometry(importomaticNode,
                             assetId,
                             locationExpression=None):

    filename = ''
    assetPlugin = AssetAPI.GetDefaultAssetPlugin()
    if assetPlugin.isAssetId(assetId):
        filename = assetPlugin.resolveAsset(assetId)
    else:
        return

    fileBase = os.path.basename(filename)
    rootParamName = os.path.splitext(fileBase)[0]

    # Parse XML to extract relevant information
    xmlTree = ET.parse(filename)
    xmlRoot = xmlTree.getroot()

    node = None

    # Find all instances of type reference
    rootInstanceList = xmlRoot.find("instanceList")
    if rootInstanceList is not None:
        rootInstance = rootInstanceList.find("instance")
        rootInstanceName = rootInstance.attrib["name"]
        rootInstanceType = rootInstance.attrib["type"]

        node = NodegraphAPI.CreateNode('Group')
        node.setName(rootParamName)
        # This seems a bit odd to set the name and then retrieve it but Katana
        # will change the name to a unique name which we can then extract
        uniqueRootName = node.getName()
        node.setType('ScenegraphXml')
        node.addOutputPort('out')

        xmlInNode = NodegraphAPI.CreateNode('ScenegraphXml_In', node)
        xmlInNode.getOutputPortByIndex(0).connect(node.getReturnPort('out'))

        # If the location parameter isn't
        # given try to intelligently guess one
        #
        if locationExpression:
            xmlInNode.getParameter('name').setExpression(
                locationExpression, True)
        else:
            baseLocation = xmlInNode.getParameter("name").getValue(0)
            location = baseLocation + '/' + uniqueRootName
            xmlInNode.getParameter('name').setValue(location, 0)

        xmlInNode.getParameter('asset').setValue(assetId, 0)
        basePath = os.path.dirname(filename) + os.sep

        assetInfoParam = node.getParameters().createChildGroup('assetInfo')
        assetInfoParam.createChildString('_ignore', 'False')
        assetInfoParam.createChildString('_sgPath', '/' + uniqueRootName)

        findInstances(rootInstanceList, assetInfoParam, node, basePath, "")

    BuildScenegraph(node)

    return node