xformOp.h
Go to the documentation of this file.
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_XFORM_OP_H
25 #define PXR_USD_USD_GEOM_XFORM_OP_H
26 
28 
29 #include "pxr/pxr.h"
30 #include "pxr/usd/usdGeom/api.h"
31 #include "pxr/usd/usd/attribute.h"
32 #include "pxr/usd/usd/attributeQuery.h"
33 #include "pxr/usd/usdGeom/tokens.h"
34 
35 #include <string>
36 #include <vector>
37 #include <typeinfo>
38 
39 #include <boost/variant.hpp>
40 
42 
43 PXR_NAMESPACE_OPEN_SCOPE
44 
45 
47 #define USDGEOM_XFORM_OP_TYPES \
48  (translate) \
49  (scale) \
50  (rotateX) \
51  (rotateY) \
52  (rotateZ) \
53  (rotateXYZ) \
54  (rotateXZY) \
55  (rotateYXZ) \
56  (rotateYZX) \
57  (rotateZXY) \
58  (rotateZYX) \
59  (orient) \
60  (transform) \
61  ((resetXformStack, "!resetXformStack!"))
62 
86 TF_DECLARE_PUBLIC_TOKENS(UsdGeomXformOpTypes, USDGEOM_API, USDGEOM_XFORM_OP_TYPES);
87 
112 {
113 public:
114 
116  enum Type {
124  TypeRotateXZY,
126  TypeRotateYXZ,
128  TypeRotateYZX,
130  TypeRotateZXY,
132  TypeRotateZYX,
134  TypeOrient,
137  };
138 
140  enum Precision {
144  };
145 
146  // Default constructor returns an invalid XformOp. Exists for
147  // container classes
149  {
150  /* NOTHING */
151  }
152 
169  USDGEOM_API
170  explicit UsdGeomXformOp(const UsdAttribute &attr, bool isInverseOp=false);
171 
172  // -------------------------------------------------------
174  // -------------------------------------------------------
175 
180  USDGEOM_API
181  static bool IsXformOp(const UsdAttribute &attr);
182 
187  USDGEOM_API
188  static bool IsXformOp(const TfToken &attrName);
189 
192  USDGEOM_API
193  static TfToken const &GetOpTypeToken(Type const opType);
194 
196  USDGEOM_API
197  static Type GetOpTypeEnum(TfToken const &opTypeToken);
198 
200  USDGEOM_API
202 
205  USDGEOM_API
206  static const SdfValueTypeName &GetValueTypeName(const Type opType,
207  const Precision precision);
208 
212  USDGEOM_API
213  static TfToken GetOpName(const Type opType,
214  const TfToken &opSuffix=TfToken(),
215  bool inverse=false);
216 
217  // -------------------------------------------------------
219  // -------------------------------------------------------
220 
222  Type GetOpType() const {
223  return _opType;
224  }
225 
227  USDGEOM_API
228  Precision GetPrecision() const;
229 
231  bool IsInverseOp() const {
232  return _isInverseOp;
233  }
234 
242  USDGEOM_API
243  TfToken GetOpName() const;
244 
246  USDGEOM_API
247  bool HasSuffix(TfToken const &suffix) const;
248 
249  // ---------------------------------------------------------------
251  // ---------------------------------------------------------------
252 
266  template <typename T>
267  bool GetAs(T* value, UsdTimeCode time) const {
268  VtValue v;
269  if (!Get(&v, time)) {
270  return false;
271  }
272  v.Cast<T>();
273  if (v.IsEmpty()){
274  TfType thisType = GetTypeName().GetType();
275  TF_CODING_ERROR("Unable to convert xformOp %s's value from %s to "
276  "requested type %s.", GetAttr().GetPath().GetText(),
277  thisType.GetTypeName().c_str(),
278  TfType::GetCanonicalTypeName(typeid(*value)).c_str());
279  return false;
280  }
281  *value = v.UncheckedGet<T>();
282  return true;
283  }
284 
294  USDGEOM_API
295  static GfMatrix4d GetOpTransform(Type const opType,
296  VtValue const &opVal,
297  bool isInverseOp=false);
298 
299 
309  USDGEOM_API
311 
317  bool MightBeTimeVarying() const {
318  return boost::apply_visitor(_GetMightBeTimeVarying(), _attr);
319  }
320 
321  // ---------------------------------------------------------------
323  // ---------------------------------------------------------------
324 
328  operator UsdAttribute const& () const { return GetAttr(); }
329 
331  UsdAttribute const &GetAttr() const {
332  return boost::apply_visitor(_GetAttr(), _attr);
333  }
334 
337  bool IsDefined() const { return IsXformOp(GetAttr()); }
338 
339 public:
345  explicit operator bool() const {
346  return IsDefined();
347  }
348 
351  friend bool operator==(const UsdGeomXformOp &lhs,
352  const UsdGeomXformOp &rhs) {
353  return lhs.GetAttr() == rhs.GetAttr();
354  }
355 
358  friend bool operator!=(const UsdGeomXformOp &lhs,
359  const UsdGeomXformOp &rhs) {
360  return !(lhs == rhs);
361  }
362 
364  TfToken const &GetName() const { return GetAttr().GetName(); }
365 
367  TfToken GetBaseName() const { return GetAttr().GetBaseName(); }
368 
370  TfToken GetNamespace() const { return GetAttr().GetNamespace(); }
371 
373  std::vector<std::string> SplitName() const { return GetAttr().SplitName(); };
374 
377 
382  template <typename T>
383  bool Get(T* value, UsdTimeCode time = UsdTimeCode::Default()) const {
384  return boost::apply_visitor(_Get<T>(value, time), _attr);
385  }
386 
393  template <typename T>
394  bool Set(T const & value, UsdTimeCode time = UsdTimeCode::Default()) const {
395  // Issue a coding error and return without setting value,
396  // if this is an inverse op.
397  if (_isInverseOp) {
398  TF_CODING_ERROR("Cannot set a value on the inverse xformOp '%s'. "
399  "Please set value on the paired non-inverse xformOp instead.",
400  GetOpName().GetText());
401  return false;
402  }
403 
404  return GetAttr().Set(value, time);
405  }
406 
409  bool GetTimeSamples(std::vector<double> *times) const {
410  return boost::apply_visitor(_GetTimeSamples(times), _attr);
411  }
412 
415  bool GetTimeSamplesInInterval(const GfInterval &interval,
416  std::vector<double> *times) const {
417  return boost::apply_visitor(
418  _GetTimeSamplesInInterval(interval, times), _attr);
419  }
420 
422  size_t GetNumTimeSamples() const {
423  return boost::apply_visitor(_GetNumTimeSamples(), _attr);
424  }
425 
426 private:
427  struct _ValidAttributeTagType {};
428 
429 public:
430  // Allow clients that guarantee \p attr is valid avoid having
431  // UsdGeomXformOp's ctor check again.
432  USDGEOM_API
433  UsdGeomXformOp(const UsdAttribute &attr, bool isInverseOp,
434  _ValidAttributeTagType);
435  USDGEOM_API
436  UsdGeomXformOp(UsdAttributeQuery &&query, bool isInverseOp,
437  _ValidAttributeTagType);
438 private:
439  friend class UsdGeomXformable;
440 
441  // Shared initialization function.
442  void _Init();
443 
444  // Return the op-type for the string value \p str.
445  static Type _GetOpTypeEnumFromCString(char const *str, size_t len);
446 
447  // Returns the attribute belonging to \p prim that corresponds to the
448  // given \p opName. It also populates the output parameter \p isInverseOp
449  // appropriately.
450  //
451  // The attribute that's returned will be invalid if the
452  // corresponding xformOp attribute doesn't exist on the prim.
453  //
454  static UsdAttribute _GetXformOpAttr(UsdPrim const& prim,
455  const TfToken &opName, bool *isInverseOp);
456 
457  // Private method for creating and using an attribute query interally for
458  // this xformOp.
459  void _CreateAttributeQuery() const {
460  _attr = UsdAttributeQuery(GetAttr());
461  }
462 
463  // Factory for UsdGeomXformable's use, so that we can encapsulate the
464  // logic of what discriminates XformOp in this class, while
465  // preserving the pattern that attributes can only be created
466  // via their container objects.
467  //
468  // \p opType must be one of UsdGeomXformOp::Type
469  //
470  // \p precision must be one of UsdGeomXformOp::Precision.
471  //
472  // \return an invalid UsdGeomXformOp if we failed to create a valid
473  // attribute, a valid UsdGeomXformOp otherwise. It is not an
474  // error to create over an existing, compatible attribute.
475  //
476  // It is a failed verification for \p prim to be invalid/expired
477  //
478  // \sa UsdPrim::CreateAttribute()
479  UsdGeomXformOp(UsdPrim const& prim, Type const opType,
480  Precision const precision, TfToken const &opSuffix=TfToken(),
481  bool inverse=false);
482 
483  // UsdAttributeQuery already contains a copy of the associated UsdAttribute.
484  // To minimize the memory usage, we only store one or the other.
485  //
486  // The lifetime of a UsdAttributeQuery needs to be managed very carefully as
487  // it gets invalidated whenever the associated attribute is authored.
488  // Hence, access to the creation of an attribute query is restricted inside
489  // a private member function named _CreateAttributeQuery().
490  //
491  mutable boost::variant<UsdAttribute, UsdAttributeQuery> _attr;
492 
493  Type _opType;
494  bool _isInverseOp;
495 
496  // Visitor for getting xformOp value.
497  template <class T>
498  struct _Get : public boost::static_visitor<bool>
499  {
500  _Get(T *value_,
501  UsdTimeCode time_ = UsdTimeCode::Default()) : value (value_), time(time_)
502  {}
503 
504  bool operator()(const UsdAttribute &attr) const
505  {
506  return attr.Get(value, time);
507  }
508 
509  bool operator()(const UsdAttributeQuery &attrQuery) const
510  {
511  return attrQuery.Get(value, time);
512  }
513 
514  T *value;
515  UsdTimeCode time;
516  };
517 
518  // Visitor for getting a const-reference to the UsdAttribute.
519  struct _GetAttr : public boost::static_visitor<const UsdAttribute &> {
520 
521  _GetAttr() {}
522 
523  const UsdAttribute &operator()(const UsdAttribute &attr) const
524  {
525  return attr;
526  }
527 
528  const UsdAttribute &operator()(const UsdAttributeQuery &attrQuery) const
529  {
530  return attrQuery.GetAttribute();
531  }
532  };
533 
534  // Visitor for getting all the time samples.
535  struct _GetTimeSamples : public boost::static_visitor<bool> {
536 
537  _GetTimeSamples(std::vector<double> *times_) : times(times_) {}
538 
539  bool operator()(const UsdAttribute &attr) const
540  {
541  return attr.GetTimeSamples(times);
542  }
543 
544  bool operator()(const UsdAttributeQuery &attrQuery) const
545  {
546  return attrQuery.GetTimeSamples(times);
547  }
548 
549  std::vector<double> *times;
550  };
551 
552  // Visitor for getting all the time samples within a given interval.
553  struct _GetTimeSamplesInInterval : public boost::static_visitor<bool> {
554 
555  _GetTimeSamplesInInterval(const GfInterval &interval_,
556  std::vector<double> *times_)
557  : interval(interval_), times(times_)
558  {}
559 
560  bool operator()(const UsdAttribute &attr) const
561  {
562  return attr.GetTimeSamplesInInterval(interval, times);
563  }
564 
565  bool operator()(const UsdAttributeQuery &attrQuery) const
566  {
567  return attrQuery.GetTimeSamplesInInterval(interval, times);
568  }
569 
570  const GfInterval &interval;
571  std::vector<double> *times;
572  };
573 
574  // Visitor for getting the number of time samples.
575  struct _GetNumTimeSamples : public boost::static_visitor<size_t> {
576 
577  _GetNumTimeSamples() {}
578 
579  size_t operator()(const UsdAttribute &attr) const
580  {
581  return attr.GetNumTimeSamples();
582  }
583 
584  size_t operator()(const UsdAttributeQuery &attrQuery) const
585  {
586  return attrQuery.GetNumTimeSamples();
587  }
588  };
589 
590  // Visitor for determining whether the op might vary over time.
591  struct _GetMightBeTimeVarying : public boost::static_visitor<bool> {
592 
593  _GetMightBeTimeVarying() {}
594 
595  bool operator()(const UsdAttribute &attr) const
596  {
597  return attr.ValueMightBeTimeVarying();
598  }
599 
600  bool operator()(const UsdAttributeQuery &attrQuery) const
601  {
602  return attrQuery.ValueMightBeTimeVarying();
603  }
604  };
605 
606 };
607 
608 
609 
610 PXR_NAMESPACE_CLOSE_SCOPE
611 
612 #endif // USD_XFORMOP_H
bool IsInverseOp() const
Returns whether the xformOp represents an inverse operation.
Definition: xformOp.h:231
Set of 3 canonical Euler rotations in ZYX order.
Definition: xformOp.h:133
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
static USDGEOM_API Type GetOpTypeEnum(TfToken const &opTypeToken)
Returns the Type enum associated with the given opTypeToken.
Floating-point precision.
Definition: xformOp.h:142
Set of 3 canonical Euler rotations in ZXY order.
Definition: xformOp.h:131
bool MightBeTimeVarying() const
Determine whether there is any possibility that this op's value may vary over time.
Definition: xformOp.h:317
static USDGEOM_API const SdfValueTypeName & GetValueTypeName(const Type opType, const Precision precision)
Returns the value typeName token that corresponds to the given combination of opType and precision.
Arbitrary axis/angle rotation, expressed as a quaternion.
Definition: xformOp.h:135
Object for efficiently making repeated queries for attribute values.
TF_DECLARE_PUBLIC_TOKENS(UsdGeomXformOpTypes, USDGEOM_API, USDGEOM_XFORM_OP_TYPES)
UsdAttribute const & GetAttr() const
Explicit UsdAttribute extractor.
Definition: xformOp.h:331
Type GetOpType() const
Return the operation type of this op, one of UsdGeomXformOp::Type.
Definition: xformOp.h:222
static USDGEOM_API TfToken const & GetOpTypeToken(Type const opType)
Returns the TfToken used to encode the given opType.
Schema wrapper for UsdAttribute for authoring and computing transformation operations,...
Definition: xformOp.h:111
#define TF_CODING_ERROR(fmt, args)
Issue an internal programming error, but continue execution.
Definition: diagnostic.h:85
Type
Enumerates the set of all transformation operation types.
Definition: xformOp.h:116
USDGEOM_API TfToken GetOpName() const
Returns the opName as it appears in the xformOpOrder attribute.
USD_API bool GetTimeSamples(std::vector< double > *times) const
Populates a vector with authored sample times.
Represents a value type name, i.e.
Definition: valueTypeName.h:87
Scenegraph object for authoring and retrieving numeric, string, and array valued data,...
Definition: attribute.h:176
USDGEOM_API bool HasSuffix(TfToken const &suffix) const
Does this op have the given suffix in its name.
TfToken GetBaseName() const
Definition: xformOp.h:367
USD_API size_t GetNumTimeSamples() const
Returns the number of time samples that have been authored.
TF_API const std::string & GetTypeName() const
Return the machine-independent name for this type.
friend bool operator!=(const UsdGeomXformOp &lhs, const UsdGeomXformOp &rhs)
Inequality comparison.
Definition: xformOp.h:358
static USDGEOM_API GfMatrix4d GetOpTransform(Type const opType, VtValue const &opVal, bool isInverseOp=false)
Return the 4x4 matrix that applies the transformation encoded by op opType and data value opVal.
USD_API const UsdAttribute & GetAttribute() const
Return the attribute associated with this query.
bool Set(T const &value, UsdTimeCode time=UsdTimeCode::Default()) const
Set the attribute value of the XformOp at time.
Definition: xformOp.h:394
Set of 3 canonical Euler rotations in XZY order.
Definition: xformOp.h:125
Token for efficient comparison, assignment, and hashing of known strings.
Definition: token.h:87
bool GetTimeSamples(std::vector< double > *times) const
Populates the list of time samples at which the associated attribute is authored.
Definition: xformOp.h:409
SdfValueTypeName GetTypeName() const
Definition: xformOp.h:376
static TF_API std::string GetCanonicalTypeName(const std::type_info &)
Return the canonical typeName used for a given std::type_info.
Stores a 4x4 matrix of double elements.
Definition: matrix4d.h:88
bool IsEmpty() const
Returns true iff this value is empty.
Definition: value.h:1244
USD_API bool ValueMightBeTimeVarying() const
Return true if it is possible, but not certain, that this attribute's value changes over time,...
Represent a time value, which may be either numeric, holding a double value, or a sentinel value UsdT...
Definition: timeCode.h:85
Rotation about the Z-axis, in degrees.
Definition: xformOp.h:122
USD_API std::vector< std::string > SplitName() const
Return this property's name elements including namespaces and its base name as the final element.
Represents an invalid xformOp.
Definition: xformOp.h:117
USD_API bool GetTimeSamplesInInterval(const GfInterval &interval, std::vector< double > *times) const
Populates a vector with authored sample times in interval.
UsdPrim is the sole persistent scenegraph object on a UsdStage, and is the embodiment of a "Prim" as ...
Definition: prim.h:132
A 4x4 matrix transformation.
Definition: xformOp.h:136
Rotation about the Y-axis, in degrees.
Definition: xformOp.h:121
friend bool operator==(const UsdGeomXformOp &lhs, const UsdGeomXformOp &rhs)
Equality comparison.
Definition: xformOp.h:351
A basic mathematical interval class.
Definition: interval.h:50
TfToken const & GetName() const
Definition: xformOp.h:364
T const & UncheckedGet() const
Returns a const reference to the held object if the held object is of type T.
Definition: value.h:1090
static VtValue Cast(VtValue const &val)
Return a VtValue holding val cast to hold T.
Definition: value.h:1152
bool Get(T *value, UsdTimeCode time=UsdTimeCode::Default()) const
Perform value resolution to fetch the value of the attribute associated with this query at the reques...
USD_API bool GetTimeSamples(std::vector< double > *times) const
Populates a vector with authored sample times.
bool GetAs(T *value, UsdTimeCode time) const
We allow ops to be encoded with varying degrees of precision, depending on the clients needs and cons...
Definition: xformOp.h:267
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
static USDGEOM_API Precision GetPrecisionFromValueTypeName(const SdfValueTypeName &typeName)
Returns the precision corresponding to the given value typeName.
Precision
Precision with which the value of the tranformation operation is encoded.
Definition: xformOp.h:140
Set of 3 canonical Euler rotations in YZX order.
Definition: xformOp.h:129
USDGEOM_API Precision GetPrecision() const
Returns the precision level of the xform op.
TfToken GetNamespace() const
Definition: xformOp.h:370
USD_API bool ValueMightBeTimeVarying() const
Return true if it is possible, but not certain, that this attribute's value changes over time,...
This file defines some macros that are useful for declaring and using static TfTokens.
XYZ translation.
Definition: xformOp.h:118
static constexpr UsdTimeCode Default()
Produce a UsdTimeCode representing the sentinel value for 'default'.
Definition: timeCode.h:113
USD_API size_t GetNumTimeSamples() const
Returns the number of time samples that have been authored.
const TfToken & GetName() const
Return the full name of this object, i.e.
Definition: object.h:229
static USDGEOM_API bool IsXformOp(const UsdAttribute &attr)
Test whether a given UsdAttribute represents valid XformOp, which implies that creating a UsdGeomXfor...
Set of 3 canonical Euler rotations in YXZ order.
Definition: xformOp.h:127
USD_API bool GetTimeSamplesInInterval(const GfInterval &interval, std::vector< double > *times) const
Populates a vector with authored sample times in interval.
TfType represents a dynamic runtime type.
Definition: type.h:64
std::vector< std::string > SplitName() const
Definition: xformOp.h:373
size_t GetNumTimeSamples() const
Returns the number of time samples authored for this xformOp.
Definition: xformOp.h:422
Rotation about the X-axis, in degrees.
Definition: xformOp.h:120
Half-float precision.
Definition: xformOp.h:143
USD_API SdfValueTypeName GetTypeName() const
Return the "scene description" value type name for this attribute.
USD_API TfToken GetBaseName() const
Return this property's name with all namespace prefixes removed, i.e.
bool GetTimeSamplesInInterval(const GfInterval &interval, std::vector< double > *times) const
Populates the list of time samples within the given interval, at which the associated attribute is au...
Definition: xformOp.h:415
Set of 3 canonical Euler rotations in XYZ order.
Definition: xformOp.h:123
bool Get(T *value, UsdTimeCode time=UsdTimeCode::Default()) const
Get the attribute value of the XformOp at time.
Definition: xformOp.h:383
Base class for all transformable prims, which allows arbitrary sequences of component affine transfor...
Definition: xformable.h:252
SDF_API const TfType & GetType() const
Returns the TfType of the type.
bool IsDefined() const
Return true if the wrapped UsdAttribute::IsDefined(), and in addition the attribute is identified as ...
Definition: xformOp.h:337
Provides a container which may hold any type, and provides introspection and iteration over array typ...
Definition: value.h:168
USD_API TfToken GetNamespace() const
Return this property's complete namespace prefix.