usdrt::UsdGeomPointInstancer

Defined in usdrt/scenegraph/usd/usdGeom/pointInstancer.h

Functions

Variables

class UsdGeomPointInstancer : public usdrt::UsdGeomBoundable

Encodes vectorized instancing of multiple, potentially animated, prototypes (object/instance masters), which can be arbitrary prims/subtrees on a UsdStage.

PointInstancer is a “multi instancer”, as it allows multiple prototypes to be scattered among its “points”. We use a UsdRelationship prototypes to identify and order all of the possible prototypes, by targeting the root prim of each prototype. The ordering imparted by relationships associates a zero-based integer with each prototype, and it is these integers we use to identify the prototype of each instance, compactly, and allowing prototypes to be swapped out without needing to reauthor all of the per-instance data.

The PointInstancer schema is designed to scale to billions of instances, which motivates the choice to split the per-instance transformation into position, (quaternion) orientation, and scales, rather than a 4x4 matrix per-instance. In addition to requiring fewer bytes even if all elements are authored (32 bytes vs 64 for a single-precision 4x4 matrix), we can also be selective about which attributes need to animate over time, for substantial data reduction in many cases.

Note that PointInstancer is not a Gprim, since it is not a graphical primitive by any stretch of the imagination. It is, however, Boundable, since we will sometimes want to treat the entire PointInstancer similarly to a procedural, from the perspective of inclusion or framing.

Varying Instance Identity over Time

PointInstancers originating from simulations often have the characteristic that points/instances are “born”, move around for some time period, and then die (or leave the area of interest). In such cases, billions of instances may be birthed over time, while at any specific time, only a much smaller number are actually alive. To encode this situation efficiently, the simulator may re-use indices in the instance arrays, when a particle dies, its index will be taken over by a new particle that may be birthed in a much different location. This presents challenges both for identity-tracking, and for motion-blur.

We facilitate identity tracking by providing an optional, animatable ids attribute, that specifies the 64 bit integer ID of the particle at each index, at each point in time. If the simulator keeps monotonically increasing a particle-count each time a new particle is birthed, it will serve perfectly as particle ids.

We facilitate motion blur for varying-topology particle streams by optionally allowing per-instance velocities and angularVelocities to be authored. If instance transforms are requested at a time between samples and either of the velocity attributes is authored, then we will not attempt to interpolate samples of positions or orientations. If not authored, and the bracketing samples have the same length, then we will interpolate.

Computing an Instance Transform

Each instance’s transformation is a combination of the SRT affine transform described by its scale, orientation, and position, applied after (i.e. less locally) than the transformation computed at the root of the prototype it is instancing. In other words, to put an instance of a PointInstancer into the space of the PointInstancer’s parent prim:

  1. Apply (most locally) the authored transformation for prototypes[protoIndices[i]]

  2. If scales is authored, next apply the scaling matrix from scales[i]

  3. If orientations is authored: if is authored, first multiply orientations[i] by the unit quaternion derived by scaling angularVelocities[i] by the time differential from the left-bracketing timeSample for orientation to the requested evaluation time t, storing the result in R, else assign R directly from orientations[i]. Apply the rotation matrix derived from R.

  4. Apply the translation derived from positions[i]. If velocities is authored, apply the translation deriving from velocities[i] scaled by the time differential from the left-bracketing timeSample for positions to the requested evaluation time t.

  5. Least locally, apply the transformation authored on the PointInstancer prim itself (or the UsdGeomImageable::ComputeLocalToWorldTransform() of the PointInstancer to put the instance directly into world space)

If neither velocities nor angularVelocities are authored, we fallback to standard position and orientation computation logic (using linear interpolation between timeSamples) as described by UsdGeom_VelocityInterpolation .

Scaling Velocities for Interpolation

When computing time-differentials by which to apply velocity or angularVelocity to positions or orientations, we must scale by ( 1.0 / UsdStage::GetTimeCodesPerSecond() ), because velocities are recorded in units/second, while we are interpolating in UsdTimeCode ordinates.

We provide both high and low-level API’s for dealing with the transformation as a matrix, both will compute the instance matrices using multiple threads; the low-level API allows the client to cache unvarying inputs so that they need not be read duplicately when computing over time.

See also UsdGeom_VelocityInterpolation .

Primvars on PointInstancer

