I’m adding instancing support to a basic USD reader, and have set up a simple example with instancing, with an Xform called Cube that has an instanceable mesh, with the path Cube/Cube.
There are three Xforms called Cube_01, Cube_02, Cube_03 that reference the Cube mesh, with prepend references = </Cube>.
I’m converting the mesh data to my own format, and would like to take advantage of instancing so that I don’t have to duplicate the mesh data across the instances.
If I’ve already read the data for the mesh Cube/Cube, how can I know this given the information available at the instance/prototype level?
E.g. I can get the prim prototype (called /__Prototype_1 in this case, but I understand that can change) from the XForm/Cube_01, and I can get the child mesh of that prototype: /Cube_01/Cube. I don’t see how to know that /Cube_01/Cube is actually /Cube/Cube…?
The prim at /Cube/Cube returns false for IsInPrototype
IsPrototype and IsInPrototype are really for the prototypes themselves (I still have to figure out “when” I would use those…).
You can use “GetPrototype()” on each Cube_XX and you can see they will return you which “/__PrototypeXXX” they point to.
Hi Paolo,
thanks very much for the reply. sadly it doesn’t really answer my question, which isn’t perhaps super clear.
My issue is that in this example, I only have one actual mesh defined. I expect to read that mesh and then when reading the instances, to be able to somehow identify that I have already done so, and reuse it.
But the only path I can find to a mesh from an instance is via a prototype, so although I have found a common mesh that I can read and share amongst the three cube_XX instances, I end up reading two meshes.
Those are (in this case) Cube/Cube (which I read by getting all mesh prims from the stage) and /__Prototype_1/Cube, which I reach from each instance and finding their prototypes. /__Prototype_1/Cube and Cube/Cube should be the same mesh, but I don’t see a way to know that… is this just something I need to live with?
First off, there’s a subtlety to defining prototypes on the same stage that instances them that requires some restructing in your scene. </Cube/Cube> is not the native instancing prototype on your composed stage. It is the source scene description for the prototype, but trying to compare any instances to it will not be useful. So our suggestion (which makes me think we should create an instancing user guide) is that you define your prototypes in such a way that they are elided from default stage traversals. You can accomplish this by making be either an over or a class instead of a def.
That’s part one. Part two is that now if you are doing a “ignore instancing” traversal of the scene and you come to a Mesh that you want to see if you’ve processed already, call prim.GetPrototype() on it. If that returns a valid prim, then it is instanced, and you can use that prim (or its path) as a key to determine whether you’ve processed the Mesh before. Warning that any editing of the stage that affects any “instancing keys” (i.e. compositional configuration of instanceable prims) may cause prototypes to be recomputed and reassigned, making your keys invalid. But for a single traversal of the stage with no authoring, you should be fine.
It’s easier to capture the internal structure of prototypes for sharing if you instead do a “default” traversal of the stage that stops when it hits instance prims (i.e. don’t use UsdTraverseInstanceProxies())
thanks for that, I’m just reading a file that’s been output by another system, so restructuring/changing how I define prototypes isn’t really an option, but that’s really good to know.
An instancing user guide would be great. I’ve been using this page for the most part, and it has been useful, but a more detailed guide on putting different model parts together from an instance would be very good to have.
Thanks for the informative response!