def cacheDialog(dagPath, pulledMayaRefPrim, _):
    '''Display dialog to cache the argument pulled Maya reference prim to USD.'''

    global _mayaRefDagPath
    global _pulledMayaRefPrim

    _mayaRefDagPath = dagPath
    _pulledMayaRefPrim = pulledMayaRefPrim

    ok = getMayaUsdLibString('kCacheMayaRefCache')
    fileFilter = getMayaUsdLibString(
        "kAllUsdFiles"
    ) + " (*.usd *.usda *.usdc *.usdz);;*.usd;;*.usda;;*.usdc;;*.usdz"

    # As per Maya projectViewer.mel code structure, the UI creation
    # (optionsUICreate) creates the main UI framework, and UI initialization
    # (optionsUIInit) puts up the export options.
    files = cmds.fileDialog2(
        returnFilter=1,
        fileMode=0,
        caption=getMayaUsdLibString('kCaptionCacheToUsd'),
        fileFilter=fileFilter,
        dialogStyle=2,
        okCaption=ok,
        # The callbacks below must be MEL procedures, as per fileDialog2
        # requirements.  They call their corresponding Python functions.
        optionsUICreate="mayaUsdCacheMayaReference_cacheCreateUi",
        optionsUIInit="mayaUsdCacheMayaReference_cacheInitUi",
        optionsUITitle="",
        optionsUICommit2="mayaUsdCacheMayaReference_cacheCommitUi",
        startingDirectory=cmds.workspace(query=True, directory=True))
Exemple #2
0
def createMayaReferenceMenuItem(dagPath, precedingItem):
    '''Create a merge to USD menuItem for Maya references.

    If the Maya object at dagPath is a transform corresponding to a Maya
    reference, create a menuItem for it.
    '''

    # The dagPath must have the pull information that brings us to the USD
    # prim.  If this prim is of type Maya reference, create a specific menu
    # item for it, otherwise return an empty string for the chain of
    # responsibility.

    # The dagPath may come in as a shortest unique name.  Expand it to full
    # name; ls -l would be an alternate implementation.
    sn = om.MSelectionList()
    sn.add(dagPath)
    fullDagPath = sn.getDagPath(0).fullPathName()
    mayaItem = ufe.Hierarchy.createItem(ufe.PathString.path(fullDagPath))
    pathMapper = ufe.PathMappingHandler.pathMappingHandler(mayaItem)
    pulledPath = pathMapper.fromHost(mayaItem.path())
    prim = mayaUsd.ufe.ufePathToPrim(ufe.PathString.string(pulledPath))

    # If the pulled prim isn't a MayaReference, not our responsibility.
    if prim.GetTypeName() != 'MayaReference':
        return ''

    cmd = partial(mayaUsdCacheMayaReference.cacheDialog, fullDagPath, prim)
    cacheLabel = getMayaUsdLibString('kMenuCacheToUsd')
    return cmds.menuItem(label=cacheLabel,
                         insertAfter=precedingItem,
                         image="cache_to_USD.png",
                         command=cmd)
def variantNameChanged(selectedItem):
    # If the "Create New" item is selected, we show the text input
    # to the right of the optionMenu. For existing variant names
    # the field is hidden.
    createNew = getMayaUsdLibString('kMayaRefCreateNew')
    cmds.textField('variantNameText',
                   edit=True,
                   visible=(selectedItem == createNew))
