I am new to the Omniverse/USD world and after some experimenting, I’ve written a python script that generates a USD file that mimics the layout of an area using cubes. I’m happy with the positioning but I’d like to swap the cubes out for a 3D model that we have in a USD file. The cubes get translated, have the size set, rotated, and scaled. Here is the generic version of the method I’m using to create the cubes. How do I update this to use my 3d model?
After some digging, I’ve found some code to add a reference as an xform but xforms don’t have the same methods as the cube prim. I’ve only figured out how to translate the model so far
I’m trying to figure out how to do the following commands, but on the referenced asset instead of the cube
cubePrim.GetSizeAttr().Set(size)
cubePrim.GetExtentAttr().Set(extentAttr.Get() * size)
cubePrim.AddRotateXYZOp().Set(Gf.Vec3d(0, rotationAngle, 0))
cubePrim.AddScaleOp().Set((length, height, width))
I actually realized that I can transform, scale, and rotate the referenced model (code was breaking before I got there :) ). What is left is figuring out how to set the size and the extents.
Ah, ok. I realize you figured some of this out before I finished, but I’ll post the whole thing for completeness. :)
Size is specific to the Cube prim. To resize or scale your asset, you should do it with “xformOp:scale” like your last line.
Extent is an attribute that is only available to UsdGeomBoundable prims. Xforms do not inherit from that. Instead, you can calculate the bbox for you xform and all of its descendants using the snippet I provided: Compute the Bounding Box for a Prim — Omniverse Kit documentation. You can use the UsdGeomModelAPI to cache that computed bbox for an asset if that makes sense for your pipeline. These are known as extent hints: Universal Scene Description: UsdGeomModelAPI Class Reference I wouldn’t worry to much about setting the extents as you’re prototyping, but definitely worth understanding and authoring it as you scale up your pipeline.
I’m going to need many copies of the 3d model. In my code, I’m calling the create method in a loop that will be executed 100s of times. Should I add the reference each time (.GetReferences().AddReference()) or should I add it once and then somehow refer to that in the loop? My code is currently adding the reference repeatedly but I’m wondering if that’s necessary/good practice.
Yes, that’s the correct way. By adding a reference to a prim, you can think of it as though you’re saying, “This prim uses this blueprint”. And the blueprint may just give the prim a type and set some properties or it might add some additional children prims to it. USD isn’t fetching the referenced later multiple times if that’s what you’re worried about.