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

Tremblp/maya 114706/validate pull push capability #1845

Merged
merged 5 commits into from
Nov 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
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
14 changes: 13 additions & 1 deletion lib/mayaUsd/fileio/primUpdater.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <mayaUsd/fileio/jobs/jobArgs.h>
#include <mayaUsd/fileio/jobs/readJob.h>
#include <mayaUsd/fileio/jobs/writeJob.h>
#include <mayaUsd/fileio/primReaderRegistry.h>
#include <mayaUsd/fileio/utils/writeUtil.h>
#include <mayaUsd/nodes/proxyShapeBase.h>
#include <mayaUsd/ufe/Utils.h>
Expand Down Expand Up @@ -65,7 +66,18 @@ UsdMayaPrimUpdater::UsdMayaPrimUpdater(const MFnDependencyNode& depNodeFn, const
{
}

bool UsdMayaPrimUpdater::pull(const UsdMayaPrimUpdaterContext& context) { return true; }
bool UsdMayaPrimUpdater::canEditAsMaya() const
{
// To be editable as Maya data we must ensure that there is an importer (to
// Maya). As of 17-Nov-2021 it is not possible to determine how the
// prim will round-trip back through export, so we do not check for
// exporter (to USD) capability.
auto prim = MayaUsd::ufe::ufePathToPrim(_path);
TF_AXIOM(prim);
return (UsdMayaPrimReaderRegistry::Find(prim.GetTypeName()) != nullptr);
}

bool UsdMayaPrimUpdater::editAsMaya(const UsdMayaPrimUpdaterContext& context) { return true; }

bool UsdMayaPrimUpdater::discardEdits(const UsdMayaPrimUpdaterContext& context)
{
Expand Down
13 changes: 10 additions & 3 deletions lib/mayaUsd/fileio/primUpdater.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,16 @@ class UsdMayaPrimUpdater
SdfLayerRefPtr dstLayer,
const SdfPath& dstSdfPath);

/// Query to determine if the prim corresponding to this updater can be
/// edited as Maya. The default implementation in this class checks
/// whether there is an importer for the prim.
MAYAUSD_CORE_PUBLIC
virtual bool canEditAsMaya() const;

/// Customize the pulled prim after pull import. Default implementation in
/// this class is a no-op.
MAYAUSD_CORE_PUBLIC
virtual bool pull(const UsdMayaPrimUpdaterContext& context);
virtual bool editAsMaya(const UsdMayaPrimUpdaterContext& context);

/// Discard edits done in Maya. Implementation in this class removes the
/// Maya node.
Expand Down Expand Up @@ -98,10 +104,11 @@ class UsdMayaPrimUpdater

private:
/// The MObject for the Maya node being updated, valid for both DAG and DG
/// node prim updaters.
/// node prim updaters. Can be a null object if the updater was created
/// only for canEditAsMaya() query purposes.
const MObject _mayaObject;

/// The proxy shape and destination sdf path if provided
/// The proxy shape and destination Sdf path if provided.
const Ufe::Path _path;
};

Expand Down
39 changes: 30 additions & 9 deletions lib/mayaUsd/fileio/primUpdaterManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@
#include <functional>
#include <tuple>

using UpdaterFactoryFn = UsdMayaPrimUpdaterRegistry::UpdaterFactoryFn;

// Allow for use of MObjectHandle with std::unordered_map.
namespace std {
template <> struct hash<MObjectHandle>
Expand Down Expand Up @@ -292,11 +294,14 @@ PullImportPaths pullImport(
}
}

// Execute the command
// Execute the command, which can succeed but import nothing.
bool success = readJob.Read(&addedDagPaths);
if (!success || addedDagPaths.size() == 0) {
return PullImportPaths({}, {});
}

