Maya native usd plugin

any plans to add usd create option in maya, Being able to write out simple usd binary files using the mayaUSDExport could be very handy.

It’s definitely something that’ll come and get added. I’d be happy to implement a draft if I have some time.

To understand your goals/needs:

  1. What version of Maya are you using?
  2. What export flags are important to you? Like how are you using the export feature currently?
  3. Are you also loading them in maya, if so - how are you using it currently?
  4. Any remarks or special things you might need this to support?

At the moment roughly. Exporting manually usd binaries from maya2024 for then to use the tray publisher to get them into ayon.
Then using the pixar api or maya(bifrost or usd layer editor) to collect usd’s into assembly.usda file. defining purpose attributes and reference paths(payload,reference). Again using the tray publisher to get them into ayon db
here is example for animation export, pay attention to the -parentScope flag:

mayaUSDExport -v -shadingMode none -convertMaterialsTo none -eulerFilter on -exportUVs on  -stripNamespaces on -exportComponentTags on -defaultMeshScheme catmullClark -worldspace on -exportInstances on -exportVisibility on -mergeTransformAndShape on -parentScope cat_main_model -staticSingleSample off -frameRange 1001 1250 -frameStride 1 -frameSample 0.0 -exportRoots "cat_main_01:cat_main_modelRender_01:render" -file "/path/seq001_0020_cat_main_01_v001.usd";

and here the camera:

mayaUSDExport -v -shadingMode none -convertMaterialsTo none -eulerFilter on -stripNamespaces on -exportComponentTags on -worldspace on -exportVisibility on -mergeTransformAndShape on -staticSingleSample off -frameRange 1000 1251 -frameStride 1 -frameSample 0.0 -exportRoots "camera_GRP" -file "/job/pipetest/pet3/film/ep101/seq001/seq001_0020/publish/camera/cameraRender/v006/seq001_0020_cameraRender_v006.usd";

For a asset or subAsset the api is then writing a usda publish in this format:

#usda 1.0
(
    defaultPrim = "walls_main_model"
)

def Scope "walls_main_model" (
    kind = "group"
)
{
    def Scope "render" (
        kind = "component"
        prepend payload = @/somepath/walls/walls_main/publish/model/modelRender/v002/walls_main_modelRender_v002.usd@</render>
    )
    {
        uniform token purpose = "render"
    }

    def Scope "proxy" (
        kind = "component"
        prepend references = @/somepath/walls/walls_main/publish/model/modelProxy/v002/walls_main_modelProxy_v002.usd@</proxy>
    )
    {
        uniform token purpose = "proxy"
    }

    def Scope "guide" (
        kind = "component"
        prepend references = @/somepath/walls/walls_main/publish/model/modelGuide/v002/walls_main_modelGuide_v002.usd@</guide>
    )
    {
        uniform token purpose = "guide"
    }
}

multiple subAssets are then collected into top asset with variants if need to be.
Hope this helps :slight_smile:
Thanks
R

1 Like

Is this logic you currently have automated and publicly/readily available to share? Or something you wish to have at the end. It sounds quite familiar to some logic that was in place for Houdini USD in an earlier prototype I’ve produced (which I’m not sure is still available in that state in OpenPype).

Anyway, thanks for the input!


@milan @antirotor are you able to provide some details what part of that request might already be in development with regards to the Asset Resolver? I suspect there’s little overlap?

A code design question regarding this @milan @tokestuartjepsen @iLLiCiT - in Maya we currently have the Multiverse USD support that uses the usd family to extract multiverse content with its multiverse settings, etc.

However, the maya native USD has different settings of course so it’d be a different creator. I prototyped it here, gave it usd family as well but of course now Multiverse USD validators + extractors trigger because they run over usd family.

What’s the idea to support both - should we have a maya-usd family and multiverse-usd family (exact naming to be determined) and then solely make sure the integrated representation gets the usd family for both? That way the publishing can be configured for maya-usd one and multiverse-usd one without conflicts, but still result in a regular usd family output?

Soo let’s open up this can of worms :slight_smile:

I’ll try to answer various parts, but let’s focus on the product type / representations question first.

I have quite a strong belief that we should do our best to work with USD on the representation level as much as possible. That being said USD family should almost act as a catchall with not much (or none at all) validation so it mimics how we work with mayaScene, HDA or blenderScene it’s a backup solution when nothing more specific is iimplemented for a give product type I’m publishing.

