Skip to content

Commit

Permalink
Merge pull request #3676 from Autodesk/bailp/EMSUSD-1038/import-plugi…
Browse files Browse the repository at this point in the history
…n-config

EMSUSD-1038 import plugin config UI
  • Loading branch information
seando-adsk authored Mar 28, 2024
2 parents b311cd5 + f3d2dc9 commit cfe8396
Show file tree
Hide file tree
Showing 16 changed files with 687 additions and 85 deletions.
2 changes: 1 addition & 1 deletion README_DOC.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
## Core Modules
+ [Common Plug-in Base Commands](lib/mayaUsd/commands/Readme.md)
+ [Managing Translation (Import/Export) Options](lib/mayaUsd/fileio/doc/Managing_export_options_via_JobContext_in_Python.md)
+ [Example Export Plugin in Python](tutorials/export-plugin/README.md)
+ [Example Import and Export Plugin in Python](tutorials/import-export-plugin/README.md)
+ [SchemaAPI Translators](lib/mayaUsd/fileio/doc/SchemaAPI_Import_Export_in_Python.md)
+ [UFE Transform](lib/mayaUsd/ufe/UsdTransform3d.md)
+ [Undo/Redo Support](lib/mayaUsd/undo/README.md)
Expand Down
27 changes: 27 additions & 0 deletions lib/mayaUsd/commands/baseListJobContextsCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ const char* _exportAnnotationStr = "exportAnnotation";
const char* _exportArgumentsStr = "exportArguments";
const char* _hasExportUIStr = "hasExportUI";
const char* _showExportUIStr = "showExportUI";
const char* _hasImportUIStr = "hasImportUI";
const char* _showImportUIStr = "showImportUI";
const char* _importStr = "import";
const char* _importAnnotationStr = "importAnnotation";
const char* _importArgumentsStr = "importArguments";
Expand Down Expand Up @@ -128,6 +130,29 @@ MStatus MayaUSDListJobContextsCommand::doIt(const MArgList& args)

