Instancing in USD#
When instancing is enabled (Instancing Style set to “Reference” or “Instanceable Reference”), the HOOPS converter creates USD scenegraph instancing structures to efficiently represent product occurrences that reference a prototype from the CAD file. In HOOPS Exchange, a prototype is a product occurrence that contains geometry meant to be instanced in multiple places; product occurrences that reference it become USD instanceable prims. This document explains how the converter uses USD instancing and how to work with the resulting structure.
For detailed information about USD Scenegraph Instancing concepts, see the NVIDIA Learn OpenUSD documentation on Scenegraph Instancing.
Pre-Conversion Considerations: Before converting CAD files to USD, consider reviewing the CAD Conversion Considerations guide, which provides recommendations for preparing CAD data before conversion, including reducing part count, reorganizing hierarchies, and optimizing scene scale.
Why Use Instancing#
Instancing provides declarative deduplication of repeated geometry, offering significant benefits:
Memory Efficiency: Geometry, materials, and other properties are stored once in the prototype rather than duplicated for each instance, reducing memory usage.
Performance: Rendering and scene traversal are optimized when multiple instances share the same prototype, improving overall performance.
File Size: USD files with instancing are typically smaller than files with duplicated geometry.
Instancing accelerates performance by allowing USD to recognize that certain scene elements are identical without needing to check each individual copy at runtime.
How the Converter Uses Instancing#
When instancing is enabled, the converter creates scenegraph instances by setting instanceable = true metadata on Prims representing product occurrences that reference a prototype. USD then automatically creates implicit prototypes based on the composition arcs (references) used by these Instanceable Prims.
The converter creates a hierarchical structure in USD:
Prototypes Prim: A
PrototypesScope prim is created as a child of the default prim and is authored as a class Scope (abstract class prim). This prim serves as a container for all prototype definitions.Prototype definitions: Under the
PrototypesScope, the converter creates one def Xform prim per unique prototype from the CAD assembly (e.g.Prototype_1,Prototype_2). These def prims contain the geometry and other properties that are shared across multiple instances. Each prototype definition has a local def ScopeLooksthat contains materials; the converter uses a Specialize arc so that these materials are composed from a shared root-levelLooksScope, making them local to each prototype under its own Scope.Looks Scope: A def Scope
Looksis created (as a sibling ofPrototypesunder the default prim) and holds the shared material definitions. The prototype definitions underPrototypeseach have their ownLooksScope that specializes this rootLooks, so materials are available locally within each prototype.Instanceable Prims: In the main scene hierarchy, product occurrences that reference a prototype are represented as def Xform prims with
instanceable = trueand areferencescomposition arc pointing at the corresponding prototype definition underPrototypes(e.g.prepend references = </ModelName/Prototypes/Prototype_1>). When “Instanceable Reference” is selected, these instance prims are marked instanceable so USD can optimize rendering and memory usage. These instance prims are mutable and can have unique transformations and other properties.Instance Proxies: When traversing instances, USD provides Instance Proxies that allow you to query properties of the prototype prims without following the indirection to the prototype.
The structure in the converted USD looks like:
/ModelName (default prim, def Xform)
├── Prototypes (class Scope - abstract class prim)
│ ├── Prototype_1 (def Xform - prototype definition)
│ │ ├── Geometry
│ │ └── Looks (def Scope, specializes "/ModelName/Looks" — materials local to prototype)
│ └── Prototype_2 (def Xform - prototype definition)
│ ├── Geometry
│ └── Looks (def Scope, specializes "/ModelName/Looks" — materials local to prototype)
├── Looks (def Scope, shared material definitions)
├── Instance_1 (Instanceable Prim, references Prototype_1)
│ ├── Geometry (Instance Proxy)
│ └── Materials (Instance Proxy)
└── Instance_2 (Instanceable Prim, references Prototype_1)
├── Geometry (Instance Proxy)
└── Materials (Instance Proxy)
Key Concepts:
Explicit Instances, Implicit Prototypes: You explicitly mark Prims as instanceable, and USD implicitly creates prototypes based on composition arcs.
Instanceable Prims are Mutable: The root Prim of each instance can be edited (e.g., transformations, visibility) to position and control individual instances.
Instance Proxies are Immutable: Descendants within an instance (Instance Proxies) cannot be directly edited, which enables the performance benefits of instancing.
Why the Prototypes Prim Is a Class Prim#
Only the Prototypes Scope (the container) is created as an abstract class prim (the class specifier in USD). The prototype definition prims under it (e.g. Prototype_1, Prototype_2) are authored as def Xform prims, not class. Using a class for the Prototypes container follows USD best practices: it marks the Scope as a non-editable container, prevents accidental edits to the prototype root, and helps distinguish the prototype container from the instance prims (def Xform with instanceable = true and references) in the main scene hierarchy. If the Prototypes prim appears non-editable in your DCC or viewer, it is because of this class specifier; the prototype definition prims under it are def and hold the actual geometry and materials.
Converting the Prototypes Prim to Def for Debugging#
If you need to make the Prototypes Scope itself editable (for example, to reparent or inspect it in the hierarchy), you can change it from a class to a concrete def in a stronger layer or in the same layer by re-authoring the prim spec with specifier def instead of class (e.g. via the USD Python API or an editor that supports changing prim specifiers). After converting to def, the Prototypes Scope becomes a normal prim; edits to prototype definitions under it still affect all instances that reference them. Use this only for debugging; it changes the intended structure of the instanced scene.
Refining Scenegraph Instances#
While Instance Proxies (descendants within instances) are immutable, there are several techniques available to introduce variety and customization into instanced scenes while maintaining performance benefits. These refinement techniques allow you to balance optimization with authoring flexibility.
Instance Editability Rules#
Understanding instance editability is key to working with instanced scenes:
Prototypes are not editable: Prototypes are runtime data structures and cannot be directly edited.
Instance Proxies are not editable: Local opinions on Instance Proxies are discarded. You cannot edit Prims within an instance hierarchy.
Instanceable Prims are editable: The root Prim of each instance can be edited, allowing unique transformations, visibility, and other properties per instance.
For more details, see the Introduction to Scenegraph Instance Refinement.
Refinement Techniques#
The following refinement techniques are available for working with instanced scenes:
Deinstancing: Disable instancing on specific Instanceable Prims (
instanceable = false) to regain full editability. This trades some optimization for complete control. See Deinstancing Refinement.Variant Sets: Use variant selections on Instanceable Prims to create new prototypes. This scales well for common workflow patterns. See Refinement Using Variant Sets.
Hierarchical Refinement: Use inherited properties on Instanceable Prims or their ancestors:
Primvars: Set primvar values (e.g., colors) that inherit through the hierarchy
Transformation Operations: Apply unique transforms to Instanceable Prims
Visibility: Control visibility of Instanceable Prims
This technique does not create new prototypes. See Hierarchical Refinement.
Ad Hoc Arcs: Add new composition arcs (references, inherits, etc.) to Instanceable Prims to create new prototypes. Most beneficial when multiple instances will share the same override. See Ad Hoc Arcs Refinement.
Broadcasted Refinement: Leverage inherits or specializes arcs to broadcast changes to multiple instances simultaneously. See Broadcasted Refinement.
For comprehensive information on all refinement techniques, see the Refining Scenegraph Instances documentation.