HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
pointInstancer.h
Go to the documentation of this file.
1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the terms set forth in the LICENSE.txt file available at
5 // https://openusd.org/license.
6 //
7 #ifndef USDGEOM_GENERATED_POINTINSTANCER_H
8 #define USDGEOM_GENERATED_POINTINSTANCER_H
9 
10 /// \file usdGeom/pointInstancer.h
11 
12 #include "pxr/pxr.h"
13 #include "pxr/usd/usdGeom/api.h"
15 #include "pxr/usd/usd/prim.h"
16 #include "pxr/usd/usd/stage.h"
17 #include "pxr/usd/usdGeom/tokens.h"
18 
19 #include "pxr/base/vt/value.h"
20 
21 #include "pxr/base/gf/vec3d.h"
22 #include "pxr/base/gf/vec3f.h"
23 #include "pxr/base/gf/matrix4d.h"
24 
25 #include "pxr/base/tf/token.h"
26 #include "pxr/base/tf/type.h"
27 
29 
30 class SdfAssetPath;
31 
32 // -------------------------------------------------------------------------- //
33 // POINTINSTANCER //
34 // -------------------------------------------------------------------------- //
35 
36 /// \class UsdGeomPointInstancer
37 ///
38 /// Encodes vectorized instancing of multiple, potentially
39 /// animated, prototypes (object/instance masters), which can be arbitrary
40 /// prims/subtrees on a UsdStage.
41 ///
42 /// PointInstancer is a "multi instancer", as it allows multiple prototypes
43 /// to be scattered among its "points". We use a UsdRelationship
44 /// \em prototypes to identify and order all of the possible prototypes, by
45 /// targeting the root prim of each prototype. The ordering imparted by
46 /// relationships associates a zero-based integer with each prototype, and
47 /// it is these integers we use to identify the prototype of each instance,
48 /// compactly, and allowing prototypes to be swapped out without needing to
49 /// reauthor all of the per-instance data.
50 ///
51 /// The PointInstancer schema is designed to scale to billions of instances,
52 /// which motivates the choice to split the per-instance transformation into
53 /// position, (quaternion) orientation, and scales, rather than a
54 /// 4x4 matrix per-instance. In addition to requiring fewer bytes even if
55 /// all elements are authored (32 bytes vs 64 for a single-precision 4x4
56 /// matrix), we can also be selective about which attributes need to animate
57 /// over time, for substantial data reduction in many cases.
58 ///
59 /// Note that PointInstancer is \em not a Gprim, since it is not a graphical
60 /// primitive by any stretch of the imagination. It \em is, however,
61 /// Boundable, since we will sometimes want to treat the entire PointInstancer
62 /// similarly to a procedural, from the perspective of inclusion or framing.
63 ///
64 /// \section UsdGeomPointInstancer_varyingTopo Varying Instance Identity over Time
65 ///
66 /// PointInstancers originating from simulations often have the characteristic
67 /// that points/instances are "born", move around for some time period, and then
68 /// die (or leave the area of interest). In such cases, billions of instances
69 /// may be birthed over time, while at any \em specific time, only a much
70 /// smaller number are actually alive. To encode this situation efficiently,
71 /// the simulator may re-use indices in the instance arrays, when a particle
72 /// dies, its index will be taken over by a new particle that may be birthed in
73 /// a much different location. This presents challenges both for
74 /// identity-tracking, and for motion-blur.
75 ///
76 /// We facilitate identity tracking by providing an optional, animatable
77 /// \em ids attribute, that specifies the 64 bit integer ID of the particle
78 /// at each index, at each point in time. If the simulator keeps monotonically
79 /// increasing a particle-count each time a new particle is birthed, it will
80 /// serve perfectly as particle \em ids.
81 ///
82 /// We facilitate motion blur for varying-topology particle streams by
83 /// optionally allowing per-instance \em velocities and \em angularVelocities
84 /// to be authored. If instance transforms are requested at a time between
85 /// samples and either of the velocity attributes is authored, then we will
86 /// not attempt to interpolate samples of \em positions or \em orientations.
87 /// If not authored, and the bracketing samples have the same length, then we
88 /// will interpolate.
89 ///
90 /// \section UsdGeomPointInstancer_transform Computing an Instance Transform
91 ///
92 /// Each instance's transformation is a combination of the SRT affine transform
93 /// described by its scale, orientation, and position, applied \em after
94 /// (i.e. less locally than) the local to parent transformation computed at
95 /// the root of the prototype it is instancing.
96 ///
97 /// If your processing of prototype geometry naturally takes into account the
98 /// transform of the prototype root, then this term can be omitted from the
99 /// computation of each instance transform, and this can be controlled when
100 /// computing instance transformation matrices using the
101 /// UsdGeomPointInstancer::PrototypeXformInclusion enumeration.
102 ///
103 /// To understand the computation of the instance transform, in order to put
104 /// an instance of a PointInstancer into the space of the PointInstancer's
105 /// parent prim we do the following:
106 ///
107 /// 1. Apply (most locally) the authored local to parent transformation for
108 /// <em>prototypes[protoIndices[i]]</em>
109 /// 2. If *scales* is authored, next apply the scaling matrix from *scales[i]*
110 /// 3. If *orientations* is authored: **if *angularVelocities* is authored**,
111 /// first multiply *orientations[i]* by the unit quaternion derived by scaling
112 /// *angularVelocities[i]* by the \ref UsdGeom_PITimeScaling "time differential"
113 /// from the left-bracketing timeSample for *orientation* to the requested
114 /// evaluation time *t*, storing the result in *R*, **else** assign *R*
115 /// directly from *orientations[i]*. Apply the rotation matrix derived
116 /// from *R*.
117 /// 4. Apply the translation derived from *positions[i]*. If *velocities* is
118 /// authored, apply the translation deriving from *velocities[i]* scaled by
119 /// the time differential from the left-bracketing timeSample for *positions*
120 /// to the requested evaluation time *t*.
121 /// 5. Least locally, apply the transformation authored on the PointInstancer
122 /// prim itself (or the UsdGeomImageable::ComputeLocalToWorldTransform() of the
123 /// PointInstancer to put the instance directly into world space)
124 ///
125 /// If neither *velocities* nor *angularVelocities* are authored, we fallback to
126 /// standard position and orientation computation logic (using linear
127 /// interpolation between timeSamples) as described by
128 /// \ref UsdGeom_VelocityInterpolation .
129 ///
130 /// \anchor UsdGeom_PITimeScaling
131 /// <b>Scaling Velocities for Interpolation</b>
132 ///
133 /// When computing time-differentials by which to apply velocity or
134 /// angularVelocity to positions or orientations, we must scale by
135 /// ( 1.0 / UsdStage::GetTimeCodesPerSecond() ), because velocities are recorded
136 /// in units/second, while we are interpolating in UsdTimeCode ordinates.
137 ///
138 /// We provide both high and low-level API's for dealing with the
139 /// transformation as a matrix, both will compute the instance matrices using
140 /// multiple threads; the low-level API allows the client to cache unvarying
141 /// inputs so that they need not be read duplicately when computing over
142 /// time.
143 ///
144 /// See also \ref UsdGeom_VelocityInterpolation .
145 ///
146 /// \section UsdGeomPointInstancer_primvars Primvars on PointInstancer
147 ///
148 /// \ref UsdGeomPrimvar "Primvars" authored on a PointInstancer prim should
149 /// always be applied to each instance with \em constant interpolation at
150 /// the root of the instance. When you are authoring primvars on a
151 /// PointInstancer, think about it as if you were authoring them on a
152 /// point-cloud (e.g. a UsdGeomPoints gprim). The same
153 /// <A HREF="https://renderman.pixar.com/resources/RenderMan_20/appnote.22.html#classSpecifiers">interpolation rules for points</A> apply here, substituting
154 /// "instance" for "point".
155 ///
156 /// In other words, the (constant) value extracted for each instance
157 /// from the authored primvar value depends on the authored \em interpolation
158 /// and \em elementSize of the primvar, as follows:
159 /// \li <b>constant</b> or <b>uniform</b> : the entire authored value of the
160 /// primvar should be applied exactly to each instance.
161 /// \li <b>varying</b>, <b>vertex</b>, or <b>faceVarying</b>: the first
162 /// \em elementSize elements of the authored primvar array should be assigned to
163 /// instance zero, the second \em elementSize elements should be assigned to
164 /// instance one, and so forth.
165 ///
166 ///
167 /// \section UsdGeomPointInstancer_masking Masking Instances: "Deactivating" and Invising
168 ///
169 /// Often a PointInstancer is created "upstream" in a graphics pipeline, and
170 /// the needs of "downstream" clients necessitate eliminating some of the
171 /// instances from further consideration. Accomplishing this pruning by
172 /// re-authoring all of the per-instance attributes is not very attractive,
173 /// since it may mean destructively editing a large quantity of data. We
174 /// therefore provide means of "masking" instances by ID, such that the
175 /// instance data is unmolested, but per-instance transform and primvar data
176 /// can be retrieved with the no-longer-desired instances eliminated from the
177 /// (smaller) arrays. PointInstancer allows two independent means of masking
178 /// instances by ID, each with different features that meet the needs of
179 /// various clients in a pipeline. Both pruning features' lists of ID's are
180 /// combined to produce the mask returned by ComputeMaskAtTime().
181 ///
182 /// \note If a PointInstancer has no authored \em ids attribute, the masking
183 /// features will still be available, with the integers specifying element
184 /// position in the \em protoIndices array rather than ID.
185 ///
186 /// \subsection UsdGeomPointInstancer_inactiveIds InactiveIds: List-edited, Unvarying Masking
187 ///
188 /// The first masking feature encodes a list of IDs in a list-editable metadatum
189 /// called \em inactiveIds, which, although it does not have any similar
190 /// impact to stage population as \ref UsdPrim::SetActive() "prim activation",
191 /// it shares with that feature that its application is uniform over all time.
192 /// Because it is list-editable, we can \em sparsely add and remove instances
193 /// from it in many layers.
194 ///
195 /// This sparse application pattern makes \em inactiveIds a good choice when
196 /// further downstream clients may need to reverse masking decisions made
197 /// upstream, in a manner that is robust to many kinds of future changes to
198 /// the upstream data.
199 ///
200 /// See ActivateId(), ActivateIds(), DeactivateId(), DeactivateIds(),
201 /// ActivateAllIds()
202 ///
203 /// \subsection UsdGeomPointInstancer_invisibleIds invisibleIds: Animatable Masking
204 ///
205 /// The second masking feature encodes a list of IDs in a time-varying
206 /// Int64Array-valued UsdAttribute called \em invisibleIds , since it shares
207 /// with \ref UsdGeomImageable::GetVisibilityAttr() "Imageable visibility"
208 /// the ability to animate object visibility.
209 ///
210 /// Unlike \em inactiveIds, overriding a set of opinions for \em invisibleIds
211 /// is not at all straightforward, because one will, in general need to
212 /// reauthor (in the overriding layer) **all** timeSamples for the attribute
213 /// just to change one Id's visibility state, so it cannot be authored
214 /// sparsely. But it can be a very useful tool for situations like encoding
215 /// pre-computed camera-frustum culling of geometry when either or both of
216 /// the instances or the camera is animated.
217 ///
218 /// See VisId(), VisIds(), InvisId(), InvisIds(), VisAllIds()
219 ///
220 /// \section UsdGeomPointInstancer_protoProcessing Processing and Not Processing Prototypes
221 ///
222 /// Any prim in the scenegraph can be targeted as a prototype by the
223 /// \em prototypes relationship. We do not, however, provide a specific
224 /// mechanism for identifying prototypes as geometry that should not be drawn
225 /// (or processed) in their own, local spaces in the scenegraph. We
226 /// encourage organizing all prototypes as children of the PointInstancer
227 /// prim that consumes them, and pruning "raw" processing and drawing
228 /// traversals when they encounter a PointInstancer prim; this is what the
229 /// UsdGeomBBoxCache and UsdImaging engines do.
230 ///
231 /// There \em is a pattern one can deploy for organizing the prototypes such
232 /// that they will automatically be skipped by basic UsdPrim::GetChildren() or
233 /// UsdPrimRange traversals. Usd prims each have a \ref Usd_PrimSpecifiers
234 /// "specifier" of "def", "over", or "class". The default traversals skip over
235 /// prims that are "pure overs" or classes. So to protect prototypes from all
236 /// generic traversals and processing, place them under a prim that is a "class"
237 /// or "over". "class" is recommended , while "over" should be used when
238 /// backwards compatibility with older versions of USD is needed. For example,
239 /// \code
240 /// 01 def PointInstancer "Crowd_Mid"
241 /// 02 {
242 /// 03 rel prototypes = [ </Crowd_Mid/Prototypes/MaleThin_Business>, </Crowd_Mid/OtherPrototypes/MaleThin_Casual> ]
243 /// 04
244 /// 05 over "Prototypes"
245 /// 06 {
246 /// 07 def "MaleThin_Business" (
247 /// 08 references = [@MaleGroupA/usd/MaleGroupA.usd@</MaleGroupA>]
248 /// 09 variants = {
249 /// 10 string modelingVariant = "Thin"
250 /// 11 string costumeVariant = "BusinessAttire"
251 /// 12 }
252 /// 13 )
253 /// 14 { ... }
254 /// 15 }
255 /// 16
256 /// 17 class "OtherPrototypes"
257 /// 18 {
258 /// 19 def "MaleThin_Casual"
259 /// 20 ...
260 /// 21 }
261 /// 22 }
262 /// \endcode
263 ///
264 ///
266 {
267 public:
268  /// Compile time constant representing what kind of schema this class is.
269  ///
270  /// \sa UsdSchemaKind
272 
273  /// Construct a UsdGeomPointInstancer on UsdPrim \p prim .
274  /// Equivalent to UsdGeomPointInstancer::Get(prim.GetStage(), prim.GetPath())
275  /// for a \em valid \p prim, but will not immediately throw an error for
276  /// an invalid \p prim
277  explicit UsdGeomPointInstancer(const UsdPrim& prim=UsdPrim())
278  : UsdGeomBoundable(prim)
279  {
280  }
281 
282  /// Construct a UsdGeomPointInstancer on the prim held by \p schemaObj .
283  /// Should be preferred over UsdGeomPointInstancer(schemaObj.GetPrim()),
284  /// as it preserves SchemaBase state.
285  explicit UsdGeomPointInstancer(const UsdSchemaBase& schemaObj)
286  : UsdGeomBoundable(schemaObj)
287  {
288  }
289 
290  /// Destructor.
292  virtual ~UsdGeomPointInstancer();
293 
294  /// Return a vector of names of all pre-declared attributes for this schema
295  /// class and all its ancestor classes. Does not include attributes that
296  /// may be authored by custom/extended methods of the schemas involved.
298  static const TfTokenVector &
299  GetSchemaAttributeNames(bool includeInherited=true);
300 
301  /// Return a UsdGeomPointInstancer holding the prim adhering to this
302  /// schema at \p path on \p stage. If no prim exists at \p path on
303  /// \p stage, or if the prim at that path does not adhere to this schema,
304  /// return an invalid schema object. This is shorthand for the following:
305  ///
306  /// \code
307  /// UsdGeomPointInstancer(stage->GetPrimAtPath(path));
308  /// \endcode
309  ///
311  static UsdGeomPointInstancer
312  Get(const UsdStagePtr &stage, const SdfPath &path);
313 
314  /// Attempt to ensure a \a UsdPrim adhering to this schema at \p path
315  /// is defined (according to UsdPrim::IsDefined()) on this stage.
316  ///
317  /// If a prim adhering to this schema at \p path is already defined on this
318  /// stage, return that prim. Otherwise author an \a SdfPrimSpec with
319  /// \a specifier == \a SdfSpecifierDef and this schema's prim type name for
320  /// the prim at \p path at the current EditTarget. Author \a SdfPrimSpec s
321  /// with \p specifier == \a SdfSpecifierDef and empty typeName at the
322  /// current EditTarget for any nonexistent, or existing but not \a Defined
323  /// ancestors.
324  ///
325  /// The given \a path must be an absolute prim path that does not contain
326  /// any variant selections.
327  ///
328  /// If it is impossible to author any of the necessary PrimSpecs, (for
329  /// example, in case \a path cannot map to the current UsdEditTarget's
330  /// namespace) issue an error and return an invalid \a UsdPrim.
331  ///
332  /// Note that this method may return a defined prim whose typeName does not
333  /// specify this schema class, in case a stronger typeName opinion overrides
334  /// the opinion at the current EditTarget.
335  ///
337  static UsdGeomPointInstancer
338  Define(const UsdStagePtr &stage, const SdfPath &path);
339 
340 protected:
341  /// Returns the kind of schema this class belongs to.
342  ///
343  /// \sa UsdSchemaKind
345  UsdSchemaKind _GetSchemaKind() const override;
346 
347 private:
348  // needs to invoke _GetStaticTfType.
349  friend class UsdSchemaRegistry;
351  static const TfType &_GetStaticTfType();
352 
353  static bool _IsTypedSchema();
354 
355  // override SchemaBase virtuals.
357  const TfType &_GetTfType() const override;
358 
359 public:
360  // --------------------------------------------------------------------- //
361  // PROTOINDICES
362  // --------------------------------------------------------------------- //
363  /// <b>Required property</b>. Per-instance index into
364  /// \em prototypes relationship that identifies what geometry should be
365  /// drawn for each instance. <b>Topology attribute</b> - can be animated,
366  /// but at a potential performance impact for streaming.
367  ///
368  /// | ||
369  /// | -- | -- |
370  /// | Declaration | `int[] protoIndices` |
371  /// | C++ Type | VtArray<int> |
372  /// | \ref Usd_Datatypes "Usd Type" | SdfValueTypeNames->IntArray |
375 
376  /// See GetProtoIndicesAttr(), and also
377  /// \ref Usd_Create_Or_Get_Property for when to use Get vs Create.
378  /// If specified, author \p defaultValue as the attribute's default,
379  /// sparsely (when it makes sense to do so) if \p writeSparsely is \c true -
380  /// the default for \p writeSparsely is \c false.
382  UsdAttribute CreateProtoIndicesAttr(VtValue const &defaultValue = VtValue(), bool writeSparsely=false) const;
383 
384 public:
385  // --------------------------------------------------------------------- //
386  // IDS
387  // --------------------------------------------------------------------- //
388  /// Ids are optional; if authored, the ids array should be the same
389  /// length as the \em protoIndices array, specifying (at each timeSample if
390  /// instance identities are changing) the id of each instance. The
391  /// type is signed intentionally, so that clients can encode some
392  /// binary state on Id'd instances without adding a separate primvar.
393  /// See also \ref UsdGeomPointInstancer_varyingTopo
394  ///
395  /// | ||
396  /// | -- | -- |
397  /// | Declaration | `int64[] ids` |
398  /// | C++ Type | VtArray<int64_t> |
399  /// | \ref Usd_Datatypes "Usd Type" | SdfValueTypeNames->Int64Array |
401  UsdAttribute GetIdsAttr() const;
402 
403  /// See GetIdsAttr(), and also
404  /// \ref Usd_Create_Or_Get_Property for when to use Get vs Create.
405  /// If specified, author \p defaultValue as the attribute's default,
406  /// sparsely (when it makes sense to do so) if \p writeSparsely is \c true -
407  /// the default for \p writeSparsely is \c false.
409  UsdAttribute CreateIdsAttr(VtValue const &defaultValue = VtValue(), bool writeSparsely=false) const;
410 
411 public:
412  // --------------------------------------------------------------------- //
413  // POSITIONS
414  // --------------------------------------------------------------------- //
415  /// <b>Required property</b>. Per-instance position. See also
416  /// \ref UsdGeomPointInstancer_transform .
417  ///
418  /// | ||
419  /// | -- | -- |
420  /// | Declaration | `point3f[] positions` |
421  /// | C++ Type | VtArray<GfVec3f> |
422  /// | \ref Usd_Datatypes "Usd Type" | SdfValueTypeNames->Point3fArray |
425 
426  /// See GetPositionsAttr(), and also
427  /// \ref Usd_Create_Or_Get_Property for when to use Get vs Create.
428  /// If specified, author \p defaultValue as the attribute's default,
429  /// sparsely (when it makes sense to do so) if \p writeSparsely is \c true -
430  /// the default for \p writeSparsely is \c false.
432  UsdAttribute CreatePositionsAttr(VtValue const &defaultValue = VtValue(), bool writeSparsely=false) const;
433 
434 public:
435  // --------------------------------------------------------------------- //
436  // ORIENTATIONS
437  // --------------------------------------------------------------------- //
438  /// If authored, per-instance orientation of each instance about its
439  /// prototype's origin, represented as a unit length quaternion, which
440  /// allows us to encode it with sufficient precision in a compact GfQuath.
441  ///
442  /// It is client's responsibility to ensure that authored quaternions are
443  /// unit length; the convenience API below for authoring orientations from
444  /// rotation matrices will ensure that quaternions are unit length, though
445  /// it will not make any attempt to select the "better (for interpolation
446  /// with respect to neighboring samples)" of the two possible quaternions
447  /// that encode the rotation.
448  ///
449  /// See also \ref UsdGeomPointInstancer_transform .
450  ///
451  /// | ||
452  /// | -- | -- |
453  /// | Declaration | `quath[] orientations` |
454  /// | C++ Type | VtArray<GfQuath> |
455  /// | \ref Usd_Datatypes "Usd Type" | SdfValueTypeNames->QuathArray |
458 
459  /// See GetOrientationsAttr(), and also
460  /// \ref Usd_Create_Or_Get_Property for when to use Get vs Create.
461  /// If specified, author \p defaultValue as the attribute's default,
462  /// sparsely (when it makes sense to do so) if \p writeSparsely is \c true -
463  /// the default for \p writeSparsely is \c false.
465  UsdAttribute CreateOrientationsAttr(VtValue const &defaultValue = VtValue(), bool writeSparsely=false) const;
466 
467 public:
468  // --------------------------------------------------------------------- //
469  // ORIENTATIONSF
470  // --------------------------------------------------------------------- //
471  /// If authored, per-instance orientation of each instance about its
472  /// prototype's origin, represented as a unit length quaternion, encoded
473  /// as a GfQuatf to support higher precision computations.
474  ///
475  /// It is client's responsibility to ensure that authored quaternions are
476  /// unit length; the convenience API below for authoring orientations from
477  /// rotation matrices will ensure that quaternions are unit length, though
478  /// it will not make any attempt to select the "better (for interpolation
479  /// with respect to neighboring samples)" of the two possible quaternions
480  /// that encode the rotation. Note that if the earliest time sample (or
481  /// default value if there are no time samples) of orientationsf is not empty
482  /// orientationsf will be preferred over orientations if both are authored.
483  ///
484  /// See also \ref UsdGeomPointInstancer_transform .
485  ///
486  /// | ||
487  /// | -- | -- |
488  /// | Declaration | `quatf[] orientationsf` |
489  /// | C++ Type | VtArray<GfQuatf> |
490  /// | \ref Usd_Datatypes "Usd Type" | SdfValueTypeNames->QuatfArray |
493 
494  /// See GetOrientationsfAttr(), and also
495  /// \ref Usd_Create_Or_Get_Property for when to use Get vs Create.
496  /// If specified, author \p defaultValue as the attribute's default,
497  /// sparsely (when it makes sense to do so) if \p writeSparsely is \c true -
498  /// the default for \p writeSparsely is \c false.
500  UsdAttribute CreateOrientationsfAttr(VtValue const &defaultValue = VtValue(), bool writeSparsely=false) const;
501 
502 public:
503  // --------------------------------------------------------------------- //
504  // SCALES
505  // --------------------------------------------------------------------- //
506  /// If authored, per-instance scale to be applied to
507  /// each instance, before any rotation is applied.
508  ///
509  /// See also \ref UsdGeomPointInstancer_transform .
510  ///
511  /// | ||
512  /// | -- | -- |
513  /// | Declaration | `float3[] scales` |
514  /// | C++ Type | VtArray<GfVec3f> |
515  /// | \ref Usd_Datatypes "Usd Type" | SdfValueTypeNames->Float3Array |
517  UsdAttribute GetScalesAttr() const;
518 
519  /// See GetScalesAttr(), and also
520  /// \ref Usd_Create_Or_Get_Property for when to use Get vs Create.
521  /// If specified, author \p defaultValue as the attribute's default,
522  /// sparsely (when it makes sense to do so) if \p writeSparsely is \c true -
523  /// the default for \p writeSparsely is \c false.
525  UsdAttribute CreateScalesAttr(VtValue const &defaultValue = VtValue(), bool writeSparsely=false) const;
526 
527 public:
528  // --------------------------------------------------------------------- //
529  // VELOCITIES
530  // --------------------------------------------------------------------- //
531  /// If provided, per-instance 'velocities' will be used to
532  /// compute positions between samples for the 'positions' attribute,
533  /// rather than interpolating between neighboring 'positions' samples.
534  /// Velocities should be considered mandatory if both \em protoIndices
535  /// and \em positions are animated. Velocity is measured in position
536  /// units per second, as per most simulation software. To convert to
537  /// position units per UsdTimeCode, divide by
538  /// UsdStage::GetTimeCodesPerSecond().
539  ///
540  /// See also \ref UsdGeomPointInstancer_transform,
541  /// \ref UsdGeom_VelocityInterpolation .
542  ///
543  /// | ||
544  /// | -- | -- |
545  /// | Declaration | `vector3f[] velocities` |
546  /// | C++ Type | VtArray<GfVec3f> |
547  /// | \ref Usd_Datatypes "Usd Type" | SdfValueTypeNames->Vector3fArray |
550 
551  /// See GetVelocitiesAttr(), and also
552  /// \ref Usd_Create_Or_Get_Property for when to use Get vs Create.
553  /// If specified, author \p defaultValue as the attribute's default,
554  /// sparsely (when it makes sense to do so) if \p writeSparsely is \c true -
555  /// the default for \p writeSparsely is \c false.
557  UsdAttribute CreateVelocitiesAttr(VtValue const &defaultValue = VtValue(), bool writeSparsely=false) const;
558 
559 public:
560  // --------------------------------------------------------------------- //
561  // ACCELERATIONS
562  // --------------------------------------------------------------------- //
563  /// If authored, per-instance 'accelerations' will be used with
564  /// velocities to compute positions between samples for the 'positions'
565  /// attribute rather than interpolating between neighboring 'positions'
566  /// samples. Acceleration is measured in position units per second-squared.
567  /// To convert to position units per squared UsdTimeCode, divide by the
568  /// square of UsdStage::GetTimeCodesPerSecond().
569  ///
570  /// | ||
571  /// | -- | -- |
572  /// | Declaration | `vector3f[] accelerations` |
573  /// | C++ Type | VtArray<GfVec3f> |
574  /// | \ref Usd_Datatypes "Usd Type" | SdfValueTypeNames->Vector3fArray |
577 
578  /// See GetAccelerationsAttr(), and also
579  /// \ref Usd_Create_Or_Get_Property for when to use Get vs Create.
580  /// If specified, author \p defaultValue as the attribute's default,
581  /// sparsely (when it makes sense to do so) if \p writeSparsely is \c true -
582  /// the default for \p writeSparsely is \c false.
584  UsdAttribute CreateAccelerationsAttr(VtValue const &defaultValue = VtValue(), bool writeSparsely=false) const;
585 
586 public:
587  // --------------------------------------------------------------------- //
588  // ANGULARVELOCITIES
589  // --------------------------------------------------------------------- //
590  /// If authored, per-instance angular velocity vector to be used for
591  /// interoplating orientations. Angular velocities should be considered
592  /// mandatory if both \em protoIndices and \em orientations are animated.
593  /// Angular velocity is measured in <b>degrees</b> per second. To convert
594  /// to degrees per UsdTimeCode, divide by
595  /// UsdStage::GetTimeCodesPerSecond().
596  ///
597  /// See also \ref UsdGeomPointInstancer_transform .
598  ///
599  /// | ||
600  /// | -- | -- |
601  /// | Declaration | `vector3f[] angularVelocities` |
602  /// | C++ Type | VtArray<GfVec3f> |
603  /// | \ref Usd_Datatypes "Usd Type" | SdfValueTypeNames->Vector3fArray |
606 
607  /// See GetAngularVelocitiesAttr(), and also
608  /// \ref Usd_Create_Or_Get_Property for when to use Get vs Create.
609  /// If specified, author \p defaultValue as the attribute's default,
610  /// sparsely (when it makes sense to do so) if \p writeSparsely is \c true -
611  /// the default for \p writeSparsely is \c false.
613  UsdAttribute CreateAngularVelocitiesAttr(VtValue const &defaultValue = VtValue(), bool writeSparsely=false) const;
614 
615 public:
616  // --------------------------------------------------------------------- //
617  // INVISIBLEIDS
618  // --------------------------------------------------------------------- //
619  /// A list of id's to make invisible at the evaluation time.
620  /// See \ref UsdGeomPointInstancer_invisibleIds .
621  ///
622  /// | ||
623  /// | -- | -- |
624  /// | Declaration | `int64[] invisibleIds = []` |
625  /// | C++ Type | VtArray<int64_t> |
626  /// | \ref Usd_Datatypes "Usd Type" | SdfValueTypeNames->Int64Array |
629 
630  /// See GetInvisibleIdsAttr(), and also
631  /// \ref Usd_Create_Or_Get_Property for when to use Get vs Create.
632  /// If specified, author \p defaultValue as the attribute's default,
633  /// sparsely (when it makes sense to do so) if \p writeSparsely is \c true -
634  /// the default for \p writeSparsely is \c false.
636  UsdAttribute CreateInvisibleIdsAttr(VtValue const &defaultValue = VtValue(), bool writeSparsely=false) const;
637 
638 public:
639  // --------------------------------------------------------------------- //
640  // PROTOTYPES
641  // --------------------------------------------------------------------- //
642  /// <b>Required property</b>. Orders and targets the prototype root
643  /// prims, which can be located anywhere in the scenegraph that is convenient,
644  /// although we promote organizing prototypes as children of the
645  /// PointInstancer. The position of a prototype in this relationship defines
646  /// the value an instance would specify in the \em protoIndices attribute to
647  /// instance that prototype. Since relationships are uniform, this property
648  /// cannot be animated.
649  ///
652 
653  /// See GetPrototypesRel(), and also
654  /// \ref Usd_Create_Or_Get_Property for when to use Get vs Create
657 
658 public:
659  // ===================================================================== //
660  // Feel free to add custom code below this line, it will be preserved by
661  // the code generator.
662  //
663  // Just remember to:
664  // - Close the class declaration with };
665  // - Close the namespace with PXR_NAMESPACE_CLOSE_SCOPE
666  // - Close the include guard with #endif
667  // ===================================================================== //
668  // --(BEGIN CUSTOM CODE)--
669 
670  // --------------------------------------------------------------------- //
671  /// \name Id-based Instance Masking/Pruning
672  /// See \ref UsdGeomPointInstancer_masking
673  /// @{
674  // --------------------------------------------------------------------- //
675 
676  /// Ensure that the instance identified by \p id is active over all time.
677  /// This activation is encoded sparsely, affecting no other instances.
678  ///
679  /// This does not guarantee that the instance will be rendered, because
680  /// it may still be "invisible" due to \p id being present in the
681  /// \em invisibleIds attribute (see VisId(), InvisId())
683  bool ActivateId(int64_t id) const;
684 
685  /// Ensure that the instances identified by \p ids are active over all time.
686  /// This activation is encoded sparsely, affecting no other instances.
687  ///
688  /// This does not guarantee that the instances will be rendered, because
689  /// each may still be "invisible" due to its presence in the
690  /// \em invisibleIds attribute (see VisId(), InvisId())
692  bool ActivateIds(VtInt64Array const &ids) const;
693 
694  /// Ensure that all instances are active over all time.
695  ///
696  /// This does not guarantee that the instances will be rendered, because
697  /// each may still be "invisible" due to its presence in the
698  /// \em invisibleIds attribute (see VisId(), InvisId())
700  bool ActivateAllIds() const;
701 
702  /// Ensure that the instance identified by \p id is inactive over all time.
703  /// This deactivation is encoded sparsely, affecting no other instances.
704  ///
705  /// A deactivated instance is guaranteed not to render if the renderer
706  /// honors masking.
708  bool DeactivateId(int64_t id) const;
709 
710  /// Ensure that the instances identified by \p ids are inactive over all time.
711  /// This deactivation is encoded sparsely, affecting no other instances.
712  ///
713  /// A deactivated instance is guaranteed not to render if the renderer
714  /// honors masking.
716  bool DeactivateIds(VtInt64Array const &ids) const;
717 
718 
719  /// Ensure that the instance identified by \p id is visible at \p time.
720  /// This will cause \em invisibleIds to first be broken down (keyed)
721  /// at \p time, causing all animation in weaker layers that the current
722  /// UsdEditTarget to be overridden. Has no effect on any timeSamples other
723  /// than the one at \p time. If the \em invisibleIds attribute is not
724  /// authored or is blocked, this operation is a no-op.
725  ///
726  /// This does not guarantee that the instance will be rendered, because
727  /// it may still be "inactive" due to \p id being present in the
728  /// \em inactivevIds metadata (see ActivateId(), DeactivateId())
730  bool VisId(int64_t id, UsdTimeCode const &time) const;
731 
732  /// Ensure that the instances identified by \p ids are visible at \p time.
733  /// This will cause \em invisibleIds to first be broken down (keyed)
734  /// at \p time, causing all animation in weaker layers that the current
735  /// UsdEditTarget to be overridden. Has no effect on any timeSamples other
736  /// than the one at \p time. If the \em invisibleIds attribute is not
737  /// authored or is blocked, this operation is a no-op.
738  ///
739  /// This does not guarantee that the instances will be rendered, because
740  /// each may still be "inactive" due to \p id being present in the
741  /// \em inactivevIds metadata (see ActivateId(), DeactivateId())
743  bool VisIds(VtInt64Array const &ids, UsdTimeCode const &time) const;
744 
745  /// Ensure that all instances are visible at \p time.
746  /// Operates by authoring an empty array at \p time.
747  ///
748  /// This does not guarantee that the instances will be rendered, because
749  /// each may still be "inactive" due to its id being present in the
750  /// \em inactivevIds metadata (see ActivateId(), DeactivateId())
752  bool VisAllIds(UsdTimeCode const &time) const;
753 
754  /// Ensure that the instance identified by \p id is invisible at \p time.
755  /// This will cause \em invisibleIds to first be broken down (keyed)
756  /// at \p time, causing all animation in weaker layers that the current
757  /// UsdEditTarget to be overridden. Has no effect on any timeSamples other
758  /// than the one at \p time.
759  ///
760  /// An invised instance is guaranteed not to render if the renderer
761  /// honors masking.
763  bool InvisId(int64_t id, UsdTimeCode const &time) const;
764 
765  /// Ensure that the instances identified by \p ids are invisible at \p time.
766  /// This will cause \em invisibleIds to first be broken down (keyed)
767  /// at \p time, causing all animation in weaker layers that the current
768  /// UsdEditTarget to be overridden. Has no effect on any timeSamples other
769  /// than the one at \p time.
770  ///
771  /// An invised instance is guaranteed not to render if the renderer
772  /// honors masking.
774  bool InvisIds(VtInt64Array const &ids, UsdTimeCode const &time) const;
775 
776  /// Computes a presence mask to be applied to per-instance data arrays
777  /// based on authored \em inactiveIds, \em invisibleIds, and \em ids .
778  ///
779  /// If no \em ids attribute has been authored, then the values in
780  /// \em inactiveIds and \em invisibleIds will be interpreted directly
781  /// as indices of \em protoIndices .
782  ///
783  /// If \p ids is non-NULL, it is assumed to be the id-mapping to apply,
784  /// and must match the length of \em protoIndices at \p time .
785  /// If NULL, we will call GetIdsAttr().Get(time)
786  ///
787  /// \note If all "live" instances at UsdTimeCode \p time pass the mask,
788  /// we will return an <b>empty</b> mask so that clients can trivially
789  /// recognize the common "no masking" case.
790  ///
791  /// The returned mask can be used with ApplyMaskToArray(), and will contain
792  /// a \c true value for every element that should survive.
794  std::vector<bool> ComputeMaskAtTime(UsdTimeCode time,
795  VtInt64Array const *ids = nullptr) const;
796 
797  /// Contract \p dataArray in-place to contain only the elements whose
798  /// index in \p mask is \c true.
799  ///
800  /// \note an empty \p mask specifies "all pass", in which case \p dataArray
801  /// is trivially unmodified
802  ///
803  /// - It is an error for \p dataArray to be NULL .
804  /// - If \em elementSize times \em mask.size() does not equal
805  /// \em dataArray->size(), warn and fail.
806  ///
807  /// \return true on success, false on failure.
808  /// \sa ComputeMaskAtTime()
809  template <class T>
810  static bool ApplyMaskToArray(std::vector<bool> const &mask,
811  VtArray<T> *dataArray,
812  const int elementSize = 1);
813 
814  /// Determines if we should prefer orientationsf over orientations
815  /// based on whether or not orientationsf has been authored to a non
816  /// empty array. Assumes that orientationsf is empty if the earliest time
817  /// sample or default value if there are no time samples are empty
818  ///
819  /// \param rotationsAttr the outparameter for the corresponding attribute. If
820  /// this function returns true then orientationsf will be
821  /// stored in rotationsAttr, and orientations if not
823  bool UsesOrientationsf(UsdAttribute *rotationsAttr) const;
824 
825  /// \overload same functionality as
826  /// UsesOrientationsf(UsdAttribute &rotationsAttr) but populates a
827  /// TfToken instead
828  ///
829  /// \param rotationsToken (optional) the outparameter for the corresponding
830  /// attribute. If this function returns true then
831  /// UsdGeomTokens->orientationsf will be stored in UsdToken,
832  /// and UsdGeomTokens->orientations if not
834  bool UsesOrientationsf(TfToken *rotationsToken = nullptr) const;
835 
836  // --------------------------------------------------------------------- //
837  /// @}
838  // --------------------------------------------------------------------- //
839 
840  /// \enum ProtoXformInclusion
841  ///
842  /// Encodes whether to include each prototype's root prim's transformation
843  /// as the most-local component of computed instance transforms.
845  IncludeProtoXform, //!< Include the transform on the proto's root
846  ExcludeProtoXform //!< Exclude the transform on the proto's root
847  };
848 
849 
850  /// \enum MaskApplication
851  ///
852  /// Encodes whether to evaluate and apply the PointInstancer's
853  /// mask to computed results.
854  /// \sa ComputeMaskAtTime()
856  ApplyMask, //!< Compute and apply the PointInstancer mask
857  IgnoreMask //!< Ignore the PointInstancer mask
858  };
859 
860 
861  /// Compute the per-instance, "PointInstancer relative" transforms given
862  /// the positions, scales, orientations, velocities and angularVelocities
863  /// at \p time, as described in \ref UsdGeomPointInstancer_transform .
864  ///
865  /// This will return \c false and leave \p xforms untouched if:
866  /// - \p xforms is NULL
867  /// - one of \p time and \p baseTime is numeric and the other is
868  /// UsdTimeCode::Default() (they must either both be numeric or both be
869  /// default)
870  /// - there is no authored \em protoIndices attribute or \em positions
871  /// attribute
872  /// - the size of any of the per-instance attributes does not match the
873  /// size of \em protoIndices
874  /// - \p doProtoXforms is \c IncludeProtoXform but an index value in
875  /// \em protoIndices is outside the range [0, prototypes.size())
876  /// - \p applyMask is \c ApplyMask and a mask is set but the size of the
877  /// mask does not match the size of \em protoIndices.
878  ///
879  /// If there is no error, we will return \c true and \p xforms will contain
880  /// the computed transformations.
881  ///
882  /// \param xforms - the out parameter for the transformations. Its size
883  /// will depend on the authored data and \p applyMask
884  /// \param time - UsdTimeCode at which we want to evaluate the transforms
885  /// \param baseTime - required for correct interpolation between samples
886  /// when \em velocities or \em angularVelocities are
887  /// present. If there are samples for \em positions and
888  /// \em velocities at t1 and t2, normal value resolution
889  /// would attempt to interpolate between the two samples,
890  /// and if they could not be interpolated because they
891  /// differ in size (common in cases where velocity is
892  /// authored), will choose the sample at t1. When
893  /// sampling for the purposes of motion-blur, for example,
894  /// it is common, when rendering the frame at t2, to
895  /// sample at [ t2-shutter/2, t2+shutter/2 ] for a
896  /// shutter interval of \em shutter. The first sample
897  /// falls between t1 and t2, but we must sample at t2
898  /// and apply velocity-based interpolation based on those
899  /// samples to get a correct result. In such scenarios,
900  /// one should provide a \p baseTime of t2 when querying
901  /// \em both samples. If your application does not care
902  /// about off-sample interpolation, it can supply the
903  /// same value for \p baseTime that it does for \p time.
904  /// When \p baseTime is less than or equal to \p time,
905  /// we will choose the lower bracketing timeSample.
906  /// Selecting sample times with respect to baseTime will
907  /// be performed independently for positions and
908  /// orientations.
909  /// \param doProtoXforms - specifies whether to include the root
910  /// transformation of each instance's prototype in the
911  /// instance's transform. Default is to include it, but
912  /// some clients may want to apply the proto transform as
913  /// part of the prototype itself, so they can specify
914  /// \c ExcludeProtoXform instead.
915  /// \param applyMask - specifies whether to apply ApplyMaskToArray() to the
916  /// computed result. The default is \c ApplyMask.
918  bool
920  VtArray<GfMatrix4d>* xforms,
921  const UsdTimeCode time,
922  const UsdTimeCode baseTime,
923  const ProtoXformInclusion doProtoXforms = IncludeProtoXform,
924  const MaskApplication applyMask = ApplyMask) const;
925 
926  /// Compute the per-instance transforms as in
927  /// ComputeInstanceTransformsAtTime, but using multiple sample times. An
928  /// array of matrix arrays is returned where each matrix array contains the
929  /// instance transforms for the corresponding time in \p times .
930  ///
931  /// \param times - A vector containing the UsdTimeCodes at which we want to
932  /// sample.
934  bool
936  std::vector<VtArray<GfMatrix4d>>* xformsArray,
937  const std::vector<UsdTimeCode>& times,
938  const UsdTimeCode baseTime,
939  const ProtoXformInclusion doProtoXforms = IncludeProtoXform,
940  const MaskApplication applyMask = ApplyMask) const;
941 
942  /// \overload
943  /// Perform the per-instance transform computation as described in
944  /// \ref UsdGeomPointInstancer_transform . This does the same computation as
945  /// the non-static ComputeInstanceTransformsAtTime method, but takes all
946  /// data as parameters rather than accessing authored data.
947  ///
948  /// \param xforms - the out parameter for the transformations. Its size
949  /// will depend on the given data and \p applyMask
950  /// \param stage - the UsdStage
951  /// \param time - time at which we want to evaluate the transforms
952  /// \param protoIndices - array containing all instance prototype indices.
953  /// \param positions - array containing all instance positions. This array
954  /// must be the same size as \p protoIndices .
955  /// \param velocities - array containing all instance velocities. This array
956  /// must be either the same size as \p protoIndices or
957  /// empty. If it is empty, transforms are computed as if
958  /// all velocities were zero in all dimensions.
959  /// \param velocitiesSampleTime - time at which the samples from
960  /// \p velocities were taken.
961  /// \param accelerations - array containing all instance accelerations.
962  /// This array must be either the same size as
963  /// \p protoIndicesor empty. If it is empty, transforms
964  /// are computed as if all accelerations were zero in
965  /// all dimensions.
966  /// \param scales - array containing all instance scales. This array must be
967  /// either the same size as \p protoIndices or empty. If it
968  /// is empty, transforms are computed with no change in
969  /// scale.
970  /// \param orientations - array containing all instance orientations. This
971  /// array must be either the same size as
972  /// \p protoIndices or empty. If it is empty,
973  /// transforms are computed with no change in
974  /// orientation
975  /// \param angularVelocities - array containing all instance angular
976  /// velocities. This array must be either the
977  /// same size as \p protoIndices or empty. If it
978  /// is empty, transforms are computed as if all
979  /// angular velocities were zero in all
980  /// dimensions.
981  /// \param angularVelocitiesSampleTime - time at which the samples from
982  /// \p angularVelocities were taken.
983  /// \param protoPaths - array containing the paths for all instance
984  /// prototypes. If this array is not empty, prototype
985  /// transforms are applied to the instance transforms.
986  /// \param mask - vector containing a mask to apply to the computed result.
987  /// This vector must be either the same size as
988  /// \p protoIndices or empty. If it is empty, no mask is
989  /// applied.
990  /// \param velocityScale - \deprecated.
992  static bool
994  VtArray<GfMatrix4d>* xforms,
995  UsdStageWeakPtr& stage,
997  const VtIntArray& protoIndices,
998  const VtVec3fArray& positions,
999  const VtVec3fArray& velocities,
1000  UsdTimeCode velocitiesSampleTime,
1001  const VtVec3fArray& accelerations,
1002  const VtVec3fArray& scales,
1003  const VtQuatfArray& orientations,
1004  const VtVec3fArray& angularVelocities,
1005  UsdTimeCode angularVelocitiesSampleTime,
1006  const SdfPathVector& protoPaths,
1007  const std::vector<bool>& mask,
1008  float velocityScale = 1.0);
1009 
1010  /// \overload Perform the per-instance transform computation as described
1011  /// in \ref UsdGeomPointInstancer_transform . This does the same
1012  /// computation as the static ComputeInstanceTransformsAtTime method, but
1013  /// supports half precision rotations
1014  USDGEOM_API
1015  static bool
1017  VtArray<GfMatrix4d>* xforms,
1018  UsdStageWeakPtr& stage,
1019  UsdTimeCode time,
1020  const VtIntArray& protoIndices,
1021  const VtVec3fArray& positions,
1022  const VtVec3fArray& velocities,
1023  UsdTimeCode velocitiesSampleTime,
1024  const VtVec3fArray& accelerations,
1025  const VtVec3fArray& scales,
1026  const VtQuathArray& orientations,
1027  const VtVec3fArray& angularVelocities,
1028  UsdTimeCode angularVelocitiesSampleTime,
1029  const SdfPathVector& protoPaths,
1030  const std::vector<bool>& mask,
1031  float velocityScale = 1.0);
1032 
1033 private:
1034 
1035  // Get the authored prototype paths. Fail if there are no authored prototype
1036  // paths or the prototype indices are out of bounds.
1037  bool _GetPrototypePathsForInstanceTransforms(
1038  const VtIntArray& protoIndices,
1039  SdfPathVector* protoPaths) const;
1040 
1041  // Get the authored prototype indices for instance transform computation.
1042  // Fail if prototype indices are not authored.
1043  bool _GetProtoIndicesForInstanceTransforms(
1044  UsdTimeCode baseTime,
1045  VtIntArray* protoIndices) const;
1046 
1047  // Fetches data from attributes specific to UsdGeomPointInstancer
1048  // required for instance transform calculations; this includes
1049  // protoIndices, protoPaths, and the mask.
1050  bool _ComputePointInstancerAttributesPreamble(
1051  const UsdTimeCode baseTime,
1052  const ProtoXformInclusion doProtoXforms,
1053  const MaskApplication applyMask,
1054  VtIntArray* protoIndices,
1055  SdfPathVector* protoPaths,
1056  std::vector<bool>* mask) const;
1057 
1058  /// Compute the per-instance transforms as in
1059  /// ComputeInstanceTransformsAtTime, but using multiple sample times.
1060  /// Returns am array of matrix arrays where each matrix array contains the
1061  /// instance transforms for the corresponding time in \p times . Templated
1062  /// to support both full and half precision rotations.
1063  template<class QuatType>
1064  bool _DoComputeInstanceTransformsAtTimes(
1065  std::vector<VtArray<GfMatrix4d>>* xformsArray,
1066  const std::vector<UsdTimeCode>& times,
1067  const UsdTimeCode baseTime,
1068  const ProtoXformInclusion doProtoXforms,
1069  const MaskApplication applyMask,
1070  const UsdAttribute orientationsAttr) const;
1071 
1072  /// Helper implementation for static ComputeInstanceTransformsAtTime
1073  template <class QuatType>
1074  static bool _DoComputeInstanceTransformsAtTime(
1075  VtArray<GfMatrix4d>* xforms,
1076  UsdStageWeakPtr& stage,
1077  UsdTimeCode time,
1078  const VtIntArray& protoIndices,
1079  const VtVec3fArray& positions,
1080  const VtVec3fArray& velocities,
1081  UsdTimeCode velocitiesSampleTime,
1082  const VtVec3fArray& accelerations,
1083  const VtVec3fArray& scales,
1084  const VtArray<QuatType>& orientations,
1085  const VtVec3fArray& angularVelocities,
1086  UsdTimeCode angularVelocitiesSampleTime,
1087  const SdfPathVector& protoPaths,
1088  const std::vector<bool>& mask,
1089  float velocityScale = 1.0);
1090 
1091 public:
1092 
1093  /// Compute the extent of the point instancer based on the per-instance,
1094  /// "PointInstancer relative" transforms at \p time, as described in
1095  /// \ref UsdGeomPointInstancer_transform .
1096  ///
1097  /// If there is no error, we return \c true and \p extent will be the
1098  /// tightest bounds we can compute efficiently. If an error occurs,
1099  /// \c false will be returned and \p extent will be left untouched.
1100  ///
1101  /// For now, this uses a UsdGeomBBoxCache with the "default", "proxy", and
1102  /// "render" purposes.
1103  ///
1104  /// \param extent - the out parameter for the extent. On success, it will
1105  /// contain two elements representing the min and max.
1106  /// \param time - UsdTimeCode at which we want to evaluate the extent
1107  /// \param baseTime - required for correct interpolation between samples
1108  /// when \em velocities or \em angularVelocities are
1109  /// present. If there are samples for \em positions and
1110  /// \em velocities at t1 and t2, normal value resolution
1111  /// would attempt to interpolate between the two samples,
1112  /// and if they could not be interpolated because they
1113  /// differ in size (common in cases where velocity is
1114  /// authored), will choose the sample at t1. When
1115  /// sampling for the purposes of motion-blur, for example,
1116  /// it is common, when rendering the frame at t2, to
1117  /// sample at [ t2-shutter/2, t2+shutter/2 ] for a
1118  /// shutter interval of \em shutter. The first sample
1119  /// falls between t1 and t2, but we must sample at t2
1120  /// and apply velocity-based interpolation based on those
1121  /// samples to get a correct result. In such scenarios,
1122  /// one should provide a \p baseTime of t2 when querying
1123  /// \em both samples. If your application does not care
1124  /// about off-sample interpolation, it can supply the
1125  /// same value for \p baseTime that it does for \p time.
1126  /// When \p baseTime is less than or equal to \p time,
1127  /// we will choose the lower bracketing timeSample.
1128  USDGEOM_API
1129  bool ComputeExtentAtTime(
1130  VtVec3fArray* extent,
1131  const UsdTimeCode time,
1132  const UsdTimeCode baseTime) const;
1133 
1134  /// \overload
1135  /// Computes the extent as if the matrix \p transform was first applied.
1136  USDGEOM_API
1137  bool ComputeExtentAtTime(
1138  VtVec3fArray* extent,
1139  const UsdTimeCode time,
1140  const UsdTimeCode baseTime,
1141  const GfMatrix4d& transform) const;
1142 
1143  /// Compute the extent of the point instancer as in
1144  /// \ref ComputeExtentAtTime , but across multiple \p times . This is
1145  /// equivalent to, but more efficient than, calling ComputeExtentAtTime
1146  /// several times. Each element in \p extents is the computed extent at the
1147  /// corresponding time in \p times .
1148  ///
1149  /// As in \ref ComputeExtentAtTime, if there is no error, we return \c true
1150  /// and \p extents will be the tightest bounds we can compute efficiently.
1151  /// If an error occurs computing the extent at any time, \c false will be
1152  /// returned and \p extents will be left untouched.
1153  ///
1154  /// \param times - A vector containing the UsdTimeCodes at which we want to
1155  /// sample.
1156  USDGEOM_API
1157  bool ComputeExtentAtTimes(
1158  std::vector<VtVec3fArray>* extents,
1159  const std::vector<UsdTimeCode>& times,
1160  const UsdTimeCode baseTime) const;
1161 
1162  /// \overload
1163  /// Computes the extent as if the matrix \p transform was first applied at
1164  /// each time.
1165  USDGEOM_API
1166  bool ComputeExtentAtTimes(
1167  std::vector<VtVec3fArray>* extents,
1168  const std::vector<UsdTimeCode>& times,
1169  const UsdTimeCode baseTime,
1170  const GfMatrix4d& transform) const;
1171 
1172  /// Returns the number of instances as defined by the size of the
1173  /// _protoIndices_ array at _timeCode_.
1174  ///
1175  /// \snippetdoc snippets.dox GetCount
1176  /// \sa GetProtoIndicesAttr()
1177  USDGEOM_API
1178  size_t GetInstanceCount(UsdTimeCode timeCode = UsdTimeCode::Default()) const;
1179 
1180 private:
1181 
1182  bool _ComputeExtentAtTimePreamble(
1183  UsdTimeCode baseTime,
1184  VtIntArray* protoIndices,
1185  std::vector<bool>* mask,
1186  UsdRelationship* prototypes,
1187  SdfPathVector* protoPaths) const;
1188 
1189  bool _ComputeExtentFromTransforms(
1190  VtVec3fArray* extent,
1191  const VtIntArray& protoIndices,
1192  const std::vector<bool>& mask,
1193  const UsdRelationship& prototypes,
1194  const SdfPathVector& protoPaths,
1195  const VtMatrix4dArray& instanceTransforms,
1196  UsdTimeCode time,
1197  const GfMatrix4d* transform) const;
1198 
1199  bool _ComputeExtentAtTime(
1200  VtVec3fArray* extent,
1201  const UsdTimeCode time,
1202  const UsdTimeCode baseTime,
1203  const GfMatrix4d* transform) const;
1204 
1205  bool _ComputeExtentAtTimes(
1206  std::vector<VtVec3fArray>* extent,
1207  const std::vector<UsdTimeCode>& times,
1208  const UsdTimeCode baseTime,
1209  const GfMatrix4d* transform) const;
1210 };
1211 
1212 template <class T>
1213 bool
1215  VtArray<T> *dataArray,
1216  const int elementSize)
1217 {
1218  if (!dataArray) {
1219  TF_CODING_ERROR("NULL dataArray.");
1220  return false;
1221  }
1222  size_t maskSize = mask.size();
1223  if (maskSize == 0 || dataArray->size() == (size_t)elementSize){
1224  return true;
1225  }
1226  else if ((maskSize * elementSize) != dataArray->size()){
1227  TF_WARN("Input mask's size (%zu) is not compatible with the "
1228  "input dataArray (%zu) and elementSize (%d).",
1229  maskSize, dataArray->size(), elementSize);
1230  return false;
1231  }
1232 
1233  T* beginData = dataArray->data();
1234  T* currData = beginData;
1235  size_t numPreserved = 0;
1236  for (size_t i = 0; i < maskSize; ++i) {
1237  // XXX Could add a fast-path for elementSize == 1 ?
1238  if (mask[i]) {
1239  for (int j = 0; j < elementSize; ++j) {
1240  *currData = beginData[i + j];
1241  ++currData;
1242  }
1243  numPreserved += elementSize;
1244  }
1245  }
1246  if (numPreserved < dataArray->size()) {
1247  dataArray->resize(numPreserved);
1248  }
1249  return true;
1250 }
1251 
1252 /// Returns true if list ops should be composed with SdfListOp::ApplyOperations()
1253 /// Returns false if list ops should be composed with SdfListOp::ComposeOperations().
1255 bool
1257 
1258 /// Applies a list operation of type \p op using \p items
1259 /// over the existing list operation on \p prim with the name
1260 /// \p metadataName.
1261 USDGEOM_API
1262 bool
1263 UsdGeomPointInstancerSetOrMergeOverOp(std::vector<int64_t> const &items,
1264  SdfListOpType op,
1265  UsdPrim const &prim,
1266  TfToken const &metadataName);
1267 
1269 
1270 #endif
Exclude the transform on the proto's root.
UsdGeomPointInstancer(const UsdSchemaBase &schemaObj)
Compute and apply the PointInstancer mask.
USDGEOM_API UsdRelationship CreatePrototypesRel() const
USDGEOM_API bool DeactivateIds(VtInt64Array const &ids) const
static constexpr UsdTimeCode Default()
Definition: timeCode.h:113
USDGEOM_API bool ComputeExtentAtTimes(std::vector< VtVec3fArray > *extents, const std::vector< UsdTimeCode > &times, const UsdTimeCode baseTime) const
USDGEOM_API UsdAttribute CreateOrientationsAttr(VtValue const &defaultValue=VtValue(), bool writeSparsely=false) const
GT_API const UT_StringHolder time
#define PXR_NAMESPACE_OPEN_SCOPE
Definition: pxr.h:73
USDGEOM_API UsdAttribute CreatePositionsAttr(VtValue const &defaultValue=VtValue(), bool writeSparsely=false) const
USDGEOM_API UsdAttribute CreateIdsAttr(VtValue const &defaultValue=VtValue(), bool writeSparsely=false) const
GLsizei const GLchar *const * path
Definition: glcorearb.h:3341
#define TF_CODING_ERROR
static const UsdSchemaKind schemaKind
USDGEOM_API bool ActivateId(int64_t id) const
USDGEOM_API UsdRelationship GetPrototypesRel() const
USDGEOM_API UsdAttribute CreateAngularVelocitiesAttr(VtValue const &defaultValue=VtValue(), bool writeSparsely=false) const
UsdGeomPointInstancer(const UsdPrim &prim=UsdPrim())
USDGEOM_API UsdAttribute CreateAccelerationsAttr(VtValue const &defaultValue=VtValue(), bool writeSparsely=false) const
UsdStagePtr UsdStageWeakPtr
Definition: common.h:38
USDGEOM_API UsdAttribute CreateScalesAttr(VtValue const &defaultValue=VtValue(), bool writeSparsely=false) const
USDGEOM_API UsdAttribute CreateProtoIndicesAttr(VtValue const &defaultValue=VtValue(), bool writeSparsely=false) const
static bool ApplyMaskToArray(std::vector< bool > const &mask, VtArray< T > *dataArray, const int elementSize=1)
static USDGEOM_API const TfTokenVector & GetSchemaAttributeNames(bool includeInherited=true)
Definition: token.h:70
Represents a concrete typed schema.
USDGEOM_API UsdAttribute GetOrientationsAttr() const
USDGEOM_API UsdAttribute GetPositionsAttr() const
USDGEOM_API bool InvisIds(VtInt64Array const &ids, UsdTimeCode const &time) const
std::vector< class SdfPath > SdfPathVector
SdfListOpType
Definition: listOp.h:30
#define TF_WARN
USDGEOM_API size_t GetInstanceCount(UsdTimeCode timeCode=UsdTimeCode::Default()) const
USDGEOM_API bool UsdGeomPointInstancerSetOrMergeOverOp(std::vector< int64_t > const &items, SdfListOpType op, UsdPrim const &prim, TfToken const &metadataName)
GLint GLuint mask
Definition: glcorearb.h:124
USDGEOM_API UsdAttribute GetScalesAttr() const
USDGEOM_API UsdAttribute GetAccelerationsAttr() const
Definition: prim.h:116
virtual USDGEOM_API ~UsdGeomPointInstancer()
Destructor.
std::vector< TfToken > TfTokenVector
Convenience types.
Definition: token.h:440
USDGEOM_API bool ComputeExtentAtTime(VtVec3fArray *extent, const UsdTimeCode time, const UsdTimeCode baseTime) const
Definition: types.h:152
Definition: path.h:280
static USDGEOM_API UsdGeomPointInstancer Get(const UsdStagePtr &stage, const SdfPath &path)
USDGEOM_API std::vector< bool > ComputeMaskAtTime(UsdTimeCode time, VtInt64Array const *ids=nullptr) const
GA_API const UT_StringHolder transform
USDGEOM_API UsdSchemaKind _GetSchemaKind() const override
USDGEOM_API UsdAttribute CreateInvisibleIdsAttr(VtValue const &defaultValue=VtValue(), bool writeSparsely=false) const
USDGEOM_API bool UsdGeomPointInstancerApplyNewStyleListOps()
USDGEOM_API UsdAttribute GetVelocitiesAttr() const
UsdSchemaKind
Definition: common.h:112
GLint j
Definition: glad.h:2733
GLsizeiptr size
Definition: glcorearb.h:664
USDGEOM_API UsdAttribute GetAngularVelocitiesAttr() const
USDGEOM_API bool VisId(int64_t id, UsdTimeCode const &time) const
USDGEOM_API UsdAttribute GetInvisibleIdsAttr() const
USDGEOM_API bool ActivateAllIds() const
USDGEOM_API UsdAttribute GetOrientationsfAttr() const
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
USDGEOM_API bool InvisId(int64_t id, UsdTimeCode const &time) const
Definition: type.h:47
static USDGEOM_API UsdGeomPointInstancer Define(const UsdStagePtr &stage, const SdfPath &path)
USDGEOM_API bool VisIds(VtInt64Array const &ids, UsdTimeCode const &time) const
USDGEOM_API bool ActivateIds(VtInt64Array const &ids) const
USDGEOM_API UsdAttribute CreateVelocitiesAttr(VtValue const &defaultValue=VtValue(), bool writeSparsely=false) const
USDGEOM_API bool ComputeInstanceTransformsAtTime(VtArray< GfMatrix4d > *xforms, const UsdTimeCode time, const UsdTimeCode baseTime, const ProtoXformInclusion doProtoXforms=IncludeProtoXform, const MaskApplication applyMask=ApplyMask) const
#define USDGEOM_API
Definition: api.h:23
USDGEOM_API bool VisAllIds(UsdTimeCode const &time) const
USDGEOM_API UsdAttribute GetProtoIndicesAttr() const
Ignore the PointInstancer mask.
USDGEOM_API bool UsesOrientationsf(UsdAttribute *rotationsAttr) const
GLuint * ids
Definition: glcorearb.h:652
USDGEOM_API bool ComputeInstanceTransformsAtTimes(std::vector< VtArray< GfMatrix4d >> *xformsArray, const std::vector< UsdTimeCode > &times, const UsdTimeCode baseTime, const ProtoXformInclusion doProtoXforms=IncludeProtoXform, const MaskApplication applyMask=ApplyMask) const
Definition: value.h:89
USDGEOM_API UsdAttribute CreateOrientationsfAttr(VtValue const &defaultValue=VtValue(), bool writeSparsely=false) const
USDGEOM_API UsdAttribute GetIdsAttr() const
USDGEOM_API bool DeactivateId(int64_t id) const
Include the transform on the proto's root.