setResult(convertDictionaryToText(
info.exportUICallback(info.jobContext, parentUIStr.asChar(), inputSettings)));
} else if (argData.isFlagSet(_hasImportUIStr)) {
auto const& info = _GetInfo(argData, _hasImportUIStr);
setResult(bool(info.importUICallback != nullptr));
} else if (argData.isFlagSet(_showImportUIStr)) {
auto const& info = _GetInfo(argData, _showImportUIStr);
if (!info.importUICallback)
return MS::kInvalidParameter;

MString parentUIStr;
if (argData.getFlagArgument(_showImportUIStr, 1, parentUIStr) != MS::kSuccess)
return MS::kInvalidParameter;

MString settingsStr;
if (argData.getFlagArgument(_showImportUIStr, 2, settingsStr) != MS::kSuccess)
return MS::kInvalidParameter;

VtDictionary inputSettings;
if (UsdMayaJobImportArgs::GetDictionaryFromEncodedOptions(settingsStr, &inputSettings)
!= MS::kSuccess)
return MS::kInvalidParameter;

setResult(convertDictionaryToText(
info.importUICallback(info.jobContext, parentUIStr.asChar(), inputSettings)));
} else if (argData.isFlagSet(_importStr)) {
for (auto const& c : UsdMayaJobContextRegistry::ListJobContexts()) {
auto const& info = UsdMayaJobContextRegistry::GetJobContextInfo(c);
Expand Down Expand Up @@ -163,6 +188,8 @@ MSyntax MayaUSDListJobContextsCommand::createSyntax()
syntax.addFlag("-eg", "-exportArguments", MSyntax::kString);
syntax.addFlag("-heu", "-hasExportUI", MSyntax::kString);
syntax.addFlag("-seu", "-showExportUI", MSyntax::kString, MSyntax::kString, MSyntax::kString);
syntax.addFlag("-hiu", "-hasImportUI", MSyntax::kString);
syntax.addFlag("-siu", "-showImportUI", MSyntax::kString, MSyntax::kString, MSyntax::kString);
syntax.addFlag("-im", "-import", MSyntax::kNoArg);
syntax.addFlag("-ia", "-importAnnotation", MSyntax::kString);
syntax.addFlag("-ig", "-importArguments", MSyntax::kString);
Expand Down
23 changes: 23 additions & 0 deletions lib/mayaUsd/fileio/jobContextRegistry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,29 @@ void UsdMayaJobContextRegistry::RegisterImportJobContext(
}
}

void UsdMayaJobContextRegistry::SetImportOptionsUI(
const std::string& jobContext,
UIFn uiFct,
bool fromPython)
{
const ContextInfo key { TfToken(jobContext), {}, {}, {}, {}, {} };
auto iter = _jobContextReg.find(key);
if (iter == _jobContextReg.end()) {
TF_CODING_ERROR("Import job context %s does not exist", jobContext.c_str());
return;
}

// Note: the container for the plugin info is a set so it cannot be modified.
// We need to copy the entry, modify the copy, remove the old entry and
// insert the newly updated entry.

ContextInfo updatedInfo(*iter);
updatedInfo.importUICallback = uiFct;
UsdMaya_RegistryHelper::AddUnloader([key]() { _jobContextReg.erase(key); }, fromPython);
_jobContextReg.erase(iter);
_jobContextReg.insert(updatedInfo);
}

TfTokenVector UsdMayaJobContextRegistry::_ListJobContexts()
{
UsdMaya_RegistryHelper::LoadJobContextPlugins();
Expand Down
12 changes: 12 additions & 0 deletions lib/mayaUsd/fileio/jobContextRegistry.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ class UsdMayaJobContextRegistry : public TfWeakBase
UIFn exportUICallback;
TfToken importDescription;
EnablerFn importEnablerCallback;
UIFn importUICallback;

ContextInfo() = default;

Expand Down Expand Up @@ -176,6 +177,17 @@ class UsdMayaJobContextRegistry : public TfWeakBase
EnablerFn enablerFct,
bool fromPython = false);

/// Registers an import job context UI dialog.
///
/// The \p jobContext name will be used directly in the render option string as one of
/// the valid values of the job context option.
///
/// The \p uiFct will be called to show a modal dialog to modify options by the user.
///
/// The \p fromPython flag indicates the function is a Python function.
MAYAUSD_CORE_PUBLIC
void SetImportOptionsUI(const std::string& jobContext, UIFn uiFct, bool fromPython = false);

MAYAUSD_CORE_PUBLIC
static UsdMayaJobContextRegistry& GetInstance();

Expand Down
35 changes: 34 additions & 1 deletion lib/mayaUsd/fileio/jobs/jobArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -834,7 +834,7 @@ MStatus UsdMayaJobExportArgs::GetDictionaryFromEncodedOptions(
MStringArray optionList;
MStringArray theOption;
optionsString.split(';', optionList);
for (int i = 0; i < (int)optionList.length(); ++i) {
for (unsigned int i = 0; i < optionList.length(); ++i) {
theOption.clear();
optionList[i].split('=', theOption);
if (theOption.length() != 2) {
Expand Down Expand Up @@ -1216,6 +1216,39 @@ UsdMayaJobImportArgs UsdMayaJobImportArgs::CreateFromDictionary(
return UsdMayaJobImportArgs(allUserArgs, importWithProxyShapes, timeInterval);
}

/* static */
MStatus UsdMayaJobImportArgs::GetDictionaryFromEncodedOptions(
const MString& optionsString,
VtDictionary* toFill)
{
if (!toFill)
return MS::kFailure;

VtDictionary& userArgs = *toFill;

// Get the options
if (optionsString.length() > 0) {
MStringArray optionList;
MStringArray theOption;
optionsString.split(';', optionList);
for (unsigned int i = 0; i < optionList.length(); ++i) {
theOption.clear();
optionList[i].split('=', theOption);
if (theOption.length() != 2) {
continue;
}

// Note: if some argument needs special handling, do like in the
// same function in the export version in UsdMayaJobExportArgs
std::string argName(theOption[0].asChar());
userArgs[argName] = UsdMayaUtil::ParseArgumentValue(
argName, theOption[1].asChar(), UsdMayaJobExportArgs::GetGuideDictionary());
}
}

return MS::kSuccess;
}

/* static */
const VtDictionary& UsdMayaJobImportArgs::GetDefaultDictionary()
{
Expand Down
8 changes: 8 additions & 0 deletions lib/mayaUsd/fileio/jobs/jobArgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,14 @@ struct UsdMayaJobImportArgs
const bool importWithProxyShapes = false,
const GfInterval& timeInterval = GfInterval::GetFullInterval());

/// Fills a VtDictionary from the given text-encoded options.
/// Issues runtime errors if some options contain values of the wrong format.
///
/// The text encoding is in the form: name1=value1;name2=value2;...
MAYAUSD_CORE_PUBLIC
static MStatus
GetDictionaryFromEncodedOptions(const MString& optionsString, VtDictionary* toFill);

/// Gets the default arguments dictionary for UsdMayaJobImportArgs.
MAYAUSD_CORE_PUBLIC
static const VtDictionary& GetDefaultDictionary();
Expand Down
20 changes: 19 additions & 1 deletion lib/mayaUsd/python/wrapJobContextRegistry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,22 @@ class JobContextRegistry
true);
}

static void SetImportOptionsUI(const std::string& jobContext, boost::python::object uiFct)
{
if (!PyCallable_Check(uiFct.ptr()))
TF_CODING_ERROR(
"Parameter uiFct should be a callable function returning a dictionary.");

UsdMayaJobContextRegistry::GetInstance().SetImportOptionsUI(
jobContext,
[=](const TfToken& jobContext,
const std::string& parentUI,
const VtDictionary& settings) {
return callUIFn(uiFct, jobContext, parentUI, settings);
},
true);
}

private:
static VtDictionary callEnablerFn(boost::python::object fnc)
{
Expand Down Expand Up @@ -119,5 +135,7 @@ void wrapJobContextRegistry()
.def("RegisterExportJobContext", &JobContextRegistry::RegisterExportJobContext)
.staticmethod("RegisterExportJobContext")
.def("SetExportOptionsUI", &JobContextRegistry::SetExportOptionsUI)
.staticmethod("SetExportOptionsUI");
.staticmethod("SetExportOptionsUI")
.def("SetImportOptionsUI", &JobContextRegistry::SetImportOptionsUI)
.staticmethod("SetImportOptionsUI");
}
8 changes: 7 additions & 1 deletion plugin/adsk/scripts/mayaUSDRegisterStrings.mel
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ global proc mayaUSDRegisterStrings()
register("kExportPluginConfigAnn", "Turn on the plug-ins you wish to include for this process.\n" +
"When turned on, plug-ins (like Arnold) can modify or create data to ensure compatibility.\n" +
"Plug-ins may have extra settings you can adjust.");
register("kExportPluginConfigButtonLbl", "Options");
register("kExportPluginConfigButtonAnn", "Options");
register("kExportMaterialsAnn", "Select the material(s) to bind to prims for export. With USD, you can bind multiple materials to prims.");
register("kExportMaterialsDefaultScopeName", "mtl");
register("kExportMergeShapesAnn", "Merges Maya transform and shape nodes into a single USD prim.");
Expand Down Expand Up @@ -254,6 +254,12 @@ global proc mayaUSDRegisterStrings()
register("kImportUSDZTxtAnn", "When a .usdz file is chosen and this is selected, .usdz texture files are imported and copied to new files on disk. To locate these files, navigate to the current Maya workspace /sourceimages directory.");
register("kImportUSDZTxtLbl", "USDZ Texture Import");
register("kImportVariantsInScopeNumLbl", "Variants Switched in Scope:");
register("kImportPluginConfigLbl", "Plug-in Configurations");
register("kImportPluginConfigAnn", "Turn on the plug-ins you wish to include for this process.\n" +
"When turned on, plug-ins (like Arnold) can modify or create data to ensure compatibility.\n" +
"Plug-ins may have extra settings you can adjust.");
register("kImportPluginConfigButtonAnn", "Options");

register("kMayaDiscardEdits", "Discard Maya Edits");
register("kMayaRefDiscardEdits", "Cancel Editing as Maya Data");
register("kMayaRefDuplicateAsUsdData", "Duplicate As USD Data");
Expand Down
10 changes: 5 additions & 5 deletions plugin/adsk/scripts/mayaUsdTranslatorExport.mel
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ proc mayaUsdTranslatorExport_createContextOptions(string $parent, string $sectio
text -label $contextLabel -ann $tooltip -align "left";
iconTextButton
-w 16 -h 16 -style "iconAndTextVertical"
-image1 "menu_options" -label "" -ann `getMayaUsdString("kExportPluginConfigButtonLbl")`
-image1 "menu_options" -label "" -ann `getMayaUsdString("kExportPluginConfigButtonAnn")`
-command ("mayaUsdTranslatorExport_contextOptionsButtonCB(\"" + $contextLabel + "\")") $buttonName;

rowLayout -width 2 -height $rowHeight -backgroundColor $color[0] $color[1] $color[2];
Expand Down Expand Up @@ -745,7 +745,7 @@ global proc mayaUsdTranslatorExport_EnableAllControls() {
global proc mayaUsdTranslatorExport_SetFromOptions(string $currentOptions, int $enable, int $processJobContext) {
string $optionList[];
string $optionBreakDown[];
string $jobContext = "";
string $listOfJobContexts = "";
int $index;

if (size($currentOptions) > 0) {
Expand Down Expand Up @@ -802,7 +802,7 @@ global proc mayaUsdTranslatorExport_SetFromOptions(string $currentOptions, int $
mayaUsdTranslatorExport_SetCheckbox($optionBreakDown[1], $enable, "exportComponentTagsCheckBox");
} else if ($optionBreakDown[0] == "jobContext" && $processJobContext == 1) {
// Must be kept last, and only done on main options:
$jobContext = $optionBreakDown[1];
$listOfJobContexts = $optionBreakDown[1];
} else if ($optionBreakDown[0] == "defaultMeshScheme") {
mayaUsdTranslatorExport_SetOptionMenuByAnnotation($optionBreakDown[1], $enable, "defaultMeshSchemePopup");
} else if ($optionBreakDown[0] == "defaultUSDFormat") {
Expand Down Expand Up @@ -857,8 +857,8 @@ global proc mayaUsdTranslatorExport_SetFromOptions(string $currentOptions, int $
mayaUsdTranslatorExport_MeshCB();
}

if ($jobContext != "" && $processJobContext == 1) {
mayaUsdTranslatorExport_fillContextOptionsUI($jobContext);
if ($listOfJobContexts != "" && $processJobContext == 1) {
mayaUsdTranslatorExport_fillContextOptionsUI($listOfJobContexts);
}
if ($processJobContext == 0 && $supportsMultiExport == 0) {
mayaUsdTranslatorExport_DisableConvertMaterialsToCheckboxes();
Expand Down
Loading

0 comments on commit cfe8396

Please sign in to comment.