Skip to content

Commit

Permalink
Merge pull request #3495 from Autodesk/bailp/EMSUSD-788/relative-cach…
Browse files Browse the repository at this point in the history
…e-usd

EMSUSD-788 support relative cache to USD in anon layers
  • Loading branch information
seando-adsk authored Dec 7, 2023
2 parents fe7868c + 55b6218 commit 8574f82
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 9 deletions.
6 changes: 6 additions & 0 deletions lib/mayaUsd/python/wrapUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ std::string ensureUSDFileExtension(const std::string& fileToCheck)
return ret;
}

void updatePostponedPaths(const PXR_NS::SdfLayerHandle& layer)
{
UsdMayaUtilFileSystem::updatePostponedRelativePaths(layer);
}

} // namespace

void wrapUtil()
Expand All @@ -69,6 +74,7 @@ void wrapUtil()
.def(
"handleAssetPathThatMaybeRelativeToLayer",
UsdMayaUtilFileSystem::handleAssetPathThatMaybeRelativeToLayer)
.def("updatePostponedRelativePaths", updatePostponedPaths)
.def("ensureUSDFileExtension", ensureUSDFileExtension)
.staticmethod("getPathRelativeToMayaSceneFile");
}
23 changes: 15 additions & 8 deletions lib/mayaUsd/utils/mayaEditRouter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,15 +168,22 @@ void cacheMayaReference(const PXR_NS::VtDictionary& context, PXR_NS::VtDictionar
std::string relDistLayerPath = dstLayerPath;
if (makePathRelative) {
const std::string layerDirPath = MayaUsd::getTargetLayerFolder(stage);
const auto relativePathAndSuccess
= PXR_NS::UsdMayaUtilFileSystem::makePathRelativeTo(dstLayerPath, layerDirPath);
if (relativePathAndSuccess.second) {
relDistLayerPath = relativePathAndSuccess.first;
if (layerDirPath.empty()) {
// Making the path relative is postponed until the containing layer is saved.
auto layer = getCurrentTargetLayer(stage);
UsdMayaUtilFileSystem::markPathAsPostponedRelative(layer, dstLayerPath);
} else {
TF_WARN(
"File name (%s) cannot be resolved as relative to the current edit target layer, "
"using the absolute path.",
dstLayerPath.c_str());
const auto relativePathAndSuccess
= PXR_NS::UsdMayaUtilFileSystem::makePathRelativeTo(dstLayerPath, layerDirPath);
if (relativePathAndSuccess.second) {
relDistLayerPath = relativePathAndSuccess.first;
} else {
TF_WARN(
"File name (%s) cannot be resolved as relative to the current edit target "
"layer, "
"using the absolute path.",
dstLayerPath.c_str());
}
}
}

Expand Down
8 changes: 8 additions & 0 deletions lib/mayaUsd/utils/utilFileSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,14 @@ void updatePostponedRelativePathsForPrim(
}
}

void UsdMayaUtilFileSystem::updatePostponedRelativePaths(const PXR_NS::SdfLayerHandle& layer)
{
if (!layer)
return;

updatePostponedRelativePaths(layer, layer->GetRealPath());
}

void UsdMayaUtilFileSystem::updatePostponedRelativePaths(
const PXR_NS::SdfLayerHandle& layer,
const std::string& layerFileName)
Expand Down
5 changes: 5 additions & 0 deletions lib/mayaUsd/utils/utilFileSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,11 @@ void updatePostponedRelativePaths(
const PXR_NS::SdfLayerHandle& layer,
const std::string& layerFileName);

/*! \brief Turns the file paths marked through the call 'markPathAsPostponedRelative' to relative.
*/
MAYAUSD_CORE_PUBLIC
void updatePostponedRelativePaths(const PXR_NS::SdfLayerHandle& layer);

/*! \brief returns the flag specifying whether USD file paths should be saved as relative to Maya
* scene file
*/
Expand Down
22 changes: 21 additions & 1 deletion test/lib/mayaUsd/fileio/testCacheToUsd.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,13 @@ def setUp(self):
import mayaUsd_createStageWithNewLayer
self.proxyShapePathStr = mayaUsd_createStageWithNewLayer.createStageWithNewLayer()
self.stage = mayaUsd.lib.GetPrim(self.proxyShapePathStr).GetStage()
self.stage.GetRootLayer().identifier = self.getRootLayerFileName()

def tearDown(self):
self.removeCacheFile()

def makeRootLayerNotAnonymous(self):
self.stage.GetRootLayer().identifier = self.getRootLayerFileName()

def verifyCacheFileDefaultPrim(self, cacheFilename, defaultPrimName):
layer = Sdf.Layer.FindOrOpen(cacheFilename)
self.assertIsNotNone(layer)
Expand Down Expand Up @@ -309,27 +311,41 @@ def runTestCacheToUsd(self, createMayaRefPrimFn, checkCacheParentFn):
# - Due to the way layer caching works in OpenUSD, asking for
# the layer identifier returns the absolute path.
if relativePath:
if self.stage.GetRootLayer().anonymous:
self.assertNotIn('payload = @testCacheToUsd.usda', self.stage.GetRootLayer().ExportToString())
self.assertRegexpMatches(self.stage.GetRootLayer().ExportToString(), 'payload = @.*testCacheToUsd.usda')
self.makeRootLayerNotAnonymous()
mayaUsd.lib.Util.updatePostponedRelativePaths(self.stage.GetRootLayer())

self.assertIn('payload = @testCacheToUsd.usda', self.stage.GetRootLayer().ExportToString())

self.verifyCacheFileDefaultPrim(cacheFile, cachePrimName)

def testCacheToUsdSibling(self):
self.makeRootLayerNotAnonymous()
self.runTestCacheToUsd(createMayaRefPrimSiblingCache, checkSiblingCacheParent)

def testCacheToUsdSiblingWithRelativePath(self):
self.makeRootLayerNotAnonymous()
self.runTestCacheToUsd(createMayaRefPrimSiblingCacheWithRelativePath, checkSiblingCacheParent)

def testCacheToUsdVariant(self):
self.makeRootLayerNotAnonymous()
self.runTestCacheToUsd(createMayaRefPrimVariantCache, checkVariantCacheParent)

def testCacheToUsdVariantWithRelativePath(self):
self.makeRootLayerNotAnonymous()
self.runTestCacheToUsd(createMayaRefPrimVariantCacheWithRelativePath, checkVariantCacheParent)

def testCacheToUsdVariantWithRelativePathInAnonLayer(self):
self.runTestCacheToUsd(createMayaRefPrimVariantCacheWithRelativePath, checkVariantCacheParent)

def testAutoEditAndCache(self):
'''Test editing then caching a Maya Reference.
Add a Maya Reference using auto-edit, then cache the edits.
'''
self.makeRootLayerNotAnonymous()
kDefaultPrimName = mayaRefUtils.defaultMayaReferencePrimName()

# Since this is a brand new prim, it should not have variant sets.
Expand Down Expand Up @@ -392,6 +408,7 @@ def testEditAndMergeRigMayaRef(self):
In particular, the rig generates multiple translation xform on some
prim, verify that we do get these multiple translations.
'''
self.makeRootLayerNotAnonymous()
kDefaultPrimName = mayaRefUtils.defaultMayaReferencePrimName()

# Since this is a brand new prim, it should not have variant sets.
Expand Down Expand Up @@ -484,6 +501,7 @@ def runTestMayaRefPrimTransform(self, createMayaRefPrimFn, checkCacheParentFn):

# Create a Maya reference prim using the defaults, under a
# newly-created parent.
self.makeRootLayerNotAnonymous()
cacheParent = self.stage.DefinePrim('/CacheParent', 'Xform')
cacheParentPathStr = self.proxyShapePathStr + ',/CacheParent'
self.assertFalse(cacheParent.HasVariantSets())
Expand Down Expand Up @@ -578,10 +596,12 @@ def runTestMayaRefPrimTransform(self, createMayaRefPrimFn, checkCacheParentFn):

def testMayaRefPrimTransform(self):
'''Test transforming the Maya Reference prim, editing it in Maya, then merging back the result.'''
self.makeRootLayerNotAnonymous()
self.runTestMayaRefPrimTransform(createMayaRefPrimSiblingCache, checkSiblingCacheParent)

def testMayaRefPrimTransformToVariant(self):
'''Test transforming the Maya Reference prim, editing it in Maya, then merging back the result.'''
self.makeRootLayerNotAnonymous()
self.runTestMayaRefPrimTransform(createMayaRefPrimVariantCache, checkVariantCacheParent)

if __name__ == '__main__':
Expand Down

0 comments on commit 8574f82

Please sign in to comment.