Skip to content

Commit

Permalink
Added isDuplicating export arg
Browse files Browse the repository at this point in the history
  • Loading branch information
barbalt committed Sep 26, 2024
1 parent 7ba0b06 commit d8f42ab
Show file tree
Hide file tree
Showing 10 changed files with 83 additions and 9 deletions.
10 changes: 10 additions & 0 deletions lib/mayaUsd/fileio/chaser/exportChaser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,14 @@ bool UsdMayaExportChaser::PostExport()
return true;
}

void UsdMayaExportChaser::RegisterExtraPrimsPaths(const std::vector<SdfPath>& extraPrimPaths)
{
_extraPrimsPaths.insert(_extraPrimsPaths.end(), extraPrimPaths.begin(), extraPrimPaths.end());
}

const std::vector<SdfPath>& UsdMayaExportChaser::GetExtraPrimsPaths() const
{
return _extraPrimsPaths;
}

PXR_NAMESPACE_CLOSE_SCOPE
15 changes: 15 additions & 0 deletions lib/mayaUsd/fileio/chaser/exportChaser.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <pxr/base/tf/declarePtrs.h>
#include <pxr/base/tf/refPtr.h>
#include <pxr/pxr.h>
#include <pxr/usd/sdf/path.h>
#include <pxr/usd/usd/timeCode.h>

PXR_NAMESPACE_OPEN_SCOPE
Expand Down Expand Up @@ -69,6 +70,20 @@ class UsdMayaExportChaser : public TfRefBase
/// Returning false will terminate the whole export.
MAYAUSD_CORE_PUBLIC
virtual bool PostExport();

/// Optional helper method to cache the given path array in the chaser.
/// The cached array is used internally to track any extra prim created by the chasers.
/// For example: when duplicating Maya data to USD we'll internally ask the chaser for those.
MAYAUSD_CORE_PUBLIC
virtual void RegisterExtraPrimsPaths(const std::vector<SdfPath>& extraPrimPaths);

/// Get the array of extra prim paths set by the chaser.
/// Returns the array of cached prim paths.
MAYAUSD_CORE_PUBLIC
virtual const std::vector<SdfPath>& GetExtraPrimsPaths() const;

private:
std::vector<SdfPath> _extraPrimsPaths;
};

