Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MAYA-103409 Minimal Create USD Stage #306

Merged
merged 2 commits into from
Feb 27, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 31 additions & 2 deletions lib/nodes/proxyShapeBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ const MString MayaUsdProxyShapeBase::displayFilterLabel("USD Proxies");
MObject MayaUsdProxyShapeBase::filePathAttr;
MObject MayaUsdProxyShapeBase::primPathAttr;
MObject MayaUsdProxyShapeBase::excludePrimPathsAttr;
MObject MayaUsdProxyShapeBase::loadPayloadsAttr;
MObject MayaUsdProxyShapeBase::timeAttr;
MObject MayaUsdProxyShapeBase::complexityAttr;
MObject MayaUsdProxyShapeBase::inStageDataAttr;
Expand Down Expand Up @@ -177,6 +178,20 @@ MayaUsdProxyShapeBase::initialize()
retValue = addAttribute(excludePrimPathsAttr);
CHECK_MSTATUS_AND_RETURN_IT(retValue);

loadPayloadsAttr = numericAttrFn.create(
"loadPayloads",
"lpl",
MFnNumericData::kBoolean,
0.0,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this attribute be turned on by default? That would preserve existing behavior of loading payloads when opening the stage.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point, but it does default to 'true', there is setDefault(true) call a couple of lines below. Maybe I should not have been so clever

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let me fix that by doing in the definition line instead

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, sorry! I read right past that setDefault(true) call.

But yeah, looks a bit cleaner to just have it in the initial definition. Thanks!

&retValue);
CHECK_MSTATUS_AND_RETURN_IT(retValue);
numericAttrFn.setDefault(true);
numericAttrFn.setKeyable(true);
numericAttrFn.setReadable(false);
numericAttrFn.setAffectsAppearance(true);
retValue = addAttribute(loadPayloadsAttr);
CHECK_MSTATUS_AND_RETURN_IT(retValue);

timeAttr = unitAttrFn.create(
"time",
"tm",
Expand Down Expand Up @@ -296,6 +311,11 @@ MayaUsdProxyShapeBase::initialize()
retValue = attributeAffects(primPathAttr, outStageDataAttr);
CHECK_MSTATUS_AND_RETURN_IT(retValue);

retValue = attributeAffects(loadPayloadsAttr, inStageDataCachedAttr);
CHECK_MSTATUS_AND_RETURN_IT(retValue);
retValue = attributeAffects(loadPayloadsAttr, outStageDataAttr);
CHECK_MSTATUS_AND_RETURN_IT(retValue);

retValue = attributeAffects(inStageDataAttr, inStageDataCachedAttr);
CHECK_MSTATUS_AND_RETURN_IT(retValue);
retValue = attributeAffects(inStageDataAttr, outStageDataAttr);
Expand Down Expand Up @@ -453,17 +473,26 @@ MayaUsdProxyShapeBase::computeInStageDataCached(MDataBlock& dataBlock)
// == Load the Stage
UsdStageRefPtr usdStage;
SdfPath primPath;
auto loadSet = UsdStage::InitialLoadSet::LoadAll;

MDataHandle loadPayloadsHandle = dataBlock.inputValue(loadPayloadsAttr, &retValue);
CHECK_MSTATUS_AND_RETURN_IT(retValue);
if (!loadPayloadsHandle.asBool()) {
loadSet = UsdStage::InitialLoadSet::LoadNone;
}

if (SdfLayerRefPtr rootLayer = SdfLayer::FindOrOpen(fileString)) {
UsdStageCacheContext ctx(UsdMayaStageCache::Get());
SdfLayerRefPtr sessionLayer = computeSessionLayer(dataBlock);
if (sessionLayer) {
usdStage = UsdStage::Open(rootLayer,
sessionLayer,
ArGetResolver().GetCurrentContext());
ArGetResolver().GetCurrentContext(),
loadSet);
} else {
usdStage = UsdStage::Open(rootLayer,
ArGetResolver().GetCurrentContext());
ArGetResolver().GetCurrentContext(),
loadSet);
}

usdStage->SetEditTarget(usdStage->GetSessionLayer());
Expand Down
2 changes: 2 additions & 0 deletions lib/nodes/proxyShapeBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ class MayaUsdProxyShapeBase : public MPxSurfaceShape,
MAYAUSD_CORE_PUBLIC
static MObject excludePrimPathsAttr;
MAYAUSD_CORE_PUBLIC
static MObject loadPayloadsAttr;
MAYAUSD_CORE_PUBLIC
static MObject timeAttr;
MAYAUSD_CORE_PUBLIC
static MObject complexityAttr;
Expand Down
5 changes: 5 additions & 0 deletions plugin/adsk/plugin/plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ MStatus initializePlugin(MObject obj)
}
#endif