def fileOptionsTabPage(tabLayout):
    mayaRefUtils.pushOptionsUITemplate()

    cmds.setParent(tabLayout)

    # See fileOptions.mel:fileOptionsTabPage() comments.  Contrary to that
    # code, we are not keeping 'optionsBoxForm' as a global MEL variable.  We
    # assume that we don't need to reference this directly to hide UI
    # temporarily.
    optBoxForm = cmds.formLayout('optionsBoxForm')

    topFrame = cmds.frameLayout('optionsBoxFrame',
                                collapsable=False,
                                labelVisible=False,
                                marginWidth=10,
                                borderVisible=False)
    cmds.formLayout(optBoxForm,
                    edit=True,
                    af=[(topFrame, 'left', 0), (topFrame, 'top', 0),
                        (topFrame, 'right', 0), (topFrame, 'bottom', 0)])

    topForm = cmds.columnLayout('actionOptionsForm', rowSpacing=5)

    cmds.setParent(topForm)
    cmds.frameLayout(label=getMayaUsdLibString("kMayaRefDescription"))
    cmds.columnLayout(adjustableColumn=True)
    cmds.text(align="left", label="TBD")

    cmds.setParent(topForm)
    cmds.frameLayout(label=getMayaUsdLibString("kCacheMayaRefOptions"))

    # USD file option controls will be parented under this layout.
    # resultCallback not called on "post", is therefore an empty string.
    fileOptionsScroll = cmds.columnLayout('fileOptionsScroll')
    mel.eval(
        'mayaUsdTranslatorExport("fileOptionsScroll", "post=all;!animation-data", "'
        + getCacheOptions() + '", "")')

    cacheFileUsdHierarchyOptions(topForm)

    cmds.setUITemplate(popTemplate=True)
Exemple #5
0
def createDefaultMenuItem(dagPath, precedingItem):
    # This is the final callable in the chain of responsibility, so it must
    # always return a menu item.
    cmd = 'maya.mel.eval("mayaUsdMenu_pushBackToUSD ' + dagPath + '")'
    mergeLabel = getMayaUsdLibString('kMenuMergeMayaEdits')
    returnedItem = cmds.menuItem(label=mergeLabel,
                                 insertAfter=precedingItem,
                                 image="merge_to_USD.png",
                                 command=cmd)
    cmd = 'maya.mel.eval("mayaUsdMenu_pushBackToUSDOptions ' + dagPath + '")'
    cmds.menuItem(insertAfter=returnedItem, optionBox=True, command=cmd)
    return returnedItem
Exemple #6
0
def createMenuItem(dagPath, precedingItem):
    '''Create a merge to USD menuItem for Maya object at dagPath.

    The menuItem will be placed in the menu after precedingItem, which must be
    a menuItem string name.
    '''

    for creator in _menuItemCreators:
        created = creator(dagPath, precedingItem)
        if created:
            return created

    # The following means that default menu item creation failed.
    errorMsg = getMayaUsdLibString('kErrorMergeToUsdMenuItem')
    cmds.error(errorMsg)
def cacheCommitUi(parent, selectedFile):
    # Read data to set up cache.

    # The following call will set _cacheOptions.  Initial settings not accessed
    # on "query", is therefore an empty string.
    mel.eval(
        'mayaUsdTranslatorExport("fileOptionsScroll", "query", "", "mayaUsdCacheMayaReference_setCacheOptions")'
    )

    # Regardless of UI, animation is always on.
    cacheOptionsText = re.sub(r'animation=.', 'animation=1', getCacheOptions())

    userArgs = mayaUsd.lib.Util.getDictionaryFromEncodedOptions(
        cacheOptionsText)

    primName = cmds.textFieldGrp('primNameText', query=True, text=True)
    defineInVariant = cmds.radioButtonGrp('variantRadioBtn',
                                          query=True,
                                          select=True)
    userArgs['rn_layer'] = selectedFile
    userArgs['rn_primName'] = primName
    userArgs['rn_defineInVariant'] = defineInVariant
    userArgs['rn_payloadOrReference'] = cmds.optionMenuGrp(
        'compositionArcTypeMenu', query=True, value=True)
    userArgs['rn_listEditType'] = cmds.optionMenu('listEditedAsMenu',
                                                  query=True,
                                                  value=True)

    if defineInVariant:
        userArgs['rn_variantSetName'] = cmds.optionMenu('variantSetMenu',
                                                        query=True,
                                                        value=True)
        variantName = cmds.optionMenu('variantNameMenu',
                                      query=True,
                                      value=True)
        if variantName == 'Create New':
            variantName = cmds.textField('variantNameText',
                                         query=True,
                                         text=True)
        userArgs['rn_variantName'] = variantName

    # Call push.
    if not mayaUsd.lib.PrimUpdaterManager.mergeToUsd(_mayaRefDagPath,
                                                     userArgs):
        errorMsgFormat = getMayaUsdLibString('kErrorCacheToUsdFailed')
        errorMsg = cmds.format(errorMsgFormat, stringArg=(_mayaRefDagPath))
        cmds.error(errorMsg)