PXR_NAMESPACE_CLOSE_SCOPE
Expand Down
5 changes: 5 additions & 0 deletions lib/mayaUsd/fileio/jobs/jobArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,8 @@ UsdMayaJobExportArgs::UsdMayaJobExportArgs(
, ignoreWarnings(extractBoolean(userArgs, UsdMayaJobExportArgsTokens->ignoreWarnings))
, includeEmptyTransforms(
extractBoolean(userArgs, UsdMayaJobExportArgsTokens->includeEmptyTransforms))
, isDuplicating(
extractBoolean(userArgs, UsdMayaJobExportArgsTokens->isDuplicating))
, materialCollectionsPath(
extractAbsolutePath(userArgs, UsdMayaJobExportArgsTokens->materialCollectionsPath))
, materialsScopeName(_GetMaterialsScopeName(
Expand Down Expand Up @@ -840,6 +842,7 @@ std::ostream& operator<<(std::ostream& out, const UsdMayaJobExportArgs& exportAr
<< "file: " << exportArgs.file << std::endl
<< "ignoreWarnings: " << TfStringify(exportArgs.ignoreWarnings) << std::endl
<< "includeEmptyTransforms: " << TfStringify(exportArgs.includeEmptyTransforms)
<< "isDuplicating: " << TfStringify(exportArgs.isDuplicating)
<< std::endl;
out << "includeAPINames (" << exportArgs.includeAPINames.size() << ")" << std::endl;
for (const std::string& includeAPIName : exportArgs.includeAPINames) {
Expand Down Expand Up @@ -1124,6 +1127,7 @@ const VtDictionary& UsdMayaJobExportArgs::GetDefaultDictionary()
d[UsdMayaJobExportArgsTokens->filterTypes] = std::vector<VtValue>();
d[UsdMayaJobExportArgsTokens->ignoreWarnings] = false;
d[UsdMayaJobExportArgsTokens->includeEmptyTransforms] = true;
d[UsdMayaJobExportArgsTokens->isDuplicating] = false;
d[UsdMayaJobExportArgsTokens->kind] = std::string();
d[UsdMayaJobExportArgsTokens->disableModelKindProcessor] = false;
d[UsdMayaJobExportArgsTokens->materialCollectionsPath] = std::string();
Expand Down Expand Up @@ -1228,6 +1232,7 @@ const VtDictionary& UsdMayaJobExportArgs::GetGuideDictionary()
d[UsdMayaJobExportArgsTokens->filterTypes] = _stringVector;
d[UsdMayaJobExportArgsTokens->ignoreWarnings] = _boolean;
d[UsdMayaJobExportArgsTokens->includeEmptyTransforms] = _boolean;
d[UsdMayaJobExportArgsTokens->isDuplicating] = _boolean;
d[UsdMayaJobExportArgsTokens->kind] = _string;
d[UsdMayaJobExportArgsTokens->disableModelKindProcessor] = _boolean;
d[UsdMayaJobExportArgsTokens->materialCollectionsPath] = _string;
Expand Down
2 changes: 2 additions & 0 deletions lib/mayaUsd/fileio/jobs/jobArgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ TF_DECLARE_PUBLIC_TOKENS(
(filterTypes) \
(ignoreWarnings) \
(includeEmptyTransforms) \
(isDuplicating) \
(kind) \
(disableModelKindProcessor) \
(materialCollectionsPath) \
Expand Down Expand Up @@ -232,6 +233,7 @@ struct UsdMayaJobExportArgs
const std::string file;
const bool ignoreWarnings;
const bool includeEmptyTransforms;
const bool isDuplicating;

/// If this is not empty, then a set of collections are exported on the
/// prim pointed to by the path, each representing the collection of
Expand Down
7 changes: 7 additions & 0 deletions lib/mayaUsd/fileio/jobs/writeJob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -634,12 +634,19 @@ bool UsdMaya_WriteJob::_FinishWriting()
primWriterLoop.loopAdvance();
}

_extrasPrimsPaths.clear();

// Run post export function on the chasers.
MayaUsd::ProgressBarLoopScope chasersLoop(mChasers.size());
for (const UsdMayaExportChaserRefPtr& chaser : mChasers) {
if (!chaser->PostExport()) {
return false;
}

// Collect extra prims paths from chasers
for (const SdfPath& path : chaser->GetExtraPrimsPaths()) {
_extrasPrimsPaths.emplace_back(path);
}
chasersLoop.loopAdvance();
}

Expand Down
7 changes: 7 additions & 0 deletions lib/mayaUsd/fileio/jobs/writeJob.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ class UsdMaya_WriteJob
MAYAUSD_CORE_PUBLIC
const std::vector<SdfPath>& GetMaterialPaths() { return mJobCtx.GetMaterialPaths(); }

// Cached prims paths from chasers
MAYAUSD_CORE_PUBLIC
const std::vector<SdfPath>& GetExtraPrimsPaths() { return _extrasPrimsPaths; }

private:
/// Begins constructing the USD stage, writing out the values at the default
/// time. Returns \c true if the stage can be created successfully.
Expand Down Expand Up @@ -102,6 +106,9 @@ class UsdMaya_WriteJob

UsdMayaUtil::MDagPathMap<SdfPath> mDagPathToUsdPathMap;

// Array to track any extra prims created chasers
std::vector<SdfPath> _extrasPrimsPaths;

// Currently only used if stripNamespaces is on, to ensure we don't have clashes
TfHashMap<SdfPath, MDagPath, SdfPath::Hash> mUsdPathToDagPathMap;

Expand Down
11 changes: 8 additions & 3 deletions lib/mayaUsd/fileio/primUpdaterManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,7 @@ struct PushExportResult
SdfLayerRefPtr layer;
std::shared_ptr<UsdPathToDagPathMap> usdToDag;
std::vector<SdfPath> materialPaths;
std::vector<SdfPath> extraPrimsPaths;
};

PushExportResult pushExport(const MObject& mayaObject, const UsdMayaPrimUpdaterContext& context)
Expand Down Expand Up @@ -585,6 +586,7 @@ PushExportResult pushExport(const MObject& mayaObject, const UsdMayaPrimUpdaterC
if (!writeJob.Write(fileName, false /* append */)) {
return result;
}
result.extraPrimsPaths = writeJob.GetExtraPrimsPaths();
progressBar.advance();

result.srcRootPath = writeJob.MapDagPathToSdfPath(dagPath);
Expand Down Expand Up @@ -1661,6 +1663,7 @@ std::vector<Ufe::Path> PrimUpdaterManager::duplicateToUsd(
// Setting the export-selected flag will allow filtering materials so that
// only materials in the prim selected to be copied will be included.
ctxArgs[UsdMayaJobExportArgsTokens->exportSelected] = true;
ctxArgs[UsdMayaJobExportArgsTokens->isDuplicating] = true;

const UsdStageRefPtr dstStage = dstProxyShape->getUsdStage();
const SdfLayerHandle& layer = dstStage->GetEditTarget().GetLayer();
Expand Down Expand Up @@ -1713,9 +1716,11 @@ std::vector<Ufe::Path> PrimUpdaterManager::duplicateToUsd(
options.mergeScopes = true;

std::vector<SdfPath> primsToCopy = { pushExportResult.srcRootPath };
for (const auto& prim : srcStage->Traverse()) {
primsToCopy.push_back(prim.GetPath());
}
primsToCopy.reserve(primsToCopy.size() + pushExportResult.extraPrimsPaths.size());
primsToCopy.insert(
primsToCopy.end(),
pushExportResult.extraPrimsPaths.begin(),
pushExportResult.extraPrimsPaths.end());

CopyLayerPrimsResult copyResult = copyLayerPrims(
srcStage, srcLayer, srcParentPath, dstStage, dstLayer, dstParentPath, primsToCopy, options);
Expand Down
10 changes: 10 additions & 0 deletions lib/mayaUsd/python/wrapExportChaser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,16 @@ void wrapExportChaser()
.def("ExportDefault", &This::ExportDefault, &ExportChaserWrapper::default_ExportDefault)
.def("ExportFrame", &This::ExportFrame, &ExportChaserWrapper::default_ExportFrame)
.def("PostExport", &This::PostExport, &ExportChaserWrapper::default_PostExport)
.def(
"RegisterExtraPrimsPaths",
&This::RegisterExtraPrimsPaths,
boost::python::arg("extraPrimPaths"),
"Method to cache the path for any extra prim path created by the chaser.")
.def(
"GetExtraPrimsPaths",
&This::GetExtraPrimsPaths,
boost::python::return_internal_reference<>(),
"Get the array of the currently cached extra paths.")
.def("Register", &ExportChaserWrapper::Register)
.staticmethod("Register")
.def("Unregister", &ExportChaserWrapper::Unregister)
Expand Down
1 change: 1 addition & 0 deletions lib/mayaUsd/python/wrapPrimWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,7 @@ void wrapJobExportArgs()
&UsdMayaJobExportArgs::geomSidedness, return_value_policy<return_by_value>()))
.def_readonly("ignoreWarnings", &UsdMayaJobExportArgs::ignoreWarnings)
.def_readonly("includeEmptyTransforms", &UsdMayaJobExportArgs::includeEmptyTransforms)
.def_readonly("isDuplicating", &UsdMayaJobExportArgs::isDuplicating)
.add_property(
"includeAPINames",
make_getter(
Expand Down
24 changes: 18 additions & 6 deletions test/lib/mayaUsd/fileio/testExportChaserJobContext.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import fixturesUtils, os
import mayaUsd_createStageWithNewLayer
import mayaUsdDuplicateAsUsdDataOptions
import mayaUsdOptions

import unittest

Expand All @@ -50,16 +49,25 @@ class ChaserExample1(mayaUsd.lib.ExportChaser):
seenChasers = None
seenChaserArgs = None

isDuplicating = False

def __init__(self, factoryContext, *args, **kwargs):
super(ChaserExample1, self).__init__(factoryContext, *args, **kwargs)
jobArgs = factoryContext.GetJobArgs()
self.stage = factoryContext.GetStage()
self.isDuplicating = factoryContext.GetJobArgs().isDuplicating
ChaserExample1.seenChasers = jobArgs.chaserNames
if ChaserExample1.name in jobArgs.allChaserArgs:
ChaserExample1.seenChaserArgs = jobArgs.allChaserArgs[ChaserExample1.name]

def ExportDefault(self):
ChaserExample1.exportDefaultCalled = True

if self.isDuplicating:
# creating an extra prim to be tested on Duplicate As
scope = self.stage.DefinePrim("/TestExportDefault", "Scope")
self.RegisterExtraPrimsPaths([scope.GetPath()])

return self.ExportFrame(Usd.TimeCode.Default())

def ExportFrame(self, frame):
Expand All @@ -69,8 +77,10 @@ def ExportFrame(self, frame):
def PostExport(self):
ChaserExample1.postExportCalled = True

# creating an extra prim to be tested on Duplicate As
scope = self.stage.DefinePrim("/TestScope", "Scope")
if self.isDuplicating:
# creating an extra prim to be tested on Duplicate As
scope = self.stage.DefinePrim("/TestPostExport", "Scope")
self.RegisterExtraPrimsPaths([scope.GetPath()])

return True

Expand Down Expand Up @@ -259,13 +269,15 @@ def testChaserWithDuplicateAsUsd(self):
modifiedDuplicateAsUsdDataOptions = defaultDuplicateAsUsdDataOptions + ";jobContext=[JobContextExample1]"
cmds.mayaUsdDuplicate(cmds.ls(sphere, long=True)[0], psPathStr, exportOptions=modifiedDuplicateAsUsdDataOptions)

# check if the extra prim has also been duplicated
# Check if the extra prims have also been duplicated
stage = mayaUsd.lib.GetPrim(psPathStr).GetStage()
spherePrim = stage.GetPrimAtPath("/TestSphere")
scopePrim = stage.GetPrimAtPath("/TestScope")
scopeExportPrim = stage.GetPrimAtPath("/TestExportDefault")
scopePostPrim = stage.GetPrimAtPath("/TestPostExport")

self.assertTrue(spherePrim.IsValid())
self.assertTrue(scopePrim.IsValid())
self.assertTrue(scopeExportPrim.IsValid())
self.assertTrue(scopePostPrim.IsValid())

if __name__ == '__main__':
unittest.main(verbosity=2)

0 comments on commit d8f42ab

Please sign in to comment.