Primvars authored on a PointInstancer prim should always be applied to each instance with constant interpolation at the root of the instance. When you are authoring primvars on a PointInstancer, think about it as if you were authoring them on a point-cloud (e.g. a UsdGeomPoints gprim). The same interpolation rules for points apply here, substituting “instance” for “point”.

In other words, the (constant) value extracted for each instance from the authored primvar value depends on the authored interpolation and elementSize of the primvar, as follows:

  • constant or uniform : the entire authored value of the primvar should be applied exactly to each instance.

  • varying, vertex, or faceVarying: the first elementSize elements of the authored primvar array should be assigned to instance zero, the second elementSize elements should be assigned to instance one, and so forth.

Masking Instances: “Deactivating” and Invising

Often a PointInstancer is created “upstream” in a graphics pipeline, and the needs of “downstream” clients necessitate eliminating some of the instances from further consideration. Accomplishing this pruning by re-authoring all of the per-instance attributes is not very attractive, since it may mean destructively editing a large quantity of data. We therefore provide means of “masking” instances by ID, such that the instance data is unmolested, but per-instance transform and primvar data can be retrieved with the no-longer-desired instances eliminated from the (smaller) arrays. PointInstancer allows two independent means of masking instances by ID, each with different features that meet the needs of various clients in a pipeline. Both pruning features’ lists of ID’s are combined to produce the mask returned by ComputeMaskAtTime().

InactiveIds: List-edited, Unvarying Masking

The first masking feature encodes a list of IDs in a list-editable metadatum called inactiveIds, which, although it does not have any similar impact to stage population as prim activation, it shares with that feature that its application is uniform over all time. Because it is list-editable, we can sparsely add and remove instances from it in many layers.

This sparse application pattern makes inactiveIds a good choice when further downstream clients may need to reverse masking decisions made upstream, in a manner that is robust to many kinds of future changes to the upstream data.

See ActivateId(), ActivateIds(), DeactivateId(), DeactivateIds(), ActivateAllIds()

invisibleIds: Animatable Masking

The second masking feature encodes a list of IDs in a time-varying Int64Array-valued UsdAttribute called invisibleIds , since it shares with Imageable visibility the ability to animate object visibility.

Unlike inactiveIds, overriding a set of opinions for invisibleIds is not at all straightforward, because one will, in general need to reauthor (in the overriding layer) all timeSamples for the attribute just to change one Id’s visibility state, so it cannot be authored sparsely. But it can be a very useful tool for situations like encoding pre-computed camera-frustum culling of geometry when either or both of the instances or the camera is animated.

See VisId(), VisIds(), InvisId(), InvisIds(), VisAllIds()

Processing and Not Processing Prototypes

Any prim in the scenegraph can be targeted as a prototype by the prototypes relationship. We do not, however, provide a specific mechanism for identifying prototypes as geometry that should not be drawn (or processed) in their own, local spaces in the scenegraph. We encourage organizing all prototypes as children of the PointInstancer prim that consumes them, and pruning “raw” processing and drawing traversals when they encounter a PointInstancer prim; this is what the UsdGeomBBoxCache and UsdImaging engines do.

There is a pattern one can deploy for organizing the prototypes such that they will automatically be skipped by basic UsdPrim::GetChildren() or UsdPrimRange traversals. Usd prims each have a specifier of “def”, “over”, or “class”. The default traversals skip over prims that are “pure overs” or classes. So to protect prototypes from all generic traversals and processing, place them under a prim that is just an “over”. For example,

01 def PointInstancer "Crowd_Mid"
02 {
03     rel prototypes = [ </Crowd_Mid/Prototypes/MaleThin_Business>, </Crowd_Mid/Prototypes/MaleThin_Casual> ]
04
05     over "Prototypes"
06     {
07          def "MaleThin_Business" (
08              references = [@MaleGroupA/usd/MaleGroupA.usd@</MaleGroupA>]
09              variants = {
10                  string modelingVariant = "Thin"
11                  string costumeVariant = "BusinessAttire"
12              }
13          )
14          { ... }
15
16          def "MaleThin_Casual"
17          ...
18     }
19 }

Note

If a PointInstancer has no authored ids attribute, the masking features will still be available, with the integers specifying element position in the protoIndices array rather than ID.

Public Functions

inline explicit UsdGeomPointInstancer(const UsdPrim &prim = UsdPrim())

