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 <string>
33 #include <vector>
34 
35 PXR_NAMESPACE_OPEN_SCOPE
36 
37 
261 {
262 public:
263 
264  // Default constructor returns an invalid Primvar. Exists for
265  // container classes
267  {
268  /* NOTHING */
269  }
270 
280  USDGEOM_API
281  explicit UsdGeomPrimvar(const UsdAttribute &attr);
282 
288  USDGEOM_API
289  TfToken GetInterpolation() const;
290 
299  USDGEOM_API
300  bool SetInterpolation(const TfToken &interpolation);
301 
305  USDGEOM_API
306  bool HasAuthoredInterpolation() const;
307 
327  USDGEOM_API
328  int GetElementSize() const;
329 
335  USDGEOM_API
336  bool SetElementSize(int eltSize);
337 
341  USDGEOM_API
342  bool HasAuthoredElementSize() const;
343 
344 
349  USDGEOM_API
350  static bool IsPrimvar(const UsdAttribute &attr);
351 
352 
357  USDGEOM_API
358  static bool IsValidPrimvarName(const TfToken& name);
359 
362  USDGEOM_API
363  static TfToken StripPrimvarsName(const TfToken& name);
364 
367  USDGEOM_API
368  static bool IsValidInterpolation(const TfToken &interpolation);
369 
376  USDGEOM_API
377  void GetDeclarationInfo(TfToken *name, SdfValueTypeName *typeName,
378  TfToken *interpolation, int *elementSize) const;
379 
380  // ---------------------------------------------------------------
382  // ---------------------------------------------------------------
384 
388  operator UsdAttribute const& () const { return _attr; }
389 
391  UsdAttribute const &GetAttr() const { return _attr; }
392 
396  bool IsDefined() const { return IsPrimvar(_attr); }
397 
400  bool HasValue() const { return _attr.HasValue(); }
401 
404  bool HasAuthoredValue() const { return _attr.HasAuthoredValue(); }
405 
409  explicit operator bool() const {
410  return IsDefined() ? &UsdGeomPrimvar::_attr : 0;
411  }
412 
414  TfToken const &GetName() const { return _attr.GetName(); }
415 
422  USDGEOM_API
423  TfToken GetPrimvarName() const;
424 
431  USDGEOM_API
432  bool NameContainsNamespaces() const;
433 
435  TfToken GetBaseName() const { return _attr.GetBaseName(); }
436 
438  TfToken GetNamespace() const { return _attr.GetNamespace(); }
439 
441  std::vector<std::string> SplitName() const { return _attr.SplitName(); };
442 
444  SdfValueTypeName GetTypeName() const { return _attr.GetTypeName(); }
445 
450  template <typename T>
451  bool Get(T* value, UsdTimeCode time = UsdTimeCode::Default()) const {
452  return _attr.Get(value, time);
453  }
454 
456  template <typename T>
457  bool Set(const T& value, UsdTimeCode time = UsdTimeCode::Default()) const {
458  return _attr.Set(value, time);
459  }
460 
468  USDGEOM_API
469  bool GetTimeSamples(std::vector<double>* times) const;
470 
477  USDGEOM_API
478  bool GetTimeSamplesInInterval(const GfInterval& interval,
479  std::vector<double>* times) const;
480 
488  USDGEOM_API
489  bool ValueMightBeTimeVarying() const;
490 
492 
493  // ---------------------------------------------------------------
519 
526  USDGEOM_API
527  bool SetIndices(const VtIntArray &indices,
528  UsdTimeCode time = UsdTimeCode::Default()) const;
529 
534  USDGEOM_API
535  bool GetIndices(VtIntArray *indices,
536  UsdTimeCode time = UsdTimeCode::Default()) const;
537 
541  USDGEOM_API
542  void BlockIndices() const;
543 
549  USDGEOM_API
550  bool IsIndexed() const;
551 
554  USDGEOM_API
556 
559  USDGEOM_API
561 
574  USDGEOM_API
575  bool SetUnauthoredValuesIndex(int unauthoredValuesIndex) const;
576 
580  USDGEOM_API
581  int GetUnauthoredValuesIndex() const;
582 
589  template <typename ScalarType>
591  UsdTimeCode time = UsdTimeCode::Default()) const;
592 
600  USDGEOM_API
601  bool ComputeFlattened(VtValue *value,
602  UsdTimeCode time=UsdTimeCode::Default()) const;
603 
614  USDGEOM_API
615  static bool ComputeFlattened(VtValue *value, const VtValue &attrVal,
616  const VtIntArray &indices,
617  std::string *errString);
618 
619 
621 
622  // ---------------------------------------------------------------
652  // ---------------------------------------------------------------
653 
657  USDGEOM_API
658  bool IsIdTarget() const;
659 
664  USDGEOM_API
665  bool SetIdTarget(const SdfPath& path) const;
666 
668 
671  friend bool operator==(const UsdGeomPrimvar &lhs, const UsdGeomPrimvar &rhs) {
672  return lhs.GetAttr() == rhs.GetAttr();
673  }
674 
677  friend bool operator!=(const UsdGeomPrimvar &lhs, const UsdGeomPrimvar &rhs) {
678  return !(lhs == rhs);
679  }
680 
684  friend bool operator<(const UsdGeomPrimvar &lhs, const UsdGeomPrimvar &rhs) {
685  return lhs.GetAttr().GetPath() < rhs.GetAttr().GetPath();
686  }
687 
688  // hash_value overload for std/boost hash.
689  USDGEOM_API
690  friend size_t hash_value(const UsdGeomPrimvar &obj) {
691  return hash_value(obj.GetAttr());
692  }
693 
694 
695 private:
696  friend class UsdGeomImageable;
697  friend class UsdGeomPrimvarsAPI;
698 
701  static bool _IsNamespaced(const TfToken& name);
702 
710  static TfToken _MakeNamespaced(const TfToken& name, bool quiet=false);
711 
712  static TfToken const &_GetNamespacePrefix();
713 
733  UsdGeomPrimvar(const UsdPrim& prim, const TfToken& attrName,
734  const SdfValueTypeName &typeName);
735 
736  UsdAttribute _attr;
737 
738  // upon construction, we'll take note of the attrType. If we're a type
739  // that could possibly have an Id associated with it, we'll store that name
740  // so we don't have to pay the cost of constructing that token per-Get().
741  void _SetIdTargetRelName();
742 
743  // Gets or creates the indices attribute corresponding to the primvar.
744  UsdAttribute _GetIndicesAttr(bool create) const;
745 
746  // Helper method for computing the flattened value of an indexed primvar.
747  template<typename ScalarType>
748  static bool _ComputeFlattenedHelper(const VtArray<ScalarType> &authored,
749  const VtIntArray &indices,
750  VtArray<ScalarType> *value,
751  std::string *errString);
752 
753  // Helper function to evaluate the flattened array value of a primvar given
754  // the attribute value and the indices array.
755  template <typename ArrayType>
756  static bool _ComputeFlattenedArray(const VtValue &attrVal,
757  const VtIntArray &indices,
758  VtValue *value,
759  std::string *errString);
760 
761  // Should only be called if _idTargetRelName is set
762  UsdRelationship _GetIdTargetRel(bool create) const;
763  TfToken _idTargetRelName;
764 };
765 
766 // We instantiate the following so we can check and provide the correct value
767 // for Id attributes.
768 template <>
769 USDGEOM_API bool UsdGeomPrimvar::Get(std::string* value, UsdTimeCode time) const;
770 
771 template <>
772 USDGEOM_API bool UsdGeomPrimvar::Get(VtStringArray* value, UsdTimeCode time) const;
773 
774 template <>
775 USDGEOM_API bool UsdGeomPrimvar::Get(VtValue* value, UsdTimeCode time) const;
776 
777 template <typename ScalarType>
778 bool
780 {
781  VtArray<ScalarType> authored;
782  if (!Get(&authored, time))
783  return false;
784 
785  if (!IsIndexed()) {
786  *value = authored;
787  return true;
788  }
789 
790  VtIntArray indices;
791  if (!GetIndices(&indices, time)) {
792  TF_WARN("No indices authored for indexed primvar <%s>.",
793  _attr.GetPath().GetText());
794  return false;
795  }
796 
797  // If the authored array is empty, there's nothing to do.
798  if (authored.empty())
799  return false;
800 
801  std::string errString;
802  bool res = _ComputeFlattenedHelper(authored, indices, value, &errString);
803  if (!errString.empty()) {
804  TF_WARN("For primvar %s: %s",
805  UsdDescribe(_attr).c_str(), errString.c_str());
806  }
807  return res;
808 }
809 
810 template<typename ScalarType>
811 bool
812 UsdGeomPrimvar::_ComputeFlattenedHelper(const VtArray<ScalarType> &authored,
813  const VtIntArray &indices,
814  VtArray<ScalarType> *value,
815  std::string *errString)
816 {
817  value->resize(indices.size());
818  bool success = true;
819 
820  std::vector<size_t> invalidIndexPositions;
821  for (size_t i=0; i < indices.size(); i++) {
822  int index = indices[i];
823  if (index >= 0 && (size_t)index < authored.size()) {
824  (*value)[i] = authored[index];
825  } else {
826  invalidIndexPositions.push_back(i);
827  success = false;
828  }
829  }
830 
831  if (!invalidIndexPositions.empty()) {
832  std::vector<std::string> invalidPositionsStrVec;
833  // Print a maximum of 5 invalid index positions.
834  size_t numElementsToPrint = std::min(invalidIndexPositions.size(),
835  size_t(5));
836  invalidPositionsStrVec.reserve(numElementsToPrint);
837  for (size_t i = 0; i < numElementsToPrint ; ++i) {
838  invalidPositionsStrVec.push_back(
839  TfStringify(invalidIndexPositions[i]));
840  }
841 
842  if (errString) {
843  *errString = TfStringPrintf(
844  "Found %ld invalid indices at positions [%s%s] that are out of "
845  "range [0,%ld).", invalidIndexPositions.size(),
846  TfStringJoin(invalidPositionsStrVec, ", ").c_str(),
847  invalidIndexPositions.size() > 5 ? ", ..." : "",
848  authored.size());
849  }
850  }
851 
852  return success;
853 }
854 
855 
856 PXR_NAMESPACE_CLOSE_SCOPE
857 
858 #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:677
TfToken GetBaseName() const
Definition: primvar.h:435
bool Set(const T &value, UsdTimeCode time=UsdTimeCode::Default()) const
Set the attribute value of the Primvar at time.
Definition: primvar.h:457
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:505
#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:441
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:564
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:779
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:444
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:132
A basic mathematical interval class.
Definition: interval.h:50
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:288
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:364
UsdAttribute const & GetAttr() const
Explicit UsdAttribute extractor.
Definition: primvar.h:391
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:462
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:404
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:438
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:521
bool HasValue() const
Return true if the underlying attribute has a value, either from authored scene description or a fall...
Definition: primvar.h:400
bool Get(T *value, UsdTimeCode time=UsdTimeCode::Default()) const
Get the attribute value of the Primvar at time .
Definition: primvar.h:451
bool IsDefined() const
Return true if the underlying UsdAttribute::IsDefined(), and in addition the attribute is identified ...
Definition: primvar.h:396
Schema wrapper for UsdAttribute for authoring and introspecting attributes that are primvars.
Definition: primvar.h:260
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:527
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:414
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:671
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:684
Provides a container which may hold any type, and provides introspection and iteration over array typ...
Definition: value.h:168
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.