def variantSetNameChanged(selectedItem):
    # Update the Variant Name option menu from the input Variant Set.
    mayaRefPrimParent = _pulledMayaRefPrim.GetParent()
    cmds.optionMenu('variantNameMenu', edit=True, deleteAllItems=True)

    variantNames = mayaRefPrimParent.GetVariantSet(
        selectedItem).GetVariantNames()
    cmds.menuItem(getMayaUsdLibString('kMayaRefCreateNew'),
                  parent='variantNameMenu')
    for vName in variantNames:
        cmds.menuItem(label=vName, parent='variantNameMenu')
    # Select 'Create New' by default and set the text field to default value.
    cmds.optionMenu('variantNameMenu', edit=True, select=1)
    cmds.textField('variantNameText',
                   edit=True,
                   visible=True,
                   text=kDefaultCacheVariantName)
def ProxyShapeFilePathChanged(filePathAttr, newFilePath=None):
    # Function called from the MayaUsd Proxy Shape template when the file path
    # text field of the file path attibute custom control is modified or interacted with.
    #
    # Arguments:
    # - filePathAttr: string representing the file path attribute.
    # - newFilePath : If None, the user clicked the file browser button.
    #                 - In this case a file dialog will be opened to allow user to pick USD file.
    #                 Otherwise when a string, the user entered a filename directly in the field.
    #                 - In this case simply try and load the file.
    #
    # Return Value:
    # - True:  The input file path attribute was updated with a new value.
    # - False: No update to file path attribute was done.
    #
    debugMessage('ProxyShapeFilePathChanged(%s, %s)' % (filePathAttr, newFilePath))
    try:
        stageName, proxyStage = GetStageFromProxyShapeAttr(filePathAttr)

        # Does the filepath attribute contain a valid file?
        currFilePath = cmds.getAttr(filePathAttr)
        dirtyStack = False
        openFileDialog = False
        if currFilePath:
            # We have a current file path, so check if any layer in the layerstack is dirty?
            dirtyStack = IsProxyShapeLayerStackDirty(proxyStage)
            if not dirtyStack:
                openFileDialog = True
        else:
            # No current file path, so do we just have an empty stage or was something added to
            # this anon layer?
            rootLayer = proxyStage.GetRootLayer()
            if rootLayer and not rootLayer.empty:
                dirtyStack = True
            elif newFilePath is None:
                debugMessage('  Empty stage, opening file dialog...')
                openFileDialog = True

        # If we have a dirty layer stack, display dialog to confirm new loading.
        if dirtyStack:
            kTitleFormat = getMayaUsdString("kDiscardStageEditsTitle")
            kMsgFormat = getMayaUsdString("kDiscardStageEditsLoadMsg")
            kYes = getMayaUsdString("kButtonYes")
            kNo = getMayaUsdString("kButtonNo")
            kTitle = cmds.format(kTitleFormat, stringArg=stageName)
            # Our title is a little long, and the confirmDialog command is not making the
            # dialog wide enough to show it all. So by telling the message string to not
            # word-wrap, the dialog is forced wider.
            kMsg = "<p style='white-space:pre'>" + cmds.format(kMsgFormat, stringArg=stageName)
            res = cmds.confirmDialog(title=kTitle,
                                     message=kMsg, messageAlign='left', 
                                     button=[kYes, kNo], defaultButton=kYes, cancelButton=kNo, dismissString=kNo,
                                     icon='warning')
            if res == kYes:
                debugMessage('  User confirmed load action, opening file dialog...')
                openFileDialog = True
            else:
                # User said NO to update, so don't proceed any farther.
                return False

        if openFileDialog and newFilePath is None:
            # Pop the file open dialog for user to load new usd file.
            title = getMayaUsdString("kLoadUSDFile")
            okCaption = getMayaUsdString("kLoad")
            fileFilter = getMayaUsdLibString("kAllUsdFiles") + ' (*.usd *.usda *.usdc *.usdz );;*.usd;;*.usda;;*.usdc;;*.usdz';
            res = cmds.fileDialog2(caption=title, fileMode=1, ff=fileFilter, okc=okCaption)
            if res and len(res) == 1:
                debugMessage('    User picked USD file, setting file path attribute')
                # Simply set the file path attribute. The proxy shape will load the file.
                usdFileToLoad = res[0]
                cmds.setAttr(filePathAttr, usdFileToLoad, type='string')
                return True
        elif newFilePath is not None:
            # Instead of opening a file dialog to get the USD file, simply
            # use the one provided as input.
            # Note: it is important to check "not None" since the new file path can be
            #       an empty string.
            debugMessage('  New file to load provided, setting filepath="%s"' % newFilePath)
            cmds.setAttr(filePathAttr, newFilePath, type='string')
            return True
    except Exception as e:
        debugMessage('ProxyShapeFilePathChanged() - Error: %s' % str(e))
        pass
    return False
