diff --git a/lib/mayaUsd/resources/scripts/mayaUsdAddUSDReference.mel b/lib/mayaUsd/resources/scripts/mayaUsdAddUSDReference.mel index a260d81219..53f1def48b 100644 --- a/lib/mayaUsd/resources/scripts/mayaUsdAddUSDReference.mel +++ b/lib/mayaUsd/resources/scripts/mayaUsdAddUSDReference.mel @@ -21,16 +21,16 @@ global proc addUSDReferenceCreateUi(string $parent) { setParent $parent; string $layout = `scrollLayout -childResizable true`; - python("import mayaUsd_USDRootFileRelative as murel\nmurel.usdFileRelativeToEditTargetLayer.uiCreate(r'''" + $layout + "''')"); + python("import mayaUsd_USDRootFileRelative as murel\nmurel.usdAddRefOrPayloadRelativeToEditTargetLayer.uiCreate(r'''" + $layout + "''')"); } global proc addUSDReferenceInitUi(string $parent, string $filterType) { - python("import mayaUsd_USDRootFileRelative as murel\nmurel.usdFileRelativeToEditTargetLayer.uiInit(r'''" + $parent + "''', r'''" + $filterType + "''')"); + python("import mayaUsd_USDRootFileRelative as murel\nmurel.usdAddRefOrPayloadRelativeToEditTargetLayer.uiInit(r'''" + $parent + "''', r'''" + $filterType + "''')"); } global proc addUSDReferenceToUsdCommitUi(string $parent, string $selectedFile) { setParent $parent; - python("import mayaUsd_USDRootFileRelative as murel\nmurel.usdFileRelativeToEditTargetLayer.uiCommit(r'''" + $parent + "''', r'''" + $selectedFile + "''')"); + python("import mayaUsd_USDRootFileRelative as murel\nmurel.usdAddRefOrPayloadRelativeToEditTargetLayer.uiCommit(r'''" + $parent + "''', r'''" + $selectedFile + "''')"); } diff --git a/lib/mayaUsd/resources/scripts/mayaUsdCacheMayaReference.py b/lib/mayaUsd/resources/scripts/mayaUsdCacheMayaReference.py index 5ec42cd80f..ea5ae44e42 100644 --- a/lib/mayaUsd/resources/scripts/mayaUsdCacheMayaReference.py +++ b/lib/mayaUsd/resources/scripts/mayaUsdCacheMayaReference.py @@ -47,61 +47,6 @@ # Pulled Maya reference prim. _pulledMayaRefPrim = None -_compositionArcLabels = [getMayaUsdLibString('kMenuPayload'), getMayaUsdLibString('kMenuReference')] -_compositionArcValues = [ 'Payload', 'Reference' ] - -_listEditedAsLabels = [getMayaUsdLibString('kMenuAppend'), getMayaUsdLibString('kMenuPrepend')] -_listEditedAsValues = [ 'Append', 'Prepend' ] - - -def _getMenuGrpValue(menuName, values, defaultIndex = 0): - """ - Retrieves the currently selected values from a menu. - """ - # Note: option menu selection index start at 1, so we subtract 1. - menuIndex = cmds.optionMenuGrp(menuName, query=True, select=True) - 1 - if 0 <= menuIndex < len(values): - return values[menuIndex] - else: - return values[defaultIndex] - -def _getMenuValue(menuName, values, defaultIndex = 0): - """ - Retrieves the currently selected values from a menu. - """ - # Note: option menu selection index start at 1, so we subtract 1. - menuIndex = cmds.optionMenu(menuName, query=True, select=True) - 1 - if 0 <= menuIndex < len(values): - return values[menuIndex] - else: - return values[defaultIndex] - - -def _getMenuIndex(values, current, defaultIndex = 1): - """ - Retrieves the menu index corresponding to the current value selected amongst values. - If the value is invalid, returns the defaultIndex. - """ - try: - # Note: menu index is 1-based. - return values.index(current) + 1 - except: - return defaultIndex - - -def compositionArcChanged(selectedItem): - """ - Reacts to the composition arc type being selected by the user. - """ - pass - - -def listEditChanged(selectedItem): - """ - Reacts to the list edited UI being changed by the user. - """ - pass - def variantSetNameChanged(selectedItem): """ @@ -183,18 +128,7 @@ def cacheFileUsdHierarchyOptions(topForm): l=getMayaUsdLibString('kCacheFileWillAppear')) cmds.textField(text=str(_pulledMayaRefPrim.GetParent().GetPath()), editable=False) - with mayaRefUtils.SetParentContext(cmds.rowLayout(numberOfColumns=2)): - cmds.optionMenuGrp('compositionArcTypeMenu', - label=getMayaUsdLibString('kOptionAsUSDReference'), - cc=compositionArcChanged, - annotation=getMayaUsdLibString('kOptionAsUSDReferenceToolTip')) - for label in _compositionArcLabels: - cmds.menuItem(label=label) - cmds.optionMenu('listEditedAsMenu', - label=getMayaUsdLibString('kOptionListEditedAs'), - cc=listEditChanged) - for label in _listEditedAsLabels: - cmds.menuItem(label=label) + mayaRefUtils.createUsdRefOrPayloadUI() variantRb = cmds.radioButtonGrp('variantRadioButton', nrb=1, @@ -322,11 +256,9 @@ def cacheInitUi(parent, filterType): # variant is the default, otherwise all variant options are disabled. mayaRefPrimParent = _pulledMayaRefPrim.GetParent() - menuIndex = _getMenuIndex(_compositionArcValues, optionsDict['rn_payloadOrReference']) - cmds.optionMenuGrp('compositionArcTypeMenu', edit=True, select=menuIndex) - - menuIndex = _getMenuIndex(_listEditedAsValues, optionsDict['rn_listEditType']) - cmds.optionMenu('listEditedAsMenu', edit=True, select=menuIndex) + mayaRefUtils.initUsdRefOrPayloadUI({ + mayaRefUtils.compositionArcKey: optionsDict['rn_payloadOrReference'], + mayaRefUtils.listEditTypeKey: optionsDict['rn_listEditType']}) if mayaRefPrimParent.HasVariantSets(): # Define in variant is the default. @@ -379,8 +311,10 @@ def cacheCommitUi(parent, selectedFile): mel.eval('mayaUsdTranslatorExport("fileOptionsScroll", "query={exportOpts}", "", "mayaUsdCacheMayaReference_setCacheOptions")'.format(exportOpts=kTranslatorExportOptions)) primName = cmds.textFieldGrp('primNameText', query=True, text=True) - payloadOrReference = _getMenuGrpValue('compositionArcTypeMenu', _compositionArcValues) - listEditType = _getMenuValue('listEditedAsMenu', _listEditedAsValues) + + values = mayaRefUtils.commitUsdRefOrPayloadUI() + compositionArc = values[mayaRefUtils.compositionArcKey] + listEditType = values[mayaRefUtils.listEditTypeKey] defineInVariant = cmds.radioButtonGrp('variantRadioButton', query=True, select=True) if defineInVariant: @@ -393,7 +327,7 @@ def cacheCommitUi(parent, selectedFile): variantSetName = None userArgs = cacheToUsd.createCacheCreationOptions( - getCacheExportOptions(), selectedFile, primName, payloadOrReference, + getCacheExportOptions(), selectedFile, primName, compositionArc, listEditType, variantSetName, variantName) cacheToUsd.saveCacheCreationOptions(userArgs) diff --git a/lib/mayaUsd/resources/scripts/mayaUsdLibRegisterStrings.mel b/lib/mayaUsd/resources/scripts/mayaUsdLibRegisterStrings.mel index 51cb033058..98066f0e7b 100644 --- a/lib/mayaUsd/resources/scripts/mayaUsdLibRegisterStrings.mel +++ b/lib/mayaUsd/resources/scripts/mayaUsdLibRegisterStrings.mel @@ -46,7 +46,7 @@ global proc mayaUsdLibRegisterStrings() register("kMayaRefEditAsMayaDataAnn", "Select this checkbox to enable editing the MayaReference prim as a Maya Reference."); register("kMayaRefOptions", "Maya Reference Options"); register("kMayaRefCreateNew", "Create New"); - register("kMayaRefAddToPrim", "Add Maya Reference to USD Prim"); + register("kMayaRefAddToPrim", "Add Maya Reference to Prim"); register("kMayaRefReference", "Reference"); // Used in multiple places. diff --git a/lib/mayaUsd/resources/scripts/mayaUsdLibRegisterStrings.py b/lib/mayaUsd/resources/scripts/mayaUsdLibRegisterStrings.py index 7b3f5ffd8b..aa5d4c6840 100644 --- a/lib/mayaUsd/resources/scripts/mayaUsdLibRegisterStrings.py +++ b/lib/mayaUsd/resources/scripts/mayaUsdLibRegisterStrings.py @@ -62,9 +62,10 @@ def mayaUsdLibRegisterStrings(): register('kMenuPayload', 'Payload') register('kMenuPrepend', 'Prepend') register('kMenuReference', 'Reference') - register('kOptionAsUSDReference', 'As USD Reference:') + register('kOptionAsUSDReference', 'Composition Arc:') register('kOptionAsUSDReferenceToolTip', '

Choose the type of USD Reference composition arc for your Maya Reference:

Payloads are a type of reference. They are recorded, but not traversed in the scene hierarchy. Select this arc if your goal is to manually construct
a "working set" that is a subset of an entire scene, in which only parts of the scene are required/loaded. Note: payloads are
weaker than direct references in any given LayerStack.

References are general and can be used to compose smaller units of scene description into larger aggregates, building up a namespace that
includes the "encapsulated" result of composing the scene description targeted by a reference. Select this arc if your goal is not to unload your
references.

') register('kOptionListEditedAs', 'List Edited As') + register('kOptionLoadPayload', 'Load Payload:') register('kTextDefineIn', 'Define in:') register('kTextVariant', 'Variant') register('kTextVariantToolTip','If selected, your Maya reference will be defined in a variant. This will enable your prim to\nhave 2 variants you can switch between in the Outliner; the Maya reference and its USD cache.') diff --git a/lib/mayaUsd/resources/scripts/mayaUsdMayaReferenceUtils.py b/lib/mayaUsd/resources/scripts/mayaUsdMayaReferenceUtils.py index 65b84a0f57..ebe633bdd8 100644 --- a/lib/mayaUsd/resources/scripts/mayaUsdMayaReferenceUtils.py +++ b/lib/mayaUsd/resources/scripts/mayaUsdMayaReferenceUtils.py @@ -15,12 +15,25 @@ # import maya.cmds as cmds +from mayaUsdLibRegisterStrings import getMayaUsdLibString # These names should not be localized as Usd only accepts [a-z,A-Z] as valid characters. kDefaultMayaReferencePrimName = 'MayaReference1' kDefaultVariantSetName = 'Representation' kDefaultVariantName = 'MayaReference' +compositionArcKey = 'compositionArc' +compositionArcPayload = 'Payload' +compositionArcReference = 'Reference' +_compositionArcValues = [compositionArcPayload, compositionArcReference] + +listEditTypeKey = '' +listEditTypeAppend = 'Append' +listEditTypePrepend = 'Prepend' +_listEditedAsValues = [listEditTypeAppend, listEditTypePrepend] + +loadPayloadKey = 'loadPayload' + def defaultMayaReferencePrimName(): return kDefaultMayaReferencePrimName @@ -64,3 +77,83 @@ def pushOptionsUITemplate(): cmds.setUITemplate('optionsTemplate', pushTemplate=True) +def _getMenuIndex(values, current, defaultIndex = 1): + """ + Retrieves the menu index corresponding to the current value selected amongst values. + If the value is invalid, returns the defaultIndex. + """ + try: + # Note: menu index is 1-based. + return values.index(current) + 1 + except: + return defaultIndex + +def _getMenuGrpValue(menuName, values, defaultIndex = 0): + """ + Retrieves the currently selected values from a menu. + """ + # Note: option menu selection index start at 1, so we subtract 1. + menuIndex = cmds.optionMenuGrp(menuName, query=True, select=True) - 1 + if 0 <= menuIndex < len(values): + return values[menuIndex] + else: + return values[defaultIndex] + +def _getMenuValue(menuName, values, defaultIndex = 0): + """ + Retrieves the currently selected values from a menu. + """ + # Note: option menu selection index start at 1, so we subtract 1. + menuIndex = cmds.optionMenu(menuName, query=True, select=True) - 1 + if 0 <= menuIndex < len(values): + return values[menuIndex] + else: + return values[defaultIndex] + +def _compositionArcChanged(selectedItem): + """ + Reacts to the composition arc type being selected by the user. + """ + compositionArc = _getMenuGrpValue('compositionArcTypeMenu', _compositionArcValues) + enableLoadPayload = bool(compositionArc == compositionArcPayload) + cmds.checkBoxGrp('loadPayload', edit=True, enable=enableLoadPayload) + +def createUsdRefOrPayloadUI(showLoadPayload=False): + with SetParentContext(cmds.rowLayout(numberOfColumns=2)): + tooltip = getMayaUsdLibString('kOptionAsUSDReferenceToolTip') + cmds.optionMenuGrp('compositionArcTypeMenu', + label=getMayaUsdLibString('kOptionAsUSDReference'), + annotation=tooltip) + compositionArcLabels = [getMayaUsdLibString('kMenuPayload'), getMayaUsdLibString('kMenuReference')] + for label in compositionArcLabels: + cmds.menuItem(label=label) + cmds.optionMenu('listEditedAsMenu', + label=getMayaUsdLibString('kOptionListEditedAs'), + annotation=tooltip) + listEditedAsLabels = [getMayaUsdLibString('kMenuAppend'), getMayaUsdLibString('kMenuPrepend')] + for label in listEditedAsLabels: + cmds.menuItem(label=label) + + if showLoadPayload: + cmds.checkBoxGrp('loadPayload', + label=getMayaUsdLibString('kOptionLoadPayload'), + ncb=1) + +def initUsdRefOrPayloadUI(values, showLoadPayload=False): + compositionArcMenuIndex = _getMenuIndex(_compositionArcValues, values[compositionArcKey]) + cmds.optionMenuGrp('compositionArcTypeMenu', edit=True, select=compositionArcMenuIndex) + + listEditTypeMenuIndex = _getMenuIndex(_listEditedAsValues,values[listEditTypeKey]) + cmds.optionMenu('listEditedAsMenu', edit=True, select=listEditTypeMenuIndex) + + if showLoadPayload: + cmds.optionMenuGrp('compositionArcTypeMenu', edit=True, cc=_compositionArcChanged) + _compositionArcChanged(compositionArcMenuIndex) + cmds.checkBoxGrp('loadPayload', edit=True, value1=values[loadPayloadKey]) + +def commitUsdRefOrPayloadUI(showLoadPayload=False): + values = {} + values[compositionArcKey] = _getMenuGrpValue('compositionArcTypeMenu', _compositionArcValues) + values[listEditTypeKey ] = _getMenuValue('listEditedAsMenu', _listEditedAsValues) + values[loadPayloadKey ] = cmds.checkBoxGrp('loadPayload', query=True, value1=True) if showLoadPayload else True + return values diff --git a/lib/mayaUsd/resources/scripts/mayaUsdUtils.py b/lib/mayaUsd/resources/scripts/mayaUsdUtils.py index 9294a39210..57efddd474 100644 --- a/lib/mayaUsd/resources/scripts/mayaUsdUtils.py +++ b/lib/mayaUsd/resources/scripts/mayaUsdUtils.py @@ -169,4 +169,28 @@ def setUserSelectedUSDDialogFileFilter(fileFilter): _userSelectedUSDDialogFileFilter = fileFilter +def wantReferenceCompositionArc(): + opVarName = "mayaUsd_WantReferenceCompositionArc" + return cmds.optionVar(exists=opVarName) and cmds.optionVar(query=opVarName) + +def saveWantReferenceCompositionArc(want): + opVarName = "mayaUsd_WantReferenceCompositionArc" + cmds.optionVar(iv=(opVarName, want)) + +def wantPrependCompositionArc(): + opVarName = "mayaUsd_WantPrependCompositionArc" + return cmds.optionVar(exists=opVarName) and cmds.optionVar(query=opVarName) + +def saveWantPrependCompositionArc(want): + opVarName = "mayaUsd_WantPrependCompositionArc" + cmds.optionVar(iv=(opVarName, want)) + +def wantPayloadLoaded(): + opVarName = "mayaUsd_WantPayloadLoaded" + return cmds.optionVar(exists=opVarName) and cmds.optionVar(query=opVarName) + +def saveWantPayloadLoaded(want): + opVarName = "mayaUsd_WantPayloadLoaded" + cmds.optionVar(iv=(opVarName, want)) + diff --git a/lib/mayaUsd/ufe/UsdContextOps.cpp b/lib/mayaUsd/ufe/UsdContextOps.cpp index 05d905ce0b..9b03497c53 100644 --- a/lib/mayaUsd/ufe/UsdContextOps.cpp +++ b/lib/mayaUsd/ufe/UsdContextOps.cpp @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -145,6 +146,8 @@ static constexpr char kAddNewMaterialLabel[] = "Add New Material"; static constexpr char kAssignExistingMaterialItem[] = "Assign Existing Material"; static constexpr char kAssignExistingMaterialLabel[] = "Assign Existing Material"; #endif +static constexpr char kAddRefOrPayloadLabel[] = "Add USD Reference/Payload..."; +static constexpr char kAddRefOrPayloadItem[] = "AddReferenceOrPayload"; static constexpr char kAllRegisteredTypesItem[] = "All Registered"; static constexpr char kAllRegisteredTypesLabel[] = "All Registered"; @@ -465,7 +468,7 @@ const char* _selectUSDFileScript() { string $result[] = `fileDialog2 -fileMode 1 - -caption "Add Reference to USD Prim" + -caption "Add Reference/Payload to Prim" -fileFilter "USD Files (%s);;%s" -optionsUICreate addUSDReferenceCreateUi -optionsUIInit addUSDReferenceInitUi @@ -521,12 +524,11 @@ ClearAllUSDReferencesConfirm(); class AddUsdReferenceUndoableCommand : public Ufe::UndoableCommand { public: - static const std::string commandName; - - AddUsdReferenceUndoableCommand(const UsdPrim& prim, const std::string& filePath) + AddUsdReferenceUndoableCommand(const UsdPrim& prim, const std::string& filePath, bool prepend) : _prim(prim) , _sdfRef() , _filePath(filePath) + , _listPos(prepend ? UsdListPositionBackOfPrependList : UsdListPositionBackOfAppendList) { } @@ -547,16 +549,57 @@ class AddUsdReferenceUndoableCommand : public Ufe::UndoableCommand _sdfRef = SdfReference(_filePath); } UsdReferences primRefs = _prim.GetReferences(); - primRefs.AddReference(_sdfRef); + primRefs.AddReference(_sdfRef, _listPos); + } + } + +private: + UsdPrim _prim; + SdfReference _sdfRef; + std::string _filePath; + UsdListPosition _listPos; +}; + +class AddUsdPayloadUndoableCommand : public Ufe::UndoableCommand +{ +public: + AddUsdPayloadUndoableCommand(const UsdPrim& prim, const std::string& filePath, bool prepend) + : _prim(prim) + , _sdfPayload() + , _filePath(filePath) + , _listPos(prepend ? UsdListPositionBackOfPrependList : UsdListPositionBackOfAppendList) + { + } + + void undo() override + { + if (!_prim.IsValid()) + return; + + UsdPayloads primPayloads = _prim.GetPayloads(); + primPayloads.RemovePayload(_sdfPayload); + } + + void redo() override + { + if (!_prim.IsValid()) + return; + + if (TfStringEndsWith(_filePath, ".mtlx")) { + _sdfPayload = SdfPayload(_filePath, SdfPath("/MaterialX")); + } else { + _sdfPayload = SdfPayload(_filePath); } + UsdPayloads primPayloads = _prim.GetPayloads(); + primPayloads.AddPayload(_sdfPayload, _listPos); } private: - UsdPrim _prim; - SdfReference _sdfRef; - const std::string _filePath; + UsdPrim _prim; + SdfPayload _sdfPayload; + std::string _filePath; + UsdListPosition _listPos; }; -const std::string AddUsdReferenceUndoableCommand::commandName("Add USD Reference..."); class ClearAllReferencesUndoableCommand : public Ufe::UndoableCommand { @@ -850,9 +893,7 @@ Ufe::ContextOps::Items UsdContextOps::getItems(const Ufe::ContextOps::ItemPath& // Top level item - Add New Prim (for all context op types). items.emplace_back(kUSDAddNewPrimItem, kUSDAddNewPrimLabel, Ufe::ContextItem::kHasChildren); if (!fIsAGatewayType) { - items.emplace_back( - AddUsdReferenceUndoableCommand::commandName, - AddUsdReferenceUndoableCommand::commandName); + items.emplace_back(kAddRefOrPayloadItem, kAddRefOrPayloadLabel); items.emplace_back( ClearAllReferencesUndoableCommand::commandName, ClearAllReferencesUndoableCommand::commandName); @@ -1178,7 +1219,7 @@ Ufe::UndoableCommand::Ptr UsdContextOps::doOpCmd(const ItemPath& itemPath) MGlobal::executeCommand(script); return nullptr; #endif - } else if (itemPath[0] == AddUsdReferenceUndoableCommand::commandName) { + } else if (itemPath[0] == kAddRefOrPayloadItem) { if (!_prepareUSDReferenceTargetLayer(prim())) return nullptr; @@ -1191,7 +1232,27 @@ Ufe::UndoableCommand::Ptr UsdContextOps::doOpCmd(const ItemPath& itemPath) if (path.empty()) return nullptr; - return std::make_shared(prim(), path); + const bool asRef = UsdMayaUtilFileSystem::wantReferenceCompositionArc(); + const bool prepend = UsdMayaUtilFileSystem::wantPrependCompositionArc(); + if (asRef) { + return std::make_shared(prim(), path, prepend); + } else { + Ufe::UndoableCommand::Ptr preloadCmd; + const bool preload = UsdMayaUtilFileSystem::wantPayloadLoaded(); + if (preload) { + preloadCmd = std::make_shared(prim(), UsdLoadWithDescendants); + } else { + preloadCmd = std::make_shared(prim()); + } + + auto payloadCmd = std::make_shared(prim(), path, prepend); + + auto compoCmd = std::make_shared(); + compoCmd->append(preloadCmd); + compoCmd->append(payloadCmd); + + return compoCmd; + } } else if (itemPath[0] == ClearAllReferencesUndoableCommand::commandName) { MString confirmation = MGlobal::executeCommandStringResult(clearAllReferencesConfirmScript); if (ClearAllReferencesUndoableCommand::cancelRemoval == confirmation) diff --git a/lib/mayaUsd/utils/utilFileSystem.cpp b/lib/mayaUsd/utils/utilFileSystem.cpp index f7207efea9..0d8cf7de97 100644 --- a/lib/mayaUsd/utils/utilFileSystem.cpp +++ b/lib/mayaUsd/utils/utilFileSystem.cpp @@ -272,6 +272,27 @@ bool UsdMayaUtilFileSystem::requireUsdPathsRelativeToEditTargetLayer() && MGlobal::optionVarIntValue(MAKE_PATH_RELATIVE_TO_EDIT_TARGET_LAYER_FILE); } +bool UsdMayaUtilFileSystem::wantReferenceCompositionArc() +{ + static const MString WANT_REFERENCE_COMPOSITION_ARC = "mayaUsd_WantReferenceCompositionArc"; + return MGlobal::optionVarExists(WANT_REFERENCE_COMPOSITION_ARC) + && MGlobal::optionVarIntValue(WANT_REFERENCE_COMPOSITION_ARC); +} + +bool UsdMayaUtilFileSystem::wantPrependCompositionArc() +{ + static const MString WANT_PREPEND_COMPOSITION_ARC = "mayaUsd_WantPrependCompositionArc"; + return MGlobal::optionVarExists(WANT_PREPEND_COMPOSITION_ARC) + && MGlobal::optionVarIntValue(WANT_PREPEND_COMPOSITION_ARC); +} + +bool UsdMayaUtilFileSystem::wantPayloadLoaded() +{ + static const MString WANT_PAYLOAD_LOADED = "mayaUsd_WantPayloadLoaded"; + return MGlobal::optionVarExists(WANT_PAYLOAD_LOADED) + && MGlobal::optionVarIntValue(WANT_PAYLOAD_LOADED); +} + const char* getScenesFolderScript = R"( global proc string UsdMayaUtilFileSystem_GetScenesFolder() { diff --git a/lib/mayaUsd/utils/utilFileSystem.h b/lib/mayaUsd/utils/utilFileSystem.h index 35d146aa44..507ddc34d2 100644 --- a/lib/mayaUsd/utils/utilFileSystem.h +++ b/lib/mayaUsd/utils/utilFileSystem.h @@ -122,6 +122,21 @@ getPathRelativeToLayerFile(const std::string& fileName, const PXR_NS::SdfLayerHa MAYAUSD_CORE_PUBLIC bool requireUsdPathsRelativeToMayaSceneFile(); +/*! \brief returns true if the USD file should be added as a reference, false for as a payload. + */ +MAYAUSD_CORE_PUBLIC +bool wantReferenceCompositionArc(); + +/*! \brief returns true if the USD the reference or payload should be prepend, else append. + */ +MAYAUSD_CORE_PUBLIC +bool wantPrependCompositionArc(); + +/*! \brief returns true if the USD payload should be immediately loaded. + */ +MAYAUSD_CORE_PUBLIC +bool wantPayloadLoaded(); + /*! \brief prepares the UI used to save layers, so that the UI can potentially make the selected file name relative to the given directory. */ diff --git a/plugin/adsk/scripts/AETemplateHelpers.py b/plugin/adsk/scripts/AETemplateHelpers.py index 39525f6143..b3ad9bed5b 100644 --- a/plugin/adsk/scripts/AETemplateHelpers.py +++ b/plugin/adsk/scripts/AETemplateHelpers.py @@ -62,7 +62,8 @@ def GetStageFromProxyShapeAttr(attr): return(stageName, proxyStage) def RequireUsdPathsRelativeToMayaSceneFile(): - return cmds.optionVar(exists="mayaUsd_MakePathRelativeToSceneFile") and cmds.optionVar(query="mayaUsd_MakePathRelativeToSceneFile") + opVarName = "mayaUsd_MakePathRelativeToSceneFile" + return cmds.optionVar(exists=opVarName) and cmds.optionVar(query=opVarName) def ProxyShapeFilePathChanged(filePathAttr, newFilePath=None): # Function called from the MayaUsd Proxy Shape template when the file path diff --git a/plugin/adsk/scripts/mayaUSDRegisterStrings.py b/plugin/adsk/scripts/mayaUSDRegisterStrings.py index d9a522db2a..138407e39d 100644 --- a/plugin/adsk/scripts/mayaUSDRegisterStrings.py +++ b/plugin/adsk/scripts/mayaUSDRegisterStrings.py @@ -45,3 +45,4 @@ def mayaUSDRegisterStrings(): register("kUnresolvedPathAnn", "This field indicates the path with the file name currently chosen in your text input. Note: This is the string that will be written out to the file in the chosen directory in order to enable portability.") register("kResolvedPath", "Resolved Path:") register("kResolvedPathAnn", "This field indicates the resolved path of your chosen working directory for your USD file. Note: The resolved path for the file can vary for each individual as the file is handed off.") + register("kCompositionArcOptions", "Composition Arc Options") diff --git a/plugin/adsk/scripts/mayaUsd_USDRootFileRelative.py b/plugin/adsk/scripts/mayaUsd_USDRootFileRelative.py index dbba03730c..4fd9f513c8 100644 --- a/plugin/adsk/scripts/mayaUsd_USDRootFileRelative.py +++ b/plugin/adsk/scripts/mayaUsd_USDRootFileRelative.py @@ -3,7 +3,8 @@ import maya.OpenMayaUI as omui import mayaUsd.lib as mayaUsdLib from mayaUSDRegisterStrings import getMayaUsdString -from mayaUsdMayaReferenceUtils import pushOptionsUITemplate +import mayaUsdMayaReferenceUtils as mayaRefUtils +import mayaUsdUtils try: from PySide2.QtWidgets import QFileDialog, QLineEdit, QDialogButtonBox, QComboBox, QApplication @@ -72,7 +73,7 @@ def uiCreate(cls, parentLayout, relativeToWhat): Input relativeToWhat tells what the file is relative to. See the class docs. """ - pushOptionsUITemplate() + mayaRefUtils.pushOptionsUITemplate() cmds.setParent(parentLayout) optBoxForm = cmds.formLayout('optionsBoxForm') @@ -106,6 +107,8 @@ def uiCreate(cls, parentLayout, relativeToWhat): cmds.textFieldGrp(cls.kResolvedPathTextField, label=kResolvedPathStr, ann=kResolvedPathAnnStr , editable=False) cls._haveRelativePathFields = True + return topForm + @classmethod def uiInit(cls, parentLayout, canBeRelative, relativeToWhat): """ @@ -286,7 +289,7 @@ class usdRootFileRelative(usdFileRelative): @classmethod def uiCreate(cls, parentLayout): - super(usdRootFileRelative, cls).uiCreate(parentLayout, cls.kRelativeToWhat) + return super(usdRootFileRelative, cls).uiCreate(parentLayout, cls.kRelativeToWhat) @classmethod def uiInit(cls, parentLayout, filterType): @@ -319,7 +322,7 @@ class usdSubLayerFileRelative(usdFileRelative): @classmethod def uiCreate(cls, parentLayout): - super(usdSubLayerFileRelative, cls).uiCreate(parentLayout, cls.kRelativeToWhat) + return super(usdSubLayerFileRelative, cls).uiCreate(parentLayout, cls.kRelativeToWhat) @classmethod def uiInit(cls, parentLayout, filterType, parentLayerPath = ""): @@ -351,7 +354,7 @@ class usdFileRelativeToEditTargetLayer(usdFileRelative): @classmethod def uiCreate(cls, parentLayout): - super(usdFileRelativeToEditTargetLayer, cls).uiCreate(parentLayout, cls.kRelativeToWhat) + return super(usdFileRelativeToEditTargetLayer, cls).uiCreate(parentLayout, cls.kRelativeToWhat) @classmethod def uiInit(cls, parentLayout, filterType): @@ -370,3 +373,65 @@ def uiCommit(cls, parentLayout, selectedFile=None): with the dialog2 command API. ''' super(usdFileRelativeToEditTargetLayer, cls).uiCommit(parentLayout, cls.kRelativeToWhat) + +class usdAddRefOrPayloadRelativeToEditTargetLayer(usdFileRelativeToEditTargetLayer): + ''' + Helper class to create the UI for add reference or payload optionally + relative to a layer file. + ''' + + @classmethod + def uiCreate(cls, parentLayout): + topForm = super(usdAddRefOrPayloadRelativeToEditTargetLayer, cls).uiCreate(parentLayout) + + cmds.setParent(topForm) + cmds.frameLayout(label=getMayaUsdString("kCompositionArcOptions"), collapsable=False) + + mayaRefUtils.createUsdRefOrPayloadUI(True) + + return topForm + + @classmethod + def uiInit(cls, parentLayout, filterType): + ''' + Note: the function takes an unused filterType argument to be compatible + with the dialog2 command API. + ''' + super(usdAddRefOrPayloadRelativeToEditTargetLayer, cls).uiInit(parentLayout, filterType) + + wantRef = mayaUsdUtils.wantReferenceCompositionArc() + wantPrepend = mayaUsdUtils.wantPrependCompositionArc() + wantLoad = mayaUsdUtils.wantPayloadLoaded() + + compositionArc = mayaRefUtils.compositionArcReference if wantRef else mayaRefUtils.compositionArcPayload + listEditType = mayaRefUtils.listEditTypePrepend if wantPrepend else mayaRefUtils.listEditTypeAppend + loadPayload = bool(wantLoad) + + values = { + mayaRefUtils.compositionArcKey: compositionArc, + mayaRefUtils.listEditTypeKey: listEditType, + mayaRefUtils.loadPayloadKey: loadPayload, + } + mayaRefUtils.initUsdRefOrPayloadUI(values, True) + + @classmethod + def uiCommit(cls, parentLayout, selectedFile=None): + ''' + Note: the function takes an unused selectedFile argument to be compatible + with the dialog2 command API. + ''' + super(usdAddRefOrPayloadRelativeToEditTargetLayer, cls).uiCommit(parentLayout, selectedFile) + + values = mayaRefUtils.commitUsdRefOrPayloadUI(True) + + compositionArc = values[mayaRefUtils.compositionArcKey] + listEditType = values[mayaRefUtils.listEditTypeKey] + loadPayload = values[mayaRefUtils.loadPayloadKey] + + wantReference = bool(compositionArc == mayaRefUtils.compositionArcReference) + wantPrepend = bool(listEditType == mayaRefUtils.listEditTypePrepend) + wantLoad = bool(loadPayload) + + mayaUsdUtils.saveWantReferenceCompositionArc(wantReference) + mayaUsdUtils.saveWantPrependCompositionArc(wantPrepend) + mayaUsdUtils.saveWantPayloadLoaded(wantLoad)