MGlobal::executeCommand("source \"mayaUsdMenu.mel\"");
MGlobal::executeCommand("mayaUsdMenu_loadui");

// As of 2-Aug-2019, these PlugPlugin translators are not loaded
// automatically. To be investigated. A duplicate of this code is in the
// Pixar plugin.cpp.
Expand Down Expand Up @@ -128,6 +131,8 @@ MStatus uninitializePlugin(MObject obj)
MFnPlugin plugin(obj);
MStatus status;

MGlobal::executeCommand("mayaUsdMenu_unloadui");

status = UsdMayaUndoHelperCommand::finalize(plugin);
if (!status) {
status.perror(std::string("deregisterCommand ").append(
Expand Down
2 changes: 2 additions & 0 deletions plugin/adsk/scripts/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ list(APPEND scripts_src
mayaUsdTranslatorImport.mel
mayaUsdTranslatorExport.mel
AEmayaUsdProxyShapeTemplate.mel
mayaUsdMenu.mel
mayaUsd_createStagesFromExistingLayer.mel
)

install(FILES ${scripts_src}
Expand Down
141 changes: 141 additions & 0 deletions plugin/adsk/scripts/mayaUsdMenu.mel
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
// Copyright 2020 Autodesk
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

///////////////////////////////////////////////////////////////////////////////
// globals
// variable used to keep track of created menus
global string $gMayaUsdCreateSubMenu = "";

///////////////////////////////////////////////////////////////////////////////
// findDividerByLabel
// search a menu for a divider by its (localized) label
proc string findDividerByLabel(string $menuName, string $label) {
$allMenuItems = `menu -q -itemArray $menuName`;
for ($menuItem in $allMenuItems) {
if (`menuItem -q -divider $menuItem`) {
if ($label == `menuItem -q -dividerLabel $menuItem`) {
return $menuItem;
}
}
}
return "";
}

///////////////////////////////////////////////////////////////////////////////
// addMenuCallback
// safely add a post menu callback to a menu
proc addMenuCallback(string $menuName, string $cmd) {
string $existingCallbacks = `menu -q -pmc $menuName`;
// append the callback
menu -e -pmc ($existingCallbacks + ";" + $cmd + ";") $menuName;
}

///////////////////////////////////////////////////////////////////////////////
// removeMenuCallback
// safely remove a post menu callback to a menu
proc removeMenuCallback(string $menuName, string $cmd) {
string $existingCallbacks = `menu -q -pmc $menuName`;
// remove our callback from the string of callbacks
string $newCallbacks =
`substitute (";"+$cmd+".*;") $existingCallbacks ""`;
menu -e -pmc $newCallbacks $menuName;

}

///////////////////////////////////////////////////////////////////////////////
// initRuntimeCommands
// create all the runtime commands we'll use and the user can map to hotkeys
proc initRuntimeCommands() {
if (!`runTimeCommand -exists mayaUsdCreateStageFromExistingLayer`) {
runTimeCommand -default true
-label "Stage From Existing Layer..."
-annotation "Create a USD Stage from an existing USD layer"
-category "Menu items.Maya USD"
-command "mayaUsd_createStagesFromExistingLayer"
mayaUsdCreateStageFromExistingLayer;
source "mayaUsd_createStagesFromExistingLayer.mel";
}
}

///////////////////////////////////////////////////////////////////////////////
// getMayaMajorVersion
// this is used to get the "new feature" highlight
proc string getMayaMajorVersion() {
string $version = `about -apiVersion`;
return `substring $version 1 4`;
}

///////////////////////////////////////////////////////////////////////////////
// mayaUsdMenu_createMenuCallback
// setup the items in Maya's "Create" menu
global proc mayaUsdMenu_createMenuCallback() {
global string $gMayaUsdCreateSubMenu;

if ($gMayaUsdCreateSubMenu == "") {
global string $gMainCreateMenu; // maya's create menu

string $mayaVersion = getMayaMajorVersion();
// find the insertion point, after the Scene Management separator
$sceneManagementDivider = findDividerByLabel($gMainCreateMenu, uiRes("m_ModCreateMenu.kCreateSceneMgt"));
if ($sceneManagementDivider != "") {
$gMayaUsdCreateSubMenu = `menuItem -subMenu true -insertAfter $sceneManagementDivider
-label "Universal Scene Description (USD)"
-annotation "Create a USD stage"
-version $mayaVersion`;
menuItem -runTimeCommand mayaUsdCreateStageFromExistingLayer -version $mayaVersion;
} else {
error "Could not create mayaUSD create menu";
}
}
}

///////////////////////////////////////////////////////////////////////////////
// initCreateMenu
// setup the items in Maya's "Create" menu
proc initCreateMenu() {
global string $gMainCreateMenu; // maya's create menu
addMenuCallback($gMainCreateMenu, "mayaUsdMenu_createMenuCallback()");
}

///////////////////////////////////////////////////////////////////////////////
// termCreateMenu
// destroys the items in Maya's "Create" menu
proc termCreateMenu() {
global string $gMainCreateMenu; // maya's create menu
global string $gMayaUsdCreateSubMenu;
if ($gMayaUsdCreateSubMenu != "") {
deleteUI -mi $gMayaUsdCreateSubMenu;
$gMayaUsdCreateSubMenu = "";
}
removeMenuCallback($gMainCreateMenu, "mayaUsdMenu_createMenuCallback()");
}


///////////////////////////////////////////////////////////////////////////////
// mayaUsdMenu_loadui
// main entry point on plugin load
global proc mayaUsdMenu_loadui() {

initRuntimeCommands();
initCreateMenu();
}

///////////////////////////////////////////////////////////////////////////////
// mayaUsdMenu_unloadui
// main entry point on plugin unload
global proc mayaUsdMenu_unloadui() {
termCreateMenu();
}

94 changes: 94 additions & 0 deletions plugin/adsk/scripts/mayaUsd_createStagesFromExistingLayer.mel
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// Copyright 2020 Autodesk
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

global string $stageFromExistingLayer_primPath = "";
global string $stageFromExistingLayer_excludePrimPath = "";
global int $stageFromExistingLayer_loadPayloads = 1;

// stageFromExistingLayer_UISetup
// creates the options of the stageFromExistingLayer dialog
global proc stageFromExistingLayer_UISetup(string $parent) {
setParent $parent;
$parent = `scrollLayout -childResizable true`;

frameLayout -label "USD Layer Options";
textFieldGrp -l "Prim Path:"
-ann "Loads the specified prim path. If a matching prim path is not found, all prims in the file are loaded."
-sbm "Loads the specified prim path"
primPathField;
textFieldGrp -l "Exclude Prim Paths:"
-ann "Excludes the specified prim paths from the loaded USD data. Multiple prim paths must be separated by a comma."
-sbm "Excludes the specified prim paths from the loaded USD data"
excludePrimPathField;
checkBoxGrp -l "Load Payloads:"
-ann "When on, loads all prims marked as payloads. When off, all prims marked as payloads and their children are not loaded."
-sbm "Loads prims marked as payloads"
loadPayloadsCheckBox;
}

// stageFromExistingLayer_UIInit
// init defaults values for the options of the stageFromExistingLayer dialog
global proc stageFromExistingLayer_UIInit(string $parent, string $filterType) {
global string $stageFromExistingLayer_primPath;
global string $stageFromExistingLayer_excludePrimPath;
global int $stageFromExistingLayer_loadPayloads;

setParent $parent;
textFieldGrp -e -text $stageFromExistingLayer_primPath primPathField;
textFieldGrp -e -text $stageFromExistingLayer_excludePrimPath excludePrimPathField;
checkBoxGrp -e -value1 $stageFromExistingLayer_loadPayloads loadPayloadsCheckBox;
}

global proc stageFromExistingLayer_UICommit(string $parent, string $selectedFile) {
global string $stageFromExistingLayer_primPath;
global string $stageFromExistingLayer_excludePrimPath;
global int $stageFromExistingLayer_loadPayloads;

setParent $parent;
// fetch values
$stageFromExistingLayer_primPath = `textFieldGrp -q -text primPathField`;
$stageFromExistingLayer_excludePrimPath = `textFieldGrp -q -text excludePrimPathField`;
$stageFromExistingLayer_loadPayloads = `checkBoxGrp -q -value1 loadPayloadsCheckBox`;

// actually load the file
string $fileName = $selectedFile;
string $baseName = capitalizeString(`basenameEx $fileName`);
if( isValidObjectName($baseName) )
$baseName += "_usd";
else
$baseName = "UsdStage";

string $shapeNode = `createNode "mayaUsdProxyShape" -skipSelect -name ($baseName+"Shape")`;
setAttr -type "string" ($shapeNode+".filePath") $fileName;
setAttr -type "string" ($shapeNode+".primPath") $stageFromExistingLayer_primPath;
setAttr -type "string" ($shapeNode+".excludePrimPaths") $stageFromExistingLayer_excludePrimPath;
setAttr ($shapeNode+".loadPayloads") $stageFromExistingLayer_loadPayloads;
connectAttr time1.outTime ($shapeNode+".time");
}

global proc mayaUsd_createStagesFromExistingLayer() {
fileDialog2
-fileMode 1
-caption "Create USD Stage From Existing Layer"
-fileFilter "All USD Files (*.usd *.usda *.usdc *.usdz);;*.usd;;*.usda;;*.usdc;;*.usdz"
-okCaption "Create"
-optionsUICreate "stageFromExistingLayer_UISetup"
-optionsUIInit "stageFromExistingLayer_UIInit"
-optionsUICommit2 "stageFromExistingLayer_UICommit";
}