Skip to content

Commit

Permalink
Merge pull request #2377 from Autodesk/t_bailp/MAYA-122926/reset-flag…
Browse files Browse the repository at this point in the history
…-in-all-variants

MAYA-122926 reset auto-edit in all variants
  • Loading branch information
seando-adsk authored May 25, 2022
2 parents eaf89e2 + dbeae8b commit 8d0a425
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 12 deletions.
2 changes: 2 additions & 0 deletions lib/mayaUsd/utils/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ target_sources(${PROJECT_NAME}
util.cpp
utilFileSystem.cpp
utilSerialization.cpp
variants.cpp
)

set(HEADERS
Expand All @@ -43,6 +44,7 @@ set(HEADERS
util.h
utilFileSystem.h
utilSerialization.h
variants.h
)

set(PLUGINFO
Expand Down
62 changes: 62 additions & 0 deletions lib/mayaUsd/utils/variants.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
//
// Copyright 2022 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.
//
#include "variants.h"

#include <pxr/usd/usd/stage.h>

/// General utility functions for variants
namespace MAYAUSD_NS_DEF {

void applyToAllVariants(
const PXR_NS::UsdPrim& primWithVariants,
bool includeNonVariant,
const std::function<void()>& func)
{
// Record if we saw at least one variant to apply the function on.
// Used when non-variant are included.
bool atLeastOneVariant = false;

// Clear the edit flag in all other variants, in all variant sets if any.
PXR_NS::UsdStagePtr stage = primWithVariants.GetStage();
PXR_NS::UsdVariantSets variantSets = primWithVariants.GetVariantSets();
for (const std::string& variantSetName : variantSets.GetNames()) {

PXR_NS::UsdVariantSet variantSet = primWithVariants.GetVariantSet(variantSetName);

// Make sure to restore the current selected variant even if the face
// of exceptions.
AutoVariantRestore variantRestore(variantSet);

for (const std::string& variantName : variantSet.GetVariantNames()) {
if (variantSet.SetVariantSelection(variantName)) {
PXR_NS::UsdEditTarget target = stage->GetEditTarget();

PXR_NS::UsdEditContext switchEditContext(
stage, variantSet.GetVariantEditTarget(target.GetLayer()));

func();
atLeastOneVariant = true;
}
}
}

// When not a single variant was found and the caller wants to apply
// the function even in the absence of vairants, call it now.
if (includeNonVariant && !atLeastOneVariant)
func();
}

} // namespace MAYAUSD_NS_DEF
75 changes: 75 additions & 0 deletions lib/mayaUsd/utils/variants.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
//
// Copyright 2022 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.
//
#ifndef MAYAUSD_UTILS_VARIANTS_H
#define MAYAUSD_UTILS_VARIANTS_H

#include <mayaUsd/base/api.h>

#include <pxr/usd/usd/editContext.h>
#include <pxr/usd/usd/prim.h>
#include <pxr/usd/usd/variantSets.h>

#include <functional>
#include <string>

/// General utility functions for variants
namespace MAYAUSD_NS_DEF {

/*! \brief Apply a function to all variants on a prim.
Optionally, if includeNonVariant is true, apply it even if the prim
has no variant at all, which is useful when you want to edit something
on all variations of a prim, even if there are no variations.
*/
MAYAUSD_CORE_PUBLIC
void applyToAllVariants(
const PXR_NS::UsdPrim& primWithVariants,
bool includeNonVariant,
const std::function<void()>& func);

/*! \brief Keep track of the current variant and restore it on destruction.
The reason we don't make this an variant auto-switcher is that
switching variant recomposes the stage and one main user of the
restore is visiting all variants, which would double the number
of recompose if we restored the variant between each visit.
IOW, for a set with three variants A, B, C, this design permits
the switch Current -> A -> B -> C -> Current instead of doing
Current -> A -> Current -> B -> Current -> C -> Current.
*/

class AutoVariantRestore
{
public:
MAYAUSD_CORE_PUBLIC
AutoVariantRestore(PXR_NS::UsdVariantSet& variantSet)
: _variantSet(variantSet)
, _variant(variantSet.GetVariantSelection())
{
}

MAYAUSD_CORE_PUBLIC
~AutoVariantRestore() { _variantSet.SetVariantSelection(_variant); }

private:
PXR_NS::UsdVariantSet& _variantSet;
std::string _variant;
};

} // namespace MAYAUSD_NS_DEF

#endif // MAYAUSD_UTILS_VARIANTS_H
24 changes: 12 additions & 12 deletions lib/usd/translators/mayaReferenceUpdater.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <mayaUsd/utils/editRouter.h>
#include <mayaUsd/utils/util.h>
#include <mayaUsd/utils/utilSerialization.h>
#include <mayaUsd/utils/variants.h>
#include <mayaUsdUtils/MergePrims.h>
#include <mayaUsd_Schemas/ALMayaReference.h>
#include <mayaUsd_Schemas/MayaReference.h>
Expand All @@ -48,14 +49,21 @@

namespace {

// Clear the auto-edit flag on a USD Maya Reference so that it does not
// get edited immediately again. Clear in all variants, since each
// variant has its own copy of the flag.
void clearAutoEdit(const UsdPrim& prim)
{
if (prim.IsValid()) {
UsdPrim parentPrim = prim.GetParent();
MAYAUSD_NS::applyToAllVariants(parentPrim, true, [prim]() {
// Note: the prim might not exist in all variants, so check its validity.
if (!prim.IsValid())
return;

UsdAttribute mayaAutoEditAttr = prim.GetAttribute(MayaUsd_SchemasTokens->mayaAutoEdit);
if (mayaAutoEditAttr.IsValid()) {
if (mayaAutoEditAttr.IsValid())
mayaAutoEditAttr.Set<bool>(false);
}
}
});
}

std::string findValue(const PXR_NS::VtDictionary& routingData, const PXR_NS::TfToken& key)
Expand Down Expand Up @@ -214,9 +222,6 @@ UsdMayaPrimUpdater::PushCopySpecs PxrUsdTranslators_MayaReferenceUpdater::pushCo

// The Maya reference is meant as a cache, and therefore fully
// overwritten, so we don't call MayaUsdUtils::mergePrims().
// As of 13-Dec-2021 pushEnd() will not be called on the
// MayaReferenceUpdater, because the prim updater type information
// is not correctly preserved. Unload the reference here. PPT.
if (SdfCopySpec(srcLayer, srcSdfPath, dstLayer, dstPath)) {
const MObject& parentNode = getMayaObject();
UsdMayaTranslatorMayaReference::UnloadMayaReference(parentNode);
Expand Down Expand Up @@ -256,11 +261,6 @@ bool PxrUsdTranslators_MayaReferenceUpdater::discardEdits()
/* virtual */
bool PxrUsdTranslators_MayaReferenceUpdater::pushEnd()
{
// As of 25-Feb-2022 the Maya transform node pulled from the Maya reference
// prim ends up being unlocked by the unlock traversal in
// PrimUpdaterManager::mergeToUsd(). However, more robust to enforce
// separation of concerns and perform the inverse of editAsMaya() here.

// Unnecessary to unlock individual attributes, as the Maya transform node
// is removed at pushEnd().
MDagPath transformPath;
Expand Down

0 comments on commit 8d0a425

Please sign in to comment.