const bool isCopy = context.GetArgs()._copyOperation;
if (success && !isCopy) {
if (!isCopy) {
// Quick workaround to reuse some POC code - to rewrite later
auto ufeChild = MayaUsd::ufe::dagPathToUfe(addedDagPaths[0]);

Expand Down Expand Up @@ -373,7 +378,7 @@ bool pullCustomize(const PullImportPaths& importedPaths, const UsdMayaPrimUpdate
// customization step. This is a frequent difficulty for operations on
// multiple data, especially since we can't roll back the result of
// the execution of previous updaters. Revisit this. PPT, 15-Sep-2021.
if (!updater->pull(context)) {
if (!updater->editAsMaya(context)) {
return false;
}
}
Expand Down Expand Up @@ -485,8 +490,6 @@ UsdMayaPrimUpdaterSharedPtr createUpdater(
const SdfPath& primSpecPath,
const UsdMayaPrimUpdaterContext& context)
{
using UpdaterFactoryFn = UsdMayaPrimUpdaterRegistry::UpdaterFactoryFn;

// Get the primSpec from the src layer.
auto primSpec = srcLayer->GetPrimAtPath(primSpecPath);
if (!TF_VERIFY(primSpec)) {
Expand Down Expand Up @@ -541,7 +544,6 @@ bool pushCustomize(

// Traverse the layer, creating a prim updater for each primSpec
// along the way, and call PushCopySpec on the prim.
using UpdaterFactoryFn = UsdMayaPrimUpdaterRegistry::UpdaterFactoryFn;
auto pushCopySpecsFn
= [&context, srcStage, srcLayer, dstLayer, dstRootParentPath](const SdfPath& srcPath) {
// We can be called with a primSpec path that is not a prim path
Expand Down Expand Up @@ -676,7 +678,7 @@ PrimUpdaterManager::~PrimUpdaterManager()
_cbIds.clear();
}

bool PrimUpdaterManager::push(const MFnDependencyNode& depNodeFn, const Ufe::Path& pulledPath)
bool PrimUpdaterManager::mergeToUsd(const MFnDependencyNode& depNodeFn, const Ufe::Path& pulledPath)
{
MayaUsdProxyShapeBase* proxyShape = MayaUsd::ufe::getProxyShape(pulledPath);
if (!proxyShape) {
Expand Down Expand Up @@ -748,7 +750,7 @@ bool PrimUpdaterManager::push(const MFnDependencyNode& depNodeFn, const Ufe::Pat
return true;
}

bool PrimUpdaterManager::pull(const Ufe::Path& path)
bool PrimUpdaterManager::editAsMaya(const Ufe::Path& path)
{
MayaUsdProxyShapeBase* proxyShape = MayaUsd::ufe::getProxyShape(path);
if (!proxyShape) {
Expand Down Expand Up @@ -785,6 +787,9 @@ bool PrimUpdaterManager::pull(const Ufe::Path& path)

// 1) Perform the import
PullImportPaths importedPaths = pullImport(path, pulledPrim, context);
if (importedPaths.first.empty()) {
return false;
}

// 2) Iterate over all imported Dag paths.
if (!pullCustomize(importedPaths, context)) {
Expand All @@ -804,6 +809,22 @@ bool PrimUpdaterManager::pull(const Ufe::Path& path)
return true;
}

bool PrimUpdaterManager::canEditAsMaya(const Ufe::Path& path) const
{
// Create a prim updater for the path, and ask it if the prim can be edited
// as Maya.
auto prim = MayaUsd::ufe::ufePathToPrim(path);
if (!prim) {
return false;
}
auto typeName = prim.GetTypeName();
auto regItem = UsdMayaPrimUpdaterRegistry::FindOrFallback(typeName);
auto factory = std::get<UpdaterFactoryFn>(regItem);
// No Maya Dag path for the prim updater, so pass in a null MObject.
auto updater = factory(MFnDependencyNode(MObject()), path);
return updater ? updater->canEditAsMaya() : false;
}

bool PrimUpdaterManager::discardEdits(const Ufe::Path& pulledPath)
{
MayaUsdProxyShapeBase* proxyShape = MayaUsd::ufe::getProxyShape(pulledPath);
Expand Down Expand Up @@ -962,7 +983,7 @@ void PrimUpdaterManager::onProxyContentChanged(
= MayaUsd::ufe::usdPathToUfePathSegment(prim.GetPath());
const Ufe::Path path = proxyNotice.GetProxyShape().ufePath() + pathSegment;

pull(path);
editAsMaya(path);
}
}
}
Expand Down
8 changes: 6 additions & 2 deletions lib/mayaUsd/fileio/primUpdaterManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,14 @@ class PrimUpdaterManager : public PXR_NS::TfWeakBase
~PrimUpdaterManager();

MAYAUSD_CORE_PUBLIC
bool push(const MFnDependencyNode& depNodeFn, const Ufe::Path& pulledPath);
bool mergeToUsd(const MFnDependencyNode& depNodeFn, const Ufe::Path& pulledPath);

MAYAUSD_CORE_PUBLIC
bool pull(const Ufe::Path& path);
bool editAsMaya(const Ufe::Path& path);

// Can the prim at the argument path be edited as Maya.
MAYAUSD_CORE_PUBLIC
bool canEditAsMaya(const Ufe::Path& path) const;

MAYAUSD_CORE_PUBLIC
bool discardEdits(const Ufe::Path& path);
Expand Down
6 changes: 3 additions & 3 deletions lib/mayaUsd/fileio/primUpdaterRegistry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ void UsdMayaPrimUpdaterRegistry::Register(
TfToken tfTypeName(tfType.GetTypeName());

TF_DEBUG(PXRUSDMAYA_REGISTRY)
.Msg("Registering UsdMayaPrimWriter for TfType type %s.\n", tfTypeName.GetText());
.Msg("Registering UsdMayaPrimUpdater for TfType type %s.\n", tfTypeName.GetText());

auto insertStatus = _regTfType.insert(std::make_pair(tfTypeName, std::make_tuple(sup, fn)));
if (insertStatus.second) {
Expand All @@ -86,8 +86,8 @@ UsdMayaPrimUpdaterRegistry::FindOrFallback(const TfToken& usdTypeName)
{
TfRegistryManager::GetInstance().SubscribeTo<UsdMayaPrimUpdaterRegistry>();

// unfortunately, usdTypeName is diff from the tfTypeName which we use to
// register. do the conversion here.
// Unfortunately, usdTypeName is diff from the tfTypeName which we use to
// register. Do the conversion here.
TfType tfType = PlugRegistry::FindDerivedTypeByName<UsdSchemaBase>(usdTypeName);
std::string typeNameStr = tfType.GetTypeName();
TfToken typeName(typeNameStr);
Expand Down
6 changes: 3 additions & 3 deletions lib/mayaUsd/fileio/primUpdaterRegistry.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,12 @@ struct UsdMayaPrimUpdaterRegistry
UsdMayaPrimUpdater::Supports sup,
UpdaterFactoryFn fn);

/// \brief Register \p fn as a reader provider for \p T.
/// \brief Register \p fn as an updater provider for \p T.
///
/// Example for registering a reader factory in your custom plugin, assuming
/// Example for registering an updater factory in your custom plugin, assuming
/// that MyType is registered with the TfType system:
/// \code{.cpp}
/// class MyReader : public UsdMayaPrimUpdater {
/// class MyUpdater : public UsdMayaPrimUpdater {
/// static UsdMayaPrimReaderSharedPtr Create(
/// const UsdMayaPrimReaderArgs&);
/// };
Expand Down
21 changes: 12 additions & 9 deletions lib/mayaUsd/python/wrapPrimUpdaterManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ using namespace boost;
PXR_NAMESPACE_USING_DIRECTIVE

namespace {
bool push(const std::string& nodeName)
bool mergeToUsd(const std::string& nodeName)
{
MObject obj;
MStatus status = UsdMayaUtil::GetMObjectByName(nodeName, obj);
Expand All @@ -54,14 +54,19 @@ bool push(const std::string& nodeName)
if (!PrimUpdaterManager::readPullInformation(dagPath, path))
return false;

return PrimUpdaterManager::getInstance().push(dagNode, path);
return PrimUpdaterManager::getInstance().mergeToUsd(dagNode, path);
}

bool pull(const std::string& ufePathString)
bool editAsMaya(const std::string& ufePathString)
{
Ufe::Path path = Ufe::PathString::path(ufePathString);

return PrimUpdaterManager::getInstance().pull(path);
return PrimUpdaterManager::getInstance().editAsMaya(path);
}

bool canEditAsMaya(const std::string& ufePathString)
{
return PrimUpdaterManager::getInstance().canEditAsMaya(Ufe::PathString::path(ufePathString));
}

bool discardEdits(const std::string& nodeName)
Expand Down Expand Up @@ -92,11 +97,9 @@ void wrapPrimUpdaterManager()
{
using This = PrimUpdaterManager;
class_<This>("PrimUpdaterManager", no_init)
.def("push", push)
.def("pull", pull)
.def("pullClear", discardEdits)
.def("mergeToUsd", push)
.def("editAsMaya", pull)
.def("mergeToUsd", mergeToUsd)
.def("editAsMaya", editAsMaya)
.def("canEditAsMaya", canEditAsMaya)
.def("discardEdits", discardEdits)
.def("duplicate", duplicate);
}
11 changes: 10 additions & 1 deletion lib/mayaUsd/ufe/UsdContextOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@

#include "private/UfeNotifGuard.h"

#ifdef UFE_V3_FEATURES_AVAILABLE
#include <mayaUsd/fileio/primUpdaterManager.h>
#endif
#include <mayaUsd/ufe/UsdObject3d.h>
#include <mayaUsd/ufe/UsdSceneItem.h>
#include <mayaUsd/ufe/UsdUndoAddNewPrimCommand.h>
Expand Down Expand Up @@ -573,7 +576,13 @@ Ufe::ContextOps::Items UsdContextOps::getItems(const Ufe::ContextOps::ItemPath&

// Top-level items (do not add for gateway type node):
if (!fIsAGatewayType) {
items.emplace_back(kEditAsMayaItem, kEditAsMayaLabel, kEditAsMayaImage);
#ifdef UFE_V3_FEATURES_AVAILABLE
if (PrimUpdaterManager::getInstance().canEditAsMaya(path())) {
#endif
items.emplace_back(kEditAsMayaItem, kEditAsMayaLabel, kEditAsMayaImage);
#ifdef UFE_V3_FEATURES_AVAILABLE
}
#endif
items.emplace_back(kDuplicateAsMayaItem, kDuplicateAsMayaLabel);
items.emplace_back(Ufe::ContextItem::kSeparator);

Expand Down
3 changes: 3 additions & 0 deletions lib/usd/translators/mayaReferenceUpdater.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ PxrUsdTranslators_MayaReferenceUpdater::PxrUsdTranslators_MayaReferenceUpdater(
{
}

/* virtual */
bool PxrUsdTranslators_MayaReferenceUpdater::canEditAsMaya() const { return true; }

/* virtual */
bool PxrUsdTranslators_MayaReferenceUpdater::pushCopySpecs(
UsdStageRefPtr srcStage,
Expand Down
5 changes: 5 additions & 0 deletions lib/usd/translators/mayaReferenceUpdater.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ class PxrUsdTranslators_MayaReferenceUpdater : public UsdMayaPrimUpdater
MAYAUSD_CORE_PUBLIC
bool discardEdits(const UsdMayaPrimUpdaterContext& context) override;

/// Query to determine if the prim corresponding to this updater can be
/// edited as Maya. The implementation in this class returns true.
MAYAUSD_CORE_PUBLIC
bool canEditAsMaya() const override;

protected:
MAYAUSD_CORE_PUBLIC
bool pushCopySpecs(
Expand Down
18 changes: 16 additions & 2 deletions plugin/adsk/scripts/USDMenuProc.mel
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,26 @@
// limitations under the License.
//

proc int canEditAsMaya(string $obj)
{
if (size($obj) == 0) {
string $nonMayaObjs[] = `python("import maya.internal.ufeSupport.utils as ufeUtils; ufeUtils.getNonMayaSelectedItems()")`;
$obj = $nonMayaObjs[0];
}
if (size($obj) != 0) {
return `python("from mayaUsd.lib import PrimUpdaterManager; PrimUpdaterManager.canEditAsMaya('" + $obj + "')")`;
}
return 0;
}

global proc mayaUsdMenu_pullToDG(string $obj)
{
if (size($obj) == 0) {
string $nonMayaObjs[] = `python("import maya.internal.ufeSupport.utils as ufeUtils; ufeUtils.getNonMayaSelectedItems()")`;
$obj = $nonMayaObjs[0];
}
if (size($obj) != 0) {
python("from mayaUsd.lib import PrimUpdaterManager; import ufe; PrimUpdaterManager.pull('" + $obj + "');");
python("from mayaUsd.lib import PrimUpdaterManager; import ufe; PrimUpdaterManager.editAsMaya('" + $obj + "');");
}
}

Expand All @@ -44,7 +56,9 @@ global proc USDMenuProc(string $parent, string $obj)
setParent -menu $parent;

setParent -menu ..;
menuItem -label "Edit As Maya Data" -image "edit_as_Maya.png" -command ("mayaUsdMenu_pullToDG \"" + $obj + "\"");
if (canEditAsMaya($obj)) {
menuItem -label "Edit As Maya Data" -image "edit_as_Maya.png" -command ("mayaUsdMenu_pullToDG \"" + $obj + "\"");
}
menuItem -label "Duplicate As Maya Data" -command ("mayaUsdMenu_duplicateToDG \"" + $obj + "\"");
}
}
2 changes: 1 addition & 1 deletion plugin/adsk/scripts/mayaUsdMenu.mel
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,7 @@ global proc mayaUsdMenu_pushBackToUSD(string $obj)
}
}
if (size($obj)) {
python("from mayaUsd.lib import PrimUpdaterManager; PrimUpdaterManager.push('" + $obj + "');");
python("from mayaUsd.lib import PrimUpdaterManager; PrimUpdaterManager.mergeToUsd('" + $obj + "');");
}
}

Expand Down
Loading