Skip to content

Batched export and merge to USD #4279

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

Open
wants to merge 14 commits into
base: dev
Choose a base branch
from

Conversation

jufrantz
Copy link
Contributor

@jufrantz jufrantz commented Jul 25, 2025

With this PR PrimUpdaterManager::mergeToUsd can now merge multiple pulled DAG paths to separate prims in a single invocation.

This is mostly interesting in the context of animated rigs, referenced with MayaReference prims.

The feature matches our previous Alembic "cache-and-swap" workflow that used AbcExport with multiple jobArgs flags, to export multiple rigs animation to separate files in one go.


Why it matters

Constraint‑safe

mergeToUsd removes the Maya data at end of the operation, swapping it to the USD data. For a MayaRefeference prim, the Maya reference gets unloaded.

In animation work, rigs are often connected to each others. Characters might be constrained to vehicles, props to characters, characters to characters, etc

Artists (and tools) must therefore cache the rig animations in an appropriate order (driven first then driver) so every constrained rig evaluates with their complete upstream graph, this can become a complex task. If the rig graph contains a cycle, which is possible at the rig-level, caching becomes impossible without another manual pre-baking.

With a "merge batch", all referenced rigs remain loaded until all USD data is authored, so the rigs remain connected to live Maya data during the whole evaluation. Artists can export the whole scene, or a group of related rigs, in one go. Order and cycles stop mattering.

Less waiting

Batching merge operations optimizes “Cache to USD” for animated rigs. In production, rig animation evaluation is the main cost of this caching. Currently, artists must export each referenced rig one‑by‑one; each export walks the same frame range again, making some rigs recompute identical results.

The new batched export walks the timeline once and shares evaluations across all rigs, eliminating this redundancy.

I tested performances with this scene four_animated_rhinos.ma and using this script test_merge_four_animated_rhinos.py. The scene is featuring 4 animated references to rhino_rig_001.ma, the rig file was found in maya-usd unit-tests.

4 sequential mergeToUsd Batched mergeToUsd Speed‑up
DG 56 s 35 s 1.8×
EM parallel 42 s 25 s 1.7×

Details

UsdMaya_WriteJobBatch

New class, a collection of UsdMaya_WriteJob, that will execute all jobs, each writing to a separate stage, and write the timeSamples in a single unioned Maya timeline pass. jufrantz@aacaf4d

UsdMaya_WriteJob

Destination file name and append flag are now supplied in the constructor, instead of the Write method. This is to ease implementation of UsdMaya_WriteJobBatch. If this is a concern, I could rework this change. jufrantz@5e32d35

Internal refactors

  • Shared write logic for both UsdMaya_WriteJob and UsdMaya_WriteJobBatch is centralized in a new private class UsdMaya_WriteJobImpl. jufrantz@aacaf4d
  • UsdMaya_WriteJob::_BeginWriting was adapting the maya scene forrenderLayerMode, upAxis, and unit options.
  • These tweaks need to remain for whole scene evaluation with multiple active (began) UsdMaya_WriteJob, so I refactored those aspects:
    • Maya scene tweaking is now done in UsdMaya_WriteJobBatch::WriteJobs and encloses multiple jobs evaluation.
    • USD authoring related to these options is still done by each UsdMaya_WriteJob.
    • cf jufrantz@5a06213, jufrantz@afb00e2

PrimUpdaterManager

  • Added a new PushToUsdArgs struct that bundles all inputs common to push‑style operations (mergeToUsd, duplicateToUsd). jufrantz@aaa06a7
  • PrimUpdaterManager::mergeToUsd now takes a std::vector<PushToUsdArgs>, so multiple DAGs can be exported in one call. jufrantz@3f68054
  • Added a mergeToUsd python overload taking a sequence of tuples giving the dagPath and associated options dict. jufrantz@80d417d.
mayaUsd.lib.PrimUpdaterManager.mergeToUsd([
    ("MayaReference1", {"rn_layer":"cache1.usd", "rn_primName":"Cache1"}), 
    ("MayaReference2", {"rn_layer":"cache2.usd", "rn_primName":"Cache2"})])
  • The original single‑object python signature remains for backward compatibility.
  • The mayaUsdMergeToUsd command is also extended. It can export multiple DAGs with their exportOptions. jufrantz@d857156.
cmds.mayaUsdMergeToUsd(
    "Xform1", "Xform2",
    exportOptions=["animation=1;startTime=1;endTime=5", "animation=1;startTime=1;endTime=10"])

Tests

Added unit tests for batched merge, custom rig updaters, MayaReference caching, undo/redo integrity.
jufrantz@0bbf955, jufrantz@a537f29