For instance model should just have USD representation, but from pipeline perspective still be Model Product. Same for Layout and a bunch of others.

Regarding the validators, we can actually make them more specific. The final product type can be usd, but the multiverse validators should really only trigger on instances that also have multiverse family, so we could be cleaner in that distinction.

resulting data is just USD, validators check how it’s produced in a give context

Edit: just to simplify… technically exactly what you’re proposing. Sorry had to read it again

1 Like

So, say for the “animation” instance it auto-generates a USD output. Currently I believe it also triggers the Multiverse export if the instance has both animation and usd family. But we might want to configure pipelines so that we can produce both Multiverse + Maya native USD exports too.

Code design wise in OpenPype - how should I be changing things to allow choosing of publishing Maya USD exports or Multiverse USD exports.

Yup, the resulting Product Type would be usd

I think I’m asking more about how we should now structure the publish families to be used sensibly - to define which current exporter technique to use to generate the product (and also what settings should show in the publisher?)
Any pointers?

Feel like simply making multiple creators that generate publishing instances with families: ["usd", "usd-maya"] or ["usd", "usd-multiverse"].

That should give differentiation for the rest of the publishing and should also be able to provide any publisher option that are common vs separate

Thanks - and looking at other current existing families that’d likely be usdMaya and usdMultiverse correct?

@iLLiCiT Is there any simple built-in/native system to the new style Creators as to how a Creator could say: I’m usdMultiverse family but also always give publish instances the usd family? It’s quite a similar question to how this recently got tweaked for Pointcaches in Houdini where a pointcache turned to be either bgeo or abc but also remain pointcache family. As in, how should a Creator define the instance as families ["usd", "usdMaya"] so that available settings for the instance also are correctly read for all its families.

No, there is not. Other question is if should be. What is the advantage? Is it required for publish attributes to show? If not then it doesn’t worth it, and there should be a dedicated collector for the creator that adds tha family for publishing.

As far as I know family class atteibute is an one string, however publish instances have families class attributes. So I think we can have something in the middle like adding families attribute in creators

I think it’s similar to the idea of having
default_variant and default_variants in new creators


But, I’m wondering
What if we create create instance with just 'MayaUSD' or 'MultiverseUSD' then a collector will take care of that and appends 'usd' to their families

Downside to that is that the new publisher doesn’t provide any attribute definitions then for plug-ins for usd families. As far as I know it only does so for any families it “pre-collected” for the new publisher as opposed to from the Collector pyblish plugins.

yeah, you are right.

I was a little curious and I dug a little bit in code to learn more.

so, Created Instances only have a single string family value
and, when these are instances are discovered, their family somehow are transformed into a list families ?

why it doesn’t happen in the first place as long as this single value will be saved to a list any way ?

Because I believe family is considered its main family and the others are just additional mix-ins or alike. Hmm, not sure if that’s the best explanation.

Regarding the design choices for the new publisher I think it’s best to take that up with @iLLiCiT @milan. At the initial design proposals I had argued that maybe it’d have been better to have a pre-collect stage similar to this Post-collect. So basically before publishing instead of running all collectors there would just be a very few that e.g. could mix-in important data for the publisher UI to actually show. However, technically that’d have meant that if any attribute was changed on an instance that the pre-collect plug-ins might need to re-trigger to ensure the resulting data remained sync. So there are arguments against it. Having all initial data being solely defined by the one creator might be limiting slightly more, but technically it allows for the same things, keeps things together and can allow for more optimization.

Anyway, I’d prefer that the Creators would then return the instances as, this instance has families ["usdMaya", "usd"] without it writing that actual data onto attributes, since it being those types is 100% defined by the creator itself just for the publishing system - it’s not intended to be a customizable attribute and thus not a storable/writable one.

I think it’s not doable without saving that list to node parameters

as far as I know a create instance is not saved as a class objects however it’s just a set or a rop that marked with some extra parameters and publish plugins try to find all sets and rops that contain extra parameters

I’ve implemented a prototype in this draft PR here: Maya: Implement USD publish and load using native `mayaUsdPlugin` by BigRoy · Pull Request #5573 · ynput/OpenPype · GitHub

I did some magical approach by allowing the creator to define multiple publish families without storing it as node parameters which seemed like the best approach to me. @iLLiCiT @milan design wise it’d be good if you could take a peek to join the discussion on that front.

1 Like