All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
bboxCache.h
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 PXR_USD_USD_GEOM_BBOX_CACHE_H
25 #define PXR_USD_USD_GEOM_BBOX_CACHE_H
26 
27 #include "pxr/pxr.h"
28 #include "pxr/usd/usdGeom/api.h"
29 #include "pxr/usd/usdGeom/xformCache.h"
30 #include "pxr/usd/usdGeom/pointInstancer.h"
31 #include "pxr/usd/usd/attributeQuery.h"
32 #include "pxr/base/gf/bbox3d.h"
33 #include "pxr/base/tf/hashmap.h"
34 #include "pxr/base/work/arenaDispatcher.h"
35 
36 #include <boost/optional.hpp>
37 #include <boost/shared_array.hpp>
38 
39 PXR_NAMESPACE_OPEN_SCOPE
40 
41 
42 class UsdGeomModelAPI;
43 
88 {
89 public:
107  USDGEOM_API
108  UsdGeomBBoxCache(UsdTimeCode time, TfTokenVector includedPurposes,
109  bool useExtentsHint=false, bool ignoreVisibility=false);
110 
112  USDGEOM_API
113  UsdGeomBBoxCache(UsdGeomBBoxCache const &other);
114 
116  USDGEOM_API
117  UsdGeomBBoxCache &operator=(UsdGeomBBoxCache const &other);
118 
128  USDGEOM_API
129  GfBBox3d ComputeWorldBound(const UsdPrim& prim);
130 
138  USDGEOM_API
140  const UsdPrim &relativeToAncestorPrim);
141 
150  USDGEOM_API
151  GfBBox3d ComputeLocalBound(const UsdPrim& prim);
152 
163  USDGEOM_API
165 
182  USDGEOM_API
184  const UsdPrim &prim,
185  const SdfPathSet &pathsToSkip,
186  const TfHashMap<SdfPath, GfMatrix4d, SdfPath::Hash> &ctmOverrides);
187 
193  USDGEOM_API
194  bool
196  const UsdGeomPointInstancer& instancer,
197  int64_t const *instanceIdBegin,
198  size_t numIds,
199  GfBBox3d *result);
200 
203  GfBBox3d
205  const UsdGeomPointInstancer& instancer, int64_t instanceId) {
206  GfBBox3d ret;
207  ComputePointInstanceWorldBounds(instancer, &instanceId, 1, &ret);
208  return ret;
209  }
210 
221  USDGEOM_API
222  bool
224  const UsdGeomPointInstancer &instancer,
225  int64_t const *instanceIdBegin,
226  size_t numIds,
227  const UsdPrim &relativeToAncestorPrim,
228  GfBBox3d *result);
229 
232  GfBBox3d
234  const UsdGeomPointInstancer &instancer,
235  int64_t instanceId,
236  const UsdPrim &relativeToAncestorPrim) {
237  GfBBox3d ret;
239  instancer, &instanceId, 1, relativeToAncestorPrim, &ret);
240  return ret;
241  }
242 
251  USDGEOM_API
252  bool
254  const UsdGeomPointInstancer& instancer,
255  int64_t const *instanceIdBegin,
256  size_t numIds,
257  GfBBox3d *result);
258 
260  GfBBox3d
262  const UsdGeomPointInstancer& instancer,
263  int64_t instanceId) {
264  GfBBox3d ret;
265  ComputePointInstanceLocalBounds(instancer, &instanceId, 1, &ret);
266  return ret;
267  }
268 
269 
280  USDGEOM_API
281  bool
283  const UsdGeomPointInstancer& instancer,
284  int64_t const *instanceIdBegin,
285  size_t numIds,
286  GfBBox3d *result);
287 
290  GfBBox3d
292  const UsdGeomPointInstancer& instancer,
293  int64_t instanceId) {
294  GfBBox3d ret;
296  instancer, &instanceId, 1, &ret);
297  return ret;
298  }
299 
301  USDGEOM_API
302  void Clear();
303 
312  USDGEOM_API
313  void SetIncludedPurposes(const TfTokenVector& includedPurposes);
314 
316  const TfTokenVector& GetIncludedPurposes() { return _includedPurposes; }
317 
320  bool GetUseExtentsHint() const {
321  return _useExtentsHint;
322  }
323 
326  bool GetIgnoreVisibility() const {
327  return _ignoreVisibility;
328  }
329 
333  USDGEOM_API
334  void SetTime(UsdTimeCode time);
335 
337  UsdTimeCode GetTime() const { return _time; }
338 
347  void SetBaseTime(UsdTimeCode baseTime) {
348  _baseTime = baseTime;
349  }
350 
354  return _baseTime.get_value_or(GetTime());
355  }
356 
359  void ClearBaseTime() {
360  _baseTime = boost::none;
361  }
362 
365  bool HasBaseTime() const {
366  return static_cast<bool>(_baseTime);
367  }
368 
369 private:
370  // Worker task.
371  class _BBoxTask;
372 
373  // Helper object for computing bounding boxes for instance masters.
374  class _MasterBBoxResolver;
375 
376  // Map of purpose tokens to associated bboxes.
377  typedef std::map<TfToken, GfBBox3d, TfTokenFastArbitraryLessThan>
378  _PurposeToBBoxMap;
379 
380  // Each individual prim will have it's own entry in the bbox cache.
381  // When instancing is involved we store the master prims and their children
382  // in the cache for use by each prim that instances each master.
383  // However, because of the way we compute and inherit purpose, we may end
384  // up needed to compute multitple different bboxes for masters and their
385  // children if the prims that instance them would cause these masters to
386  // inherit a different purpose value when the prims under the master don't
387  // have an authored purpose of their own.
388  //
389  // This struct is here to represent a prim and the purpose that it would
390  // inherit from the prim that instances it. It is used as the key for the
391  // map of prim's to the cached entries, allowing prim's in masters to have
392  // more than one bbox cache entry for each distinct context needed to
393  // appropriately compute for all instances. instanceInheritablePurpose will
394  // always be empty for prims that aren't masters or children of masters,
395  // meaning that prims not in masters will only have one context each.
396  struct _PrimContext {
397  // The prim itself
398  UsdPrim prim;
399 
400  // The purpose that would be inherited from the instancing prim if this
401  // prim does not have an explicit purpose.
402  TfToken instanceInheritablePurpose;
403 
404  _PrimContext() = default;
405  explicit _PrimContext(const UsdPrim &prim_,
406  const TfToken &purpose = TfToken())
407  : prim(prim_), instanceInheritablePurpose(purpose) {};
408 
409  bool operator==(const _PrimContext &rhs) const {
410  return prim == rhs.prim &&
411  instanceInheritablePurpose == rhs.instanceInheritablePurpose;
412  }
413 
414  // Convenience stringify for debugging.
415  std::string ToString() const;
416  };
417 
418  bool
419  _ComputePointInstanceBoundsHelper(
420  const UsdGeomPointInstancer &instancer,
421  int64_t const *instanceIdBegin,
422  size_t numIds,
423  GfMatrix4d const &xform,
424  GfBBox3d *result);
425 
426  // Returns true if the \p prim should be included during child bounds
427  // accumulation.
428  bool _ShouldIncludePrim(const UsdPrim& prim);
429 
430  // True if \p attr or \p query may return different values given different
431  // time queries. Note that a true result implies the attribute may have no
432  // value, a default value or a single time sample value.
433  bool _IsVarying(const UsdAttribute& attr);
434  bool _IsVarying(const UsdAttributeQuery& query);
435 
436  // Populate the local bbox for the requested prim, without the
437  // local-to-world transform or local transform applied. Return true when
438  // bbox volume > 0.
439  bool _Resolve(const UsdPrim& prim, _PurposeToBBoxMap *bboxes);
440 
441  // Compute the extent of a UsdGeomBoundable object. Return true if the
442  // computation succeeds and false on failure.
443  bool _ComputeExtent(
444  const UsdGeomBoundable& boundableObj,
445  VtVec3fArray* extent) const;
446 
447  // Resolves a single prim. This method must be thread safe. Assumes the
448  // cache entry has been created for \p prim.
449  //
450  // \p inverseComponentCtm is used to combine all the child bboxes in
451  // component-relative space.
452  void _ResolvePrim(_BBoxTask* task,
453  const _PrimContext& prim,
454  const GfMatrix4d &inverseComponentCtm);
455 
456  struct _Entry {
457  _Entry()
458  : isComplete(false)
459  , isVarying(false)
460  , isIncluded(false)
461  { }
462 
463  // The cached bboxes for the various values of purpose token.
464  _PurposeToBBoxMap bboxes;
465 
466  // True when data in the entry is valid.
467  bool isComplete;
468 
469  // True when the entry varies over time.
470  bool isVarying;
471 
472  // True when the entry is visible.
473  bool isIncluded;
474 
475  // Computed purpose info of the prim that's associated with the entry.
476  // This data includes the prim's actual computed purpose as well as
477  // whether this purpose is inheritable by child prims.
478  UsdGeomImageable::PurposeInfo purposeInfo;
479 
480  // Queries for attributes that need to be re-computed at each
481  // time for this entry. This will be invalid for non-varying entries.
482  boost::shared_array<UsdAttributeQuery> queries;
483  };
484 
485  // Returns the cache entry for the given \p prim if one already exists.
486  // If no entry exists, creates (but does not resolve) entries for
487  // \p prim and all of its descendents. In this case, the master prims
488  // whose bounding boxes need to be resolved in order to resolve \p prim
489  // will be returned in \p masterPrims.
490  _Entry* _FindOrCreateEntriesForPrim(
491  const _PrimContext& prim,
492  std::vector<_PrimContext> *masterPrimContexts);
493 
494  // Returns the combined bounding box for the currently included set of
495  // purposes given a _PurposeToBBoxMap.
496  GfBBox3d _GetCombinedBBoxForIncludedPurposes(
497  const _PurposeToBBoxMap &bboxes);
498 
499  // Populates \p bbox with the bounding box computed from the authored
500  // extents hint. Based on the included purposes, the extents in the
501  // extentsHint attribute are combined together to compute the bounding box.
502  bool _GetBBoxFromExtentsHint(
503  const UsdGeomModelAPI &geomModel,
504  const UsdAttributeQuery &extentsHintQuery,
505  _PurposeToBBoxMap *bboxes);
506 
507  // Returns whether the children of the given prim can be pruned
508  // from the traversal to pre-populate entries.
509  bool _ShouldPruneChildren(const UsdPrim &prim, _Entry *entry);
510 
511  // Helper function for computing a prim's purpose info efficiently by
512  // using the parent entry's cached computed purpose info and caching it
513  // its cache entry.
514  // Optionally this can recursively compute and cache the purposes for any
515  // existing parent entries in the cache that haven't had their purposes
516  // computed yet.
517  template <bool IsRecursive>
518  void _ComputePurposeInfo(_Entry *entry, const _PrimContext &prim);
519 
520  // Helper to determine if we should use extents hints for \p prim.
521  inline bool _UseExtentsHintForPrim(UsdPrim const &prim) const;
522 
523  // Need hash_value for boost to key cache entries by prim context.
524  friend size_t hash_value(const _PrimContext &key);
525 
526  typedef boost::hash<_PrimContext> _PrimContextHash;
527  typedef TfHashMap<_PrimContext, _Entry, _PrimContextHash> _PrimBBoxHashMap;
528 
529  // Finds the cache entry for the prim context if it exists.
530  _Entry *_FindEntry(const _PrimContext &primContext)
531  {
532  return TfMapLookupPtr(_bboxCache, primContext);
533  }
534 
535  // Returns the cache entry for the prim context, adding it if doesn't
536  // exist.
537  _Entry *_InsertEntry(const _PrimContext &primContext)
538  {
539  return &(_bboxCache[primContext]);
540  }
541 
542  WorkArenaDispatcher _dispatcher;
543  UsdTimeCode _time;
544  boost::optional<UsdTimeCode> _baseTime;
545  TfTokenVector _includedPurposes;
546  UsdGeomXformCache _ctmCache;
547  _PrimBBoxHashMap _bboxCache;
548  bool _useExtentsHint;
549  bool _ignoreVisibility;
550 };
551 
552 
553 PXR_NAMESPACE_CLOSE_SCOPE
554 
555 #endif // PXR_USD_USD_GEOM_BBOX_CACHE_H
USDGEOM_API UsdGeomBBoxCache & operator=(UsdGeomBBoxCache const &other)
Copy assignment.
UsdGeomModelAPI extends the generic UsdModelAPI schema with geometry specific concepts such as cached...
Definition: modelAPI.h:146
USDGEOM_API bool ComputePointInstanceLocalBounds(const UsdGeomPointInstancer &instancer, int64_t const *instanceIdBegin, size_t numIds, GfBBox3d *result)
Compute the oriented bounding boxes of the given point instances.
Object for efficiently making repeated queries for attribute values.
const TfTokenVector & GetIncludedPurposes()
Get the current set of included purposes.
Definition: bboxCache.h:316
UsdTimeCode GetTime() const
Get the current time from which this cache is reading values.
Definition: bboxCache.h:337
void ClearBaseTime()
Clear this cache&#39;s baseTime if one has been set.
Definition: bboxCache.h:359
bool HasBaseTime() const
Return true if this cache has a baseTime that&#39;s been explicitly set, false otherwise.
Definition: bboxCache.h:365
Caches bounds by recursively computing and aggregating bounds of children in world space and aggregat...
Definition: bboxCache.h:87
Scenegraph object for authoring and retrieving numeric, string, and array valued data, sampled over time.
Definition: attribute.h:176
USDGEOM_API void Clear()
Clears all pre-cached values.
GfBBox3d ComputePointInstanceRelativeBound(const UsdGeomPointInstancer &instancer, int64_t instanceId, const UsdPrim &relativeToAncestorPrim)
Compute the bound of the given point instance in the space of an ancestor prim relativeToAncestorPrim...
Definition: bboxCache.h:233
Token for efficient comparison, assignment, and hashing of known strings.
Definition: token.h:87
void SetBaseTime(UsdTimeCode baseTime)
Set the base time value for this bbox cache.
Definition: bboxCache.h:347
Stores a 4x4 matrix of double elements.
Definition: matrix4d.h:88
Represent a time value, which may be either numeric, holding a double value, or a sentinel value UsdT...
Definition: timeCode.h:85
USDGEOM_API bool ComputePointInstanceUntransformedBounds(const UsdGeomPointInstancer &instancer, int64_t const *instanceIdBegin, size_t numIds, GfBBox3d *result)
Computes the bound of the given point instances, but does not include the transform (if any) authored...
Value type containing information about a prim&#39;s computed effective purpose as well as storing whethe...
Definition: imageable.h:391
Boundable introduces the ability for a prim to persistently cache a rectilinear, local-space, extent.
Definition: boundable.h:82
UsdPrim is the sole persistent scenegraph object on a UsdStage, and is the embodiment of a &quot;Prim&quot; as ...
Definition: prim.h:132
USDGEOM_API GfBBox3d ComputeWorldBound(const UsdPrim &prim)
Compute the bound of the given prim in world space, leveraging any pre-existing, cached bounds...
std::vector< TfToken > TfTokenVector
Convenience types.
Definition: token.h:431
USDGEOM_API bool ComputePointInstanceWorldBounds(const UsdGeomPointInstancer &instancer, int64_t const *instanceIdBegin, size_t numIds, GfBBox3d *result)
Compute the bound of the given point instances in world space.
GfBBox3d ComputePointInstanceUntransformedBound(const UsdGeomPointInstancer &instancer, int64_t instanceId)
Computes the bound of the given point instances, but does not include the instancer&#39;s transform...
Definition: bboxCache.h:291
USDGEOM_API GfBBox3d ComputeRelativeBound(const UsdPrim &prim, const UsdPrim &relativeToAncestorPrim)
Compute the bound of the given prim in the space of an ancestor prim, relativeToAncestorPrim, leveraging any pre-existing cached bounds.
Container::mapped_type * TfMapLookupPtr(Container &map, Key const &key)
Checks if an item exists in a map or TfHashMap, without copying it.
Definition: stl.h:143
USDGEOM_API bool ComputePointInstanceRelativeBounds(const UsdGeomPointInstancer &instancer, int64_t const *instanceIdBegin, size_t numIds, const UsdPrim &relativeToAncestorPrim, GfBBox3d *result)
Compute the bounds of the given point instances in the space of an ancestor prim relativeToAncestorPr...
USDGEOM_API GfBBox3d ComputeLocalBound(const UsdPrim &prim)
Computes the oriented bounding box of the given prim, leveraging any pre-existing, cached bounds.
USDGEOM_API UsdGeomBBoxCache(UsdTimeCode time, TfTokenVector includedPurposes, bool useExtentsHint=false, bool ignoreVisibility=false)
Construct a new BBoxCache for a specific time and set of includedPurposes.
GfBBox3d ComputePointInstanceLocalBound(const UsdGeomPointInstancer &instancer, int64_t instanceId)
Compute the oriented bounding boxes of the given point instances.
Definition: bboxCache.h:261
GfBBox3d ComputePointInstanceWorldBound(const UsdGeomPointInstancer &instancer, int64_t instanceId)
Compute the bound of the given point instance in world space.
Definition: bboxCache.h:204
bool GetIgnoreVisibility() const
Returns whether prim visibility should be ignored when computing bounding boxes.
Definition: bboxCache.h:326
This is a specialization of the WorkDispatcher that uses an isolated arena to Run() all its tasks in...
UsdTimeCode GetBaseTime() const
Return the base time if set, otherwise GetTime().
Definition: bboxCache.h:353
Encodes vectorized instancing of multiple, potentially animated, prototypes (object/instance masters)...
VT_API bool operator==(VtDictionary const &, VtDictionary const &)
Equality comparison.
USDGEOM_API void SetTime(UsdTimeCode time)
Use the new time when computing values and may clear any existing values cached for the previous time...
USDGEOM_API GfBBox3d ComputeUntransformedBound(const UsdPrim &prim)
Computes the bound of the prim&#39;s children leveraging any pre-existing, cached bounds, but does not include the transform (if any) authored on the prim itself.
USDGEOM_API void SetIncludedPurposes(const TfTokenVector &includedPurposes)
Indicate the set of includedPurposes to use when resolving child bounds.
bool GetUseExtentsHint() const
Returns whether authored extent hints are used to compute bounding boxes.
Definition: bboxCache.h:320
Basic type: arbitrarily oriented 3D bounding box.
Definition: bbox3d.h:84
A caching mechanism for transform matrices.
Definition: xformCache.h:58