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