def cacheFileUsdHierarchyOptions(topForm):
    '''Create controls to insert Maya reference USD cache into USD hierarchy.'''

    cmds.setParent(topForm)
    cmds.frameLayout(label=getMayaUsdLibString("kCacheMayaRefUsdHierarchy"))
    widgetColumn = cmds.columnLayout()

    rl = mel.eval('createRowLayoutforMayaReference("' + widgetColumn +
                  '", "cacheFilePreviewRow", 2)')
    with mayaRefUtils.SetParentContext(rl):
        cmds.iconTextStaticLabel(st="iconAndTextHorizontal",
                                 i1="info.png",
                                 l=getMayaUsdLibString('kCacheFileWillAppear'))
        cmds.textField(text=str(_pulledMayaRefPrim.GetParent().GetPath()),
                       editable=False)

    with mayaRefUtils.SetParentContext(cmds.rowLayout(numberOfColumns=2)):
        cmds.optionMenuGrp(
            'compositionArcTypeMenu',
            label=getMayaUsdLibString('kOptionAsCompositionArc'),
            cc=compositionArcChanged)
        cmds.menuItem(label=getMayaUsdLibString('kMenuPayload'))
        cmds.menuItem(label=getMayaUsdLibString('kMenuReference'))
        cmds.optionMenu('listEditedAsMenu',
                        label=getMayaUsdLibString('kOptionListEditedAs'),
                        cc=listEditChanged)
        cmds.menuItem(label=getMayaUsdLibString('kMenuAppend'))
        cmds.menuItem(label=getMayaUsdLibString('kMenuPrepend'))

    variantRb = cmds.radioButtonGrp('variantRadioBtn',
                                    nrb=1,
                                    label=getMayaUsdLibString('kTextDefineIn'),
                                    l1=getMayaUsdLibString('kTextVariant'))

    rl = mel.eval('createRowLayoutforMayaReference("' + widgetColumn +
                  '", "usdCacheVariantSetRow", 3)')
    with mayaRefUtils.SetParentContext(rl):
        cmds.text(label=getMayaUsdLibString('kMayaRefVariantSetName'))
        cmds.optionMenu('variantSetMenu', cc=variantSetNameChanged)
        cmds.textField(visible=False)

    rl = mel.eval('createRowLayoutforMayaReference("' + widgetColumn +
                  '", "usdCacheVariantNameRow", 3)')
    with mayaRefUtils.SetParentContext(rl):
        cmds.text(label=getMayaUsdLibString('kMayaRefVariantName'))
        cmds.optionMenu('variantNameMenu', cc=variantNameChanged)
        cmds.textField('variantNameText', cc=variantNameTextChanged)

    newChildRb = cmds.radioButtonGrp(
        'newChildPrimRadioBtn',
        nrb=1,
        label='',
        scl=variantRb,
        l1=getMayaUsdLibString('kButtonNewChildPrim'))

    cmds.textFieldGrp('primNameText',
                      label=getMayaUsdLibString('kMayaRefPrimName'),
                      cc=primNameTextChanged)

    cmds.radioButtonGrp(variantRb, edit=True, select=1)
Exemple #11
0
def createMayaReferencePrim(
        ufePathStr,
        mayaReferencePath,
        mayaNamespace,
        mayaReferencePrimName=mayaRefUtils.defaultMayaReferencePrimName(),
        groupPrim=None,
        variantSet=None,
        mayaAutoEdit=kDefaultEditAsMayaData):
    '''Create a Maya reference prim and optional group prim parented to the argument path.
    Optionally create a variant set and name and placed the edits inside that variant.

    Naming of Maya Reference prim is supported, otherwise default name is used.

    The group prim is optional.

    The variant set and name are optional

    Parameters:
    -----------
    ufePathStr : str : Ufe PathString of parent prim to add Maya Reference
    mayaReferencePath : str : File path of Maya Reference (for attribute)
    mayaNamespace : str : Namespace (for attribute)
    mayaReferencePrimName : str [optional] : Name for the Maya Reference prim
    groupPrim : tuple(str,str,str) [optional] : The Group prim Name, Type & Kind to create
                                                Note: the name is optional and will be auto-computed
                                                      if empty or not provided.
                                                Note: Type and Kind are both mandatory, but Kind is
                                                      allowed to be empty string.
    variantSet : tuple(str,str) [optional] : The Variant Set Name and Variant Name to create

    Return:
    -------
    The Usd prim of the newly created Maya Reference or an invalid prim if there is an error.
    '''

    # Make sure the prim name is valid and doesn't already exist.
    parentPrim = mayaUsd.ufe.ufePathToPrim(ufePathStr)

    # There are special conditions when we are given the ProxyShape gateway node.
    ufePath = ufe.PathString.path(ufePathStr)
    isGateway = (ufePath.nbSegments() == 1)

    # Were we given a Group prim to create?
    groupPrimName = None
    groupPrimType = None
    groupPrimKind = None
    if groupPrim:
        if (len(groupPrim) == 2):
            groupPrimType, groupPrimKind = groupPrim
        elif (len(groupPrim) == 3):
            groupPrimName, groupPrimType, groupPrimKind = groupPrim

            # Make sure the input Group prim name doesn't exist already
            # and validate the input name.
            # Note: it is allowed to be input as empty in which case a default is used.
            if groupPrimName:
                checkGroupPrimName = mayaUsd.ufe.uniqueChildName(
                    parentPrim, groupPrimName)
                if checkGroupPrimName != groupPrimName:
                    errorMsgFormat = getMayaUsdLibString(
                        'kErrorGroupPrimExists')
                    errorMsg = cmds.format(errorMsgFormat,
                                           stringArg=(groupPrimName,
                                                      ufePathStr))
                    om.MGlobal.displayError(errorMsg)
                    return Usd.Prim()
                groupPrimName = Tf.MakeValidIdentifier(checkGroupPrimName)

        # If the group prim was either not provided or empty we use a default name.
        if not groupPrimName:
            groupPrimName = getDefaultGroupPrimName(parentPrim, mayaNamespace)

    # When the input is a gateway we cannot have in variant unless group is also given.
    if isGateway and variantSet and not groupPrimName:
        errorMsg = getMayaUsdLibString('kErrorCannotAddToProxyShape')
        om.MGlobal.displayError(errorMsg)
        return Usd.Prim()

    # Make sure the input Maya Reference prim name doesn't exist already
    # and validate the input name.
    # Note: if we are given a group prim to create, then we know that the
    #       Maya Reference prim name will be unique since it will be the
    #       only child (of the newly created group prim).
    checkName = mayaUsd.ufe.uniqueChildName(
        parentPrim,
        mayaReferencePrimName) if groupPrim is None else mayaReferencePrimName
    if checkName != mayaReferencePrimName:
        errorMsgFormat = getMayaUsdLibString('kErrorMayaRefPrimExists')
        errorMsg = cmds.format(errorMsgFormat,
                               stringArg=(mayaReferencePrimName, ufePathStr))
        om.MGlobal.displayError(errorMsg)
        return Usd.Prim()
    validatedPrimName = Tf.MakeValidIdentifier(checkName)

    # Extract the USD path segment from the UFE path and append the Maya
    # reference prim to it.
    parentPath = str(ufePath.segments[1]) if ufePath.nbSegments() > 1 else ''

    stage = mayaUsd.ufe.getStage(ufePathStr)

    # Optionally insert a Group prim as a parent of the Maya reference prim.
    groupPrim = None
    if groupPrimName:
        groupPath = Sdf.AssetPath(parentPath + '/' + groupPrimName)
        try:
            groupPrim = stage.DefinePrim(groupPath.path, groupPrimType)
        except (Tf.ErrorException):
            groupPrim = Usd.Prim()
        if not groupPrim.IsValid():
            errorMsgFormat = getMayaUsdLibString('kErrorCreatingGroupPrim')
            errorMsg = cmds.format(errorMsgFormat, stringArg=(ufePathStr))
            om.MGlobal.displayError(errorMsg)
            return Usd.Prim()
        if groupPrimKind:
            model = Usd.ModelAPI(groupPrim)
            model.SetKind(groupPrimKind)

    if groupPrim:
        primPath = Sdf.AssetPath(groupPrim.GetPath().pathString + '/' +
                                 validatedPrimName)
    else:
        primPath = Sdf.AssetPath(parentPath + '/' + validatedPrimName)

    # Were we given a Variant Set to create?
    variantSetName = None
    variantName = None
    if variantSet and (len(variantSet) == 2):
        variantSetName, variantName = variantSet
    if variantSetName and variantName:
        validatedVariantSetName = Tf.MakeValidIdentifier(variantSetName)
        validatedVariantName = Tf.MakeValidIdentifier(variantName)

        # If we created a group prim add the variant set there, otherwise add it
        # to the prim that corresponds to the input ufe path.
        variantPrim = groupPrim if groupPrim else mayaUsd.ufe.ufePathToPrim(
            ufePathStr)
        vset = variantPrim.GetVariantSet(validatedVariantSetName)
        vset.AddVariant(validatedVariantName)
        vset.SetVariantSelection(validatedVariantName)
        with vset.GetVariantEditContext():
            # Now all of our subsequent edits will go "inside" the
            # 'variantName' variant of 'variantSetName'.
            prim = createPrimAndAttributes(stage, primPath, mayaReferencePath,
                                           mayaNamespace, mayaAutoEdit)
    else:
        prim = createPrimAndAttributes(stage, primPath, mayaReferencePath,
                                       mayaNamespace, mayaAutoEdit)
    if prim is None or not prim.IsValid():
        errorMsgFormat = getMayaUsdLibString('kErrorCreatingMayaRefPrim')
        errorMsg = cmds.format(errorMsgFormat, stringArg=(ufePathStr))
        om.MGlobal.displayError(errorMsg)
        return Usd.Prim()

    return prim