Construct a UsdGeomPointInstancer on UsdPrim prim. Equivalent to UsdGeomPointInstancer::Get(prim.GetStage(), prim.GetPath()) for a valid prim , but will not immediately throw an error for an invalid prim.

inline explicit UsdGeomPointInstancer(const UsdSchemaBase &schemaObj)

Construct a UsdGeomPointInstancer on the prim held by schemaObj . Should be preferred over UsdGeomPointInstancer(schemaObj.GetPrim()), as it preserves SchemaBase state.

inline virtual ~UsdGeomPointInstancer()

Destructor.

inline operator bool() const

Boolean operator.

Returns

Return true if the contained prim is an instance of this schema using IsA, and false otherwise.

inline UsdAttribute GetProtoIndicesAttr() const

Required property. Per-instance index into prototypes relationship that identifies what geometry should be drawn for each instance. Topology attribute - can be animated, but at a potential performance impact for streaming.

Declaration

int[] protoIndices

C++ Type

VtArray<int>

Usd Type

SdfValueTypeNames->IntArray

inline UsdAttribute CreateProtoIndicesAttr() const

See GetProtoIndicesAttr(), and also Create vs Get Property Methods for when to use Get vs Create. If specified, author defaultValue as the attribute’s default, sparsely (when it makes sense to do so) if writeSparsely is true - the default for writeSparsely is false.

inline UsdAttribute GetIdsAttr() const

Ids are optional; if authored, the ids array should be the same length as the protoIndices array, specifying (at each timeSample if instance identities are changing) the id of each instance. The type is signed intentionally, so that clients can encode some binary state on Id’d instances without adding a separate primvar. See also Varying Instance Identity over Time.

Declaration

int64[] ids

C++ Type

VtArray<int64_t>

Usd Type

SdfValueTypeNames->Int64Array

inline UsdAttribute CreateIdsAttr() const

See GetIdsAttr(), and also Create vs Get Property Methods for when to use Get vs Create. If specified, author defaultValue as the attribute’s default, sparsely (when it makes sense to do so) if writeSparsely is true - the default for writeSparsely is false.

inline UsdAttribute GetPositionsAttr() const

Required property. Per-instance position. See also Computing an Instance Transform .

Declaration

point3f[] positions

C++ Type

VtArray<GfVec3f>

Usd Type

SdfValueTypeNames->Point3fArray

inline UsdAttribute CreatePositionsAttr() const

See GetPositionsAttr(), and also Create vs Get Property Methods for when to use Get vs Create. If specified, author defaultValue as the attribute’s default, sparsely (when it makes sense to do so) if writeSparsely is true - the default for writeSparsely is false.

inline UsdAttribute GetOrientationsAttr() const

If authored, per-instance orientation of each instance about its prototype’s origin, represented as a unit length quaternion, which allows us to encode it with sufficient precision in a compact GfQuath.

It is client’s responsibility to ensure that authored quaternions are unit length; the convenience API below for authoring orientations from rotation matrices will ensure that quaternions are unit length, though it will not make any attempt to select the “better (for interpolation

with respect to neighboring samples)” of the two possible quaternions that encode the rotation.

See also Computing an Instance Transform .

Declaration

quath[] orientations

C++ Type

VtArray<GfQuath>

Usd Type

SdfValueTypeNames->QuathArray

inline UsdAttribute CreateOrientationsAttr() const

See GetOrientationsAttr(), and also Create vs Get Property Methods for when to use Get vs Create. If specified, author defaultValue as the attribute’s default, sparsely (when it makes sense to do so) if writeSparsely is true - the default for writeSparsely is false.

inline UsdAttribute GetScalesAttr() const

If authored, per-instance scale to be applied to each instance, before any rotation is applied.

See also Computing an Instance Transform .

Declaration

float3[] scales

C++ Type

VtArray<GfVec3f>

Usd Type

SdfValueTypeNames->Float3Array

inline UsdAttribute CreateScalesAttr() const

See GetScalesAttr(), and also Create vs Get Property Methods for when to use Get vs Create. If specified, author defaultValue as the attribute’s default, sparsely (when it makes sense to do so) if writeSparsely is true - the default for writeSparsely is false.

inline UsdAttribute GetVelocitiesAttr() const

If provided, per-instance ‘velocities’ will be used to compute positions between samples for the ‘positions’ attribute, rather than interpolating between neighboring ‘positions’ samples. Velocities should be considered mandatory if both protoIndices and positions are animated. Velocity is measured in position units per second, as per most simulation software. To convert to position units per UsdTimeCode, divide by UsdStage::GetTimeCodesPerSecond().

See also Computing an Instance Transform, UsdGeom_VelocityInterpolation .

Declaration

vector3f[] velocities

C++ Type

VtArray<GfVec3f>

Usd Type

SdfValueTypeNames->Vector3fArray

inline UsdAttribute CreateVelocitiesAttr() const

See GetVelocitiesAttr(), and also Create vs Get Property Methods for when to use Get vs Create. If specified, author defaultValue as the attribute’s default, sparsely (when it makes sense to do so) if writeSparsely is true - the default for writeSparsely is false.

inline UsdAttribute GetAccelerationsAttr() const

If authored, per-instance ‘accelerations’ will be used with velocities to compute positions between samples for the ‘positions’ attribute rather than interpolating between neighboring ‘positions’ samples. Acceleration is measured in position units per second-squared. To convert to position units per squared UsdTimeCode, divide by the square of UsdStage::GetTimeCodesPerSecond().

Declaration

vector3f[] accelerations

C++ Type

VtArray<GfVec3f>

Usd Type

SdfValueTypeNames->Vector3fArray

inline UsdAttribute CreateAccelerationsAttr() const

See GetAccelerationsAttr(), and also Create vs Get Property Methods for when to use Get vs Create. If specified, author defaultValue as the attribute’s default, sparsely (when it makes sense to do so) if writeSparsely is true - the default for writeSparsely is false.

inline UsdAttribute GetAngularVelocitiesAttr() const

If authored, per-instance angular velocity vector to be used for interoplating orientations. Angular velocities should be considered mandatory if both protoIndices and orientations are animated. Angular velocity is measured in degrees per second. To convert to degrees per UsdTimeCode, divide by UsdStage::GetTimeCodesPerSecond().

See also Computing an Instance Transform .

Declaration

vector3f[] angularVelocities

C++ Type

VtArray<GfVec3f>

Usd Type

SdfValueTypeNames->Vector3fArray

inline UsdAttribute CreateAngularVelocitiesAttr() const

See GetAngularVelocitiesAttr(), and also Create vs Get Property Methods for when to use Get vs Create. If specified, author defaultValue as the attribute’s default, sparsely (when it makes sense to do so) if writeSparsely is true - the default for writeSparsely is false.

inline UsdAttribute GetInvisibleIdsAttr() const

A list of id’s to make invisible at the evaluation time. See invisibleIds: Animatable Masking .

Declaration

int64[] invisibleIds = []

C++ Type

VtArray<int64_t>

Usd Type

SdfValueTypeNames->Int64Array

inline UsdAttribute CreateInvisibleIdsAttr() const

See GetInvisibleIdsAttr(), and also Create vs Get Property Methods for when to use Get vs Create. If specified, author defaultValue as the attribute’s default, sparsely (when it makes sense to do so) if writeSparsely is true - the default for writeSparsely is false.

inline UsdRelationship GetPrototypesRel() const

Required property. Orders and targets the prototype root prims, which can be located anywhere in the scenegraph that is convenient, although we promote organizing prototypes as children of the PointInstancer. The position of a prototype in this relationship defines the value an instance would specify in the protoIndices attribute to instance that prototype. Since relationships are uniform, this property cannot be animated.

inline UsdRelationship CreatePrototypesRel() const

See GetPrototypesRel(), and also Create vs Get Property Methods for when to use Get vs Create.

inline UsdAttribute GetExtentAttr() const

Extent is a three dimensional range measuring the geometric extent of the authored gprim in its own local space (i.e. its own transform not applied), without accounting for any shader-induced displacement. If any extent value has been authored for a given Boundable, then it should be authored at every timeSample at which geometry-affecting properties are authored, to ensure correct evaluation via ComputeExtent(). If no extent value has been authored, then ComputeExtent() will call the Boundable’s registered ComputeExtentFunction(), which may be expensive, which is why we strongly encourage proper authoring of extent.

An authored extent on a prim which has children is expected to include the extent of all children, as they will be pruned from BBox computation during traversal.

See also

ComputeExtent()

See also

Why Extent and not Bounds ?.

Declaration

float3[] extent

C++ Type

VtArray<GfVec3f>

Usd Type

SdfValueTypeNames->Float3Array