I did not

  • Add batched export support to the mayaUsdExport command. I imagine this could be added with a flag similar to AbcExport -jobArg / mayaUsdMergeToUsd -exportOptions, but I am unsure of the best syntax.
  • Implement a batched duplicateToUsd; though the same technique would work.
  • Expose the feature in UFE context menus (e.g., a multi‑selection “Cache To USD”). For now it’s meant mainly for studio pipeline tools.

I'd be happy to add any of these in a later PR if you think they are useful.

PS

This PR introduces a large set of changes, but I prefered to keep everything in one pull request to give you the full picture. However there are clearly 2 subsets of changes (UsdMaya_WriteJob + PrimUpdaterManager), I could split this PR in two if you prefer.

I've organized the changes into logical commits to make the review easier. Hope that helps.

Feedbacks are very welcome,
Julien

Julien Frantz added 14 commits July 24, 2025 16:09
Extracted USD stage metadata authoring from AutoUpAxisAndUnitsChanger to
UsdMaya_WriteJob::_Finalize.

AutoUpAxisAndUnitsChanger now only temporarily tweaks Maya scene within
the scope of _Write, it is not related anymore to a stage.

This change is needed for following changes to allow batching multiple
writeJobs, writing to multiple stages, in a single maya timeline run.
So that the maya scene tweaks needed for the export time are done and
restored at the Write method scope.

This change is needed for following changes to allow batching multiple
writeJobs, writing to multiple stages, in a single maya timeline run.
- _PostWrite that might fail.
- _FinishWriting is now assumed to always succeed.
This message does not seem useful with maya-usd coalesced diagnostics
and its removal simplifies upcoming changes enabling jobs batching.
…ovided at construction.

This simplifies upcoming changes enabling jobs batching.
…f jobs.

UsdMaya_WriteJobBatch:

The public API to queue multiple independent UsdMaya_WriteJobs, each
writing to a different output stage. It optimizes the export of multiple
USD stages from an animated Maya scene by reducing redundant evaluations
to a single timeline pass.

UsdMaya_WriteJobImpl:

Implements the writing logic shared by UsdMaya_WriteJob::Write() and
UsdMaya_WriteJobBatch::Write():
- Applies the temporary Maya scene tweaks needed for the export.
- Calls `_BeginWriting`, `_PostExport`, `_FinishWriting` for each job.
- Builds a sorted union of all jobs’ `timeSamples`, then for every
  frame in that union:
  - Advances Maya to the frame.
  - Advances each job’s sample iterator and writes or skips the frame
    as appropriate.

This keeps per-job code focused on writing USD data while ensuring we
it does not over-evaluate the Maya animation.
- Add class PushToUsdArgs, the arguments needed for push-like operations:
  the source and destination objects, UsdMayaPrimUpdaterArgs and userArgs
  dict. It has convenient factory methods that will mainly apply the
  userArgs overrides required for the wanted push operation.

- Added a mergeToUsd overload which takes a PushToUsdArgs.

- pushExport now takes a PushToUsdArgs, it does not need anymore a
  UsdMayaPrimUpdaterContext.

- Updated maya command and python bindings to use the new mergeToUsd
  overload, and the PushToUsdArgs factory method.

- These changes will help to implement a mergeToUsd method than can
  execute multiple objects merge operations.
… in single call.

- pushExport now takes a vector of PushToUsdArgs, it will export animation
  of all push operations in a single timeline pass thanx to
  UsdMaya_WriteJobBatch.

- mergeToUsd now takes a vector of PushToUsdArgs. This allows for
  multiple merge operations in a single call. It will:
  - validate all args and prepare for pushExport in a first phase.
  - Call pushExport once.
  - pushCustomise and perform other post pushExport process for all
    pushed items.

- Did not change the signature of duplicateToUsd to allow batched
  duplications, but it could also be added if needed.
… in a single call.

It accepts a sequence of tuple: the pulled dagPath name and the userArgs
dictionary for each object merge operation.
- testMergeToUsd.testBatchMergeToUsd: Tests basic batch merge
  functionality, and batch args validation.

- testCustomRig.py.testCustomRigUpdaterBatchMergeAnimToUsd: Tests batch
  merge with a custom updater. Also tests animation evaluation aspects.

- testCacheToUsd.testEditAndBatchMergeRigMayaRefs: Tests caching to USD
  a batch of MayaReference prims.
…le call.

The command now accepts multiple string object arguments, instead of a
single dagPath.

exportOptions flag is now multiUse. If any, there must be the same
number of exportOptions as dag objects.
@jufrantz jufrantz changed the title Batched export and merge to usd Batched export and merge to USD Jul 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant