# Callbacks

# USD Writer Callbacks

When exporting to a USD file, we can have MfM optionally call custom python code over the generated USD file. This allows for custom pipeline steps that can be tailed by each client. Examples can be:

  • Clean-up "reference" prims - delete from final file any prims that were originally used as a guide for modelling without needing to place them in separate hierarchies.

  • Notify some back end that a specific asset has been written - this can be a database, a Slack notification, etc.

Within this script, the full functionality of the USD Python API can be used, as well as all standard Python. Processing can be done directly on the USD, on the filepath of where the file is written, or environment variables.

Callback scripts are specified to be executed via the API write commands:

import multiverse as mv
opts = mv.AssetWriteOptions()
opts.customPostCallback = '~/CustomCallback.py'
mv.WriteAsset('~/assets00.usda', ['assetGroup'], opts)
1
2
3
4

# Clean-up by name

Given the following Maya scene, we want to keep assetGroup/Hero, but remove the assetGroup/_ReferenceHero and assetGroup/TEMP_Mesh:

The following script "cleans up" the exported USD file according to some regex pattern matching. This script will live somewhere in your pipeline's path, call it ~/CleanupByName.py.

Note

Note the usage of the namespaced Multiverse mvpxr Python module (instead of the USD default pxr one). This ensures a level of protection in case other Maya plugins that link with different versions of the USD libraries are concurrently loaded in Maya.

import sys
import mvpxr
import re

PRIM_TRIM_MATCH = ['^_Reference', '^TEMP']


def CollectTrimPrims(stage):
    trimPrims = []
    for prim in stage.Traverse():
        primName = prim.GetName()
        for pattern in PRIM_TRIM_MATCH:
            if re.search(pattern, primName):
                trimPrims.append(prim)
    return trimPrims


def main(filePath):
    stage = mvpxr.Usd.Stage.Open(filePath)
    primsToTrim = CollectTrimPrims(stage)
    for prim in primsToTrim:
        if prim.IsValid():
            print('Removing', prim)
            stage.RemovePrim(prim.GetPath())
    stage.GetRootLayer().Save()
    stage.Unload()


if __name__ == '__main__':
    filePath = sys.argv[sys.argv.index('--filePath')+1]
    main(filePath)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

The resulting USD will contain the Hero prim, but not the _Reference* or the TEMP*.

# Adding Scene & Shot Information

If you automatically want to add any properties to any specific prim based on the filepath, the following script can be used as a starting point. It assumes that as part of your final filepath, you have the words sceneXX and shotYY, where XX and YY are the scene and shot numbers, eg: /projects/ultra/scene31/shot42/asset77.usda.

import sys
import mvpxr
import re


def GetPart(pattern, text):
    match = re.findall(pattern, text)
    if match:
        return match[0]


def GetSceneShot(filePath):
    scene = GetPart(r'(scene\d+)', filePath)
    shot = GetPart(r'(shot\d+)', filePath)
    return scene, shot


def main(filePath):
    scene, shot = GetSceneShot(filePath)
    if scene and shot:
        stage = mvpxr.Usd.Stage.Open(filePath)
        prim = stage.GetDefaultPrim()
        prim.CreateAttribute('scene', Sdf.ValueTypeNames.String).Set(scene)
        prim.CreateAttribute('shot', Sdf.ValueTypeNames.String).Set(shot)
        stage.GetRootLayer().Save()
        stage.Unload()


if __name__ == '__main__':
    filePath = sys.argv[sys.argv.index('--filePath')+1]
    main(filePath)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

The resulting USD file will have properties scene31 and shot42 added to the default prim.

Last Updated: 3/24/2023, 8:55:22 AM