Ground planes seem to not survive IO via API

Hello everyone,

I am just starting to integrate ragdoll IO with out pipeline and I am having difficulty with importing/exporting via the api.

So it seems the majority of options exist for importing/loading/reinterpreting. Whereas on export you can only choose the the filename. I did find it confusing that I cannot explicitly provide a list of rRagdoll nodes to export. But then I saw that a majority of nodes have an

.export
attribute. So I have been disabling that attribute on non desired nodes and then using

from ragdoll import api; api.export_physics()

That portion seems to be working alright.

But when I try to import/reinterpret/load the physics file, the character will rebuild but the ground plane will not be found or recreated.
Forgive my inability to provide an example, I work at a vfx studio and as such I am more air-gapped than George Clooney in Gravity.

But I can recreate the issue by using the UI

  1. Load up the ragdoll browser (Same ui for looking at your license) & select the rhino
  2. Reset settings on the export physics and export (desktop is fine)
  3. Delete all physics in the scene
  4. Reset and import physics from your desktop
  5. The rhino will recreate itself as desired, but I am getting inconsistent results with the groundplane stopping. So the rhino will just fall.

I am exporting the desired/target solver nodes (including the solver)from the scene. Perhaps I should export all the nodes and try to selectively load instead of doing so on export?

Here are the import/load options I have been interacting with to try and fix the issue.

    opts = {
        "roots": [],
        # preserve the attrs on the solver in the scene, or use the ones from the file
        "preserveAttributes": load_options["preserveAttributes"],
        # create transforms missing from the scene, like the collision objects, ground etc
        "createMissingTransforms": load_options["createMissingTransforms"],
        # search and replace names
        "searchAndReplace": ["", ""],
        # namespace to put all the nodes under, there is no concept of target ns, yet
        "namespace": ragdoll_ns,
        # match by name or hierarchy, only two options
        "matchBy": ragdoll.constants.MatchByName,
        # unsure the following have an effect
        # "retarget": True,
        # "importNamespaceCustom": 1
    }
    # override with the scene solver, if one exists
    existingSolver = str(next(iter(cmdx.ls(type="rdSolver")), "")) or None
    if existingSolver:
        opts["overrideSolver"] = existingSolver

I have also tried api.reinterpret_physics and dump.Louder(opts) and I cannot seem to get the ground plane to recreate. Also I noticed the “rdEnvironment” node does not have a “export” attribute. Perhaps it is treated differently?

I will try to export all options and then selectively load to see if I can get desired setup.

So if anyone can see what I am doing wrong and perhaps provide an api I/O example that would be great. I have been trying to get this to work for hours now.

Also, a question/note about the idea of “target namespaces”. We plan to use ragdoll how it is often demoed; getting and applying its final performance onto a target rig. So is there scope to provide namespaceA for ragdoll nodes and namespaceB(target namespace) the rig?

We can probably continue on just fine with one namespace for both, but it would ideal if such was supported.

Thank you for any help you can share.

Hey @rav,

That’s it. The Export UI doesn’t visualise this, but it’s present in the Attribute Editor on every Ragdoll node and is respected during export.

Import works by re-assigning Markers onto things it finds in your scene that matches that on export. The ground is likely not in the scene you are importing into, as it is just a normal Maya (flat) box. The box is automatically created and assigned a Marker when you assign your first Marker.

To have it re-created, there is an option to generate new nodes for nodes that are missing in your scene called “Create Missing Transforms”.

Environments are not exported, because these represent the original Maya geometry and are intended for things like scenery and terrains. Those can be millions of polygons and are not expected to be beneficial in an exported file. If you do need static geometry to be part of an export, you’ll have to assign a Marker and set it to Animated. Animated Markers will be part of the export.

Not sure I understand, can you rephrase this? The target namespace is where to find matching transforms on import. E.g. you export a Marker assigned to batman:arm_ctl and import it onto joker:arm_ctl then batman will be present in the exported file, and the target namespace allows you to remap it to joker.

Okay this makes sense. What made me assume I had an issue with the IO was I was exporting the physics, deleting all physics in the scene and then reimporting/loading. With the ground plane present and it was still not assigning anything to it.

But the animation team is content with assigning ground planes as needed. Just wanted to make sure I was not “holding it wrong”.

Say I have a rig in the scene, under the batman namespace and I am going to import some ragdoll nodes into a batmanRagdoll namespace. Can you show me an api example of how I can have nodes in the batmanRagdoll namespace drive the rig in batman ns?

Thank you for help!

The vanilla Maya API should help here.

from ragdoll import api
from maya import cmds

cmds.namespace(set="batmanRagdoll")
api.reinterpret_physics(...)
cmds.namespace(set="batman")

The import command will create nodes via cmds.createNode which inherits whatever namespace is currently set.