inline UsdAttribute CreateExtentAttr() const

See GetExtentAttr(), and also Create vs Get Property Methods for when to use Get vs Create. If specified, author defaultValue as the attribute’s default, sparsely (when it makes sense to do so) if writeSparsely is true - the default for writeSparsely is false.

inline UsdAttribute GetXformOpOrderAttr() const

Encodes the sequence of transformation operations in the order in which they should be pushed onto a transform stack while visiting a UsdStage’s prims in a graph traversal that will effect the desired positioning for this prim and its descendant prims.

You should rarely, if ever, need to manipulate this attribute directly. It is managed by the AddXformOp(), SetResetXformStack(), and SetXformOpOrder(), and consulted by GetOrderedXformOps() and GetLocalTransformation().

Declaration

uniform token[] xformOpOrder

C++ Type

VtArray<TfToken>

Usd Type

SdfValueTypeNames->TokenArray

Variability

SdfVariabilityUniform

inline UsdAttribute CreateXformOpOrderAttr() const

See GetXformOpOrderAttr(), and also Create vs Get Property Methods for when to use Get vs Create. If specified, author defaultValue as the attribute’s default, sparsely (when it makes sense to do so) if writeSparsely is true - the default for writeSparsely is false.

inline UsdAttribute GetVisibilityAttr() const

Visibility is meant to be the simplest form of “pruning” visibility that is supported by most DCC apps. Visibility is animatable, allowing a sub-tree of geometry to be present for some segment of a shot, and absent from others; unlike the action of deactivating geometry prims, invisible geometry is still available for inspection, for positioning, for defining volumes, etc.

Declaration

token visibility = "inherited"

C++ Type

TfToken

Usd Type

SdfValueTypeNames->Token

Allowed Values

inherited, invisible

inline UsdAttribute CreateVisibilityAttr() const

See GetVisibilityAttr(), and also Create vs Get Property Methods for when to use Get vs Create. If specified, author defaultValue as the attribute’s default, sparsely (when it makes sense to do so) if writeSparsely is true - the default for writeSparsely is false.

inline UsdAttribute GetPurposeAttr() const

Purpose is a classification of geometry into categories that can each be independently included or excluded from traversals of prims on a stage, such as rendering or bounding-box computation traversals.

See UsdGeom_ImageablePurpose for more detail about how purpose is computed and used.

Declaration

uniform token purpose = "default"

C++ Type

TfToken

Usd Type

SdfValueTypeNames->Token

Variability

SdfVariabilityUniform

Allowed Values

default, render, proxy, guide

inline UsdAttribute CreatePurposeAttr() const

See GetPurposeAttr(), and also Create vs Get Property Methods for when to use Get vs Create. If specified, author defaultValue as the attribute’s default, sparsely (when it makes sense to do so) if writeSparsely is true - the default for writeSparsely is false.

inline UsdRelationship GetProxyPrimRel() const

The proxyPrim relationship allows us to link a prim whose purpose is “render” to its (single target) purpose=”proxy” prim. This is entirely optional, but can be useful in several scenarios:

  • In a pipeline that does pruning (for complexity management) by deactivating prims composed from asset references, when we deactivate a purpose=”render” prim, we will be able to discover and additionally deactivate its associated purpose=”proxy” prim, so that preview renders reflect the pruning accurately.

  • DCC importers may be able to make more aggressive optimizations for interactive processing and display if they can discover the proxy for a given render prim.

  • With a little more work, a Hydra-based application will be able to map a picked proxy prim back to its render geometry for selection.

Note

It is only valid to author the proxyPrim relationship on prims whose purpose is “render”.

inline UsdRelationship CreateProxyPrimRel() const

See GetProxyPrimRel(), and also Create vs Get Property Methods for when to use Get vs Create.

UsdPrim GetPrim() const

Return this schema object’s held prim.

SdfPath GetPath() const

Return the SdfPath to this schema object’s held prim.

Public Static Functions

static inline UsdGeomPointInstancer Define(const UsdStageRefPtr &stage, const SdfPath &path)

Attempt to ensure a UsdPrim adhering to this schema at path is defined (according to UsdPrim::IsDefined()) on this stage.

Public Static Attributes

static const UsdSchemaType schemaType = UsdSchemaType::ConcreteTyped

Compile time constant representing what kind of schema this class is.

See also

UsdSchemaType