Performing an in-depth compare of 2 .usda files

For regression testing, I’d like to compare an existing “golden” .usda file with another that’s just been generated. The files are both “flat” in the sense that they will not be making use of any composition arcs at all. But the comparison will need to be deep so it should be able to check the data of every property of the prim (all primvars etc.)

I’m aware of one aspect that might be problematic[1] but there are other issues I’m not sure how best to handle. For instance, the order of prims in both files are wildly different (and not easily enforced on the write side). Searching for how to reorder prims in a file, and re-save, is surprisingly nonexistent? I was hoping to get the output of the test to be easily human-readable (diff’able) so it would be nice look at if failures do occur.

Are there any APIs or techniques that others have used for this?

[1] Autodesk: Add support for controlling how floats and doubles are streamed out by erikaharrison-adsk · Pull Request #3001 · PixarAnimationStudios/OpenUSD · GitHub

You could make use of the name children order to make ordering explicit. If it’s a flat file, it should be consistent if that’s set.

Thanks for the suggestion! Though I might be using it wrong? It only seems to author the reorder nameChildren property, but it doesn’t physically reorder the prims in the resulting file when saving the Stage.

BTW, for folks passing through - the API is NOT exposed as SetNameChildrenOrder(...) in python, it’s exposed as the .nameChildrenOrder property that you assign too.

Ah yeah, that Python API is because anytime you get into the SDF API, the Python bindings switch to using properties instead of getter/setter methods. Always trips me up, and maybe something we can switch away from someday somehow.

And yeah, I guess if you’re trying to diff the USD as text, it wouldn’t help. I haven’t found a good way to do that, and I prefer doing a load into USD as SDF and doing a diff at that point.

The Sdf.PrimSpec object you get when traversing the layer will also sport a primSpec.nameChildren property that is an editor object that (I believe) models a list. So you should be able to use that thing to directly move around the prim’s children. See OpenUSD/pxr/usd/sdf/testenv/testSdfPrim.py at dev · PixarAnimationStudios/OpenUSD · GitHub for some example usage.

I also just wanted to note that authored prim order is meaningful (e.g. it will be for key rigging behaviors built on top of OpenExec) and meant to be preserved in layers, which may become problematic beyond diffing if different tools or runs are producing different orders of prims. You will be able to “correct” ordering using the reorder statement in downstream layers, but that brings its own issues along.

I wasn’t able to succeed with just modifying the .nameChildren property. It’s like a weird dictionary of sorts and I couldn’t figure out how to remove an item from that set and re-insert at the correct position. PrimSpecs die once being removed.

So I went with the brute force option of using BatchNamespaceEdit to move the unordered /root/* prims to their final ordering under /root/temp/* and then, in the same batch, I moved them all back again :slight_smile:

But then I noticed there’s already a Sdf.NamespaceEdit.Reorder directive! Too bad I discovered that it is still broken-ish: SdfNamespaceEdit.Reorder posts a misleading error · Issue #1160 · PixarAnimationStudios/OpenUSD · GitHub

Sorry for the trouble, @deadpin . It’s not well documented, but @amohr showed me how to do it. Here’s a simple example:

parent.nameChildren[:] = reversed(parent.nameChildren)

but you can create any list of parents children, and then assign that list as above, and no primSpecs will die in the process.

That… works and is way simpler than what I had going :slight_smile: Thank you!