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  // hash_value overload for std/boost hash.
698  USDGEOM_API
699  friend size_t hash_value(const UsdGeomPrimvar &obj) {
700  return hash_value(obj.GetAttr());
701  }
702 
703 
704 private:
705  friend class UsdGeomImageable;
706  friend class UsdGeomPrimvarsAPI;
707 
710  static bool _IsNamespaced(const TfToken& name);
711 
719  static TfToken _MakeNamespaced(const TfToken& name, bool quiet=false);
720 
721  static TfToken const &_GetNamespacePrefix();
722 
742  UsdGeomPrimvar(const UsdPrim& prim, const TfToken& attrName,
743  const SdfValueTypeName &typeName);
744 
745  UsdAttribute _attr;
746 
747  // Gets or creates the indices attribute corresponding to the primvar.
748  UsdAttribute _GetIndicesAttr(bool create) const;
749 
750  // Helper method for computing the flattened value of an indexed primvar.
751  template<typename ScalarType>
752  static bool _ComputeFlattenedHelper(const VtArray<ScalarType> &authored,
753  const VtIntArray &indices,
754  VtArray<ScalarType> *value,
755  std::string *errString);
756 
757  // Helper function to evaluate the flattened array value of a primvar given
758  // the attribute value and the indices array.
759  template <typename ArrayType>
760  static bool _ComputeFlattenedArray(const VtValue &attrVal,
761  const VtIntArray &indices,
762  VtValue *value,
763  std::string *errString);
764 
765  // Should only be called if _idTargetRelName is set
766  UsdRelationship _GetIdTargetRel(bool create) const;
767 
768  // Compute & cache whether or not this primvar can be an idtarget. After a
769  // call to this function, _idTargetStatus will be either IdTargetImpossible
770  // or IdTargetPossible. If the result is "possible" then _idTargetRelName
771  // will contain the relationship name. This function returns true if
772  // _idTargetStatus was set to IdTargetPossible, else false.
773  bool _ComputeIdTargetPossibility() const;
774 
775  enum _IdTargetStatus {
776  IdTargetUninitialized,
777  IdTargetInitializing,
778  IdTargetImpossible,
779  IdTargetPossible };
780 
781  mutable TfToken _idTargetRelName;
782  mutable std::atomic<_IdTargetStatus> _idTargetStatus;
783 };
784 
785 // We instantiate the following so we can check and provide the correct value
786 // for Id attributes.
787 template <>
788 USDGEOM_API bool UsdGeomPrimvar::Get(std::string* value, UsdTimeCode time) const;
789 
790 template <>
791 USDGEOM_API bool UsdGeomPrimvar::Get(VtStringArray* value, UsdTimeCode time) const;
792 
793 template <>
794 USDGEOM_API bool UsdGeomPrimvar::Get(VtValue* value, UsdTimeCode time) const;
795 
796 template <typename ScalarType>
797 bool
799 {
800  VtArray<ScalarType> authored;
801  if (!Get(&authored, time))
802  return false;
803 
804  if (!IsIndexed()) {
805  *value = authored;
806  return true;
807  }
808 
809  VtIntArray indices;
810  if (!GetIndices(&indices, time)) {
811  TF_WARN("No indices authored for indexed primvar <%s>.",
812  _attr.GetPath().GetText());
813  return false;
814  }
815 
816  // If the authored array is empty, there's nothing to do.
817  if (authored.empty())
818  return false;
819 
820  std::string errString;
821  bool res = _ComputeFlattenedHelper(authored, indices, value, &errString);
822  if (!errString.empty()) {
823  TF_WARN("For primvar %s: %s",
824  UsdDescribe(_attr).c_str(), errString.c_str());
825  }
826  return res;
827 }
828 
829 template<typename ScalarType>
830 bool
831 UsdGeomPrimvar::_ComputeFlattenedHelper(const VtArray<ScalarType> &authored,
832  const VtIntArray &indices,
833  VtArray<ScalarType> *value,
834  std::string *errString)
835 {
836  value->resize(indices.size());
837  bool success = true;
838 
839  std::vector<size_t> invalidIndexPositions;
840  for (size_t i=0; i < indices.size(); i++) {
841  int index = indices[i];
842  if (index >= 0 && (size_t)index < authored.size()) {
843  (*value)[i] = authored[index];
844  } else {
845  invalidIndexPositions.push_back(i);
846  success = false;
847  }
848  }
849 
850  if (!invalidIndexPositions.empty()) {
851  std::vector<std::string> invalidPositionsStrVec;
852  // Print a maximum of 5 invalid index positions.
853  size_t numElementsToPrint = std::min(invalidIndexPositions.size(),
854  size_t(5));
855  invalidPositionsStrVec.reserve(numElementsToPrint);
856  for (size_t i = 0; i < numElementsToPrint ; ++i) {
857  invalidPositionsStrVec.push_back(
858  TfStringify(invalidIndexPositions[i]));
859  }
860 
861  if (errString) {
862  *errString = TfStringPrintf(
863  "Found %ld invalid indices at positions [%s%s] that are out of "
864  "range [0,%ld).", invalidIndexPositions.size(),
865  TfStringJoin(invalidPositionsStrVec, ", ").c_str(),
866  invalidIndexPositions.size() > 5 ? ", ..." : "",
867  authored.size());
868  }
869  }
870 
871  return success;
872 }
873 
874 
875 PXR_NAMESPACE_CLOSE_SCOPE
876 
877 #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:491
#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:560
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.
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:798
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:85
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:230
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:113
const TfToken & GetName() const
Return the full name of this object, i.e.
Definition: object.h:229
bool empty() const
Return true if this array contains no elements, false otherwise.
Definition: array.h:517
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:194
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.