primvar.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_PRIMVAR_H
25 #define PXR_USD_USD_GEOM_PRIMVAR_H
26 
27 #include "pxr/pxr.h"
28 #include "pxr/usd/usdGeom/api.h"
29 #include "pxr/usd/usd/attribute.h"
30 #include "pxr/usd/usdGeom/tokens.h"
31 
32 #include <atomic>
33 #include <string>
34 #include <vector>
35 
36 PXR_NAMESPACE_OPEN_SCOPE
37 
38 
262 {
263 public:
264 
265  // Default constructor returns an invalid Primvar. Exists for
266  // container classes
268  {
269  /* NOTHING */
270  }
271 
273  USDGEOM_API
274  UsdGeomPrimvar(const UsdGeomPrimvar &other);
275 
277  USDGEOM_API
278  UsdGeomPrimvar &operator=(const UsdGeomPrimvar &other);
279 
289  USDGEOM_API
290  explicit UsdGeomPrimvar(const UsdAttribute &attr);
291 
297  USDGEOM_API
298  TfToken GetInterpolation() const;
299 
308  USDGEOM_API
309  bool SetInterpolation(const TfToken &interpolation);
310 
314  USDGEOM_API
315  bool HasAuthoredInterpolation() const;
316 
336  USDGEOM_API
337  int GetElementSize() const;
338 
344  USDGEOM_API
345  bool SetElementSize(int eltSize);
346 
350  USDGEOM_API
351  bool HasAuthoredElementSize() const;
352 
353 
358  USDGEOM_API
359  static bool IsPrimvar(const UsdAttribute &attr);
360 
361 
366  USDGEOM_API
367  static bool IsValidPrimvarName(const TfToken& name);
368 
371  USDGEOM_API
372  static TfToken StripPrimvarsName(const TfToken& name);
373 
376  USDGEOM_API
377  static bool IsValidInterpolation(const TfToken &interpolation);
378 
385  USDGEOM_API
386  void GetDeclarationInfo(TfToken *name, SdfValueTypeName *typeName,
387  TfToken *interpolation, int *elementSize) const;
388 
389  // ---------------------------------------------------------------
391  // ---------------------------------------------------------------
393 
397  operator UsdAttribute const& () const { return _attr; }
398 
400  UsdAttribute const &GetAttr() const { return _attr; }
401 
405  bool IsDefined() const { return IsPrimvar(_attr); }
406 
409  bool HasValue() const { return _attr.HasValue(); }
410 
413  bool HasAuthoredValue() const { return _attr.HasAuthoredValue(); }
414 
418  explicit operator bool() const {
419  return IsDefined() ? &UsdGeomPrimvar::_attr : 0;
420  }
421 
423  TfToken const &GetName() const { return _attr.GetName(); }
424 
431  USDGEOM_API
432  TfToken GetPrimvarName() const;
433 
440  USDGEOM_API
441  bool NameContainsNamespaces() const;
442 
444  TfToken GetBaseName() const { return _attr.GetBaseName(); }
445 
447  TfToken GetNamespace() const { return _attr.GetNamespace(); }
448 
450  std::vector<std::string> SplitName() const { return _attr.SplitName(); };
451 
453  SdfValueTypeName GetTypeName() const { return _attr.GetTypeName(); }
454 
459  template <typename T>
460  bool Get(T* value, UsdTimeCode time = UsdTimeCode::Default()) const {
461  return _attr.Get(value, time);
462  }
463 
465  template <typename T>
466  bool Set(const T& value, UsdTimeCode time = UsdTimeCode::Default()) const {
467  return _attr.Set(value, time);
468  }
469 
477  USDGEOM_API
478  bool GetTimeSamples(std::vector<double>* times) const;
479 
486  USDGEOM_API
487  bool GetTimeSamplesInInterval(const GfInterval& interval,
488  std::vector<double>* times) const;
489 
497  USDGEOM_API
498  bool ValueMightBeTimeVarying() const;
499 
501 
502  // ---------------------------------------------------------------
528 
535  USDGEOM_API
536  bool SetIndices(const VtIntArray &indices,
537  UsdTimeCode time = UsdTimeCode::Default()) const;
538 
543  USDGEOM_API
544  bool GetIndices(VtIntArray *indices,
545  UsdTimeCode time = UsdTimeCode::Default()) const;
546 
550  USDGEOM_API
551  void BlockIndices() const;
552 
558  USDGEOM_API
559  bool IsIndexed() const;
560 
563  USDGEOM_API
565 
568  USDGEOM_API
570 
583  USDGEOM_API
584  bool SetUnauthoredValuesIndex(int unauthoredValuesIndex) const;
585 
589  USDGEOM_API
590  int GetUnauthoredValuesIndex() const;
591 
598  template <typename ScalarType>
600  UsdTimeCode time = UsdTimeCode::Default()) const;
601 
609  USDGEOM_API
610  bool ComputeFlattened(VtValue *value,
611  UsdTimeCode time=UsdTimeCode::Default()) const;
612 
623  USDGEOM_API
624  static bool ComputeFlattened(VtValue *value, const VtValue &attrVal,
625  const VtIntArray &indices,
626  std::string *errString);
627 
628 
630 
631  // ---------------------------------------------------------------
661  // ---------------------------------------------------------------
662 
666  USDGEOM_API
667  bool IsIdTarget() const;
668 
673  USDGEOM_API
674  bool SetIdTarget(const SdfPath& path) const;
675 
677 
680  friend bool operator==(const UsdGeomPrimvar &lhs, const UsdGeomPrimvar &rhs) {
681  return lhs.GetAttr() == rhs.GetAttr();
682  }
683 
686  friend bool operator!=(const UsdGeomPrimvar &lhs, const UsdGeomPrimvar &rhs) {
687  return !(lhs == rhs);
688  }
689 
693  friend bool operator<(const UsdGeomPrimvar &lhs, const UsdGeomPrimvar &rhs) {
694  return lhs.GetAttr().GetPath() < rhs.GetAttr().GetPath();
695  }
696 
697  // Specialize TfHashAppend for TfHash
698  template <typename HashState>
699  friend void TfHashAppend(HashState& h, const UsdGeomPrimvar& obj) {
700  h.Append(obj.GetAttr());
701  }
702 
703  // hash_value overload for std/boost hash.
704  friend size_t hash_value(const UsdGeomPrimvar &obj) {
705  return TfHash{}(obj);
706  }
707 
708 
709 private:
710  friend class UsdGeomImageable;
711  friend class UsdGeomPrimvarsAPI;
712 
715  static bool _IsNamespaced(const TfToken& name);
716 
724  static TfToken _MakeNamespaced(const TfToken& name, bool quiet=false);
725 
726  static TfToken const &_GetNamespacePrefix();
727 
747  UsdGeomPrimvar(const UsdPrim& prim, const TfToken& attrName,
748  const SdfValueTypeName &typeName);
749 
750  UsdAttribute _attr;
751 
752  // Gets or creates the indices attribute corresponding to the primvar.
753  UsdAttribute _GetIndicesAttr(bool create) const;
754 
755  // Helper method for computing the flattened value of an indexed primvar.
756  template<typename ScalarType>
757  static bool _ComputeFlattenedHelper(const VtArray<ScalarType> &authored,
758  const VtIntArray &indices,
759  VtArray<ScalarType> *value,
760  std::string *errString);
761 
762  // Helper function to evaluate the flattened array value of a primvar given
763  // the attribute value and the indices array.
764  template <typename ArrayType>
765  static bool _ComputeFlattenedArray(const VtValue &attrVal,
766  const VtIntArray &indices,
767  VtValue *value,
768  std::string *errString);
769 
770  // Should only be called if _idTargetRelName is set
771  UsdRelationship _GetIdTargetRel(bool create) const;
772 
773  // Compute & cache whether or not this primvar can be an idtarget. After a
774  // call to this function, _idTargetStatus will be either IdTargetImpossible
775  // or IdTargetPossible. If the result is "possible" then _idTargetRelName
776  // will contain the relationship name. This function returns true if
777  // _idTargetStatus was set to IdTargetPossible, else false.
778  bool _ComputeIdTargetPossibility() const;
779 
780  enum _IdTargetStatus {
781  IdTargetUninitialized,
782  IdTargetInitializing,
783  IdTargetImpossible,
784  IdTargetPossible };
785 
786  mutable TfToken _idTargetRelName;
787  mutable std::atomic<_IdTargetStatus> _idTargetStatus;
788 };
789 
790 // We instantiate the following so we can check and provide the correct value
791 // for Id attributes.
792 template <>
793 USDGEOM_API bool UsdGeomPrimvar::Get(std::string* value, UsdTimeCode time) const;
794 
795 template <>
796 USDGEOM_API bool UsdGeomPrimvar::Get(VtStringArray* value, UsdTimeCode time) const;
797 
798 template <>
799 USDGEOM_API bool UsdGeomPrimvar::Get(VtValue* value, UsdTimeCode time) const;
800 
801 template <typename ScalarType>
802 bool
804 {
805  VtArray<ScalarType> authored;
806  if (!Get(&authored, time))
807  return false;
808 
809  if (!IsIndexed()) {
810  *value = authored;
811  return true;
812  }
813 
814  VtIntArray indices;
815  if (!GetIndices(&indices, time)) {
816  TF_WARN("No indices authored for indexed primvar <%s>.",
817  _attr.GetPath().GetText());
818  return false;
819  }
820 
821  // If the authored array is empty, there's nothing to do.
822  if (authored.empty())
823  return false;
824 
825  std::string errString;
826  bool res = _ComputeFlattenedHelper(authored, indices, value, &errString);
827  if (!errString.empty()) {
828  TF_WARN("For primvar %s: %s",
829  UsdDescribe(_attr).c_str(), errString.c_str());
830  }
831  return res;
832 }
833 
834 template<typename ScalarType>
835 bool
836 UsdGeomPrimvar::_ComputeFlattenedHelper(const VtArray<ScalarType> &authored,
837  const VtIntArray &indices,
838  VtArray<ScalarType> *value,
839  std::string *errString)
840 {
841  value->resize(indices.size());
842  bool success = true;
843 
844  std::vector<size_t> invalidIndexPositions;
845  for (size_t i=0; i < indices.size(); i++) {
846  int index = indices[i];
847  if (index >= 0 && (size_t)index < authored.size()) {
848  (*value)[i] = authored[index];
849  } else {
850  invalidIndexPositions.push_back(i);
851  success = false;
852  }
853  }
854 
855  if (!invalidIndexPositions.empty()) {
856  std::vector<std::string> invalidPositionsStrVec;
857  // Print a maximum of 5 invalid index positions.
858  size_t numElementsToPrint = std::min(invalidIndexPositions.size(),
859  size_t(5));
860  invalidPositionsStrVec.reserve(numElementsToPrint);
861  for (size_t i = 0; i < numElementsToPrint ; ++i) {
862  invalidPositionsStrVec.push_back(
863  TfStringify(invalidIndexPositions[i]));
864  }
865 
866  if (errString) {
867  *errString = TfStringPrintf(
868  "Found %ld invalid indices at positions [%s%s] that are out of "
869  "range [0,%ld).", invalidIndexPositions.size(),
870  TfStringJoin(invalidPositionsStrVec, ", ").c_str(),
871  invalidIndexPositions.size() > 5 ? ", ..." : "",
872  authored.size());
873  }
874  }
875 
876  return success;
877 }
878 
879 
880 PXR_NAMESPACE_CLOSE_SCOPE
881 
882 #endif // USD_PRIMVAR_H
USDGEOM_API bool SetElementSize(int eltSize)
Set the elementSize for this Primvar.
TF_API std::string TfStringPrintf(const char *fmt,...)
Returns a string formed by a printf()-like specification.
bool Get(T *value, UsdTimeCode time=UsdTimeCode::Default()) const
Perform value resolution to fetch the value of this attribute at the requested UsdTimeCode time,...
Definition: attribute.h:431
USDGEOM_API bool IsIdTarget() const
Returns true if the primvar is an Id primvar.
USDGEOM_API bool SetIndices(const VtIntArray &indices, UsdTimeCode time=UsdTimeCode::Default()) const
Sets the indices value of the indexed primvar at time.
friend bool operator!=(const UsdGeomPrimvar &lhs, const UsdGeomPrimvar &rhs)
Inequality comparison.
Definition: primvar.h:686
TfToken GetBaseName() const
Definition: primvar.h:444
bool Set(const T &value, UsdTimeCode time=UsdTimeCode::Default()) const
Set the attribute value of the Primvar at time.
Definition: primvar.h:466
USDGEOM_API void GetDeclarationInfo(TfToken *name, SdfValueTypeName *typeName, TfToken *interpolation, int *elementSize) const
Convenience function for fetching all information required to properly declare this Primvar.
USDGEOM_API bool HasAuthoredInterpolation() const
Has interpolation been explicitly authored on this Primvar?
size_t size() const
Return the total number of elements in this array.
Definition: array.h:490
#define TF_WARN(...)
Issue a warning, but continue execution.
Definition: diagnostic.h:149
USD_API bool HasValue() const
Return true if this attribute has an authored default value, authored time samples or a fallback valu...
USDGEOM_API bool NameContainsNamespaces() const
Does this primvar contain any namespaces other than the "primvars:" namespace?
static USDGEOM_API bool IsPrimvar(const UsdAttribute &attr)
Test whether a given UsdAttribute represents valid Primvar, which implies that creating a UsdGeomPrim...
std::vector< std::string > SplitName() const
Definition: primvar.h:450
Represents a value type name, i.e.
Definition: valueTypeName.h:87
SDF_API const char * GetText() const
Returns the string representation of this path as a c string.
Scenegraph object for authoring and retrieving numeric, string, and array valued data,...
Definition: attribute.h:176
USDGEOM_API UsdAttribute GetIndicesAttr() const
Returns a valid indices attribute if the primvar is indexed.
void resize(size_t newSize)
Resize this array.
Definition: array.h:559
USDGEOM_API TfToken GetInterpolation() const
Return the Primvar's interpolation, which is UsdGeomTokens->constant if unauthored.
USDGEOM_API void BlockIndices() const
Block the indices that were previously set.
USD_API std::string UsdDescribe(const UsdObject &)
Return a human-readable description.
A user-extensible hashing mechanism for use with runtime hash tables.
Definition: hash.h:504
UsdGeomPrimvarsAPI encodes geometric "primitive variables", as UsdGeomPrimvar, which interpolate acro...
Definition: primvarsAPI.h:82
USDGEOM_API bool SetInterpolation(const TfToken &interpolation)
Set the Primvar's interpolation.
Token for efficient comparison, assignment, and hashing of known strings.
Definition: token.h:87
bool ComputeFlattened(VtArray< ScalarType > *value, UsdTimeCode time=UsdTimeCode::Default()) const
Computes the flattened value of the primvar at time.
Definition: primvar.h:803
USDGEOM_API bool GetTimeSamples(std::vector< double > *times) const
Populates a vector with authored sample times for this primvar.
Represent a time value, which may be either numeric, holding a double value, or a sentinel value UsdT...
Definition: timeCode.h:84
SdfValueTypeName GetTypeName() const
Definition: primvar.h:453
USDGEOM_API bool SetUnauthoredValuesIndex(int unauthoredValuesIndex) const
Set the index that represents unauthored values in the indices array.
USD_API std::vector< std::string > SplitName() const
Return this property's name elements including namespaces and its base name as the final element.
USDGEOM_API int GetUnauthoredValuesIndex() const
Returns the index that represents unauthored values in the indices array.
UsdPrim is the sole persistent scenegraph object on a UsdStage, and is the embodiment of a "Prim" as ...
Definition: prim.h:135
A basic mathematical interval class.
Definition: interval.h:49
Represents an arbitrary dimensional rectangular container class.
Definition: array.h:229
A path value used to locate objects in layers or scenegraphs.
Definition: path.h:290
USDGEOM_API bool IsIndexed() const
Returns true if the primvar is indexed, i.e., if it has an associated "indices" attribute.
USDGEOM_API bool SetIdTarget(const SdfPath &path) const
This primvar must be of String or StringArray type for this method to succeed.
USDGEOM_API UsdAttribute CreateIndicesAttr() const
Returns the existing indices attribute if the primvar is indexed or creates a new one.
std::string TfStringJoin(ForwardIterator begin, ForwardIterator end, const char *separator=" ")
Concatenates the strings (begin, end), with default separator.
Definition: stringUtils.h:359
UsdAttribute const & GetAttr() const
Explicit UsdAttribute extractor.
Definition: primvar.h:400
bool Set(const T &value, UsdTimeCode time=UsdTimeCode::Default()) const
Set the value of this attribute in the current UsdEditTarget to value at UsdTimeCode time,...
Definition: attribute.h:472
A UsdRelationship creates dependencies between scenegraph objects by allowing a prim to target other ...
Definition: relationship.h:128
bool HasAuthoredValue() const
Return true if the underlying attribute has an unblocked, authored value.
Definition: primvar.h:413
USDGEOM_API bool HasAuthoredElementSize() const
Has elementSize been explicitly authored on this Primvar?
USDGEOM_API bool GetIndices(VtIntArray *indices, UsdTimeCode time=UsdTimeCode::Default()) const
Returns the value of the indices array associated with the indexed primvar at time.
USDGEOM_API int GetElementSize() const
Return the "element size" for this Primvar, which is 1 if unauthored.
TfToken GetNamespace() const
Definition: primvar.h:447
static USDGEOM_API bool IsValidPrimvarName(const TfToken &name)
Test whether a given name represents a valid name of a primvar, which implies that creating a UsdGeom...
static USDGEOM_API TfToken StripPrimvarsName(const TfToken &name)
Returns the name, devoid of the "primvars:" token if present, otherwise returns the name unchanged.
static constexpr UsdTimeCode Default()
Produce a UsdTimeCode representing the sentinel value for 'default'.
Definition: timeCode.h:112
const TfToken & GetName() const
Return the full name of this object, i.e.
Definition: object.h:238
bool empty() const
Return true if this array contains no elements, false otherwise.
Definition: array.h:516
bool HasValue() const
Return true if the underlying attribute has a value, either from authored scene description or a fall...
Definition: primvar.h:409
USDGEOM_API UsdGeomPrimvar & operator=(const UsdGeomPrimvar &other)
Copy assign.
bool Get(T *value, UsdTimeCode time=UsdTimeCode::Default()) const
Get the attribute value of the Primvar at time .
Definition: primvar.h:460
bool IsDefined() const
Return true if the underlying UsdAttribute::IsDefined(), and in addition the attribute is identified ...
Definition: primvar.h:405
Schema wrapper for UsdAttribute for authoring and introspecting attributes that are primvars.
Definition: primvar.h:261
std::enable_if<!std::is_enum< T >::value, std::string >::type TfStringify(const T &v)
Convert an arbitrary type into a string.
Definition: stringUtils.h:541
USDGEOM_API bool GetTimeSamplesInInterval(const GfInterval &interval, std::vector< double > *times) const
Populates a vector with authored sample times in interval.
USD_API SdfValueTypeName GetTypeName() const
Return the "scene description" value type name for this attribute.
TfToken const & GetName() const
Definition: primvar.h:423
USD_API TfToken GetBaseName() const
Return this property's name with all namespace prefixes removed, i.e.
friend bool operator==(const UsdGeomPrimvar &lhs, const UsdGeomPrimvar &rhs)
Equality comparison.
Definition: primvar.h:680
USD_API bool HasAuthoredValue() const
Return true if this attribute has either an authored default value or authored time samples.
Base class for all prims that may require rendering or visualization of some sort.
Definition: imageable.h:74
friend bool operator<(const UsdGeomPrimvar &lhs, const UsdGeomPrimvar &rhs)
Less-than operator.
Definition: primvar.h:693
Provides a container which may hold any type, and provides introspection and iteration over array typ...
Definition: value.h:166
static USDGEOM_API bool IsValidInterpolation(const TfToken &interpolation)
Validate that the provided interpolation is a valid setting for interpolation as defined by Interpola...
USD_API TfToken GetNamespace() const
Return this property's complete namespace prefix.
SdfPath GetPath() const
Return the complete scene path to this object on its UsdStage, which may (UsdPrim) or may not (all ot...
Definition: object.h:203
USDGEOM_API bool ValueMightBeTimeVarying() const
Return true if it is possible, but not certain, that this primvar's value changes over time,...
USDGEOM_API TfToken GetPrimvarName() const
Returns the primvar's name, devoid of the "primvars:" namespace.